mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 05:32:07 -04:00
186 lines
7.3 KiB
Lua
186 lines
7.3 KiB
Lua
#!/usr/bin/env luajit
|
|
-- pokefirered/src/daycare.c:1749
|
|
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
|
|
local failed = 0
|
|
local function check(cond, msg)
|
|
if cond then
|
|
print("[ok] " .. msg)
|
|
else
|
|
failed = failed + 1
|
|
print("[FAIL] " .. msg)
|
|
end
|
|
end
|
|
|
|
local function eq(a, b, msg)
|
|
check(a == b, string.format("%s (%s == %s)", msg, tostring(a), tostring(b)))
|
|
end
|
|
|
|
local function finish()
|
|
if failed > 0 then
|
|
print("[test] FAILED " .. failed)
|
|
os.exit(1)
|
|
end
|
|
print("[test] all passed")
|
|
os.exit(0)
|
|
end
|
|
|
|
local songs, ses, fanfares, cries = {}, {}, {}, {}
|
|
package.loaded["src.core.game3.audio"] = setmetatable({
|
|
_mapSong = 101,
|
|
playSong = function(id) songs[#songs + 1] = id end,
|
|
playSe = function(id) ses[#ses + 1] = id end,
|
|
playFanfare = function(id) fanfares[#fanfares + 1] = id end,
|
|
playCry = function(id) cries[#cries + 1] = id end,
|
|
isCryFinished = function() return true end,
|
|
isFanfareFinished = function() return true end,
|
|
}, { __index = function() return function() end end })
|
|
|
|
local hudMessages = {}
|
|
package.loaded["src.ui.game3.hud"] = {
|
|
openMessage = function(_game, text, opts)
|
|
hudMessages[#hudMessages + 1] = text
|
|
if opts and opts.done then opts.done() end
|
|
end,
|
|
}
|
|
|
|
local store = { flags = {}, vars = {} }
|
|
local session = {
|
|
store = store, map = "FR_FOUR_ISLAND_POKEMON_DAY_CARE", party = {},
|
|
name = "RED", trainerId = 4242, vars = {}, flags = {},
|
|
dex = { seen = {}, owned = {} },
|
|
}
|
|
package.loaded["src.core.game3.runtime"] = {
|
|
getSession = function() return session end,
|
|
isActive = function() return true end,
|
|
}
|
|
|
|
local Daycare = require("src.core.game3.daycare")
|
|
local StepEvents = require("src.core.game3.step_events")
|
|
local EggHatch = require("src.ui.game3.egg_hatch")
|
|
local Stack = require("src.ui.game3.stack")
|
|
local Message = require("src.ui.game3.message")
|
|
local Choice = require("src.ui.game3.choice")
|
|
|
|
print("[test] 1. the hatch scene is its own scene, not the evolution scene")
|
|
-- pokefirered/src/daycare.c:1749 EggHatch is a CB2 of its own
|
|
check(type(EggHatch.start) == "function", "src/ui/game3/egg_hatch.lua exposes start")
|
|
local stepSource = assert(io.open("src/core/game3/step_events.lua")):read("*a")
|
|
check(stepSource:find("src.ui.game3.egg_hatch", 1, true) ~= nil,
|
|
"the hatch leg of step_events opens the egg-hatch scene")
|
|
check(stepSource:find("evolution_scene", 1, true) == nil,
|
|
"and no longer routes a hatching EGG into the evolution scene")
|
|
|
|
local Cache = require("tests.game3_cache")
|
|
local cacheRoot = Cache.mount("meta.json")
|
|
if not cacheRoot then
|
|
print("[skip] game3_daycare_hatch_test needs species data: " .. tostring(Cache.reason))
|
|
finish()
|
|
end
|
|
print("[info] FireRed cache at " .. cacheRoot)
|
|
|
|
local Pokemon = require("src.core.game3.pokemon")
|
|
Pokemon.install(nil)
|
|
local Party = require("src.core.game3.party")
|
|
local Breeding = require("src.core.game3.breeding")
|
|
|
|
local MAGIKARP = 129
|
|
|
|
print("[test] 2. an egg in the party hatches out of the daycare step counter")
|
|
local scratch = { party = {}, name = "RED", trainerId = 4242, map = session.map }
|
|
local ok, _, egg = Party.giveMon(scratch, MAGIKARP, 5, "EGG")
|
|
check(ok, "built a MAGIKARP")
|
|
Breeding.applyEggData(egg, true)
|
|
egg.nickname = "EGG"
|
|
-- pokefirered/src/daycare.c:1106 METLOC_SPECIAL_EGG
|
|
eq(egg.metLocation, 253, "CreateEgg's hot springs met location")
|
|
local cycles = tonumber(Pokemon.speciesMeta(MAGIKARP).eggCycles)
|
|
eq(egg.friendship, cycles, "the hatch counter is the species' eggCycles")
|
|
session.party = { egg }
|
|
session.dex = { seen = {}, owned = {} }
|
|
StepEvents.flush()
|
|
|
|
local dc = Daycare.stateOf(session)
|
|
dc.stepCounter = 0
|
|
local steps, hatchEvent = 0, nil
|
|
while steps < 256 * (cycles + 3) and not hatchEvent do
|
|
StepEvents.onStepTaken(session, nil)
|
|
steps = steps + 1
|
|
for _, event in ipairs(StepEvents._queue) do
|
|
if event.type == "egg_hatch" then hatchEvent = event end
|
|
end
|
|
end
|
|
check(hatchEvent ~= nil, "the egg queued its hatch event")
|
|
-- pokefirered/src/daycare.c:1157
|
|
eq(steps, 255 + cycles * 256, "on the cart's 255 + eggCycles * 256th step")
|
|
check(not session.dex.seen[MAGIKARP], "and the egg was still unknown to the POKeDEX")
|
|
-- pokefirered/src/field_control_avatar.c:672 GAME_STAT_HATCHED_EGGS
|
|
eq(session.gameStats and session.gameStats[13], 1, "the hatched-eggs game stat went up")
|
|
|
|
print("[test] 3. the scene shows Huh? then the hatch line, not an evolution")
|
|
local doneResult = nil
|
|
hatchEvent.run(function(result) doneResult = result end)
|
|
-- pokefirered/data/scripts/day_care.inc:112 DayCare_Text_Huh
|
|
eq(hudMessages[1], "Huh?", "the field script prints DayCare_Text_Huh first")
|
|
check(EggHatch.isOpen(), "the egg-hatch scene is on the stack")
|
|
check(Stack.has("egg_hatch"), "as its own stack layer")
|
|
check(not Stack.has("evolution_scene"), "and no evolution scene was pushed")
|
|
eq(egg.isEgg, false, "AddHatchedMonToParty ran at scene setup")
|
|
check(session.dex.seen[MAGIKARP], "which is where the POKeDEX flags are set")
|
|
|
|
local guard = 0
|
|
local framesSeen, maxShards = {}, 0
|
|
while EggHatch._state ~= "hatched_msg" and guard < 600 do
|
|
EggHatch.update(1 / 60)
|
|
local f = EggHatch._eggFrame or 0
|
|
if framesSeen[#framesSeen] ~= f then framesSeen[#framesSeen + 1] = f end
|
|
maxShards = math.max(maxShards, #(EggHatch._shards or {}))
|
|
guard = guard + 1
|
|
end
|
|
eq(EggHatch._state, "hatched_msg", "the shake sequence reached the hatch message")
|
|
-- pokefirered/src/daycare.c:2009 StartSpriteAnim 1, then 2, then 2 again
|
|
eq(table.concat(framesSeen, ","), "0,1,2", "the egg walked sEggHatchTiles frames 0, 1, 2")
|
|
-- pokefirered/src/daycare.c:2128 CreateRandomEggShardSprite
|
|
check(maxShards >= 16, "the shards flew, most of them at the flash, got " .. tostring(maxShards))
|
|
-- pokefirered/src/daycare.c:2091 PlaySE(SE_EGG_HATCH)
|
|
check(ses[#ses] == 106, "SE_EGG_HATCH closed the crack sequence, got " .. tostring(ses[#ses]))
|
|
check(Message.isOpen(), "the message box is open")
|
|
local page = Message.currentPage() or ""
|
|
check(tostring(page):find("hatched from the EGG", 1, true) ~= nil,
|
|
"gText_HatchedFromEgg is on screen, got " .. tostring(page))
|
|
-- pokefirered/src/daycare.c:1929 PlayFanfare(MUS_EVOLVED)
|
|
eq(fanfares[1], 259, "MUS_EVOLVED played")
|
|
eq(cries[1], MAGIKARP, "the hatchling cried")
|
|
-- pokefirered/src/daycare.c:2008 PlaySE(SE_BALL)
|
|
check(#ses >= 4, "the egg cracked on all four PlaySE(SE_BALL) beats, got " .. tostring(#ses))
|
|
|
|
print("[test] 4. the nickname prompt, and No returns to the field")
|
|
guard = 0
|
|
while EggHatch._state ~= "nickname_ask" and guard < 600 do
|
|
EggHatch.update(1 / 60)
|
|
guard = guard + 1
|
|
end
|
|
eq(EggHatch._state, "nickname_ask", "the scene asked about a nickname")
|
|
page = Message.currentPage() or ""
|
|
check(tostring(page):find("nickname the newly", 1, true) ~= nil,
|
|
"gText_NickHatchPrompt is on screen, got " .. tostring(page))
|
|
check(Choice.active, "the yes/no menu is up")
|
|
eq(Choice.left, 21, "at sYesNoWinTemplate's tilemapLeft")
|
|
eq(Choice.top, 9, "and tilemapTop")
|
|
Choice.cancel()
|
|
guard = 0
|
|
while EggHatch.isOpen() and guard < 600 do
|
|
EggHatch.update(1 / 60)
|
|
guard = guard + 1
|
|
end
|
|
check(not EggHatch.isOpen(), "the scene closed")
|
|
-- pokefirered/src/daycare.c:2125 DestroySprite past y2 > 20
|
|
check(#(EggHatch._shards or {}) == 0, "every shard fell past its 20px floor")
|
|
check(not Stack.has("egg_hatch"), "and left the stack")
|
|
eq(doneResult, "hatched", "the step event was released")
|
|
eq(songs[#songs], 101, "the map song came back")
|
|
eq(egg.nickname, "", "declining the prompt leaves the species name")
|
|
|
|
finish()
|