mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
23617f43b4
CLOSES #2290, CLOSES #2338, CLOSES #2186, CLOSES #2305, CLOSES #2332, CLOSES #2320, CLOSES #2344, CLOSES #2291, CLOSES #2335, CLOSES #2340, CLOSES #2385, CLOSES #2352, CLOSES #2378, CLOSES #2403, CLOSES #2404, CLOSES #2405, CLOSES #2367, CLOSES #2037, CLOSES #2177, CLOSES #2368, CLOSES #2382, CLOSES #1951
206 lines
6.9 KiB
Lua
206 lines
6.9 KiB
Lua
-- scripts/PewterPokecenter_2.asm:10-68
|
|
-- engine/pikachu/pikachu_emotions.asm:318
|
|
-- engine/pikachu/pikachu_movement.asm:973
|
|
return function(game)
|
|
local U = dofile("tests/drivers/util.lua")
|
|
local GameVersion = require("src.core.GameVersion")
|
|
local Pokemon = require("src.pokemon.Pokemon")
|
|
local TextBox = require("src.render.TextBox")
|
|
local PikachuFollower = require("src.world.PikachuFollower")
|
|
|
|
local DIR = os.getenv("POKEPORT_SHOT_DIR") or os.getenv("SHOT_DIR") or "/tmp/shots"
|
|
local MAP = "PEWTER_POKECENTER"
|
|
local PUFF = "PEWTERPOKECENTER_JIGGLYPUFF"
|
|
local failures = 0
|
|
|
|
local function check(label, ok)
|
|
U.log(ok and "PASS" or "FAIL", label)
|
|
if not ok then failures = failures + 1 end
|
|
return ok
|
|
end
|
|
|
|
local function finish()
|
|
U.log(failures == 0 and "ALL PASS" or ("DONE " .. failures .. " check(s) failed"))
|
|
love.event.quit(failures == 0 and 0 or 1)
|
|
while true do coroutine.yield() end
|
|
end
|
|
|
|
if not check("2335_yellow_cache", GameVersion.isYellow()) then finish() end
|
|
|
|
local starter = Pokemon.new(game.data, "PIKACHU", 12)
|
|
require("src.battle.BattleState").stampOT(game.save, starter)
|
|
game.save.party = { starter }
|
|
game.save.flags = game.save.flags or {}
|
|
game.save.flags.EVENT_GOT_STARTER = true
|
|
game.save.flags.EVENT_BATTLED_RIVAL_IN_OAKS_LAB = true
|
|
game.save.pikachuInBall = false
|
|
|
|
U.teleport(game, MAP, 2, 3, "left")
|
|
U.wait(20)
|
|
local ow = game.overworld
|
|
|
|
local function find(pred)
|
|
for _, n in ipairs(ow.npcs or {}) do
|
|
if pred(n) then return n end
|
|
end
|
|
return nil
|
|
end
|
|
local puff = find(function(n) return n.def and n.def.name == PUFF end)
|
|
local pika = find(function(n) return n.pikachuFollower end)
|
|
check("2335_puff_loaded", puff ~= nil)
|
|
if not check("2335_follower_spawned", pika ~= nil) then finish() end
|
|
U.log("player", ow.player.cellX, ow.player.cellY, "pikachu", pika.cellX, pika.cellY)
|
|
|
|
local function facingNpc(n)
|
|
local fx, fy = ow.player:facingCell()
|
|
return ow:npcAtCell(fx, fy) == n
|
|
end
|
|
if not check("2335_facing_puff", facingNpc(puff)) then finish() end
|
|
|
|
local function boxOnTop()
|
|
local top = game.stack:top()
|
|
if getmetatable(top) == TextBox then return top end
|
|
return nil
|
|
end
|
|
|
|
U.tap(game, "a")
|
|
U.wait(2)
|
|
local box = boxOnTop()
|
|
if not check("2335_dance_box_open", box ~= nil and box.auto ~= nil) then finish() end
|
|
|
|
local turns, frames, last = 0, 0, puff.facing
|
|
local shotStart, shotMid = false, false
|
|
while boxOnTop() == box and frames < 1500 do
|
|
U.wait(1)
|
|
frames = frames + 1
|
|
if puff.facing ~= last then
|
|
turns = turns + 1
|
|
last = puff.facing
|
|
if turns == 1 and not shotStart then
|
|
shotStart = true
|
|
U.shot(game, DIR .. "/2335_01_song_first_turn.png")
|
|
elseif turns == 8 and not shotMid then
|
|
shotMid = true
|
|
U.shot(game, DIR .. "/2335_02_mid_dance_still_boxed.png")
|
|
end
|
|
end
|
|
end
|
|
U.log("dance: turns", turns, "frames after open", frames)
|
|
check("2335_box_closed_itself", boxOnTop() ~= box)
|
|
check("2335_four_spins", turns >= 14)
|
|
check("2335_sleep_flag_set", ow.pikachuPewterSleepScene == true)
|
|
check("2335_following_disabled", PikachuFollower.isFollowingDisabled(ow))
|
|
U.wait(4)
|
|
U.shot(game, DIR .. "/2335_03_box_closed_pikachu_asleep.png")
|
|
|
|
local function step(dir)
|
|
local p = ow.player
|
|
local x, y = p.cellX, p.cellY
|
|
for _ = 1, 30 do
|
|
U.hold(game, dir, 1)
|
|
if p.moving then break end
|
|
end
|
|
for _ = 1, 40 do
|
|
if not p.moving then break end
|
|
U.wait(1)
|
|
end
|
|
U.wait(4)
|
|
return p.cellX ~= x or p.cellY ~= y
|
|
end
|
|
|
|
local px, py = pika.cellX, pika.cellY
|
|
local route = { "down", "down", "right", "right", "right" }
|
|
local walked = 0
|
|
for _, d in ipairs(route) do
|
|
if step(d) then walked = walked + 1 end
|
|
end
|
|
U.log("walked", walked, "player", ow.player.cellX, ow.player.cellY,
|
|
"pikachu", pika.cellX, pika.cellY)
|
|
check("2335_player_walked_away", walked >= 4)
|
|
check("2335_pikachu_stayed_put", pika.cellX == px and pika.cellY == py)
|
|
U.shot(game, DIR .. "/2335_04_walked_away_pikachu_stays.png")
|
|
|
|
local DIRS = { { "up", 0, -1 }, { "down", 0, 1 }, { "left", -1, 0 }, { "right", 1, 0 } }
|
|
local function free(x, y)
|
|
return ow.map:inBounds(x, y) and ow.map:isWalkableCell(x, y) and not ow:npcAtCell(x, y)
|
|
end
|
|
local function pathTo(goal)
|
|
local sx, sy = ow.player.cellX, ow.player.cellY
|
|
local key = function(x, y) return x .. "," .. y end
|
|
local prev, queue, head = { [key(sx, sy)] = false }, { { sx, sy } }, 1
|
|
while queue[head] do
|
|
local c = queue[head]
|
|
head = head + 1
|
|
if goal(c[1], c[2]) then
|
|
local path, k = {}, key(c[1], c[2])
|
|
while prev[k] do
|
|
table.insert(path, 1, prev[k].dir)
|
|
k = prev[k].from
|
|
end
|
|
return path
|
|
end
|
|
for _, d in ipairs(DIRS) do
|
|
local nx, ny = c[1] + d[2], c[2] + d[3]
|
|
local nk = key(nx, ny)
|
|
if prev[nk] == nil and free(nx, ny) then
|
|
prev[nk] = { dir = d[1], from = key(c[1], c[2]) }
|
|
queue[#queue + 1] = { nx, ny }
|
|
end
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
local faceDir
|
|
local path = pathTo(function(x, y)
|
|
for _, d in ipairs(DIRS) do
|
|
if x + d[2] == px and y + d[3] == py then faceDir = d[1] return true end
|
|
end
|
|
return false
|
|
end)
|
|
if path then
|
|
for _, d in ipairs(path) do step(d) end
|
|
if ow.player.facing ~= faceDir then U.tap(game, faceDir) U.wait(8) end
|
|
end
|
|
if not check("2335_facing_sleeping_pikachu", facingNpc(pika)) then
|
|
U.log("player", ow.player.cellX, ow.player.cellY, ow.player.facing,
|
|
"pikachu", pika.cellX, pika.cellY)
|
|
finish()
|
|
end
|
|
check("2335_still_asleep_before_talk", ow.pikachuPewterSleepScene == true)
|
|
|
|
U.tap(game, "a")
|
|
local sawBubble, sawPic, picPath = false, false, nil
|
|
for _ = 1, 600 do
|
|
local e = ow.emote
|
|
if e and e.bubble and not sawBubble then
|
|
sawBubble = true
|
|
U.shot(game, DIR .. "/2335_05_zzz_bubble.png")
|
|
elseif e and e.pikaPic and not sawPic then
|
|
sawPic, picPath = true, e.pikaPic
|
|
U.wait(20)
|
|
U.shot(game, DIR .. "/2335_06_pikapic_wake_face.png")
|
|
end
|
|
if sawPic and not ow.emote then break end
|
|
U.wait(1)
|
|
end
|
|
U.log("pikapic:", tostring(picPath))
|
|
check("2335_zzz_bubble_shown", sawBubble)
|
|
check("2335_pikapic_26_shown", picPath ~= nil and picPath:find("pikapic_26", 1, true) ~= nil)
|
|
U.wait(10)
|
|
check("2335_sleep_flag_cleared", ow.pikachuPewterSleepScene == nil)
|
|
check("2335_following_reenabled", not PikachuFollower.isFollowingDisabled(ow))
|
|
|
|
local qx, qy = pika.cellX, pika.cellY
|
|
local moved = 0
|
|
for _, d in ipairs({ "down", "down" }) do
|
|
if step(d) then moved = moved + 1 end
|
|
end
|
|
U.wait(20)
|
|
U.log("after wake: player", ow.player.cellX, ow.player.cellY, "pikachu", pika.cellX, pika.cellY)
|
|
check("2335_pikachu_follows_again",
|
|
moved > 0 and (pika.cellX ~= qx or pika.cellY ~= qy))
|
|
U.shot(game, DIR .. "/2335_07_pikachu_follows_again.png")
|
|
|
|
finish()
|
|
end
|