From 4987a24fd873b0c30b4b1d4df0de60acaaecebed Mon Sep 17 00:00:00 2001 From: "H. C. Kruse" Date: Sun, 21 Apr 2024 19:55:45 +0200 Subject: [PATCH] feat: Parse lootgeneration --- Loader/LootLoader.cs | 83 +++++++++++++++++ Loader/LootService.cs | 16 ++++ Loader/Program.cs | 18 +++- .../scdb.Xml/Lootgeneration/LootArchetype.cs | 88 +++++++++++++++++++ Loader/scdb.Xml/Lootgeneration/LootTable.cs | 25 ++++++ 5 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 Loader/LootLoader.cs create mode 100644 Loader/LootService.cs create mode 100644 Loader/scdb.Xml/Lootgeneration/LootArchetype.cs create mode 100644 Loader/scdb.Xml/Lootgeneration/LootTable.cs diff --git a/Loader/LootLoader.cs b/Loader/LootLoader.cs new file mode 100644 index 000000000..4ed3c874b --- /dev/null +++ b/Loader/LootLoader.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Xml; +using System.Xml.Serialization; +using Newtonsoft.Json; +using Scdb.Xml; +using scdb.Xml.Entities; +using scdb.Xml.Lootgeneration; + +namespace Loader +{ + public class LootLoader + { + public string OutputFolder { get; set; } + public string DataRoot { get; set; } + + public Dictionary LoadArchetypes() + { + Directory.CreateDirectory(Path.Combine(OutputFolder, "loot")); + Directory.CreateDirectory(Path.Combine(OutputFolder, "loot", "archetypes")); + + var output = new Dictionary(); + + + var path = Path.Combine(DataRoot, Path.Join("Data", "Libs", "Foundry", "Records", "lootgeneration")); + + foreach (var entityFilename in Directory.EnumerateFiles(Path.Join(path, "lootarchetypes"), "*.xml")) + { + var archetype = Parse(entityFilename); + output.Add(archetype.__ref, archetype); + File.WriteAllText(Path.Combine(OutputFolder, "loot", "archetypes", $"{archetype.ClassName.ToLower()}.json"), JsonConvert.SerializeObject(archetype)); + } + + return output; + } + + public Dictionary LoadTables() + { + Directory.CreateDirectory(Path.Combine(OutputFolder, "loot")); + Directory.CreateDirectory(Path.Combine(OutputFolder, "loot", "tables")); + + var output = new Dictionary(); + + var path = Path.Combine(DataRoot, Path.Join("Data", "Libs", "Foundry", "Records", "lootgeneration")); + + foreach (var entityFilename in Directory.EnumerateFiles(Path.Join(path, "loottables"), "*.xml", SearchOption.AllDirectories)) + { + var lootTable = Parse(entityFilename); + output.Add(lootTable.__ref, lootTable); + File.WriteAllText(Path.Combine(OutputFolder, "loot", "tables", $"{lootTable.ClassName.ToLower()}.json"), JsonConvert.SerializeObject(lootTable)); + } + + return output; + } + + T Parse(string xmlFilename) where T : ClassBase + { + string rootNodeName; + using (var reader = XmlReader.Create(new StreamReader(xmlFilename))) + { + reader.MoveToContent(); + rootNodeName = reader.Name; + } + + var split = rootNodeName.Split('.'); + string className = split[split.Length - 1]; + + var xml = File.ReadAllText(xmlFilename); + var doc = new XmlDocument(); + doc.LoadXml(xml); + + var serialiser = new XmlSerializer(typeof(T), new XmlRootAttribute { ElementName = rootNodeName }); + using (var stream = new XmlNodeReader(doc)) + { + var entity = (T)serialiser.Deserialize(stream); + entity.ClassName = className; + return entity; + } + } + } +} diff --git a/Loader/LootService.cs b/Loader/LootService.cs new file mode 100644 index 000000000..b9086a74a --- /dev/null +++ b/Loader/LootService.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using scdb.Xml.Lootgeneration; + +namespace Loader; + +public class LootService +{ + public Dictionary archetypes; + public Dictionary tables; + + public LootService(Dictionary archetypes, Dictionary tables) + { + this.archetypes = archetypes; + this.tables = tables; + } +} diff --git a/Loader/Program.cs b/Loader/Program.cs index 89716d068..0dde70640 100644 --- a/Loader/Program.cs +++ b/Loader/Program.cs @@ -93,6 +93,17 @@ static void Main(string[] args) var manufacturerIndex = manufacturerLoader.Load(); var manufacturerSvc = new ManufacturerService(manufacturerIndex); + // Loot + Console.WriteLine("Load Loot Archetypes"); + var lootLoader = new LootLoader + { + OutputFolder = outputRoot, + DataRoot = scDataRoot + }; + var lootArchetypes = lootLoader.LoadArchetypes(); + var lootTables = lootLoader.LoadTables(); + var lootSvc = new LootService(lootArchetypes, lootTables); + // Ammunition Console.WriteLine("Load Ammunition"); var ammoLoader = new AmmoLoader @@ -127,12 +138,17 @@ static void Main(string[] args) var loadoutLoader = new LoadoutLoader(xmlLoadoutLoader, manualLoadoutLoader); var itemBuilder = new ItemBuilder(localisationSvc, manufacturerSvc, ammoSvc, entitySvc, inventorySvc); var itemInstaller = new ItemInstaller(entitySvc, loadoutLoader, itemBuilder); + var meleeLoader = new MeleeCombatLoader{ + OutputFolder = outputRoot, + DataRoot = scDataRoot + };; + var meleeConfigSvc = new MeleeCombatService(meleeLoader.Load()); // Items if (doItems) { Console.WriteLine("Load Items"); - var itemLoader = new ItemLoader(itemBuilder, manufacturerSvc, entitySvc, ammoSvc, itemInstaller, loadoutLoader, inventorySvc) + var itemLoader = new ItemLoader(itemBuilder, manufacturerSvc, entitySvc, ammoSvc, itemInstaller, loadoutLoader, inventorySvc, meleeConfigSvc) { OutputFolder = outputRoot, DataRoot = scDataRoot, diff --git a/Loader/scdb.Xml/Lootgeneration/LootArchetype.cs b/Loader/scdb.Xml/Lootgeneration/LootArchetype.cs new file mode 100644 index 000000000..e516bbaa0 --- /dev/null +++ b/Loader/scdb.Xml/Lootgeneration/LootArchetype.cs @@ -0,0 +1,88 @@ +using System.Xml; +using System.Xml.Serialization; +using scdb.Xml.Entities; + +namespace scdb.Xml.Lootgeneration +{ + public class LootArchetype: ClassBase + { + public ExcludedTags excludedTags; + + public PrimaryOrGroup primaryOrGroup; + public SecondaryOrGroups secondaryOrGroups; + } + + + public class ExcludedTags + { + public Reference[] tags; + } + + public class PrimaryOrGroup + { + [XmlAttribute] public string __type; + public LootArchetypeEntry_Primary[] entries; + } + + + public class SecondaryOrGroups + { + public LootArchetypeOrGroup_Secondary LootArchetypeOrGroup_Secondary; + } + + public class LootArchetypeEntry + { + [XmlAttribute] public string name; + [XmlAttribute] public string groupName; + [XmlAttribute] public string tag; + [XmlAttribute] public double weight; + [XmlAttribute] public string __type; + public AdditionalTags additionalTags; + public OptionalData optionalData; + } + + public class LootArchetypeEntry_Primary : LootArchetypeEntry; + + public class LootArchetypeEntry_Secondary + { + [XmlAttribute] public string tag; + [XmlAttribute] public double weight; + [XmlAttribute] public string __type; + }; + + public class LootArchetypeOrGroup_Secondary + { + + public LootArchetypeEntry_Secondary[] entries; + }; + + public class OptionalData + { + public EntryOptionalData_StackSize EntryOptionalData_StackSize; + public EntryOptionalData_SpawnWith EntryOptionalData_SpawnWith; + } + + public class EntryOptionalData_StackSize + { + [XmlAttribute] public double min; + [XmlAttribute] public double max; + } + + public class EntryOptionalData_SpawnWith: EntryOptionalData_StackSize + { + [XmlAttribute] public string name; + [XmlAttribute] public string mode; + + public TagsToMatch tagsToMatch; + } + + public class PnTags + { + public Reference[] positiveTags; + public Reference[] negativeTags; + } + + public class AdditionalTags : PnTags; + + public class TagsToMatch : PnTags; +} diff --git a/Loader/scdb.Xml/Lootgeneration/LootTable.cs b/Loader/scdb.Xml/Lootgeneration/LootTable.cs new file mode 100644 index 000000000..7eb8c8391 --- /dev/null +++ b/Loader/scdb.Xml/Lootgeneration/LootTable.cs @@ -0,0 +1,25 @@ +using System.Xml; +using System.Xml.Serialization; +using scdb.Xml.Entities; + +namespace scdb.Xml.Lootgeneration +{ + public class LootTable: ClassBase + { + public WeightedLootArchetype[] lootArchetypes; + } + + public class WeightedLootArchetype + { + [XmlAttribute] public string archetype; + [XmlAttribute] public double weight; + public NumberOfResultsConstraints numberOfResultsConstraints; + } + + public class NumberOfResultsConstraints + { + [XmlAttribute] public double minResults; + [XmlAttribute] public double maxResults; + + } +}