forked from phenom/healer-man
45 lines
2.3 KiB
TypeScript
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 }];
|
|
});
|
|
}
|