mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-28 23:00:21 -04:00
135 lines
5.4 KiB
Lua
135 lines
5.4 KiB
Lua
local U = require("tests.drivers.util")
|
|
local S = require("tests.drivers.em_story_util")
|
|
|
|
return function(game)
|
|
local d = S.new("em_apprentice", "/tmp/em_apprentice")
|
|
local check, note = d.check, d.note
|
|
local function shot(name) d.shot(game, name) end
|
|
local function finish() return d.finish() end
|
|
|
|
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
|
|
|
|
local SaveData = require("src.core.SaveData")
|
|
local Schema = require("src.core.game3.save_schema_firered")
|
|
local raw = love.filesystem.read("saves/emerald/slot1.lua")
|
|
if not check(type(raw) == "string", "identity has the post-Hall-of-Fame save") then return finish() end
|
|
local session = Schema.fromSaveTable(SaveData.decode(raw))
|
|
require("src.core.game3.options").bind(session, game.options)
|
|
game:adoptSave(session, true)
|
|
game.sessionStartedAt = os.time()
|
|
game:_enterField(session, "continue")
|
|
U.wait(30)
|
|
S.settle(game)
|
|
|
|
local Runtime = require("src.core.game3.runtime")
|
|
local Map = require("src.core.game3.map")
|
|
local Natives = require("src.core.game3.scripting.natives")
|
|
local Objects = require("src.core.game3.objects")
|
|
local EasyChat = require("src.ui.game3.easy_chat")
|
|
local Choice = require("src.ui.game3.choice")
|
|
session = Runtime.getSession()
|
|
Natives.ensureBound(session)
|
|
local Ap = require("src.core.game3.rse.frontier.apprentice")
|
|
check(Natives.handlerFor("CallApprenticeFunction") ~= nil, "CallApprenticeFunction bound on Emerald")
|
|
require("src.core.game3.encounters").onStep = function() return nil end
|
|
local Bag = require("src.core.game3.bag")
|
|
Bag.add(session.bag, S.item("ITEM_LEFTOVERS"), 1)
|
|
Bag.add(session.bag, S.item("ITEM_QUICK_CLAW"), 1)
|
|
Bag.add(session.bag, S.item("ITEM_SITRUS_BERRY"), 1)
|
|
|
|
local function teleport(mapId, x, y, facing)
|
|
S.settle(game)
|
|
local ok, err = pcall(function() Map.load(nil, game, mapId, { x = x, y = y, facing = facing }) end)
|
|
if not ok then note("Map.load " .. mapId .. ": " .. tostring(err)) end
|
|
local s = Runtime.getSession()
|
|
if s then s.x, s.y, s.facing = x, y, facing end
|
|
U.wait(30)
|
|
S.settle(game)
|
|
return ok
|
|
end
|
|
|
|
local p = Ap.player(session)
|
|
local startId = p.id
|
|
local asked = {}
|
|
local shots = 0
|
|
local chatDone = false
|
|
local bagPick = 0
|
|
for day = 1, 14 do
|
|
S.setFlag("FLAG_DAILY_APPRENTICE_LEAVES", false)
|
|
S.setFlag("FLAG_HIDE_APPRENTICE", false)
|
|
if not teleport("EM_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY", 1, 7, "up") then break end
|
|
local app = S.objectByScript("BattleFrontier_BattleTowerLobby_EventScript_Apprentice")
|
|
if not app or app.hidden then
|
|
note("day " .. day .. ": apprentice not shown")
|
|
break
|
|
end
|
|
if day == 1 then
|
|
check(tonumber(app.graphicsId) == S.var("VAR_OBJ_GFX_ID_0") or app.graphicsId ~= nil,
|
|
"apprentice_setgfx picks the apprentice's gfx")
|
|
shot("01_apprentice_in_lobby")
|
|
end
|
|
local before = p.questionsAnswered
|
|
local menus = 0
|
|
local settleOpts
|
|
local tick = 0
|
|
settleOpts = { limit = 20000,
|
|
watch = function()
|
|
tick = tick + 1
|
|
if tick % 3000 == 0 then
|
|
note("stuck? day " .. day .. " vm " .. S.vmWhere() .. " choice " .. tostring(Choice.isOpen()) .. " msg "
|
|
.. tostring(require("src.ui.game3.message").isOpen()) .. " fade " .. tostring(require("src.ui.game3.fade").isActive and require("src.ui.game3.fade").isActive()))
|
|
end
|
|
end,
|
|
choice = function(ch)
|
|
menus = menus + 1
|
|
if shots < 4 then
|
|
shots = shots + 1
|
|
U.wait(6)
|
|
shot(string.format("02_question_%d", shots))
|
|
end
|
|
local n = #(ch.options or {})
|
|
local last = ch.options and ch.options[n]
|
|
if n > 2 and tostring(type(last) == "table" and (last.text or last[1]) or last):upper():find("CANCEL", 1, true) then
|
|
bagPick = bagPick % (n - 1) + 1
|
|
return bagPick
|
|
end
|
|
return 1
|
|
end,
|
|
onIdleUi = function()
|
|
if EasyChat.isOpen() then
|
|
local def = Ap.def(p.id)
|
|
U.wait(10)
|
|
shot("03_win_speech_easy_chat")
|
|
EasyChat.close(true, def and def.speechLost or { 1, 2, 3 })
|
|
chatDone = true
|
|
U.wait(10)
|
|
return true
|
|
end
|
|
return false
|
|
end }
|
|
S.talkTo(game, app, { settle = settleOpts })
|
|
S.settle(game, settleOpts)
|
|
local qs = {}
|
|
for i = 1, Ap.MAX_QUESTIONS do qs[i] = tostring(p.questions[i].questionId) end
|
|
note("questions " .. table.concat(qs, ","))
|
|
asked[#asked + 1] = string.format("day %d answered %d->%d menus %d", day, before, p.questionsAnswered, menus)
|
|
if chatDone then break end
|
|
end
|
|
for _, a in ipairs(asked) do note(a) end
|
|
check(#asked >= 4, "the apprentice asked on several days (" .. #asked .. ")")
|
|
check(p.lvlMode ~= 0 or chatDone, "the first meeting sets the level mode")
|
|
check(chatDone, "the apprentice finally asks for a win speech through the easy chat screen")
|
|
local saved = Ap.saved(session)[1]
|
|
check(saved.number >= 1 and saved.id == startId, "SaveApprentice stored apprentice " .. tostring(startId)
|
|
.. " as number " .. tostring(saved.number))
|
|
check(saved.party[1].species ~= 0 and saved.party[2].species ~= 0 and saved.party[3].species ~= 0,
|
|
"the saved apprentice has a three-mon party")
|
|
check(saved.speechWon[1] ~= Ap.EC_EMPTY_WORD, "the win speech is saved")
|
|
check(Ap.player(session).questionsAnswered == 0, "apprentice_reset starts a new apprentice")
|
|
finish()
|
|
end
|