Files
gen1recomp/tests/game3_collision_interactions_test.lua
T

144 lines
5.0 KiB
Lua

#!/usr/bin/env luajit
-- pokefirered/src/field_control_avatar.c:515 GetInteractedMetatileScript
package.path = "./?.lua;./?/init.lua;" .. package.path
local failed = 0
local function check(cond, msg)
if cond then
print("[ok] " .. msg)
else
failed = failed + 1
print("[FAIL] " .. msg)
end
end
local function finish()
if failed > 0 then
print("[test] FAILED " .. failed)
os.exit(1)
end
print("[test] all passed")
os.exit(0)
end
local I = require("src.core.game3.scripting.interaction_scripts")
-- pokefirered/include/constants/metatile_behaviors.h:104
local MB_CABLE_CLUB_WIRELESS_MONITOR = 0x8D
local MB_BATTLE_RECORDS = 0x8E
local MB_QUESTIONNAIRE = 0x8F
local MB_TRAINER_TOWER_MONITOR = 0xA3
print("[test] 1. the four code-side interaction behaviors dispatch")
check(I.scriptFor(MB_TRAINER_TOWER_MONITOR, "down")
== "TrainerTower_EventScript_ShowTime",
"0xA3 opens TrainerTower_EventScript_ShowTime from any facing")
check(I.scriptFor(MB_QUESTIONNAIRE, "left") == "EventScript_Questionnaire",
"0x8F opens EventScript_Questionnaire from any facing")
check(I.scriptFor(MB_CABLE_CLUB_WIRELESS_MONITOR, "up")
== "CableClub_EventScript_ShowWirelessCommunicationScreen",
"0x8D facing north opens the wireless communication screen")
check(I.scriptFor(MB_BATTLE_RECORDS, "up")
== "CableClub_EventScript_ShowBattleRecords",
"0x8E facing north opens the battle records")
-- src/metatile_behavior.c:854, :864
for _, facing in ipairs({ "down", "left", "right" }) do
check(I.scriptFor(MB_CABLE_CLUB_WIRELESS_MONITOR, facing) == nil,
"0x8D facing " .. facing .. " is not an interaction")
check(I.scriptFor(MB_BATTLE_RECORDS, facing) == nil,
"0x8E facing " .. facing .. " is not an interaction")
end
check(I.scriptFor(MB_BATTLE_RECORDS, 2) == "CableClub_EventScript_ShowBattleRecords",
"0x8E accepts DIR_NORTH as the number 2")
print("[test] 2. the flavor table is still the ROM's 28-entry block")
check(#I.FLAVOR == 28,
"I.FLAVOR has 28 rows, the length of pret/data/scripts/flavor_text.inc")
local FLAVOR_ORDER = {
"Bookshelf", "PokeMartShelf", "Food", "VideoGame", "Computer",
"ImpressiveMachine", "Blueprints", "Burglary", "PlayerFacingTVScreen",
"Cabinet", "Kitchen", "Dresser", "Snacks", "Painting", "PowerPlantMachine",
"Telephone", "AdvertisingPoster", "TastyFood", "TrashBin", "Cup",
"PolishedWindow", "BeautifulSkyWindow", "BlinkingLights",
"NeatlyLinedUpTools", "PokemartSign", "PokecenterSign",
"Indigo_UltimateGoal", "Indigo_HighestAuthority",
}
local orderOk = true
for i, name in ipairs(FLAVOR_ORDER) do
if not I.FLAVOR[i] or I.FLAVOR[i][2] ~= name then orderOk = false end
end
check(orderOk,
"and they are in the order object_interactions_extract seeds them from the ROM")
for _, row in ipairs(I.CODE) do
local clash = false
for _, f in ipairs(I.FLAVOR) do
if f[1] == row[1] then clash = true end
end
check(not clash, string.format("0x%02X is not also a flavor row", row[1]))
end
print("[test] 3. the behaviors that already worked still do")
check(I.scriptFor(0x83, "down") == "EventScript_PC", "0x83 is still the PC")
check(I.scriptFor(0x85, "up") == "EventScript_WallTownMap",
"0x85 is still the wall town map")
check(I.scriptFor(0x81, "down") == "EventScript_Bookshelf",
"0x81 is still the bookshelf")
check(I.scriptFor(0x86, "up") == "EventScript_PlayerFacingTVScreen",
"0x86 facing north is still the TV screen")
check(I.scriptFor(0x86, "down") == nil, "0x86 facing south is still nothing")
check(I.scriptFor(0x00, "down") == nil, "a plain floor is still nothing")
print("[test] 4. the cells these behaviors sit on")
local Cache = require("tests.game3_cache")
local cacheRoot = Cache.mount("scripts/events.lua", { native = true })
if not cacheRoot then
print("[skip] game3_collision_interactions_test map checks: " .. tostring(Cache.reason))
finish()
end
print("[info] FireRed cache at " .. cacheRoot)
local Dataset = require("src.core.game3.dataset")
local Collision = require("src.core.game3.collision")
local game = { data = {} }
Dataset.hydrate(game)
local function census(beh)
local cells, maps = 0, 0
for mapId, def in pairs(game.data.maps) do
if def.midLayout then
Collision.bindMap(game, mapId, def)
local here = 0
for y = 0, Collision._heightCells - 1 do
for x = 0, Collision._widthCells - 1 do
if Collision.behavior(x, y) == beh then here = here + 1 end
end
end
if here > 0 then
cells = cells + here
maps = maps + 1
end
end
end
return cells, maps
end
local CENSUS = {
{ MB_CABLE_CLUB_WIRELESS_MONITOR, 19, 19, "wireless communication monitor" },
{ MB_BATTLE_RECORDS, 19, 19, "battle records" },
{ MB_QUESTIONNAIRE, 12, 12, "questionnaire" },
{ MB_TRAINER_TOWER_MONITOR, 8, 8, "Trainer Tower monitor" },
}
for _, row in ipairs(CENSUS) do
local cells, maps = census(row[1])
check(cells == row[2] and maps == row[3],
string.format("%s: %d cells over %d maps (got %d / %d)",
row[4], row[2], row[3], cells, maps))
end
finish()