mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
a9ce423bdc
CLOSES #1275, CLOSES #1295, CLOSES #1384, CLOSES #1628, CLOSES #1677, CLOSES #1682, CLOSES #1691, CLOSES #1813, CLOSES #1822, CLOSES #1861, CLOSES #1867, CLOSES #1868, CLOSES #1869, CLOSES #1870, CLOSES #1871, CLOSES #1872, CLOSES #1874, CLOSES #1876, CLOSES #1878, CLOSES #1880, CLOSES #1881, CLOSES #1882, CLOSES #1884, CLOSES #1885, CLOSES #1886, CLOSES #1887, CLOSES #1888, CLOSES #1889, CLOSES #1890, CLOSES #1891, CLOSES #1892, CLOSES #1893, CLOSES #1894, CLOSES #1895, CLOSES #1896, CLOSES #1899, CLOSES #1900, CLOSES #1901
221 lines
8.0 KiB
Lua
221 lines
8.0 KiB
Lua
-- engine/pokemon/caught_data.asm:72-81, :163-233
|
|
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
|
|
love = require("tests.love_stub")
|
|
|
|
local T = require("tests.harness")
|
|
local Breeding = require("src.core.gen2.Breeding")
|
|
local Catching = require("src.battle.gen2.Catching")
|
|
local Mon = require("src.battle.gen2.Mon")
|
|
local NpcTrade = require("src.core.gen2.NpcTrade")
|
|
local UI = require("src.ui.gen2.BattleState")
|
|
local World = require("src.world.gen2.World")
|
|
|
|
local NEW_BARK = 1
|
|
local ROUTE_29 = 2
|
|
|
|
local POKEMON = {
|
|
growthRates = {
|
|
GROWTH_MEDIUM_FAST = { numerator = 1, denominator = 1, squared = 0,
|
|
linear = 0, constant = 0 },
|
|
},
|
|
RATTATA = {
|
|
id = "RATTATA", index = 19, name = "RATTATA",
|
|
baseStats = { hp = 30, attack = 56, defense = 35, speed = 72,
|
|
specialAttack = 25, specialDefense = 35 },
|
|
types = { "NORMAL", "NORMAL" }, catchRate = 255, baseExp = 51,
|
|
growthRate = "GROWTH_MEDIUM_FAST", genderRatio = 127,
|
|
levelMoves = { { level = 1, move = "TACKLE" } }, evolutions = {},
|
|
},
|
|
DODRIO = {
|
|
id = "DODRIO", index = 85, name = "DODRIO",
|
|
baseStats = { hp = 60, attack = 110, defense = 70, speed = 100,
|
|
specialAttack = 60, specialDefense = 60 },
|
|
types = { "NORMAL", "FLYING" }, catchRate = 45, baseExp = 158,
|
|
growthRate = "GROWTH_MEDIUM_FAST", genderRatio = 127,
|
|
levelMoves = { { level = 1, move = "TACKLE" } }, evolutions = {},
|
|
},
|
|
}
|
|
|
|
local DATA = {
|
|
pokemon = POKEMON,
|
|
moves = { TACKLE = { id = "TACKLE", name = "TACKLE", power = 35,
|
|
type = "NORMAL", accuracy = 100, pp = 35, effect = "EFFECT_NORMAL_HIT" } },
|
|
type_chart = { types = {}, matchups = {} },
|
|
items = {},
|
|
}
|
|
|
|
local function newSave(version, gender)
|
|
return {
|
|
version = version, party = {},
|
|
player = { name = "KRIS", id = 4242, gender = gender or "female" },
|
|
pokedex = { seen = {}, caught = {} },
|
|
}
|
|
end
|
|
|
|
local function newWorld()
|
|
return {
|
|
tod = "NITE",
|
|
maps = {
|
|
ROUTE_29 = { id = "ROUTE_29", landmark = ROUTE_29 },
|
|
NEW_BARK_TOWN = { id = "NEW_BARK_TOWN", landmark = NEW_BARK },
|
|
},
|
|
map = { def = { id = "ROUTE_29", landmark = ROUTE_29 } },
|
|
timeOfDayId = World.timeOfDayId,
|
|
}
|
|
end
|
|
|
|
local function newState(save, world, opts)
|
|
opts = opts or {}
|
|
return setmetatable({
|
|
save = save, queue = {},
|
|
battle = { timeOfDay = opts.timeOfDay },
|
|
contest = opts.contest,
|
|
game = { save = save, data = DATA, world = world },
|
|
}, { __index = UI })
|
|
end
|
|
|
|
do
|
|
local save = newSave("crystal", "female")
|
|
local state = newState(save, newWorld(), { timeOfDay = 1 })
|
|
local enemy = { species = "RATTATA", level = 4 }
|
|
state:pushCaught(enemy, "POKE_BALL")
|
|
T.eq(save.party[1], enemy, "the catch joins the party")
|
|
T.eq(enemy.caughtTime, 2, "wTimeOfDay DAY stores as 2")
|
|
T.eq(enemy.caughtLevel, 4, "the level rides the same byte")
|
|
T.eq(enemy.caughtLocation, ROUTE_29, "the map header's landmark")
|
|
T.eq(enemy.caughtByGender, "girl", "wPlayerGender bit 0 on bit 7")
|
|
end
|
|
|
|
do
|
|
local save = newSave("crystal", "male")
|
|
for i = 1, 6 do save.party[i] = { species = "RATTATA", level = 5 } end
|
|
local state = newState(save, newWorld(), { timeOfDay = 0 })
|
|
local enemy = { species = "RATTATA", level = 7 }
|
|
state:pushCaught(enemy, "POKE_BALL")
|
|
T.eq(#save.party, 6, "a full party sends the catch to the PC")
|
|
T.eq(enemy.caughtTime, 1, "MORN stores as 1, so 0 stays 'unknown'")
|
|
T.eq(enemy.caughtByGender, "boy", "a male player stamps CAUGHT_BY_BOY")
|
|
T.eq(enemy.caughtLocation, ROUTE_29, "and the same landmark")
|
|
end
|
|
|
|
do
|
|
local save = newSave("crystal", "female")
|
|
local state = newState(save, newWorld())
|
|
local enemy = { species = "RATTATA", level = 4 }
|
|
state:pushCaught(enemy, "POKE_BALL")
|
|
T.eq(enemy.caughtTime, 3, "NITE stores as 3")
|
|
end
|
|
|
|
do
|
|
local save = newSave("gold", "male")
|
|
local state = newState(save, newWorld(), { timeOfDay = 1 })
|
|
local enemy = { species = "RATTATA", level = 4 }
|
|
state:pushCaught(enemy, "POKE_BALL")
|
|
T.eq(enemy.caughtTime, nil, "Gold stamps no caught time")
|
|
T.eq(enemy.caughtByGender, nil, "and no OT gender")
|
|
T.eq(enemy.caughtLocation, nil, "and no landmark")
|
|
end
|
|
|
|
do
|
|
local save = newSave("crystal", "female")
|
|
local state = newState(save, newWorld(), { timeOfDay = 1, contest = true })
|
|
local enemy = { species = "RATTATA", level = 9 }
|
|
state:pushCaught(enemy, "PARK_BALL")
|
|
T.eq(save.bugContest.caught, enemy, "the contest only HOLDS the catch")
|
|
T.eq(enemy.caughtLocation, Catching.LANDMARK_NATIONAL_PARK,
|
|
"the location is rewritten to the park")
|
|
T.eq(enemy.caughtByGender, "girl", "and the gender bit survives the rewrite")
|
|
T.eq(enemy.caughtTime, 2, "the time byte is the plain SetCaughtData one")
|
|
end
|
|
|
|
do
|
|
local world = newWorld()
|
|
world.map = { def = { id = "POKECENTER_2F", landmark = 0x7f } }
|
|
world.backupMapId = "NEW_BARK_TOWN"
|
|
local save = newSave("crystal", "male")
|
|
local state = newState(save, world, { timeOfDay = 1 })
|
|
local enemy = { species = "RATTATA", level = 4 }
|
|
state:pushCaught(enemy, "POKE_BALL")
|
|
T.eq(enemy.caughtLocation, NEW_BARK, "the backup map's landmark is used")
|
|
end
|
|
|
|
do
|
|
local world = newWorld()
|
|
local save = newSave("crystal", "female")
|
|
world.game = { save = save, data = DATA }
|
|
local opts = World.caughtDataOpts(world)
|
|
T.eq(opts.version, "crystal", "the save's version gates the stamp")
|
|
T.eq(opts.timeOfDay, 2, "NITE is wTimeOfDay 2")
|
|
T.eq(opts.landmark, ROUTE_29, "the landmark is resolved up front")
|
|
T.eq(opts.playerGender, "female", "and wPlayerGender comes along")
|
|
|
|
world.map = { def = { id = "POKECENTER_2F", landmark = 0x7f } }
|
|
world.backupMapId = "NEW_BARK_TOWN"
|
|
T.eq(World.caughtDataOpts(world).landmark, NEW_BARK,
|
|
"with the POKECENTER_2F backup swap")
|
|
end
|
|
|
|
do
|
|
local source = io.open("src/world/gen2/World.lua"):read("*a")
|
|
T.check(source:find("Mon.setGiftCaughtData(mon, opts.caughtBy", 1, true)
|
|
~= nil, "the trainer arm stamps LANDMARK_GIFT")
|
|
T.check(source:find("Catching.stampCaughtData(mon, self:caughtDataOpts())",
|
|
1, true) ~= nil, "the wild arm runs SetCaughtData")
|
|
end
|
|
|
|
do
|
|
local save = newSave("crystal", "female")
|
|
local egg = Mon.new(DATA, "RATTATA", Breeding.EGG_LEVEL, {})
|
|
egg.isEgg = true
|
|
egg.eggSteps = 0
|
|
save.party[1] = egg
|
|
local world = newWorld()
|
|
world.game = { save = save, data = DATA }
|
|
local hatched = Breeding.hatch(DATA, save, 1, nil, World.caughtDataOpts(world))
|
|
T.check(hatched ~= nil, "the egg hatches")
|
|
T.eq(hatched.caughtLevel, Mon.CAUGHT_EGG_LEVEL, "CAUGHT_EGG_LEVEL")
|
|
T.eq(hatched.caughtTime, 3, "NITE")
|
|
T.eq(hatched.caughtLocation, ROUTE_29, "the hatch site's landmark")
|
|
T.eq(hatched.caughtByGender, "girl", "and the player's gender")
|
|
end
|
|
|
|
do
|
|
local save = newSave("crystal", "male")
|
|
save.party[1] = Mon.new(DATA, "RATTATA", 20, {})
|
|
local row = { id = 3, dialog = "TRADE_DIALOGSET_GIRL", give = "RATTATA",
|
|
get = "DODRIO", nickname = "DORIS", dvs = { 0x77, 0x66 }, otName = "EMY",
|
|
otId = 283 }
|
|
local _, received = NpcTrade.perform(DATA, save, row, 1)
|
|
T.check(received ~= nil, "the trade completes")
|
|
T.eq(received.caughtTime, 0, "a gift has no caught time")
|
|
T.eq(received.caughtLevel, 0, "and no caught level")
|
|
T.eq(received.caughtLocation, Mon.LANDMARK_GIFT, "LANDMARK_GIFT")
|
|
T.eq(received.caughtByGender, "girl", "TRADE_DIALOGSET_GIRL is CAUGHT_BY_GIRL")
|
|
end
|
|
|
|
do
|
|
local save = newSave("crystal", "male")
|
|
save.party[1] = Mon.new(DATA, "RATTATA", 20, {})
|
|
local row = { id = 0, dialog = "TRADE_DIALOGSET_COLLECTOR", give = "RATTATA",
|
|
get = "DODRIO", nickname = "MUSCLE", dvs = { 0x37, 0x66 }, otName = "MIKE",
|
|
otId = 37460 }
|
|
local _, received = NpcTrade.perform(DATA, save, row, 1)
|
|
T.eq(received.caughtLocation, Mon.LANDMARK_GIFT, "still LANDMARK_GIFT")
|
|
T.eq(received.caughtByGender, "boy",
|
|
"CAUGHT_BY_UNKNOWN leaves the gender bit clear")
|
|
end
|
|
|
|
do
|
|
local save = newSave("gold", "male")
|
|
save.party[1] = Mon.new(DATA, "RATTATA", 20, {})
|
|
local row = { id = 3, dialog = "TRADE_DIALOGSET_GIRL", give = "RATTATA",
|
|
get = "DODRIO", nickname = "DORIS", dvs = { 0x77, 0x66 }, otName = "EMY",
|
|
otId = 283 }
|
|
local _, received = NpcTrade.perform(DATA, save, row, 1)
|
|
T.eq(received.caughtLocation, nil, "Gold trades stamp nothing")
|
|
end
|
|
|
|
T.finish("gen2 caught data stamp bug 1886")
|