Пример #1
0
        protected override void DumpMembers(LuaTextWriter output)
        {
            if (Alignment != null)
            {
                output.WriteKeyValue("Alignment", Alignment);
            }

            if (Descriptor != null)
            {
                output.WriteKeyValue("Descriptor", Descriptor);
            }

            if (School != null)
            {
                output.WriteKeyValue("School", School);
            }

            if (SubSchool != null)
            {
                output.WriteKeyValue("SubSchool", SubSchool);
            }

            if (Names.Any())
            {
                output.WriteObjectValue("Names", () =>
                {
                    foreach (var name in Names)
                    {
                        output.WriteValue(name);
                        output.Write(",\n");
                    }
                });
            }
            base.DumpMembers(output);
        }
Пример #2
0
 protected override void DumpMembers(LuaTextWriter output)
 {
     output.WriteList("Definitions", Definitions);
     output.WriteList("Bonuses", Bonuses);
     output.WriteList("ProhibitedSpells", ProhibitedSpells);
     output.WriteList("Domains", Domains);
     output.WriteList("Abilities", Abilities);
     output.WriteList("ClassSkills", ClassSkills);
     output.WriteList("AddedSpellCasterLevels", AddedSpellCasterLevels);
     output.WriteList("SpellLists", SpellLists);
     if (WeaponBonusProficiencySelections.Any())
     {
         output.WriteObjectValue("WeaponBonusProficiencySelections", () =>
         {
             foreach (var selection in WeaponBonusProficiencySelections)
             {
                 output.WriteStartObject();
                 foreach (var option in selection)
                 {
                     output.WriteValue(option);
                     output.Write(", ");
                 }
                 output.WriteLine();
                 output.WriteEndObject();
             }
         });
     }
     base.DumpMembers(output);
 }
