コード例 #1
0
        /// <summary>
        /// Fills the dialog placeholders
        /// </summary>
        /// <param name="code">Code</param>
        /// <param name="npc">Npc</param>
        /// <returns>Filled code</returns>
        private async Task <string> FillDialogPlaceholders(string code, KortistoNpc npc)
        {
            GoNorthProject project = await _cachedDbAccess.GetDefaultProject();

            TaleDialog dialog = await _taleDbAccess.GetDialogByRelatedObjectId(npc.Id);

            try
            {
                _errorCollection.CurrentErrorContext = _localizer["DialogErrorContext"].Value;
                _dialogParser.SetErrorCollection(_errorCollection);
                _dialogRenderer.SetErrorCollection(_errorCollection);
                ExportDialogData exportDialog   = null;
                bool             hasValidDialog = HasValidDialog(dialog);
                if (hasValidDialog)
                {
                    exportDialog = _dialogParser.ParseDialog(dialog);
                    if (exportDialog == null)
                    {
                        return(string.Empty);
                    }
                    exportDialog = await _dialogFunctionGenerator.GenerateFunctions(project.Id, npc.Id, exportDialog, _errorCollection);
                }

                code = ExportUtil.RenderPlaceholderIfTrue(code, Placeholder_HasDialog_Start, Placeholder_HasDialog_End, hasValidDialog);

                code = await RenderDialog(project, code, exportDialog, dialog, npc);
            }
            finally
            {
                _errorCollection.CurrentErrorContext = "";
            }

            return(code);
        }
コード例 #2
0
        /// <summary>
        /// Returns the npc use
        /// </summary>
        /// <param name="flexFieldObject">Flex field object</param>
        /// <param name="parsedData">Parsed data</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <returns>Value Object</returns>
        private async Task <IFlexFieldExportable> GetNpc(FlexFieldObject flexFieldObject, UseItemActionRenderer.UseItemActionData parsedData, ExportPlaceholderErrorCollection errorCollection)
        {
            if (_isPickNpc)
            {
                KortistoNpc npc = await _cachedDbAccess.GetNpcById(parsedData.NpcId);

                if (npc == null)
                {
                    errorCollection.AddDialogItemNotFoundError();
                    return(null);
                }

                return(npc);
            }
            else if (_isPlayer)
            {
                GoNorthProject curProject = await _cachedDbAccess.GetDefaultProject();

                KortistoNpc npc = await _cachedDbAccess.GetPlayerNpc(curProject.Id);

                if (npc == null)
                {
                    errorCollection.AddNoPlayerNpcExistsError();
                    return(null);
                }

                return(npc);
            }

            return(flexFieldObject);
        }
        /// <summary>
        /// Fills the daily routine placeholders
        /// </summary>
        /// <param name="code">Code</param>
        /// <param name="npc">Npc</param>
        /// <returns>Filled code</returns>
        private async Task <string> FillDailyRoutinePlaceholders(string code, KortistoNpc npc)
        {
            GoNorthProject project = await _cachedDbAccess.GetDefaultProject();

            ExportTemplate dailyRoutineEventTemplate = await _defaultTemplateProvider.GetDefaultTemplateByType(project.Id, TemplateType.ObjectDailyRoutineEventList);

            ExportTemplate dailyRoutineFunctionListTemplate = await _defaultTemplateProvider.GetDefaultTemplateByType(project.Id, TemplateType.ObjectDailyRoutineFunctionList);

            ExportTemplate dailyRoutineFunctionTemplate = await _defaultTemplateProvider.GetDefaultTemplateByType(project.Id, TemplateType.ObjectDailyRoutineFunction);

            code = ExportUtil.BuildPlaceholderRegex(Placeholder_DailyRoutine_Events, ExportConstants.ListIndentPrefix).Replace(code, m => {
                return(ExportUtil.IndentListTemplate(dailyRoutineEventTemplate.Code, m.Groups[1].Value));
            });

            code = ExportUtil.BuildPlaceholderRegex(Placeholder_DailyRoutine_Functions, ExportConstants.ListIndentPrefix).Replace(code, m => {
                return(ExportUtil.IndentListTemplate(dailyRoutineFunctionListTemplate.Code, m.Groups[1].Value));
            });

            code = ExportUtil.BuildPlaceholderRegex(Placeholder_DailyRoutine_Function, ExportConstants.ListIndentPrefix).Replace(code, m => {
                return(ExportUtil.IndentListTemplate(dailyRoutineFunctionTemplate.Code, m.Groups[1].Value));
            });

            code = ExportUtil.RenderPlaceholderIfTrue(code, Placeholder_HasDailyRoutine_Start, Placeholder_HasDailyRoutine_End, npc.DailyRoutine != null && npc.DailyRoutine.Count > 0);

            code = ExportUtil.BuildRangePlaceholderRegex(Placeholder_DailyRoutine_Events_Start, Placeholder_DailyRoutine_Events_End).Replace(code, m => {
                return(ExportUtil.TrimEmptyLines(BuildEventList(m.Groups[1].Value, project, npc)));
            });

            code = ExportUtil.BuildRangePlaceholderRegex(Placeholder_DailyRoutine_Functions_Start, Placeholder_DailyRoutine_Functions_End).Replace(code, m => {
                return(ExportUtil.TrimEmptyLines(BuildFunctionList(m.Groups[1].Value, project, npc)));
            });

            return(code);
        }
