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

120 lines
3.7 KiB
Lua

local U = require("tests.drivers.util")
local L = {}
local function flat(t)
if type(t) == "table" then
local ok, s = pcall(require("src.core.game3.scripting.text_ir").toAscii, t, {})
t = ok and s or ""
end
return (tostring(t):gsub("\\[lnp]", " "):gsub("[\n\r]", " "):gsub(" +", " "))
end
function L.logIndex(needle)
local Ui = require("src.core.game3.battle.ui")
needle = flat(needle)
for i, t in ipairs(Ui.log and Ui.log() or {}) do
if flat(t):find(needle, 1, true) then return i end
end
return nil
end
function L.logHas(needle)
return L.logIndex(needle) ~= nil
end
function L.dumpLog(prefix)
local Ui = require("src.core.game3.battle.ui")
for i, t in ipairs(Ui.log and Ui.log() or {}) do
print((prefix or "[log]") .. " " .. i .. " " .. flat(t))
end
end
local function pickMove(st, id)
local Commands = require("src.core.game3.battle.commands")
local Moves = require("src.core.game3.battle.moves")
local b = st and st.battlers and st.battlers[id]
local mon = b and b.mon
if not mon then return nil end
local best, bestPow
for slot = 1, 4 do
local mv = mon.moves and mon.moves[slot]
if mv and mv ~= 0 and Commands.moveUsable(st, slot, id) then
local def = Moves.get(mv)
local pow = def and tonumber(def.power) or 0
if not best or pow > bestPow then best, bestPow = slot, pow end
end
end
return best
end
function L.run(game, opts)
opts = opts or {}
local Battle = require("src.core.game3.battle")
local Ui = require("src.core.game3.battle.ui")
local Anim = require("src.core.game3.battle.anim")
local PartyMenu = require("src.ui.game3.party_menu")
local StatGrowth = require("src.ui.game3.stat_growth")
local cap = opts.turnCap or 30
local onFrame = opts.onFrame
local guard = 0
while Battle.isActive() and guard < (opts.guard or 30000) do
guard = guard + 1
local st = Battle._st
if st and (st.turn or 0) > cap then break end
if onFrame then onFrame(st, Battle._phase) end
local phase = Battle._phase
if PartyMenu.isOpen and PartyMenu.isOpen() then
local pick
for i = 1, #(PartyMenu._party or {}) do
local ok = PartyMenu._validate == nil or PartyMenu._validate(i) == nil
local mon = PartyMenu._party[i]
if ok and mon and (tonumber(mon.hp) or 0) > 0 then pick = i break end
end
if not pick then return false, "no replacement" end
PartyMenu.cursor = pick
U.wait(10)
U.tap(game, "a")
U.wait(10)
PartyMenu.actionCursor = 1
U.tap(game, "a")
U.wait(10)
elseif phase == "command" and Ui._mode == "menu" and not Anim.busy() then
U.tap(game, "a")
U.wait(6)
elseif phase == "command" and Ui._mode == "moves" then
local who = Ui.activeBattler and Ui.activeBattler() or 0
local slot = pickMove(st, who)
if slot then
for _ = 1, 6 do
local cur = (Ui._moveIndex or 1) - 1
local want = slot - 1
if cur == want then break end
local key
if cur % 2 ~= want % 2 then
key = (cur % 2 == 0) and "right" or "left"
else
key = (cur < want) and "down" or "up"
end
U.tap(game, key)
U.wait(4)
end
end
U.tap(game, "a")
U.wait(6)
elseif phase == "command" and (Ui._mode == "selmsg" or Ui._mode == "target") then
U.tap(game, "a")
U.wait(6)
elseif StatGrowth.isOpen() then
U.tap(game, "a")
U.wait(4)
else
if Ui.dialogPending and Ui.dialogPending() then U.tap(game, "a") else U.wait(1) end
if Ui.choiceActive and Ui.choiceActive() then U.tap(game, "b") U.wait(4) end
end
end
return not Battle.isActive()
end
return L