mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 00:10:56 +02:00
189 lines
8.1 KiB
Lua
189 lines
8.1 KiB
Lua
-- Manual check of the ghost MAROWAK send-off on POKEMON_TOWER_6F (#867).
|
|
-- PokemonTower6FMarowakDepartedText (pokered scripts/PokemonTower6F.asm) is
|
|
-- two texts: the CUBONE's-mother line, then PlayCry RESTLESS_SOUL + 30 frames
|
|
-- before the calmed line; the port showed only the calmed line and no cry.
|
|
-- Never under POKEPORT_SPEED -- the cry-then-text beat is the thing under test.
|
|
-- POKEPORT_DRIVER=tests/drivers/marowak_departed_bug867_test.lua POKEPORT_IDENTITY=bug867 POKEPORT_TOUCH=0 SHOT_DIR=/tmp/shots love .
|
|
return function(game)
|
|
local U = dofile("tests/drivers/util.lua")
|
|
local DIR = os.getenv("SHOT_DIR") or "/tmp/shots"
|
|
local Pokemon = require("src.pokemon.Pokemon")
|
|
local BattleState = require("src.battle.BattleState")
|
|
local TextBox = require("src.render.TextBox")
|
|
|
|
local pass, fail = 0, 0
|
|
local function check(label, ok)
|
|
if ok then pass = pass + 1 else fail = fail + 1 end
|
|
U.log(ok and "PASS" or "FAIL", label)
|
|
return ok
|
|
end
|
|
|
|
-- ---- machine checks ----------------------------------------------------
|
|
-- Both keys come out of the stock extractor (data/generated/text.lua); a
|
|
-- rename there would drop story3.lua onto its hand fallbacks, which still
|
|
-- displays but is worth knowing about.
|
|
local mother = game.data.text._PokemonTower6FGhostWasCubonesMotherText
|
|
local calmed = game.data.text._PokemonTower6FSoulWasCalmedText
|
|
check("_PokemonTower6FGhostWasCubonesMotherText extracted",
|
|
type(mother) == "string" and mother ~= "")
|
|
check("_PokemonTower6FSoulWasCalmedText extracted",
|
|
type(calmed) == "string" and calmed ~= "")
|
|
if type(mother) == "string" then
|
|
U.log("first line reads:", (mother:gsub("[\n\011\012]", " / ")))
|
|
end
|
|
if type(calmed) == "string" then
|
|
U.log("second line reads:", (calmed:gsub("[\n\011\012]", " / ")))
|
|
end
|
|
check("MAROWAK is a real species (RESTLESS_SOUL EQU MAROWAK)",
|
|
game.data.pokemon.MAROWAK ~= nil)
|
|
|
|
local opts = game.save.options or {}
|
|
U.log("sfxVol", tostring(opts.sfxVol), "musicVol", tostring(opts.musicVol))
|
|
if opts.sfxVol == 0 then
|
|
U.log("sfxVol is 0: raise it in OPTION or the cry cannot be judged")
|
|
end
|
|
|
|
-- ---- reach the trigger -------------------------------------------------
|
|
-- pokered scripts/PokemonTower6F.asm PokemonTower6FMarowakCoords:
|
|
-- dbmapcoord 10, 16 (a coord array, not an object). Row 17 is solid wall
|
|
-- and (9, 16) is the stairwell warp, so the approach is from (10, 15)
|
|
-- facing down, same as tests/drivers/ghost_unveil_bug492_test.lua.
|
|
local MAP = "POKEMON_TOWER_6F"
|
|
local TRIGGER = { x = 10, y = 16 }
|
|
local STAND = { x = 10, y = 15, facing = "down", step = "down" }
|
|
|
|
-- one mon, one damaging move: the A-mash below always picks FIGHT slot 1,
|
|
-- and a stat move there stalls the run (route.lua learned this the hard way)
|
|
local mon = Pokemon.new(game.data, "MEWTWO", 100)
|
|
if game.data.moves.PSYCHIC_M then
|
|
mon.moves = { { id = "PSYCHIC_M", pp = 99 } }
|
|
end
|
|
game.save.party = { mon }
|
|
game.save.player.name = "RED"
|
|
-- the scope buys the unveil so the ghost can be damaged at all (#492)
|
|
game.save.inventory.SILPH_SCOPE = 1
|
|
game.save.flags.EVENT_BEAT_GHOST_MAROWAK = nil
|
|
|
|
U.teleport(game, MAP, STAND.x, STAND.y, STAND.facing)
|
|
U.wait(10)
|
|
local ow = game.overworld
|
|
check("the overworld is up on " .. MAP, ow ~= nil and ow.map ~= nil)
|
|
|
|
if ow and ow.map and not ow.map:isWalkableCell(STAND.x, STAND.y) then
|
|
-- a map edit moved the approach: stand on any walkable neighbour of the
|
|
-- trigger that is not the stairwell warp and step back onto it.
|
|
-- {dx, dy, facing} is the trigger-to-stand offset plus the direction
|
|
-- that walks back onto the trigger cell.
|
|
local sides = { { 0, -1, "down" }, { 1, 0, "left" },
|
|
{ -1, 0, "right" }, { 0, 1, "up" } }
|
|
for _, s in ipairs(sides) do
|
|
local cx, cy = TRIGGER.x + s[1], TRIGGER.y + s[2]
|
|
if ow.map:isWalkableCell(cx, cy) and not ow.map:warpAtCell(cx, cy) then
|
|
U.log(("(%d, %d) is blocked, approaching from"):format(STAND.x, STAND.y),
|
|
cx, cy, "stepping", s[3])
|
|
STAND = { x = cx, y = cy, facing = s[3], step = s[3] }
|
|
U.teleport(game, MAP, cx, cy, s[3])
|
|
U.wait(10)
|
|
ow = game.overworld
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
-- walk onto the trigger; MapScripts onStep fires on the completed step
|
|
U.hold(game, STAND.step, 20)
|
|
U.wait(20)
|
|
check("the Be-gone text opened", game.stack:top() ~= game.overworld)
|
|
|
|
-- ---- win the battle ----------------------------------------------------
|
|
local sawBattle = false
|
|
for _ = 1, 1500 do
|
|
-- onFinish sets the flag and queues the departed rows in the same call,
|
|
-- so break on the flag BEFORE tapping: a stray A here would eat the
|
|
-- CUBONE's-mother box before it is recorded
|
|
if game.save.flags.EVENT_BEAT_GHOST_MAROWAK then break end
|
|
if getmetatable(game.stack:top()) == BattleState then sawBattle = true end
|
|
U.tap(game, "a")
|
|
U.wait(4)
|
|
end
|
|
check("the MAROWAK battle opened", sawBattle)
|
|
check("the battle was won (EVENT_BEAT_GHOST_MAROWAK set)",
|
|
game.save.flags.EVENT_BEAT_GHOST_MAROWAK == true)
|
|
|
|
-- ---- record the send-off boxes -----------------------------------------
|
|
-- Each box is sampled the frame it is first seen: the calmed box carries
|
|
-- the armed cry as opts.auto {sound, wait} (src/script/Commands.lua), and
|
|
-- TextBox clears .auto once the cry has played, so a late read looks like
|
|
-- no cry at all.
|
|
local boxes = {}
|
|
local lastBox = nil
|
|
local budget = 1200
|
|
while budget > 0 do
|
|
local top = game.stack:top()
|
|
if getmetatable(top) == TextBox then
|
|
if top ~= lastBox then
|
|
lastBox = top
|
|
local shown = {}
|
|
for _, page in ipairs(top.pages or {}) do
|
|
for _, line in ipairs(page) do shown[#shown + 1] = line end
|
|
end
|
|
boxes[#boxes + 1] = {
|
|
text = table.concat(shown, " / "),
|
|
cry = top.auto ~= nil and top.auto.sound ~= nil,
|
|
}
|
|
U.log(("box %d reads:"):format(#boxes), boxes[#boxes].text)
|
|
-- let the typewriter finish before the shot so the capture shows the
|
|
-- line; the auto sample above already happened on the open frame
|
|
for _ = 1, 240 do
|
|
if top.waiting or top.done or game.stack:top() ~= top then break end
|
|
U.wait(1)
|
|
budget = budget - 1
|
|
end
|
|
U.shot(game, DIR .. ("/bug867_box%d.png"):format(#boxes))
|
|
end
|
|
U.tap(game, "a")
|
|
U.wait(3)
|
|
budget = budget - 4
|
|
else
|
|
if #boxes >= 2 then break end
|
|
U.wait(1)
|
|
budget = budget - 1
|
|
end
|
|
end
|
|
|
|
check("the send-off is two boxes, not one (#867)", #boxes == 2)
|
|
check("box 1 is the CUBONE's-mother line",
|
|
boxes[1] ~= nil and boxes[1].text:find("CUBONE", 1, true) ~= nil)
|
|
check("box 1 opens silent (the asm plays no cry before it)",
|
|
boxes[1] ~= nil and not boxes[1].cry)
|
|
check("box 2 is the calmed line",
|
|
boxes[2] ~= nil and boxes[2].text:find("calmed", 1, true) ~= nil)
|
|
check("box 2 opens with the MAROWAK cry armed",
|
|
boxes[2] ~= nil and boxes[2].cry == true)
|
|
|
|
-- ---- the trigger is spent ----------------------------------------------
|
|
-- step off and back onto (10, 16): with the flag set, onStep must pass
|
|
local back = ({ down = "up", up = "down", left = "right", right = "left" })
|
|
[STAND.step]
|
|
U.hold(game, back, 20)
|
|
U.wait(10)
|
|
U.hold(game, STAND.step, 20)
|
|
U.wait(20)
|
|
check("re-stepping the trigger cell stays quiet",
|
|
getmetatable(game.stack:top()) ~= TextBox)
|
|
U.shot(game, DIR .. "/bug867_after.png")
|
|
U.log(("machine checks: %d passed, %d failed"):format(pass, fail))
|
|
|
|
-- ---- hand off ----------------------------------------------------------
|
|
U.log("The pad is yours on 6F with the ghost already sent off. What should")
|
|
U.log("have happened: after the win, \"The GHOST was the / restless soul of /")
|
|
U.log("CUBONE's mother!\" first, then the MAROWAK cry sounds as the second box")
|
|
U.log("opens with \"The mother's soul / was calmed.\" The old bug jumped")
|
|
U.log("straight to the calmed line, no mother line and no cry at all.")
|
|
U.log("Screenshots: " .. DIR .. "/bug867_*.png")
|
|
|
|
while true do
|
|
coroutine.yield()
|
|
end
|
|
end
|