Files
gen1recomp/tests/drivers/em_warp_effects.lua
T
bryanthaboi 690f0cd9a1 TOUCHDOWN
2026-09-27 16:07:31 -04:00

173 lines
6.8 KiB
Lua

local U = require("tests.drivers.util")
local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/em_warp_effects"
local failures = 0
local function check(ok, label)
print((ok and "PASS " or "FAIL ") .. label)
if not ok then failures = failures + 1 end
return ok
end
local function finish()
print((failures == 0 and "PASS" or "FAIL") .. " em_warp_effects failures=" .. failures)
love.event.quit(failures == 0 and 0 or 1)
end
return function(game)
for _ = 1, 900 do
if game.phase == "boot" and game.boot then break end
U.wait(1)
end
if not check(game.boot ~= nil, "boot reached") then return finish() end
game:_handleBootAction({ action = "new_game", name = "BRENDAN", gender = 0 })
U.wait(60)
local Runtime = require("src.core.game3.runtime")
local Map = require("src.core.game3.map")
local Player = require("src.core.game3.player")
local Warp = require("src.core.game3.warp")
local Message = require("src.ui.game3.message")
local Space = require("src.core.game3.scripting.space")
local Collision = require("src.core.game3.collision")
local Field = require("src.core.game3.field")
local MB = require("src.core.game3.mb")
local Audio = require("src.core.game3.audio")
local SE = require("src.core.game3.se_ids")
local session = Runtime.getSession()
if not check(session ~= nil, "field session exists") then return finish() end
local playedSe = {}
local origPlaySe = Audio.playSe
Audio.playSe = function(id, ...)
playedSe[#playedSe + 1] = SE.resolve(id)
return origPlaySe(id, ...)
end
local function sawSe(name)
for _, v in ipairs(playedSe) do if v == SE[name] then return true end end
return false
end
local function mapNow() local s = Runtime.getSession(); return s and s.map end
local function idle()
return not Warp.isBusy() and not Field.locked and not (Space.vm and Space.vm:isRunning())
and not (Message.isOpen and Message.isOpen())
end
local function settle(frames)
for _ = 1, frames or 900 do
if idle() then return true end
if Message.isOpen and Message.isOpen() then U.tap(game, "b") end
U.wait(1)
end
return idle()
end
local function place(mapId, x, y, facing)
settle()
Map.load(nil, game, mapId, { x = x, y = y, facing = facing or "down" })
local s = Runtime.getSession()
s.x, s.y, s.facing = x, y, facing or "down"
Field.unlock()
U.wait(20)
settle()
end
local DIRS = { { 0, 1, "up" }, { 0, -1, "down" }, { 1, 0, "left" }, { -1, 0, "right" } }
local function warpWithBehavior(mapId, behName)
place(mapId, 1, 1)
local def = Map.currentDef()
for _, w in ipairs(def and def.warps or {}) do
local x, y = tonumber(w.x), tonumber(w.y)
if Collision.behavior(x, y) == MB.id(behName) then
for _, d in ipairs(DIRS) do
local ax, ay = x + d[1], y + d[2]
if Collision.isWalkable(ax, ay) and Collision.behavior(ax, ay) ~= MB.id(behName) then
return x, y, ax, ay, d[3]
end
end
end
end
return nil
end
local function stepOnto(mapId, behName, label)
local wx, wy, ax, ay, dir = warpWithBehavior(mapId, behName)
if not check(wx ~= nil, label .. ": warp cell with " .. behName) then return nil end
place(mapId, ax, ay, dir)
playedSe = {}
local fromMap = mapNow()
U.hold(game, dir, 16)
local sawInvisible, sawOffset, sawPan = false, false, false
for _ = 1, 1200 do
if not Player.isVisible() then sawInvisible = true end
if (Player.spriteYOffset or 0) ~= 0 then sawOffset = true end
local FieldView = package.loaded["src.core.game3.field_view"]
if FieldView and (FieldView.cameraPanY or 0) ~= 0 then sawPan = true end
if idle() and (mapNow() ~= fromMap or not Warp.isBusy()) and U.frame() then
if mapNow() ~= fromMap or (Player.cellX ~= ax or Player.cellY ~= ay) then break end
end
U.wait(1)
end
settle()
return { from = fromMap, to = mapNow(), x = Player.cellX, y = Player.cellY, invisible = sawInvisible,
offset = sawOffset, pan = sawPan, wx = wx, wy = wy }
end
local r = stepOnto("EM_LAVARIDGE_TOWN_GYM_1F", "LAVARIDGE_GYM_1F_WARP", "Lavaridge 1F")
if r then
check(r.to == "EM_LAVARIDGE_TOWN_GYM_B1F", "Lavaridge 1F warp sinks to B1F (" .. tostring(r.to) .. ")")
check(sawSe("SE_LAVARIDGE_FALL_WARP"), "SE_LAVARIDGE_FALL_WARP plays while sinking")
check(r.invisible, "the player disappears into the ash")
check(r.offset, "B1F arrival drops the player in from above (FieldCB_FallWarpExit)")
U.shot(game, DIR .. "/01_lavaridge_b1f_arrival.png")
end
r = stepOnto("EM_LAVARIDGE_TOWN_GYM_B1F", "LAVARIDGE_GYM_B1F_WARP", "Lavaridge B1F")
if r then
check(r.to == "EM_LAVARIDGE_TOWN_GYM_1F", "Lavaridge B1F warp launches to 1F (" .. tostring(r.to) .. ")")
check(sawSe("SE_M_EXPLOSION") and sawSe("SE_M_DIG"), "SE_M_EXPLOSION on launch, SE_M_DIG on pop-out")
check(r.pan, "camera shakes during the launch")
check(r.offset, "the player rises off screen")
U.shot(game, DIR .. "/02_lavaridge_1f_popout.png")
end
r = stepOnto("EM_MOSSDEEP_CITY_GYM", "MOSSDEEP_GYM_WARP", "Mossdeep Gym")
if r then
check(r.to == "EM_MOSSDEEP_CITY_GYM" and (r.x ~= r.wx or r.y ~= r.wy), string.format(
"Mossdeep gym pad warps within the gym (%s %d,%d)", tostring(r.to), r.x, r.y))
check(sawSe("SE_WARP_IN") and sawSe("SE_WARP_OUT"), "SE_WARP_IN / SE_WARP_OUT")
U.shot(game, DIR .. "/03_mossdeep_gym_pad.png")
end
local aqua = nil
for _, id in ipairs({ "EM_AQUA_HIDEOUT_B1F", "EM_AQUA_HIDEOUT_B2F" }) do
if not aqua and warpWithBehavior(id, "AQUA_HIDEOUT_WARP") then aqua = id end
end
r = aqua and stepOnto(aqua, "AQUA_HIDEOUT_WARP", "Aqua Hideout")
check(aqua ~= nil, "an Aqua Hideout map has AQUA_HIDEOUT_WARP pads")
if r then
check(r.to ~= nil and (r.to ~= r.from or r.x ~= r.wx or r.y ~= r.wy), "Aqua Hideout pad teleports (" .. tostring(r.to) .. ")")
check(sawSe("SE_WARP_IN") and sawSe("SE_WARP_OUT"), "teleport tile plays SE_WARP_IN then SE_WARP_OUT")
check(r.offset, "arrival spins in from above (DoPlayerSpinEntrance)")
U.shot(game, DIR .. "/04_aqua_hideout_pad.png")
end
local pyre = nil
for _, id in ipairs({ "EM_MT_PYRE_2F", "EM_MT_PYRE_3F", "EM_MT_PYRE_4F", "EM_MT_PYRE_5F", "EM_MT_PYRE_6F" }) do
if not pyre and warpWithBehavior(id, "MT_PYRE_HOLE") then pyre = id end
end
check(pyre ~= nil, "a Mt. Pyre floor has MT_PYRE_HOLE")
r = pyre and stepOnto(pyre, "MT_PYRE_HOLE", "Mt. Pyre")
if r then
check(r.to ~= r.from, "Mt. Pyre hole drops to the floor below (" .. tostring(r.from) .. " -> " .. tostring(r.to) .. ")")
check(sawSe("SE_FALL"), "SE_FALL plays")
check(r.invisible and r.offset, "player vanishes then falls in from above")
U.shot(game, DIR .. "/05_mt_pyre_hole.png")
end
Audio.playSe = origPlaySe
finish()
end