mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-28 18:06:09 +02:00
142 lines
5.5 KiB
Lua
142 lines
5.5 KiB
Lua
-- #1862: the whirlpool must stay on screen for the whole surf wash.
|
|
-- DisappearWhirlpool blanks hBGMapMode before the redraw, plays the sound and
|
|
-- only then buffers the screen -- engine/events/overworld.asm:1150-1165,
|
|
-- engine/events/field_moves.asm:5-10. No POKEPORT_SPEED: audio runs on its
|
|
-- own real-time accumulator and the ordering is the whole point.
|
|
-- POKEPORT_IDENTITY=c10-gold POKEPORT_GAME=gold POKEPORT_TOUCH=0 POKEPORT_DRIVER=tests/drivers/gold_whirlpool_block_bug1862_test.lua POKEPORT_SHOT_DIR=/tmp/gold-bug1862 love .
|
|
local U = require("tests.drivers.util")
|
|
|
|
local FieldMoves = require("src.world.gen2.FieldMoves")
|
|
local Mon = require("src.battle.gen2.Mon")
|
|
local Permissions = require("src.world.gen2.Permissions")
|
|
|
|
-- data/generated/maps.lua, ROUTE_41: whirlpools at (22,12), (42,24), (6,30)
|
|
-- and (28,48). Stand one cell north of the first and face it.
|
|
local MAP = "ROUTE_41"
|
|
local WHIRL = { x = 22, y = 12 }
|
|
|
|
return function(game)
|
|
local out = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/gold-bug1862"
|
|
local fails, lines = 0, {}
|
|
local function claim(ok, text)
|
|
if not ok then fails = fails + 1 end
|
|
lines[#lines + 1] = (ok and "PASS " or "FAIL ") .. text
|
|
return ok
|
|
end
|
|
local function report()
|
|
for _, line in ipairs(lines) do U.log(line) end
|
|
U.log(("%d checks, %d failed"):format(#lines, fails))
|
|
end
|
|
|
|
U.wait(45)
|
|
local world = game.world
|
|
if not (world and world.map) then
|
|
U.log("FAIL the gold world never booted, nothing to drain")
|
|
while true do coroutine.yield() end
|
|
end
|
|
|
|
local vol = game.save.options and game.save.options.sfxVol
|
|
claim(vol ~= 0, ("SFX VOL is %s"):format(tostring(vol)))
|
|
if vol == 0 then
|
|
U.log("SFX VOL is ZERO, so the wash this is timed against is inaudible;")
|
|
U.log("turn it up in OPTION before judging anything by ear.")
|
|
end
|
|
|
|
local badges = game.save.player.badges or {}
|
|
game.save.player.badges = badges
|
|
for _, badge in pairs(FieldMoves.BADGE) do badges[badge] = true end
|
|
local swimmer = Mon.new(game.data, "LAPRAS", 30,
|
|
{ moves = { { id = "SURF" }, { id = "WHIRLPOOL" } } })
|
|
claim(swimmer ~= nil, "a LAPRAS that knows SURF and WHIRLPOOL")
|
|
game.save.party = { swimmer }
|
|
|
|
world:applyPlayerState(FieldMoves.PLAYER_SURF)
|
|
world:setMap(MAP, WHIRL.x, WHIRL.y - 1, "down")
|
|
U.wait(15)
|
|
world.noWildEncounters = true
|
|
|
|
local ctx = world:fieldContext()
|
|
local facing = Permissions.isWhirlpool(ctx.facingColl)
|
|
if not facing then
|
|
-- A re-import moved it: take any whirlpool with open water above it.
|
|
local def = world.maps[MAP]
|
|
for y = 1, (def.height or 0) * 2 - 1 do
|
|
for x = 0, (def.width or 0) * 2 - 1 do
|
|
if not facing and Permissions.isWhirlpool(world.map:cellCollision(x, y))
|
|
and Permissions.isWater(world.map:cellCollision(x, y - 1)) then
|
|
WHIRL.x, WHIRL.y = x, y
|
|
world:setMap(MAP, x, y - 1, "down")
|
|
world:applyPlayerState(FieldMoves.PLAYER_SURF)
|
|
U.wait(10)
|
|
ctx = world:fieldContext()
|
|
facing = Permissions.isWhirlpool(ctx.facingColl)
|
|
U.log(("note: using the whirlpool at (%d,%d)"):format(x, y))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
claim(facing, ("facing the whirlpool at (%d,%d) on %s"):format(
|
|
WHIRL.x, WHIRL.y, MAP))
|
|
local blocks = world.maps[MAP] and world.maps[MAP].blocks
|
|
local index = ctx.facingBlockIndex
|
|
local before = blocks and index and blocks[index]
|
|
claim(before ~= nil, "and the block behind it is readable")
|
|
if not (facing and before) then
|
|
report()
|
|
U.log("nothing to drive; stopping rather than faking the moment")
|
|
while true do coroutine.yield() end
|
|
end
|
|
U.shot(game, out .. "/01-facing.png")
|
|
|
|
local function tap(button, gap)
|
|
table.insert(game.input.pressQueue, button)
|
|
game.input.state[button] = true
|
|
coroutine.yield()
|
|
game.input.state[button] = false
|
|
for _ = 1, (gap or 8) do coroutine.yield() end
|
|
end
|
|
|
|
-- A into the whirlpool, then A through the ask box (YES is the default) and
|
|
-- the USED WHIRLPOOL line.
|
|
for _ = 1, 24 do
|
|
if world.fieldMove and world.fieldMove.phase == "whirlpoolsfx" then break end
|
|
tap("a")
|
|
end
|
|
claim(world.fieldMove and world.fieldMove.phase == "whirlpoolsfx",
|
|
"the drain reached PlayWhirlpoolSound")
|
|
claim(blocks[index] == before,
|
|
"the whirlpool is still in the block buffer as the wash starts")
|
|
U.shot(game, out .. "/02-wash-starts.png")
|
|
|
|
local swapped, phaseFrames = nil, 0
|
|
for _ = 1, 300 do
|
|
if world.fieldMove and world.fieldMove.phase == "whirlpoolsfx" then
|
|
phaseFrames = phaseFrames + 1
|
|
if blocks[index] ~= before and not swapped then swapped = phaseFrames end
|
|
if phaseFrames == 6 then U.shot(game, out .. "/03-mid-wash.png") end
|
|
end
|
|
if not world:busy() then break end
|
|
coroutine.yield()
|
|
end
|
|
claim(swapped == nil,
|
|
"and it stayed there for every frame of the wash")
|
|
claim(blocks[index] ~= before,
|
|
"the block was swapped once the wash ended")
|
|
claim(phaseFrames > 0 and phaseFrames < 180,
|
|
("the wash ended on its own after %d frames"):format(phaseFrames))
|
|
U.wait(4)
|
|
U.shot(game, out .. "/04-drained.png")
|
|
|
|
report()
|
|
if fails > 0 then
|
|
U.log("a FAIL above means the run is not showing what it claims to")
|
|
end
|
|
U.log("what right looks like: the whirlpool keeps spinning through the whole")
|
|
U.log("surf wash and only pops out of the water when the sound has finished.")
|
|
U.log("water where the whirlpool was while the wash is still playing is the")
|
|
U.log("bug; a whirlpool still there after control comes back is the overshoot.")
|
|
U.log("the pad is yours -- the other whirlpools are further south.")
|
|
|
|
while true do coroutine.yield() end
|
|
end
|