Advertisement
uglenXD

CLM.cs

Apr 22nd, 2019
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.82 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class CLM : MonoBehaviour {
  6.  
  7.     public static LINE Interpret(string rawLine)
  8.     {
  9.         return new LINE(rawLine);
  10.     }
  11.  
  12.     public class LINE
  13.     {
  14.         /// <summary>Who is speaking on this line. </summary>
  15.         public string speaker = "";
  16.  
  17.         /// <summary>The segments on this line that make up each piece of dialogue. </summary>
  18.         public List<SEGMENT> segments = new List<SEGMENT>();
  19.         /// <summary> All the actions to be called during or at the end of this line. </summary>
  20.         public List<string> actions = new List<string>();
  21.  
  22.         public string lastSegmentsWholeDialogue = "";
  23.  
  24.         public LINE(string rawLine)
  25.         {
  26.             string[] dialogueAndActions = rawLine.Split('"');
  27.             char actionSplitter = ' ';
  28.             string[] actionsArr = dialogueAndActions.Length == 3 ? dialogueAndActions[2].Split(actionSplitter) : dialogueAndActions[0].Split(actionSplitter);
  29.  
  30.             if (dialogueAndActions.Length == 3)//contains dialogue
  31.             {
  32.                 speaker = dialogueAndActions[0] == "" ? NovelController.instance.cachedLastSpeaker : dialogueAndActions[0];
  33.                 if (speaker[speaker.Length-1] == ' ')
  34.                     speaker = speaker.Remove(speaker.Length-1);
  35.  
  36.                 //cache the speaker
  37.                 NovelController.instance.cachedLastSpeaker = speaker;
  38.  
  39.                 //segment the dialogue.
  40.                 SegmentDialogue(dialogueAndActions[1]);
  41.             }
  42.  
  43.             //now handle actions. Just capture all actions into the line. They will be handled later.
  44.             for(int i = 0; i < actionsArr.Length; i++)
  45.             {
  46.                 actions.Add(actionsArr[i]);
  47.             }
  48.  
  49.             //the line is now segmented, the actions are loaded, and it is ready to be used.
  50.         }
  51.  
  52.         /// <summary>
  53.         /// Segments a line of dialogue into a list of individual parts separated by input delays.
  54.         /// </summary>
  55.         /// <param name="dialogue">Dialogue.</param>
  56.         void SegmentDialogue(string dialogue)
  57.         {
  58.             segments.Clear();
  59.             string[] parts = dialogue.Split('{','}');
  60.  
  61.             for (int i = 0; i < parts.Length; i++)
  62.             {
  63.                 SEGMENT segment = new SEGMENT();
  64.                 bool isOdd = i % 2 != 0;
  65.  
  66.                 //commands are odd indexed. Dialogue is always even.
  67.                 if (isOdd)
  68.                 {
  69.                     //commands and data are split by spaces
  70.                     string[] commandData = parts[i].Split(' ');
  71.                     switch(commandData[0])
  72.                     {
  73.                     case "c"://wait for input and clear.
  74.                         segment.trigger = SEGMENT.TRIGGER.waitClickClear;
  75.                         break;
  76.                     case "a"://wait for input and append.
  77.                         segment.trigger = SEGMENT.TRIGGER.waitClick;
  78.                         //appending requires fetching the text of the previous segment to be the pre text
  79.                         segment.pretext = segments.Count > 0 ? segments[segments.Count-1].dialogue : "";
  80.                         break;
  81.                     case "w"://wait for set time and clear.
  82.                         segment.trigger = SEGMENT.TRIGGER.autoDelay;
  83.                         segment.autoDelay = float.Parse(commandData[1]);
  84.                         break;
  85.                     case "wa"://wait for set time and append.
  86.                         segment.trigger = SEGMENT.TRIGGER.autoDelay;
  87.                         segment.autoDelay = float.Parse(commandData[1]);
  88.                         //appending requires fetching the text of the previous segment to be the pre text
  89.                         segment.pretext = segments.Count > 0 ? segments[segments.Count-1].dialogue : "";
  90.                         break;
  91.                     }
  92.                     i++;//increment so we move past the command and to the next bit of dialogue.
  93.                 }
  94.  
  95.                 segment.dialogue = parts[i];
  96.                 segment.line = this;
  97.  
  98.                 segments.Add(segment);
  99.             }
  100.         }
  101.  
  102.         public class SEGMENT
  103.         {
  104.             public LINE line;
  105.             public string dialogue = "";
  106.             public string pretext = "";
  107.             public enum TRIGGER{waitClick,waitClickClear,autoDelay}
  108.             public TRIGGER trigger = TRIGGER.waitClickClear;
  109.  
  110.             public float autoDelay = 0;
  111.  
  112.             /// <summary>
  113.             /// Run the segment and watch the dialogue build and display on the screen.
  114.             /// </summary>
  115.             public void Run()
  116.             {
  117.                 if (running != null)
  118.                     NovelController.instance.StopCoroutine(running);
  119.                 running = NovelController.instance.StartCoroutine(Running());
  120.             }
  121.  
  122.             public bool isRunning {get{return running != null;}}
  123.             Coroutine running = null;
  124.             public TextArchitect architect = null;
  125.             List<string> allCurrentlyExecutedEvents = new List<string>();
  126.             IEnumerator Running()
  127.             {
  128.                 allCurrentlyExecutedEvents.Clear();
  129.                 //take care of any tags that must be injected into the dialogue before we worry about events.
  130.                 TagManager.Inject(ref dialogue);
  131.  
  132.                 //split the dialogue by the event characters.
  133.                 string[] parts = dialogue.Split('[',']');
  134.  
  135.                 for (int i = 0; i < parts.Length; i++)
  136.                 {
  137.                     //events will always be odd indexed. Execute an event.
  138.                     bool isOdd = i % 2 != 0;
  139.                     if (isOdd)
  140.                     {
  141.                         DialogueEvents.HandleEvent(parts[i], this);
  142.                         allCurrentlyExecutedEvents.Add(parts[i]);
  143.                         i++;
  144.                     }
  145.  
  146.                     string targDialogue = parts[i];
  147.  
  148.                     if (line.speaker != "narrator" && !line.speaker.Contains("*"))
  149.                     {
  150.                         print(line.speaker);
  151.                         Characters character = CharacterManager.instance.GetCharacter(line.speaker);
  152.                         //This is a valid character that can show up on the screen. Get the character and make them speak.
  153.                         //if (character != null)
  154.                             character.Say(targDialogue, i > 0 ? true : pretext != "");
  155.                         //This is a character that has no images to display. Only show the name and the dialogue.
  156.                         //else
  157.                             //DialogueSystem.instance.Say(targDialogue, line.speaker, i > 0 ? true : pretext != ""); does not work yet
  158.                     }
  159.                     else
  160.                     {
  161.                         DialogSystem.instance.Say(targDialogue, line.speaker, i > 0 ? true : pretext != "");
  162.                     }
  163.  
  164.                     //yield while the dialogue system's architect is constructing the dialogue.
  165.                     architect = DialogSystem.instance.currentArchitect;
  166.  
  167.                     while(architect.isConstructing)
  168.                         yield return new WaitForEndOfFrame();
  169.                 }
  170.  
  171.                 running = null;
  172.             }
  173.                
  174.             public void ForceFinish()
  175.             {
  176.                 if (running != null)
  177.                     NovelController.instance.StopCoroutine(running);
  178.                 running = null;
  179.  
  180.                 if (architect != null)
  181.                 {
  182.                     architect.ForceFinish();
  183.  
  184.                     //time to complete the entire dialogue string since an interrupted segment with events will only autocomplete to the next event.
  185.                     if (pretext == "")
  186.                         line.lastSegmentsWholeDialogue = "";
  187.  
  188.                     //execute all actions that have not been made yet.
  189.                     string[] parts = dialogue.Split('[',']');
  190.                     for(int i = 0; i < parts.Length; i++)
  191.                     {
  192.                         bool isOdd = i % 2 != 0;
  193.                         if (isOdd)
  194.                         {
  195.                             string e = parts[i];
  196.                             if (allCurrentlyExecutedEvents.Contains(e))
  197.                             {
  198.                                 allCurrentlyExecutedEvents.Remove(e);
  199.                             }
  200.                             else
  201.                             {
  202.                                 DialogueEvents.HandleEvent(e,this);
  203.                             }
  204.                             i++;
  205.                         }
  206.                         //append only the dialogue to the whole dialogue and make the architect show it.
  207.                         line.lastSegmentsWholeDialogue += parts[i];
  208.                     }
  209.  
  210.                     //show the whole dialogue on the architect.
  211.                     architect.ShowText(line.lastSegmentsWholeDialogue);
  212.                 }
  213.             }
  214.         }
  215.     }
  216. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement