Skip to content
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

Use the Terra Indomita province mappings for the I:R Antiquitas mod #2367

Merged
merged 1 commit into from
Dec 16, 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
8 changes: 8 additions & 0 deletions ImperatorToCK3.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
<s:Boolean x:Key="/Default/Environment/Filtering/ExcludeCoverageFilters/=Fronter_003B_002A_003B_002A_003B_002A/@EntryIndexRemoved">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=adjacencies/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Adnanite/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=aegyptian/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Alexandros/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=angeBy/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Antigonid/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=antiquitas/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=apulia/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=aquitane/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=arberian/@EntryIndexedValue">True</s:Boolean>
Expand All @@ -42,6 +44,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=configurables/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Cornelli/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=cuman/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=cyrenaican/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=datacontext/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Defs/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=diadochi/@EntryIndexedValue">True</s:Boolean>
Expand All @@ -66,10 +69,13 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=IMPERATOR/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=IMPTOCK/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Incontinentia/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=indomita/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=instabuild/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Invicta/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=invictus/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=IRTOCK/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=italia/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=italiotian/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Jailor/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=jailors/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Jure/@EntryIndexedValue">True</s:Boolean>
Expand Down Expand Up @@ -98,6 +104,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Petair/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Phrygian/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Playset/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=pontic/@EntryIndexedValue">True</s:Boolean>
<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>
Expand All @@ -115,6 +122,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=shudra/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=simp/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=slovien/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=syracusan/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=tengri/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=toogle/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Travellers/@EntryIndexedValue">True</s:Boolean>
Expand Down
13 changes: 7 additions & 6 deletions ImperatorToCK3/CK3/World.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
ColorFactory ck3ColorFactory = new();
// Now that we have the mod filesystem, we can initialize the localization database.
Parallel.Invoke(
() => LoadCorrectProvinceMappingsFile(impWorld), // Depends on loaded mods.
() => LoadCorrectProvinceMappingsFile(impWorld, config), // Depends on loaded mods.
() => {
LocDB.LoadLocFromModFS(ModFS, config.GetActiveCK3ModFlags());
Logger.IncrementProgress();
Expand Down Expand Up @@ -425,14 +425,15 @@
Logger.IncrementProgress();
}

private void LoadCorrectProvinceMappingsFile(Imperator.World imperatorWorld) {
private void LoadCorrectProvinceMappingsFile(Imperator.World irWorld, Configuration config) {
string mappingsToUse;

bool irHasTI = imperatorWorld.Countries.Any(c => c.Variables.Contains("unification_points"));
bool ck3HasAEP = LoadedMods.Any(m => m.Name == "Asia Expansion Project");
if (irHasTI && ck3HasAEP) {
// Terra Indomita mappings should be used if either TI or Antiquitas is detected.
bool irHasTI = irWorld.Countries.Any(c => c.Variables.Contains("unification_points")) || irWorld.UsableMods.Any(m => m.Name == "Antiquitas");

if (irHasTI && config.AsiaExpansionProjectEnabled) {
mappingsToUse = "terra_indomita_to_aep";
} else if (imperatorWorld.GlobalFlags.Contains("is_playing_invictus")) {
} else if (irWorld.GlobalFlags.Contains("is_playing_invictus")) {
mappingsToUse = "imperator_invictus";
} else {
mappingsToUse = "imperator_vanilla";
Expand Down Expand Up @@ -912,160 +913,160 @@
}
}

private void GenerateFillerHoldersForUnownedLands(CultureCollection cultures, Configuration config) {
Logger.Info("Generating filler holders for unowned lands...");
var date = config.CK3BookmarkDate;
List<Title> unheldCounties = [];
foreach (var county in LandedTitles.Counties) {
var holderId = county.GetHolderId(date);
if (holderId == "0") {
unheldCounties.Add(county);
} else if (Characters.TryGetValue(holderId, out var holder)) {
if (holder.DeathDate is not null && holder.DeathDate <= date) {
Logger.Debug($"Adding {county.Id} to unheld counties because holder {holderId} is dead.");
unheldCounties.Add(county);
}
}
}

var duchyIdToHolderDict = new Dictionary<string, Character>();

foreach (var county in unheldCounties) {
if (config.FillerDukes) {
var duchy = county.DeJureLiege;
if (duchy is not null && duchy.Rank == TitleRank.duchy) {
if (duchyIdToHolderDict.TryGetValue(duchy.Id, out var duchyHolder)) {
county.SetHolder(duchyHolder, date);
continue;
}
}
}

var candidateProvinces = new OrderedSet<Province>();
if (county.CapitalBaronyProvinceId is not null) {
// Give priority to capital province.
if (Provinces.TryGetValue(county.CapitalBaronyProvinceId.Value, out var capitalProvince)) {
candidateProvinces.Add(capitalProvince);
}
}

var allCountyProvinces = county.CountyProvinceIds
.Select(id => Provinces.TryGetValue(id, out var province) ? province : null)
.Where(p => p is not null)
.Select(p => p!);
candidateProvinces.UnionWith(allCountyProvinces);

int pseudoRandomSeed;
if (candidateProvinces.Count != 0) {
pseudoRandomSeed = (int)candidateProvinces.First().Id;
} else {
// Use county ID for seed if no province is available.
pseudoRandomSeed = county.Id.Aggregate(0, (current, c) => current + c);
}

// Determine culture of the holder.
var culture = candidateProvinces
.Select(p => p.GetCulture(date, cultures))
.FirstOrDefault(c => c is not null);
if (culture is null) {
Logger.Debug($"Trying to use de jure duchy for culture of holder for {county.Id}...");
var deJureDuchy = county.DeJureLiege;
if (deJureDuchy is not null) {
culture = Provinces
.Where(p => deJureDuchy.DuchyContainsProvince(p.Id))
.Select(p => p.GetCulture(date, cultures))
.FirstOrDefault(c => c is not null);
}
if (culture is null && deJureDuchy?.DeJureLiege is not null) {
Logger.Debug($"Trying to use de jure kingdom for culture of holder for {county.Id}...");
var deJureKingdom = deJureDuchy.DeJureLiege;
culture = Provinces
.Where(p => deJureKingdom.KingdomContainsProvince(p.Id))
.Select(p => p.GetCulture(date, cultures))
.FirstOrDefault(c => c is not null);
}
if (culture is null) {
Logger.Warn($"Found no fitting culture for generated holder of {county.Id}, " +
$"using first culture from database!");
culture = cultures.First();
}
}

// Determine faith of the holder.
var faithId = candidateProvinces
.Select(p => p.GetFaithId(date))
.FirstOrDefault(f => f is not null);
if (faithId is null) {
Logger.Debug($"Trying to use de jure duchy for faith of holder for {county.Id}...");
var deJureDuchy = county.DeJureLiege;
if (deJureDuchy is not null) {
faithId = Provinces
.Where(p => deJureDuchy.DuchyContainsProvince(p.Id))
.Select(p => p.GetFaithId(date))
.FirstOrDefault(f => f is not null);
}
if (faithId is null && deJureDuchy?.DeJureLiege is not null) {
Logger.Debug($"Trying to use de jure kingdom for faith of holder for {county.Id}...");
var deJureKingdom = deJureDuchy.DeJureLiege;
faithId = Provinces
.Where(p => deJureKingdom.KingdomContainsProvince(p.Id))
.Select(p => p.GetFaithId(date))
.FirstOrDefault(f => f is not null);
}
if (faithId is null) {
Logger.Warn($"Found no fitting faith for generated holder of {county.Id}, " +
$"using first faith from database!");
faithId = Religions.Faiths.First().Id;
}
}

bool female = false;
string name;
var maleNames = culture.MaleNames.ToImmutableList();
if (maleNames.Count > 0) {
name = maleNames.ElementAt(pseudoRandomSeed % maleNames.Count);
} else { // Generate a female if no male name is available.
female = true;
var femaleNames = culture.FemaleNames.ToImmutableList();
name = femaleNames.ElementAt(pseudoRandomSeed % femaleNames.Count);
}
int age = 18 + (pseudoRandomSeed % 60);
var holder = new Character($"IRToCK3_{county.Id}_holder", name, date, Characters) {
FromImperator = true,
Female = female,
BirthDate = date.ChangeByYears(-age)
};
holder.SetFaithId(faithId, null);
holder.SetCultureId(culture.Id, null);
Characters.AddOrReplace(holder);

var countyHoldingTypes = county.CountyProvinceIds
.Select(id => Provinces.TryGetValue(id, out var province) ? province : null)
.Where(p => p is not null)
.Select(p => p!.GetHoldingType(date))
.Where(t => t is not null)
.Select(t => t!)
.ToHashSet();
string government = countyHoldingTypes.Contains("castle_holding")
? "feudal_government"
: "tribal_government";

county.SetHolder(holder, date);
if (config.FillerDukes) {
var duchy = county.DeJureLiege;
if (duchy is null || duchy.Rank != TitleRank.duchy) {
continue;
}

duchy.SetHolder(holder, date);
duchy.SetGovernment(government, date);
duchyIdToHolderDict[duchy.Id] = holder;
} else {
county.SetGovernment(government, date);
}
}
}

Check notice on line 1069 in ImperatorToCK3/CK3/World.cs

View check run for this annotation

codefactor.io / CodeFactor

ImperatorToCK3/CK3/World.cs#L916-L1069

Complex Method
private void DetermineCK3Dlcs(Configuration config) {
var dlcFolderPath = Path.Join(config.CK3Path, "game/dlc");
if (!Directory.Exists(dlcFolderPath)) {
Expand Down
5 changes: 4 additions & 1 deletion ImperatorToCK3/Data_Files/configurables/culture_map.txt
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,10 @@ link = { ck3=somali
## Meroitic
# TFE
link = { ck3=meroitic ir=meroitic ir=alutan }
link = { ck3=meroitic ck3=cushite } # Cushitic is from I:R Antiquitas mod.
# vanilla CK3
link = { ck3=nubian ir=meroitic }
link = { ck3=nubian ir=cushite }
# Invictus mod
link = { ck3=nubian ir=nubian ir=lower_nubian ir=napatan ir=moyan ir=alutan }

Expand Down Expand Up @@ -428,7 +430,8 @@ link = { ck3 = german @ir_all_germanic_cultures }


## Hellenic
@ir_greek_cultures = "ir=greek ir=athenian ir=peloponnesian ir=massalian ir=cyrenaican ir=bosporan ir=thessalian ir=cypriot ir=bithynian ir=ionian ir=troan ir=aeolian ir=greco_pontic ir=aegean ir=aetolian ir=euboean ir=boeotian ir=epirote ir=arcadian ir=argolian ir=parthinian ir=cretan ir=achaean ir=enetoian"
@ir_antiquitas_greek_cultures="ir=doric ir=north_western_doric ir=attican ir=western_ionic ir=eastern_ionic ir=eteocretan ir=elean ir=kerkyran" # # Antiquitas (https://steamcommunity.com/sharedfiles/filedetails/?id=2992438857)
@ir_greek_cultures = "ir=greek ir=athenian ir=peloponnesian ir=massalian ir=cyrenaican ir=bosporan ir=thessalian ir=cypriot ir=bithynian ir=ionian ir=troan ir=aeolian ir=greco_pontic ir=aegean ir=aetolian ir=euboean ir=boeotian ir=epirote ir=arcadian ir=argolian ir=parthinian ir=cretan ir=achaean ir=enetoian @ir_antiquitas_greek_cultures"
# TFE
link = { ck3 = pontic ir = greco_pontic }
link = { ck3 = syrian ir=macedonian ir=hellenistic ir=syracusan ir=thracian @ir_greek_cultures @culture_splitting_region_N }
Expand Down
3 changes: 3 additions & 0 deletions ImperatorToCK3/Imperator/World.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ internal partial class World {
private GenesDB genesDB = new();
public InventionsDB InventionsDB { get; } = new();
public ColorFactory ColorFactory { get; } = new();

public IReadOnlyList<Mod> UsableMods { get; private set; } = Array.Empty<Mod>();

private enum SaveType { Invalid, Plaintext, CompressedEncoded }
private SaveType saveType = SaveType.Invalid;
Expand Down Expand Up @@ -335,6 +337,7 @@ private void ParseSave(Configuration config, ConverterVersion converterVersion,
// Let's locate, verify and potentially update those mods immediately.
ModLoader modLoader = new();
modLoader.LoadMods(config.ImperatorDocPath, incomingMods);
UsableMods = new Mods(modLoader.UsableMods);
ModFS = new ModFilesystem(imperatorRoot, modLoader.UsableMods);

// Now that we have the list of mods used, we can load data from Imperator mod filesystem
Expand Down
Loading