mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
288 lines
9.6 KiB
Lua
288 lines
9.6 KiB
Lua
local U = require("tests.drivers.util")
|
|
local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/game3_corner_prize"
|
|
|
|
local PRIZE_ROOM = "FR_CELADON_CITY_GAME_CORNER_PRIZE_ROOM"
|
|
-- pokefirered/include/constants/flags.h:604
|
|
local FLAG_GOT_COIN_CASE = 0x243
|
|
-- pokefirered/include/constants/items.h:312
|
|
local ITEM_TM13 = 301
|
|
local TM13_PRICE = 4000
|
|
-- pokefirered/include/constants/items.h:205
|
|
local ITEM_SMOKE_BALL = 194
|
|
local SMOKE_BALL_PRICE = 800
|
|
|
|
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 corner_prize")
|
|
love.event.quit(0)
|
|
else
|
|
print("FAIL corner_prize 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 Space = require("src.core.game3.scripting.space")
|
|
local Flags = require("src.core.game3.scripting.flags")
|
|
local Player = require("src.core.game3.player")
|
|
local Message = require("src.ui.game3.message")
|
|
local Choice = require("src.ui.game3.choice")
|
|
local Bag = require("src.core.game3.bag")
|
|
local Prize = require("src.ui.game3.prize_corner")
|
|
local CoinsBox = require("src.ui.game3.coins_box")
|
|
|
|
local session = Runtime.getSession()
|
|
if not result(session ~= nil, "new game reached the game3 field") then return finish() end
|
|
|
|
local function ctx() return Space.vm and Space.vm.ctx end
|
|
local function coins() return Bag.Coins.get(session) end
|
|
local function bagCount()
|
|
return Bag.get(session.bag, ITEM_TM13) or 0
|
|
end
|
|
|
|
-- pokefirered/data/maps/CeladonCity_GameCorner_PrizeRoom/scripts.inc:240
|
|
Flags.setFlag(Space.store, ctx(), FLAG_GOT_COIN_CASE, true)
|
|
Bag.Coins.set(session, TM13_PRICE)
|
|
|
|
local function standAt(x, y)
|
|
Player.cellX, Player.cellY = x, y
|
|
Player.px, Player.py = x * 16, y * 16
|
|
Player.targetX, Player.targetY = x, y
|
|
Player.facing = "up"
|
|
if game.session then
|
|
game.session.x, game.session.y, game.session.facing = x, y, "up"
|
|
end
|
|
end
|
|
|
|
Map.load(nil, game, PRIZE_ROOM, { x = 6, y = 4, facing = "up" })
|
|
standAt(6, 4)
|
|
U.wait(90)
|
|
result(Space.mapId == PRIZE_ROOM, "standing at the prize counter, map=" .. tostring(Space.mapId))
|
|
result(coins() == TM13_PRICE, "the coin case holds " .. coins() .. " coins")
|
|
U.shot(game, DIR .. "/corner_prize_01_prize_room.png")
|
|
|
|
local function talkToClerk()
|
|
U.tap(game, "a")
|
|
U.wait(20)
|
|
for _ = 1, 100 do
|
|
if Prize.isOpen() then return true end
|
|
if Message.isOpen() or Choice.active or (Space.vm and Space.vm:isRunning()) then
|
|
U.tap(game, "a")
|
|
end
|
|
U.wait(10)
|
|
end
|
|
return Prize.isOpen()
|
|
end
|
|
|
|
if not talkToClerk() then
|
|
print("[driver] no list from (6,4); trying the counter cell")
|
|
standAt(6, 3)
|
|
U.wait(30)
|
|
talkToClerk()
|
|
end
|
|
if not result(Prize.isOpen(), "the TM clerk opened the prize list") then
|
|
print("[driver] vm running=" .. tostring(Space.vm and Space.vm:isRunning()) ..
|
|
" message=" .. tostring(Message.isOpen()) .. " choice=" .. tostring(Choice.active))
|
|
return finish()
|
|
end
|
|
result(Prize.listId == Prize.LIST_TM_PRIZES,
|
|
"the list is the TM prize list, id=" .. tostring(Prize.listId))
|
|
result(CoinsBox.isVisible and CoinsBox.isVisible(), "the coins box is up beside the list")
|
|
|
|
local rows = Prize.rows or {}
|
|
result(#rows == 6, "the list has pret's six rows, got " .. #rows)
|
|
local priced = 0
|
|
for _, row in ipairs(rows) do
|
|
if row.amount and row.column then priced = priced + 1 end
|
|
end
|
|
result(priced == 5, "five rows print a price in their own column, got " .. priced)
|
|
print("[driver] row 1 name=" .. tostring(rows[1] and rows[1].name) ..
|
|
" price=" .. tostring(rows[1] and rows[1].amount) ..
|
|
" column=" .. tostring(rows[1] and rows[1].column))
|
|
U.wait(20)
|
|
U.shot(game, DIR .. "/corner_prize_02_tm_list.png")
|
|
|
|
U.tap(game, "down")
|
|
U.wait(10)
|
|
result(Prize.cursor == 2, "the cursor walks down the list, at " .. tostring(Prize.cursor))
|
|
U.shot(game, DIR .. "/corner_prize_03_cursor_moved.png")
|
|
U.tap(game, "up")
|
|
U.wait(10)
|
|
result(Prize.cursor == 1, "and back up to TM13")
|
|
|
|
local before = coins()
|
|
U.tap(game, "a")
|
|
U.wait(20)
|
|
for _ = 1, 60 do
|
|
if Choice.active then break end
|
|
U.wait(5)
|
|
end
|
|
result(Choice.active, "the clerk asks to confirm the purchase")
|
|
U.shot(game, DIR .. "/corner_prize_04_confirm.png")
|
|
|
|
U.tap(game, "a")
|
|
U.wait(20)
|
|
for _ = 1, 200 do
|
|
if bagCount() > 0 then break end
|
|
if Message.isOpen() or Choice.active then U.tap(game, "a") end
|
|
U.wait(6)
|
|
end
|
|
result(bagCount() > 0, "TM13 landed in the bag, count=" .. bagCount())
|
|
result(coins() == before - TM13_PRICE,
|
|
string.format("the purchase debited %d coins (%d to %d)", TM13_PRICE, before, coins()))
|
|
U.shot(game, DIR .. "/corner_prize_05_bought.png")
|
|
|
|
for _ = 1, 200 do
|
|
if not (Space.vm and Space.vm:isRunning()) then break end
|
|
if Message.isOpen() or Choice.active or Prize.isOpen() then U.tap(game, "a") end
|
|
U.wait(6)
|
|
end
|
|
result(not (Space.vm and Space.vm:isRunning()), "the script released the player")
|
|
|
|
local StartMenu = require("src.ui.game3.start_menu")
|
|
local BagMenu = require("src.ui.game3.bag_menu")
|
|
local TmCase = require("src.ui.game3.tm_case")
|
|
local ItemsData = require("src.core.game3.items_data")
|
|
Bag.add(session.bag, ItemsData.ITEM_TM_CASE, 1)
|
|
U.tap(game, "start")
|
|
U.wait(30)
|
|
if result(StartMenu.isOpen(), "the start menu opened") then
|
|
local bagIdx
|
|
for i, e in ipairs(StartMenu.ENTRIES or {}) do
|
|
if e.id == "bag" then bagIdx = i break end
|
|
end
|
|
for _ = 1, 20 do
|
|
if StartMenu.cursor == bagIdx then break end
|
|
U.tap(game, "down")
|
|
U.wait(6)
|
|
end
|
|
U.tap(game, "a")
|
|
U.wait(60)
|
|
if result(BagMenu.isOpen(), "the bag opened") then
|
|
local function rowFor(id)
|
|
for i, r in ipairs(BagMenu.list() or {}) do
|
|
if tonumber(r.id) == id then return i end
|
|
end
|
|
end
|
|
for _ = 1, 6 do
|
|
if rowFor(ItemsData.ITEM_TM_CASE) then break end
|
|
U.tap(game, "right")
|
|
U.wait(20)
|
|
end
|
|
local caseRow = rowFor(ItemsData.ITEM_TM_CASE)
|
|
if result(caseRow ~= nil, "the TM CASE is in the KEY ITEMS pocket") then
|
|
for _ = 1, 30 do
|
|
if BagMenu.cursor == caseRow then break end
|
|
U.tap(game, "down")
|
|
U.wait(6)
|
|
end
|
|
U.tap(game, "a")
|
|
U.wait(30)
|
|
for _ = 1, 40 do
|
|
if TmCase.isOpen() then break end
|
|
U.tap(game, "a")
|
|
U.wait(10)
|
|
end
|
|
if result(TmCase.isOpen(), "the TM CASE opened") then
|
|
local found = false
|
|
for _, r in ipairs(TmCase.list() or {}) do
|
|
if tonumber(r.id) == ITEM_TM13 then found = true end
|
|
end
|
|
result(found, "TM13 is filed in the TM CASE")
|
|
U.shot(game, DIR .. "/corner_prize_06_tm_case.png")
|
|
end
|
|
end
|
|
end
|
|
for _ = 1, 30 do
|
|
if not (TmCase.isOpen() or BagMenu.isOpen() or StartMenu.isOpen()) then break end
|
|
U.tap(game, "b")
|
|
U.wait(20)
|
|
end
|
|
end
|
|
|
|
-- pokefirered/data/maps/CeladonCity_GameCorner_PrizeRoom/scripts.inc:203
|
|
Bag.Coins.set(session, TM13_PRICE - 1)
|
|
local short = coins()
|
|
talkToClerk()
|
|
if result(Prize.isOpen(), "the clerk opened the list again") then
|
|
U.tap(game, "a")
|
|
U.wait(20)
|
|
for _ = 1, 60 do
|
|
if Choice.active then break end
|
|
U.wait(5)
|
|
end
|
|
U.tap(game, "a")
|
|
U.wait(30)
|
|
U.shot(game, DIR .. "/corner_prize_07_not_enough.png")
|
|
for _ = 1, 200 do
|
|
if not (Space.vm and Space.vm:isRunning()) then break end
|
|
if Message.isOpen() or Choice.active or Prize.isOpen() then U.tap(game, "a") end
|
|
U.wait(6)
|
|
end
|
|
result(coins() == short,
|
|
string.format("a short purse buys nothing (%d still there)", coins()))
|
|
result(bagCount() == 1, "the bag still holds exactly one TM13, count=" .. bagCount())
|
|
end
|
|
|
|
U.wait(30)
|
|
U.shot(game, DIR .. "/corner_prize_08_back_at_counter.png")
|
|
result(Space.mapId == PRIZE_ROOM, "the player is still in the prize room")
|
|
|
|
-- pokefirered/data/maps/CeladonCity_GameCorner_PrizeRoom/scripts.inc:324
|
|
local ItemsData = require("src.core.game3.items_data")
|
|
local filled = 0
|
|
local id = 1
|
|
while filled < (ItemsData.CAPACITY.ITEMS or 42) and id <= 400 do
|
|
if id ~= ITEM_SMOKE_BALL and ItemsData.pocketOf(id) == "ITEMS" then
|
|
if Bag.add(session.bag, id, 1) then filled = filled + 1 end
|
|
end
|
|
id = id + 1
|
|
end
|
|
result(filled == ItemsData.CAPACITY.ITEMS, "the ITEMS pocket is full, slots=" .. filled)
|
|
Bag.Coins.set(session, SMOKE_BALL_PRICE)
|
|
local fullPurse = coins()
|
|
|
|
standAt(2, 4)
|
|
U.wait(30)
|
|
if result(talkToClerk(), "the battle item clerk opened his list") then
|
|
result(Prize.listId == Prize.LIST_BATTLE_ITEM_PRIZES,
|
|
"the list is the battle item prize list, id=" .. tostring(Prize.listId))
|
|
U.tap(game, "a")
|
|
U.wait(20)
|
|
for _ = 1, 60 do
|
|
if Choice.active then break end
|
|
U.wait(5)
|
|
end
|
|
U.tap(game, "a")
|
|
U.wait(40)
|
|
U.shot(game, DIR .. "/corner_prize_09_bag_full.png")
|
|
for _ = 1, 200 do
|
|
if not (Space.vm and Space.vm:isRunning()) then break end
|
|
if Message.isOpen() or Choice.active or Prize.isOpen() then U.tap(game, "a") end
|
|
U.wait(6)
|
|
end
|
|
result(coins() == fullPurse,
|
|
string.format("a full bag buys nothing (%d still there)", coins()))
|
|
result((Bag.get(session.bag, ITEM_SMOKE_BALL) or 0) == 0, "no SMOKE BALL reached the bag")
|
|
end
|
|
|
|
finish()
|
|
end
|