Files
gen1recomp/tests/drivers/game3_special_trade.lua

234 lines
7.5 KiB
Lua

local U = require("tests.drivers.util")
local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/game3_special_trade"
-- pokefirered/data/maps/Route2_House/scripts.inc:8 Route2_House_EventScript_Reyley
local HOUSE = "FR_ROUTE_2_HOUSE"
local REYLEY_X, REYLEY_Y = 7, 2
-- pokefirered/include/constants/species.h:67
local SPECIES_ABRA = 63
-- pokefirered/include/constants/species.h:126
local SPECIES_MR_MIME = 122
-- pokefirered/include/constants/flags.h:609
local FLAG_DID_MIMIEN_TRADE = 0x248
local failures = 0
local function say(line)
print(line)
os.execute('mkdir -p "' .. DIR .. '" 2>/dev/null')
local fh = io.open(DIR .. "/special_trade.log", "a")
if fh then
fh:write(line, "\n")
fh:close()
end
end
local function result(ok, label)
say((ok and "PASS " or "FAIL ") .. label)
if not ok then failures = failures + 1 end
return ok
end
local function finish()
if failures == 0 then
say("PASS special_trade")
love.event.quit(0)
else
say("FAIL special_trade 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 Flags = require("src.core.game3.scripting.flags")
local Player = require("src.core.game3.player")
local Party = require("src.core.game3.party")
local Pokemon = require("src.core.game3.pokemon")
local PartyMenu = require("src.ui.game3.party_menu")
local StartMenu = require("src.ui.game3.start_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 = {}
require("src.core.game3.scripting.flags").setFlag(require("src.core.game3.scripting.space").store, nil, 0x828, true) -- data/maps/PalletTown_ProfessorOaksLab/scripts.inc:1120
Party.giveMon(session, SPECIES_ABRA, 18)
Party.giveMon(session, 4, 14)
result(#session.party == 2 and session.party[1].species == SPECIES_ABRA,
"the party leads with the ABRA Reyley asks for")
local function ctx() return Space.vm and Space.vm.ctx end
local function getVar(id) return tonumber(Flags.getVar(Space.store, ctx(), id)) or 0 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
result(Flags.getFlag(Space.store, ctx(), FLAG_DID_MIMIEN_TRADE) ~= true,
"FLAG_DID_MIMIEN_TRADE starts clear")
goTo(HOUSE, REYLEY_X, REYLEY_Y + 1, "up")
U.shot(game, DIR .. "/special_trade_01_reyley.png")
local function scriptRunning()
return Space.vm and Space.vm.isRunning and Space.vm:isRunning() or false
end
say("[driver] talking to Reyley")
local asked = false
for _ = 1, 40 do
if Choice.active then
asked = true
break
end
if Message.isWaiting and Message.isWaiting() then
U.tap(game, "a")
elseif not scriptRunning() then
U.tap(game, "a")
end
U.wait(8)
end
result(asked, "Reyley asked to trade his MR. MIME for an ABRA")
U.shot(game, DIR .. "/special_trade_02_offer.png")
-- pokefirered/data/maps/Route2_House/scripts.inc:14
for _ = 1, 10 do
if Choice.cursor == 1 then break end
U.tap(game, "up")
U.wait(6)
end
U.tap(game, "a")
U.wait(20)
local picker = false
for _ = 1, 90 do
if PartyMenu.isOpen and PartyMenu.isOpen() then
picker = true
break
end
if Choice.active or (Message.isWaiting and Message.isWaiting()) then U.tap(game, "a") end
U.wait(6)
end
result(picker, "ChoosePartyMon opened the party picker")
if not picker then
U.shot(game, DIR .. "/special_trade_03_no_picker.png")
return finish()
end
say("[driver] handing over the ABRA in slot 1")
U.tap(game, "a")
U.wait(30)
result(getVar(0x8004) == 0, "VAR_0x8004 = 0 for slot 1, got " .. tostring(getVar(0x8004)))
local TradeScene = require("src.core.game3.trade_scene")
local sawScene = false
for _ = 1, 600 do
if TradeScene.isOpen() then sawScene = true break end
U.wait(1)
end
result(sawScene, "DoInGameTradeScene started the trade animation")
U.tap(game, "a")
U.wait(4)
local waited = false
for _ = 1, 3000 do
if TradeScene.phase() == "end_link_trade" then waited = true break end
U.wait(1)
end
result(waited, "the trade animation reaches the A-button wait")
U.wait(60)
result(TradeScene.phase() == "end_link_trade",
"an A pressed mid-animation does not skip the final A wait (trade_scene.c:1772)")
U.shot(game, DIR .. "/special_trade_02b_take_good_care.png")
local swapped = false
for _ = 1, 400 do
local lead = session.party and session.party[1]
if lead and (tonumber(lead.species) or 0) == SPECIES_MR_MIME then
swapped = true
break
end
if TradeScene.phase() == "end_link_trade" then U.tap(game, "a") end
U.wait(4)
end
result(swapped, "DoInGameTradeScene put MR. MIME in the party")
local lead = session.party and session.party[1] or {}
result(tostring(lead.nickname) == "MIMIEN",
"the received mon is nicknamed MIMIEN, got " .. tostring(lead.nickname))
result(tonumber(lead.otId) == 1985,
"its OT id is the cart's 1985, got " .. tostring(lead.otId))
result(tostring(lead.otName) == "REYLEY",
"its OT name is REYLEY, got " .. tostring(lead.otName))
result(tonumber(lead.level) == 18,
"it arrived at the ABRA's level 18, got " .. tostring(lead.level))
result(tonumber(lead.friendship) == 70,
"a traded mon starts at 70 friendship, got " .. tostring(lead.friendship))
result(session.dex and session.dex.owned and session.dex.owned[SPECIES_MR_MIME] == true,
"MR. MIME is registered as owned")
for _ = 1, 200 do
if not scriptRunning() and not (Message.isOpen and Message.isOpen()) then break end
if Message.isWaiting and Message.isWaiting() then U.tap(game, "a") end
U.wait(6)
end
result(Flags.getFlag(Space.store, ctx(), FLAG_DID_MIMIEN_TRADE) == true,
"FLAG_DID_MIMIEN_TRADE is set once the trade finished")
local function openParty()
for _ = 1, 40 do
if PartyMenu.isOpen and PartyMenu.isOpen() then return true end
if StartMenu.isOpen and StartMenu.isOpen() then break end
U.tap(game, "start")
U.wait(8)
end
for _ = 1, 20 do
local e = StartMenu.ENTRIES and StartMenu.ENTRIES[StartMenu.cursor]
if e and e.id == "pokemon" then break end
U.tap(game, "down")
U.wait(6)
end
U.tap(game, "a")
for _ = 1, 80 do
if PartyMenu.isOpen and PartyMenu.isOpen() then return true end
U.wait(4)
end
return false
end
result(openParty(), "the party screen opened")
U.wait(20)
U.shot(game, DIR .. "/special_trade_03_mimien_in_party.png")
U.log("lead mon: " .. tostring(Pokemon.name(lead.species)) .. " / " ..
tostring(lead.nickname) .. " Lv" .. tostring(lead.level))
finish()
end