Files
gen1recomp/tests/drivers/game3_collision_npc_edge.lua

121 lines
3.8 KiB
Lua

local U = require("tests.drivers.util")
local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/game3_collision_npc_edge"
local MAP = "FR_VICTORY_ROAD_1F"
local NAOMI = 2
-- pokefirered/include/constants/metatile_behaviors.h:41
local MB_IMPASSABLE_NORTH = 0x32
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 collision_npc_edge")
love.event.quit(0)
else
print("FAIL collision_npc_edge 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 Player = require("src.core.game3.player")
local Collision = require("src.core.game3.collision")
local Objects = require("src.core.game3.objects")
local Space = require("src.core.game3.scripting.space")
local Message = require("src.ui.game3.message")
if not result(Runtime.getSession() ~= nil, "new game reached the game3 field") then
return finish()
end
local function settle(limit)
for _ = 1, (limit or 240) do
local busy = (Space.vm and Space.vm:isRunning())
or (Message.isOpen and Message.isOpen())
if not busy then return true end
if Message.isOpen and Message.isOpen() then U.tap(game, "a") end
U.wait(4)
end
return false
end
local function place(x, y, facing)
Player.cellX, Player.cellY = x, y
Player.px, Player.py = x * 16, y * 16
Player.targetX, Player.targetY = x, y
Player.moving = false
Player.progress = 0
Player.facing = facing or "down"
if game.session then
game.session.x, game.session.y, game.session.facing = x, y, facing or "down"
end
end
Map.load(nil, game, MAP, { x = 11, y = 9, facing = "right" })
place(11, 9, "right")
U.wait(90)
settle(600)
place(11, 9, "right")
U.wait(20)
result(Collision.behavior(14, 5) == MB_IMPASSABLE_NORTH,
string.format("%s (14,5) is MB_IMPASSABLE_NORTH (0x%02X)", MAP,
Collision.behavior(14, 5) or 0))
result(Collision.cell(14, 5) ~= 0x07, "(14,5) is walkable rock, not a wall")
result(Collision.cell(14, 4) ~= 0x07, "(14,4) above it is open cave floor")
-- pokefirered/src/scrcmd.c:1162 ScrCmd_setobjectmovementtype
Objects.setObjectXY(NAOMI, 14, 5)
Objects.setMovementType(NAOMI, 3)
local naomi = Objects.find(NAOMI)
if not result(naomi ~= nil, "Naomi is on the map") then return finish() end
result(naomi.movement == "WALK" and naomi.range == "UP_DOWN",
"Naomi wanders up and down from the sealed band at (14,5)")
U.wait(20)
U.shot(game, DIR .. "/collision_npc_edge_01_naomi_on_the_band.png")
local visited = {}
local shotSouth = false
for _ = 1, 3000 do
U.wait(1)
visited[naomi.cellX .. "," .. naomi.cellY] = true
visited[naomi.targetX .. "," .. naomi.targetY] = true
if not shotSouth and naomi.cellY == 6 and not naomi.moving then
U.shot(game, DIR .. "/collision_npc_edge_02_naomi_stepped_south.png")
shotSouth = true
end
end
local cells = {}
for k in pairs(visited) do cells[#cells + 1] = k end
table.sort(cells)
print("[driver] Naomi occupied " .. table.concat(cells, " "))
result(visited["14,6"] == true, "she really wanders: she reached (14,6)")
result(visited["14,4"] ~= true, "she never crossed the sealed north edge to (14,4)")
result(shotSouth, "the southward step was captured")
local okUp = Collision.canEnter(game, 14, 4,
{ fromX = 14, fromY = 5, dir = "up", surfing = false })
result(okUp == false, "GetCollisionAtCoords refuses her northbound step")
finish()
end