Skip to content

Commit

Permalink
Fix some character history entries being set after character death (#…
Browse files Browse the repository at this point in the history
…2260) #patch
  • Loading branch information
IhateTrains authored Oct 10, 2024
1 parent 33ae4bf commit 33ce877
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 26 deletions.
3 changes: 2 additions & 1 deletion ImperatorToCK3/CK3/Characters/Character.cs
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,8 @@ ISet<string> unlocalizedImperatorNames

var nicknameMatch = nicknameMapper.GetCK3NicknameForImperatorNickname(ImperatorCharacter.Nickname);
if (nicknameMatch is not null) {
SetNickname(nicknameMatch, dateOnConversion);
var nicknameDate = ImperatorCharacter.DeathDate ?? dateOnConversion;
SetNickname(nicknameMatch, nicknameDate);
}

if (ImperatorCharacter.Wealth != 0) {
Expand Down
14 changes: 14 additions & 0 deletions ImperatorToCK3/CK3/Characters/CharacterCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,16 @@ public void GenerateSuccessorsForOldCharacters(Title.LandedTitles titles, Cultur
foreach (var oldCharacter in oldCharacters.Except(oldTitleHolders)) {
// Roll a dice to determine how much longer the character will live.
var yearsToLive = randomForCharactersWithoutTitles.Next(0, 30);

// If the character is female and pregnant, make sure she doesn't die before the pregnancy ends.
if (oldCharacter is {Female: true, ImperatorCharacter: not null}) {
var lastPregnancy = oldCharacter.Pregnancies.OrderBy(p => p.BirthDate).LastOrDefault();
if (lastPregnancy is not null) {
oldCharacter.DeathDate = lastPregnancy.BirthDate.ChangeByYears(yearsToLive);
continue;
}
}

oldCharacter.DeathDate = irSaveDate.ChangeByYears(yearsToLive);
}

Expand Down Expand Up @@ -803,6 +813,10 @@ public void GenerateSuccessorsForOldCharacters(Title.LandedTitles titles, Cultur
// After the loop, currentCharacter should represent the successor at bookmark date.
// Set his DNA to avoid weird looking character on the bookmark screen in CK3.
currentCharacter.DNA = oldCharacter.DNA;
// Transfer gold to the living successor.
currentCharacter.Gold = oldCharacter.Gold;
oldCharacter.Gold = null;
});
}

