mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
209 lines
8.1 KiB
Lua
209 lines
8.1 KiB
Lua
-- pokefirered/data/scripts/pc.inc:1
|
|
local U = require("tests.drivers.util")
|
|
local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/game3_pc_rom_script"
|
|
|
|
local FLAG_SYS_POKEDEX_GET = 0x829 -- include/constants/flags.h:1375
|
|
local FLAG_SYS_GAME_CLEAR = 0x82C -- include/constants/flags.h:1378
|
|
local FLAG_SYS_PC_STORAGE_DISABLED = 0x841 -- include/constants/flags.h:1399
|
|
local MB_PC = 0x83 -- include/constants/metatile_behaviors.h:94
|
|
local SE_PC_LOGIN = 2 -- include/constants/songs.h:6
|
|
local VAR_MAP_SCENE_ONE_ISLAND_POKEMON_CENTER_1F = 0x4076 -- include/constants/vars.h:170
|
|
|
|
local failures = 0
|
|
local function result(ok, label)
|
|
print((ok and "PASS " or "FAIL ") .. label)
|
|
if not ok then failures = failures + 1 end
|
|
return ok
|
|
end
|
|
|
|
local function finish()
|
|
if failures == 0 then
|
|
print("PASS game3_pc_rom_script")
|
|
love.event.quit(0)
|
|
else
|
|
print("FAIL game3_pc_rom_script failures=" .. failures)
|
|
love.event.quit(1)
|
|
end
|
|
end
|
|
|
|
local function flat(s)
|
|
return (tostring(s or ""):gsub("[\n\f]", " "))
|
|
end
|
|
|
|
local function Message() return require("src.ui.game3.message") end
|
|
local function PcMenu() return require("src.ui.game3.pc_menu") end
|
|
local function Choice() return require("src.ui.game3.choice") end
|
|
|
|
local function waitPage(game, pattern, frames)
|
|
local seen = {}
|
|
for _ = 1, frames do
|
|
local M = Message()
|
|
if M.isOpen() then
|
|
local page = flat(M.currentPage())
|
|
if page:find(pattern, 1, true) then
|
|
while not M.isWaiting() do U.wait(1) end
|
|
return true, page
|
|
end
|
|
if seen[#seen] ~= page then seen[#seen + 1] = page end
|
|
if M.isWaiting() and not (Choice().active) then
|
|
U.tap(game, "a")
|
|
end
|
|
end
|
|
if Choice().active then U.tap(game, "a") end
|
|
U.wait(1)
|
|
end
|
|
return false, table.concat(seen, " | ")
|
|
end
|
|
|
|
local function waitMenu(game, frames)
|
|
for _ = 1, frames do
|
|
local P = PcMenu()
|
|
if P.isOpen() and P.mode == "root" then return true end
|
|
local M = Message()
|
|
local prompt = flat(M.currentPage()):find("Which PC should be accessed?", 1, true)
|
|
if M.isOpen() and M.isWaiting() and not prompt then U.tap(game, "a") end
|
|
U.wait(1)
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function pickRow(game, id)
|
|
local P = PcMenu()
|
|
for i, r in ipairs(P._rootEntries()) do
|
|
if r.id == id then P.cursor = i end
|
|
end
|
|
U.tap(game, "a")
|
|
end
|
|
|
|
local function waitReleased(game, frames)
|
|
local Space = require("src.core.game3.scripting.space")
|
|
for _ = 1, frames do
|
|
local running = Space.vm and Space.vm:isRunning()
|
|
if not running and not Message().isOpen() and not PcMenu().isOpen() then return true end
|
|
if Message().isOpen() and Message().isWaiting() then U.tap(game, "a") end
|
|
U.wait(1)
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function standAtPc(game, mapId)
|
|
local Map = require("src.core.game3.map")
|
|
Map.load(nil, game, mapId, { x = 1, y = 1, facing = "up" })
|
|
U.wait(30)
|
|
local Collision = require("src.core.game3.collision")
|
|
for y = 1, 20 do
|
|
for x = 0, 30 do
|
|
if Collision.behavior(x, y) == MB_PC then
|
|
Map.load(nil, game, mapId, { x = x, y = y + 1, facing = "up" })
|
|
game.session.x, game.session.y, game.session.facing = x, y + 1, "up"
|
|
U.wait(60)
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
return function(game)
|
|
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 MapCatalog = require("src.import.gba.map_catalog")
|
|
local Space = require("src.core.game3.scripting.space")
|
|
local Flags = require("src.core.game3.scripting.flags")
|
|
local session = Runtime.getSession()
|
|
if not result(session ~= nil, "new game reached the game3 field") then return finish() end
|
|
|
|
local Audio = require("src.core.game3.audio")
|
|
local origSe = Audio.playSe
|
|
local seLog = {}
|
|
Audio.playSe = function(id, ...)
|
|
seLog[#seLog + 1] = id
|
|
return origSe(id, ...)
|
|
end
|
|
|
|
-- data/maps/OneIsland_PokemonCenter_1F/scripts.inc:116
|
|
local ONE = MapCatalog.pretToEngine("OneIsland_PokemonCenter_1F")
|
|
Flags.setVar(Space.store, nil, VAR_MAP_SCENE_ONE_ISLAND_POKEMON_CENTER_1F, 1)
|
|
Flags.setFlag(Space.store, nil, FLAG_SYS_PC_STORAGE_DISABLED, true)
|
|
if not result(standAtPc(game, ONE), "One Island Pokemon Center PC found") then return finish() end
|
|
U.tap(game, "a")
|
|
local ok, page = waitPage(game, "The usual PC services aren't available…", 300)
|
|
result(ok, "One Island before Celio: \"The usual PC services aren't available…\" (got " .. page .. ")")
|
|
if ok then U.shot(game, DIR .. "/pc_one_island_services_unavailable.png") end
|
|
result(not PcMenu().isOpen(), "One Island PC does not open the PC menu")
|
|
result(waitReleased(game, 300), "One Island PC releases the player")
|
|
Flags.setFlag(Space.store, nil, FLAG_SYS_PC_STORAGE_DISABLED, false)
|
|
|
|
local VIRIDIAN = "FR_VIRIDIAN_CITY_POKEMON_CENTER_1F"
|
|
if not result(standAtPc(game, VIRIDIAN), "Viridian Pokemon Center PC found") then return finish() end
|
|
Flags.setFlag(Space.store, nil, FLAG_SYS_POKEDEX_GET, true)
|
|
U.tap(game, "a")
|
|
if not result(waitMenu(game, 300), "PC menu opens after booted-up text") then return finish() end
|
|
pickRow(game, "oak")
|
|
ok, page = waitPage(game, "Accessed PROF. OAK's PC…", 300)
|
|
result(ok, "Oak's PC: \"Accessed PROF. OAK's PC…\" (got " .. page .. ")")
|
|
ok, page = waitPage(game, "PROF. OAK's rating:", 2400)
|
|
result(ok, "Oak's PC runs PokedexRating_EventScript_Rate (got " .. page .. ")")
|
|
if ok then U.shot(game, DIR .. "/pc_oak_pc_rating.png") end
|
|
ok, page = waitPage(game, "Closed link to PROF. OAK's PC.", 3000)
|
|
result(ok, "Oak's PC: \"Closed link to PROF. OAK's PC.\" (got " .. page .. ")")
|
|
result(waitMenu(game, 300), "Oak's PC returns to the PC menu")
|
|
pickRow(game, "quit")
|
|
result(waitReleased(game, 300), "LOG OFF releases the player")
|
|
|
|
Flags.setFlag(Space.store, nil, FLAG_SYS_GAME_CLEAR, true)
|
|
session.gameStats = session.gameStats or {}
|
|
session.gameStats[10] = 3
|
|
session.hallOfFameTeams = {
|
|
{
|
|
{ species = 6, level = 50, nickname = "CHARIZARD", trainerId = 12345, personality = 0 },
|
|
{ species = 25, level = 42, nickname = "SPARKY", trainerId = 12345, personality = 0xFF },
|
|
{ species = 412, level = 5, nickname = "EGG", trainerId = 12345, personality = 0 },
|
|
},
|
|
{
|
|
{ species = 3, level = 61, nickname = "VENUSAUR", trainerId = 12345, personality = 0x10 },
|
|
{ species = 9, level = 60, nickname = "BLASTOISE", trainerId = 12345, personality = 0 },
|
|
{ species = 65, level = 58, nickname = "ALAKAZAM", trainerId = 12345, personality = 0xF0 },
|
|
{ species = 143, level = 55, nickname = "SNORLAX", trainerId = 12345, personality = 0 },
|
|
{ species = 130, level = 55, nickname = "GYARADOS", trainerId = 12345, personality = 0 },
|
|
{ species = 29, level = 50, nickname = "NIDORAN", trainerId = 12345, personality = 0 },
|
|
},
|
|
}
|
|
U.tap(game, "a")
|
|
if not result(waitMenu(game, 300), "PC menu opens with HALL OF FAME row") then return finish() end
|
|
local mark = #seLog
|
|
pickRow(game, "hall")
|
|
local HofPc = require("src.ui.game3.hall_of_fame_pc")
|
|
for _ = 1, 120 do
|
|
if HofPc.isOpen() then break end
|
|
U.wait(1)
|
|
end
|
|
if not result(HofPc.isOpen(), "HALL OF FAME row opens the HoF PC viewer") then return finish() end
|
|
local login = false
|
|
for i = mark + 1, #seLog do if seLog[i] == SE_PC_LOGIN then login = true end end
|
|
result(login, "AccessHallOfFame plays SE_PC_LOGIN from the ROM script")
|
|
result(HofPc._team == 2 and HofPc._number == 3, "viewer starts on the newest team, HALL OF FAME No. 3")
|
|
U.wait(30)
|
|
U.shot(game, DIR .. "/pc_hof_viewer_newest_team.png")
|
|
U.tap(game, "a")
|
|
U.wait(20)
|
|
result(HofPc._team == 1 and HofPc._number == 2, "A steps to the older team, No. 2")
|
|
U.tap(game, "down")
|
|
U.wait(20)
|
|
result(HofPc._mon == 2, "DOWN selects the second member")
|
|
U.shot(game, DIR .. "/pc_hof_viewer_older_team_mon2.png")
|
|
U.tap(game, "b")
|
|
result(waitMenu(game, 300) and not HofPc.isOpen(), "B leaves the viewer and reshows the PC menu")
|
|
pickRow(game, "quit")
|
|
result(waitReleased(game, 300), "LOG OFF after the viewer releases the player")
|
|
|
|
Audio.playSe = origSe
|
|
finish()
|
|
end
|