Adds level prefabs, theme assets, audio, extensions, and deployment scripts for the Unity WebGL migration. Co-authored-by: Cursor <cursoragent@cursor.com>
70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
import { Node } from 'cc';
|
||
import { LevelConfig, SpawnConfig } from './LevelTypes';
|
||
import { LevelMapData } from './LevelMapData';
|
||
|
||
function hasKeys(rec?: Record<string, unknown>): boolean {
|
||
return !!rec && Object.keys(rec).length > 0;
|
||
}
|
||
|
||
/** 地图是否覆盖玩家/道具/载具 spawn 格(旧预制体常残留错误横向砖块) */
|
||
function groundCoversSpawns(ground: Record<string, unknown> | 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<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;
|
||
}
|
||
|
||
/**
|
||
* 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<string, unknown>)
|
||
? prefabBorder
|
||
: config.border;
|
||
|
||
return {
|
||
...config,
|
||
theme: prefabTheme || config.theme?.trim() || config.theme,
|
||
ground: pickGround(
|
||
prefabGround as LevelConfig['ground'],
|
||
config.ground,
|
||
config.spawns ?? [],
|
||
),
|
||
border,
|
||
};
|
||
}
|