const lastStand = new Map(); let boonUntil = 0; export function applyLastStand(id: string, now: number): number { const previous = lastStand.get(id); const stacks = Math.min(3, (previous && previous.expiresAt > now ? previous.stacks : 0) + 1); lastStand.set(id, { stacks, expiresAt: now + 6_000 }); return stacks; } export function lastStandStacks(id: string, now: number): number { const state = lastStand.get(id); if (!state || state.expiresAt <= now) { lastStand.delete(id); return 0; } return state.stacks; } export function activeLastStand(now: number): readonly { id: string; stacks: number }[] { return [...lastStand.keys()].flatMap((id) => { const stacks = lastStandStacks(id, now); return stacks ? [{ id, stacks }] : []; }); } export function raceAffixMobDamageMultiplier(id: string, now: number): number { return 1 + lastStandStacks(id, now) * 0.25; } export function grantRaceAffixBoon(now: number): void { boonUntil = now + 8_000; } export function raceAffixHasteMultiplier(now = Date.now()): number { return boonUntil > now ? 1.15 : 1; } export function raceAffixBoonUntil(): number { return boonUntil; } export function shiftDungeonRaceAffixBuffs(elapsedMs: number): void { if (elapsedMs <= 0) return; for (const [id, state] of lastStand) lastStand.set(id, { ...state, expiresAt: state.expiresAt + elapsedMs }); if (boonUntil > 0) boonUntil += elapsedMs; } export function resetDungeonRaceAffixBuffs(): void { lastStand.clear(); boonUntil = 0; }