Skip to content

Commit 97e0e1b

Browse files
authored
Fix for TFE conversion crashes (#2533) #patch
closes #2202
1 parent 72a7fb9 commit 97e0e1b

23 files changed

+804
-135
lines changed

ImperatorToCK3.UnitTests/CK3/Cultures/CultureCollectionTests.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ static CultureCollectionTests() {
2727
public void ColorIsLoadedIfDefinedOrGeneratedIfMissing() {
2828
var cultures = new CultureCollection(colorFactory, pillars, ck3ModFlags);
2929
cultures.LoadNameLists(ck3ModFS);
30-
cultures.LoadCultures(ck3ModFS);
30+
cultures.LoadCultures(ck3ModFS, new Configuration());
3131

3232
var cultureWithColor = cultures["culture_with_color"];
3333
Assert.Equal(new Color(10, 20, 30), cultureWithColor.Color);
@@ -52,7 +52,7 @@ public void ConverterHeritageCanBeMergedIntoExistingHeritage() {
5252

5353
cultures.AddNameList(new NameList("name_list_albanian", new BufferedReader()));
5454
cultures.LoadConverterPillars("TestFiles/CK3/CultureCollectionTests/configurables/converter_pillars", ck3ModFlags);
55-
cultures.LoadConverterCultures("TestFiles/CK3/CultureCollectionTests/configurables/converter_cultures.txt");
55+
cultures.LoadConverterCultures("TestFiles/CK3/CultureCollectionTests/configurables/converter_cultures.txt", new Configuration());
5656

5757
Assert.Equal(2, cultures.Count);
5858
Assert.Equal("heritage_arberian", cultures["arberian"].Heritage.Id);
@@ -72,7 +72,7 @@ public void ConverterLanguageCanBeMergedIntoExistingLanguage() {
7272

7373
cultures.AddNameList(new NameList("name_list_albanian", new BufferedReader()));
7474
cultures.LoadConverterPillars("TestFiles/CK3/CultureCollectionTests/configurables/converter_pillars", ck3ModFlags);
75-
cultures.LoadConverterCultures("TestFiles/CK3/CultureCollectionTests/configurables/converter_cultures.txt");
75+
cultures.LoadConverterCultures("TestFiles/CK3/CultureCollectionTests/configurables/converter_cultures.txt", new Configuration());
7676

7777
Assert.Equal(2, cultures.Count);
7878
Assert.Equal("language_illyrian", cultures["albanian"].Language.Id);

ImperatorToCK3/CK3/Characters/CharactersLoader.cs

+10
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,16 @@ public void LoadCK3Characters(ModFilesystem ck3ModFS, Date bookmarkDate) {
9393
character.History.Fields["effects"].RemoveAllEntries(
9494
entry => irrelevantEffects.Any(effect => entry.ToString()?.Contains(effect) ?? false));
9595

96+
// Fix characters being set as their own fathers/mothers.
97+
if (character.FatherId == character.Id) {
98+
Logger.Warn($"Character {character.Id} is set as their own father! Fixing.");
99+
character.Father = null;
100+
}
101+
if (character.MotherId == character.Id) {
102+
Logger.Warn($"Character {character.Id} is set as their own mother! Fixing.");
103+
character.Mother = null;
104+
}
105+
96106
character.InitSpousesCache();
97107
character.InitConcubinesCache();
98108
character.UpdateChildrenCacheOfParents();

ImperatorToCK3/CK3/Cultures/Culture.cs

+6-6
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,15 @@ public string Serialize(string indent, bool withBraces) {
5858
sb.AppendLine("{");
5959
}
6060

61-
sb.Append(contentIndent).AppendLine($"color={Color.OutputRgb()}");
61+
sb.Append(contentIndent).AppendLine($"color = {Color.OutputRgb()}");
6262
if (ParentCultureIds.Count != 0) {
63-
sb.Append(contentIndent).AppendLine($"parents={PDXSerializer.Serialize(ParentCultureIds)}");
63+
sb.Append(contentIndent).AppendLine($"parents = {PDXSerializer.Serialize(ParentCultureIds)}");
6464
}
65-
sb.Append(contentIndent).AppendLine($"heritage={Heritage.Id}");
66-
sb.Append(contentIndent).AppendLine($"language={Language.Id}");
67-
sb.Append(contentIndent).AppendLine($"traditions={PDXSerializer.Serialize(TraditionIds)}");
65+
sb.Append(contentIndent).AppendLine($"heritage = {Heritage.Id}");
66+
sb.Append(contentIndent).AppendLine($"language = {Language.Id}");
67+
sb.Append(contentIndent).AppendLine($"traditions = {PDXSerializer.Serialize(TraditionIds)}");
6868
foreach (var nameList in NameLists) {
69-
sb.Append(contentIndent).AppendLine($"name_list={nameList.Id}");
69+
sb.Append(contentIndent).AppendLine($"name_list = {nameList.Id}");
7070
}
7171
sb.AppendLine(PDXSerializer.Serialize(Attributes, indent: contentIndent, withBraces: false));
7272

ImperatorToCK3/CK3/Cultures/CultureCollection.cs

+45-7
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ private void LoadInvalidatingCultureIds(OrderedDictionary<string, bool> ck3ModFl
9191
cultureIdsPerModFlagParser.ParseStream(reader);
9292
}
9393

94-
public void LoadCultures(ModFilesystem ck3ModFS) {
94+
public void LoadCultures(ModFilesystem ck3ModFS, Configuration config) {
9595
Logger.Info("Loading cultures...");
9696

9797
OrderedDictionary<string, CultureData> culturesData = new(); // Preserves order of insertion.
@@ -102,12 +102,12 @@ public void LoadCultures(ModFilesystem ck3ModFS) {
102102
parser.ParseGameFolder("common/culture/cultures", ck3ModFS, "txt", recursive: true, logFilePaths: true);
103103

104104
// After we've load all cultures data, we can validate it and create cultures.
105-
ValidateAndLoadCultures(culturesData);
105+
ValidateAndLoadCultures(culturesData, config);
106106

107107
ReplaceInvalidatedParents();
108108
}
109109

110-
public void LoadConverterCultures(string converterCulturesPath) {
110+
public void LoadConverterCultures(string converterCulturesPath, Configuration config) {
111111
Logger.Info("Loading converter cultures...");
112112

113113
OrderedDictionary<string, CultureData> culturesData = new(); // Preserves order of insertion.
@@ -118,7 +118,7 @@ public void LoadConverterCultures(string converterCulturesPath) {
118118
parser.ParseFile(converterCulturesPath);
119119

120120
// After we've load all cultures data, we can validate it and create cultures.
121-
ValidateAndLoadCultures(culturesData);
121+
ValidateAndLoadCultures(culturesData, config);
122122

123123
ReplaceInvalidatedParents();
124124
}
@@ -130,7 +130,7 @@ private CultureData LoadCultureData(BufferedReader cultureReader) {
130130
return cultureData;
131131
}
132132

133-
private void ValidateAndLoadCultures(OrderedDictionary<string, CultureData> culturesData) {
133+
private void ValidateAndLoadCultures(OrderedDictionary<string, CultureData> culturesData, Configuration config) {
134134
foreach (var (cultureId, data) in culturesData) {
135135
if (data.InvalidatingCultureIds.Any()) {
136136
bool isInvalidated = false;
@@ -148,8 +148,14 @@ private void ValidateAndLoadCultures(OrderedDictionary<string, CultureData> cult
148148
Logger.Debug($"Loading optional culture {cultureId}...");
149149
}
150150
if (data.Heritage is null) {
151-
Logger.Warn($"Culture {cultureId} has no valid heritage defined! Skipping.");
152-
continue;
151+
// Special handling for TFE hunnic culture. #TODO: remove this when it's fixed on TFE side.
152+
if (config.FallenEagleEnabled && cultureId == "hunnic" && PillarCollection.GetHeritageForId("heritage_turkic") is Pillar turkicHeritage) {
153+
Logger.Debug("Applying turkic heritage to TFE hunnic culture.");
154+
data.Heritage = turkicHeritage;
155+
} else {
156+
Logger.Warn($"Culture {cultureId} has no valid heritage defined! Skipping.");
157+
continue;
158+
}
153159
}
154160
if (data.Language is null) {
155161
Logger.Warn($"Culture {cultureId} has no valid language defined! Skipping.");
@@ -248,6 +254,38 @@ public void LoadInnovationIds(ModFilesystem ck3ModFS) {
248254
}
249255
}
250256

257+
internal void WarnAboutCircularParents() {
258+
// For every culture, check if it isn't set as its own immediate or distant parent.
259+
Logger.Debug("Checking for circular culture parents...");
260+
foreach (var culture in this) {
261+
var allParents = GetImmediateAndDistantParentsOfCulture(culture);
262+
if (allParents.Contains(culture.Id)) {
263+
Logger.Error($"Culture {culture.Id} is set as its own parent!");
264+
}
265+
}
266+
}
267+
268+
private HashSet<string> GetImmediateAndDistantParentsOfCulture(Culture cultureToCheck, HashSet<string>? alreadyChecked = null) {
269+
HashSet<string> allParents = [];
270+
271+
// Get immediate parents.
272+
foreach (var parentCultureId in cultureToCheck.ParentCultureIds) {
273+
// Avoid infinite recursion.
274+
if (alreadyChecked?.Contains(parentCultureId) == true) {
275+
continue;
276+
}
277+
278+
allParents.Add(parentCultureId);
279+
var parentCulture = this[parentCultureId];
280+
281+
// Add the parent's parents.
282+
var parentParents = GetImmediateAndDistantParentsOfCulture(parentCulture, allParents);
283+
allParents.UnionWith(parentParents);
284+
}
285+
286+
return allParents;
287+
}
288+
251289
private readonly IDictionary<string, string> cultureReplacements = new Dictionary<string, string>(); // replaced culture -> replacing culture
252290

253291
protected readonly PillarCollection PillarCollection;

ImperatorToCK3/CK3/World.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,9 @@ public World(Imperator.World impWorld, Configuration config, Thread? irCoaExtrac
139139
Cultures = new CultureCollection(ck3ColorFactory, CulturalPillars, ck3ModFlags);
140140
Cultures.LoadNameLists(ModFS);
141141
Cultures.LoadInnovationIds(ModFS);
142-
Cultures.LoadCultures(ModFS);
143-
Cultures.LoadConverterCultures("configurables/converter_cultures.txt");
142+
Cultures.LoadCultures(ModFS, config);
143+
Cultures.LoadConverterCultures("configurables/converter_cultures.txt", config);
144+
Cultures.WarnAboutCircularParents();
144145
Logger.IncrementProgress();
145146
},
146147
() => LoadMenAtArmsTypes(ModFS, ScriptValues), // depends on ScriptValues

ImperatorToCK3/Data_Files/blankMod/output/common/culture/creation_names/IRToCK3_names.liquid

+2-2
Original file line numberDiff line numberDiff line change
@@ -228,12 +228,12 @@ hyperborean = {
228228

229229
coptic = {
230230
trigger = {
231-
religion = religion:christianity
231+
religion = religion:christianity_religion
232232
culture = culture:ancient_egyptian
233233
any_sub_realm_county = {
234234
AND = {
235235
culture = culture:ancient_egyptian
236-
religion = religion:christianity
236+
religion = religion:christianity_religion
237237
}
238238
}
239239
}

ImperatorToCK3/Data_Files/blankMod/output/common/culture/name_equivalency/IR_names.txt

+4-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ ir_spurius_male = { Spurie Spurius }
4949
ir_titus_male = { Tite Titus Tito Titos }
5050
ir_vibius_male = { Vipie Vibius }
5151
ir_fausta_female = { Fasthi Hasthi Fausta }
52-
ir_quintus_male = { Quintus Cuinte }
5352
ir_publius_male = { Publius Puplie }
5453
ir_aretas_male = { Aretas al-Harith }
5554
ir_euclid_male = { Euclid Eukleides }
@@ -245,6 +244,9 @@ first_male = { Primus Pervoy }
245244
second_male = { Secundus Vtorak }
246245
third_male = { Tertius Tretyak }
247246
fourth_male = { Quartus Chetvertak }
248-
fifth_male = { Quintus Pyatak }
247+
fifth_male = {
248+
Quintus Cuinte # from the Roman "Quintus"
249+
Pyatak # from the Russian "Pyaty" (fifth)
250+
}
249251
sixth_male = { Sextus Shestak }
250252
seventh_male = { Septimus Semoy }

ImperatorToCK3/Data_Files/blankMod/output/localization/french/sea_dynasties_l_french.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@
611611
dynn_Hkanan:0 "Hkanan"
612612
dynn_Hkawt:0 "Hkawt"
613613
dynn_Hke:0 "Hke"
614-
dynn_Hkeng:0 "Hkeng"
614+
#dynn_Hkeng:0 "Hkeng"
615615
dynn_Hkon:0 "Hkon"
616616
dynn_Hkum:0 "Hkum"
617617
dynn_Hkun:0 "Hkun"

ImperatorToCK3/Data_Files/blankMod/output/localization/german/sea_dynasties_l_german.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@
611611
dynn_Hkanan:0 "Hkanan"
612612
dynn_Hkawt:0 "Hkawt"
613613
dynn_Hke:0 "Hke"
614-
dynn_Hkeng:0 "Hkeng"
614+
#dynn_Hkeng:0 "Hkeng"
615615
dynn_Hkon:0 "Hkon"
616616
dynn_Hkum:0 "Hkum"
617617
dynn_Hkun:0 "Hkun"

ImperatorToCK3/Data_Files/blankMod/output/localization/russian/sea_dynasties_l_russian.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@
611611
dynn_Hkanan:0 "Хканан"
612612
dynn_Hkawt:0 "Hkawt"
613613
dynn_Hke:0 "Нкэ"
614-
dynn_Hkeng:0 "Хкенг"
614+
#dynn_Hkeng:0 "Хкенг"
615615
dynn_Hkon:0 "Хкон"
616616
dynn_Hkum:0 "Хкум"
617617
dynn_Hkun:0 "Хкун"

ImperatorToCK3/Data_Files/configurables/ccu_heritage_parameters.txt

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ heritage_groups = {
1313
heritage_group_nuragic
1414
} ELSE_IF tfe = {
1515
heritage_group_nuragic
16+
heritage_group_austroasiatic
1617
}
1718
}
1819
}

ImperatorToCK3/Data_Files/configurables/ccu_language_parameters.txt

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ language_families = {
1515
language_family_tyrsenian
1616
} ELSE_IF tfe = {
1717
language_family_paleo_sardinian
18+
language_family_kra_dai
1819
}
1920
}
2021
}
@@ -43,6 +44,7 @@ language_groups = {
4344
} ELSE_IF tfe = {
4445
language_group_nuragic
4546
language_group_italic
47+
language_group_tai
4648
}
4749
}
4850
}

0 commit comments

Comments
 (0)