Merge pull request #950 from jherediagu/fix/translation-readiness

Translation-readiness: route the last hardcoded labels through the Strings catalog.
This commit is contained in:
bryanthaboi
2026-08-07 12:36:47 -04:00
committed by GitHub
4 changed files with 45 additions and 17 deletions
+6 -6
View File
@@ -424,7 +424,7 @@ function StatBox:draw()
{ Strings("SPEED"), s.speed },
{ Strings("SPECIAL"), s.special } }
for i, r in ipairs(rows) do
Font.draw(r[1], 88, 24 + (i - 1) * 16)
Font.draw(Strings(r[1]), 88, 24 + (i - 1) * 16)
Font.draw(("%3d"):format(r[2]), 128, 32 + (i - 1) * 16)
end
love.graphics.setColor(1, 1, 1, 1)
@@ -5587,9 +5587,9 @@ function BattleState:drawTextArea()
-- -- next to FIGHT (9,14) for the first 80 frames, then ITEM (9,16)
Font.drawBox(8, 12, 12, 6)
love.graphics.setColor(0, 0, 0, 1)
Font.draw(Strings("FIGHT"), 80, 112)
Font.draw(Strings("FIGHT", "battle"), 80, 112)
Font.drawCode(0xE1, 128, 112); Font.drawCode(0xE2, 136, 112)
Font.draw(Strings("ITEM"), 80, 128); Font.draw(Strings("RUN"), 128, 128)
Font.draw(Strings("ITEM", "battle"), 80, 128); Font.draw(Strings("RUN", "battle"), 128, 128)
Font.drawCode(0xED, 72, (self.demoTimer or 0) <= 80 and 112 or 128)
elseif self.phase == "menu" then
local col = (self.menuIndex - 1) % 2
@@ -5599,7 +5599,7 @@ function BattleState:drawTextArea()
-- THROW ROCK RUN" from (2,14)
Font.drawBox(0, 12, 20, 6)
Font.draw(Strings("BALLx"), 16, 112); Font.draw(Strings("BAIT"), 112, 112)
Font.draw(Strings("THROW ROCK"), 16, 128); Font.draw(Strings("RUN"), 112, 128)
Font.draw(Strings("THROW ROCK"), 16, 128); Font.draw(Strings("RUN", "battle"), 112, 128)
-- DisplayBattleMenu .safariLeftColumn / .safariRightColumn print
-- wNumSafariBalls at hlcoord 7,14 with `lb bc, 1, 2` -- one byte, two
-- digits, space padded -- right after the "BALLx" label at columns
@@ -5610,9 +5610,9 @@ function BattleState:drawTextArea()
-- BATTLE_MENU_TEMPLATE: box (8,12)-(19,17), "FIGHT <PK><MN> /
-- ITEM RUN" from (10,14); cursor columns 9 / 15
Font.drawBox(8, 12, 12, 6)
Font.draw(Strings("FIGHT"), 80, 112)
Font.draw(Strings("FIGHT", "battle"), 80, 112)
Font.drawCode(0xE1, 128, 112); Font.drawCode(0xE2, 136, 112)
Font.draw(Strings("ITEM"), 80, 128); Font.draw(Strings("RUN"), 128, 128)
Font.draw(Strings("ITEM", "battle"), 80, 128); Font.draw(Strings("RUN", "battle"), 128, 128)
Font.drawCode(0xED, (col == 0 and 72 or 120), 112 + row * 16)
end
elseif self.phase == "moveSelect" then
+3 -3
View File
@@ -94,7 +94,7 @@ function DexEntryMenu.render(game, def, sprite, forceOwned, trueColor)
-- same number width as the list (constants.dexDigits), so a dex past 999
-- prints the extra digit everywhere at once
local digits = (game.data.constants or {}).dexDigits or 3
Font.draw(("No.%0" .. digits .. "d"):format(def.dex or 0), 72, 32)
Font.draw(Strings("No.") .. ("%0" .. digits .. "d"):format(def.dex or 0), 72, 32)
local owned = forceOwned
or (game.save.pokedex and game.save.pokedex.owned[def.id])
-- height/weight print only once owned, like the description
@@ -105,8 +105,8 @@ function DexEntryMenu.render(game, def, sprite, forceOwned, trueColor)
-- pokedex.asm; the tiles come from gfx/pokedex/pokedex.png via
-- engine/gfx/load_pokedex_tiles.asm)
if e.heightM then
Font.draw((("GR. %.1fm"):format(e.heightM):gsub("(%d)%.(%d)", "%1,%2")), 64, 44)
Font.draw((("GEW. %.1fkg"):format(e.weightKg or 0):gsub("(%d)%.(%d)", "%1,%2")), 64, 54)
Font.draw((Strings("GR. %.1fm", e.heightM):gsub("(%d)%.(%d)", "%1,%2")), 72, 44)
Font.draw((Strings("GEW. %.1fkg", e.weightKg or 0):gsub("(%d)%.(%d)", "%1,%2")), 72, 54)
else
Font.draw(Strings("HT %d%02d″", e.heightFt, e.heightIn or 0), 72, 44)
Font.draw(Strings("WT %.1flb", (e.weight or 0) / 10), 72, 54)
+1 -1
View File
@@ -44,7 +44,7 @@ local function askQuantity(game, list, count, id, cb)
cb(1)
return
end
list.footer = "How many?"
list.footer = Strings("How many?")
local QuantityBox = require("src.ui.QuantityBox")
game.stack:push(QuantityBox.new(game, {
max = count,
+35 -7
View File
@@ -107,7 +107,12 @@ local CYCLE_FRAMES = 240 -- the original waits ~4s between picks
local function tryImage(path)
if not path then return nil end
local ok, img = pcall(love.graphics.newImage, path)
-- resolve through Assets so a mod's derived art (save/mod-derived/)
-- wins here the way it does for every other generated sheet -- but
-- load uncached, because on NX the per-version overlay redirects the
-- open itself and a cached image would leak across Yellow/Blue boots
local ok, img = pcall(love.graphics.newImage,
require("src.render.Assets").resolve(path))
return ok and img or nil
end
@@ -151,10 +156,24 @@ function TitleState.new(game, opts)
-- branding comes from field.title with the shipped art as fallback, so
-- a total conversion rebrands the title without replacing the screen
local title = (game.data.field and game.data.field.title) or {}
-- field.title itself is extraction data the field schema never exposes;
-- boot.title is the mod-reachable half of the same seam, so its keys
-- override here (a localized ribbon, a rebranded logo)
local boot = game.data.field and game.data.field.boot
if boot and type(boot.title) == "table" then
local merged = {}
for key, value in pairs(title) do merged[key] = value end
for key, value in pairs(boot.title) do merged[key] = value end
title = merged
end
self.title = title
self.logo = tryImage(imagePath(title.logo)
or "assets/logo/pokemon_logo.png")
-- versionRibbon is the file-12 key; version is the importer's
-- versionRibbon is the file-12 key; version is the importer's. The
-- vanilla sheet is two fragments the draw pass repositions, so an
-- explicit ribbon (a conversion's or a translation's continuous art)
-- draws whole instead.
self.versionFull = imagePath(title.versionRibbon) ~= nil
self.version = tryImage(imagePath(title.versionRibbon or title.version)
or "assets/generated/title/red_version.png")
self.player = tryImage("assets/generated/title/player.png")
@@ -347,8 +366,12 @@ function ContinueInfo:draw()
-- box at (4,7), 8x14 content; labels double-spaced from (5,9)
Font.drawBox(4, 7, 16, 10)
love.graphics.setColor(0, 0, 0, 1)
Font.draw(Strings("PLAYER"), 40, 72)
Font.draw((save.player and save.player.name) or "RED", 96, 72)
-- the name follows the label's real width (one space after it), so a
-- localized label longer than PLAYER's six glyphs cannot run into it
local playerLabel = Strings("PLAYER")
Font.draw(playerLabel, 40, 72)
Font.draw((save.player and save.player.name) or "RED",
math.max(96, 40 + (#Font.split(playerLabel) + 1) * 8), 72)
local badges = require("src.inventory.Badges").count(self.game.data, save)
Font.draw(Strings("BADGES"), 40, 88)
Font.draw(("%2d"):format(badges), 128, 88)
@@ -401,8 +424,10 @@ function TitleState:openMenu()
end
local th = #items * 2 + 2
local menu = Menu.new(game, items, { tx = 0, ty = 0, tw = 13, th = th })
-- full-width title LOGO zones would recolor this box; see sgbPalettes
menu.titleUiBox = { 0, 0, 12, th - 1 }
-- full-width title LOGO zones would recolor this box; see sgbPalettes.
-- Menu.new may have grown tw for longer (e.g. localized) labels, so the
-- recolor zone follows the box's real width instead of the vanilla 13.
menu.titleUiBox = { 0, 0, menu.tw - 1, th - 1 }
game.stack:push(menu)
end
@@ -490,7 +515,10 @@ function TitleState:draw()
-- the Yellow fallback layout draws no ribbon at all.
if self.version and not self.yellow then
local iw, ih = self.version:getDimensions()
if self.blue then
if self.versionFull then
-- a continuous ribbon (versionRibbon) centers as one piece
love.graphics.draw(self.version, math.floor((160 - iw) / 2), 64)
elseif self.blue then
love.graphics.draw(self.version,
love.graphics.newQuad(0, 0, 64, 8, iw, ih), 56, 64)
else