Files
gen1recomp/tests/engine/evolution_double_after_battle_bug2664.lua
T

165 lines
5.2 KiB
Lua

-- engine/pokemon/evos_moves.asm:156
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")
package.loaded["src.core.Sound"] = {
play = function() end,
playCry = function() end,
playPress = function() end,
stopLoop = function() end,
}
local Fixtures = require("tests.modkit.fixtures")
local Music = require("src.core.Music")
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)
local restores = 0
Music.restoreMap = function() restores = restores + 1 end
local A_KEY, B_KEY = "z", "x"
local function newGame(count)
local game = { data = Data }
local party = {}
for i = 1, count do party[i] = Pokemon.new(Data, "FIXMON_A", 16) end
game.save = {
party = party,
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()
local under = { isOpaque = true, update = function() end, draw = function() end }
game.stack:push(under)
return game, party, under
end
local function step(game, key)
if key then Input:keypressed(key) end
game.input:step()
game.stack:update(1 / 60)
if key then Input:keyreleased(key) end
end
local function indexOf(game, state)
for i, s in ipairs(game.stack.states) do
if s == state then return i end
end
end
local function leftovers(game)
local n = 0
for _, s in ipairs(game.stack.states) do
if s.evoClear or s.evoIntro or getmetatable(s) == EvolutionState then
n = n + 1
end
end
return n
end
local function runBatch(cancelFirst)
local game, party, battle = newGame(2)
restores = 0
local finished = false
local leveled = { [party[1]] = true, [party[2]] = true }
Evolution.checkParty(game, function() finished = true end, leveled)
local intros, seen = 0, {}
local secondIntro
local restoresBeforeSecond
for frame = 1, 6000 do
if finished then break end
local top = game.stack:top()
if top and top.evoIntro and not seen[top] then
seen[top] = true
intros = intros + 1
if intros == 2 then
secondIntro = {
below = game.stack.states[indexOf(game, top) - 1],
base = game.stack:visibleBase(),
battleAt = indexOf(game, battle),
}
restoresBeforeSecond = restores
end
end
local key = A_KEY
if cancelFirst and intros == 1 and getmetatable(top) == EvolutionState
and top.t > 100 and not top.done then
key = B_KEY
elseif frame % 2 == 0 then
key = nil
end
step(game, key)
end
return {
game = game, party = party, battle = battle, finished = finished,
intros = intros, second = secondIntro,
restoresBeforeSecond = restoresBeforeSecond,
}
end
for _, cancelFirst in ipairs({ false, true }) do
local label = cancelFirst and "cancelled first mon" or "two evolutions"
local r = runBatch(cancelFirst)
eq(r.intros, 2, label .. ": both mons get an IsEvolvingText box")
if check(r.second ~= nil, label .. ": the second intro box went up") then
check(r.second.below and r.second.below.evoClear and r.second.below.isOpaque,
label .. ": the second intro draws over an opaque blank screen")
check(r.second.base > r.second.battleAt,
label .. ": the battle screen is not drawn under the second intro")
eq(r.restoresBeforeSecond, 0,
label .. ": no map music between the two evolutions")
end
check(r.finished, label .. ": the batch finished")
eq(r.game.stack:top(), r.battle, label .. ": the battle is top again")
eq(leftovers(r.game), 0, label .. ": no evolution layers are left")
eq(restores, 0, label .. ": the in-battle batch never restores map music")
eq(r.party[2].species, "FIXMON_B", label .. ": the second mon evolved")
eq(r.party[1].species, cancelFirst and "FIXMON_A" or "FIXMON_B",
label .. ": the first mon's species")
end
for _, via in ipairs({ "ITEM", "TRADE" }) do
local game, party, menu = newGame(1)
restores = 0
local finished, topAtDone = false, nil
Evolution.evolve(game, party[1], "FIXMON_B", function()
finished = true
topAtDone = game.stack:top()
end, via)
local sawClear = false
local realClear = Evolution.clearScreen
Evolution.clearScreen = function(g, species)
realClear(g, species)
local top = g.stack:top()
if top and top.evoClear and top.isOpaque then sawClear = true end
end
for frame = 1, 6000 do
if finished then break end
step(game, frame % 2 == 1 and A_KEY or nil)
end
check(finished, via .. ": the single evolution finished")
eq(topAtDone, menu, via .. ": the caller's screen is top when onDone runs")
eq(leftovers(game), 0, via .. ": no evolution layers are left")
eq(restores, 1, via .. ": map music comes back once after the result box")
Evolution.clearScreen = realClear
check(sawClear, via .. ": the screen clears once the result box closes")
end
T.finish()