mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 16:31:05 +02:00
154 lines
5.1 KiB
Lua
154 lines
5.1 KiB
Lua
-- A level-up evolution survives the B held from the level-up box (#968, #1031); a fresh press still cancels (#290, #213).
|
|
-- pokered engine/movie/evolution.asm EvolveMon, Evolution_CheckForCancel.
|
|
|
|
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")
|
|
|
|
-- TextBox and EvolutionState both require Sound inside update, so seeding
|
|
package.loaded["src.core.Sound"] = {
|
|
play = function() end,
|
|
playCry = function() end,
|
|
}
|
|
|
|
local Fixtures = require("tests.modkit.fixtures")
|
|
local Evolution = require("src.pokemon.Evolution")
|
|
local EvolutionState = require("src.ui.EvolutionState")
|
|
local Input = require("src.core.Input")
|
|
local Pokemon = require("src.pokemon.Pokemon")
|
|
local StateStack = require("src.core.StateStack")
|
|
local TextBox = require("src.render.TextBox")
|
|
|
|
local Data = Fixtures.fresh()
|
|
require("src.render.Font").load(Data)
|
|
|
|
-- FIXMON_A evolves into FIXMON_B at 16 (tests/fixture_data/pokemon.lua)
|
|
local EVO_LEVEL = 16
|
|
-- x is the default keyboard B (src/core/Input.lua DEFAULT_BINDINGS)
|
|
local B_KEY = "x"
|
|
|
|
local function newGame()
|
|
local game = { data = Data }
|
|
local mon = Pokemon.new(Data, "FIXMON_A", EVO_LEVEL)
|
|
game.save = {
|
|
party = { mon },
|
|
player = { name = "RED", id = 1 },
|
|
options = { textSpeed = 5 },
|
|
flags = {},
|
|
pokedex = { seen = {}, owned = {} },
|
|
}
|
|
game.stack = setmetatable({}, { __index = StateStack })
|
|
game.stack:init()
|
|
game.input = Input
|
|
Input:init()
|
|
return game, mon
|
|
end
|
|
|
|
-- one fixed step, in Game:step's order: promote the queued edges, then
|
|
local function step(game)
|
|
game.input:step()
|
|
game.stack:update(1 / 60)
|
|
end
|
|
|
|
-- the post-battle sequence: grew-to-level box, then Evolution.checkParty
|
|
local function levelUpBox(game, mon)
|
|
game.stack:push(TextBox.new(game, "FIXMON A grew\nto level 16!",
|
|
function() Evolution.checkParty(game, nil, { [mon] = true }) end))
|
|
end
|
|
|
|
-- one B edge on the box, still held when the movie takes over: the bug's handoff
|
|
local function dismissWithB(game, mon)
|
|
levelUpBox(game, mon)
|
|
local box = game.stack:top()
|
|
for _ = 1, 900 do
|
|
if box.done then break end
|
|
step(game)
|
|
end
|
|
if not box.done then return nil, "the level-up text never finished typing" end
|
|
Input:keypressed(B_KEY)
|
|
step(game)
|
|
local top = game.stack:top()
|
|
if getmetatable(top) ~= EvolutionState then
|
|
return nil, "the evolution screen never opened"
|
|
end
|
|
return top
|
|
end
|
|
|
|
local function textOf(box)
|
|
local out = {}
|
|
for _, page in ipairs(box.pages) do
|
|
for _, line in ipairs(page) do out[#out + 1] = line end
|
|
end
|
|
return table.concat(out, " ")
|
|
end
|
|
|
|
-- B held out of the text box: the movie must run to the end and evolve.
|
|
do
|
|
local game, mon = newGame()
|
|
local evo, why = dismissWithB(game, mon)
|
|
if check(evo ~= nil, "the level-up box handed off to the movie: " .. tostring(why)) then
|
|
check(Input:isDown("b"),
|
|
"B is still physically down as the movie starts, which is what "
|
|
.. "the old isDown poll cancelled on")
|
|
eq(evo.cancelable, true,
|
|
"and this is a cancelable level-up evolution, so the movie really "
|
|
.. "is reading the button (#290)")
|
|
-- never released: no second edge ever reaches the movie
|
|
for _ = 1, 400 do
|
|
if evo.done then break end
|
|
step(game)
|
|
end
|
|
check(Input:isDown("b"), "B was held for the whole movie")
|
|
eq(evo.canceled, false, "the held B did not cancel the evolution")
|
|
eq(mon.species, "FIXMON_B", "the mon actually evolved")
|
|
eq(mon.stats.hp, require("src.pokemon.Stats")
|
|
.calc(Data.pokemon.FIXMON_B, EVO_LEVEL, mon.dvs, mon.statExp).hp,
|
|
"and Evolution.apply recalculated its stats on the new species")
|
|
local top = game.stack:top()
|
|
check(getmetatable(top) == TextBox and textOf(top):find("evolved into"),
|
|
"the congratulations text is what closes the movie")
|
|
end
|
|
end
|
|
|
|
-- A deliberate fresh press after the 80-frame delay still cancels.
|
|
do
|
|
local game, mon = newGame()
|
|
local evo = assert(dismissWithB(game, mon))
|
|
Input:keyreleased(B_KEY)
|
|
for _ = 1, 400 do
|
|
if evo.t > 80 then break end
|
|
step(game)
|
|
end
|
|
check(evo.t > 80 and not evo.done,
|
|
"the movie is past the DelayFrames window and still running")
|
|
Input:keypressed(B_KEY)
|
|
step(game)
|
|
eq(evo.canceled, true, "a fresh B press cancels the evolution (#213)")
|
|
eq(mon.species, "FIXMON_A", "and the mon keeps its species")
|
|
local top = game.stack:top()
|
|
check(getmetatable(top) == TextBox and textOf(top):find("stopped evolving"),
|
|
"_StoppedEvolvingText prints instead of the congratulations")
|
|
end
|
|
|
|
-- A press inside the 80 frames is not polled at all, so the mon still
|
|
do
|
|
local game, mon = newGame()
|
|
local evo = assert(dismissWithB(game, mon))
|
|
Input:keyreleased(B_KEY)
|
|
for _ = 1, 10 do step(game) end
|
|
Input:keypressed(B_KEY)
|
|
step(game)
|
|
Input:keyreleased(B_KEY)
|
|
check(evo.t <= 80, "the press landed inside the delay window")
|
|
eq(evo.canceled, false, "a B press during the delay is never polled")
|
|
for _ = 1, 400 do
|
|
if evo.done then break end
|
|
step(game)
|
|
end
|
|
eq(mon.species, "FIXMON_B", "so the evolution still completes")
|
|
end
|
|
|
|
T.finish()
|