mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
155 lines
5.6 KiB
Lua
155 lines
5.6 KiB
Lua
-- ../pokecrystal/data/wild/treemons.asm:1 TreeMons
|
|
-- ../pokecrystal/data/wild/treemons_asleep.asm:3 AsleepTreeMonsNite
|
|
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
|
|
local T = require("tests.harness")
|
|
local check, eq = T.check, T.eq
|
|
love = love or require("tests.love_stub")
|
|
|
|
local Extractor = require("src.import.RomExtractorGen2")
|
|
local Encounter = require("src.battle.gen2.Encounter")
|
|
|
|
local SPEAROW, AIPOM, HERACROSS = 21, 190, 214
|
|
local KRABBY, SHUCKLE = 98, 213
|
|
local CATERPIE, HOOTHOOT = 10, 163
|
|
|
|
local SPECIES = {
|
|
[SPEAROW] = "SPEAROW", [AIPOM] = "AIPOM", [HERACROSS] = "HERACROSS",
|
|
[KRABBY] = "KRABBY", [SHUCKLE] = "SHUCKLE",
|
|
[CATERPIE] = "CATERPIE", [HOOTHOOT] = "HOOTHOOT",
|
|
}
|
|
|
|
local function fakeRom(banks)
|
|
local rom = {}
|
|
function rom:byte(bank, address)
|
|
return (banks[bank] or {})[address] or 0
|
|
end
|
|
function rom:word(bank, address)
|
|
return self:byte(bank, address) + self:byte(bank, address + 1) * 0x100
|
|
end
|
|
return rom
|
|
end
|
|
|
|
local function put(bytes, at, ...)
|
|
for index, b in ipairs({ ... }) do bytes[at + index - 1] = b end
|
|
return at + select("#", ...)
|
|
end
|
|
|
|
do
|
|
local bank = {}
|
|
local TABLE, CANYON, ROCK = 0x42e8, 0x4300, 0x43de
|
|
put(bank, TABLE,
|
|
CANYON % 256, math.floor(CANYON / 256),
|
|
CANYON % 256, math.floor(CANYON / 256),
|
|
ROCK % 256, math.floor(ROCK / 256))
|
|
local at = put(bank, CANYON, 50, SPEAROW, 10, 50, AIPOM, 10, 0xff)
|
|
put(bank, at, 50, SPEAROW, 10, 50, HERACROSS, 10, 0xff)
|
|
at = put(bank, ROCK, 90, KRABBY, 15, 10, SHUCKLE, 15, 0xff)
|
|
-- ../pokecrystal/engine/events/treemons.asm:126 GetTreeMon
|
|
put(bank, at, 0xe5, 0xcd, 0x99, 0x43, 0xe1, 0xa7, 0x28, 0x08, 0xfe, 0x01,
|
|
0x28, 0x0e, 0xfe, 0x02, 0x28, 0x16, 0xc9, 0x3e, 0x0a, 0xcd)
|
|
|
|
local extractor = setmetatable({
|
|
rom = fakeRom({ [0x2e] = bank }),
|
|
edition = "crystal",
|
|
symbols = { TreeMons = { 0x2e, TABLE } },
|
|
manifest = { constants = {
|
|
treeMonSetOrder = { "TREEMON_SET_NONE", "TREEMON_SET_CANYON",
|
|
"TREEMON_SET_ROCK" },
|
|
speciesOrder = SPECIES,
|
|
} },
|
|
}, Extractor)
|
|
|
|
local sets = extractor:readTreeMons()
|
|
local canyon = sets.TREEMON_SET_CANYON
|
|
eq(#canyon.common, 2, "a headbutt set reads its common list")
|
|
eq(canyon.common[1].species, "SPEAROW", "first common row")
|
|
eq(canyon.common[2].level, 10, "with its level")
|
|
eq(#canyon.rare, 2, "and its rare list")
|
|
eq(canyon.rare[2].species, "HERACROSS", "the rare row past the -1")
|
|
|
|
local rock = sets.TREEMON_SET_ROCK
|
|
eq(#rock.common, 2, "TREEMON_SET_ROCK is the 90/10 list")
|
|
eq(rock.common[1].species, "KRABBY", "KRABBY")
|
|
eq(rock.common[1].chance, 90, "at 90")
|
|
eq(rock.common[2].species, "SHUCKLE", "SHUCKLE")
|
|
eq(rock.rare, nil,
|
|
"and no second list: the bytes after its -1 are GetTreeMon's code")
|
|
end
|
|
|
|
do
|
|
local encounters = {
|
|
trees = { ROCKY = "TREEMON_SET_ROCK" },
|
|
treeSets = { TREEMON_SET_ROCK = {
|
|
common = { { chance = 100, species = "KRABBY", level = 15 } } } },
|
|
}
|
|
eq(Encounter.treeScore(0, 0, 4), Encounter.TREEMON_SCORE_RARE,
|
|
"coords (0,0) with OT id 4 score RARE")
|
|
eq(Encounter.treeSlot(encounters, "ROCKY", 0, 0, function() return 0 end,
|
|
{ otId = 4, engine = "crystal" }), nil,
|
|
"a RARE roll against a one-list set answers nothing rather than erroring")
|
|
end
|
|
|
|
do
|
|
local bank = {}
|
|
local NITE, DAY, MORN = 0x6b5d, 0x6b69, 0x6b6f
|
|
put(bank, NITE, CATERPIE, SPEAROW, 0xff)
|
|
put(bank, DAY, HOOTHOOT, 0xff)
|
|
put(bank, MORN, HOOTHOOT, HERACROSS, 0xff)
|
|
local symbols = {
|
|
AsleepTreeMonsNite = { 0x0f, NITE },
|
|
AsleepTreeMonsDay = { 0x0f, DAY },
|
|
AsleepTreeMonsMorn = { 0x0f, MORN },
|
|
}
|
|
local extractor = setmetatable({
|
|
rom = fakeRom({ [0x0f] = bank }),
|
|
edition = "crystal",
|
|
symbols = symbols,
|
|
manifest = { constants = { speciesOrder = SPECIES } },
|
|
}, Extractor)
|
|
local asleep = extractor:readAsleepTreeMons()
|
|
eq(#asleep.NITE, 2, "Nite list length")
|
|
eq(asleep.NITE[1], "CATERPIE", "Nite[1]")
|
|
eq(asleep.NITE[2], "SPEAROW", "Nite[2]")
|
|
eq(asleep.DAY[1], "HOOTHOOT", "Day[1]")
|
|
eq(#asleep.DAY, 1, "Day list length")
|
|
eq(asleep.MORN[2], "HERACROSS", "Morn[2]")
|
|
|
|
local gold = setmetatable({
|
|
rom = fakeRom({}), edition = "gold",
|
|
symbols = { AsleepTreeMonsNite = { 0x0f, NITE } },
|
|
manifest = { constants = { speciesOrder = SPECIES } },
|
|
}, Extractor)
|
|
eq(gold:readAsleepTreeMons(), nil,
|
|
"a ROM without all three labels (pokegold) has no list")
|
|
end
|
|
|
|
-- ../pokecrystal/engine/battle/core.asm:6422 CheckSleepingTreeMon
|
|
do
|
|
local encounters = { treeMonsAsleep = {
|
|
NITE = { "SPEAROW" }, DAY = { "HOOTHOOT" }, MORN = { "AIPOM" } } }
|
|
eq(Encounter.treeMonAsleep("SPEAROW", "NITE", "crystal", encounters), true,
|
|
"the extracted Nite list is read")
|
|
eq(Encounter.treeMonAsleep("SPEAROW", "DARK", "crystal", encounters), true,
|
|
"DARKNESS_F falls through to Nite")
|
|
eq(Encounter.treeMonAsleep("SPEAROW", "DAY", "crystal", encounters), false,
|
|
"and SPEAROW is awake by day")
|
|
eq(Encounter.treeMonAsleep("AIPOM", "MORN", "crystal", encounters), true,
|
|
"the Morn list is its own")
|
|
eq(Encounter.treeMonAsleep("AIPOM", "DAY", "crystal", encounters), false,
|
|
"and not the Day list")
|
|
eq(Encounter.treeMonAsleep("HOOTHOOT", "DAY", "gs", encounters), false,
|
|
"pokegold never sleeps a tree mon")
|
|
|
|
local empty = { treeMonsAsleep = { NITE = {}, DAY = {}, MORN = {} } }
|
|
eq(Encounter.treeMonAsleep("SPEAROW", "NITE", "crystal", empty), false,
|
|
"an extracted list wins over the transcribed constant")
|
|
eq(Encounter.treeMonAsleep("SPEAROW", "NITE", "crystal", nil), true,
|
|
"which still answers for a cache without the table")
|
|
eq(Encounter.treeMonAsleep("SPEAROW", "NITE", "crystal", {}), true,
|
|
"or with it missing")
|
|
end
|
|
|
|
T.finish("gen2 treemon extract bug2043")
|