import type { MobCombatState } from "./combatStore"; import type { ManastormEncounterDefinition, ManastormPhase, } from "./manastorm"; /** * Ascension's published Chapter 2 tuning: each remaining Chaotic Link stack * grants roughly 25% boss health and 10% boss damage. The number of stacks is * approximately half of the creatures between the party and the boss. */ export const MANASTORM_CHAOTIC_LINK_HEALTH_PER_STACK = 0.25; export const MANASTORM_CHAOTIC_LINK_DAMAGE_PER_STACK = 0.10; export interface ManastormChaoticLinkState { readonly guardianCount: number; readonly defeatedGuardians: number; readonly requiredGuardianKills: number; readonly activeStacks: number; readonly broken: boolean; readonly bossHealthMultiplier: number; readonly bossDamageMultiplier: number; } function uniqueGuardianIds( encounter: ManastormEncounterDefinition, ): readonly string[] { return [...new Set( (encounter.trashRuntimeIds ?? []) .filter((runtimeId) => Boolean(runtimeId) && runtimeId !== encounter.bossRuntimeId), )]; } /** * Missing guardian registrations count as alive. This prevents a partially * mounted scene from prematurely breaking the link before its actors exist. */ export function manastormChaoticLinkState( encounter: ManastormEncounterDefinition, mobs: Readonly>, ): ManastormChaoticLinkState { const guardianIds = uniqueGuardianIds(encounter); const guardianCount = guardianIds.length; const defeatedGuardians = guardianIds.filter( (runtimeId) => mobs[runtimeId]?.dead === true, ).length; const requiredGuardianKills = encounter.chaoticLinkEnabled === false ? 0 : Math.max( 0, Math.min( guardianCount, Math.trunc(encounter.requiredGuardianKills ?? Math.ceil(guardianCount / 2)), ), ); const activeStacks = Math.max(0, requiredGuardianKills - defeatedGuardians); return Object.freeze({ guardianCount, defeatedGuardians, requiredGuardianKills, activeStacks, broken: activeStacks === 0, bossHealthMultiplier: 1 + activeStacks * MANASTORM_CHAOTIC_LINK_HEALTH_PER_STACK, bossDamageMultiplier: 1 + activeStacks * MANASTORM_CHAOTIC_LINK_DAMAGE_PER_STACK, }); } /** * Chaotic Link requires the boss and its linked creatures to coexist. The boss * may be challenged immediately at full strength; killing approximately half * of the linked guardians first removes the aura. */ export function manastormChaoticLinkRuntimeIds( encounter: ManastormEncounterDefinition | null, phase: ManastormPhase, ): readonly string[] { if ( !encounter || phase === "idle" || phase === "next" || phase === "failed" || phase === "complete" ) { return []; } return [...new Set([ ...(encounter.trashRuntimeIds ?? []), encounter.bossRuntimeId, ])]; }