mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-19 12:15:31 +02:00
CLOSES #223, CLOSES #233, CLOSES #236, CLOSES #240, CLOSES #241, CLOSES #249, CLOSES #252, CLOSES #255, CLOSES #257, CLOSES #258, CLOSES #263, CLOSES #265, CLOSES #274, CLOSES #275, CLOSES #276, CLOSES #279, CLOSES #280, CLOSES #282, CLOSES #283, CLOSES #287, CLOSES #291, CLOSES #292, CLOSES #293, CLOSES #301, CLOSES #304, CLOSES #315, CLOSES #316, CLOSES #317, CLOSES #321, CLOSES #322, CLOSES #330
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
-- Regression: the first completed step after a warp still checks for a warp
|
||||
-- under the player's feet (#265). home/overworld.asm:391 CheckWarpsNoCollision
|
||||
-- runs on EVERY completed step with no first-step-after-a-warp counter, so the
|
||||
-- arrival disable is POSITIONAL (the cell you came in on is inert until you
|
||||
-- leave it), which is what warpEntryCell models. #230's stand-still bonk guard,
|
||||
-- still backed by justWarped, is asserted here too.
|
||||
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||
if not _G.love then _G.love = require("tests.love_stub") end
|
||||
|
||||
local Data = require("src.core.Data")
|
||||
if not (Data.maps and Data.maps.SEAFOAM_ISLANDS_B3F) then Data:load() end
|
||||
|
||||
local Game = require("src.core.Game")
|
||||
local Input = require("src.core.Input")
|
||||
local MapLoader = require("src.world.MapLoader")
|
||||
local Renderer = require("src.render.Renderer")
|
||||
local SaveData = require("src.core.SaveData")
|
||||
local StateStack = require("src.core.StateStack")
|
||||
local Warp = require("src.world.Warp")
|
||||
local OW = require("src.world.OverworldController")
|
||||
local S = require("tests.harness").suite("parity warp after warp step")
|
||||
local check, eq = S.check, S.eq
|
||||
|
||||
-- ---- ground truth: two ladders one cell apart ----------------------------
|
||||
local b3 = MapLoader.load(Data, "SEAFOAM_ISLANDS_B3F")
|
||||
eq(b3:cellTile(25, 3), 0x1A, "B3F (25,3) is a CAVERN ladder tile")
|
||||
eq(b3:cellTile(25, 4), 0x18, "B3F (25,4) is the other CAVERN ladder tile")
|
||||
local up = Warp.onArrive(b3, 25, 3)
|
||||
local down = Warp.onArrive(b3, 25, 4)
|
||||
check(up ~= nil, "(25,3) carries a warp")
|
||||
check(down ~= nil, "(25,4) carries a warp")
|
||||
eq(up and up.def.destMap, "SEAFOAM_ISLANDS_B2F", "(25,3) climbs back to B2F")
|
||||
eq(down and down.def.destMap, "SEAFOAM_ISLANDS_B4F", "(25,4) drops to B4F")
|
||||
|
||||
local reds2 = MapLoader.load(Data, "REDS_HOUSE_2F")
|
||||
eq(reds2:cellTile(7, 1), 0x1A, "REDS_HOUSE_2F (7,1) is the staircase warp tile")
|
||||
eq(reds2.def.width * 2, 8, "REDS_HOUSE_2F is 8 cells wide, so x=7 is the east edge")
|
||||
|
||||
-- ---- live engine ---------------------------------------------------------
|
||||
Game.data = Data
|
||||
Game.input = Input; Input:init()
|
||||
Game.renderer = Renderer; Renderer:init()
|
||||
Game.stack = StateStack; StateStack:init()
|
||||
Game.save = SaveData.newGame()
|
||||
Game.overworld = OW
|
||||
|
||||
-- Reproduce a warp ARRIVAL without running the fade: startWarpTo sets exactly
|
||||
-- these two fields once setMap has placed the player (OverworldController.lua,
|
||||
-- inside the Transition callback). takeWarp is stubbed per instance so the
|
||||
-- assertion is which warp the engine decided to take, with no Transition to pump.
|
||||
local function arriveOn(mapId, x, y, facing)
|
||||
Input:reset()
|
||||
while Game.stack:top() do Game.stack:pop() end
|
||||
Game.stack:push(OW, mapId, x, y, facing or "down")
|
||||
local ow = Game.stack:top()
|
||||
ow.player.moving = false
|
||||
ow.player.turnTimer = 0
|
||||
ow.justWarped = true
|
||||
ow.warpEntryCell = { x = x, y = y }
|
||||
ow.taken = nil
|
||||
ow.takeWarp = function(self, def) self.taken = def end
|
||||
return ow
|
||||
end
|
||||
|
||||
-- Walk one cell the way Player:update would leave things, then run the
|
||||
-- completed-step handler.
|
||||
local function stepTo(ow, x, y, facing)
|
||||
local p = ow.player
|
||||
p.facing = facing or p.facing
|
||||
p.cellX, p.cellY = x, y
|
||||
p.px, p.py = x * 16, y * 16
|
||||
p.moving = false
|
||||
ow:onStepComplete()
|
||||
end
|
||||
|
||||
-- The reported case: down the B2F ladder onto (25,3), then one press of DOWN
|
||||
-- onto the adjacent ladder at (25,4).
|
||||
do
|
||||
local ow = arriveOn("SEAFOAM_ISLANDS_B3F", 25, 3, "down")
|
||||
check(ow:onWarpArrivalCell(), "the cell just arrived on is inert")
|
||||
stepTo(ow, 25, 4, "down")
|
||||
check(ow.taken ~= nil, "the step onto (25,4) fires a warp")
|
||||
eq(ow.taken and ow.taken.destMap, "SEAFOAM_ISLANDS_B4F",
|
||||
"and it is the ladder down to B4F")
|
||||
check(ow.justWarped == false, "the arrival record is cleared by that step")
|
||||
end
|
||||
|
||||
-- The arrival cell stays inert while you stand on it, even if a scripted nudge
|
||||
-- re-runs the step handler there. That is warpEntryCell's job, not justWarped's.
|
||||
do
|
||||
local ow = arriveOn("SEAFOAM_ISLANDS_B3F", 25, 3, "down")
|
||||
stepTo(ow, 25, 3, "down")
|
||||
check(ow.taken == nil, "standing on the arrival ladder does not re-fire it")
|
||||
eq(ow.warpEntryCell and ow.warpEntryCell.x, 25, "the entry cell is remembered")
|
||||
eq(ow.warpEntryCell and ow.warpEntryCell.y, 3, "at the arrival row")
|
||||
end
|
||||
|
||||
-- Once you have left it, that cell is live again (a real second visit).
|
||||
do
|
||||
local ow = arriveOn("SEAFOAM_ISLANDS_B3F", 25, 3, "down")
|
||||
stepTo(ow, 25, 2, "up")
|
||||
check(ow.taken == nil, "stepping onto a plain floor cell warps nowhere")
|
||||
check(ow.warpEntryCell == nil, "leaving clears the entry record")
|
||||
stepTo(ow, 25, 3, "down")
|
||||
check(ow.taken ~= nil, "coming back onto the ladder now takes it")
|
||||
eq(ow.taken and ow.taken.destMap, "SEAFOAM_ISLANDS_B2F", "back up to B2F")
|
||||
end
|
||||
|
||||
-- #230 must not come back: justWarped still guards the two STAND-STILL warp
|
||||
-- triggers, where no step ever completes. Red's house 2F staircase is on the
|
||||
-- map's east edge, so pushing into that edge has to bonk, not bounce floors.
|
||||
do
|
||||
local ow = arriveOn("REDS_HOUSE_2F", 7, 1, "down")
|
||||
check(ow:onWarpArrivalCell(), "the staircase arrival cell reports inert")
|
||||
check(ow:checkEdgeExit("right") == false,
|
||||
"pushing east off the map edge from it does not warp (#230)")
|
||||
Input.state.right = true
|
||||
Input.pressed = {}
|
||||
for _ = 1, 30 do
|
||||
ow.player.turnTimer = 0
|
||||
ow:handleInput()
|
||||
ow.player:update()
|
||||
end
|
||||
check(ow.taken == nil, "holding RIGHT into the edge never fires the staircase")
|
||||
eq(ow.player.cellX, 7, "and the player has not moved")
|
||||
eq(ow.player.cellY, 1, "in either axis")
|
||||
Input:reset()
|
||||
|
||||
-- the same from the blocked-step path: north of (7,1) is solid wall
|
||||
Input.state.up = true
|
||||
Input.pressed = {}
|
||||
for _ = 1, 30 do
|
||||
ow.player.turnTimer = 0
|
||||
ow:handleInput()
|
||||
ow.player:update()
|
||||
end
|
||||
check(ow.taken == nil, "bonking the wall from the arrival cell does not warp")
|
||||
Input:reset()
|
||||
end
|
||||
|
||||
S.finish()
|
||||
Reference in New Issue
Block a user