Files
gen1recomp/tests/drivers/game3_stitchscript_mail.lua
T

225 lines
7.4 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 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)
for _ = 1, frames or 900 do
if pred() then return true end
if 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()) then
U.tap(game, "a")
U.wait(10)
else
U.wait(4)
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