mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 05:32:07 -04:00
109 lines
5.3 KiB
Lua
109 lines
5.3 KiB
Lua
#!/usr/bin/env luajit
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
love = love or require("tests.love_stub")
|
|
local GAME = require("tests.game3_cart_cache").mountOrSkip("game3_cart_import_load_test")
|
|
|
|
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 unrle(s)
|
|
local out = {}
|
|
for tok in s:gmatch("%S+") do
|
|
local k, n = tok:match("^([ZF])(%x+)$")
|
|
if k then
|
|
out[#out + 1] = string.rep(k == "Z" and "\0" or "\255", tonumber(n, 16))
|
|
else
|
|
out[#out + 1] = (tok:gsub("%x%x", function(h) return string.char(tonumber(h, 16)) end))
|
|
end
|
|
end
|
|
return table.concat(out)
|
|
end
|
|
|
|
local SaveConvert = require("src.save_convert.SaveConvert")
|
|
local SaveSerializer = require("src.core.SaveSerializer")
|
|
local Schema = require("src.core.game3.save_schema_firered")
|
|
local Pokemon = require("src.core.game3.pokemon")
|
|
local F = require("tests.fixture_data.gen3_saves")
|
|
|
|
local oracle = F.oracle.fr_rich_game
|
|
local save = assert(SaveConvert.importSav(unrle(F.images.fr_rich_game), GAME, GAME))
|
|
save = assert(SaveSerializer.decode(SaveSerializer.encode(save)))
|
|
local s = Schema.fromSaveTable(save)
|
|
|
|
check(s.map == "FR_PLAYERS_HOUSE_2F" and s.x == 6 and s.y == 6, "continue lands in the bedroom at 6,6")
|
|
check(s.healMap == "FR_PLAYERS_HOUSE_1F" and s.healX == 8 and s.healY == 5,
|
|
"the Pallet heal spot resolves to Mom's tile (" .. tostring(s.healMap) .. " " .. tostring(s.healX) .. "," .. tostring(s.healY) .. ")")
|
|
check(s.modData.cartImport == nil, "the import marker is spent after the first load")
|
|
for i, o in ipairs(oracle.party) do
|
|
local m = s.party[i]
|
|
check(m.level == o.statLevel, ("party %d level %s"):format(i, tostring(m.level)))
|
|
check(m.maxHp == o.maxHp, ("party %d max HP %s == %s"):format(i, tostring(m.maxHp), tostring(o.maxHp)))
|
|
check(m.attack == o.stats[1] and m.defense == o.stats[2] and m.speed == o.stats[3]
|
|
and m.spAtk == o.stats[4] and m.spDef == o.stats[5], ("party %d stats match the cart"):format(i))
|
|
check(m.hp == o.hp, ("party %d HP %s"):format(i, tostring(m.hp)))
|
|
check(m.cartImport == nil, ("party %d finished"):format(i))
|
|
end
|
|
check(s.party[1].nickname == "BLAZE", "a real nickname stays")
|
|
check(s.party[2].nickname == "", "a nickname equal to the species name clears")
|
|
check(s.party[2].name == Pokemon.name(277), "Treecko name comes from the species table")
|
|
check(s.party[1].gender == Pokemon.gender(6, oracle.party[1].pid), "gender from personality")
|
|
check(s.party[1].ability == Pokemon.abilities(6)[1], "ability slot 1")
|
|
check(s.party[1].maxPp[1] == Pokemon.movePp(53) + math.floor(Pokemon.movePp(53) * 20 * 3 / 100),
|
|
"three PP Ups raise max PP on move 1")
|
|
check(s.party[1].maxPp[2] == Pokemon.movePp(17), "no PP Ups on move 2")
|
|
check(s.party[3].isEgg == true and s.party[3].eggCycles == 10, "the egg keeps its cycles")
|
|
local levels = {}
|
|
for _, b in ipairs(oracle.boxes) do
|
|
local m = s.storage.boxes[b.box + 1].mons[b.slot + 1]
|
|
levels[#levels + 1] = m and m.level
|
|
end
|
|
check(levels[1] == 4 and levels[2] == 3 and levels[3] == 70 and levels[4] == 30 and levels[5] == 50,
|
|
"box levels come from exp (" .. table.concat(levels, ",") .. ")")
|
|
check(s.storage.boxes[2].mons[20].hp == s.storage.boxes[2].mons[20].maxHp, "box mons are full HP")
|
|
for _, nat in ipairs(oracle.caught) do
|
|
local sp = Pokemon.speciesFromNational(nat)
|
|
check(s.dex.owned[sp] == true and s.dex.caught[sp] == true, "caught national " .. nat .. " -> species " .. tostring(sp))
|
|
end
|
|
for _, nat in ipairs(oracle.seen) do
|
|
check(s.dex.seen[Pokemon.speciesFromNational(nat)] == true, "seen national " .. nat)
|
|
end
|
|
check(s.dex.owned[277] == true and s.dex.owned[252] == nil, "Treecko is internal 277, not 252")
|
|
check(s.options.textSpeed == 1, "text speed carried")
|
|
check(#s.bag.pockets.ITEMS == 3, "bag items")
|
|
|
|
do
|
|
local Gen3Save = require("src.save_convert.Gen3Save")
|
|
local L = require("src.save_convert.Gen3Layout")
|
|
local Mail = require("src.core.game3.mail")
|
|
local c, blocks = Gen3Save.decode(unrle(F.images.fr_rich_game))
|
|
c.party[1].heldItem, c.party[1].mail = 121, 0
|
|
c.mail[1] = { words = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, playerName = "AAA", trainerId = c.trainerId, species = 6, itemId = 121 }
|
|
local N = L.NATIONAL_DEX
|
|
c.dexNationalMagic, c.vars[N.var] = N.magic, N.varValue
|
|
c.flags[#c.flags + 1] = N.flag
|
|
c.fameChecker[3] = { pickState = 1, flavorTextFlags = 5 }
|
|
local img = Gen3Save.buildFlash(Gen3Save.encodeBlocks(c, blocks), { counter = c.counter + 1, image = blocks.image })
|
|
local cart = assert(SaveConvert.importSav(img, GAME, GAME))
|
|
local s2 = Schema.fromSaveTable(assert(SaveSerializer.decode(SaveSerializer.encode(cart))))
|
|
check(Mail.monHasMail(s2.party[1]), "a cart mon holding mail still has its letter after load")
|
|
local letter = Mail.get(s2, s2.party[1].mail)
|
|
check(letter ~= nil and letter.words[1] == 1 and letter.itemId == 121, "the letter's words survive the load")
|
|
check(require("src.core.game3.pokedex_data").isNationalUnlocked(s2, s2.dex) == true, "a National Dex cart loads unlocked")
|
|
local fc = require("src.core.game3.fame_checker").records(s2)
|
|
check(fc and fc[3].pickState == 1 and fc[3].flavorTextFlags == 5, "Fame Checker progress loads")
|
|
end
|
|
|
|
if failed > 0 then
|
|
print(string.format("\n%d FAILED", failed))
|
|
os.exit(1)
|
|
end
|
|
print("\nAll cart import load tests passed.")
|
|
os.exit(0)
|