diff --git a/src/battle/BattleState.lua b/src/battle/BattleState.lua index e5140bdf..3e7f729f 100644 --- a/src/battle/BattleState.lua +++ b/src/battle/BattleState.lua @@ -4542,11 +4542,15 @@ end -- pixels, so it scales with the pic's draw scale (the player's default 2x -- sinks 2x as fast to sink at the same visual rate); a mod scale composes -- the same way. scale defaults to the vanilla side scale when unknown. +-- SlideDownFaintedMonPic drops the pic one 8px row per 2-frame step, so +-- the offset advances Timing.FAINT_SLIDE_STEP (4px) per frame at 1x -- +-- the full 56px PIC_HEIGHT slide over the 14-frame budget (#671: the +-- old (30 - frames) math teleported the sprite 32px down on frame one). function BattleState:fxFaintOffset(battler, scale) local fx = self.fx if self:fxFaintActive(battler) then scale = scale or (battler.isPlayer and 2 or 1) - return (30 - fx.faint.frames) * 2 * scale + return (Timing.FAINT_SLIDE - fx.faint.frames) * Timing.FAINT_SLIDE_STEP * scale end return 0 end diff --git a/src/core/Timing.lua b/src/core/Timing.lua index f00d3d43..1a1e05bf 100644 --- a/src/core/Timing.lua +++ b/src/core/Timing.lua @@ -129,6 +129,7 @@ Timing.NO_MOVES_LEFT = 60 -- core.asm:2753-2754 Timing.TRAINER_VICTORY = 40 -- core.asm:940-941 Timing.PLAYER_BLACKOUT = 40 -- core.asm:1143-1144 Timing.FAINT_SLIDE_ROW = 2 -- core.asm:1216-1217, per row +Timing.FAINT_SLIDE_STEP = 8 / Timing.FAINT_SLIDE_ROW -- 4px per frame at 1x Timing.TRAINER_SLIDE_COL = 2 -- core.asm:1267-1268, per column -- HP bar (engine/gfx/hp_bar.asm) --------------------------------------------- diff --git a/tests/engine/timing_parity.lua b/tests/engine/timing_parity.lua index 9b09f8bd..e08f3a71 100644 --- a/tests/engine/timing_parity.lua +++ b/tests/engine/timing_parity.lua @@ -273,6 +273,26 @@ T.eq(Timing.BLINK_MON % 10, 0, -- SlideDownFaintedMonPic: b = PIC_HEIGHT slide steps of DelayFrames 2 T.eq(Timing.FAINT_SLIDE, 14, "the faint slide is 7 steps x 2 frames") +-- #671: the slide must start at the sprite's resting spot and sink the +-- full PIC_HEIGHT (7 rows x 8px = 56px at 1x) across those 14 frames. +-- The old (30 - frames) * 2 math teleported the pic 32px down on frame +-- one once the budget was shortened from 30 to 14 frames. +local faintBattle = newBattle() +faintBattle.fx = { faint = { battler = faintBattle.enemy, + frames = Timing.FAINT_SLIDE } } +T.eq(faintBattle:fxFaintOffset(faintBattle.enemy, 1), 0, + "the faint slide starts at offset 0 (#671)") +faintBattle.fx.faint.frames = Timing.FAINT_SLIDE - 7 +T.eq(faintBattle:fxFaintOffset(faintBattle.enemy, 1), + 7 * Timing.FAINT_SLIDE_STEP, + "the slide sinks one 8px row per step") +faintBattle.fx.faint.frames = 1 +T.eq(faintBattle:fxFaintOffset(faintBattle.enemy, 1), + (Timing.FAINT_SLIDE - 1) * Timing.FAINT_SLIDE_STEP, + "the slide reaches 52px by the last visible frame") +T.eq(Timing.FAINT_SLIDE * Timing.FAINT_SLIDE_STEP, 56, + "and covers the full 7-row pic height over the whole budget") + T.eq(Timing.MOVE_STATUS_OR_MISS, 30, "a status move or a miss holds DelayFrames 30 before its text")