Files
healer-man/src/game/dungeonBossCards.ts
T
2026-09-26 22:02:18 -04:00

45 lines
2.3 KiB
TypeScript

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<string>();
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 }];
});
}