mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
285 lines
10 KiB
Lua
285 lines
10 KiB
Lua
local U = require("tests.drivers.util")
|
|
local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/game3_pp_items_2420"
|
|
|
|
-- pokefirered/include/constants/items.h:38
|
|
local ITEM_ETHER = 34
|
|
local ITEM_PP_UP = 69
|
|
local ITEM_LEPPA_BERRY = 138
|
|
local ITEM_BERRY_POUCH = 365
|
|
local PALLET = "FR_PALLET_TOWN"
|
|
|
|
local failures = 0
|
|
local function result(ok, label)
|
|
print((ok and "PASS " or "FAIL ") .. label)
|
|
if not ok then failures = failures + 1 end
|
|
return ok
|
|
end
|
|
|
|
local function finish()
|
|
if failures == 0 then
|
|
print("PASS pp_items_2420")
|
|
love.event.quit(0)
|
|
else
|
|
print("FAIL pp_items_2420 failures=" .. failures)
|
|
love.event.quit(1)
|
|
end
|
|
end
|
|
|
|
return function(game)
|
|
for _ = 1, 900 do
|
|
if game.phase == "boot" and game.boot then break end
|
|
U.wait(1)
|
|
end
|
|
game:_handleBootAction({ action = "new_game", name = "RED" })
|
|
U.wait(240)
|
|
|
|
local Runtime = require("src.core.game3.runtime")
|
|
local Map = require("src.core.game3.map")
|
|
local Player = require("src.core.game3.player")
|
|
local Bag = require("src.core.game3.bag")
|
|
local Party = require("src.core.game3.party")
|
|
local Pokemon = require("src.core.game3.pokemon")
|
|
local StartMenu = require("src.ui.game3.start_menu")
|
|
local BagMenu = require("src.ui.game3.bag_menu")
|
|
local PartyMenu = require("src.ui.game3.party_menu")
|
|
local BerryPouch = require("src.ui.game3.berry_pouch")
|
|
|
|
local session = Runtime.getSession()
|
|
if not result(session ~= nil, "new game reached the game3 field") then return finish() end
|
|
|
|
session.party = {}
|
|
Party.giveMon(session, 7, 15)
|
|
local mon = session.party[1]
|
|
mon.moves = { 33, 39, 145, 110 }
|
|
mon.pp = { 2, 30, 30, 40 }
|
|
mon.maxPp = { 35, 30, 30, 40 }
|
|
mon.ppBonusesPacked = nil
|
|
session.bag = session.bag or {}
|
|
Bag.add(session.bag, ITEM_ETHER, 3)
|
|
Bag.add(session.bag, ITEM_PP_UP, 1)
|
|
Bag.add(session.bag, ITEM_LEPPA_BERRY, 2)
|
|
Bag.add(session.bag, ITEM_BERRY_POUCH, 1)
|
|
|
|
Map.load(nil, game, PALLET, { x = 7, y = 10, facing = "down" })
|
|
Player.moving = false
|
|
Player.cellX, Player.cellY = 7, 10
|
|
Player.px, Player.py = 7 * 16, 10 * 16
|
|
Player.targetX, Player.targetY = 7, 10
|
|
U.wait(90)
|
|
|
|
local function pickInBag(pocket, itemId)
|
|
for _ = 1, 6 do
|
|
if BagMenu.currentPocket() == pocket then break end
|
|
U.tap(game, "right")
|
|
U.wait(15)
|
|
end
|
|
for _ = 1, 30 do
|
|
local want
|
|
for i, r in ipairs(BagMenu.list() or {}) do
|
|
if tonumber(r.id) == itemId then want = i end
|
|
end
|
|
if not want or BagMenu.cursor == want then break end
|
|
U.tap(game, (BagMenu.cursor > want) and "up" or "down")
|
|
U.wait(8)
|
|
end
|
|
local row = BagMenu.isOpen() and BagMenu.list()[BagMenu.cursor]
|
|
return row and tonumber(row.id) == itemId
|
|
end
|
|
|
|
local function openFieldBag(pocket, itemId)
|
|
U.tap(game, "start")
|
|
U.wait(30)
|
|
for _ = 1, 12 do
|
|
local e = StartMenu.ENTRIES and StartMenu.ENTRIES[StartMenu.cursor]
|
|
if e and e.id == "bag" then break end
|
|
U.tap(game, "down")
|
|
U.wait(8)
|
|
end
|
|
U.tap(game, "a")
|
|
U.wait(60)
|
|
return pickInBag(pocket, itemId)
|
|
end
|
|
|
|
local function waitMode(m, n)
|
|
for _ = 1, n or 120 do
|
|
if PartyMenu.isOpen() and PartyMenu.mode == m then return true end
|
|
U.wait(1)
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function closeAllField()
|
|
for _ = 1, 20 do
|
|
if not (PartyMenu.isOpen() or BagMenu.isOpen() or (StartMenu.isOpen and StartMenu.isOpen())) then break end
|
|
U.tap(game, "b")
|
|
U.wait(20)
|
|
end
|
|
end
|
|
|
|
-- pokefirered/src/party_menu.c:4591 ItemUseCB_TryRestorePP
|
|
if not result(openFieldBag("ITEMS", ITEM_ETHER), "field bag cursor on ETHER") then return finish() end
|
|
U.tap(game, "a")
|
|
U.wait(20)
|
|
U.tap(game, "a")
|
|
if not result(waitMode("use", 120), "USE opened the party menu") then return finish() end
|
|
U.wait(20)
|
|
PartyMenu.cursor = 1
|
|
U.tap(game, "a")
|
|
U.wait(10)
|
|
result(waitMode("forget", 30), "a move-select window opened")
|
|
result(PartyMenu._forgetPrompt == "Restore which move?",
|
|
"prompt is gText_RestoreWhichMove (" .. tostring(PartyMenu._forgetPrompt) .. ")")
|
|
U.wait(10)
|
|
U.shot(game, DIR .. "/2420_field_ether_restore_which_move.png")
|
|
local hp0 = mon.hp
|
|
U.tap(game, "a")
|
|
waitMode("message", 60)
|
|
U.wait(20)
|
|
result((PartyMenu._messageText or ""):find("PP was restored.", 1, true) ~= nil,
|
|
"gText_PPWasRestored shown (" .. tostring(PartyMenu._messageText) .. ")")
|
|
U.shot(game, DIR .. "/2420_field_ether_pp_restored.png")
|
|
result(mon.pp[1] == 12, "field ETHER restored TACKLE 2 -> " .. tostring(mon.pp[1]))
|
|
result(mon.hp == hp0, "and HP unchanged")
|
|
result(Bag.has(session.bag, ITEM_ETHER, 2) and not Bag.has(session.bag, ITEM_ETHER, 3),
|
|
"one ETHER consumed")
|
|
U.tap(game, "a")
|
|
U.wait(20)
|
|
closeAllField()
|
|
|
|
-- pokefirered/src/party_menu.c:4709 ItemUseCB_PPUp
|
|
if not result(openFieldBag("ITEMS", ITEM_PP_UP), "field bag cursor on PP UP") then return finish() end
|
|
U.tap(game, "a")
|
|
U.wait(20)
|
|
U.tap(game, "a")
|
|
if not result(waitMode("use", 120), "USE opened the party menu for PP UP") then return finish() end
|
|
U.wait(20)
|
|
PartyMenu.cursor = 1
|
|
U.tap(game, "a")
|
|
U.wait(10)
|
|
result(waitMode("forget", 30) and PartyMenu._forgetPrompt == "Boost PP of which?",
|
|
"prompt is gText_BoostPp (" .. tostring(PartyMenu._forgetPrompt) .. ")")
|
|
U.wait(10)
|
|
U.shot(game, DIR .. "/2420_field_ppup_boost_which.png")
|
|
local base = Pokemon.movePp(33)
|
|
U.tap(game, "a")
|
|
waitMode("message", 60)
|
|
U.wait(20)
|
|
result((PartyMenu._messageText or ""):find("TACKLE's PP increased.", 1, true) ~= nil,
|
|
"gText_MovesPPIncreased shown (" .. tostring(PartyMenu._messageText) .. ")")
|
|
U.shot(game, DIR .. "/2420_field_ppup_pp_increased.png")
|
|
local want = base + math.floor(base * 20 / 100)
|
|
result(mon.maxPp[1] == want, string.format("PP UP max PP %d -> %s (+20%% of base)", base, tostring(mon.maxPp[1])))
|
|
result(mon.pp[1] == 12 + want - base, "and current PP rose by the same step (" .. tostring(mon.pp[1]) .. ")")
|
|
U.tap(game, "a")
|
|
U.wait(20)
|
|
closeAllField()
|
|
|
|
local BattleBridge = require("src.core.game3.battle_bridge")
|
|
local Battle = require("src.core.game3.battle")
|
|
local Ui = require("src.core.game3.battle.ui")
|
|
local ok, err = BattleBridge.startWild(Runtime._mod, game, { species = 16, level = 5 }, { fade = false })
|
|
if not result(ok == true, "wild battle started " .. tostring(err or "")) then return finish() end
|
|
|
|
local function at_command()
|
|
return Battle.isActive() and Battle._phase == "command" and Ui._mode == "menu"
|
|
end
|
|
local lastTap, f = 0, 0
|
|
local function pumpToCommand(n)
|
|
for _ = 1, n or 3000 do
|
|
f = f + 1
|
|
if at_command() then return true end
|
|
if Ui.dialogPending and Ui.dialogPending() and f - lastTap >= 14 then
|
|
lastTap = f
|
|
U.tap(game, "a")
|
|
else
|
|
U.wait(1)
|
|
end
|
|
end
|
|
return at_command()
|
|
end
|
|
if not result(pumpToCommand(), "reached the battle command menu") then return finish() end
|
|
local st = Battle.getState()
|
|
st.enemy.mon.moves = { 150, 0, 0, 0 }
|
|
st.enemy.mon.pp = { 40, 0, 0, 0 }
|
|
local State = require("src.core.game3.battle.state")
|
|
local bmon = State.ensureBattleMoves(st.player)
|
|
bmon.pp[1] = 1
|
|
bmon.pp[2] = 0
|
|
local party = st.playerParty
|
|
local pmon = party[st.player.partyIndex or 1]
|
|
pmon.hp = math.max(1, (tonumber(pmon.maxHp) or 20) - 5)
|
|
st.player.mon.hp = pmon.hp
|
|
|
|
local function openBattleBag()
|
|
Ui._menuIndex = 2
|
|
U.tap(game, "a")
|
|
for _ = 1, 120 do
|
|
if BagMenu.isOpen() and BagMenu.mode == "list" then break end
|
|
U.wait(1)
|
|
end
|
|
U.wait(30)
|
|
return BagMenu.isOpen()
|
|
end
|
|
|
|
local function pickMonAndMove(moveCursor, shotName, msgShot)
|
|
if not waitMode("use", 120) then return false end
|
|
U.wait(20)
|
|
PartyMenu.cursor = 1
|
|
U.tap(game, "a")
|
|
U.wait(10)
|
|
if not waitMode("forget", 30) then return false end
|
|
for _ = 2, moveCursor do
|
|
U.tap(game, "down")
|
|
U.wait(6)
|
|
end
|
|
U.wait(10)
|
|
U.shot(game, DIR .. "/" .. shotName)
|
|
U.tap(game, "a")
|
|
waitMode("message", 60)
|
|
U.wait(20)
|
|
U.shot(game, DIR .. "/" .. msgShot)
|
|
local txt = PartyMenu._messageText
|
|
U.tap(game, "a")
|
|
return true, txt
|
|
end
|
|
|
|
-- pokefirered/src/party_menu.c:4675 TryUsePPItemInBattle
|
|
local hpBefore = pmon.hp
|
|
if not result(openBattleBag(), "battle BAG opened") then return finish() end
|
|
if not result(pickInBag("ITEMS", ITEM_ETHER), "battle bag cursor on ETHER") then return finish() end
|
|
U.tap(game, "a")
|
|
U.wait(20)
|
|
U.tap(game, "a")
|
|
local okE, txtE = pickMonAndMove(1, "2420_battle_ether_restore_which_move.png", "2420_battle_ether_pp_restored.png")
|
|
result(okE and (txtE or ""):find("PP was restored.", 1, true) ~= nil,
|
|
"battle ETHER picked a move and showed PP was restored (" .. tostring(txtE) .. ")")
|
|
pumpToCommand()
|
|
result(st.player.mon.pp[1] == 11, "battle ETHER restored the active battler's PP 1 -> " .. tostring(st.player.mon.pp[1]))
|
|
result(pmon.pp[1] == 11, "and the party mon's PP matches (" .. tostring(pmon.pp[1]) .. ")")
|
|
result(pmon.hp == hpBefore and st.player.mon.hp == hpBefore,
|
|
"HP unchanged " .. tostring(hpBefore) .. " -> " .. tostring(st.player.mon.hp))
|
|
local sawUsed = false
|
|
for _, t in ipairs(Ui.log()) do if t:find("ETHER", 1, true) then sawUsed = true end end
|
|
result(sawUsed, "battle log has RED used the ETHER")
|
|
|
|
if not result(openBattleBag(), "battle BAG opened again") then return finish() end
|
|
if not result(pickInBag("KEY_ITEMS", ITEM_BERRY_POUCH), "battle bag cursor on BERRY POUCH") then return finish() end
|
|
BerryPouch.show(session, session.bag, { session = session, bag = session.bag })
|
|
U.wait(30)
|
|
for i, r in ipairs(BerryPouch.list() or {}) do
|
|
if tonumber(r.id) == ITEM_LEPPA_BERRY then BerryPouch.cursor = i end
|
|
end
|
|
U.tap(game, "a")
|
|
U.wait(15)
|
|
U.tap(game, "a")
|
|
local okL, txtL = pickMonAndMove(2, "2420_battle_leppa_restore_which_move.png", "2420_battle_leppa_pp_restored.png")
|
|
result(okL and (txtL or ""):find("PP was restored.", 1, true) ~= nil,
|
|
"battle LEPPA picked a move and showed PP was restored (" .. tostring(txtL) .. ")")
|
|
pumpToCommand()
|
|
result(st.player.mon.pp[2] == 10, "battle LEPPA restored move 2 PP 0 -> " .. tostring(st.player.mon.pp[2]))
|
|
result(pmon.pp[2] == 10, "and the party mon's PP matches (" .. tostring(pmon.pp[2]) .. ")")
|
|
result(pmon.hp == hpBefore, "HP still unchanged (" .. tostring(pmon.hp) .. ")")
|
|
|
|
finish()
|
|
end
|