コード例 #4
0
        /// <summary>
        /// Returns the npc to use
        /// </summary>
        /// <param name="flexFieldObject">Flex field object to which the dialog belongs</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <returns>Value Object</returns>
        private async Task<IFlexFieldExportable> GetNpc(FlexFieldObject flexFieldObject, ExportPlaceholderErrorCollection errorCollection)
        {
            if(_isPlayer)
            {
                GoNorthProject curProject = await _cachedDbAccess.GetDefaultProject();
                flexFieldObject = await _cachedDbAccess.GetPlayerNpc(curProject.Id);
                if(flexFieldObject == null)
                {
                    errorCollection.AddNoPlayerNpcExistsError();
                    return null;
                }
            }

            return flexFieldObject;
        }
コード例 #5
0
        /// <summary>
        /// Fills the language key Placeholders
        /// </summary>
        /// <param name="code">Code to fill</param>
        /// <param name="flexFieldObject">Flex Field Object</param>
        /// <returns>Filled Code</returns>
        private async Task <string> FillLanguageKeyPlaceholders(string code, IFlexFieldExportable flexFieldObject)
        {
            GoNorthProject project = await _cachedDbAccess.GetDefaultProject();

            List <LanguageKey> languageKeys = await _languageKeyDbAccess.GetLanguageKeysByGroupId(project.Id, flexFieldObject.Id);

            ExportSettings exportSettings = await _cachedDbAccess.GetExportSettings(project.Id);

            code = ExportUtil.BuildPlaceholderRegex(Placeholder_ObjectName).Replace(code, flexFieldObject.Name);
            code = ExportUtil.BuildRangePlaceholderRegex(Placeholder_LanguageKeys_Start, Placeholder_LanguageKeys_End).Replace(code, m => {
                return(BuildLanguageKeyList(m.Groups[1].Value, languageKeys, exportSettings));
            });

            return(code);
        }
コード例 #6
0
        /// <summary>
        /// Fills the inventory placeholders
        /// </summary>
        /// <param name="code">Code</param>
        /// <param name="npc">Npc</param>
        /// <returns>Filled code</returns>
        private async Task <string> FillInventoryPlaceholders(string code, KortistoNpc npc)
        {
            GoNorthProject project = await _cachedDbAccess.GetDefaultProject();

            ExportTemplate inventoryTemplate = await _defaultTemplateProvider.GetDefaultTemplateByType(project.Id, TemplateType.ObjectInventory);

            code = ExportUtil.BuildPlaceholderRegex(Placeholder_Inventory, ExportConstants.ListIndentPrefix).Replace(code, m => {
                return(ExportUtil.IndentListTemplate(inventoryTemplate.Code, m.Groups[1].Value));
            });

            code = ExportUtil.BuildRangePlaceholderRegex(Placeholder_Inventory_Start, Placeholder_Inventory_End).Replace(code, m => {
                return(ExportUtil.TrimEmptyLines(BuildInventory(m.Groups[1].Value, npc)));
            });

            return(code);
        }
