mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
161 lines
6.0 KiB
Lua
161 lines
6.0 KiB
Lua
#!/usr/bin/env luajit
|
|
-- pokefirered/src/overworld.c:639 UpdateEscapeWarp
|
|
|
|
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 done()
|
|
if failed > 0 then
|
|
print("[test] FAILED " .. failed)
|
|
os.exit(1)
|
|
end
|
|
print("[test] all passed")
|
|
os.exit(0)
|
|
end
|
|
|
|
require("src.core.GameVersion").set("firered")
|
|
|
|
local Cache = require("tests.game3_cache")
|
|
local cacheRoot = Cache.mount("scripts/events.lua", { native = true })
|
|
if not cacheRoot then
|
|
print("[skip] game3_stitchcoll_escape_warp_test: " .. tostring(Cache.reason))
|
|
done()
|
|
end
|
|
|
|
local Dataset = require("src.core.game3.dataset")
|
|
local MapCatalog = require("src.import.gba.map_catalog")
|
|
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 Schema = require("src.core.game3.save_schema_firered")
|
|
|
|
local TOWN = MapCatalog.pretToEngine("PalletTown")
|
|
local HOUSE = MapCatalog.pretToEngine("PalletTown_PlayersHouse_1F")
|
|
local HOUSE_2F = MapCatalog.pretToEngine("PalletTown_PlayersHouse_2F")
|
|
local FOREST = MapCatalog.pretToEngine("ViridianForest")
|
|
local FOREST_GATE = MapCatalog.pretToEngine("Route2_ViridianForest_SouthEntrance")
|
|
|
|
local game = { data = {} }
|
|
Dataset.hydrate(game)
|
|
local session = Schema.newGame({ rngSeed = 0x3131 })
|
|
game.session = session
|
|
Runtime.start(nil, game, session, { reason = "new_game" })
|
|
|
|
local function defOf(id) return id and game.data.maps[id] end
|
|
for _, id in ipairs({ TOWN, HOUSE, HOUSE_2F, FOREST, FOREST_GATE }) do
|
|
check(defOf(id) ~= nil, tostring(id) .. " is in the cache")
|
|
end
|
|
if not (defOf(TOWN) and defOf(HOUSE) and defOf(HOUSE_2F) and defOf(FOREST) and defOf(FOREST_GATE)) then
|
|
done()
|
|
end
|
|
|
|
local function warpTo(def, destId)
|
|
for _, w in ipairs((def and def.warps) or {}) do
|
|
if (w.destMap or w.map) == destId then return w end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
local function goTo(mapId, x, y, facing)
|
|
Map.load(nil, game, mapId, { x = x, y = y, facing = facing or "down" })
|
|
Player.reset(x, y, facing or "down")
|
|
end
|
|
|
|
local function walkThrough(fromMap, toMap, facing)
|
|
local w = warpTo(defOf(fromMap), toMap)
|
|
if not w then return nil end
|
|
goTo(fromMap, tonumber(w.x), tonumber(w.y), facing)
|
|
Warp.request(nil, game, toMap, 1, 1, "down", {
|
|
fade = false, se = false, doorX = tonumber(w.x), doorY = tonumber(w.y),
|
|
})
|
|
return w
|
|
end
|
|
|
|
print("[test] 1. walking off a town into a house records the doorstep")
|
|
-- pokefirered/src/overworld.c:647 SetEscapeWarp
|
|
session.escapeWarp = nil
|
|
local door = walkThrough(TOWN, HOUSE, "up")
|
|
check(door ~= nil, "Pallet Town has a warp into the player's house")
|
|
if not door then done() end
|
|
local esc = session.escapeWarp
|
|
check(type(esc) == "table", "the warp wrote an escape warp")
|
|
if type(esc) ~= "table" then done() end
|
|
eq(esc.map, TOWN, "it points back at the outdoor map")
|
|
eq(esc.x, tonumber(door.x), "at the door's own column")
|
|
-- pokefirered/src/overworld.c:646 delta = GetPlayerFacingDirection() != DIR_SOUTH
|
|
eq(esc.y, tonumber(door.y) + 1, "one row below the door, because the player walked north")
|
|
eq(esc.warpId, 255, "with WARP_ID_NONE, so the coords decide")
|
|
|
|
print("[test] 2. an indoor to indoor warp leaves it alone")
|
|
local kept = { map = esc.map, x = esc.x, y = esc.y }
|
|
local up = walkThrough(HOUSE, HOUSE_2F, "up")
|
|
check(up ~= nil, "the house has stairs to 2F")
|
|
eq(session.escapeWarp.map, kept.map, "the escape warp still names the town")
|
|
eq(session.escapeWarp.x, kept.x, "same column")
|
|
eq(session.escapeWarp.y, kept.y, "same row")
|
|
|
|
print("[test] 3. Viridian Forest is the map pret excludes by hand")
|
|
-- pokefirered/src/overworld.c:644 MAP_VIRIDIAN_FOREST
|
|
local gate = walkThrough(FOREST, FOREST_GATE, "down")
|
|
check(gate ~= nil, "the forest has a warp into the south entrance")
|
|
eq(session.escapeWarp.map, kept.map, "the forest did not overwrite the escape warp")
|
|
eq(session.escapeWarp.y, kept.y, "not even the row")
|
|
|
|
print("[test] 4. a warp tile stepped onto while walking south keeps that tile")
|
|
session.escapeWarp = nil
|
|
local lab = walkThrough(TOWN, MapCatalog.pretToEngine("PalletTown_ProfessorOaksLab"), "down")
|
|
check(lab ~= nil, "Pallet Town has a warp into Oak's lab")
|
|
if lab then
|
|
eq(session.escapeWarp.y, tonumber(lab.y), "delta is 0 for DIR_SOUTH")
|
|
eq(session.escapeWarp.x, tonumber(lab.x), "and the column is the warp tile's own")
|
|
end
|
|
|
|
print("[test] 5. a warp with no warp event behind it leaves the slot alone")
|
|
-- pokefirered/src/field_control_avatar.c:965 SetupWarp
|
|
local before = session.escapeWarp
|
|
goTo(TOWN, 5, 5, "up")
|
|
Warp.request(nil, game, HOUSE, 1, 1, "down", { fade = false, se = false })
|
|
eq(session.escapeWarp, before, "a scripted warp is not a warp event")
|
|
|
|
print("[test] 6. walking up into a real door records the tile below it")
|
|
-- pokefirered/src/field_control_avatar.c:987 TryDoorWarp
|
|
session.escapeWarp = nil
|
|
local Task = require("src.core.game3.task")
|
|
local Fade = require("src.ui.game3.fade")
|
|
local doorWarp = warpTo(defOf(TOWN), HOUSE)
|
|
goTo(TOWN, tonumber(doorWarp.x), tonumber(doorWarp.y) + 1, "up")
|
|
check(Warp.startDoorEntrance(nil, game, HOUSE, 1, 1,
|
|
tonumber(doorWarp.x), tonumber(doorWarp.y)) ~= false, "the door sequence starts")
|
|
local Doors = require("src.core.game3.doors")
|
|
for _ = 1, 900 do
|
|
Task.update(1 / 60)
|
|
Doors.update(1 / 60)
|
|
Player.tick(game)
|
|
Fade.tick(1 / 60)
|
|
if not Warp.isBusy() then break end
|
|
end
|
|
eq(session.map, HOUSE, "the door sequence finished inside the house")
|
|
eq((session.escapeWarp or {}).map, TOWN, "and the escape warp names the town")
|
|
eq((session.escapeWarp or {}).y, tonumber(doorWarp.y) + 1, "on the doorstep the player left")
|
|
|
|
print("[test] 7. the recorded warp rides the save")
|
|
local save = Schema.toSaveTable(session)
|
|
eq((save.escapeWarp or {}).map, TOWN, "toSaveTable carries it")
|
|
eq(Schema.fromSaveTable(save).escapeWarp.y, session.escapeWarp.y, "and it comes back whole")
|
|
|
|
done()
|