mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
138 lines
4.7 KiB
Lua
138 lines
4.7 KiB
Lua
-- engine/battle/animations.asm:2639, home/delay.asm:15
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
|
|
local T = require("tests.modkit")
|
|
local Data = T.fixtures.fresh()
|
|
require("src.render.Font").load(Data)
|
|
local BattleState = require("src.battle.BattleState")
|
|
local Pokemon = require("src.pokemon.Pokemon")
|
|
local SaveData = require("src.core.SaveData")
|
|
local TypeChart = require("src.battle.TypeChart")
|
|
local Sound = require("src.core.Sound")
|
|
TypeChart.load(Data)
|
|
|
|
local busy, budget = false, 0
|
|
Sound.moveSfxBusy = function() return busy end
|
|
Sound.moveSfxWaitFrames = function() return budget end
|
|
|
|
local function newBattle(hit, alarm)
|
|
local save = SaveData.newGame()
|
|
save.party = { Pokemon.new(Data, "FIXMON_A", 40) }
|
|
local game = { data = Data, save = save,
|
|
stack = { top = function() return nil end, push = function() end } }
|
|
local battle = BattleState.newWild(game, "FIXMON_C", 40)
|
|
battle.queue, battle.nextInsert = {}, 0
|
|
battle.fx = {}
|
|
battle.animPlayer = { update = function() end,
|
|
isDone = function() return true end,
|
|
pollEffects = function() return {} end }
|
|
battle.animPlaying = true
|
|
battle.pendingHit = hit
|
|
battle.lowHealthAlarmActive = function() return alarm == true end
|
|
return battle
|
|
end
|
|
|
|
local function fxArmed(battle)
|
|
return (battle.fx.shakeProg ~= nil) or (battle.fx.blink ~= nil)
|
|
end
|
|
|
|
for _, t in ipairs({ 1, 2, 5 }) do
|
|
busy, budget = true, 5
|
|
local battle = newBattle({ animType = t, sfx = "Damage" })
|
|
for i = 1, 5 do
|
|
T.eq(battle:updateQueue(), true,
|
|
("type %d holds the queue on frame %d"):format(t, i))
|
|
T.check(not fxArmed(battle),
|
|
("type %d arms no applying-attack fx while the sfx sounds"):format(t))
|
|
T.check(battle.pendingHit ~= nil,
|
|
("type %d keeps its hit row pending"):format(t))
|
|
T.eq(battle.animPlaying, true,
|
|
("type %d stays in the animation branch"):format(t))
|
|
end
|
|
battle:updateQueue()
|
|
T.check(fxArmed(battle),
|
|
("type %d arms its fx once the budget expires"):format(t))
|
|
T.eq(battle.pendingHit, nil, ("type %d consumes its hit row"):format(t))
|
|
T.eq(battle.hitSfxWait, nil, ("type %d clears the hold counter"):format(t))
|
|
end
|
|
|
|
do
|
|
busy, budget = true, 3
|
|
local battle = newBattle(nil)
|
|
battle.pendingHit = { animType = 4, sfx = "Damage", blink = battle.enemy }
|
|
battle:updateQueue()
|
|
T.eq(battle.fx.blink, nil, "type 4 does not blink while the sfx sounds")
|
|
for _ = 1, 3 do battle:updateQueue() end
|
|
T.check(battle.fx.blink ~= nil, "type 4 blinks once the sfx has finished")
|
|
end
|
|
|
|
do
|
|
busy, budget = true, 60
|
|
local battle = newBattle({ animType = 1, sfx = "Damage" })
|
|
battle:updateQueue()
|
|
battle:updateQueue()
|
|
T.check(not fxArmed(battle), "still held while CHAN5/6/8 are busy")
|
|
busy = false
|
|
battle:updateQueue()
|
|
T.check(fxArmed(battle), "released the frame the sfx channels go idle")
|
|
T.eq(battle.hitSfxWait, nil, "and the hold counter is cleared")
|
|
end
|
|
|
|
-- animations.asm:495 / :498 ShakeScreenHorizontallySlow, ...Slow2
|
|
for _, t in ipairs({ 3, 6 }) do
|
|
busy, budget = true, 60
|
|
local battle = newBattle({ animType = t })
|
|
battle:updateQueue()
|
|
T.check(battle.fx.shakeProg ~= nil,
|
|
("type %d shakes without waiting for the sfx"):format(t))
|
|
T.eq(battle.hitSfxWait, nil, ("type %d sets no hold counter"):format(t))
|
|
end
|
|
|
|
do
|
|
busy, budget = true, 60
|
|
local battle = newBattle({ animType = 1, sfx = "Damage" }, true)
|
|
battle:updateQueue()
|
|
T.check(fxArmed(battle), "the low-health alarm bypasses the wait")
|
|
T.eq(battle.hitSfxWait, nil, "and leaves no hold counter behind")
|
|
end
|
|
|
|
do
|
|
busy, budget = true, 60
|
|
local battle = newBattle(nil)
|
|
battle:updateQueue()
|
|
T.eq(battle.animPlaying, false, "a hitless animation row ends on its own")
|
|
T.eq(battle.hitSfxWait, nil, "and sets no hold counter")
|
|
end
|
|
|
|
do
|
|
busy, budget = true, 0
|
|
local battle = newBattle({ animType = 1, sfx = "Damage" })
|
|
battle:updateQueue()
|
|
T.check(fxArmed(battle), "a zero budget releases immediately")
|
|
end
|
|
|
|
do
|
|
busy, budget = true, 100000
|
|
local battle = newBattle({ animType = 1, sfx = "Damage" })
|
|
battle:updateQueue()
|
|
T.eq(battle.hitSfxWait, 179, "the budget is capped at 180 logic frames")
|
|
for _ = 1, 200 do
|
|
if fxArmed(battle) then break end
|
|
battle:updateQueue()
|
|
end
|
|
T.check(fxArmed(battle), "and a stuck source cannot wedge the battle")
|
|
end
|
|
|
|
do
|
|
Sound.moveSfxBusy, Sound.moveSfxWaitFrames = nil, nil
|
|
package.loaded["src.core.Sound"] = nil
|
|
local Fresh = require("src.core.Sound")
|
|
T.eq(type(Fresh.moveSfxBusy), "function", "Sound exposes moveSfxBusy")
|
|
T.eq(type(Fresh.moveSfxWaitFrames), "function",
|
|
"Sound exposes moveSfxWaitFrames")
|
|
T.eq(Fresh.moveSfxBusy(), false, "no move sfx sounding, no wait")
|
|
T.eq(Fresh.moveSfxWaitFrames(), 0, "and a zero frame budget")
|
|
end
|
|
|
|
T.finish()
|