diff --git a/src/core/game3/rse/secret_base.lua b/src/core/game3/rse/secret_base.lua index dd62431b..85a55c62 100644 --- a/src/core/game3/rse/secret_base.lua +++ b/src/core/game3/rse/secret_base.lua @@ -580,11 +580,18 @@ function SB.ownedByAnotherPlayer(sess) return SB.base(sess, 0).secretBaseId ~= SB._curId end --- pokeemerald/src/secret_base.c:728 +-- pokeemerald/src/secret_base.c:728; the European carts put the owner in the +-- row's STR_VAR_1 ("BASE DE {STR_VAR_1}", pret pokeemerald multi-language, +-- src/secret_base.c:732), the US and Japanese ones append the row to it. function SB.name(idx, sess) local b = SB.base(sess, idx) - local ok, suffix = pcall(Rse.text, "gText_ApostropheSBase") - return tostring(b.trainerName or "") .. (ok and suffix or "'s BASE") + local owner = tostring(b.trainerName or "") + local ok, base = pcall(function() + return require("src.core.game3.rom_text").plain("gText_ApostropheSBase", { stringVars = { "\1" } }) + end) + if not ok then return owner .. "'s BASE" end + if base:find("\1", 1, true) then return (base:gsub("\1", function() return owner end)) end + return owner .. base end -- pokeemerald/src/secret_base.c:735 diff --git a/src/ui/game3/naming.lua b/src/ui/game3/naming.lua index d246021a..382a3cde 100644 --- a/src/ui/game3/naming.lua +++ b/src/ui/game3/naming.lua @@ -32,10 +32,21 @@ Naming.TEMPLATE = { -- pokeemerald/include/naming_screen.h:7 Naming.TEMPLATE_ORDER = { "PLAYER", "BOX", "CAUGHT_MON", "NICKNAME", "WALDA" } +-- A name and a cart string the US code appends after it. The French, Italian +-- and Spanish carts put the name in the string's STR_VAR_1 instead, wherever +-- the row places it (pret pokeemerald multi-language, src/naming_screen.c:1746); +-- a row without one keeps the US order. +function Naming.nameInto(key, name) + name = tostring(name or "") + local text = RomText.plain(key, { stringVars = { "\1" } }) + if text:find("\1", 1, true) then return (text:gsub("\1", function() return name end)) end + return name .. text +end + -- pokeemerald/src/naming_screen.c:1715 function Naming.monTitle(speciesName) -- pokeemerald/src/text.c:972 - return tostring(speciesName or "") .. RomText.plain("gText_PkmnsNickname", { stringVars = {} }) + return Naming.nameInto("gText_PkmnsNickname", speciesName) end -- pret sKeyboardChars + sPageColumnXPos (cursor). diff --git a/tests/engine/game3_european_name_placeholder_test.lua b/tests/engine/game3_european_name_placeholder_test.lua new file mode 100644 index 00000000..0971b06d --- /dev/null +++ b/tests/engine/game3_european_name_placeholder_test.lua @@ -0,0 +1,50 @@ +-- A name joined to a cart string the US code appends after it: the European +-- carts put it in the string's STR_VAR_1 (pret pokeemerald multi-language, +-- src/naming_screen.c:1746, src/secret_base.c:732). + +package.path = "./?.lua;./?/init.lua;" .. package.path + +local T = require("tests.harness") +local eq = T.eq + +local RomText = require("src.core.game3.rom_text") +local Naming = require("src.ui.game3.naming") +local SB = require("src.core.game3.rse.secret_base") + +local saved = {} +local function set(key, ir) + if saved[key] == nil then saved[key] = RomText.overrides[key] or false end + RomText.overrides[key] = ir +end +local function text(s) return { { t = "text", s = s }, { t = "eos" } } end + +-- src/naming_screen.c:1746 +set("gText_PkmnsNickname", text("'s nickname?")) +eq(Naming.monTitle("BULBASAUR"), "BULBASAUR's nickname?", "FireRed's US row has no placeholder: the name goes first") +set("gText_PkmnsNickname", { { t = "strvar", n = 1 }, { t = "text", s = "'s nickname?" }, { t = "eos" } }) +eq(Naming.monTitle("MUDKIP"), "MUDKIP's nickname?", "Emerald's US row prints the same") +set("gText_PkmnsNickname", { { t = "text", s = "Surnom de " }, { t = "strvar", n = 1 }, { t = "text", s = "?" }, { t = "eos" } }) +eq(Naming.monTitle("POUSSIFEU"), "Surnom de POUSSIFEU?", "French: the species fills the row's STR_VAR_1") +eq(Naming.monTitle(nil), "Surnom de ?", "a missing name leaves the placeholder empty") +set("gText_PkmnsNickname", text(" の ニックネームは?")) +eq(Naming.monTitle("フシギダネ"), "フシギダネ の ニックネームは?", "FireRed's Japanese row has no placeholder either") + +-- a mod's catalog entry for the English source: the name still lands in it +local Strings = require("src.core.Strings") +set("gText_PkmnsNickname", { { t = "strvar", n = 1 }, { t = "text", s = "'s nickname?" }, { t = "eos" } }) +Strings.load({ strings = { ["%s's nickname?"] = "Surnom de %s?" } }) +eq(Naming.monTitle("MUDKIP"), "Surnom de MUDKIP?", "a catalog translation takes the name in its %s") +Strings.load(nil) + +-- src/secret_base.c:732 +local sess = { secretBases = { { trainerName = "SACHA" } } } +set("gText_ApostropheSBase", text("'s BASE")) +eq(SB.name(0, sess), "SACHA's BASE", "US: the row follows the owner") +set("gText_ApostropheSBase", text(" きち")) +eq(SB.name(0, sess), "SACHA きち", "Japanese: the same") +set("gText_ApostropheSBase", { { t = "text", s = "BASE DE " }, { t = "strvar", n = 1 }, { t = "eos" } }) +eq(SB.name(0, sess), "BASE DE SACHA", "French: the owner fills the row's STR_VAR_1") + +for key, ir in pairs(saved) do RomText.overrides[key] = ir or nil end + +T.finish("game3_european_name_placeholder_test")