mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
180 lines
6.7 KiB
Lua
180 lines
6.7 KiB
Lua
#!/usr/bin/env luajit
|
|
-- pokefirered/src/item_use.c:622 ItemUseOutOfBattle_EscapeRope
|
|
-- pokefirered/src/item_use.c:634 ItemUseOnFieldCB_EscapeRope
|
|
-- pokefirered/src/item_use.c:642 Task_UseDigEscapeRopeOnField
|
|
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
require("tests.game3_cache").mountOrSkip("game3_stitchmap_escape_rope_test")
|
|
|
|
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 warps = {}
|
|
package.loaded["src.core.game3.warp"] = {
|
|
request = function(_mod, _game, mapId, x, y, facing)
|
|
warps[#warps + 1] = { map = mapId, x = x, y = y, facing = facing }
|
|
return true
|
|
end,
|
|
startEscapeRope = function(_game, mapId, x, y)
|
|
warps[#warps + 1] = { map = mapId, x = x, y = y }
|
|
return true
|
|
end,
|
|
isBusy = function() return false end,
|
|
}
|
|
|
|
local fieldMessages = {}
|
|
local fieldDone = nil
|
|
package.loaded["src.ui.game3.message"] = {
|
|
show = function(text, opts)
|
|
fieldMessages[#fieldMessages + 1] = tostring(text)
|
|
fieldDone = type(opts) == "table" and opts.done or (type(opts) == "function" and opts or nil)
|
|
end,
|
|
showStay = function(text) fieldMessages[#fieldMessages + 1] = tostring(text) end,
|
|
close = function() end,
|
|
isOpen = function() return false end,
|
|
}
|
|
|
|
local GameVersion = require("src.core.GameVersion")
|
|
GameVersion.set("firered")
|
|
|
|
local Cache = require("tests.game3_cache")
|
|
Cache.mountOrSkip("escape rope message + warp order", "map_tree/census.json")
|
|
|
|
local Dataset = require("src.core.game3.dataset")
|
|
local MapCatalog = require("src.import.gba.map_catalog")
|
|
local ItemsData = require("src.core.game3.items_data")
|
|
local ItemUse = require("src.core.game3.item_use")
|
|
local Bag = require("src.core.game3.bag")
|
|
local BagMenu = require("src.ui.game3.bag_menu")
|
|
local Runtime = require("src.core.game3.runtime")
|
|
local Strings = require("src.core.Strings")
|
|
|
|
local ITEM_ESCAPE_ROPE = 85 -- pokefirered/include/constants/items.h:89
|
|
|
|
local game = { data = {} }
|
|
Dataset.hydrate(game)
|
|
Runtime._game = game
|
|
Runtime._mod = {}
|
|
|
|
local CAVE = MapCatalog.pretToEngine("MtMoon_1F")
|
|
local HOUSE = MapCatalog.pretToEngine("PalletTown_PlayersHouse_1F")
|
|
check(CAVE ~= nil and game.data.maps[CAVE] ~= nil, "MtMoon_1F is in the cache")
|
|
check(HOUSE ~= nil and game.data.maps[HOUSE] ~= nil, "PalletTown_PlayersHouse_1F is in the cache")
|
|
if not (CAVE and HOUSE) then finish() end
|
|
|
|
local input = {
|
|
_p = {},
|
|
wasPressed = function(self, key) return self._p[key] == true end,
|
|
isDown = function() return false end,
|
|
press = function(self, key) self._p = { [key] = true } end,
|
|
}
|
|
|
|
local function new_session(mapId)
|
|
return {
|
|
name = "RED", map = mapId, party = {}, flags = {}, vars = {},
|
|
healMap = "FR_PLAYERS_HOUSE_1F", healX = 8, healY = 5,
|
|
bag = Bag.new(),
|
|
}
|
|
end
|
|
|
|
local function use_from_bag(session, id)
|
|
BagMenu.show(session, { session = session, bag = session.bag, pocket = "ITEMS" })
|
|
BagMenu.settle()
|
|
local want = ItemsData.toNumericId(id)
|
|
for i, r in ipairs(BagMenu.list()) do
|
|
if ItemsData.toNumericId(r.id) == want then BagMenu.cursor = i end
|
|
end
|
|
input:press("a")
|
|
BagMenu.handleInput(input)
|
|
if BagMenu.mode ~= "action" then return false end
|
|
for k, a in ipairs(BagMenu.ACTIONS) do
|
|
if a == "USE" then BagMenu.actionCursor = k end
|
|
end
|
|
input:press("a")
|
|
BagMenu.handleInput(input)
|
|
BagMenu.settle()
|
|
return true
|
|
end
|
|
|
|
-- pokefirered/src/strings.c:197 gText_PlayerUsedVar2
|
|
local USED = "RED used the\nESCAPE ROPE."
|
|
|
|
print("[test] 1. the bag fades out before the rope's line prints")
|
|
local s1 = new_session(CAVE)
|
|
Bag.add(s1.bag, ITEM_ESCAPE_ROPE, 1)
|
|
warps, fieldMessages, fieldDone = {}, {}, nil
|
|
check(use_from_bag(s1, ITEM_ESCAPE_ROPE), "the rope reached USE in the bag")
|
|
check(BagMenu.isOpen() == false, "the bag is gone before the line shows")
|
|
check(BagMenu.messageText ~= USED,
|
|
"the line is not in the bag's own frame (got " .. tostring(BagMenu.messageText) .. ")")
|
|
check(fieldMessages[1] == USED,
|
|
"DisplayItemMessageOnField carries gText_PlayerUsedVar2 (got "
|
|
.. tostring(fieldMessages[1]) .. ")")
|
|
check(#warps == 0, "and nothing warped while the message was up")
|
|
-- pokefirered/src/item_use.c:573 RemoveUsedItem
|
|
check(Bag.get(s1.bag, ITEM_ESCAPE_ROPE) == 0, "the rope was consumed")
|
|
|
|
print("[test] 2. dismissing the field box warps exactly once")
|
|
check(type(fieldDone) == "function", "the field box carries the follow-up task")
|
|
if type(fieldDone) == "function" then fieldDone() end
|
|
check(#warps == 1, "Warp.startEscapeRope ran exactly once (got " .. #warps .. ")")
|
|
check(warps[1] and warps[1].map == "FR_PLAYERS_HOUSE_1F"
|
|
and warps[1].x == 8 and warps[1].y == 5,
|
|
"it warps to the last heal spot")
|
|
|
|
print("[test] 3. with the bag closed the line goes to the field box first")
|
|
local s3 = new_session(CAVE)
|
|
Bag.add(s3.bag, ITEM_ESCAPE_ROPE, 1)
|
|
warps, fieldMessages, fieldDone = {}, {}, nil
|
|
local ok, kind, text = ItemUse.useField(s3, s3.bag, ITEM_ESCAPE_ROPE, nil)
|
|
check(ok == true and kind == "escape", "useField accepts the rope in a cave")
|
|
check(text == USED, "it hands the caller the same line")
|
|
check(fieldMessages[1] == USED,
|
|
"the field message box got it (got " .. tostring(fieldMessages[1]) .. ")")
|
|
check(#warps == 0, "no warp while the box is open")
|
|
check(type(fieldDone) == "function", "the box carries the follow-up task")
|
|
fieldDone()
|
|
check(#warps == 1, "closing the box runs the warp (got " .. #warps .. ")")
|
|
|
|
print("[test] 4. a map with allowEscaping 0 refuses it and moves nothing")
|
|
local s4 = new_session(HOUSE)
|
|
Bag.add(s4.bag, ITEM_ESCAPE_ROPE, 1)
|
|
warps, fieldMessages = {}, {}
|
|
local okH, kindH, textH = ItemUse.useField(s4, s4.bag, ITEM_ESCAPE_ROPE, nil)
|
|
check(okH == false and kindH == "escape", "the rope is refused indoors")
|
|
check(textH == "OAK: RED!\nThis isn't the time to use that!", "with OAK's refusal")
|
|
check(#warps == 0, "nothing warped")
|
|
check(Bag.get(s4.bag, ITEM_ESCAPE_ROPE) == 1, "and the rope was not consumed")
|
|
|
|
print("[test] 5. a recorded escape warp beats the heal spot")
|
|
-- pokefirered/src/field_effect.c:2126 SetWarpDestinationToEscapeWarp
|
|
local s5 = new_session(CAVE)
|
|
-- pokefirered/src/overworld.c:651 SetEscapeWarp
|
|
s5.escapeWarp = { map = MapCatalog.pretToEngine("Route4"), warpId = 255, x = 16, y = 6 }
|
|
Bag.add(s5.bag, ITEM_ESCAPE_ROPE, 1)
|
|
warps, fieldMessages, fieldDone = {}, {}, nil
|
|
check(ItemUse.useField(s5, s5.bag, ITEM_ESCAPE_ROPE, nil) == true, "the rope is accepted")
|
|
if type(fieldDone) == "function" then fieldDone() end
|
|
check(#warps == 1, "it warped once (got " .. #warps .. ")")
|
|
check(warps[1] and warps[1].map == s5.escapeWarp.map
|
|
and warps[1].x == 16 and warps[1].y == 6,
|
|
"to the doorstep UpdateEscapeWarp recorded, got " .. tostring(warps[1] and warps[1].map))
|
|
|
|
finish()
|