mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-19 20:20:19 +02:00
Merge branch 'dev' of https://github.com/bryanthaboi/gen1recomp into dev
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
-- The museum 1F ticket clerk's take-your-time/not-enough-money/come-again
|
||||
-- lines used to be bare English literals, invisible to game.data.text no
|
||||
-- matter what a translation mod put there. tests/engine/museum_money_box_
|
||||
-- bug1335.lua only ever runs with an empty game.data.text, so it can't
|
||||
-- tell a properly-wired t._Key or "..." fallback apart from a literal that
|
||||
-- never looked at t at all -- every assertion there passes either way.
|
||||
-- This test populates game.data.text with translated values and checks
|
||||
-- they actually reach the pushed TextBox, for all three lines.
|
||||
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||
|
||||
local T = require("tests.harness")
|
||||
|
||||
package.loaded["src.render.TextBox"] = {
|
||||
new = function(_, text, onDone, opts)
|
||||
return { text = text, onDone = onDone, opts = opts }
|
||||
end,
|
||||
}
|
||||
|
||||
local M = assert(loadfile("data/scripts/story2.lua"))()
|
||||
local clerk = M.MUSEUM_1F.talk.TEXT_MUSEUM1F_SCIENTIST1
|
||||
|
||||
local TRANSLATED = {
|
||||
_Museum1FScientist1TakePlentyOfTimeText = "Prends ton temps\net profite bien !",
|
||||
_Museum1FScientist1DontHaveEnoughMoneyText = "Tu n'as pas assez\nd'argent.",
|
||||
_Museum1FScientist1ComeAgainText = "Reviens vite !",
|
||||
}
|
||||
|
||||
local pushed
|
||||
local function mkGame(cash)
|
||||
pushed = {}
|
||||
return {
|
||||
data = { text = TRANSLATED },
|
||||
save = { money = cash, flags = {} },
|
||||
stack = { push = function(_, box) pushed[#pushed + 1] = box end },
|
||||
}
|
||||
end
|
||||
|
||||
-- already ticketed: take-your-time line
|
||||
local g = mkGame(3000)
|
||||
g.save.flags.EVENT_BOUGHT_MUSEUM_TICKET = true
|
||||
clerk(g, nil, nil, function() end)
|
||||
T.eq(pushed[1].text, TRANSLATED._Museum1FScientist1TakePlentyOfTimeText,
|
||||
"an existing ticket holder gets the translated take-your-time line")
|
||||
|
||||
-- YES but short on cash: not-enough-money line
|
||||
g = mkGame(20)
|
||||
clerk(g, nil, nil, function() end)
|
||||
pushed[1].opts.choice(true)
|
||||
T.eq(pushed[2].text, TRANSLATED._Museum1FScientist1DontHaveEnoughMoneyText,
|
||||
"short on cash opens the translated not-enough-money box")
|
||||
|
||||
-- NO: come-again line
|
||||
g = mkGame(3000)
|
||||
clerk(g, nil, nil, function() end)
|
||||
pushed[1].opts.choice(false)
|
||||
T.eq(pushed[2].text, TRANSLATED._Museum1FScientist1ComeAgainText,
|
||||
"declining opens the translated come-again box")
|
||||
|
||||
-- unpopulated game.data.text still falls back to the English literal
|
||||
g = { data = { text = {} }, save = { money = 3000, flags = {} },
|
||||
stack = { push = function(_, box) pushed[#pushed + 1] = box end } }
|
||||
pushed = {}
|
||||
g.save.flags.EVENT_BOUGHT_MUSEUM_TICKET = true
|
||||
clerk(g, nil, nil, function() end)
|
||||
T.check(tostring(pushed[1].text):find("Take your time", 1, true) ~= nil,
|
||||
"an empty catalog still falls back to the English take-your-time line")
|
||||
|
||||
T.finish("museum_1f_clerk_translation_test")
|
||||
@@ -490,6 +490,11 @@ check("hurt is easier to catch", hurtRate > fullRate, true)
|
||||
local asleepRate = Catching.rate({
|
||||
maxHp = 60, hp = 1, catchRate = 45, ball = "POKE_BALL", status = "sleep" })
|
||||
check("sleep adds 10", asleepRate, math.min(255, hurtRate + 10))
|
||||
checkNear("preview converts the exact byte roll", Catching.chance({
|
||||
maxHp = 60, hp = 60, catchRate = 45, ball = "POKE_BALL" }),
|
||||
fullRate * 100 / 256, 0.000001)
|
||||
check("master ball preview is certain", Catching.chance({
|
||||
maxHp = 60, hp = 60, catchRate = 1, ball = "MASTER_BALL" }), 100)
|
||||
-- The cart's bug: burn/poison/paralysis add nothing.
|
||||
check("poison adds nothing (cart bug)", Catching.rate({
|
||||
maxHp = 60, hp = 1, catchRate = 45, ball = "POKE_BALL",
|
||||
|
||||
@@ -282,6 +282,16 @@ local function runToMenu(screen, cap)
|
||||
return false
|
||||
end
|
||||
|
||||
do
|
||||
local screen = newScreen({ inventory = {
|
||||
MASTER_BALL = 1, POKE_BALL = 1,
|
||||
} })
|
||||
eq(screen:catchChance("MASTER_BALL"), 100,
|
||||
"the battle screen exposes a certain Master Ball preview")
|
||||
check(type(screen:catchChance("POKE_BALL")) == "number",
|
||||
"the battle screen exposes the live wild catch preview")
|
||||
end
|
||||
|
||||
-- ---- BattleMenu empties the textbox ---------------------------------------
|
||||
do
|
||||
local screen = newScreen()
|
||||
|
||||
@@ -163,14 +163,23 @@ function screen2:chooseMove(slot)
|
||||
return true
|
||||
end
|
||||
function screen2:cancelMove() self.phase = "menu" return true end
|
||||
function screen2:catchChance(ball)
|
||||
return ball == "MASTER_BALL" and 100 or 37.5
|
||||
end
|
||||
local game2 = {
|
||||
data = {
|
||||
pokemon = { CHIKORITA = { name = "CHIKORITA" },
|
||||
RATTATA = { name = "RATTATA" } },
|
||||
moves = { TACKLE = { name = "TACKLE", type = "NORMAL",
|
||||
power = 35, accuracy = 95, pp = 35 } },
|
||||
items = {
|
||||
MASTER_BALL = { name = "MASTER BALL", pocket = "BALL" },
|
||||
POTION = { name = "POTION", pocket = "ITEM" },
|
||||
},
|
||||
},
|
||||
save = { party = { player2 } }, stack = { states = { screen2 } },
|
||||
save = { party = { player2 }, inventory = {
|
||||
MASTER_BALL = 1, POTION = 2,
|
||||
} }, stack = { states = { screen2 } },
|
||||
}
|
||||
|
||||
local api2 = require("src.battle.gen2.BattleAPI").new(game2)
|
||||
@@ -179,6 +188,9 @@ check(snapshot2 and snapshot2.kind == "wild" and snapshot2.prompt == "menu",
|
||||
"Gold battle is discovered through its screen id")
|
||||
eq(snapshot2.player.maxHp, 21, "Gold max HP uses the mon field")
|
||||
eq(snapshot2.moves[1].name, "TACKLE", "Gold moves are copied")
|
||||
eq(#snapshot2.items, 1, "Gold exposes balls without guessing targeted items")
|
||||
eq(snapshot2.items[1].catchChance, 100,
|
||||
"Gold ball records expose the exact catch preview")
|
||||
snapshot2.player.hp = 0
|
||||
snapshot2.moves[1].pp = 0
|
||||
eq(player2.hp, 20, "changing a snapshot cannot change a Gold Pokemon")
|
||||
|
||||
@@ -166,6 +166,47 @@ eq(ri._requiredImported.importId, "source", "focus routes to the pending declara
|
||||
check(love.filesystem.getInfo("picked_required_import.bin") == nil,
|
||||
"focus removes the staged required-file pick")
|
||||
|
||||
-- Android releases with the updated launcher but the older native bridge do
|
||||
-- not advertise required_import. They still support the established ROM SAF
|
||||
-- picker, whose result must be quarantined to the pending dependency request.
|
||||
love.system.pickFileKinds = function() return "rom,mod,sav" end
|
||||
pickCalls = {}
|
||||
ri = freshImporter({ red = true, blue = true })
|
||||
ri.nativePicker = true
|
||||
ri.mobileFileBridge = true
|
||||
ri.mods = { {
|
||||
id = "needs_source",
|
||||
manifest = { id = "needs_source", name = "Needs Source",
|
||||
required_imports = { { id = "source", name = "Source", file = "source.bin",
|
||||
format = "raw", md5 = { "00000000000000000000000000000000" } } } },
|
||||
} }
|
||||
ri:chooseRequiredImport("needs_source", "source")
|
||||
eq(pickCalls[1], "rom", "legacy Android bridge falls back to its ROM SAF picker")
|
||||
check(ri.requiredImportLegacyRomPick,
|
||||
"legacy Android ROM picker result is marked as a required import")
|
||||
ri._importRequiredSource = function(self, modId, importId, source)
|
||||
self._requiredImported = { modId = modId, importId = importId, source = source }
|
||||
return true
|
||||
end
|
||||
love.filesystem.write("picked_rom.gb", "source bytes")
|
||||
ri:focus(true)
|
||||
eq(ri._requiredImported.source, "picked_rom.gb",
|
||||
"legacy Android ROM staging name is routed to the required import")
|
||||
eq(ri._requiredImported.modId, "needs_source",
|
||||
"legacy Android picker preserves the requested mod")
|
||||
check(love.filesystem.getInfo("picked_rom.gb") == nil,
|
||||
"legacy Android dependency pick is removed after import")
|
||||
|
||||
-- A legacy bridge reports a failed copy using that same staging basename; it
|
||||
-- must stay on the dependency page rather than becoming a game-ROM error.
|
||||
ri:chooseRequiredImport("needs_source", "source")
|
||||
love.filesystem.write("pick_error.flag", "picked_rom.gb")
|
||||
ri:focus(true)
|
||||
check(ri.modNotice ~= nil and ri.modNotice.ok == false,
|
||||
"legacy Android picker errors are shown as dependency import errors")
|
||||
check(ri.pickerPendingKind == nil,
|
||||
"legacy Android picker error clears the pending dependency request")
|
||||
|
||||
love.system.getOS = saved.getOS
|
||||
love.system.pickFile = saved.pickFile
|
||||
love.system.pickFileKinds = saved.pickFileKinds
|
||||
@@ -174,5 +215,6 @@ love.filesystem.remove("usb_mod.zip")
|
||||
love.filesystem.remove("picked_mod.zip")
|
||||
love.filesystem.remove("picked_save.sav")
|
||||
love.filesystem.remove("picked_required_import.bin")
|
||||
love.filesystem.remove("picked_rom.gb")
|
||||
|
||||
S.finish()
|
||||
|
||||
Reference in New Issue
Block a user