import { Node } from 'cc'; import { LevelConfig, SpawnConfig } from './LevelTypes'; import { LevelMapData } from './LevelMapData'; function hasKeys(rec?: Record): boolean { return !!rec && Object.keys(rec).length > 0; } /** 地图是否覆盖玩家/道具/载具 spawn 格(旧预制体常残留错误横向砖块) */ function groundCoversSpawns(ground: Record | undefined, spawns: SpawnConfig[]): boolean { if (!ground || !spawns.length) return false; for (const s of spawns) { if (s.kind !== 'player' && s.kind !== 'prop' && s.kind !== 'vehicle') continue; if (!ground[`${s.x},${s.y}`]) return false; } return true; } /** Cocos 预制体 LevelMapData 优先;DB 仅作 spawns 载体时的回退 */ function pickGround( fromPrefab: LevelConfig['ground'], fromDb: LevelConfig['ground'], spawns: SpawnConfig[], ): LevelConfig['ground'] { if (groundCoversSpawns(fromPrefab, spawns)) return fromPrefab; if (groundCoversSpawns(fromDb, spawns)) return fromDb; if (hasKeys(fromPrefab)) return fromPrefab; return fromDb; } function parseJsonRecord(json: string): Record | undefined { try { const o = JSON.parse(json || '{}') as unknown; if (o && typeof o === 'object' && !Array.isArray(o)) { return o as Record; } } catch { /* ignore */ } return undefined; } /** * Cocos 预制体 LevelMapData 为地图/主题权威;levels-database 主要提供 spawns。 */ export function mergeLevelConfigWithMapData(config: LevelConfig, levelRoot: Node): LevelConfig { if (!levelRoot?.isValid) return config; const md = levelRoot.getComponent(LevelMapData); if (!md) return config; const prefabGround = parseJsonRecord(md.groundJson) as LevelConfig['ground']; const prefabBorder = parseJsonRecord(md.borderJson) as LevelConfig['border']; const prefabTheme = md.theme?.trim(); const border = hasKeys(prefabBorder as Record) ? prefabBorder : config.border; return { ...config, theme: prefabTheme || config.theme?.trim() || config.theme, ground: pickGround( prefabGround as LevelConfig['ground'], config.ground, config.spawns ?? [], ), border, }; }