import type { ContentCategoryId } from "../app/contentCategories"; import { standardWowDungeonCreatureHealth } from "./azerothCoreReference"; import { clampPlayerLevel } from "./progression"; const ROM_PARTY_HEALTH_SCALE = 1.15; const COA_PARTY_HEALTH_SCALE = 1.75; /** * Normal campaign dungeons scale to the character instead of retaining the * source client's original 15-80 level gates. Bosses keep a one-level edge so * encounter hierarchy remains visible without making the opening tier lethal. */ export function scaledDungeonEnemyLevel(characterLevel: number, boss: boolean): number { return clampPlayerLevel(characterLevel + (boss ? 1 : 0)); } /** * Enemy durability follows the party's combat catalog, not the dungeon's * source game. This lets a WoW party take its familiar curve into a RoM * dungeon while stronger RoM and CoA parties retain meaningful kill times in * every catalog. Authored creature and boss multipliers are applied separately. */ export function dungeonEnemyHealthBaseline(level: number, partySource: ContentCategoryId): number { const safeLevel = clampPlayerLevel(level); if (partySource === "wow") return standardWowDungeonCreatureHealth(safeLevel); const romBaseline = 1_000 + safeLevel * 100 + safeLevel * safeLevel * 8; if (partySource === "rom") return romBaseline; return Math.round(romBaseline * COA_PARTY_HEALTH_SCALE / ROM_PARTY_HEALTH_SCALE); } /** Keeps trash and boss source calibration on the same relative power scale. */ export function dungeonPartyHealthScale(partySource: ContentCategoryId): number { if (partySource === "wow" || partySource === "rom") return 1; return COA_PARTY_HEALTH_SCALE / ROM_PARTY_HEALTH_SCALE; }