Expand Down
8 changes: 4 additions & 4 deletions ImperatorToCK3/CK3/Titles/LandedTitles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1446,7 +1446,7 @@ private void DistributeExcessDevelopment(Date date) {
/// https://ck3.paradoxwikis.com/Council
/// https://ck3.paradoxwikis.com/Court#Court_positions
/// </summary>
public void ImportImperatorGovernmentOffices(ICollection<OfficeJob> irOfficeJobs, ReligionCollection religionCollection, Date bookmarkDate) {
public void ImportImperatorGovernmentOffices(ICollection<OfficeJob> irOfficeJobs, ReligionCollection religionCollection, Date irSaveDate) {
Logger.Info("Converting government offices...");
var titlesFromImperator = GetCountriesImportedFromImperator();

Expand Down Expand Up @@ -1485,7 +1485,7 @@ public void ImportImperatorGovernmentOffices(ICollection<OfficeJob> irOfficeJobs
}

// Make sure the ruler actually holds something in CK3.
if (this.All(t => t.GetHolderId(bookmarkDate) != ck3Ruler.Id)) {
if (this.All(t => t.GetHolderId(irSaveDate) != ck3Ruler.Id)) {
continue;
}

Expand All @@ -1495,8 +1495,8 @@ public void ImportImperatorGovernmentOffices(ICollection<OfficeJob> irOfficeJobs
}

var alreadyEmployedCharacters = new HashSet<string>();
title.AppointCouncilMembersFromImperator(religionCollection, councilPositionToSourcesDict, convertibleJobs, alreadyEmployedCharacters, ck3Ruler, bookmarkDate);
title.AppointCourtierPositionsFromImperator(courtPositionToSourcesDict, convertibleJobs, alreadyEmployedCharacters, ck3Ruler, bookmarkDate);
title.AppointCouncilMembersFromImperator(religionCollection, councilPositionToSourcesDict, convertibleJobs, alreadyEmployedCharacters, ck3Ruler, irSaveDate);
title.AppointCourtierPositionsFromImperator(courtPositionToSourcesDict, convertibleJobs, alreadyEmployedCharacters, ck3Ruler, irSaveDate);
}
}

Expand Down
22 changes: 11 additions & 11 deletions ImperatorToCK3/CK3/Titles/Title.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1309,7 +1309,7 @@ private void AppointCourtierPositionsFromImperator(Dictionary<string, string[]>
List<OfficeJob> convertibleJobs,
HashSet<string> alreadyEmployedCharacters,
Character ck3Ruler,
Date bookmarkDate) {
Date irSaveDate) {
Dictionary<string, int> heldTitlesPerCharacterCache = [];

foreach (var (ck3Position, sources) in courtPositionToSourcesDict) {
Expand All @@ -1334,7 +1334,7 @@ private void AppointCourtierPositionsFromImperator(Dictionary<string, string[]>
}

if (!heldTitlesPerCharacterCache.ContainsKey(ck3Official.Id)) {
heldTitlesPerCharacterCache[ck3Official.Id] = parentCollection.Count(t => t.GetHolderId(bookmarkDate) == ck3Official.Id);
heldTitlesPerCharacterCache[ck3Official.Id] = parentCollection.Count(t => t.GetHolderId(irSaveDate) == ck3Official.Id);
}
// A potential courtier must not be a ruler.
if (heldTitlesPerCharacterCache[ck3Official.Id] > 0) {
Expand All @@ -1360,7 +1360,7 @@ private void AppointCourtierPositionsFromImperator(Dictionary<string, string[]>
}
}
""");
ck3Ruler.History.AddFieldValue(bookmarkDate, "effects", "effect", courtPositionEffect);
ck3Ruler.History.AddFieldValue(irSaveDate, "effects", "effect", courtPositionEffect);

// One character should only hold one CK3 position.
convertibleJobs.Remove(job);
Expand All @@ -1376,7 +1376,7 @@ private void AppointCouncilMembersFromImperator(ReligionCollection religionColle
List<OfficeJob> convertibleJobs,
HashSet<string> alreadyEmployedCharacters,
Character ck3Ruler,
Date bookmarkDate) {
Date irSaveDate) {
Dictionary<string, int> heldTitlesPerCharacterCache = [];

foreach (var (ck3Position, sources) in councilPositionToSourcesDict) {
Expand All @@ -1401,14 +1401,14 @@ private void AppointCouncilMembersFromImperator(ReligionCollection religionColle
}

if (!heldTitlesPerCharacterCache.TryGetValue(ck3Official.Id, out int heldTitlesCount)) {
heldTitlesCount = parentCollection.Count(t => t.GetHolderId(bookmarkDate) == ck3Official.Id);
heldTitlesCount = parentCollection.Count(t => t.GetHolderId(irSaveDate) == ck3Official.Id);
heldTitlesPerCharacterCache[ck3Official.Id] = heldTitlesCount;
}

if (ck3Position == "councillor_court_chaplain") {
// Court chaplains need to have the same faith as the ruler.
var rulerFaithId = ck3Ruler.GetFaithId(bookmarkDate);
if (rulerFaithId is null || rulerFaithId != ck3Official.GetFaithId(bookmarkDate)) {
var rulerFaithId = ck3Ruler.GetFaithId(irSaveDate);
if (rulerFaithId is null || rulerFaithId != ck3Official.GetFaithId(irSaveDate)) {
continue;
}

Expand All @@ -1418,7 +1418,7 @@ private void AppointCouncilMembersFromImperator(ReligionCollection religionColle
continue;
}
if (rulerFaith.HasDoctrine("doctrine_clerical_marriage_disallowed")) {
if (ck3Official.GetSpouseIds(bookmarkDate).Count > 0) {
if (ck3Official.GetSpouseIds(irSaveDate).Count > 0) {
continue;
}
}
Expand All @@ -1445,7 +1445,7 @@ private void AppointCouncilMembersFromImperator(ReligionCollection religionColle
} else if (ck3Position == "councillor_steward" || ck3Position == "councillor_chancellor" || ck3Position == "councillor_marshal") {
// Unless they are rulers, stewards, chancellors and marshals need to have the dominant gender of the faith.
if (heldTitlesCount == 0) {
var courtFaith = ck3Ruler.GetFaithId(bookmarkDate);
var courtFaith = ck3Ruler.GetFaithId(irSaveDate);
if (courtFaith is not null) {
var dominantGenderDoctrine = religionCollection.GetFaith(courtFaith)?
.GetDoctrineIdForDoctrineCategoryId("doctrine_gender");
Expand All @@ -1461,9 +1461,9 @@ private void AppointCouncilMembersFromImperator(ReligionCollection religionColle

// We only need to set the employer when the council member is landless.
if (heldTitlesCount == 0) {
ck3Official.History.AddFieldValue(bookmarkDate, "employer", "employer", ck3Ruler.Id);
ck3Official.History.AddFieldValue(irSaveDate, "employer", "employer", ck3Ruler.Id);
}
ck3Official.History.AddFieldValue(bookmarkDate, "council_position", "give_council_position", ck3Position);
ck3Official.History.AddFieldValue(irSaveDate, "council_position", "give_council_position", ck3Position);

// One character should only hold one CK3 position.
convertibleJobs.Remove(job);
Expand Down
16 changes: 8 additions & 8 deletions ImperatorToCK3/CK3/World.cs
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ public World(Imperator.World impWorld, Configuration config, Thread? irCoaExtrac
deathReasonMapper,
dnaFactory,
LocDB,
CorrectedDate,
impWorld.EndDate,
config
);
// Now that we have loaded all characters, we can mark some of them as non-removable.
Expand Down Expand Up @@ -345,6 +345,12 @@ public World(Imperator.World impWorld, Configuration config, Thread? irCoaExtrac
}

Dynasties.SetCoasForRulingDynasties(LandedTitles, config.CK3BookmarkDate);

// If there's a gap between the I:R save date and the CK3 bookmark date,
// generate successors for old I:R characters instead of making them live for centuries.
if (config.CK3BookmarkDate.DiffInYears(impWorld.EndDate) > 1) {
Characters.GenerateSuccessorsForOldCharacters(LandedTitles, Cultures, impWorld.EndDate, config.CK3BookmarkDate, impWorld.RandomSeed);
}

Characters.DistributeCountriesGold(LandedTitles, config);
Characters.ImportLegions(LandedTitles, impWorld.Units, impWorld.Characters, CorrectedDate, unitTypeMapper, MenAtArmsTypes, provinceMapper, LocDB, config);
Expand All @@ -359,7 +365,7 @@ public World(Imperator.World impWorld, Configuration config, Thread? irCoaExtrac
LandedTitles.CleanUpHistory(Characters, config.CK3BookmarkDate);

// Now that the title history is basically done, convert officials as council members and courtiers.
LandedTitles.ImportImperatorGovernmentOffices(impWorld.JobsDB.OfficeJobs, Religions, config.CK3BookmarkDate);
LandedTitles.ImportImperatorGovernmentOffices(impWorld.JobsDB.OfficeJobs, Religions, impWorld.EndDate);

// Check if any muslim religion exists in Imperator. Otherwise, remove Islam from the entire CK3 map.
var possibleMuslimReligionNames = new List<string> { "muslim", "islam", "sunni", "shiite" };
Expand All @@ -371,12 +377,6 @@ public World(Imperator.World impWorld, Configuration config, Thread? irCoaExtrac
RemoveIslam(config);
}
Logger.IncrementProgress();

// If there's a gap between the I:R save date and the CK3 bookmark date,
// generate successors for old I:R characters instead of making them live for centuries.
if (config.CK3BookmarkDate.DiffInYears(impWorld.EndDate) > 1) {
Characters.GenerateSuccessorsForOldCharacters(LandedTitles, Cultures, impWorld.EndDate, config.CK3BookmarkDate, impWorld.RandomSeed);
}

Parallel.Invoke(
() => ImportImperatorWars(impWorld, config.CK3BookmarkDate),
Expand Down
2 changes: 1 addition & 1 deletion ImperatorToCK3/Outputter/CharacterOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public static void WriteCharacter(StringBuilder sb, Character character, Date co
string effectStr = gold > 0 ?
$"{{ add_gold={gold.ToString("0.00", CultureInfo.InvariantCulture)} }}" :
$"{{ remove_long_term_gold={(-gold).ToString("0.00", CultureInfo.InvariantCulture)} }}";
character.History.AddFieldValue(conversionDate, "effects", "effect", effectStr);
character.History.AddFieldValue(ck3BookmarkDate, "effects", "effect", effectStr);
}

// Output history.
Expand Down
2 changes: 1 addition & 1 deletion ImperatorToCK3/Outputter/WorldOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public static void OutputWorld(World ck3World, Imperator.World imperatorWorld, C
Task.WaitAll(
FileTweaker.RemoveUnneededPartsOfFiles(ck3World.ModFS, outputPath, config),

CharactersOutputter.OutputEverything(outputPath, ck3World.Characters, ck3World.CorrectedDate, config.CK3BookmarkDate, ck3World.ModFS),
CharactersOutputter.OutputEverything(outputPath, ck3World.Characters, imperatorWorld.EndDate, config.CK3BookmarkDate, ck3World.ModFS),
DynastiesOutputter.OutputDynastiesAndHouses(outputPath, ck3World.Dynasties, ck3World.DynastyHouses),

ProvincesOutputter.OutputProvinces(outputPath, ck3World.Provinces, ck3World.LandedTitles),
Expand Down

0 comments on commit 33ce877

Please sign in to comment.