import { GameMapType } from "./Game"; import { GameMapLoader, MapData } from "./GameMapLoader"; import { MapManifest } from "./TerrainMapLoader"; export interface BinModule { default: string; } interface NationMapModule { default: MapManifest; } export class BinaryLoaderGameMapLoader implements GameMapLoader { private maps: Map; constructor() { this.maps = new Map(); } private createLazyLoader(importFn: () => Promise): () => Promise { let cache: Promise | null = null; return () => { cache ??= importFn(); return cache; }; } getMapData(map: GameMapType): MapData { const cachedMap = this.maps.get(map); if (cachedMap) { return cachedMap; } const key = Object.keys(GameMapType).find( (k) => GameMapType[k as keyof typeof GameMapType] === map, ); const fileName = key?.toLowerCase(); const mapData = { mapBin: this.createLazyLoader(() => ( import( `!!binary-loader!../../../resources/maps/${fileName}/map.bin` ) as Promise ).then((m) => this.toUInt8Array(m.default)), ), map4xBin: this.createLazyLoader(() => ( import( `!!binary-loader!../../../resources/maps/${fileName}/map4x.bin` ) as Promise ).then((m) => this.toUInt8Array(m.default)), ), map16xBin: this.createLazyLoader(() => ( import( `!!binary-loader!../../../resources/maps/${fileName}/map16x.bin` ) as Promise ).then((m) => this.toUInt8Array(m.default)), ), manifest: this.createLazyLoader(() => ( import( `../../../resources/maps/${fileName}/manifest.json` ) as Promise ).then((m) => m.default), ), webpPath: this.createLazyLoader(() => ( import( `../../../resources/maps/${fileName}/thumbnail.webp` ) as Promise<{ default: string }> ).then((m) => m.default), ), } satisfies MapData; this.maps.set(map, mapData); return mapData; } /** * Converts a given string into a UInt8Array where each character in the string * is represented as an 8-bit unsigned integer. */ private toUInt8Array(data: string) { const rawData = new Uint8Array(data.length); for (let i = 0; i < data.length; i++) { rawData[i] = data.charCodeAt(i); } return rawData; } }