mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
165 lines
6.2 KiB
Lua
165 lines
6.2 KiB
Lua
-- ../pokecrystal/engine/pokemon/mon_menu.asm:724 MonMenu_Softboiled_MilkDrink
|
|
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
|
|
local T = require("tests.harness")
|
|
local check, eq = T.check, T.eq
|
|
love = love or require("tests.love_stub")
|
|
|
|
local FieldMoves = require("src.world.gen2.FieldMoves")
|
|
local PartyMenu = require("src.ui.gen2.PartyMenu")
|
|
|
|
local function mon(maxHp, hp, extra)
|
|
local m = { species = "CHANSEY", nickname = "CHANSEY",
|
|
stats = { hp = maxHp }, hp = hp }
|
|
for k, v in pairs(extra or {}) do m[k] = v end
|
|
return m
|
|
end
|
|
|
|
-- ../pokecrystal/data/mon_menu.asm MonMenuOptions
|
|
do
|
|
local missing = {}
|
|
for _, id in ipairs(PartyMenu.FIELD_MOVES) do
|
|
if not FieldMoves.FROM_MENU[id] then missing[#missing + 1] = id end
|
|
end
|
|
eq(table.concat(missing, ","), "",
|
|
"every MonMenuOptions row has a from-menu routine")
|
|
check(FieldMoves.FROM_MENU.SOFTBOILED, "SOFTBOILED has one")
|
|
check(FieldMoves.FROM_MENU.MILK_DRINK, "MILK_DRINK shares it")
|
|
end
|
|
|
|
-- ../pokecrystal/engine/events/overworld.asm:1317 TryRockSmashFromMenu
|
|
do
|
|
local rock = { def = { index = 2, movement = 0x18 } }
|
|
local nothing = FieldMoves.fromMenu("ROCK_SMASH", {})
|
|
check(not nothing.ok, "nothing faced is .no_rock")
|
|
eq(nothing.text, FieldMoves.TEXT.CANT_USE_HERE, "with FieldMoveFailed's line")
|
|
|
|
local person = FieldMoves.fromMenu("ROCK_SMASH",
|
|
{ facingObject = { def = { index = 1, movement = 0x06 } } })
|
|
check(not person.ok, "a standing NPC is not SPRITEMOVEDATA_SMASHABLE_ROCK")
|
|
|
|
local ok = FieldMoves.fromMenu("ROCK_SMASH", { facingObject = rock })
|
|
check(ok.ok, "the rock in front of the player is")
|
|
eq(ok.action, "rocksmash", "and the menu queues the smash")
|
|
eq(ok.lastTalked, 3, "hLastTalked is the object const, index + 1")
|
|
end
|
|
|
|
-- ../pokecrystal/engine/events/overworld.asm:1357 RockSmashFromMenuScript
|
|
do
|
|
local std = { scripts = { SmashRockScript = { key = "40:4158" } } }
|
|
local scripts = {
|
|
["40:4158"] = { { op = "farsjump", script = "03:4f60" } },
|
|
["03:4f60"] = {
|
|
{ op = "callasm" },
|
|
{ op = "ifequal", script = "03:4f72", value = 1 },
|
|
{ op = "opentext" },
|
|
{ op = "writetext", text = "03:4f7a" },
|
|
{ op = "yesorno" },
|
|
{ op = "iftrue", script = "03:4f35" },
|
|
{ op = "closetext" },
|
|
{ op = "end" },
|
|
},
|
|
}
|
|
eq(FieldMoves.rockSmashScriptKey(std, scripts), "03:4f35",
|
|
"AskRockSmashScript's iftrue target is RockSmashScript")
|
|
eq(FieldMoves.rockSmashScriptKey(std, {}), nil, "an absent chain is nil")
|
|
|
|
local script = FieldMoves.rockSmashFromMenuScript(std, scripts,
|
|
function(name) return name == "UpdateTimePals" and 7 or nil end)
|
|
eq(#script, 3, "refreshmap, special UpdateTimePals, then the fallthrough")
|
|
eq(script[1].op, "refreshmap", "refreshmap first")
|
|
eq(script[2].id, 7, "UpdateTimePals resolved through the cache's order")
|
|
eq(script[3].op, "sjump", "and RockSmashScript is entered without the ask")
|
|
eq(script[3].script, "03:4f35", "at the key the chain resolved")
|
|
eq(FieldMoves.rockSmashFromMenuScript(std, {}, function() return 7 end), nil,
|
|
"no key, no queued script")
|
|
end
|
|
|
|
-- ../pokecrystal/engine/pokemon/mon_menu.asm:744 .CheckMonHasEnoughHP
|
|
do
|
|
local refused = FieldMoves.softboiledFromMenu({ mon = mon(100, 20) })
|
|
check(not refused.ok, "exactly a fifth left is refused")
|
|
eq(refused.text, FieldMoves.TEXT.NOT_ENOUGH_HP, "with _PokemonNotEnoughHPText")
|
|
|
|
local ok = FieldMoves.softboiledFromMenu({ mon = mon(100, 21) })
|
|
check(ok.ok, "one HP more is allowed")
|
|
eq(ok.cost, 20, "and the transfer is the USER's maxHP/5")
|
|
check(ok.inMenu, "the $3 return keeps the party list up")
|
|
eq(ok.action, "softboiled", "the action names itself")
|
|
end
|
|
|
|
-- ../pokecrystal/engine/items/item_effects.asm:2043 .cant_use
|
|
do
|
|
local user = mon(100, 60)
|
|
eq(FieldMoves.softboiledTargetOk(user, user), false, "the user is no target")
|
|
eq(FieldMoves.softboiledTargetOk(user, mon(50, 50)), false,
|
|
"nor is a full-health mon")
|
|
eq(FieldMoves.softboiledTargetOk(user, mon(50, 0)), false,
|
|
"nor a fainted one")
|
|
eq(FieldMoves.softboiledTargetOk(user, mon(50, 10, { isEgg = true })), false,
|
|
"nor an EGG")
|
|
eq(FieldMoves.softboiledTargetOk(user, mon(50, 10)), true,
|
|
"a hurt teammate is")
|
|
end
|
|
|
|
-- ../pokecrystal/engine/items/item_effects.asm:1997 RemoveHP / :2005 RestoreHealth
|
|
do
|
|
local user, target = mon(100, 60), mon(50, 10)
|
|
local before, after = FieldMoves.softboiledTransfer(user, target, 20)
|
|
eq(before, 10, "the recipient's HP before")
|
|
eq(after, 30, "and after the user's fifth landed")
|
|
eq(user.hp, 40, "the user paid its own fifth")
|
|
|
|
local capped = mon(50, 45)
|
|
local b2, a2 = FieldMoves.softboiledTransfer(user, capped, 20)
|
|
eq(b2, 45, "a nearly full mon still takes it")
|
|
eq(a2, 50, "capped at max HP")
|
|
|
|
local refused = FieldMoves.softboiledTransfer(user, user, 20)
|
|
eq(refused, nil, "a refused transfer spends nothing")
|
|
eq(user.hp, 20, "so the user's HP is untouched by it")
|
|
end
|
|
|
|
-- ../pokecrystal/engine/items/item_effects.asm:1999 HealHP_SFX_GFX
|
|
do
|
|
local input = { pressed = {} }
|
|
function input:wasPressed(button)
|
|
if self.pressed[button] then
|
|
self.pressed[button] = nil
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
function input:isDown() return false end
|
|
|
|
local party = {
|
|
mon(100, 60),
|
|
mon(50, 10, { species = "GEODUDE", nickname = "GEODUDE" }),
|
|
}
|
|
local game = { data = { gen2MenuGfx = {} }, input = input,
|
|
save = { party = party } }
|
|
local menu = PartyMenu.new(game, { party = party, prompt = "useItem" })
|
|
menu:beginSoftboiled(1, 20)
|
|
menu.index = 2
|
|
menu:finishSoftboiled()
|
|
|
|
eq(menu.itemResult.slot, 1, "the user's own bar drops first")
|
|
eq(menu:shownHpFor(1, party[1]), 60, "starting at its pre-cost HP")
|
|
eq(menu:shownHpFor(2, party[2]), 10,
|
|
"with the recipient still frozen at its own")
|
|
eq(menu.itemResult.text, nil, "and nothing printed over it")
|
|
|
|
for _ = 1, 60 do
|
|
if menu.itemResult and menu.itemResult.slot == 2 then break end
|
|
menu:update(1 / 60)
|
|
end
|
|
eq(menu.itemResult.slot, 2, "then the recipient's climb takes over")
|
|
eq(menu.itemResult.shown, 10, "from its pre-heal HP")
|
|
eq(menu:shownHpFor(1, party[1]), 40, "the user reads the paid-down HP now")
|
|
eq(menu.itemResult.text, "GEODUDE\nrecovered 20HP!",
|
|
"and _RecoveredSomeHPText arrives with the climb")
|
|
end
|
|
|
|
T.finish("gen2 softboiled field bug2041")
|