mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 08:21:02 +02:00
103 lines
4.1 KiB
Lua
103 lines
4.1 KiB
Lua
-- Engine-owned battle continuations replace unserializable onFinish closures
|
|
-- after a persistent checkpoint reconstructs the overworld and battle.
|
|
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
love = love or require("tests.love_stub")
|
|
|
|
local T = require("tests.harness").suite("battle checkpoint continuation")
|
|
local GameMethods = require("src.core.Game")
|
|
local OverworldState = require("src.world.OverworldController")
|
|
|
|
local function fakeOverworld()
|
|
local npc = { id = "FIX_TOWN_obj_1", frozen = true }
|
|
local ow = setmetatable({
|
|
map = { id = "FIX_TOWN" },
|
|
npcPool = { [npc.id] = npc },
|
|
engaging = true,
|
|
}, { __index = OverworldState })
|
|
ow.afterBattle = function(self, result, battle)
|
|
self.after = { result = result, battle = battle }
|
|
end
|
|
ow.checkVictoryRewards = function(self, class, party)
|
|
self.reward = { class = class, party = party }
|
|
end
|
|
return ow, npc
|
|
end
|
|
|
|
local wildOw = fakeOverworld()
|
|
local wildGame = { save = { defeatedTrainers = {}, flags = {} } }
|
|
local wild = { game = wildGame, kind = "wild" }
|
|
T.check(wildOw:restoreBattleContinuation(wild,
|
|
{ kind = "wild_encounter", map = "FIX_TOWN" }) == true,
|
|
"ordinary wild continuation binds")
|
|
wild.onFinish("run")
|
|
T.same(wildOw.after, { result = "run", battle = wild },
|
|
"wild continuation returns through canonical afterBattle")
|
|
|
|
local trainerOw, trainerNpc = fakeOverworld()
|
|
local trainerGame = { save = { defeatedTrainers = {}, flags = {} } }
|
|
local trainer = {
|
|
game = trainerGame, kind = "trainer",
|
|
oppClass = "OPP_FIX_YOUNGSTER", partyIndex = 1,
|
|
}
|
|
local trainerOrigin = {
|
|
kind = "trainer_encounter", map = "FIX_TOWN",
|
|
npcId = trainerNpc.id, trainerClass = trainer.oppClass, partyIndex = 1,
|
|
event = "EVENT_BEAT_FIX_TRAINER",
|
|
}
|
|
T.check(trainerOw:restoreBattleContinuation(trainer, trainerOrigin) == true,
|
|
"ordinary trainer continuation binds")
|
|
trainer.onFinish("win")
|
|
T.check(trainerGame.save.defeatedTrainers[trainerNpc.id] == true,
|
|
"trainer win stamps the stable object id")
|
|
T.check(trainerGame.save.flags.EVENT_BEAT_FIX_TRAINER == true,
|
|
"trainer win stamps the header event")
|
|
T.same(trainerOw.reward,
|
|
{ class = "OPP_FIX_YOUNGSTER", party = 1 },
|
|
"trainer win runs canonical victory rewards")
|
|
T.same(trainerOw.after, { result = "win", battle = trainer },
|
|
"trainer win returns through canonical afterBattle")
|
|
T.check(trainerOw.engaging == false and trainerNpc.frozen == false,
|
|
"reconstructed trainer completion leaves overworld input unfrozen")
|
|
|
|
local lossOw, lossNpc = fakeOverworld()
|
|
local lossGame = { save = { defeatedTrainers = {}, flags = {} } }
|
|
local lossBattle = {
|
|
game = lossGame, kind = "trainer",
|
|
oppClass = "OPP_FIX_YOUNGSTER", partyIndex = 1,
|
|
}
|
|
T.check(lossOw:restoreBattleContinuation(lossBattle, trainerOrigin) == true,
|
|
"trainer loss continuation binds")
|
|
lossBattle.onFinish("lose")
|
|
T.eq(lossGame.save.defeatedTrainers[lossNpc.id], nil,
|
|
"trainer loss does not stamp the trainer defeated")
|
|
T.eq(lossGame.save.flags.EVENT_BEAT_FIX_TRAINER, nil,
|
|
"trainer loss does not stamp the header event")
|
|
T.eq(lossOw.reward, nil, "trainer loss does not grant victory rewards")
|
|
|
|
local mismatchOw = fakeOverworld()
|
|
T.check(mismatchOw:restoreBattleContinuation(trainer, {
|
|
kind = "trainer_encounter", map = "OTHER_MAP", npcId = trainerNpc.id,
|
|
trainerClass = trainer.oppClass, partyIndex = 1,
|
|
}) == false, "continuation from another map is rejected")
|
|
T.check(mismatchOw:restoreBattleContinuation(trainer, {
|
|
kind = "trainer_encounter", map = "FIX_TOWN", npcId = trainerNpc.id,
|
|
trainerClass = "OPP_OTHER", partyIndex = 1,
|
|
}) == false, "mismatched trainer identity is rejected")
|
|
|
|
local ow = {}
|
|
local stack = { states = { ow } }
|
|
function stack:top() return self.states[#self.states] end
|
|
local game = setmetatable({ overworld = ow, stack = stack }, { __index = GameMethods })
|
|
local entered, resumed = false, false
|
|
local battle = {
|
|
enter = function() entered = true end,
|
|
resumeCheckpoint = function() resumed = true end,
|
|
}
|
|
game:restoreCheckpointBattle(battle)
|
|
T.check(game.stack:top() == battle, "reconstructed battle is installed on stack")
|
|
T.check(resumed == true, "checkpoint-specific battle resume path runs")
|
|
T.check(entered == false, "ordinary battle intro is not replayed")
|
|
|
|
T.finish()
|