import type { DungeonDefinition, DungeonPresentation, DungeonTraversalRamp } from "./dungeonTypes"; import stairCatalog from "./generated/wowDungeonStairs.generated.json"; type LightingProfile = Pick & { readonly fog: Pick; }; // Imported WoW environments do not carry the original client's baked lighting. // Stockades' reviewed fill levels are the baseline; color remains environment-specific. export const WOW_DUNGEON_LIGHTING: Readonly> = { stone: { background: "#171815", fog: { color: "#1b1c18", near: 44 }, ambientLight: { color: "#d8c9aa", intensity: 0.58 }, hemisphereLight: { skyColor: "#cfc3a5", groundColor: "#292820", intensity: 0.86 }, directionalLight: { color: "#ffe0a8", intensity: 1.1, offset: [10, 18, -5] }, }, cavern: { background: "#121914", fog: { color: "#172019", near: 44 }, ambientLight: { color: "#bcccaf", intensity: 0.58 }, hemisphereLight: { skyColor: "#b2c6b5", groundColor: "#242b22", intensity: 0.86 }, directionalLight: { color: "#dce5bc", intensity: 1.1, offset: [10, 18, -5] }, }, fire: { background: "#211612", fog: { color: "#291c17", near: 44 }, ambientLight: { color: "#d3bca9", intensity: 0.58 }, hemisphereLight: { skyColor: "#d1bca6", groundColor: "#30251f", intensity: 0.86 }, directionalLight: { color: "#ffd3a1", intensity: 1.1, offset: [10, 18, -5] }, }, arcane: { background: "#161827", fog: { color: "#1c2030", near: 44 }, ambientLight: { color: "#c4c8de", intensity: 0.58 }, hemisphereLight: { skyColor: "#bdc9e6", groundColor: "#25283a", intensity: 0.86 }, directionalLight: { color: "#e0e9ff", intensity: 1.1, offset: [10, 18, -5] }, }, crypt: { background: "#171721", fog: { color: "#1d1d28", near: 44 }, ambientLight: { color: "#c8c3d1", intensity: 0.58 }, hemisphereLight: { skyColor: "#c0c2d3", groundColor: "#282530", intensity: 0.86 }, directionalLight: { color: "#e7ddcf", intensity: 1.1, offset: [10, 18, -5] }, }, outdoor: { background: "#293330", fog: { color: "#35423e", near: 80 }, ambientLight: { color: "#d4dccb", intensity: 0.58 }, hemisphereLight: { skyColor: "#c9d9e5", groundColor: "#30382b", intensity: 0.86 }, directionalLight: { color: "#fff0cd", intensity: 1.1, offset: [10, 18, -5] }, }, }; const PROFILE_DUNGEONS: Readonly> = { cavern: ["wailing-caverns", "razorfen-kraul", "razorfen-downs", "blackfathom-deeps", "maraudon", "underbog", "slave-pens", "steamvault"], fire: ["ragefire-chasm", "blackrock-depths", "blackrock-spire", "hellfire-ramparts", "blood-furnace", "shattered-halls"], arcane: ["gnomeregan", "arcatraz", "botanica", "mechanar", "magisters-terrace", "the-nexus", "the-oculus", "violet-hold", "tinkertech-showdown"], crypt: ["shadowfang-keep", "scholomance", "stratholme", "sunken-temple", "auchenai-crypts", "mana-tombs", "sethekk-halls", "shadow-labyrinth", "azjol-nerub", "ahnkahet-old-kingdom", "forge-of-souls", "halls-of-reflection"], outdoor: ["zulfarrak", "black-morass", "escape-from-durnholde", "culling-of-stratholme", "trial-of-the-champion", "pit-of-saron", "frozen-reach"], }; export function wowDungeonLightingProfile(id: string): string { return Object.entries(PROFILE_DUNGEONS).find(([, ids]) => ids.includes(id))?.[0] ?? "stone"; } /** Shared adapter also covers authored Wailing Caverns and survives campaign regeneration. */ export function withWowDungeonEnvironment(definition: DungeonDefinition): DungeonDefinition { if (definition.expansion === "runewaker") return definition; const profile = WOW_DUNGEON_LIGHTING[wowDungeonLightingProfile(definition.id)]; const stairs = (stairCatalog.dungeons as unknown as Readonly>)[definition.id]; // Never apply package-space coordinates to a newly replaced environment. const matchingAssets = stairs && definition.assets.collision.length === stairs.collision.length && definition.assets.collision.every((asset, index) => asset.url === stairs.collision[index].url && asset.checksum === stairs.collision[index].checksum); const matchingNavigation = !stairs?.ramps.some((ramp) => ramp.navigationBridges?.length) || (definition.assets.navigation?.url === stairs?.navigation?.url && definition.assets.navigation?.checksum === stairs?.navigation?.checksum); return { ...definition, presentation: definition.id === "stormwind-stockade" ? definition.presentation : { ...definition.presentation, ...profile, fog: { ...definition.presentation.fog, ...profile.fog }, }, ...(matchingAssets && matchingNavigation && stairs.ramps.length ? { traversalRamps: stairs.ramps } : {}), }; }