mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-10-08 09:42:55 -04:00
Merge pull request #2724 from thibautbus/feat/rs-translation-runtime
This commit is contained in:
@@ -231,7 +231,7 @@ function M.commit(token, words)
|
||||
elseif token.type == 6 then writeBard(token, words)
|
||||
elseif token.type == 10 then token.session.gabbyAndTyData.quote[0] = words[1]
|
||||
elseif token.type == 9 then
|
||||
out.stringVar2 = Easy.rawWord(words[1]) .. " " .. Easy.rawWord(words[2])
|
||||
out.stringVar2 = Easy.word(words[1]) .. " " .. Easy.word(words[2])
|
||||
out.input = require("src.core.game3.rs.dewford_trend").trySetTrendyPhrase(words, token.session) and 1 or 0
|
||||
elseif token.type ~= 13 then writeTv(token, words) end
|
||||
if token.type == 0 then out.input = M.passphrase(words) and 1 or 0 end
|
||||
|
||||
@@ -118,7 +118,7 @@ function M.word(id)
|
||||
local E = require("src.core.game3.easy_chat_text")
|
||||
local group = E.group(math.floor(value / 512) % 128)
|
||||
if group then
|
||||
for _, word in ipairs(group.words) do if word.id == value then return word.text end end
|
||||
for _, word in ipairs(group.words) do if word.id == value then return E.word(value) end end
|
||||
end
|
||||
return romText("gOtherText_ThreeQuestions")
|
||||
end, id)
|
||||
|
||||
@@ -79,7 +79,12 @@ M.BY_NAME.GabbyAndTyGetLastQuote = function(ctx, adapters)
|
||||
local session, g = R.session(), gabby()
|
||||
local quote = n(g.quote[0]) % 65536
|
||||
if quote == 65535 then return false, 0 end
|
||||
stringVar(ctx, adapters, 1, session, Q.encode(session, Playback.word(quote)))
|
||||
local word = Playback.word(quote)
|
||||
local bytes = Q.encode(session, word)
|
||||
if Playback.displayBytes(session, bytes) ~= word then
|
||||
bytes = Q.encode(session, require("src.core.game3.easy_chat_text").rawWord(quote))
|
||||
end
|
||||
stringVar(ctx, adapters, 1, session, bytes)
|
||||
g.quote[0] = 65535
|
||||
return false, 1
|
||||
end
|
||||
|
||||
@@ -17,19 +17,7 @@ return function(V)
|
||||
}
|
||||
end
|
||||
|
||||
local stems = {
|
||||
UNKNOWN = "Empty", KUN_MALE = "Kun", KUN_FEMALE = "Chan",
|
||||
RIVAL_MALE = "May", RIVAL_FEMALE = "Brendan",
|
||||
VERSION = V.GAME == "sapphire" and "Sapphire" or "Ruby",
|
||||
AQUA = "Aqua", MAGMA = "Magma", ARCHIE = "Archie", MAXIE = "Maxie",
|
||||
KYOGRE = "Kyogre", GROUDON = "Groudon",
|
||||
}
|
||||
-- pokeruby/src/string_util.c:476
|
||||
local evil, good = { "Magma", "Maxie", "Groudon" }, { "Aqua", "Archie", "Kyogre" }
|
||||
if V.GAME == "sapphire" then evil, good = good, evil end
|
||||
for i, name in ipairs({ "TEAM", "LEADER", "LEGENDARY" }) do
|
||||
stems["EVIL_" .. name], stems["GOOD_" .. name] = evil[i], good[i]
|
||||
end
|
||||
V.TEXT_PLACEHOLDERS = {}
|
||||
for name, stem in pairs(stems) do V.TEXT_PLACEHOLDERS[name] = V.sym("gExpandedPlaceholder_" .. stem) end
|
||||
local Placeholders = require("src.import.gba.text_placeholders_extract")
|
||||
for name, label in pairs(Placeholders.rsSymbols(V.GAME)) do V.TEXT_PLACEHOLDERS[name] = V.sym(label) end
|
||||
end
|
||||
|
||||
@@ -153,6 +153,12 @@ function PokedexChromeExtract.extractEntries(rom, cache, root)
|
||||
end
|
||||
end
|
||||
|
||||
local syms = Versions.SYMS
|
||||
local function symbolAt(ptr)
|
||||
if not (syms and syms.namesAt and ptr and ptr >= 0x08000000 and ptr < 0x0A000000) then return nil end
|
||||
return syms.namesAt(ptr - 0x08000000)[1]
|
||||
end
|
||||
|
||||
local entries = {}
|
||||
-- src/data/pokemon/pokedex_entries.h:3
|
||||
for nat = 0, natDexCount do
|
||||
@@ -177,6 +183,8 @@ function PokedexChromeExtract.extractEntries(rom, cache, root)
|
||||
weight = weight,
|
||||
description = desc1,
|
||||
description2 = desc2,
|
||||
descriptionLabel = symbolAt(descPtr1),
|
||||
descriptionLabel2 = E.desc2 and symbolAt(descPtr2) or nil,
|
||||
pokemonScale = pokemonScale,
|
||||
pokemonOffset = pokemonOffset,
|
||||
trainerScale = trainerScale,
|
||||
@@ -195,8 +203,12 @@ function PokedexChromeExtract.extractEntries(rom, cache, root)
|
||||
table.sort(ids)
|
||||
for _, id in ipairs(ids) do
|
||||
local e = entries[id]
|
||||
local labels = ""
|
||||
for _, field in ipairs({ "descriptionLabel", "descriptionLabel2" }) do
|
||||
if e[field] then labels = labels .. string.format(", %s = \"%s\"", field, escape_lua(e[field])) end
|
||||
end
|
||||
lines[#lines + 1] = string.format(
|
||||
" [%d] = { category = \"%s\", height = %d, weight = %d, description = \"%s\", description2 = \"%s\", pokemonScale = %d, pokemonOffset = %d, trainerScale = %d, trainerOffset = %d },",
|
||||
" [%d] = { category = \"%s\", height = %d, weight = %d, description = \"%s\", description2 = \"%s\", pokemonScale = %d, pokemonOffset = %d, trainerScale = %d, trainerOffset = %d%s },",
|
||||
id,
|
||||
escape_lua(e.category),
|
||||
e.height or 0,
|
||||
@@ -206,7 +218,8 @@ function PokedexChromeExtract.extractEntries(rom, cache, root)
|
||||
e.pokemonScale or 256,
|
||||
e.pokemonOffset or 0,
|
||||
e.trainerScale or 256,
|
||||
e.trainerOffset or 0
|
||||
e.trainerOffset or 0,
|
||||
labels
|
||||
)
|
||||
end
|
||||
lines[#lines + 1] = "}"
|
||||
|
||||
@@ -23,6 +23,11 @@ function PokedexEntriesExtract.ready(cache, cacheRoot)
|
||||
for _, f in ipairs(PokedexEntriesExtract.files()) do
|
||||
if not cache:exists(root .. f) then return false end
|
||||
end
|
||||
local okL, L = pcall(function() return require("src.import.gba.layouts.registry").active() end)
|
||||
if okL and type(L) == "table" and L.id == "rs" then
|
||||
local body = cache.read and cache:read(root .. "entries.lua")
|
||||
return body ~= nil and body:find("descriptionLabel", 1, true) ~= nil
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@ function M.text(c, off)
|
||||
end
|
||||
error("RS text is unterminated")
|
||||
end
|
||||
function M.label(c, off)
|
||||
return off and c.S.namesAt(off)[1] or nil
|
||||
end
|
||||
function M.pairs(c, name, signed)
|
||||
local off, out = c:off(name), {}
|
||||
for i = 0, c.S.size(name) / 2 - 1 do
|
||||
|
||||
@@ -19,7 +19,7 @@ local PACKS = {
|
||||
{"naming", {version = 3}}, {"rse/menus"}, {"rse/common_ui"}, {"rse/bag"},
|
||||
{"rse/berry_tag"}, {"rse/party"}, {"rse/summary"}, {"rse/mail"}, {"rse/easy_chat"},
|
||||
{"rse/trendy_phrase"}, {"rse/easy_chat_editor", {editorVersion = 2}}, {"rse/rs_egg_hatch"},
|
||||
{"pokemon/storage", {version = 5}}, {"rse/pokedex"}, {"rse/pokedex_detail"}, {"rse/diploma"},
|
||||
{"pokemon/storage", {version = 5}}, {"rse/pokedex", {packVersion = 1}}, {"rse/pokedex_detail"}, {"rse/diploma"},
|
||||
{"rse/trainer_card"}, {"rse/trade"}, {"rse/pokenav"}, {"rse/pokenav_detail"},
|
||||
{"rse/pokenav_shell"}, {"rse/pokenav_condition"}, {"rse/pokenav_ribbons"}, {"rs/assets"},
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
local K = require("src.import.gba.rse.boot_gfx")
|
||||
local A = require("src.import.gba.rs.assets")
|
||||
local M = {SUB = "rse/pokedex"}
|
||||
local M = {SUB = "rse/pokedex", packVersion = 1}
|
||||
local N = "pokedex.o:"
|
||||
local maps = {{"list", "gUnknown_08E96738"}, {"list_underlay", "gUnknown_08E9C6DC"},
|
||||
{"start_menu_main", "gPokedexStartMenuMain_Tilemap"}, {"start_menu_search", "gPokedexStartMenuSearchResults_Tilemap"},
|
||||
@@ -18,18 +18,24 @@ local function bytes(c, name, stride)
|
||||
for i = 0, c.S.count(name, stride or 1) - 1 do out[i + 1] = stride == 2 and c:u16(off + i * 2) or c:u8(off + i) end
|
||||
return out
|
||||
end
|
||||
-- pokeruby/src/pokedex.c:1116
|
||||
local function ownLabel(c, off)
|
||||
local label = A.label(c, off)
|
||||
return label and label:match("^DexText_") and label or nil
|
||||
end
|
||||
local function options(c, name)
|
||||
local out, off = {}, c:off(N .. name)
|
||||
for i = 0, c.S.count(N .. name, 8) - 1 do
|
||||
local a, b = c:ptr(off + i * 8), c:ptr(off + i * 8 + 4)
|
||||
if not b then break end
|
||||
out[#out + 1] = {description = a and A.text(c, a) or "", title = A.text(c, b)}
|
||||
out[#out + 1] = {description = a and A.text(c, a) or "", title = A.text(c, b),
|
||||
descriptionKey = ownLabel(c, a), titleKey = ownLabel(c, b)}
|
||||
end
|
||||
return out
|
||||
end
|
||||
function M.run(rom, cache, opts)
|
||||
local c = A.context(rom, cache, opts, M.SUB)
|
||||
local man = {screen = "pokedex", coverage = "native_list_detail_search_backgrounds_and_search_tables", gfx = {}, maps = {}, layers = {}, palettes = {}}
|
||||
local man = {screen = "pokedex", packVersion = M.packVersion, coverage = "native_list_detail_search_backgrounds_and_search_tables", gfx = {}, maps = {}, layers = {}, palettes = {}}
|
||||
-- pokeruby/src/pokedex.c:1967
|
||||
local pals = {hoenn = c:palAt(c:off("gPokedexMenu_Pal"), 96), national = c:pal(N .. "sNationalPokedexPalette", 96),
|
||||
searchResults = c:pal(N .. "sPokedexSearchPalette", 96), search = c:pal("gPokedexMenuSearch_Pal", 64)}
|
||||
@@ -54,12 +60,14 @@ function M.run(rom, cache, opts)
|
||||
local top = c:off(N .. "sSearchMenuTopBarItems")
|
||||
for i = 0, c.S.count(N .. "sSearchMenuTopBarItems", 8) - 1 do
|
||||
local o = top + i * 8
|
||||
search.topBar[i + 1] = {description = A.text(c, assert(c:ptr(o))), x = c:u8(o + 4), y = c:u8(o + 5), width = c:u8(o + 6)}
|
||||
search.topBar[i + 1] = {description = A.text(c, assert(c:ptr(o))), descriptionKey = A.label(c, c:ptr(o)),
|
||||
x = c:u8(o + 4), y = c:u8(o + 5), width = c:u8(o + 6)}
|
||||
end
|
||||
local io = c:off(N .. "sSearchMenuItems")
|
||||
for i = 0, c.S.count(N .. "sSearchMenuItems", 12) - 1 do
|
||||
local o = io + i * 12
|
||||
search.items[i + 1] = {description = A.text(c, assert(c:ptr(o))), titleX = c:u8(o + 4), titleY = c:u8(o + 5), titleWidth = c:u8(o + 6),
|
||||
search.items[i + 1] = {description = A.text(c, assert(c:ptr(o))), descriptionKey = A.label(c, c:ptr(o)),
|
||||
titleX = c:u8(o + 4), titleY = c:u8(o + 5), titleWidth = c:u8(o + 6),
|
||||
selX = c:u8(o + 7), selY = c:u8(o + 8), selWidth = c:u8(o + 9)}
|
||||
end
|
||||
for _, k in ipairs({"SearchNatDex", "ShiftNatDex", "SearchHoennDex", "ShiftHoennDex"}) do
|
||||
@@ -74,5 +82,9 @@ function M.run(rom, cache, opts)
|
||||
c.files[#c.files + 1] = "orders.lua"
|
||||
return A.finish(c, man)
|
||||
end
|
||||
function M.ready(cache, root) return A.ready(M.SUB, cache, root) end
|
||||
function M.ready(cache, root)
|
||||
if not A.ready(M.SUB, cache, root) then return false end
|
||||
local body = cache:read((root or "data/generated/gba") .. "/" .. M.SUB .. "/manifest.lua")
|
||||
return body:find("packVersion = " .. M.packVersion, 1, true) ~= nil
|
||||
end
|
||||
return M
|
||||
|
||||
@@ -20,6 +20,30 @@ TextPlaceholders.SYMBOLS = {
|
||||
GROUDON = "gText_ExpandedPlaceholder_Groudon",
|
||||
}
|
||||
|
||||
-- pokeruby/src/string_util.c:476
|
||||
function TextPlaceholders.rsSymbols(game)
|
||||
local stems = {
|
||||
UNKNOWN = "Empty", KUN_MALE = "Kun", KUN_FEMALE = "Chan",
|
||||
RIVAL_MALE = "May", RIVAL_FEMALE = "Brendan",
|
||||
VERSION = game == "sapphire" and "Sapphire" or "Ruby",
|
||||
AQUA = "Aqua", MAGMA = "Magma", ARCHIE = "Archie", MAXIE = "Maxie",
|
||||
KYOGRE = "Kyogre", GROUDON = "Groudon",
|
||||
}
|
||||
local evil, good = { "Magma", "Maxie", "Groudon" }, { "Aqua", "Archie", "Kyogre" }
|
||||
if game == "sapphire" then evil, good = good, evil end
|
||||
for i, name in ipairs({ "TEAM", "LEADER", "LEGENDARY" }) do
|
||||
stems["EVIL_" .. name], stems["GOOD_" .. name] = evil[i], good[i]
|
||||
end
|
||||
local out = {}
|
||||
for name, stem in pairs(stems) do out[name] = "gExpandedPlaceholder_" .. stem end
|
||||
return out
|
||||
end
|
||||
|
||||
function TextPlaceholders.symbolsFor(game)
|
||||
if game == "ruby" or game == "sapphire" then return TextPlaceholders.rsSymbols(game) end
|
||||
return TextPlaceholders.SYMBOLS
|
||||
end
|
||||
|
||||
-- pokeemerald/src/string_util.c:448
|
||||
TextPlaceholders.BY_GENDER = {
|
||||
KUN = { male = "KUN_MALE", female = "KUN_FEMALE" },
|
||||
|
||||
@@ -42,17 +42,18 @@ end
|
||||
local placeholderCache = {}
|
||||
|
||||
-- pokeemerald/src/strings.c:6
|
||||
local function cartPlaceholders(extracted)
|
||||
local function cartPlaceholders(extracted, game)
|
||||
local Extract = require("src.import.gba.text_placeholders_extract")
|
||||
local RomText = require("src.core.game3.rom_text")
|
||||
local symbols = Extract.symbolsFor(game)
|
||||
local function value(name)
|
||||
local label = Extract.SYMBOLS[name]
|
||||
local label = symbols[name]
|
||||
if label and RomText.has(label) then return RomText.plain(label) end
|
||||
return extracted[name]
|
||||
end
|
||||
local out, byGender = {}, {}
|
||||
for name, v in pairs(extracted) do out[name] = v end
|
||||
for name in pairs(Extract.SYMBOLS) do out[name] = value(name) end
|
||||
for name in pairs(symbols) do out[name] = value(name) end
|
||||
for name, pair in pairs(extracted.byGender or {}) do byGender[name] = pair end
|
||||
for name, pair in pairs(Extract.BY_GENDER) do
|
||||
byGender[name] = { male = out[pair.male], female = out[pair.female] }
|
||||
@@ -94,7 +95,7 @@ TextIR.setContextProvider(function(kind, dialect, ctx)
|
||||
local okC, CacheFs = pcall(require, "src.import.CacheFs")
|
||||
local t = okC and CacheFs.loadActive(dialect.placeholders) or nil
|
||||
if type(t) == "table" then
|
||||
placeholderCache[id] = { bundle = bundle, values = cartPlaceholders(t) }
|
||||
placeholderCache[id] = { bundle = bundle, values = cartPlaceholders(t, id) }
|
||||
return placeholderCache[id].values
|
||||
end
|
||||
return nil
|
||||
|
||||
@@ -137,6 +137,7 @@ local function action_texts(list)
|
||||
PartyMenu._actionTexts = { list = list, texts = texts }
|
||||
return texts
|
||||
end
|
||||
PartyMenu._actionTextsFor = action_texts
|
||||
|
||||
local FR_INSETS = { msgX = 2, msgY = 2, actX = 9, actY = 2, cursorX = 1 }
|
||||
local function textInsets()
|
||||
@@ -944,6 +945,7 @@ function PartyMenu.show(sessionParty, moveOverlay, opts)
|
||||
end
|
||||
opts = opts or {}
|
||||
PartyMenu._order = nil
|
||||
PartyMenu._rsPrompt = nil
|
||||
if opts.mode == "battle_switch" or opts.mode == "battle_faint" or (opts.mode == "use" and opts.battleOrder) then
|
||||
local party0 = sessionParty or (opts.session and opts.session.party)
|
||||
local ov0 = moveOverlay or (opts.session and (opts.session.move_overlay or opts.session.moveOverlay))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
local Base = require("src.ui.game3.rse.contest_painting")
|
||||
local IR = require("src.core.game3.scripting.text_ir")
|
||||
local RomText = require("src.core.game3.rom_text")
|
||||
local Kit = require("src.ui.game3.rse.scene_kit")
|
||||
local Font = require("src.ui.game3.frlg_font")
|
||||
local Painting = {ID = Base.ID, SUB = Base.SUB}
|
||||
@@ -11,9 +12,9 @@ local function manifest()
|
||||
return man
|
||||
end
|
||||
|
||||
local function render(bytes)
|
||||
local function render(ir)
|
||||
local out = {}
|
||||
for _, seg in ipairs(IR.decode(bytes, {dialect = "rs"})) do
|
||||
for _, seg in ipairs(ir) do
|
||||
if seg.t == "ext" then
|
||||
out[#out + 1] = string.char(252, seg.cmd)
|
||||
for _, arg in ipairs(seg.args or {}) do out[#out + 1] = string.char(arg) end
|
||||
@@ -21,7 +22,10 @@ local function render(bytes)
|
||||
end
|
||||
return table.concat(out)
|
||||
end
|
||||
local function text(man, key) return render(assert(man.textBytes[key], "native painting caption missing: " .. key)) end
|
||||
local function text(man, key)
|
||||
local bytes = assert(man.textBytes[key], "native painting caption missing: " .. key)
|
||||
return render(RomText.irOr(key, IR.decode(bytes, {dialect = "rs"})))
|
||||
end
|
||||
local function name(value, limit)
|
||||
if type(value) == "table" then
|
||||
local bytes = {}
|
||||
@@ -30,7 +34,7 @@ local function name(value, limit)
|
||||
bytes[#bytes + 1] = value[i]
|
||||
end
|
||||
bytes[#bytes + 1] = 255
|
||||
return render(bytes)
|
||||
return render(IR.decode(bytes, {dialect = "rs"}))
|
||||
end
|
||||
if type(value) ~= "string" then return "" end
|
||||
if not limit then return value end
|
||||
@@ -48,9 +52,11 @@ function Painting.caption(saveIdx, winner, artist, man)
|
||||
local nickname = name(winner.monName or winner.nickname, man.captionLayout.nicknameBytes)
|
||||
local category = tonumber(winner.contestCategory) or 0
|
||||
if saveIdx < man.captionLayout.museumStart then
|
||||
-- pokeruby/src/contest_painting.c:234
|
||||
local possessive, first, second = text(man, man.hallPossessive), name(winner.trainerName), nickname
|
||||
if possessive:find("^[ ,]") then first, second = nickname, name(winner.trainerName) end
|
||||
return text(man, assert(man.rankNames[category], "native painting category")) .. text(man, man.hallCaption)
|
||||
.. name(winner.trainerName) .. string.char(unpack(man.captionLayout.hallLatinControl))
|
||||
.. text(man, man.hallPossessive) .. nickname
|
||||
.. first .. string.char(unpack(man.captionLayout.hallLatinControl)) .. possessive .. second
|
||||
end
|
||||
local pair = assert(man.captionParts[category], "native museum caption pair")
|
||||
return text(man, pair.prefix) .. nickname .. text(man, pair.suffix)
|
||||
|
||||
@@ -27,9 +27,16 @@ local aliases = {
|
||||
UI.TEXT_ALIASES = {gText_ApostropheSBase = "gOtherText_PlayersBase"}
|
||||
local cats = {gText_Desk = 0, gText_Chair = 1, gText_Plant = 2, gText_Ornament = 3,
|
||||
gText_Mat = 4, gText_Poster = 5, gText_Doll = 6, gText_Cushion = 7}
|
||||
local resolved = {}
|
||||
local function nativeText(key, vars)
|
||||
if cats[key] ~= nil then return Inv.categoryName(cats[key]) end
|
||||
local native, m = aliases[key] or key, Decor.manifest()
|
||||
if not vars and resolved[native] then return resolved[native] end
|
||||
if Text.has(native) then
|
||||
local value = Text.plain(native, vars and {stringVars = vars} or nil)
|
||||
if not vars then resolved[native] = value end
|
||||
return value
|
||||
end
|
||||
if m.textBytes and m.textBytes[native] then
|
||||
return IR.toPlain(IR.decode(m.textBytes[native], {dialect = "rs"}), {stringVars = vars or {}})
|
||||
end
|
||||
@@ -116,6 +123,7 @@ function UI.draw(d, host)
|
||||
end
|
||||
local function options(opts)
|
||||
opts = opts or {}
|
||||
resolved = {}
|
||||
opts.text, opts.draw = nativeText, UI.draw
|
||||
opts.recordSecretBaseVisit = false
|
||||
opts.avatarGfx = function(s, female)
|
||||
|
||||
@@ -6,6 +6,15 @@ local Cursor = require("src.ui.game3.rs.menu_cursor")
|
||||
local Pal = require("src.core.game3.pal_fade")
|
||||
local Fx = require("src.core.game3.gba_fx")
|
||||
local Easy = require("src.core.game3.easy_chat_text")
|
||||
local words, groups = {}, {}
|
||||
local function wordText(id)
|
||||
if words[id] == nil then words[id] = Easy.word(id) end
|
||||
return words[id]
|
||||
end
|
||||
local function groupText(group)
|
||||
if groups[group] == nil then groups[group] = Easy.groupName(group) end
|
||||
return groups[group]
|
||||
end
|
||||
local Policy = require("src.ui.game3.rs.easy_chat_editor_policy")
|
||||
local Frames = require("src.ui.game3.rs.easy_chat_editor_frames")
|
||||
local C = {isMenu = true, open = false}
|
||||
@@ -33,6 +42,7 @@ function C.manifest(kind)
|
||||
end
|
||||
function C.show(opts)
|
||||
opts = opts or {}
|
||||
words, groups = {}, {}
|
||||
assert(opts.token and opts.type ~= 9, "native RS editor requires its save contract; type9 uses its separate host")
|
||||
C._man, C._session, C._opts = C.manifest(opts.type), assert(opts.session), opts
|
||||
C._before, C.words = copyWords(opts.words), copyWords(opts.words)
|
||||
@@ -347,7 +357,7 @@ local function phraseWords()
|
||||
local line = {}
|
||||
for col = 0, C._man.columns - 1 do
|
||||
local i = row * C._man.columns + col + 1
|
||||
if i <= C._man.wordCount and C.words[i] ~= Policy.EMPTY then line[#line + 1] = Easy.rawWord(C.words[i]) .. " " end
|
||||
if i <= C._man.wordCount and C.words[i] ~= Policy.EMPTY then line[#line + 1] = wordText(C.words[i]) .. " " end
|
||||
end
|
||||
local pen = C._man.wordPens[row * C._man.columns + 1]
|
||||
if pen then text(table.concat(line), pen.x, pen.y, "phrase") end
|
||||
@@ -360,7 +370,7 @@ local function phraseWords()
|
||||
local image = assert(Kit.image(C._man.blankWord))
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
Fx.draw(function() love.graphics.draw(image, x, y) end, C._pal:fx(0))
|
||||
else text(Easy.rawWord(C.words[i]), x, y, "phrase") end
|
||||
else text(wordText(C.words[i]), x, y, "phrase") end
|
||||
end
|
||||
end
|
||||
local function pickerText()
|
||||
@@ -382,7 +392,7 @@ local function pickerText()
|
||||
local word = (view == "groups" and C.groups or C._list)[row * 2 + col + 1]
|
||||
if word then
|
||||
local x = (view == "groups" and 16 or 48) + col * 88
|
||||
text(view == "groups" and word.name or word.text, x, 88 + (row - state.top) * 16 + offset, "picker")
|
||||
text(view == "groups" and groupText(word) or wordText(word.id), x, 88 + (row - state.top) * 16 + offset, "picker")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,6 +6,15 @@ local Cursor = require("src.ui.game3.rs.menu_cursor")
|
||||
local Pal = require("src.core.game3.pal_fade")
|
||||
local Fx = require("src.core.game3.gba_fx")
|
||||
local Easy = require("src.core.game3.easy_chat_text")
|
||||
local words, groups = {}, {}
|
||||
local function wordText(id)
|
||||
if words[id] == nil then words[id] = Easy.word(id) end
|
||||
return words[id]
|
||||
end
|
||||
local function groupText(group)
|
||||
if groups[group] == nil then groups[group] = Easy.groupName(group) end
|
||||
return groups[group]
|
||||
end
|
||||
local Policy = require("src.ui.game3.rs.mail_composer_policy")
|
||||
local Frames = require("src.ui.game3.rs.mail_composer_frames")
|
||||
local C = {isMenu = true, open = false}
|
||||
@@ -23,6 +32,7 @@ function C.manifest()
|
||||
end
|
||||
function C.write(record, opts)
|
||||
opts = opts or {}
|
||||
words, groups = {}, {}
|
||||
C._man, C._record, C._session, C._opts = C.manifest(), assert(record), assert(opts.session), opts
|
||||
C._before, C.words = copyWords(record.words), copyWords(record.words)
|
||||
C.groups = Policy.groups(C._session, opts.gates)
|
||||
@@ -259,7 +269,7 @@ local function phraseWords()
|
||||
local parts = {}
|
||||
for col = 0, 1 do
|
||||
local i = row * 2 + col + 1
|
||||
if i <= 9 and C.words[i] ~= Policy.EMPTY then parts[#parts + 1] = Easy.rawWord(C.words[i]) .. " " end
|
||||
if i <= 9 and C.words[i] ~= Policy.EMPTY then parts[#parts + 1] = wordText(C.words[i]) .. " " end
|
||||
end
|
||||
text(table.concat(parts), 40, row * 16, "phrase")
|
||||
end
|
||||
@@ -271,7 +281,7 @@ local function phraseWords()
|
||||
local image = assert(Kit.image(C._man.blankWord))
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
Fx.draw(function() love.graphics.draw(image, x, y) end, C._pal:fx(0))
|
||||
else text(Easy.rawWord(C.words[i]), x, y, "phrase") end
|
||||
else text(wordText(C.words[i]), x, y, "phrase") end
|
||||
end
|
||||
end
|
||||
local function pickerText()
|
||||
@@ -293,7 +303,7 @@ local function pickerText()
|
||||
local word = (view == "groups" and C.groups or C._list)[row * 2 + col + 1]
|
||||
if word then
|
||||
local x = (view == "groups" and 16 or 48) + col * 88
|
||||
text(view == "groups" and word.name or word.text, x, 88 + (row - state.top) * 16 + offset, "picker")
|
||||
text(view == "groups" and groupText(word) or wordText(word.id), x, 88 + (row - state.top) * 16 + offset, "picker")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -43,7 +43,7 @@ function Reader.content(mail, man)
|
||||
local parts = {}
|
||||
for i = 1, line.words do
|
||||
local id = tonumber(mail.words and mail.words[word]) or 65535
|
||||
parts[#parts + 1] = Easy.rawWord(id)
|
||||
parts[#parts + 1] = Easy.word(id)
|
||||
if i < line.words and id ~= 65535 then parts[#parts + 1] = " " end
|
||||
word = word + 1
|
||||
end
|
||||
|
||||
@@ -3,6 +3,7 @@ local Kit = require("src.ui.game3.rse.scene_kit")
|
||||
local Font = require("src.ui.game3.frlg_font")
|
||||
local Pokemon = require("src.core.game3.pokemon")
|
||||
local IR = require("src.core.game3.scripting.text_ir")
|
||||
local RomText = require("src.core.game3.rom_text")
|
||||
local bit = require("bit")
|
||||
local UI = {}
|
||||
local keys = {gText_TeachWhichMoveToPkmn = "gOtherText_TeachWhichMove",
|
||||
@@ -13,13 +14,20 @@ local function manifest()
|
||||
assert(m.assetLayout == "rs", "native RS move tutor pack required")
|
||||
return m
|
||||
end
|
||||
local resolved = {}
|
||||
local function cartIr(native)
|
||||
if not resolved[native] then
|
||||
resolved[native] = RomText.irOr(native,
|
||||
IR.decode(assert(manifest().textBytes[native], "native tutor text " .. native), {dialect = "rs"}))
|
||||
end
|
||||
return resolved[native]
|
||||
end
|
||||
local function text(key, ctx)
|
||||
local m, native = manifest(), keys[key] or key
|
||||
return IR.toPlain(IR.decode(assert(m.textBytes[native], "native tutor text " .. native), {dialect = "rs"}), ctx or {})
|
||||
return IR.toPlain(cartIr(keys[key] or key), ctx or {})
|
||||
end
|
||||
local function pages(key, vars)
|
||||
local out = {}
|
||||
local value = IR.toAscii(IR.decode(assert(manifest().textBytes[key]), {dialect = "rs"}), {stringVars = vars})
|
||||
local value = IR.toAscii(cartIr(key), {stringVars = vars})
|
||||
for page in (value .. "\\p"):gmatch("(.-)\\p") do if page ~= "" then out[#out + 1] = page end end
|
||||
return out
|
||||
end
|
||||
@@ -164,6 +172,7 @@ function UI.draw(st)
|
||||
end
|
||||
function UI.show(mon, opts)
|
||||
manifest(); opts = opts or {}
|
||||
resolved = {}
|
||||
opts.maxShown, opts.text, opts.draw, opts.startLearn = 3, text, UI.draw, startLearn
|
||||
return Base.show(mon, opts)
|
||||
end
|
||||
|
||||
@@ -12,12 +12,23 @@ local function menuData()
|
||||
return assert(require("src.ui.game3.rse.scene_kit").manifest(Data.manifest).party)
|
||||
end
|
||||
|
||||
-- pokeruby/src/pokemon_menu.c:126
|
||||
Data.actionLabels = {"OtherText_Summary", "OtherText_Switch2", "OtherText_Item", "gOtherText_CancelNoTerminator",
|
||||
"OtherText_Give2", "OtherText_Take2", "OtherText_Take", "OtherText_Mail", "OtherText_Read2",
|
||||
"gOtherText_CancelNoTerminator"}
|
||||
|
||||
function Data.actionText(action, fields)
|
||||
local RomText = require("src.core.game3.rom_text")
|
||||
local nativeId = Data.actionIds[action]
|
||||
if nativeId then return assert(menuData().cursorOptions[nativeId + 1]) end
|
||||
if Data.extraLabels[action] then return require("src.core.game3.rom_text").plain(Data.extraLabels[action]) end
|
||||
if nativeId then
|
||||
local label = Data.actionLabels[nativeId + 1]
|
||||
if RomText.has(label) then return RomText.plain(label) end
|
||||
return assert(menuData().cursorOptions[nativeId + 1])
|
||||
end
|
||||
if Data.extraLabels[action] then return RomText.plain(Data.extraLabels[action]) end
|
||||
assert(fields and fields.index[action] ~= nil, "unknown native RS party action: " .. tostring(action))
|
||||
return action
|
||||
local move = fields.moves and fields.moves[fields.index[action] + 1]
|
||||
return move and require("src.core.game3.pokemon").moveName(move) or action
|
||||
end
|
||||
|
||||
function Data.buildActions(mon, party, fields)
|
||||
@@ -152,11 +163,23 @@ function Data.drawDescription(desc, x, y)
|
||||
love.graphics.draw(image, quad, x, y)
|
||||
end
|
||||
|
||||
local function prompt(id, width)
|
||||
local function promptText(id, name)
|
||||
local RomText = require("src.core.game3.rom_text")
|
||||
local key = RomText.key("PartyMenuPromptTexts", id)
|
||||
if RomText.has(key) then return RomText.plain(key, {stringVars = {name or ""}}) end
|
||||
return assert(require("src.ui.game3.rse.scene_kit").manifest("rse/party").prompts[id + 1])
|
||||
end
|
||||
|
||||
local function prompt(ui, anchor, id, width)
|
||||
local memo = ui._rsPrompt
|
||||
if not (memo and memo.anchor == anchor and memo.id == id) then
|
||||
local mon = id == 5 and ui._party and ui._party[ui.cursor]
|
||||
memo = {anchor = anchor, id = id, text = promptText(id, mon and require("src.core.game3.pokemon").displayName(mon))}
|
||||
ui._rsPrompt = memo
|
||||
end
|
||||
local Chrome = require("src.ui.game3.chrome")
|
||||
Chrome.stdFrame(1, 17, width, 2)
|
||||
require("src.ui.game3.frlg_font").draw(assert(require("src.ui.game3.rse.scene_kit").manifest("rse/party").prompts[id + 1]), 8, 136,
|
||||
require("src.ui.game3.rs.party_chrome").textOptions("menu"))
|
||||
require("src.ui.game3.frlg_font").draw(memo.text, 8, 136, require("src.ui.game3.rs.party_chrome").textOptions("menu"))
|
||||
end
|
||||
|
||||
function Data.drawActions(ui, item)
|
||||
@@ -166,9 +189,10 @@ function Data.drawActions(ui, item)
|
||||
local left = item and (30 - (width + 1)) or 19
|
||||
local top = item and (20 - (count * 2 + 2)) or (18 - count * 2)
|
||||
local Font = require("src.ui.game3.frlg_font")
|
||||
prompt(item and ui._submenuKind ~= "MAIL" and 13 or 5, item and (ui._submenuKind == "MAIL" and 18 or 21) or 17)
|
||||
prompt(ui, actions, item and ui._submenuKind ~= "MAIL" and 13 or 5, item and (ui._submenuKind == "MAIL" and 18 or 21) or 17)
|
||||
require("src.ui.game3.chrome").stdFrame(left + 1, top + 1, width - 1, count * 2)
|
||||
for i, action in ipairs(actions) do Font.draw(Data.actionText(action, ui._fieldMoveData), (left + 1) * 8, (top + 1) * 8 + (i - 1) * 16,
|
||||
local texts = ui._actionTextsFor(actions)
|
||||
for i in ipairs(actions) do Font.draw(texts[i], (left + 1) * 8, (top + 1) * 8 + (i - 1) * 16,
|
||||
require("src.ui.game3.rs.party_chrome").textOptions("menu")) end
|
||||
local cursor = item and ui.itemActionCursor or ui.actionCursor
|
||||
require("src.ui.game3.rs.menu_cursor").draw((left + 1) * 8, (top + 1) * 8 + (cursor - 1) * 16, (width - 1) * 8)
|
||||
@@ -180,7 +204,7 @@ function Data.drawPrompt(ui)
|
||||
elseif ui.mode == "give" then id = 4
|
||||
elseif ui.mode == "move_tutor" then id = 20
|
||||
elseif ui.mode == "use" then id = require("src.core.game3.items_data").isTm(ui._item) and 2 or 3 end
|
||||
prompt(id, 22)
|
||||
prompt(ui, ui.mode, id, 22)
|
||||
end
|
||||
|
||||
function Data.yesNoLabels()
|
||||
|
||||
@@ -5,6 +5,7 @@ local Chrome = require("src.ui.game3.chrome")
|
||||
local Cursor = require("src.ui.game3.rs.menu_cursor")
|
||||
local Window = require("src.ui.game3.window")
|
||||
local TextIR = require("src.core.game3.scripting.text_ir")
|
||||
local RomText = require("src.core.game3.rom_text")
|
||||
local Items = require("src.core.game3.items_data")
|
||||
local UI = {CAMERA_OFFSET = {x = -3, y = -3}}
|
||||
UI.WIN = {money = Window.template(1, 1, 12, 2), qty = Window.template(1, 11, 12, 2),
|
||||
@@ -15,10 +16,14 @@ local function manifest()
|
||||
assert(man.assetLayout == "rs" and man.shopVersion == 2, "native RS shop schema required")
|
||||
return man
|
||||
end
|
||||
local resolved = {}
|
||||
function UI.ir(key)
|
||||
if resolved[key] then return resolved[key] end
|
||||
local man = manifest()
|
||||
local native = assert(man.textAliases[key] or (man.textBytes[key] and key), "native RS shop text policy missing: " .. key)
|
||||
return TextIR.decode(assert(man.textBytes[native], "native RS shop text bytes missing: " .. native), {dialect = "rs"})
|
||||
resolved[key] = RomText.irOr(native,
|
||||
TextIR.decode(assert(man.textBytes[native], "native RS shop text bytes missing: " .. native), {dialect = "rs"}))
|
||||
return resolved[key]
|
||||
end
|
||||
function UI.plain(key, ctx) return TextIR.toPlain(UI.ir(key), ctx or {}) end
|
||||
function UI.box(key, ctx) return UI.plain(key, ctx) end
|
||||
@@ -176,6 +181,7 @@ function UI.drawSell(sale)
|
||||
end
|
||||
function UI.show(shop, opts)
|
||||
opts = opts or {}; opts.nativePolicy = UI
|
||||
resolved = {}
|
||||
manifest()
|
||||
shop._rsShopFrame = 0
|
||||
return Base.show(shop, opts)
|
||||
|
||||
@@ -50,6 +50,7 @@ local function detailRows(open) S._detailRowsOpen = open end
|
||||
function S.openMenu(party, index, opts)
|
||||
opts = opts or {}
|
||||
S._man, S._party, S._opts = S.manifest(), party or {}, opts
|
||||
S._contestDescriptions = {}
|
||||
S._cursor = index or 1
|
||||
S._playerState = opts.playerState or opts.session
|
||||
or require("src.core.game3.runtime").getSession()
|
||||
@@ -500,7 +501,10 @@ local function moves()
|
||||
local amount = value == 255 and 0 or math.floor(value / 10)
|
||||
for i = 0, 7 do frame(S._man.hearts, row == 1 and (i < amount and 1 or 0) or (i < amount and 3 or 4), 48 + i % 4 * 8, 120 + (row - 1) * 16 + math.floor(i / 4) * 8) end
|
||||
end
|
||||
print(effect.description, 88, 120, 255)
|
||||
local descriptions = S._contestDescriptions or {}
|
||||
S._contestDescriptions = descriptions
|
||||
descriptions[effect] = descriptions[effect] or SummaryData.contestEffectDescription(effect)
|
||||
print(descriptions[effect], 88, 120, 255)
|
||||
else
|
||||
local def = Pokemon.battleMove(id)
|
||||
text("gOtherText_Power2", 8, 120); text("gOtherText_Accuracy2", 8, 136)
|
||||
|
||||
@@ -18,6 +18,12 @@ local function copiedCard(card)
|
||||
out.stars = math.max(0, math.min(4, math.floor(tonumber(out.stars) or 0)))
|
||||
return out
|
||||
end
|
||||
local function profilePhrase(card)
|
||||
local Easy, words = require("src.core.game3.easy_chat_text"), card.easyChatProfile or {}
|
||||
local out = {}
|
||||
for row = 0, 1 do out[row + 1] = Easy.word(words[row * 2 + 1] or 65535) .. " " .. Easy.word(words[row * 2 + 2] or 65535) end
|
||||
return out
|
||||
end
|
||||
function T.show(opts)
|
||||
opts = opts or {}
|
||||
local rt = package.loaded["src.core.game3.runtime"]
|
||||
@@ -25,6 +31,7 @@ function T.show(opts)
|
||||
T._clockSession = opts.clockSession or (rt and rt.getSession and rt.getSession()) or T._session
|
||||
T._link = opts.linkCard == true or (T._session.dex == nil and T._session.stars ~= nil)
|
||||
T._card = T._link and copiedCard(T._session) or Policy.generate(T._session)
|
||||
T._phrase = T._link and profilePhrase(T._card) or nil
|
||||
T._man, T._onClose = T.manifest(), opts.onClose
|
||||
T.open, T.side, T._phase, T._setup = true, "front", "setup", 0
|
||||
T._pal, T._stepper = Pal.new(), Kit.stepper()
|
||||
@@ -143,8 +150,8 @@ function T.texts(card, side, colon)
|
||||
local time = T._link and c or T._session
|
||||
put("time", tostring(tonumber(time.playTimeHours) or 0) .. (colon and " : " or " ") .. string.format("%02d", tonumber(time.playTimeMinutes) or 0), 80, 96, "values", false, 48)
|
||||
if T._link then
|
||||
local Easy, words = require("src.core.game3.easy_chat_text"), c.easyChatProfile or {}
|
||||
for row = 0, 1 do put("phrase" .. row, Easy.rawWord(words[row * 2 + 1] or 65535) .. " " .. Easy.rawWord(words[row * 2 + 2] or 65535), 16, 112 + row * 16) end
|
||||
local phrase = T._phrase or profilePhrase(c)
|
||||
for row = 0, 1 do put("phrase" .. row, phrase[row + 1], 16, 112 + row * 16) end
|
||||
end
|
||||
else
|
||||
put("name", c.name .. s.nameSuffix, 224, 16, "values", true)
|
||||
|
||||
@@ -6,6 +6,15 @@ local Cursor = require("src.ui.game3.rs.menu_cursor")
|
||||
local Pal = require("src.core.game3.pal_fade")
|
||||
local Fx = require("src.core.game3.gba_fx")
|
||||
local Easy = require("src.core.game3.easy_chat_text")
|
||||
local words, groups = {}, {}
|
||||
local function wordText(id)
|
||||
if words[id] == nil then words[id] = Easy.word(id) end
|
||||
return words[id]
|
||||
end
|
||||
local function groupText(group)
|
||||
if groups[group] == nil then groups[group] = Easy.groupName(group) end
|
||||
return groups[group]
|
||||
end
|
||||
local Policy = require("src.ui.game3.rs.trendy_phrase_policy")
|
||||
local Frames = require("src.ui.game3.rs.trendy_phrase_frames")
|
||||
local C = {isMenu = true, open = false}
|
||||
@@ -27,6 +36,7 @@ function C.manifest()
|
||||
end
|
||||
function C.show(opts)
|
||||
opts = opts or {}
|
||||
words, groups = {}, {}
|
||||
C._man, C._session, C._opts = C.manifest(), assert(opts.session), opts
|
||||
C._before, C.words = copyWords(opts.words), copyWords(opts.words)
|
||||
C.groups = Policy.groups(C._session, opts.gates)
|
||||
@@ -264,7 +274,7 @@ local function triangle(x, y)
|
||||
end
|
||||
local function phraseWords()
|
||||
if C._confirm and C._confirm.kind == "save" then
|
||||
text(Easy.rawWord(C.words[1]) .. " " .. Easy.rawWord(C.words[2]) .. " ", 48, 24, "phrase")
|
||||
text(wordText(C.words[1]) .. " " .. wordText(C.words[2]) .. " ", 48, 24, "phrase")
|
||||
return
|
||||
end
|
||||
for i = 1, 2 do
|
||||
@@ -273,7 +283,7 @@ local function phraseWords()
|
||||
local image = assert(Kit.image(C._man.blankWord))
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
Fx.draw(function() love.graphics.draw(image, x, y) end, C._pal:fx(0))
|
||||
else text(Easy.rawWord(C.words[i]), x, y, "phrase") end
|
||||
else text(wordText(C.words[i]), x, y, "phrase") end
|
||||
end
|
||||
end
|
||||
local function pickerText()
|
||||
@@ -295,7 +305,7 @@ local function pickerText()
|
||||
local word = (view == "groups" and C.groups or C._list)[row * 2 + col + 1]
|
||||
if word then
|
||||
local x = (view == "groups" and 16 or 48) + col * 88
|
||||
text(view == "groups" and word.name or word.text, x, 88 + (row - state.top) * 16 + offset, "picker")
|
||||
text(view == "groups" and groupText(word) or wordText(word.id), x, 88 + (row - state.top) * 16 + offset, "picker")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,8 +12,32 @@ local RsPolicy = require("src.ui.game3.rs.pokedex_policy")
|
||||
local function nativeRs() return Gfx.manifest().assetLayout == "rs" end
|
||||
local rsTextNames = {gText_CryOf = "CryOf", gText_SizeComparedTo = "SizeComparedTo", gText_SelectorArrow = "RightPointingTriangle",
|
||||
gText_SearchingPleaseWait = "Searching", gText_SearchCompleted = "SearchComplete", gText_NoMatchingPkmnWereFound = "NoMatching"}
|
||||
local function cached(label, copy)
|
||||
if label and RomText.has(label) then return RomText.plain(label) end
|
||||
return copy
|
||||
end
|
||||
local RS_LABELS = {RightPointingTriangle = "DexText_RightPointingTriangle"}
|
||||
local function rsString(key)
|
||||
local copy = assert(Gfx.manifest().strings[key], "native RS dex text " .. tostring(key))
|
||||
local text = cached(RS_LABELS[key] or ("gDexText_" .. key), nil)
|
||||
if text == nil then return copy end
|
||||
return (copy:match("^\252\019.") or "") .. text
|
||||
end
|
||||
-- pokeruby/src/pokedex.c:4228
|
||||
local function categorySuffix(unknown)
|
||||
local i, marks = 1, 0
|
||||
while i <= #unknown do
|
||||
local c = unknown:sub(i, i)
|
||||
if c == "?" then marks, i = marks + 1, i + 1
|
||||
elseif c == " " then i = i + 1
|
||||
elseif unknown:sub(i, i + 2) == "?" then marks, i = marks + 1, i + 3
|
||||
else break end
|
||||
end
|
||||
if marks == 0 or i > #unknown then return "" end
|
||||
return (unknown:sub(i - 1, i - 1) == " " and " " or "") .. unknown:sub(i)
|
||||
end
|
||||
local function dexText(key)
|
||||
return nativeRs() and assert(Gfx.manifest().strings[assert(rsTextNames[key], "native RS dex text alias")]) or RomText.plain(key)
|
||||
return nativeRs() and rsString(assert(rsTextNames[key], "native RS dex text alias")) or RomText.plain(key)
|
||||
end
|
||||
|
||||
local Pokedex = {}
|
||||
@@ -910,20 +934,26 @@ end
|
||||
local function monInfo(s, nat, nationalNumber, owned, newEntry)
|
||||
local e = entryFor(nat)
|
||||
if nativeRs() then
|
||||
local strings, out = Gfx.manifest().strings, {}
|
||||
local out = {}
|
||||
if newEntry then
|
||||
local t = strings.RegisterComplete
|
||||
local t = rsString("RegisterComplete")
|
||||
out[#out + 1] = {text = t, x = 16 + math.floor((208 - FrlgFont.measure(t)) / 2), y = 0}
|
||||
end
|
||||
local num = nationalNumber and nat or (Pokedex.hoennNumber(nat) or nat)
|
||||
out[#out + 1] = {text = string.format("%03d", num), x = 104, y = 24}
|
||||
out[#out + 1] = {text = pokemon().name(Pokedex.speciesOf(nat)) or Gfx.manifest().tenDashes, x = 128, y = 24}
|
||||
local category = owned and ((e.category or "") .. " " .. strings.UnknownPoke:match("[^? ]+.*$")) or strings.UnknownPoke
|
||||
local cx = 88 + (owned and (FrlgFont.measure(strings.UnknownPoke) - FrlgFont.measure(category)) or 0)
|
||||
local unknown = rsString("UnknownPoke")
|
||||
local category = owned and (Strings(e.category or "") .. categorySuffix(unknown)) or unknown
|
||||
local cx = 88 + (owned and (FrlgFont.measure(unknown) - FrlgFont.measure(category)) or 0)
|
||||
out[#out + 1] = {text = category, x = cx, y = 40}
|
||||
out[#out + 1] = {text = owned and Pokedex.heightText(e.height or 0) or strings.UnknownHeight, x = 128, y = 56}
|
||||
out[#out + 1] = {text = owned and RsPolicy.weightText(e.weight or 0) or strings.UnknownWeight, x = 128, y = 72}
|
||||
local desc = s.descriptionPage == 1 and e.description2 or e.description
|
||||
out[#out + 1] = {text = owned and Pokedex.heightText(e.height or 0) or rsString("UnknownHeight"), x = 128, y = 56}
|
||||
out[#out + 1] = {text = owned and RsPolicy.weightText(e.weight or 0) or rsString("UnknownWeight"), x = 128, y = 72}
|
||||
local desc
|
||||
if s.descriptionPage == 1 then
|
||||
desc = cached(e.descriptionLabel2, e.description2)
|
||||
else
|
||||
desc = cached(e.descriptionLabel, e.description)
|
||||
end
|
||||
out[#out + 1] = {text = owned and (desc or "") or "", x = 16, y = 104}
|
||||
return out
|
||||
end
|
||||
@@ -1535,7 +1565,8 @@ function tasks.loadSize(s)
|
||||
s.state = 3
|
||||
elseif st == 3 then
|
||||
local name = s.session and (s.session.name or s.session.playerName) or ""
|
||||
local t = dexText("gText_SizeComparedTo") .. tostring(name)
|
||||
local label = dexText("gText_SizeComparedTo")
|
||||
local t = label:find("^の") and tostring(name) .. label or label .. tostring(name)
|
||||
local w = FrlgFont.measure(t) or 0
|
||||
s.sizeText = { text = t, x = nativeRs() and (24 + 96 - math.floor(w / 2)) or (w < 240 and math.floor((240 - w) / 2) or 0), y = nativeRs() and 120 or 121 }
|
||||
s.state = 4
|
||||
@@ -1593,10 +1624,7 @@ function tasks.switchFromSize(s)
|
||||
end
|
||||
end
|
||||
|
||||
local function cartText(key, fallback)
|
||||
if key and RomText.has(key) then return RomText.plain(key) end
|
||||
return fallback
|
||||
end
|
||||
local cartText = cached
|
||||
|
||||
-- pokeemerald/src/pokedex.c:1330
|
||||
local TYPE_OPTION = { "gText_DexSearchTypeNone" }
|
||||
@@ -1632,11 +1660,13 @@ local ITEM_DESCRIPTIONS = { "gText_ListByFirstLetter", "gText_ListByBodyColor",
|
||||
"gText_ListByType", "gText_SelectPokedexListingMode", "gText_SelectPokedexMode", "gText_ExecuteSearchSwitch" }
|
||||
|
||||
local function topBarDescription(i)
|
||||
return cartText(TOPBAR_DESCRIPTIONS[i + 1], Gfx.manifest().search.topBar[i + 1].description)
|
||||
local row = Gfx.manifest().search.topBar[i + 1]
|
||||
return cartText(row.descriptionKey or TOPBAR_DESCRIPTIONS[i + 1], row.description)
|
||||
end
|
||||
|
||||
local function itemDescription(i)
|
||||
return cartText(ITEM_DESCRIPTIONS[i + 1], Gfx.manifest().search.items[i + 1].description)
|
||||
local row = Gfx.manifest().search.items[i + 1]
|
||||
return cartText(row.descriptionKey or ITEM_DESCRIPTIONS[i + 1], row.description)
|
||||
end
|
||||
|
||||
-- pokeemerald/src/pokedex.c:1437
|
||||
@@ -1657,8 +1687,8 @@ local function searchOptionTexts(which)
|
||||
local out = {}
|
||||
for i, t in ipairs(list) do
|
||||
out[i] = {
|
||||
title = cartText(keys.titles[i], t.title),
|
||||
description = cartText(keys.descriptions and keys.descriptions[i], t.description),
|
||||
title = cartText(t.titleKey or keys.titles[i], t.title),
|
||||
description = cartText(t.descriptionKey or (keys.descriptions and keys.descriptions[i]), t.description),
|
||||
}
|
||||
end
|
||||
return out
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
-- Ruby and Sapphire read the cart strings a translation mod overrides from
|
||||
-- the script cache, where the mod's text overrides land, as Emerald does
|
||||
-- (game3_emerald_pack_text_test.lua); the extract's or the pack's copy stays
|
||||
-- the fallback.
|
||||
|
||||
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||
|
||||
local function ir(s) return { { t = "text", s = s }, { t = "eos" } } end
|
||||
|
||||
local BUNDLE = { text = {} }
|
||||
package.loaded["src.core.game3.scripting.space"] = { ensureBundle = function() return BUNDLE end }
|
||||
|
||||
local TextIR = require("src.core.game3.scripting.text_ir")
|
||||
|
||||
local failed = 0
|
||||
local function check(cond, msg)
|
||||
if cond then
|
||||
print("[ok] " .. msg)
|
||||
else
|
||||
failed = failed + 1
|
||||
print("[FAIL] " .. msg)
|
||||
end
|
||||
end
|
||||
|
||||
-- Expanded placeholders (pokeruby/src/string_util.c:476): the teams, their
|
||||
-- leaders and legendaries by edition, the version, the rival and the
|
||||
-- honorific.
|
||||
local Extract = require("src.import.gba.text_placeholders_extract")
|
||||
local ruby, sapphire = Extract.rsSymbols("ruby"), Extract.rsSymbols("sapphire")
|
||||
check(ruby.EVIL_TEAM == "gExpandedPlaceholder_Magma" and sapphire.EVIL_TEAM == "gExpandedPlaceholder_Aqua",
|
||||
"the evil team is Magma in Ruby and Aqua in Sapphire")
|
||||
check(ruby.GOOD_LEADER == "gExpandedPlaceholder_Archie" and sapphire.GOOD_LEADER == "gExpandedPlaceholder_Maxie",
|
||||
"the good team's leader follows the edition")
|
||||
check(ruby.VERSION == "gExpandedPlaceholder_Ruby" and sapphire.VERSION == "gExpandedPlaceholder_Sapphire",
|
||||
"the version names the edition")
|
||||
check(Extract.symbolsFor("emerald") == Extract.SYMBOLS, "Emerald keeps its own labels")
|
||||
|
||||
local Message = require("src.ui.game3.message")
|
||||
BUNDLE.text = {
|
||||
gExpandedPlaceholder_Maxie = ir("MAX"), gExpandedPlaceholder_Archie = ir("ARTHUR"),
|
||||
gExpandedPlaceholder_Ruby = ir("RUBIS"), gExpandedPlaceholder_May = ir("FLORA"),
|
||||
gExpandedPlaceholder_Kun = ir("くん"),
|
||||
}
|
||||
local placeholders = Message.cartPlaceholders({
|
||||
EVIL_TEAM = "MAGMA", EVIL_LEADER = "MAXIE", GOOD_LEADER = "ARCHIE", VERSION = "RUBY",
|
||||
RIVAL_MALE = "MAY", RIVAL_FEMALE = "BRENDAN", KUN_MALE = "", KUN_FEMALE = "",
|
||||
byGender = { RIVAL = { male = "MAY", female = "BRENDAN" }, KUN = { male = "", female = "" } },
|
||||
}, "ruby")
|
||||
check(placeholders.EVIL_LEADER == "MAX" and placeholders.GOOD_LEADER == "ARTHUR",
|
||||
"the leaders' names read the cache by the edition's labels")
|
||||
check(placeholders.VERSION == "RUBIS", "the version's name reads the cache")
|
||||
check(placeholders.EVIL_TEAM == "MAGMA", "a placeholder missing from the cache keeps the copy")
|
||||
check(placeholders.byGender.RIVAL.male == "FLORA", "the rival's name reads the cache")
|
||||
local line = { { t = "player" }, { t = "ph", code = 5, name = "KUN" }, { t = "text", s = ": " },
|
||||
{ t = "ph", code = 10, name = "EVIL_LEADER" }, { t = "text", s = " / " },
|
||||
{ t = "ph", code = 6, name = "RIVAL" }, { t = "eos" } }
|
||||
check(TextIR.toPlain(line, { dialect = "rs", playerName = "RED", playerGender = 0, placeholders = placeholders })
|
||||
== "REDくん: MAX / FLORA", "a Ruby line expands the honorific, the leader and the rival from the cache")
|
||||
BUNDLE.text = { gExpandedPlaceholder_Archie = ir("ARTHUR"), gExpandedPlaceholder_Maxie = ir("MAX") }
|
||||
local sapphireLine = Message.cartPlaceholders({ EVIL_LEADER = "ARCHIE", byGender = {} }, "sapphire")
|
||||
check(sapphireLine.EVIL_LEADER == "ARTHUR", "Sapphire's evil leader is Archie's row")
|
||||
|
||||
-- The native Pokédex (src/ui/game3/rse/pokedex.lua): the entry's pages by
|
||||
-- their own labels, its labels and the search screen by the labels the
|
||||
-- packs name next to their copies.
|
||||
local MANIFEST = {
|
||||
assetLayout = "rs",
|
||||
strings = { UnknownPoke = " ????? POKéMON", CryOf = "\252\019\002CRY OF", RegisterComplete = "REGISTERED",
|
||||
UnknownHeight = "\252\019\012??'??\"", UnknownWeight = "????.? lbs.", SizeComparedTo = "SIZE COMPARED TO ",
|
||||
Searching = "Searching...", SearchComplete = "Search completed.", NoMatching = "No matching POKéMON.",
|
||||
RightPointingTriangle = ">" },
|
||||
search = {
|
||||
topBar = { { description = "Search for POKéMON.", descriptionKey = "DexText_SearchForPoke" } },
|
||||
items = { { description = "List by the first letter.", descriptionKey = "DexText_ListByABC" } },
|
||||
names = { { title = "ABC", titleKey = "DexText_ABC", description = "" } },
|
||||
colors = {}, types = {}, orders = {}, modes = {},
|
||||
},
|
||||
}
|
||||
package.loaded["src.ui.game3.rse.pokedex_gfx"] = setmetatable({ manifest = function() return MANIFEST end },
|
||||
{ __index = function() return function() end end })
|
||||
package.loaded["src.ui.game3.rse.mapsec"] = setmetatable({ readLua = function(path)
|
||||
if path:find("entries", 1, true) then
|
||||
return { [277] = { category = "WOOD GECKO", height = 5, weight = 50, description = "Ruby page one.",
|
||||
description2 = "Ruby page two.", descriptionLabel = "DexDescription_Treecko_1",
|
||||
descriptionLabel2 = "DexDescription_Treecko_2" } }
|
||||
end
|
||||
return { nationalToRegional = {} }
|
||||
end }, { __index = function() return function() end end })
|
||||
package.loaded["src.core.game3.pokemon"] = { speciesFromNational = function() return 277 end,
|
||||
name = function() return "ARCKO" end }
|
||||
local Pokedex = require("src.ui.game3.rse.pokedex")
|
||||
BUNDLE.text = {
|
||||
DexDescription_Treecko_2 = ir("Page deux."), gDexText_UnknownPoke = ir(" ????? POKéMON"),
|
||||
gDexText_CryOf = ir("CRI DE"), DexText_SearchForPoke = ir("Chercher des POKéMON."), DexText_ABC = ir("ABC FR"),
|
||||
}
|
||||
local function texts(rows)
|
||||
local out = {}
|
||||
for _, row in ipairs(rows) do out[#out + 1] = row.text end
|
||||
return table.concat(out, "|")
|
||||
end
|
||||
local page1 = texts(Pokedex.monInfo({ descriptionPage = 0 }, 252, true, true, false))
|
||||
local page2 = texts(Pokedex.monInfo({ descriptionPage = 1 }, 252, true, true, false))
|
||||
check(page1:find("Ruby page one.", 1, true) ~= nil, "a page missing from the cache keeps the pack's copy")
|
||||
check(page2:find("Page deux.", 1, true) ~= nil, "the second page reads the cache by its own label")
|
||||
check(page1:find("WOOD GECKO POKéMON", 1, true) ~= nil, "the category keeps the cart's POKéMON after it")
|
||||
check(Pokedex.topBarDescription(0) == "Chercher des POKéMON.", "the search top bar reads its own label")
|
||||
check(Pokedex.itemDescription(0) == "List by the first letter.", "a search line missing from the cache keeps the copy")
|
||||
check(Pokedex.searchOptionTexts(Pokedex.SEARCH.NAME)[1].title == "ABC FR", "a search option reads its own label")
|
||||
-- pokeruby/src/pokedex.c:4228: only the English cart follows the category
|
||||
-- with the word after its unknown-category string's question marks.
|
||||
local function infoRow(owned, y)
|
||||
for _, row in ipairs(Pokedex.monInfo({ descriptionPage = 0 }, 252, true, owned, false)) do
|
||||
if row.y == y then return row.text end
|
||||
end
|
||||
end
|
||||
local function category(unknown)
|
||||
BUNDLE.text.gDexText_UnknownPoke = ir(unknown)
|
||||
return infoRow(true, 40)
|
||||
end
|
||||
check(category(" ????? POKéMON") == "WOOD GECKO POKéMON", "the English cart follows the category with POKéMON")
|
||||
check(category("?????") == "WOOD GECKO", "the French and German carts print the category alone")
|
||||
check(category("POKéMON ?????") == "WOOD GECKO", "so does the Italian cart, whose word comes first")
|
||||
check(category("?????ポケモン") == "WOOD GECKOポケモン", "the Japanese word follows the category without a space")
|
||||
BUNDLE.text.gDexText_UnknownHeight = ir("???,? m")
|
||||
check(infoRow(false, 56) == "\252\019\012???,? m", "a label keeps its copy's CLEAR_TO in front of the cache's text")
|
||||
local Registry = require("src.import.gba.layouts.registry")
|
||||
local active = Registry.active
|
||||
Registry.active = function() return { id = "rs" } end
|
||||
local Entries = require("src.import.gba.pokedex_entries_extract")
|
||||
local function entriesCache(body) return { exists = function() return true end, read = function() return body end } end
|
||||
check(not Entries.ready(entriesCache("return { [277] = { description = \"x\" } }")),
|
||||
"an R/S cache without the description labels extracts its entries again")
|
||||
check(Entries.ready(entriesCache("return { [277] = { descriptionLabel = \"DexDescription_Treecko_1\" } }")),
|
||||
"an R/S cache with the labels keeps its entries")
|
||||
Registry.active = active
|
||||
|
||||
-- Native screens that keep a cart string in their pack under its pret label
|
||||
-- read the script cache's text under that label first.
|
||||
local COPY = { 0xBD, 0xC9, 0xCA, 0xD3, 0xFF } -- "COPY"
|
||||
local Kit = require("src.ui.game3.rse.scene_kit")
|
||||
local MANIFESTS = {
|
||||
["items/shop"] = { assetLayout = "rs", shopVersion = 2, textAliases = { gText_HowMayIServeYou = "gOtherText_HowMayIServe" },
|
||||
textBytes = { gOtherText_HowMayIServe = COPY, gOtherText_Unnamed = COPY } },
|
||||
}
|
||||
Kit.manifest = function(sub)
|
||||
if MANIFESTS[sub] then return MANIFESTS[sub] end
|
||||
return { assetLayout = "rs", textBytes = { gOtherText_TeachWhichMove = COPY, gOtherText_Unnamed = COPY } }
|
||||
end
|
||||
local Shop = require("src.ui.game3.rs.shop_menu")
|
||||
BUNDLE.text = { gOtherText_HowMayIServe = ir("Que puis-je faire pour vous ?"),
|
||||
gOtherText_TeachWhichMove = ir("Quelle capacité apprendre ?") }
|
||||
check(Shop.plain("gText_HowMayIServeYou") == "Que puis-je faire pour vous ?", "the shop reads the cache by its label")
|
||||
check(Shop.plain("gOtherText_Unnamed") == "COPY", "a shop line missing from the cache keeps the pack's copy")
|
||||
|
||||
-- The move relearner, the decoration menus and the museum's painting
|
||||
-- captions, through the text function each screen hands its shared base.
|
||||
package.loaded["src.ui.game3.rse.move_relearner"] = { SUB = "tutor", show = function(_, opts) return opts end }
|
||||
local tutorText = require("src.ui.game3.rs.move_relearner").show({}, {}).text
|
||||
check(tutorText("gText_TeachWhichMoveToPkmn") == "Quelle capacité apprendre ?", "the move relearner reads the cache by its label")
|
||||
check(tutorText("gOtherText_Unnamed") == "COPY", "a move relearner line missing from the cache keeps the pack's copy")
|
||||
BUNDLE.text.gOtherText_TeachWhichMove = ir("Autre texte")
|
||||
check(tutorText("gText_TeachWhichMoveToPkmn") == "Quelle capacité apprendre ?", "a screen resolves its text once while it is open")
|
||||
tutorText = require("src.ui.game3.rs.move_relearner").show({}, {}).text
|
||||
check(tutorText("gText_TeachWhichMoveToPkmn") == "Autre texte", "and again when it opens")
|
||||
|
||||
package.loaded["src.ui.game3.rse.decoration"] = { open = function(opts) return opts end }
|
||||
package.loaded["src.core.game3.rse.decoration"] = { manifest = function()
|
||||
return { textBytes = { gSecretBaseText_DecorReturned = COPY, gSecretBaseText_NoDecor = COPY }, strings = {} }
|
||||
end }
|
||||
package.loaded["src.core.game3.rse.decoration_inventory"] = { categoryName = function() return "" end }
|
||||
local decorText = require("src.ui.game3.rs.decoration").open().text
|
||||
BUNDLE.text = { gSecretBaseText_DecorReturned = ir("La décoration est retournée au PC.") }
|
||||
check(decorText("gText_DecorationReturnedToPC") == "La décoration est retournée au PC.", "the decoration menus read the cache by their labels")
|
||||
check(decorText("gText_NoDecorationHere") == "COPY", "a decoration line missing from the cache keeps the pack's copy")
|
||||
|
||||
package.loaded["src.ui.game3.rse.contest_painting"] = { ID = "contest_painting", SUB = "contest_painting" }
|
||||
local Painting = require("src.ui.game3.rs.contest_painting")
|
||||
local PAINT = { captionLayout = { museumStart = 5, nicknameBytes = 10 },
|
||||
captionParts = { [0] = { prefix = "gContestPaintingCool1", suffix = "gContestPaintingCool2" } },
|
||||
textBytes = { gContestPaintingCool1 = COPY, gContestPaintingCool2 = COPY } }
|
||||
BUNDLE.text = { gContestPaintingCool1 = ir("Le POKéMON ") }
|
||||
check(Painting.caption(5, { nickname = "ZIGZATON", contestCategory = 0 }, nil, PAINT) == "Le POKéMON ZIGZATONCOPY",
|
||||
"a painting's caption reads the cache by its labels, the pack's copy where the cache has none")
|
||||
-- pokeruby/src/contest_painting.c:234: the European carts name the POKéMON
|
||||
-- first ("ZIGZATON von MAY"), the US and Japanese ones the trainer.
|
||||
PAINT.rankNames = { [0] = "gContestRankNormal" }
|
||||
PAINT.hallCaption, PAINT.hallPossessive = "gContestText_ContestWinner", "gOtherText_Unknown1"
|
||||
PAINT.captionLayout.hallLatinControl = {}
|
||||
PAINT.textBytes.gContestRankNormal, PAINT.textBytes.gContestText_ContestWinner, PAINT.textBytes.gOtherText_Unknown1 = COPY, COPY, COPY
|
||||
local winner = { nickname = "ZIGZATON", trainerName = "MAY", contestCategory = 0 }
|
||||
BUNDLE.text = { gContestRankNormal = ir("NORMAL "), gContestText_ContestWinner = ir("WINNER "), gOtherText_Unknown1 = ir("'s ") }
|
||||
check(Painting.caption(0, winner, nil, PAINT) == "NORMAL WINNER MAY's ZIGZATON", "the US hall caption names the trainer first")
|
||||
BUNDLE.text.gOtherText_Unknown1 = ir(" von ")
|
||||
check(Painting.caption(0, winner, nil, PAINT) == "NORMAL WINNER ZIGZATON von MAY", "a European hall caption names the POKéMON first")
|
||||
|
||||
-- Easy Chat: what the player reads prints each word translated
|
||||
-- (EasyChatText.word); what the scripts compare keeps the cart's word.
|
||||
package.loaded["src.core.game3.easy_chat_text"] = {
|
||||
-- 1513 is 513's cart word under another id, translated differently
|
||||
rawWord = function(id) return "RAW" .. id % 1000 end, word = function(id) return "MOT" .. id end,
|
||||
group = function() return { words = { { id = 513, text = "RAW513" } } } end,
|
||||
}
|
||||
package.loaded["src.core.game3.rs.dewford_trend"] = { editorValid = function() return true end,
|
||||
trySetTrendyPhrase = function() return true end }
|
||||
local Contracts = require("src.core.game3.rs.easy_chat_contracts")
|
||||
local trend = Contracts.commit({ type = 9, wordCount = 2, before = { 0xFFFF, 0xFFFF }, session = {} }, { 513, 514 })
|
||||
check(trend.stringVar2 == "MOT513 MOT514", "the trendy phrase the script prints is translated")
|
||||
check(trend.result == 1, "a new trend counts as a change")
|
||||
local same = Contracts.commit({ type = 9, wordCount = 2, before = { 1513, 514 }, session = {} }, { 513, 514 })
|
||||
check(same.result == 0, "the change is measured on the cart's words, not their translation")
|
||||
check(require("src.core.game3.rs.tv_playback").word(513) == "MOT513", "the TV prints a word translated")
|
||||
-- Gabby and Ty's last quote is printed from the cart's bytes: a translated
|
||||
-- word the cart's charset cannot hold keeps the cart's word.
|
||||
local Routes = require("src.core.game3.scripting.natives_rs_tv_routes")
|
||||
local Rse, Tv = require("src.core.game3.rse.init"), require("src.core.game3.rse.tv")
|
||||
local session, gabbyData = { version = "ruby" }, { quote = {} }
|
||||
local rseSession, tvState = Rse.session, Tv.state
|
||||
Rse.session = function() return session end
|
||||
Tv.state = function() return { gabbyAndTyData = gabbyData } end
|
||||
local function lastQuote()
|
||||
gabbyData.quote[0] = 513
|
||||
local ctx = {}
|
||||
Routes.BY_NAME.GabbyAndTyGetLastQuote(ctx, nil)
|
||||
return ctx.stringVars[1]
|
||||
end
|
||||
check(lastQuote() == "MOT513", "Gabby and Ty quote a word translated")
|
||||
local EASY = package.loaded["src.core.game3.easy_chat_text"]
|
||||
local word = EASY.word
|
||||
EASY.word = function() return "ともだち" end
|
||||
check(lastQuote() == "RAW513", "a word the cart cannot print keeps the cart's word")
|
||||
EASY.word, Rse.session, Tv.state = word, rseSession, tvState
|
||||
|
||||
|
||||
-- The party menu's actions (pokeruby/src/pokemon_menu.c:126) read the
|
||||
-- script cache by their pret labels, and a field move prints its move's name.
|
||||
MANIFESTS["rse/menus"] = { party = { cursorOptions = { "SUMMARY", "SWITCH", "ITEM", "CANCEL", "GIVE", "TAKE",
|
||||
"TAKE", "MAIL", "READ", "CANCEL", "CUT" } } }
|
||||
package.loaded["src.core.game3.pokemon"].moveName = function(move) return move == 15 and "COUPE" or nil end
|
||||
local PartyData = require("src.ui.game3.rs.party_menu_data")
|
||||
BUNDLE.text = { OtherText_Summary = ir("RESUME"), OtherText_Take = ir("PRENDRE") }
|
||||
check(PartyData.actionText("SUMMARY") == "RESUME", "a party action reads the cache by its label")
|
||||
check(PartyData.actionText("TAKE_MAIL") == "PRENDRE", "the mail's TAKE reads its own label")
|
||||
check(PartyData.actionText("SWITCH") == "SWITCH", "an action missing from the cache keeps the pack's copy")
|
||||
check(PartyData.actionText("CUT", { index = { CUT = 0 }, moves = { 15 } }) == "COUPE", "a field move prints its move's name")
|
||||
MANIFESTS["rse/party"] = { prompts = setmetatable({}, { __index = function() return "PROMPT" end }) }
|
||||
local drawn, resolved = {}, 0
|
||||
local font, chrome, cursor, partyChrome = package.loaded["src.ui.game3.frlg_font"], package.loaded["src.ui.game3.chrome"],
|
||||
package.loaded["src.ui.game3.rs.menu_cursor"], package.loaded["src.ui.game3.rs.party_chrome"]
|
||||
package.loaded["src.ui.game3.frlg_font"] = { draw = function(text) drawn[#drawn + 1] = text end }
|
||||
package.loaded["src.ui.game3.chrome"] = { stdFrame = function() end }
|
||||
package.loaded["src.ui.game3.rs.menu_cursor"] = { draw = function() end }
|
||||
package.loaded["src.ui.game3.rs.party_chrome"] = { textOptions = function() return {} end }
|
||||
local menu = { ACTIONS = { "SUMMARY", "CANCEL" }, actionCursor = 1,
|
||||
_actionTextsFor = function(list) resolved = resolved + 1 return { "RESUME", "RETOUR" } end }
|
||||
PartyData.drawActions(menu, false)
|
||||
check(drawn[2] == "RESUME" and drawn[3] == "RETOUR" and resolved == 1, "the action menu draws the texts resolved for its list")
|
||||
local displayName = package.loaded["src.core.game3.pokemon"].displayName
|
||||
package.loaded["src.core.game3.pokemon"].displayName = function(mon) return mon.nickname end
|
||||
BUNDLE.text = { ["PartyMenuPromptTexts[5]"] = { { t = "text", s = "Que faire avec " }, { t = "strvar", n = 1 },
|
||||
{ t = "text", s = "?" }, { t = "eos" } } }
|
||||
drawn, menu.ACTIONS, menu._party, menu.cursor = {}, { "SUMMARY", "CANCEL" }, { { nickname = "POUSSIFEU" } }, 1
|
||||
PartyData.drawActions(menu, false)
|
||||
check(drawn[1] == "Que faire avec POUSSIFEU?", "the action prompt reads the cache and names the POKeMON")
|
||||
BUNDLE.text = {}
|
||||
drawn = {}
|
||||
PartyData.drawActions(menu, false)
|
||||
check(drawn[1] == "Que faire avec POUSSIFEU?", "the prompt resolved for this menu is drawn again without a lookup")
|
||||
BUNDLE.text = { ["PartyMenuPromptTexts[5]"] = { { t = "text", s = "Que faire avec " }, { t = "strvar", n = 1 },
|
||||
{ t = "text", s = "?" }, { t = "eos" } } }
|
||||
drawn, menu.ACTIONS, menu._party = {}, { "SUMMARY", "CANCEL" }, { { nickname = "GOBOU" } }
|
||||
PartyData.drawActions(menu, false)
|
||||
check(drawn[1] == "Que faire avec GOBOU?", "a new action menu names its own POKeMON")
|
||||
package.loaded["src.core.game3.pokemon"].displayName = displayName
|
||||
package.loaded["src.ui.game3.frlg_font"], package.loaded["src.ui.game3.chrome"] = font, chrome
|
||||
package.loaded["src.ui.game3.rs.menu_cursor"], package.loaded["src.ui.game3.rs.party_chrome"] = cursor, partyChrome
|
||||
if failed > 0 then
|
||||
print(failed .. " check(s) failed")
|
||||
os.exit(1)
|
||||
end
|
||||
print("all checks passed")
|
||||
Reference in New Issue
Block a user