Skip to content

Commit

Permalink
Support has_ck3_dlc parameter in succession law mappings
Browse files Browse the repository at this point in the history
  • Loading branch information
IhateTrains committed Jan 20, 2025
1 parent b713452 commit e75daa8
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,25 @@ namespace ImperatorToCK3.UnitTests.Mappers.SuccessionLaw;
[Collection("Sequential")]
[CollectionDefinition("Sequential", DisableParallelization = true)]
public class SuccessionLawMapperTests {
private static OrderedDictionary<string, bool> ck3ModFlags = [];
private static readonly OrderedDictionary<string, bool> ck3ModFlags = [];
private static readonly string[] enabledCK3Dlcs = [];

[Fact]
public void NonMatchGivesEmptySet() {
var reader = new BufferedReader("link = { ir=implaw ck3 = ck3law }");
var mapper = new SuccessionLawMapper(reader);

var ck3Laws = mapper.GetCK3LawsForImperatorLaws(new SortedSet<string> { "madeUpLaw" });
var ck3Laws = mapper.GetCK3LawsForImperatorLaws(["madeUpLaw"], enabledCK3Dlcs);
Assert.Empty(ck3Laws);
}

[Fact]
public void Ck3LawCanBeFound() {
public void CK3LawCanBeFound() {
var reader = new BufferedReader("link = { ir=implaw ck3 = ck3law }");
var mapper = new SuccessionLawMapper(reader);

var ck3Laws = mapper.GetCK3LawsForImperatorLaws(new SortedSet<string> { "implaw" });
Assert.Equal(new SortedSet<string> { "ck3law" }, ck3Laws);
var ck3Laws = mapper.GetCK3LawsForImperatorLaws(["implaw"], enabledCK3Dlcs);
Assert.Equal(["ck3law"], ck3Laws);
}

[Fact]
Expand All @@ -44,28 +45,47 @@ public void LinkWithNoCK3LawResultsInWarning() {
[Fact]
public void MultipleLawsCanBeReturned() {
var reader = new BufferedReader(
"link = { ir=implaw ck3 = ck3law ck3 = ck3law2 }\n" +
"link = { ir=implaw ck3 = ck3law3 }\n" +
"link = { ir=implaw2 ck3 = ck3law4 }\n" +
"link = { ir=implaw3 ck3 = ck3law5 }\n"
"""
link = { ir=implaw ck3 = ck3law ck3 = ck3law2 }
link = { ir=implaw ck3 = ck3law3 } # Will not be used because the first link matches implaw
link = { ir=implaw2 ck3 = ck3law4 }
link = { ir=implaw3 ck3 = ck3law5 }
"""
);
var mapper = new SuccessionLawMapper(reader);

var ck3Laws = mapper.GetCK3LawsForImperatorLaws(new SortedSet<string> { "implaw", "implaw3" });
var expectedReturnedLaws = new SortedSet<string> { "ck3law", "ck3law2", "ck3law3", "ck3law5" };
var ck3Laws = mapper.GetCK3LawsForImperatorLaws(["implaw", "implaw3"], enabledCK3Dlcs);
var expectedReturnedLaws = new SortedSet<string> { "ck3law", "ck3law2", "ck3law5" };
Assert.Equal(expectedReturnedLaws, ck3Laws);
}

[Fact]
public void EnabledDlcsCanBeUsedInMappings() {
var reader = new BufferedReader(
"""
link = { ir=implaw ck3=ck3lawForDLC has_ck3_dlc=roads_to_power }
link = { ir=implaw ck3=ck3law }
"""
);
var mapper = new SuccessionLawMapper(reader);

var ck3LawsWithDlc = mapper.GetCK3LawsForImperatorLaws(["implaw"], ["roads_to_power"]);
Assert.Equal(["ck3lawForDLC"], ck3LawsWithDlc);

var ck3LawsWithoutDlc = mapper.GetCK3LawsForImperatorLaws(["implaw"], []);
Assert.Equal(["ck3law"], ck3LawsWithoutDlc);
}

[Fact]
public void MappingsAreReadFromFile() {
var mapper = new SuccessionLawMapper("TestFiles/configurables/succession_law_map.txt", ck3ModFlags);
Assert.Equal(
new SortedSet<string> { "ck3law1", "ck3law2" },
mapper.GetCK3LawsForImperatorLaws(new() { "implaw1" })
["ck3law1", "ck3law2"],
mapper.GetCK3LawsForImperatorLaws(["implaw1"], enabledCK3Dlcs)
);
Assert.Equal(
new SortedSet<string> { "ck3law3" },
mapper.GetCK3LawsForImperatorLaws(new() { "implaw2" })
["ck3law3"],
mapper.GetCK3LawsForImperatorLaws(["implaw2"], enabledCK3Dlcs)
);
}
}
2 changes: 1 addition & 1 deletion ImperatorToCK3/CK3/Titles/Title.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ IReadOnlyCollection<string> enabledCK3Dlcs
History.AddFieldValue(conversionDate,
"succession_laws",
"succession_laws",
successionLawMapper.GetCK3LawsForImperatorLaws(ImperatorCountry.GetLaws())
successionLawMapper.GetCK3LawsForImperatorLaws(ImperatorCountry.GetLaws(), enabledCK3Dlcs)
);

// Determine CoA.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

# CK3 has default succession laws

# For mappings with multiple ck3 laws, all laws will be written out
# For mappings with multiple ck3 laws, all laws will be written out.
# For a given Imperator law, only the first matching link will be used.


# Monarchy
Expand Down
29 changes: 15 additions & 14 deletions ImperatorToCK3/Mappers/SuccessionLaw/SuccessionLawMapper.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
using commonItems;
using commonItems.Collections;
using ImperatorToCK3.CK3;
using System.Collections.Generic;

namespace ImperatorToCK3.Mappers.SuccessionLaw;

public sealed class SuccessionLawMapper {
private readonly Dictionary<string, SortedSet<string>> impToCK3SuccessionLawMap = new();
private readonly List<SuccessionLawMapping> mappings = [];

public SuccessionLawMapper() { }
public SuccessionLawMapper(string filePath, OrderedDictionary<string, bool> ck3ModFlags) {
Logger.Info("Parsing succession law mappings...");
var parser = new Parser();
RegisterKeys(parser);
parser.ParseLiquidFile(filePath, ck3ModFlags);
Logger.Info($"Loaded {impToCK3SuccessionLawMap.Count} succession law links.");
Logger.Info($"Loaded {mappings.Count} succession law links.");

Logger.IncrementProgress();
}
Expand All @@ -24,23 +25,23 @@ public SuccessionLawMapper(BufferedReader reader) {
}
private void RegisterKeys(Parser parser) {
parser.RegisterKeyword("link", reader => {
var mapping = new SuccessionLawMapping(reader);
if (mapping.CK3SuccessionLaws.Count == 0) {
Logger.Warn("SuccessionLawMapper: link with no CK3 successions laws");
return;
}
if (!impToCK3SuccessionLawMap.TryAdd(mapping.ImperatorLaw, mapping.CK3SuccessionLaws)) {
impToCK3SuccessionLawMap[mapping.ImperatorLaw].UnionWith(mapping.CK3SuccessionLaws);
}
mappings.Add(new(reader));
});
parser.RegisterRegex(CommonRegexes.Catchall, ParserHelpers.IgnoreAndLogItem);
}
public SortedSet<string> GetCK3LawsForImperatorLaws(SortedSet<string> impLaws) {
var lawsToReturn = new SortedSet<string>();
public OrderedSet<string> GetCK3LawsForImperatorLaws(SortedSet<string> impLaws, IReadOnlyCollection<string> enabledCK3Dlcs) {
var lawsToReturn = new OrderedSet<string>();
foreach (var impLaw in impLaws) {
if (impToCK3SuccessionLawMap.TryGetValue(impLaw, out var ck3Laws)) {
lawsToReturn.UnionWith(ck3Laws);
foreach (var mapping in mappings) {
var match = mapping.Match(impLaw, enabledCK3Dlcs);
if (match is null) {
continue;
}

lawsToReturn.UnionWith(match);
break;
}

}

Check notice on line 45 in ImperatorToCK3/Mappers/SuccessionLaw/SuccessionLawMapper.cs

View check run for this annotation

codefactor.io / CodeFactor

ImperatorToCK3/Mappers/SuccessionLaw/SuccessionLawMapper.cs#L45

A closing brace should not be preceded by a blank line. (SA1508)
return lawsToReturn;
}
Expand Down
30 changes: 28 additions & 2 deletions ImperatorToCK3/Mappers/SuccessionLaw/SuccessionLawMapping.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,42 @@
using commonItems;
using commonItems.Collections;
using System.Collections.Generic;

namespace ImperatorToCK3.Mappers.SuccessionLaw;

internal sealed class SuccessionLawMapping {
public string ImperatorLaw { get; set; } = "";
public SortedSet<string> CK3SuccessionLaws { get; } = new();
private string ImperatorLaw { get; set; } = "";
private OrderedSet<string> CK3SuccessionLaws { get; } = [];
private HashSet<string> RequiredCK3Dlcs { get; } = [];

public SuccessionLawMapping(BufferedReader mappingReader) {
var parser = new Parser();
parser.RegisterKeyword("ir", reader => ImperatorLaw = reader.GetString());
parser.RegisterKeyword("ck3", reader => CK3SuccessionLaws.Add(reader.GetString()));
parser.RegisterKeyword("has_ck3_dlc", reader => RequiredCK3Dlcs.Add(reader.GetString()));
parser.RegisterRegex(CommonRegexes.Catchall, ParserHelpers.IgnoreAndLogItem);
parser.ParseStream(mappingReader);


if (CK3SuccessionLaws.Count == 0) {
Logger.Warn("SuccessionLawMapper: link with no CK3 successions laws");
}
}

internal OrderedSet<string>? Match(string irLaw, IReadOnlyCollection<string> enabledCK3Dlcs) {
if (irLaw != ImperatorLaw) {
return null;
}

if (RequiredCK3Dlcs.Count != 0) {
if (enabledCK3Dlcs.Count == 0) {
return null;
}
if (!RequiredCK3Dlcs.IsSubsetOf(enabledCK3Dlcs)) {
return null;
}
}

return new(CK3SuccessionLaws);

Check notice on line 40 in ImperatorToCK3/Mappers/SuccessionLaw/SuccessionLawMapping.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

ImperatorToCK3/Mappers/SuccessionLaw/SuccessionLawMapping.cs#L40

Remove the explicit nullable type creation; it is redundant.
}
}

0 comments on commit e75daa8

Please sign in to comment.