mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
231 lines
7.7 KiB
Lua
231 lines
7.7 KiB
Lua
local U = require("tests.drivers.util")
|
|
local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/game3_stitchscript_mail"
|
|
|
|
-- pokefirered/data/maps/CeruleanCity_House3/scripts.inc:8
|
|
local TRADE_HOUSE = "FR_CERULEAN_CITY_HOUSE3"
|
|
local DONTAE_X, DONTAE_Y = 2, 2
|
|
-- pokefirered/data/scripts/day_care.inc:1
|
|
local DAY_CARE = "FR_ROUTE_5_POKEMON_DAY_CARE"
|
|
local DAYCARE_X, DAYCARE_Y = 4, 4
|
|
|
|
local SPECIES_POLIWHIRL = 61
|
|
local SPECIES_JYNX = 124
|
|
local SPECIES_BULBASAUR = 1
|
|
local ITEM_FAB_MAIL = 131
|
|
|
|
-- pokefirered/src/data/ingame_trades.h:184 sInGameTradeMailMessages
|
|
local ZYNX_WORDS = { 3613, 4128, 5147, 10876, 3072, 4102, 5183, 4143, 4137 }
|
|
|
|
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 stitchscript_mail")
|
|
love.event.quit(0)
|
|
else
|
|
print("FAIL stitchscript_mail failures=" .. failures)
|
|
love.event.quit(1)
|
|
end
|
|
end
|
|
|
|
return function(game)
|
|
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 Map = require("src.core.game3.map")
|
|
local Space = require("src.core.game3.scripting.space")
|
|
local Player = require("src.core.game3.player")
|
|
local Party = require("src.core.game3.party")
|
|
local Mail = require("src.core.game3.mail")
|
|
local Daycare = require("src.core.game3.scripting.natives_daycare")
|
|
local PartyMenu = require("src.ui.game3.party_menu")
|
|
local Message = require("src.ui.game3.message")
|
|
local Choice = require("src.ui.game3.choice")
|
|
local Audio = require("src.core.game3.audio")
|
|
local TradeSceneUi = require("src.ui.game3.trade_scene")
|
|
|
|
local session = Runtime.getSession()
|
|
if not result(session ~= nil, "new game reached the game3 field") then return finish() end
|
|
|
|
session.party = {}
|
|
Party.giveMonToPlayer(session, SPECIES_POLIWHIRL, 20)
|
|
Party.giveMonToPlayer(session, SPECIES_BULBASAUR, 20)
|
|
session.money = 9999
|
|
result(#session.party == 2, "the player has a POLIWHIRL and a spare, " ..
|
|
tostring(#session.party) .. " mons")
|
|
|
|
local function scriptRunning()
|
|
return (Space.vm and Space.vm.isRunning and Space.vm:isRunning()) or false
|
|
end
|
|
|
|
local function goTo(mapId, x, y, facing)
|
|
Map.load(nil, game, mapId, { x = x, y = y, facing = facing or "up" })
|
|
if game.session then
|
|
game.session.x, game.session.y, game.session.facing = x, y, facing or "up"
|
|
end
|
|
Player.cellX, Player.cellY = x, y
|
|
Player.px, Player.py = x * 16, y * 16
|
|
Player.targetX, Player.targetY = x, y
|
|
Player.facing = facing or "up"
|
|
U.wait(30)
|
|
local Preview = package.loaded["src.ui.game3.map_preview_screen"]
|
|
for _ = 1, 240 do
|
|
if not (Preview and Preview.isActive and Preview.isActive()) then break end
|
|
U.wait(5)
|
|
end
|
|
U.wait(60)
|
|
end
|
|
|
|
local function talkUntilRunning()
|
|
for _ = 1, 24 do
|
|
if scriptRunning() then return true end
|
|
U.tap(game, "a")
|
|
U.wait(12)
|
|
end
|
|
return scriptRunning()
|
|
end
|
|
|
|
local function pumpUntil(pred, frames)
|
|
local budget = frames or 900
|
|
while budget > 0 do
|
|
if pred() then return true end
|
|
if Audio.isSePlaying() then
|
|
U.wait(4)
|
|
elseif PartyMenu.isOpen and PartyMenu.isOpen() then
|
|
U.tap(game, "a")
|
|
U.wait(24)
|
|
elseif Choice.active or (Message.isWaiting and Message.isWaiting())
|
|
or (Message.isOpen and Message.isOpen()) or TradeSceneUi.isOpen() then
|
|
U.tap(game, "a")
|
|
U.wait(10)
|
|
else
|
|
U.wait(4)
|
|
end
|
|
if not Audio.isSePlaying() then budget = budget - 1 end
|
|
end
|
|
return pred()
|
|
end
|
|
|
|
local function shotOnMessage(path, frames)
|
|
for _ = 1, frames or 400 do
|
|
if Message.isOpen and Message.isOpen() then
|
|
U.wait(10)
|
|
U.shot(game, path)
|
|
return true
|
|
end
|
|
U.wait(4)
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function wordsOf(record)
|
|
local out = {}
|
|
for i = 1, Mail.MAIL_WORDS_COUNT do
|
|
out[i] = tostring(record and record.words and record.words[i])
|
|
end
|
|
return table.concat(out, ",")
|
|
end
|
|
|
|
goTo(TRADE_HOUSE, DONTAE_X, DONTAE_Y + 1, "up")
|
|
result(talkUntilRunning(), "DONTAE answers in Cerulean House 3")
|
|
U.wait(30)
|
|
U.shot(game, DIR .. "/stitchscript_mail_01_trade_offer.png")
|
|
|
|
local traded = pumpUntil(function()
|
|
local mon = session.party[1]
|
|
return mon ~= nil and (mon.species or mon.speciesId) == SPECIES_JYNX
|
|
end, 1800)
|
|
result(traded, "the POLIWHIRL became ZYNX")
|
|
|
|
local zynx = session.party[1]
|
|
result(zynx ~= nil and zynx.item == ITEM_FAB_MAIL,
|
|
"ZYNX arrived holding FAB MAIL, got " .. tostring(zynx and zynx.item))
|
|
result(Mail.monHasMail(zynx), "MonHasMail sees the letter DONTAE attached")
|
|
local letter = Mail.get(session, zynx and zynx.mail)
|
|
result(letter ~= nil, "the letter is in the player's mail pool")
|
|
result(wordsOf(letter) == table.concat(ZYNX_WORDS, ","),
|
|
"with sInGameTradeMailMessages[0], got " .. wordsOf(letter))
|
|
result(letter ~= nil and letter.playerName == "DONTAE",
|
|
"signed DONTAE, got " .. tostring(letter and letter.playerName))
|
|
result(letter ~= nil and letter.trainerId == 36728,
|
|
"with DONTAE's trainer id, got " .. tostring(letter and letter.trainerId))
|
|
|
|
result(shotOnMessage(DIR .. "/stitchscript_mail_02_trade_thanks.png"),
|
|
"DONTAE says his piece after the swap")
|
|
|
|
for _ = 1, 240 do
|
|
if not scriptRunning() then break end
|
|
U.tap(game, "a")
|
|
U.wait(8)
|
|
end
|
|
|
|
goTo(DAY_CARE, DAYCARE_X, DAYCARE_Y + 1, "up")
|
|
result(talkUntilRunning(), "the Route 5 day-care man answers")
|
|
U.wait(30)
|
|
U.shot(game, DIR .. "/stitchscript_mail_03_daycare_offer.png")
|
|
|
|
local deposited = pumpUntil(function()
|
|
local r5 = Daycare.route5Of(session)
|
|
return r5 ~= nil and r5.mon ~= nil
|
|
end, 1800)
|
|
result(deposited, "ZYNX went into the day care")
|
|
|
|
local r5 = Daycare.route5Of(session)
|
|
result(r5 ~= nil and r5.mon ~= nil and (r5.mon.item == 0 or r5.mon.item == nil),
|
|
"TakeMailFromMon emptied its hands on the way in, got " ..
|
|
tostring(r5 and r5.mon and r5.mon.item))
|
|
result(r5 ~= nil and r5.mail ~= nil, "the letter moved into the day-care slot")
|
|
result(r5 ~= nil and r5.mail ~= nil and r5.mail.monName == "ZYNX",
|
|
"DayCareMail.monName is ZYNX, got " .. tostring(r5 and r5.mail and r5.mail.monName))
|
|
result(Mail.get(session, 0) == nil, "and the mail pool slot is free while it is away")
|
|
|
|
for _ = 1, 240 do
|
|
if not scriptRunning() then break end
|
|
U.tap(game, "a")
|
|
U.wait(8)
|
|
end
|
|
U.wait(60)
|
|
|
|
result(talkUntilRunning(), "the day-care man answers again for the pick-up")
|
|
local back = pumpUntil(function()
|
|
for _, mon in ipairs(session.party) do
|
|
if (mon.species or mon.speciesId) == SPECIES_JYNX then return true end
|
|
end
|
|
return false
|
|
end, 1800)
|
|
result(back, "ZYNX came back out of the day care")
|
|
|
|
local returned = nil
|
|
for _, mon in ipairs(session.party) do
|
|
if (mon.species or mon.speciesId) == SPECIES_JYNX then returned = mon end
|
|
end
|
|
result(returned ~= nil and returned.item == ITEM_FAB_MAIL,
|
|
"GiveMailToMon2 put the FAB MAIL back in its hands, got " ..
|
|
tostring(returned and returned.item))
|
|
result(Mail.monHasMail(returned), "and it holds its letter again")
|
|
local backLetter = Mail.get(session, returned and returned.mail)
|
|
result(wordsOf(backLetter) == table.concat(ZYNX_WORDS, ","),
|
|
"the nine words survived the day care, got " .. wordsOf(backLetter))
|
|
result(Daycare.route5Of(session).mail == nil, "the day-care slot kept no copy")
|
|
result(shotOnMessage(DIR .. "/stitchscript_mail_04_daycare_return.png"),
|
|
"the day-care man hands ZYNX back")
|
|
|
|
for _ = 1, 240 do
|
|
if not scriptRunning() then break end
|
|
U.tap(game, "a")
|
|
U.wait(8)
|
|
end
|
|
|
|
finish()
|
|
end
|