editor_mappanel_wrapper = function (editor) { // 暂时先 注释+分类 内部函数未完成重构 /** * 在绘图区格子内画一个随机色块 */ editor.uifunctions.fillPos = function (pos) { editor.dom.euiCtx.fillStyle = '#' + ~~(Math.random() * 8) + ~~(Math.random() * 8) + ~~(Math.random() * 8); var grid = _getGridByPos({ x: pos.x, y: pos.y }); editor.dom.euiCtx.fillRect(grid.x + grid.size * 3 / 8, grid.y + grid.size * 3 / 8, grid.size / 4, grid.size / 4); } /** * 从鼠标点击返回可用的组件内坐标 */ editor.uifunctions.eToLoc = function (e) { var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft var scrollTop = document.documentElement.scrollTop || document.body.scrollTop var xx = e.clientX, yy = e.clientY if (editor.isMobile) { xx = e.touches[0].clientX, yy = e.touches[0].clientY } editor.loc = { 'x': scrollLeft + xx - editor.dom.mid.offsetLeft - editor.dom.mapEdit.offsetLeft, 'y': scrollTop + yy - editor.dom.mid.offsetTop - editor.dom.mapEdit.offsetTop, 'size': editor.isMobile ? (32 * innerWidth * 0.96 / core.__PIXELS__) : 32 }; return editor.loc; } /** * 组件内坐标转地图位置 * @param {Boolean} addViewportOffset 是否加上大地图的偏置 */ editor.uifunctions.locToPos = function (loc, addViewportOffset) { if (editor.uivalues.bigmap) { var info = editor.uivalues.bigmapInfo; var size = loc.size / 32 * info.size; return { x: core.clamp(Math.floor((loc.x - info.left) / size), 0, editor.currentFloorData.width - 1), y: core.clamp(Math.floor((loc.y - info.top) / size), 0, editor.currentFloorData.height - 1), } } var offsetX = 0, offsetY = 0; if (addViewportOffset) { offsetX = core.bigmap.offsetX / 32; offsetY = core.bigmap.offsetY / 32; } return { 'x': ~~(loc.x / loc.size) + offsetX, 'y': ~~(loc.y / loc.size) + offsetY } } /** * editor.dom.eui.ondblclick * 双击地图可以选中素材 */ editor.uifunctions.map_doubleClick = function (e) { if (editor.uivalues.bindSpecialDoor.loc != null) return; var loc = editor.uifunctions.eToLoc(e); var pos = editor.uifunctions.locToPos(loc, true); editor.setSelectBoxFromInfo(editor[editor.layerMod][pos.y][pos.x], true); return; } /** * 用于鼠标移出map后清除状态 */ editor.uifunctions.clearMapStepStatus = function () { if (editor.uivalues.mouseOutCheck > 1) { editor.uivalues.mouseOutCheck--; setTimeout(editor.uifunctions.clearMapStepStatus, 1000); return; } editor.uivalues.holdingPath = 0; editor.uivalues.stepPostfix = []; editor.dom.euiCtx.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__); editor.uivalues.startPos = editor.uivalues.endPos = null; } /** * editor.dom.eui.onmousedown * + 绑定机关门事件的选择怪物 * + 右键进入菜单 * + 非绘图时选中 * + 绘图时画个矩形在那个位置 */ editor.uifunctions.map_ondown = function (e) { editor.uivalues.selectedArea = null; editor.uivalues.lastMoveE = e; var loc = editor.uifunctions.eToLoc(e); var pos = editor.uifunctions.locToPos(loc, true); editor.pos = pos; if (editor.uivalues.bindSpecialDoor.loc != null) { var x = pos.x, y = pos.y, id = (editor.map[y][x] || {}).id; // 检测是否是怪物 if (id && editor.game.getEnemy(id)) { var locstr = x + "," + y, index = editor.uivalues.bindSpecialDoor.enemys.indexOf(locstr); if (index >= 0) editor.uivalues.bindSpecialDoor.enemys.splice(index, 1); else editor.uivalues.bindSpecialDoor.enemys.push(locstr); editor.drawEventBlock(); editor.uifunctions._extraEvent_bindSpecialDoor_doAction(); } return false; } // if (e.buttons == 2) { // 挪到onup // editor.uifunctions.showMidMenu(e.clientX, e.clientY); // return false; // } if (!selectBox.isSelected()) { editor_mode.onmode('nextChange'); editor_mode.onmode('loc'); //editor_mode.loc(); editor.uifunctions.showTips(6); editor.uivalues.startPos = pos; editor.dom.euiCtx.strokeStyle = '#FF0000'; editor.dom.euiCtx.lineWidth = 2; if (editor.isMobile) editor.uifunctions.showMidMenu(e.clientX, e.clientY); return false; } editor.uivalues.holdingPath = 1; editor.uivalues.mouseOutCheck = 2; setTimeout(editor.uifunctions.clearMapStepStatus); editor.dom.euiCtx.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__); editor.uivalues.stepPostfix = []; editor.uivalues.stepPostfix.push(pos); if (editor.brushMod == 'line') editor.uifunctions.fillPos(pos); return false; } var _getGridByPos = function (pos) { if (editor.uivalues.bigmap) { var info = editor.uivalues.bigmapInfo; return { x: info.left + info.size * pos.x, y: info.top + info.size * pos.y, size: info.size }; } else { return { x: 32 * pos.x - core.bigmap.offsetX, y: 32 * pos.y - core.bigmap.offsetY, size: 32 }; } } var _setMarksHightlight = function (marks, index) { for (var i = 0; i < marks.length; ++i) { if (marks[i].classList.contains('highlight')) { if (i == index) index = null; else marks[i].classList.remove('highlight'); } } if (index != null) { marks[index].classList.add('highlight'); } } /** * editor.dom.eui.onmousemove * + 非绘图模式时维护起止位置并画箭头 * + 绘图模式时找到与队列尾相邻的鼠标方向的点画个矩形 */ editor.uifunctions.map_onmove = function (e) { editor.uivalues.lastMoveE = e; if (!editor.uivalues.bigmap && !editor.isMobile && editor.dom.midMenu.style.display == 'none') { var loc = editor.uifunctions.eToLoc(e); var pos = editor.uifunctions.locToPos(loc); _setMarksHightlight(Array.from(editor.dom.mapColMark.children[0].rows[0].cells), pos.x); _setMarksHightlight(Array.from(editor.dom.mapRowMark.children[0].rows).map(function (tr) { return tr.cells[0]; }), pos.y); } if (!selectBox.isSelected()) { if (editor.uivalues.startPos == null) return; var loc = editor.uifunctions.eToLoc(e); var pos = editor.uifunctions.locToPos(loc, true); if (editor.uivalues.endPos != null && editor.uivalues.endPos.x == pos.x && editor.uivalues.endPos.y == pos.y) return; var startGrid = _getGridByPos(editor.uivalues.startPos), endGrid; if (editor.uivalues.endPos != null) { endGrid = _getGridByPos(editor.uivalues.endPos); editor.dom.euiCtx.clearRect(Math.min(startGrid.x, endGrid.x), Math.min(startGrid.y, endGrid.y), (Math.abs(editor.uivalues.startPos.x - editor.uivalues.endPos.x) + 1) * startGrid.size, (Math.abs(editor.uivalues.startPos.y - editor.uivalues.endPos.y) + 1) * startGrid.size); } editor.uivalues.endPos = pos; endGrid = _getGridByPos(editor.uivalues.endPos); if (editor.uivalues.startPos != null) { if (editor.uivalues.startPos.x != editor.uivalues.endPos.x || editor.uivalues.startPos.y != editor.uivalues.endPos.y) { if (e.buttons == 2) { // 右键拖拽: 画选的区域 var x0 = editor.uivalues.startPos.x; var y0 = editor.uivalues.startPos.y; var x1 = editor.uivalues.endPos.x; var y1 = editor.uivalues.endPos.y; if (x0 > x1) { x0 ^= x1; x1 ^= x0; x0 ^= x1; }//swap if (y0 > y1) { y0 ^= y1; y1 ^= y0; y0 ^= y1; }//swap // draw rect editor.dom.euiCtx.clearRect(0, 0, editor.dom.euiCtx.canvas.width, editor.dom.euiCtx.canvas.height); editor.dom.euiCtx.fillStyle = 'rgba(0, 127, 255, 0.4)'; var grid = _getGridByPos({ x: x0, y: y0 }); editor.dom.euiCtx.fillRect(grid.x, grid.y, grid.size * (x1 - x0 + 1), grid.size * (y1 - y0 + 1)); } else { // 左键拖拽: 画箭头 core.drawArrow('eui', startGrid.x + startGrid.size / 2, startGrid.y + startGrid.size / 2, endGrid.x + endGrid.size / 2, endGrid.y + endGrid.size / 2); } } } // editor_mode.onmode('nextChange'); // editor_mode.onmode('loc'); //editor_mode.loc(); return false; } if (editor.uivalues.holdingPath == 0) { return false; } editor.uivalues.mouseOutCheck = 2; var loc = editor.uifunctions.eToLoc(e); var pos = editor.uifunctions.locToPos(loc, true); var pos0 = editor.uivalues.stepPostfix[editor.uivalues.stepPostfix.length - 1] var directionDistance = [pos.y - pos0.y, pos0.x - pos.x, pos0.y - pos.y, pos.x - pos0.x] var max = 0, index = 4; for (var i = 0; i < 4; i++) { if (directionDistance[i] > max) { index = i; max = directionDistance[i]; } } var pos = [{ 'x': 0, 'y': 1 }, { 'x': -1, 'y': 0 }, { 'x': 0, 'y': -1 }, { 'x': 1, 'y': 0 }, false][index] if (pos) { pos.x += pos0.x; pos.y += pos0.y; if (editor.brushMod == 'line') editor.uifunctions.fillPos(pos); else { var x0 = editor.uivalues.stepPostfix[0].x; var y0 = editor.uivalues.stepPostfix[0].y; var x1 = pos.x; var y1 = pos.y; if (x0 > x1) { x0 ^= x1; x1 ^= x0; x0 ^= x1; }//swap if (y0 > y1) { y0 ^= y1; y1 ^= y0; y0 ^= y1; }//swap // draw rect editor.dom.euiCtx.clearRect(0, 0, editor.dom.euiCtx.canvas.width, editor.dom.euiCtx.canvas.height); editor.dom.euiCtx.fillStyle = 'rgba(0, 127, 255, 0.4)'; var grid = _getGridByPos({ x: x0, y: y0 }); editor.dom.euiCtx.fillRect(grid.x, grid.y, grid.size * (x1 - x0 + 1), grid.size * (y1 - y0 + 1)); } editor.uivalues.stepPostfix.push(pos); } return false; } editor.uifunctions.map_onmoveout = function () { if (!editor.uivalues.bigmap && !editor.isMobile) { _setMarksHightlight(Array.from(editor.dom.mapColMark.children[0].rows[0].cells)); _setMarksHightlight(Array.from(editor.dom.mapRowMark.children[0].rows).map(function (tr) { return tr.cells[0]; })); } } /** * editor.dom.eui.onmouseup * + 非绘图模式时, 交换首末点的内容 * + 绘图模式时, 根据画线/画矩形/画tileset 做对应的绘制 */ editor.uifunctions.map_onup = function (ee) { editor.uivalues.selectedArea = null; ee.preventDefault(); ee.stopPropagation(); var e = editor.uivalues.lastMoveE; if (e.buttons == 2 && (editor.uivalues.endPos == null || (editor.uivalues.startPos.x == editor.uivalues.endPos.x && editor.uivalues.startPos.y == editor.uivalues.endPos.y))) { editor.uifunctions.showMidMenu(e.clientX, e.clientY); editor.uivalues.holdingPath = 0; editor.uivalues.stepPostfix = []; editor.dom.euiCtx.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__); editor.uivalues.startPos = editor.uivalues.endPos = null; return false; } if (!selectBox.isSelected()) { if (e.buttons == 2) { // 右键拖拽: 选中区域 printf('已经选中该区域') editor.uivalues.selectedArea = Object.assign({}, editor.uivalues.startPos, { x1: editor.uivalues.endPos.x, y1: editor.uivalues.endPos.y }); // 后续的处理 } else { // 左键拖拽: 交换 editor.savePreMap(); // editor.movePos(editor.uivalues.startPos, editor.uivalues.endPos); editor.exchangePos(editor.uivalues.startPos, editor.uivalues.endPos); editor.uifunctions.unhighlightSaveFloorButton(); editor.dom.euiCtx.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__); } editor.uivalues.startPos = editor.uivalues.endPos = null; return false; } editor.uivalues.holdingPath = 0; if (editor.uivalues.stepPostfix && editor.uivalues.stepPostfix.length) { editor.savePreMap(); if (editor.brushMod !== 'line') { var x0 = editor.uivalues.stepPostfix[0].x; var y0 = editor.uivalues.stepPostfix[0].y; var x1 = editor.uivalues.stepPostfix[editor.uivalues.stepPostfix.length - 1].x; var y1 = editor.uivalues.stepPostfix[editor.uivalues.stepPostfix.length - 1].y; if (x0 > x1) { x0 ^= x1; x1 ^= x0; x0 ^= x1; }//swap if (y0 > y1) { y0 ^= y1; y1 ^= y0; y0 ^= y1; }//swap editor.uivalues.stepPostfix = []; for (var jj = y0; jj <= y1; jj++) { for (var ii = x0; ii <= x1; ii++) { editor.uivalues.stepPostfix.push({ x: ii, y: jj }) } } } var useBrushMode = editor.brushMod == 'tileset'; if (editor.uivalues.stepPostfix.length == 1 && (editor.uivalues.tileSize[0] > 1 || editor.uivalues.tileSize[1] > 1)) { useBrushMode = true; var x0 = editor.uivalues.stepPostfix[0].x; var y0 = editor.uivalues.stepPostfix[0].y; editor.uivalues.stepPostfix = []; for (var jj = y0; jj < y0 + editor.uivalues.tileSize[1]; ++jj) { for (var ii = x0; ii < x0 + editor.uivalues.tileSize[0]; ++ii) { if (jj >= editor[editor.layerMod].length || ii >= editor[editor.layerMod][0].length) continue; editor.uivalues.stepPostfix.push({ x: ii, y: jj }); } } } if (useBrushMode && core.tilesets.indexOf(editor.info.images) !== -1) { var imgWidth = ~~(core.material.images.tilesets[editor.info.images].width / 32); var x0 = editor.uivalues.stepPostfix[0].x; var y0 = editor.uivalues.stepPostfix[0].y; var idnum = editor.info.idnum; var pmod = function (a, b) { return (a % b + b) % b; } for (var ii = 0; ii < editor.uivalues.stepPostfix.length; ii++) { var dx = pmod(editor.uivalues.stepPostfix[ii].x - x0, editor.uivalues.tileSize[0]); var dy = pmod(editor.uivalues.stepPostfix[ii].y - y0, editor.uivalues.tileSize[1]); editor[editor.layerMod][editor.uivalues.stepPostfix[ii].y][editor.uivalues.stepPostfix[ii].x] = editor.ids[editor.indexs[idnum + dx + dy * imgWidth]]; } } else { // 检测是否是填充模式 if (editor.uivalues.stepPostfix.length == 1 && editor.brushMod == 'fill') { editor.uivalues.stepPostfix = editor.uifunctions._fillMode_bfs(editor[editor.layerMod], editor.uivalues.stepPostfix[0].x, editor.uivalues.stepPostfix[0].y, editor[editor.layerMod][0].length, editor[editor.layerMod].length); } for (var ii = 0; ii < editor.uivalues.stepPostfix.length; ii++) { var currx = editor.uivalues.stepPostfix[ii].x, curry = editor.uivalues.stepPostfix[ii].y; editor[editor.layerMod][curry][currx] = editor.info; // 检查上下楼梯绑定 if (editor.layerMod == 'map' && editor.info && editor.info.id == 'upFloor') { editor.currentFloorData.changeFloor[currx + "," + curry] = { "floorId": ":next", "stair": "downFloor" }; editor.drawEventBlock(); } if (editor.layerMod == 'map' && editor.info && editor.info.id == 'downFloor') { editor.currentFloorData.changeFloor[currx + "," + curry] = { "floorId": ":before", "stair": "upFloor" }; editor.drawEventBlock(); } } } // console.log(editor.map); if (editor.info.y != null) { var found = false; editor.uivalues.lastUsed.forEach(function (one) { if (one.id == editor.info.id) { found = true; one.recent = new Date().getTime(); one.frequent = (one.frequent || 0) + 1; } }) if (!found) { editor.uivalues.lastUsed.push(Object.assign({}, editor.info, { recent: new Date().getTime(), frequent: 1 })); } editor.config.set("lastUsed", editor.uivalues.lastUsed); } editor.updateMap(); editor.uivalues.holdingPath = 0; editor.uivalues.stepPostfix = []; editor.dom.euiCtx.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__); editor.uifunctions.highlightSaveFloorButton(); } return false; } /** * bfs找寻和某点相连的全部相同图块坐标 */ editor.uifunctions._fillMode_bfs = function (array, x, y, maxWidth, maxHeight) { var _getNumber = function (x, y) { if (x < 0 || y < 0 || x >= maxWidth || y >= maxHeight) return null; return array[y][x].idnum || array[y][x] || 0; } var number = _getNumber(x, y) || 0; var visited = {}, result = []; var list = [{ x: x, y: y }]; while (list.length != 0) { var next = list.shift(), key = next.x + "," + next.y; if (visited[key]) continue; visited[key] = true; result.push(next); [[-1, 0], [1, 0], [0, -1], [0, 1]].forEach(function (dir) { var nx = next.x + dir[0], ny = next.y + dir[1]; if (_getNumber(nx, ny) == number) { list.push({ x: nx, y: ny }); } }); } return result; } /** * editor.dom.mid.onmousewheel * 在地图编辑区域滚轮切换楼层 */ editor.uifunctions.map_mousewheel = function (e) { var wheel = function (direct) { var index = editor.core.floorIds.indexOf(editor.currentFloorId); var toId = editor.currentFloorId; var saveFloor = document.getElementById('saveFloor'); if (saveFloor && saveFloor.classList.contains('highlight')) { return; } if (direct > 0 && index < editor.core.floorIds.length - 1) toId = editor.core.floorIds[index + 1]; else if (direct < 0 && index > 0) toId = editor.core.floorIds[index - 1]; else return; editor_mode.onmode('nextChange'); editor_mode.onmode('floor'); editor.dom.selectFloor.value = toId; editor.uivalues.recentFloors.push(editor.currentFloorId); editor.changeFloor(toId); } try { if (e.wheelDelta) wheel(Math.sign(e.wheelDelta)) else if (e.detail) wheel(Math.sign(e.detail)); } catch (e) { console.error(e); } return false; } editor.uifunctions.undoFloor_click = function () { var saveFloor = document.getElementById('saveFloor'); if (saveFloor && saveFloor.classList.contains('highlight')) { return; } var toId = editor.uivalues.recentFloors.pop(); if (toId == null || toId == editor.currentFloorId) return; editor_mode.onmode('nextChange'); editor_mode.onmode('floor'); editor.dom.selectFloor.value = toId; editor.changeFloor(toId); } editor.uifunctions.selectFloorBtn_click = function () { editor.uievent.selectFloor(null, '选择楼层', function (floorId) { if (!floorId || floorId == editor.currentFloorId) return; var saveFloor = document.getElementById('saveFloor'); if (saveFloor && saveFloor.classList.contains('highlight')) { printe('请先保存地图!'); return; } editor_mode.onmode('nextChange'); editor_mode.onmode('floor'); editor.dom.selectFloor.value = floorId; editor.changeFloor(floorId); }) } editor.uifunctions.editorTheme_onchange = function () { var theme = editor.dom.editorTheme.value; editor.config.set('theme', theme); document.getElementById('color_css').href = '_server/css/' + theme + '.css'; } /** * 显示右键菜单 */ editor.uifunctions.showMidMenu = function (x, y) { // --- copy var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft; var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; // 检测是否是上下楼 var thisevent = editor.map[editor.pos.y][editor.pos.x]; var extraEvent = editor.dom.extraEvent, parent = extraEvent.parentElement; if (thisevent == 0) { parent.removeChild(extraEvent); parent.appendChild(extraEvent); editor.dom.extraEvent.style.display = 'block'; editor.dom.extraEvent.children[0].innerHTML = '绑定出生点为此点'; } else if (editor.currentFloorData.changeFloor[editor.pos.x + "," + editor.pos.y]) { parent.removeChild(extraEvent); parent.insertBefore(extraEvent, parent.firstChild); editor.dom.extraEvent.style.display = 'block'; editor.dom.extraEvent.children[0].innerHTML = '跳转到目标传送点'; } else if (thisevent.id == 'upFloor') { parent.removeChild(extraEvent); parent.insertBefore(extraEvent, parent.firstChild); editor.dom.extraEvent.style.display = 'block'; editor.dom.extraEvent.children[0].innerHTML = '绑定上楼事件'; } else if (thisevent.id == 'downFloor') { parent.removeChild(extraEvent); parent.insertBefore(extraEvent, parent.firstChild); editor.dom.extraEvent.style.display = 'block'; editor.dom.extraEvent.children[0].innerHTML = '绑定下楼事件'; } else if (['leftPortal', 'rightPortal', 'downPortal', 'upPortal'].indexOf(thisevent.id) >= 0) { parent.removeChild(extraEvent); parent.insertBefore(extraEvent, parent.firstChild); editor.dom.extraEvent.style.display = 'block'; editor.dom.extraEvent.children[0].innerHTML = '绑定楼传事件'; } else if (thisevent.id == 'specialDoor') { parent.removeChild(extraEvent); parent.insertBefore(extraEvent, parent.firstChild); editor.dom.extraEvent.style.display = 'block'; editor.dom.extraEvent.children[0].innerHTML = '绑定机关门事件'; } else editor.dom.extraEvent.style.display = 'none'; editor.dom.chooseThis.children[0].innerHTML = '选中此点' + '(' + editor.pos.x + ',' + editor.pos.y + ')' editor.dom.copyLoc.children[0].innerHTML = '复制此事件'; editor.dom.pasteLoc.children[0].innerHTML = '粘贴到此事件'; editor.dom.midMenu.style = 'top:' + (y + scrollTop) + 'px;left:' + (x + scrollLeft) + 'px;'; } /** * 隐藏右键菜单 */ editor.uifunctions.hideMidMenu = function () { editor.uivalues.lastMoveE = { buttons: 0, clientX: 0, clientY: 0 }; editor.dom.midMenu.style = 'display:none'; } /** * editor.dom.extraEvent.onmousedown * 菜单 附加点操作 */ editor.uifunctions.extraEvent_click = function (e) { editor.uifunctions.hideMidMenu(); e.stopPropagation(); var thisevent = editor.map[editor.pos.y][editor.pos.x]; return editor.uifunctions._extraEvent_bindStartPoint(thisevent) || editor.uifunctions._extraEvent_changeFloor() || editor.uifunctions._extraEvent_bindStair(thisevent) || editor.uifunctions._extraEvent_bindSpecialDoor(thisevent); } /** * 绑定该空地点为起始点 */ editor.uifunctions._extraEvent_bindStartPoint = function (thisevent) { if (thisevent != 0) return false; if (!confirm('再次确认,你想绑定此点为出生点吗?')) return false; editor.mode.onmode('tower'); editor.mode.addAction(["change", "['firstData']['floorId']", editor.currentFloorId]); editor.mode.addAction(["change", "['firstData']['hero']['loc']['x']", editor.pos.x]); editor.mode.addAction(["change", "['firstData']['hero']['loc']['y']", editor.pos.y]); editor.mode.onmode('save', function () { core.firstData.floorId = editor.currentFloorId; core.firstData.hero.loc.x = editor.pos.x; core.firstData.hero.loc.y = editor.pos.y; editor.drawPosSelection(); editor.drawEventBlock(); editor.mode.tower(); printf('绑定初始点成功'); }); } editor.uifunctions._extraEvent_changeFloor = function () { var changeFloor = editor.currentFloorData.changeFloor[editor.pos.x + "," + editor.pos.y]; if (!changeFloor) return false; core.status.hero.loc = { x: editor.pos.x, y: editor.pos.y, direction: "up" }; var targetLoc = changeFloor.loc ? { x: changeFloor.loc[0], y: changeFloor.loc[1] } : null; var info = core.events._changeFloor_getInfo(changeFloor.floorId, changeFloor.stair, targetLoc); editor_mode.onmode('nextChange'); editor_mode.onmode('floor'); editor.dom.selectFloor.value = info.floorId; editor.uivalues.recentFloors.push(editor.currentFloorId); editor.changeFloor(info.floorId, function () { editor.pos.x = info.heroLoc.x; editor.pos.y = info.heroLoc.y; editor.setViewport(32 * (editor.pos.x - core.__HALF_SIZE__), 32 * (editor.pos.y - core.__HALF_SIZE__)); editor.drawPosSelection(); }); return true; } /** * 绑定该楼梯的楼传事件 */ editor.uifunctions._extraEvent_bindStair = function (thisevent) { if (['upFloor', 'downFloor', 'leftPortal', 'rightPortal', 'upPortal', 'downPortal'].indexOf(thisevent.id) < 0) return false; var loc = editor.pos.x + "," + editor.pos.y; if (thisevent.id == 'upFloor') { editor.currentFloorData.changeFloor[loc] = { "floorId": ":next", "stair": "downFloor" }; } else if (thisevent.id == 'downFloor') { editor.currentFloorData.changeFloor[loc] = { "floorId": ":before", "stair": "upFloor" }; } else if (thisevent.id == 'leftPortal' || thisevent.id == 'rightPortal') { editor.currentFloorData.changeFloor[loc] = { "floorId": ":next", "stair": ":symmetry_x" } } else if (thisevent.id == 'upPortal' || thisevent.id == 'downPortal') { editor.currentFloorData.changeFloor[loc] = { "floorId": ":next", "stair": ":symmetry_y" } } editor.file.saveFloorFile(function (err) { if (err) { printe(err); throw (err) } editor.drawPosSelection(); editor.drawEventBlock(); editor_mode.showMode('loc'); printf('添加楼梯事件成功'); editor.uifunctions.unhighlightSaveFloorButton(); }); return true; } /** * 绑定该机关门的事件 */ editor.uifunctions._extraEvent_bindSpecialDoor = function (thisevent) { if (thisevent.id != 'specialDoor') return false; var number = parseInt(prompt("请输入该机关门的怪物数量", "0")) || 0; if (number <= 0) return true; editor.uivalues.bindSpecialDoor.n = number; editor.uivalues.bindSpecialDoor.loc = editor.pos.x + ',' + editor.pos.y; editor.uivalues.bindSpecialDoor.enemys = []; printf("请点击选择" + number + "个怪物;切换楼层或刷新页面取消操作。"); } /** * 确定绑定该机关门的事件 * cancel:是否取消此模式 */ editor.uifunctions._extraEvent_bindSpecialDoor_doAction = function (cancel) { var bindSpecialDoor = editor.uivalues.bindSpecialDoor; if (cancel) { bindSpecialDoor.loc = null; bindSpecialDoor.enemys = []; bindSpecialDoor.n = 0; editor.drawEventBlock(); printf(""); return; } if (bindSpecialDoor.loc == null || bindSpecialDoor.enemys.length != bindSpecialDoor.n) return; // 添加机关门自动事件 var doorFlag = "flag:door_" + editor.currentFloorId + "_" + bindSpecialDoor.loc.replace(',', '_'); editor.currentFloorData.autoEvent[bindSpecialDoor.loc] = { '0': { "condition": doorFlag + "==" + bindSpecialDoor.n, "currentFloor": true, "priority": 0, "delayExecute": false, "multiExecute": false, "data": [ { "type": "openDoor" }, { "type": "setValue", "name": doorFlag, "operator": "=", "value": "null" }, ] } }; bindSpecialDoor.enemys.forEach(function (loc) { if (!editor.currentFloorData.afterBattle[loc]) editor.currentFloorData.afterBattle[loc] = []; editor.currentFloorData.afterBattle[loc].push({ "type": "setValue", "name": doorFlag, "operator": "+=", "value": "1" }); }); editor.file.saveFloorFile(function (err) { if (err) { printe(err); throw (err) } editor.drawEventBlock(); editor.drawPosSelection(); editor_mode.showMode('loc'); printf('绑定机关门事件成功'); editor.uifunctions.unhighlightSaveFloorButton(); }); bindSpecialDoor.loc = null; bindSpecialDoor.enemys = []; bindSpecialDoor.n = 0; } /** * editor.dom.chooseThis.onmousedown * 菜单 选中此点 */ editor.uifunctions.chooseThis_click = function (e) { editor.uifunctions.hideMidMenu(); e.stopPropagation(); e.stopImmediatePropagation(); e.preventDefault(); selectBox.isSelected(false); editor_mode.onmode('nextChange'); editor_mode.onmode('loc'); //editor_mode.loc(); if (editor.isMobile) editor.showdataarea(false); return false; } /** * editor.dom.chooseInRight.onmousedown * 菜单 在素材区选中此图块 */ editor.uifunctions.chooseInRight_click = function (e) { editor.uifunctions.hideMidMenu(); e.stopPropagation(); e.stopImmediatePropagation(); e.preventDefault(); var thisevent = editor[editor.layerMod][editor.pos.y][editor.pos.x]; editor.setSelectBoxFromInfo(thisevent, true); return false; } /** * editor.dom.copyLoc.onmousedown * 菜单 复制此事件 */ editor.uifunctions.copyLoc_click = function (e) { editor.uifunctions.hideMidMenu(); e.stopPropagation(); e.stopImmediatePropagation(); e.preventDefault(); editor_mode.onmode(''); editor.uivalues.copyedInfo = editor.copyFromPos(); printf('该点事件已复制'); return false; } /** * editor.dom.pasteLoc.onmousedown * 菜单 移动此事件 */ editor.uifunctions.pasteLoc_click = function (e) { editor.uifunctions.hideMidMenu(); e.stopPropagation(); e.stopImmediatePropagation(); e.preventDefault(); if (!editor.uivalues.copyedInfo) { printe("没有复制的事件"); return false; } editor.savePreMap(); editor_mode.onmode(''); editor.pasteToPos(editor.uivalues.copyedInfo); editor.updateMap(); editor.file.saveFloorFile(function (err) { if (err) { printe(err); throw (err) } ; printf('粘贴到事件成功'); editor.uifunctions.unhighlightSaveFloorButton(); editor.drawPosSelection(); }); return false; } /** * editor.dom.clearEvent.onmousedown * 菜单 仅清空此点事件 */ editor.uifunctions.clearEvent_click = function (e) { e.stopPropagation(); e.stopImmediatePropagation(); e.preventDefault(); editor.clearPos(false); editor.uifunctions.unhighlightSaveFloorButton(); return false; } /** * editor.dom.clearLoc.onmousedown * 菜单 清空此点及事件 */ editor.uifunctions.clearLoc_click = function (e) { e.stopPropagation(); e.stopImmediatePropagation(); e.preventDefault(); editor.clearPos(true); editor.uifunctions.unhighlightSaveFloorButton(); return false; } /** * editor.dom.showMovable.onchange * 点击【】 */ editor.uifunctions.showMovable_onchange = function () { printf('此模式下将显示每个点的不可通行状态。
请注意,修改了图块属性的不可出入方向后需要刷新才会正确显示在地图上。'); editor.uivalues.showMovable = editor.dom.showMovable.checked; editor.drawEventBlock(); } /** * editor.dom.brushMod.onchange * 切换画笔模式 */ editor.uifunctions.brushMod_onchange = function () { editor.brushMod = editor.dom.brushMod.value; if (editor.brushMod == 'fill') { printf('填充模式下,将会用选中的素材替换所有和目标点联通的相同素材'); } } /** * editor.dom.brushMod2.onchange * 切换画笔模式 */ editor.uifunctions.brushMod2_onchange = function () { editor.brushMod = editor.dom.brushMod2.value; } /** * editor.dom.brushMod3.onchange * 切换画笔模式 */ editor.uifunctions.brushMod3_onchange = function () { if (!editor.config.get('alertTileModeV2.7') && !confirm("从V2.7开始,请直接素材区拖框进行绘制区域。\n\n点取消将不再显示此提示。")) { editor.config.set('alertTileModeV2.7', true); } printf('tileset平铺模式下可以按选中tileset素材,并在地图上拖动来一次绘制一个区域'); editor.brushMod = editor.dom.brushMod3.value; } editor.uifunctions.brushMod4_onchange = function () { printf('填充模式下,将会用选中的素材替换所有和目标点联通的相同素材'); editor.brushMod = editor.dom.brushMod4.value; } editor.uifunctions.setLayerMod = function (layer) { editor.layerMod = layer; var canvas = ['ev', 'ev2'].concat(editor.dom.canvas); canvas.forEach(function (one) { editor.dom[one + 'c'].style.opacity = 1; }); if (layer != 'map') { canvas.filter(function (one) { return one + 'map' != editor.layerMod }).forEach(function (one) { editor.dom[one + 'c'].style.opacity = 0.3; }); } } /** * editor.dom.layerMod.onchange * 切换编辑的层 */ editor.uifunctions.layerMod_onchange = function () { editor.uifunctions.setLayerMod(editor.dom.layerMod.value); } /** * editor.dom.layerMod2.onchange * 切换编辑的层 */ editor.uifunctions.layerMod2_onchange = function () { editor.uifunctions.setLayerMod('bgmap'); } /** * editor.dom.layerMod3.onchange * 切换编辑的层 */ editor.uifunctions.layerMod3_onchange = function () { editor.uifunctions.setLayerMod('fgmap'); } editor.uifunctions.triggerBigmap = function () { editor.uivalues.bigmap = !editor.uivalues.bigmap; if (editor.uivalues.bigmap) { editor.dom.bigmapBtn.classList.add('highlight'); printf("已进入大地图模式"); } else { editor.dom.bigmapBtn.classList.remove('highlight'); editor.setViewport(32 * (editor.pos.x - core.__HALF_SIZE__), 32 * (editor.pos.y - core.__HALF_SIZE__)); printf("已退出大地图模式"); } editor.dom.ebmCtx.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__); editor.uivalues.startPos = editor.uivalues.endPos = null; editor.updateMap(); editor.drawPosSelection(); } /** * 移动大地图可视窗口的绑定 */ editor.uifunctions.viewportButtons_func = function () { var pressTimer = null; for (var ii = 0, node; node = editor.dom.viewportButtons.children[ii]; ii++) { if (ii == 4) { // 大地图 node.onclick = function () { editor.uifunctions.triggerBigmap(); } continue; } (function (x, y) { var move = function () { editor.moveViewport(x, y); } node.onmousedown = function () { clearTimeout(pressTimer); pressTimer = setTimeout(function () { pressTimer = -1; var f = function () { if (pressTimer != null) { move(); setTimeout(f, 150); } } f(); }, 500); }; node.onmouseup = function () { if (pressTimer > 0) { clearTimeout(pressTimer); move(); } pressTimer = null; } })([-1, 0, 0, 1][ii], [0, -1, 1, 0][ii]); } } editor.uifunctions.selectFloor_func = function () { var selectFloor = document.getElementById('selectFloor'); editor.game.getFloorFileList(function (floors) { var outstr = []; floors[0].forEach(function (floor) { outstr.push(["\n'].join('')); }); selectFloor.innerHTML = outstr.join(''); selectFloor.value = core.status.floorId; selectFloor.onchange = function () { editor_mode.onmode('nextChange'); editor_mode.onmode('floor'); editor.uivalues.recentFloors.push(editor.currentFloorId); editor.changeFloor(selectFloor.value); } }); } editor.uifunctions.highlightSaveFloorButton = function () { var saveFloor = document.getElementById('saveFloor'); saveFloor.classList.add('highlight'); } editor.uifunctions.unhighlightSaveFloorButton = function () { var saveFloor = document.getElementById('saveFloor'); saveFloor.classList.remove('highlight'); } editor.uifunctions.saveFloor_func = function () { var saveFloor = document.getElementById('saveFloor'); editor_mode.saveFloor = function () { editor_mode.onmode(''); editor.file.saveFloorFile(function (err) { if (err) { printe(err); throw (err) } ; printf('保存成功'); editor.uifunctions.unhighlightSaveFloorButton() }); } saveFloor.onclick = editor_mode.saveFloor; } editor.uifunctions.openDoc_func = function () { var openDoc = document.getElementById('openDoc'); openDoc.onclick = function () { if (editor.isMobile) { if (!confirm('你确定要打开帮助文档吗?')) return; window.location = '/_docs/'; } else { window.open('/_docs/', '_blank'); } } } editor.uifunctions.lastUsed_click = function (e) { e.preventDefault(); e.stopImmediatePropagation(); e.stopPropagation(); if (editor.isMobile) return false; editor.uivalues.tileSize = [1, 1]; var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft var scrollTop = document.documentElement.scrollTop || document.body.scrollTop var px = scrollLeft + e.clientX - editor.dom.mid2.offsetLeft - editor.dom.lastUsedDiv.offsetLeft + editor.dom.lastUsedDiv.scrollLeft, py = scrollTop + e.clientY - editor.dom.mid2.offsetTop - editor.dom.lastUsedDiv.offsetTop + editor.dom.lastUsedDiv.scrollTop; var x = parseInt(px / 32), y = parseInt(py / 32); if (x == core.__SIZE__ - 1) return false; var index = x + (core.__SIZE__ - 1) * y; if (index >= editor.uivalues.lastUsed.length) return; var lastUsed = editor.uivalues.lastUsed.sort(function (a, b) { if ((a.istop || 0) != (b.istop || 0)) return (b.istop || 0) - (a.istop || 0); return (b[editor.uivalues.lastUsedType] || 0) - (a[editor.uivalues.lastUsedType] || 0); }); if (e.button == 2) { lastUsed[index].istop = lastUsed[index].istop ? 0 : 1; printf("已" + (lastUsed[index].istop ? '置顶' : '取消置顶') + "该图块"); editor.config.set('lastUsed', editor.uivalues.lastUsed); editor.updateLastUsedMap(); return false; } var one = Object.assign({}, lastUsed[index]); delete one['recent']; delete one['frequent']; delete one['istop']; editor.setSelectBoxFromInfo(one); return false; } editor.uifunctions.clearLastUsedBtn_click = function () { if (editor.isMobile) return; if (confirm("你确定要清理全部最近使用图块么?\n所有最近使用和最常使用图块(含置顶图块)都将被清除;此过程不可逆!")) { editor.uivalues.lastUsed = []; editor.config.set('lastUsed', []); editor.updateLastUsedMap(); editor.dom.lastUsedDiv.scroll(0, 0); } } ///////////////////////////////////////////////////////////////////////////// editor.constructor.prototype.copyFromPos = function (pos) { editor.uivalues.tileSize = [1, 1]; var fields = Object.keys(editor.file.comment._data.floors._data.loc._data); pos = pos || editor.pos; var x0 = pos.x, y0 = pos.y, x1 = pos.x1, y1 = pos.y1; if (x1 == null) x1 = x0; if (y1 == null) y1 = y0; if (x0 > x1) { x0 ^= x1; x1 ^= x0; x0 ^= x1; }//swap if (y0 > y1) { y0 ^= y1; y1 ^= y0; y0 ^= y1; }//swap var result = { w: x1 - x0 + 1, h: y1 - y0 + 1, layer: editor.layerMod, data: [] }; for (var i = x0; i <= x1; ++i) { for (var j = y0; j <= y1; ++j) { var map = core.clone(editor[editor.layerMod][j][i]); var events = {}; fields.forEach(function (v) { events[v] = core.clone(editor.currentFloorData[v][i + ',' + j]); }) result.data.push({ map: map, events: events }); } } return result; } editor.constructor.prototype.pasteToPos = function (info, pos) { editor.uivalues.tileSize = [1, 1]; if (info == null) return; var fields = Object.keys(editor.file.comment._data.floors._data.loc._data); pos = pos || editor.pos; var w = info.w || 1, h = info.h || 1, layer = info.layer || 'map'; var data = core.clone(info.data || []); for (var i = pos.x; i < pos.x + w; ++i) { for (var j = pos.y; j < pos.y + h; ++j) { var one = data.shift(); if (j >= editor[editor.layerMod].length || i >= editor[editor.layerMod][0].length) continue; editor[editor.layerMod][j][i] = core.clone(one.map); if (layer == 'map' && editor.layerMod == 'map') { fields.forEach(function (v) { if (one.events[v] == null) delete editor.currentFloorData[v][i + "," + j]; else editor.currentFloorData[v][i + "," + j] = core.clone(one.events[v]); }); } } } } editor.constructor.prototype.movePos = function (startPos, endPos, callback) { editor.uivalues.tileSize = [1, 1]; if (!startPos || !endPos) return; if (startPos.x == endPos.x && startPos.y == endPos.y) return; var copyed = editor.copyFromPos(startPos); editor.pasteToPos({ w: 1, h: 1, layer: 'map', data: [{ map: 0, events: {} }] }, startPos); editor.pasteToPos(copyed, endPos); editor.updateMap(); editor.file.saveFloorFile(function (err) { if (err) { printe(err); throw (err) } ; printf('移动事件成功'); editor.drawPosSelection(); if (callback) callback(); }); } editor.constructor.prototype.exchangePos = function (startPos, endPos, callback) { editor.uivalues.tileSize = [1, 1]; if (!startPos || !endPos) return; if (startPos.x == endPos.x && startPos.y == endPos.y) return; var startInfo = editor.copyFromPos(startPos); var endInfo = editor.copyFromPos(endPos); editor.pasteToPos(startInfo, endPos); editor.pasteToPos(endInfo, startPos); editor.updateMap(); editor.file.saveFloorFile(function (err) { if (err) { printe(err); throw (err) } ; printf('交换事件成功'); editor.drawPosSelection(); if (callback) callback(); }); } editor.constructor.prototype.savePreMap = function () { if (editor.map.length * editor.map[0].length >= 4096) return; var dt = {}; editor.dom.maps.forEach(function (one) { dt[one] = editor[one]; }); if (editor.uivalues.preMapData.length == 0 || !core.same(editor.uivalues.preMapData[editor.uivalues.preMapData.length - 1], dt)) { editor.uivalues.preMapData.push(core.clone(dt)); if (editor.uivalues.preMapData.length > editor.uivalues.preMapMax) { editor.uivalues.preMapData.shift(); } } } editor.constructor.prototype.clearPos = function (clearPos, pos, callback) { var fields = Object.keys(editor.file.comment._data.floors._data.loc._data); pos = pos || editor.pos; var x0 = pos.x, y0 = pos.y, x1 = pos.x1, y1 = pos.y1; if (x1 == null) x1 = x0; if (y1 == null) y1 = y0; if (x0 > x1) { x0 ^= x1; x1 ^= x0; x0 ^= x1; }//swap if (y0 > y1) { y0 ^= y1; y1 ^= y0; y0 ^= y1; }//swap editor.uifunctions.hideMidMenu(); editor.savePreMap(); editor.info = 0; editor_mode.onmode(''); for (var i = x0; i <= x1; ++i) { for (var j = y0; j <= y1; ++j) { if (j >= editor[editor.layerMod].length || i >= editor[editor.layerMod][0].length) continue; if (clearPos) editor[editor.layerMod][j][i] = 0; if (editor.layerMod == 'map') { fields.forEach(function (v) { delete editor.currentFloorData[v][i + "," + j]; }); } } } editor.updateMap(); editor.file.saveFloorFile(function (err) { if (err) { printe(err); throw (err) } ; printf(clearPos ? '清空该点和事件成功' : '只清空该点事件成功'); editor.drawPosSelection(); if (callback) callback(); }); } }