コード例 #7
0
        /// <summary>
        /// Returns the currently valid npc for the action
        /// </summary>
        /// <param name="parsedData">Parsed data</param>
        /// <param name="flexFieldObject">Flex field object</param>
        /// <returns>Npc</returns>
        private async Task <KortistoNpc> GetNpc(MoveNpcActionRenderer.MoveNpcActionData parsedData, FlexFieldObject flexFieldObject)
        {
            if (_isPickedNpc)
            {
                return(await _cachedDbAccess.GetNpcById(parsedData.ObjectId));
            }

            if (_isPlayer)
            {
                GoNorthProject project = await _cachedDbAccess.GetDefaultProject();

                return(await _cachedDbAccess.GetPlayerNpc(project.Id));
            }

            return(flexFieldObject as KortistoNpc);
        }
コード例 #8
0
        /// <summary>
        /// Returns the npc to use
        /// </summary>
        /// <param name="npc">Npc to which the dialog belongs</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <returns>Value Object</returns>
        private async Task <IFlexFieldExportable> GetNpc(KortistoNpc npc, ExportPlaceholderErrorCollection errorCollection)
        {
            if (_isPlayer)
            {
                GoNorthProject curProject = await _cachedDbAccess.GetDefaultProject();

                npc = await _cachedDbAccess.GetPlayerNpc(curProject.Id);

                if (npc == null)
                {
                    errorCollection.AddNoPlayerNpcExistsError();
                    return(null);
                }
            }

            return(npc);
        }
コード例 #9
0
        /// <summary>
        /// Fills the skill placeholders
        /// </summary>
        /// <param name="code">Code</param>
        /// <param name="npc">Npc</param>
        /// <returns>Filled code</returns>
        private async Task <string> FillSkillPlaceholders(string code, KortistoNpc npc)
        {
            GoNorthProject project = await _cachedDbAccess.GetDefaultProject();

            ExportTemplate skillTemplate = await _defaultTemplateProvider.GetDefaultTemplateByType(project.Id, TemplateType.ObjectSkillList);

            code = ExportUtil.BuildPlaceholderRegex(Placeholder_Skills, ExportConstants.ListIndentPrefix).Replace(code, m => {
                return(ExportUtil.IndentListTemplate(skillTemplate.Code, m.Groups[1].Value));
            });

            code = ExportUtil.RenderPlaceholderIfTrue(code, Placeholder_HasSkills_Start, Placeholder_HasSkills_End, npc.Skills != null && npc.Skills.Count > 0);

            code = ExportUtil.BuildRangePlaceholderRegex(Placeholder_Skill_Start, Placeholder_Skill_End).Replace(code, m => {
                return(ExportUtil.TrimEmptyLines(BuildSkills(m.Groups[1].Value, npc)));
            });

            return(code);
        }
