Skip to content

Commit 08d7866

Browse files
authored
Fix for an independent counties problem reported by LastCaptainBonk (#3019) #patch
https://forum.paradoxplaza.com/forum/threads/imperator-to-ck3-release-thread.1415172/post-31167652
2 parents 06f16f9 + 7fee88f commit 08d7866

File tree

4 files changed

+73
-68
lines changed

4 files changed

+73
-68
lines changed

ImperatorToCK3.UnitTests/CK3/Characters/CK3CharacterTests.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -383,19 +383,37 @@ public void NameCanBeInitializedFromImperator() {
383383
Name = "alexandros"
384384
};
385385

386-
var locDB = new LocDB("english");
387-
var nameLocBlock = locDB.AddLocBlock("alexandros");
386+
var irLocDB = new LocDB("english");
387+
var nameLocBlock = irLocDB.AddLocBlock("alexandros");
388388
nameLocBlock["english"] = "Alexandros";
389389

390390
var ck3LocDB = new TestCK3LocDB();
391391

392392
var character = builder
393393
.WithImperatorCharacter(imperatorCharacter)
394-
.WithIRLocDB(locDB)
394+
.WithIRLocDB(irLocDB)
395395
.WithCK3LocDB(ck3LocDB)
396396
.Build();
397397
Assert.Equal("alexandros", character.GetName(ConversionDate));
398398
Assert.Equal("Alexandros", ck3LocDB.GetLocBlockForKey("alexandros")!["english"]);
399+
400+
// Also check if names with escaped quotes are converted correctly.
401+
const string irCharacter2Input = """
402+
first_name_loc={
403+
name="Predrag \"Peja\" Stojaković"
404+
}
405+
""";
406+
imperatorCharacter = ImperatorToCK3.Imperator.Characters.Character.Parse(new BufferedReader(irCharacter2Input), "2", new GenesDB());
407+
character = builder
408+
.WithImperatorCharacter(imperatorCharacter)
409+
.WithIRLocDB(irLocDB)
410+
.WithCK3LocDB(ck3LocDB)
411+
.Build();
412+
string? irCharacter2NameLocKey = character.GetName(ConversionDate);
413+
Assert.NotNull(irCharacter2NameLocKey);
414+
Assert.Equal("irtock3_char_2", irCharacter2NameLocKey);
415+
Assert.Equal("Predrag \"Peja\" Stojaković", ck3LocDB.GetLocBlockForKey(irCharacter2NameLocKey)!["english"]);
416+
Assert.Equal($" {irCharacter2NameLocKey}: \"Predrag \\\"Peja\\\" Stojaković\"", ck3LocDB.GetYmlLocLineForLanguage(irCharacter2NameLocKey, "english"));
399417
}
400418

401419
[Fact]

