diff --git a/libs/actions.js b/libs/actions.js index 8a5cee2a..c391ecea 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -1284,6 +1284,7 @@ actions.prototype._clickBookDetail = function () { core.status.event.id = 'book'; } +////// 楼层传送器界面/楼传界面时隐藏/显示单个楼层的操作 ////// function _hideFly(floorId) { const hideFloors = core.getFlag('hideFloors', {}); if (hideFloors.hasOwnProperty(floorId)) { @@ -1301,33 +1302,105 @@ function _isFloorHided(floorId) { return !core.hasFlag('noHideFly') && core.getFlag('hideFloors', {}).hasOwnProperty(floorId); } -////// 楼层传送器界面时的点击操作 ////// -actions.prototype._clickFly = function (x, y) { - if ((x == this.SIZE - 2 || x == this.SIZE - 3) && y == this.HSIZE + 3) { core.playSound('光标移动'); core.ui.drawFly(this._getNextFlyFloor(-1)); } - if ((x == this.SIZE - 2 || x == this.SIZE - 3) && y == this.HSIZE - 1) { core.playSound('光标移动'); core.ui.drawFly(this._getNextFlyFloor(1)); } - if ((x == this.SIZE - 2 || x == this.SIZE - 3) && y == this.HSIZE + 4) { core.playSound('光标移动'); core.ui.drawFly(this._getNextFlyFloor(-10)); } - if ((x == this.SIZE - 2 || x == this.SIZE - 3) && y == this.HSIZE - 2) { core.playSound('光标移动'); core.ui.drawFly(this._getNextFlyFloor(10)); } - if (x >= this.HSIZE - 1 && x <= this.HSIZE + 1 && y == this.LAST) { core.playSound('取消'); core.ui.closePanel(); } +////// 楼层传送器界面/楼传界面时的点击操作 ////// +actions.prototype._clickFly = function (x, y, px, py) { + if ((x == this.SIZE - 2 || x == this.SIZE - 3) && y == this.HSIZE + 3) { + core.playSound('光标移动'); + core.ui.drawFly(this._getNextFlyFloor(-1)); + } + if ((x == this.SIZE - 2 || x == this.SIZE - 3) && y == this.HSIZE - 1) { + core.playSound('光标移动'); + core.ui.drawFly(this._getNextFlyFloor(1)); + } + if ((x == this.SIZE - 2 || x == this.SIZE - 3) && y == this.HSIZE + 4) { + core.playSound('光标移动'); + core.ui.drawFly(this._getNextFlyFloor(-10)); + } + if ((x == this.SIZE - 2 || x == this.SIZE - 3) && y == this.HSIZE - 2) { + core.playSound('光标移动'); + core.ui.drawFly(this._getNextFlyFloor(10)); + } + if (x >= this.HSIZE - 1 && x <= this.HSIZE + 1 && y == this.LAST) { + core.playSound('取消'); + core.ui.closePanel(); + } const floorId = core.floorIds[core.status.event.data]; if (x >= 0 && x <= this.HSIZE + 3 && y >= 3 && y <= this.LAST - 1) core.flyTo(floorId); - if (x >= 1 && x <= 2 && y === 2) { + if (px >= 30 && px <= 110 && y === 2) { _hideFly(floorId); core.ui.drawFly(core.status.event.data); } - if (x >= 3 && x <= 6 && y === 2) { + if (x >= 4 && x <= 6 && y === 2) { core.setFlag('noHideFly', !core.hasFlag('noHideFly')); core.ui.drawFly(core.status.event.data); } + + // 隐藏楼层数据统计的按钮 + if (px >= core.__PIXELS__ - 90 && px <= core.__PIXELS__ - 70 && py >= 6 && py <= 26) { + core.setFlag('hideMapCount', !core.hasFlag('hideMapCount')); + core.ui.drawFly(core.status.event.data); + } + + // 隐藏地图上物品的按钮 + if (px >= core.__PIXELS__ - 60 && px <= core.__PIXELS__ - 40 && py >= 6 && py <= 26) { + core.ui.closePanel(); + ignoreItemsOnMap(floorId); + } return; } -////// 楼层传送器界面时,按下某个键的操作 ////// +function ignoreItemsOnMap(floorId) { + // 选定要忽略的物品 + const ignoreItems = core.getFlag('ignoreItems', {}); + const currIgnoreItems = new Set(ignoreItems[floorId]); + core.control.lockControl(); + core.setFlag('pickingIgnoreItems', true); + const ctx = core.createCanvas('ignoreItems', 0, 0, core.__PIXELS__, core.__PIXELS__, 141); + ctx.lineJoin = 'round'; + core.drawThumbnail(floorId, null, { damage: false, x: 0, y: 0, size: core.__PIXELS__, ctx: ctx }); + core.fillBoldText('ignoreItems', '选择有物品的图块,在统计数据时将忽略该位置。点楼传退出。', 35, 12, 'red', 'white', '12px Verdana'); + const drawIgnoreItems = () => { + const ctx = core.createCanvas('ignoreItemsMark', 0, 0, core.__PIXELS__, core.__PIXELS__, 142); + currIgnoreItems.forEach(pos => { + const [x, y] = pos.split(',').map(char => parseInt(char)); + core.drawCrossLine(ctx, 32 * x + 2, 32 * y + 2, 32 * (x + 1) - 2, 32 * (y + 1) - 2, 'red', 2); + }); + } + core.registerAction('ondown', 'ignoreItem', (x, y) => { + if (core.getBlockCls(x, y, floorId) !== 'items') return; + const posStr = x + ',' + y; + if (currIgnoreItems.has(posStr)) { + currIgnoreItems.delete(posStr); + } + else { + currIgnoreItems.add(posStr); + } + ignoreItems[floorId] = [...currIgnoreItems]; + core.setFlag('ignoreItems', ignoreItems); + drawIgnoreItems(); + }, 120); + drawIgnoreItems(); +} + +////// 楼层传送器/楼传界面界面时,按下某个键的操作 ////// actions.prototype._keyDownFly = function (keycode) { - if (keycode == 37) { core.playSound('光标移动'); core.ui.drawFly(this._getNextFlyFloor(-10)); } - else if (keycode == 38) { core.playSound('光标移动'); core.ui.drawFly(this._getNextFlyFloor(1)); } - else if (keycode == 39) { core.playSound('光标移动'); core.ui.drawFly(this._getNextFlyFloor(10)); } - else if (keycode == 40) { core.playSound('光标移动'); core.ui.drawFly(this._getNextFlyFloor(-1)); } + if (keycode == 37) { + core.playSound('光标移动'); + core.ui.drawFly(this._getNextFlyFloor(-10)); + } + else if (keycode == 38) { + core.playSound('光标移动'); + core.ui.drawFly(this._getNextFlyFloor(1)); + } + else if (keycode == 39) { + core.playSound('光标移动'); + core.ui.drawFly(this._getNextFlyFloor(10)); + } + else if (keycode == 40) { + core.playSound('光标移动'); + core.ui.drawFly(this._getNextFlyFloor(-1)); + } return; } @@ -1351,14 +1424,19 @@ actions.prototype._getNextFlyFloor = function (delta, index) { return ans; } -////// 楼层传送器界面时,放开某个键的操作 ////// +////// 楼层传送器/楼传界面时,放开某个键的操作 ////// actions.prototype._keyUpFly = function (keycode) { - if (keycode == 71 || keycode == 27 || keycode == 88) { + const floorId = core.floorIds[core.status.event.data]; + if (keycode === 71 || keycode === 27 || keycode === 88) { core.playSound('取消'); core.ui.closePanel(); } - if (keycode == 13 || keycode == 32 || keycode == 67) + else if (keycode === 13 || keycode === 32 || keycode === 67) this._clickFly(this.HSIZE - 1, this.HSIZE - 1); + else if (keycode === 72) { // H键 + _hideFly(floorId); + core.ui.drawFly(core.status.event.data); + } return; } diff --git a/libs/events.js b/libs/events.js index f4f06c01..6b457b73 100644 --- a/libs/events.js +++ b/libs/events.js @@ -2792,6 +2792,16 @@ events.prototype.useFly = function (fromUserAction) { return; } + // 退出隐藏物品模式 + if (core.hasFlag('pickingIgnoreItems')) { + core.setFlag('pickingIgnoreItems', false); + core.deleteCanvas('ignoreItems'); + core.deleteCanvas('ignoreItemsMark'); + core.unregisterAction('ondown', 'ignoreItem'); + core.unlockControl(); + return; + } + if (!this._checkStatus('fly', fromUserAction, true)) return; if (core.flags.flyNearStair && !core.nearStair()) { core.playSound('操作失败'); diff --git a/libs/ui.js b/libs/ui.js index 2a4480d3..c1b937dc 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -403,6 +403,22 @@ ui.prototype.drawLine = function (name, x1, y1, x2, y2, style, lineWidth) { ctx.stroke(); } +////// 在某个canvas上绘制一个叉符号 ////// +ui.prototype.drawCrossLine = function (name, x1, y1, x2, y2, style, lineWidth) { + if (style) core.setStrokeStyle(name, style); + if (lineWidth != null) core.setLineWidth(name, lineWidth); + var ctx = this.getContextByName(name); + if (!ctx) return; + ctx.beginPath(); + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); + ctx.stroke(); + ctx.beginPath(); + ctx.moveTo(x1, y2); + ctx.lineTo(x2, y1); + ctx.stroke(); +} + ui.prototype._uievent_drawLine = function (data) { this._createUIEvent(); this.drawLine('uievent', core.calValue(data.x1), core.calValue(data.y1), core.calValue(data.x2), core.calValue(data.y2), data.style, data.lineWidth); @@ -2555,7 +2571,10 @@ function getFloorBlockCounts(floorId) { }; core.extractBlocks(floorId); const blocks = core.status.maps[floorId].blocks; + const ignoreItems = core.getFlag('ignoreItems', {}); + const currIgnoreItems = new Set(ignoreItems[floorId]); blocks.forEach(block => { + if (currIgnoreItems.has(block.x + ',' + block.y)) return; switch (block.event.cls) { case 'enemys': case 'enemy48': @@ -2573,7 +2592,7 @@ function getFloorBlockCounts(floorId) { return blockType; } -////// 绘制楼层传送器 ////// +////// 绘制楼传/楼层传送器 ////// ui.prototype.drawFly = function (page) { core.status.event.data = page; var floorId = core.floorIds[page]; @@ -2593,8 +2612,8 @@ ui.prototype.drawFly = function (page) { const isHide = core.getFlag('hideFloors', {}).hasOwnProperty(floorId); const noHideFly = core.hasFlag('noHideFly'); - core.fillText('ui', isHide ? '[显示本层]' : '[隐藏本层]', 60, 80, '#EEEEEE', this._buildFont(12, false)); - core.fillText('ui', '[显示隐藏层:' + (noHideFly ? 'ON' : 'OFF') + ']', 160, 80, '#EEEEEE', this._buildFont(12, false)); + core.fillText('ui', isHide ? '[显示本层(H)]' : '[隐藏本层(H)]', 70, 80, '#EEEEEE', this._buildFont(12, false)); + core.fillText('ui', '[显示隐藏层:' + (noHideFly ? 'ON' : 'OFF') + ']', 175, 80, '#EEEEEE', this._buildFont(12, false)); var middle = this.HPIXEL + 39; // 换行 @@ -2617,30 +2636,62 @@ ui.prototype.drawFly = function (page) { core.fillText('ui', '▼', this.PIXEL - 60, middle + 96); core.fillText('ui', '▼', this.PIXEL - 60, middle + 96 + 7); } - var size = this.PIXEL - 143; + const size = this.PIXEL - 143; core.strokeRect('ui', 20, 100, size, size, '#FFFFFF', 2); if (isHide) core.setAlpha('ui', 0.6); core.drawThumbnail(floorId, null, { ctx: 'ui', x: 20, y: 100, size: size, damage: true }); if (isHide) core.setAlpha('ui', 1); - const blockCounts = getFloorBlockCounts(floorId); + // 绘制被忽略的图块的标记 + const ignoreItems = core.getFlag('ignoreItems', {}); + const currIgnoreItems = new Set(ignoreItems[floorId]); + currIgnoreItems.forEach(pos => { + const [ignoreX, ignoreY] = pos.split(',').map(char => parseInt(char)); + const blockSize = size / core.__SIZE__; + core.drawCrossLine('ui', 20 + blockSize * ignoreX + 2, 100 + blockSize * ignoreY + 2, + 20 + blockSize * (ignoreX + 1) - 2, 100 + blockSize * (ignoreY + 1) - 2, 'red', 2); + }); - if (blockCounts.enemy > 0) { - core.drawIcon('ui', 'greenSlime', this.PIXEL - 90, 30, 16, 16); - core.drawIcon('ui', 'redSlime', this.PIXEL - 85, 35, 16, 16); - core.fillText('ui', '× ' + blockCounts.enemy, this.PIXEL - 50, 47, 'white', '12px Verdana'); - } - if (blockCounts.item > 0) { - core.drawIcon('ui', 'redGem', this.PIXEL - 90, 60, 16, 16); - core.drawIcon('ui', 'bluePotion', this.PIXEL - 85, 65, 16, 16); - core.fillText('ui', '× ' + blockCounts.item, this.PIXEL - 50, 77, 'white', '12px Verdana'); - } + const hideMapCount = core.getFlag('hideMapCount', false); + if (!hideMapCount) { + const blockCounts = getFloorBlockCounts(floorId); - if (blockCounts.npc > 0) { - core.drawIcon('ui', 'man', this.PIXEL - 90, 90, 16, 16); - core.drawIcon('ui', 'trader', this.PIXEL - 85, 95, 16, 16); - core.fillText('ui', '× ' + blockCounts.npc, this.PIXEL - 50, 107, 'white', '12px Verdana'); + if (blockCounts.enemy > 0) { + core.drawIcon('ui', 'greenSlime', this.PIXEL - 90, 35, 16, 16); + core.drawIcon('ui', 'redSlime', this.PIXEL - 85, 40, 16, 16); + core.fillText('ui', '× ' + blockCounts.enemy, this.PIXEL - 50, 52, 'white', '12px Verdana'); + } + if (blockCounts.item > 0) { + core.drawIcon('ui', 'redGem', this.PIXEL - 90, 65, 16, 16); + core.drawIcon('ui', 'bluePotion', this.PIXEL - 85, 70, 16, 16); + core.fillText('ui', '× ' + blockCounts.item, this.PIXEL - 50, 82, 'white', '12px Verdana'); + } + + if (blockCounts.npc > 0) { + core.drawIcon('ui', 'man', this.PIXEL - 90, 95, 16, 16); + core.drawIcon('ui', 'trader', this.PIXEL - 85, 100, 16, 16); + core.fillText('ui', '× ' + blockCounts.npc, this.PIXEL - 50, 112, 'white', '12px Verdana'); + } + } + const { IconBtn } = core.plugin.uiBase; + if (IconBtn) { + // 显示/隐藏地图数据显示的按钮 + const showItemCountBtn = new IconBtn(this.PIXEL - 90, 6, 20, 20, 'greenSlime', { + fillStyle: 'Silver', strokeStyle: 'DimGray', lineWidth: 2, + crossline1: !hideMapCount, crossline2: !hideMapCount, + }); + showItemCountBtn.ctx = 'ui'; + showItemCountBtn.draw(); + + // 隐藏地图上物品的按钮 + const hideMapItemBtn = new IconBtn(this.PIXEL - 60, 6, 20, 20, 'redPotion', { + fillStyle: 'Silver', strokeStyle: 'DimGray', lineWidth: 2, + iconX: this.PIXEL - 58, iconY: 8, iconW: 16, iconH: 16, + crossline1: true, crossline2: true + }); + hideMapItemBtn.ctx = 'ui'; + hideMapItemBtn.draw(); } } @@ -3347,8 +3398,12 @@ ui.prototype._drawStatistics_floorId = function (floorId, obj) { var floor = core.status.maps[floorId], blocks = floor.blocks; // 隐藏层不给看 if (floor.cannotViewMap && floorId != core.status.floorId) return; + const ignoreItems = core.getFlag('ignoreItems', {}); + const currIgnoreItems = new Set(ignoreItems[floorId]); blocks.forEach(function (block) { if (block.disable) return; + // 被屏蔽的道具不计入 + if (currIgnoreItems.has(block.x + ',' + block.y)) return; var event = block.event; if (event.cls.indexOf("enemy") == 0) { core.ui._drawStatistics_enemy(floorId, event.id, obj); diff --git a/project/plugins.js b/project/plugins.js index 786ee47b..e6e72abf 100644 --- a/project/plugins.js +++ b/project/plugins.js @@ -2821,11 +2821,24 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = const { x, y, w, h } = this; const { strokeStyle = 'black', fillStyle = 'white', - radius = 3, lineWidth = 1, angle = null, frame = 0 + radius = 3, lineWidth = 1, angle = null, frame = 0, + iconX = x, iconY = y, iconW = w, iconH = h, + crossline1 = false, crossline2 = false, crossLineOffset = 2, + crossLineStyle = 'red', crossLineWidth = 2, } = this.config || {}; if (fillStyle !== 'none') core.fillRoundRect(ctx, x, y, w, h, radius, fillStyle, angle); if (strokeStyle !== 'none') core.strokeRoundRect(ctx, x, y, w, h, radius, strokeStyle, lineWidth, angle); - core.drawIcon(ctx, this.icon, x, y, w, h, frame); + core.drawIcon(ctx, this.icon, iconX, iconY, iconW, iconH, frame); + if (crossline1) { + core.drawLine(ctx, x + crossLineOffset, y + crossLineOffset, + x + w - crossLineOffset, y + h - crossLineOffset, + crossLineStyle, crossLineWidth); + } + if (crossline2) { + core.drawLine(ctx, x + crossLineOffset, y + h - crossLineOffset, + x + w - crossLineOffset, y + crossLineOffset, + crossLineStyle, crossLineWidth); + } } }