fix(flags): map pony flags to sprite sheet coordinates

Pony flag selector order differs from the sprite layout, so derive
positions from explicit coordinates instead of entry index.
This commit is contained in:
Tommaso Casaburi
2026-06-08 17:12:59 +07:00
parent 46aa197562
commit cbdd4edf7b
2 changed files with 94 additions and 2 deletions
+6 -1
View File
@@ -56,7 +56,12 @@ describe('board-flags', () => {
x: 0,
y: 0,
});
expect(getBoardFlagDefinition('pony', 'AJ')).toMatchObject({ code: 'AJ', label: 'Applejack', x: 80, y: 0 });
// Selector order (PONY_FLAG_ENTRIES) differs from the sprite's alphabetical-by-code layout,
// so these codes only land on the right cell via PONY_FLAG_COORDINATES.
expect(getBoardFlagDefinition('pony', 'AB')).toMatchObject({ code: 'AB', label: 'Aria Blaze', x: 16, y: 0 });
expect(getBoardFlagDefinition('pony', 'ADA')).toMatchObject({ code: 'ADA', label: 'Adagio Dazzle', x: 32, y: 0 });
expect(getBoardFlagDefinition('pony', 'AJ')).toMatchObject({ code: 'AJ', label: 'Applejack', x: 48, y: 0 });
expect(getBoardFlagDefinition('pony', 'AN')).toMatchObject({ code: 'AN', label: 'Anon', x: 64, y: 0 });
expect(getBoardFlagDefinition('pony', 'ZS')).toMatchObject({ code: 'ZS', label: 'Zipp Storm', x: 16, y: 144 });
});
});
+88 -1
View File
@@ -78,6 +78,7 @@ const POLITICAL_FLAG_COORDINATES = {
WP: [64, 48],
} as const satisfies Record<(typeof POLITICAL_FLAG_ENTRIES)[number][0], readonly [number, number]>;
// Order follows 4chan's board flag selector. Coordinates follow flags/mlp/flags.1.css.
const PONY_FLAG_ENTRIES = [
['4CC', '4cc /mlp/'],
['ADA', 'Adagio Dazzle'],
@@ -164,6 +165,92 @@ const PONY_FLAG_ENTRIES = [
['ZS', 'Zipp Storm'],
] as const;
const PONY_FLAG_COORDINATES = {
'4CC': [0, 0],
AB: [16, 0],
ADA: [32, 0],
AJ: [48, 0],
AN: [64, 0],
ANF: [80, 0],
APB: [96, 0],
AU: [112, 0],
BB: [128, 0],
BM: [0, 16],
BP: [16, 16],
BS: [32, 16],
CB: [48, 16],
CG: [64, 16],
CHE: [80, 16],
CL: [96, 16],
CO: [112, 16],
DAY: [128, 16],
DD: [0, 32],
DER: [16, 32],
DIS: [32, 32],
DT: [48, 32],
EQA: [64, 32],
EQF: [80, 32],
EQI: [96, 32],
EQP: [112, 32],
EQR: [128, 32],
EQS: [0, 48],
EQT: [16, 48],
ERA: [32, 48],
FAU: [48, 48],
FL: [64, 48],
FLE: [80, 48],
GI: [96, 48],
HT: [112, 48],
IZ: [128, 48],
LI: [0, 64],
LT: [16, 64],
LY: [32, 64],
MA: [48, 64],
MAU: [64, 64],
MIN: [80, 64],
NI: [96, 64],
NUR: [112, 64],
OCT: [128, 64],
PAR: [0, 80],
PC: [16, 80],
PCE: [32, 80],
PI: [48, 80],
PLU: [64, 80],
PM: [80, 80],
PP: [96, 80],
QC: [112, 80],
RAR: [128, 80],
RD: [0, 96],
RLU: [16, 96],
S1L: [32, 96],
SCO: [48, 96],
SHI: [64, 96],
SIL: [80, 96],
SON: [96, 96],
SP: [112, 96],
SPI: [128, 96],
SPT: [0, 112],
SS: [16, 112],
STA: [32, 112],
STL: [48, 112],
SUN: [64, 112],
SUS: [80, 112],
SWB: [96, 112],
TFA: [112, 112],
TFO: [128, 112],
TFP: [0, 128],
TFS: [16, 128],
TFT: [32, 128],
TFV: [48, 128],
TP: [64, 128],
TS: [80, 128],
TWI: [96, 128],
TX: [112, 128],
VS: [128, 128],
ZE: [0, 144],
ZS: [16, 144],
} as const satisfies Record<(typeof PONY_FLAG_ENTRIES)[number][0], readonly [number, number]>;
const normalizeCode = (value: string | undefined) => value?.trim().toUpperCase();
const buildFlagDefinitions = (
@@ -204,7 +291,7 @@ const BOARD_FLAGS_BY_KIND: Record<BoardFlagKind, ReadonlyMap<string, BoardFlagDe
POLITICAL_FLAG_COLUMNS,
POLITICAL_FLAG_COORDINATES,
),
pony: buildFlagDefinitions(PONY_FLAG_ENTRIES, 'pony', PONY_FLAG_SPRITE_PATH, PONY_FLAG_WIDTH, PONY_FLAG_HEIGHT, PONY_FLAG_COLUMNS),
pony: buildFlagDefinitions(PONY_FLAG_ENTRIES, 'pony', PONY_FLAG_SPRITE_PATH, PONY_FLAG_WIDTH, PONY_FLAG_HEIGHT, PONY_FLAG_COLUMNS, PONY_FLAG_COORDINATES),
};
export const normalizeBoardFlagKind = (value: string | undefined): BoardFlagKind | undefined => {