Use straight apostrophe for Gen3/4 (#4275)

Colosseum/XD/PBR/Ranch/Gen5 all treat the apostrophe/right single quote as a straight apostrophe (U+0027).

This primarily affects unnicknamed Colo/XD Farfetch'd, which need to use `'` instead of `’` to be traded to GBA correctly.
This commit is contained in:
abcboy101 2024-05-18 11:04:25 -04:00 committed by GitHub
parent 3811f8d114
commit 94e408d445
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 50 additions and 11 deletions

View file

@ -186,8 +186,8 @@ public sealed record EncounterTrade3 : IEncounterable, IEncounterMatch, IFixedTr
Span<char> tmp = stackalloc char[name.Length];
StringConverter345.TransferGlyphs34(name, language, tmp);
if (pk.Context == EntityContext.Gen5)
StringConverter345.TransferGlyphs45(tmp); // Apostrophe ' vs
if (pk.Context >= EntityContext.Gen6)
StringConverter345.TransferGlyphs56(tmp); // Apostrophe ' vs
return nickname.SequenceEqual(tmp);
}

View file

@ -9,10 +9,9 @@ public static class StringConverter3
{
public const byte TerminatorByte = 0xFF;
private const char Terminator = (char)TerminatorByte;
private const char Apostrophe = '\''; //
private const byte ApostropheByte = 0xB4;
private const byte QuoteLeftByte = 0xB1;
private const byte QuoteRightByte = 0xB2;
private const byte ApostropheByte = 0xB4;
private const char FGM = '♂';
private const char FGF = '♀';
@ -175,7 +174,7 @@ public static class StringConverter3
{
result = c switch
{
Apostrophe => ApostropheByte,
'' => ApostropheByte, // -> '
'“' => language != (int)LanguageID.German ? QuoteLeftByte : QuoteRightByte,
'”' => QuoteRightByte,
'«' => QuoteLeftByte,
@ -201,7 +200,7 @@ public static class StringConverter3
'ィ', 'ゥ', 'ェ', 'ォ', 'ャ', 'ュ', 'ョ', 'ガ', 'ギ', 'グ', 'ゲ', 'ゴ', 'ザ', 'ジ', 'ズ', 'ゼ', // 8
'ゾ', 'ダ', 'ヂ', 'ヅ', 'デ', 'ド', 'バ', 'ビ', 'ブ', 'ベ', 'ボ', 'パ', 'ピ', 'プ', 'ペ', 'ポ', // 9
'ッ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '!', '?', '.', '-', '・',// A
'⑬', '“', '”', '', '', HGM, HGF, '$', ',', '⑧', '/', 'A', 'B', 'C', 'D', 'E', // B
'⑬', '“', '”', '', '\'', HGM, HGF, '$', ',', '⑧', '/', 'A', 'B', 'C', 'D', 'E', // B
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', // C
'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', // D
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '►', // E

View file

@ -101,8 +101,6 @@ public static class StringConverter345
var c = input[i];
if (IsInvalid45(c))
input[i] = '?';
else if (c == '') // Farfetchd and CHDING nicknames
input[i] = '\''; // Wrong apostrophe, nice. Only is corrected when converted to Gen6.
}
}
@ -128,6 +126,22 @@ public static class StringConverter345
}
}
/// <summary>
/// Remaps Gen5 Glyphs to unicode codepoint.
/// </summary>
/// <param name="input">Input characters to transfer in place</param>
public static void TransferGlyphs56(Span<char> input)
{
for (int i = 0; i < input.Length; i += 2)
{
var c = input[i];
if (IsPrivateUseChar(c))
input[i] = (char)GetMigratedPrivateChar(c);
else if (c is '\'') // Fix all apostrophes. ' ->
input[i] = '';
}
}
/// <summary>
/// Remaps private use unicode codepoint back to Gen5 private use codepoint.
/// </summary>
@ -143,6 +157,22 @@ public static class StringConverter345
}
}
/// <summary>
/// Remaps private use unicode codepoint back to Gen5 private use codepoint.
/// </summary>
/// <param name="input">Input characters to transfer in place</param>
public static void TransferGlyphs65(Span<char> input)
{
for (int i = 0; i < input.Length; i += 2)
{
var c = input[i];
if (IsPrivateUseCharUnicode(c))
input[i] = (char)GetUnmigratedPrivateChar(c);
else if (c is '') // Fix all apostrophes. -> '
input[i] = '\'';
}
}
// Nonstandard characters for Gen 5 are stored at 0x2460 instead of the reserved section.
// We could ignore inaccessible indexes, but we'll just remap them in bulk.
private const ushort PrivateUseStartGlyph = 0x2460;

View file

@ -35,6 +35,8 @@ public static class StringConverter4Util
index = TableKOR.IndexOf(c);
if (index >= 0)
return (ushort)(index + TableKORStart);
if (c == '')
return Apostrophe; // -> '
return SaveInvalidAs;
}
@ -71,6 +73,7 @@ public static class StringConverter4Util
private const ushort SaveInvalidAs = 0x1AC; // '?'
private const char NUL = (char)StringConverter4.Terminator;
private const char EMP = NUL; // Empty, not available on keyboard.
private const ushort Apostrophe = 0x1B3;
/// <summary>
/// Half-width gender 16-bit char representation.
@ -132,7 +135,7 @@ public static class StringConverter4Util
'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ð', // 180-18F
'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', '⑨', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'þ', 'ÿ', 'Œ', // 190-19F
'œ', 'Ş', 'ş', 'ª', 'º', '⑩', '⑪', '⑫', '$', '¡', '¿', '!', '?', ',', '.', '⑬', // 1A0-1AF
'・', '/', '', '', '“', '”', '„', '«', '»', '(', ')', HGM, HGF, '+', '-', '*', // 1B0-1BF
'・', '/', '', '\'', '“', '”', '„', '«', '»', '(', ')', HGM, HGF, '+', '-', '*', // 1B0-1BF
'#', '=', '&', '~', ':', ';', '⑯', '⑰', '⑱', '⑲', '⑳', '⑴', '⑵', '⑶', '⑷', '⑸', // 1C0-1CF
'@', '⑹', '%', '⑺', '⑻', '⑼', '⑽', '⑾', '⑿', '⒀', '⒁', '⒂', '⒃', '⒄', ' ', '⒅', // 1D0-1DF
'⒆', '⒇', '⒈', '⒉', '⒊', '⒋', '⒌', '⒍', '°', '_', '_', '⒎', '⒏', // 1E0-1EC*

View file

@ -167,7 +167,14 @@ public static class SpeciesName
// Gen1/2 species names do not have spaces.
if (generation >= 3)
{
// Gen3/4 use straight apostrophe instead of slanted apostrophe.
// The only Gen3/4 species with an apostrophe is Farfetch'd.
if (species is (int)Species.Farfetchd && IsApostropheFarfetchdLanguage(language))
result[^2] = '\'';
return new string(result);
}
// The only Gen1/2 species with a space is Mr. Mime; different period and no space.
if (species == (int)Species.MrMime)

View file

@ -6,7 +6,7 @@ NINO
MARC
MARC
ZYNX
CHDING
CH'DING
ESPHERE
TANGENY
SEELOR

View file

@ -6,7 +6,7 @@ NINO
MARC
MARC
ZYNX
CHDING
CH'DING
ESPHERE
TANGENY
SEELOR