From e38c2b4b38f58f15d7afc213facb966b70a0d1f5 Mon Sep 17 00:00:00 2001 From: wenhe <1046926120@qq.com> Date: Wed, 5 Aug 2026 16:53:52 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AE=AD=E8=A2=8B=20=E9=80=80=E5=87=BA?= =?UTF-8?q?=E6=B8=B8=E6=88=8F=E5=90=8E=20=E6=97=A0=E6=B3=95=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ceshi/BlockSwitchData.py | 16 +- .../ceshi/service/BlockSwitchService.py | 141 +++++++++++++++++- 2 files changed, 150 insertions(+), 7 deletions(-) diff --git a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/ceshi/BlockSwitchData.py b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/ceshi/BlockSwitchData.py index e762114..c0bb3e2 100644 --- a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/ceshi/BlockSwitchData.py +++ b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/ceshi/BlockSwitchData.py @@ -22,25 +22,34 @@ CookingService 启动时会自动把两边的数据合并成一份字典,O(1) maxCount: 记录型最多存多少(箭桶32只、盘子架5个等) time: 计时型转换需要多少秒 tool: 特定工具要求(如"剑") + arrowMode: 箭桶专用,"store"=存箭模式,"retrieve"=取箭模式 + 存箭:批量存入手中所有箭(至多maxCount),支持普通箭+药水箭 + 取箭:一次性取回方块记录的所有箭 """ BLOCK_SWITCHES = [ # 一、箭桶 # ============================================================ - # 【放箭】箭桶_0 → 箭桶_1 + # 【存箭】箭桶_0 → 箭桶_1 + # 支持所有箭类型:minecraft:arrow(普通箭)、minecraft:tipped_arrow(药水箭) + # 批量存入手中所有箭(至多 maxCount 只),记录箭类型(itemName + auxValue) + # 例如:手持 64 只中毒之箭右键 → 存 32 只,手上剩 32 只 + # 手持 31 只中毒之箭右键 → 存 31 只,手上清空 { "source": "rtdd:arrowbarrel_0", - "item": "minecraft:arrow", + "item": None, "target": "rtdd:arrowbarrel_1", - "consume": 1, + "consume": 0, "type": "switch", "record": True, "recordType": "count", "maxCount": 32, "giveItem": None, + "arrowMode": "store", }, # 【取箭】箭桶_1 → 箭桶_0 + # 一次性取回方块内记录的所有箭(数量、类型按记录来) { "source": "rtdd:arrowbarrel_1", "item": None, @@ -50,6 +59,7 @@ BLOCK_SWITCHES = [ "record": True, "recordType": "count", "giveItem": None, + "arrowMode": "retrieve", }, diff --git a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/ceshi/service/BlockSwitchService.py b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/ceshi/service/BlockSwitchService.py index 8ef93d3..5a0d04c 100644 --- a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/ceshi/service/BlockSwitchService.py +++ b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/ceshi/service/BlockSwitchService.py @@ -225,6 +225,7 @@ class BlockSwitchService(BlueFoxServerSystem): 匹配条件: 1. 先精确匹配 (方块名, 物品名) 2. 如果没找到,尝试匹配 (方块名, None) —— 空手也能触发的规则 + 3. 如果匹配到的是 arrowMode 规则,额外检查手中物品是否为箭 返回:匹配到的规则 dict,找不到返回 None """ @@ -238,10 +239,25 @@ class BlockSwitchService(BlueFoxServerSystem): # 空手匹配:(方块名, None) recipe = self.switchRecipes.get((blockName, None)) if recipe: + # 如果规则是 arrowMode 存箭模式,检查手中物品是否为箭 + if recipe.get("arrowMode") == "store": + if itemDict and self._isArrow(itemDict): + return recipe + return None return recipe return None + def _isArrow(self, itemDict): + """ + 判断手中物品是否为箭(普通箭或药水箭)。 + 返回 True/False。 + """ + if not itemDict: + return False + itemName = itemDict.get("newItemName", "") + return itemName == "minecraft:arrow" or itemName == "minecraft:tipped_arrow" + # ============================================================================ # 工具方块切换处理 # ============================================================================ @@ -277,6 +293,13 @@ class BlockSwitchService(BlueFoxServerSystem): return self.switchCooldown[key] = now + # ---- 箭桶模式(arrowMode):存箭 / 取箭 ---- + # 独立于普通 count/stack 逻辑,因为箭桶需要批量操作 + arrowMode = recipe.get("arrowMode") + if arrowMode: + self._handleArrowMode(arrowMode, recipe, playerId, pos, dim, itemDict, key, blockName) + return + # ---- 计时型:直接替换方块,不消耗物品,不记录 ---- if recipe.get("type") == "timer": if recipe.get("target"): @@ -298,6 +321,7 @@ class BlockSwitchService(BlueFoxServerSystem): record = { "count": 0, "itemName": itemDict["newItemName"], + "auxValue": itemDict.get("newAuxValue", 0), } # 检查是否满了 maxCount = recipe.get("maxCount", 999) @@ -451,7 +475,8 @@ class BlockSwitchService(BlueFoxServerSystem): self._writeBlockData(dim, pos, rtdd_swt="count", rtdd_swc=record["count"], - rtdd_swi=record.get("itemName", "")) + rtdd_swi=record.get("itemName", ""), + rtdd_swa=record.get("auxValue", 0)) elif "stack" in record: self._writeBlockData(dim, pos, rtdd_swt="stack", @@ -472,6 +497,7 @@ class BlockSwitchService(BlueFoxServerSystem): return { "count": blockData["rtdd_swc"], "itemName": blockData["rtdd_swi"], + "auxValue": blockData.get("rtdd_swa", 0), } elif swt == "stack": return { @@ -485,7 +511,7 @@ class BlockSwitchService(BlueFoxServerSystem): 清除工具方块的记录数据(内存+方块实体数据)。 """ self.switchRecord.pop(key, None) - self._writeBlockData(dim, pos, rtdd_swt="", rtdd_swc=0, rtdd_swi="", rtdd_sws=[]) + self._writeBlockData(dim, pos, rtdd_swt="", rtdd_swc=0, rtdd_swi="", rtdd_swa=0, rtdd_sws=[]) # ============================================================================ # 工具方法:获取玩家手中物品 @@ -555,10 +581,117 @@ class BlockSwitchService(BlueFoxServerSystem): # 工具方法:给玩家物品 # ============================================================================ - def giveItem(self, playerId, itemName, count=1): + def giveItem(self, playerId, itemName, count=1, auxValue=0): """ 往玩家背包里塞一个物品。 如果背包满了,物品会掉在地上。 """ comp.CreateItem(playerId).SpawnItemToPlayerInv( - {"itemName": itemName, "count": count, "auxValue": 0}, playerId) \ No newline at end of file + {"itemName": itemName, "count": count, "auxValue": auxValue}, playerId) + + # ============================================================================ + # 箭桶模式(arrowMode):存箭 / 取箭 + # ============================================================================ + + def _handleArrowMode(self, arrowMode, recipe, playerId, pos, dim, itemDict, key, blockName): + """ + 处理箭桶的存箭/取箭逻辑。 + + 【存箭流程】 + 1. 检查手中是否为箭(_isArrow 已在 findRecipe 验证过) + 2. 检查方块是否有记录且类型匹配: + a. 已有记录 → 检查手中箭类型(itemName+auxValue)是否匹配 → 不匹配则 return + b. 无记录 → 新建记录 + 3. 计算实际可存数量 = min(手中数量, maxCount - 已有数量) + 4. 如果可存数量 <= 0 → return + 5. 从手中扣减,更新记录,替换方块 + + 【取箭流程】 + 1. 检查方块是否有记录且 count > 0 + 2. 给玩家手中/背包添加 count 只箭(itemName + auxValue 按记录) + 3. 清空记录,替换方块 + """ + record = self.switchRecord.get(key) + + if arrowMode == "store": + # ---- 存箭 ---- + handCount = itemDict.get("count", 0) + if handCount <= 0: + return + + handItemName = itemDict.get("newItemName", "") + handAuxValue = itemDict.get("newAuxValue", 0) + + # 检查方块是否有记录且类型匹配 + if record and record["count"] > 0: + # 已有记录 → 检查箭类型是否一致 + if record.get("itemName") != handItemName or record.get("auxValue", 0) != handAuxValue: + return # 类型不匹配,不能混存 + else: + # 无记录 → 新建 + record = { + "count": 0, + "itemName": handItemName, + "auxValue": handAuxValue, + } + + # 计算实际可存数量 + maxCount = recipe.get("maxCount", 32) + if record["count"] >= maxCount: + return # 已满 + storeCount = min(handCount, maxCount - record["count"]) + + # 从玩家手中扣减 + self._consumeItemCount(playerId, itemDict, storeCount) + + # 更新记录 + record["count"] += storeCount + + # 替换方块 + if recipe.get("target"): + self.replaceBlock(pos, dim, recipe["target"], playerId) + + # 保存记录到新方块 + self._saveRecord(key, playerId, pos, dim, record) + + elif arrowMode == "retrieve": + # ---- 取箭 ---- + if not record or record["count"] <= 0: + return + + retCount = record["count"] + retItemName = record["itemName"] + retAuxValue = record.get("auxValue", 0) + + # 给玩家箭 + self.giveItem(playerId, retItemName, retCount, retAuxValue) + + # 替换方块 + if recipe.get("target"): + self.replaceBlock(pos, dim, recipe["target"], playerId) + + # 清空记录 + self.clearSwitchRecord(key, playerId, pos, dim) + + def _consumeItemCount(self, playerId, itemDict, amount): + """ + 从玩家主手批量扣减指定数量的物品。 + 如果手中数量刚好等于 amount → 清空主手。 + 如果手中数量大于 amount → 减少 amount。 + """ + if not itemDict or amount <= 0: + return + count = itemDict.get("count", 0) + if count <= amount: + # 数量不够或刚好用完 → 清空主手 + comp.CreateItem(playerId).SetEntityItem( + serverApi.GetMinecraftEnum().ItemPosType.CARRIED, + {"itemName": "minecraft:air", "count": 0, "auxValue": 0}) + else: + # 数量够 → 减少 amount 个 + itemDict["count"] = count - amount + comp.CreateItem(playerId).SetEntityItem( + serverApi.GetMinecraftEnum().ItemPosType.CARRIED, + {"itemName": itemDict["newItemName"], + "count": itemDict["count"], + "auxValue": itemDict.get("newAuxValue", 0)}) \ No newline at end of file