コード例 #10
0
        /// <summary>
        /// Resolved the placeholders for a single daily routine event
        /// </summary>
        /// <param name="code">Code to resolve the placeholders in</param>
        /// <param name="npc">Npc to which the event belongs</param>
        /// <param name="dailyRoutineEvent">Daily routine to use for resolving the placeholders</param>
        /// <returns>Code with resolved placeholders</returns>
        public async Task <string> ResolveDailyRoutineEventPlaceholders(string code, KortistoNpc npc, KortistoNpcDailyRoutineEvent dailyRoutineEvent)
        {
            GoNorthProject defaultProject = await _cachedDbAccess.GetDefaultProject();

            MiscProjectConfig projectConfig = await _cachedDbAccess.GetMiscProjectConfig();

            code = ExportUtil.RenderPlaceholderIfTrue(code, Placeholder_HasMovementTargetStart, Placeholder_HasMovementTargetEnd, dailyRoutineEvent.MovementTarget != null && !string.IsNullOrEmpty(dailyRoutineEvent.MovementTarget.Name));
            code = ExportUtil.RenderPlaceholderIfTrue(code, Placeholder_HasNoMovementTargetStart, Placeholder_HasNoMovementTargetEnd, dailyRoutineEvent.MovementTarget == null || string.IsNullOrEmpty(dailyRoutineEvent.MovementTarget.Name));
            code = ExportUtil.RenderPlaceholderIfTrue(code, Placeholder_HasMovementTargetExportNameStart, Placeholder_HasMovementTargetExportNameEnd, dailyRoutineEvent.MovementTarget != null && !string.IsNullOrEmpty(dailyRoutineEvent.MovementTarget.ExportName));
            code = ExportUtil.RenderPlaceholderIfTrue(code, Placeholder_HasNoMovementTargetExportNameStart, Placeholder_HasNoMovementTargetExportNameEnd, dailyRoutineEvent.MovementTarget == null || string.IsNullOrEmpty(dailyRoutineEvent.MovementTarget.ExportName));
            code = ExportUtil.RenderPlaceholderIfTrue(code, Placeholder_HasNoScriptStart, Placeholder_HasNoScriptEnd, dailyRoutineEvent.ScriptType == ScriptType_None);
            code = ExportUtil.RenderPlaceholderIfTrue(code, Placeholder_HasScriptStart, Placeholder_HasScriptEnd, dailyRoutineEvent.ScriptType != ScriptType_None);
            code = ExportUtil.RenderPlaceholderIfTrue(code, Placeholder_HasNodeGraphScriptStart, Placeholder_HasNodeGraphScriptEnd, dailyRoutineEvent.ScriptType == ScriptType_NodeGraph);
            code = ExportUtil.RenderPlaceholderIfTrue(code, Placeholder_HasCodeScriptStart, Placeholder_HasCodeScriptEnd, dailyRoutineEvent.ScriptType == ScriptType_Code);
            code = ExportUtil.RenderPlaceholderIfTrue(code, Placeholder_HasTargetStateStart, Placeholder_HasTargetStateEnd, !string.IsNullOrEmpty(dailyRoutineEvent.TargetState));
            code = ExportUtil.RenderPlaceholderIfTrue(code, Placeholder_HasNoTargetStateStart, Placeholder_HasNoTargetStateEnd, string.IsNullOrEmpty(dailyRoutineEvent.TargetState));
            code = ExportUtil.RenderPlaceholderIfTrue(code, Placeholder_IsEnabledByDefaultStart, Placeholder_IsEnabledByDefaultEnd, dailyRoutineEvent.EnabledByDefault);
            code = ExportUtil.RenderPlaceholderIfTrue(code, Placeholder_IsDisabledByDefaultStart, Placeholder_IsDisabledByDefaultEnd, !dailyRoutineEvent.EnabledByDefault);

            code = ExportUtil.BuildPlaceholderRegex(Placeholder_EventId).Replace(code, dailyRoutineEvent.EventId);
            code = ExportUtil.BuildPlaceholderRegex(Placeholder_EarliestTime_Hours).Replace(code, dailyRoutineEvent.EarliestTime != null ? dailyRoutineEvent.EarliestTime.Hours.ToString() : string.Empty);
            code = ExportUtil.BuildPlaceholderRegex(Placeholder_EarliestTime_Minutes).Replace(code, dailyRoutineEvent.EarliestTime != null ? dailyRoutineEvent.EarliestTime.Minutes.ToString() : string.Empty);
            code = ExportUtil.BuildPlaceholderRegex(Placeholder_EarliestTime_TotalMinutes).Replace(code, dailyRoutineEvent.EarliestTime != null ? (dailyRoutineEvent.EarliestTime.Hours * projectConfig.MinutesPerHour + dailyRoutineEvent.EarliestTime.Minutes).ToString() : string.Empty);
            code = ExportUtil.BuildPlaceholderRegex(Placeholder_LatestTime_Hours).Replace(code, dailyRoutineEvent.LatestTime != null ? dailyRoutineEvent.LatestTime.Hours.ToString() : string.Empty);
            code = ExportUtil.BuildPlaceholderRegex(Placeholder_LatestTime_Minutes).Replace(code, dailyRoutineEvent.LatestTime != null ? dailyRoutineEvent.LatestTime.Minutes.ToString() : string.Empty);
            code = ExportUtil.BuildPlaceholderRegex(Placeholder_LatestTime_TotalMinutes).Replace(code, dailyRoutineEvent.LatestTime != null ? (dailyRoutineEvent.LatestTime.Hours * projectConfig.MinutesPerHour + dailyRoutineEvent.LatestTime.Minutes).ToString() : string.Empty);
            code = ExportUtil.BuildPlaceholderRegex(Placeholder_MovementTargetName).Replace(code, dailyRoutineEvent.MovementTarget != null && dailyRoutineEvent.MovementTarget.Name != null ? dailyRoutineEvent.MovementTarget.Name : string.Empty);
            code = ExportUtil.BuildPlaceholderRegex(Placeholder_MovementTargetExportName).Replace(code, dailyRoutineEvent.MovementTarget != null && dailyRoutineEvent.MovementTarget.ExportName != null ? dailyRoutineEvent.MovementTarget.ExportName : string.Empty);
            code = ExportUtil.BuildPlaceholderRegex(Placeholder_MovementTargetExportNameOrName).Replace(code, dailyRoutineEvent.MovementTarget != null && !string.IsNullOrEmpty(dailyRoutineEvent.MovementTarget.ExportName) ? dailyRoutineEvent.MovementTarget.ExportName : (dailyRoutineEvent.MovementTarget != null && dailyRoutineEvent.MovementTarget.Name != null ? dailyRoutineEvent.MovementTarget.Name : string.Empty));
            code = ExportUtil.BuildPlaceholderRegex(Placeholder_ScriptFunctionName).Replace(code, m => {
                return(_dailyRoutineFunctionNameGenerator.GetNewDailyRoutineStepFunction(defaultProject.Id, npc.Id, dailyRoutineEvent.EventId).Result);
            });
            code = ExportUtil.BuildPlaceholderRegex(Placeholder_ScriptName).Replace(code, dailyRoutineEvent.ScriptName != null ? dailyRoutineEvent.ScriptName : string.Empty);
            code = ExportUtil.BuildPlaceholderRegex(Placeholder_TargetState).Replace(code, dailyRoutineEvent.TargetState != null ? dailyRoutineEvent.TargetState : string.Empty);

            return(code);
        }
