Files
gen1recomp/tests/engine/battle_transition_oam_bug1948.lua

155 lines
5.9 KiB
Lua

-- engine/battle/battle_transitions.asm:28
package.path = "./?.lua;./?/init.lua;" .. package.path
if not _G.love then _G.love = require("tests.love_stub") end
local T = require("tests.harness")
local check, eq = T.check, T.eq
local OW = require("src.world.OverworldController")
local Commands = require("src.script.Commands")
local Renderer = require("src.render.Renderer")
local player = { id = "player" }
local trainer = { id = "trainer" }
local bystander = { id = "bystander" }
do
local ow = { player = player }
check(OW.oamCulled(ow, bystander) == false,
"no transition up: nothing is culled")
check(OW.oamCulled(ow, player) == false, "no transition up: the player draws")
ow.battleOamKeep = false
check(OW.oamCulled(ow, player) == false, "wild battle keeps the player block")
check(OW.oamCulled(ow, trainer) == true, "wild battle clears every other block")
ow.battleOamKeep = trainer
check(OW.oamCulled(ow, player) == false, "trainer battle keeps the player")
check(OW.oamCulled(ow, trainer) == false, "trainer battle keeps the engaged NPC")
check(OW.oamCulled(ow, bystander) == true, "trainer battle clears bystanders")
end
do
local got
local ctx = { npc = trainer, overworld = {
pushBattle = function(_, _, keep) got = keep end } }
Commands.pushBattle(ctx, { kind = "trainer" })
eq(got, trainer, "a scripted trainer battle keeps the talked-to NPC")
got = "unset"
-- home/text_script.asm:8
Commands.pushBattle(ctx, { kind = "wild" })
eq(got, trainer, "a scripted wild battle keeps the talked-to NPC (#2119)")
local oak = { id = "oak" }
local bare = { overworld = ctx.overworld }
got = "unset"
Commands.pushBattle(bare, { kind = "wild" }, oak)
eq(got, oak, "an explicit keep wins when the ctx has no npc")
got = "unset"
Commands.pushBattle(ctx, { kind = "wild" }, oak)
eq(got, oak, "an explicit keep wins over ctx.npc")
got = "unset"
Commands.pushBattle(bare, { kind = "wild" })
eq(got, nil, "no npc and no keep: the player only")
end
-- home/text_script.asm:8
do
local rival = { id = "rival" }
local other = { id = "other" }
local got
local ow = {
player = player,
pushBattle = function(_, _, keep) got = keep end,
npcByIndex = function(_, i)
if i == 1 then return rival elseif i == 2 then return other end
end,
}
local ctx = { overworld = ow, runner = {} }
Commands.pushBattle(ctx, { kind = "trainer" })
eq(got, nil, "an unaddressed ambush still keeps nothing")
Commands.face_object(ctx, 1, "down")
Commands.pushBattle(ctx, { kind = "trainer" })
eq(got, rival, "face_object stamps the sprite an ambush battle keeps")
Commands.place_npc(ctx, 2, 3, 4)
Commands.pushBattle(ctx, { kind = "trainer" })
eq(got, other, "place_npc restamps, like hSpriteIndex being overwritten")
Commands.walk_npc(ctx, 1, {})
Commands.pushBattle(ctx, { kind = "trainer" })
eq(got, rival, "walk_npc stamps the object it moves")
Commands.walk_npc(ctx, "player", {})
Commands.pushBattle(ctx, { kind = "trainer" })
eq(got, rival, "walk_npc \"player\" leaves the stamp alone")
local talked = { id = "talked" }
ctx.npc = talked
Commands.pushBattle(ctx, { kind = "trainer" })
eq(got, talked, "a talked-to npc still wins over the script stamp")
Commands.pushBattle(ctx, { kind = "trainer" }, other)
eq(got, other, "an explicit keep still wins over both")
end
do
Renderer.wipeSprites = function() end
Renderer.wipeWox, Renderer.wipeWoy = 1, 2
Renderer.wipeSx, Renderer.wipeSy = 3, 4
Renderer.battleWipe = { prog = 0.5 }
local ok = pcall(Renderer.beginFrame, Renderer, true)
check(ok, "beginFrame runs headless")
check(Renderer.wipeSprites == nil, "beginFrame drops last frame's survivors")
check(Renderer.wipeWox == nil and Renderer.wipeWoy == nil
and Renderer.wipeSx == nil and Renderer.wipeSy == nil,
"beginFrame drops last frame's world placement")
check(Renderer.battleWipe == nil, "beginFrame drops last frame's wipe")
end
do
local f = io.open("src/render/Renderer.lua", "rb")
check(f ~= nil, "Renderer source is readable")
local src = f:read("*a")
f:close()
local guard = src:match("if self%.wipeSprites and self%.wipeWox%s*\n"
.. "%s*and %(self%.battleWipe%.prog or 0%) < 1 then")
check(guard ~= nil,
"the survivor replay stops at prog >= 1 (BattleTransition_BlackScreen)")
local body = src:match("drawBattleWipe%(self%.battleWipe.-\n end\n")
check(body ~= nil and body:find("pcall%(self%.wipeSprites%)") ~= nil,
"the replay runs after drawBattleWipe, not before it")
end
do
local PaletteFX = require("src.render.PaletteFX")
local savedMode = PaletteFX.mode
PaletteFX.setMode("ogred")
local seen = {}
local function ent()
return { px = 0, py = 0,
draw = function() seen[#seen + 1] = PaletteFX.spriteRedrawPassActive() end }
end
local keep, hero = ent(), ent()
local ow = { camera = { x = 0, y = 0 }, player = hero, battleOamKeep = keep,
sgbWorldZones = function() return nil end }
PaletteFX.setPass("ui")
local ok, err = pcall(OW.drawWipeSprites, ow)
check(ok, "drawWipeSprites runs headless: " .. tostring(err))
eq(#seen, 2, "both survivors are replayed")
check(seen[1] == true and seen[2] == true,
"OG RED replays inside the world pass so SpriteRenderer takes the ogObj bake")
eq(PaletteFX.pass(), "ui", "the caller's pass is restored")
PaletteFX.setPass(nil)
PaletteFX.setMode(savedMode)
end
do
local f = io.open("src/world/OverworldController.lua", "rb")
check(f ~= nil, "OverworldController source is readable")
local src = f:read("*a")
f:close()
check(src:find("Game.renderer.wipeSprites = self.wipeSpritesFn", 1, true) ~= nil,
"drawWorld hands over the hoisted closure instead of allocating one")
check(src:find("self.wipeSpritesFn = function() self:drawWipeSprites() end",
1, true) ~= nil,
"pushBattle owns the one closure")
end
T.finish("battle_transition_oam_bug1948")