Files
2026-09-21 11:14:17 -04:00

183 lines
6.5 KiB
Lua

local U = require("tests.drivers.util")
local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/game3_teachy_item"
-- pokefirered/data/maps/ViridianCity/scripts.inc:235 giveitem ITEM_TEACHY_TV
local ITEM_TEACHY_TV = 366
-- pokefirered/include/constants/items.h:436
local ITEM_TM_CASE = 364
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 teachy_item")
love.event.quit(0)
else
print("FAIL teachy_item failures=" .. failures)
love.event.quit(1)
end
end
return function(game)
print("PASS driver_started")
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 Bag = require("src.core.game3.bag")
local StartMenu = require("src.ui.game3.start_menu")
local BagMenu = require("src.ui.game3.bag_menu")
local TeachyTv = require("src.core.game3.teachy_tv")
local TvUi = require("src.ui.game3.teachy_tv")
local session = Runtime.getSession()
if not result(session ~= nil, "new game reached the game3 field") then return finish() end
session.bag = session.bag or Bag.new()
Bag.add(session.bag, ITEM_TEACHY_TV, 1)
result(Bag.get(session.bag, ITEM_TEACHY_TV) == 1, "the TEACHY TV is in the KEY ITEMS pocket")
result(not TeachyTv.hasTmCase(session), "the player has no TM CASE yet")
local function openBagToTeachyTv()
U.tap(game, "start")
U.wait(30)
if not result(StartMenu.isOpen(), "START opened the field menu") then return false end
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)
if not result(BagMenu.isOpen(), "BAG opened") then return false end
for _ = 1, 4 do
if BagMenu.currentPocket() == "KEY_ITEMS" then break end
U.tap(game, "right")
U.wait(15)
end
if not result(BagMenu.currentPocket() == "KEY_ITEMS",
"walked to KEY ITEMS, at " .. tostring(BagMenu.currentPocket())) then
return false
end
local function selectedName()
local rows = BagMenu.list()
local row = rows and rows[BagMenu.cursor]
return row and tostring(row.name) or nil
end
for _ = 1, 20 do
if selectedName() == "TEACHY TV" then break end
U.tap(game, "down")
U.wait(8)
end
return result(selectedName() == "TEACHY TV",
"the bag cursor is on TEACHY TV, at " .. tostring(selectedName()))
end
if not openBagToTeachyTv() then return finish() end
U.shot(game, DIR .. "/teachy_item_01_bag.png")
U.tap(game, "a")
U.wait(25)
local firstAction = BagMenu.ACTIONS and BagMenu.ACTIONS[BagMenu.actionCursor]
result(firstAction == "USE", "USE is the first key-item action, got " .. tostring(firstAction))
U.tap(game, "a")
U.wait(60)
-- pokefirered/src/item_use.c:518 FieldUseFunc_TeachyTv
if not result(TvUi.isOpen(), "USE opened the TEACHY TV") then
U.shot(game, DIR .. "/teachy_item_02_no_tv.png")
return finish()
end
result(TvUi.state == "list", "the TV opens on the lesson list, state=" .. tostring(TvUi.state))
-- pokefirered/src/teachy_tv.c:201 sListMenuItems_NoTMCase
local rows = TvUi.rows()
result(#rows == 5, "five rows without a TM CASE, got " .. tostring(#rows))
result(rows[1] and rows[1].index == TeachyTv.SCRIPT.BATTLE, "row 1 is the battle lesson")
result(rows[4] and rows[4].index == TeachyTv.SCRIPT.CATCHING, "row 4 is the catching lesson")
result(rows[5] and rows[5].index == TeachyTv.CANCEL, "row 5 is CANCEL")
U.wait(30)
U.shot(game, DIR .. "/teachy_item_02_lesson_menu.png")
for _ = 1, 3 do
U.tap(game, "down")
U.wait(14)
end
result(TvUi.cursor == 4, "the cursor walked to the catching lesson, at " .. tostring(TvUi.cursor))
U.wait(20)
U.shot(game, DIR .. "/teachy_item_03_cursor_catching.png")
-- pokefirered/src/teachy_tv.c:740 TeachyTvOptionListController
U.tap(game, "a")
U.wait(10)
result(TvUi.state == "lesson", "A started the lesson, state=" .. tostring(TvUi.state))
result(TeachyTv.whichScript(session) == TeachyTv.SCRIPT.CATCHING,
"whichScript is TTVSCR_CATCHING, got " .. tostring(TeachyTv.whichScript(session)))
result(TvUi.stepName() == "transition_render_bg2",
"the cluster starts on the transition, step=" .. tostring(TvUi.stepName()))
local function waitFor(fn, budget)
for _ = 1, (budget or 600) do
if fn() then return true end
U.wait(1)
end
return fn() and true or false
end
-- pokefirered/src/teachy_tv.c:782 TTVcmd_NpcMoveAndSetupTextPrinter
result(waitFor(function() return TvUi.phase == "hello" end, 700),
"the POKé DUDE walked in and said hello, phase=" .. tostring(TvUi.phase))
print("[driver] hello page 1: " .. tostring(TvUi.pages()[1]))
U.wait(20)
U.shot(game, DIR .. "/teachy_item_04_lesson_hello.png")
-- pokefirered/src/teachy_tv.c:808 TeachyTvRenderMsgAndSwitchClusterFuncs
U.tap(game, "b")
U.wait(10)
result(TvUi.stepName() == "end", "B jumped the cluster to TTVcmd_End")
result(waitFor(function() return TvUi.state == "list" end, 200),
"B dropped back to the lesson list, state=" .. tostring(TvUi.state))
result(TvUi.isOpen(), "the TV is still open after B")
U.wait(20)
U.shot(game, DIR .. "/teachy_item_05_back_on_list.png")
U.tap(game, "b")
U.wait(45)
result(not TvUi.isOpen(), "B on the list closed the TV")
result(BagMenu.isOpen(), "the BAG is underneath again, the way CB2_BagMenuFromStartMenu returns")
U.wait(20)
U.shot(game, DIR .. "/teachy_item_06_back_in_bag.png")
-- pokefirered/src/teachy_tv.c:553 TeachyTvSetupWindow
Bag.add(session.bag, ITEM_TM_CASE, 1)
result(TeachyTv.hasTmCase(session), "the TM CASE is in the bag now")
U.tap(game, "a")
U.wait(25)
U.tap(game, "a")
U.wait(60)
if not result(TvUi.isOpen(), "the TEACHY TV opened a second time") then return finish() end
rows = TvUi.rows()
result(#rows == 7, "seven rows with a TM CASE, got " .. tostring(#rows))
result(rows[5] and rows[5].index == TeachyTv.SCRIPT.TMS, "the TM lesson appeared")
result(rows[6] and rows[6].index == TeachyTv.SCRIPT.REGISTER, "the register lesson appeared")
U.wait(30)
U.shot(game, DIR .. "/teachy_item_07_tmcase_rows.png")
U.tap(game, "b")
U.wait(45)
result(not TvUi.isOpen(), "the TV closed again")
finish()
end