feat: 隐藏楼层道具功能

This commit is contained in:
ShakeFlower 2025-07-27 11:31:54 +08:00
parent 3315948b18
commit cebb1bb15d
4 changed files with 194 additions and 38 deletions

View File

@ -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;
}

View File

@ -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('操作失败');

View File

@ -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);

View File

@ -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);
}
}
}