import { spawnMatchesDifficulty, type MobPackDefinition, type StaticMobSpawnDefinition, } from "./mobPopulation"; import type { DungeonEncounterSpawnGroupDefinition } from "./dungeonTypes"; export function activeEncounterSpawnGroupSpawns( groups: readonly DungeonEncounterSpawnGroupDefinition[], activeGroupIds: readonly string[], difficultyMask: number, existingSpawns: readonly StaticMobSpawnDefinition[] = [], ): readonly StaticMobSpawnDefinition[] { const active = new Set(activeGroupIds); const existing = new Set(existingSpawns.map((spawn) => spawn.id)); const included = new Set(); return groups .filter((group) => active.has(group.id)) .flatMap((group) => group.spawns) .filter((spawn) => { if (existing.has(spawn.id) || included.has(spawn.id)) return false; if (!spawnMatchesDifficulty(spawn.spawnMask, difficultyMask)) return false; included.add(spawn.id); return true; }); } export function suppressCompletedDungeonPopulation( staticSpawns: readonly StaticMobSpawnDefinition[], roamingPacks: readonly MobPackDefinition[], completedObjectiveIds: readonly string[], ): { readonly staticSpawns: readonly StaticMobSpawnDefinition[]; readonly roamingPacks: readonly MobPackDefinition[]; } { if (!completedObjectiveIds.length) return { staticSpawns, roamingPacks }; const completed = new Set(completedObjectiveIds); return { staticSpawns: staticSpawns.filter((spawn) => !completed.has(spawn.id)), roamingPacks: roamingPacks.flatMap((pack) => { const members = pack.members.filter( (member) => !completed.has(`${pack.id}:${member.id}`), ); return members.length ? [{ ...pack, members }] : []; }), }; }