Files
gen1recomp/tests/drivers/game3_encounters_dark_cave.lua

199 lines
6.6 KiB
Lua

local U = require("tests.drivers.util")
local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/game3_encounters_dark_cave"
local ROCK_TUNNEL = "FR_ROCK_TUNNEL_1F"
local ROCK_TUNNEL_B1F = "FR_ROCK_TUNNEL_B1F"
local ROUTE_10 = "FR_ROUTE_10"
-- pokefirered/include/constants/flags.h:1364
local FLAG_BADGE01_GET = 0x820
-- pokefirered/include/constants/flags.h:1333
local FLAG_SYS_FLASH_ACTIVE = 0x806
-- pokefirered/include/constants/flags.h:1374
local FLAG_SYS_POKEMON_GET = 0x828
-- pokefirered/include/constants/moves.h:152
local MOVE_FLASH = 148
local ENTRY_X, ENTRY_Y = 17, 3
return function(game)
local fails = 0
local function result(ok, label)
print((ok and "PASS " or "FAIL ") .. label)
if not ok then fails = fails + 1 end
return ok
end
local function finish()
if fails == 0 then
print("PASS encounters_dark_cave")
love.event.quit(0)
else
print("FAIL encounters_dark_cave failures=" .. fails)
love.event.quit(1)
end
end
for _ = 1, 900 do
if game.phase == "boot" and game.boot then break end
U.wait(1)
end
game:_handleBootAction({ action = "new_game", name = "RED" })
U.wait(240)
local Runtime = require("src.core.game3.runtime")
local Party = require("src.core.game3.party")
local Map = require("src.core.game3.map")
local Player = require("src.core.game3.player")
local Space = require("src.core.game3.scripting.space")
local Flags = require("src.core.game3.scripting.flags")
local StartMenu = require("src.ui.game3.start_menu")
local PartyMenu = require("src.ui.game3.party_menu")
local Message = require("src.ui.game3.message")
local FieldView = require("src.core.game3.field_view")
local FieldEffects = require("src.core.game3.field_effects")
local Field = require("src.core.game3.field")
local session = Runtime.getSession()
if not result(session ~= nil, "new game reached the game3 field") then return finish() end
local function ctx() return Space.vm and Space.vm.ctx end
session.party = {}
Party.giveMon(session, 25, 20)
local lead = session.party[1]
lead.moves = { MOVE_FLASH }
lead.pp = { 20 }
lead.maxPp = { 20 }
Flags.setFlag(Space.store, ctx(), FLAG_BADGE01_GET, true)
Flags.setFlag(Space.store, ctx(), FLAG_SYS_POKEMON_GET, true)
local function placeAt(mapId, x, y, facing)
Map.load(nil, game, mapId, { x = x, y = y, facing = facing or "down" })
if game.session then
game.session.x, game.session.y, game.session.facing = x, y, facing or "down"
end
Player.cellX, Player.cellY = x, y
Player.px, Player.py = x * 16, y * 16
Player.targetX, Player.targetY = x, y
Player.facing = facing or "down"
U.wait(90)
end
local function flashActive()
return Flags.getFlag(Space.store, ctx(), FLAG_SYS_FLASH_ACTIVE) == true
end
placeAt(ROCK_TUNNEL, ENTRY_X, ENTRY_Y, "down")
local def = game.data and game.data.maps and game.data.maps[ROCK_TUNNEL]
result(def ~= nil and (tonumber(def.cave) or 0) == 1,
"Rock Tunnel 1F carries requires_flash in its map header")
result(not flashActive(), "FLAG_SYS_FLASH_ACTIVE is clear on arrival")
result(FieldView.getFlashLevel() == 4,
"the cave loads at gMaxFlashLevel (" .. tostring(FieldView.getFlashLevel()) .. ")")
result(FieldView.flashRadius() == 24, "the visible window is a 24px radius")
U.shot(game, DIR .. "/dark_cave_01_dark.png")
U.tap(game, "start")
U.wait(30)
if not result(StartMenu.isOpen(), "start menu opened") then return finish() end
local pokeIdx
for i, e in ipairs(StartMenu.ENTRIES or {}) do
if e.id == "pokemon" then pokeIdx = i end
end
if not result(pokeIdx ~= nil, "start menu lists POKEMON") then return finish() end
for _ = 1, 20 do
if StartMenu.cursor == pokeIdx then break end
U.tap(game, "down")
U.wait(6)
end
U.tap(game, "a")
U.wait(60)
if not result(PartyMenu.isOpen and PartyMenu.isOpen(), "party menu opened") then
return finish()
end
U.tap(game, "a")
U.wait(30)
local flashIdx
for i, act in ipairs(PartyMenu.ACTIONS or {}) do
if act == "FLASH" then flashIdx = i end
end
U.log("party actions: " .. table.concat(PartyMenu.ACTIONS or {}, ", "))
if not result(flashIdx ~= nil, "FLASH is offered on the lead's action menu") then
return finish()
end
for _ = 1, 20 do
if PartyMenu.actionCursor == flashIdx then break end
U.tap(game, "down")
U.wait(6)
end
U.tap(game, "a")
for _ = 1, 60 do
if flashActive() then break end
U.wait(2)
end
local txt = Message.currentPage and Message.currentPage()
if type(txt) == "string" and txt ~= "" then
U.log("dialog: " .. txt:gsub("\n", " / "))
end
result(flashActive(), "using Flash set FLAG_SYS_FLASH_ACTIVE")
local grew = false
local last = FieldView.flashRadius() or 0
local unlockedEarly = false
for _ = 1, 30 do
U.wait(4)
local r = FieldView.flashRadius()
if r == nil or r > last then grew = true end
if r then last = r end
if r and not Field.locked then unlockedEarly = true end
if r and r > 90 then break end
end
result(grew, "the lit radius is opening out (" .. tostring(last) .. "px)")
-- pokefirered/src/field_screen_effect.c:202
result(not unlockedEarly, "the player stays locked while the circle is opening")
U.shot(game, DIR .. "/dark_cave_02_opening.png")
for _ = 1, 120 do
if FieldView.getFlashLevel() == 0 and FieldView.flashRadius() == nil then break end
U.wait(4)
end
result(FieldView.getFlashLevel() == 0, "AnimateFlash ended on flash level 0")
result(FieldView.flashRadius() == nil, "nothing is masked any more")
U.wait(10)
result(not Field.locked, "and control comes back when the animation ends")
U.wait(30)
U.shot(game, DIR .. "/dark_cave_03_lit.png")
placeAt(ROCK_TUNNEL_B1F, 5, 5, "down")
result(FieldView.getFlashLevel() == 0,
"B1F stays lit while FLAG_SYS_FLASH_ACTIVE is set")
placeAt(ROUTE_10, 11, 19, "down")
U.wait(60)
result(FieldView.getFlashLevel() == 0, "Route 10 is never masked")
result(not flashActive(), "ClearTempFieldEventData drops the flag outdoors")
placeAt(ROCK_TUNNEL, ENTRY_X, ENTRY_Y, "down")
result(FieldView.getFlashLevel() == 4, "walking back in is dark again")
-- pokefirered/src/field_effect.c:1258
FieldEffects.startLandingShake()
local pans, zero = {}, false
for _ = 1, 16 do
pans[#pans + 1] = FieldView.cameraPanY
U.wait(1)
end
for _ = 1, 30 do
if FieldView.cameraPanY == 0 then zero = true break end
U.wait(1)
end
local shook = false
for _, p in ipairs(pans) do
if p ~= 0 then shook = true end
end
U.log("camera pan samples: " .. table.concat(pans, ","))
result(shook, "the fall landing shakes the camera")
result(zero, "and the camera settles back at 0")
finish()
end