mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
149 lines
4.8 KiB
Lua
149 lines
4.8 KiB
Lua
-- engine/items/item_effects.asm:1226-1238, engine/menus/party_menu.asm:8-13
|
|
-- engine/menus/start_sub_menus.asm:285-295, home/window.asm:119
|
|
-- Self-contained; run via `luajit tests/parity_party_cursor_erase.lua`.
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
if not _G.love then _G.love = require("tests.love_stub") end
|
|
local S = require("tests.harness").suite("parity party cursor erase")
|
|
local check, eq = S.check, S.eq
|
|
|
|
local Data = require("src.core.Data")
|
|
Data:load()
|
|
|
|
local Pokemon = require("src.pokemon.Pokemon")
|
|
local Bag = require("src.inventory.Bag")
|
|
|
|
local realTextBox = package.loaded["src.render.TextBox"]
|
|
local realBag = package.loaded["src.ui.BagMenu"]
|
|
local realParty = package.loaded["src.ui.PartyMenu"]
|
|
local soundOpts = require("src.render.TextBox").soundOpts
|
|
package.loaded["src.render.TextBox"] = {
|
|
new = function(_, text, done) return { textBox = true, text = text, done = done } end,
|
|
soundOpts = soundOpts,
|
|
}
|
|
package.loaded["src.ui.BagMenu"] = nil
|
|
package.loaded["src.ui.PartyMenu"] = nil
|
|
local BagMenu = require("src.ui.BagMenu")
|
|
local PartyMenu = require("src.ui.PartyMenu")
|
|
require("src.ui.Screens").invalidate()
|
|
|
|
local function newStack()
|
|
local stack = { states = {} }
|
|
function stack:push(s) self.states[#self.states + 1] = s end
|
|
function stack:pop() return table.remove(self.states) end
|
|
function stack:top() return self.states[#self.states] end
|
|
return stack
|
|
end
|
|
|
|
local function newInput()
|
|
local input = { pressed = nil }
|
|
function input:wasPressed(b) return self.pressed == b end
|
|
return input
|
|
end
|
|
|
|
local function freshGame(hp)
|
|
local lead = Pokemon.new(Data, "CHARIZARD", 50)
|
|
lead.hp = hp
|
|
local game = {
|
|
data = Data,
|
|
stack = newStack(),
|
|
input = newInput(),
|
|
save = {
|
|
party = { lead },
|
|
player = { name = "RED" },
|
|
inventory = {},
|
|
options = { battleStyle = "set", battleAnim = "on" },
|
|
pokedex = { seen = {}, owned = {} },
|
|
flags = {},
|
|
money = 0,
|
|
},
|
|
}
|
|
Bag.add(game.save, "POTION", 5)
|
|
return game, lead
|
|
end
|
|
|
|
local function isPicker(s) return getmetatable(s) == PartyMenu end
|
|
local function isBox(s) return type(s) == "table" and s.textBox == true end
|
|
|
|
local function rowFor(list, id)
|
|
for i, r in ipairs(list.items) do
|
|
if r.value == id then return i end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
local function usePotion(game, list)
|
|
local row = rowFor(list, "POTION")
|
|
if not row then return nil, "no POTION row in the bag" end
|
|
list.index = row
|
|
list.onChoose(list.items[row], list)
|
|
local sub = game.stack:top()
|
|
if sub and sub.items and sub.items[1] and sub.items[1].onSelect then
|
|
game.stack:pop()
|
|
sub.items[1].onSelect()
|
|
end
|
|
local picker = game.stack:top()
|
|
if not isPicker(picker) then return nil, "party picker never opened" end
|
|
game.input.pressed = "a"
|
|
picker:update(1 / 60)
|
|
game.input.pressed = nil
|
|
return picker
|
|
end
|
|
|
|
do
|
|
local game, lead = freshGame(1)
|
|
local list = BagMenu.new(game, {})
|
|
game.stack:push(list)
|
|
|
|
local picker, why = usePotion(game, list)
|
|
check(isPicker(picker), "the party picker opened for POTION" ..
|
|
(why and (" (" .. why .. ")") or ""))
|
|
check(type(picker.heal) == "table", "UpdateHPBar2's fill is running")
|
|
check(picker.cursorsErased ~= true, "the cursor is still drawn while the bar fills")
|
|
|
|
local frames = 0
|
|
while picker.heal and frames < 400 do
|
|
picker:update(1 / 60)
|
|
frames = frames + 1
|
|
end
|
|
check(frames > 1 and frames < 400, "the fill landed")
|
|
eq(lead.hp, 21, "the POTION restored 20 HP")
|
|
|
|
local box = game.stack:top()
|
|
check(isBox(box), "the message box opened over the picker")
|
|
check(isPicker(game.stack.states[2]), "the party menu is still the backdrop")
|
|
check(picker.cursorsErased == true,
|
|
"the menu cursor is erased while the message prints (#2062)")
|
|
|
|
picker:update(1 / 60)
|
|
check(picker.cursorsErased == nil,
|
|
"the cursor comes back the frame the picker reads input again")
|
|
end
|
|
|
|
do
|
|
local game, lead = freshGame(nil)
|
|
lead.hp = lead.stats.hp
|
|
local list = BagMenu.new(game, {})
|
|
game.stack:push(list)
|
|
|
|
local picker = usePotion(game, list)
|
|
check(isPicker(picker), "the picker opened for the full-HP mon")
|
|
check(picker.heal == nil, "no fill for a refusal")
|
|
check(isBox(game.stack:top()), "the no-effect message opened")
|
|
check(picker.cursorsErased ~= true,
|
|
"the refusal leaves the cursor alone (ItemUseNoEffect, no RedrawPartyMenu)")
|
|
eq(game.save.inventory.POTION, 5, "and the POTION was not consumed")
|
|
end
|
|
|
|
do
|
|
local game = freshGame(10)
|
|
local picker = PartyMenu.new(game, { pickOnly = true })
|
|
check(type(picker.eraseCursors) == "function", "PartyMenu:eraseCursors exists")
|
|
check(picker.cursorsErased == nil, "a fresh picker draws its cursor")
|
|
end
|
|
|
|
package.loaded["src.render.TextBox"] = realTextBox
|
|
package.loaded["src.ui.BagMenu"] = realBag
|
|
package.loaded["src.ui.PartyMenu"] = realParty
|
|
require("src.ui.Screens").invalidate()
|
|
S.finish()
|