Files
gen1recomp/tests/drivers/gold_evolution_shots.lua
T
bryanthaboi ae6cac89e1 G2 support
2026-08-11 11:53:30 -04:00

100 lines
4.0 KiB
Lua

-- Contact sheet: the Gen 2 evolution animation, frame by frame.
--
-- POKEPORT_GAME=gold POKEPORT_DRIVER=tests/drivers/gold_evolution_shots.lua love .
--
-- Shoots src/ui/gen2/EvolutionAnim.lua into /tmp/gold-evo, one frame every few,
-- for a normal evolution and then for a B-cancelled one. A test can assert
-- that the flash loop ran eight rounds; only a picture says the two pics are
-- swapping in the same 7x7 box at hlcoord 7, 2, that the silhouette really is
-- PREDEFPAL_BLACKOUT, and that the new mon's colours land on the last swap.
--
-- POKEPORT_EVO_SPECIES / POKEPORT_EVO_LEVEL pick the mon (default: a level 16
-- CHIKORITA, the first evolution a Gold playthrough actually reaches).
-- POKEPORT_SHOT_INTERVAL is how many frames apart the shots are.
local U = require("tests.drivers.util")
local Evolution = require("src.core.gen2.Evolution")
local EvolutionAnim = require("src.ui.gen2.EvolutionAnim")
local Mon = require("src.battle.gen2.Mon")
-- Frames to give one evolution before calling it hung: 50 (EvolvingText) + 80
-- (MUSIC_EVOLUTION) + 144 (the flash loop) + 64 (balls of light) + the text
-- pages, with room to spare.
local FRAME_LIMIT = 900
return function(game)
local out = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/gold-evo"
local interval = tonumber(os.getenv("POKEPORT_SHOT_INTERVAL") or "4")
local species = os.getenv("POKEPORT_EVO_SPECIES") or "CHIKORITA"
local level = tonumber(os.getenv("POKEPORT_EVO_LEVEL") or "16")
U.wait(45)
local world = game.world
assert(world and world.map, "gold world did not boot")
local mon = Mon.new(game.data, species, level)
assert(mon, "could not build a level " .. level .. " " .. species)
-- The after-battle sweep's context: no link, no stone, and the clock's own
-- time of day for the TR_MORNDAY / TR_NITE rows.
local Palettes = require("src.world.gen2.Palettes")
local entry = Evolution.checkMon(game.data, mon,
{ timeOfDay = Palettes.clockDaytime() })
assert(entry, species .. " at level " .. level
.. " has no evolution to show -- pick another with POKEPORT_EVO_SPECIES")
print(("[driver] %s -> %s"):format(species, entry.into))
-- One run of the screen, shooting every `interval` frames. `cancelAt` is
-- the frame to tap B on, which .WaitFrames_CheckPressedB only honours during
-- a hold; nil runs it through to the end.
local function run(prefix, cancelAt)
game.save.party = { Mon.new(game.data, species, level) }
local finished = nil
local screen = EvolutionAnim.new(game, {
mon = game.save.party[1],
entry = entry,
index = 1,
party = game.save.party,
save = game.save,
onDone = function(result) finished = result end,
})
game.stack:push(screen)
local frame = 0
while not finished and frame < FRAME_LIMIT do
if frame % interval == 0 then
U.shot(game, ("%s/%s-%04d-%s.png"):format(out, prefix, frame,
screen.phase or "?"))
end
if cancelAt and frame == cancelAt then
U.tap(game, "b")
else
U.wait(1)
end
frame = frame + 1
end
assert(finished, prefix .. " never finished")
game.stack:pop()
print(("[driver] %-8s %d frames, canceled=%s, species now %s"):format(
prefix, frame, tostring(finished.canceled),
tostring(game.save.party[1].species)))
return finished
end
local full = run("evolve", nil)
assert(not full.canceled, "the uncancelled run reported a cancel")
assert(game.save.party[1].species == entry.into,
"the party slot did not take the new species")
-- B during the very first hold, which is the 16 frames after the 50 + 80 of
-- text and music: .cancel_evo leaves the OLD pic on screen and prints
-- StoppedEvolvingText.
local canceled = run("cancel",
Evolution.EVOLVING_FRAMES + Evolution.MUSIC_FRAMES + 4)
assert(canceled.canceled, "the B press did not cancel the evolution")
assert(game.save.party[1].species == species,
"a cancelled evolution changed the species anyway")
print("[driver] PASS gold evolution in " .. out)
love.event.quit()
end