Files
gen1recomp/tests/engine/gen2_trainer_card_text_palette_test.lua
thibautbus f07ebfe423 Route remaining Gen2 UI text through translations
CELADON_TM/MON and GOLDENROD_TM/MON stored each Game Corner row as one
hand-padded "NAME    COST" literal; a translated name of a different length
than the English original shifted or overlapped the price that used to be
right-aligned by the padding alone. Split each row into a translatable name
and the existing numeric cost field, print them as two separate calls (the
cost right-aligned against a fixed priceRight column per counter, the same
column-aware approach MartMenu.printPriceOpaque already uses), and clamp the
name to the tile budget before the price column with Font.split (glyph-aware,
so a <PK><MN> macro or multi-byte UTF-8 character -- including one whose
expansion straddles the clamp boundary -- is never cut mid-sequence).

TEXTS (SlotMachine.lua) kept a hand-typed English line array next to each
entry's Strings.source() template; derive the array from source once at load
instead, and cache localizedLines()'s parsed split per source table so the
bet/result screens do not re-run the same gmatch split every draw() call.

ContestMenu.TEXT.alreadyCaught's line split now uses the same gmatch loop
the rest of this file's line-parsing already uses (an anchored ^(.-)\n(.*)$
match assumed exactly one \n and left a nil hole when a translation merges
the two lines into one clause).

Four of PrizeMenu.TEXTS' Game Corner vendor messages (Celadon's and
Goldenrod's prize-vendor intros, Goldenrod's quit line, and the coin
vendor's no-COIN-CASE refusal) used \f where the real cart text
(poke-corpus GoldSilver, e.g. gs.CeladonGameCornerPrizeRoom.
CeladonPrizeRoom_PrizeVendorIntroText) ends in \v: a plain page clear
instead of a scroll, so the vendor's last line appeared alone with no
lead-in instead of continuing under the previous one. Found and confirmed
against the corpus while auditing this branch for the same class of bug as
CenterPcMenu.lua's \n-vs-\v fix.
2026-09-01 21:52:55 +02:00

119 lines
4.2 KiB
Lua

-- TrainerCard had two palette gaps: its own text drew through flat
-- Chrome.print/cursor, fixed with a print/:cursor pair routed through
-- printThrough/cursorThrough via self:colorsAt; and drawPanel() painted
-- the screen with a flat white rectangle before anything else, leaving the
-- NAME/ID/MONEY/STATUS/BADGES interiors white, fixed by routing that fill
-- through Chrome.paletteFill.
package.path = "./?.lua;./?/init.lua;" .. package.path
local T = require("tests.harness")
love = require("tests.love_stub")
require("src.core.Logger").warn = function() end
local GbcPalette = require("src.render.GbcPalette")
local TrainerCard = require("src.ui.gen2.TrainerCard")
local Strings = require("src.core.Strings")
GbcPalette.available = function() return true end
GbcPalette.setCustomRamp({ { 255, 0, 255 }, { 200, 0, 200 }, { 100, 0, 100 },
{ 0, 0, 0 } })
local calls
local function spy(name)
local original = GbcPalette[name]
GbcPalette[name] = function(...)
calls[name] = (calls[name] or 0) + 1
return original(...)
end
end
local function fakeCard()
return {
colorsAt = function() return { { 255, 255, 255 }, { 200, 0, 200 },
{ 100, 0, 100 }, { 0, 0, 0 } } end,
}
end
do
calls = {}
spy("resolve"); spy("use"); spy("with")
TrainerCard.print(fakeCard(), "NAME/", 2, 2)
T.check((calls.resolve or 0) > 0 or (calls.use or 0) > 0 or (calls.with or 0) > 0,
"TrainerCard:print() reaches the GbcPalette seam via self:colorsAt")
end
do
calls = {}
spy("resolve"); spy("use"); spy("with")
TrainerCard.cursor(fakeCard(), 18, 15)
T.check((calls.resolve or 0) > 0 or (calls.use or 0) > 0 or (calls.with or 0) > 0,
"TrainerCard:cursor() reaches the GbcPalette seam via self:colorsAt")
end
-- drawPanel() painted the whole screen with a flat white rectangle before
-- drawing the card, and self:frame only draws border tiles, so panel
-- interiors stayed white regardless of the picked palette. drawCard is
-- stubbed here to isolate that base fill from the print/cursor seam
-- covered above.
do
local fake = { styled = function() return true end, page = 1,
drawCard = function() end }
calls = {}
spy("resolve"); spy("use"); spy("with")
TrainerCard.drawPanel(fake)
T.check((calls.resolve or 0) > 0 or (calls.use or 0) > 0 or (calls.with or 0) > 0,
"TrainerCard:drawPanel()'s base fill reaches the GbcPalette seam")
end
-- Text labels are catalog-backed, while the player's chosen name is content
-- and must remain verbatim.
do
local Chrome = require("src.ui.gen2.Chrome")
local priorPrintThrough = Chrome.printThrough
local printed = {}
Chrome.printThrough = function(text) printed[#printed + 1] = text end
Strings.load({ strings = {
["NAME/"] = "NOM/", MONEY = "ARGENT", ["POKéDEX"] = "DEX-FR",
["PLAY TIME"] = "TEMPS", BADGES = "BADGES-FR", GOLD = "INTERDIT",
} })
TrainerCard.drawPlain({
page = 1,
save = { player = { name = "GOLD", id = 7, money = 12 }, playTime = {} },
caughtCount = function() return 0 end,
})
local all = table.concat(printed, "|")
T.check(all:find("NOM/", 1, true) and all:find("ARGENT", 1, true)
and all:find("DEX-FR", 1, true) and all:find("TEMPS", 1, true),
"Trainer Card's finite labels pass through Strings")
T.check(all:find("GOLD", 1, true) and not all:find("INTERDIT", 1, true),
"the player's name stays raw")
Strings.load({})
Chrome.printThrough = priorPrintThrough
end
-- Badge names are finite UI labels too; unlike the player's name above they
-- must be looked up when the page is drawn (and then shortened to four chars).
do
local Chrome = require("src.ui.gen2.Chrome")
local priorPrintThrough = Chrome.printThrough
local printed = {}
Chrome.printThrough = function(text) printed[#printed + 1] = text end
Strings.load({ strings = {
["JOHTO BADGES"] = "BADGES JOHTO",
ZEPHYR = "ÉCLAIR",
} })
TrainerCard.drawPlain({
page = 2,
save = { player = { badges = { ZEPHYR = true } } },
})
local all = table.concat(printed, "|")
T.check(all:find("BADGES JOHTO", 1, true) and all:find("ÉCLA", 1, true),
"Trainer Card translates and clips badge names on font-glyph boundaries")
Strings.load({})
Chrome.printThrough = priorPrintThrough
end
T.finish()