From 83fc09272c983ca0a6803c0d348667d7ae56e5ac Mon Sep 17 00:00:00 2001 From: Christopher Date: Tue, 26 Jul 2016 10:43:38 +0100 Subject: [PATCH] Refactored ConversationManager to do text processing in two distinct phases. --- .../FungusLua/Scripts/ConversationManager.cs | 235 ++++++++++-------- .../Thirdparty/FungusLua/Scripts/LuaUtils.cs | 2 +- 2 files changed, 137 insertions(+), 100 deletions(-) diff --git a/Assets/Fungus/Thirdparty/FungusLua/Scripts/ConversationManager.cs b/Assets/Fungus/Thirdparty/FungusLua/Scripts/ConversationManager.cs index 5b61c988..1324effd 100644 --- a/Assets/Fungus/Thirdparty/FungusLua/Scripts/ConversationManager.cs +++ b/Assets/Fungus/Thirdparty/FungusLua/Scripts/ConversationManager.cs @@ -8,22 +8,22 @@ namespace Fungus { public class ConversationManager { - protected Character[] characters; - - protected Character currentCharacter; - protected Sprite currentPortrait; - protected RectTransform currentPosition; + protected struct ConversationItem + { + public string Text { get; set; } + public Character Character { get; set; } + public Sprite Portrait { get; set; } + public RectTransform Position { get; set; } + } - protected Character previousCharacter; - protected Sprite previousPortrait; - protected RectTransform previousPosition; + protected Character[] characters; protected bool exitSayWait; public ConversationManager () { // cache characters for faster lookup - characters = GameObject.FindObjectsOfType(); + characters = UnityEngine.Object.FindObjectsOfType(); } protected Stage GetActiveStage() @@ -41,7 +41,7 @@ namespace Fungus /// Parse and execute a conversation string /// /// - public IEnumerator Conversation(string conv) + public IEnumerator DoConversation(string conv) { if (string.IsNullOrEmpty(conv)) { @@ -55,130 +55,180 @@ namespace Fungus yield break; } - //find SimpleScript say strings with portrait options - //You can test regex matches here: http://regexstorm.net/tester - Regex sayRegex = new Regex(@"((?[\w ,]*):)?(?.*\r*\n)"); - MatchCollection sayMatches = sayRegex.Matches(conv); + var conversationItems = ParseConversation(conv); - for (int i = 0; i < sayMatches.Count; i++) - { - previousCharacter = currentCharacter; - previousPortrait = currentPortrait; - previousPosition = currentPosition; + // Play the conversation - string sayParams = sayMatches[i].Groups["sayParams"].Value; - if (!string.IsNullOrEmpty(sayParams)) - { - string[] separateParams; - if (sayParams.Contains(",")) - { - separateParams = sayParams.Split(','); - for (int j = 0; j < separateParams.Length; j++) - { - separateParams[j] = separateParams[j].Trim(); - } - } - else - { - separateParams = sayParams.Split(' '); - } + Character currentCharacter = null; + Sprite currentPortrait = null; + RectTransform currentPosition = null; - SetParams(separateParams); - } - else - { - //no params! Use previous settings? - } + Character previousCharacter = null; + Sprite previousPortrait = null; + RectTransform previousPosition = null; - string text = sayMatches[i].Groups["text"].Value; + for (int i = 0; i < conversationItems.Count; ++i) + { + ConversationItem item = conversationItems[i]; - sayDialog.gameObject.SetActive(true); + if (item.Character != null) + { + currentCharacter = item.Character; + } - if (currentCharacter != null && currentCharacter != previousCharacter) - { - sayDialog.SetCharacter(currentCharacter); - } + if (item.Portrait != null) + { + currentPortrait = item.Portrait; + } + + if (item.Position != null) + { + currentPosition = item.Position; + } + + sayDialog.gameObject.SetActive(true); + + if (currentCharacter != null && + currentCharacter != previousCharacter) + { + sayDialog.SetCharacter(currentCharacter); + } Stage stage = GetActiveStage(); - if (stage != null && currentCharacter != null && (currentPortrait != previousPortrait || currentPosition != previousPosition)) - { - PortraitOptions portraitOptions = new PortraitOptions(true); - portraitOptions.character = currentCharacter; - portraitOptions.fromPosition = currentCharacter.state.position ?? previousPosition; - portraitOptions.toPosition = currentPosition; - portraitOptions.portrait = currentPortrait; + if (stage != null && + currentCharacter != null && + (currentPortrait != previousPortrait || currentPosition != previousPosition)) + { + PortraitOptions portraitOptions = new PortraitOptions(true); + portraitOptions.character = currentCharacter; + portraitOptions.fromPosition = currentCharacter.state.position ?? previousPosition; + portraitOptions.toPosition = currentPosition; + portraitOptions.portrait = currentPortrait; + + stage.Show(portraitOptions); + } + + previousCharacter = currentCharacter; + previousPortrait = currentPortrait; + previousPosition = currentPosition; - stage.Show(portraitOptions); - } - // Ignore Lua style comments and blank lines - if (text.StartsWith("--") || text.Trim() == "") + if (item.Text.StartsWith("--") || item.Text.Trim() == "") { continue; } - exitSayWait = false; - sayDialog.Say(text, true, true, true, false, null, () => { - exitSayWait = true; - }); + exitSayWait = false; + sayDialog.Say(item.Text, true, true, true, false, null, () => { + exitSayWait = true; + }); - while (!exitSayWait) - { - yield return null; - } - exitSayWait = false; - } - + while (!exitSayWait) + { + yield return null; + } + exitSayWait = false; + } } - + + protected virtual List ParseConversation(string conv) + { + //find SimpleScript say strings with portrait options + //You can test regex matches here: http://regexstorm.net/tester + Regex sayRegex = new Regex(@"((?[\w ,]*):)?(?.*\r*\n)"); + MatchCollection sayMatches = sayRegex.Matches(conv); + + var items = new List(sayMatches.Count); + + Character currentCharacter = null; + for (int i = 0; i < sayMatches.Count; i++) + { + string text = sayMatches[i].Groups["text"].Value; + string sayParams = sayMatches[i].Groups["sayParams"].Value; + string[] separateParams = null; + + if (!string.IsNullOrEmpty(sayParams)) + { + if (sayParams.Contains(",")) + { + separateParams = sayParams.Split(','); + for (int j = 0; j < separateParams.Length; j++) + { + separateParams[j] = separateParams[j].Trim(); + } + } + else + { + separateParams = sayParams.Split(' '); + } + } + + var item = CreateConversationItem(separateParams, text, currentCharacter); + + // Previous speaking character is the default for next conversation item + currentCharacter = item.Character; + + items.Add(item); + } + + return items; + } + /// /// Using the string of say parameters before the ':', /// set the current character, position and portrait if provided. /// /// The list of say parameters - private void SetParams(string[] sayParams) + protected virtual ConversationItem CreateConversationItem(string[] sayParams, string text, Character currentCharacter) { - Character character = null; - Sprite portrait = null; - RectTransform position = null; + var item = new ConversationItem(); + + // Populate the story text to be written + item.Text = text; - // try to find the character first, since we need to get its portrait + if (sayParams == null || sayParams.Length == 0) + { + // Text only, no params - early out. + return item; + } + + // try to find the character param first, since we need to get its portrait int characterIndex = -1; - for (int i = 0; character == null && i < sayParams.Length; i++) + for (int i = 0; item.Character == null && i < sayParams.Length; i++) { for (int j = 0; j < characters.Length; j++) { if (characters[j].NameStartsWith(sayParams[i])) { characterIndex = i; - character = characters[j]; + item.Character = characters[j]; break; } } } // Assume last used character if none is specified now - if (character == null) + if (item.Character == null) { - character = currentCharacter; + item.Character = currentCharacter; } // Next see if we can find a portrait for this character int portraitIndex = -1; - if (character != null) + if (item.Character != null) { for (int i = 0; i < sayParams.Length; i++) { - if (portrait == null && - character != null && + if (item.Portrait == null && + item.Character != null && i != characterIndex) { - Sprite s = character.GetPortrait(sayParams[i]); + Sprite s = item.Character.GetPortrait(sayParams[i]); if (s != null) { portraitIndex = i; - portrait = s; + item.Portrait = s; break; } } @@ -194,26 +244,13 @@ namespace Fungus if (i != characterIndex && i != portraitIndex) { - position = stage.GetPosition(sayParams[i]); + item.Position = stage.GetPosition(sayParams[i]); break; } } } - if (character != null) - { - currentCharacter = character; - } - - if (portrait != null) - { - currentPortrait = portrait; - } - - if (position != null) - { - currentPosition = position; - } + return item; } } } \ No newline at end of file diff --git a/Assets/Fungus/Thirdparty/FungusLua/Scripts/LuaUtils.cs b/Assets/Fungus/Thirdparty/FungusLua/Scripts/LuaUtils.cs index 0dd85716..c4b6a8e0 100644 --- a/Assets/Fungus/Thirdparty/FungusLua/Scripts/LuaUtils.cs +++ b/Assets/Fungus/Thirdparty/FungusLua/Scripts/LuaUtils.cs @@ -477,7 +477,7 @@ namespace Fungus /// public virtual IEnumerator Conversation(string conv) { - return conversationManager.Conversation(conv); + return conversationManager.DoConversation(conv); } }