mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-17 19:24:01 +02:00
Bugs and stuff (#144)
* main menu scrollable when over 8 items * buggies * more buggies * Lorelei, Bruno, and Agatha now push their AfterBattle text right after a win
This commit is contained in:
@@ -120,8 +120,11 @@ FieldDefaults.FIELD = {
|
||||
doorBlock = { bx = 2, by = 2, block = 5 } },
|
||||
},
|
||||
-- IsSurfingAllowed refuses SURF on the B4F stairs square until both
|
||||
-- plug boulders are down (engine/overworld/field_move_messages.asm)
|
||||
-- plug boulders are down (engine/overworld/field_move_messages.asm).
|
||||
-- B3F currents set BIT_FORCED_WARP so the south-edge water warps fire
|
||||
-- without a held d-pad (scripts/SeafoamIslandsB3F.asm).
|
||||
seafoam = {
|
||||
SEAFOAM_ISLANDS_B3F = { setsForcedWarp = true },
|
||||
SEAFOAM_ISLANDS_B4F = {
|
||||
surfBlocked = { { x = 7, y = 11, untilEvents = {
|
||||
"EVENT_SEAFOAM4_BOULDER1_DOWN_HOLE",
|
||||
|
||||
@@ -303,6 +303,9 @@ function OverworldState:setMap(mapId, x, y, facing, opts)
|
||||
else
|
||||
self.player = Player.new(Game.data, x, y, facing)
|
||||
end
|
||||
-- crossConnection re-arms this after setMap; clear so a warp/reload
|
||||
-- cannot leave a stale deferred PlayMapMusic pending
|
||||
self.pendingSeamMusic = nil
|
||||
self.entities = { self.player }
|
||||
for _, n in ipairs(self.npcs) do table.insert(self.entities, n) end
|
||||
|
||||
@@ -322,6 +325,12 @@ function OverworldState:setMap(mapId, x, y, facing, opts)
|
||||
-- 16/18 gate exits), and the scripted door-mat walkout that follows
|
||||
-- suppresses onStepComplete, so waiting for a plain step never mounts
|
||||
self:checkForcedMovement()
|
||||
-- Seafoam B4F's map script pushes off the B3F stair warps every frame
|
||||
-- while the upper plugs are out (SeafoamIslandsB4FDefaultScript); the
|
||||
-- B3F/B4F force-surf mouths also arm their MOVE_OBJECT current scripts
|
||||
-- from CheckForceBikeOrSurf. Re-check here so a warp-in does not sit
|
||||
-- idle on those cells waiting for a player step.
|
||||
self:checkSeafoamCurrent()
|
||||
|
||||
-- snap the camera immediately: the overworld doesn't update while a
|
||||
-- Transition is on top, so a stale camera would show the new map at
|
||||
@@ -802,6 +811,15 @@ function OverworldState:update(dt)
|
||||
if entry and (self.player.cellX ~= entry.x or self.player.cellY ~= entry.y) then
|
||||
self.warpEntryCell = nil
|
||||
end
|
||||
-- deferred PlayMapMusic from crossConnection (issue #93)
|
||||
if stepped and self.pendingSeamMusic then
|
||||
local mapId = self.pendingSeamMusic
|
||||
self.pendingSeamMusic = nil
|
||||
if mapId == self.map.id then
|
||||
require("src.core.Music").playMap(Game.data, mapId, Game.save.onBike,
|
||||
self.player.surfing)
|
||||
end
|
||||
end
|
||||
if stepped and not scripted then
|
||||
self:onStepComplete()
|
||||
end
|
||||
@@ -1050,7 +1068,15 @@ function OverworldState:crossConnection(dir, conn)
|
||||
if not Map.defPassable(dest, ts, x, y, p.surfing) then
|
||||
return false
|
||||
end
|
||||
self:setMap(conn.map, x, y, p.facing, { seamless = true })
|
||||
-- keepMusic: defer PlayMapMusic until the seam step lands. Starting a
|
||||
-- new chip song inside setMap used to hitch the render thread (~200ms)
|
||||
-- so FixedStep catch-up ate the walk frames (issue #93). Threaded synth
|
||||
-- removed most of that hitch; discarding catch-up + deferring the song
|
||||
-- still protects the visible step when neighbor rebuild or the sync
|
||||
-- fallback stalls, and avoids the rare one-frame volume spike from a
|
||||
-- song swap mid-step.
|
||||
self:setMap(conn.map, x, y, p.facing, { seamless = true, keepMusic = true })
|
||||
self.pendingSeamMusic = conn.map
|
||||
-- place the player one cell before the seam (their old world spot,
|
||||
-- which the neighbor strip renders identically) and start the step
|
||||
-- into the new map RIGHT NOW so there is no one-frame stall at the
|
||||
@@ -1064,9 +1090,13 @@ function OverworldState:crossConnection(dir, conn)
|
||||
p.targetX, p.targetY = x, y
|
||||
p.moving = true
|
||||
p.progress = 0
|
||||
-- fresh walk-cycle clock so the seam step always shows leg frames
|
||||
-- (mid-cycle stand phase would otherwise look like a slide)
|
||||
p.animClock = 0
|
||||
p.stepFramesCur = Game.save.onBike
|
||||
and (FieldDefaults.world(Game.data, "bikeStepFrames") or 8)
|
||||
or (FieldDefaults.world(Game.data, "stepFrames") or 16)
|
||||
require("src.core.FixedStep"):discardCatchup()
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -2669,8 +2699,11 @@ function OverworldState:onStepComplete()
|
||||
elseif entry then
|
||||
-- still standing on the warp we arrived through; do not re-trigger it
|
||||
else
|
||||
-- CheckWarpsNoCollision: door/warp tiles fire immediately; otherwise
|
||||
-- ExtraWarpCheck must pass AND either a d-pad is held or BIT_FORCED_WARP
|
||||
-- is set (Seafoam B3F currents — home/overworld.asm).
|
||||
local w = Warp.onArrive(self.map, p.cellX, p.cellY)
|
||||
if not w and self:dirHeld() then
|
||||
if not w and (self:dirHeld() or self.forcedWarp) then
|
||||
w = Warp.onCollision(self.map, Game.data.field.warpCarpets,
|
||||
p.cellX, p.cellY, p.facing)
|
||||
end
|
||||
@@ -2751,9 +2784,11 @@ function OverworldState:runSpinnerMoves(moves, i)
|
||||
local mv = moves[i]
|
||||
if not mv then
|
||||
self.player.spinning = false
|
||||
if not self:checkSpinner() and self.player.surfing then
|
||||
self:checkSeafoamCurrent()
|
||||
end
|
||||
-- Scripted steps skip onStepComplete while they run; once the RLE
|
||||
-- finishes, re-enter the normal landing pipeline so chained spinners,
|
||||
-- Seafoam currents, and CheckWarpsNoCollision (incl. BIT_FORCED_WARP)
|
||||
-- see the tile we stopped on — same as pokered after simulated joypad.
|
||||
self:onStepComplete()
|
||||
return
|
||||
end
|
||||
self.player.spinning = true -- spin the sprite while sliding
|
||||
@@ -2926,6 +2961,9 @@ function OverworldState:checkSeafoamCurrent()
|
||||
if sf.forcedExit and p.surfing and not allSet(sf.forcedExit.activeUntilEvents) then
|
||||
for _, c in ipairs(sf.forcedExit.coords) do
|
||||
if p.cellX == c.x and p.cellY == c.y then
|
||||
-- SeafoamIslandsB4FDefaultScript: res BIT_FORCED_WARP before the
|
||||
-- push so the B3F stair warps underfoot cannot bounce you back.
|
||||
self.forcedWarp = false
|
||||
require("src.core.Sound").play(Game.data, "Collision")
|
||||
self:scriptMove(p, "up", c.y == 17 and 2 or 1)
|
||||
return true
|
||||
@@ -2947,6 +2985,12 @@ function OverworldState:checkSeafoamCurrent()
|
||||
end
|
||||
for _, c in ipairs(active) do
|
||||
if p.cellX == c.x and p.cellY == c.y then
|
||||
-- SeafoamIslandsB3F.asm sets BIT_FORCED_WARP before DecodeRLEList so
|
||||
-- the south-edge water stairs auto-warp when the current ends.
|
||||
if FieldDefaults.fieldValue(Game.data, "seafoam", self.map.id,
|
||||
"setsForcedWarp") then
|
||||
self.forcedWarp = true
|
||||
end
|
||||
self:runSpinnerMoves(c.moves, 1)
|
||||
return true
|
||||
end
|
||||
@@ -3155,16 +3199,20 @@ end
|
||||
-- Warp to the last heal point (blackout, ESCAPE ROPE, DIG/TELEPORT).
|
||||
-- The heal point is usually an interior, so LAST_MAP exits are re-pointed
|
||||
-- at its remembered town door rather than wherever the player left from.
|
||||
function OverworldState:warpToHealPoint(onDone)
|
||||
--
|
||||
-- opts.arrive = "teleport" for Dig/Teleport/Escape Rope (LeaveMapAnim /
|
||||
-- EnterMapAnim). Blackouts omit it: pret HandleBlackOut only
|
||||
-- GBFadeOutToBlack + PrepareForSpecialWarp + SpecialEnterMap, and never
|
||||
-- sets BIT_FLY_WARP / BIT_DUNGEON_WARP, so EnterMap never runs EnterMapAnim.
|
||||
function OverworldState:warpToHealPoint(onDone, opts)
|
||||
local heal = self:healPoint()
|
||||
self.player.surfing = false
|
||||
-- HandleFlyWarpOrDungeonWarp + DisplayPlayerBlackedOutText both clear
|
||||
-- BIT_ALWAYS_ON_BIKE (home/overworld.asm / home/text_script.asm)
|
||||
Game.save.forcedBike = nil
|
||||
-- rematerializing plays the teleport-in poof (EnterMapAnim in
|
||||
-- engine/overworld/player_animations.asm: SFX_TELEPORT_ENTER_1, then
|
||||
-- ENTER_2 after the spin-down); blackouts take this path too
|
||||
self.arriveWarp = "teleport"
|
||||
if opts and opts.arrive == "teleport" then
|
||||
self.arriveWarp = "teleport"
|
||||
end
|
||||
self:startWarpTo(heal.map, heal.x, heal.y, "down", onDone)
|
||||
if heal.outdoor then
|
||||
self:rememberOutdoor(heal.outdoor.id, heal.outdoor.x, heal.outdoor.y)
|
||||
@@ -3202,9 +3250,9 @@ function OverworldState:startWarpTo(mapId, x, y, facing, onDone, opts)
|
||||
-- one-step justWarped guard, which only skipped the very next frame's
|
||||
-- check and so let a mon walked back onto the pad re-trigger it.
|
||||
self.warpEntryCell = { x = x, y = y }
|
||||
-- Fly/Teleport/Dig/Escape-Rope/blackout landings poof the player
|
||||
-- back in (player_animations.asm EnterMapAnim); ordinary door
|
||||
-- warps never take this branch
|
||||
-- Fly/Teleport/Dig/Escape-Rope landings poof the player back in
|
||||
-- (player_animations.asm EnterMapAnim). Blackouts and ordinary
|
||||
-- door warps never take this branch.
|
||||
if arriveWarp == "fly" then
|
||||
require("src.core.Sound").play(Game.data, "Fly")
|
||||
elseif arriveWarp == "teleport" then
|
||||
|
||||
Reference in New Issue
Block a user