Adds level prefabs, theme assets, audio, extensions, and deployment scripts for the Unity WebGL migration. Co-authored-by: Cursor <cursoragent@cursor.com>
110 lines
2.7 KiB
JavaScript
110 lines
2.7 KiB
JavaScript
'use strict';
|
||
|
||
/** 与 Unity / 主站 config.js BEGINNING_REAL_LVID、LevelRegistry.LEVEL_ID_BASE 一致 */
|
||
const LEVEL_ID_BASE = 91601;
|
||
const PREFAB_DIR = 'level-prefabs';
|
||
|
||
/** internalIndex 0 → 91601(首关) */
|
||
function externalLevelId(internalIndex) {
|
||
return LEVEL_ID_BASE + internalIndex;
|
||
}
|
||
|
||
function internalLevelIndex(levelId) {
|
||
return levelId >= LEVEL_ID_BASE ? levelId - LEVEL_ID_BASE : levelId;
|
||
}
|
||
|
||
function isGameLevelId(levelId) {
|
||
return levelId >= LEVEL_ID_BASE;
|
||
}
|
||
|
||
function isExternalLevelId(levelId) {
|
||
return isGameLevelId(levelId);
|
||
}
|
||
|
||
function minLevelId() {
|
||
return LEVEL_ID_BASE;
|
||
}
|
||
|
||
function prefabResourcePath(levelId) {
|
||
return `${PREFAB_DIR}/Level${levelId}`;
|
||
}
|
||
|
||
function normalizeDb(db) {
|
||
if (!db.levels) db.levels = {};
|
||
db.levelIdBase = LEVEL_ID_BASE;
|
||
return db;
|
||
}
|
||
|
||
function nextAvailableLevelId(db) {
|
||
const keys = Object.keys(db.levels || {});
|
||
if (!keys.length) return LEVEL_ID_BASE;
|
||
const ids = keys.map((k) => parseInt(k, 10)).filter((n) => !Number.isNaN(n));
|
||
return Math.max(...ids) + 1;
|
||
}
|
||
|
||
function syncLevelEntry(cfg, levelId) {
|
||
const out = { ...cfg };
|
||
out.levelID = levelId;
|
||
out.cocosPrefab = prefabResourcePath(levelId);
|
||
if (typeof out.unityPrefab === 'string' && out.unityPrefab) {
|
||
out.unityPrefab = out.unityPrefab.replace(/Level\d+\.prefab$/i, `Level${levelId}.prefab`);
|
||
}
|
||
return out;
|
||
}
|
||
|
||
function updateDbStats(db) {
|
||
const total = Object.keys(db.levels || {}).length;
|
||
db.stats = { ...(db.stats || {}), total, withPrefabTilemap: total };
|
||
}
|
||
|
||
function touchDatabase(db, levelId) {
|
||
normalizeDb(db);
|
||
const key = String(levelId);
|
||
if (db.levels[key]) {
|
||
db.levels[key] = syncLevelEntry(db.levels[key], levelId);
|
||
}
|
||
updateDbStats(db);
|
||
db.generatedAt = new Date().toISOString();
|
||
}
|
||
|
||
function sortedLevelIds(db) {
|
||
return Object.keys(db.levels || {})
|
||
.map((k) => parseInt(k, 10))
|
||
.filter((n) => !Number.isNaN(n))
|
||
.sort((a, b) => a - b);
|
||
}
|
||
|
||
function prevLevelIdInDb(db, cur) {
|
||
const ids = sortedLevelIds(db);
|
||
if (!ids.length) return cur;
|
||
const i = ids.indexOf(cur);
|
||
if (i < 0) return ids[0];
|
||
return ids[(i - 1 + ids.length) % ids.length];
|
||
}
|
||
|
||
function nextLevelIdInDb(db, cur) {
|
||
const ids = sortedLevelIds(db);
|
||
if (!ids.length) return cur;
|
||
const i = ids.indexOf(cur);
|
||
if (i < 0) return ids[0];
|
||
return ids[(i + 1) % ids.length];
|
||
}
|
||
|
||
module.exports = {
|
||
LEVEL_ID_BASE,
|
||
PREFAB_DIR,
|
||
externalLevelId,
|
||
internalLevelIndex,
|
||
isExternalLevelId,
|
||
minLevelId,
|
||
prefabResourcePath,
|
||
normalizeDb,
|
||
nextAvailableLevelId,
|
||
syncLevelEntry,
|
||
updateDbStats,
|
||
touchDatabase,
|
||
sortedLevelIds,
|
||
prevLevelIdInDb,
|
||
nextLevelIdInDb,
|
||
};
|