Files
gen1recomp/tests/game3_objects_flag_sync_test.lua
T

187 lines
6.1 KiB
Lua

#!/usr/bin/env luajit
package.path = "./?.lua;./?/init.lua;" .. package.path
local GameVersion = require("src.core.GameVersion")
GameVersion.set("firered")
local Flags = require("src.core.game3.scripting.flags")
local Vm = require("src.core.game3.scripting.vm")
local Adapters = require("src.core.game3.scripting.adapters")
local Player = require("src.core.game3.player")
local Objects = require("src.core.game3.objects")
local failed = 0
local function check(cond, msg)
if cond then
print("[ok] " .. msg)
else
failed = failed + 1
print("[FAIL] " .. msg)
end
end
local TOWER = "FR_POKEMON_TOWER_7F"
local FUJI = 10
local FLAG_HIDE_TOWER_FUJI = 0x34
local FLAG_HIDE_POKEHOUSE_FUJI = 0x35
local FLAG_RESCUED_MR_FUJI = 0x23C
local function towerDef()
return {
midLayout = { width = 20, height = 40 },
objects = {
{ localId = FUJI, graphicsId = 30, x = 11, y = 4, movementType = 8, flag = FLAG_HIDE_TOWER_FUJI },
{ localId = 2, graphicsId = 40, x = 11, y = 34, movementType = 8, flag = 0x3F0 },
{ localId = 3, graphicsId = 40, x = 5, y = 5, movementType = 8, flag = 0x3F1 },
},
}
end
local function placePlayer(x, y)
Player.cellX, Player.cellY = x, y
Player.targetX, Player.targetY = x, y
Player.px, Player.py = x * 16, y * 16
Player.moving = false
end
local function fresh()
Objects.reset()
Objects.loadMap(nil, TOWER, towerDef())
end
print("[test] 1. setflag on an on-screen object's hide flag leaves it visible")
fresh()
placePlayer(11, 5)
Objects.syncFlagVisibility(FLAG_HIDE_TOWER_FUJI, true)
local fuji = Objects.find(FUJI)
check(fuji and fuji.visible and not fuji.hidden, "Fuji still visible after his hide flag is set")
print("[test] 2. an object outside the camera box is culled and stays gone")
Objects.syncFlagVisibility(0x3F0, true)
local far = Objects.find(2)
check(far and far.hidden and not far.visible, "far object (11,34) hidden")
print("[test] 3. clearflag still respawns a removed object")
Objects.removeObject(3)
check(Objects.find(3).hidden, "object 3 removed")
Objects.syncFlagVisibility(0x3F1, false)
check(Objects.find(3).visible and not Objects.find(3).hidden, "clearflag brings object 3 back")
print("[test] 4. forced sync (mod SDK) still hides on-screen objects")
fresh()
placePlayer(11, 5)
Objects.syncFlagVisibility(FLAG_HIDE_TOWER_FUJI, true, true)
check(Objects.find(FUJI).hidden, "forced hide removes Fuji")
print("[test] 5. Mr Fuji's script leaves him on screen through the msgbox")
fresh()
placePlayer(11, 5)
local store = Flags.newStore()
Flags.setFlag(store, nil, FLAG_HIDE_POKEHOUSE_FUJI, true)
local vm = Vm.new({
store = store,
adapters = Adapters.host(nil, nil, nil),
scripts = {
fuji = {
{ op = "setflag", [1] = FLAG_HIDE_TOWER_FUJI },
{ op = "clearflag", [1] = FLAG_HIDE_POKEHOUSE_FUJI },
{ op = "setflag", [1] = FLAG_RESCUED_MR_FUJI },
{ op = "end" },
},
},
})
vm:start("fuji")
for _ = 1, 16 do
if not vm:isRunning() then break end
vm:tick()
end
check(Flags.getFlag(store, vm.ctx, FLAG_HIDE_TOWER_FUJI), "FLAG_HIDE_TOWER_FUJI set")
check(Flags.getFlag(store, vm.ctx, FLAG_RESCUED_MR_FUJI), "FLAG_RESCUED_MR_FUJI set")
check(not Flags.getFlag(store, vm.ctx, FLAG_HIDE_POKEHOUSE_FUJI), "FLAG_HIDE_POKEHOUSE_FUJI cleared")
fuji = Objects.find(FUJI)
check(fuji and fuji.visible and not fuji.hidden, "Fuji still drawn after the script's setflag")
local drawn = false
for _, eo in ipairs(Objects.forDraw()) do
if eo.localId == FUJI then drawn = true end
end
check(drawn, "Fuji in forDraw")
print("[test] 6. ON_TRANSITION / ON_LOAD hides run before spawn: in-view objects are gone")
local Space = require("src.core.game3.scripting.space")
local VERMILION = "FR_VERMILION_CITY"
local AIDE = 8
local FLAG_HIDE_AIDE = 0x0A1
local FLAG_HIDE_LOAD = 0x3F2
local function vermilionDef()
return {
midLayout = { width = 50, height = 40 },
objects = {
{ localId = AIDE, graphicsId = 30, x = 25, y = 7, movementType = 8, flag = FLAG_HIDE_AIDE },
{ localId = 9, graphicsId = 40, x = 16, y = 8, movementType = 8, flag = FLAG_HIDE_LOAD },
},
}
end
local enterStore = Flags.newStore()
local saved = {
bundle = Space.bundle, vm = Space.vm, store = Space.store,
mapId = Space.mapId, active = Space.active,
}
Space.bundle = {
events = {
[VERMILION] = { mapScripts = { onTransition = "vermilion_transition", onLoad = "vermilion_load" } },
},
}
Space.store = enterStore
Space.vm = Vm.new({
store = enterStore,
adapters = Adapters.host(nil, nil, nil),
scripts = {
-- data/maps/VermilionCity/scripts.inc:28
vermilion_transition = {
{ op = "setflag", [1] = FLAG_HIDE_AIDE },
{ op = "end" },
},
vermilion_load = {
{ op = "setflag", [1] = FLAG_HIDE_LOAD },
{ op = "end" },
},
later = {
{ op = "setflag", [1] = FLAG_HIDE_AIDE },
{ op = "end" },
},
},
})
Space.mapId = VERMILION
Space.active = true
Objects.reset()
Objects.loadMap(nil, VERMILION, vermilionDef())
placePlayer(15, 7)
local okEnter, errEnter = pcall(Space.runEnterScripts, nil, VERMILION, nil, nil, { enterVia = "warp" })
check(okEnter, "runEnterScripts ran" .. (okEnter and "" or (": " .. tostring(errEnter))))
check(Flags.getFlag(enterStore, nil, FLAG_HIDE_AIDE), "ON_TRANSITION set the aide hide flag")
local aide = Objects.find(AIDE)
check(aide and aide.hidden and not aide.visible, "aide at (25,7) hidden though in view of (15,7)")
check(Objects.find(9) and Objects.find(9).hidden, "ON_LOAD setflag hides an in-view object")
check(not Space._inTransition, "transition window closed after the drain")
print("[test] 7. setflag after the entry drain keeps cart semantics")
Objects.syncFlagVisibility(FLAG_HIDE_AIDE, false)
check(Objects.find(AIDE).visible, "aide respawned by clearflag")
Flags.setFlag(enterStore, nil, FLAG_HIDE_AIDE, false)
Space.vm:start("later")
for _ = 1, 16 do
if not Space.vm:isRunning() then break end
Space.vm:tick()
end
check(Objects.find(AIDE).visible, "mid-map setflag leaves the in-view aide drawn")
Space.bundle, Space.vm, Space.store = saved.bundle, saved.vm, saved.store
Space.mapId, Space.active = saved.mapId, saved.active
if failed > 0 then
print("[test] FAILED " .. failed)
os.exit(1)
end
print("[test] all passed")