Files
gen1recomp/tests/game3_surf_connections_test.lua

134 lines
6.8 KiB
Lua

package.path = "./?.lua;./?/init.lua;" .. package.path
require("tests.game3_cache").requireData("game3_surf_connections_test")
require("src.core.GameVersion").set("firered")
local Cache = require("tests.game3_cache")
Cache.mountOrSkip("game3_surf_connections_test", "scripts/events.lua", { native = true })
local Dataset = require("src.core.game3.dataset")
local Collision = require("src.core.game3.collision")
local Player = require("src.core.game3.player")
local Map = require("src.core.game3.map")
local Runtime = require("src.core.game3.runtime")
local Field = require("src.core.game3.field")
local Ghosts = require("src.core.game3.ghosts")
local Objects = require("src.core.game3.objects")
local Space = require("src.core.game3.scripting.space")
local game = { data = {}, save = {}, session = { flags = {}, vars = {} } }
Dataset.hydrate(game)
local Behaviors = require("src.core.game3.scripting.interaction_scripts").behaviors
Runtime.session = game.session
Field._game, Field._session, Field.running = game, game.session, true
Space.runEnterScripts = function() end
Space.vm = nil
local failures = 0
local function check(ok, label)
print((ok and "PASS " or "FAIL ") .. label)
if not ok then failures = failures + 1 end
end
local function setup(map, x, y, dir, surfing)
Ghosts.clear()
Map.load(nil, game, map, { x = x, y = y, facing = dir })
game.session = Runtime.getSession()
game.session.x, game.session.y = Player.cellX, Player.cellY
Field.locked = false
Player.surfing, Player.elevation = surfing, surfing and 1 or 3
end
local function finishStep()
Player._onStepDone = function() end
for _ = 1, 32 do
if not Player.moving then break end
Player.tick(game)
end
end
local routes = {
{ "FR_PALLET_TOWN", 9, 19, "down", "FR_ROUTE_21_NORTH", 9, 0 },
{ "FR_ROUTE_21_NORTH", 9, 0, "up", "FR_PALLET_TOWN", 9, 19 },
{ "FR_ROUTE_19", 0, 49, "left", "FR_ROUTE_20", 119, 9 },
{ "FR_ROUTE_20", 119, 9, "right", "FR_ROUTE_19", 0, 49 },
}
for _, r in ipairs(routes) do
setup(r[1], r[2], r[3], r[4], true)
local status = Player.tryMove(r[4], game, false)
check(status == "connection", "surf_crosses_" .. r[1] .. "_to_" .. r[5])
finishStep()
check(Map.current == r[5] and Player.cellX == r[6] and Player.cellY == r[7]
and Player.surfing and Player.elevation == 1 and not Player.dismounting
and game.session.map == r[5] and game.session.x == r[6] and game.session.y == r[7]
and game.save.position.map == r[5] and game.save.position.x == r[6]
and game.save.position.y == r[7], "surf_landing_state_" .. r[5])
end
local function def(coll, elevation, behavior)
local layout = { width = 2, height = 2, pair = "surf_test", _coll = coll, _elev = elevation, _mid = behavior }
function layout:collAt() return self._coll end
function layout:elevAt() return self._elev end
function layout:midAt() return self._mid end
function layout:collArray() return { self._coll, self._coll, self._coll, self._coll } end
return { width = 2, height = 2, midLayout = layout, pair = "surf_test", objects = {}, warps = {}, connections = {} }
end
Behaviors.surf_test = setmetatable({}, { __index = function(_, mid) return mid end })
local source, dest = def(0x29, 1, 0x15), def(0x29, 1, 0x15)
source.connections.south = { map = "FR_SURF_TEST_DEST", offset = 0 }
game.data.maps.FR_SURF_TEST_SOURCE, game.data.maps.FR_SURF_TEST_DEST = source, dest
local function synthetic(surfing)
dest.midLayout._coll, dest.midLayout._elev, dest.midLayout._mid = 0x29, 1, 0x15
source.midLayout._coll, source.midLayout._elev, source.midLayout._mid = 0x29, 1, 0x15
dest.objects = {}
setup("FR_SURF_TEST_SOURCE", 0, 1, "down", surfing ~= false)
end
local function refuse(label)
local oldMap, oldX, oldY, oldElev, oldSurf = Map.current, Player.cellX, Player.cellY, Player.elevation, Player.surfing
local saveMap, saveX, saveY = game.save.position.map, game.save.position.x, game.save.position.y
check(Player.tryMove("down", game, false) == "blocked"
and Map.current == oldMap and Player.cellX == oldX and Player.cellY == oldY
and Player.elevation == oldElev and Player.surfing == oldSurf and not Player.moving
and game.session.map == oldMap and game.session.x == oldX and game.session.y == oldY
and game.save.position.map == saveMap and game.save.position.x == saveX and game.save.position.y == saveY,
label)
end
synthetic(false); refuse("foot_cannot_cross_into_water")
for _, coll in ipairs({ 0x07, 0xff, 0xA0, 0xA2 }) do
synthetic(); dest.midLayout._coll = coll
refuse("surf_rejects_solid_or_ledge_" .. coll)
end
synthetic(); source.midLayout._mid = 0x33; refuse("source_leave_direction_blocks_seam")
synthetic(); dest.midLayout._mid = 0x32; refuse("destination_enter_direction_blocks_seam")
synthetic(); dest.midLayout._elev = 4; refuse("water_elevation_mismatch_blocks_seam")
synthetic(); dest.midLayout._coll, dest.midLayout._elev, dest.midLayout._mid = 0, 4, 0
refuse("surf_cannot_dismount_at_wrong_elevation")
for _, moving in ipairs({ false, true }) do
synthetic()
local pool = Objects.spawnFromDefs({ { localId = 1, x = moving and 1 or 0, y = 0 } }, dest)
pool.byId[1].moving, pool.byId[1].targetX, pool.byId[1].targetY = moving, 0, 0
Ghosts._pools.FR_SURF_TEST_DEST = pool
refuse(moving and "inflight_neighbor_occupancy_blocks_seam" or "current_neighbor_occupancy_blocks_seam")
end
synthetic()
Ghosts._pools.FR_SURF_TEST_DEST = nil
dest.objects = { { localId = 1, x = 0, y = 0 } }
refuse("unloaded_neighbor_template_blocks_seam")
for _, state in ipairs({ "hidden", "passable", "invisible" }) do
synthetic()
local pool = Objects.spawnFromDefs({ { localId = 1, x = 0, y = 0 } }, dest)
if state == "invisible" then pool.byId[1].visible = false else pool.byId[1][state] = true end
Ghosts._pools.FR_SURF_TEST_DEST = pool
check(Player.tryMove("down", game, false) == "connection", state .. "_neighbor_does_not_block")
finishStep()
end
for _, behavior in ipairs({ 0x16, 0x17 }) do
synthetic(); dest.midLayout._coll, dest.midLayout._mid = 0, behavior
check(Player.tryMove("down", game, false) == "connection", "elevation1_shallow_water_seam_" .. behavior)
finishStep()
check(Player.surfing and Player.elevation == 1, "shallow_water_retains_surf_" .. behavior)
end
synthetic(); dest.midLayout._coll, dest.midLayout._elev, dest.midLayout._mid = 0, 3, 0
check(Player.tryMove("down", game, false) == "connection" and Player.dismounting
and Player.surfing and Player.elevation == 1, "dismount_seam_preserves_inflight_surf_and_elevation")
finishStep()
check(not Player.surfing and not Player.dismounting and Player.elevation == 3,
"dismount_seam_finishes_on_land")
synthetic(false); dest.midLayout._coll, dest.midLayout._elev, dest.midLayout._mid = 0, 3, 0
check(Player.tryMove("down", game, false) == "connection", "ordinary_land_connection_still_works")
finishStep()
check(not Player.surfing, "ordinary_land_connection_does_not_enable_surf")
os.exit(failures == 0 and 0 or 1)