Spaces:
Running on Zero
Running on Zero
| /** | |
| * ============================================================================ | |
| * COMBO MANAGER - Streak tracking & multiplier calculation | |
| * ============================================================================ | |
| * | |
| * Tracks consecutive correct actions (answers, hits, etc.) and calculates | |
| * a damage/score multiplier based on configurable tier thresholds. | |
| * | |
| * USAGE: | |
| * const cm = new ComboManager({ | |
| * tiers: [ | |
| * { minStreak: 0, multiplier: 1.0, label: '' }, | |
| * { minStreak: 2, multiplier: 1.2, label: 'GOOD' }, | |
| * { minStreak: 4, multiplier: 1.5, label: 'GREAT' }, | |
| * { minStreak: 6, multiplier: 2.0, label: 'PERFECT' }, | |
| * ], | |
| * }); | |
| * | |
| * cm.hit(); // streak +1 | |
| * cm.hit(); // streak +2 | |
| * cm.getMultiplier(); // 1.2 | |
| * cm.miss(); // streak reset to 0 | |
| */ | |
| export interface ComboTier { | |
| /** Minimum streak to reach this tier */ | |
| minStreak: number; | |
| /** Damage/score multiplier at this tier */ | |
| multiplier: number; | |
| /** Display label (e.g., "GREAT!", "PERFECT!") */ | |
| label: string; | |
| } | |
| export interface ComboManagerConfig { | |
| /** Multiplier tiers (sorted by minStreak ascending) */ | |
| tiers: ComboTier[]; | |
| } | |
| export class ComboManager { | |
| private config: ComboManagerConfig; | |
| private currentStreak: number = 0; | |
| private bestStreak: number = 0; | |
| constructor(config: ComboManagerConfig) { | |
| this.config = config; | |
| } | |
| // -- Actions -- | |
| /** Register a successful action (correct answer, hit, etc.) */ | |
| hit(): void { | |
| this.currentStreak++; | |
| this.bestStreak = Math.max(this.bestStreak, this.currentStreak); | |
| } | |
| /** Register a failure (wrong answer, miss). Resets streak. */ | |
| miss(): void { | |
| this.currentStreak = 0; | |
| } | |
| /** Reset all tracking. */ | |
| reset(): void { | |
| this.currentStreak = 0; | |
| this.bestStreak = 0; | |
| } | |
| // -- Query -- | |
| /** Get current streak count. */ | |
| getStreak(): number { | |
| return this.currentStreak; | |
| } | |
| /** Get best streak count. */ | |
| getBestStreak(): number { | |
| return this.bestStreak; | |
| } | |
| /** Get current multiplier based on streak. */ | |
| getMultiplier(): number { | |
| return this.getCurrentTier().multiplier; | |
| } | |
| /** Get current tier label (e.g., "GREAT!"). */ | |
| getLabel(): string { | |
| return this.getCurrentTier().label; | |
| } | |
| /** Get current tier object. Returns a default tier if tiers array is empty. */ | |
| getCurrentTier(): ComboTier { | |
| const tiers = this.config.tiers; | |
| if (tiers.length === 0) { | |
| return { minStreak: 0, multiplier: 1.0, label: '' }; | |
| } | |
| let current = tiers[0]; | |
| for (const tier of tiers) { | |
| if (this.currentStreak >= tier.minStreak) { | |
| current = tier; | |
| } | |
| } | |
| return current; | |
| } | |
| /** Apply multiplier to a value. */ | |
| applyMultiplier(baseValue: number): number { | |
| return Math.floor(baseValue * this.getMultiplier()); | |
| } | |
| } | |