export type MemberId = "aelia" | "brann" | "nia" | "orin" | "vale"; export type AbilityId = "mend" | "renew" | "shield" | "purify" | "radiance" | "barrier"; export type BossId = "bulldrome" | "vexa" | "cindermaw" | "ember-mantis-duelist"; export type GamePhase = "briefing" | "combat" | "victory" | "defeat"; export type BottomTab = "combat" | "map" | "pack"; export type PulseKind = AbilityId | "boss" | "debuff" | "charge" | "pounce" | "tether" | "venom" | "breath" | "skyfall" | "slash"; export type BossMotionMode = | "holding" | "telegraph" | "charging" | "returning" | "stacking" | "pouncing" | "tethering" | "venom_cast" | "breath_telegraph" | "breath_sweeping" | "skyfall" | "mantis_sidestep" | "mantis_line_telegraph" | "mantis_cross_telegraph" | "mantis_recover"; export type WorldPosition = [number, number]; export type CircleHazardKind = "venom_pool" | "skyfall"; export interface CircleHazard { id: string; kind: CircleHazardKind; center: WorldPosition; radius: number; activatesAt: number; expiresAt: number; damage: number; tickInterval?: number; nextDamageAt: Partial>; resolved: boolean; hitIds: MemberId[]; } export interface SlashLane { id: string; start: WorldPosition; end: WorldPosition; width: number; damage: number; } export interface Debuff { id: string; name: string; expiresAt: number; nextTickAt: number; tickDamage: number; } export interface PartyMember { id: MemberId; name: string; className: string; role: "Healer" | "Tank" | "Damage"; color: string; maxHp: number; hp: number; absorb: number; renewExpiresAt: number; renewNextTickAt: number; knockedUntil: number; debuffs: Debuff[]; } export interface BossState { id: BossId; name: string; maxHp: number; hp: number; nextMeleeAt: number; nextNovaAt: number; nextBrandAt: number; brandCount: number; } export interface BossMotionState { bossId: BossId; formationOffsetX: number; mode: BossMotionMode; position: WorldPosition; chargeStart: WorldPosition; chargeEnd: WorldPosition; chargeTargetId: MemberId; chargeHitIds: MemberId[]; phaseEndsAt: number; nextChargeAt: number; chargeCount: number; chargesSincePounce: number; pounceTargetId: MemberId; pounceCenter: WorldPosition; pounceCount: number; nextMechanicAt: number; mechanicCount: number; phaseStartedAt: number; mechanicHitIds: MemberId[]; mechanicNextDamageAt: Partial>; tetherIds: MemberId[]; tetherBreakDistance: number; breathAngle: number; breathStartAngle: number; breathEndAngle: number; hazards: CircleHazard[]; slashLanes: SlashLane[]; } export interface AbilityDefinition { id: AbilityId; name: string; shortName: string; key: string; gamepad: string; cooldown: number; castTime?: number; mana: number; icon: string; description: string; targeting: "enemy" | "ally" | "party"; color: string; } export interface ActiveCast { abilityId: "mend"; targetId: MemberId; startedAt: number; completesAt: number; } export interface BarrierState { center: WorldPosition; expiresAt: number; } export interface ScenePulse { id: number; kind: PulseKind; targetId?: MemberId; } export interface InventoryItem { id: string; name: string; slot: string; rarity: "Common" | "Uncommon" | "Rare"; icon: string; stats: string[]; effect: string; equipped: boolean; } export type HealerClassId = "priest" | "druid" | "shaman"; export interface HealerClassDefinition { id: HealerClassId; name: string; specialization: string; icon: string; color: string; resourceName: string; description: string; abilities: Record; }