diff --git a/docs/modding/reference/registries.md b/docs/modding/reference/registries.md index 96693e63..fcd96383 100644 --- a/docs/modding/reference/registries.md +++ b/docs/modding/reference/registries.md @@ -821,7 +821,7 @@ mod.content.phone_contacts:patch("PHONE_YOUNGSTER_JOEY", { map = "ROUTE_31" }) | `catchRate` | integer 0..255 | yes | | `cry` | cries id | no | | `dex` | integer >= 1 | yes | -| `dexEntry` | {heightFt, heightIn, heightM?, kind, text, weight, weightKg?} | no | +| `dexEntry` | {heightFt, heightIn, heightM?, kind, text, text2?, weight, weightKg?} | no | | `evolutions` | list of {item?, level?, method, species} | yes | | `frontSize` | integer 1..7 | yes | | `growthRate` | growth_rates id | yes | diff --git a/src/core/Game2.lua b/src/core/Game2.lua index dbc6a0fc..4e274e86 100644 --- a/src/core/Game2.lua +++ b/src/core/Game2.lua @@ -1024,6 +1024,11 @@ function Game2:load() require("src.core.gen2.Phone").useRegistry(self.data) require("src.core.gen2.Decorations").useRegistry(self.data) require("src.core.gen2.Apricorns").useRegistry(self.data) + -- data.gen2Pokedex is a separate table from the `pokemon` registry's own + -- merge target (data.pokemon): a translation mod's + -- mod.content.pokemon:patch(id, { dexEntry = ... }) would otherwise never + -- reach the #DEX screen. See src/core/gen2/PokedexText.lua. + require("src.core.gen2.PokedexText").apply(self.data) -- Rendering pipelines: the engine half of the render_pipelines registry -- (src/render/Pipelines.lua). install() points it at GOLD's merged dataset diff --git a/src/core/gen2/PokedexText.lua b/src/core/gen2/PokedexText.lua new file mode 100644 index 00000000..f25379ae --- /dev/null +++ b/src/core/gen2/PokedexText.lua @@ -0,0 +1,39 @@ +-- Projects a mod's `pokemon` registry dexEntry onto the #DEX screen's own +-- data table. +-- +-- data.gen2Pokedex.entries[species] (data/generated/pokedex.lua, +-- RomExtractorGen2:extractPokedex) is what src/ui/gen2/PokedexMenu.lua +-- actually reads for the KIND label and the two description pages +-- (entry.kind, entry.text, entry.text2) -- a table loaded straight from +-- disk in Game2:load, BEFORE mods:load runs, and never routed through a +-- registry. The `pokemon` registry's own merge target is the separate +-- data.pokemon table (src/mods/Schemas.lua, R.pokemon: `target = "pokemon"`), +-- which mod.content.pokemon:patch(id, { dexEntry = { kind = ..., text = ..., +-- text2 = ... } }) already reaches -- so a translation mod's #DEX text was +-- silently invisible in-game despite validating against the registry. +-- +-- This is the missing link: called once after the merge (src/core/Game2.lua), +-- the same way ItemEffects.applyHeldItems projects held_items onto +-- data.gen2HeldItems. height/weight/dex stay untouched -- game state, not +-- text a translation carries. +local PokedexText = {} + +function PokedexText.apply(data) + local dex = data and data.gen2Pokedex + local pokemon = data and data.pokemon + if not (dex and dex.entries and pokemon) then return 0 end + local count = 0 + for species, entry in pairs(dex.entries) do + local def = pokemon[species] + local override = def and def.dexEntry + if override and (override.kind or override.text or override.text2) then + if override.kind then entry.kind = override.kind end + if override.text then entry.text = override.text end + if override.text2 then entry.text2 = override.text2 end + count = count + 1 + end + end + return count +end + +return PokedexText diff --git a/src/mods/Schemas.lua b/src/mods/Schemas.lua index 2b6e8d38..1861aae7 100644 --- a/src/mods/Schemas.lua +++ b/src/mods/Schemas.lua @@ -826,10 +826,14 @@ R.pokemon = { item = f.opt(f.id("items")), species = f.id("pokemon") }), spriteFront = f.path, spriteBack = f.path, frontSize = f.int(1, 7), + -- text2 is the #DEX entry's second description page (Pokedex_asm's bare + -- `page` macro, engine/pokedex/pokedex.asm): PokedexMenu:drawEntryBody + -- shows `entry.text` on page 1 and `entry.text2` on page 2, so a + -- translation needs both to cover the whole entry. dexEntry = f.opt(f.rec{ kind = f.str, heightFt = f.int(0), heightIn = f.int(0, 11), weight = f.num, heightM = f.opt(f.num), weightKg = f.opt(f.num), - text = f.str }), + text = f.str, text2 = f.opt(f.str) }), icon = f.opt(f.union{ f.str, f.rec{ image = f.path, frames = f.opt(f.int(1)) } }), cry = f.opt(f.id("cries")), palette = f.opt(f.id("palettes")), diff --git a/src/ui/gen2/PokedexMenu.lua b/src/ui/gen2/PokedexMenu.lua index 3b023465..9a1b3b70 100644 --- a/src/ui/gen2/PokedexMenu.lua +++ b/src/ui/gen2/PokedexMenu.lua @@ -37,6 +37,13 @@ local TileSheet = require("src.ui.gen2.TileSheet") local Nests = require("src.core.gen2.Nests") local Sound = require("src.core.Sound") local Unown = require("src.core.gen2.Unown") +local Strings = require("src.core.Strings") + +-- `db $3b, " OPTION ", $3c` / `db $3b, " SEARCH ", $3c"`: the panel titles +-- drawn by drawOption/drawSearch below, declared here (rather than inline) +-- so Strings.source puts them in the catalog harvest. +local OPTION_LABEL = Strings.source(" OPTION ") +local SEARCH_LABEL = Strings.source(" SEARCH ") local PokedexMenu = {} PokedexMenu.__index = PokedexMenu @@ -776,7 +783,6 @@ function PokedexMenu:printEntry() local row = self:current() if not row then return end local Printer = require("src.core.Printer") - local Strings = require("src.core.Strings") local TextBox = require("src.render.TextBox") local name = (self.pokemon and self.pokemon[row.species] and self.pokemon[row.species].name) or tostring(row.species) @@ -1385,7 +1391,7 @@ function PokedexMenu:drawOption() -- `db $3b, " OPTION ", $3c`: the two end-cap tiles are the dex sheet's, not -- font glyphs. self:tile(0x3b, 0, 1) - self:text(" OPTION ", 1, 1) + self:text(Strings(OPTION_LABEL), 1, 1) self:tile(0x3c, 9, 1) local rows = self:optionRows() for i, row in ipairs(rows) do @@ -1405,7 +1411,7 @@ function PokedexMenu:drawSearch() self:fill(TILE_BG, 0, 0, Chrome.SCREEN_W, Chrome.SCREEN_H) self:border(0, 2, 14, 18) self:tile(0x3b, 0, 1) - self:text(" SEARCH ", 1, 1) + self:text(Strings(SEARCH_LABEL), 1, 1) self:tile(0x3c, 9, 1) self:text("TYPE1", 3, 4) self:text("TYPE2", 3, 6)