'use strict'; /** 各主题推荐贴图路径(resources 相对路径,无 .png),供编辑器「从主题填充」 */ /** Prop_kuai1 → nProp_kuai1;Prop → nProp */ function propToGroundPath(blockPath) { if (!blockPath) return ''; const norm = String(blockPath).trim().replace(/\\/g, '/'); const slash = norm.lastIndexOf('/'); const dir = slash >= 0 ? norm.slice(0, slash + 1) : ''; const file = slash >= 0 ? norm.slice(slash + 1) : norm; if (file.startsWith('Prop_')) return `${dir}n${file}`; if (file === 'Prop') return `${dir}nProp`; if (file.startsWith('nProp')) return norm; return norm.replace(/\/Prop([^/]*)$/, '/nProp$1'); } function withPropGround(preset) { return { ...preset, propGround: propToGroundPath(preset.prop), }; } function vehicleFourWay(folder, prefix) { const base = `textures/${folder}/${prefix}`; return { vehicleNorth: `${base}_N`, vehicleEast: `${base}_E`, vehicleSouth: `${base}_S`, vehicleWest: `${base}_W`, }; } const THEME_ENTITY_PRESETS = { default: withPropGround({ playerFront: 'textures/default/player_F', playerBack: 'textures/default/player_B', ...vehicleFourWay('default', 'ship'), prop: 'textures/default/Prop', }), silu: withPropGround({ playerFront: 'textures/silu/skin/待机正面/1', playerBack: 'textures/silu/skin/待机背面/1', ...vehicleFourWay('silu', 'siluShip'), prop: 'textures/silu/Prop_kuai1', }), chinese: withPropGround({ playerFront: 'textures/chinese/chineseShip_F', playerBack: 'textures/chinese/chineseShip_B', ...vehicleFourWay('chinese', 'chineseShip'), prop: 'textures/chinese/Prop_kuai1', }), sanxing: withPropGround({ playerFront: 'textures/sanxing/skin/待机正面/1', playerBack: 'textures/sanxing/skin/待机背面/1', ...vehicleFourWay('sanxing', 'sanxingShip'), prop: 'textures/sanxing/Prop_kuai1', }), snow: withPropGround({ playerFront: 'textures/snow/skin/待机正面/1', playerBack: 'textures/snow/skin/待机背面/1', ...vehicleFourWay('snow', 'snowShip'), prop: 'textures/snow/Prop_kuai1', }), numMan: withPropGround({ playerFront: 'textures/numMan/skin/待机正面/1', playerBack: 'textures/numMan/skin/待机背面/1', ...vehicleFourWay('numMan', 'numManShip'), prop: 'textures/numMan/Prop_kuai11', }), redArmy: withPropGround({ playerFront: 'textures/redArmy/skin/待机正面/1', playerBack: 'textures/redArmy/skin/待机背面/1', ...vehicleFourWay('redArmy', 'redArmyShip'), prop: 'textures/redArmy/Prop_kuai1', }), redarmy: withPropGround({ playerFront: 'textures/redArmy/skin/待机正面/1', playerBack: 'textures/redArmy/skin/待机背面/1', ...vehicleFourWay('redArmy', 'redArmyShip'), prop: 'textures/redArmy/Prop_kuai1', }), }; const ENTITY_TEXTURE_FIELDS = [ { key: 'playerFront', label: '角色正面' }, { key: 'playerBack', label: '角色背面' }, { key: 'vehicleNorth', label: '载具北' }, { key: 'vehicleEast', label: '载具东' }, { key: 'vehicleSouth', label: '载具南' }, { key: 'vehicleWest', label: '载具西' }, { key: 'prop', label: '可拾取物(砖块 Prop)' }, { key: 'propGround', label: '可拾取物(空地 nProp)' }, ]; function normalizeTexturePath(raw) { if (!raw) return ''; let p = String(raw).trim().replace(/\\/g, '/'); if (p.startsWith('assets/resources/')) p = p.slice('assets/resources/'.length); if (p.startsWith('resources/')) p = p.slice('resources/'.length); if (p.startsWith('/')) p = p.slice(1); if (p.endsWith('.png')) p = p.slice(0, -4); return p; } function ensureEntityTextures(state) { if (!state.config) return null; if (!state.config.entityTextures || typeof state.config.entityTextures !== 'object') { state.config.entityTextures = {}; } return state.config.entityTextures; } function presetForTheme(theme) { return THEME_ENTITY_PRESETS[theme] || THEME_ENTITY_PRESETS.silu; } function applyThemePreset(state, theme) { const et = ensureEntityTextures(state); if (!et) return false; const preset = presetForTheme(theme || state.theme || 'silu'); Object.assign(et, { ...preset }); return true; } function readEntityTexturesFromPanel(listEl) { const out = {}; for (const f of ENTITY_TEXTURE_FIELDS) { const el = listEl?.querySelector(`#entity-tex-${f.key}`); const v = normalizeTexturePath(el?.value || ''); if (v) out[f.key] = v; } return out; } function writeEntityTexturesToPanel(listEl, entityTextures) { const et = entityTextures || {}; for (const f of ENTITY_TEXTURE_FIELDS) { const el = listEl?.querySelector(`#entity-tex-${f.key}`); if (el) el.value = et[f.key] || ''; } } function pruneEmptyEntityTextures(state) { const et = state.config?.entityTextures; if (!et) return; let hasAny = false; for (const f of ENTITY_TEXTURE_FIELDS) { const v = normalizeTexturePath(et[f.key]); if (v) { et[f.key] = v; hasAny = true; } else { delete et[f.key]; } } if (!hasAny) delete state.config.entityTextures; } module.exports = { THEME_ENTITY_PRESETS, ENTITY_TEXTURE_FIELDS, normalizeTexturePath, ensureEntityTextures, presetForTheme, applyThemePreset, readEntityTexturesFromPanel, writeEntityTexturesToPanel, pruneEmptyEntityTextures, };