Exemplo n.º 1
0
        /// <summary>
        /// Builds a parent text preview for the a dialog step
        /// </summary>
        /// <param name="child">Child node</param>
        /// <param name="parent">Parent</param>
        /// <param name="flexFieldObject">Flex field object to which the dialog belongs</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <returns>Parent text preview for the dialog step</returns>
        public async Task <string> BuildParentTextPreview(ExportDialogData child, ExportDialogData parent, FlexFieldObject flexFieldObject, ExportPlaceholderErrorCollection errorCollection)
        {
            ConditionNode conditionNode = parent.Condition;

            if (conditionNode == null)
            {
                return(null);
            }

            List <string> previewForConditions = new List <string>();

            foreach (Condition curCondition in conditionNode.Conditions)
            {
                ExportDialogDataChild childObj = parent.Children.FirstOrDefault(c => c.NodeChildId == curCondition.Id);
                if (childObj == null || childObj.Child != child)
                {
                    continue;
                }

                string conditionText = await _conditionRenderer.RenderCondition(_project, curCondition, _errorCollection, flexFieldObject, _exportSettings);

                previewForConditions.Add(ExportUtil.BuildTextPreview(conditionText));
            }

            if (parent.Children.Any(c => c.Child == child && c.NodeChildId == ExportConstants.ConditionElseNodeChildId))
            {
                previewForConditions.Add("else");
            }

            return(string.Join(", ", previewForConditions));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Builds a parent text preview for the a dialog step
        /// </summary>
        /// <param name="child">Child node</param>
        /// <param name="parent">Parent</param>
        /// <param name="flexFieldObject">Flex field to which the dialog belongs</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <returns>Parent text preview for the dialog step</returns>
        public async Task <string> BuildParentTextPreview(ExportDialogData child, ExportDialogData parent, FlexFieldObject flexFieldObject, ExportPlaceholderErrorCollection errorCollection)
        {
            if (parent.Reference == null)
            {
                return(null);
            }

            ReferenceNodeData referenceNode = await GetReferenceNodeData(parent.Reference);

            if (referenceNode == null)
            {
                return(null);
            }

            string referencedObjectName = "<<UNKNOWN REFERENCE OBJECT>>";

            switch (referenceNode.ObjectType.ToLowerInvariant())
            {
            case ExportConstants.ExportObjectTypeNpc:
                referencedObjectName = referenceNode.Npc.Name;
                break;

            case ExportConstants.ExportObjectTypeItem:
                referencedObjectName = referenceNode.Item.Name;
                break;

            case ExportConstants.ExportObjectTypeSkill:
                referencedObjectName = referenceNode.Skill.Name;
                break;

            case ExportConstants.ExportObjectTypeQuest:
                referencedObjectName = referenceNode.Quest.Name;
                break;

            case ExportConstants.ExportObjectTypeWikiPage:
                referencedObjectName = referenceNode.WikiPage.Name;
                break;

            case ExportConstants.ExportObjectTypeMapMarker:
                referencedObjectName = string.Format("{0} ({1})", referenceNode.Marker.MarkerName, referenceNode.Marker.MapName);
                break;

            case ExportConstants.ExportObjectTypeDailyRoutineEvent:
                string formattedTime;
                if (referenceNode.DailyRoutineEvent.EarliestTime.Hours != referenceNode.DailyRoutineEvent.LatestTime.Hours ||
                    referenceNode.DailyRoutineEvent.EarliestTime.Minutes != referenceNode.DailyRoutineEvent.LatestTime.Minutes)
                {
                    formattedTime = string.Format("{0} - {1}", referenceNode.DailyRoutineEvent.EarliestTime.ToString(TimeFormat), referenceNode.DailyRoutineEvent.LatestTime.ToString(TimeFormat));
                }
                else
                {
                    formattedTime = referenceNode.DailyRoutineEvent.EarliestTime.ToString(TimeFormat);
                }
                referencedObjectName = string.Format("{0} ({1})", formattedTime, referenceNode.Npc.Name);
                break;
            }

            return(ExportUtil.BuildTextPreview(string.Format("Reference Node ({0})", referencedObjectName)));
        }
        /// <summary>
        /// Builds a preview text from parsed data
        /// </summary>
        /// <param name="parsedData">Parsed data</param>
        /// <param name="flexFieldObject">Flex field object to which the dialog belongs</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <param name="child">Child node</param>
        /// <param name="parent">Parent</param>
        /// <returns>Preview text</returns>
        public override async Task<string> BuildPreviewTextFromParsedData(ChangeNpcStateActionRenderer.ChangeNpcStateActionData parsedData, FlexFieldObject flexFieldObject, ExportPlaceholderErrorCollection errorCollection, ExportDialogData child, ExportDialogData parent)
        {
            IFlexFieldExportable valueObject = await GetNpc(flexFieldObject, errorCollection);
            if(valueObject == null)
            {
                return string.Empty;
            }

            return "SetNpcState (" + valueObject.Name + ", " + ExportUtil.BuildTextPreview(parsedData.ObjectState) + ")";
        }
Exemplo n.º 4
0
        /// <summary>
        /// Builds a preview text from parsed data
        /// </summary>
        /// <param name="parsedData">Parsed data</param>
        /// <param name="npc">Npc to which the dialog belongs</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <returns>Preview text</returns>
        public override async Task <string> BuildPreviewTextFromParsedData(PlayAnimationActionRenderer.PlayAnimationActionData parsedData, KortistoNpc npc, ExportPlaceholderErrorCollection errorCollection)
        {
            IFlexFieldExportable valueObject = await GetNpc(npc, errorCollection);

            if (valueObject == null)
            {
                return(string.Empty);
            }

            return("PlayAnimation (" + valueObject.Name + ", " + ExportUtil.BuildTextPreview(parsedData.AnimationName) + ")");
        }
Exemplo n.º 5
0
        /// <summary>
        /// Builds a preview text from parsed data
        /// </summary>
        /// <param name="parsedData">Parsed data</param>
        /// <param name="npc">Npc to which the dialog belongs</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <returns>Preview text</returns>
        public override async Task <string> BuildPreviewTextFromParsedData(AddQuestTextRenderer.AddQuestTextData parsedData, KortistoNpc npc, ExportPlaceholderErrorCollection errorCollection)
        {
            IFlexFieldExportable valueObject = await GetQuest(parsedData, errorCollection);

            if (valueObject == null)
            {
                return(string.Empty);
            }

            return("AddQuestText (" + valueObject.Name + ", " + ExportUtil.BuildTextPreview(parsedData.QuestText) + ")");
        }
Exemplo n.º 6
0
        /// <summary>
        /// Builds a parent text preview for the a dialog step
        /// </summary>
        /// <param name="child">Child node</param>
        /// <param name="parent">Parent</param>
        /// <param name="npc">Npc to which the dialog belongs</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <returns>Parent text preview for the dialog step</returns>
        public Task <string> BuildParentTextPreview(ExportDialogData child, ExportDialogData parent, KortistoNpc npc, ExportPlaceholderErrorCollection errorCollection)
        {
            TextNode textNode = GetValidTextNode(parent);

            if (textNode == null)
            {
                return(Task.FromResult <string>(null));
            }

            return(Task.FromResult(ExportUtil.BuildTextPreview(textNode.Text)));
        }
        /// <summary>
        /// Builds a preview text from parsed data
        /// </summary>
        /// <param name="parsedData">Parsed data</param>
        /// <param name="flexFieldObject">Flex field object to which the dialog belongs</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <param name="child">Child node</param>
        /// <param name="parent">Parent</param>
        /// <returns>Preview text</returns>
        public override async Task <string> BuildPreviewTextFromParsedData(PlayAnimationActionData parsedData, FlexFieldObject flexFieldObject, ExportPlaceholderErrorCollection errorCollection, ExportDialogData child, ExportDialogData parent)
        {
            IFlexFieldExportable valueObject = await GetNpc(flexFieldObject, errorCollection);

            if (valueObject == null)
            {
                return(string.Empty);
            }

            return("PlayAnimation (" + valueObject.Name + ", " + ExportUtil.BuildTextPreview(parsedData.AnimationName) + ")");
        }
Exemplo n.º 8
0
        /// <summary>
        /// Builds a preview text from parsed data
        /// </summary>
        /// <param name="parsedData">Parsed data</param>
        /// <param name="flexFieldObject">Flex field object to which the dialog belongs</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <param name="child">Child node</param>
        /// <param name="parent">Parent</param>
        /// <returns>Preview text</returns>
        public override Task <string> BuildPreviewTextFromParsedData(ChangeTargetNpcStateActionRenderer.ChangeTargetNpcStateActionData parsedData, FlexFieldObject flexFieldObject, ExportPlaceholderErrorCollection errorCollection, ExportDialogData child, ExportDialogData parent)
        {
            IFlexFieldExportable valueObject = flexFieldObject as IFlexFieldExportable;

            if (valueObject == null)
            {
                return(Task.FromResult(string.Empty));
            }

            return(Task.FromResult("SetTargetNpcState (" + valueObject.Name + ", " + ExportUtil.BuildTextPreview(parsedData.ObjectState) + ")"));
        }
        /// <summary>
        /// Fills the placeholders
        /// </summary>
        /// <param name="template">Template to use</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <param name="parsedData">Parsed config data</param>
        /// <param name="flexFieldObject">Flex field object to which the dialog belongs</param>
        /// <param name="valueObject">Value object to export</param>
        /// <param name="curStep">Current step that is rendered</param>
        /// <param name="nextStep">Next step that is being rendered</param>
        /// <param name="exportSettings">Export Settings</param>
        /// <param name="stepRenderer">Action Step renderer</param>
        /// <returns>Filled placeholders</returns>
        protected override async Task <string> FillPlaceholders(ExportTemplate template, ExportPlaceholderErrorCollection errorCollection, AddQuestTextData parsedData, IFlexFieldExportable valueObject, FlexFieldObject flexFieldObject,
                                                                ExportDialogData curStep, ExportDialogData nextStep, ExportSettings exportSettings, IActionStepRenderer stepRenderer)
        {
            ScribanAddQuestTextActionData actionData = new ScribanAddQuestTextActionData();

            actionData.Quest           = FlexFieldValueCollectorUtil.BuildFlexFieldValueObject <ScribanExportQuest>(null, null, valueObject, exportSettings, errorCollection);
            actionData.Text            = ExportUtil.EscapeCharacters(parsedData.QuestText, exportSettings.EscapeCharacter, exportSettings.CharactersNeedingEscaping, exportSettings.NewlineCharacter);
            actionData.UnescapedText   = parsedData.QuestText;
            actionData.TextPreview     = ExportUtil.BuildTextPreview(parsedData.QuestText);
            actionData.FlexFieldObject = flexFieldObject;
            actionData.NodeStep        = curStep;

            return(await ScribanActionRenderingUtil.FillPlaceholders(_cachedDbAccess, errorCollection, template.Code, actionData, flexFieldObject, curStep, nextStep, _scribanLanguageKeyGenerator, stepRenderer));
        }
        /// <summary>
        /// Builds a parent text preview for the a dialog step
        /// </summary>
        /// <param name="child">Child node</param>
        /// <param name="parent">Parent</param>
        /// <param name="npc">Npc to which the dialog belongs</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <returns>Parent text preview for the dialog step</returns>
        public Task <string> BuildParentTextPreview(ExportDialogData child, ExportDialogData parent, KortistoNpc npc, ExportPlaceholderErrorCollection errorCollection)
        {
            TaleChoiceNode choiceNode = parent.Choice;

            if (choiceNode == null)
            {
                return(Task.FromResult <string>(null));
            }

            List <string> previewForChoices = new List <string>();

            foreach (TaleChoice curChoice in choiceNode.Choices)
            {
                ExportDialogDataChild childObj = parent.Children.FirstOrDefault(c => c.NodeChildId == curChoice.Id);
                if (childObj == null || childObj.Child != child)
                {
                    continue;
                }
                previewForChoices.Add(ExportUtil.BuildTextPreview(curChoice.Text));
            }
            return(Task.FromResult(string.Join(", ", previewForChoices)));
        }
Exemplo n.º 11
0
        /// <summary>
        /// Builds an action from parsed data
        /// </summary>
        /// <param name="template">Export template</param>
        /// <param name="parsedData">Parsed data</param>
        /// <param name="data">Dialog data</param>
        /// <param name="nextStep">Next step in the dialog</param>
        /// <param name="project">Project</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <param name="flexFieldObject">Flex field object to which the dialog belongs</param>
        /// <param name="exportSettings">Export Settings</param>
        /// <param name="stepRenderer">Action Step renderer</param>
        /// <returns>Action string</returns>
        public override async Task <string> BuildActionFromParsedData(ExportTemplate template, FloatingTextActionData parsedData, ExportDialogData data, ExportDialogData nextStep, GoNorthProject project, ExportPlaceholderErrorCollection errorCollection,
                                                                      FlexFieldObject flexFieldObject, ExportSettings exportSettings, IActionStepRenderer stepRenderer)
        {
            KortistoNpc targetNpc = await GetValueObject(project, parsedData, flexFieldObject);

            if (targetNpc == null)
            {
                errorCollection.AddDialogNpcNotFoundError();
                return(string.Empty);
            }

            ScribanShowFloatingTextActionData actionData = new ScribanShowFloatingTextActionData();

            actionData.TargetNpc          = FlexFieldValueCollectorUtil.BuildFlexFieldValueObject <ScribanExportNpc>(null, null, targetNpc, exportSettings, errorCollection);
            actionData.TargetNpc.IsPlayer = targetNpc.IsPlayerNpc;
            actionData.Text            = ExportUtil.EscapeCharacters(parsedData.FloatingText, exportSettings.EscapeCharacter, exportSettings.CharactersNeedingEscaping, exportSettings.NewlineCharacter);
            actionData.UnescapedText   = parsedData.FloatingText;
            actionData.TextPreview     = ExportUtil.BuildTextPreview(parsedData.FloatingText);
            actionData.FlexFieldObject = flexFieldObject;
            actionData.NodeStep        = data;

            return(await ScribanActionRenderingUtil.FillPlaceholders(_cachedDbAccess, errorCollection, template.Code, actionData, flexFieldObject, data, nextStep, _scribanLanguageKeyGenerator, stepRenderer));
        }
Exemplo n.º 12
0
        /// <summary>
        /// Renders a dialog step
        /// </summary>
        /// <param name="template">Export template</param>
        /// <param name="data">Dialog Step Data</param>
        /// <param name="npc">Npc object to which the dialog belongs</param>
        /// <param name="textNode">Text node to render</param>
        /// <returns>Dialog Step Render Result</returns>
        public async Task <ExportDialogStepRenderResult> RenderDialogStep(ExportTemplate template, ExportDialogData data, KortistoNpc npc, TextNode textNode)
        {
            ExportDialogStepRenderResult renderResult = new ExportDialogStepRenderResult();

            renderResult.StepCode = ReplaceBaseStepPlaceholders(template.Code, data, data.Children.FirstOrDefault() != null ? data.Children.FirstOrDefault().Child : null);
            renderResult.StepCode = ExportUtil.BuildPlaceholderRegex(Placeholder_TextLine).Replace(renderResult.StepCode, ExportUtil.EscapeCharacters(textNode.Text, _exportSettings.EscapeCharacter, _exportSettings.CharactersNeedingEscaping, _exportSettings.NewlineCharacter));
            renderResult.StepCode = ExportUtil.BuildPlaceholderRegex(Placeholder_TextLine_Preview).Replace(renderResult.StepCode, ExportUtil.BuildTextPreview(textNode.Text));
            renderResult.StepCode = await ExportUtil.BuildPlaceholderRegex(Placeholder_TextLine_LangKey).ReplaceAsync(renderResult.StepCode, async m => {
                return(await _languageKeyGenerator.GetDialogTextLineKey(npc.Id, npc.Name, _isPlayerLine ? ExportConstants.LanguageKeyTypePlayer : ExportConstants.LanguageKeyTypeNpc, textNode.Id, textNode.Text));
            });

            return(renderResult);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Builds an action from parsed data
        /// </summary>
        /// <param name="parsedData">Parsed data</param>
        /// <param name="data">Dialog data</param>
        /// <param name="project">Project</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <param name="npc">Npc to which the dialog belongs</param>
        /// <param name="exportSettings">Export Settings</param>
        /// <returns>Action string</returns>
        public override async Task <string> BuildActionFromParsedData(AddQuestTextRenderer.AddQuestTextData parsedData, ExportDialogData data, GoNorthProject project, ExportPlaceholderErrorCollection errorCollection, KortistoNpc npc, ExportSettings exportSettings)
        {
            ExportTemplate actionTemplate = await GetExportTemplate(project);

            IFlexFieldExportable valueObject = await GetQuest(parsedData, errorCollection);

            if (valueObject == null)
            {
                return(string.Empty);
            }

            string actionCode = ExportUtil.BuildPlaceholderRegex(Placeholder_QuestText).Replace(actionTemplate.Code, ExportUtil.EscapeCharacters(parsedData.QuestText, exportSettings.EscapeCharacter, exportSettings.CharactersNeedingEscaping, exportSettings.NewlineCharacter));

            actionCode = ExportUtil.BuildPlaceholderRegex(Placeholder_QuestText_Preview).Replace(actionCode, ExportUtil.BuildTextPreview(parsedData.QuestText));
            actionCode = ExportUtil.BuildPlaceholderRegex(Placeholder_QuestText_LangKey).Replace(actionCode, m => {
                return(_languageKeyGenerator.GetDialogTextLineKey(npc.Id, valueObject.Name, ExportConstants.LanguageKeyTypeQuest, data.Id, parsedData.QuestText).Result);
            });

            ExportObjectData flexFieldExportData = new ExportObjectData();

            flexFieldExportData.ExportData.Add(ExportConstants.ExportDataObject, valueObject);
            flexFieldExportData.ExportData.Add(ExportConstants.ExportDataObjectType, ExportConstants.ExportObjectTypeQuest);

            _flexFieldPlaceholderResolver.SetErrorMessageCollection(errorCollection);
            actionCode = _flexFieldPlaceholderResolver.FillPlaceholders(actionCode, flexFieldExportData).Result;

            return(actionCode);
        }
Exemplo n.º 14
0
 /// <summary>
 /// Builds a preview text from parsed data
 /// </summary>
 /// <param name="parsedData">Parsed data</param>
 /// <param name="flexFieldObject">Flex field to which the dialog belongs</param>
 /// <param name="errorCollection">Error Collection</param>
 /// <param name="child">Child node</param>
 /// <param name="parent">Parent</param>
 /// <returns>Preview text</returns>
 public override Task <string> BuildPreviewTextFromParsedData(CodeActionRenderer.CodeActionData parsedData, FlexFieldObject flexFieldObject, ExportPlaceholderErrorCollection errorCollection, ExportDialogData child, ExportDialogData parent)
 {
     return(Task <string> .FromResult("Script (" + ExportUtil.BuildTextPreview(parsedData.ScriptName) + ")"));
 }
Exemplo n.º 15
0
        /// <summary>
        /// Renders a dialog step
        /// </summary>
        /// <param name="data">Dialog Step Data</param>
        /// <param name="npc">Npc to which the dialog belongs</param>
        /// <returns>Dialog Step Render Result</returns>
        public async Task <ExportDialogStepRenderResult> RenderDialogStep(ExportDialogData data, KortistoNpc npc)
        {
            TextNode textNode = GetValidTextNode(data);

            if (textNode == null)
            {
                return(null);
            }

            ExportTemplate template = await _defaultTemplateProvider.GetDefaultTemplateByType(_project.Id, _isPlayerLine?TemplateType.TalePlayerTextLine : TemplateType.TaleNpcTextLine);

            ExportDialogStepRenderResult renderResult = new ExportDialogStepRenderResult();

            renderResult.StepCode = ReplaceBaseStepPlaceholders(template.Code, data, data.Children.FirstOrDefault() != null ? data.Children.FirstOrDefault().Child : null);
            renderResult.StepCode = ExportUtil.BuildPlaceholderRegex(Placeholder_TextLine).Replace(renderResult.StepCode, ExportUtil.EscapeCharacters(textNode.Text, _exportSettings.EscapeCharacter, _exportSettings.CharactersNeedingEscaping, _exportSettings.NewlineCharacter));
            renderResult.StepCode = ExportUtil.BuildPlaceholderRegex(Placeholder_TextLine_Preview).Replace(renderResult.StepCode, ExportUtil.BuildTextPreview(textNode.Text));
            renderResult.StepCode = ExportUtil.BuildPlaceholderRegex(Placeholder_TextLine_LangKey).Replace(renderResult.StepCode, m => {
                return(_languageKeyGenerator.GetDialogTextLineKey(npc.Id, npc.Name, _isPlayerLine ? "player" : "npc", textNode.Id, textNode.Text).Result);
            });

            return(renderResult);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Fills the placeholders
        /// </summary>
        /// <param name="template">Template to use</param>
        /// <param name="errorCollection">Error Collection</param>
        /// <param name="parsedData">Parsed config data</param>
        /// <param name="flexFieldObject">Flex field object to which the dialog belongs</param>
        /// <param name="valueObject">Value object to export</param>
        /// <param name="curStep">Current step that is rendered</param>
        /// <param name="nextStep">Next step that is being rendered</param>
        /// <param name="exportSettings">Export Settings</param>
        /// <param name="stepRenderer">Action Step renderer</param>
        /// <returns>Filled placeholders</returns>
        protected override async Task <string> FillPlaceholders(ExportTemplate template, ExportPlaceholderErrorCollection errorCollection, AddQuestTextData parsedData, IFlexFieldExportable valueObject, FlexFieldObject flexFieldObject,
                                                                ExportDialogData curStep, ExportDialogData nextStep, ExportSettings exportSettings, IActionStepRenderer stepRenderer)
        {
            string actionCode = ExportUtil.BuildPlaceholderRegex(Placeholder_QuestText).Replace(template.Code, ExportUtil.EscapeCharacters(parsedData.QuestText, exportSettings.EscapeCharacter, exportSettings.CharactersNeedingEscaping, exportSettings.NewlineCharacter));

            actionCode = ExportUtil.BuildPlaceholderRegex(Placeholder_QuestText_Preview).Replace(actionCode, ExportUtil.BuildTextPreview(parsedData.QuestText));
            actionCode = await ExportUtil.BuildPlaceholderRegex(Placeholder_QuestText_LangKey).ReplaceAsync(actionCode, async m => {
                return(await _languageKeyGenerator.GetDialogTextLineKey(flexFieldObject.Id, valueObject.Name, ExportConstants.LanguageKeyTypeQuest, curStep.Id, parsedData.QuestText));
            });

            ExportObjectData flexFieldExportData = new ExportObjectData();

            flexFieldExportData.ExportData.Add(ExportConstants.ExportDataObject, valueObject);
            flexFieldExportData.ExportData.Add(ExportConstants.ExportDataObjectType, ExportConstants.ExportObjectTypeQuest);

            _flexFieldPlaceholderResolver.SetErrorMessageCollection(errorCollection);
            actionCode = await _flexFieldPlaceholderResolver.FillPlaceholders(actionCode, flexFieldExportData);

            return(await stepRenderer.ReplaceBasePlaceholders(errorCollection, actionCode, curStep, nextStep, flexFieldObject));
        }
Exemplo n.º 17
0
 /// <summary>
 /// Builds a preview text from parsed data
 /// </summary>
 /// <param name="parsedData">Parsed data</param>
 /// <param name="npc">Npc to which the dialog belongs</param>
 /// <param name="errorCollection">Error Collection</param>
 /// <returns>Preview text</returns>
 public override Task <string> BuildPreviewTextFromParsedData(CodeActionRenderer.CodeActionData parsedData, KortistoNpc npc, ExportPlaceholderErrorCollection errorCollection)
 {
     return(Task <string> .FromResult("Script (" + ExportUtil.BuildTextPreview(parsedData.ScriptName) + ")"));
 }
        /// <summary>
        /// Builds a choice
        /// </summary>
        /// <param name="choiceTemplate">Choice Template</param>
        /// <param name="data">Export dialog data</param>
        /// <param name="choiceObj">Choice element</param>
        /// <param name="choiceNode">Choice node</param>
        /// <param name="npc">Npc to which the dialog belongs</param>
        /// <param name="choiceIndex">Index of the choice</param>
        /// <returns>Choices as string</returns>
        private string BuildSingleChoice(string choiceTemplate, ExportDialogData data, TaleChoice choiceObj, TaleChoiceNode choiceNode, KortistoNpc npc, int choiceIndex)
        {
            ExportDialogDataChild choice = data.Children.FirstOrDefault(c => c.NodeChildId == choiceObj.Id);
            string choiceContent         = ReplaceBaseStepPlaceholders(choiceTemplate, data, choice != null ? choice.Child : null);

            choiceContent = ExportUtil.BuildPlaceholderRegex(Placeholder_Choice_Id).Replace(choiceContent, choiceObj.Id.ToString());
            choiceContent = ExportUtil.BuildPlaceholderRegex(Placeholder_Choice_Index).Replace(choiceContent, choiceIndex.ToString());
            choiceContent = ExportUtil.RenderPlaceholderIfTrue(choiceContent, Placeholder_HasConditionStart, Placeholder_HasConditionEnd, choiceObj.Condition != null && !string.IsNullOrEmpty(choiceObj.Condition.ConditionElements));
            choiceContent = ExportUtil.BuildPlaceholderRegex(Placeholder_Condition).Replace(choiceContent, m => {
                return(BuildCondition(choiceObj.Condition, npc));
            });
            choiceContent = ExportUtil.RenderPlaceholderIfTrue(choiceContent, Placeholder_Choice_IsRepeatable_Start, Placeholder_Choice_IsRepeatable_End, choiceObj.IsRepeatable);
            choiceContent = ExportUtil.RenderPlaceholderIfTrue(choiceContent, Placeholder_Choice_IsNotRepeatable_Start, Placeholder_Choice_IsNotRepeatable_End, !choiceObj.IsRepeatable);
            choiceContent = ExportUtil.BuildPlaceholderRegex(Placeholder_Choice_Text).Replace(choiceContent, ExportUtil.EscapeCharacters(choiceObj.Text, _exportSettings.EscapeCharacter, _exportSettings.CharactersNeedingEscaping, _exportSettings.NewlineCharacter));
            choiceContent = ExportUtil.BuildPlaceholderRegex(Placeholder_Choice_Text_Preview).Replace(choiceContent, ExportUtil.BuildTextPreview(choiceObj.Text));
            choiceContent = ExportUtil.BuildPlaceholderRegex(Placeholder_Choice_Text_LangKey).Replace(choiceContent, m => {
                return(_languageKeyGenerator.GetDialogTextLineKey(npc.Id, npc.Name, "choice", choiceNode.Id + "_" + choiceObj.Id, choiceObj.Text).Result);
            });

            return(choiceContent);
        }