From a91952851e2a28a8eed8315746af3a91ed533a37 Mon Sep 17 00:00:00 2001 From: ShakeFlower Date: Thu, 14 Aug 2025 09:45:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=B7=BB=E5=8A=A0=E7=9B=B4=E6=8E=A5?= =?UTF-8?q?=E5=8F=AF=E8=BE=BE=E6=A5=BC=E4=BC=A0=E7=9A=84=E5=88=A4=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _server/MotaAction.g4 | 4 ++-- _server/table/data.comment.js | 6 ++++++ libs/control.js | 2 +- libs/events.js | 6 +++--- libs/maps.js | 38 ++++++++++++++++++++++++++++++++++- project/data.js | 1 + project/items.js | 2 +- runtime.d.ts | 7 +++++++ 8 files changed, 58 insertions(+), 8 deletions(-) diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index bb9a6bb8..4e9cca5e 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -4126,8 +4126,8 @@ Global_Value_List Global_Flag_List - : '显示当前楼层'|'显示勇士图标'|'显示当前等级'|'启用生命上限'|'显示生命值'|'显示魔力值'|'显示攻击力'|'显示防御力'|'显示护盾值'|'显示金币值'|'显示经验值'|'允许等级提升'|'升级扣除模式'|'显示钥匙数量'|'显示绿钥匙'|'显示破炸飞'|'显示毒衰咒'|'显示当前技能'|'横屏底部工具栏'|'楼梯边才能楼传'|'楼传平面塔模式'|'开启加点'|'开启负伤'|'夹击不超伤害值'|'二分计算临界'|'允许轻按'|'允许走到将死领域'|'允许瞬间移动'|'阻激夹域后禁用快捷商店'|'虚化前景层' - /*Global_Flag_List ['s:enableFloor','s:enableName','s:enableLv', 's:enableHPMax', 's:enableHP', 's:enableMana', 's:enableAtk', 's:enableDef', 's:enableMDef', 's:enableMoney', 's:enableExp', 's:enableLevelUp', 's:levelUpLeftMode', 's:enableKeys', 's:enableGreenKey', 's:enablePZF', 's:enableDebuff', 's:enableSkill', 'extendToolbar', 'flyNearStair', 'flyRecordPosition', 'enableAddPoint', 'enableNegativeDamage', 'betweenAttackMax', 'useLoop', 'enableGentleClick', 'canGoDeadZone', 'enableMoveDirectly', 'disableShopOnDamage', 'blurFg']*/; + : '显示当前楼层'|'显示勇士图标'|'显示当前等级'|'启用生命上限'|'显示生命值'|'显示魔力值'|'显示攻击力'|'显示防御力'|'显示护盾值'|'显示金币值'|'显示经验值'|'允许等级提升'|'升级扣除模式'|'显示钥匙数量'|'显示绿钥匙'|'显示破炸飞'|'显示毒衰咒'|'显示当前技能'|'横屏底部工具栏'|'楼梯边才能楼传'|'可达楼梯才能楼传'|'楼传平面塔模式'|'开启加点'|'开启负伤'|'夹击不超伤害值'|'二分计算临界'|'允许轻按'|'允许走到将死领域'|'允许瞬间移动'|'阻激夹域后禁用快捷商店'|'虚化前景层' + /*Global_Flag_List ['s:enableFloor','s:enableName','s:enableLv', 's:enableHPMax', 's:enableHP', 's:enableMana', 's:enableAtk', 's:enableDef', 's:enableMDef', 's:enableMoney', 's:enableExp', 's:enableLevelUp', 's:levelUpLeftMode', 's:enableKeys', 's:enableGreenKey', 's:enablePZF', 's:enableDebuff', 's:enableSkill', 'extendToolbar', 'flyNearStair', 'flyAccessStair', 'flyRecordPosition', 'enableAddPoint', 'enableNegativeDamage', 'betweenAttackMax', 'useLoop', 'enableGentleClick', 'canGoDeadZone', 'enableMoveDirectly', 'disableShopOnDamage', 'blurFg']*/; NextXY_List : '横坐标'|'纵坐标' diff --git a/_server/table/data.comment.js b/_server/table/data.comment.js index 0e6addfa..507bfcfc 100644 --- a/_server/table/data.comment.js +++ b/_server/table/data.comment.js @@ -570,6 +570,12 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "_docs": "楼传需在楼梯边", "_data": "传送器是否需要在楼梯边使用;如果flyRecordPosition开启,则此项对箭头也有效。" }, + "flyAccessStair": { + "_leaf": true, + "_type": "checkbox", + "_docs": "楼传需可达楼梯", + "_data": "传送器是否需要在当前可到达楼梯时使用;如果flyNearStair开启,则覆盖此项;如果flyRecordPosition开启,则此项对箭头也有效。" + }, "flyRecordPosition": { "_leaf": true, "_type": "checkbox", diff --git a/libs/control.js b/libs/control.js index 76b85cb9..b14530a6 100644 --- a/libs/control.js +++ b/libs/control.js @@ -1975,7 +1975,7 @@ control.prototype._replayAction_fly = function (action) { if (action.indexOf("fly:") != 0) return false; var floorId = action.substring(4); var toIndex = core.floorIds.indexOf(floorId); - if (!core.canUseItem('fly') || (core.flags.flyNearStair && !core.nearStair())) return false; + if (!core.canUseItem('fly') || (!core.maps.canUseFlyHere())) return false; core.ui.drawFly(toIndex); if (core.status.replay.speed == 24) { if (!core.flyTo(floorId, core.replay)) diff --git a/libs/events.js b/libs/events.js index 9033ad17..98fbbf97 100644 --- a/libs/events.js +++ b/libs/events.js @@ -2793,7 +2793,7 @@ events.prototype.useFly = function (fromUserAction) { if (!core.hasItem('fly')) { core.playSound('操作失败'); core.drawTip('你没有' + core.material.items['fly'].name, 'fly'); - } else if (!core.canUseItem('fly') || (core.flags.flyNearStair && !core.nearStair())) { + } else if (!core.canUseItem('fly') || (!core.maps.canUseFlyHere())) { core.playSound('操作失败'); core.drawTip('无法传送到当前层', 'fly'); } else { @@ -2808,7 +2808,7 @@ events.prototype.useFly = function (fromUserAction) { } if (!this._checkStatus('fly', fromUserAction, true)) return; - if (core.flags.flyNearStair && !core.nearStair()) { + if (!core.maps.canUseFlyHere()) { core.playSound('操作失败'); core.drawTip("只有在楼梯边才能使用" + core.material.items['fly'].name, 'fly'); core.unlockControl(); @@ -2818,7 +2818,7 @@ events.prototype.useFly = function (fromUserAction) { } if (!core.canUseItem('fly')) { core.playSound('操作失败'); - core.drawTip(core.material.items['fly'].name + "好像失效了", 'fly'); + core.drawTip(core.material.items['fly'].name + "失效了", 'fly'); core.unlockControl(); core.status.event.data = null; core.status.event.id = null; diff --git a/libs/maps.js b/libs/maps.js index 1f9ffa68..3f88b1a5 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -1924,10 +1924,46 @@ maps.prototype.stairExists = function (x, y, floorId) { ////// 当前位置是否在楼梯边 ////// maps.prototype.nearStair = function () { - var x = core.getHeroLoc('x'), y = core.getHeroLoc('y'); + const { x, y } = core.status.hero.loc; return this.stairExists(x, y) || this.stairExists(x - 1, y) || this.stairExists(x, y - 1) || this.stairExists(x + 1, y) || this.stairExists(x, y + 1); } +////// 当前位置是否可到达某一楼梯 ////// +maps.prototype.accessStair = function () { + const stairIdList = ['upFloor', 'downFloor', 'leftPortal', 'rightPortal', 'upPortal', 'downPortal', 'portal', 'starPortal']; + const floorId = core.status.floorId; + core.extractBlocks(floorId); + /** 筛选那些在楼梯附近一格,且为空地的图块 只计入空地,不判断可入性,因为可能存在踩灯这类一次性事件 */ + const nearStairPos = []; + core.status.maps[floorId].blocks.forEach(function (block) { + if (stairIdList.includes(block.event.id)) { + for (let dir in core.utils.scan) { + const nx = block.x + core.utils.scan[dir].x, + ny = block.y + core.utils.scan[dir].y; + if (nx < 0 || ny < 0 || nx >= core.floors[floorId].width || ny >= core.floors[floorId].height) continue; + if (core.getBlock(nx, ny, floorId) == null) { + nearStairPos.push([nx, ny]); + } + } + } + }); + const canMoveArr = this.canMoveDirectlyArray(nearStairPos); + return canMoveArr.some(canMoveStep => canMoveStep >= 0); +} + +// 当前位置是否满足使用飞行器的条件 +maps.prototype.canUseFlyHere = function () { + if (core.flags.flyNearStair) { + return this.nearStair(); + } + else if (core.flags.flyAccessStair) { + return this.accessStair(); + } + else { + return true; + } +} + ////// 某个点是否存在(指定的)怪物 ////// maps.prototype.enemyExists = function (x, y, id, floorId) { var block = this.getBlock(x, y, floorId); diff --git a/project/data.js b/project/data.js index 78b79255..41687d85 100644 --- a/project/data.js +++ b/project/data.js @@ -729,6 +729,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "autoScale": true, "extendToolbar": false, "flyNearStair": true, + "flyAccessStair": false, "flyRecordPosition": false, "itemFirstText": false, "equipboxButton": false, diff --git a/project/items.js b/project/items.js index aed38eab..27812c8d 100644 --- a/project/items.js +++ b/project/items.js @@ -366,7 +366,7 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = "hideInReplay": true, "hideInToolbox": true, "useItemEffect": "core.ui.drawFly(core.floorIds.indexOf(core.status.floorId));", - "canUseItemEffect": "(function () {\n\tif (core.flags.flyNearStair && !core.nearStair()) return false;\n\treturn core.status.maps[core.status.floorId].canFlyFrom;\n})();" + "canUseItemEffect": "(function () {\n\tif (!core.maps.canUseFlyHere()) return false;\n\treturn core.status.maps[core.status.floorId].canFlyFrom;\n})();" }, "coin": { "cls": "constants", diff --git a/runtime.d.ts b/runtime.d.ts index 5012e9ad..3790bf8b 100644 --- a/runtime.d.ts +++ b/runtime.d.ts @@ -134,6 +134,7 @@ type MotaAction = { type SystemFlags = { enableXxx: boolean flyNearStair: boolean + flyAccessStair: boolean steelDoorWithoutKey: boolean betweenAttackMax: boolean ignoreChangeFloor: boolean @@ -2130,6 +2131,12 @@ interface maps { /** 当前位置是否在楼梯边;在楼传平面塔模式下对箭头也有效 */ nearStair(): boolean + /** 当前位置是否可以直接移动到某个楼梯附近的空地 */ + accessStair(): boolean + + /** 当前位置是否满足使用楼传的条件 */ + canUseFlyHere(): boolean + /** 某个点是否存在(指定的)怪物 */ enemyExists(x?: number, y?: number, id?: string, floorId?: string): boolean