Files
gen1recomp/tests/game3_hall_of_fame_test.lua

145 lines
5.2 KiB
Lua

#!/usr/bin/env luajit
-- FRLG Hall of Fame Induction Screen & Egg Skipping Unit Test Suite
package.path = "./?.lua;./?/init.lua;" .. package.path
local Game3Cache = require("tests.game3_cache")
if not Game3Cache.bundle() then print("[skip] hall_of_fame: " .. tostring(Game3Cache.reason)) return end
local failed = 0
local function check(cond, msg)
if cond then
print("[ok] " .. msg)
else
failed = failed + 1
print("[FAIL] " .. msg)
end
end
local HallOfFame = require("src.ui.game3.hall_of_fame")
local Pokemon = require("src.core.game3.pokemon")
local Adapters = require("src.core.game3.scripting.adapters")
local Natives = require("src.core.game3.scripting.natives")
local Std = require("src.core.game3.scripting.stdscripts")
print("=== [TEST 1] Hall of Fame induction order and timing ===")
do
local party = {
{ species = 6, name = "CHARIZARD", level = 55, otId = 12345, moves = { "FLAMETHROWER", "FLY", "SLASH", "FIRE_SPIN" } },
{ species = 412, isEgg = true, egg = true, name = "EGG", level = 1 }, -- Egg in slot 2
{ species = 25, name = "PIKACHU", level = 52, otId = 12345, moves = { "THUNDERBOLT", "QUICK_ATTACK", "THUNDER_WAVE", "SLAM" } },
{ species = 175, egg = true, name = "TOGEPI EGG", level = 1 }, -- Egg in slot 4
{ species = 9, name = "BLASTOISE", level = 54, otId = 12345, moves = { "SURF", "HYDRO_PUMP", "ICE_BEAM", "BITE" } },
{ species = 143, name = "SNORLAX", level = 53, otId = 12345, moves = { "BODY_SLAM", "REST", "HYPER_BEAM", "EARTHQUAKE" } },
}
local session = {
name = "RED",
trainerId = 12345,
playTimeHours = 14,
playTimeMinutes = 22,
playTimeSeconds = 35,
party = party,
flags = {},
}
local doneCalled = false
HallOfFame.start({
session = session,
onDone = function() doneCalled = true end,
warp = false,
})
check(HallOfFame.isOpen() == true, "HallOfFame is open")
-- pokefirered/src/hall_of_fame.c:390
check(#HallOfFame._mons == 6, "every occupied party slot is inducted, eggs included")
local inpA = {
wasPressed = function(_, k) return k == "a" end,
isDown = function() return false end,
}
local shown = {}
local lastInfo = nil
local frames = 0
while HallOfFame.isOpen() and HallOfFame.phase() ~= "exitwait" and frames < 20000 do
HallOfFame.handleInput(inpA)
HallOfFame.update(1 / 60)
frames = frames + 1
if HallOfFame._info and HallOfFame._info ~= lastInfo then
lastInfo = HallOfFame._info
shown[#shown + 1] = lastInfo.name
end
end
check(HallOfFame.phase() == "exitwait", "the induction ran to the player card on its own timers")
check(table.concat(shown, ",") == "CHARIZARD,EGG,PIKACHU,TOGEPI EGG,BLASTOISE,SNORLAX",
"mons were shown in party order: " .. table.concat(shown, ","))
check(HallOfFame.isOpen() == true, "A presses before the player card did not close the screen")
HallOfFame.handleInput(inpA)
for _ = 1, 400 do
if not HallOfFame.isOpen() then break end
HallOfFame.update(1 / 60)
end
check(HallOfFame.isOpen() == false, "HallOfFame closed cleanly")
check(doneCalled == true, "onDone credits yield callback executed")
-- Verify Flag & Debut Timestamp Recording
check(session.flags[0x82C] == true, "FLAG_SYS_GAME_CLEAR (0x82C) is set")
check(session.game_cleared == true, "session.game_cleared is true")
check(session.hofDebutTime == "14:22:35", "session.hofDebutTime stamped correctly")
check(session.hofDebutHours == 14 and session.hofDebutMinutes == 22, "hofDebutHours and Minutes stamped")
check(#session.hallOfFameTeams == 1, "Hall of fame team record saved")
local rec = session.hallOfFameTeams[1]
check(#rec == 6, "Saved team record keeps all 6 party slots (hall_of_fame.c:389)")
check(rec[2].species == 412 and rec[4].species == 412, "Eggs are recorded as SPECIES_EGG")
check(session.gameStats[10] == 1, "GAME_STAT_ENTERED_HOF incremented (save.c:665)")
end
print("=== [TEST 2] Scripting Special Native EnterHallOfFame Integration ===")
do
local hofCalled = false
local session = {
flags = {},
party = { { species = 1, name = "BULBASAUR", level = 50 } },
playTimeHours = 5,
playTimeMinutes = 10,
}
local adapters = Adapters.stub({
session = session,
hallOfFame = function(done)
hofCalled = true
HallOfFame.start({
session = session,
onDone = done,
warp = false,
})
end,
})
local nativeFn = Natives.ALLOW["special:" .. Std.SPECIAL.EnterHallOfFame]
check(type(nativeFn) == "function", "Special 272 EnterHallOfFame handler exists")
local ctx = { pc = 1, waiting = false }
local yielded = nativeFn(ctx, adapters)
check(yielded == true, "Special EnterHallOfFame yielded execution to HallOfFame")
check(hofCalled == true, "adapters.hallOfFame was invoked")
check(HallOfFame.isOpen() == true, "HallOfFame UI is open")
for _ = 1, 200 do
if HallOfFame.phase() == "display" then break end
HallOfFame.update(1 / 60)
end
check(session.flags[0x82C] == true, "FLAG_SYS_GAME_CLEAR saved with the induction")
-- Close
HallOfFame.close()
check(HallOfFame.isOpen() == false, "HallOfFame closed")
end
if failed > 0 then
print(string.format("\n[FAILED] %d test(s) failed", failed))
os.exit(1)
else
print("\nALL HALL OF FAME TESTS PASSED CLEANLY!")
end