mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-28 23:00:21 -04:00
159 lines
6.8 KiB
Lua
159 lines
6.8 KiB
Lua
local U = require("tests.drivers.util")
|
|
local X = require("tests.drivers.em_xa_util")
|
|
|
|
local d = X.new("em_slots", "/tmp/em_slots")
|
|
|
|
local GC = function() return require("src.core.game3.scripting.natives_game_corner_rse") end
|
|
|
|
local function hookSnapshots(screen, wants)
|
|
local orig = screen.frame
|
|
screen.frame = function(self, inp)
|
|
orig(self, inp)
|
|
for _, w in ipairs(wants) do
|
|
if not w.taken and w.when(self) then
|
|
w.taken = true
|
|
if self.m.ppu.render then
|
|
local ok, data = pcall(function() return self.m.ppu:snapshot():encode("png"):getString() end)
|
|
if ok then
|
|
os.execute('mkdir -p "' .. d.dir .. '" 2>/dev/null')
|
|
local h = io.open(d.dir .. "/" .. w.name, "wb")
|
|
if h then h:write(data) h:close() end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return function(game)
|
|
local sess = X.newGame(d, game, 0)
|
|
if not sess then return d.finish() end
|
|
local Constants = require("src.core.game3.constants")
|
|
local C = Constants.of("emerald")
|
|
local Bag = require("src.core.game3.bag")
|
|
Bag.add(sess.bag, C:require("items", "ITEM_COIN_CASE"), 1)
|
|
Bag.Coins.set(sess, 120)
|
|
X.setVar("VAR_DAILY_SLOTS", 0)
|
|
|
|
d.check(X.goTo(d, game, "EM_MAUVILLE_CITY_GAME_CORNER", 4, 7, "left"), "Mauville Game Corner loads")
|
|
U.wait(20)
|
|
d.shot(game, "00_game_corner.png")
|
|
GC().last = nil
|
|
U.tap(game, "a")
|
|
local opened = X.waitFor(function() return GC().last and GC().last.screen ~= nil end, 600)
|
|
if not d.check(opened, "slot machine 3 script opens the RSE slot machine (" .. tostring(GC().last and GC().last.phase) .. ")") then
|
|
return d.finish()
|
|
end
|
|
local ui = GC().last.screen
|
|
d.check(ui.machineId >= 0 and ui.machineId <= 5 and ui.machineId == GC().last.machineId,
|
|
"GetSlotMachineId picks machine " .. tostring(ui.machineId) .. " for VAR_0x8004=3")
|
|
local snaps = {
|
|
{ name = "01_bet_prompt.png", when = function(s) return s.core.state == 5 and s.frames > 40 end },
|
|
{ name = "02_reels_spinning.png", when = function(s) return s.core.state == 12 end },
|
|
{ name = "03_stopped.png", when = function(s) return s.core.state == 14 or s.core.state == 15 or s.core.state == 20 end },
|
|
{ name = "05_reel_time_window.png", when = function(s) return s.reelTimeTaskId and s.m.tasks:get(s.reelTimeTaskId).isActive and s.m.tasks:get(s.reelTimeTaskId).data[0] == 4 end },
|
|
{ name = "06_reel_time_outcome.png", when = function(s) return s.reelTimeTaskId and s.m.tasks:get(s.reelTimeTaskId).isActive and (s.m.tasks:get(s.reelTimeTaskId).data[0] == 9 or s.m.tasks:get(s.reelTimeTaskId).data[0] == 16) end },
|
|
}
|
|
hookSnapshots(ui, snaps)
|
|
X.waitFor(function() return ui.core.state == 5 end, 600)
|
|
d.check(ui.core.state == 5, "bet prompt reached (state " .. ui.core.state .. ")")
|
|
d.check(ui.core.coins == 120, "machine starts with the coin case's 120 coins")
|
|
U.wait(10)
|
|
d.still(game, "01b_bet_screen.png")
|
|
|
|
local spins, won = 0, 0
|
|
local function spin(maxBet)
|
|
local before = ui.core.coins
|
|
if maxBet then
|
|
U.tap(game, "r")
|
|
else
|
|
U.tap(game, "down")
|
|
U.wait(2)
|
|
U.tap(game, "a")
|
|
end
|
|
local started = X.waitFor(function() return ui.core.state == 12 end, 900)
|
|
if not started then return false end
|
|
spins = spins + 1
|
|
for _ = 1, 3 do
|
|
X.waitFor(function() return ui.core.state == 12 end, 900)
|
|
U.tap(game, "a")
|
|
U.wait(3)
|
|
end
|
|
local back = X.waitFor(function() return ui.core.state == 5 or ui.core.state == 12 end, 3000)
|
|
if ui.core.state == 12 then return "replay" end
|
|
if ui.core.coins >= before then won = won + 1 end
|
|
return back
|
|
end
|
|
local r = spin(true)
|
|
d.check(r, "max bet spins and stops all three reels")
|
|
d.check(ui.core.bet == 0 or ui.core.state == 12, "round resolves back to the bet prompt")
|
|
d.still(game, "03b_after_spin.png")
|
|
for _ = 1, 6 do
|
|
local rr = spin(false)
|
|
while rr == "replay" do
|
|
for _ = 1, 3 do
|
|
X.waitFor(function() return ui.core.state == 12 end, 900)
|
|
U.tap(game, "a")
|
|
U.wait(3)
|
|
end
|
|
X.waitFor(function() return ui.core.state == 5 or ui.core.state == 12 end, 3000)
|
|
rr = ui.core.state == 12 and "replay" or true
|
|
end
|
|
end
|
|
d.note(string.format("played %d spins, %d without a net loss, coins now %d, bolts %d", spins, won, ui.core.coins, ui.core.pikaPowerBolts))
|
|
|
|
U.tap(game, "select")
|
|
local function infoState()
|
|
for i = 0, 15 do
|
|
local t = ui.m.tasks:get(i)
|
|
if t.isActive and t.func == ui.infoBoxFn then return t.data[0] end
|
|
end
|
|
return -1
|
|
end
|
|
local boxOpen = X.waitFor(function() return infoState() == 6 end, 600)
|
|
d.check(boxOpen and ui.infoWindow and ui.infoWindow.text, "SELECT opens the Reel Time info box")
|
|
d.still(game, "04_info_box.png")
|
|
U.tap(game, "b")
|
|
local boxClosed = X.waitFor(function() return ui:isInfoBoxClosed() and ui.core.state == 5 end, 600)
|
|
d.check(boxClosed, "B closes the info box back to the bet prompt")
|
|
|
|
ui.core.machineBias = bit.bor(ui.core.machineBias, require("src.core.game3.rse.slot_machine").BIAS.REELTIME)
|
|
local rtStart = ui.core.coins
|
|
U.tap(game, "r")
|
|
local rtRan = X.waitFor(function() return ui.reelTimeTaskId ~= nil end, 600)
|
|
d.check(rtRan, "a Reel Time bias starts the Reel Time lottery")
|
|
local rtDone = X.waitFor(function() return ui:isReelTimeTaskDone() and ui.core.state == 12 end, 6000)
|
|
d.check(rtDone, "Reel Time lottery resolves (draw=" .. ui.core.reelTimeDraw .. ", spins left=" .. ui.core.reelTimeSpinsLeft .. ")")
|
|
for _ = 1, 3 do
|
|
X.waitFor(function() return ui.core.state == 12 end, 900)
|
|
U.tap(game, "a")
|
|
U.wait(3)
|
|
end
|
|
X.waitFor(function() return ui.core.state == 5 end, 3000)
|
|
d.note("after Reel Time round coins " .. rtStart .. " -> " .. ui.core.coins)
|
|
|
|
local daily = spins + 1
|
|
X.waitFor(function() return ui.core.state == 5 and not ui.m.ppu.palette.active end, 600)
|
|
U.tap(game, "b")
|
|
local asked = X.waitFor(function() return ui.message ~= nil and ui.yesNo ~= nil end, 600)
|
|
d.check(asked, "B asks to quit")
|
|
U.wait(10)
|
|
d.still(game, "07_quit_prompt.png")
|
|
local final = ui.core.coins
|
|
U.tap(game, "a")
|
|
local closed = X.waitFor(function() return GC().last.phase == "done" end, 1200)
|
|
d.check(closed, "YES fades out and returns to the field")
|
|
X.settle(game, 600)
|
|
X.waitFor(function() return not X.scriptRunning() end, 600)
|
|
U.wait(30)
|
|
local s = X.session()
|
|
d.check(s.map == "EM_MAUVILLE_CITY_GAME_CORNER", "back in the Game Corner (" .. tostring(s.map) .. ")")
|
|
d.check(Bag.Coins.get(s) == final, "coin case holds the machine's coins (" .. Bag.Coins.get(s) .. " == " .. final .. ")")
|
|
d.check(X.var("VAR_DAILY_SLOTS") >= daily - 1 and X.var("VAR_DAILY_SLOTS") > 0,
|
|
"IncrementDailySlotsUses counted the spins (" .. X.var("VAR_DAILY_SLOTS") .. ")")
|
|
d.check(not X.scriptRunning(), "slot machine script released")
|
|
d.shot(game, "08_back_in_field.png")
|
|
for _, w in ipairs(snaps) do d.note("snapshot " .. w.name .. " " .. tostring(w.taken)) end
|
|
d.finish()
|
|
end
|