i18n: route hardcoded UI strings through Strings(), auto-size menu boxes, optional metric dex fields

Makes several UI spots reachable for translation mods without forking the
engine. All behavior-neutral for the base game: Strings(x) is the identity
function when no catalog is loaded, and the metric dex fields are opt-in.

- ListMenu: draw the title via Strings() (covers bag/PC/box/fly/move lists)
- Menu / (see follow-up ChoiceBox): grow the box to the widest label so longer
  localized labels don't overflow the frame
- OptionsMenu: wrap toggle values (ON/OFF, SET/SHIFT, WIDE/OG, text speed) and
  the ruleset display name in Strings()
- Schemas: add optional dexEntry.heightM / weightKg
- DexEntryMenu: render metric height/weight when those fields are present,
  otherwise unchanged (ft/in + lb)
This commit is contained in:
Cyberboy
2026-07-30 15:03:35 +02:00
parent e63fa70700
commit 350402b179
5 changed files with 28 additions and 8 deletions
+14
View File
@@ -19,6 +19,20 @@ function Menu.new(game, items, opts)
self.tx = opts.tx or 10
self.ty = opts.ty or 0
self.tw = opts.tw or 10
-- grow the box to the widest label so longer (e.g. localized) labels don't
-- overflow the frame; nudge tx left to keep the box on-screen (20 tiles).
do
local widest = 0
for _, it in ipairs(items) do
if it.label then
local n = #Font.split(it.label)
if n > widest then widest = n end
end
end
local needed = widest + 3
if needed > self.tw then self.tw = needed end
if self.tx + self.tw > 20 then self.tx = math.max(0, 20 - self.tw) end
end
self.rowStep = opts.rowStep or 2
-- maxVisible: cap the box to this many rows and scroll the rest instead
-- of growing past it (e.g. the start menu, whose row count varies with