import { loadScenarioDefinitionById } from '@sammo-ts/game-engine/scenario/scenarioLoader.js'; import type { ScenarioDefinition } from '@sammo-ts/logic'; import { loadMapDefinitionByName } from './mapDefinition.js'; export interface MapLayoutCity { id: number; name: string; level: number; region: number; x: number; y: number; path: number[]; } export interface MapLayout { mapName: string; cityList: MapLayoutCity[]; regionMap: Record; levelMap: Record; } export interface MapLayoutLoaderOptions { loadScenario?: (scenarioId: number) => Promise; loadMap?: typeof loadMapDefinitionByName; } const layoutCache = new Map(); const parseScenarioId = (scenario: string): number | null => { const normalized = scenario.replace(/^scenario_/i, '').replace(/\.json$/i, ''); if (!/^\d+$/.test(normalized)) { return null; } const scenarioId = Number(normalized); return Number.isSafeInteger(scenarioId) ? scenarioId : null; }; const resolveMapName = async ( scenario: string, loadScenario: (scenarioId: number) => Promise ): Promise => { const scenarioId = parseScenarioId(scenario); if (scenarioId === null) { return 'che'; } try { const definition = await loadScenario(scenarioId); return definition.config.environment.mapName; } catch { // 운영 DB가 보존된 상태에서 해당 commit에 scenario resource가 없을 수 // 있으므로 기존 기본 map인 che로 안전하게 돌아갑니다. return 'che'; } }; export const loadMapLayout = async (scenario: string, options: MapLayoutLoaderOptions = {}): Promise => { const mapName = await resolveMapName(scenario, options.loadScenario ?? loadScenarioDefinitionById); const useCache = !options.loadScenario && !options.loadMap; const cached = useCache ? layoutCache.get(mapName) : undefined; if (cached) { return cached; } const map = await (options.loadMap ?? loadMapDefinitionByName)(mapName); const layout: MapLayout = { mapName, cityList: map.cities.map((city) => ({ id: city.id, name: city.name, level: city.level, region: city.region, x: city.position.x, y: city.position.y, path: [...city.connections], })), regionMap: {}, levelMap: {}, }; if (useCache) { layoutCache.set(mapName, layout); } return layout; };