ImperatorToCK3/CK3/Characters/Character.cs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -538,19 +538,26 @@ private void SetCharacterNameFromImperator(ImperatorCharacter irCharacter, LocDB
538538
}
539539
} else {
540540
var nameLoc = irCharacter.Name;
541-
if (nameOverrides.TryGetValue(nameLoc, out var overrideName)) {
542-
nameLoc = overrideName;
541+
bool hasOverride = nameOverrides.TryGetValue(nameLoc, out var overrideName);
542+
if (hasOverride) {
543+
nameLoc = overrideName!;
543544
}
544545
var name = nameLoc.Replace(' ', '_');
545-
SetName(name, null);
546546
if (!string.IsNullOrEmpty(name)) {
547-
var ck3NameLocBlock = ck3LocDB.GetOrCreateLocBlock(name);
548547
var matchedLocBlock = irLocDB.GetLocBlockForKey(name);
549-
if (matchedLocBlock is not null) {
550-
ck3NameLocBlock.CopyFrom(matchedLocBlock);
551-
} else { // fallback: use unlocalized name as displayed name
552-
unlocalizedImperatorNames.Add(name);
553-
ck3NameLocBlock[ConverterGlobals.PrimaryLanguage] = nameLoc;
548+
if (matchedLocBlock is not null || hasOverride) {
549+
SetName(name, null);
550+
var ck3NameLocBlock = ck3LocDB.GetOrCreateLocBlock(name);
551+
if (matchedLocBlock is not null) {
552+
ck3NameLocBlock.CopyFrom(matchedLocBlock);
553+
} else {
554+
ck3NameLocBlock[ConverterGlobals.PrimaryLanguage] = nameLoc;
555+
}
556+
} else {
557+
var generatedKey = $"irtock3_char_{irCharacter.Id}";
558+
SetName(generatedKey, null);
559+
var ck3NameLocBlock = ck3LocDB.GetOrCreateLocBlock(generatedKey);
560+
ck3NameLocBlock[ConverterGlobals.PrimaryLanguage] = nameLoc.Replace("\\\"", "\"");
554561
}
555562
}
556563
}

ImperatorToCK3/CK3/Localization/CK3LocBlock.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ public void ModifyForEveryLanguage(LocDelegate modifyingFunction) {
127127
}
128128

129129
public string GetYmlLocLineForLanguage(string language) {
130-
return $" {Id}: \"{this[language]}\"";
130+
var value = this[language]?.Replace("\"", "\\\"") ?? string.Empty;
131+
return $" {Id}: \"{value}\"";
131132
}
132133

133134
public CK3LocType? GetLocTypeForLanguage(string language) {

ImperatorToCK3/Imperator/Characters/Character.cs

Lines changed: 34 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public string AgeSex {
112112
public static ConcurrentIgnoredKeywordsSet IgnoredTokens { get; } = [];
113113

114114
private static void RegisterCharacterKeywords(Parser parser, Character character) {
115-
parser.RegisterKeyword("first_name_loc", SetCharacterName(character));
115+
parser.RegisterKeyword("first_name_loc", r => SetCharacterName(character, r));
116116
parser.RegisterKeyword("family_name", reader => character.FamilyName = reader.GetString());
117117
parser.RegisterKeyword("country", reader => character.parsedCountryId = reader.GetULong());
118118
parser.RegisterKeyword("home_country", reader => character.parsedHomeCountryId = reader.GetULong());
@@ -126,34 +126,32 @@ private static void RegisterCharacterKeywords(Parser parser, Character character
126126
parser.RegisterKeyword("female", reader => character.Female = reader.GetBool());
127127
parser.RegisterKeyword("children", reader => character.parsedChildrenIds = [.. reader.GetULongs()]);
128128
parser.RegisterKeyword("spouse", reader => character.parsedSpouseIds = [.. reader.GetULongs()]);
129-
parser.RegisterKeyword("friends", SetFriendIds(character));
130-
parser.RegisterKeyword("rivals", SetRivalIds(character));
129+
parser.RegisterKeyword("friends", r => SetFriendIds(character, r));
130+
parser.RegisterKeyword("rivals", r => SetRivalIds(character, r));
131131
parser.RegisterKeyword("age", reader => character.Age = (uint)reader.GetInt());
132-
parser.RegisterKeyword("birth_date", SetBirthDate(character));
133-
parser.RegisterKeyword("death_date", SetDeathDate(character));
132+
parser.RegisterKeyword("birth_date", r => SetBirthDate(character, r));
133+
parser.RegisterKeyword("death_date", r => SetDeathDate(character, r));
134134
parser.RegisterKeyword("death", reader => character.DeathReason = string.Intern(reader.GetString()));
135135
parser.RegisterKeyword("attributes", reader => character.Attributes = CharacterAttributes.Parse(reader));
136136
parser.RegisterKeyword("nickname", reader => character.Nickname = string.Intern(reader.GetString()));
137137
parser.RegisterKeyword("dna", reader => character.DNA = reader.GetString());
138138
parser.RegisterKeyword("mother", reader => character.parsedMotherId = reader.GetULong());
139139
parser.RegisterKeyword("father", reader => character.parsedFatherId = reader.GetULong());
140140
parser.RegisterKeyword("wealth", reader => character.Wealth = reader.GetFloat());
141-
parser.RegisterKeyword("unborn", SetUnborns(character));
141+
parser.RegisterKeyword("unborn", r => SetUnborns(character, r));
142142
parser.RegisterKeyword("prisoner_home", reader => character.parsedPrisonerHomeId = reader.GetULong());
143-
parser.RegisterKeyword("variables", SetVariables(character));
143+
parser.RegisterKeyword("variables", r => SetVariables(character, r));
144144
parser.IgnoreAndStoreUnregisteredItems(IgnoredTokens);
145145
}
146146

147-
private static SimpleDel SetVariables(Character character)
148-
{
149-
return reader => {
150-
var variables = new HashSet<string>();
147+
private static void SetVariables(Character character, BufferedReader reader) {
148+
var variables = new HashSet<string>();
151149
var variablesParser = new Parser();
152150
variablesParser.RegisterKeyword("data", dataReader => {
153151
var blobParser = new Parser();
154152
blobParser.RegisterKeyword("flag", blobReader => variables.Add(string.Intern(blobReader.GetString())));
155153
blobParser.IgnoreUnregisteredItems();
156-
154+
157155
foreach (var blob in new BlobList(dataReader).Blobs) {
158156
blobParser.ParseStream(new BufferedReader(blob));
159157
}
@@ -162,62 +160,43 @@ private static SimpleDel SetVariables(Character character)
162160
variablesParser.IgnoreAndLogUnregisteredItems();
163161
variablesParser.ParseStream(reader);
164162
character.Variables = variables.ToImmutableHashSet();
165-
};
166163
}
167164

168-
private static SimpleDel SetCharacterName(Character character)
169-
{
170-
return reader => {
171-
var characterName = new CharacterName(reader);
172-
character.Name = characterName.Name;
173-
character.CustomName = characterName.CustomName;
174-
};
165+
private static void SetCharacterName(Character character, BufferedReader reader) {
166+
var characterName = new CharacterName(reader);
167+
character.Name = characterName.Name;
168+
character.CustomName = characterName.CustomName;
175169
}
176170

177-
private static SimpleDel SetDeathDate(Character character)
178-
{
179-
return reader => {
180-
character.DeathDate = new Date(reader.GetString(), AUC: true); // converted to AD
181-
};
171+
private static void SetDeathDate(Character character, BufferedReader reader) {
172+
character.DeathDate = new Date(reader.GetString(), AUC: true); // converted to AD
182173
}
183174

184-
private static SimpleDel SetBirthDate(Character character)
185-
{
186-
return reader => {
187-
character.BirthDate = new Date(reader.GetString(), AUC: true); // converted to AD
188-
};
175+
private static void SetBirthDate(Character character, BufferedReader reader) {
176+
character.BirthDate = new Date(reader.GetString(), AUC: true); // converted to AD
189177
}
190178

191-
private static SimpleDel SetFriendIds(Character character)
192-
{
193-
return reader => {
194-
character.FriendIds.Clear();
195-
character.FriendIds.AddRange(reader.GetULongs());
196-
};
179+
private static void SetFriendIds(Character character, BufferedReader reader) {
180+
character.FriendIds.Clear();
181+
character.FriendIds.AddRange(reader.GetULongs());
197182
}
198183

199-
private static SimpleDel SetRivalIds(Character character)
200-
{
201-
return reader => {
202-
character.RivalIds.Clear();
203-
character.RivalIds.AddRange(reader.GetULongs());
204-
};
184+
private static void SetRivalIds(Character character, BufferedReader reader) {
185+
character.RivalIds.Clear();
186+
character.RivalIds.AddRange(reader.GetULongs());
205187
}
206188

207-
private static SimpleDel SetUnborns(Character character)
208-
{
209-
return reader => {
210-
var unborns = new List<Unborn>();
211-
foreach (var blob in new BlobList(reader).Blobs) {
212-
var blobReader = new BufferedReader(blob);
213-
var unborn = Unborn.Parse(blobReader);
214-
if (unborn is null) {
215-
continue;
216-
}
217-
unborns.Add(unborn);
189+
private static void SetUnborns(Character character, BufferedReader reader) {
190+
var unborns = new List<Unborn>();
191+
foreach (var blob in new BlobList(reader).Blobs) {
192+
var blobReader = new BufferedReader(blob);
193+
var unborn = Unborn.Parse(blobReader);
194+
if (unborn is null) {
195+
continue;
218196
}
219-
character.Unborns = [.. unborns];
220-
};
197+
unborns.Add(unborn);
198+
}
199+
character.Unborns = [.. unborns];
221200
}
222201

223202
public static Character Parse(BufferedReader reader, string idString, GenesDB? genesDB) {

0 commit comments

Comments
 (0)