mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
f07ebfe423
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.
72 lines
3.2 KiB
Lua
72 lines
3.2 KiB
Lua
-- The Game Corner price columns (PrizeMenu.lua) are right-aligned against a
|
|
-- fixed priceRight column per counter; a translated prize name longer than
|
|
-- the tile budget before that column would otherwise overlap or run into
|
|
-- the price digits Chrome.print draws right after it, since the name and
|
|
-- price are now two separate draw calls (#1642-adjacent). This drives
|
|
-- drawPanel() with an over-long name via a mod's strings override and
|
|
-- checks the drawn name never crosses into the price column.
|
|
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 drawn
|
|
package.loaded["src.ui.gen2.Chrome"] = setmetatable({
|
|
print = function(text, x, y) drawn[#drawn + 1] = { text = text, x = x, y = y } end,
|
|
clear = function() end,
|
|
textbox = function() end,
|
|
cursor = function() end,
|
|
}, { __index = require("src.ui.gen2.Chrome") })
|
|
|
|
local PrizeMenu = require("src.ui.gen2.PrizeMenu")
|
|
local Font = require("src.render.Font")
|
|
local Strings = require("src.core.Strings")
|
|
Strings.load({ strings = { ["MR.MIME"] = "A NAME MUCH LONGER THAN THE COUNTER ROW" } })
|
|
|
|
local counter = PrizeMenu.COUNTERS.CELADON_MON
|
|
local prize = counter.prizes[1] -- MR.MIME, cost 3333
|
|
drawn = {}
|
|
local self = setmetatable({
|
|
save = {}, phase = "menu", index = 1, counter = counter,
|
|
prizes = { prize }, text = {},
|
|
}, PrizeMenu)
|
|
self:drawPanel()
|
|
|
|
-- drawn[1..2] are drawCoinBox()'s COIN label and coin count.
|
|
local nameDraw, priceDraw = drawn[3], drawn[4]
|
|
T.check(nameDraw and nameDraw.text:find("^A NAME"), "the translated name is drawn")
|
|
T.check(#nameDraw.text <= counter.priceRight - #tostring(prize.cost) - 2,
|
|
"the drawn name is clamped to the tile budget before the price column")
|
|
T.eq(priceDraw and priceDraw.text, "3333", "the price still draws in full")
|
|
T.check(priceDraw.x > nameDraw.x + #nameDraw.text,
|
|
"the price column starts after the clamped name ends")
|
|
|
|
-- The redrawn text must never exceed the tile budget either: byte length
|
|
-- alone is not the right measure once a macro is involved (see below).
|
|
T.check(#Font.split(nameDraw.text) <= counter.priceRight - #tostring(prize.cost) - 2,
|
|
"the drawn name's glyph width (not byte length) fits the tile budget")
|
|
|
|
-- Font.split's "#" macro expands to four glyphs (POKé) from one source
|
|
-- byte; a naive byte-position cut lands inside that expansion and still
|
|
-- copies the whole "#" byte, which re-expands past the budget on redraw.
|
|
-- Position it so exactly one tile is free where the whole four-glyph
|
|
-- macro would be needed.
|
|
Strings.load({ strings = { ["EEVEE"] = "AAAAAAAAA#EXTRA" } })
|
|
drawn = {}
|
|
local eevee = counter.prizes[2] -- EEVEE, cost 6666
|
|
local self2 = setmetatable({
|
|
save = {}, phase = "menu", index = 1, counter = counter,
|
|
prizes = { eevee }, text = {},
|
|
}, PrizeMenu)
|
|
self2:drawPanel()
|
|
local macroNameDraw = drawn[3]
|
|
local macroBudget = counter.priceRight - #tostring(eevee.cost) - 2
|
|
T.check(macroNameDraw and macroNameDraw.text == ("A"):rep(9),
|
|
"a macro straddling the budget is dropped whole, not cut mid-expansion")
|
|
T.check(#Font.split(macroNameDraw.text) <= macroBudget,
|
|
"the macro-adjacent name's glyph width fits the tile budget after redraw")
|
|
|
|
Strings.load(nil)
|
|
T.finish("prize_counter_name_clamp_test")
|