mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 08:21:02 +02:00
129 lines
4.5 KiB
Lua
129 lines
4.5 KiB
Lua
-- The caller-ID box an incoming call puts across the top of the screen:
|
|
-- Phone_TextboxWithName (pokegold engine/phone/phone.asm:582), reached from
|
|
-- RingTwice_StartCall's .CallerTextboxWithName (:466, :474).
|
|
--
|
|
-- Three shots, because the whole bug was "there is no box at all" and only a
|
|
-- picture can answer that:
|
|
--
|
|
-- 01-ring.png the ring, box up, naming who is calling
|
|
-- 02-talking.png the caller's own script talking UNDER the box
|
|
-- 03-after.png the call over, box gone, overworld clean
|
|
--
|
|
-- POKEPORT_GAME=gold POKEPORT_DRIVER=tests/drivers/gold_phone_caller_box.lua love .
|
|
-- POKEPORT_SHOT_DIR=/tmp/gold-callerbox (default)
|
|
--
|
|
-- The assertions cover the same ground for a run nobody is looking at: the box
|
|
-- is on the stack while the call runs, it is UNDER the text pages rather than
|
|
-- over them, and it is off the stack once the script has ended (a box left
|
|
-- behind would sit on the overworld forever -- it has no `update`, so nothing
|
|
-- would ever take it down).
|
|
local U = require("tests.drivers.util")
|
|
|
|
local Phone = require("src.core.gen2.Phone")
|
|
|
|
-- The tag src/script/gen2/CallAsm.lua marks the pushed state with.
|
|
local CALLER_BOX = "gen2CallerBox"
|
|
|
|
return function(game)
|
|
local out = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/gold-callerbox"
|
|
local failures = 0
|
|
|
|
local function ok(label, condition, detail)
|
|
if condition then
|
|
print("[callerbox] ok " .. label)
|
|
else
|
|
failures = failures + 1
|
|
print("[callerbox] FAIL " .. label .. " " .. tostring(detail))
|
|
end
|
|
end
|
|
|
|
-- Index of the caller box on the stack, or nil.
|
|
local function boxIndex()
|
|
for index, state in ipairs(game.stack.states or {}) do
|
|
if state[CALLER_BOX] then return index end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
U.wait(45)
|
|
local world = game.world
|
|
assert(world and world.map, "gold world did not boot")
|
|
local save = game.save
|
|
|
|
game.clock = { day = 0, hour = 9, minute = 0 }
|
|
save.phone = nil
|
|
assert(world:setMap("ROUTE_31", 8, 6, "down"), "setMap failed for ROUTE_31")
|
|
U.wait(3)
|
|
-- CheckStandingOnEntrance refuses a call on a door tile, so stand on floor.
|
|
local cx, cy = world.player.cellX, world.player.cellY
|
|
for y = 2, 16 do
|
|
for x = 2, 16 do
|
|
if world.map:cellCollision(x, y) == 0x00 then cx, cy = x, y end
|
|
end
|
|
end
|
|
assert(world:setMap("ROUTE_31", cx, cy, "down"), "no floor cell on ROUTE_31")
|
|
U.wait(3)
|
|
|
|
ok("no caller box before the phone rings", boxIndex() == nil, boxIndex())
|
|
|
|
Phone.addContact(save, 15) -- Joey, ROUTE_30, reachable from ROUTE_31
|
|
|
|
-- Wind the clock forward twenty in-game minutes at a time until
|
|
-- CheckReceiveCallTimer lands a random call.
|
|
local rang = false
|
|
for _ = 1, 40 do
|
|
game.clock.minute = game.clock.minute + 20
|
|
for _ = 1, 20 do
|
|
U.wait(1)
|
|
if world:busy() then break end
|
|
end
|
|
if world:busy() then rang = true break end
|
|
end
|
|
ok("a call rang in the overworld", rang)
|
|
if not rang then
|
|
print("FAIL gold_phone_caller_box (no call)")
|
|
love.event.quit(1)
|
|
return
|
|
end
|
|
|
|
-- The box goes up on the FIRST ring; the ring page only arrives after the
|
|
-- second pass, three Phone_Wait20Frames later (engine/phone/phone.asm:576),
|
|
-- so wait for the page rather than for a fixed count -- then let it type.
|
|
for _ = 1, 300 do
|
|
if #game.stack.states > 1 then break end
|
|
U.wait(1)
|
|
end
|
|
U.wait(40)
|
|
local ringIndex = boxIndex()
|
|
ok("the caller box is up during the ring", ringIndex ~= nil)
|
|
ok("and sits UNDER the ring's text page",
|
|
ringIndex ~= nil and ringIndex < #game.stack.states,
|
|
ringIndex and (ringIndex .. " of " .. #game.stack.states))
|
|
U.shot(game, out .. "/01-ring.png")
|
|
|
|
-- Into the caller's own script. One A gets past the ring page; the shot is
|
|
-- taken with a page of Joey's chatter up, which is what the player sees for
|
|
-- most of a call.
|
|
U.tap(game, "a")
|
|
U.wait(40)
|
|
ok("the box survives into the call itself", boxIndex() ~= nil)
|
|
U.shot(game, out .. "/02-talking.png")
|
|
|
|
-- Now page through to the end: the hang-up Click!, then the tail rows.
|
|
local finished = false
|
|
for _ = 1, 400 do
|
|
if not world:busy() and boxIndex() == nil then finished = true break end
|
|
U.tap(game, "a")
|
|
U.wait(4)
|
|
end
|
|
ok("the call ran to the end", finished, world:busy())
|
|
ok("and InitCallReceiveDelay took the caller box down",
|
|
boxIndex() == nil, boxIndex())
|
|
U.wait(10)
|
|
U.shot(game, out .. "/03-after.png")
|
|
|
|
print(failures == 0 and "PASS gold_phone_caller_box"
|
|
or ("FAIL gold_phone_caller_box (%d)"):format(failures))
|
|
love.event.quit(failures == 0 and 0 or 1)
|
|
end
|