/// <summary> /// Initializes a new DialogueEntry copied from a Chat Mapper DialogEntry. /// </summary> /// <param name='chatMapperDialogEntry'> /// The Chat Mapper dialog entry to copy. /// </param> public DialogueEntry(ChatMapper.DialogEntry chatMapperDialogEntry) { if (chatMapperDialogEntry != null) { id = chatMapperDialogEntry.ID; fields = Field.CreateListFromChatMapperFields(chatMapperDialogEntry.Fields); //--- Removed in Chat Mapper 1.7: conversationID = chatMapperDialogEntry.ConversationID; isRoot = chatMapperDialogEntry.IsRoot; isGroup = chatMapperDialogEntry.IsGroup; if (isGroup) { Sequence = "None()"; } nodeColor = chatMapperDialogEntry.NodeColor; delaySimStatus = chatMapperDialogEntry.DelaySimStatus; falseConditionAction = chatMapperDialogEntry.FalseCondtionAction; conditionPriority = ConditionPriorityTools.StringToConditionPriority(chatMapperDialogEntry.ConditionPriority); foreach (var chatMapperLink in chatMapperDialogEntry.OutgoingLinks) { outgoingLinks.Add(new Link(chatMapperLink)); } conditionsString = chatMapperDialogEntry.ConditionsString; userScript = chatMapperDialogEntry.UserScript; } }
/// <summary> /// Copy constructor. /// </summary> /// <param name="sourceLink">Source link.</param> public Link(Link sourceLink) { this.originConversationID = sourceLink.originConversationID; this.originDialogueID = sourceLink.originDialogueID; this.destinationConversationID = sourceLink.destinationConversationID; this.destinationDialogueID = sourceLink.destinationDialogueID; this.isConnector = sourceLink.isConnector; this.priority = sourceLink.priority; }
private Link NewLink(DialogueEntry origin, DialogueEntry destination, ConditionPriority priority = ConditionPriority.Normal) { var newLink = new Link(); newLink.originConversationID = origin.conversationID; newLink.originDialogueID = origin.id; newLink.destinationConversationID = destination.conversationID; newLink.destinationDialogueID = destination.id; newLink.isConnector = (origin.conversationID != destination.conversationID); newLink.priority = priority; return(newLink); }
/// <summary> /// Copy constructor. /// </summary> /// <param name="sourceEntry">Source entry.</param> public DialogueEntry(DialogueEntry sourceEntry) { this.id = sourceEntry.id; this.fields = Field.CopyFields(sourceEntry.fields); this.conversationID = sourceEntry.conversationID; this.isRoot = sourceEntry.isRoot; this.isGroup = sourceEntry.isGroup; this.nodeColor = sourceEntry.nodeColor; this.delaySimStatus = sourceEntry.delaySimStatus; this.falseConditionAction = sourceEntry.falseConditionAction; this.conditionPriority = ConditionPriority.Normal; this.outgoingLinks = CopyLinks(sourceEntry.outgoingLinks); this.conditionsString = sourceEntry.conditionsString; this.userScript = sourceEntry.userScript; }
private void EvaluateLinksAtPriority(ConditionPriority priority, DialogueEntry entry, List <Response> npcResponses, List <Response> pcResponses, List <DialogueEntry> visited) { if (entry != null) { foreach (Link link in entry.outgoingLinks) { DialogueEntry destinationEntry = database.GetDialogueEntry(link); if ((destinationEntry != null) && ((destinationEntry.conditionPriority == priority) || (link.priority == priority))) { CharacterType characterType = database.GetCharacterType(destinationEntry.ActorID); bool isValid = Lua.IsTrue(destinationEntry.conditionsString, DialogueDebug.LogInfo, allowLuaExceptions) && ((IsDialogueEntryValid == null) || IsDialogueEntryValid(destinationEntry)); if (isValid) { // Condition is true (or blank), so add this link: if (destinationEntry.isGroup) { // For groups, evaluate their links (after running the group node's Lua code): if (DialogueDebug.LogInfo) { Debug.Log(string.Format("{0}: Add Group ({1}): ID={2}:{3} '{4}'", new System.Object[] { DialogueDebug.Prefix, GetActorName(database.GetActor(destinationEntry.ActorID)), link.destinationConversationID, link.destinationDialogueID, destinationEntry.Title })); } Lua.Run(destinationEntry.userScript, DialogueDebug.LogInfo, allowLuaExceptions); for (int i = (int)ConditionPriority.High; i >= 0; i--) { int originalResponseCount = npcResponses.Count + pcResponses.Count;; EvaluateLinksAtPriority((ConditionPriority)i, destinationEntry, npcResponses, pcResponses, visited); if ((npcResponses.Count + pcResponses.Count) > originalResponseCount) { break; } } } else { // For regular entries, just add them: if (DialogueDebug.LogInfo) { Debug.Log(string.Format("{0}: Add Link ({1}): ID={2}:{3} '{4}'", new System.Object[] { DialogueDebug.Prefix, GetActorName(database.GetActor(destinationEntry.ActorID)), link.destinationConversationID, link.destinationDialogueID, GetLinkText(characterType, destinationEntry) })); } if (characterType == CharacterType.NPC) { // Add NPC response: npcResponses.Add(new Response(FormattedText.Parse(destinationEntry.SubtitleText, database.emphasisSettings), destinationEntry)); } else { // Add PC response, wrapping old responses in em tags if specified: string text = destinationEntry.ResponseButtonText; if (emTagForOldResponses != EmTag.None) { string simStatus = Lua.Run(string.Format("return Conversation[{0}].Dialog[{1}].SimStatus", new System.Object[] { destinationEntry.conversationID, destinationEntry.id })).AsString; bool isOldResponse = string.Equals(simStatus, "WasDisplayed"); if (isOldResponse) { text = string.Format("[em{0}]{1}[/em{0}]", (int)emTagForOldResponses, text); } } pcResponses.Add(new Response(FormattedText.Parse(text, database.emphasisSettings), destinationEntry)); DialogueLua.MarkDialogueEntryOffered(destinationEntry); } } } else { // Condition is false, so block or pass through according to destination entry's setting: if (LinkTools.IsPassthroughOnFalse(destinationEntry)) { if (DialogueDebug.LogInfo) { Debug.Log(string.Format("{0}: Passthrough on False Link ({1}): ID={2}:{3} '{4}' Condition='{5}'", new System.Object[] { DialogueDebug.Prefix, GetActorName(database.GetActor(destinationEntry.ActorID)), link.destinationConversationID, link.destinationDialogueID, GetLinkText(characterType, destinationEntry), destinationEntry.conditionsString })); } List <Response> linkNpcResponses = new List <Response>(); List <Response> linkPcResponses = new List <Response>(); EvaluateLinks(destinationEntry, linkNpcResponses, linkPcResponses, visited); npcResponses.AddRange(linkNpcResponses); pcResponses.AddRange(linkPcResponses); } else { if (DialogueDebug.LogInfo) { Debug.Log(string.Format("{0}: Block on False Link ({1}): ID={2}:{3} '{4}' Condition='{5}'", new System.Object[] { DialogueDebug.Prefix, GetActorName(database.GetActor(destinationEntry.ActorID)), link.destinationConversationID, link.destinationDialogueID, GetLinkText(characterType, destinationEntry), destinationEntry.conditionsString })); } } } } } } }
private void SplitEntryAtPipes(int originalEntryIndex, string dialogueText, bool putEndSequenceOnLastSplit, bool trimWhitespace) { // Split by Dialogue Text: var substrings = dialogueText.Split(new char[] { '|' }); var originalEntry = dialogueEntries[originalEntryIndex]; originalEntry.DialogueText = trimWhitespace ? substrings[0].Trim() : substrings[0]; var originalOutgoingLinks = originalEntry.outgoingLinks; ConditionPriority priority = ((originalOutgoingLinks != null) && (originalOutgoingLinks.Count > 0)) ? originalOutgoingLinks[0].priority : ConditionPriority.Normal; var currentEntry = originalEntry; var entries = new List <DialogueEntry>(); entries.Add(currentEntry); // Split Menu Text: var defaultMenuText = (originalEntry != null && originalEntry.MenuText != null) ? originalEntry.MenuText : string.Empty; var menuTextSubstrings = defaultMenuText.Split(new char[] { '|' }); // Split Audio Files: var audioFilesText = originalEntry.AudioFiles; audioFilesText = ((audioFilesText != null) && (audioFilesText.Length >= 2)) ? audioFilesText.Substring(1, audioFilesText.Length - 2) : string.Empty; var audioFiles = audioFilesText.Split(new char[] { ';' }); currentEntry.AudioFiles = string.Format("[{0}]", new System.Object[] { (audioFiles.Length > 0) ? audioFiles[0] : string.Empty }); // Create new dialogue entries for the split parts: int i = 1; while (i < substrings.Length) { var newEntryDialogueText = substrings[i]; var newEntryMenuText = (i < menuTextSubstrings.Length) ? menuTextSubstrings[i] : string.Empty; if (trimWhitespace) { newEntryDialogueText = newEntryDialogueText.Trim(); newEntryMenuText = newEntryMenuText.Trim(); } var newEntry = AddNewDialogueEntry(originalEntry, newEntryDialogueText, i, trimWhitespace); newEntry.canvasRect = new Rect(originalEntry.canvasRect.x + i * 20, originalEntry.canvasRect.y + i * 10, originalEntry.canvasRect.width, originalEntry.canvasRect.height); newEntry.currentMenuText = newEntryMenuText; newEntry.AudioFiles = string.Format("[{0}]", new System.Object[] { (i < audioFiles.Length) ? audioFiles[i] : string.Empty }); currentEntry.outgoingLinks = new List <Link>() { NewLink(currentEntry, newEntry, priority) }; currentEntry = newEntry; entries.Add(newEntry); i++; } // Set the last entry's links to the original outgoing links: currentEntry.outgoingLinks = originalOutgoingLinks; // Fix up the other splittable fields in the original entry: foreach (var field in originalEntry.fields) { if (string.IsNullOrEmpty(field.title)) { continue; } string fieldValue = (field.value != null) ? field.value : string.Empty; bool isSequence = field.title.StartsWith(DialogueSystemFields.Sequence); bool isLocalization = (field.type == FieldType.Localization); bool containsPipes = fieldValue.Contains("|"); bool isSplittable = (isSequence || isLocalization) && !string.IsNullOrEmpty(field.value) && containsPipes; if (isSplittable) { substrings = field.value.Split(new char[] { '|' }); if (substrings.Length > 1) { fieldValue = trimWhitespace ? substrings[0].Trim() : substrings[0]; field.value = fieldValue; } } else if (isSequence && putEndSequenceOnLastSplit && !containsPipes) { if (field.value.Contains(SequencerKeywords.End)) { PutEndSequenceOnLastSplit(entries, field); } } } }
private void EvaluateLinksAtPriority(ConditionPriority priority, DialogueEntry entry, List <Response> npcResponses, List <Response> pcResponses, List <DialogueEntry> visited, bool stopAtFirstValid = false) { if (entry != null) { for (int ol = 0; ol < entry.outgoingLinks.Count; ol++) { var link = entry.outgoingLinks[ol]; DialogueEntry destinationEntry = m_database.GetDialogueEntry(link); if ((destinationEntry != null) && (/*(destinationEntry.conditionPriority == priority) ||*/ (link.priority == priority))) // Note: Only observe link priority. Why does Chat Mapper even have conditionPriority? { CharacterType characterType = m_database.GetCharacterType(destinationEntry.ActorID); Lua.Run("thisID = " + destinationEntry.id); bool isValid = Lua.IsTrue(destinationEntry.conditionsString, DialogueDebug.logInfo, m_allowLuaExceptions) && ((isDialogueEntryValid == null) || isDialogueEntryValid(destinationEntry)); if (isValid || (m_includeInvalidEntries && (characterType == CharacterType.PC))) { // Condition is true (or blank), so add this link: if (destinationEntry.isGroup) { // For groups, evaluate their links (after running the group node's Lua code and OnExecute() event): if (DialogueDebug.logInfo) { Debug.Log(string.Format("{0}: Add Group ({1}): ID={2}:{3} '{4}' ({5})", new System.Object[] { DialogueDebug.Prefix, GetActorName(m_database.GetActor(destinationEntry.ActorID)), link.destinationConversationID, link.destinationDialogueID, destinationEntry.Title, isValid })); } Lua.Run(destinationEntry.userScript, DialogueDebug.logInfo, m_allowLuaExceptions); destinationEntry.onExecute.Invoke(); for (int i = (int)ConditionPriority.High; i >= 0; i--) { int originalResponseCount = npcResponses.Count + pcResponses.Count;; EvaluateLinksAtPriority((ConditionPriority)i, destinationEntry, npcResponses, pcResponses, visited); if ((npcResponses.Count + pcResponses.Count) > originalResponseCount) { break; } } } else { // For regular entries, just add them: if (DialogueDebug.logInfo) { Debug.Log(string.Format("{0}: Add Link ({1}): ID={2}:{3} '{4}' ({5})", new System.Object[] { DialogueDebug.Prefix, GetActorName(m_database.GetActor(destinationEntry.ActorID)), link.destinationConversationID, link.destinationDialogueID, GetLinkText(characterType, destinationEntry), isValid })); } if (characterType == CharacterType.NPC) { // Add NPC response: npcResponses.Add(new Response(FormattedText.Parse(destinationEntry.subtitleText, m_database.emphasisSettings), destinationEntry, isValid)); } else { // Add PC response, wrapping old responses in em tags if specified: string text = destinationEntry.responseButtonText; if (m_emTagForOldResponses != EmTag.None) { string simStatus = Lua.Run(string.Format("return Conversation[{0}].Dialog[{1}].SimStatus", new System.Object[] { destinationEntry.conversationID, destinationEntry.id })).asString; bool isOldResponse = string.Equals(simStatus, DialogueLua.WasDisplayed); if (isOldResponse) { text = string.Format("[em{0}]{1}[/em{0}]", (int)m_emTagForOldResponses, text); } } if (m_emTagForInvalidResponses != EmTag.None) { if (!isValid) { text = string.Format("[em{0}]{1}[/em{0}]", (int)m_emTagForInvalidResponses, text); } } pcResponses.Add(new Response(FormattedText.Parse(text, m_database.emphasisSettings), destinationEntry, isValid)); DialogueLua.MarkDialogueEntryOffered(destinationEntry); } } if (stopAtFirstValid) { return; } } else { // Condition is false, so block or pass through according to destination entry's setting: if (LinkUtility.IsPassthroughOnFalse(destinationEntry)) { if (DialogueDebug.logInfo) { Debug.Log(string.Format("{0}: Passthrough on False Link ({1}): ID={2}:{3} '{4}' Condition='{5}'", new System.Object[] { DialogueDebug.Prefix, GetActorName(m_database.GetActor(destinationEntry.ActorID)), link.destinationConversationID, link.destinationDialogueID, GetLinkText(characterType, destinationEntry), destinationEntry.conditionsString })); } List <Response> linkNpcResponses = new List <Response>(); List <Response> linkPcResponses = new List <Response>(); EvaluateLinks(destinationEntry, linkNpcResponses, linkPcResponses, visited); npcResponses.AddRange(linkNpcResponses); pcResponses.AddRange(linkPcResponses); } else { if (DialogueDebug.logInfo) { Debug.Log(string.Format("{0}: Block on False Link ({1}): ID={2}:{3} '{4}' Condition='{5}'", new System.Object[] { DialogueDebug.Prefix, GetActorName(m_database.GetActor(destinationEntry.ActorID)), link.destinationConversationID, link.destinationDialogueID, GetLinkText(characterType, destinationEntry), destinationEntry.conditionsString })); } } } } } } }
private Link NewLink(DialogueEntry origin, DialogueEntry destination, ConditionPriority priority = ConditionPriority.Normal) { Link newLink = new Link(); newLink.originConversationID = origin.conversationID; newLink.originDialogueID = origin.id; newLink.destinationConversationID = destination.conversationID; newLink.destinationDialogueID = destination.id; newLink.isConnector = (origin.conversationID != destination.conversationID); newLink.priority = priority; return newLink; }
private void EvaluateLinksAtPriority(ConditionPriority priority, DialogueEntry entry, List<Response> npcResponses, List<Response> pcResponses, List<DialogueEntry> visited, bool stopAtFirstValid = false) { if (entry != null) { foreach (Link link in entry.outgoingLinks) { DialogueEntry destinationEntry = database.GetDialogueEntry(link); if ((destinationEntry != null) && ((destinationEntry.conditionPriority == priority) || (link.priority == priority))) { CharacterType characterType = database.GetCharacterType(destinationEntry.ActorID); bool isValid = Lua.IsTrue(destinationEntry.conditionsString, DialogueDebug.LogInfo, allowLuaExceptions) && ((IsDialogueEntryValid == null) || IsDialogueEntryValid(destinationEntry)); if (isValid || includeInvalidEntries) { // Condition is true (or blank), so add this link: if (destinationEntry.isGroup) { // For groups, evaluate their links (after running the group node's Lua code): if (DialogueDebug.LogInfo) Debug.Log(string.Format("{0}: Add Group ({1}): ID={2}:{3} '{4}' ({5})", new System.Object[] { DialogueDebug.Prefix, GetActorName(database.GetActor(destinationEntry.ActorID)), link.destinationConversationID, link.destinationDialogueID, destinationEntry.Title, isValid })); Lua.Run(destinationEntry.userScript, DialogueDebug.LogInfo, allowLuaExceptions); for (int i = (int) ConditionPriority.High; i >= 0; i--) { int originalResponseCount = npcResponses.Count + pcResponses.Count;; EvaluateLinksAtPriority((ConditionPriority) i, destinationEntry, npcResponses, pcResponses, visited); if ((npcResponses.Count + pcResponses.Count) > originalResponseCount) break; } } else { // For regular entries, just add them: if (DialogueDebug.LogInfo) Debug.Log(string.Format("{0}: Add Link ({1}): ID={2}:{3} '{4}' ({5})", new System.Object[] { DialogueDebug.Prefix, GetActorName(database.GetActor(destinationEntry.ActorID)), link.destinationConversationID, link.destinationDialogueID, GetLinkText(characterType, destinationEntry), isValid })); if (characterType == CharacterType.NPC) { // Add NPC response: npcResponses.Add(new Response(FormattedText.Parse(destinationEntry.SubtitleText, database.emphasisSettings), destinationEntry, isValid)); } else { // Add PC response, wrapping old responses in em tags if specified: string text = destinationEntry.ResponseButtonText; if (emTagForOldResponses != EmTag.None) { string simStatus = Lua.Run(string.Format("return Conversation[{0}].Dialog[{1}].SimStatus", new System.Object[] { destinationEntry.conversationID, destinationEntry.id })).AsString; bool isOldResponse = string.Equals(simStatus, "WasDisplayed"); if (isOldResponse) text = string.Format("[em{0}]{1}[/em{0}]", (int) emTagForOldResponses, text); } pcResponses.Add(new Response(FormattedText.Parse(text, database.emphasisSettings), destinationEntry, isValid)); DialogueLua.MarkDialogueEntryOffered(destinationEntry); } } if (stopAtFirstValid) return; } else { // Condition is false, so block or pass through according to destination entry's setting: if (LinkTools.IsPassthroughOnFalse(destinationEntry)) { if (DialogueDebug.LogInfo) Debug.Log(string.Format("{0}: Passthrough on False Link ({1}): ID={2}:{3} '{4}' Condition='{5}'", new System.Object[] { DialogueDebug.Prefix, GetActorName(database.GetActor(destinationEntry.ActorID)), link.destinationConversationID, link.destinationDialogueID, GetLinkText(characterType, destinationEntry), destinationEntry.conditionsString })); List<Response> linkNpcResponses = new List<Response>(); List<Response> linkPcResponses = new List<Response>(); EvaluateLinks(destinationEntry, linkNpcResponses, linkPcResponses, visited); npcResponses.AddRange(linkNpcResponses); pcResponses.AddRange(linkPcResponses); } else { if (DialogueDebug.LogInfo) Debug.Log(string.Format("{0}: Block on False Link ({1}): ID={2}:{3} '{4}' Condition='{5}'", new System.Object[] { DialogueDebug.Prefix, GetActorName(database.GetActor(destinationEntry.ActorID)), link.destinationConversationID, link.destinationDialogueID, GetLinkText(characterType, destinationEntry), destinationEntry.conditionsString })); } } } } } }
private void SplitEntryAtPipes(int originalEntryIndex, string dialogueText) { // Split by Dialogue Text: string[] substrings = dialogueText.Split(new char[] { '|' }); DialogueEntry originalEntry = dialogueEntries[originalEntryIndex]; originalEntry.DefaultDialogueText = substrings[0]; List <Link> originalOutgoingLinks = originalEntry.outgoingLinks; ConditionPriority priority = ((originalOutgoingLinks != null) && (originalOutgoingLinks.Count > 0)) ? originalOutgoingLinks[0].priority : ConditionPriority.Normal; DialogueEntry currentEntry = originalEntry; // Split Menu Text: string[] menuTextSubstrings = originalEntry.DefaultMenuText.Split(new char[] { '|' }); // Split Audio Files: string audioFilesText = originalEntry.AudioFiles; audioFilesText = ((audioFilesText != null) && (audioFilesText.Length >= 2)) ? audioFilesText.Substring(1, audioFilesText.Length - 2) : string.Empty; string[] audioFiles = audioFilesText.Split(new char[] { ';' }); currentEntry.AudioFiles = string.Format("[{0}]", new System.Object[] { (audioFiles.Length > 0) ? audioFiles[0] : string.Empty }); // Create new dialogue entries for the split parts: int i = 1; while (i < substrings.Length) { DialogueEntry newEntry = AddNewDialogueEntry(originalEntry, substrings[i], i); newEntry.MenuText = (i < menuTextSubstrings.Length) ? menuTextSubstrings[i] : string.Empty; newEntry.AudioFiles = string.Format("[{0}]", new System.Object[] { (i < audioFiles.Length) ? audioFiles[i] : string.Empty }); currentEntry.outgoingLinks = new List <Link>() { NewLink(currentEntry, newEntry, priority) }; currentEntry = newEntry; i++; } // Set the last entry's links to the original outgoing links: currentEntry.outgoingLinks = originalOutgoingLinks; // Fix up the other splittable fields in the original entry: foreach (var field in originalEntry.fields) { if (string.IsNullOrEmpty(field.title)) { continue; } string fieldValue = field.value; bool isSplittable = (field.title.StartsWith("Sequence") || (field.type == FieldType.Localization)) && !string.IsNullOrEmpty(field.value) && field.value.Contains("|"); if (isSplittable) { substrings = field.value.Split(new char[] { '|' }); if (substrings.Length > 1) { fieldValue = substrings[0]; field.value = fieldValue; } } } }
/// <summary> /// Initializes a new DialogueEntry copied from a Chat Mapper DialogEntry. /// </summary> /// <param name='chatMapperDialogEntry'> /// The Chat Mapper dialog entry to copy. /// </param> public DialogueEntry(ChatMapper.DialogEntry chatMapperDialogEntry) { if (chatMapperDialogEntry != null) { id = chatMapperDialogEntry.ID; fields = Field.CreateListFromChatMapperFields(chatMapperDialogEntry.Fields); //--- Removed in Chat Mapper 1.7: conversationID = chatMapperDialogEntry.ConversationID; isRoot = chatMapperDialogEntry.IsRoot; isGroup = chatMapperDialogEntry.IsGroup; if (isGroup) Sequence = "None()"; nodeColor = chatMapperDialogEntry.NodeColor; delaySimStatus = chatMapperDialogEntry.DelaySimStatus; falseConditionAction = chatMapperDialogEntry.FalseCondtionAction; conditionPriority = ConditionPriorityTools.StringToConditionPriority(chatMapperDialogEntry.ConditionPriority); foreach (var chatMapperLink in chatMapperDialogEntry.OutgoingLinks) { outgoingLinks.Add(new Link(chatMapperLink)); } conditionsString = chatMapperDialogEntry.ConditionsString; userScript = chatMapperDialogEntry.UserScript; } }