Skip to content

Commit

Permalink
Fix landed title definitions from multiple files not being correctly …
Browse files Browse the repository at this point in the history
…merged (#2240)
  • Loading branch information
IhateTrains authored Oct 3, 2024
1 parent de13a4d commit 75cfdd9
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 17 deletions.
27 changes: 26 additions & 1 deletion ImperatorToCK3.UnitTests/CK3/Titles/LandedTitlesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -582,4 +582,29 @@ public void GetBaronyForProvinceReturnsCorrectBaronyOrNullWhenNotFound() {
Assert.Equal("b_barony3", titles.GetBaronyForProvince(3)?.Id);
Assert.Null(titles.GetBaronyForProvince(4));
}
}

[Fact]
public void TitlesCanBeExpandedInOtherFiles() {
var titles = new Title.LandedTitles();
titles.LoadTitles(ck3ModFS, new TestCK3LocDB());

// e_mongolia's color is defined in base_landed_titles.txt.
// But its capital is defined in extra_landed_titles.txt.
// If both are properly set, it means that we're correctly loading a title from multiple files.
var mongoliaEmpire = titles["e_mongolia"];
Assert.Equal(new Color(90, 90, 240), mongoliaEmpire.Color1);
Assert.Equal("c_karakorum", mongoliaEmpire.CapitalCountyId);

// It has k_mongolia and k_angara defined as de jure vassals in base_landed_titles.txt.
// It also has k_jubu defined as a de jure vassal in extra_landed_titles.txt.
Assert.Equal(3, mongoliaEmpire.DeJureVassals.Count);

// k_mongolia's color is defined in base_landed_titles.txt.
// But its capital is defined in extra_landed_titles.txt.
// This checks if we can correctly load lower rank titles (nested in the structure) from multiple files.
var mongoliaKingdom = titles["k_mongolia"];
Assert.Equal(new Color(20, 65, 25), mongoliaKingdom.Color1);
Assert.Equal("c_karakorum", mongoliaKingdom.CapitalCountyId);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
e_mongolia = {
color = { 90 90 240 }

k_mongolia = {
color = { 20 65 25 }
}

k_angara = {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
e_mongolia = {
capital = c_karakorum

k_mongolia = {
capital = c_karakorum
}

k_jubu = {}
}
14 changes: 9 additions & 5 deletions ImperatorToCK3/CK3/Titles/LandedTitles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,14 @@ private void RegisterKeys(Parser parser) {
Variables[variableName[1..]] = variableValue;
});
parser.RegisterRegex(Regexes.TitleId, (reader, titleNameStr) => {
// Pull the titles beneath this one and add them to the lot, overwriting existing ones.
var newTitle = Add(titleNameStr);
newTitle.LoadTitles(reader);
// Pull the titles beneath this one and add them to the lot.
// A title can be defined in multiple files, in that case merge the definitions.
if (TryGetValue(titleNameStr, out var titleToUpdate)) {
titleToUpdate.LoadTitles(reader);
} else {
var newTitle = Add(titleNameStr);
newTitle.LoadTitles(reader);
}
});
parser.IgnoreAndLogUnregisteredItems();
}
Expand Down Expand Up @@ -221,8 +226,7 @@ ImperatorRegionMapper imperatorRegionMapper
}
public override void Remove(string name) {
if (dict.TryGetValue(name, out var titleToErase)) {
var deJureLiege = titleToErase.DeJureLiege;
deJureLiege?.DeJureVassals.Remove(name);
titleToErase.DeJureLiege = null; // Remove two-way liege-vassal link.

foreach (var vassal in titleToErase.DeJureVassals) {
vassal.DeJureLiege = null;
Expand Down
26 changes: 16 additions & 10 deletions ImperatorToCK3/CK3/Titles/Title.cs
Original file line number Diff line number Diff line change
Expand Up @@ -940,9 +940,9 @@ public Title? DeJureLiege { // direct de jure liege title
Logger.Warn($"Cannot set de jure liege {value} to {Id}: rank is not higher!");
return;
}
deJureLiege?.DeJureVassals.Remove(Id);
deJureLiege?.deJureVassals.Remove(Id);
deJureLiege = value;
value?.DeJureVassals.AddOrReplace(this);
value?.deJureVassals.AddOrReplace(this);
}
}
public Title? GetDeFactoLiege(Date date) { // direct de facto liege title
Expand Down Expand Up @@ -978,7 +978,8 @@ public void SetDeFactoLiege(Title? newLiege, Date date) {
}
}

[SerializeOnlyValue] public TitleCollection DeJureVassals { get; } = new(); // DIRECT de jure vassals
private readonly TitleCollection deJureVassals = [];
[SerializeOnlyValue] public IReadOnlyTitleCollection DeJureVassals => deJureVassals; // DIRECT de jure vassals
public IDictionary<string, Title> GetDeJureVassalsAndBelow() {
return GetDeJureVassalsAndBelow("bcdke");
}
Expand Down Expand Up @@ -1090,16 +1091,21 @@ public ICollection<string> GetSuccessionLaws(Date date) {

private void RegisterKeys(Parser parser) {
parser.RegisterRegex(Regexes.TitleId, (reader, titleNameStr) => {
// Pull the titles beneath this one and add them to the lot, overwriting existing ones.
var newTitle = parentCollection.Add(titleNameStr);
newTitle.LoadTitles(reader);
// Pull the titles beneath this one and add them to the lot.
// A title can be defined in multiple files, in that case merge the definitions.
if (parentCollection.TryGetValue(titleNameStr, out var childTitle)) {
childTitle.LoadTitles(reader);
} else {
childTitle = parentCollection.Add(titleNameStr);
childTitle.LoadTitles(reader);
}
if (newTitle.Rank == TitleRank.barony && string.IsNullOrEmpty(CapitalBaronyId)) {
if (childTitle.Rank == TitleRank.barony && string.IsNullOrEmpty(CapitalBaronyId)) {
// title is a barony, and no other barony has been found in this scope yet
CapitalBaronyId = newTitle.Id;
CapitalBaronyId = childTitle.Id;
}
newTitle.DeJureLiege = this;
childTitle.DeJureLiege = this;
});
parser.RegisterKeyword("definite_form", reader => HasDefiniteForm = reader.GetBool());
parser.RegisterKeyword("ruler_uses_title_name", reader => RulerUsesTitleName = reader.GetBool());
Expand Down
7 changes: 6 additions & 1 deletion ImperatorToCK3/CK3/Titles/TitleCollection.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
using commonItems.Collections;
using System.Collections.Generic;

namespace ImperatorToCK3.CK3.Titles;

public class TitleCollection : IdObjectCollection<string, Title>;
public interface IReadOnlyTitleCollection : IReadOnlyCollection<Title> {
public bool ContainsKey(string key);
}

public class TitleCollection : IdObjectCollection<string, Title>, IReadOnlyTitleCollection;

0 comments on commit 75cfdd9

Please sign in to comment.