static void ParsePageTexts(QuestPage page, QuestStream stream)
 {
     _pageTextsBuffer.Length = 0;
     while (true)
     {
         var line = stream.Next();
         if (line.Length == 0)
         {
             break;
         }
         if (line[0] == '*' || line[0] == '-')
         {
             stream.Previous(); break;
         }
         if (_pageTextsBuffer.Length > 0)
         {
             _pageTextsBuffer.Append(" ");
         }
         _pageTextsBuffer.Append(line);
     }
     if (_pageTextsBuffer.Length == 0)
     {
         throw new Exception(string.Format("Invalid page texts at line: {0}", stream.pointer));
     }
     page.texts.AddRange(Regex.Split(_pageTextsBuffer.ToString(), "\\s?\\[br\\]\\s?"));
 }
 static void ParsePageLogics(QuestPage page, QuestStream stream)
 {
     while (true)
     {
         var line = stream.Next();
         if (line.Length == 0)
         {
             break;
         }
         if (line[0] != '{')
         {
             stream.Previous(); break;
         }
         var matching = Regex.Match(line, "\\{(.+?)\\}");
         if (!matching.Success || string.IsNullOrEmpty(matching.Groups[1].Value))
         {
             throw new Exception(string.Format("Invalid logic at line: {0}", stream.pointer));
         }
         var cond = ParseLogic(QuestLogicFilter.State, matching.Groups[1].Value, stream.pointer);
         if (cond != null)
         {
             if (page.logics == null)
             {
                 page.logics = new List <QuestLogic> ();
             }
             page.logics.Add(cond);
         }
     }
 }
 /// <summary>
 /// Checks for auto execution single choice without text and process it if requires.
 /// Will return success of this check & execution.
 /// </summary>
 /// <param name="page">Page to check.</param>
 public bool MakeAutoChoice(QuestPage page)
 {
     if (page.choices.Count == 1 && string.IsNullOrEmpty(page.choices[0].text))
     {
         SetCurrentPage(page.choices[0].link);
         return(true);
     }
     return(false);
 }
        static void ParsePageChoices(QuestPage page, QuestStream stream)
        {
            var lineId = stream.pointer;

            while (true)
            {
                var line = stream.Next();
                if (line.Length == 0)
                {
                    break;
                }
                if (line[0] != '*')
                {
                    stream.Previous(); break;
                }
                var matching = Regex.Match(line, "\\*(.*?)->\\s*?(\\b.+)");
                if (!matching.Success)
                {
                    throw new Exception(string.Format("Invalid choice syntax at line: {0}", lineId));
                }
                lineId = stream.pointer;
                var choice = new QuestChoice();
                choice.link = matching.Groups[2].Value.ToLowerInvariant();
                var rawChoiceText = matching.Groups[1].Value;
                if (!string.IsNullOrEmpty(rawChoiceText))
                {
                    var matchingCond = Regex.Match(rawChoiceText, "\\{(.*?)\\}(.+)");
                    if (!matchingCond.Success)
                    {
                        choice.text = rawChoiceText.Trim();
                    }
                    else
                    {
                        choice.condition = ParseLogic(QuestLogicFilter.Expression, matchingCond.Groups[1].Value, lineId);
                        choice.text      = matchingCond.Groups[2].Value.Trim();
                    }
                }
                page.choices.Add(choice);
            }
            if (page.choices.Count == 0)
            {
                throw new Exception(string.Format("No choices at line: {0}", lineId));
            }
            if (page.choices.Count == 1 && page.choices[0].condition != null)
            {
                throw new Exception(string.Format("Auto choice cant use condition at line: {0}", lineId));
            }
        }
        static QuestPage ParsePage(QuestStream stream, out string pageName)
        {
            var line     = stream.Next();
            var matching = Regex.Match(line, "->\\s*?(\\b.+)");

            if (!matching.Success)
            {
                throw new Exception(string.Format("Invalid page header at line: {0}", stream.pointer));
            }
            var name = matching.Groups[1].Value.ToLowerInvariant();

            if (name == "end")
            {
                throw new Exception(string.Format("Invalid page name at line: {0}", stream.pointer));
            }
            var page = new QuestPage();

            ParsePageLogics(page, stream);
            ParsePageTexts(page, stream);
            ParsePageChoices(page, stream);
            pageName = name;
            return(page);
        }