public void CompileFile(string path)
    {
        var dlgContent = Tig.FS.ReadTextFile(path);

        var parser = new DialogScriptParser(path, dlgContent);

        while (parser.GetSingleLine(out var dialogLine, out var lineNumber))
        {
        }
    }
Exemplo n.º 2
0
    private void ConvertDialog()
    {
        var dialogFiles = Tig.FS.ListDirectory("dlg")
                          .Where(f => f.EndsWith(".dlg"))
                          .Distinct()
                          .ToList();

        Console.WriteLine($"Found {dialogFiles.Count} dialog files.");

        var dlgFilePattern = new Regex(@"(\d{5}).*");

        foreach (var dialogFile in dialogFiles)
        {
            var m = dlgFilePattern.Match(dialogFile);
            if (!m.Success)
            {
                Console.WriteLine($"Skipping dialog file that doesn't match expected pattern: {dialogFile}'.");
                continue;
            }

            var scriptId         = int.Parse(m.Groups[1].Value);
            var associatedScript = _convertedScripts.FirstOrDefault(s => s.Type == ScriptType.Object &&
                                                                    s.ScriptId == scriptId);
            if (associatedScript == null)
            {
                Console.WriteLine($"Dialog file {dialogFile} with id {scriptId} has no associated script!");
                continue;
            }

            var outputDir = Path.Join(
                Path.GetDirectoryName(associatedScript.OutputPath),
                "Dialog"
                );
            Directory.CreateDirectory(Path.Combine(_outputDirectory, outputDir));

            var outputPath = Path.Join(outputDir,
                                       Path.GetFileNameWithoutExtension(associatedScript.OutputPath) + "Dialog.cs");
            if (_writeDialog)
            {
                File.Delete(Path.Combine(_outputDirectory, outputPath));
            }

            var dialogContent = Tig.FS.ReadTextFile("dlg/" + dialogFile);
            var parser        = new DialogScriptParser(dialogFile, dialogContent);

            // We're going to build a class file for the dialog script that contains two methods,
            // and extends from the object script of the same script id

            var conditions  = new List <(int, string, string)>();
            var effects     = new List <(int, string, string)>();
            var skillChecks = new List <(int, SkillCheck)>();

            while (parser.GetSingleLine(out var dialogLine, out var fileLine))
            {
                var effectPython = dialogLine.effectField;
                if (effectPython == "pc.barter(npc)" &&
                    dialogLine.txt.StartsWith("b:", StringComparison.OrdinalIgnoreCase))
                {
                    continue; // Skip bogus barter effect (this is implied by B:)
                }

                try
                {
                    if (!string.IsNullOrEmpty(effectPython))
                    {
                        var converted = converter.ConvertSnippet(effectPython, associatedScript, DialogContext);
                        effects.Add((dialogLine.key, effectPython, converted));
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(
                        $"[e] Failed to convert effect for line {dialogLine.key} ({effectPython}): {e}");
                    effects.Add((dialogLine.key, effectPython, null));
                }

                if (dialogLine.IsPcLine)
                {
                    var conditionPython = dialogLine.testField;
                    try
                    {
                        if (!string.IsNullOrEmpty(conditionPython))
                        {
                            foreach (var skillCheck in converter.FindSkillChecks(conditionPython))
                            {
                                skillChecks.Add((dialogLine.key, skillCheck));
                            }

                            var converted =
                                converter.ConvertSnippet(conditionPython, associatedScript, DialogContext);
                            conditions.Add((dialogLine.key, conditionPython, converted));
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(
                            $"[e] Failed to convert condition for line {dialogLine.key} ({conditionPython}): {e}");
                        conditions.Add((dialogLine.key, conditionPython, null));
                    }
                }
            }

            if (_writeDialog)
            {
                var dialogScript = new StringBuilder();

                dialogScript.AppendLine(@"
using System;
using System.Collections.Generic;
using System.Diagnostics;
using OpenTemple.Core.GameObject;
using OpenTemple.Core.Systems;
using OpenTemple.Core.Systems.Dialog;
using OpenTemple.Core.Systems.Feats;
using OpenTemple.Core.Systems.D20;
using OpenTemple.Core.Systems.Script;
using OpenTemple.Core.Systems.Spells;
using OpenTemple.Core.Systems.GameObjects;
using OpenTemple.Core.Systems.D20.Conditions;
using OpenTemple.Core.Location;
using OpenTemple.Core.Systems.ObjScript;
using OpenTemple.Core.Ui;
using System.Linq;
using OpenTemple.Core.Systems.Script.Extensions;
using OpenTemple.Core.Utils;
using static OpenTemple.Core.Systems.Script.ScriptUtilities;
");
                dialogScript.AppendLine("namespace " + associatedScript.Namespace + ".Dialog");
                dialogScript.AppendLine("{");
                dialogScript.Append("[DialogScript(").Append(associatedScript.ScriptId).AppendLine(")]");
                dialogScript.AppendLine("public class " + associatedScript.ClassName + "Dialog : " +
                                        associatedScript.ClassName + ", IDialogScript");
                dialogScript.AppendLine("{");

                WriteDialogMethod(dialogScript, conditions, false);
                WriteDialogMethod(dialogScript, effects, true);
                WriteSkillChecksMethod(dialogScript, skillChecks);

                dialogScript.AppendLine("}");
                dialogScript.AppendLine("}");

                var parseOptions  = new CSharpParseOptions(LanguageVersion.Latest);
                var syntaxTree    = CSharpSyntaxTree.ParseText(dialogScript.ToString(), parseOptions);
                var formattedNode = Formatter.Format(syntaxTree.GetRoot(), workspace);

                File.WriteAllText(Path.Join(_outputDirectory, outputPath), formattedNode.ToFullString());
            }
        }
    }