Пример #3
0
        protected virtual void DumpMembers(LuaTextWriter output)
        {
            var props = new Dictionary <string, object?>(_properties);

            foreach (var key in PropertyOrder)
            {
                if (props.Remove(key, out var value))
                {
                    output.WriteProperty(key, value);
                }
            }

            foreach (var(key, value) in props.OrderBy(GetOrder).ThenBy(p => p.Key))
            {
                output.WriteProperty(key, value);
            }

            if (Clear.Any())
            {
                output.WriteObjectValue("Clear", () =>
                {
                    foreach (var(k, v) in Clear)
                    {
                        output.WriteKey(k);
                        output.Write("=");
                        output.WriteValue((object?)v);
                        output.Write(",\n");
                    }
                });
 protected override void DumpMembers(LuaTextWriter output)
 {
     output.WriteObjectValue("Choice", () =>
     {
         output.WriteProperty("Kind", ChoiceKind);
         output.WriteProperty("Value", ChoiceValue);
     });
     output.WriteProperty("Levels", Levels);
     base.DumpMembers(output);
 }
Пример #5
0
        private static void ProcessPCCFile(string pccFile, string outputDirectory)
        {
            var pccLines = ReadTsv(pccFile);

            DataSourceInfo?sourceInfo = new DataSourceInfo();

            var filesToProcess = new List <(string kind, string path)>();

            Directory.CreateDirectory(outputDirectory);
            var indexFile = Path.Join(outputDirectory, Path.GetFileName(pccFile) + ".lua");

            using (var outputStream = new FileStream(indexFile, FileMode.Create, FileAccess.Write))
                using (var output = new StreamWriter(outputStream))
                {
                    var luaWriter = new LuaTextWriter(output);
                    foreach (var line in pccLines)
                    {
                        if (line.Fields.Count > 1)
                        {
                            throw new ParseFailedException(line.Fields.First(), "Unexpected multiple fields in line.");
                        }

                        var field = line.Fields.Single();
                        if (sourceInfo != null && TryParsePCCDataField(field, sourceInfo))
                        {
                            continue;
                        }

                        if (sourceInfo != null)
                        {
                            luaWriter.Write("SetDataSetInfo(");
                            sourceInfo.Dump(luaWriter);
                            luaWriter.Write(")\n\n");
                            sourceInfo = null;
                        }

                        var(k, v) = field.SplitTuple(':');
                        switch (k.Value)
                        {
                        case "DATATABLE":
                        case "DYNAMIC":
                            // These files have nothing in them.....
                            break;

                        case "GLOBALMODIFIER":
                            // These files have only one line, and its undocumented and looks useless
                            break;

                        case "DEITY":
                        case "ABILITY":
                        case "ABILITYCATEGORY":
                        case "ALIGNMENT":
                        case "ARMORPROF":
                        case "BIOSET":
                        case "CLASS":
                        case "COMPANIONMOD":
                        case "DATACONTROL":
                        case "DOMAIN":
                        case "EQUIPMENT":
                        case "EQUIPMOD":
                        case "KIT":
                        case "LANGUAGE":
                        case "RACE":
                        case "SAVE":
                        case "SHIELDPROF":
                        case "SKILL":
                        case "SIZE":
                        case "STAT":
                        case "SPELL":
                        case "TEMPLATE":
                        case "VARIABLE":
                        case "WEAPONPROF":
                        {
                            var parts = v.Split('|').ToArray();
                            if (parts.Length < 1)
                            {
                                throw new ParseFailedException(v, $"Unable to parse {k.Value}");
                            }

                            var luaFile = Path.ChangeExtension(parts[0].Value, "lua");
                            filesToProcess.Add((k.Value, parts[0].Value));

                            var includes   = new List <(string?category, string name)>();
                            var excludes   = new List <(string?category, string name)>();
                            var conditions = new List <CampaignCondition>();
                            foreach (var part in parts.Skip(1))
                            {
                                if (part.StartsWith("(INCLUDE:CATEGORY=") && part.EndsWith(')') ||
                                    part.StartsWith("(EXCLUDE:CATEGORY=") && part.EndsWith(')'))
                                {
                                    var inside = part.Substring("(INCLUDE:CATEGORY=".Length,
                                                                part.Value.Length - "(INCLUDE:CATEGORY=)".Length);
                                    foreach (var group in inside.Split('|'))
                                    {
                                        var(category, names) = group.SplitTuple(',');
                                        foreach (var name in names.Split(','))
                                        {
                                            if (part.StartsWith("(IN"))
                                            {
                                                includes.Add((category.Value, name.Value));
                                            }
                                            else
                                            {
                                                excludes.Add((category.Value, name.Value));
                                            }
                                        }
                                    }
                                }
                                else if (part.StartsWith("(INCLUDE:") && part.EndsWith(")") ||
                                         part.StartsWith("(EXCLUDE:") && part.EndsWith(")"))
                                {
                                    var inside = part.Substring("(INCLUDE:".Length,
                                                                part.Value.Length - "(INCLUDE:CATEGORY=)".Length);
                                    foreach (var name in inside.Split('|'))
                                    {
                                        if (part.StartsWith("(IN"))
                                        {
                                            includes.Add((null, name.Value));
                                        }
                                        else
                                        {
                                            excludes.Add((null, name.Value));
                                        }
                                    }
                                }
                                else if (part.StartsWith("!PRECAMPAIGN:") || part.StartsWith("PRECAMPAIGN:"))
                                {
                                    var(_, conditionValue) = part.SplitTuple(':');
                                    conditions.Add(CampaignCondition.Parse(part.StartsWith("!"), conditionValue));
                                }
                            }

                            if (!includes.Any() && !excludes.Any() && !conditions.Any())
                            {
                                luaWriter.Write($"ImportFile(\"{luaFile}\")\n");
                            }
                            else
                            {
                                luaWriter.Write($"ImportFile(\"{luaFile}\", ");
                                luaWriter.WriteStartObject();
                                luaWriter.WriteObjectValue("Includes", () =>
                                    {
                                        foreach (var include in includes)
                                        {
                                            luaWriter.WriteStartObject();
                                            if (include.category != null)
                                            {
                                                luaWriter.WriteProperty("Category", include.category);
                                            }

                                            luaWriter.WriteProperty("Name", include.name);
                                            luaWriter.WriteEndObject();
                                        }
                                    });
                                luaWriter.WriteObjectValue("Excludes", () =>
                                    {
                                        foreach (var exclude in excludes)
                                        {
                                            luaWriter.WriteStartObject();
                                            if (exclude.category != null)
                                            {
                                                luaWriter.WriteProperty("Category", exclude.category);
                                            }

                                            luaWriter.WriteProperty("Name", exclude.name);
                                            luaWriter.WriteEndObject();
                                            luaWriter.Write(",\n");
                                        }
                                    });
                                luaWriter.WriteObjectValue("Conditions", () =>
                                    {
                                        foreach (var condition in conditions)
                                        {
                                            condition.Dump(luaWriter);
                                            luaWriter.Write(",\n");
                                        }
                                    });
                                luaWriter.WriteEndObject();
                                luaWriter.Write(")\n");
                            }

                            break;
                        }

                        case "LSTEXCLUDE":
                            foreach (var file in v.Value.Split('|'))
                            {
                                luaWriter.Write($"ExcludeFile(\"{Path.ChangeExtension(file.Replace("\\", "/"), "lua")}\")\n");
                            }
                            break;

                        case "ALLOWDUPES":
                            switch (v.Value)
                            {
                            case "SPELL":
                                luaWriter.Write("AllowDuplicateSpells()\n");
                                break;

                            case "LANGUAGE":
                                luaWriter.Write("AllowDuplicateLanguages()\n");
                                break;

                            default:
                                throw new ParseFailedException(v, "Unable to parse ALLOWDUPES");
                            }
                            break;

                        case "PCC":
                        {
                            var file = v.Value + ".lua";
                            luaWriter.Write($"ImportDataSet(\"{file}\")\n");
                            break;
                        }

                        case "HIDETYPE":
                        {
                            var parts = v.Value.Split('|');
                            var type  = parts.First();
                            var names = parts.Skip(1);
                            luaWriter.Write($"HideObjects(\"{type}\", ");
                            luaWriter.WriteStartObject();
                            luaWriter.WriteValue(names);
                            luaWriter.WriteEndObject();
                            luaWriter.Write(")\n");
                            break;
                        }

                        case "COMPANIONLIST":
                        {
                            var parts = v.Split('|').ToArray();
                            if (parts.Length < 2)
                            {
                                throw new ParseFailedException(v, "Cannot parse COMPANIONLIST");
                            }

                            var type = parts[0].Value;
                            var data = parts[1].Value;
                            int?followerAdjustment = null;
                            var conditions         = new List <Condition>();

                            foreach (var part in parts.Skip(2))
                            {
                                if (part.StartsWith("FOLLOWERADJUSTMENT:"))
                                {
                                    followerAdjustment = Helpers.ParseInt(part.Substring("FOLLOWERADJUSTMENT:".Length));
                                    continue;
                                }
                                if (!Condition.TryParse(part, out var condition))
                                {
                                    throw new ParseFailedException(part, "Unable to parse condition.");
                                }
                                conditions.Add(condition);
                            }
                            luaWriter.Write("AddAvailableCompanions(");
                            luaWriter.WriteValue(type.AsSpan());
                            luaWriter.Write(", ");
                            luaWriter.WriteStartObject();
                            foreach (var piece in data.Split(','))
                            {
                                if (piece == "ANY")
                                {
                                    luaWriter.WriteStartObject();
                                    luaWriter.WriteProperty("Any", true);
                                    luaWriter.WriteEndObject();
                                }
                                else if (piece.StartsWith("RACESUBTYPE="))
                                {
                                    var subtype = piece.Substring("RACESUBTYPE=".Length);
                                    luaWriter.WriteStartObject();
                                    luaWriter.WriteProperty("SubType", subtype);
                                    luaWriter.WriteEndObject();
                                }
                                else if (piece.StartsWith("RACETYPE="))
                                {
                                    var subtype = piece.Substring("RACETYPE=".Length);
                                    luaWriter.WriteStartObject();
                                    luaWriter.WriteProperty("Type", subtype);
                                    luaWriter.WriteEndObject();
                                }
                                else
                                {
                                    luaWriter.WriteStartObject();
                                    luaWriter.WriteProperty("Name", piece);
                                    luaWriter.WriteEndObject();
                                }

                                luaWriter.Write(",\n");
                            }
                            luaWriter.WriteEndObject();
                            luaWriter.Write(", ");
                            luaWriter.WriteStartObject();
                            if (followerAdjustment.HasValue)
                            {
                                luaWriter.WriteProperty("FollowerAdjustment", followerAdjustment.Value);
                            }

                            if (conditions.Any())
                            {
                                luaWriter.WriteProperty("Conditions", conditions);
                            }
                            luaWriter.WriteEndObject();
                            luaWriter.Write(")\n");


                            break;
                        }

                        case "FORWARDREF":
                            break;

                        default:
                            throw new ParseFailedException(field, $"Unknown field '{k.Value}'");
                        }
                    }
                }


            var pccDirectory = Path.GetDirectoryName(pccFile);

            foreach (var(kind, inputFile) in filesToProcess)
            {
                if (inputFile.StartsWith("@") || inputFile.StartsWith("&") || inputFile.StartsWith("*"))
                {
                    Console.WriteLine($"Not Converting absolute path '{inputFile}'.");
                    continue;
                }

                var inputFileFullPath = Path.Join(pccDirectory, inputFile);
                var outputFile        = Path.ChangeExtension(Path.Join(outputDirectory, inputFile), "lua");
                var outputDir         = Path.GetDirectoryName(outputFile);
                Directory.CreateDirectory(outputDir);

                Console.WriteLine($"Converting {kind} file {inputFileFullPath} -> {outputFile}");
                switch (kind)
                {
                case "CLASS":
                    new ClassFileConverter().Convert(inputFileFullPath, outputFile);
                    break;

                case "KIT":
                    new StartingKitFileConverter().Convert(inputFileFullPath, outputFile);
                    break;

                case "ABILITY":
                    new SingleObjectFileConverter <AbilityDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "ALIGNMENT":
                    new SingleObjectFileConverter <AlignmentDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "DATACONTROL":
                    new DataControlFileConverter().Convert(inputFileFullPath, outputFile);
                    break;

                case "SAVE":
                    new SingleObjectFileConverter <SaveDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "STAT":
                    new SingleObjectFileConverter <StatDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "VARIABLE":
                    new SingleObjectFileConverter <VariableDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "ABILITYCATEGORY":
                    new SingleObjectFileConverter <AbilityCategoryDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "DOMAIN":
                    new SingleObjectFileConverter <DomainDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "EQUIPMENT":
                    new SingleObjectFileConverter <EquipmentDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "EQUIPMOD":
                    new SingleObjectFileConverter <EquipmentModifierDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "LANGUAGE":
                    new SingleObjectFileConverter <LanguageDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "RACE":
                    new SingleObjectFileConverter <RaceDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "SKILL":
                    new SingleObjectFileConverter <SkillDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "SPELL":
                    new SingleObjectFileConverter <SpellDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "TEMPLATE":
                    new SingleObjectFileConverter <TemplateDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "ARMORPROF":
                    new SingleObjectFileConverter <ArmorProficiencyDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "SHIELDPROF":
                    new SingleObjectFileConverter <ShieldProficiencyDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "WEAPONPROF":
                    new SingleObjectFileConverter <WeaponProficiencyDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "COMPANIONMOD":
                    new CompanionModFileConverter().Convert(inputFileFullPath, outputFile);
                    break;

                case "DEITY":
                    new SingleObjectFileConverter <DeityDefinition>().Convert(inputFileFullPath, outputFile);
                    break;

                case "BIOSET":
                case "DATATABLE":
                case "DYNAMIC":
                case "GLOBALMODIFIER":
                case "SIZE":
                    Console.WriteLine($"Skipping Not-Yet-Implemented file kind {kind}");
                    //throw new NotImplementedException($"File kind {kind} not implemented.");
                    break;

                default:
                    throw new NotSupportedException($"File kind {kind} not supported.");
                }
            }
        }