Files
gen1recomp/tests/game3_stitchcoll_fall_shake_test.lua

136 lines
4.2 KiB
Lua

#!/usr/bin/env luajit
-- pokefirered/src/field_effect.c:1249 FallWarpEffect_5
-- pokefirered/src/field_effect.c:1274 FallWarpEffect_7
package.path = "./?.lua;./?/init.lua;" .. package.path
local failed = 0
local function check(cond, msg)
if cond then
print("[ok] " .. msg)
else
failed = failed + 1
print("[FAIL] " .. msg)
end
end
local function eq(a, b, msg)
check(a == b, string.format("%s (%s == %s)", msg, tostring(a), tostring(b)))
end
local function finish()
if failed > 0 then
print("[test] FAILED " .. failed)
os.exit(1)
end
print("[test] all passed")
os.exit(0)
end
local GameVersion = require("src.core.GameVersion")
GameVersion.set("firered")
local FieldEffects = require("src.core.game3.field_effects")
local FieldView = require("src.core.game3.field_view")
print("[test] 1. the landing shake is pret's 12 frame camera pan")
FieldEffects._anims = {}
FieldView.setCameraPanning(0, 0)
local shakeDone = 0
FieldEffects.startLandingShake(function() shakeDone = shakeDone + 1 end)
local pans = {}
local doneAt = nil
for i = 1, 20 do
FieldEffects.step()
pans[i] = FieldView.cameraPanY
if shakeDone > 0 and not doneAt then doneAt = i end
end
eq(table.concat(pans, ",", 1, 13), "4,-4,4,-4,2,-2,2,-2,1,-1,1,-1,0",
"the pan halves every four frames and settles back on zero")
eq(doneAt, 13, "the callback runs on the frame the pan reaches zero")
eq(shakeDone, 1, "and it runs exactly once")
print("[test] 2. the real fall warp shakes the screen before it gives control back")
local Cache = require("tests.game3_cache")
local cacheRoot = Cache.mount("scripts/events.lua", { native = true })
if not cacheRoot then
print("[skip] game3_stitchcoll_fall_shake_test map checks: " .. tostring(Cache.reason))
finish()
end
print("[info] FireRed cache at " .. cacheRoot)
local Dataset = require("src.core.game3.dataset")
local Collision = require("src.core.game3.collision")
local Objects = require("src.core.game3.objects")
local Player = require("src.core.game3.player")
local Field = require("src.core.game3.field")
local Space = require("src.core.game3.scripting.space")
local Runtime = require("src.core.game3.runtime")
local Warp = require("src.core.game3.warp")
local Task = require("src.core.game3.task")
local Fade = require("src.ui.game3.fade")
local game = { data = {} }
Dataset.hydrate(game)
local session = { map = nil, flags = {}, vars = {} }
game.session = session
Runtime.session = session
local CAVE_1F = "FR_FOUR_ISLAND_ICEFALL_CAVE_1F"
local CAVE_B1F = "FR_FOUR_ISLAND_ICEFALL_CAVE_B1F"
local HOLE_X, HOLE_Y = 8, 14
local def = game.data.maps[CAVE_1F]
check(def ~= nil, CAVE_1F .. " is in the cache")
if not def then finish() end
check(game.data.maps[CAVE_B1F] ~= nil, CAVE_B1F .. " is in the cache")
Field._game = game
session.map = CAVE_1F
Field._session = session
Field.running = true
Field.locked = false
Space.activate(nil, CAVE_1F, game, nil)
Collision.bindMap(game, CAVE_1F, def)
Objects.loadMap(game, CAVE_1F, def)
Player.reset(HOLE_X, HOLE_Y, "down")
FieldEffects._anims = {}
FieldView.setCameraPanning(0, 0)
Task.clear()
check(Warp.startFall(nil, game, CAVE_B1F, HOLE_X, HOLE_Y) == true,
"the fall warp starts")
local landedAt, unlockedAt, panFrames = nil, nil, 0
local wasFalling = false
for frame = 1, 600 do
Task.update(1 / 60)
Fade.tick(1 / 60)
FieldEffects.step()
if (Player.spriteYOffset or 0) < 0 then wasFalling = true end
if wasFalling and not landedAt and (Player.spriteYOffset or 0) == 0 then
landedAt = frame
end
if landedAt and (FieldView.cameraPanY or 0) ~= 0 then panFrames = panFrames + 1 end
if not Warp.isBusy() and not unlockedAt then
unlockedAt = frame
break
end
end
check(landedAt ~= nil, "the player fell and landed")
eq(session.map, CAVE_B1F, "the fall landed on " .. CAVE_B1F)
check(unlockedAt ~= nil, "the fall sequence finished")
if not (landedAt and unlockedAt) then finish() end
eq(panFrames, 12, "the screen shook for 12 frames after the landing")
eq(unlockedAt - landedAt, 12,
"control comes back 12 frames after the landing, not on the landing frame")
eq(Warp.isBusy(), false, "the warp is no longer busy")
eq(Field.locked, false, "the field is unlocked again")
eq(FieldView.cameraPanY, 0, "the camera pan is back to zero")
eq(#FieldEffects._anims, 0, "no field effect is left running")
finish()