mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-22 13:36:14 +02:00
Fix transition state pop, Gen 2 Bide/Sleep Talk/exp bugs, pp repair, TM pocket capacity and Bill's PC arrows
CLOSES #1663, CLOSES #1664, CLOSES #1665, CLOSES #1666, CLOSES #1667, CLOSES #1668, CLOSES #1670, CLOSES #1672
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
-- home/overworld.asm:690-703 (PlayMapChangeSound tail-calls GBFadeOutToBlack)
|
||||
-- and home/fade.asm:43-46: the map-change fade has no matching fade in, so the
|
||||
-- warp shape ends in the same frame its midpoint runs. The midpoint is where
|
||||
-- setMap opens things (the Cycling Road refusal box, a map script's onEnter),
|
||||
-- and a fade that popped the top of the stack after that ate them and then
|
||||
-- finished a second time (#1663).
|
||||
-- luajit tests/engine/transition_identity_pop_bug1663.lua
|
||||
|
||||
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||
|
||||
local T = require("tests.harness")
|
||||
local check, eq = T.check, T.eq
|
||||
love = love or require("tests.love_stub")
|
||||
|
||||
local StateStack = require("src.core.StateStack")
|
||||
local Transition = require("src.render.Transition")
|
||||
local Timing = require("src.core.Timing")
|
||||
|
||||
local function overworld() return { name = "overworld", isOpaque = true } end
|
||||
|
||||
-- ------------------------------------------------ the warp shape (#1663)
|
||||
|
||||
do
|
||||
StateStack:init()
|
||||
local ow = overworld()
|
||||
StateStack:push(ow)
|
||||
|
||||
local box = { name = "refusal" }
|
||||
local entered, depthAtMidpoint, topAtMidpoint = 0, nil, nil
|
||||
function box:enter() entered = entered + 1 end
|
||||
local dones = 0
|
||||
local fade
|
||||
fade = Transition.new({ stack = StateStack }, function()
|
||||
depthAtMidpoint = #StateStack.states
|
||||
topAtMidpoint = StateStack:top()
|
||||
StateStack:push(box)
|
||||
end, function() dones = dones + 1 end, true)
|
||||
StateStack:push(fade)
|
||||
|
||||
local finishedOn
|
||||
for frame = 1, 120 do
|
||||
StateStack:update(1 / 60)
|
||||
if dones > 0 and not finishedOn then finishedOn = frame end
|
||||
end
|
||||
|
||||
eq(finishedOn, Timing.WARP_FADE_OUT, "the warp hands back at the end of the fade")
|
||||
eq(dones, 1, "and hands back exactly once")
|
||||
eq(depthAtMidpoint, 1, "the fade is off the stack before the midpoint runs")
|
||||
check(topAtMidpoint == ow, "so the map switch sees the overworld on top")
|
||||
eq(entered, 1, "the state the midpoint pushed entered once")
|
||||
eq(#StateStack.states, 2, "the fade is gone and the pushed state is not")
|
||||
check(StateStack.states[1] == ow, "the overworld is still the base")
|
||||
check(StateStack:top() == box, "the box the midpoint opened owns the screen")
|
||||
end
|
||||
|
||||
-- a midpoint that pushes nothing still leaves exactly the overworld behind
|
||||
do
|
||||
StateStack:init()
|
||||
local ow = overworld()
|
||||
StateStack:push(ow)
|
||||
local mids, dones = 0, 0
|
||||
local fade = Transition.new({ stack = StateStack },
|
||||
function() mids = mids + 1 end,
|
||||
function() dones = dones + 1 end, true)
|
||||
StateStack:push(fade)
|
||||
for _ = 1, 120 do StateStack:update(1 / 60) end
|
||||
eq(mids, 1, "the map switched once")
|
||||
eq(dones, 1, "the plain warp still hands back exactly once")
|
||||
eq(#StateStack.states, 1, "and pops nothing but itself")
|
||||
check(StateStack:top() == ow, "leaving the overworld on top")
|
||||
end
|
||||
|
||||
-- ------------------------------------------ the script fade is unchanged
|
||||
|
||||
-- ViridianGym.asm .afterBeat / RocketHideoutB4F BeatGiovanniScript bracket
|
||||
-- their HideObject with GBFadeOutToBlack -> GBFadeInFromBlack, so those keep
|
||||
-- a real fade in and wait under whatever the midpoint opened.
|
||||
do
|
||||
StateStack:init()
|
||||
local ow = overworld()
|
||||
StateStack:push(ow)
|
||||
|
||||
local box = { name = "script box" }
|
||||
local dones = 0
|
||||
local fade = Transition.new({ stack = StateStack },
|
||||
function() StateStack:push(box) end,
|
||||
function() dones = dones + 1 end, false)
|
||||
StateStack:push(fade)
|
||||
|
||||
for _ = 1, Timing.WARP_FADE_OUT + 8 do StateStack:update(1 / 60) end
|
||||
eq(dones, 0, "a fade with a fade-in waits under what its midpoint opened")
|
||||
check(StateStack:top() == box, "the pushed state is on top")
|
||||
check(StateStack.states[2] == fade, "with the fade still underneath it")
|
||||
|
||||
StateStack:pop()
|
||||
for _ = 1, Timing.FADE_IN_FROM_BLACK + 8 do StateStack:update(1 / 60) end
|
||||
eq(dones, 1, "and finishes once the box is gone")
|
||||
eq(#StateStack.states, 1, "leaving the overworld alone on the stack")
|
||||
check(StateStack:top() == ow, "and nothing else came off with it")
|
||||
end
|
||||
|
||||
-- ------------------------------------------------- finish is idempotent
|
||||
|
||||
do
|
||||
StateStack:init()
|
||||
local ow = overworld()
|
||||
StateStack:push(ow)
|
||||
local dones = 0
|
||||
local fade = Transition.new({ stack = StateStack }, nil,
|
||||
function() dones = dones + 1 end, true)
|
||||
StateStack:push(fade)
|
||||
fade:finish()
|
||||
fade:finish()
|
||||
eq(dones, 1, "a second finish does not hand back a second time")
|
||||
eq(#StateStack.states, 1, "and takes nothing else off the stack")
|
||||
check(StateStack:top() == ow, "the overworld survives the second call")
|
||||
end
|
||||
|
||||
-- a mod record may still ask a warp for a fade in; framesIn 0 is truthy in
|
||||
-- Lua, so the built-in warp keeps its 0 and the retimed one keeps its own
|
||||
do
|
||||
local retimed = { transitions = { warp_fade = { kind = "fade", frames = 32,
|
||||
framesIn = 16 } } }
|
||||
local fade = Transition.new({ data = retimed, stack = StateStack }, nil,
|
||||
nil, true)
|
||||
eq(fade.framesIn, 16, "a retimed warp record keeps its fade in")
|
||||
local vanilla = Transition.new({ stack = StateStack }, nil, nil, true)
|
||||
eq(vanilla.framesIn, Timing.WARP_FADE_IN, "the built-in warp has none")
|
||||
end
|
||||
|
||||
StateStack:clear()
|
||||
|
||||
T.finish("transition_identity_pop_bug1663")
|
||||
Reference in New Issue
Block a user