50
extensions/level-map-editor/dist/editor-tools.js
vendored
50
extensions/level-map-editor/dist/editor-tools.js
vendored
@@ -37,8 +37,12 @@ function removeCell(state, key) {
|
||||
}
|
||||
|
||||
function setCell(state, key, tileKey) {
|
||||
if (state.editLayer === 'ground') state.config.ground[key] = tileKey;
|
||||
else state.config.border[key] = tileKey;
|
||||
if (state.editLayer === 'ground') {
|
||||
state.config.ground[key] = tileKey === 'JumpBlock' ? 'JumpBlock' : 'Baseblock';
|
||||
} else {
|
||||
const s = typeof tileKey === 'string' ? tileKey.trim() : '';
|
||||
state.config.border[key] = (!s || s === 'Baseblock' || s === 'JumpBlock') ? 'WallBlock' : s;
|
||||
}
|
||||
}
|
||||
|
||||
function canPaintBrush(state) {
|
||||
@@ -135,6 +139,45 @@ function findPaletteTile(state, tileKey, layer) {
|
||||
return state.tiles.find((t) => t.tileKey === tileKey && t.layer === layer) || null;
|
||||
}
|
||||
|
||||
/** Ground 瓦片中文名 */
|
||||
function groundTileLabel(tileKey) {
|
||||
if (tileKey === 'JumpBlock') return '跳跃砖(JumpBlock)';
|
||||
return '可移动砖块(Baseblock)';
|
||||
}
|
||||
|
||||
/** Border 瓦片中文名 */
|
||||
function borderTileLabel(tileKey) {
|
||||
const s = tileKey === true || tileKey === 1 ? 'WallBlock' : String(tileKey || 'WallBlock').trim();
|
||||
if (!s || s === 'WallBlock') return '墙砖(WallBlock)';
|
||||
return `墙饰(${s})`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 汇总格子上全部内容(两层瓦片 + 实体),用于状态栏悬停提示。
|
||||
* @param {object} state
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {{ kind: string, propPlacement?: string }[]} [spawnHits]
|
||||
* @param {Record<string, string>} [spawnKindLabels]
|
||||
*/
|
||||
function describeCellContents(state, x, y, spawnHits, spawnKindLabels) {
|
||||
const key = `${x},${y}`;
|
||||
const parts = [];
|
||||
const ground = state.config?.ground?.[key];
|
||||
if (ground !== undefined) parts.push(groundTileLabel(ground));
|
||||
const border = state.config?.border?.[key];
|
||||
if (border !== undefined) parts.push(borderTileLabel(border));
|
||||
if (Array.isArray(spawnHits)) {
|
||||
for (const h of spawnHits) {
|
||||
let label = (spawnKindLabels && spawnKindLabels[h.kind]) || h.kind;
|
||||
if (h.kind === 'player') label = '人物';
|
||||
if (h.kind === 'prop' && h.propPlacement === 'ground') label = `${label}(空地)`;
|
||||
parts.push(label);
|
||||
}
|
||||
}
|
||||
return parts.length ? parts.join(' + ') : '空';
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
TOOLS,
|
||||
TOOL_LABELS,
|
||||
@@ -150,4 +193,7 @@ module.exports = {
|
||||
floodFill,
|
||||
floodErase,
|
||||
findPaletteTile,
|
||||
groundTileLabel,
|
||||
borderTileLabel,
|
||||
describeCellContents,
|
||||
};
|
||||
|
||||
@@ -196,9 +196,25 @@ function bindOnce(el, event, handler) {
|
||||
function normalizeBorder(border) {
|
||||
const out = {};
|
||||
for (const [k, v] of Object.entries(border || {})) {
|
||||
if (v === true || v === 1) out[k] = 'WallBlock';
|
||||
else if (typeof v === 'string') out[k] = v;
|
||||
else out[k] = 'WallBlock';
|
||||
if (v === true || v === 1) {
|
||||
out[k] = 'WallBlock';
|
||||
continue;
|
||||
}
|
||||
if (typeof v === 'string') {
|
||||
const s = v.trim();
|
||||
// 地砖名不得进入 Border
|
||||
out[k] = (!s || s === 'Baseblock' || s === 'JumpBlock') ? 'WallBlock' : s;
|
||||
continue;
|
||||
}
|
||||
out[k] = 'WallBlock';
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function normalizeGround(ground) {
|
||||
const out = {};
|
||||
for (const [k, v] of Object.entries(ground || {})) {
|
||||
out[k] = v === 'JumpBlock' ? 'JumpBlock' : 'Baseblock';
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -504,7 +520,7 @@ exports.ready = function () {
|
||||
if (this.$.levelId) this.$.levelId.value = String(id);
|
||||
state.config = levelIdUtil.syncLevelEntry(JSON.parse(JSON.stringify(cfg)), id);
|
||||
state.selectedSpawn = null;
|
||||
state.config.ground = state.config.ground || {};
|
||||
state.config.ground = normalizeGround(state.config.ground || {});
|
||||
state.config.border = normalizeBorder(state.config.border);
|
||||
state.config.spawns = Array.isArray(cfg.spawns) ? JSON.parse(JSON.stringify(cfg.spawns)) : [];
|
||||
spawnTools.ensureSpawns(state);
|
||||
@@ -1115,20 +1131,27 @@ exports.ready = function () {
|
||||
}
|
||||
if (changed) drawGrid.call(this, state);
|
||||
if (!state.painting && this.$.status && c) {
|
||||
if (state.editMode === 'spawns') {
|
||||
const hits = spawnTools.spawnsAt(state, c.x, c.y);
|
||||
const hitInfo = hits.length
|
||||
? ` [${hits.map((h) => spawnTools.SPAWN_KIND_LABELS[h.kind] || h.kind).join('+')}]`
|
||||
: '';
|
||||
const hint = spawnTools.validationHint(state);
|
||||
this.$.status.textContent = `[实体] 格子 (${c.x},${c.y})${hitInfo} · ${spawnTools.spawnSummary(state)}${hint ? ` · ${hint}` : ''}`;
|
||||
} else {
|
||||
const layer = state.editLayer === 'ground' ? 'Ground' : 'Border';
|
||||
const v = isInGrid(c) ? tools.getCell(state, c.key) : undefined;
|
||||
const info = v !== undefined ? ` 当前=${v === true ? '墙' : v}` : ' 空';
|
||||
const bounds = isInGrid(c) ? '' : ' [超出 60×60]';
|
||||
this.$.status.textContent = `[${layer}] 格子 (${c.x},${c.y})${info}${bounds} · 缩放 ${Math.round(state.zoom * 100)}% — ${tools.TOOL_LABELS[state.tool]}`;
|
||||
}
|
||||
const modeTag = state.editMode === 'spawns'
|
||||
? '实体'
|
||||
: (state.editLayer === 'ground' ? 'Ground' : 'Border');
|
||||
const bounds = isInGrid(c) ? '' : ' [超出 60×60]';
|
||||
const contents = isInGrid(c)
|
||||
? tools.describeCellContents(
|
||||
state,
|
||||
c.x,
|
||||
c.y,
|
||||
spawnTools.spawnsAt(state, c.x, c.y),
|
||||
spawnTools.SPAWN_KIND_LABELS,
|
||||
)
|
||||
: '空';
|
||||
const hint = state.editMode === 'spawns'
|
||||
? spawnTools.validationHint(state)
|
||||
: tools.TOOL_LABELS[state.tool];
|
||||
const summary = state.editMode === 'spawns' ? ` · ${spawnTools.spawnSummary(state)}` : '';
|
||||
this.$.status.textContent =
|
||||
`[${modeTag}] 格子 (${c.x},${c.y}) ${contents}${bounds}`
|
||||
+ ` · 缩放 ${Math.round(state.zoom * 100)}%`
|
||||
+ `${summary}${hint ? ` — ${hint}` : ''}`;
|
||||
}
|
||||
if (state.painting && state.editMode === 'map' && (state.tool === 'paint' || state.tool === 'eraser') && c && isInGrid(c)) {
|
||||
if (applyToolAt(c)) drawGrid.call(this, state);
|
||||
|
||||
@@ -152,9 +152,10 @@ function parseTilesFromNodes(objs, projectPath) {
|
||||
const layer = m[1] === 'g' ? 'ground' : 'border';
|
||||
const tileKey = tileKeyFromSpriteUuid(spriteUuidOnNode(objs, obj), projectPath);
|
||||
if (layer === 'ground') {
|
||||
ground[key] = tileKey || 'Baseblock';
|
||||
ground[key] = tileKey === 'JumpBlock' ? 'JumpBlock' : 'Baseblock';
|
||||
} else {
|
||||
border[key] = tileKey || 'WallBlock';
|
||||
const s = tileKey || 'WallBlock';
|
||||
border[key] = (s === 'Baseblock' || s === 'JumpBlock') ? 'WallBlock' : s;
|
||||
}
|
||||
}
|
||||
return { ground, border };
|
||||
|
||||
Reference in New Issue
Block a user