mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 05:32:07 -04:00
151 lines
7.6 KiB
Lua
151 lines
7.6 KiB
Lua
-- Tests for 1:1 National Pokédex Gating, Systems, and Story Triggers matching pret pokefirered.
|
|
|
|
require("tests.game3_cache").requireData("game3_national_dex_test")
|
|
local Dex = require("src.core.game3.dex")
|
|
local PokedexData = require("src.core.game3.pokedex_data")
|
|
local Evolution = require("src.core.game3.evolution")
|
|
local ItemUse = require("src.core.game3.item_use")
|
|
local Std = require("src.core.game3.scripting.stdscripts")
|
|
local Natives = require("src.core.game3.scripting.natives")
|
|
local Flags = require("src.core.game3.scripting.flags")
|
|
|
|
print("=== [TEST 1] National Dex specials constants ===")
|
|
assert(Std.SPECIAL.EnableNationalPokedex == 0x16F, "EnableNationalPokedex special constant must be 0x16F")
|
|
assert(Std.SPECIAL.SetUnlockedPokedexFlags == 0x181, "SetUnlockedPokedexFlags special constant must be 0x181")
|
|
assert(Std.SPECIAL.IsNationalPokedexEnabled == 0x193, "IsNationalPokedexEnabled special constant must be 0x193")
|
|
print("[PASS] Special constants match pret specials.inc (0x16F, 0x181, 0x193)")
|
|
|
|
print("=== [TEST 2] Script Special Execution & State Machine ===")
|
|
local store = Flags.newStore()
|
|
local Space = { store = store }
|
|
function Space.ensureBundle()
|
|
if not Space.bundle then require("tests.game3_cache").bundle() end
|
|
return Space.bundle
|
|
end
|
|
package.loaded["src.core.game3.scripting.space"] = Space
|
|
|
|
local session = {
|
|
national_dex_unlocked = false,
|
|
dex = Dex.new(),
|
|
store = store,
|
|
}
|
|
local Runtime = {
|
|
getSession = function() return session end,
|
|
}
|
|
package.loaded["src.core.game3.runtime"] = Runtime
|
|
|
|
-- 1. Check IsNationalPokedexEnabled before unlock (should be 0)
|
|
local ctx = require("src.core.game3.scripting.ctx").new({})
|
|
Flags.setVar(store, ctx, 0x800D, 9)
|
|
local _, natVal = Natives.special(ctx, Std.SPECIAL.IsNationalPokedexEnabled)
|
|
assert(natVal == 0, "IsNationalPokedexEnabled should hand specialvar 0 before unlock")
|
|
assert(Flags.getVar(store, ctx, 0x800D) == 0, "IsNationalPokedexEnabled should set VAR_RESULT to 0 before unlock")
|
|
assert(not PokedexData.isNationalUnlocked(session, session.dex), "isNationalUnlocked must return false before unlock")
|
|
|
|
-- 2. Execute EnableNationalPokedex
|
|
Natives.special(ctx, Std.SPECIAL.EnableNationalPokedex)
|
|
assert(Flags.getFlag(store, nil, 0x840) == true, "EnableNationalPokedex must set FLAG_SYS_NATIONAL_DEX (0x840)")
|
|
assert(Flags.getVar(store, nil, 0x404E) == 0x6258, "EnableNationalPokedex must set VAR_NATIONAL_DEX (0x404E) to 0x6258")
|
|
assert(session.national_dex_unlocked == true, "session.national_dex_unlocked must be true")
|
|
assert(session.dex.nationalUnlocked == true, "dex.nationalUnlocked must be true")
|
|
|
|
-- 3. Check IsNationalPokedexEnabled after unlock (should be 1)
|
|
local _, natOn = Natives.special(ctx, Std.SPECIAL.IsNationalPokedexEnabled)
|
|
assert(natOn == 1, "IsNationalPokedexEnabled should hand specialvar 1 after unlock")
|
|
assert(Flags.getVar(store, ctx, 0x800D) == 1, "IsNationalPokedexEnabled should set VAR_RESULT to 1 after unlock")
|
|
assert(PokedexData.isNationalUnlocked(session, session.dex) == true, "isNationalUnlocked must return true after unlock")
|
|
print("[PASS] Script specials EnableNationalPokedex and IsNationalPokedexEnabled verified")
|
|
|
|
print("=== [TEST 3] Evolution Gating (pret evolution_scene.c:641) ===")
|
|
-- Reset national dex
|
|
session.national_dex_unlocked = false
|
|
session.dex.nationalUnlocked = false
|
|
Flags.setFlag(store, nil, 0x840, false)
|
|
Flags.setVar(store, nil, 0x404E, 0)
|
|
|
|
-- Golbat (42) evolving into Crobat (169) by friendship
|
|
local golbat = { species = 42, level = 50, friendship = 220 }
|
|
local crobatTarget = Evolution.levelTarget(golbat, session)
|
|
-- Should be blocked (nil) before National Dex
|
|
assert(crobatTarget == nil, "Golbat cannot evolve into Crobat (169 > 151) when National Dex is locked")
|
|
|
|
-- Onix (95) evolving into Steelix (208) with Metal Coat
|
|
local onix = { species = 95, level = 30 }
|
|
local steelixTarget = Evolution.itemTarget(onix, "ITEM_METAL_COAT", session)
|
|
assert(steelixTarget == nil, "Onix cannot evolve into Steelix (208 > 151) when National Dex is locked")
|
|
|
|
-- Kanto evolution (Bulbasaur 1 -> Ivysaur 2) is allowed
|
|
local bulbasaur = { species = 1, level = 16 }
|
|
local ivysaurTarget = Evolution.levelTarget(bulbasaur, session)
|
|
assert(ivysaurTarget == 2, "Kanto evolutions (1 -> 2) must remain allowed when National Dex is locked")
|
|
|
|
-- Now unlock National Dex: Golbat -> Crobat must be allowed
|
|
session.national_dex_unlocked = true
|
|
Flags.setFlag(store, nil, 0x840, true)
|
|
local crobatUnlocked = Evolution.levelTarget(golbat, session)
|
|
assert(crobatUnlocked == 169, "Golbat must evolve into Crobat (169) once National Dex is unlocked")
|
|
print("[PASS] Evolution gating before/after National Dex verified")
|
|
|
|
print("=== [TEST 4] Capture Registration Gating ===")
|
|
local lockedStore = Flags.newStore()
|
|
Space.store = lockedStore
|
|
local lockedDex = Dex.new()
|
|
local lockedSession = { national_dex_unlocked = false, dex = lockedDex, store = lockedStore }
|
|
Runtime.getSession = function() return lockedSession end
|
|
|
|
-- Try to register non-Kanto species (169 = Crobat, 252 = Treecko) before National Dex
|
|
Dex.registerEncounter(lockedDex, 169, lockedSession)
|
|
Dex.registerCapture(lockedDex, 169, lockedSession)
|
|
assert(not Dex.isSeen(lockedDex, 169), "Crobat should NOT be marked seen in locked Kanto Dex")
|
|
assert(not Dex.isCaught(lockedDex, 169), "Crobat should NOT be marked caught in locked Kanto Dex")
|
|
|
|
-- Kanto species (19 = Rattata) registers normally
|
|
Dex.registerEncounter(lockedDex, 19, lockedSession)
|
|
Dex.registerCapture(lockedDex, 19, lockedSession)
|
|
assert(Dex.isSeen(lockedDex, 19) == true, "Rattata must be marked seen in locked Kanto Dex")
|
|
assert(Dex.isCaught(lockedDex, 19) == true, "Rattata must be marked caught in locked Kanto Dex")
|
|
|
|
-- Unlock National Dex: Crobat now registers normally
|
|
local unlockedDex = Dex.new()
|
|
unlockedDex.nationalUnlocked = true
|
|
local unlockedSession = { national_dex_unlocked = true, dex = unlockedDex, store = Flags.newStore() }
|
|
Flags.setFlag(unlockedSession.store, nil, 0x840, true)
|
|
Runtime.getSession = function() return unlockedSession end
|
|
|
|
Dex.registerEncounter(unlockedDex, 169, unlockedSession)
|
|
Dex.registerCapture(unlockedDex, 169, unlockedSession)
|
|
assert(Dex.isSeen(unlockedDex, 169) == true, "Crobat MUST be marked seen in unlocked National Dex")
|
|
assert(Dex.isCaught(unlockedDex, 169) == true, "Crobat MUST be marked caught in unlocked National Dex")
|
|
print("=== [TEST 5] Pokédex Top Menu Mode Gating ===")
|
|
local Pokedex = require("src.ui.game3.pokedex")
|
|
Pokedex.show(lockedDex, { session = lockedSession })
|
|
local lockedModes = Pokedex.MODES
|
|
local hasNationalMode = false
|
|
local hasSearch = false
|
|
for _, m in ipairs(lockedModes) do
|
|
if m.id == "numerical_national" then hasNationalMode = true end
|
|
if m.id == "atoz" or m.id == "type" then hasSearch = true end
|
|
end
|
|
assert(not hasNationalMode, "Locked Pokédex must NOT have NUMERICAL MODE: NATIONAL")
|
|
-- pokefirered/src/pokedex_screen.c:333-337
|
|
assert(hasSearch, "Locked Pokédex keeps the SEARCH section of sListMenuItems_KantoDexModeSelect")
|
|
assert(Pokedex.maxSpecies() == 151, "Locked Pokédex maxSpecies must be 151")
|
|
|
|
-- Open with unlocked National Dex
|
|
Pokedex.show(unlockedDex, { session = unlockedSession })
|
|
local unlockedModes = Pokedex.MODES
|
|
local hasKantoMode = false
|
|
local hasNatMode = false
|
|
local hasAtoZ = false
|
|
for _, m in ipairs(unlockedModes) do
|
|
if m.id == "numerical_kanto" then hasKantoMode = true end
|
|
if m.id == "numerical_national" then hasNatMode = true end
|
|
if m.id == "atoz" then hasAtoZ = true end
|
|
end
|
|
assert(hasKantoMode, "Unlocked Pokédex must have NUMERICAL MODE: KANTO")
|
|
assert(hasNatMode, "Unlocked Pokédex must have NUMERICAL MODE: NATIONAL")
|
|
assert(hasAtoZ, "Unlocked Pokédex must have SEARCH section with A TO Z MODE")
|
|
print("[PASS] Pokédex top menu modes before/after National Dex unlock verified")
|
|
|
|
print("=== ALL NATIONAL DEX GATING TESTS PASSED! ===")
|