import type { DungeonAssetChunk, DungeonDefinition } from "./dungeonTypes"; import type { ManastormStageAssetPackage } from "./manastormStageAssets"; import { dungeonModules } from "@dungeonAssetModules"; function findAsset(dungeonId: string, chunk: DungeonAssetChunk | undefined): string | null { if (!chunk) return null; if (chunk.url?.startsWith("/")) return chunk.url; if (import.meta.env.VITE_CONTENT_MODE === "downloadable") { return `/assets/game/dungeons/${dungeonId}/${chunk.fileName}`; } const suffix = `/dungeons/${dungeonId}/${chunk.fileName}`.toLowerCase(); return Object.entries(dungeonModules).find(([path]) => path.replace(/\\/g, "/").toLowerCase().endsWith(suffix))?.[1] ?? null; } export interface ResolvedDungeonAssets { readonly visual: readonly string[]; readonly collision: readonly string[]; readonly navigation: string | null; } export function resolveDungeonAssets(definition: DungeonDefinition): ResolvedDungeonAssets { return { visual: definition.assets.visual.flatMap((chunk) => findAsset(definition.id, chunk) ?? []), collision: definition.assets.collision.flatMap((chunk) => findAsset(definition.id, chunk) ?? []), navigation: findAsset(definition.id, definition.assets.navigation), }; } export function resolveManastormStageAssets( assetPackage: ManastormStageAssetPackage, ): ResolvedDungeonAssets { return { visual: assetPackage.visual.map((chunk) => chunk.url), collision: assetPackage.collision.map((chunk) => chunk.url), navigation: assetPackage.navigation.url, }; } /** Every regular-dungeon GLB owned by this definition, with shared URLs deduplicated. */ export function dungeonGltfUrls(definition: DungeonDefinition): readonly string[] { const assets = resolveDungeonAssets(definition); const urls = new Set([ ...assets.visual, ...assets.collision, ...(assets.navigation ? [assets.navigation] : []), ]); for (const entity of Object.values(definition.entities)) { if (entity.visual.model?.url) urls.add(entity.visual.model.url); } return [...urls]; }