From a417dceca71024c4670f7bdb37cb89b26a006a01 Mon Sep 17 00:00:00 2001 From: IhateTrains Date: Wed, 10 Jul 2024 11:03:27 +0100 Subject: [PATCH] Fix dynamic empire adjective using unlocalized county adjective (#2065) #patch --- .../CK3/Characters/CK3CharacterTests.cs | 24 ++- .../Characters/CharacterCollectionTests.cs | 7 + .../CK3/Dynasties/DynastyTests.cs | 27 ++- .../CK3/Titles/LandedTitlesTests.cs | 9 +- .../CK3/Titles/RulerTermTests.cs | 2 + .../CK3/Titles/TitleTests.cs | 17 +- .../Mappers/TagTitle/TagTitleMapperTests.cs | 4 + .../Outputter/CoatOfArmsOutputterTests.cs | 3 + .../Outputter/DynastiesOutputterTests.cs | 8 +- .../TestHelpers/TestCK3LocDB.cs | 7 + ImperatorToCK3/CK3/CK3LocDB.cs | 197 ++++++++++++++++++ ImperatorToCK3/CK3/Characters/Character.cs | 49 ++--- .../CK3/Characters/CharacterCollection.cs | 9 +- ImperatorToCK3/CK3/Dynasties/Dynasty.cs | 22 +- .../CK3/Dynasties/DynastyCollection.cs | 10 +- ImperatorToCK3/CK3/Titles/LandedTitles.cs | 69 ++++-- ImperatorToCK3/CK3/Titles/RulerTerm.cs | 2 + ImperatorToCK3/CK3/Titles/Title.cs | 70 ++++--- ImperatorToCK3/CK3/World.cs | 17 +- ImperatorToCK3/Outputter/BookmarkOutputter.cs | 10 +- .../Outputter/LocalizationOutputter.cs | 172 ++------------- .../Outputter/ReligionsOutputter.cs | 6 +- ImperatorToCK3/Outputter/WorldOutputter.cs | 9 +- 23 files changed, 451 insertions(+), 299 deletions(-) create mode 100644 ImperatorToCK3.UnitTests/TestHelpers/TestCK3LocDB.cs create mode 100644 ImperatorToCK3/CK3/CK3LocDB.cs diff --git a/ImperatorToCK3.UnitTests/CK3/Characters/CK3CharacterTests.cs b/ImperatorToCK3.UnitTests/CK3/Characters/CK3CharacterTests.cs index 0107160ba..2555f68d0 100644 --- a/ImperatorToCK3.UnitTests/CK3/Characters/CK3CharacterTests.cs +++ b/ImperatorToCK3.UnitTests/CK3/Characters/CK3CharacterTests.cs @@ -4,6 +4,7 @@ using commonItems.Localization; using commonItems.Mods; using FluentAssertions; +using ImperatorToCK3.CK3; using ImperatorToCK3.CK3.Characters; using ImperatorToCK3.CK3.Cultures; using ImperatorToCK3.CK3.Dynasties; @@ -70,7 +71,8 @@ public class CK3CharacterBuilder { private CultureMapper cultureMapper = new(IRRegionMapper, new CK3RegionMapper(), cultures); private TraitMapper traitMapper = new("TestFiles/configurables/trait_map.txt", CK3ModFS); private NicknameMapper nicknameMapper = new("TestFiles/configurables/nickname_map.txt"); - private LocDB locDB = new("english"); + private LocDB irLocDB = new("english"); + private CK3LocDB ck3LocDB = new(CK3ModFS); private ProvinceMapper provinceMapper = new(); private DeathReasonMapper deathReasonMapper = new(); @@ -84,7 +86,8 @@ public Character Build() { cultureMapper, traitMapper, nicknameMapper, - locDB, + irLocDB, + ck3LocDB, irMapData, provinceMapper, deathReasonMapper, @@ -119,8 +122,12 @@ public CK3CharacterBuilder WithNicknameMapper(NicknameMapper nicknameMapper) { this.nicknameMapper = nicknameMapper; return this; } - public CK3CharacterBuilder WithLocDB(LocDB locDB) { - this.locDB = locDB; + public CK3CharacterBuilder WithIRLocDB(LocDB irLocDB) { + this.irLocDB = irLocDB; + return this; + } + public CK3CharacterBuilder WithCK3LocDB(CK3LocDB ck3LocDB) { + this.ck3LocDB = ck3LocDB; return this; } public CK3CharacterBuilder WithProvinceMapper(ProvinceMapper provinceMapper) { @@ -382,12 +389,15 @@ public void NameCanBeInitializedFromImperator() { var nameLocBlock = locDB.AddLocBlock("alexandros"); nameLocBlock["english"] = "Alexandros"; + var ck3LocDB = new TestCK3LocDB(); + var character = builder .WithImperatorCharacter(imperatorCharacter) - .WithLocDB(locDB) + .WithIRLocDB(locDB) + .WithCK3LocDB(ck3LocDB) .Build(); Assert.Equal("alexandros", character.GetName(ConversionDate)); - Assert.Equal("Alexandros", character.Localizations["alexandros"]["english"]); + Assert.Equal("Alexandros", ck3LocDB.GetLocBlockForKey("alexandros")!["english"]); } [Fact] @@ -502,7 +512,7 @@ public void DeadLandlessCharactersArePurgedIfChildless() { landedCharacter.Father = fatherOfLandedCharacter; childlessRelative.Father = fatherOfLandedCharacter; - var dynasty = new ImperatorToCK3.CK3.Dynasties.Dynasty(irFamily, irCharacters, new CulturesDB(), CultureMapper, new LocDB("english"), ConversionDate); + var dynasty = new ImperatorToCK3.CK3.Dynasties.Dynasty(irFamily, irCharacters, new CulturesDB(), CultureMapper, new LocDB("english"), new TestCK3LocDB(), ConversionDate); var dynasties = new DynastyCollection { dynasty }; Assert.Equal(dynasty.Id, landedCharacter.GetDynastyId(ConversionDate)); Assert.Equal(dynasty.Id, fatherOfLandedCharacter.GetDynastyId(ConversionDate)); diff --git a/ImperatorToCK3.UnitTests/CK3/Characters/CharacterCollectionTests.cs b/ImperatorToCK3.UnitTests/CK3/Characters/CharacterCollectionTests.cs index c95f867fe..62cdfec30 100644 --- a/ImperatorToCK3.UnitTests/CK3/Characters/CharacterCollectionTests.cs +++ b/ImperatorToCK3.UnitTests/CK3/Characters/CharacterCollectionTests.cs @@ -97,6 +97,7 @@ public void MarriageDateCanBeEstimatedFromChild() { new ProvinceMapper(), new DeathReasonMapper(), new DNAFactory(irModFS, ck3ModFS), + new TestCK3LocDB(), endDate, configuration); @@ -141,6 +142,7 @@ public void MarriageDateCanBeEstimatedFromUnbornChild() { new ProvinceMapper(), new DeathReasonMapper(), new DNAFactory(irModFS, ck3ModFS), + new TestCK3LocDB(), endDate, configuration); @@ -192,6 +194,7 @@ public void OnlyEarlyPregnanciesAreImportedFromImperator() { new ProvinceMapper(), new DeathReasonMapper(), new DNAFactory(irModFS, ck3ModFS), + new TestCK3LocDB(), conversionDate, configuration); @@ -297,6 +300,7 @@ public void ImperatorCountriesGoldCanBeDistributedAmongRulerAndVassals() { var traitMapper = new TraitMapper(); var nicknameMapper = new NicknameMapper(); var deathReasonMapper = new DeathReasonMapper(); + var ck3LocDB = new TestCK3LocDB(); // Import Imperator ruler and governors. var characters = new CharacterCollection(); @@ -310,6 +314,7 @@ public void ImperatorCountriesGoldCanBeDistributedAmongRulerAndVassals() { provinceMapper, deathReasonMapper, new DNAFactory(irModFS, ck3ModFS), + ck3LocDB, conversionDate, config); @@ -319,6 +324,7 @@ public void ImperatorCountriesGoldCanBeDistributedAmongRulerAndVassals() { Array.Empty(), tagTitleMapper, imperatorWorld.LocDB, + ck3LocDB, provinceMapper, coaMapper, new GovernmentMapper(ck3GovernmentIds: Array.Empty()), @@ -340,6 +346,7 @@ public void ImperatorCountriesGoldCanBeDistributedAmongRulerAndVassals() { provinces, tagTitleMapper, imperatorWorld.LocDB, + ck3LocDB, config, provinceMapper, definiteFormMapper, diff --git a/ImperatorToCK3.UnitTests/CK3/Dynasties/DynastyTests.cs b/ImperatorToCK3.UnitTests/CK3/Dynasties/DynastyTests.cs index 61ca5e217..c54650720 100644 --- a/ImperatorToCK3.UnitTests/CK3/Dynasties/DynastyTests.cs +++ b/ImperatorToCK3.UnitTests/CK3/Dynasties/DynastyTests.cs @@ -2,6 +2,7 @@ using commonItems.Colors; using commonItems.Localization; using commonItems.Mods; +using ImperatorToCK3.CK3; using ImperatorToCK3.CK3.Characters; using ImperatorToCK3.CK3.Dynasties; using ImperatorToCK3.CK3.Religions; @@ -82,6 +83,7 @@ public Character Build() { traitMapper, nicknameMapper, locDB, + new CK3LocDB(ck3ModFS), irMapData, provinceMapper, deathReasonMapper, @@ -140,8 +142,8 @@ public void IdAndNameAreProperlyConverted() { var reader = new BufferedReader(string.Empty); var family = Family.Parse(reader, 45); - var locMapper = new LocDB("english"); - var dynasty = new Dynasty(family, characters, new CulturesDB(), CultureMapper, locMapper, BookmarkDate); + var irLocDB = new LocDB("english"); + var dynasty = new Dynasty(family, characters, new CulturesDB(), CultureMapper, irLocDB, new TestCK3LocDB(), BookmarkDate); Assert.Equal("dynn_irtock3_45", dynasty.Id); Assert.Equal("dynn_irtock3_45", dynasty.Name); @@ -153,12 +155,14 @@ public void LocalizationIsConverted() { var reader = new BufferedReader("key = cornelii"); var family = Family.Parse(reader, 45); - var locDB = new LocDB("english"); - var dynLoc = locDB.AddLocBlock("cornelii"); + var irLocDB = new LocDB("english"); + var dynLoc = irLocDB.AddLocBlock("cornelii"); dynLoc["english"] = "Cornelii"; - var dynasty = new Dynasty(family, characters, new CulturesDB(), CultureMapper, locDB, BookmarkDate); + + var ck3LocDB = new TestCK3LocDB(); + var dynasty = new Dynasty(family, characters, new CulturesDB(), CultureMapper, irLocDB, ck3LocDB, BookmarkDate); - Assert.Equal("Cornelii", dynasty.LocalizedName!["english"]); + Assert.Equal("Cornelii", ck3LocDB.GetLocBlockForKey(dynasty.Id)!["english"]); } [Fact] @@ -167,10 +171,11 @@ public void LocalizationDefaultsToUnlocalizedKey() { var reader = new BufferedReader("key = cornelii"); var family = Family.Parse(reader, 45); - var locDB = new LocDB("english"); - var dynasty = new Dynasty(family, characters, new CulturesDB(), CultureMapper, locDB, BookmarkDate); + var irLocDB = new LocDB("english"); + var ck3LocDB = new TestCK3LocDB(); + var dynasty = new Dynasty(family, characters, new CulturesDB(), CultureMapper, irLocDB, ck3LocDB, BookmarkDate); - Assert.Equal("cornelii", dynasty.LocalizedName!["english"]); + Assert.Equal("cornelii", ck3LocDB.GetLocBlockForKey(dynasty.Id)!["english"]); } [Fact] public void CultureIsBasedOnFirstImperatorMember() { @@ -201,7 +206,7 @@ public void CultureIsBasedOnFirstImperatorMember() { new CK3RegionMapper(), Cultures ); - var locDB = new LocDB("english"); + var irLocDB = new LocDB("english"); var ck3Member1 = new CK3CharacterBuilder() .WithCultureMapper(cultureMapper) .WithImperatorCharacter(member1) @@ -214,7 +219,7 @@ public void CultureIsBasedOnFirstImperatorMember() { .WithCultureMapper(cultureMapper) .WithImperatorCharacter(member3) .Build(); - var dynasty = new Dynasty(family, characters, new CulturesDB(), cultureMapper, locDB, BookmarkDate); + var dynasty = new Dynasty(family, characters, new CulturesDB(), cultureMapper, irLocDB, new TestCK3LocDB(), BookmarkDate); Assert.Equal("latin", dynasty.CultureId); } diff --git a/ImperatorToCK3.UnitTests/CK3/Titles/LandedTitlesTests.cs b/ImperatorToCK3.UnitTests/CK3/Titles/LandedTitlesTests.cs index 7d6a28a00..c8d3f5e8d 100644 --- a/ImperatorToCK3.UnitTests/CK3/Titles/LandedTitlesTests.cs +++ b/ImperatorToCK3.UnitTests/CK3/Titles/LandedTitlesTests.cs @@ -269,7 +269,7 @@ public void GovernorshipsCanBeRecognizedAsCountyLevel() { var tagTitleMapper = new TagTitleMapper(); var provinceMapper = new ProvinceMapper(); provinceMapper.LoadMappings(provinceMappingsPath, "test_version"); - var locDB = new LocDB("english"); + var irLocDB = new LocDB("english"); var ck3Religions = new ReligionCollection(titles); var religionMapper = new ReligionMapper(ck3Religions, irRegionMapper, ck3RegionMapper); var cultureMapper = new CultureMapper(irRegionMapper, ck3RegionMapper, cultures); @@ -293,12 +293,15 @@ public void GovernorshipsCanBeRecognizedAsCountyLevel() { provinceMapper, deathReasonMapper, dnaFactory, + new TestCK3LocDB(), conversionDate, config ); + var ck3LocDB = new TestCK3LocDB(); + // Import country 589. - titles.ImportImperatorCountries(imperatorWorld.Countries, imperatorWorld.Dependencies, tagTitleMapper, locDB, provinceMapper, coaMapper, new GovernmentMapper(ck3GovernmentIds: Array.Empty()), new SuccessionLawMapper(), definiteFormMapper, religionMapper, cultureMapper, nicknameMapper, characters, conversionDate, config, new List>()); + titles.ImportImperatorCountries(imperatorWorld.Countries, imperatorWorld.Dependencies, tagTitleMapper, irLocDB, ck3LocDB, provinceMapper, coaMapper, new GovernmentMapper(ck3GovernmentIds: Array.Empty()), new SuccessionLawMapper(), definiteFormMapper, religionMapper, cultureMapper, nicknameMapper, characters, conversionDate, config, new List>()); Assert.Collection(titles, title => Assert.Equal("c_county1", title.Id), title => Assert.Equal("b_barony1", title.Id), @@ -312,7 +315,7 @@ public void GovernorshipsCanBeRecognizedAsCountyLevel() { var provinces = new ProvinceCollection(ck3ModFS); provinces.ImportImperatorProvinces(imperatorWorld, titles, cultureMapper, religionMapper, provinceMapper, conversionDate, config); // Country 589 is imported as duchy-level title, so its governorship of galatia_region will be county level. - titles.ImportImperatorGovernorships(imperatorWorld, provinces, tagTitleMapper, locDB, config, provinceMapper, definiteFormMapper, irRegionMapper, coaMapper, countyLevelGovernorships); + titles.ImportImperatorGovernorships(imperatorWorld, provinces, tagTitleMapper, irLocDB, ck3LocDB, config, provinceMapper, definiteFormMapper, irRegionMapper, coaMapper, countyLevelGovernorships); Assert.Collection(titles, title => Assert.Equal("c_county1", title.Id), diff --git a/ImperatorToCK3.UnitTests/CK3/Titles/RulerTermTests.cs b/ImperatorToCK3.UnitTests/CK3/Titles/RulerTermTests.cs index d90c5b969..c5423be08 100644 --- a/ImperatorToCK3.UnitTests/CK3/Titles/RulerTermTests.cs +++ b/ImperatorToCK3.UnitTests/CK3/Titles/RulerTermTests.cs @@ -57,6 +57,7 @@ public void ImperatorRulerTermIsCorrectlyConverted() { new ImperatorToCK3.CK3.Characters.CharacterCollection(), govMapper, new LocDB("english"), + new TestCK3LocDB(), new ReligionMapper(ck3Religions, irRegionMapper, ck3RegionMapper), new CultureMapper(irRegionMapper, ck3RegionMapper, new CultureCollection(new ColorFactory(), new PillarCollection(new ColorFactory(), []), [])), new NicknameMapper("TestFiles/configurables/nickname_map.txt"), @@ -98,6 +99,7 @@ public void PreImperatorTermIsCorrectlyConverted() { ck3Characters, govMapper, new LocDB("english"), + new TestCK3LocDB(), religionMapper, new CultureMapper(new BufferedReader("link = { ir=spartan ck3=greek }"), irRegionMapper, ck3RegionMapper, cultures), new NicknameMapper("TestFiles/configurables/nickname_map.txt"), diff --git a/ImperatorToCK3.UnitTests/CK3/Titles/TitleTests.cs b/ImperatorToCK3.UnitTests/CK3/Titles/TitleTests.cs index 9539351d3..1c9c73c16 100644 --- a/ImperatorToCK3.UnitTests/CK3/Titles/TitleTests.cs +++ b/ImperatorToCK3.UnitTests/CK3/Titles/TitleTests.cs @@ -24,6 +24,7 @@ using Xunit; using CharacterCollection = ImperatorToCK3.CK3.Characters.CharacterCollection; using ImperatorToCK3.Mappers.Region; +using ImperatorToCK3.UnitTests.TestHelpers; using System; using System.IO; @@ -77,6 +78,7 @@ public Title BuildFromTag() { dependency: null, imperatorCountries, locDB, + new TestCK3LocDB(), provinceMapper, coaMapper, tagTitleMapper, @@ -171,21 +173,6 @@ public void TitlePrimitivesCanBeLoaded() { Assert.Equal("c_roma", title.CapitalCountyId); } - [Fact] - public void LocalizationCanBeSet() { - var titles = new Title.LandedTitles(); - var title = titles.Add("k_testtitle"); - var nameLoc = title.Localizations.AddLocBlock(title.Id); - nameLoc["english"] = "engloc"; - nameLoc["french"] = "frloc"; - nameLoc["german"] = "germloc"; - nameLoc["russian"] = "rusloc"; - nameLoc["simp_chinese"] = "simploc"; - nameLoc["spanish"] = "spaloc"; - - Assert.Equal("engloc", title.Localizations.GetLocBlockForKey(title.Id)!["english"]); - } - [Fact] public void MembersDefaultToBlank() { var titles = new Title.LandedTitles(); diff --git a/ImperatorToCK3.UnitTests/Mappers/TagTitle/TagTitleMapperTests.cs b/ImperatorToCK3.UnitTests/Mappers/TagTitle/TagTitleMapperTests.cs index 8e11878f6..26a462da8 100644 --- a/ImperatorToCK3.UnitTests/Mappers/TagTitle/TagTitleMapperTests.cs +++ b/ImperatorToCK3.UnitTests/Mappers/TagTitle/TagTitleMapperTests.cs @@ -21,6 +21,7 @@ using ImperatorToCK3.Mappers.Religion; using ImperatorToCK3.Mappers.SuccessionLaw; using ImperatorToCK3.Mappers.TagTitle; +using ImperatorToCK3.UnitTests.TestHelpers; using System; using System.Collections.Generic; using System.IO; @@ -80,6 +81,7 @@ public void TitleCanBeMatchedFromGovernorship() { Array.Empty(), mapper, new LocDB("english"), + new TestCK3LocDB(), provMapper, new CoaMapper(), new GovernmentMapper(ck3GovernmentIds: Array.Empty()), @@ -154,6 +156,7 @@ public void TitleCanBeGeneratedFromGovernorship() { Array.Empty(), mapper, new LocDB("english"), + new TestCK3LocDB(), provMapper, new CoaMapper(), new GovernmentMapper(ck3GovernmentIds: Array.Empty()), @@ -247,6 +250,7 @@ public void GovernorshipCanBeRegistered() { Array.Empty(), mapper, new LocDB("english"), + new TestCK3LocDB(), provMapper, new CoaMapper(), new GovernmentMapper(ck3GovernmentIds: Array.Empty()), diff --git a/ImperatorToCK3.UnitTests/Outputter/CoatOfArmsOutputterTests.cs b/ImperatorToCK3.UnitTests/Outputter/CoatOfArmsOutputterTests.cs index 1958caeec..c546d3e3d 100644 --- a/ImperatorToCK3.UnitTests/Outputter/CoatOfArmsOutputterTests.cs +++ b/ImperatorToCK3.UnitTests/Outputter/CoatOfArmsOutputterTests.cs @@ -21,6 +21,7 @@ using ImperatorToCK3.Mappers.SuccessionLaw; using ImperatorToCK3.Mappers.TagTitle; using ImperatorToCK3.Outputter; +using ImperatorToCK3.UnitTests.TestHelpers; using System; using System.Collections.Generic; using System.IO; @@ -60,6 +61,7 @@ public async Task CoaIsOutputtedForCountryWithFlagSet() { Array.Empty(), new TagTitleMapper(), new LocDB("english"), + new TestCK3LocDB(), new ProvinceMapper(), new CoaMapper(irModFS), new GovernmentMapper(ck3GovernmentIds: Array.Empty()), @@ -105,6 +107,7 @@ public async Task CoaIsNotOutputtedForCountryWithoutFlagSet() { Array.Empty(), new TagTitleMapper(), new LocDB("english"), + new TestCK3LocDB(), new ProvinceMapper(), new CoaMapper(irModFS), new GovernmentMapper(ck3GovernmentIds: Array.Empty()), diff --git a/ImperatorToCK3.UnitTests/Outputter/DynastiesOutputterTests.cs b/ImperatorToCK3.UnitTests/Outputter/DynastiesOutputterTests.cs index 9aea7b0bd..f83c8cae6 100644 --- a/ImperatorToCK3.UnitTests/Outputter/DynastiesOutputterTests.cs +++ b/ImperatorToCK3.UnitTests/Outputter/DynastiesOutputterTests.cs @@ -12,6 +12,7 @@ using ImperatorToCK3.Mappers.Culture; using ImperatorToCK3.Mappers.Region; using ImperatorToCK3.Outputter; +using ImperatorToCK3.UnitTests.TestHelpers; using System; using System.IO; using System.Threading.Tasks; @@ -25,7 +26,8 @@ public class DynastiesOutputterTests { [Fact] public async Task DynastiesAreOutputted() { const string outputModPath = "output/outputMod"; - var locDB = new LocDB("english"); + var irLocDB = new LocDB("english"); + var ck3LocDB = new TestCK3LocDB(); const string imperatorRoot = "TestFiles/Imperator/root"; ModFilesystem irModFS = new(imperatorRoot, Array.Empty()); var irMapData = new MapData(irModFS); @@ -42,11 +44,11 @@ public async Task DynastiesAreOutputted() { var cultures = new CulturesDB(); var family1 = new Family(1); - var dynasty1 = new Dynasty(family1, characters, cultures, cultureMapper, locDB, ConversionDate); + var dynasty1 = new Dynasty(family1, characters, cultures, cultureMapper, irLocDB, ck3LocDB, ConversionDate); dynasties.Add(dynasty1); var family2 = new Family(2); - var dynasty2 = new Dynasty(family2, characters, cultures, cultureMapper, locDB, ConversionDate) { + var dynasty2 = new Dynasty(family2, characters, cultures, cultureMapper, irLocDB, ck3LocDB, ConversionDate) { CultureId = "roman" }; dynasties.Add(dynasty2); diff --git a/ImperatorToCK3.UnitTests/TestHelpers/TestCK3LocDB.cs b/ImperatorToCK3.UnitTests/TestHelpers/TestCK3LocDB.cs new file mode 100644 index 000000000..a0c880898 --- /dev/null +++ b/ImperatorToCK3.UnitTests/TestHelpers/TestCK3LocDB.cs @@ -0,0 +1,7 @@ +using ImperatorToCK3.CK3; + +namespace ImperatorToCK3.UnitTests.TestHelpers; + +public class TestCK3LocDB : CK3LocDB { + public TestCK3LocDB() { } +} \ No newline at end of file diff --git a/ImperatorToCK3/CK3/CK3LocDB.cs b/ImperatorToCK3/CK3/CK3LocDB.cs new file mode 100644 index 000000000..9b836b5a6 --- /dev/null +++ b/ImperatorToCK3/CK3/CK3LocDB.cs @@ -0,0 +1,197 @@ +using commonItems; +using commonItems.Localization; +using commonItems.Mods; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; + +namespace ImperatorToCK3.CK3; + +public class CK3LocDB : IEnumerable { + private LocDB ModFSLocDB { get; } = new LocDB(ConverterGlobals.PrimaryLanguage, ConverterGlobals.SecondaryLanguages); + private LocDB ConverterGeneratedLocDB { get; } = new LocDB(ConverterGlobals.PrimaryLanguage, ConverterGlobals.SecondaryLanguages); + private LocDB OptionalConverterLocDB { get; } = new LocDB(ConverterGlobals.PrimaryLanguage, ConverterGlobals.SecondaryLanguages); + + protected CK3LocDB() { } // Only for inheritance + + public CK3LocDB(ModFilesystem ck3ModFS) { + // Read loc from CK3 and selected CK3 mods. + ModFSLocDB.ScrapeLocalizations(ck3ModFS); + + // Read loc from ImperatorToCK3 congifurables. + // It will only be outputted for keys localized in neither ModFSLocDB nor ConverterGeneratedLocDB. + LoadOptionalLoc(); + } + + private void LoadOptionalLoc() { + const string optionalLocDir = "configurables/localization"; + if (!Directory.Exists(optionalLocDir)) { + Logger.Warn("Optional loc directory not found, skipping optional loc loading."); + return; + } + + var optionalLocFilePaths = Directory.GetFiles(optionalLocDir, "*.yml", SearchOption.AllDirectories); + foreach (var outputtedLocFilePath in optionalLocFilePaths) { + OptionalConverterLocDB.ScrapeFile(outputtedLocFilePath); + } + } + + private readonly object insertionLock = new(); + + public LocBlock AddLocBlock(string id) { + lock (insertionLock) { + return ConverterGeneratedLocDB.AddLocBlock(id); + } + } + + public bool ContainsKey(string key) { + if (ModFSLocDB.ContainsKey(key)) { + return true; + } + if (ConverterGeneratedLocDB.ContainsKey(key)) { + return true; + } + if (OptionalConverterLocDB.ContainsKey(key)) { + return true; + } + return false; + } + + public bool TryGetValue(string key, [MaybeNullWhen(false)] out LocBlock locBlock) { + if (ModFSLocDB.TryGetValue(key, out locBlock)) { + return true; + } + if (ConverterGeneratedLocDB.TryGetValue(key, out locBlock)) { + return true; + } + if (OptionalConverterLocDB.TryGetValue(key, out locBlock)) { + return true; + } + return false; + } + + public LocBlock? GetLocBlockForKey(string key) { + if (TryGetValue(key, out var locBlock)) { + return locBlock; + } + + return null; + } + + public bool HasKeyLocForLanguage(string key, string language) { + if (ModFSLocDB.ContainsKey(key) && ModFSLocDB[key].HasLocForLanguage(language)) { + return true; + } + if (ConverterGeneratedLocDB.ContainsKey(key) && ConverterGeneratedLocDB[key].HasLocForLanguage(language)) { + return true; + } + if (OptionalConverterLocDB.ContainsKey(key) && OptionalConverterLocDB[key].HasLocForLanguage(language)) { + return true; + } + return false; + } + + public void AddLocForLanguage(string key, string language, string loc) { + lock (insertionLock) { + ConverterGeneratedLocDB.AddLocForKeyAndLanguage(key, language, loc); + } + } + + public string? GetYmlLocLineForLanguage(string key, string language) { + if (ConverterGeneratedLocDB.TryGetValue(key, out var locBlock) && locBlock.HasLocForLanguage(language)) { + return locBlock.GetYmlLocLineForLanguage(language); + } + if (ModFSLocDB.TryGetValue(key, out locBlock) && locBlock.HasLocForLanguage(language)) { + return locBlock.GetYmlLocLineForLanguage(language); + } + if (OptionalConverterLocDB.TryGetValue(key, out locBlock) && locBlock.HasLocForLanguage(language)) { + return locBlock.GetYmlLocLineForLanguage(language); + } + + return null; + } + + IEnumerator IEnumerable.GetEnumerator() { + return GetEnumerator(); + } + + public IEnumerator GetEnumerator() { + var alreadyOutputtedLocKeys = new HashSet(); + + foreach (var locBlock in ModFSLocDB) { + yield return locBlock; + alreadyOutputtedLocKeys.Add(locBlock.Id); + } + + foreach (var locBlock in ConverterGeneratedLocDB) { + if (alreadyOutputtedLocKeys.Contains(locBlock.Id)) { + continue; + } + + yield return locBlock; + alreadyOutputtedLocKeys.Add(locBlock.Id); + } + + foreach (var locBlock in OptionalConverterLocDB) { + if (alreadyOutputtedLocKeys.Contains(locBlock.Id)) { + continue; + } + + yield return locBlock; + alreadyOutputtedLocKeys.Add(locBlock.Id); + } + } + + private HashSet GetAlreadyOutputtedLocKeysForLanguage(string language) { + var keysPerLanguage = new HashSet(); + + foreach (var locBlock in ModFSLocDB) { + if (locBlock.HasLocForLanguage(language)) { + keysPerLanguage.Add(locBlock.Id); + } + } + + return keysPerLanguage; + } + + public List GetLocLinesToOutputForLanguage(string language) { + var locLinesToOutput = new List(); + + var alreadyWrittenLocForLanguage = GetAlreadyOutputtedLocKeysForLanguage(language); + + foreach (var locBlock in ConverterGeneratedLocDB) { + if (!locBlock.HasLocForLanguage(language)) { + continue; + } + + var loc = locBlock[language]; + if (loc is null) { + continue; + } + + locLinesToOutput.Add(locBlock.GetYmlLocLineForLanguage(language)); + alreadyWrittenLocForLanguage.Add(locBlock.Id); + } + + foreach (var locBlock in OptionalConverterLocDB) { + if (alreadyWrittenLocForLanguage.Contains(locBlock.Id)) { + continue; + } + + if (!locBlock.HasLocForLanguage(language)) { + continue; + } + + var loc = locBlock[language]; + if (loc is null) { + continue; + } + + locLinesToOutput.Add(locBlock.GetYmlLocLineForLanguage(language)); + alreadyWrittenLocForLanguage.Add(locBlock.Id); + } + + return locLinesToOutput; + } +} \ No newline at end of file diff --git a/ImperatorToCK3/CK3/Characters/Character.cs b/ImperatorToCK3/CK3/Characters/Character.cs index cce52868f..0858cba2a 100644 --- a/ImperatorToCK3/CK3/Characters/Character.cs +++ b/ImperatorToCK3/CK3/Characters/Character.cs @@ -151,7 +151,6 @@ public string? DeathReason { public IDictionary MenAtArmsStacksPerType { get; } = new Dictionary(); public IDictionary PrisonerIds { get; } = new Dictionary(); // - public IDictionary Localizations { get; } = new Dictionary(); public DNA? DNA { get; private set; } @@ -234,6 +233,7 @@ public Character( Country imperatorCountry, CharacterCollection characters, LocDB irLocDB, + CK3LocDB ck3LocDB, ReligionMapper religionMapper, CultureMapper cultureMapper, NicknameMapper nicknameMapper, @@ -248,12 +248,11 @@ Configuration config SetName(name, null); if (!string.IsNullOrEmpty(name)) { var impNameLoc = irLocDB.GetLocBlockForKey(name); + LocBlock ck3NameLoc = ck3LocDB.AddLocBlock(name); if (impNameLoc is not null) { - Localizations.Add(name, impNameLoc); + ck3NameLoc.CopyFrom(impNameLoc); } else { // fallback: use unlocalized name as displayed name - Localizations.Add(name, new LocBlock(name, ConverterGlobals.PrimaryLanguage) { - [ConverterGlobals.PrimaryLanguage] = name, - }); + ck3NameLoc[ConverterGlobals.PrimaryLanguage] = name; } } @@ -308,6 +307,7 @@ public Character( TraitMapper traitMapper, NicknameMapper nicknameMapper, LocDB irLocDB, + CK3LocDB ck3LocDB, MapData irMapData, ProvinceMapper provinceMapper, // used to determine ck3 province for religion mapper DeathReasonMapper deathReasonMapper, @@ -328,25 +328,23 @@ ISet unlocalizedImperatorNames var locKey = CommonFunctions.NormalizeUTF8Path(loc.FoldToASCII().Replace(' ', '_')); var name = $"IRTOCK3_CUSTOM_NAME_{locKey}"; SetName(name, null); - - var locBlock = new LocBlock(name, ConverterGlobals.PrimaryLanguage) { - [ConverterGlobals.PrimaryLanguage] = loc - }; - Localizations.Add(name, locBlock); + + var ck3NameLocBlock = ck3LocDB.AddLocBlock(name); + foreach (var language in ConverterGlobals.SupportedLanguages) { + ck3NameLocBlock[language] = loc; + } } else { var nameLoc = ImperatorCharacter.Name; var name = nameLoc.Replace(' ', '_'); SetName(name, null); if (!string.IsNullOrEmpty(name)) { + var ck3NameLocBlock = ck3LocDB.AddLocBlock(name); var matchedLocBlock = irLocDB.GetLocBlockForKey(name); if (matchedLocBlock is not null) { - Localizations.Add(name, matchedLocBlock); + ck3NameLocBlock.CopyFrom(matchedLocBlock); } else { // fallback: use unlocalized name as displayed name unlocalizedImperatorNames.Add(name); - var locBlock = new LocBlock(name, ConverterGlobals.PrimaryLanguage) { - [ConverterGlobals.PrimaryLanguage] = nameLoc - }; - Localizations.Add(name, locBlock); + ck3NameLocBlock[ConverterGlobals.PrimaryLanguage] = nameLoc; } } } @@ -658,13 +656,12 @@ public void ImportUnitsAsMenAtArms( IEnumerable countryUnits, Date date, UnitTypeMapper unitTypeMapper, - IdObjectCollection menAtArmsTypes + IdObjectCollection menAtArmsTypes, + CK3LocDB ck3LocDB ) { var locKey = $"IRToCK3_character_{Id}"; - var locBlock = new LocBlock(locKey, ConverterGlobals.PrimaryLanguage) { - [ConverterGlobals.PrimaryLanguage] = $"[GetPlayer.MakeScope.Var('IRToCK3_character_{Id}').Char.GetID]" - }; - Localizations.Add(locKey, locBlock); + var locBlock = ck3LocDB.AddLocBlock(locKey); + locBlock[ConverterGlobals.PrimaryLanguage] = $"[GetPlayer.MakeScope.Var('IRToCK3_character_{Id}').Char.GetID]"; var menPerUnitType = new Dictionary(); foreach (var unit in countryUnits) { @@ -683,10 +680,8 @@ IdObjectCollection menAtArmsTypes menAtArmsTypes.Add(dedicatedType); MenAtArmsStacksPerType[dedicatedType.Id] = 1; - var maaTypeLocBlock = new LocBlock(dedicatedType.Id, ConverterGlobals.PrimaryLanguage) { - [ConverterGlobals.PrimaryLanguage] = $"${baseType.Id}$" - }; - Localizations.Add(dedicatedType.Id, maaTypeLocBlock); + var maaTypeLocBlock = ck3LocDB.AddLocBlock(dedicatedType.Id); + maaTypeLocBlock[ConverterGlobals.PrimaryLanguage] = $"${baseType.Id}$"; } var sb = new StringBuilder(); @@ -699,7 +694,8 @@ public void ImportUnitsAsSpecialTroops( Imperator.Characters.CharacterCollection imperatorCharacters, Date date, UnitTypeMapper unitTypeMapper, - ProvinceMapper provinceMapper + ProvinceMapper provinceMapper, + CK3LocDB ck3LocDB ) { var sb = new StringBuilder(); sb.AppendLine("{"); @@ -718,7 +714,8 @@ ProvinceMapper provinceMapper if (unit.LocalizedName is not null) { var locKey = unit.LocalizedName.Id; sb.AppendLine($"\t\t\tname={locKey}"); - Localizations[locKey] = unit.LocalizedName; + var unitLocBlock = ck3LocDB.AddLocBlock(locKey); + unitLocBlock.CopyFrom(unit.LocalizedName); } foreach (var (type, men) in menPerUnitType) { diff --git a/ImperatorToCK3/CK3/Characters/CharacterCollection.cs b/ImperatorToCK3/CK3/Characters/CharacterCollection.cs index 4c2ce1545..a8100cf1b 100644 --- a/ImperatorToCK3/CK3/Characters/CharacterCollection.cs +++ b/ImperatorToCK3/CK3/Characters/CharacterCollection.cs @@ -34,6 +34,7 @@ public void ImportImperatorCharacters( ProvinceMapper provinceMapper, DeathReasonMapper deathReasonMapper, DNAFactory dnaFactory, + CK3LocDB ck3LocDB, Date conversionDate, Configuration config ) { @@ -49,6 +50,7 @@ Configuration config traitMapper, nicknameMapper, impWorld.LocDB, + ck3LocDB, impWorld.MapData, provinceMapper, deathReasonMapper, @@ -85,6 +87,7 @@ private void ImportImperatorCharacter( TraitMapper traitMapper, NicknameMapper nicknameMapper, LocDB irLocDB, + CK3LocDB ck3LocDB, MapData irMapData, ProvinceMapper provinceMapper, DeathReasonMapper deathReasonMapper, @@ -101,6 +104,7 @@ private void ImportImperatorCharacter( traitMapper, nicknameMapper, irLocDB, + ck3LocDB, irMapData, provinceMapper, deathReasonMapper, @@ -586,6 +590,7 @@ public void ImportLegions( UnitTypeMapper unitTypeMapper, IdObjectCollection menAtArmsTypes, ProvinceMapper provinceMapper, + CK3LocDB ck3LocDB, Configuration config ) { Logger.Info("Importing Imperator armies..."); @@ -607,9 +612,9 @@ Configuration config var ruler = this[rulerId]; if (config.LegionConversion == LegionConversion.MenAtArms) { - ruler.ImportUnitsAsMenAtArms(countryLegions, date, unitTypeMapper, menAtArmsTypes); + ruler.ImportUnitsAsMenAtArms(countryLegions, date, unitTypeMapper, menAtArmsTypes, ck3LocDB); } else if (config.LegionConversion == LegionConversion.SpecialTroops) { - ruler.ImportUnitsAsSpecialTroops(countryLegions, imperatorCharacters, date, unitTypeMapper, provinceMapper); + ruler.ImportUnitsAsSpecialTroops(countryLegions, imperatorCharacters, date, unitTypeMapper, provinceMapper, ck3LocDB); } } diff --git a/ImperatorToCK3/CK3/Dynasties/Dynasty.cs b/ImperatorToCK3/CK3/Dynasties/Dynasty.cs index 19c81f1b9..9f1b0d4de 100644 --- a/ImperatorToCK3/CK3/Dynasties/Dynasty.cs +++ b/ImperatorToCK3/CK3/Dynasties/Dynasty.cs @@ -14,7 +14,7 @@ namespace ImperatorToCK3.CK3.Dynasties; [SerializationByProperties] public sealed partial class Dynasty : IPDXSerializable, IIdentifiable { - public Dynasty(Family irFamily, CharacterCollection irCharacters, CulturesDB irCulturesDB, CultureMapper cultureMapper, LocDB irLocDB, Date date) { + public Dynasty(Family irFamily, CharacterCollection irCharacters, CulturesDB irCulturesDB, CultureMapper cultureMapper, LocDB irLocDB, CK3LocDB ck3LocDB, Date date) { FromImperator = true; Id = $"dynn_irtock3_{irFamily.Id}"; Name = Id; @@ -31,10 +31,10 @@ public Dynasty(Family irFamily, CharacterCollection irCharacters, CulturesDB irC ck3Member?.SetDynastyId(Id, date: null); } - SetLocFromImperatorFamilyName(irFamily.GetMaleForm(irCulturesDB), irLocDB); + SetLocFromImperatorFamilyName(irFamily.GetMaleForm(irCulturesDB), irLocDB, ck3LocDB); } - public Dynasty(CK3.Characters.Character character, string irFamilyName, CulturesDB irCulturesDB, LocDB irLocDB, Date date) { + public Dynasty(CK3.Characters.Character character, string irFamilyName, CulturesDB irCulturesDB, LocDB irLocDB, CK3LocDB ck3LocDB, Date date) { FromImperator = true; Id = $"dynn_irtock3_from_{character.Id}"; Name = Id; @@ -46,7 +46,7 @@ public Dynasty(CK3.Characters.Character character, string irFamilyName, Cultures character.SetDynastyId(Id, null); - SetLocFromImperatorFamilyName(Family.GetMaleForm(irFamilyName, irCulturesDB), irLocDB); + SetLocFromImperatorFamilyName(Family.GetMaleForm(irFamilyName, irCulturesDB), irLocDB, ck3LocDB); } public Dynasty(string dynastyId, BufferedReader dynastyReader) { @@ -74,8 +74,6 @@ public Dynasty(string dynastyId, BufferedReader dynastyReader) { [SerializedName("culture")] public string? CultureId { get; set; } [SerializedName("motto")] public string? Motto { get; set; } [SerializedName("forced_coa_religiongroup")] public string? ForcedCoaReligionGroup { get; set; } - - [NonSerialized] public LocBlock? LocalizedName { get; private set; } [NonSerialized] public StringOfItem? CoA { get; set; } [NonSerialized] public bool FromImperator { get; private set; } = false; @@ -117,20 +115,20 @@ private void SetCultureFromImperator(Family irFamily, IReadOnlyList i Logger.Warn($"Couldn't determine culture for dynasty {Id}, needs manual setting!"); } - private void SetLocFromImperatorFamilyName(string irFamilyLocKey, LocDB irLocDB) { + private void SetLocFromImperatorFamilyName(string irFamilyLocKey, LocDB irLocDB, CK3LocDB ck3LocDB) { var irFamilyLoc = irLocDB.GetLocBlockForKey(irFamilyLocKey); + var ck3NameLoc = ck3LocDB.AddLocBlock(Name); if (irFamilyLoc is not null) { - LocalizedName = new LocBlock(Name, irFamilyLoc); - LocalizedName.ModifyForEveryLanguage(irFamilyLoc, (orig, other, lang) => { + ck3NameLoc.CopyFrom(irFamilyLoc); + ck3NameLoc.ModifyForEveryLanguage(irFamilyLoc, (orig, other, lang) => { if (!string.IsNullOrEmpty(orig)) { return orig; } return !string.IsNullOrEmpty(other) ? other : irFamilyLoc.Id; }); } else { // fallback: use unlocalized Imperator family key - LocalizedName = new LocBlock(Name, ConverterGlobals.PrimaryLanguage) { - [ConverterGlobals.PrimaryLanguage] = irFamilyLocKey - }; + Logger.Debug($"Dynasty {Id} has no localization for name \"{irFamilyLocKey}\"! Using unlocalized name."); + ck3NameLoc[ConverterGlobals.PrimaryLanguage] = irFamilyLocKey; } } } \ No newline at end of file diff --git a/ImperatorToCK3/CK3/Dynasties/DynastyCollection.cs b/ImperatorToCK3/CK3/Dynasties/DynastyCollection.cs index cfba37f21..d35e92391 100644 --- a/ImperatorToCK3/CK3/Dynasties/DynastyCollection.cs +++ b/ImperatorToCK3/CK3/Dynasties/DynastyCollection.cs @@ -13,7 +13,7 @@ namespace ImperatorToCK3.CK3.Dynasties; public sealed class DynastyCollection : ConcurrentIdObjectCollection { - public void ImportImperatorFamilies(Imperator.World irWorld, CultureMapper cultureMapper, LocDB irLocDB, Date date) { + public void ImportImperatorFamilies(Imperator.World irWorld, CultureMapper cultureMapper, LocDB irLocDB, CK3LocDB ck3LocDB, Date date) { Logger.Info("Importing Imperator families..."); var imperatorCharacters = irWorld.Characters; @@ -24,13 +24,13 @@ public void ImportImperatorFamilies(Imperator.World irWorld, CultureMapper cultu return; } - var newDynasty = new Dynasty(family, imperatorCharacters, irWorld.CulturesDB, cultureMapper, irLocDB, date); + var newDynasty = new Dynasty(family, imperatorCharacters, irWorld.CulturesDB, cultureMapper, irLocDB, ck3LocDB, date); AddOrReplace(newDynasty); Interlocked.Increment(ref importedCount); }); Logger.Info($"{importedCount} total families imported."); - CreateDynastiesForCharactersFromMinorFamilies(irWorld, irLocDB, date); + CreateDynastiesForCharactersFromMinorFamilies(irWorld, irLocDB, ck3LocDB, date); Logger.IncrementProgress(); } @@ -47,7 +47,7 @@ public void LoadCK3Dynasties(ModFilesystem ck3ModFS) { parser.ParseGameFolder("common/dynasties", ck3ModFS, "txt", recursive: true, parallel: true); } - private void CreateDynastiesForCharactersFromMinorFamilies(Imperator.World irWorld, LocDB irLocDB, Date date) { + private void CreateDynastiesForCharactersFromMinorFamilies(Imperator.World irWorld, LocDB irLocDB, CK3LocDB ck3LocDB, Date date) { Logger.Info("Creating dynasties for characters from minor families..."); var relevantImperatorCharacters = irWorld.Characters @@ -77,7 +77,7 @@ private void CreateDynastiesForCharactersFromMinorFamilies(Imperator.World irWor } // Neither character nor their father have a dynasty, so we need to create a new one. - var newDynasty = new Dynasty(ck3Character, irFamilyName, irWorld.CulturesDB, irLocDB, date); + var newDynasty = new Dynasty(ck3Character, irFamilyName, irWorld.CulturesDB, irLocDB, ck3LocDB, date); Add(newDynasty); ++createdDynastiesCount; } diff --git a/ImperatorToCK3/CK3/Titles/LandedTitles.cs b/ImperatorToCK3/CK3/Titles/LandedTitles.cs index c5f070cc1..049cc2183 100644 --- a/ImperatorToCK3/CK3/Titles/LandedTitles.cs +++ b/ImperatorToCK3/CK3/Titles/LandedTitles.cs @@ -39,14 +39,34 @@ public sealed partial class Title { // Since titles are nested according to hierarchy we do this recursively. public sealed class LandedTitles : TitleCollection { public Dictionary Variables { get; } = []; + + public IEnumerable Counties => this.Where(t => t.Rank == TitleRank.county); - public void LoadTitles(ModFilesystem ck3ModFS) { + public void LoadTitles(ModFilesystem ck3ModFS, CK3LocDB ck3LocDB) { Logger.Info("Loading landed titles..."); var parser = new Parser(); RegisterKeys(parser); parser.ParseGameFolder("common/landed_titles", ck3ModFS, "txt", recursive: true, logFilePaths: true); LogIgnoredTokens(); + + // Make sure every county has an adjective. + foreach (var county in Counties) { + string adjLocKey = county.Id + "_adj"; + + // Use the name loc as the adjective loc. + var nameLoc = ck3LocDB.GetLocBlockForKey(county.Id); + if (nameLoc is null) { + continue; + } + foreach (var language in ConverterGlobals.SupportedLanguages) { + if (ck3LocDB.HasKeyLocForLanguage(adjLocKey, language)) { + continue; + } + + ck3LocDB.AddLocForLanguage(adjLocKey, language, nameLoc[language] ?? nameLoc[ConverterGlobals.PrimaryLanguage] ?? county.Id); + } + } Logger.IncrementProgress(); } @@ -128,6 +148,7 @@ public Title Add( Dependency? dependency, CountryCollection imperatorCountries, LocDB irLocDB, + CK3LocDB ck3LocDB, ProvinceMapper provinceMapper, CoaMapper coaMapper, TagTitleMapper tagTitleMapper, @@ -146,6 +167,7 @@ Configuration config dependency, imperatorCountries, irLocDB, + ck3LocDB, provinceMapper, coaMapper, tagTitleMapper, @@ -172,6 +194,7 @@ public Title Add( bool regionHasMultipleGovernorships, bool staticDeJure, LocDB irLocDB, + CK3LocDB ck3LocDB, ProvinceMapper provinceMapper, CoaMapper coaMapper, DefiniteFormMapper definiteFormMapper, @@ -186,6 +209,7 @@ ImperatorRegionMapper imperatorRegionMapper regionHasMultipleGovernorships, staticDeJure, irLocDB, + ck3LocDB, provinceMapper, coaMapper, definiteFormMapper, @@ -239,6 +263,7 @@ public void ImportImperatorCountries( IReadOnlyCollection<Dependency> dependencies, TagTitleMapper tagTitleMapper, LocDB irLocDB, + CK3LocDB ck3LocDB, ProvinceMapper provinceMapper, CoaMapper coaMapper, GovernmentMapper governmentMapper, @@ -272,6 +297,7 @@ public void ImportImperatorCountries( imperatorCountries, tagTitleMapper, irLocDB, + ck3LocDB, provinceMapper, coaMapper, governmentMapper, @@ -294,6 +320,7 @@ public void ImportImperatorCountries( imperatorCountries, tagTitleMapper, irLocDB, + ck3LocDB, provinceMapper, coaMapper, governmentMapper, @@ -318,6 +345,7 @@ private void ImportImperatorCountry( CountryCollection imperatorCountries, TagTitleMapper tagTitleMapper, LocDB irLocDB, + CK3LocDB ck3LocDB, ProvinceMapper provinceMapper, CoaMapper coaMapper, GovernmentMapper governmentMapper, @@ -345,6 +373,7 @@ private void ImportImperatorCountry( dependency, imperatorCountries, irLocDB, + ck3LocDB, provinceMapper, coaMapper, governmentMapper, @@ -363,6 +392,7 @@ private void ImportImperatorCountry( dependency, imperatorCountries, irLocDB, + ck3LocDB, provinceMapper, coaMapper, tagTitleMapper, @@ -384,6 +414,7 @@ public void ImportImperatorGovernorships( ProvinceCollection ck3Provinces, TagTitleMapper tagTitleMapper, LocDB irLocDB, + CK3LocDB ck3LocDB, Configuration config, ProvinceMapper provinceMapper, DefiniteFormMapper definiteFormMapper, @@ -411,6 +442,7 @@ List<Governorship> countyLevelGovernorships config.StaticDeJure, tagTitleMapper, irLocDB, + ck3LocDB, provinceMapper, definiteFormMapper, imperatorRegionMapper, @@ -432,6 +464,7 @@ private void ImportImperatorGovernorship( bool staticDeJure, TagTitleMapper tagTitleMapper, LocDB irLocDB, + CK3LocDB ck3LocDB, ProvinceMapper provinceMapper, DefiniteFormMapper definiteFormMapper, ImperatorRegionMapper imperatorRegionMapper, @@ -461,6 +494,7 @@ List<Governorship> countyLevelGovernorships regionHasMultipleGovernorships, staticDeJure, irLocDB, + ck3LocDB, provinceMapper, definiteFormMapper, imperatorRegionMapper @@ -475,6 +509,7 @@ List<Governorship> countyLevelGovernorships regionHasMultipleGovernorships, staticDeJure, irLocDB, + ck3LocDB, provinceMapper, coaMapper, definiteFormMapper, @@ -614,7 +649,7 @@ public void RemoveInvalidLandlessTitles(Date ck3BookmarkDate) { Logger.IncrementProgress(); } - private void SetDeJureKingdoms(Date ck3BookmarkDate) { + private void SetDeJureKingdoms(CK3LocDB ck3LocDB, Date ck3BookmarkDate) { Logger.Info("Setting de jure kingdoms..."); var duchies = this.Where(t => t.Rank == TitleRank.duchy).ToHashSet(); @@ -630,12 +665,12 @@ private void SetDeJureKingdoms(Date ck3BookmarkDate) { kingdom.Color1 = duchy.Color1; kingdom.CapitalCounty = duchy.CapitalCounty; - var kingdomNameLoc = kingdom.Localizations.AddLocBlock(kingdom.Id); + var kingdomNameLoc = ck3LocDB.AddLocBlock(kingdom.Id); kingdomNameLoc.ModifyForEveryLanguage( (orig, language) => $"${duchy.Id}$" ); - var kingdomAdjLoc = kingdom.Localizations.AddLocBlock(kingdom.Id + "_adj"); + var kingdomAdjLoc = ck3LocDB.AddLocBlock(kingdom.Id + "_adj"); kingdomAdjLoc.ModifyForEveryLanguage( (orig, language) => $"${duchy.Id}_adj$" ); @@ -679,7 +714,7 @@ private void SetDeJureKingdoms(Date ck3BookmarkDate) { Logger.IncrementProgress(); } - private void SetDeJureEmpires(CultureCollection ck3Cultures, CharacterCollection ck3Characters, MapData ck3MapData, Date ck3BookmarkDate) { + private void SetDeJureEmpires(CultureCollection ck3Cultures, CharacterCollection ck3Characters, MapData ck3MapData, CK3LocDB ck3LocDB, Date ck3BookmarkDate) { Logger.Info("Setting de jure empires..."); var deJureKingdoms = GetDeJureKingdoms(); @@ -719,7 +754,7 @@ private void SetDeJureEmpires(CultureCollection ck3Cultures, CharacterCollection var removableEmpireIds = new HashSet<string>(); var kingdomToDominantHeritagesDict = new Dictionary<string, ImmutableArray<Pillar>>(); var heritageToEmpireDict = GetHeritageIdToExistingTitleDict(); - CreateEmpiresBasedOnDominantHeritages(deJureKingdoms, ck3Cultures, ck3Characters, removableEmpireIds, kingdomToDominantHeritagesDict, heritageToEmpireDict, ck3BookmarkDate); + CreateEmpiresBasedOnDominantHeritages(deJureKingdoms, ck3Cultures, ck3Characters, removableEmpireIds, kingdomToDominantHeritagesDict, heritageToEmpireDict, ck3LocDB, ck3BookmarkDate); Logger.Debug("Building kingdom adjacencies dict..."); // Create a cache of province IDs per kingdom. @@ -734,7 +769,7 @@ private void SetDeJureEmpires(CultureCollection ck3Cultures, CharacterCollection FindKingdomsAdjacentToKingdom(ck3MapData, deJureKingdoms, kingdom.Id, provincesPerKingdomDict, kingdomAdjacenciesByLand, kingdomAdjacenciesByWaterBody); }); - SplitDisconnectedEmpires(kingdomAdjacenciesByLand, kingdomAdjacenciesByWaterBody, removableEmpireIds, kingdomToDominantHeritagesDict, heritageToEmpireDict, ck3BookmarkDate); + SplitDisconnectedEmpires(kingdomAdjacenciesByLand, kingdomAdjacenciesByWaterBody, removableEmpireIds, kingdomToDominantHeritagesDict, heritageToEmpireDict, ck3LocDB, ck3BookmarkDate); SetEmpireCapitals(ck3BookmarkDate); } @@ -746,6 +781,7 @@ private void CreateEmpiresBasedOnDominantHeritages( HashSet<string> removableEmpireIds, IDictionary<string, ImmutableArray<Pillar>> kingdomToDominantHeritagesDict, Dictionary<string, Title> heritageToEmpireDict, + CK3LocDB ck3LocDB, Date ck3BookmarkDate ) { var kingdomsWithoutEmpire = deJureKingdoms @@ -782,7 +818,7 @@ Date ck3BookmarkDate kingdom.DeJureLiege = empire; } else { // Create new de jure empire based on heritage. - var heritageEmpire = CreateEmpireForHeritage(dominantHeritage, ck3Cultures); + var heritageEmpire = CreateEmpireForHeritage(dominantHeritage, ck3Cultures, ck3LocDB); removableEmpireIds.Add(heritageEmpire.Id); kingdom.DeJureLiege = heritageEmpire; @@ -839,12 +875,12 @@ private Dictionary<string, Title> GetHeritageIdToExistingTitleDict() { return heritageToEmpireDict; } - private Title CreateEmpireForHeritage(Pillar heritage, CultureCollection ck3Cultures) { + private Title CreateEmpireForHeritage(Pillar heritage, CultureCollection ck3Cultures, CK3LocDB ck3LocDB) { var newEmpireId = $"e_IRTOCK3_heritage_{heritage.Id}"; var newEmpire = Add(newEmpireId); - var nameLocBlock = newEmpire.Localizations.AddLocBlock(newEmpire.Id); + var nameLocBlock = ck3LocDB.AddLocBlock(newEmpire.Id); nameLocBlock[ConverterGlobals.PrimaryLanguage] = $"${heritage.Id}_name$ Empire"; - var adjectiveLocBlock = newEmpire.Localizations.AddLocBlock($"{newEmpire.Id}_adj"); + var adjectiveLocBlock = ck3LocDB.AddLocBlock($"{newEmpire.Id}_adj"); adjectiveLocBlock[ConverterGlobals.PrimaryLanguage] = $"${heritage.Id}_name$"; newEmpire.HasDefiniteForm = true; @@ -861,6 +897,7 @@ private void SplitDisconnectedEmpires( HashSet<string> removableEmpireIds, Dictionary<string, ImmutableArray<Pillar>> kingdomToDominantHeritagesDict, Dictionary<string, Title> heritageToEmpireDict, + CK3LocDB ck3LocDB, Date date ) { Logger.Debug("Splitting disconnected empires..."); @@ -969,12 +1006,12 @@ Date date newEmpire.CapitalCounty = mostDevelopedCounty; newEmpire.HasDefiniteForm = false; - var empireNameLoc = newEmpire.Localizations.AddLocBlock(newEmpireId); + var empireNameLoc = ck3LocDB.AddLocBlock(newEmpireId); empireNameLoc.ModifyForEveryLanguage( (orig, language) => $"${mostDevelopedCounty.Id}$" ); - var empireAdjLoc = newEmpire.Localizations.AddLocBlock(newEmpireId + "_adj"); + var empireAdjLoc = ck3LocDB.AddLocBlock(newEmpireId + "_adj"); empireAdjLoc.ModifyForEveryLanguage( (orig, language) => $"${mostDevelopedCounty.Id}_adj$" ); @@ -1097,9 +1134,9 @@ private void SetEmpireCapitals(Date ck3BookmarkDate) { } } - public void SetDeJureKingdomsAndEmpires(Date ck3BookmarkDate, CultureCollection ck3Cultures, CharacterCollection ck3Characters, MapData ck3MapData) { - SetDeJureKingdoms(ck3BookmarkDate); - SetDeJureEmpires(ck3Cultures, ck3Characters, ck3MapData, ck3BookmarkDate); + public void SetDeJureKingdomsAndEmpires(Date ck3BookmarkDate, CultureCollection ck3Cultures, CharacterCollection ck3Characters, MapData ck3MapData, CK3LocDB ck3LocDB) { + SetDeJureKingdoms(ck3LocDB, ck3BookmarkDate); + SetDeJureEmpires(ck3Cultures, ck3Characters, ck3MapData, ck3LocDB, ck3BookmarkDate); } private HashSet<string> GetCountyHolderIds(Date date) { diff --git a/ImperatorToCK3/CK3/Titles/RulerTerm.cs b/ImperatorToCK3/CK3/Titles/RulerTerm.cs index ebc0ce954..f9b547f2b 100644 --- a/ImperatorToCK3/CK3/Titles/RulerTerm.cs +++ b/ImperatorToCK3/CK3/Titles/RulerTerm.cs @@ -20,6 +20,7 @@ public RulerTerm( Characters.CharacterCollection characters, GovernmentMapper governmentMapper, LocDB irLocDB, + CK3LocDB ck3LocDB, ReligionMapper religionMapper, CultureMapper cultureMapper, NicknameMapper nicknameMapper, @@ -49,6 +50,7 @@ Configuration config PreImperatorRuler.Country, characters, irLocDB, + ck3LocDB, religionMapper, cultureMapper, nicknameMapper, diff --git a/ImperatorToCK3/CK3/Titles/Title.cs b/ImperatorToCK3/CK3/Titles/Title.cs index a08bb754c..501814ff2 100644 --- a/ImperatorToCK3/CK3/Titles/Title.cs +++ b/ImperatorToCK3/CK3/Titles/Title.cs @@ -49,6 +49,7 @@ private Title(LandedTitles parentCollection, Dependency? dependency, CountryCollection imperatorCountries, LocDB irLocDB, + CK3LocDB ck3LocDB, ProvinceMapper provinceMapper, CoaMapper coaMapper, TagTitleMapper tagTitleMapper, @@ -71,6 +72,7 @@ Configuration config dependency, imperatorCountries, irLocDB, + ck3LocDB, provinceMapper, coaMapper, governmentMapper, @@ -93,6 +95,7 @@ private Title(LandedTitles parentCollection, bool regionHasMultipleGovernorships, bool staticDeJure, LocDB irLocDB, + CK3LocDB ck3LocDB, ProvinceMapper provinceMapper, CoaMapper coaMapper, DefiniteFormMapper definiteFormMapper, @@ -110,6 +113,7 @@ ImperatorRegionMapper imperatorRegionMapper regionHasMultipleGovernorships, staticDeJure, irLocDB, + ck3LocDB, provinceMapper, definiteFormMapper, imperatorRegionMapper @@ -136,7 +140,6 @@ private Title(Title? baseTitle, Title overrideTitle, LandedTitles parentCollecti CoA = baseTitle.CoA; CapitalCounty = baseTitle.CapitalCounty; - Localizations = baseTitle.Localizations; AIPrimaryPriority = baseTitle.AIPrimaryPriority; RulerUsesTitleName = baseTitle.RulerUsesTitleName; @@ -173,6 +176,7 @@ public void InitializeFromTag( Dependency? dependency, CountryCollection imperatorCountries, LocDB irLocDB, + CK3LocDB ck3LocDB, ProvinceMapper provinceMapper, CoaMapper coaMapper, GovernmentMapper governmentMapper, @@ -197,7 +201,7 @@ Configuration config ClearHolderSpecificHistory(); - FillHolderAndGovernmentHistory(country, characters, governmentMapper, irLocDB, religionMapper, cultureMapper, nicknameMapper, provinceMapper, config, conversionDate); + FillHolderAndGovernmentHistory(country, characters, governmentMapper, irLocDB, ck3LocDB, religionMapper, cultureMapper, nicknameMapper, provinceMapper, config, conversionDate); // Determine color. var color1Opt = ImperatorCountry.Color1; @@ -240,14 +244,14 @@ Configuration config // determine country name localization var nameSet = false; if (validatedName is not null) { - var nameLocBlock = Localizations.AddLocBlock(Id); + var nameLocBlock = ck3LocDB.AddLocBlock(Id); nameLocBlock.CopyFrom(validatedName); nameSet = true; } if (!nameSet) { var irTagLoc = irLocDB.GetLocBlockForKey(ImperatorCountry.Tag); if (irTagLoc is not null) { - var nameLocBlock = Localizations.AddLocBlock(Id); + var nameLocBlock = ck3LocDB.AddLocBlock(Id); nameLocBlock.CopyFrom(irTagLoc); nameSet = true; } @@ -257,7 +261,7 @@ Configuration config var name = ImperatorCountry.Name; if (!string.IsNullOrEmpty(name)) { Logger.Warn($"Using unlocalized Imperator name {name} as name for {Id}!"); - var nameLocBlock = Localizations.AddLocBlock(Id); + var nameLocBlock = ck3LocDB.AddLocBlock(Id); nameLocBlock[ConverterGlobals.PrimaryLanguage] = name; nameSet = true; } @@ -268,7 +272,7 @@ Configuration config } // determine adjective localization - TrySetAdjectiveLoc(irLocDB, imperatorCountries); + TrySetAdjectiveLoc(irLocDB, imperatorCountries, ck3LocDB); // If country is a subject, convert it to a vassal. if (dependency is not null) { @@ -288,6 +292,7 @@ private void FillHolderAndGovernmentHistory(Country imperatorCountry, CharacterCollection characters, GovernmentMapper governmentMapper, LocDB irLocDB, + CK3LocDB ck3LocDB, ReligionMapper religionMapper, CultureMapper cultureMapper, NicknameMapper nicknameMapper, @@ -302,6 +307,7 @@ private void FillHolderAndGovernmentHistory(Country imperatorCountry, characters, governmentMapper, irLocDB, + ck3LocDB, religionMapper, cultureMapper, nicknameMapper, @@ -449,6 +455,7 @@ public void InitializeFromGovernorship( bool regionHasMultipleGovernorships, bool staticDeJure, LocDB irLocDB, + CK3LocDB ck3LocDB, ProvinceMapper provinceMapper, DefiniteFormMapper definiteFormMapper, ImperatorRegionMapper imperatorRegionMapper @@ -516,21 +523,21 @@ ImperatorRegionMapper imperatorRegionMapper } } - TrySetNameFromGovernorship(governorship, imperatorRegionMapper, country, irProvinces, regionHasMultipleGovernorships, irLocDB); - TrySetAdjectiveFromGovernorship(governorship, country, irLocDB); + TrySetNameFromGovernorship(governorship, imperatorRegionMapper, country, irProvinces, regionHasMultipleGovernorships, irLocDB, ck3LocDB); + TrySetAdjectiveFromGovernorship(governorship, country, irLocDB, ck3LocDB); } - private void TrySetAdjectiveFromGovernorship(Governorship governorship, Country country, LocDB irLocDB) { + private void TrySetAdjectiveFromGovernorship(Governorship governorship, Country country, LocDB irLocDB, CK3LocDB ck3LocDB) { var adjKey = $"{Id}_adj"; - if (Localizations.ContainsKey(adjKey)) { + if (ck3LocDB.ContainsKey(adjKey)) { return; } var adjSet = false; // Try to generate adjective from name. - var nameLocBlock = Localizations.GetLocBlockForKey(Id) ?? irLocDB.GetLocBlockForKey(governorship.Region.Id); + var nameLocBlock = ck3LocDB.GetLocBlockForKey(Id) ?? irLocDB.GetLocBlockForKey(governorship.Region.Id); if (!adjSet && nameLocBlock is not null) { - var adjLocBlock = Localizations.AddLocBlock(adjKey); + var adjLocBlock = ck3LocDB.AddLocBlock(adjKey); adjLocBlock.CopyFrom(nameLocBlock); var englishLoc = adjLocBlock["english"]; @@ -546,8 +553,8 @@ private void TrySetAdjectiveFromGovernorship(Governorship governorship, Country if (ck3Country is null) { return; } - if (ck3Country.Localizations.TryGetValue($"{ck3Country.Id}_adj", out var countryAdjectiveLocBlock)) { - var adjLocBlock = Localizations.AddLocBlock(adjKey); + if (ck3LocDB.TryGetValue($"{ck3Country.Id}_adj", out var countryAdjectiveLocBlock)) { + var adjLocBlock = ck3LocDB.AddLocBlock(adjKey); adjLocBlock.CopyFrom(countryAdjectiveLocBlock); adjSet = true; } @@ -564,9 +571,10 @@ private void TrySetNameFromGovernorship( Country country, Imperator.Provinces.ProvinceCollection irProvinces, bool regionHasMultipleGovernorships, - LocDB irLocDB + LocDB irLocDB, + CK3LocDB ck3LocDB ) { - if (Localizations.ContainsKey(Id)) { + if (ck3LocDB.ContainsKey(Id)) { return; } @@ -597,11 +605,11 @@ LocDB irLocDB if (potentialSourceArea is not null && irLocDB.TryGetValue(potentialSourceArea.Id, out var areaLocBlock)) { Logger.Debug($"Naming {Id} after I:R area {potentialSourceArea.Id} majorly ({biggestOwnershipPercentage:P}) controlled by {country.Tag}..."); - var nameLocBlock = Localizations.AddLocBlock(Id); + var nameLocBlock = ck3LocDB.AddLocBlock(Id); nameLocBlock.CopyFrom(areaLocBlock); nameSet = true; - var adjLocBlock = Localizations.AddLocBlock($"{Id}_adj"); + var adjLocBlock = ck3LocDB.AddLocBlock($"{Id}_adj"); adjLocBlock.CopyFrom(nameLocBlock); adjLocBlock.ModifyForEveryLanguage((loc, language) => language == "english" ? loc?.GetAdjective() : loc); } @@ -613,11 +621,11 @@ LocDB irLocDB .MaxBy(p => p.CivilizationValue); if (sourceProvince is not null && irLocDB.TryGetValue(sourceProvince.Name, out var provinceLocBlock)) { Logger.Debug($"Naming {Id} after most developed I:R territory: {sourceProvince.Id}..."); - var nameLocBlock = Localizations.AddLocBlock(Id); + var nameLocBlock = ck3LocDB.AddLocBlock(Id); nameLocBlock.CopyFrom(provinceLocBlock); nameSet = true; - var adjLocBlock = Localizations.AddLocBlock($"{Id}_adj"); + var adjLocBlock = ck3LocDB.AddLocBlock($"{Id}_adj"); adjLocBlock.CopyFrom(nameLocBlock); adjLocBlock.ModifyForEveryLanguage((loc, language) => language == "english" ? loc?.GetAdjective() : loc); } @@ -626,9 +634,9 @@ LocDB irLocDB // Example: Mauretania -> Roman Mauretania if (!nameSet && regionHasMultipleGovernorships && regionLocBlock is not null) { var ck3Country = country.CK3Title; - if (ck3Country is not null && ck3Country.Localizations.TryGetValue($"{ck3Country.Id}_adj", out var countryAdjectiveLocBlock)) { + if (ck3Country is not null && ck3LocDB.TryGetValue($"{ck3Country.Id}_adj", out var countryAdjectiveLocBlock)) { Logger.Debug($"Naming {Id} after governorship with country adjective: {country.Tag} {governorship.Region.Id}..."); - var nameLocBlock = Localizations.AddLocBlock(Id); + var nameLocBlock = ck3LocDB.AddLocBlock(Id); nameLocBlock.CopyFrom(regionLocBlock); nameLocBlock.ModifyForEveryLanguage(countryAdjectiveLocBlock, (orig, adj, _) => $"{adj} {orig}" @@ -638,7 +646,7 @@ LocDB irLocDB } if (!nameSet && regionLocBlock is not null) { Logger.Debug($"Naming {Id} after governorship: {governorship.Region.Id}..."); - var nameLocBlock = Localizations.AddLocBlock(Id); + var nameLocBlock = ck3LocDB.AddLocBlock(Id); nameLocBlock.CopyFrom(regionLocBlock); nameSet = true; } @@ -704,9 +712,7 @@ public void SetDevelopmentLevel(int value, Date date) { History.AddFieldValue(date, "development_level", "change_development_level", value); } - [commonItems.Serialization.NonSerialized] public LocDB Localizations { get; } = new(ConverterGlobals.PrimaryLanguage, ConverterGlobals.SecondaryLanguages); - - private void TrySetAdjectiveLoc(LocDB irLocDB, CountryCollection imperatorCountries) { + private void TrySetAdjectiveLoc(LocDB irLocDB, CountryCollection imperatorCountries, CK3LocDB ck3LocDB) { if (ImperatorCountry is null) { Logger.Warn($"Cannot set adjective for CK3 title {Id} from null Imperator country!"); return; @@ -778,7 +784,7 @@ private void TrySetAdjectiveLoc(LocDB irLocDB, CountryCollection imperatorCountr } if (validatedAdj is not null) { - var adjLocBlock = Localizations.AddLocBlock(locKey); + var adjLocBlock = ck3LocDB.AddLocBlock(locKey); adjLocBlock.CopyFrom(validatedAdj); adjSet = true; } @@ -786,7 +792,7 @@ private void TrySetAdjectiveLoc(LocDB irLocDB, CountryCollection imperatorCountr if (!adjSet) { var adjOpt = ImperatorCountry.CountryName.GetAdjectiveLocBlock(irLocDB, imperatorCountries); if (adjOpt is not null) { - var adjLocBlock = Localizations.AddLocBlock(locKey); + var adjLocBlock = ck3LocDB.AddLocBlock(locKey); adjLocBlock.CopyFrom(adjOpt); adjSet = true; } @@ -794,7 +800,7 @@ private void TrySetAdjectiveLoc(LocDB irLocDB, CountryCollection imperatorCountr if (!adjSet) { var adjLocalizationMatch = irLocDB.GetLocBlockForKey(ImperatorCountry.Tag); if (adjLocalizationMatch is not null) { - var adjLocBlock = Localizations.AddLocBlock(locKey); + var adjLocBlock = ck3LocDB.AddLocBlock(locKey); adjLocBlock.CopyFrom(adjLocalizationMatch); adjSet = true; } @@ -802,14 +808,14 @@ private void TrySetAdjectiveLoc(LocDB irLocDB, CountryCollection imperatorCountr // Try to generate English adjective from country name. if (!adjSet) { - if (Localizations.TryGetValue(Id, out var nameLocBlock) && nameLocBlock["english"] is string name) { + if (ck3LocDB.TryGetValue(Id, out var nameLocBlock) && nameLocBlock["english"] is {} name) { // If name has 3 characters and last 2 characters are digits, it's probably a raw Imperator tag. // In that case, we don't want to use it as a base for adjective. if (!(name.Length == 3 && char.IsDigit(name[1]) && char.IsDigit(name[2]))) { var generatedAdjective = name.GetAdjective(); Logger.Debug($"Generated adjective for country \"{name}\": \"{generatedAdjective}\""); - var adjLocBlock = Localizations.AddLocBlock(locKey); + var adjLocBlock = ck3LocDB.AddLocBlock(locKey); adjLocBlock["english"] = generatedAdjective; adjSet = true; } @@ -821,7 +827,7 @@ private void TrySetAdjectiveLoc(LocDB irLocDB, CountryCollection imperatorCountr var name = ImperatorCountry.Name; if (!string.IsNullOrEmpty(name)) { Logger.Warn($"Using unlocalized Imperator name {name} as adjective for {Id}!"); - var adjLocBlock = Localizations.AddLocBlock(locKey); + var adjLocBlock = ck3LocDB.AddLocBlock(locKey); adjLocBlock[ConverterGlobals.PrimaryLanguage] = name; adjSet = true; } diff --git a/ImperatorToCK3/CK3/World.cs b/ImperatorToCK3/CK3/World.cs index 83848c0ae..774998037 100644 --- a/ImperatorToCK3/CK3/World.cs +++ b/ImperatorToCK3/CK3/World.cs @@ -41,6 +41,7 @@ namespace ImperatorToCK3.CK3; public sealed class World { public OrderedSet<Mod> LoadedMods { get; } public ModFilesystem ModFS { get; } + public CK3LocDB LocDB { get; } private ScriptValueCollection ScriptValues { get; } = new(); public NamedColorCollection NamedColors { get; } = new(); public CharacterCollection Characters { get; } = new(); @@ -101,6 +102,8 @@ public World(Imperator.World impWorld, Configuration config) { // Include a fake mod pointing to blankMod. LoadedMods.Add(new Mod("blankMod", "blankMod/output")); ModFS = new ModFilesystem(Path.Combine(config.CK3Path, "game"), LoadedMods); + // Now that we have the mod filesystem, we can initialize the localization database. + LocDB = new(ModFS); Logger.IncrementProgress(); ScriptValues.LoadScriptValues(ModFS); @@ -128,7 +131,7 @@ public World(Imperator.World impWorld, Configuration config) { MapData = new MapData(ModFS); // Load vanilla CK3 landed titles and their history - LandedTitles.LoadTitles(ModFS); + LandedTitles.LoadTitles(ModFS, LocDB); if (config.StaticDeJure) { Logger.Info("Setting static de jure kingdoms and empires..."); @@ -196,13 +199,14 @@ public World(Imperator.World impWorld, Configuration config) { provinceMapper, deathReasonMapper, dnaFactory, + LocDB, CorrectedDate, config ); ClearFeaturedCharactersDescriptions(config.CK3BookmarkDate); Dynasties.LoadCK3Dynasties(ModFS); - Dynasties.ImportImperatorFamilies(impWorld, cultureMapper, impWorld.LocDB, CorrectedDate); + Dynasties.ImportImperatorFamilies(impWorld, cultureMapper, impWorld.LocDB, LocDB, CorrectedDate); DynastyHouses.LoadCK3Houses(ModFS); // Load existing CK3 government IDs. @@ -224,6 +228,7 @@ public World(Imperator.World impWorld, Configuration config) { impWorld.Dependencies, tagTitleMapper, impWorld.LocDB, + LocDB, provinceMapper, impWorld.CoaMapper, governmentMapper, @@ -252,6 +257,7 @@ public World(Imperator.World impWorld, Configuration config) { Provinces, tagTitleMapper, impWorld.LocDB, + LocDB, config, provinceMapper, definiteFormMapper, @@ -274,13 +280,13 @@ public World(Imperator.World impWorld, Configuration config) { GenerateFillerHoldersForUnownedLands(Cultures, config); Logger.IncrementProgress(); if (!config.StaticDeJure) { - LandedTitles.SetDeJureKingdomsAndEmpires(config.CK3BookmarkDate, Cultures, Characters, MapData); + LandedTitles.SetDeJureKingdomsAndEmpires(config.CK3BookmarkDate, Cultures, Characters, MapData, LocDB); } Dynasties.SetCoasForRulingDynasties(LandedTitles, config.CK3BookmarkDate); Characters.DistributeCountriesGold(LandedTitles, config); - Characters.ImportLegions(LandedTitles, impWorld.Units, impWorld.Characters, CorrectedDate, unitTypeMapper, MenAtArmsTypes, provinceMapper, config); + Characters.ImportLegions(LandedTitles, impWorld.Units, impWorld.Characters, CorrectedDate, unitTypeMapper, MenAtArmsTypes, provinceMapper, LocDB, config); Characters.RemoveEmployerIdFromLandedCharacters(LandedTitles, CorrectedDate); Characters.PurgeUnneededCharacters(LandedTitles, Dynasties, DynastyHouses, config.CK3BookmarkDate); @@ -367,7 +373,8 @@ private void ClearFeaturedCharactersDescriptions(Date ck3BookmarkDate) { } var holderId = title.GetHolderId(ck3BookmarkDate); if (holderId != "0" && Characters.TryGetValue(holderId, out var holder)) { - title.Localizations.AddLocBlock($"{holder.GetName(ck3BookmarkDate)}_desc"); + var locBlock = LocDB.AddLocBlock($"{holder.GetName(ck3BookmarkDate)}_desc"); + locBlock.ModifyForEveryLanguage((loc, language) => string.Empty); } } } diff --git a/ImperatorToCK3/Outputter/BookmarkOutputter.cs b/ImperatorToCK3/Outputter/BookmarkOutputter.cs index 068a945f4..0a5eca902 100644 --- a/ImperatorToCK3/Outputter/BookmarkOutputter.cs +++ b/ImperatorToCK3/Outputter/BookmarkOutputter.cs @@ -20,7 +20,7 @@ namespace ImperatorToCK3.Outputter; public static class BookmarkOutputter { - public static async Task OutputBookmark(World world, Configuration config, LocDB ck3LocDB) { + public static async Task OutputBookmark(World world, Configuration config, CK3LocDB ck3LocDB) { Logger.Info("Creating bookmark..."); await OutputBookmarkGroup(config); @@ -68,7 +68,7 @@ private static async Task AddTitleToBookmarkScreen( StringBuilder sb, string holderId, World world, - LocDB ck3LocDB, + CK3LocDB ck3LocDB, IReadOnlyDictionary<ulong, ProvincePosition> provincePositions, Configuration config ) { @@ -76,7 +76,11 @@ Configuration config // Add character localization for bookmark screen. var holderLoc = ck3LocDB.AddLocBlock($"bm_converted_{holder.Id}"); - holderLoc.CopyFrom(holder.Localizations[holder.GetName(config.CK3BookmarkDate)!]); + if (holder.GetName(config.CK3BookmarkDate) is {} holderName) { + if (ck3LocDB.TryGetValue(holderName, out var holderNameLoc)) { + holderLoc.CopyFrom(holderNameLoc); + } + } var holderDescLoc = ck3LocDB.AddLocBlock($"bm_converted_{holder.Id}_desc"); foreach (var language in ConverterGlobals.SupportedLanguages) { holderDescLoc[language] = string.Empty; diff --git a/ImperatorToCK3/Outputter/LocalizationOutputter.cs b/ImperatorToCK3/Outputter/LocalizationOutputter.cs index 9b6429872..881ddd3c1 100644 --- a/ImperatorToCK3/Outputter/LocalizationOutputter.cs +++ b/ImperatorToCK3/Outputter/LocalizationOutputter.cs @@ -1,48 +1,28 @@ using commonItems; -using commonItems.Localization; -using commonItems.Mods; using ImperatorToCK3.CK3; using ImperatorToCK3.CommonUtils; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text; namespace ImperatorToCK3.Outputter; public static class LocalizationOutputter { - public static void OutputLocalization(string outputModPath, World ck3World, LocDB locToOutputDB) { + public static void OutputLocalization(string outputModPath, World ck3World) { Logger.Info("Writing Localization..."); var baseLocDir = Path.Join(outputModPath, "localization"); var baseReplaceLocDir = Path.Join(baseLocDir, "replace"); var sb = new StringBuilder(); foreach (var language in ConverterGlobals.SupportedLanguages) { - sb.AppendLine($"l_{language}:"); - - foreach (var locBlock in locToOutputDB) { - if (!locBlock.HasLocForLanguage(language)) { - continue; - } - sb.AppendLine(locBlock.GetYmlLocLineForLanguage(language)); - } - - // title localization - foreach (var title in ck3World.LandedTitles) { - foreach (var locBlock in title.Localizations) { - sb.AppendLine(locBlock.GetYmlLocLineForLanguage(language)); - } + var locLinesForLanguage = ck3World.LocDB.GetLocLinesToOutputForLanguage(language); + if (locLinesForLanguage.Count == 0) { + continue; } - - // character name localization - var uniqueKeys = new HashSet<string>(); - foreach (var character in ck3World.Characters) { - foreach (var (key, locBlock) in character.Localizations) { - if (uniqueKeys.Contains(key)) { - continue; - } - - sb.AppendLine(locBlock.GetYmlLocLineForLanguage(language)); - uniqueKeys.Add(key); - } + + sb.AppendLine($"l_{language}:"); + foreach (var line in locLinesForLanguage) { + sb.AppendLine(line); } var locFilePath = Path.Join(baseReplaceLocDir, language, $"converter_l_{language}.yml"); @@ -50,147 +30,39 @@ public static void OutputLocalization(string outputModPath, World ck3World, LocD locWriter.WriteLine(sb.ToString()); sb.Clear(); } - - // dynasty localization - foreach (var language in ConverterGlobals.SupportedLanguages) { - sb.AppendLine($"l_{language}:"); - - foreach (var dynasty in ck3World.Dynasties) { - var localizedName = dynasty.LocalizedName; - if (localizedName is not null) { - sb.AppendLine(localizedName.GetYmlLocLineForLanguage(language)); - } else if (dynasty.FromImperator) { - Logger.Warn($"Dynasty {dynasty.Id} has no localizations!"); - sb.AppendLine($" {dynasty.Name}: \"{dynasty.Name}\""); - } - } - - var dynastyLocFilePath = Path.Combine(baseLocDir, $"{language}/irtock3_dynasty_l_{language}.yml"); - using var dynastyLocWriter = FileOpeningHelper.OpenWriteWithRetries(dynastyLocFilePath, Encoding.UTF8); - dynastyLocWriter.Write(sb.ToString()); - sb.Clear(); - } - var alreadyWrittenLocDB = GetLocDBOfAlreadyWrittenLoc(baseLocDir, ck3World.ModFS); - - OutputOptionalLocFromConfigurables(baseLocDir, alreadyWrittenLocDB); - OutputFallbackLocForMissingSecondaryLanguageLoc(baseLocDir, alreadyWrittenLocDB); + OutputFallbackLocForMissingSecondaryLanguageLoc(baseLocDir, ck3World.LocDB); Logger.IncrementProgress(); } - private static LocDB GetLocDBOfAlreadyWrittenLoc(string baseLocDir, ModFilesystem ck3ModFS) { - // Read loc from CK3 and selected CK3 mods. - var ck3LocDB = new LocDB(ConverterGlobals.PrimaryLanguage, ConverterGlobals.SecondaryLanguages); - ck3LocDB.ScrapeLocalizations(ck3ModFS); - - // Also read already outputted loc from the output directory. - var locFilesInOutputDir = Directory.GetFiles(baseLocDir, "*.yml", SearchOption.AllDirectories); - foreach (var outputtedLocFilePath in locFilesInOutputDir) { - ck3LocDB.ScrapeFile(outputtedLocFilePath); - } - - return ck3LocDB; - } - - private static Dictionary<string, HashSet<string>> GetDictOfLocPerLanguage(LocDB locDB) { - var keysPerLanguage = new Dictionary<string, HashSet<string>>(); - foreach (var language in ConverterGlobals.SupportedLanguages) { - keysPerLanguage[language] = []; - } - - foreach (var locBlock in locDB) { - foreach (var language in ConverterGlobals.SupportedLanguages) { - if (locBlock.HasLocForLanguage(language)) { - keysPerLanguage[language].Add(locBlock.Id); - } - } - } - - return keysPerLanguage; - } - - private static void OutputOptionalLocFromConfigurables(string baseLocDir, LocDB alreadyWrittenLocDB) { - string optionalLocDir = "configurables/localization"; - if (!Directory.Exists(optionalLocDir)) { - Logger.Warn("Optional loc directory not found, skipping optional loc output."); - return; - } - Logger.Debug("Outputting optional loc..."); - var optionalLocDB = new LocDB(ConverterGlobals.PrimaryLanguage, ConverterGlobals.SecondaryLanguages); - var optionalLocFilePaths = Directory.GetFiles(optionalLocDir, "*.yml", SearchOption.AllDirectories); - foreach (var outputtedLocFilePath in optionalLocFilePaths) { - optionalLocDB.ScrapeFile(outputtedLocFilePath); - } - - var alreadyWrittenLocPerLanguage = GetDictOfLocPerLanguage(alreadyWrittenLocDB); - - foreach (var language in ConverterGlobals.SupportedLanguages) { - var alreadyWrittenLocForLanguage = alreadyWrittenLocPerLanguage[language]; - - var optionalLocLinesToOutput = new List<string>(); - - foreach (var locBlock in optionalLocDB) { - if (alreadyWrittenLocForLanguage.Contains(locBlock.Id)) { - continue; - } - - if (!locBlock.HasLocForLanguage(language)) { - continue; - } - - var loc = locBlock[language]; - if (loc is null) { - continue; - } - - optionalLocLinesToOutput.Add(locBlock.GetYmlLocLineForLanguage(language)); - alreadyWrittenLocDB.AddLocForKeyAndLanguage(locBlock.Id, language, loc); - } - - if (optionalLocLinesToOutput.Count == 0) { - continue; - } - - Logger.Debug($"Outputting {optionalLocLinesToOutput.Count} optional loc lines for {language}..."); - var sb = new StringBuilder(); - sb.AppendLine($"l_{language}:"); - foreach (var line in optionalLocLinesToOutput) { - sb.AppendLine(line); - } - - var locFilePath = Path.Combine(baseLocDir, $"{language}/irtock3_optional_loc_l_{language}.yml"); - using var locWriter = FileOpeningHelper.OpenWriteWithRetries(locFilePath, Encoding.UTF8); - locWriter.Write(sb.ToString()); - } - } - - private static void OutputFallbackLocForMissingSecondaryLanguageLoc(string baseLocDir, LocDB ck3LocDB) { + private static void OutputFallbackLocForMissingSecondaryLanguageLoc(string baseLocDir, CK3LocDB ck3LocDB) { Logger.Debug("Outputting fallback loc for missing secondary language loc..."); - var primaryLanguage = ConverterGlobals.PrimaryLanguage; - var secondaryLanguages = ConverterGlobals.SecondaryLanguages; var languageToLocLinesDict = new Dictionary<string, List<string>>(); - foreach (var language in secondaryLanguages) { + foreach (var language in ConverterGlobals.SecondaryLanguages) { languageToLocLinesDict[language] = []; } + + var allLocKeys = ck3LocDB.Select(locBlock => locBlock.Id).ToHashSet(); - foreach (var locBlock in ck3LocDB) { - if (!locBlock.HasLocForLanguage(primaryLanguage)) { + foreach (var locKey in allLocKeys) { + if (!ck3LocDB.HasKeyLocForLanguage(locKey, ConverterGlobals.PrimaryLanguage)) { continue; } - foreach (var secondaryLanguage in secondaryLanguages) { - if (locBlock.HasLocForLanguage(secondaryLanguage)) { + foreach (var secondaryLanguage in ConverterGlobals.SecondaryLanguages) { + if (ck3LocDB.HasKeyLocForLanguage(locKey, secondaryLanguage)) { continue; } - - languageToLocLinesDict[secondaryLanguage].Add(locBlock.GetYmlLocLineForLanguage(primaryLanguage)); + + var locLine = ck3LocDB.GetYmlLocLineForLanguage(locKey, ConverterGlobals.PrimaryLanguage); + languageToLocLinesDict[secondaryLanguage].Add(locLine!); } } var sb = new StringBuilder(); - foreach (var language in secondaryLanguages) { + foreach (var language in ConverterGlobals.SecondaryLanguages) { var linesToOutput = languageToLocLinesDict[language]; if (linesToOutput.Count == 0) { continue; diff --git a/ImperatorToCK3/Outputter/ReligionsOutputter.cs b/ImperatorToCK3/Outputter/ReligionsOutputter.cs index 3d1ef181a..68c646b7e 100644 --- a/ImperatorToCK3/Outputter/ReligionsOutputter.cs +++ b/ImperatorToCK3/Outputter/ReligionsOutputter.cs @@ -1,6 +1,6 @@ using commonItems; -using commonItems.Localization; using commonItems.Serialization; +using ImperatorToCK3.CK3; using ImperatorToCK3.CK3.Religions; using ImperatorToCK3.CommonUtils; using System.IO; @@ -11,7 +11,7 @@ namespace ImperatorToCK3.Outputter; public static class ReligionsOutputter { - public static async Task OutputReligionsAndHolySites(string outputModPath, ReligionCollection ck3ReligionCollection, LocDB ck3LocDB) { + public static async Task OutputReligionsAndHolySites(string outputModPath, ReligionCollection ck3ReligionCollection, CK3LocDB ck3LocDB) { await Task.WhenAll( OutputHolySites(outputModPath, ck3ReligionCollection, ck3LocDB), OutputReligions(outputModPath, ck3ReligionCollection) @@ -19,7 +19,7 @@ await Task.WhenAll( Logger.IncrementProgress(); } - private static async Task OutputHolySites(string outputModPath, ReligionCollection ck3ReligionCollection, LocDB ck3LocDB) { + private static async Task OutputHolySites(string outputModPath, ReligionCollection ck3ReligionCollection, CK3LocDB ck3LocDB) { Logger.Info("Writing holy sites..."); var sitesToOutput = ck3ReligionCollection.HolySites.Where(s => s.IsGeneratedByConverter) diff --git a/ImperatorToCK3/Outputter/WorldOutputter.cs b/ImperatorToCK3/Outputter/WorldOutputter.cs index 6d6f361f7..dec832063 100644 --- a/ImperatorToCK3/Outputter/WorldOutputter.cs +++ b/ImperatorToCK3/Outputter/WorldOutputter.cs @@ -1,6 +1,5 @@ using commonItems; using commonItems.Collections; -using commonItems.Localization; using commonItems.Mods; using commonItems.Serialization; using ImperatorToCK3.CK3; @@ -26,8 +25,6 @@ public static void OutputWorld(World ck3World, Imperator.World imperatorWorld, C CreateFolders(outputPath); CopyBlankModFilesToOutput(outputPath); - - var ck3LocToOutputDB = new LocDB(ConverterGlobals.PrimaryLanguage, ConverterGlobals.SecondaryLanguages); Task.WaitAll( CharactersOutputter.OutputEverything(outputPath, ck3World.Characters, ck3World.CorrectedDate, ck3World.ModFS), @@ -39,7 +36,7 @@ public static void OutputWorld(World ck3World, Imperator.World imperatorWorld, C PillarOutputter.OutputPillars(outputPath, ck3World.CulturalPillars), CulturesOutputter.OutputCultures(outputPath, ck3World.Cultures, ck3World.CorrectedDate), - ReligionsOutputter.OutputReligionsAndHolySites(outputPath, ck3World.Religions, ck3LocToOutputDB), + ReligionsOutputter.OutputReligionsAndHolySites(outputPath, ck3World.Religions, ck3World.LocDB), WarsOutputter.OutputWars(outputPath, ck3World.Wars), @@ -56,7 +53,7 @@ public static void OutputWorld(World ck3World, Imperator.World imperatorWorld, C CoatOfArmsOutputter.OutputCoas(outputPath, ck3World.LandedTitles, ck3World.Dynasties), Task.Run(() => CoatOfArmsOutputter.CopyCoaPatterns(imperatorWorld.ModFS, outputPath)), - BookmarkOutputter.OutputBookmark(ck3World, config, ck3LocToOutputDB) + BookmarkOutputter.OutputBookmark(ck3World, config, ck3World.LocDB) ); if (config.LegionConversion == LegionConversion.MenAtArms) { @@ -64,7 +61,7 @@ public static void OutputWorld(World ck3World, Imperator.World imperatorWorld, C } // Localization should be output last, as it uses data written by other outputters. - LocalizationOutputter.OutputLocalization(outputPath, ck3World, ck3LocToOutputDB); + LocalizationOutputter.OutputLocalization(outputPath, ck3World); OutputPlaysetInfo(ck3World, outputName); }