import { DAZZA_TEXTS, type DazzaLine } from '../../data/strings/dazza'; // Pure: decides which of Dazza's texts are due. Rule-bearing texts fire on the // clock (they are law the moment they land, design §3.1); everything else fires // when the night gives him something to complain about, so his commentary reads // as a reaction rather than a timer. export interface DazzaWorld { vibe: number; aggro: number; queueLength: number; insideCount: number; fired: ReadonlySet; } /** Conditions for the non-rule texts, keyed by DazzaLine id. */ const MOOD: Record boolean> = { 'vibe-mid': (w) => w.vibe < 35, 'vibe-good': (w) => w.vibe > 72, 'vibe-queue': (w) => w.queueLength >= 6, 'vibe-empty': (w) => w.insideCount <= 3, kayden: (w) => w.queueLength >= 3, }; export function dazzaDue(clockMin: number, world: DazzaWorld): DazzaLine[] { const due: DazzaLine[] = []; for (const line of DAZZA_TEXTS) { if (world.fired.has(line.id)) continue; if (clockMin < line.fromMin) continue; const gate = MOOD[line.id]; if (gate && !gate(world)) continue; due.push(line); } // Rules first when several come due at once — the player needs the law before // the philosophy. return due.sort((a, b) => Number(!!b.ruleId) - Number(!!a.ruleId) || a.fromMin - b.fromMin); } /** At most one text per minute, so a quiet stretch does not become a wall of Dazza. */ export function nextDazza(clockMin: number, world: DazzaWorld): DazzaLine | undefined { return dazzaDue(clockMin, world)[0]; }