/** The local player's auto-attack state for one frame. `swingTimer` counts DOWN in seconds to 0 (= a swing lands). */ export interface SwingPlayerInput { autoAttack: boolean; swingTimer: number; weapon: { speed: number; }; } /** The current target, or the fields the bar needs from it. */ export interface SwingTargetInput { dead: boolean; /** Entity kind; an `"object"` target (a node/chest) never shows a swing bar. */ kind: string; } /** Whether the bar shows a "ready" label or the seconds-remaining countdown. */ export type SwingLabelKind = "ready" | "seconds"; /** One frame of swing-bar state plus the cursor (`nextPeriod`/`nextTimer`) the caller carries back into the next call. */ export interface SwingTimerState { /** Whether the bar should render at all. */ visible: boolean; /** Fill 0..1, growing toward 1 as the next swing nears. */ frac: number; /** True the moment the swing is ready to land. */ ready: boolean; labelKind: SwingLabelKind; /** Seconds remaining until the next swing (0 when ready). */ seconds: number; /** Recovered swing period this frame — pass back as `prevPeriod` next call. */ nextPeriod: number; /** This frame's timer — pass back as `prevTimer` next call to detect the reset edge. */ nextTimer: number; } /** Threshold above which a timer jump is treated as a fresh swing (period reset). */ export declare const SWING_EDGE_EPSILON = 0.0001; /** * Pure swing-timer bar state — no hidden state, no clock, no DOM. The caller * threads `prevPeriod`/`prevTimer` back each frame. The period is recovered on * the reset edge (when `swingTimer` jumps up = a new swing began) as * `max(swingTimer, weapon.speed)`, so the fill is correct even without knowing * the weapon's exact cadence. Hidden unless auto-attacking a live, non-object target. */ export declare function swingTimerState(player: SwingPlayerInput, target: SwingTargetInput | null, prevPeriod: number, prevTimer: number): SwingTimerState;