Skip to content

Formatting and performance tweaks #2019

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jun 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 28 additions & 30 deletions ImperatorToCK3/CK3/Characters/CharacterCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Configuration config
ImportFriendships(impWorld.Characters, conversionDate);
ImportRivalries(impWorld.Characters, conversionDate);
Logger.IncrementProgress();

ImportPregnancies(impWorld.Characters, conversionDate);

if (config.FallenEagleEnabled) {
Expand Down Expand Up @@ -116,7 +116,7 @@ private void ImportImperatorCharacter(
public override void Remove(string key) {
BulkRemove([key]);
}

private void BulkRemove(ICollection<string> keys) {
foreach (var key in keys) {
var characterToRemove = this[key];
Expand All @@ -128,16 +128,16 @@ private void BulkRemove(ICollection<string> keys) {
if (irCharacter is not null) {
irCharacter.CK3Character = null;
}

base.Remove(key);
}

RemoveCharacterReferencesFromHistory(keys);
}

private void RemoveCharacterReferencesFromHistory(ICollection<string> idsToRemove) {
var idsCapturingGroup = "(" + string.Join('|', idsToRemove) + ")";

// Effects like "break_alliance = character:ID" entries should be removed.
const string commandsGroup = "(break_alliance|make_concubine)";
var simpleCommandsRegex = new Regex(commandsGroup + @"\s*=\s*character:" + idsCapturingGroup + @"\s*\b");
Expand Down Expand Up @@ -255,14 +255,14 @@ Date GetEstimatedMarriageDate(Imperator.Characters.Character imperatorCharacter,
Date? GetBirthDateOfFirstCommonChild(Imperator.Characters.Character father, Imperator.Characters.Character mother) {
var childrenOfFather = father.Children.Values.ToHashSet();
var childrenOfMother = mother.Children.Values.ToHashSet();
var commonChildren = childrenOfFather.Intersect(childrenOfMother).OrderBy(child => child.BirthDate).ToList();
var commonChildren = childrenOfFather.Intersect(childrenOfMother).OrderBy(child => child.BirthDate).ToArray();

Date? firstChildBirthDate = commonChildren.Count > 0 ? commonChildren.FirstOrDefault()?.BirthDate : null;
Date? firstChildBirthDate = commonChildren.Length > 0 ? commonChildren.FirstOrDefault()?.BirthDate : null;
if (firstChildBirthDate is not null) {
return firstChildBirthDate;
}

var unborns = mother.Unborns.Where(u => u.FatherId == father.Id).OrderBy(u => u.BirthDate).ToList();
var unborns = mother.Unborns.Where(u => u.FatherId == father.Id).OrderBy(u => u.BirthDate).ToArray();
return unborns.FirstOrDefault()?.BirthDate;
}

Expand Down Expand Up @@ -296,7 +296,7 @@ private static void ImportFriendships(Imperator.Characters.CharacterCollection i

var irFriend = irCharacters[irFriendId];
var ck3Friend = irFriend.CK3Character;

if (ck3Friend is not null) {
var effectStr = $"{{ set_relation_friend={{ reason=friend_generic_history target=character:{ck3Friend.Id} }} }}";
ck3Character.History.AddFieldValue(conversionDate, "effects", "effect", effectStr);
Expand Down Expand Up @@ -324,7 +324,7 @@ private static void ImportRivalries(Imperator.Characters.CharacterCollection irC

var irRival = irCharacters[irRivalId];
var ck3Rival = irRival.CK3Character;

if (ck3Rival is not null) {
var effectStr = $"{{ set_relation_rival={{ reason=rival_historical target=character:{ck3Rival.Id} }} }}";
ck3Character.History.AddFieldValue(conversionDate, "effects", "effect", effectStr);
Expand Down Expand Up @@ -375,17 +375,17 @@ private void SetCharacterCastes(CultureCollection cultures, Date ck3BookmarkDate
.Select(c => c.Id)
.ToHashSet();
var learningEducationTraits = new[]{"education_learning_1", "education_learning_2", "education_learning_3", "education_learning_4"};

foreach (var character in this.OrderBy(c => c.BirthDate)) {
if (character.ImperatorCharacter is null) {
continue;
}

var cultureId = character.GetCultureId(ck3BookmarkDate);
if (cultureId is null || !casteSystemCultureIds.Contains(cultureId)) {
continue;
}

// The caste is hereditary.
var father = character.Father;
if (father is not null) {
Expand All @@ -403,7 +403,7 @@ private void SetCharacterCastes(CultureCollection cultures, Date ck3BookmarkDate
continue;
}
}

// Try to set caste based on character's traits.
var traitIds = character.BaseTraits.ToHashSet();
character.AddBaseTrait(traitIds.Intersect(learningEducationTraits).Any() ? "brahmin" : "kshatriya");
Expand Down Expand Up @@ -434,34 +434,34 @@ private static IEnumerable<string> LoadCharacterIDsToPreserve() {

public void PurgeUnneededCharacters(Title.LandedTitles titles, DynastyCollection dynasties, HouseCollection houses, Date ck3BookmarkDate) {
Logger.Info("Purging unneeded characters...");

// Characters that hold or held titles should always be kept.
var landedCharacterIds = titles.GetAllHolderIds();
var landedCharacters = this
.Where(character => landedCharacterIds.Contains(character.Id))
.ToList();
.ToArray();
var charactersToCheck = this.Except(landedCharacters);

// Don't purge animation_test or easter egg characters.
charactersToCheck = charactersToCheck
.Where(c => !c.Id.StartsWith("animation_test_") && !c.Id.StartsWith("easteregg_"));

// Keep alive Imperator characters.
charactersToCheck = charactersToCheck
.Where(c => c is not {FromImperator: true, Dead: false});

// Make some exceptions for characters referenced in game's script files.
var characterIdsToKeep = LoadCharacterIDsToPreserve();

charactersToCheck = charactersToCheck
.Where(character => !characterIdsToKeep.Contains(character.Id))
.ToList();
.ToArray();

var dynastyIdsOfLandedCharacters = landedCharacters
.Select(character => character.GetDynastyId(ck3BookmarkDate))
.Distinct()
.ToHashSet();

var i = 0;
var charactersToRemove = new List<Character>();
var parentIdsCache = new HashSet<string>();
Expand All @@ -470,7 +470,7 @@ public void PurgeUnneededCharacters(Title.LandedTitles titles, DynastyCollection
charactersToRemove.Clear();
parentIdsCache.Clear();
++i;

// Build cache of all parent IDs.
foreach (var character in this) {
var motherId = character.MotherId;
Expand Down Expand Up @@ -498,13 +498,13 @@ public void PurgeUnneededCharacters(Title.LandedTitles titles, DynastyCollection

charactersToRemove.Add(character);
}
BulkRemove(charactersToRemove.Select(c => c.Id).ToList());

BulkRemove(charactersToRemove.ConvertAll(c => c.Id));

Logger.Debug($"\tPurged {charactersToRemove.Count} unneeded characters in iteration {i}.");
charactersToCheck = charactersToCheck.Except(charactersToRemove).ToList();
charactersToCheck = charactersToCheck.Except(charactersToRemove).ToArray();
} while(charactersToRemove.Count > 0);

// At this point we probably have many dynasties with no characters left.
// Let's purge them.
houses.PurgeUnneededHouses(this, ck3BookmarkDate);
Expand Down Expand Up @@ -599,10 +599,8 @@ Configuration config
}

var imperatorCountry = ck3Country.ImperatorCountry!;
var countryLegions = imperatorUnits.Where(u => u.CountryId == imperatorCountry.Id)
.Where(unit => unit.IsArmy && unit.IsLegion) // drop navies and levies
.ToList();
if (!countryLegions.Any()) {
var countryLegions = imperatorUnits.Where(u => u.CountryId == imperatorCountry.Id && u.IsArmy && u.IsLegion).ToArray();
if (countryLegions.Length == 0) {
continue;
}

Expand Down
16 changes: 8 additions & 8 deletions ImperatorToCK3/CK3/Characters/CharactersLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,28 @@ public void LoadCK3Characters(ModFilesystem ck3ModFS, Date bookmarkDate) {
Logger.Info("Loading characters from CK3...");

var loadedCharacters = new ConcurrentList<Character>();

var parser = new Parser();
parser.RegisterRegex(CommonRegexes.String, (reader, characterId) => {
var character = new Character(characterId, reader, this);

// Check if character has a birth date:
if (character.History.Fields["birth"].DateToEntriesDict.Count == 0) {
Logger.Debug($"Ignoring character {characterId} with no valid birth date.");
return;
}

AddOrReplace(character);
loadedCharacters.Add(character);
});
parser.IgnoreAndLogUnregisteredItems();
parser.ParseGameFolder("history/characters", ck3ModFS, "txt", recursive: true, parallel: true);
string[] irrelevantEffects = ["set_relation_rival", "set_relation_potential_rival", "set_relation_nemesis",

string[] irrelevantEffects = ["set_relation_rival", "set_relation_potential_rival", "set_relation_nemesis",
"set_relation_lover", "set_relation_soulmate",
"set_relation_friend", "set_relation_potential_friend", "set_relation_best_friend",
"set_relation_ward", "set_relation_mentor",];

foreach (var character in loadedCharacters) {
// Remove post-bookmark history except for births and deaths.
foreach (var field in character.History.Fields) {
Expand All @@ -45,7 +45,7 @@ public void LoadCK3Characters(ModFilesystem ck3ModFS, Date bookmarkDate) {
var birthField = character.History.Fields["birth"];
birthField.RemoveAllEntries();
birthField.AddEntryToHistory(character.BirthDate, "birth", value: true);

// Replace complex death entries like "death = { death_reason = death_murder_known killer = 9051 }"
// with "death = yes".
Date? deathDate = character.DeathDate;
Expand All @@ -54,7 +54,7 @@ public void LoadCK3Characters(ModFilesystem ck3ModFS, Date bookmarkDate) {
deathField.RemoveAllEntries();
deathField.AddEntryToHistory(deathDate, "death", value: true);
}

// Remove effects that set relations. They don't matter a lot in our alternate timeline.
character.History.Fields["effects"].RemoveAllEntries(
entry => irrelevantEffects.Any(effect => entry.ToString()?.Contains(effect) ?? false));
Expand Down
4 changes: 2 additions & 2 deletions ImperatorToCK3/CK3/Characters/DNAColorGeneValue.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using System;

namespace ImperatorToCK3.CK3.Characters;
namespace ImperatorToCK3.CK3.Characters;

public readonly struct DNAColorGeneValue : IEquatable<DNAColorGeneValue> {
public required byte X { get; init; }
public required byte Y { get; init; }
public required byte XRecessive { get; init; }
public required byte YRecessive { get; init; }

public override string ToString() {
return $"{X} {Y} {XRecessive} {YRecessive}";
}
Expand Down
8 changes: 4 additions & 4 deletions ImperatorToCK3/CK3/Characters/DNAFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,99 +69,99 @@
BuildColorConversionCaches(ck3HairPalettePixels, ck3SkinPalettePixels, ck3EyePalettePixels);
}

public DNA GenerateDNA(Imperator.Characters.Character irCharacter, PortraitData irPortraitData) {
var id = $"dna_{irCharacter.Id}";

var colorDNAValues = new Dictionary<string, DNAColorGeneValue>();
var morphDNAValues = new Dictionary<string, DNAGeneValue>();

// Convert colors. Palettes are 512x512, but we need a 0-255 value, so we divide the coordinates by 2.
var hairCoordinates = GetPaletteCoordinates(
irPortraitData.HairColorPaletteCoordinates, irHairPalettePixels, ck3HairColorToPaletteCoordinatesDict
);
var hairCoordinates2 = GetPaletteCoordinates(
irPortraitData.HairColor2PaletteCoordinates, irHairPalettePixels, ck3HairColorToPaletteCoordinatesDict
);
colorDNAValues.Add("hair_color", new DNAColorGeneValue {
X = (byte)(hairCoordinates.X/2),
Y = (byte)(hairCoordinates.Y/2),
XRecessive = (byte)(hairCoordinates2.X/2),
YRecessive = (byte)(hairCoordinates2.Y/2)
});

var skinCoordinates = GetPaletteCoordinates(
irPortraitData.SkinColorPaletteCoordinates, irSkinPalettePixels, ck3SkinColorToPaletteCoordinatesDict
);
var skinCoordinates2 = GetPaletteCoordinates(
irPortraitData.SkinColor2PaletteCoordinates, irSkinPalettePixels, ck3SkinColorToPaletteCoordinatesDict
);
colorDNAValues.Add("skin_color", new DNAColorGeneValue {
X = (byte)(skinCoordinates.X/2),
Y = (byte)(skinCoordinates.Y/2),
XRecessive = (byte)(skinCoordinates2.X/2),
YRecessive = (byte)(skinCoordinates2.Y/2)
});

var eyeCoordinates = GetPaletteCoordinates(
irPortraitData.EyeColorPaletteCoordinates, irEyePalettePixels, ck3EyeColorToPaletteCoordinatesDict
);
var eyeCoordinates2 = GetPaletteCoordinates(
irPortraitData.EyeColor2PaletteCoordinates, irEyePalettePixels, ck3EyeColorToPaletteCoordinatesDict
);
colorDNAValues.Add("eye_color", new DNAColorGeneValue {
X = (byte)(eyeCoordinates.X/2),
Y = (byte)(eyeCoordinates.Y/2),
XRecessive = (byte)(eyeCoordinates2.X/2),
YRecessive = (byte)(eyeCoordinates2.Y/2)
});

// Convert some accessory genes.
var accessoryDNAValues = new Dictionary<string, DNAAccessoryGeneValue>();

if (ck3GenesDB.SpecialAccessoryGenes.TryGetValue("beards", out var beardGene)) {
var beardGeneValue = MatchAccessoryGeneValueByObject(
irCharacter,
irPortraitData,
"beards",
beardGene
);
if (beardGeneValue is not null) {
accessoryDNAValues.Add("beards", beardGeneValue.Value);
}
} else {
Logger.Warn("beards not found in CK3 special accessory genes!");
}

if (ck3GenesDB.SpecialAccessoryGenes.TryGetValue("hairstyles", out var hairstylesGene)) {
var hairstylesGeneValue = MatchAccessoryGeneValueByObject(
irCharacter,
irPortraitData,
"hairstyles",
hairstylesGene
);
if (hairstylesGeneValue is not null) {
accessoryDNAValues.Add("hairstyles", hairstylesGeneValue.Value);
}
} else {
Logger.Warn("hairstyles not found in CK3 special accessory genes!");
}

if (ck3GenesDB.SpecialAccessoryGenes.TryGetValue("clothes", out var ck3ClothesGene)) {
var clothesGeneValue = MatchAccessoryGeneValueByTemplate(irCharacter, irPortraitData, "clothes", ck3ClothesGene);
if (clothesGeneValue is not null) {
accessoryDNAValues.Add(ck3ClothesGene.Id, clothesGeneValue.Value);
}
} else {
Logger.Warn("clothes not found in CK3 special accessory genes!");
}

// Convert eye accessories.
var irEyeAccessoryGeneTemplateName = irPortraitData.AccessoryGenesDict["eye_accessory"].GeneTemplate;
switch (irEyeAccessoryGeneTemplateName) {
case "normal_eyes":
break;
case "eyepatch_1":
case "eyepatch_2": // TODO: check if this is correctly added to portrait modifiers if needed

Check warning on line 164 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (self-hosted, linux)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 164 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (macos-14)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 164 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (self-hosted, windows)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 164 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test (macos-14)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 164 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test_and_check_coverage

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 164 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test (self-hosted, windows)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)
var eyePatchTemplate = ck3GenesDB.SpecialAccessoryGenes["special_headgear_eye_patch"]
.GeneTemplates["eye_patch"];
if (eyePatchTemplate.AgeSexWeightBlocks.TryGetValue(irCharacter.AgeSex, out WeightBlock? eyePatchWeightBlock)) {
Expand All @@ -170,7 +170,7 @@
}

break;
case "blindfold_1": // TODO: check if this is correctly added to portrait modifiers if needed

Check warning on line 173 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (self-hosted, linux)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 173 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (macos-14)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 173 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (self-hosted, windows)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 173 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test (macos-14)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 173 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test_and_check_coverage

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 173 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test (self-hosted, windows)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)
var blindfoldTemplate = ck3GenesDB.SpecialAccessoryGenes["special_headgear_blindfold"]
.GeneTemplates["blindfold"];
if (blindfoldTemplate.AgeSexWeightBlocks.TryGetValue(irCharacter.AgeSex, out WeightBlock? blindfoldWeightBlock)) {
Expand All @@ -179,7 +179,7 @@
}

break;
case "blind_eyes": // TODO: check if this is correctly added to portrait modifiers if needed

Check warning on line 182 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (self-hosted, linux)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 182 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (macos-14)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 182 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (self-hosted, windows)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 182 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test (macos-14)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 182 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test_and_check_coverage

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 182 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test (self-hosted, windows)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)
var blindEyesTemplate = ck3GenesDB.AccessoryGenes["eye_accessory"]
.GeneTemplates["blind_eyes"];
if (blindEyesTemplate.AgeSexWeightBlocks.TryGetValue(irCharacter.AgeSex, out WeightBlock? blindEyesWeightBlock)) {
Expand All @@ -188,7 +188,7 @@
}

break;
case "red_eyes": // TODO: check if this is correctly converted

Check warning on line 191 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (self-hosted, linux)

Check warning on line 191 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (macos-14)

Check warning on line 191 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (self-hosted, windows)

Check warning on line 191 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test (macos-14)

Check warning on line 191 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test_and_check_coverage

Check warning on line 191 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test (self-hosted, windows)

var magickRed = new MagickColor("#ff0000");
var redEyeCoordinates = GetCoordinatesOfClosestCK3Color(magickRed, ck3EyeColorToPaletteCoordinatesDict);
colorDNAValues["eye_color"] = colorDNAValues["eye_color"] with {
Expand All @@ -204,21 +204,21 @@
var blindEyesTemplate = ck3GenesDB.AccessoryGenes["eye_accessory"].GeneTemplates["blind_eyes"];
if (blindEyesTemplate.AgeSexWeightBlocks.TryGetValue(irCharacter.AgeSex, out WeightBlock? blindEyesWeighBlock)) {
var blindEyesObjectName = blindEyesWeighBlock.GetMatchingObject(1) ?? blindEyesWeighBlock.ObjectNames.Last();
accessoryDNAValues["eye_accessory"] = new(blindEyesTemplate.Id, blindEyesObjectName, blindEyesWeighBlock); // TODO: check if this is correctly added to portrait modifiers if needed

Check warning on line 207 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (self-hosted, linux)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 207 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (macos-14)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 207 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (self-hosted, windows)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 207 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test (macos-14)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 207 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test_and_check_coverage

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 207 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test (self-hosted, windows)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)
}

var blindfoldTemplate = ck3GenesDB.SpecialAccessoryGenes["special_headgear_blindfold"]
.GeneTemplates["blindfold"];
if (blindfoldTemplate.AgeSexWeightBlocks.TryGetValue(irCharacter.AgeSex, out WeightBlock? blindfoldWeighBlock)) {
var blindfoldObjectName = blindfoldWeighBlock.GetMatchingObject(1) ?? blindfoldWeighBlock.ObjectNames.Last();
accessoryDNAValues["special_headgear_blindfold"] = new(blindfoldTemplate.Id, blindfoldObjectName, blindfoldWeighBlock); // TODO: check if this is correctly added to portrait modifiers if needed

Check warning on line 214 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (self-hosted, linux)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 214 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (macos-14)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 214 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (self-hosted, windows)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 214 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test (macos-14)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 214 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test_and_check_coverage

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 214 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test (self-hosted, windows)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)
}
} else if (irCharacter.Traits.Contains("one_eyed")) {
var eyePatchTemplate = ck3GenesDB.SpecialAccessoryGenes["special_headgear_eye_patch"]
.GeneTemplates["eye_patch"];
if (eyePatchTemplate.AgeSexWeightBlocks.TryGetValue(irCharacter.AgeSex, out WeightBlock? eyePatchWeighBlock)) {
var eyePatchObjectName = eyePatchWeighBlock.GetMatchingObject(1) ?? eyePatchWeighBlock.ObjectNames.Last();
accessoryDNAValues["special_headgear_eye_patch"] = new(eyePatchTemplate.Id, eyePatchObjectName, eyePatchWeighBlock); // TODO: check if this is correctly added to portrait modifiers if needed

Check warning on line 221 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (self-hosted, linux)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 221 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (macos-14)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 221 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (self-hosted, windows)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 221 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test (macos-14)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 221 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test_and_check_coverage

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 221 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test (self-hosted, windows)

TODO check if this is correctly added to portrait modifiers if needed (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)
}
}

Expand Down Expand Up @@ -319,7 +319,7 @@
}

Check notice on line 320 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View check run for this annotation

codefactor.io / CodeFactor

ImperatorToCK3/CK3/Characters/DNAFactory.cs#L72-L320

Complex Method
private void ConvertBaldness(Imperator.Characters.Character irCharacter, Dictionary<string, DNAGeneValue> morphDNAValues, Dictionary<string, DNAAccessoryGeneValue> accessoryDNAValues) {
if (irCharacter.IsBald) { // TODO: CHECK IF BALD CHARACTERS STILL CORRECTLY APPEAR BALD IN CK3

Check warning on line 322 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (self-hosted, linux)

TODO CHECK IF BALD CHARACTERS STILL CORRECTLY APPEAR BALD IN CK3 (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 322 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (macos-14)

TODO CHECK IF BALD CHARACTERS STILL CORRECTLY APPEAR BALD IN CK3 (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 322 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / build (self-hosted, windows)

TODO CHECK IF BALD CHARACTERS STILL CORRECTLY APPEAR BALD IN CK3 (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 322 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test (macos-14)

TODO CHECK IF BALD CHARACTERS STILL CORRECTLY APPEAR BALD IN CK3 (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 322 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test_and_check_coverage

TODO CHECK IF BALD CHARACTERS STILL CORRECTLY APPEAR BALD IN CK3 (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)

Check warning on line 322 in ImperatorToCK3/CK3/Characters/DNAFactory.cs

View workflow job for this annotation

GitHub Actions / test (self-hosted, windows)

TODO CHECK IF BALD CHARACTERS STILL CORRECTLY APPEAR BALD IN CK3 (https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md)
morphDNAValues["gene_baldness"] = new DNAGeneValue {
TemplateName = "male_pattern_baldness",
IntSliderValue = 127,
Expand Down Expand Up @@ -419,7 +419,7 @@

var validCK3TemplateIds = ck3Gene.GeneTemplates
.Select(template => template.Id)
.ToList();
.ToArray();

var ck3GeneTemplateName = accessoryGeneMapper.GetTemplateFromTemplate(imperatorGeneName, geneInfo.GeneTemplate, validCK3TemplateIds);
if (ck3GeneTemplateName is null) {
Expand Down Expand Up @@ -513,9 +513,9 @@
var excludedAgeTemplateNames = new List<string> {"old_beauty_1", "no_aging"};
var possibleAgeTemplates = ck3Gene.GeneTemplates
.Where(t => !excludedAgeTemplateNames.Contains(t.Id))
.ToList();
var selectedTemplateName = possibleAgeTemplates[(int)(irCharacter.Id % (ulong)possibleAgeTemplates.Count)].Id;
var selectedTemplateRecessiveName = possibleAgeTemplates[(int)(irCharacter.Age % possibleAgeTemplates.Count)].Id;
.ToArray();
var selectedTemplateName = possibleAgeTemplates[(int)(irCharacter.Id % (ulong)possibleAgeTemplates.Length)].Id;
var selectedTemplateRecessiveName = possibleAgeTemplates[(int)(irCharacter.Age % possibleAgeTemplates.Length)].Id;

return new DNAGeneValue {
TemplateName = selectedTemplateName,
Expand Down
6 changes: 3 additions & 3 deletions ImperatorToCK3/CK3/Dynasties/Dynasty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ public Dynasty(Family irFamily, CharacterCollection irCharacters, CulturesDB irC
var imperatorMemberIds = irFamily.MemberIds;
var imperatorMembers = irCharacters
.Where(c => imperatorMemberIds.Contains(c.Id))
.ToList();
.ToArray();

SetCultureFromImperator(irFamily, imperatorMembers, cultureMapper, date);

foreach (var member in imperatorMembers) {
var ck3Member = member.CK3Character;
ck3Member?.SetDynastyId(Id, null);
ck3Member?.SetDynastyId(Id, date: null);
}

SetLocFromImperatorFamilyName(irFamily.GetMaleForm(irCulturesDB), locDB);
Expand Down Expand Up @@ -89,7 +89,7 @@ private void SetCultureFromImperator(Family irFamily, IReadOnlyList<Character> i
}

// Try to set culture from other members.
var otherImperatorMembers = irMembers.Skip(1).ToList();
var otherImperatorMembers = irMembers.Skip(1).ToArray();
foreach (var otherImperatorMember in otherImperatorMembers) {
if (otherImperatorMember.CK3Character is null) {
continue;
Expand Down
24 changes: 12 additions & 12 deletions ImperatorToCK3/CK3/Dynasties/DynastyCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public void ImportImperatorFamilies(Imperator.World irWorld, CultureMapper cultu
Interlocked.Increment(ref importedCount);
});
Logger.Info($"{importedCount} total families imported.");

CreateDynastiesForCharactersFromMinorFamilies(irWorld, locDB, date);

Logger.IncrementProgress();
Expand All @@ -49,19 +49,19 @@ public void LoadCK3Dynasties(ModFilesystem ck3ModFS) {

private void CreateDynastiesForCharactersFromMinorFamilies(Imperator.World irWorld, LocDB locDB, Date date) {
Logger.Info("Creating dynasties for characters from minor families...");

var relevantImperatorCharacters = irWorld.Characters
.Where(c => c.CK3Character is not null && c.Family is not null && c.Family.Minor)
.Where(c => c.CK3Character is not null && c.Family?.Minor == true)
.OrderBy(c => c.Id)
.ToList();
.ToArray();

int createdDynastiesCount = 0;
foreach (var irCharacter in relevantImperatorCharacters) {
var irFamilyName = irCharacter.FamilyName;
if (string.IsNullOrEmpty(irFamilyName)) {
continue;
}

var ck3Character = irCharacter.CK3Character!;
if (ck3Character.GetDynastyId(date) is not null) {
continue;
Expand All @@ -75,13 +75,13 @@ private void CreateDynastiesForCharactersFromMinorFamilies(Imperator.World irWor
continue;
}
}

// Neither character nor their father have a dynasty, so we need to create a new one.
var newDynasty = new Dynasty(ck3Character, irFamilyName, irWorld.CulturesDB, locDB, date);
Add(newDynasty);
++createdDynastiesCount;
}

Logger.Info($"Created {createdDynastiesCount} dynasties for characters from minor families.");
}

Expand All @@ -100,23 +100,23 @@ public void SetCoasForRulingDynasties(Title.LandedTitles titles, Date date) {

public void PurgeUnneededDynasties(CharacterCollection characters, Date date) {
Logger.Info("Purging unneeded dynasties...");

HashSet<string> dynastiesToKeep = [];
foreach (var character in characters) {
var dynastyId = character.GetDynastyId(date);
if (dynastyId is not null) {
dynastiesToKeep.Add(dynastyId);
}
}

int removedCount = 0;
foreach (var dynasty in this.ToList()) {
foreach (var dynasty in this.ToArray()) {
if (!dynastiesToKeep.Contains(dynasty.Id)) {
Remove(dynasty.Id);
++removedCount;
}
}

Logger.Info($"Purged {removedCount} unneeded dynasties.");
}
}
4 changes: 2 additions & 2 deletions ImperatorToCK3/CK3/Dynasties/HouseCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace ImperatorToCK3.CK3.Dynasties;
public sealed class HouseCollection : ConcurrentIdObjectCollection<string, House> {
public void LoadCK3Houses(ModFilesystem ck3ModFS) {
Logger.Info("Loading dynasty houses from CK3...");

var parser = new Parser();
parser.RegisterRegex(CommonRegexes.String, (reader, houseId) => {
var house = new House(houseId, reader);
Expand All @@ -31,7 +31,7 @@ public void PurgeUnneededHouses(CharacterCollection ck3Characters, Date date) {
.ToHashSet();

int removedCount = 0;
foreach (var house in this.ToList()) {
foreach (var house in this.ToArray()) {
if (houseIdsToKeep.Contains(house.Id)) {
continue;
}
Expand Down
Loading
Loading