/// <summary> /// Builds the list of conditions /// </summary> /// <param name="conditionTemplate">Condition Template</param> /// <param name="data">Export dialog data</param> /// <param name="conditionNode">Condition node</param> /// <param name="flexFieldObject">Flex field to which the dialog belongs</param> /// <param name="includeConditionsWithoutChild">true if conditions without a child should be included, else false</param> /// <returns>Conditions as string</returns> private async Task <string> BuildConditions(string conditionTemplate, ExportDialogData data, ConditionNode conditionNode, FlexFieldObject flexFieldObject, bool includeConditionsWithoutChild) { if (conditionNode.Conditions == null) { return(string.Empty); } int conditionIndex = 0; string conditionsResult = string.Empty; foreach (Condition curCondition in conditionNode.Conditions) { ExportDialogDataChild conditionChild = data.Children.FirstOrDefault(c => c.NodeChildId == curCondition.Id); if (conditionChild == null && !includeConditionsWithoutChild) { continue; } conditionsResult += await BuildSingleCondition(conditionTemplate, data, curCondition, conditionNode, conditionChild, flexFieldObject, conditionIndex); ++conditionIndex; } return(conditionsResult); }
/// <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); }
/// <summary> /// Checks if a dialog node can reach the end of a dialog or is part of an infinity loop /// </summary> /// <param name="curData">Cur Data to check</param> /// <param name="checkedNodes">Checked nodes for this run</param> /// <returns>true if the dialog can reach the end of the dialog, else false</returns> protected bool CheckIfDialogDataCanReachEndOfDialog(ExportDialogData curData, HashSet <ExportDialogData> checkedNodes) { checkedNodes.Add(curData); if (curData.NotPartOfInfinityLoop || curData.Children == null || curData.Children.Count == 0 || ChoiceNodeHasChoiceWithNoChild(curData) || ConditionNodeHasConditionWithNoChild(curData)) { curData.NotPartOfInfinityLoop = true; return(true); } foreach (ExportDialogDataChild curChild in curData.Children) { if (checkedNodes.Contains(curChild.Child)) { continue; } if (CheckIfDialogDataCanReachEndOfDialog(curChild.Child, checkedNodes)) { // Save node is not part of an infinity loop to save performance by not having to travel the whole tree for every node again curData.NotPartOfInfinityLoop = true; return(true); } } return(false); }
/// <summary> /// Ensures that no infinity loop exists /// </summary> /// <param name="exportDialog">Export Dialog data</param> protected void EnsureNoInfinityLoopExists(ExportDialogData exportDialog) { HashSet <ExportDialogData> usedDialogData = new HashSet <ExportDialogData>(); Queue <ExportDialogData> dataToCheck = new Queue <ExportDialogData>(); dataToCheck.Enqueue(exportDialog); usedDialogData.Add(exportDialog); while (dataToCheck.Any()) { ExportDialogData curData = dataToCheck.Dequeue(); if (!curData.NotPartOfInfinityLoop) { HashSet <ExportDialogData> checkedNodes = new HashSet <ExportDialogData>(); if (!CheckIfDialogDataCanReachEndOfDialog(curData, checkedNodes)) { _errorCollection.AddDialogInfinityLoopError(); break; } } foreach (ExportDialogDataChild curChild in curData.Children) { if (!usedDialogData.Contains(curChild.Child)) { dataToCheck.Enqueue(curChild.Child); usedDialogData.Add(curChild.Child); } } } }
/// <summary> /// Renders a state machine event node graph /// </summary> /// <param name="functions">Functions array to fill</param> /// <param name="scriptNodeGraph">Node graph to render</param> /// <param name="flexFieldObject">Npc to which the events belong</param> /// <param name="rootStateMachineFunction">Root state machine function to fill</param> /// <returns>Task</returns> private async Task RenderStateMachineEventNodeGraph(List <StateFunction> functions, NodeGraphSnippet scriptNodeGraph, FlexFieldObject flexFieldObject, StateFunction rootStateMachineFunction) { _nodeGraphParser.SetErrorCollection(_errorCollection); ExportDialogData exportData = _nodeGraphParser.ParseNodeGraph(scriptNodeGraph); if (exportData == null) { return; } exportData = await _nodeGraphFunctionGenerator.GenerateFunctions(flexFieldObject.ProjectId, flexFieldObject.Id, exportData, _errorCollection); ExportDialogFunction rootFunction = new ExportDialogFunction(exportData); AddNodesToFunction(rootFunction, exportData); List <ExportDialogFunction> additionalFunctions = ExtractAdditionalFunctions(exportData); rootStateMachineFunction.Code = await RenderDialogStepList(rootFunction.FunctionSteps, flexFieldObject); foreach (ExportDialogFunction curAdditionalFunction in additionalFunctions) { StateFunction additionalFunction = new StateFunction(); additionalFunction.FunctionName = curAdditionalFunction.RootNode.DialogStepFunctionName; additionalFunction.ParentPreviewText = await BuildFunctionParentPreview(curAdditionalFunction, flexFieldObject); string functionContent = await RenderDialogStepList(curAdditionalFunction.FunctionSteps, flexFieldObject); additionalFunction.Code = functionContent; functions.Add(additionalFunction); } }
/// <summary> /// Parses a dialog /// </summary> /// <param name="inputNpc">Input npc</param> /// <param name="project">Project</param> /// <param name="dialog">Dialog</param> /// <returns>Export dialog data</returns> private async Task <ExportDialogData> ParseDialog(KortistoNpc inputNpc, GoNorthProject project, TaleDialog dialog) { ExportDialogData parsedDialog = null; IStringLocalizer localizer = _localizerFactory.Create(typeof(DialogValueCollector)); try { _errorCollection.CurrentErrorContext = localizer["DialogErrorContext"].Value; _dialogParser.SetErrorCollection(_errorCollection); _dialogRenderer.SetErrorCollection(_errorCollection); bool hasValidDialog = SharedDialogExportUtil.HasValidDialog(dialog); if (hasValidDialog) { parsedDialog = _dialogParser.ParseDialog(dialog); if (parsedDialog != null) { parsedDialog = await _dialogFunctionGenerator.GenerateFunctions(project.Id, inputNpc.Id, parsedDialog, _errorCollection); } } } finally { _errorCollection.CurrentErrorContext = ""; } return(parsedDialog); }
/// <summary> /// Maps a single choice /// </summary> /// <param name="data">Dialog Step Data</param> /// <param name="choice">Choice to map</param> /// <param name="npc">Npc object to which the dialog belongs</param> /// <param name="parentChoiceData">Choice data to which the choices belong</param> /// <returns>Mapped choice</returns> private async ValueTask <ScribanChoiceOption> MapSingleChoice(ExportDialogData data, TaleChoice choice, KortistoNpc npc, ScribanChoice parentChoiceData) { ExportDialogDataChild choiceData = data.Children.FirstOrDefault(c => c.NodeChildId == choice.Id); ScribanDialogStepBaseData childRenderData = null; if (choiceData != null && choiceData.Child != null) { childRenderData = new ScribanDialogStepBaseData(); SetRenderObjectBaseDataFromFlexFieldObject(childRenderData, choiceData.Child, npc); } ScribanChoiceOption choiceOption = new ScribanChoiceOption(); choiceOption.ChildNode = childRenderData; choiceOption.Id = choice.Id; choiceOption.Text = ExportUtil.EscapeCharacters(choice.Text, _exportSettings.EscapeCharacter, _exportSettings.CharactersNeedingEscaping, _exportSettings.NewlineCharacter); choiceOption.UnescapedText = choice.Text; choiceOption.TextPreview = ExportUtil.BuildTextPreview(choice.Text); choiceOption.IsRepeatable = choice.IsRepeatable; choiceOption.Condition = null; if (choice.Condition != null && !string.IsNullOrEmpty(choice.Condition.ConditionElements)) { choiceOption.Condition = await _conditionRenderer.RenderCondition(_project, choice.Condition, _errorCollection, npc, _exportSettings); } choiceOption.ParentChoice = parentChoiceData; return(choiceOption); }
/// <summary> /// Renders a node graph /// </summary> /// <param name="exportNodeGraph">Node graph snippet to parse</param> /// <param name="npc">Npc to which the dialog belongs</param> /// <returns>Result of parsing the node graph</returns> public async Task <ExportNodeGraphRenderResult> RenderNodeGraph(ExportDialogData exportNodeGraph, KortistoNpc npc) { _curProject = await _cachedDbAccess.GetDefaultProject(); _exportSettings = await _cachedDbAccess.GetExportSettings(_curProject.Id); SetupStepRenderes(); ExportNodeGraphRenderResult renderResult = new ExportNodeGraphRenderResult(); renderResult.StartStepCode = string.Empty; renderResult.AdditionalFunctionsCode = string.Empty; // Group to Functions ExportDialogFunction rootFunction = new ExportDialogFunction(exportNodeGraph); AddNodesToFunction(rootFunction, exportNodeGraph); List <ExportDialogFunction> additionalFunctions = ExtractAdditionalFunctions(exportNodeGraph); // Render functions string startStepCode = await RenderDialogStepList(rootFunction.FunctionSteps, npc); string additionalFunctionsCode = string.Empty; foreach (ExportDialogFunction curAdditionalFunction in additionalFunctions) { additionalFunctionsCode += await RenderDialogFunction(curAdditionalFunction, npc); } renderResult.StartStepCode = startStepCode; renderResult.AdditionalFunctionsCode = additionalFunctionsCode; return(renderResult); }
/// <summary> /// Extracts all additional dialog functions /// </summary> /// <param name="exportDialog">Dialog data</param> /// <returns>Additional dialog functions</returns> protected List <ExportDialogFunction> ExtractAdditionalFunctions(ExportDialogData exportDialog) { List <ExportDialogFunction> additionalDialogFunctions = new List <ExportDialogFunction>(); HashSet <ExportDialogData> usedNodesForFunctions = new HashSet <ExportDialogData>(); Queue <ExportDialogData> dataForFunctions = new Queue <ExportDialogData>(); foreach (ExportDialogDataChild curChild in exportDialog.Children) { dataForFunctions.Enqueue(curChild.Child); usedNodesForFunctions.Add(curChild.Child); } while (dataForFunctions.Any()) { ExportDialogData curDialogData = dataForFunctions.Dequeue(); if (!string.IsNullOrEmpty(curDialogData.DialogStepFunctionName)) { ExportDialogFunction curAdditionalDialogFunction = new ExportDialogFunction(curDialogData); AddNodesToFunction(curAdditionalDialogFunction, curDialogData); additionalDialogFunctions.Add(curAdditionalDialogFunction); } foreach (ExportDialogDataChild curChild in curDialogData.Children) { if (!usedNodesForFunctions.Contains(curChild.Child)) { dataForFunctions.Enqueue(curChild.Child); usedNodesForFunctions.Add(curChild.Child); } } } return(additionalDialogFunctions); }
/// <summary> /// Renders a dialog step /// </summary> /// <param name="data">Dialog Step Data</param> /// <param name="flexFieldObject">Flex field object to which the dialog belongs</param> /// <returns>Dialog Step Render Result</returns> public async Task <ExportDialogStepRenderResult> RenderDialogStep(ExportDialogData data, FlexFieldObject flexFieldObject) { ConditionNode conditionNode = data.Condition; if (conditionNode == null) { return(null); } ExportTemplate template = await _defaultTemplateProvider.GetDefaultTemplateByType(_project.Id, TemplateType.TaleCondition); if (!_renderers.ContainsKey(template.RenderingEngine)) { throw new KeyNotFoundException(string.Format("Unknown rendering engine {0} for ConditionNode", template.RenderingEngine.ToString())); } string oldContext = _errorCollection.CurrentErrorContext; _errorCollection.CurrentErrorContext = _localizer["ErrorContextCondition"]; try { return(await _renderers[template.RenderingEngine].RenderDialogStep(template, data, flexFieldObject, conditionNode)); } catch (Exception ex) { _errorCollection.AddException(ex); return(new ExportDialogStepRenderResult { StepCode = "<<ERROR_RENDERING_CONDITION>>" }); } finally { _errorCollection.CurrentErrorContext = oldContext; } }
/// <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)); }
/// <summary> /// Parses a dialog for exporting /// </summary> /// <param name="projectId">Project Id</param> /// <param name="objectId">Object Id</param> /// <param name="dialog">Dialog to parse</param> /// <param name="errorCollection">Error Collection to send errors to</param> /// <returns>Parsed dialog</returns> public async Task <ExportDialogData> GenerateFunctions(string projectId, string objectId, ExportDialogData dialog, ExportPlaceholderErrorCollection errorCollection) { DialogFunctionGenerationConditionCollection dialogFunctionGenerationConditions = await _dialogFunctionGenerationConditionProvider.GetDialogFunctionGenerationConditions(projectId); HashSet <string> usedDialogSteps = new HashSet <string>(); Queue <ExportDialogData> dialogDataToQueue = new Queue <ExportDialogData>(); dialogDataToQueue.Enqueue(dialog); while (dialogDataToQueue.Any()) { ExportDialogData curData = dialogDataToQueue.Dequeue(); await CheckAndBuildFunctionForDialogStep(curData, dialogFunctionGenerationConditions, projectId, objectId, errorCollection); foreach (ExportDialogDataChild curChild in curData.Children) { if (!usedDialogSteps.Contains(curChild.Child.Id)) { dialogDataToQueue.Enqueue(curChild.Child); usedDialogSteps.Add(curChild.Child.Id); } } } return(dialog); }
/// <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> /// Sets the render object base data /// </summary> /// <param name="renderObject">Render object to fill</param> /// <param name="stepData">Step data</param> /// <param name="exportNpc">Npc to export</param> public void SetRenderObjectBaseData(ScribanDialogStepBaseData renderObject, ExportDialogData stepData, ScribanFlexFieldObject exportNpc) { renderObject.NodeId = stepData.Id; renderObject.NodeIndex = stepData.NodeIndex; renderObject.NodeType = stepData.GetNodeType(); renderObject.NodeStepFunctionName = stepData.DialogStepFunctionName; renderObject.NodeObject = exportNpc; }
/// <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="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, CodeActionData parsedData, FlexFieldObject flexFieldObject, ExportDialogData curStep, ExportDialogData nextStep, ExportSettings exportSettings, IActionStepRenderer stepRenderer) { string actionCode = ExportUtil.BuildPlaceholderRegex(Placeholder_ScriptName).Replace(template.Code, ExportUtil.EscapeCharacters(parsedData.ScriptName, exportSettings.EscapeCharacter, exportSettings.CharactersNeedingEscaping, exportSettings.NewlineCharacter)); actionCode = ExportUtil.BuildPlaceholderRegex(Placeholder_ScriptCode).Replace(actionCode, parsedData.ScriptCode); return(await stepRenderer.ReplaceBasePlaceholders(errorCollection, actionCode, curStep, nextStep, flexFieldObject)); }
/// <summary> /// Returns true if an action node is of a certain action type /// </summary> /// <param name="dialogData">Dialog Data</param> /// <param name="actionType">Action Type</param> /// <param name="errorCollection">Error Collection to send errors to</param> /// <returns>true if node is of searched type</returns> protected bool IsNodeOfActionType(ExportDialogData dialogData, ActionType actionType, ExportPlaceholderErrorCollection errorCollection) { if (dialogData.Action == null) { return(false); } return((int)actionType == dialogData.Action.ActionType); }
/// <summary> /// Returns the stept type /// </summary> /// <param name="nextStep">Next Step</param> /// <returns>Step Type</returns> private string GetStepType(ExportDialogData nextStep) { if (nextStep == null) { return(string.Empty); } return(nextStep.GetNodeType().ToLowerInvariant()); }
/// <summary> /// Renders a dialog step /// </summary> /// <param name="data">Dialog Step Data</param> /// <param name="flexFieldObject">Flex Field to which the dialog belongs</param> /// <returns>Dialog Step Render Result</returns> public async Task <ExportDialogStepRenderResult> RenderDialogStep(ExportDialogData data, FlexFieldObject flexFieldObject) { ActionNode actionNode = data.Action; if (actionNode == null) { return(null); } ActionRendererDispatcher actionRenderer = GetActionRenderForNode(actionNode); ExportDialogDataChild nextStep = null; if (data.Children != null) { if (actionRenderer != null) { nextStep = actionRenderer.GetNextStep(data.Children); } else { nextStep = data.Children.FirstOrDefault(); } } ExportTemplate template = await _defaultTemplateProvider.GetDefaultTemplateByType(_project.Id, TemplateType.TaleAction); if (!_renderers.ContainsKey(template.RenderingEngine)) { throw new KeyNotFoundException(string.Format("Unknown rendering engine {0} for ActionNode", template.RenderingEngine.ToString())); } IActionStepRenderer stepRenderer = _renderers[template.RenderingEngine]; stepRenderer.ResetStepRenderingValues(); string oldContext = _errorCollection.CurrentErrorContext; _errorCollection.CurrentErrorContext = _localizer["ErrorContextAction", _actionTranslator.TranslateActionType((ActionType)actionNode.ActionType)]; try { string actionContent = await BuildActionContent(actionRenderer, actionNode, data, flexFieldObject, stepRenderer); return(await stepRenderer.RenderDialogStep(template, data, nextStep, flexFieldObject, actionContent)); } catch (Exception ex) { _errorCollection.AddException(ex); return(new ExportDialogStepRenderResult { StepCode = "<<ERROR_RENDERING_ACTION>>" }); } finally { _errorCollection.CurrentErrorContext = oldContext; } }
/// <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="valueObject">Value object to export</param> /// <param name="flexFieldObject">Flex field object to which the dialog belongs</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, LearnForgetSkillActionData parsedData, IFlexFieldExportable valueObject, FlexFieldObject flexFieldObject, ExportDialogData curStep, ExportDialogData nextStep, ExportSettings exportSettings, IActionStepRenderer stepRenderer) { ScribanLearnForgetSkillActionData actionData = new ScribanLearnForgetSkillActionData(); actionData.Skill = FlexFieldValueCollectorUtil.BuildFlexFieldValueObject <ScribanExportSkill>(null, null, valueObject, exportSettings, errorCollection); return(await ScribanActionRenderingUtil.FillPlaceholders(_cachedDbAccess, errorCollection, template.Code, actionData, flexFieldObject, curStep, nextStep, _scribanLanguageKeyGenerator, stepRenderer)); }
/// <summary> /// Returns true if a node is of a certain type /// </summary> /// <param name="dialogData">Dialog Data</param> /// <param name="nodeType">Node Type</param> /// <param name="errorCollection">Error Collection to send errors to</param> /// <returns>true if node is of searched type</returns> protected bool IsNodeOfType(ExportDialogData dialogData, string nodeType, ExportPlaceholderErrorCollection errorCollection) { if (string.IsNullOrEmpty(nodeType)) { return(false); } return(nodeType.ToLowerInvariant() == GetNodeType(dialogData, errorCollection).ToLowerInvariant()); }
/// <summary> /// Returns the node data to render the base data /// </summary> /// <param name="data">Dialog Step Data</param> /// <param name="nextStep">Next step in the dialog</param> /// <param name="flexFieldObject">Flex field object to which the dialog belongs</param> /// <returns>Node base data</returns> private ScribanDialogStepBaseDataWithNextNode GetBaseNodeData(ExportDialogData data, ExportDialogData nextStep, FlexFieldObject flexFieldObject) { if (_nextStepNodeData == null) { _nextStepNodeData = BuildDialogRenderObject <ScribanDialogStepBaseDataWithNextNode>(data, nextStep, flexFieldObject); } return(_nextStepNodeData); }
/// <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="valueObject">Value object to export</param> /// <param name="flexFieldObject">Flex field object to which the dialog belongs</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, InventoryActionData parsedData, IFlexFieldExportable valueObject, FlexFieldObject flexFieldObject, ExportDialogData curStep, ExportDialogData nextStep, ExportSettings exportSettings, IActionStepRenderer stepRenderer) { ScribanInventoryActionData codeActionData = new ScribanInventoryActionData(); codeActionData.SelectedItem = FlexFieldValueCollectorUtil.BuildFlexFieldValueObject <ScribanExportItem>(null, null, valueObject, exportSettings, errorCollection); codeActionData.Quantity = parsedData.Quantity.HasValue ? parsedData.Quantity.Value : 1; return(await ScribanActionRenderingUtil.FillPlaceholders(_cachedDbAccess, errorCollection, template.Code, codeActionData, flexFieldObject, curStep, nextStep, _scribanLanguageKeyGenerator, stepRenderer)); }
/// <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="projectConfig">Project config</param> /// <param name="flexFieldObject">Flex field object to which the dialog belongs</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, SetGameTimeActionData parsedData, MiscProjectConfig projectConfig, FlexFieldObject flexFieldObject, ExportDialogData curStep, ExportDialogData nextStep, ExportSettings exportSettings, IActionStepRenderer stepRenderer) { string actionCode = ExportUtil.BuildPlaceholderRegex(Placeholder_Hours).Replace(template.Code, parsedData.Hours.ToString()); actionCode = ExportUtil.BuildPlaceholderRegex(Placeholder_Minutes).Replace(actionCode, parsedData.Minutes.ToString()); actionCode = ExportUtil.BuildPlaceholderRegex(Placeholder_TotalMinutes).Replace(actionCode, (parsedData.Hours * projectConfig.MinutesPerHour + parsedData.Minutes).ToString()); return(await stepRenderer.ReplaceBasePlaceholders(errorCollection, actionCode, curStep, nextStep, flexFieldObject)); }
/// <summary> /// Builds the else part /// </summary> /// <param name="elseTemplate">Else template</param> /// <param name="data">Dialog data</param> /// <returns>Else part</returns> private string BuildElsePart(string elseTemplate, ExportDialogData data) { ExportDialogDataChild elseChild = data.Children.FirstOrDefault(c => c.NodeChildId == ExportConstants.ConditionElseNodeChildId); if (elseChild == null) { return(string.Empty); } return(ReplaceBaseStepPlaceholders(elseTemplate, data, elseChild.Child)); }
/// <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="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, CodeActionData parsedData, FlexFieldObject flexFieldObject, ExportDialogData curStep, ExportDialogData nextStep, ExportSettings exportSettings, IActionStepRenderer stepRenderer) { ScribanCodeActionData codeActionData = new ScribanCodeActionData(); codeActionData.ScriptName = ExportUtil.EscapeCharacters(parsedData.ScriptName, exportSettings.EscapeCharacter, exportSettings.CharactersNeedingEscaping, exportSettings.NewlineCharacter); codeActionData.UnescapedScriptName = parsedData.ScriptName; codeActionData.ScriptCode = parsedData.ScriptCode; return(await ScribanActionRenderingUtil.FillPlaceholders(_cachedDbAccess, errorCollection, template.Code, codeActionData, flexFieldObject, curStep, nextStep, null, stepRenderer)); }
/// <summary> /// Returns true if an action node is of a certain action type /// </summary> /// <param name="dialogData">Dialog Data</param> /// <param name="actionType">Action Type</param> /// <param name="errorCollection">Error Collection to send errors to</param> /// <returns>true if node is of searched type</returns> protected bool IsNodeOfActionType(ExportDialogData dialogData, ActionType actionType, ExportPlaceholderErrorCollection errorCollection) { int parsedActionType = 0; if (dialogData.Action == null || !int.TryParse(dialogData.Action.ActionType, out parsedActionType)) { return(false); } return((int)actionType == parsedActionType); }
/// <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="projectConfig">Project config</param> /// <param name="flexFieldObject">Flex field object to which the dialog belongs</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, SetGameTimeActionData parsedData, MiscProjectConfig projectConfig, FlexFieldObject flexFieldObject, ExportDialogData curStep, ExportDialogData nextStep, ExportSettings exportSettings, IActionStepRenderer stepRenderer) { ScribanSetGameTimeActionData setGameTimeActionData = new ScribanSetGameTimeActionData(); setGameTimeActionData.Hours = parsedData.Hours; setGameTimeActionData.Minutes = parsedData.Minutes; setGameTimeActionData.TotalMinutes = (parsedData.Hours * projectConfig.MinutesPerHour + parsedData.Minutes); return(await ScribanActionRenderingUtil.FillPlaceholders(_cachedDbAccess, errorCollection, template.Code, setGameTimeActionData, flexFieldObject, curStep, nextStep, null, stepRenderer)); }
/// <summary> /// Returns the valid text node /// </summary> /// <param name="data">Dialog step data</param> /// <returns>Valid text node</returns> private TextNode GetValidTextNode(ExportDialogData data) { TextNode textNode = data.PlayerText; if (!_isPlayerLine) { textNode = data.NpcText; } return(textNode); }
/// <summary> /// Builds an action /// </summary> /// <param name="action">Current action</param> /// <param name="data">Dialog data</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 Build Result</returns> public async Task <string> BuildActionElement(ActionNode action, ExportDialogData data, GoNorthProject project, ExportPlaceholderErrorCollection errorCollection, FlexFieldObject flexFieldObject, ExportSettings exportSettings, IActionStepRenderer stepRenderer) { ExportTemplate template = await _templateProvider.GetDefaultTemplateByType(project.Id, _templateType); if (!_renderers.ContainsKey(template.RenderingEngine)) { throw new KeyNotFoundException(string.Format("Unknown rendering engine {0} for Action {1}", template.RenderingEngine.ToString(), _templateType.ToString())); } return(await _renderers[template.RenderingEngine].BuildActionElement(template, action, data, project, errorCollection, flexFieldObject, exportSettings, stepRenderer)); }
/// <summary> /// Checks and builds the function for a dialog step /// </summary> /// <param name="dialogData">Dialog data for the step</param> /// <param name="dialogFunctionGenerationConditions">Dialog Function Generation Conditions</param> /// <param name="projectId">Project Id</param> /// <param name="objectId">Object Id</param> /// <param name="errorCollection">Error Collection to send errors to</param> protected async Task CheckAndBuildFunctionForDialogStep(ExportDialogData dialogData, DialogFunctionGenerationConditionCollection dialogFunctionGenerationConditions, string projectId, string objectId, ExportPlaceholderErrorCollection errorCollection) { if (EvaluateConditions(dialogData, dialogFunctionGenerationConditions.PreventGenerationRules, errorCollection)) { return; } if (EvaluateConditions(dialogData, dialogFunctionGenerationConditions.GenerateRules, errorCollection)) { dialogData.DialogStepFunctionName = await GenerateFunctionName(GetNodeType(dialogData, errorCollection), projectId, objectId, dialogData.Id); } }