示例#1
0
        /// <summary>
        ///  Decompiles the CST scene script and writes it to the text writer.
        /// </summary>
        /// <param name="writer">The text writer to write the decompiled script to.</param>
        private void DecompileInternal(TextWriter writer)
        {
            // Header must state the output .cst script file name
            writer.WriteLine($"#{Path.GetFileNameWithoutExtension(FileName)}");
            writer.WriteLine();

            for (int i = 0; i < Count; i++)
            {
                ISceneLine line = Lines[i];
                switch (line.Type)
                {
                case SceneLineType.Command:
                    writer.WriteLine($"\t{line.Content}");
                    break;

                case SceneLineType.Message:
                    // When a scene file has a message written on a new line after another message,
                    // a '\n' is automatically prefixed. We need to remove that.
                    if (line.Content.StartsWith("\\n"))
                    {
                        writer.WriteLine($"\t{line.Content.Substring(2)}");
                    }
                    // Empty messages are the result of '\n' as the line input
                    else if (line.Content.Length == 0)
                    {
                        writer.WriteLine("\t\\n");
                    }
                    else
                    {
                        writer.WriteLine($"\t{line.Content}");
                    }
                    break;

                case SceneLineType.Name:
                    // Write the name without tab first
                    writer.Write(line.Content);
                    // See if we can continue by writing the preceding message on the same line.
                    if (i + 1 < Count && Lines[i + 1].Type == SceneLineType.Message)
                    {
                        writer.WriteLine($"\t{Lines[i + 1].Content}");
                        i++;                         // Skip the next entry, we just wrote it
                    }
                    break;

                case SceneLineType.Input:
                    // Input is specified by an empty line, whitespace is allowed
                    writer.WriteLine();
                    break;

                case SceneLineType.Page:
                    // Page break in novel view, denoted with \p
                    writer.WriteLine();
                    writer.WriteLine("\t\\p");
                    writer.WriteLine();
                    break;
                }
            }
            writer.Flush();
        }
示例#2
0
        /// <summary>
        ///  Decompiles the CST scene script and writes it to the human readable text writer.
        /// </summary>
        /// <param name="writer">The text writer to write the human readable script to.</param>
        private void HumanReadableInternal(TextWriter writer)
        {
            // Header must state the output .cst script file name
            writer.WriteLine($"#{Path.GetFileNameWithoutExtension(FileName)}");
            writer.WriteLine();

            bool isChoice = false;

            List <string> choices = new List <string>();

            StringBuilder name    = new StringBuilder();
            StringBuilder message = new StringBuilder();

            bool firstInput = true;

            void FlushText()
            {
                if (name.Length != 0 || message.Length != 0 || isChoice)
                {
                    if (firstInput)
                    {
                        firstInput = false;
                    }
                    else
                    {
                        writer.WriteLine();
                    }

                    // The first replace prevents duplicate carraige returns
                    name.Replace("\n\r", "\n").Replace("\n", "\n\r");
                    message.Replace("\n\r", "\n").Replace("\n", "\n\r");

                    if (!isChoice && name.Length != 0)
                    {
                        writer.WriteLine(name);
                    }
                    if (message.Length != 0)
                    {
                        writer.WriteLine(message);
                    }
                    if (isChoice)
                    {
                        if (message.Length != 0)
                        {
                            writer.WriteLine();
                        }
                        writer.WriteLine("Choice:");
                        foreach (string choice in choices)
                        {
                            writer.WriteLine($"• {choice}");
                        }
                    }
                }
                message.Clear();
                name.Clear();
                choices.Clear();
                isChoice = false;
            }

            for (int i = 0; i < Count; i++)
            {
                ISceneLine line = Lines[i];
                switch (line.Type)
                {
                case SceneLineType.Command:
                    Match match;
                    if (line.Content == "fselect")
                    {
                        FlushText();
                        isChoice = true;
                    }
                    else if (isChoice && (match = ChoiceRegex.Match(line.Content)).Success)
                    {
                        //writer.WriteLine($"• {match.Groups["text"].Value}");
                        choices.Add(CatUtils.UnescapeString(match.Groups["text"].Value));
                    }
                    break;

                case SceneLineType.Message:
                    message.Append(CatUtils.UnescapeMessage(line.Content, false));
                    break;

                case SceneLineType.Name:
                    name.Append(CatUtils.UnescapeMessage(line.Content, true));
                    break;

                case SceneLineType.Input:
                    FlushText();
                    break;

                case SceneLineType.Page:
                    FlushText();
                    writer.WriteLine();
                    writer.WriteLine();
                    break;
                }
            }

            FlushText();

            writer.Flush();
        }
 internal SceneLine(ISceneLine line)
 {
     Type    = line.Type;
     Content = line.Content;
 }
示例#4
0
        /*private void ReadNovelRanges(List<NovelRange> novelRanges) {
         *      NovelCommand on = null;
         *      for (int i = 0; i < Script.Count; i++) {
         *              if (Script.Lines[i] is NovelCommand novel) {
         *                      if (on == null && novel.State) {
         *                              on = novel;
         *                      }
         *                      else if (on != null && !novel.State) {
         *                              novelRanges.Add(new NovelRange(on, novel));
         *                              on = null;
         *                      }
         *              }
         *      }
         *      if (on != null)
         *              novelRanges.Add(new NovelRange(on));
         * }*/

        private void ReadScene(List <Message> messages, List <Choice> choices)
        {
            bool mesdraw = true;
            bool novel   = false;

            Message.Builder msgBuilder = new Message.Builder(this);
            for (int i = 0; i < Script.Count; i++)
            {
                ISceneLine line = Script.Lines[i];
                switch (line)
                {
                case ScenePage _:
                case SceneInput _:
                    if (msgBuilder.HasMessage)
                    {
                        Message msg = msgBuilder.Build();
                        if (mesdraw && msg != null)
                        {
                            messages.Add(msg);
                        }
                    }
                    break;

                case NovelCommand novelCmd:
                    novel = novelCmd.State;
                    msgBuilder.IsNovel = novelCmd.State;
                    break;

                case MesdrawCommand mesdrawCmd:
                    mesdraw = mesdrawCmd.State;
                    break;

                case SceneName name:
                    msgBuilder.Names.Add(name);
                    break;

                case SceneMessage message:
                    msgBuilder.Messages.Add(message);
                    break;

                case SoundPlayCommand play:
                    if (play.SoundType == SoundType.Pcm)
                    {
                        msgBuilder.Voices.Add(play);
                    }
                    break;

                case ConditionCommand condition:
                    if (condition.Command is SoundPlayCommand conPlay && conPlay.SoundType == SoundType.Pcm)
                    {
                        Console.WriteLine(condition.Content);
                    }
                    break;

                case ChoiceCommand choice:
                    if (!JpUtils.Check(choice.ChoiceContent))
                    {
                        choices.Add(new Choice(this, choice));
                    }
                    else
                    {
                        Console.WriteLine("");
                    }
                    break;
                }
            }
        }