Files
gen1recomp/tests/gen2_berry_juice_test.lua
bryanthaboi ae6cac89e1 G2 support
2026-08-11 11:53:30 -04:00

95 lines
3.7 KiB
Lua

-- Shuckle's held BERRY fermenting into BERRY JUICE:
-- ConvertBerriesToBerryJuice (engine/events/pokerus/pokerus.asm:124).
--
-- luajit tests/gen2_berry_juice_test.lua
--
-- ROM-free. A 16/256 roll after every battle WIN, gated on
-- ENGINE_REACHED_GOLDENROD like the Pokerus roll it precedes; the first
-- party SHUCKLE holding a BERRY has its item rewritten, silently. Shuckie
-- (the Cianwood loaner) arrives holding one, which is the payoff.
package.path = "./?.lua;./?/init.lua;" .. package.path
local S = require("tests.harness").suite("gen2 berry juice")
local check, eq = S.check, S.eq
local BerryJuice = require("src.battle.gen2.BerryJuice")
local function shuckle(item)
return { species = "SHUCKLE", nickname = "SHUCKIE", item = item, hp = 20 }
end
-- ---- the roll and the walk ------------------------------------------------
do
local party = { shuckle("BERRY") }
eq(BerryJuice.convert(party, { reachedGoldenrod = true,
random = function() return 15 end }), 1,
"a roll under 16 converts")
eq(party[1].item, "BERRY_JUICE", "the held BERRY became BERRY JUICE")
party = { shuckle("BERRY") }
eq(BerryJuice.convert(party, { reachedGoldenrod = true,
random = function() return 16 end }), nil,
"a roll at 16 does nothing")
eq(party[1].item, "BERRY", "and the BERRY stays")
party = { shuckle("BERRY") }
eq(BerryJuice.convert(party, { reachedGoldenrod = false,
random = function() return 0 end }), nil,
"before Goldenrod the roll never runs")
end
-- ---- only the right mon, only the first -----------------------------------
do
local party = {
{ species = "PIDGEY", item = "BERRY", hp = 20 },
shuckle("GOLD_BERRY"),
shuckle("BERRY"),
shuckle("BERRY"),
}
eq(BerryJuice.convert(party, { reachedGoldenrod = true,
random = function() return 0 end }), 3,
"the walk finds the first SHUCKLE holding a plain BERRY")
eq(party[1].item, "BERRY", "another species' BERRY is not touched")
eq(party[2].item, "GOLD_BERRY", "a GOLD BERRY is not a BERRY")
eq(party[3].item, "BERRY_JUICE", "the first match converts")
eq(party[4].item, "BERRY",
"and the routine returns there -- one conversion per win")
end
-- ---- the battle-exit call site --------------------------------------------
do
-- convertAfterBattle mirrors Pokerus.giveAfterBattle: the flag comes off
-- save.engineFlags[21].
local save = { engineFlags = { [21] = true },
party = { shuckle("BERRY") } }
eq(BerryJuice.convertAfterBattle(save, nil,
{ random = function() return 0 end }), 1,
"the save-facing wrapper reads ENGINE_REACHED_GOLDENROD")
eq(save.party[1].item, "BERRY_JUICE", "and converts the save's party")
save = { engineFlags = {}, party = { shuckle("BERRY") } }
eq(BerryJuice.convertAfterBattle(save, nil,
{ random = function() return 0 end }), nil,
"no flag, no ferment")
-- The wire into the battle exit: GivePokerusAndConvertBerries runs the
-- conversion FIRST, and BattleState:givePokerus is the port's copy of
-- that arm. A call site that is not spelled out in the file is not
-- there at all (the same proof shape gen2_pokerus_test uses).
local f = io.open("src/ui/gen2/BattleState.lua", "r")
check(f ~= nil, "BattleState's source is readable")
local body = f:read("*a")
f:close()
check(body:find("BerryJuice.convertAfterBattle(self.save, party)", 1, true)
~= nil, "givePokerus converts the berries")
local convertAt = body:find("BerryJuice.convertAfterBattle(self.save, party)",
1, true)
local pokerusAt = body:find("Pokerus.giveAfterBattle(self.save, party)",
1, true)
check(convertAt and pokerusAt and convertAt < pokerusAt,
"and does it before the Pokerus roll, the asm's own order")
end
S.finish()