From 9401445c0f7f7bbd8afc6f61cbc36afab9b8c240 Mon Sep 17 00:00:00 2001 From: thibautbus <310327033+thibautbus@users.noreply.github.com> Date: Thu, 3 Sep 2026 19:11:23 +0200 Subject: [PATCH 1/2] Route Gen 2 move-learning and item-effect text through Strings() learnMoveOn (Game2.lua) built every move-learning message -- level-up learn, TM/HM teach, the "trying to learn X, forget a move?" flow, "stop learning?", the HM-can't-be-forgotten refusal, "which move should be forgotten?", and the "1, 2 and... forgot X, learned Y!" replace result -- with a bare string literal or a direct :format() call, bypassing Strings() entirely (src/core/Strings.lua). Game2:say()/TextBox.new() show whatever text they're handed with no lookup of their own, so this meant the entire move-learning UI stayed in English no matter what translation catalog a mod supplied -- confirmed against a real gen1recomp-translation-mods build, which has translated overrides for several of these keys that could never apply because the literal never reached the catalog. Same bug for the TM/HM teach refusals ("X can't learn Y!"/"X already knows Y!"). src/core/gen2/ItemEffects.lua had the same bug across its whole family: every item-usage message (Potion/heal, status cure, Revive, Rare Candy, Vitamin, PP restore/PP Up, "no effect"/"can't use on an EGG"/"can't use on this #MON") was either a bare table constant or built with :format() directly, none of it routed through Strings(). Its constants are now wrapped in Strings.source() at declaration (so a mod's catalog harvest still finds them, per the pattern already documented in Strings.lua) and looked up through Strings() at each use site. The Vitamin success message's own VITAMIN_LABEL table (HEALTH/ATTACK/DEFENSE/SPEED/SPECIAL) gets the same two-part fix -- each entry wrapped in Strings.source() at declaration, and Strings(VITAMIN_LABEL[stat]) at the one use site -- matching the identical stat-name tables in MoveEffects.lua/TrainerAI.lua/ gen2/Effects.lua/ContestMenu.lua/SummaryMenu.lua, which all already do this; without it a Vitamin's stat name would stay in English mid-sentence even inside an otherwise fully translated message. Two more call sites read ItemEffects.TEXT_NO_EFFECT raw outside that file and needed the same fix: PartyMenu.lua's Softboiled-no-target refusal, and BattleState.lua's X-item-reused-with-no-effect and BitterBerry-when-not-confused refusals -- both battle-side messages where every neighboring self.message assignment already correctly wraps in Strings(), which is what made these two stand out as missed. None of this changes vanilla (no mod loaded) output: Strings.get() is an identity function with no catalog active, so every message renders byte-identical to before. Verified with the headless Gen 2 suite (luajit tests/run_gen2.lua): 144/145, the one failure (gen2_fishing_time_test.lua) reproduces identically on dev before this change and is unrelated (fishing time-group logic); the full engine suite (luajit tests/run_engine.lua) is 533/533. --- src/core/Game2.lua | 24 ++++----- src/core/gen2/ItemEffects.lua | 94 ++++++++++++++++++++--------------- src/ui/gen2/BattleState.lua | 4 +- src/ui/gen2/PartyMenu.lua | 2 +- 4 files changed, 67 insertions(+), 57 deletions(-) diff --git a/src/core/Game2.lua b/src/core/Game2.lua index 22f6ea14..33dc2f40 100644 --- a/src/core/Game2.lua +++ b/src/core/Game2.lua @@ -550,7 +550,7 @@ function Game2:learnMoveOn(mon, moveId, onDone) end if ok then -- data/text/common_3.asm:119 - return self:say(("%s learned\n%s!"):format(name, moveName), + return self:say(Strings("%s learned\n%s!", name, moveName), function() finish(true) end, TextBox.soundOpts(self, "Sfx_DexFanfare5079")) end @@ -558,15 +558,14 @@ function Game2:learnMoveOn(mon, moveId, onDone) local askForget, pickMove, askStop -- DidNotLearnMoveText, then `ld b, 0` (learn.asm:110-113). local function decline() - self:say(("%s\ndid not learn\v%s."):format(name, moveName), + self:say(Strings("%s\ndid not learn\v%s.", name, moveName), function() finish(false) end) end -- ForgetMove's AskForgetMoveText + YesNoBox (learn.asm:123-127). askForget = function() self.stack:push(TextBox.new(self, - ("%s is\ntrying to learn\v%s.\fBut %s\ncan't learn more\vthan four moves." - .. "\fDelete an older\nmove to make room\vfor %s?") - :format(name, moveName, name, moveName), + Strings("%s is\ntrying to learn\v%s.\fBut %s\ncan't learn more\vthan four moves.\fDelete an older\nmove to make room\vfor %s?", + name, moveName, name, moveName), nil, { choice = function(yes) if yes then return pickMove() end return askStop() @@ -575,7 +574,7 @@ function Game2:learnMoveOn(mon, moveId, onDone) -- StopLearningMoveText, whose NO is `jp c, .loop` (learn.asm:104-108). askStop = function() self.stack:push(TextBox.new(self, - ("Stop learning\n%s?"):format(moveName), nil, + Strings("Stop learning\n%s?", moveName), nil, { choice = function(yes) if yes then return decline() end return askForget() @@ -598,7 +597,7 @@ function Game2:learnMoveOn(mon, moveId, onDone) -- MoveCantForgetHMText, then `jr .loop` (learn.asm:183-197): the -- question stays up and the list comes back over it. if old and HM_MOVES[old.id] then - return self:say("HM moves can't be\nforgotten now.", pushList) + return self:say(Strings("HM moves can't be\nforgotten now."), pushList) end self.stack:pop() -- the question the list stood on local oldDef = (self.data.moves or {})[old and old.id] @@ -608,9 +607,8 @@ function Game2:learnMoveOn(mon, moveId, onDone) -- pokemon.move_learned is raised here too. ModRuntime.emit("pokemon.move_learned", { mon = mon, moveId = moveId }) -- engine/pokemon/learn.asm:225-229, data/text/common_3.asm:165-173 - self:say(("1, 2 and…" .. TextBox.PAUSE .. " Poof!" .. TextBox.PAUSE - .. "\f%s forgot\n%s.\fAnd…\f%s learned\n%s!") - :format(name, oldName, name, moveName), + self:say(Strings("1, 2 and…\1 Poof!\1\f%s forgot\n%s.\fAnd…\f%s learned\n%s!", + name, oldName, name, moveName), function() finish(true) end, TextBox.soundOpts(self, "Sfx_DexFanfare5079", { pauseSounds = { "Sfx_SwitchPokemon" } })) @@ -620,7 +618,7 @@ function Game2:learnMoveOn(mon, moveId, onDone) -- MoveAskForgetText, a `done` text: the box stays while the list stands on -- it (learn.asm:136-137). pickMove = function() - self.stack:push(TextBox.new(self, "Which move should\nbe forgotten?", nil, + self.stack:push(TextBox.new(self, Strings("Which move should\nbe forgotten?"), nil, { stay = { onShown = pushList } })) end askForget() @@ -655,13 +653,13 @@ function Game2:useFieldItem(itemId) if id == moveId then allowed = true end end if not allowed then - self:say(("%s can't learn %s!"):format( + self:say(Strings("%s can't learn %s!", require("src.battle.gen2.Mon").displayName(mon), moveName)) return end for _, move in ipairs(mon.moves or {}) do if move.id == moveId then - self:say(("%s already knows %s!"):format( + self:say(Strings("%s already knows %s!", require("src.battle.gen2.Mon").displayName(mon), moveName)) return end diff --git a/src/core/gen2/ItemEffects.lua b/src/core/gen2/ItemEffects.lua index b0b8a8a6..9ef47adc 100644 --- a/src/core/gen2/ItemEffects.lua +++ b/src/core/gen2/ItemEffects.lua @@ -16,6 +16,7 @@ local Happiness = require("src.core.gen2.Happiness") local Mon = require("src.battle.gen2.Mon") +local Strings = require("src.core.Strings") local ItemEffects = {} @@ -72,26 +73,33 @@ local BITTER = { } -- _ItemWontHaveEffectText / _ItemCantUseOnEggText (data/text/common_3.asm). -ItemEffects.TEXT_NO_EFFECT = "It won't have any\neffect." -ItemEffects.TEXT_CANT_USE_ON_EGG = "That can't be used\non an EGG." +-- Strings.source keeps these in the catalog harvest even though they are +-- declared here and only formatted/looked up at each use site below (#186, +-- #245): every use site was a bare table read or a direct :format() call +-- until now, which meant a mod's translation catalog never had a chance to +-- apply -- every language showed this same English text. +ItemEffects.TEXT_NO_EFFECT = Strings.source("It won't have any\neffect.") +ItemEffects.TEXT_CANT_USE_ON_EGG = Strings.source("That can't be used\non an EGG.") -- _ItemCantUseOnMonText (data/text/common_3.asm:1265). -ItemEffects.TEXT_CANT_USE_ON_MON = "That can't be used\non this #MON." +ItemEffects.TEXT_CANT_USE_ON_MON = Strings.source("That can't be used\non this #MON.") -- _PPRestoredText (data/text/common_3.asm). -ItemEffects.TEXT_PP_RESTORED = "PP was restored." +ItemEffects.TEXT_PP_RESTORED = Strings.source("PP was restored.") -- _PPIsMaxedOutText / _PPsIncreasedText (data/text/common_3.asm). -ItemEffects.TEXT_PP_MAXED = "%s's PP\nis maxed out." -ItemEffects.TEXT_PP_INCREASED = "%s's PP\nincreased." +ItemEffects.TEXT_PP_MAXED = Strings.source("%s's PP\nis maxed out.") +ItemEffects.TEXT_PP_INCREASED = Strings.source("%s's PP\nincreased.") -- PrintPartyMenuActionText's .MenuActionTexts (engine/pokemon/party_menu.asm), -- keyed by the class GetItemHealingAction resolves. Each is the two rows the --- cart prints: the nickname line, then the fixed line. +-- cart prints: the nickname line, then the fixed line. Strings.source for +-- the same reason as the constants above: healStatus() below formats these +-- directly at each use, so without it a mod's catalog never sees them. local STATUS_TEXT = { - psn = "%s's\ncured of poison.", - par = "%s's\nrid of paralysis.", - brn = "%s's\nburn was healed.", - frz = "%s\nwas defrosted.", - slp = "%s\nwoke up.", - all = "%s's\nhealth returned.", + psn = Strings.source("%s's\ncured of poison."), + par = Strings.source("%s's\nrid of paralysis."), + brn = Strings.source("%s's\nburn was healed."), + frz = Strings.source("%s\nwas defrosted."), + slp = Strings.source("%s\nwoke up."), + all = Strings.source("%s's\nhealth returned."), } -- The port's party records spell status several ways (the battle writes the @@ -145,7 +153,7 @@ local function restoreHp(itemId, mon) local amount = ItemEffects.HEAL_HP[itemId] local maxHp = maxHpOf(mon) if fainted(mon) or (mon.hp or 0) >= maxHp then - return { used = false, text = ItemEffects.TEXT_NO_EFFECT } + return { used = false, text = Strings(ItemEffects.TEXT_NO_EFFECT) } end local healed = math.min(maxHp, (mon.hp or 0) + amount) local gained = healed - (mon.hp or 0) @@ -157,7 +165,7 @@ local function restoreHp(itemId, mon) used = true, -- data/text/common_1.asm:30 -- home/text.asm:772 - text = ("%s\nrecovered %dHP!"):format(monName(mon), gained), + text = Strings("%s\nrecovered %dHP!", monName(mon), gained), } end @@ -181,23 +189,23 @@ end -- confusion arm reads wPlayerSubStatus3, which does not exist out of battle. local function healStatus(itemId, mon, class, data) if fainted(mon) then - return { used = false, text = ItemEffects.TEXT_NO_EFFECT } + return { used = false, text = Strings(ItemEffects.TEXT_NO_EFFECT) } end local have = ItemEffects.healClassOf(mon.status, data) if not have or (class ~= "all" and have ~= class) then - return { used = false, text = ItemEffects.TEXT_NO_EFFECT } + return { used = false, text = Strings(ItemEffects.TEXT_NO_EFFECT) } end clearStatus(mon) bitterHappiness(itemId, mon) local shape = STATUS_TEXT[class == "all" and "all" or have] - return { used = true, text = shape:format(monName(mon)) } + return { used = true, text = Strings(shape, monName(mon)) } end -- RevivePokemon: only a fainted mon accepts; REVIVE stands it up at half max -- HP (ReviveHalfHP's `srl d / rr e`), the other two at full. local function revive(itemId, mon) if not fainted(mon) then - return { used = false, text = ItemEffects.TEXT_NO_EFFECT } + return { used = false, text = Strings(ItemEffects.TEXT_NO_EFFECT) } end local maxHp = maxHpOf(mon) mon.hp = (ItemEffects.REVIVE[itemId] == "half") @@ -206,7 +214,7 @@ local function revive(itemId, mon) bitterHappiness(itemId, mon) return { used = true, - text = ("%s\nis revitalized."):format(monName(mon)), + text = Strings("%s\nis revitalized.", monName(mon)), } end @@ -218,7 +226,7 @@ end -- exactly the new level, for the caller to offer. local function rareCandy(mon, data) if (mon.level or 0) >= Mon.MAX_LEVEL then - return { used = false, text = ItemEffects.TEXT_NO_EFFECT } + return { used = false, text = Strings(ItemEffects.TEXT_NO_EFFECT) } end local def = data and data.pokemon and data.pokemon[mon.species] -- through Mon.growthFor, so a growth_rates record a mod registered is the @@ -245,14 +253,18 @@ local function rareCandy(mon, data) learned = learned, -- data/text/common_1.asm:86 sfx = "Sfx_DexFanfare5079", - text = ("%s grew to\nlevel %d!"):format(monName(mon), newLevel), + text = Strings("%s grew to\nlevel %d!", monName(mon), newLevel), } end --- engine/items/item_effects.asm:1216 StatStrings. +-- engine/items/item_effects.asm:1216 StatStrings. Strings.source per entry, +-- the same pattern as the identical stat-name tables in MoveEffects.lua/ +-- TrainerAI.lua/gen2/Effects.lua/ContestMenu.lua/SummaryMenu.lua, so a mod's +-- catalog harvest finds these independently of any other stat-name call site. local VITAMIN_LABEL = { - hp = "HEALTH", attack = "ATTACK", defense = "DEFENSE", - speed = "SPEED", special = "SPECIAL", + hp = Strings.source("HEALTH"), attack = Strings.source("ATTACK"), + defense = Strings.source("DEFENSE"), speed = Strings.source("SPEED"), + special = Strings.source("SPECIAL"), } -- engine/items/item_effects.asm:1149 VitaminEffect. @@ -261,7 +273,7 @@ local function vitamin(itemId, mon, data) mon.statExp = mon.statExp or Mon.newStatExp() local cur = mon.statExp[stat] or 0 if cur >= 25600 then - return { used = false, text = ItemEffects.TEXT_NO_EFFECT } + return { used = false, text = Strings(ItemEffects.TEXT_NO_EFFECT) } end mon.statExp[stat] = math.min(Mon.MAX_STAT_EXP, cur + 2560) local def = data and data.pokemon and data.pokemon[mon.species] @@ -272,7 +284,7 @@ local function vitamin(itemId, mon, data) Happiness.change(mon, "USEDITEM") return { used = true, - text = ("%s's\n%s rose."):format(monName(mon), VITAMIN_LABEL[stat]), + text = Strings("%s's\n%s rose.", monName(mon), Strings(VITAMIN_LABEL[stat])), } end @@ -392,15 +404,15 @@ end -- The one-call families (everything but PP, which needs a move pick first). -- Returns { used, text, learned?, level? }. function ItemEffects.useOnMon(itemId, mon, data) - if not mon then return { used = false, text = ItemEffects.TEXT_NO_EFFECT } end + if not mon then return { used = false, text = Strings(ItemEffects.TEXT_NO_EFFECT) } end if mon.isEgg then - return { used = false, text = ItemEffects.TEXT_CANT_USE_ON_EGG } + return { used = false, text = Strings(ItemEffects.TEXT_CANT_USE_ON_EGG) } end local record = ItemEffects.recordFor(itemId, data) -- The PP family has its own entry point; reaching it here is the same -- "nothing happens" the unported items get. if not record or not record.use or record.action == "pp" then - return { used = false, text = ItemEffects.TEXT_NO_EFFECT } + return { used = false, text = Strings(ItemEffects.TEXT_NO_EFFECT) } end return record.use({ item = itemId, mon = mon, data = data }) end @@ -423,13 +435,13 @@ end -- the ELIXER family (Elixer_RestorePPofAllMoves) walks every slot and counts -- -- one restored move is enough for the item to be spent. function ItemEffects.usePpItem(itemId, mon, slot, data) - if not mon then return { used = false, text = ItemEffects.TEXT_NO_EFFECT } end + if not mon then return { used = false, text = Strings(ItemEffects.TEXT_NO_EFFECT) } end if mon.isEgg then - return { used = false, text = ItemEffects.TEXT_CANT_USE_ON_EGG } + return { used = false, text = Strings(ItemEffects.TEXT_CANT_USE_ON_EGG) } end local record = ItemEffects.recordFor(itemId, data) if not record or not record.use or record.action ~= "pp" then - return { used = false, text = ItemEffects.TEXT_NO_EFFECT } + return { used = false, text = Strings(ItemEffects.TEXT_NO_EFFECT) } end return record.use({ item = itemId, mon = mon, data = data, slot = slot }) end @@ -478,9 +490,9 @@ for itemId, row in pairs(ItemEffects.RESTORE_PP) do any = restoreMove(moves[ctx.slot], row.amount) end if not any then - return { used = false, text = ItemEffects.TEXT_NO_EFFECT } + return { used = false, text = Strings(ItemEffects.TEXT_NO_EFFECT) } end - return { used = true, text = ItemEffects.TEXT_PP_RESTORED } + return { used = true, text = Strings(ItemEffects.TEXT_PP_RESTORED) } end) end @@ -488,24 +500,24 @@ end record("PP_UP", "pp", function(ctx) local move = (ctx.mon.moves or {})[ctx.slot] if type(move) ~= "table" or not move.id then - return { used = false, text = ItemEffects.TEXT_NO_EFFECT } + return { used = false, text = Strings(ItemEffects.TEXT_NO_EFFECT) } end local row = ((ctx.data and ctx.data.moves) or {})[move.id] local name = (row and row.name) or move.id -- constants/pokemon_data_constants.asm:216 PP_UP_MASK. if move.id == "SKETCH" or (move.ppUps or 0) >= 3 then - return { used = false, text = ItemEffects.TEXT_PP_MAXED:format(name) } + return { used = false, text = Strings(ItemEffects.TEXT_PP_MAXED, name) } end local base = (row and row.pp) or move.maxPp if not base then - return { used = false, text = ItemEffects.TEXT_PP_MAXED:format(name) } + return { used = false, text = Strings(ItemEffects.TEXT_PP_MAXED, name) } end -- engine/items/item_effects.asm:2736 ComputeMaxPP. local bonus = math.min(math.floor(base / 5), 7) move.ppUps = (move.ppUps or 0) + 1 move.maxPp = base + move.ppUps * bonus move.pp = (move.pp or 0) + bonus - return { used = true, text = ItemEffects.TEXT_PP_INCREASED:format(name) } + return { used = true, text = Strings(ItemEffects.TEXT_PP_INCREASED, name) } end) for itemId in pairs(ItemEffects.VITAMIN) do @@ -522,12 +534,12 @@ for _, itemId in ipairs({ "SUN_STONE", "MOON_STONE", "FIRE_STONE", "THUNDERSTONE", "WATER_STONE", "LEAF_STONE" }) do record(itemId, "stone", function(ctx) if ctx.mon.item == "EVERSTONE" then - return { used = false, text = ItemEffects.TEXT_NO_EFFECT } + return { used = false, text = Strings(ItemEffects.TEXT_NO_EFFECT) } end local Evolution = require("src.core.gen2.Evolution") local entry = Evolution.checkMon(ctx.data, ctx.mon, { force = true, item = ctx.item }) - if not entry then return { used = false, text = ItemEffects.TEXT_NO_EFFECT } end + if not entry then return { used = false, text = Strings(ItemEffects.TEXT_NO_EFFECT) } end return { used = true, evolution = entry } end) end diff --git a/src/ui/gen2/BattleState.lua b/src/ui/gen2/BattleState.lua index 328abbf5..9df01039 100644 --- a/src/ui/gen2/BattleState.lua +++ b/src/ui/gen2/BattleState.lua @@ -3860,7 +3860,7 @@ function BattleState:useItem(itemId) if not ok then -- _ItemWontHaveEffectText's own `line` break, the same one -- ItemEffects.TEXT_NO_EFFECT carries (data/text/common_3.asm). - self.message = ItemEffects.TEXT_NO_EFFECT + self.message = Strings(ItemEffects.TEXT_NO_EFFECT) self.messageTimer = MESSAGE_FRAMES self.phase = "resolving" return @@ -3965,7 +3965,7 @@ function BattleState:cureBattleConfusion(itemId) local mon = self.battle.player local state = mon and self.battle:volatile(mon) if not (state and state.confuseCount) then - self.message = oneLine(ItemEffects.TEXT_NO_EFFECT) + self.message = oneLine(Strings(ItemEffects.TEXT_NO_EFFECT)) self.messageTimer = MESSAGE_FRAMES self.phase = "resolving" return diff --git a/src/ui/gen2/PartyMenu.lua b/src/ui/gen2/PartyMenu.lua index d7180f27..025a9ff3 100644 --- a/src/ui/gen2/PartyMenu.lua +++ b/src/ui/gen2/PartyMenu.lua @@ -396,7 +396,7 @@ function PartyMenu:finishSoftboiled() local before, after = FieldMoves.softboiledTransfer(user, target, self.softboiledCost or 0) if not before then - self:showItemResult(slot, { text = ItemEffects.TEXT_CANT_USE_ON_MON }) + self:showItemResult(slot, { text = Strings(ItemEffects.TEXT_CANT_USE_ON_MON) }) return end self.softboiledFrom, self.softboiledCost = nil, nil From fa4e96e8799707acedbf72c1590a15e68ba781a6 Mon Sep 17 00:00:00 2001 From: thibautbus <310327033+thibautbus@users.noreply.github.com> Date: Thu, 3 Sep 2026 19:11:36 +0200 Subject: [PATCH 2/2] Route Battle Tower Menu messages through Strings() BattleTowerMenu:drawPanel() shows self.message via Chrome.printWrapped directly, with no Strings() lookup of its own -- same shape as Game2:say()/TextBox.new(), which also expect their caller to have already resolved the text. Every assignment to self.message in this file used the raw Strings.source() return value (an identity/harvest marker, not a lookup) instead: the level-picker prompt, the "quit your challenge?" confirmation, the level-cap refusal, and the Uber-clause refusal (which additionally called Lua's own string.format() on the untranslated source instead of Strings(UBER_TEXT, name)). The YES/NO confirmation labels and the CANCEL row label had the identical bug one level down: declared with Strings.source() but printed via Chrome.print() with no Strings() call around them either. The whole Battle Tower level-picker menu, including its yes/no prompt, stayed in English regardless of any translation catalog a mod supplied. Found via a systematic trace of every TextBox.new() (143) and Chrome.print()/Chrome.printWrapped() call site in the engine back to its text source, cross-checked against the real tools/modkit.py harvester and an independent review of the branch. That same review also flagged src/world/OverworldController.lua:3314 (Strings.source("%s's PC"):format(playerName)) as the same bug shape, and an earlier revision of this branch "fixed" it to Strings("%s's PC", playerName) -- but that call site is not a bug: openPC() deliberately builds every PC row's label from a stable English Strings.source() value first, so the ui.pc.items mod hook can match/reorder rows by their vanilla English text, and only translates via a second translatedLabels[playerPcLabel] pass after the hook has run (openPC()'s own comment: "Hooks identify the vanilla rows by their English source labels. Delay localization until after ui.pc.items has inspected/reordered/replaced them"). Translating playerPcLabel early broke that contract -- confirmed by tests/engine/rby_translation_runtime_test.lua, which already covered this exact case and failed with "ui.pc.items sees the stable player-PC source label (got PC DE RED, want RED's PC)" once that change landed. Reverted; the label was already being translated correctly by the existing second pass, which this branch never needed to touch. A second independent review round, after the fixes above, found one more real gap in the same family: ItemEffects.lua's VITAMIN_LABEL table (folded into the previous commit once found), and confirmed everything else on the branch clean. Verified with tools/modkit.py's harvest_engine_strings that all seven BattleTowerMenu.lua literals are still discovered from their Strings.source() declarations, luajit tests/run_gen2.lua: 144/145 (the one unrelated pre-existing failure noted in the previous commit), and luajit tests/run_engine.lua: 533/533 (including the PC-label regression test above, now passing). --- src/ui/gen2/BattleTowerMenu.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ui/gen2/BattleTowerMenu.lua b/src/ui/gen2/BattleTowerMenu.lua index b47c0178..a121c249 100644 --- a/src/ui/gen2/BattleTowerMenu.lua +++ b/src/ui/gen2/BattleTowerMenu.lua @@ -76,7 +76,7 @@ function BattleTowerMenu.new(game, opts) -- `ld a, $1 / ld [wcd4f], a` (../pokecrystal/mobile/mobile_46.asm:1152-1153) self.cursor = 1 self.phase = "pick" - self.message = PICK_TEXT + self.message = Strings(PICK_TEXT) return self end @@ -116,17 +116,17 @@ function BattleTowerMenu:confirm() if not row then -- ../pokecrystal/mobile/mobile_46.asm:1291-1303 `.asm_118a3c` self.phase = "quit" - self.message = QUIT_TEXT + self.message = Strings(QUIT_TEXT) self.yes = true return end if BattleTower.levelCheck(self.party, row.group) then - return self:refuse(TOPS_TEXT) + return self:refuse(Strings(TOPS_TEXT)) end local uber = BattleTower.ubersCheck(self.party, row.group) if uber then local name = (self.monName and self.monName(uber)) or uber - return self:refuse(string.format(UBER_TEXT, name)) + return self:refuse(Strings(UBER_TEXT, name)) end self:finish(row.group) end @@ -147,7 +147,7 @@ function BattleTowerMenu:updatePick() elseif input:wasPressed("b") then self:playSfx("Sfx_ReadText2") self.phase = "quit" - self.message = QUIT_TEXT + self.message = Strings(QUIT_TEXT) self.yes = true end end @@ -165,12 +165,12 @@ function BattleTowerMenu:updateQuit() self:playSfx("Sfx_ReadText2") if self.yes then return self:finish(nil) end self.phase = "pick" - self.message = PICK_TEXT + self.message = Strings(PICK_TEXT) self.cursor = 1 elseif input:wasPressed("b") then self:playSfx("Sfx_ReadText2") self.phase = "pick" - self.message = PICK_TEXT + self.message = Strings(PICK_TEXT) self.cursor = 1 end end @@ -181,7 +181,7 @@ function BattleTowerMenu:update(_dt) self.wait = (self.wait or 0) - 1 if self.wait > 0 then return end self.phase = "pick" - self.message = PICK_TEXT + self.message = Strings(PICK_TEXT) self.cursor = 1 return end @@ -198,15 +198,15 @@ function BattleTowerMenu:drawPanel() end if self.phase == "quit" then Chrome.box(YN_X, YN_Y, YN_W, YN_H) - Chrome.print(YES_LABEL, YN_TEXT_X, YES_Y) - Chrome.print(NO_LABEL, YN_TEXT_X, NO_Y) + Chrome.print(Strings(YES_LABEL), YN_TEXT_X, YES_Y) + Chrome.print(Strings(NO_LABEL), YN_TEXT_X, NO_Y) Chrome.cursor(YN_TEXT_X - 1, self.yes and YES_Y or NO_Y) love.graphics.setColor(1, 1, 1, 1) return end Chrome.box(PICK_X, PICK_Y, PICK_W, PICK_H) local row = self.rows[self.cursor] - Chrome.print(row and BattleTowerMenu.levelLabel(row.group) or CANCEL_LABEL, + Chrome.print(row and BattleTowerMenu.levelLabel(row.group) or Strings(CANCEL_LABEL), ROW_X, ROW_Y) Chrome.print(UP_ARROW, ARROW_X, UP_Y) Chrome.print(DOWN_ARROW, ARROW_X, DOWN_Y)