コード例 #11
0
        /// <summary>
        /// Renders a dialog
        /// </summary>
        /// <param name="exportDialog">Export Dialog</param>
        /// <param name="npc">Npc to which the dialog belongs</param>
        /// <returns>Result of rendering the dialog</returns>
        public async Task <ExportDialogRenderResult> RenderDialog(ExportDialogData exportDialog, KortistoNpc npc)
        {
            _curProject = await _cachedDbAccess.GetDefaultProject();

            _exportSettings = await _cachedDbAccess.GetExportSettings(_curProject.Id);

            SetupStepRenderes();

            ExportDialogRenderResult renderResult = new ExportDialogRenderResult();

            renderResult.StartStepCode           = string.Empty;
            renderResult.AdditionalFunctionsCode = string.Empty;

            // Group to Functions
            ExportDialogFunction rootFunction = new ExportDialogFunction(exportDialog);

            AddNodesToFunction(rootFunction, exportDialog);
            List <ExportDialogFunction> additionalFunctions = ExtractAdditionalFunctions(exportDialog);

            // Render functions
            string startStepCode = await RenderDialogStepList(rootFunction.FunctionSteps, npc);

            string additionalFunctionsCode = string.Empty;

            foreach (ExportDialogFunction curAdditionalFunction in additionalFunctions)
            {
                additionalFunctionsCode += await RenderDialogFunction(curAdditionalFunction, npc);
            }

            ExportTemplate dialogStepTemplate = await _defaultTemplateProvider.GetDefaultTemplateByType(_curProject.Id, TemplateType.TaleDialogStep);

            renderResult.StartStepCode           = ExportUtil.BuildPlaceholderRegex(Placeholder_StepContent).Replace(dialogStepTemplate.Code, startStepCode);
            renderResult.AdditionalFunctionsCode = additionalFunctionsCode;

            return(renderResult);
        }
