Skip to content

Commit

Permalink
Fix portrait modifier for no beard
Browse files Browse the repository at this point in the history
  • Loading branch information
IhateTrains committed Jul 6, 2024
1 parent 440a90b commit ea38262
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 14 deletions.
8 changes: 7 additions & 1 deletion ImperatorToCK3/CK3/Characters/DNAAccessoryGeneValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public DNAAccessoryGeneValue(
string objectName,
WeightBlock weightBlock
) : this(templateName, objectName, weightBlock, templateName, objectName, weightBlock) { }

public string TemplateName { get; } = templateName;
public string ObjectName { get; } = objectName;

Expand Down Expand Up @@ -46,6 +46,12 @@ public byte IntSliderValueRecessive {
return 0;
}
}

public double SliderValueBetween0And1 {
get {
return IntSliderValue / 255.0;
}
}

public override string ToString() {
return $"\"{TemplateName}\" {IntSliderValue} \"{TemplateRecessiveName}\" {IntSliderValueRecessive}";
Expand Down
4 changes: 2 additions & 2 deletions ImperatorToCK3/CK3/Characters/DNAFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ public DNA GenerateDNA(Imperator.Characters.Character irCharacter, PortraitData

if (ck3GenesDB.SpecialAccessoryGenes.TryGetValue("beards", out var beardGene)) {
var beardGeneValue = MatchAccessoryGeneValueByObject(
irCharacter,
irPortraitData,
irCharacter,
irPortraitData,
"beards",
beardGene
);
Expand Down
47 changes: 36 additions & 11 deletions ImperatorToCK3/Outputter/CharactersOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using commonItems.Mods;
using ImperatorToCK3.CK3.Characters;
using ImperatorToCK3.CommonUtils;
using Open.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
Expand All @@ -14,22 +15,22 @@ namespace ImperatorToCK3.Outputter;
public static class CharactersOutputter {
public static async Task OutputEverything(string outputPath, CharacterCollection characters, Date conversionDate, ModFilesystem ck3ModFS) {
await Task.WhenAll(
OutputCharacters(outputPath, characters, conversionDate),
OutputCharacters(outputPath, characters, conversionDate, ck3ModFS),
BlankOutHistoricalPortraitModifiers(ck3ModFS, outputPath)
);

Logger.IncrementProgress();
}

public static async Task OutputCharacters(string outputPath, CharacterCollection characters, Date conversionDate) {
public static async Task OutputCharacters(string outputPath, CharacterCollection characters, Date conversionDate, ModFilesystem ck3ModFS) {
Logger.Info("Writing Characters...");

// Portrait modifiers need to be outputted before characters themselves,
// because while outputting the portrait modifiers we're adding character flags to character history.
var charactersWithDNA = characters
.Where(c => c.DNA is not null)
.ToImmutableList();
await OutputPortraitModifiers(outputPath, charactersWithDNA, conversionDate);
await OutputPortraitModifiers(outputPath, charactersWithDNA, conversionDate, ck3ModFS);

var charactersFromIR = characters.Where(c => c.FromImperator)
.OrderBy(c => c.Id).ToImmutableList();
Expand All @@ -46,7 +47,7 @@ public static async Task OutputCharacters(string outputPath, CharacterCollection
}

var pathForCharactersFromCK3 = $"{outputPath}/history/characters/IRToCK3_fromCK3.txt";
await using var charactersFromCK3Output = FileOpeningHelper.OpenWriteWithRetries(pathForCharactersFromCK3, System.Text.Encoding.UTF8);
await using var charactersFromCK3Output = FileOpeningHelper.OpenWriteWithRetries(pathForCharactersFromCK3, Encoding.UTF8);
foreach (var character in charactersFromCK3) {
CharacterOutputter.WriteCharacter(sb, character, conversionDate);
await charactersFromCK3Output.WriteAsync(sb.ToString());
Expand All @@ -63,7 +64,7 @@ public static async Task BlankOutHistoricalPortraitModifiers(ModFilesystem ck3Mo

if (ck3ModFS.GetActualFileLocation(modifiersFilePath) is not null) {
string dummyPath = Path.Combine(outputPath, modifiersFilePath);
await using var output = FileOpeningHelper.OpenWriteWithRetries(dummyPath, System.Text.Encoding.UTF8);
await using var output = FileOpeningHelper.OpenWriteWithRetries(dummyPath, Encoding.UTF8);
await output.WriteLineAsync("# Dummy file to blank out historical portrait modifiers from CK3.");
}
}
Expand All @@ -73,7 +74,7 @@ private static async Task OutputCharactersDNA(string outputPath, IEnumerable<Cha

// Dump all into one file.
var path = Path.Combine(outputPath, "common/dna_data/IRToCK3_dna_data.txt");
await using var output = FileOpeningHelper.OpenWriteWithRetries(path, System.Text.Encoding.UTF8);
await using var output = FileOpeningHelper.OpenWriteWithRetries(path, Encoding.UTF8);

var sb = new StringBuilder();
foreach (var character in charactersWithDNA) {
Expand All @@ -91,23 +92,43 @@ private static async Task OutputCharactersDNA(string outputPath, IEnumerable<Cha
sb.Clear();
}
}

private static HashSet<string> GetValidAccessoryIDs(ModFilesystem ck3ModFS) {
Logger.Debug("Getting valid CK3 accessory IDs...");

var accessoryIDs = new ConcurrentHashSet<string>();

var accessoryFilesParser = new Parser();
accessoryFilesParser.RegisterRegex(CommonRegexes.String, (reader, accessoryId) => {
accessoryIDs.Add(accessoryId);
ParserHelpers.IgnoreItem(reader);
});
accessoryFilesParser.IgnoreAndLogUnregisteredItems();
accessoryFilesParser.ParseGameFolder("gfx/portraits/accessories", ck3ModFS, "txt", recursive: true, logFilePaths: false, parallel: true);

return accessoryIDs.ToHashSet();
}

private static async Task OutputPortraitModifiers(string outputPath, IReadOnlyCollection<Character> charactersWithDNA, Date conversionDate) {
private static async Task OutputPortraitModifiers(string outputPath, IReadOnlyCollection<Character> charactersWithDNA, Date conversionDate, ModFilesystem ck3ModFS) {
Logger.Debug("Outputting portrait modifiers...");
// Enforce hairstyles and beards (otherwise CK3 they will only be used on bookmark screen).
// https://ck3.paradoxwikis.com/Characters_modding#Changing_appearance_through_scripts

var validAccessoryIDs = GetValidAccessoryIDs(ck3ModFS);

var portraitModifiersOutputPath = Path.Combine(outputPath, "gfx/portraits/portrait_modifiers/IRToCK3_portrait_modifiers.txt");
await using var output = FileOpeningHelper.OpenWriteWithRetries(portraitModifiersOutputPath, System.Text.Encoding.UTF8);
await using var output = FileOpeningHelper.OpenWriteWithRetries(portraitModifiersOutputPath, Encoding.UTF8);

await OutputPortraitModifiersForGene("hairstyles", charactersWithDNA, output, conversionDate);
await OutputPortraitModifiersForGene("hairstyles", validAccessoryIDs, charactersWithDNA, output, conversionDate);
var malesWithBeards = charactersWithDNA
.Where(c => !c.Female && c.DNA!.AccessoryDNAValues.ContainsKey("beards"))
.ToImmutableList();
await OutputPortraitModifiersForGene("beards", malesWithBeards, output, conversionDate);
await OutputPortraitModifiersForGene("beards", validAccessoryIDs, malesWithBeards, output, conversionDate);
}

private static async Task OutputPortraitModifiersForGene(
string geneName,
HashSet<string> validAccessoryIDs,
IReadOnlyCollection<Character> charactersWithDNA,
TextWriter output,
Date conversionDate
Expand Down Expand Up @@ -141,7 +162,11 @@ Date conversionDate
sb.AppendLine("\t\t\t\tmode = add");
sb.AppendLine($"\t\t\t\tgene = {geneName}");
sb.AppendLine($"\t\t\t\ttemplate = {templateName}");
sb.AppendLine($"\t\t\t\taccessory = {accessoryName}");

string accessoryOrValueString = validAccessoryIDs.Contains(accessoryName)
? $"accessory = {accessoryName}"
: $"value = {grouping.First().DNA!.AccessoryDNAValues[geneName].SliderValueBetween0And1}";
sb.AppendLine($"\t\t\t\t{accessoryOrValueString}");
sb.AppendLine("\t\t\t}");
sb.AppendLine("\t\t}");

Expand Down

0 comments on commit ea38262

Please sign in to comment.