import { bossCardByKey, bossCardForSource } from "./bossCardCatalog"; import { BOSS_CARD_RARITIES, type BossCardCollection, type BossCardRarity } from "./bossCards"; import { dungeonBossesForDifficulty } from "./dungeonRunStore"; import type { DungeonDefinition } from "./dungeonTypes"; import type { MobModelStyle } from "./mobPopulation"; export interface DungeonBossCard { readonly key: string; readonly name: string; readonly ownedRarities: readonly BossCardRarity[]; readonly copies: number; readonly model?: MobModelStyle; } /** The preview uses the prepared run definition, so seeded bosses match the actual dungeon. */ export function dungeonBossCards( dungeon: DungeonDefinition, difficultyId: string, collection: BossCardCollection, ): readonly DungeonBossCard[] { const seen = new Set(); return dungeonBossesForDifficulty(dungeon, difficultyId).flatMap((boss) => { const category = /^randomized:(wow|rom):boss:/.exec(boss.id)?.[1] ?? (dungeon.expansion === "runewaker" ? "rom" : "wow"); const normalizedName = boss.name.trim().toLowerCase().replace(/\s+/g, " "); const fallbackKey = `${category}:${normalizedName}`; const sourceCard = bossCardForSource(boss.id, dungeon.id, boss.name); // Seeded variants can reuse an objective id while replacing its boss identity. const card = sourceCard?.name.trim().toLowerCase().replace(/\s+/g, " ") === normalizedName ? sourceCard : bossCardByKey(fallbackKey); const spawn = dungeon.staticSpawns.find((entry) => entry.id === boss.id) ?? dungeon.encounterSpawnGroups?.flatMap((group) => group.spawns).find((entry) => entry.id === boss.id); const activeEntity = spawn ? dungeon.entities[spawn.entityId] : undefined; const activeModel = activeEntity?.name.trim().toLowerCase().replace(/\s+/g, " ") === normalizedName ? activeEntity.visual.model : undefined; const key = card?.key ?? fallbackKey; if (seen.has(key)) return []; seen.add(key); const counts = collection.counts[key] ?? {}; const ownedRarities = BOSS_CARD_RARITIES.filter((rarity) => (counts[rarity] ?? 0) > 0); const copies = BOSS_CARD_RARITIES.reduce((sum, rarity) => sum + (counts[rarity] ?? 0), 0); return [{ key, name: boss.name, ownedRarities, copies, model: activeModel ?? card?.model }]; }); }