feat:自动隐藏楼层

This commit is contained in:
ShakeFlower 2025-07-27 17:16:55 +08:00
parent 3dc78ffd14
commit 0ac52f6ffb
4 changed files with 136 additions and 19 deletions

View File

@ -1294,8 +1294,12 @@ function _hideFly(floorId) {
else { else {
hideFloors[floorId] = true; hideFloors[floorId] = true;
} }
const autoHiddenFloorList = core.getFlag("autoHiddenFloorList", []);
autoHiddenFloorList.push(floorId);
core.setFlag("autoHiddenFloorList", autoHiddenFloorList);
core.setFlag('hideFloors', hideFloors); core.setFlag('hideFloors', hideFloors);
} }
actions.prototype._hideFly = _hideFly;
function _isFloorHided(floorId) { function _isFloorHided(floorId) {
if (floorId === core.status.floorId) return false; // 当前所在层需要无条件显示 if (floorId === core.status.floorId) return false; // 当前所在层需要无条件显示
@ -1368,7 +1372,7 @@ function ignoreItemsOnMap(floorId) {
}); });
} }
core.registerAction('ondown', 'ignoreItem', (x, y) => { core.registerAction('ondown', 'ignoreItem', (x, y) => {
if (core.getBlockCls(x, y, floorId) !== 'items') return; if (!["items", "enemys", "enemy48", "npcs", "npc48"].includes(core.getBlockCls(x, y, floorId))) return;
const posStr = x + ',' + y; const posStr = x + ',' + y;
if (currIgnoreItems.has(posStr)) { if (currIgnoreItems.has(posStr)) {
currIgnoreItems.delete(posStr); currIgnoreItems.delete(posStr);
@ -1380,6 +1384,15 @@ function ignoreItemsOnMap(floorId) {
core.setFlag('ignoreItems', ignoreItems); core.setFlag('ignoreItems', ignoreItems);
drawIgnoreItems(); drawIgnoreItems();
}, 120); }, 120);
core.registerAction('keyUp', 'ignoreItem', (keyCode) => {
switch (keyCode) {
case 8: //BackSpace
case 27: //Esc
case 71: //G
core.events.quitIgnoreItems();
break;
}
}, 120);
drawIgnoreItems(); drawIgnoreItems();
} }

View File

@ -2775,6 +2775,16 @@ events.prototype.openBook = function (fromUserAction) {
core.useItem('book', true); core.useItem('book', true);
} }
////// 退出屏蔽物品界面 //////
events.prototype.quitIgnoreItems = function () {
core.setFlag('pickingIgnoreItems', false);
core.deleteCanvas('ignoreItems');
core.deleteCanvas('ignoreItemsMark');
core.unregisterAction('ondown', 'ignoreItem');
core.unregisterAction('keyUp', 'ignoreItem');
core.unlockControl();
}
////// 点击楼层传送器时的打开操作 ////// ////// 点击楼层传送器时的打开操作 //////
events.prototype.useFly = function (fromUserAction) { events.prototype.useFly = function (fromUserAction) {
if (core.isReplaying()) return; if (core.isReplaying()) return;
@ -2794,12 +2804,7 @@ events.prototype.useFly = function (fromUserAction) {
// 退出隐藏物品模式 // 退出隐藏物品模式
if (core.hasFlag('pickingIgnoreItems')) { if (core.hasFlag('pickingIgnoreItems')) {
core.setFlag('pickingIgnoreItems', false); this.quitIgnoreItems();
core.deleteCanvas('ignoreItems');
core.deleteCanvas('ignoreItemsMark');
core.unregisterAction('ondown', 'ignoreItem');
core.unlockControl();
return;
} }
if (!this._checkStatus('fly', fromUserAction, true)) return; if (!this._checkStatus('fly', fromUserAction, true)) return;

View File

@ -2563,8 +2563,56 @@ ui.prototype._drawBookDetail_drawContent = function (enemy, content, pos) {
}); });
} }
/** ":before"":next"IDevents.prototype._changeFloor_getInfo
* @param {string} floorId 待转换的floorId
* @param {string} currFloor ":before"":next"的基准floorId
*/
function getRealFloorId(floorId, currFloor) {
const index = core.floorIds.indexOf(currFloor);
if (index === -1) return floorId;
if (floorId === ":before" && index > 0) {
return core.floorIds[index - 1];
}
else if (floorId === ":next" && index < core.floorIds.length - 1) {
return core.floorIds[index - 1];
}
else return floorId;
}
// 查找嵌套JSON中是否有{type:changeFloor, floorId:xxx的格式}
function findFloorIds(obj, currFloorId) {
const result = [];
function traverse(current) {
if (current && typeof current === 'object') {
// 判断当前对象是否满足条件
if (current.type === 'changeFloor' && 'floorId' in current) {
result.push(getRealFloorId(current.floorId, currFloorId));
}
// 递归处理对象或数组中的每个元素
if (Array.isArray(current)) {
for (const item of current) {
traverse(item);
}
} else {
for (const key in current) {
traverse(current[key]);
}
}
}
}
traverse(obj);
return result;
}
/**
* @returns {{
* enemy:number,npc:number,item:number
* }}
*/
function getFloorBlockCounts(floorId) { function getFloorBlockCounts(floorId) {
const blockType = { const blockCounts = {
enemy: 0, enemy: 0,
npc: 0, npc: 0,
item: 0, item: 0,
@ -2573,23 +2621,25 @@ function getFloorBlockCounts(floorId) {
const blocks = core.status.maps[floorId].blocks; const blocks = core.status.maps[floorId].blocks;
const ignoreItems = core.getFlag('ignoreItems', {}); const ignoreItems = core.getFlag('ignoreItems', {});
const currIgnoreItems = new Set(ignoreItems[floorId]); const currIgnoreItems = new Set(ignoreItems[floorId]);
blocks.forEach(block => { blocks.forEach(block => {
if (currIgnoreItems.has(block.x + ',' + block.y)) return; if (currIgnoreItems.has(block.x + ',' + block.y)) return;
switch (block.event.cls) { switch (block.event.cls) {
case 'enemys': case 'enemys':
case 'enemy48': case 'enemy48':
blockType.enemy++; blockCounts.enemy++;
break; break;
case 'npcs': case 'npcs':
case 'npc48': case 'npc48':
blockType.npc++; blockCounts.npc++;
break; break;
case 'items': case 'items':
blockType.item++; blockCounts.item++;
break; break;
} }
}); });
return blockType; return blockCounts;
} }
////// 绘制楼传/楼层传送器 ////// ////// 绘制楼传/楼层传送器 //////
@ -2609,7 +2659,7 @@ ui.prototype.drawFly = function (page) {
core.fillText('ui', '可楼层跳跃!', this.PIXEL - 10, this.PIXEL - 11, null, this._buildFont(10, false)); core.fillText('ui', '可楼层跳跃!', this.PIXEL - 10, this.PIXEL - 11, null, this._buildFont(10, false));
core.setTextAlign('ui', 'center'); core.setTextAlign('ui', 'center');
const isHide = core.getFlag('hideFloors', {}).hasOwnProperty(floorId); let isHide = core.getFlag('hideFloors', {}).hasOwnProperty(floorId);
const noHideFly = core.hasFlag('noHideFly'); const noHideFly = core.hasFlag('noHideFly');
core.fillText('ui', isHide ? '[显示本层(H)]' : '[隐藏本层(H)]', 70, 80, '#EEEEEE', this._buildFont(12, false)); core.fillText('ui', isHide ? '[显示本层(H)]' : '[隐藏本层(H)]', 70, 80, '#EEEEEE', this._buildFont(12, false));
@ -2639,9 +2689,6 @@ ui.prototype.drawFly = function (page) {
const size = this.PIXEL - 143; const size = this.PIXEL - 143;
core.strokeRect('ui', 20, 100, size, size, '#FFFFFF', 2); 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 ignoreItems = core.getFlag('ignoreItems', {}); const ignoreItems = core.getFlag('ignoreItems', {});
@ -2654,9 +2701,8 @@ ui.prototype.drawFly = function (page) {
}); });
const hideMapCount = core.getFlag('hideMapCount', false); const hideMapCount = core.getFlag('hideMapCount', false);
const blockCounts = getFloorBlockCounts(floorId);
if (!hideMapCount) { if (!hideMapCount) {
const blockCounts = getFloorBlockCounts(floorId);
if (blockCounts.enemy > 0) { if (blockCounts.enemy > 0) {
core.drawIcon('ui', 'greenSlime', this.PIXEL - 90, 35, 16, 16); core.drawIcon('ui', 'greenSlime', this.PIXEL - 90, 35, 16, 16);
core.drawIcon('ui', 'redSlime', this.PIXEL - 85, 40, 16, 16); core.drawIcon('ui', 'redSlime', this.PIXEL - 85, 40, 16, 16);
@ -2674,12 +2720,56 @@ ui.prototype.drawFly = function (page) {
core.fillText('ui', '× ' + blockCounts.npc, this.PIXEL - 50, 112, 'white', '12px Verdana'); core.fillText('ui', '× ' + blockCounts.npc, this.PIXEL - 50, 112, 'white', '12px Verdana');
} }
} }
// 判断是否触发自动隐藏楼层,否则不检查相关信息
const autoHideFloor = core.getFlag('autoHideFloor', false);
/** 已经触发过自动隐藏的楼层的列表 该数组在手动隐藏/首次自动隐藏时触发,且只增不减 */
const autoHiddenFloorList = core.getFlag('autoHiddenFloorList', []);
if (autoHideFloor && !autoHiddenFloorList.includes(floorId)) {
// 该楼层可达的楼层
const aimFloor = [];
const addFloorIdsFromEvents = function (event) {
for (let pos in event) {
if (currIgnoreItems.has(pos)) continue;
aimFloor.push(...findFloorIds(event[pos], floorId));
}
}
const currFloorInfo = core.floors[floorId];
addFloorIdsFromEvents(currFloorInfo.afterBattle);
addFloorIdsFromEvents(currFloorInfo.beforeBattle);
addFloorIdsFromEvents(currFloorInfo.afterGetItem);
addFloorIdsFromEvents(currFloorInfo.afterOpenDoor);
addFloorIdsFromEvents(currFloorInfo.autoEvent);
addFloorIdsFromEvents(currFloorInfo.events);
for (let pos in currFloorInfo.changeFloor) {
aimFloor.push(getRealFloorId(currFloorInfo.changeFloor[pos].floorId, floorId));
}
// 该楼层可达的楼层集合
const aimFloorSet = new Set(aimFloor.filter(floorId => core.floorIds.includes(floorId)));
const isAllFloorVisited = [...aimFloorSet].every(floorId => core.hasVisitedFloor(floorId));
if (blockCounts.enemy === 0 && blockCounts.npc === 0 &&
blockCounts.item === 0 && isAllFloorVisited) {
{
core.setFlag("autoHiddenFloorList", autoHiddenFloorList);
core.actions._hideFly(floorId);
isHide = true;
core.drawTip("满足条件,已自动隐藏该层。");
}
}
}
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 { IconBtn } = core.plugin.uiBase; const { IconBtn } = core.plugin.uiBase;
if (IconBtn) { if (IconBtn) {
// 显示/隐藏地图数据显示的按钮 // 显示/隐藏地图数据显示的按钮
const showItemCountBtn = new IconBtn(this.PIXEL - 90, 6, 20, 20, 'greenSlime', { const showItemCountBtn = new IconBtn(this.PIXEL - 90, 6, 20, 20, 'greenSlime', {
fillStyle: 'Silver', strokeStyle: 'DimGray', lineWidth: 2, fillStyle: 'Silver', strokeStyle: 'DimGray', lineWidth: 2,
crossline1: !hideMapCount, crossline2: !hideMapCount, crossline1: hideMapCount, crossline2: hideMapCount,
}); });
showItemCountBtn.ctx = 'ui'; showItemCountBtn.ctx = 'ui';
showItemCountBtn.draw(); showItemCountBtn.draw();

View File

@ -4810,6 +4810,14 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
}, },
text: '在地图上显示玩家的在线留言。', text: '在地图上显示玩家的在线留言。',
replay: true, replay: true,
},
autoHideFloor: {
getName: () => '自动隐藏楼层:' + (core.hasFlag('autoHideFloor') ? '开' : '关'),
effect: () => {
invertFlag('autoHideFloor');
},
text: '一个楼层已无物品、敌人、NPC(不含已忽略图块),且无未到达楼层传送口时可被自动隐藏,仅在首次进入此状态时在楼传界面触发。',
replay: true,
} }
} }
@ -4845,6 +4853,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
['1,4', 'skipText', new SettingButton(40, 305, 150, 25)], ['1,4', 'skipText', new SettingButton(40, 305, 150, 25)],
['2,4', 'skipPeform', new SettingButton(220, 305, 150, 25)], ['2,4', 'skipPeform', new SettingButton(220, 305, 150, 25)],
['1,5', 'comment', new SettingButton(40, 330, 150, 25)], ['1,5', 'comment', new SettingButton(40, 330, 150, 25)],
['2,5', 'autoHideFloor', new SettingButton(220, 330, 150, 25)],
]); ]);
return gamePlayMenu; return gamePlayMenu;
} }