Files
gen1recomp/tests/game3_stitchscript_warp_gifts_test.lua
bryanthaboi dee935a4ea CLOSES #2430
2026-09-23 11:58:32 -04:00

187 lines
6.4 KiB
Lua

#!/usr/bin/env luajit
package.path = "./?.lua;./?/init.lua;" .. package.path
require("tests.game3_cache").stubSpeciesNames()
local GameVersion = require("src.core.GameVersion")
GameVersion.set("firered")
local Flags = require("src.core.game3.scripting.flags")
local Ctx = require("src.core.game3.scripting.ctx")
local Vm = require("src.core.game3.scripting.vm")
local Adapters = require("src.core.game3.scripting.adapters")
local Runtime = require("src.core.game3.runtime")
local Storage = require("src.core.game3.storage")
local Natives = require("src.core.game3.scripting.natives")
local Std = require("src.core.game3.scripting.stdscripts")
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 eq(a, b, msg)
check(a == b, string.format("%s (%s == %s)", msg, tostring(a), tostring(b)))
end
local VAR_TEMP_1 = 0x4001
local VAR_TEMP_2 = 0x4002
local VAR_TEMP_3 = 0x4003
local VAR_ELEVATOR_FLOOR = 0x403A
local SPECIES_MAGIKARP = 129
local SPECIES_TOGEPI = 175
local prevSession = Runtime.session
local function newSession()
local session = {
party = {},
store = Flags.newStore(),
dex = { seen = {}, owned = {} },
name = "RED",
trainerId = 1,
}
Storage.ensure(session)
Runtime.session = session
return session
end
local function run(rows, store)
store = store or Flags.newStore()
local vm = Vm.new({
store = store,
scripts = { t = rows },
adapters = Adapters.host(nil, nil, nil),
})
vm:start("t")
return vm, store
end
local function result(_, store)
return Flags.getVar(store, nil, VAR_TEMP_3)
end
print("[test] 1. setdynamicwarp stores the destination the elevator specials read")
local s1 = newSession()
local vm1, st1 = run({
{ op = "setdynamicwarp", [1] = 1, [2] = 51, [3] = 255, [4] = 22, [5] = 3 },
{ op = "end" },
})
check(type(s1.dynamicWarp) == "table", "setdynamicwarp wrote session.dynamicWarp")
local dw = s1.dynamicWarp or {}
eq(dw.map, "FR_SILPH_CO_5F", "SilphCo_Elevator scripts.inc:70 maps to the engine id")
eq(dw.warpId, -1, "WARP_ID_NONE 255 stores as the s8 -1")
eq(dw.x, 22, "x from the script row")
eq(dw.y, 3, "y from the script row")
local Elevator = require("src.core.game3.scripting.natives_elevator")
eq(Elevator.dynamicWarpMap(), "FR_SILPH_CO_5F", "Elevator.dynamicWarpMap reads it back")
s1.store = st1
local ctx1 = { specialVars = {} }
Natives.special(ctx1, Std.SPECIAL.GetElevatorFloor, Adapters.host(nil, nil, nil))
eq(Flags.getVar(st1, ctx1, VAR_ELEVATOR_FLOOR), 8,
"GetElevatorFloor reports 5F end to end from the script op")
print("[test] 2. every set*warp variant owns its own slot")
local s2 = newSession()
run({
{ op = "setdynamicwarp", [1] = 1, [2] = 42, [3] = 255, [4] = 24, [5] = 25 },
{ op = "setescapewarp", [1] = 3, [2] = 48, [3] = 255, [4] = 12, [5] = 6 },
{ op = "setwarp", [1] = 0, [2] = 1, [3] = 255, [4] = 5, [5] = 8 },
{ op = "setdivewarp", [1] = 1, [2] = 47, [3] = 0, [4] = 4, [5] = 9 },
{ op = "setholewarp", [1] = 1, [2] = 48, [3] = 1, [4] = 6, [5] = 7 },
{ op = "end" },
})
eq((s2.dynamicWarp or {}).map, "FR_ROCKET_HIDEOUT_B1F", "dynamicWarp survives the later variants")
eq((s2.escapeWarp or {}).map, "FR_THREE_ISLAND_BOND_BRIDGE", "setescapewarp slot")
eq((s2.escapeWarp or {}).x, 12, "escape warp x")
eq((s2.warpDestination or {}).map, "FR_TRADE_CENTER", "setwarp slot")
eq((s2.diveWarp or {}).map, "FR_SILPH_CO_1F", "setdivewarp slot")
eq((s2.diveWarp or {}).warpId, 0, "a real warp id is kept as is")
eq((s2.holeWarp or {}).map, "FR_SILPH_CO_2F", "setholewarp slot")
print("[test] 3. setdynamicwarp coords go through VarGet")
local s3 = newSession()
run({
{ op = "setvar", [1] = VAR_TEMP_1, [2] = 13 },
{ op = "setvar", [1] = VAR_TEMP_2, [2] = 3 },
{ op = "setdynamicwarp", [1] = 1, [2] = 57, [3] = 255, [4] = VAR_TEMP_1, [5] = VAR_TEMP_2 },
{ op = "end" },
})
eq((s3.dynamicWarp or {}).map, "FR_SILPH_CO_11F", "11F from group 1 num 57")
eq((s3.dynamicWarp or {}).x, 13, "x resolved from VAR_TEMP_1")
eq((s3.dynamicWarp or {}).y, 3, "y resolved from VAR_TEMP_2")
print("[test] 4. givemon returns MON_GIVEN_TO_PARTY until the party is full")
local s4 = newSession()
local giveMagikarp = {
{ op = "givemon", [1] = SPECIES_MAGIKARP, [2] = 5, [3] = 0, [4] = 0, [5] = 0 },
{ op = "copyvar", [1] = VAR_TEMP_3, [2] = Ctx.VAR_RESULT },
{ op = "end" },
}
for i = 1, 6 do
local vm, store = run(giveMagikarp)
eq(result(vm, store), 0, "gift " .. i .. " joined the party")
end
eq(#s4.party, 6, "the party filled up")
print("[test] 5. a gift mon with a full party is sent to the PC, not refused")
local vm5, st5 = run(giveMagikarp)
eq(result(vm5, st5), 1, "VAR_RESULT is MON_GIVEN_TO_PC")
eq(#s4.party, 6, "the party did not grow")
check(s4.storage.boxes[1].mons[1] ~= nil, "the mon landed in box 1 slot 1")
eq(s4.monBoxId, 0, "session.monBoxId is the 0-based box")
eq(s4.monBoxPos, 0, "session.monBoxPos is the 0-based slot")
check(s4.dex.owned[SPECIES_MAGIKARP] == true, "the dex was still flagged")
print("[test] 6. only a full party and a full PC report MON_CANT_GIVE")
local s6 = newSession()
for _ = 1, 6 do run(giveMagikarp) end
for b = 1, Storage.TOTAL_BOXES_COUNT do
local box = s6.storage.boxes[b]
for slot = 1, Storage.IN_BOX_COUNT do
box.mons[slot] = { species = 19, speciesId = 19, level = 3 }
end
end
local vm6, st6 = run(giveMagikarp)
eq(result(vm6, st6), 2, "VAR_RESULT is MON_CANT_GIVE")
print("[test] 7. giveegg uses the same three-valued code")
local s7 = newSession()
local giveEgg = {
{ op = "giveegg", [1] = SPECIES_TOGEPI },
{ op = "copyvar", [1] = VAR_TEMP_3, [2] = Ctx.VAR_RESULT },
{ op = "end" },
}
local vm7, st7 = run(giveEgg)
eq(result(vm7, st7), 0, "the first egg joined the party")
check(s7.party[1] and s7.party[1].isEgg == true, "it is an egg")
for _ = 1, 5 do run(giveMagikarp) end
eq(#s7.party, 6, "the party filled up")
local vm7b, st7b = run(giveEgg)
eq(result(vm7b, st7b), 1, "an egg with a full party goes to the PC")
check(s7.storage.boxes[1].mons[1] ~= nil, "the egg reached box 1")
for b = 1, Storage.TOTAL_BOXES_COUNT do
local box = s7.storage.boxes[b]
for slot = 1, Storage.IN_BOX_COUNT do
box.mons[slot] = { species = 19, speciesId = 19, level = 3 }
end
end
local vm7c, st7c = run(giveEgg)
eq(result(vm7c, st7c), 2, "a full party and a full PC refuse the egg")
Runtime.session = prevSession
if failed > 0 then
print(string.format("FAILED %d check(s)", failed))
os.exit(1)
end
print("PASS game3_stitchscript_warp_gifts")
os.exit(0)