import type { GameMode } from "./store"; import type { DungeonBossObjective, DungeonDefinition } from "./dungeonTypes"; import type { ManastormStageAssetPackage } from "./manastormStageAssets"; /** * Party navigation graphs are currently built synchronously on the main thread. * Benchmarks put 50k triangles at roughly half a second on the development * machine. Larger graphs use breadcrumb following until graph construction can * move off the main thread. */ export const MAX_SYNCHRONOUS_PARTY_NAVIGATION_TRIANGLES = 50_000; const NO_ROUTED_PARTY_OBJECTIVES = Object.freeze([]) as readonly DungeonBossObjective[]; export function shouldLoadPartyNavigation( gameMode: GameMode, dungeon: Pick, manastormPackage: Pick | null, ): boolean { const navigation = gameMode === "manastorm" && manastormPackage ? manastormPackage.navigation : dungeon.assets.navigation; if (!navigation) return false; // Navigation can be reviewed independently from encounter/checkpoint content. // Do not make safe melee routing wait for unrelated dungeon validation work. if ( gameMode === "dungeon" && dungeon.validation.status !== "green" && dungeon.validation.navigation !== "green" ) return false; const triangleCount = navigation.triangleCount; return typeof triangleCount === "number" && Number.isInteger(triangleCount) && triangleCount > 0 && triangleCount <= MAX_SYNCHRONOUS_PARTY_NAVIGATION_TRIANGLES; } /** Follow the player's safe breadcrumb trail until a usable graph is ready. */ export function partyObjectivesForNavigation( navigationReady: boolean, objectives: readonly DungeonBossObjective[], ): readonly DungeonBossObjective[] { return navigationReady ? objectives : NO_ROUTED_PARTY_OBJECTIVES; }