コード例 #12
0
        /// <summary>
        /// Fills the Flex Field Placeholders
        /// </summary>
        /// <param name="code">Code to fill</param>
        /// <param name="flexFieldObject">Flex Field Object</param>
        /// <param name="objectType">Object Type</param>
        /// <returns>Filled Code</returns>
        private async Task <string> FillFlexFieldPlaceholders(string code, IFlexFieldExportable flexFieldObject, string objectType)
        {
            GoNorthProject project = await _exportCachedDbAccess.GetDefaultProject();

            ExportSettings exportSettings = await _exportCachedDbAccess.GetExportSettings(project.Id);

            ExportTemplate attributeListTemplate = await _defaultTemplateProvider.GetDefaultTemplateByType(project.Id, TemplateType.ObjectAttributeList);

            HashSet <string> usedFields = new HashSet <string>();

            code = ExportUtil.BuildPlaceholderRegex(BuildFinalPlaceholder(Placeholder_Name)).Replace(code, flexFieldObject.Name);
            code = ExportUtil.RenderPlaceholderIfFuncTrue(code, BuildFinalPlaceholder(Placeholder_Field_Value_Equals_Start), BuildFinalPlaceholder(Placeholder_Field_Value_Equals_End), m => {
                string fieldName = m.Groups[1].Value;
                FlexField field  = FindFlexField(flexFieldObject, fieldName);
                if (field == null)
                {
                    return(false);
                }
                return(m.Groups[2].Value == field.Value);
            });
            code = ExportUtil.RenderPlaceholderIfFuncTrue(code, BuildFinalPlaceholder(Placeholder_Field_Value_NotEquals_Start), BuildFinalPlaceholder(Placeholder_Field_Value_NotEquals_End), m => {
                string fieldName = m.Groups[1].Value;
                FlexField field  = FindFlexField(flexFieldObject, fieldName);
                if (field == null)
                {
                    return(true);
                }
                return(m.Groups[2].Value != field.Value);
            });
            code = ExportUtil.RenderPlaceholderIfFuncTrue(code, BuildFinalPlaceholder(Placeholder_FlexField_HasField_Start), BuildFinalPlaceholder(Placeholder_FlexField_HasField_End), m => {
                string fieldName = m.Groups[1].Value;
                FlexField field  = FindFlexField(flexFieldObject, fieldName);
                return(field != null);
            });
            code = ExportUtil.RenderPlaceholderIfFuncTrue(code, BuildFinalPlaceholder(Placeholder_FlexField_NotHasField_Start), BuildFinalPlaceholder(Placeholder_FlexField_NotHasField_End), m => {
                string fieldName = m.Groups[1].Value;
                FlexField field  = FindFlexField(flexFieldObject, fieldName);
                return(field == null);
            });
            code = ExportUtil.RenderPlaceholderIfFuncTrue(code, BuildFinalPlaceholder(Placeholder_FlexField_FieldIsBlank_Start), BuildFinalPlaceholder(Placeholder_FlexField_FieldIsBlank_End), m => {
                string fieldName = m.Groups[1].Value;
                FlexField field  = FindFlexField(flexFieldObject, fieldName);
                if (field == null)
                {
                    return(true);
                }

                return(string.IsNullOrEmpty(field.Value));
            });
            code = ExportUtil.RenderPlaceholderIfFuncTrue(code, BuildFinalPlaceholder(Placeholder_FlexField_FieldIsNotBlank_Start), BuildFinalPlaceholder(Placeholder_FlexField_FieldIsNotBlank_End), m => {
                string fieldName = m.Groups[1].Value;
                FlexField field  = FindFlexField(flexFieldObject, fieldName);
                if (field == null)
                {
                    return(false);
                }

                return(!string.IsNullOrEmpty(field.Value));
            });
            code = ExportUtil.BuildPlaceholderRegex(BuildFinalPlaceholder(Placeholder_Name_LangKey)).Replace(code, m => {
                // Run in function to only create language key if required
                string key = _languageKeyGenerator.GetFlexFieldNameKey(flexFieldObject.Id, flexFieldObject.Name, objectType).Result;
                return(key);
            });
            code = ExportUtil.BuildPlaceholderRegex(BuildFinalPlaceholder(Placeholder_Field_Value)).Replace(code, m => {
                string fieldName = m.Groups[1].Value;
                FlexField field  = FindFlexField(flexFieldObject, fieldName);
                if (field != null)
                {
                    usedFields.Add(field.Id);
                    return(EscapedFieldValue(field, exportSettings));
                }

                _errorCollection.AddErrorFlexField(fieldName, flexFieldObject.Name);
                return("<<" + flexFieldObject.Name + "[" + fieldName + "] MISSING>>");
            });
            code = ExportUtil.BuildPlaceholderRegex(BuildFinalPlaceholder(Placeholder_Field_LangKey)).Replace(code, m => {
                string fieldName = m.Groups[1].Value;
                FlexField field  = FindFlexField(flexFieldObject, fieldName);
                if (field != null && (field.FieldType == ExportConstants.FlexFieldType_String || field.FieldType == ExportConstants.FlexFieldType_Option))
                {
                    usedFields.Add(field.Id);
                    return(BuildFlexFieldLangKey(flexFieldObject, field, objectType));
                }

                _errorCollection.AddErrorFlexField(fieldName, flexFieldObject.Name);
                return("<<" + flexFieldObject.Name + "[" + fieldName + "] MISSING>>");
            });

            code = ExportUtil.BuildPlaceholderRegex(BuildFinalPlaceholder(Placeholder_UnusedFields), ExportConstants.ListIndentPrefix).Replace(code, m => {
                return(BuildFlexFieldListTemplate(attributeListTemplate.Code, Placeholder_UnusedFields_Start, Placeholder_UnusedFields_End, m.Groups[1].Value));
            });
            code = ExportUtil.BuildPlaceholderRegex(BuildFinalPlaceholder(Placeholder_AllFields), ExportConstants.ListIndentPrefix).Replace(code, m => {
                return(BuildFlexFieldListTemplate(attributeListTemplate.Code, Placeholder_AllFields_Start, Placeholder_AllFields_End, m.Groups[1].Value));
            });
            code = ExportUtil.BuildRangePlaceholderRegex(BuildFinalPlaceholder(Placeholder_UnusedFields_Start), BuildFinalPlaceholder(Placeholder_UnusedFields_End)).Replace(code, m => {
                List <FlexField> fieldsToUse = flexFieldObject.Fields.Where(f => !usedFields.Contains(f.Id)).ToList();
                return(BuildFlexFieldList(m.Groups[1].Value, fieldsToUse, flexFieldObject, exportSettings, objectType));
            });
            code = ExportUtil.BuildRangePlaceholderRegex(BuildFinalPlaceholder(Placeholder_AllFields_Start), BuildFinalPlaceholder(Placeholder_AllFields_End)).Replace(code, m => {
                return(BuildFlexFieldList(m.Groups[1].Value, flexFieldObject.Fields, flexFieldObject, exportSettings, objectType));
            });

            return(code);
        }