Skip to content

Fix blank ruling dynasty CoA when held title comes from vanilla CK3 #2140

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 4 commits into from
Sep 5, 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
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public async Task CoaIsOutputtedForCountryWithFlagSet() {
new List<KeyValuePair<Country, Dependency?>>()
);

await CoatOfArmsOutputter.OutputCoas(outputModPath, titles, new List<Dynasty>());
await CoatOfArmsOutputter.OutputCoas(outputModPath, titles, new List<Dynasty>(), new CoaMapper());

await using var file = File.OpenRead(outputPath);
var reader = new StreamReader(file);
Expand Down Expand Up @@ -122,7 +122,7 @@ public async Task CoaIsNotOutputtedForCountryWithoutFlagSet() {
new List<KeyValuePair<Country, Dependency?>>()
);

await CoatOfArmsOutputter.OutputCoas(outputModPath, titles, new List<Dynasty>());
await CoatOfArmsOutputter.OutputCoas(outputModPath, titles, new List<Dynasty>(), new CoaMapper());

await using var file = File.OpenRead(outputPath);
var reader = new StreamReader(file);
Expand Down
17 changes: 17 additions & 0 deletions ImperatorToCK3/CK3/Titles/LandedTitles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1520,5 +1520,22 @@ public void LoadCulturalNamesFromConfigurables() {
parser.IgnoreAndLogUnregisteredItems();
parser.ParseFile(filePath);
}

public void SetCoatsOfArms(CoaMapper coaMapper) {
Logger.Info("Setting coats of arms for CK3 titles...");

int counter = 0;
foreach (var title in this) {
var coa = coaMapper.GetCoaForFlagName(title.Id, warnIfMissing: false);
if (coa is null) {
continue;
}

title.CoA = coa;
++counter;
}

Logger.Debug($"Set coats of arms for {counter} CK3 titles.");
}
}
}
5 changes: 5 additions & 0 deletions ImperatorToCK3/CK3/World.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public sealed class World {
public MapData MapData { get; }
public IList<Wars.War> Wars { get; } = new List<Wars.War>();
public LegendSeedCollection LegendSeeds { get; } = [];
public CoaMapper CK3CoaMapper { get; }

/// <summary>
/// Date based on I:R save date, but normalized for CK3 purposes.
Expand Down Expand Up @@ -142,6 +143,10 @@ public World(Imperator.World impWorld, Configuration config) {

Logger.IncrementProgress();
}

CK3CoaMapper = new(ModFS);
LandedTitles.SetCoatsOfArms(CK3CoaMapper);

LandedTitles.LoadHistory(config, ModFS);
LandedTitles.LoadCulturalNamesFromConfigurables();

Expand Down
25 changes: 20 additions & 5 deletions ImperatorToCK3/Mappers/CoA/CoaMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@ namespace ImperatorToCK3.Mappers.CoA;

public sealed class CoaMapper {
public CoaMapper() { }
public CoaMapper(ModFilesystem imperatorModFS) {
public CoaMapper(ModFilesystem modFS) {
Logger.Info("Parsing CoAs...");
var parser = new Parser();
RegisterKeys(parser);
const string coasPath = "common/coat_of_arms/coat_of_arms";
parser.ParseGameFolder(coasPath, imperatorModFS, "txt", recursive: true);
parser.ParseGameFolder(coasPath, modFS, "txt", recursive: true);

Logger.Info($"Loaded {coasMap.Count} coats of arms.");

Logger.IncrementProgress();
}
private void RegisterKeys(Parser parser) {
parser.RegisterRegex(CommonRegexes.Variable, (reader, variableName) => { // for variables like "@smCross = 0.22"
var variableValue = reader.GetString();
variablesToOutput[variableName[1..]] = variableValue;
});
parser.RegisterKeyword("template", ParserHelpers.IgnoreItem); // we don't need templates, we need CoAs!
parser.RegisterRegex(CommonRegexes.Catchall, (reader, flagName) => coasMap[flagName] = reader.GetStringOfItem().ToString());
}
Expand All @@ -31,20 +35,31 @@ public void ParseCoAs(IEnumerable<string> coaDefinitionStrings) {
}
}

public string? GetCoaForFlagName(string irFlagName) {
if (!coasMap.TryGetValue(irFlagName, out string? value)) {
Logger.Warn($"No CoA defined for flag name {irFlagName}.");
public string? GetCoaForFlagName(string flagName) {
return GetCoaForFlagName(flagName, warnIfMissing: true);
}

public string? GetCoaForFlagName(string flagName, bool warnIfMissing) {
if (!coasMap.TryGetValue(flagName, out string? value)) {
if (warnIfMissing) {
Logger.Warn($"No CoA defined for flag name {flagName}.");
}
return null;
}

return value;
}

/// <summary>
/// For a given collection of flag names, returns ones that don't have a defined CoA.
/// </summary>
public ISet<string> GetAllMissingFlagKeys(IEnumerable<string> flagKeys) {
var existingFlagKeys = coasMap.Keys.ToHashSet();
return flagKeys.Where(flagKey => !existingFlagKeys.Contains(flagKey)).ToHashSet();
}

private readonly Dictionary<string, string> coasMap = [];

private readonly Dictionary<string, object> variablesToOutput = new();
public IReadOnlyDictionary<string, object> VariablesToOutput => variablesToOutput;
}
10 changes: 8 additions & 2 deletions ImperatorToCK3/Outputter/CoatOfArmsOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using commonItems.Mods;
using ImperatorToCK3.CK3.Dynasties;
using ImperatorToCK3.CK3.Titles;
using ImperatorToCK3.Mappers.CoA;
using System;
using System.Collections.Generic;
using System.IO;
Expand All @@ -10,11 +11,16 @@

namespace ImperatorToCK3.Outputter;
public static class CoatOfArmsOutputter {
public static async Task OutputCoas(string outputModPath, Title.LandedTitles titles, IEnumerable<Dynasty> dynasties) {
public static async Task OutputCoas(string outputModPath, Title.LandedTitles titles, IEnumerable<Dynasty> dynasties, CoaMapper ck3CoaMapper) {
Logger.Info("Outputting coats of arms...");

// Output variables (like "@smCastleX = 0.27" in vanilla CK3).
var sb = new System.Text.StringBuilder();
foreach (var (variableName, variableValue) in ck3CoaMapper.VariablesToOutput) {
sb.AppendLine($"@{variableName}={variableValue}");
}

// Output CoAs for titles.
var sb = new System.Text.StringBuilder();
foreach (var title in titles) {
var coa = title.CoA;
if (coa is not null) {
Expand Down
2 changes: 1 addition & 1 deletion ImperatorToCK3/Outputter/WorldOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public static void OutputWorld(World ck3World, Imperator.World imperatorWorld, C
NamedColorsOutputter.OutputNamedColors(outputPath, imperatorWorld.NamedColors, ck3World.NamedColors),

CoatOfArmsEmblemsOutputter.CopyEmblems(outputPath, imperatorWorld.ModFS),
CoatOfArmsOutputter.OutputCoas(outputPath, ck3World.LandedTitles, ck3World.Dynasties),
CoatOfArmsOutputter.OutputCoas(outputPath, ck3World.LandedTitles, ck3World.Dynasties, ck3World.CK3CoaMapper),
Task.Run(() => CoatOfArmsOutputter.CopyCoaPatterns(imperatorWorld.ModFS, outputPath)),

BookmarkOutputter.OutputBookmark(ck3World, config, ck3World.LocDB)
Expand Down
Loading