mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
173 lines
5.8 KiB
Lua
173 lines
5.8 KiB
Lua
-- ../pokecrystal/engine/battle/battle_transition.asm:584
|
|
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
|
|
love = require("tests.love_stub")
|
|
|
|
local T = require("tests.harness")
|
|
local Transition = require("src.ui.gen2.BattleTransition")
|
|
local World = require("src.world.gen2.World")
|
|
|
|
local ballCalls = 0
|
|
local realCells = Transition.pokeballCells
|
|
Transition.pokeballCells = function(...)
|
|
ballCalls = ballCalls + 1
|
|
return realCells(...)
|
|
end
|
|
|
|
local function fakeWorld()
|
|
local world = {
|
|
map = { id = "NEW_BARK_TOWN", def = {} }, daytime = "DAY",
|
|
npcs = {}, ghosts = {}, log = {},
|
|
}
|
|
function world:gbScreenOrigin() return 0, 0 end
|
|
function world:fitScale() return 1 end
|
|
function world:zoomScale() return 1 end
|
|
function world:drawGround() self.log[#self.log + 1] = "ground" end
|
|
function world:drawPeople() self.log[#self.log + 1] = "people" end
|
|
world.drawWorldBody = World.drawWorldBody
|
|
function world:draw() self:drawWorldBody(1) end
|
|
return world
|
|
end
|
|
|
|
local function make(opts)
|
|
opts.environment = opts.environment or "TOWN"
|
|
local world = fakeWorld()
|
|
opts.world = world
|
|
local state = Transition.new(nil, opts)
|
|
local inner = world.bgOverlay
|
|
if inner then
|
|
world.bgOverlay = function(s)
|
|
world.log[#world.log + 1] = world.peopleHidden and "bgonly" or "overlay"
|
|
inner(s)
|
|
end
|
|
end
|
|
return state, world
|
|
end
|
|
|
|
local function frame(state)
|
|
local world = state.world
|
|
world.log = {}
|
|
ballCalls = 0
|
|
state:drawWidescreen(160, 144)
|
|
local seq = table.concat(world.log, ",")
|
|
local layered = seq:find("ground,overlay,people", 1, true) ~= nil
|
|
return layered, ballCalls > 0, seq
|
|
end
|
|
|
|
local function pastBall(state)
|
|
state:update()
|
|
state:update()
|
|
end
|
|
|
|
do
|
|
local cells = Transition.pokeballCells()
|
|
T.eq(#cells, 112, ".PokeBallTransition sets 112 bits")
|
|
local minX, minY, maxY = 20, 18, -1
|
|
for _, cell in ipairs(cells) do
|
|
minX = math.min(minX, cell[1])
|
|
minY = math.min(minY, cell[2])
|
|
maxY = math.max(maxY, cell[2])
|
|
end
|
|
T.eq(minX, Transition.POKEBALL_X, "the stamp starts at hlcoord 2, 1 (x)")
|
|
T.eq(minY, Transition.POKEBALL_Y, "the stamp starts at hlcoord 2, 1 (y)")
|
|
T.eq(maxY - minY + 1, 16, "and it is sixteen rows tall")
|
|
end
|
|
|
|
do
|
|
local state, world = make({ trainer = true })
|
|
T.eq(state.phase, "pokeball", "a trainer battle stamps the ball first")
|
|
T.check(world.bgOverlay ~= nil, "the ball is BG content: an overlay seam")
|
|
local layered, ball, seq = frame(state)
|
|
T.check(layered, "drawn between the ground and the people: " .. seq)
|
|
T.check(ball, "and it is the ball that is painted there")
|
|
state:update()
|
|
T.eq(state.phase, "pokeball", "two frames of ball before the flash")
|
|
T.check((frame(state)), "...both with the ball under the sprites")
|
|
|
|
state:update()
|
|
T.eq(state.phase, "flash", "then the flash starts")
|
|
local seen = 0
|
|
for _ = 1, Transition.FLASH_FRAMES do
|
|
local l, b = frame(state)
|
|
if l and b then seen = seen + 1 end
|
|
state:update()
|
|
end
|
|
T.eq(seen, Transition.FLASH_FRAMES,
|
|
"the ball is still in the tilemap for every flash frame")
|
|
T.eq(state.phase, "outro", "the flash hands off to the outro")
|
|
|
|
local drawn, missed, guard = 0, 0, 0
|
|
local filtered = 0
|
|
while state.phase == "outro" and guard < 400 do
|
|
local l, b = frame(state)
|
|
if l and b then drawn = drawn + 1 else missed = missed + 1 end
|
|
if world.spriteFilter then filtered = filtered + 1 end
|
|
state:update()
|
|
guard = guard + 1
|
|
end
|
|
T.check(drawn > 0, "and the outro paints over a ball that is still there")
|
|
T.eq(missed, 0, "no outro frame drops it early")
|
|
T.eq(filtered, drawn - 1,
|
|
"RespawnPlayerAndOpponent hides the bystanders from the second outro frame")
|
|
T.eq(state.phase, "black", "the outro ends on the black hold")
|
|
local l, b, blackSeq = frame(state)
|
|
T.eq(blackSeq, "", "which is solid black, ball included")
|
|
T.eq(l or b, false, "...no world draw at all")
|
|
|
|
while not state.finished do state:update() end
|
|
T.eq(world.bgOverlay, nil, "finish takes the seam back down")
|
|
T.eq(world.spriteFilter, nil, "...and the sprite filter with it")
|
|
end
|
|
|
|
do
|
|
local state, world = make({ trainer = false })
|
|
T.eq(state.phase, "flash", "a wild battle has no ball to stamp")
|
|
local drew, guard = false, 0
|
|
while not state.finished and guard < 400 do
|
|
local _, b = frame(state)
|
|
if b then drew = true end
|
|
state:update()
|
|
guard = guard + 1
|
|
end
|
|
T.eq(drew, false, "and never draws one")
|
|
T.eq(world.bgOverlay, nil, "the seam still comes down at the end")
|
|
end
|
|
|
|
do
|
|
local state = make({ trainer = true, dark = true })
|
|
T.eq(state.phase, "pokeball", "a DARKNESS trainer battle still stamps it")
|
|
pastBall(state)
|
|
T.eq(state.phase, "flash", "DARKNESS still walks the three Flash slots")
|
|
T.eq(state:flashPal(), nil, "...each returning on its first frame")
|
|
T.check((frame(state)), "...with the ball still on screen")
|
|
for _ = 1, Transition.FLASH_CYCLES do state:update() end
|
|
T.eq(state.phase, "outro", "...one frame per slot, then the outro")
|
|
end
|
|
|
|
do
|
|
local state, world = make({
|
|
trainer = true, environment = "CAVE", playerLevel = 10, enemyLevel = 5,
|
|
})
|
|
T.eq(state.style, "sine", "a cave trainer battle wobbles")
|
|
pastBall(state)
|
|
local guard = 0
|
|
while state.phase == "flash" and guard < 400 do
|
|
state:update()
|
|
guard = guard + 1
|
|
end
|
|
T.eq(state:lyOverrides(), nil, "NextScene: no wave yet")
|
|
state:update()
|
|
T.eq(state:lyOverrides(), nil, "SetUpForWavyOutro: still flat")
|
|
state:update()
|
|
T.check(state:lyOverrides() ~= nil, "SineWave from the third outro frame")
|
|
state.quad = { setViewport = function() end }
|
|
local layered, ball, seq = frame(state)
|
|
T.check(ball, "the ball rides the sine outro")
|
|
T.eq(seq, "ground,bgonly,people",
|
|
"the BG is captured without the people, who are drawn flat after")
|
|
T.eq(world.peopleHidden, nil, "and the people flag is not left set")
|
|
end
|
|
|
|
T.finish("gen2 trainer ball lifetime bug 2021")
|