Files
gen1recomp/tests/drivers/em_shop.lua
T
bryanthaboi 690f0cd9a1 TOUCHDOWN
2026-09-27 16:07:31 -04:00

164 lines
6.6 KiB
Lua

local U = require("tests.drivers.util")
local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/em_shop"
local failures = 0
local function check(ok, label)
print((ok and "PASS " or "FAIL ") .. label)
if not ok then failures = failures + 1 end
return ok
end
local function finish()
print((failures == 0 and "PASS" or "FAIL") .. " em_shop failures=" .. failures)
love.event.quit(failures == 0 and 0 or 1)
U.wait(10)
end
local function try(label, fn)
local ok, err = xpcall(fn, debug.traceback)
if not ok then print("[driver] " .. label .. " error: " .. tostring(err)) end
return ok
end
return function(game)
for _ = 1, 900 do
if game.phase == "boot" and game.boot then break end
U.wait(1)
end
if not check(game.boot ~= nil, "boot reached") then return finish() end
try("new_game", function() game:_handleBootAction({ action = "new_game", name = "BRENDAN", gender = 0 }) end)
U.wait(30)
local Runtime = require("src.core.game3.runtime")
local Map = require("src.core.game3.map")
local Player = require("src.core.game3.player")
local Space = require("src.core.game3.scripting.space")
local Message = require("src.ui.game3.message")
local Party = require("src.core.game3.party")
local Bag = require("src.core.game3.bag")
local ShopMenu = require("src.ui.game3.shop_menu")
local Marts = require("src.core.game3.marts")
local DecorInv = require("src.core.game3.rse.decoration_inventory")
local C = require("src.core.game3.constants").of("emerald")
local session = Runtime.getSession()
if not check(session and session.version == "emerald", "emerald session") then return finish() end
Party.giveMonToPlayer(session, C:require("species", "SPECIES_TORCHIC"), 5)
local labels = Space.bundle and Space.bundle.labels or {}
local function goTo(mapId, x, y, facing)
try("Map.load " .. mapId, function() Map.load(nil, game, mapId, { x = x, y = y, facing = facing }) end)
local s = Runtime.getSession()
if s then s.x, s.y, s.facing = x, y, facing end
Player.cellX, Player.cellY = x, y
Player.px, Player.py = x * 16, y * 16
Player.targetX, Player.targetY = x, y
Player.facing = facing
U.wait(40)
end
local function waitFor(pred, frames, pressA)
for i = 1, frames or 600 do
if pred() then return true end
if pressA and i % 12 == 0 then U.tap(game, "a") else U.wait(1) end
end
return pred()
end
local n = 0
local function shot(name) n = n + 1 U.shot(game, string.format("%s/%02d_%s.png", DIR, n, name)) end
local function settleFade() for _ = 1, 120 do if not ShopMenu._fading then break end U.wait(1) end U.wait(4) end
-- pokeemerald/data/maps/OldaleTown_Mart/map.json:1
goTo("EM_OLDALE_TOWN_MART", 3, 3, "left")
U.wait(30)
U.tap(game, "a")
U.wait(30)
print("[driver] after A: vm running " .. tostring(Space.vm:isRunning()) .. " key " .. tostring(Space.vm._scriptKey)
.. " msg " .. tostring(Message.isOpen and Message.isOpen()) .. " facing " .. tostring(Player.facing))
check(waitFor(function() return ShopMenu.isOpen() end, 600, true), "A across the counter runs the clerk and opens the mart")
check(ShopMenu._rse ~= nil and ShopMenu._martType == "NORMAL", "Emerald shop path (MART_TYPE_NORMAL)")
shot("mart_menu")
local money0 = session.money
U.tap(game, "a")
settleFade()
check(ShopMenu.state == "list" and ShopMenu.isShopCamera(), "BUY opens the buy list")
local camera = ShopMenu.shopCameraOffset()
check(camera and camera.x == -4 and camera.y == -4, "buy view offset from shop.c (-4,-4)")
shot("buy_list")
local potion = C:require("items", "ITEM_POTION")
for _ = 1, 6 do
if ShopMenu._items[ShopMenu.scroll + ShopMenu.row + 1] == potion then break end
U.tap(game, "down")
U.wait(4)
end
check(ShopMenu._items[ShopMenu.scroll + ShopMenu.row + 1] == potion, "cursor on POTION")
shot("buy_list_potion")
U.tap(game, "a")
U.wait(4)
check(ShopMenu.state == "qty", "how many prompt")
U.tap(game, "up")
U.wait(4)
check(ShopMenu.qty == 2 and ShopMenu._totalCost == 600, "quantity 2 costs 600 (" .. tostring(ShopMenu._totalCost) .. ")")
shot("how_many")
U.tap(game, "a")
U.wait(4)
check(ShopMenu.state == "confirm", "YES/NO confirm")
shot("confirm")
U.tap(game, "a")
U.wait(4)
check(Bag.get(session.bag, potion) == 2 and session.money == money0 - 600,
"bought 2 Potions (money " .. tostring(session.money) .. ")")
shot("thanks")
U.tap(game, "a")
U.wait(4)
check(ShopMenu.state == "list", "back to the list")
U.tap(game, "b")
settleFade()
check(ShopMenu.state == "root" and not ShopMenu.isShopCamera(), "B returns to BUY/SELL/QUIT")
shot("anything_else")
U.tap(game, "down")
U.wait(2)
U.tap(game, "down")
U.wait(2)
U.tap(game, "a")
check(waitFor(function() return not ShopMenu.isOpen() end, 120), "QUIT closes the mart")
check(waitFor(function() return not Space.vm:isRunning() end, 600, true), "clerk script finishes")
local key = 0x08000000 + require("src.import.gba.syms").of("emerald").off("LilycoveCity_DepartmentStore_5F_Pokemart_Dolls")
local items, entry = Marts.itemsFor(key)
check(items ~= nil and entry and entry.martType == "DECOR2", "Lilycove 5F doll list is a DECOR2 mart (" .. tostring(key) .. ")")
goTo("EM_LILYCOVE_CITY_DEPARTMENT_STORE_5F", 7, 3, "up")
session.money = 50000
local closed = false
try("openShop", function()
Space.vm.adapters.openShop(key, function() closed = true end)
end)
check(ShopMenu.isOpen() and ShopMenu._martType == "DECOR2" and #ShopMenu._items == #items, "decoration shop opens (BUY/QUIT)")
shot("decor_menu")
U.tap(game, "a")
settleFade()
shot("decor_list")
local doll = ShopMenu._items[1]
local info = DecorInv.info(doll)
check(info and info.category == 6, "first entry is a DOLL (" .. tostring(info and info.name) .. ")")
U.tap(game, "a")
U.wait(4)
check(ShopMenu.state == "confirm", "decor goes straight to YES/NO")
shot("decor_confirm")
U.tap(game, "a")
U.wait(4)
check(DecorInv.has(doll, session) and DecorInv.countInCategory(6, session) == 1, "doll sent home into the DOLL inventory")
check(session.money == 50000 - info.price, "doll price paid (" .. tostring(info.price) .. ")")
shot("decor_thanks")
U.tap(game, "a")
U.wait(4)
U.tap(game, "b")
settleFade()
U.tap(game, "b")
U.wait(10)
check(closed, "decoration shop returns to the script")
local Ops = require("src.core.game3.scripting.ops_rse")
local vmRse = require("src.core.game3.rse.init")
local r, handled = vmRse.call("decorations", "checkSpace", "checkdecorspace", nil, doll)
check(handled and r == true, "decorations system answers checkdecorspace")
check(Ops.HANDLERS.checkdecor ~= nil, "ops_rse routes checkdecor")
finish()
end