From da9f83c6dea2ecf378574b1e65a407ccc1112c67 Mon Sep 17 00:00:00 2001 From: Seweryn Presnal Date: Sat, 6 Jul 2024 21:17:42 +0200 Subject: [PATCH] Prevent multiple building_gfx entries for a culture --- ImperatorToCK3/CK3/Cultures/Culture.cs | 19 +++++--- .../CK3/Cultures/CultureCollection.cs | 46 +++++++++---------- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/ImperatorToCK3/CK3/Cultures/Culture.cs b/ImperatorToCK3/CK3/Cultures/Culture.cs index 89530f840..6bc91c65a 100644 --- a/ImperatorToCK3/CK3/Cultures/Culture.cs +++ b/ImperatorToCK3/CK3/Cultures/Culture.cs @@ -10,7 +10,7 @@ using System.Text; using System.Threading.Tasks; -namespace ImperatorToCK3.CK3.Cultures; +namespace ImperatorToCK3.CK3.Cultures; public sealed class Culture : IIdentifiable, IPDXSerializable { public string Id { get; } @@ -27,7 +27,7 @@ public sealed class Culture : IIdentifiable, IPDXSerializable { private readonly OrderedSet innovationsFromImperator = []; private readonly Dictionary innovationProgressesFromImperator = []; - + public Culture(string id, CultureData cultureData) { Id = id; @@ -38,8 +38,15 @@ public Culture(string id, CultureData cultureData) { traditionIds = cultureData.TraditionIds; nameLists = cultureData.NameLists; attributes = new List>(cultureData.Attributes); + + // Avoid multiple "building_gfx" attributes in the same culture by keeping only the last one. + var buildingGfxAttributes = attributes.Where(pair => pair.Key == "building_gfx").ToList(); + if (buildingGfxAttributes.Count > 1) { + attributes.RemoveAll(pair => pair.Key == "building_gfx"); + attributes.Add(buildingGfxAttributes[^1]); + } } - + public string Serialize(string indent, bool withBraces) { var contentIndent = indent; if (withBraces) { @@ -75,7 +82,7 @@ public async Task OutputHistory(string outputModPath, Date date) { // Nothing to output. return; } - + var historyStrBuilder = new StringBuilder(); historyStrBuilder.AppendLine("# This file was generated by the IRToCK3 converter."); @@ -90,7 +97,7 @@ public async Task OutputHistory(string outputModPath, Date date) { historyStrBuilder.AppendLine("\t}"); } historyStrBuilder.AppendLine("}"); - + var historyPath = Path.Combine(outputModPath, "history/cultures", Id + ".txt"); await using var historyWriter = File.CreateText(historyPath); await historyWriter.WriteAsync(historyStrBuilder.ToString()); @@ -98,7 +105,7 @@ public async Task OutputHistory(string outputModPath, Date date) { public void ImportInnovationsFromImperator(ISet irInventions, InnovationMapper innovationMapper) { innovationsFromImperator.AddRange(innovationMapper.GetInnovations(irInventions)); - + var progresses = innovationMapper.GetInnovationProgresses(irInventions); foreach (var (innovationId, progress) in progresses) { // If progress is 100 or more, the innovation can be considered discovered. diff --git a/ImperatorToCK3/CK3/Cultures/CultureCollection.cs b/ImperatorToCK3/CK3/Cultures/CultureCollection.cs index 96eacc0a3..c69ba2416 100644 --- a/ImperatorToCK3/CK3/Cultures/CultureCollection.cs +++ b/ImperatorToCK3/CK3/Cultures/CultureCollection.cs @@ -14,7 +14,7 @@ using System.Collections.Generic; using System.Linq; -namespace ImperatorToCK3.CK3.Cultures; +namespace ImperatorToCK3.CK3.Cultures; public class CultureCollection : IdObjectCollection { public CultureCollection(ColorFactory colorFactory, PillarCollection pillarCollection, ICollection ck3ModFlags) { @@ -64,10 +64,10 @@ private void InitCultureDataParser(ColorFactory colorFactory, ICollection ck3ModFlags, BufferedReader reader) { var cultureIdsPerModFlagParser = new Parser(); - + if (ck3ModFlags.Count == 0) { cultureIdsPerModFlagParser.RegisterKeyword("vanilla", modCultureIdsReader => { cultureData.InvalidatingCultureIds = modCultureIdsReader.GetStrings(); @@ -79,37 +79,37 @@ private void LoadInvalidatingCultureIds(ICollection ck3ModFlags, Buffere }); } } - + // Ignore culture IDs from mods that haven't been selected. cultureIdsPerModFlagParser.IgnoreAndStoreUnregisteredItems(ignoredModFlags); cultureIdsPerModFlagParser.ParseStream(reader); } - + public void LoadCultures(ModFilesystem ck3ModFS) { Logger.Info("Loading cultures..."); - + var parser = new Parser(); parser.RegisterRegex(CommonRegexes.String, (reader, cultureId) => LoadCulture(cultureId, reader)); parser.IgnoreAndLogUnregisteredItems(); - parser.ParseGameFolder("common/culture/cultures", ck3ModFS, "txt", true, logFilePaths: true); - + parser.ParseGameFolder("common/culture/cultures", ck3ModFS, "txt", recursive: true, logFilePaths: true); + ReplaceInvalidatedParents(); } - + public void LoadConverterCultures(string converterCulturesPath) { Logger.Info("Loading converter cultures..."); - + var parser = new Parser(); parser.RegisterRegex(CommonRegexes.String, (reader, cultureId) => LoadCulture(cultureId, reader)); parser.IgnoreAndLogUnregisteredItems(); parser.ParseFile(converterCulturesPath); - + ReplaceInvalidatedParents(); } private void LoadCulture(string cultureId, BufferedReader cultureReader) { cultureData = new CultureData(); - + cultureDataParser.ParseStream(cultureReader); if (cultureData.InvalidatingCultureIds.Any()) { @@ -154,7 +154,7 @@ private void ReplaceInvalidatedParents() { public void LoadNameLists(ModFilesystem ck3ModFS) { Logger.Info("Loading name lists..."); - + var parser = new Parser(); parser.RegisterRegex(CommonRegexes.String, (reader, nameListId) => { NameListCollection.AddOrReplace(new NameList(nameListId, reader)); @@ -162,10 +162,10 @@ public void LoadNameLists(ModFilesystem ck3ModFS) { parser.IgnoreAndLogUnregisteredItems(); parser.ParseGameFolder("common/culture/name_lists", ck3ModFS, "txt", recursive: true, logFilePaths: true); } - + public void LoadInnovationIds(ModFilesystem ck3ModFS) { Logger.Info("Loading CK3 innovation IDs..."); - + var parser = new Parser(); parser.RegisterRegex(CommonRegexes.String, (reader, innovationId) => { InnovationIds.Add(innovationId); @@ -181,7 +181,7 @@ public void LoadInnovationIds(ModFilesystem ck3ModFS) { if (country.CountryType == CountryType.real) { Logger.Warn($"Failed to get primary or monarch culture for Imperator country {country.Tag}!"); } - + return null; } @@ -190,25 +190,25 @@ public void LoadInnovationIds(ModFilesystem ck3ModFS) { if (irProvinceId.HasValue) { ck3ProvinceId = provinceMapper.GetCK3ProvinceNumbers(irProvinceId.Value).FirstOrDefault(); } - + return cultureMapper.Match(irCulture, ck3ProvinceId, irProvinceId, country.HistoricalTag); } public void ImportTechnology(CountryCollection countries, CultureMapper cultureMapper, ProvinceMapper provinceMapper, InventionsDB inventionsDB, LocDB irLocDB) { // TODO: add tests for this Logger.Info("Converting Imperator inventions to CK3 innovations..."); - + var innovationMapper = new InnovationMapper(); innovationMapper.LoadLinksAndBonuses("configurables/inventions_to_innovations_map.txt"); innovationMapper.LogUnmappedInventions(inventionsDB, irLocDB); innovationMapper.RemoveMappingsWithInvalidInnovations(InnovationIds); - + // Group I:R countries by corresponding CK3 culture. var countriesByCulture = countries.Select(c => new { Country = c, CK3CultureId = GetCK3CultureIdForImperatorCountry(c, cultureMapper, provinceMapper), }) .Where(c => c.CK3CultureId is not null) .GroupBy(c => c.CK3CultureId); - + foreach (var grouping in countriesByCulture) { if (!TryGetValue(grouping.Key!, out var culture)) { Logger.Warn($"Can't import technology for culture {grouping.Key}: culture not found in CK3 cultures!"); @@ -223,11 +223,11 @@ public void LoadInnovationIds(ModFilesystem ck3ModFS) { } private readonly IDictionary cultureReplacements = new Dictionary(); // replaced culture -> replacing culture - + protected readonly PillarCollection PillarCollection; - protected readonly IdObjectCollection NameListCollection = new(); + protected readonly IdObjectCollection NameListCollection = []; protected readonly HashSet InnovationIds = []; - + private CultureData cultureData = new(); private readonly Parser cultureDataParser = new(); private readonly IgnoredKeywordsSet ignoredModFlags = [];