Skip to content

Commit

Permalink
Rajas of Asia support (#2432) #minor
Browse files Browse the repository at this point in the history
closes #2431 
closes #2404

---------

Co-authored-by: tanner918 <30297148+tanner918@users.noreply.github.com>
Co-authored-by: codefactor-io <support@codefactor.io>
  • Loading branch information
3 people authored Jan 22, 2025
1 parent 4e7f038 commit 4b91655
Show file tree
Hide file tree
Showing 70 changed files with 20,869 additions and 1,731 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/build_dev_version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ jobs:
# global-json-file: global.json
- name: "Build backend"
working-directory: ImperatorToCK3
# Make sure it builds self-contained, because for the dev build we're not building the InnoSetup installer.
run: |
dotnet publish -p:PublishProfile=${{ matrix.build }} -c:Release --output:"../Publish/ImperatorToCK3"
dotnet publish -p:PublishProfile=${{ matrix.build }} -c:Release --output:"../Publish/ImperatorToCK3" -p:SelfContained=true
- name: Archive Publish folder
uses: thedoctor0/zip-release@master
with:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class CultureCollectionTests {
private static readonly ModFilesystem ck3ModFS = new("TestFiles/CK3/game", Array.Empty<Mod>());
private static readonly PillarCollection pillars;
private static readonly ColorFactory colorFactory = new();
private static readonly OrderedDictionary<string, bool> ck3ModFlags = [];
private static readonly OrderedDictionary<string, bool> ck3ModFlags = new() {{"tfe", false}, {"wtwsms", false}, {"roa", false}};

static CultureCollectionTests() {
pillars = new PillarCollection(colorFactory, []) {
Expand Down Expand Up @@ -51,7 +51,7 @@ public void ConverterHeritageCanBeMergedIntoExistingHeritage() {
Assert.Single(cultures);

cultures.AddNameList(new NameList("name_list_albanian", new BufferedReader()));
cultures.LoadConverterPillars("TestFiles/CK3/CultureCollectionTests/configurables/converter_pillars");
cultures.LoadConverterPillars("TestFiles/CK3/CultureCollectionTests/configurables/converter_pillars", ck3ModFlags);
cultures.LoadConverterCultures("TestFiles/CK3/CultureCollectionTests/configurables/converter_cultures.txt");

Assert.Equal(2, cultures.Count);
Expand All @@ -71,7 +71,7 @@ public void ConverterLanguageCanBeMergedIntoExistingLanguage() {
cultures.AddPillar(new("language_illyrian", new() {Type = "language"}));

cultures.AddNameList(new NameList("name_list_albanian", new BufferedReader()));
cultures.LoadConverterPillars("TestFiles/CK3/CultureCollectionTests/configurables/converter_pillars");
cultures.LoadConverterPillars("TestFiles/CK3/CultureCollectionTests/configurables/converter_pillars", ck3ModFlags);
cultures.LoadConverterCultures("TestFiles/CK3/CultureCollectionTests/configurables/converter_cultures.txt");

Assert.Equal(2, cultures.Count);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using commonItems.Mods;
using ImperatorToCK3.CK3.Cultures;
using System;
using System.Collections.Generic;
using System.IO;
using Xunit;

Expand All @@ -18,13 +19,14 @@ public void WarningIsLoggedWhenPillarDataIsMissingType() {
var pillarsFile = File.CreateText("pillars_test/common/culture/pillars/test_pillars.txt");
pillarsFile.WriteLine("pillar_without_type = {}");
pillarsFile.Close();


OrderedDictionary<string, bool> ck3ModFlags = [];
var modFS = new ModFilesystem("pillars_test", Array.Empty<Mod>());
var collection = new PillarCollection(new commonItems.Colors.ColorFactory(), []);
var collection = new PillarCollection(new commonItems.Colors.ColorFactory(), ck3ModFlags);

var consoleOut = new StringWriter();
Console.SetOut(consoleOut);
collection.LoadPillars(modFS);
collection.LoadPillars(modFS, ck3ModFlags);
Assert.Contains("[WARN] Pillar pillar_without_type has no type defined! Skipping.", consoleOut.ToString());
}
}
2 changes: 1 addition & 1 deletion ImperatorToCK3.UnitTests/CK3/Titles/TitleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private class TitleBuilder {
"TestFiles/configurables/governorMappings.txt",
"TestFiles/configurables/country_rank_map.txt");
private GovernmentMapper governmentMapper = new(ck3GovernmentIds: Array.Empty<string>());
private SuccessionLawMapper successionLawMapper = new("TestFiles/configurables/succession_law_map.txt");
private SuccessionLawMapper successionLawMapper = new("TestFiles/configurables/succession_law_map.liquid", ck3ModFlags: []);
private DefiniteFormMapper definiteFormMapper = new("TestFiles/configurables/definite_form_names.txt");

private readonly ReligionMapper religionMapper;
Expand Down
2 changes: 1 addition & 1 deletion ImperatorToCK3.UnitTests/ImperatorToCK3.UnitTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AwesomeAssertions" Version="8.0.0-rc.3" />
<PackageReference Include="coverlet.msbuild" Version="6.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" Version="8.0.0-rc.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.1">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using commonItems;
using ImperatorToCK3.CK3.Titles;
using ImperatorToCK3.Mappers.Government;
using System.Collections.Generic;
using Xunit;
Expand All @@ -10,22 +11,22 @@ public class GovernmentMapperTests {
public void NonMatchGivesNull() {
var reader = new BufferedReader("link = { ck3 = ck3Government ir = irGovernment }");
var mapper = new GovernmentMapper(reader, ck3GovernmentIds: new List<string> { "ck3Government" });
var ck3Gov = mapper.GetCK3GovernmentForImperatorGovernment("nonMatchingGovernment", null, []);
var ck3Gov = mapper.GetCK3GovernmentForImperatorGovernment("nonMatchingGovernment", rank: null, irCultureId: null, []);
Assert.Null(ck3Gov);
}
[Fact]
public void CK3GovernmentCanBeFound() {
var reader = new BufferedReader("link = { ck3 = ck3Government ir = irGovernment }");
var mapper = new GovernmentMapper(reader, ck3GovernmentIds: new List<string> { "ck3Government" });
var ck3Gov = mapper.GetCK3GovernmentForImperatorGovernment("irGovernment", null, []);
var ck3Gov = mapper.GetCK3GovernmentForImperatorGovernment("irGovernment", rank: null, irCultureId: null, []);
Assert.Equal("ck3Government", ck3Gov);
}
[Fact]
public void MultipleImperatorGovernmentsCanBeInARule() {
var reader = new BufferedReader("link = { ck3 = ck3Government ir = irGovernment ir = irGovernment2 }");
var mapper = new GovernmentMapper(reader, ck3GovernmentIds: new List<string> { "ck3Government" });
var ck3Gov1 = mapper.GetCK3GovernmentForImperatorGovernment("irGovernment", null, []);
var ck3Gov2 = mapper.GetCK3GovernmentForImperatorGovernment("irGovernment2", null, []);
var ck3Gov1 = mapper.GetCK3GovernmentForImperatorGovernment("irGovernment", rank: null, irCultureId: null, []);
var ck3Gov2 = mapper.GetCK3GovernmentForImperatorGovernment("irGovernment2", rank: null, irCultureId: null, []);
Assert.Equal("ck3Government", ck3Gov1);
Assert.Equal("ck3Government", ck3Gov2);
}
Expand All @@ -36,7 +37,7 @@ public void CorrectRuleMatches() {
"link = { ck3 = ck3Government2 ir = irGovernment2 }"
);
var mapper = new GovernmentMapper(reader, ck3GovernmentIds: new List<string> { "ck3Government", "ck3Government2" });
var ck3Gov = mapper.GetCK3GovernmentForImperatorGovernment("irGovernment2", null, []);
var ck3Gov = mapper.GetCK3GovernmentForImperatorGovernment("irGovernment2", rank: null, irCultureId: null, []);
Assert.Equal("ck3Government2", ck3Gov);
}

Expand All @@ -48,10 +49,32 @@ public void CultureCanBeUsedToMatch() {
"link = { ck3 = govC ir = irGovernment }"
);
var mapper = new GovernmentMapper(reader, ck3GovernmentIds: new List<string> { "govA", "govB", "govC" });
Assert.Equal("govA", mapper.GetCK3GovernmentForImperatorGovernment("irGovernment", "roman", []));
Assert.Equal("govB", mapper.GetCK3GovernmentForImperatorGovernment("irGovernment", "greek", []));
Assert.Equal("govC", mapper.GetCK3GovernmentForImperatorGovernment("irGovernment", "thracian", []));
Assert.Equal("govC", mapper.GetCK3GovernmentForImperatorGovernment("irGovernment", null, []));
Assert.Equal("govA", mapper.GetCK3GovernmentForImperatorGovernment("irGovernment", rank: null, "roman", []));
Assert.Equal("govB", mapper.GetCK3GovernmentForImperatorGovernment("irGovernment", rank: null, "greek", []));
Assert.Equal("govC", mapper.GetCK3GovernmentForImperatorGovernment("irGovernment", rank: null, "thracian", []));
Assert.Equal("govC", mapper.GetCK3GovernmentForImperatorGovernment("irGovernment", rank: null, irCultureId: null, []));
}

[Fact]
public void CK3TitleRankCanBeUsedToMatch() {
var reader = new BufferedReader(
"""
link = { ck3 = administrative_government ir = imperium ck3_title_rank = ke } # only for kingdoms and empires
link = { ck3 = feudal_government ir = imperium }
"""
);
var mapper = new GovernmentMapper(reader, ck3GovernmentIds: [ "administrative_government", "feudal_government" ]);

foreach (var rank in new List<TitleRank> { TitleRank.empire, TitleRank.kingdom }) {
Assert.Equal("administrative_government",
mapper.GetCK3GovernmentForImperatorGovernment(
irGovernmentId: "imperium", rank, irCultureId: null, enabledCK3Dlcs: []));
}
foreach (var rank in new List<TitleRank> { TitleRank.duchy, TitleRank.county, TitleRank.barony }) {
Assert.Equal("feudal_government",
mapper.GetCK3GovernmentForImperatorGovernment(
irGovernmentId: "imperium", rank, irCultureId: null, enabledCK3Dlcs: []));
}
}

[Fact]
Expand All @@ -70,7 +93,7 @@ public void CK3DlcCanBeUsedToMatch() {
""");
var mapper = new GovernmentMapper(reader, ck3GovernmentIds: [ "administrative_government", "feudal_government" ]);

Assert.Equal("administrative_government", mapper.GetCK3GovernmentForImperatorGovernment("imperium", null, enabledCK3Dlcs: ["roads_to_power"]));
Assert.Equal("feudal_government", mapper.GetCK3GovernmentForImperatorGovernment("imperium", null, enabledCK3Dlcs: []));
Assert.Equal("administrative_government", mapper.GetCK3GovernmentForImperatorGovernment("imperium", rank: null, irCultureId: null, enabledCK3Dlcs: ["roads_to_power"]));
Assert.Equal("feudal_government", mapper.GetCK3GovernmentForImperatorGovernment("imperium", rank: null, irCultureId: null, enabledCK3Dlcs: []));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,25 @@ namespace ImperatorToCK3.UnitTests.Mappers.SuccessionLaw;
[Collection("Sequential")]
[CollectionDefinition("Sequential", DisableParallelization = true)]
public class SuccessionLawMapperTests {
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(impLaws: ["madeUpLaw"], irGovernment: null, 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(impLaws: ["implaw"], irGovernment: null, enabledCK3Dlcs);
Assert.Equal(["ck3law"], ck3Laws);
}

[Fact]
Expand All @@ -42,28 +45,82 @@ 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(impLaws: ["implaw", "implaw3"], irGovernment: null, enabledCK3Dlcs);
var expectedReturnedLaws = new SortedSet<string> { "ck3law", "ck3law2", "ck3law5" };
Assert.Equal(expectedReturnedLaws, ck3Laws);
}

[Fact]
public void EnabledCK3DlcsCanBeUsedInMappings() {
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(
impLaws: ["implaw"],
irGovernment: null,
enabledCK3Dlcs:["roads_to_power"]);
Assert.Equal(["ck3lawForDLC"], ck3LawsWithDlc);

var ck3LawsWithoutDlc = mapper.GetCK3LawsForImperatorLaws(
impLaws: ["implaw"],
irGovernment: null,
enabledCK3Dlcs: []);
Assert.Equal(["ck3law"], ck3LawsWithoutDlc);
}

[Fact]
public void ImperatorGovernmentCanBeUsedInMappings() {
var reader = new BufferedReader(
"""
link = { ir=implaw ck3=ck3law1 ir_government=imperium ir_government=imperial_cult }
link = { ir=implaw ck3=ck3law2 }
"""
);
var mapper = new SuccessionLawMapper(reader);

var ck3LawsWithImperialGov = mapper.GetCK3LawsForImperatorLaws(
impLaws: ["implaw"],
irGovernment: "imperium",
enabledCK3Dlcs: enabledCK3Dlcs);
Assert.Equal(["ck3law1"], ck3LawsWithImperialGov);

var ck3LawsWithoutImperialGov = mapper.GetCK3LawsForImperatorLaws(
impLaws: ["implaw"],
irGovernment: "imperial_cult",
enabledCK3Dlcs: enabledCK3Dlcs);
Assert.Equal(["ck3law1"], ck3LawsWithoutImperialGov);

var ck3LawsWithoutImperatorGov = mapper.GetCK3LawsForImperatorLaws(
impLaws: ["implaw"],
irGovernment: "madeUpGov",
enabledCK3Dlcs: enabledCK3Dlcs);
Assert.Equal(["ck3law2"], ck3LawsWithoutImperatorGov);
}

[Fact]
public void MappingsAreReadFromFile() {
var mapper = new SuccessionLawMapper("TestFiles/configurables/succession_law_map.txt");
var mapper = new SuccessionLawMapper("TestFiles/configurables/succession_law_map.liquid", ck3ModFlags);
Assert.Equal(
new SortedSet<string> { "ck3law1", "ck3law2" },
mapper.GetCK3LawsForImperatorLaws(new() { "implaw1" })
["ck3law1", "ck3law2"],
mapper.GetCK3LawsForImperatorLaws(impLaws: ["implaw1"], irGovernment: null, enabledCK3Dlcs)
);
Assert.Equal(
new SortedSet<string> { "ck3law3" },
mapper.GetCK3LawsForImperatorLaws(new() { "implaw2" })
["ck3law3"],
mapper.GetCK3LawsForImperatorLaws(impLaws: ["implaw2"], irGovernment: null, enabledCK3Dlcs)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ namespace ImperatorToCK3.UnitTests.TestHelpers;
private static readonly ColorFactory colorFactory = new();
private static readonly OrderedDictionary<string, bool> ck3ModFlags = [];

public void LoadConverterPillars(string filePath) {
PillarCollection.LoadConverterPillars(filePath);
public void LoadConverterPillars(string filePath, OrderedDictionary<string, bool> ck3ModFlags) {
PillarCollection.LoadConverterPillars(filePath, ck3ModFlags);
}

public void AddNameList(NameList nameList) {
Expand Down
1 change: 1 addition & 0 deletions ImperatorToCK3.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=pontifex/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Provs/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Qahtanite/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=rajas/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=rakaly/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=rankless/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Rechtabra/@EntryIndexedValue">True</s:Boolean>
Expand Down
4 changes: 4 additions & 0 deletions ImperatorToCK3/CK3/Characters/Character.cs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@ public string? DeathReason {
.WithLiteralField("if", "if")
.WithSimpleField("sexuality", "sexuality", null)
.WithLiteralField("domicile", "domicile")
.WithLiteralField("create_maa_regiment", "create_maa_regiment")
.WithSimpleField("add_gold", "add_gold", null)
.WithSimpleField("add_piety_level", "add_piety_level", null)
.WithSimpleField("add_prestige_level", "add_prestige_level", null)
.Build();

public History History { get; } = historyFactory.GetHistory();
Expand Down
15 changes: 14 additions & 1 deletion ImperatorToCK3/CK3/Characters/CharactersLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,18 @@ public void LoadCK3Characters(ModFilesystem ck3ModFS, Date bookmarkDate) {
loadedCharacters.Add(character);
});
parser.IgnoreAndLogUnregisteredItems();
parser.ParseGameFolder("history/characters", ck3ModFS, "txt", recursive: true, parallel: true);
parser.ParseGameFolder("history/characters", ck3ModFS, "txt", recursive: true);

// Make all animation_test_ characters die on 2.1.1.
foreach (var character in loadedCharacters) {
if (!character.Id.StartsWith("animation_test_")) {
continue;
}

var deathField = character.History.Fields["death"];
deathField.RemoveAllEntries();
deathField.AddEntryToHistory(new Date(2, 1, 1), "death", value: true);
}

string[] irrelevantEffects = ["set_relation_rival", "set_relation_potential_rival", "set_relation_nemesis",
"set_relation_lover", "set_relation_soulmate",
Expand Down Expand Up @@ -86,6 +97,8 @@ public void LoadCK3Characters(ModFilesystem ck3ModFS, Date bookmarkDate) {
character.InitConcubinesCache();
character.UpdateChildrenCacheOfParents();
}

Logger.Info("Loaded CK3 characters.");
}

private static void RemoveInvalidMotherAndFatherEntries(Character character, HashSet<string> femaleCharacterIds, HashSet<string> maleCharacterIds) {
Expand Down
7 changes: 7 additions & 0 deletions ImperatorToCK3/CK3/Cultures/Pillar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ internal sealed class Pillar : IIdentifiable<string>, IPDXSerializable {
public string Id { get; }
public string Type { get; }
public Color? Color { get; }
private readonly Dictionary<string, string> parameters;
public IReadOnlyDictionary<string, string> Parameters => parameters;
private readonly List<KeyValuePair<string, StringOfItem>> attributes;
public IReadOnlyCollection<KeyValuePair<string, StringOfItem>> Attributes => attributes;

Expand All @@ -19,6 +21,7 @@ public Pillar(string id, PillarData pillarData) {

Type = pillarData.Type!;
Color = pillarData.Color;
parameters = new(pillarData.Parameters);
attributes = new List<KeyValuePair<string, StringOfItem>>(pillarData.Attributes);
}

Expand All @@ -37,6 +40,10 @@ public string Serialize(string indent, bool withBraces) {
if (Color is not null) {
sb.Append(contentIndent).AppendLine($"color={Color}");
}
if (parameters.Count > 0) {
sb.Append(contentIndent).Append("parameters=")
.AppendLine(PDXSerializer.Serialize(parameters, indent: contentIndent, withBraces: true));
}
sb.AppendLine(PDXSerializer.Serialize(Attributes, indent: contentIndent, withBraces: false));

if (withBraces) {
Expand Down
Loading

0 comments on commit 4b91655

Please sign in to comment.