diff --git a/ImperatorToCK3.UnitTests/Outputter/CharacterOutputterTests.cs b/ImperatorToCK3.UnitTests/Outputter/CharacterOutputterTests.cs index 159784558..25ea4ed44 100644 --- a/ImperatorToCK3.UnitTests/Outputter/CharacterOutputterTests.cs +++ b/ImperatorToCK3.UnitTests/Outputter/CharacterOutputterTests.cs @@ -3,6 +3,7 @@ using ImperatorToCK3.CK3.Characters; using ImperatorToCK3.Outputter; using System.IO; +using System.Text; using Xunit; namespace ImperatorToCK3.UnitTests.Outputter; @@ -18,10 +19,10 @@ public void PregnancyIsOutputted() { var pregnantFemale = new Character("1", "Incontinentia", birthDate: "580.1.1", characters) {Female = true}; pregnantFemale.Pregnancies.Add(new Pregnancy(fatherId:"2", motherId: "1", childBirthDate, isBastard:false)); - var output = new StringWriter(); - CharacterOutputter.OutputCharacter(output, pregnantFemale, conversionDate); + var sb = new StringBuilder(); + CharacterOutputter.WriteCharacter(sb, pregnantFemale, conversionDate); - var outputString = output.ToString(); + var outputString = sb.ToString(); outputString.Should().Contain("female = yes"); outputString.Should().Contain($"{conceptionDate}={{ effect={{ make_pregnant_no_checks={{ father=character:2 }} }} }}"); } diff --git a/ImperatorToCK3.UnitTests/Outputter/ProvinceOutputterTests.cs b/ImperatorToCK3.UnitTests/Outputter/ProvinceOutputterTests.cs index de01ddbc0..895e86866 100644 --- a/ImperatorToCK3.UnitTests/Outputter/ProvinceOutputterTests.cs +++ b/ImperatorToCK3.UnitTests/Outputter/ProvinceOutputterTests.cs @@ -16,8 +16,7 @@ public void CultureIsOutputted() { var province = new Province(1, provReader); var sb = new StringBuilder(); - var sw = new StringWriter(sb); - ProvinceOutputter.OutputProvince(sw, province); + ProvinceOutputter.WriteProvince(sb, province); var sr = new StringReader(sb.ToString()); Assert.Equal("1={", sr.ReadLine()); @@ -32,8 +31,7 @@ public void ReligionIsOutputted() { var province = new Province(1, provReader); var sb = new StringBuilder(); - var sw = new StringWriter(sb); - ProvinceOutputter.OutputProvince(sw, province); + ProvinceOutputter.WriteProvince(sb, province); var sr = new StringReader(sb.ToString()); Assert.Equal("1={", sr.ReadLine()); @@ -48,8 +46,7 @@ public void HoldingIsOutputted() { var province = new Province(1, provReader); var sb = new StringBuilder(); - var sw = new StringWriter(sb); - ProvinceOutputter.OutputProvince(sw, province); + ProvinceOutputter.WriteProvince(sb, province); var sr = new StringReader(sb.ToString()); Assert.Equal("1={", sr.ReadLine()); @@ -63,8 +60,7 @@ public void BuildingsAreOutputted() { var province = new Province(1, provReader); var sb = new StringBuilder(); - var sw = new StringWriter(sb); - ProvinceOutputter.OutputProvince(sw, province); + ProvinceOutputter.WriteProvince(sb, province); var sr = new StringReader(sb.ToString()); Assert.Equal("1={", sr.ReadLine()); diff --git a/ImperatorToCK3/CK3/Characters/DNA.cs b/ImperatorToCK3/CK3/Characters/DNA.cs index 091f423cd..c9aa42a27 100644 --- a/ImperatorToCK3/CK3/Characters/DNA.cs +++ b/ImperatorToCK3/CK3/Characters/DNA.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using System.Threading.Tasks; namespace ImperatorToCK3.CK3.Characters; @@ -44,13 +45,13 @@ IDictionary accessoryDNAValues this.accessoryDNAValues = new(accessoryDNAValues); } - public async Task OutputGenes(StreamWriter output) { - await output.WriteLineAsync("\t\tgenes={"); + public void WriteGenes(StringBuilder sb) { + sb.AppendLine("\t\tgenes={"); foreach (var dnaLine in DNALines) { - await output.WriteLineAsync($"\t\t\t{dnaLine}"); + sb.AppendLine($"\t\t\t{dnaLine}"); } - await output.WriteLineAsync("\t\t}"); + sb.AppendLine("\t\t}"); } } \ No newline at end of file diff --git a/ImperatorToCK3/CK3/Cultures/Culture.cs b/ImperatorToCK3/CK3/Cultures/Culture.cs index 249b864a9..89530f840 100644 --- a/ImperatorToCK3/CK3/Cultures/Culture.cs +++ b/ImperatorToCK3/CK3/Cultures/Culture.cs @@ -52,7 +52,7 @@ public string Serialize(string indent, bool withBraces) { } sb.Append(contentIndent).AppendLine($"color={Color.OutputRgb()}"); - if (ParentCultureIds.Any()) { + if (ParentCultureIds.Count != 0) { sb.Append(contentIndent).AppendLine($"parents={PDXSerializer.Serialize(ParentCultureIds)}"); } sb.Append(contentIndent).AppendLine($"heritage={Heritage.Id}"); @@ -76,21 +76,24 @@ public async Task OutputHistory(string outputModPath, Date date) { return; } - var historyPath = Path.Combine(outputModPath, "history/cultures", Id + ".txt"); - await using var historyWriter = File.CreateText(historyPath); - await historyWriter.WriteLineAsync("# This file was generated by the IRToCK3 converter."); + var historyStrBuilder = new StringBuilder(); + historyStrBuilder.AppendLine("# This file was generated by the IRToCK3 converter."); - await historyWriter.WriteLineAsync($"{date} = {{"); + historyStrBuilder.AppendLine($"{date} = {{"); foreach (var innovationId in innovationsFromImperator) { - await historyWriter.WriteLineAsync($"\tdiscover_innovation = {innovationId}"); + historyStrBuilder.AppendLine($"\tdiscover_innovation = {innovationId}"); } foreach (var (innovationId, progress) in innovationProgressesFromImperator) { - await historyWriter.WriteLineAsync("\tadd_innovation_progress = {"); - await historyWriter.WriteLineAsync($"\t\tculture_innovation = {innovationId}"); - await historyWriter.WriteLineAsync($"\t\tprogress = {progress}"); - await historyWriter.WriteLineAsync("\t}"); + historyStrBuilder.AppendLine("\tadd_innovation_progress = {"); + historyStrBuilder.AppendLine($"\t\tculture_innovation = {innovationId}"); + historyStrBuilder.AppendLine($"\t\tprogress = {progress}"); + historyStrBuilder.AppendLine("\t}"); } - await historyWriter.WriteLineAsync("}"); + historyStrBuilder.AppendLine("}"); + + var historyPath = Path.Combine(outputModPath, "history/cultures", Id + ".txt"); + await using var historyWriter = File.CreateText(historyPath); + await historyWriter.WriteAsync(historyStrBuilder.ToString()); } public void ImportInnovationsFromImperator(ISet irInventions, InnovationMapper innovationMapper) { diff --git a/ImperatorToCK3/Outputter/BookmarkOutputter.cs b/ImperatorToCK3/Outputter/BookmarkOutputter.cs index af8d1e19c..5a0f91668 100644 --- a/ImperatorToCK3/Outputter/BookmarkOutputter.cs +++ b/ImperatorToCK3/Outputter/BookmarkOutputter.cs @@ -25,18 +25,16 @@ public static async Task OutputBookmark(World world, Configuration config) { await OutputBookmarkGroup(config); - var path = Path.Combine("output", config.OutputModName, "common/bookmarks/bookmarks/00_bookmarks.txt"); - await using var output = FileOpeningHelper.OpenWriteWithRetries(path, Encoding.UTF8); - var provincePositions = world.MapData.ProvincePositions; - await output.WriteLineAsync("bm_converted = {"); + var sb = new StringBuilder(); + sb.AppendLine("bm_converted = {"); - await output.WriteLineAsync("\tgroup = bm_converted"); - await output.WriteLineAsync($"\tstart_date = {config.CK3BookmarkDate}"); - await output.WriteLineAsync("\tis_playable = yes"); - await output.WriteLineAsync("\trecommended = yes"); - await output.WriteLineAsync("\tweight = { value = 100 }"); + sb.AppendLine("\tgroup = bm_converted"); + sb.AppendLine($"\tstart_date = {config.CK3BookmarkDate}"); + sb.AppendLine("\tis_playable = yes"); + sb.AppendLine("\trecommended = yes"); + sb.AppendLine("\tweight = { value = 100 }"); var playerTitles = new List(world.LandedTitles.Where(title => title.PlayerCountry)); var localizations = new Dictionary<string, LocBlock>(); @@ -53,10 +51,14 @@ public static async Task OutputBookmark(World world, Configuration config) { continue; } - await AddTitleToBookmarkScreen(title, output, holderId, world, localizations, provincePositions, config); + await AddTitleToBookmarkScreen(title, sb, holderId, world, localizations, provincePositions, config); } - await output.WriteLineAsync("}"); + sb.AppendLine("}"); + + var path = Path.Combine("output", config.OutputModName, "common/bookmarks/bookmarks/00_bookmarks.txt"); + await using var output = FileOpeningHelper.OpenWriteWithRetries(path, Encoding.UTF8); + await output.WriteAsync(sb.ToString()); await Task.WhenAll( OutputBookmarkLoc(config, localizations), @@ -67,7 +69,7 @@ await Task.WhenAll( private static async Task AddTitleToBookmarkScreen( Title title, - StreamWriter output, + StringBuilder sb, string holderId, World world, Dictionary<string, LocBlock> localizations, @@ -88,33 +90,33 @@ Configuration config } localizations.Add(holderDescLoc.Id, holderDescLoc); - await output.WriteLineAsync("\tcharacter = {"); + sb.AppendLine("\tcharacter = {"); - await output.WriteLineAsync($"\t\tname = bm_converted_{holder.Id}"); + sb.AppendLine($"\t\tname = bm_converted_{holder.Id}"); var dynastyId = holder.GetDynastyId(config.CK3BookmarkDate); if (dynastyId is not null) { - await output.WriteLineAsync($"\t\tdynasty = {dynastyId}"); + sb.AppendLine($"\t\tdynasty = {dynastyId}"); } - await output.WriteLineAsync("\t\tdynasty_splendor_level = 1"); - await output.WriteLineAsync($"\t\ttype = {holder.GetAgeSex(config.CK3BookmarkDate)}"); - await output.WriteLineAsync($"\t\thistory_id = {holder.Id}"); - await output.WriteLineAsync($"\t\tbirth = {holder.BirthDate}"); - await output.WriteLineAsync($"\t\ttitle = {title.Id}"); + sb.AppendLine("\t\tdynasty_splendor_level = 1"); + sb.AppendLine($"\t\ttype = {holder.GetAgeSex(config.CK3BookmarkDate)}"); + sb.AppendLine($"\t\thistory_id = {holder.Id}"); + sb.AppendLine($"\t\tbirth = {holder.BirthDate}"); + sb.AppendLine($"\t\ttitle = {title.Id}"); var gov = title.GetGovernment(config.CK3BookmarkDate); if (gov is not null) { - await output.WriteLineAsync($"\t\tgovernment = {gov}"); + sb.AppendLine($"\t\tgovernment = {gov}"); } - await output.WriteLineAsync($"\t\tculture = {holder.GetCultureId(config.CK3BookmarkDate)}"); + sb.AppendLine($"\t\tculture = {holder.GetCultureId(config.CK3BookmarkDate)}"); var faithId = holder.GetFaithId(config.CK3BookmarkDate); if (!string.IsNullOrEmpty(faithId)) { - await output.WriteLineAsync($"\t\treligion={faithId}"); + sb.AppendLine($"\t\treligion={faithId}"); } - await output.WriteLineAsync("\t\tdifficulty = \"BOOKMARK_CHARACTER_DIFFICULTY_EASY\""); - await WritePosition(output, title, config, provincePositions); - await output.WriteLineAsync("\t\tanimation = personality_rational"); + sb.AppendLine("\t\tdifficulty = \"BOOKMARK_CHARACTER_DIFFICULTY_EASY\""); + await WritePosition(sb, title, config, provincePositions); + sb.AppendLine("\t\tanimation = personality_rational"); - await output.WriteLineAsync("\t}"); + sb.AppendLine("\t}"); string templatePath = holder.GetAgeSex(config.CK3BookmarkDate) switch { "female" => "blankMod/templates/common/bookmark_portraits/female.txt", @@ -143,20 +145,24 @@ private static async Task OutputBookmarkGroup(Configuration config) { private static async Task OutputBookmarkLoc(Configuration config, IDictionary<string, LocBlock> localizations) { var outputName = config.OutputModName; var baseLocPath = Path.Combine("output", outputName, "localization"); + + var sb = new StringBuilder(); foreach (var language in ConverterGlobals.SupportedLanguages) { - var locFilePath = Path.Combine(baseLocPath, language, $"converter_bookmark_l_{language}.yml"); - await using var locWriter = FileOpeningHelper.OpenWriteWithRetries(locFilePath, Encoding.UTF8); - - await locWriter.WriteLineAsync($"l_{language}:"); + sb.AppendLine($"l_{language}:"); // title localization foreach (var locBlock in localizations.Values) { - await locWriter.WriteLineAsync(locBlock.GetYmlLocLineForLanguage(language)); + sb.AppendLine(locBlock.GetYmlLocLineForLanguage(language)); } + + var locFilePath = Path.Combine(baseLocPath, language, $"converter_bookmark_l_{language}.yml"); + await using var locWriter = FileOpeningHelper.OpenWriteWithRetries(locFilePath, Encoding.UTF8); + await locWriter.WriteAsync(sb.ToString()); + sb.Clear(); } } - private static async Task WritePosition(TextWriter output, Title title, Configuration config, IReadOnlyDictionary<ulong, ProvincePosition> provincePositions) { + private static async Task WritePosition(StringBuilder sb, Title title, Configuration config, IReadOnlyDictionary<ulong, ProvincePosition> provincePositions) { int count = 0; double sumX = 0; double sumY = 0; @@ -175,7 +181,7 @@ private static async Task WritePosition(TextWriter output, Title title, Configur const double scale = (double)1080 / 4096; int finalX = (int)(scale * meanX); int finalY = 1080 - (int)(scale * meanY); - await output.WriteLineAsync($"\t\tposition = {{ {finalX} {finalY} }}"); + sb.AppendLine($"\t\tposition = {{ {finalX} {finalY} }}"); } private static async Task DrawBookmarkMap(Configuration config, List<Title> playerTitles, World ck3World) { diff --git a/ImperatorToCK3/Outputter/CharacterOutputter.cs b/ImperatorToCK3/Outputter/CharacterOutputter.cs index 7dc3d1ecb..e38ffb312 100644 --- a/ImperatorToCK3/Outputter/CharacterOutputter.cs +++ b/ImperatorToCK3/Outputter/CharacterOutputter.cs @@ -1,15 +1,15 @@ using commonItems; using commonItems.Serialization; using System.Globalization; -using System.IO; +using System.Text; using System.Threading.Tasks; using Character = ImperatorToCK3.CK3.Characters.Character; namespace ImperatorToCK3.Outputter; public static class CharacterOutputter { - public static async Task OutputCharacter(TextWriter output, Character character, Date conversionDate) { + public static void WriteCharacter(StringBuilder sb, Character character, Date conversionDate) { // Output ID. - await output.WriteLineAsync($"{character.Id}={{"); + sb.AppendLine($"{character.Id}={{"); if (character.Dead) { // Don't output traits and attributes of dead characters (not needed). @@ -37,39 +37,36 @@ public static async Task OutputCharacter(TextWriter output, Character character, } // Output history. - await output.WriteAsync(PDXSerializer.Serialize(character.History, "\t")); + sb.Append(PDXSerializer.Serialize(character.History, "\t")); - await OutputPregnancies(output, character); - await OutputPrisoners(output, character, conversionDate); + WritePregnancies(sb, character); + WritePrisoners(sb, character, conversionDate); - await output.WriteLineAsync("}"); + sb.AppendLine("}"); } - private static async Task OutputPrisoners(TextWriter output, Character character, Date conversionDate) { + private static void WritePrisoners(StringBuilder stringBuilder, Character character, Date conversionDate) { if (character.PrisonerIds.Count == 0) { return; } - await output.WriteLineAsync($"\t{conversionDate}={{"); + stringBuilder.AppendLine($"\t{conversionDate}={{"); foreach (var (id, type) in character.PrisonerIds) { - await output.WriteLineAsync($"\t\timprison={{target = character:{id} type={type}}}"); + stringBuilder.AppendLine($"\t\timprison={{target = character:{id} type={type}}}"); } - await output.WriteLineAsync("\t}"); + stringBuilder.AppendLine("\t}"); } /// <summary> /// Outputs unborn children if pregnancy has lasted at most 3 months in Imperator /// </summary> - private static async Task OutputPregnancies( - TextWriter output, - Character character - ) { + private static void WritePregnancies(StringBuilder stringBuilder, Character character) { foreach (var pregnancy in character.Pregnancies) { Date conceptionDate = pregnancy.EstimatedConceptionDate; string fatherReference = $"character:{pregnancy.FatherId}"; - await output.WriteAsync($"\t{conceptionDate}={{ effect={{ "); - await output.WriteAsync($"make_pregnant_no_checks={{ father={fatherReference} {(pregnancy.IsBastard ? "known_bastard=yes " : "")}}} "); - await output.WriteLineAsync("} }"); + stringBuilder.Append($"\t{conceptionDate}={{ effect={{ "); + stringBuilder.Append($"make_pregnant_no_checks={{ father={fatherReference} {(pregnancy.IsBastard ? "known_bastard=yes " : "")}}} "); + stringBuilder.AppendLine("} }"); } } } diff --git a/ImperatorToCK3/Outputter/CharactersOutputter.cs b/ImperatorToCK3/Outputter/CharactersOutputter.cs index e63a59a50..436975e91 100644 --- a/ImperatorToCK3/Outputter/CharactersOutputter.cs +++ b/ImperatorToCK3/Outputter/CharactersOutputter.cs @@ -6,6 +6,7 @@ using System.Collections.Immutable; using System.IO; using System.Linq; +using System.Text; using System.Threading.Tasks; namespace ImperatorToCK3.Outputter; @@ -35,17 +36,23 @@ public static async Task OutputCharacters(string outputPath, CharacterCollection var charactersFromCK3 = characters.Except(charactersFromIR) .OrderBy(c => c.Id).ToImmutableList(); + var sb = new StringBuilder(); var pathForCharactersFromIR = $"{outputPath}/history/characters/IRToCK3_fromImperator.txt"; - await using var output = FileOpeningHelper.OpenWriteWithRetries(pathForCharactersFromIR); + await using var charactersFromIROutput = FileOpeningHelper.OpenWriteWithRetries(pathForCharactersFromIR); foreach (var character in charactersFromIR) { - await CharacterOutputter.OutputCharacter(output, character, conversionDate); + CharacterOutputter.WriteCharacter(sb, character, conversionDate); + await charactersFromIROutput.WriteAsync(sb.ToString()); + sb.Clear(); } var pathForCharactersFromCK3 = $"{outputPath}/history/characters/IRToCK3_fromCK3.txt"; - await using var output2 = FileOpeningHelper.OpenWriteWithRetries(pathForCharactersFromCK3, System.Text.Encoding.UTF8); + await using var charactersFromCK3Output = FileOpeningHelper.OpenWriteWithRetries(pathForCharactersFromCK3, System.Text.Encoding.UTF8); foreach (var character in charactersFromCK3) { - await CharacterOutputter.OutputCharacter(output2, character, conversionDate); + CharacterOutputter.WriteCharacter(sb, character, conversionDate); + await charactersFromCK3Output.WriteAsync(sb.ToString()); + sb.Clear(); } + await OutputCharactersDNA(outputPath, charactersWithDNA); } @@ -63,19 +70,25 @@ public static async Task BlankOutHistoricalPortraitModifiers(ModFilesystem ck3Mo private static async Task OutputCharactersDNA(string outputPath, IEnumerable<Character> charactersWithDNA) { Logger.Info("Outputting DNA..."); + // 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); + + var sb = new StringBuilder(); foreach (var character in charactersWithDNA) { var dna = character.DNA!; - await output.WriteLineAsync($"{dna.Id}={{"); - await output.WriteLineAsync("\tportrait_info={"); + sb.AppendLine($"{dna.Id}={{"); + sb.AppendLine("\tportrait_info={"); - await dna.OutputGenes(output); + dna.WriteGenes(sb); - await output.WriteLineAsync("\t}"); - await output.WriteLineAsync("\tenabled=yes"); - await output.WriteLineAsync("}"); + sb.AppendLine("\t}"); + sb.AppendLine("\tenabled=yes"); + sb.AppendLine("}"); + + await output.WriteAsync(sb.ToString()); + sb.Clear(); } } @@ -99,15 +112,17 @@ private static async Task OutputPortraitModifiersForGene( TextWriter output, Date conversionDate ) { + var sb = new StringBuilder(); + var charactersByGeneValue = charactersWithDNA .Where(c => c.DNA!.AccessoryDNAValues.ContainsKey(geneName)) .GroupBy(c => new { c.DNA!.AccessoryDNAValues[geneName].TemplateName, c.DNA!.AccessoryDNAValues[geneName].ObjectName, }); - await output.WriteLineAsync($"IRToCK3_{geneName}_overrides = {{"); - await output.WriteLineAsync("\tusage = game"); - await output.WriteLineAsync("\tselection_behavior = max"); + sb.AppendLine($"IRToCK3_{geneName}_overrides = {{"); + sb.AppendLine("\tusage = game"); + sb.AppendLine("\tselection_behavior = max"); foreach (var grouping in charactersByGeneValue) { var templateName = grouping.Key.TemplateName; var accessoryName = grouping.Key.ObjectName; @@ -120,26 +135,28 @@ Date conversionDate character.History.AddFieldValue(effectDate, "effects", "effect", characterEffectStr); } - await output.WriteLineAsync($"\t{templateName}_obj_{accessoryName} = {{"); - await output.WriteLineAsync("\t\tdna_modifiers = {"); - await output.WriteLineAsync("\t\t\taccessory = {"); - await output.WriteLineAsync("\t\t\t\tmode = add"); - await output.WriteLineAsync($"\t\t\t\tgene = {geneName}"); - await output.WriteLineAsync($"\t\t\t\ttemplate = {templateName}"); - await output.WriteLineAsync($"\t\t\t\taccessory = {accessoryName}"); - await output.WriteLineAsync("\t\t\t}"); - await output.WriteLineAsync("\t\t}"); + sb.AppendLine($"\t{templateName}_obj_{accessoryName} = {{"); + sb.AppendLine("\t\tdna_modifiers = {"); + sb.AppendLine("\t\t\taccessory = {"); + 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}"); + sb.AppendLine("\t\t\t}"); + sb.AppendLine("\t\t}"); - await output.WriteLineAsync("\t\tweight = {"); - await output.WriteLineAsync("\t\t\tbase = 0"); - await output.WriteLineAsync("\t\t\tmodifier = {"); - await output.WriteLineAsync("\t\t\t\tadd = 999"); - await output.WriteLineAsync($"\t\t\t\thas_character_flag = {characterFlagName}"); - await output.WriteLineAsync("\t\t\t}"); + sb.AppendLine("\t\tweight = {"); + sb.AppendLine("\t\t\tbase = 0"); + sb.AppendLine("\t\t\tmodifier = {"); + sb.AppendLine("\t\t\t\tadd = 999"); + sb.AppendLine($"\t\t\t\thas_character_flag = {characterFlagName}"); + sb.AppendLine("\t\t\t}"); - await output.WriteLineAsync("\t\t}"); - await output.WriteLineAsync("\t}"); + sb.AppendLine("\t\t}"); + sb.AppendLine("\t}"); } - await output.WriteLineAsync("}"); + sb.AppendLine("}"); + + await output.WriteAsync(sb.ToString()); } } diff --git a/ImperatorToCK3/Outputter/CoatOfArmsOutputter.cs b/ImperatorToCK3/Outputter/CoatOfArmsOutputter.cs index 12a165645..b3d38a991 100644 --- a/ImperatorToCK3/Outputter/CoatOfArmsOutputter.cs +++ b/ImperatorToCK3/Outputter/CoatOfArmsOutputter.cs @@ -12,24 +12,26 @@ namespace ImperatorToCK3.Outputter; public static class CoatOfArmsOutputter { public static async Task OutputCoas(string outputModPath, Title.LandedTitles titles, IEnumerable<Dynasty> dynasties) { Logger.Info("Outputting coats of arms..."); - var coasPath = Path.Combine(outputModPath, "common", "coat_of_arms", "coat_of_arms"); - - var path = Path.Combine(coasPath, "zzz_IRToCK3_coas.txt"); - await using var coasWriter = new StreamWriter(path); // Output CoAs for titles. + var sb = new System.Text.StringBuilder(); foreach (var title in titles) { var coa = title.CoA; if (coa is not null) { - await coasWriter.WriteLineAsync($"{title.Id}={coa}"); + sb.AppendLine($"{title.Id}={coa}"); } } // Output CoAs for dynasties. foreach (var dynasty in dynasties.Where(d => d.CoA is not null)) { - await coasWriter.WriteLineAsync($"{dynasty.Id}={dynasty.CoA}"); + sb.AppendLine($"{dynasty.Id}={dynasty.CoA}"); } + var coasPath = Path.Combine(outputModPath, "common/coat_of_arms/coat_of_arms"); + var path = Path.Combine(coasPath, "zzz_IRToCK3_coas.txt"); + await using var coasWriter = new StreamWriter(path); + await coasWriter.WriteAsync(sb.ToString()); + Logger.IncrementProgress(); } diff --git a/ImperatorToCK3/Outputter/CulturesOutputter.cs b/ImperatorToCK3/Outputter/CulturesOutputter.cs index 73fa862f4..9e0526f99 100644 --- a/ImperatorToCK3/Outputter/CulturesOutputter.cs +++ b/ImperatorToCK3/Outputter/CulturesOutputter.cs @@ -3,6 +3,7 @@ using ImperatorToCK3.CK3.Cultures; using ImperatorToCK3.CommonUtils; using System.IO; +using System.Text; using System.Threading.Tasks; namespace ImperatorToCK3.Outputter; @@ -10,12 +11,15 @@ namespace ImperatorToCK3.Outputter; public static class CulturesOutputter { public static async Task OutputCultures(string outputModPath, CultureCollection cultures, Date date) { Logger.Info("Outputting cultures..."); - var outputPath = Path.Combine(outputModPath, "common/culture/cultures/IRtoCK3_all_cultures.txt"); - await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8); - + + var sb = new StringBuilder(); foreach (var culture in cultures) { - await output.WriteLineAsync($"{culture.Id}={PDXSerializer.Serialize(culture)}"); + sb.AppendLine($"{culture.Id}={PDXSerializer.Serialize(culture)}"); } + + var outputPath = Path.Combine(outputModPath, "common/culture/cultures/IRtoCK3_all_cultures.txt"); + await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, Encoding.UTF8); + await output.WriteAsync(sb.ToString()); await OutputCultureHistory(outputModPath, cultures, date); } diff --git a/ImperatorToCK3/Outputter/DynastiesOutputter.cs b/ImperatorToCK3/Outputter/DynastiesOutputter.cs index 35a996c64..67197bdb1 100644 --- a/ImperatorToCK3/Outputter/DynastiesOutputter.cs +++ b/ImperatorToCK3/Outputter/DynastiesOutputter.cs @@ -12,22 +12,28 @@ namespace ImperatorToCK3.Outputter; public static class DynastiesOutputter { public static async Task OutputDynasties(string outputModPath, DynastyCollection dynasties) { Logger.Info("Writing dynasties..."); - var outputPath = Path.Combine(outputModPath, "common/dynasties/irtock3_all_dynasties.txt"); - await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, encoding: Encoding.UTF8); + var sb = new StringBuilder(); foreach (var dynasty in dynasties.OrderBy(d => d.Id)) { - await output.WriteLineAsync($"{dynasty.Id}={PDXSerializer.Serialize(dynasty, string.Empty)}"); + sb.AppendLine($"{dynasty.Id}={PDXSerializer.Serialize(dynasty, string.Empty)}"); } + + var outputPath = Path.Combine(outputModPath, "common/dynasties/irtock3_all_dynasties.txt"); + await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, encoding: Encoding.UTF8); + await output.WriteAsync(sb.ToString()); } public static async Task OutputHouses(string outputModPath, HouseCollection houses) { Logger.Info("Writing dynasty houses..."); - var outputPath = Path.Combine(outputModPath, "common/dynasty_houses/irtock3_all_houses.txt"); - await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, encoding: Encoding.UTF8); + var sb = new StringBuilder(); foreach (var house in houses.OrderBy(h => h.Id)) { - await output.WriteLineAsync($"{house.Id}={PDXSerializer.Serialize(house, string.Empty)}"); + sb.AppendLine($"{house.Id}={PDXSerializer.Serialize(house, string.Empty)}"); } + + var outputPath = Path.Combine(outputModPath, "common/dynasty_houses/irtock3_all_houses.txt"); + await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, encoding: Encoding.UTF8); + await output.WriteAsync(sb.ToString()); } public static async Task OutputDynastiesAndHouses(string outputModPath, DynastyCollection dynasties, HouseCollection houses) { diff --git a/ImperatorToCK3/Outputter/LocalizationOutputter.cs b/ImperatorToCK3/Outputter/LocalizationOutputter.cs index f09692db2..337e6d2b6 100644 --- a/ImperatorToCK3/Outputter/LocalizationOutputter.cs +++ b/ImperatorToCK3/Outputter/LocalizationOutputter.cs @@ -5,6 +5,7 @@ using ImperatorToCK3.CommonUtils; using System.Collections.Generic; using System.IO; +using System.Text; using System.Threading.Tasks; namespace ImperatorToCK3.Outputter; @@ -14,16 +15,14 @@ public static async Task OutputLocalization(string outputModPath, World ck3World var baseLocDir = Path.Join(outputModPath, "localization"); var baseReplaceLocDir = Path.Join(baseLocDir, "replace"); + var sb = new StringBuilder(); foreach (var language in ConverterGlobals.SupportedLanguages) { - var locFilePath = Path.Join(baseReplaceLocDir, language, $"converter_l_{language}.yml"); - await using var locWriter = FileOpeningHelper.OpenWriteWithRetries(locFilePath, encoding: System.Text.Encoding.UTF8); - - await locWriter.WriteLineAsync($"l_{language}:"); + sb.AppendLine($"l_{language}:"); // title localization foreach (var title in ck3World.LandedTitles) { foreach (var locBlock in title.Localizations) { - await locWriter.WriteLineAsync(locBlock.GetYmlLocLineForLanguage(language)); + sb.AppendLine(locBlock.GetYmlLocLineForLanguage(language)); } } @@ -35,28 +34,35 @@ public static async Task OutputLocalization(string outputModPath, World ck3World continue; } - await locWriter.WriteLineAsync(locBlock.GetYmlLocLineForLanguage(language)); + sb.AppendLine(locBlock.GetYmlLocLineForLanguage(language)); uniqueKeys.Add(key); } } + + var locFilePath = Path.Join(baseReplaceLocDir, language, $"converter_l_{language}.yml"); + await using var locWriter = FileOpeningHelper.OpenWriteWithRetries(locFilePath, encoding: System.Text.Encoding.UTF8); + await locWriter.WriteLineAsync(sb.ToString()); + sb.Clear(); } // dynasty localization foreach (var language in ConverterGlobals.SupportedLanguages) { - var dynastyLocFilePath = Path.Combine(baseLocDir, $"{language}/irtock3_dynasty_l_{language}.yml"); - await using var dynastyLocWriter = FileOpeningHelper.OpenWriteWithRetries(dynastyLocFilePath, System.Text.Encoding.UTF8); - - await dynastyLocWriter.WriteLineAsync($"l_{language}:"); + sb.AppendLine($"l_{language}:"); foreach (var dynasty in ck3World.Dynasties) { var localizedName = dynasty.LocalizedName; if (localizedName is not null) { - await dynastyLocWriter.WriteLineAsync(localizedName.GetYmlLocLineForLanguage(language)); + sb.AppendLine(localizedName.GetYmlLocLineForLanguage(language)); } else if (dynasty.FromImperator) { Logger.Warn($"Dynasty {dynasty.Id} has no localizations!"); - await dynastyLocWriter.WriteLineAsync($" {dynasty.Name}: \"{dynasty.Name}\""); + sb.AppendLine($" {dynasty.Name}: \"{dynasty.Name}\""); } } + + var dynastyLocFilePath = Path.Combine(baseLocDir, $"{language}/irtock3_dynasty_l_{language}.yml"); + await using var dynastyLocWriter = FileOpeningHelper.OpenWriteWithRetries(dynastyLocFilePath, System.Text.Encoding.UTF8); + await dynastyLocWriter.WriteAsync(sb.ToString()); + sb.Clear(); } await OutputFallbackLocForMissingSecondaryLanguageLoc(baseLocDir, ck3World.ModFS); @@ -96,7 +102,8 @@ private static async Task OutputFallbackLocForMissingSecondaryLanguageLoc(string languageToLocLinesDict[secondaryLanguage].Add(locBlock.GetYmlLocLineForLanguage(primaryLanguage)); } } - + + var sb = new StringBuilder(); foreach (var language in secondaryLanguages) { var linesToOutput = languageToLocLinesDict[language]; if (linesToOutput.Count == 0) { @@ -104,14 +111,16 @@ private static async Task OutputFallbackLocForMissingSecondaryLanguageLoc(string } Logger.Debug($"Outputting {linesToOutput.Count} fallback loc lines for {language}..."); - - var locFilePath = Path.Combine(baseLocDir, $"{language}/irtock3_fallback_loc_l_{language}.yml"); - await using var locWriter = FileOpeningHelper.OpenWriteWithRetries(locFilePath, System.Text.Encoding.UTF8); - await locWriter.WriteLineAsync($"l_{language}:"); + sb.AppendLine($"l_{language}:"); foreach (var line in linesToOutput) { - await locWriter.WriteLineAsync(line); + sb.AppendLine(line); } + + var locFilePath = Path.Combine(baseLocDir, $"{language}/irtock3_fallback_loc_l_{language}.yml"); + await using var locWriter = FileOpeningHelper.OpenWriteWithRetries(locFilePath, System.Text.Encoding.UTF8); + await locWriter.WriteAsync(sb.ToString()); + sb.Clear(); } } } diff --git a/ImperatorToCK3/Outputter/MenAtArmsOutputter.cs b/ImperatorToCK3/Outputter/MenAtArmsOutputter.cs index 44e5febf6..88396cf4b 100644 --- a/ImperatorToCK3/Outputter/MenAtArmsOutputter.cs +++ b/ImperatorToCK3/Outputter/MenAtArmsOutputter.cs @@ -8,43 +8,49 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; namespace ImperatorToCK3.Outputter; public static class MenAtArmsOutputter { private static void OutputHiddenEvent(string outputModName, IEnumerable<Character> charactersWithMaa) { - var outputPath = Path.Combine("output", outputModName, "events", "irtock3_hidden_events.txt"); - using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8); - - output.WriteLine("namespace = irtock3_hidden_events"); - output.WriteLine(); - output.WriteLine("irtock3_hidden_events.0001 = {"); - output.WriteLine("\ttype = character_event"); - output.WriteLine("\thidden = yes"); - - output.WriteLine("\timmediate = {"); + var sb = new StringBuilder(); + + sb.AppendLine("namespace = irtock3_hidden_events"); + sb.AppendLine(); + sb.AppendLine("irtock3_hidden_events.0001 = {"); + sb.AppendLine("\ttype = character_event"); + sb.AppendLine("\thidden = yes"); + + sb.AppendLine("\timmediate = {"); foreach (var character in charactersWithMaa) { - output.WriteLine( + sb.AppendLine( "\t\tset_variable = { " + $"name=IRToCK3_character_{character.Id} " + $"value=character:{character.Id} " + "}" ); } - output.WriteLine("\t}"); + sb.AppendLine("\t}"); - output.WriteLine("}"); + sb.AppendLine("}"); + + var outputPath = Path.Combine("output", outputModName, "events", "irtock3_hidden_events.txt"); + using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8); + output.Write(sb.ToString()); } private static void OutputMenAtArmsTypes(string outputModName, IdObjectCollection<string, MenAtArmsType> menAtArmsTypes) { Logger.Info("Writing men-at-arms types..."); + + var sb = new StringBuilder(); + foreach (var type in menAtArmsTypes.Where(t=>t.ToBeOutputted)) { + sb.AppendLine($"{type.Id}={PDXSerializer.Serialize(type)}"); + } var outputPath = Path.Combine("output", outputModName, "common/men_at_arms_types/IRToCK3_generated_types.txt"); using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8); - - foreach (var type in menAtArmsTypes.Where(t=>t.ToBeOutputted)) { - output.WriteLine($"{type.Id}={PDXSerializer.Serialize(type)}"); - } + output.Write(sb.ToString()); } private static void OutputGuiContainer(string outputModName, ModFilesystem modFS, List<Character> charactersWithMaa) { @@ -57,18 +63,16 @@ private static void OutputGuiContainer(string outputModName, ModFilesystem modFS string guiText = File.ReadAllText(hudTopGuiPath); - var outputPath = Path.Combine("output", outputModName, relativeHudTopGuiPath); - using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8); - - output.WriteLine(guiText.TrimEnd().TrimEnd('}')); - output.WriteLine("\tcontainer={"); - output.WriteLine("\t\tname=\"IRToCK3_maa_toogle\""); - output.WriteLine("\t\tdatacontext=\"[GetScriptedGui('IRToCK3_create_maa')]\""); - output.WriteLine("\t\tvisible=\"[ScriptedGui.IsShown( GuiScope.SetRoot( GetPlayer.MakeScope ).End )]\""); + var sb = new StringBuilder(); + sb.AppendLine(guiText.TrimEnd().TrimEnd('}')); + sb.AppendLine("\tcontainer={"); + sb.AppendLine("\t\tname=\"IRToCK3_maa_toogle\""); + sb.AppendLine("\t\tdatacontext=\"[GetScriptedGui('IRToCK3_create_maa')]\""); + sb.AppendLine("\t\tvisible=\"[ScriptedGui.IsShown( GuiScope.SetRoot( GetPlayer.MakeScope ).End )]\""); const float duration = 0.01f; int state = 0; - output.WriteLine( + sb.AppendLine( "\t\tstate = { " + "name=_show " + $"next=state{state} " + @@ -78,7 +82,7 @@ private static void OutputGuiContainer(string outputModName, ModFilesystem modFS foreach (var character in charactersWithMaa) { foreach (var (maaType, stacks) in character.MenAtArmsStacksPerType) { for (int i = 0; i < stacks; ++i) { - output.WriteLine( + sb.AppendLine( "\t\tstate = { " + $"name=state{state++} " + $"next=state{state} " + @@ -88,15 +92,19 @@ private static void OutputGuiContainer(string outputModName, ModFilesystem modFS } } - output.WriteLine( + sb.AppendLine( "\t\tstate = { " + $"name=state{state} " + "on_start=\"[ExecuteConsoleCommand('effect remove_global_variable=IRToCK3_create_maa_flag')]\" " + $"duration={duration} " + "}"); - output.WriteLine("\t}"); - output.WriteLine("}"); + sb.AppendLine("\t}"); + sb.AppendLine("}"); + + var outputPath = Path.Combine("output", outputModName, relativeHudTopGuiPath); + using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8); + output.Write(sb.ToString()); } public static void OutputMenAtArms(string outputModName, ModFilesystem modFS, CharacterCollection ck3Characters, IdObjectCollection<string, MenAtArmsType> menAtArmsTypes) { diff --git a/ImperatorToCK3/Outputter/NamedColorsOutputter.cs b/ImperatorToCK3/Outputter/NamedColorsOutputter.cs index e5dcd0957..dfaa4c25b 100644 --- a/ImperatorToCK3/Outputter/NamedColorsOutputter.cs +++ b/ImperatorToCK3/Outputter/NamedColorsOutputter.cs @@ -3,6 +3,7 @@ using ImperatorToCK3.CommonUtils; using System.IO; using System.Linq; +using System.Text; using System.Threading.Tasks; namespace ImperatorToCK3.Outputter; @@ -23,14 +24,16 @@ public static async Task OutputNamedColors(string outputModPath, NamedColorColle Logger.Info("Outputting named colors from Imperator game and mods..."); - var outputPath = Path.Combine(outputModPath, "common", "named_colors", "IRtoCK3_colors_from_Imperator.txt"); - await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8); - - await output.WriteLineAsync("colors = {"); + var sb = new StringBuilder(); + sb.AppendLine("colors = {"); foreach (var (name, color) in diff) { - await output.WriteLineAsync($"\t{name}={color.OutputRgb()}"); + sb.AppendLine($"\t{name}={color.OutputRgb()}"); } - await output.WriteLineAsync("}"); + sb.AppendLine("}"); + + var outputPath = Path.Combine(outputModPath, "common", "named_colors", "IRtoCK3_colors_from_Imperator.txt"); + await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8); + await output.WriteAsync(sb.ToString()); Logger.IncrementProgress(); } diff --git a/ImperatorToCK3/Outputter/OnActionOutputter.cs b/ImperatorToCK3/Outputter/OnActionOutputter.cs index 0a726f6ee..024e2c70f 100644 --- a/ImperatorToCK3/Outputter/OnActionOutputter.cs +++ b/ImperatorToCK3/Outputter/OnActionOutputter.cs @@ -20,20 +20,20 @@ public static async Task OutputEverything(Configuration config, ModFilesystem ck public static async Task OutputCustomGameStartOnAction(Configuration config) { Logger.Info("Writing game start on-action..."); - var filePath = $"output/{config.OutputModName}/common/on_action/IRToCK3_game_start.txt"; - await using var writer = new StreamWriter(filePath, false, new UTF8Encoding(true)); + + var sb = new StringBuilder(); const string customOnGameStartOnAction = "irtock3_on_game_start_after_lobby"; - await writer.WriteLineAsync("on_game_start_after_lobby = {"); - await writer.WriteLineAsync($"\ton_actions = {{ {customOnGameStartOnAction } }}"); - await writer.WriteLineAsync("}"); + sb.AppendLine("on_game_start_after_lobby = {"); + sb.AppendLine($"\ton_actions = {{ {customOnGameStartOnAction } }}"); + sb.AppendLine("}"); - await writer.WriteLineAsync($"{customOnGameStartOnAction} = {{"); - await writer.WriteLineAsync("\teffect = {"); + sb.AppendLine($"{customOnGameStartOnAction} = {{"); + sb.AppendLine("\teffect = {"); if (config.LegionConversion == LegionConversion.MenAtArms) { - await writer.WriteLineAsync(""" + sb.AppendLine(""" # IRToCK3: add MAA regiments random_player = { trigger_event = irtock3_hidden_events.0001 @@ -42,13 +42,13 @@ await writer.WriteLineAsync(""" } if (config.LegionConversion == LegionConversion.MenAtArms) { - await writer.WriteLineAsync("\t\tset_global_variable = IRToCK3_create_maa_flag"); + sb.AppendLine("\t\tset_global_variable = IRToCK3_create_maa_flag"); } if (config.FallenEagleEnabled) { // As of the "Last of the Romans" update, TFE only disables Nicene for start dates >= 476.9.4. // But for the converter it's important that Nicene is disabled for all start dates >= 451.8.25. - await writer.WriteLineAsync(""" + sb.AppendLine(""" # IRToCK3: disable Nicene after the Council of Chalcedon. if = { limit = { @@ -76,8 +76,12 @@ await writer.WriteLineAsync(""" """); } - await writer.WriteLineAsync("\t}"); - await writer.WriteLineAsync("}"); + sb.AppendLine("\t}"); + sb.AppendLine("}"); + + var filePath = $"output/{config.OutputModName}/common/on_action/IRToCK3_game_start.txt"; + await using var writer = new StreamWriter(filePath, false, new UTF8Encoding(true)); + await writer.WriteAsync(sb.ToString()); } private static async Task DisableUnneededFallenEagleOnActions(string outputModPath) { diff --git a/ImperatorToCK3/Outputter/PillarOutputter.cs b/ImperatorToCK3/Outputter/PillarOutputter.cs index 347cd5bf1..35fa66a44 100644 --- a/ImperatorToCK3/Outputter/PillarOutputter.cs +++ b/ImperatorToCK3/Outputter/PillarOutputter.cs @@ -10,11 +10,14 @@ namespace ImperatorToCK3.Outputter; public static class PillarOutputter { public static async Task OutputPillars(string outputPath, PillarCollection pillars) { Logger.Info("Outputting pillars..."); - var outputFilePath = Path.Combine(outputPath, "common/culture/pillars/IRtoCK3_all_pillars.txt"); - await using var output = FileOpeningHelper.OpenWriteWithRetries(outputFilePath, System.Text.Encoding.UTF8); + var sb = new System.Text.StringBuilder(); foreach (var pillar in pillars) { - await output.WriteLineAsync($"{pillar.Id}={PDXSerializer.Serialize(pillar)}"); + sb.AppendLine($"{pillar.Id}={PDXSerializer.Serialize(pillar)}"); } + + var outputFilePath = Path.Combine(outputPath, "common/culture/pillars/IRtoCK3_all_pillars.txt"); + await using var output = FileOpeningHelper.OpenWriteWithRetries(outputFilePath, System.Text.Encoding.UTF8); + await output.WriteAsync(sb.ToString()); } } \ No newline at end of file diff --git a/ImperatorToCK3/Outputter/ProvinceOutputter.cs b/ImperatorToCK3/Outputter/ProvinceOutputter.cs index 211801097..477ee5e4d 100644 --- a/ImperatorToCK3/Outputter/ProvinceOutputter.cs +++ b/ImperatorToCK3/Outputter/ProvinceOutputter.cs @@ -1,18 +1,18 @@ using commonItems.Serialization; using ImperatorToCK3.CK3.Provinces; -using System.IO; +using System.Text; namespace ImperatorToCK3.Outputter; public static class ProvinceOutputter { - public static void OutputProvince(TextWriter writer, Province province) { + public static void WriteProvince(StringBuilder sb, Province province) { var serializedHistory = PDXSerializer.Serialize(province.History, indent: "\t"); if (string.IsNullOrWhiteSpace(serializedHistory.Trim())) { return; } - writer.WriteLine($"{province.Id}={{"); - writer.Write(serializedHistory); - writer.WriteLine("}"); + sb.AppendLine($"{province.Id}={{"); + sb.Append(serializedHistory); + sb.AppendLine("}"); } } \ No newline at end of file diff --git a/ImperatorToCK3/Outputter/ProvincesOutputter.cs b/ImperatorToCK3/Outputter/ProvincesOutputter.cs index 0b7f66927..9d38aefc5 100644 --- a/ImperatorToCK3/Outputter/ProvincesOutputter.cs +++ b/ImperatorToCK3/Outputter/ProvincesOutputter.cs @@ -21,14 +21,19 @@ Title.LandedTitles titles var deJureKingdoms = titles.GetDeJureKingdoms(); Parallel.ForEach(deJureKingdoms, kingdom => { - var filePath = $"{outputModPath}/history/provinces/{kingdom.Id}.txt"; - using var historyOutput = new StreamWriter(filePath); + var sb = new System.Text.StringBuilder(); foreach (var province in provinces) { - if (kingdom.KingdomContainsProvince(province.Id)) { - ProvinceOutputter.OutputProvince(historyOutput, province); - alreadyOutputtedProvinces.Add(province.Id); + if (!kingdom.KingdomContainsProvince(province.Id)) { + continue; } + + ProvinceOutputter.WriteProvince(sb, province); + alreadyOutputtedProvinces.Add(province.Id); } + + var filePath = $"{outputModPath}/history/provinces/{kingdom.Id}.txt"; + using var historyOutput = new StreamWriter(filePath); + historyOutput.Write(sb.ToString()); }); if (alreadyOutputtedProvinces.Count != provinces.Count) { @@ -36,17 +41,23 @@ Title.LandedTitles titles await using var historyOutput = TextWriter.Synchronized(new StreamWriter(filePath)); var deJureDuchies = titles.GetDeJureDuchies(); Parallel.ForEach(deJureDuchies, duchy => { + var sb = new System.Text.StringBuilder(); + foreach (var province in provinces) { if (alreadyOutputtedProvinces.Contains(province.Id)) { continue; } if (duchy.DuchyContainsProvince(province.Id)) { - historyOutput.WriteLine($"# {duchy.Id}"); - ProvinceOutputter.OutputProvince(historyOutput, province); + sb.AppendLine($"# {duchy.Id}"); + ProvinceOutputter.WriteProvince(sb, province); alreadyOutputtedProvinces.Add(province.Id); } } + + if (sb.Length > 0) { + historyOutput.Write(sb.ToString()); + } }); } diff --git a/ImperatorToCK3/Outputter/ReligionsOutputter.cs b/ImperatorToCK3/Outputter/ReligionsOutputter.cs index 3ee0bf0f7..84a3a37e9 100644 --- a/ImperatorToCK3/Outputter/ReligionsOutputter.cs +++ b/ImperatorToCK3/Outputter/ReligionsOutputter.cs @@ -4,6 +4,7 @@ using ImperatorToCK3.CommonUtils; using System.IO; using System.Linq; +using System.Text; using System.Threading.Tasks; namespace ImperatorToCK3.Outputter; @@ -20,46 +21,55 @@ await Task.WhenAll( private static async Task OutputHolySites(string outputModPath, ReligionCollection ck3ReligionCollection) { Logger.Info("Writing holy sites..."); - var outputPath = Path.Combine(outputModPath, "common/religion/holy_sites/IRtoCK3_sites.txt"); - await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8); - var sitesToOutput = ck3ReligionCollection.HolySites.Where(s => s.IsGeneratedByConverter) .ToList(); + var sb = new StringBuilder(); foreach (var site in sitesToOutput) { - await output.WriteLineAsync($"{site.Id}={PDXSerializer.Serialize(site)}"); + sb.AppendLine($"{site.Id}={PDXSerializer.Serialize(site)}"); } + + var outputPath = Path.Combine(outputModPath, "common/religion/holy_sites/IRtoCK3_sites.txt"); + await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8); + await output.WriteAsync(sb.ToString()); + sb.Clear(); // Output localization. foreach (string language in ConverterGlobals.SupportedLanguages) { - var locOutputPath = Path.Combine(outputModPath, $"localization/{language}/IRtoCK3_holy_sites_l_{language}.yml"); - await using var locWriter = FileOpeningHelper.OpenWriteWithRetries(locOutputPath, System.Text.Encoding.UTF8); - - await locWriter.WriteLineAsync($"l_{language}:"); + sb.AppendLine($"l_{language}:"); foreach (var site in sitesToOutput) { // holy site name var holySiteTitle = site.BaronyId ?? site.CountyId; if (holySiteTitle is not null) { string holySiteNameLocLine = $" holy_site_{site.Id}_name: \"${holySiteTitle}$\""; - await locWriter.WriteLineAsync(holySiteNameLocLine); + sb.AppendLine(holySiteNameLocLine); } else { - await locWriter.WriteLineAsync($" holy_site_{site.Id}_name: \"Holy site\""); // fallback + sb.AppendLine($" holy_site_{site.Id}_name: \"Holy site\""); // fallback } // holy site effect name string holySiteEffectLocLine = $" holy_site_{site.Id}_effect_name: \"From [holy_site|E] #weak ($holy_site_{site.Id}_name$)#!\""; - await locWriter.WriteLineAsync(holySiteEffectLocLine); + sb.AppendLine(holySiteEffectLocLine); } + + var locOutputPath = Path.Combine(outputModPath, $"localization/{language}/IRtoCK3_holy_sites_l_{language}.yml"); + await using var locWriter = FileOpeningHelper.OpenWriteWithRetries(locOutputPath, System.Text.Encoding.UTF8); + + await locWriter.WriteAsync(sb.ToString()); + sb.Clear(); } } private static async Task OutputReligions(string outputModPath, ReligionCollection ck3ReligionCollection) { Logger.Info("Writing religions..."); - var outputPath = Path.Combine(outputModPath, "common/religion/religions/IRtoCK3_all_religions.txt"); - await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8); + var sb = new StringBuilder(); foreach (var religion in ck3ReligionCollection) { - await output.WriteLineAsync($"{religion.Id}={PDXSerializer.Serialize(religion)}"); + sb.AppendLine($"{religion.Id}={PDXSerializer.Serialize(religion)}"); } + + var outputPath = Path.Combine(outputModPath, "common/religion/religions/IRtoCK3_all_religions.txt"); + await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, Encoding.UTF8); + await output.WriteAsync(sb.ToString()); } } \ No newline at end of file diff --git a/ImperatorToCK3/Outputter/SuccessionTriggersOutputter.cs b/ImperatorToCK3/Outputter/SuccessionTriggersOutputter.cs index 3ce6c4099..b42b5f9c1 100644 --- a/ImperatorToCK3/Outputter/SuccessionTriggersOutputter.cs +++ b/ImperatorToCK3/Outputter/SuccessionTriggersOutputter.cs @@ -3,19 +3,18 @@ using ImperatorToCK3.CommonUtils; using System.Collections.Generic; using System.IO; +using System.Text; using System.Threading.Tasks; namespace ImperatorToCK3.Outputter; public static class SuccessionTriggersOutputter { public static async Task OutputSuccessionTriggers(string outputModPath, Title.LandedTitles landedTitles, Date ck3BookmarkDate) { Logger.Info("Writing Succession Triggers..."); - - var outputPath = Path.Combine(outputModPath, "common/scripted_triggers/IRToCK3_succession_triggers.txt"); - - await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8); var primogenitureTitles = new List<string>(); var seniorityTitles = new List<string>(); + + var sb = new StringBuilder(); foreach (var landedTitle in landedTitles) { if (landedTitle.GetDeFactoLiege(ck3BookmarkDate) is not null) { @@ -31,21 +30,25 @@ public static async Task OutputSuccessionTriggers(string outputModPath, Title.La } } - await output.WriteLineAsync("historical_succession_access_single_heir_succession_law_trigger={"); - await output.WriteLineAsync("\tOR={"); + sb.AppendLine("historical_succession_access_single_heir_succession_law_trigger={"); + sb.AppendLine("\tOR={"); foreach (var primogenitureTitle in primogenitureTitles) { - await output.WriteLineAsync($"\t\thas_title=title:{primogenitureTitle}"); + sb.AppendLine($"\t\thas_title=title:{primogenitureTitle}"); } - await output.WriteLineAsync("\t}"); - await output.WriteLineAsync("}"); + sb.AppendLine("\t}"); + sb.AppendLine("}"); - await output.WriteLineAsync("historical_succession_access_single_heir_dynasty_house_trigger={"); - await output.WriteLineAsync("\tOR={"); + sb.AppendLine("historical_succession_access_single_heir_dynasty_house_trigger={"); + sb.AppendLine("\tOR={"); foreach (var seniorityTitle in seniorityTitles) { - await output.WriteLineAsync($"\t\thas_title=title:{seniorityTitle}"); + sb.AppendLine($"\t\thas_title=title:{seniorityTitle}"); } - await output.WriteLineAsync("\t}"); - await output.WriteLineAsync("}"); + sb.AppendLine("\t}"); + sb.AppendLine("}"); + + var outputPath = Path.Combine(outputModPath, "common/scripted_triggers/IRToCK3_succession_triggers.txt"); + await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8); + await output.WriteAsync(sb.ToString()); Logger.IncrementProgress(); } diff --git a/ImperatorToCK3/Outputter/TitlesOutputter.cs b/ImperatorToCK3/Outputter/TitlesOutputter.cs index 891ea9c0d..f6618db4a 100644 --- a/ImperatorToCK3/Outputter/TitlesOutputter.cs +++ b/ImperatorToCK3/Outputter/TitlesOutputter.cs @@ -47,16 +47,19 @@ private static async Task OutputTitlesHistory(string outputModPath, Title.Landed public static async Task OutputTitles(string outputModPath, Title.LandedTitles titles) { Logger.Info("Writing Landed Titles..."); - var outputPath = Path.Combine(outputModPath, "common/landed_titles/00_landed_titles.txt"); - await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8); - + + var sb = new System.Text.StringBuilder(); foreach (var (name, value) in titles.Variables) { - await output.WriteLineAsync($"@{name}={value}"); + sb.AppendLine($"@{name}={value}"); } // titles with a de jure liege will be outputted under the liege var topDeJureTitles = titles.Where(t => t.DeJureLiege is null); - await output.WriteAsync(PDXSerializer.Serialize(topDeJureTitles, string.Empty, false)); + sb.Append(PDXSerializer.Serialize(topDeJureTitles, string.Empty, false)); + + var outputPath = Path.Combine(outputModPath, "common/landed_titles/00_landed_titles.txt"); + await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8); + await output.WriteAsync(sb.ToString()); await OutputTitlesHistory(outputModPath, titles); Logger.IncrementProgress(); diff --git a/ImperatorToCK3/Outputter/WarsOutputter.cs b/ImperatorToCK3/Outputter/WarsOutputter.cs index 05f6d09db..74c5861ed 100644 --- a/ImperatorToCK3/Outputter/WarsOutputter.cs +++ b/ImperatorToCK3/Outputter/WarsOutputter.cs @@ -11,27 +11,31 @@ namespace ImperatorToCK3.Outputter; public static class WarsOutputter { public static async Task OutputWars(string outputModPath, IEnumerable<War> wars) { Logger.Info("Writing wars..."); - // dumping all into one file - var path = Path.Combine(outputModPath, "history/wars/00_wars.txt"); - await using var output = FileOpeningHelper.OpenWriteWithRetries(path, Encoding.UTF8); + + // Dump all into one file. + var sb = new StringBuilder(); foreach (var war in wars) { - await OutputWar(output, war); + WriteWar(sb, war); } + var path = Path.Combine(outputModPath, "history/wars/00_wars.txt"); + await using var output = FileOpeningHelper.OpenWriteWithRetries(path, Encoding.UTF8); + await output.WriteAsync(sb.ToString()); + Logger.IncrementProgress(); } - private static async Task OutputWar(TextWriter output, War war) { - await output.WriteLineAsync("war = {"); + private static void WriteWar(StringBuilder sb, War war) { + sb.AppendLine("war = {"); - await output.WriteLineAsync($"\tstart_date = {war.StartDate}"); - await output.WriteLineAsync($"\tend_date = {war.EndDate}"); - await output.WriteLineAsync($"\ttargeted_titles={{ {string.Join(' ', war.TargetedTitles)} }}"); + sb.AppendLine($"\tstart_date = {war.StartDate}"); + sb.AppendLine($"\tend_date = {war.EndDate}"); + sb.AppendLine($"\ttargeted_titles={{ {string.Join(' ', war.TargetedTitles)} }}"); if (war.CasusBelli is not null) { - await output.WriteLineAsync($"\tcasus_belli = {war.CasusBelli}"); + sb.AppendLine($"\tcasus_belli = {war.CasusBelli}"); } - await output.WriteLineAsync($"\tattackers={{ {string.Join(' ', war.Attackers)} }}"); - await output.WriteLineAsync($"\tdefenders={{ {string.Join(' ', war.Defenders)} }}"); - await output.WriteLineAsync($"\tclaimant = {war.Claimant}"); + sb.AppendLine($"\tattackers={{ {string.Join(' ', war.Attackers)} }}"); + sb.AppendLine($"\tdefenders={{ {string.Join(' ', war.Defenders)} }}"); + sb.AppendLine($"\tclaimant = {war.Claimant}"); - await output.WriteLineAsync("}"); + sb.AppendLine("}"); } } \ No newline at end of file