54 lines
1.9 KiB
TypeScript
54 lines
1.9 KiB
TypeScript
import { Node } from 'cc';
|
||
import { LevelConfig } from './LevelTypes';
|
||
import { LevelMapData } from './LevelMapData';
|
||
import { themeForLevelId } from './LevelIds';
|
||
|
||
function hasKeys(rec?: Record<string, unknown>): boolean {
|
||
return !!rec && Object.keys(rec).length > 0;
|
||
}
|
||
|
||
function parseJsonRecord(json: string): Record<string, unknown> | undefined {
|
||
try {
|
||
const o = JSON.parse(json || '{}') as unknown;
|
||
if (o && typeof o === 'object' && !Array.isArray(o)) {
|
||
return o as Record<string, unknown>;
|
||
}
|
||
} catch {
|
||
/* ignore */
|
||
}
|
||
return undefined;
|
||
}
|
||
|
||
/**
|
||
* 预制体 LevelMapData(编辑器里看到的地图)为地图/主题权威。
|
||
* levels-database 只提供 spawns / boundary;仅当预制体没有地图数据时才回退到库。
|
||
*/
|
||
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 seriesTheme = themeForLevelId(config.levelID);
|
||
const prefabHasMap =
|
||
hasKeys(prefabGround as Record<string, unknown>)
|
||
|| hasKeys(prefabBorder as Record<string, unknown>);
|
||
|
||
if (!prefabHasMap) {
|
||
return {
|
||
...config,
|
||
theme: seriesTheme || config.theme?.trim() || prefabTheme || 'silu',
|
||
};
|
||
}
|
||
|
||
return {
|
||
...config,
|
||
theme: seriesTheme || prefabTheme || config.theme?.trim() || 'silu',
|
||
ground: hasKeys(prefabGround as Record<string, unknown>) ? prefabGround : config.ground,
|
||
// 预制体已写过地图:空边框就是没有边框,不要用库里的旧 border 补上
|
||
border: prefabBorder ?? {},
|
||
};
|
||
}
|