Browse Source

Refactored ConversationManager to do text processing in two distinct phases.

master
Christopher 9 years ago
parent
commit
83fc09272c
  1. 231
      Assets/Fungus/Thirdparty/FungusLua/Scripts/ConversationManager.cs
  2. 2
      Assets/Fungus/Thirdparty/FungusLua/Scripts/LuaUtils.cs

231
Assets/Fungus/Thirdparty/FungusLua/Scripts/ConversationManager.cs vendored

@ -8,22 +8,22 @@ namespace Fungus
{ {
public class ConversationManager public class ConversationManager
{ {
protected Character[] characters; protected struct ConversationItem
{
protected Character currentCharacter; public string Text { get; set; }
protected Sprite currentPortrait; public Character Character { get; set; }
protected RectTransform currentPosition; public Sprite Portrait { get; set; }
public RectTransform Position { get; set; }
}
protected Character previousCharacter; protected Character[] characters;
protected Sprite previousPortrait;
protected RectTransform previousPosition;
protected bool exitSayWait; protected bool exitSayWait;
public ConversationManager () public ConversationManager ()
{ {
// cache characters for faster lookup // cache characters for faster lookup
characters = GameObject.FindObjectsOfType<Fungus.Character>(); characters = UnityEngine.Object.FindObjectsOfType<Character>();
} }
protected Stage GetActiveStage() protected Stage GetActiveStage()
@ -41,7 +41,7 @@ namespace Fungus
/// Parse and execute a conversation string /// Parse and execute a conversation string
/// </summary> /// </summary>
/// <param name="conv"></param> /// <param name="conv"></param>
public IEnumerator Conversation(string conv) public IEnumerator DoConversation(string conv)
{ {
if (string.IsNullOrEmpty(conv)) if (string.IsNullOrEmpty(conv))
{ {
@ -55,130 +55,180 @@ namespace Fungus
yield break; yield break;
} }
//find SimpleScript say strings with portrait options var conversationItems = ParseConversation(conv);
//You can test regex matches here: http://regexstorm.net/tester
Regex sayRegex = new Regex(@"((?<sayParams>[\w ,]*):)?(?<text>.*\r*\n)");
MatchCollection sayMatches = sayRegex.Matches(conv);
for (int i = 0; i < sayMatches.Count; i++) // Play the conversation
{
previousCharacter = currentCharacter;
previousPortrait = currentPortrait;
previousPosition = currentPosition;
string sayParams = sayMatches[i].Groups["sayParams"].Value; Character currentCharacter = null;
if (!string.IsNullOrEmpty(sayParams)) Sprite currentPortrait = null;
{ RectTransform currentPosition = null;
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(' ');
}
SetParams(separateParams); Character previousCharacter = null;
} Sprite previousPortrait = null;
else RectTransform previousPosition = null;
{
//no params! Use previous settings?
}
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) if (item.Portrait != null)
{ {
sayDialog.SetCharacter(currentCharacter); 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(); Stage stage = GetActiveStage();
if (stage != null && currentCharacter != null && (currentPortrait != previousPortrait || currentPosition != previousPosition)) if (stage != null &&
{ currentCharacter != null &&
PortraitOptions portraitOptions = new PortraitOptions(true); (currentPortrait != previousPortrait || currentPosition != previousPosition))
portraitOptions.character = currentCharacter; {
portraitOptions.fromPosition = currentCharacter.state.position ?? previousPosition; PortraitOptions portraitOptions = new PortraitOptions(true);
portraitOptions.toPosition = currentPosition; portraitOptions.character = currentCharacter;
portraitOptions.portrait = currentPortrait; portraitOptions.fromPosition = currentCharacter.state.position ?? previousPosition;
portraitOptions.toPosition = currentPosition;
portraitOptions.portrait = currentPortrait;
stage.Show(portraitOptions); stage.Show(portraitOptions);
} }
previousCharacter = currentCharacter;
previousPortrait = currentPortrait;
previousPosition = currentPosition;
// Ignore Lua style comments and blank lines // Ignore Lua style comments and blank lines
if (text.StartsWith("--") || text.Trim() == "") if (item.Text.StartsWith("--") || item.Text.Trim() == "")
{ {
continue; continue;
} }
exitSayWait = false; exitSayWait = false;
sayDialog.Say(text, true, true, true, false, null, () => { sayDialog.Say(item.Text, true, true, true, false, null, () => {
exitSayWait = true; exitSayWait = true;
}); });
while (!exitSayWait)
{
yield return null;
}
exitSayWait = false;
}
while (!exitSayWait)
{
yield return null;
}
exitSayWait = false;
}
} }
protected virtual List<ConversationItem> ParseConversation(string conv)
{
//find SimpleScript say strings with portrait options
//You can test regex matches here: http://regexstorm.net/tester
Regex sayRegex = new Regex(@"((?<sayParams>[\w ,]*):)?(?<text>.*\r*\n)");
MatchCollection sayMatches = sayRegex.Matches(conv);
var items = new List<ConversationItem>(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;
}
/// <summary> /// <summary>
/// Using the string of say parameters before the ':', /// Using the string of say parameters before the ':',
/// set the current character, position and portrait if provided. /// set the current character, position and portrait if provided.
/// </summary> /// </summary>
/// <param name="sayParams">The list of say parameters</param> /// <param name="sayParams">The list of say parameters</param>
private void SetParams(string[] sayParams) protected virtual ConversationItem CreateConversationItem(string[] sayParams, string text, Character currentCharacter)
{ {
Character character = null; var item = new ConversationItem();
Sprite portrait = null;
RectTransform position = null; // Populate the story text to be written
item.Text = text;
if (sayParams == null || sayParams.Length == 0)
{
// Text only, no params - early out.
return item;
}
// try to find the character first, since we need to get its portrait // try to find the character param first, since we need to get its portrait
int characterIndex = -1; 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++) for (int j = 0; j < characters.Length; j++)
{ {
if (characters[j].NameStartsWith(sayParams[i])) if (characters[j].NameStartsWith(sayParams[i]))
{ {
characterIndex = i; characterIndex = i;
character = characters[j]; item.Character = characters[j];
break; break;
} }
} }
} }
// Assume last used character if none is specified now // 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 // Next see if we can find a portrait for this character
int portraitIndex = -1; int portraitIndex = -1;
if (character != null) if (item.Character != null)
{ {
for (int i = 0; i < sayParams.Length; i++) for (int i = 0; i < sayParams.Length; i++)
{ {
if (portrait == null && if (item.Portrait == null &&
character != null && item.Character != null &&
i != characterIndex) i != characterIndex)
{ {
Sprite s = character.GetPortrait(sayParams[i]); Sprite s = item.Character.GetPortrait(sayParams[i]);
if (s != null) if (s != null)
{ {
portraitIndex = i; portraitIndex = i;
portrait = s; item.Portrait = s;
break; break;
} }
} }
@ -194,26 +244,13 @@ namespace Fungus
if (i != characterIndex && if (i != characterIndex &&
i != portraitIndex) i != portraitIndex)
{ {
position = stage.GetPosition(sayParams[i]); item.Position = stage.GetPosition(sayParams[i]);
break; break;
} }
} }
} }
if (character != null) return item;
{
currentCharacter = character;
}
if (portrait != null)
{
currentPortrait = portrait;
}
if (position != null)
{
currentPosition = position;
}
} }
} }
} }

2
Assets/Fungus/Thirdparty/FungusLua/Scripts/LuaUtils.cs vendored

@ -477,7 +477,7 @@ namespace Fungus
/// <param name="conv"></param> /// <param name="conv"></param>
public virtual IEnumerator Conversation(string conv) public virtual IEnumerator Conversation(string conv)
{ {
return conversationManager.Conversation(conv); return conversationManager.DoConversation(conv);
} }
} }

Loading…
Cancel
Save