From 2d918f8c6f007259d1d8da0a2fc22f19c01ba524 Mon Sep 17 00:00:00 2001 From: wenhe <1046926120@qq.com> Date: Wed, 30 Sep 2026 11:57:35 +0800 Subject: [PATCH] =?UTF-8?q?=E8=8E=B7=E5=8F=96=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SpecialFunciton/BlueFoxSystem.py | 79 +++++++++++++------ .../jiaju/service/FurnitureService.py | 8 +- 2 files changed, 58 insertions(+), 29 deletions(-) diff --git a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/BlueFoxTools/SpecialFunciton/BlueFoxSystem.py b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/BlueFoxTools/SpecialFunciton/BlueFoxSystem.py index 51d9714..78871a9 100644 --- a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/BlueFoxTools/SpecialFunciton/BlueFoxSystem.py +++ b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/BlueFoxTools/SpecialFunciton/BlueFoxSystem.py @@ -773,22 +773,31 @@ class BlueFoxServerSystem(serverBaseSystem): # ============================================================================ # 统一"主动获得物品"接口(任务一): # 所有给玩家的物品一律按优先级分发, 而非直接掉落: - # 1) 背包(非主手)存在同类可叠加 -> +1 合并 + # 1) 背包(0~35格)存在同类且未堆满(64) -> 数量 +count 合并 # 2) 主手为空 -> 放到主手 # 3) 主手有物 -> 放入背包(同类叠加/空位) # 4) 背包满且主手有物 -> 掉落物形式(在 pos 上方生成) + # pos/dim 缺省(只写 giveItemToPlayer(p, name, n) 的老调用点)时, 第4步按玩家脚下掉落, + # 而不是把物品吞掉 —— 保证"背包满时一定可见"。 # 死亡生物屠宰 / 稻谷 需要保持"纯掉落"时请勿调用本方法(仍用 CreateEngineItemEntity)。 # ============================================================================ def giveItemToPlayer(self, playerId, itemName, count=1, pos=None, dim=None, aux=0, userData=None): - """按统一优先级把物品给玩家。pos/dim 只在最终"掉落物"兜底时用(可为空)。 - 返回 True = 已成功放入(合并/主手/背包); False = 最终只能掉落或调用方无上下文。""" + """按统一优先级把物品给玩家。pos/dim 只在最终"掉落物"兜底时用(可为空, + 为空时自动取玩家脚下位置与所在维度)。 + 返回 True = 已成功放入(合并/主手/背包); False = 最终只能掉落(或连玩家位置都取不到)。""" + if not itemName: + return False itemDict = {"itemName": itemName, "count": count, "auxValue": aux} if userData: itemDict["userData"] = userData try: # 1) 背包同类合并(带 userData 的物品不合并, 避免附魔/药水数据被并错) - if not userData and self._mergeSameStackInv(playerId, itemName, count): - return True + if not userData: + remain = self._mergeSameStackInv(playerId, itemName, count, aux) + if remain <= 0: + return True + # 只把"没能并进已有堆叠"的余量继续走 2/3/4 + itemDict["count"] = remain # 2) 主手为空 -> 放主手 cur = self.getCarriedItem(playerId) hand = (cur or {}).get("newItemName") @@ -808,8 +817,14 @@ class BlueFoxServerSystem(serverBaseSystem): pass except Exception: pass - # 4) 掉落物兜底 - if pos and dim: + # 4) 掉落物兜底(没传 pos/dim 就按玩家脚下, 避免物品凭空消失) + if not (pos and dim): + try: + pos = serverCompFactory.CreatePos(playerId).GetFootPos() + dim = serverCompFactory.CreateDimension(playerId).GetEntityDimensionId() + except Exception: + pos, dim = None, None + if pos and dim is not None: try: self.CreateEngineItemEntity( itemDict, dim, (pos[0], pos[1] + 0.5, pos[2])) @@ -817,27 +832,39 @@ class BlueFoxServerSystem(serverBaseSystem): pass return False - def _mergeSameStackInv(self, playerId, itemName, count=1): - """背包(主手除外)存在可叠加同种物品 -> 数量+count 合并。 - 返回 True=已合并; False=没有可合并的同种堆叠(不新增物品)。""" - itemComp = serverCompFactory.CreateItem(playerId) - enum = serverApi.GetMinecraftEnum().ItemPosType + def _mergeSameStackInv(self, playerId, itemName, count=1, aux=0): + """把 count 个 (itemName, aux) 合并进背包(0~35格)里已有的同类堆叠(未满64)。 + 返回"剩余没能合并的数量"(0 = 全部并进了已有堆叠)。 + 读写用本工程已验证可用的 GetPlayerAllItems(0) + SetInvItemNum + (参考 FastComp.DeclarePlayerInvItem); 逐格独立 try 保护, 单格异常不影响其它格。""" + remain = count + if remain <= 0: + return 0 try: - for i in range(0, 36): - d = itemComp.GetPlayerItem(enum.INVENTORY, i, True) - if not d: - continue - if d.get("newItemName") == itemName and (d.get("count") or 0) < 64: - newCount = (d.get("count") or 0) + count - itemComp.SetEntityItem( - enum.INVENTORY, i, - {"itemName": itemName, "count": newCount, - "auxValue": d.get("newAuxValue", 0), - "userData": d.get("userData", {})}) - return True + itemComp = serverCompFactory.CreateItem(playerId) + allItems = itemComp.GetPlayerAllItems(0) # 0 = ItemPosType.INVENTORY(0~35) except Exception: - return False - return False + return count + for index in range(0, len(allItems or [])): + if remain <= 0: + break + d = allItems[index] + if not d: + continue + try: + if d.get("newItemName") != itemName: + continue + if (d.get("newAuxValue") or 0) != aux: + continue + cur = d.get("count") or 0 + if cur <= 0 or cur >= 64: + continue + add = min(64 - cur, remain) + if itemComp.SetInvItemNum(index, cur + add): + remain -= add + except Exception: + continue + return remain @BlueFoxClientListener def RucksackScreenClosed(self, args): diff --git a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/jiaju/service/FurnitureService.py b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/jiaju/service/FurnitureService.py index f6c9c7f..11c4933 100644 --- a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/jiaju/service/FurnitureService.py +++ b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/jiaju/service/FurnitureService.py @@ -335,9 +335,11 @@ class FurnitureService(BlueFoxServerSystem): retAux = record.get("aux", 0) retUserData = record.get("userData") - # 掉落物形式返回箭(根因C); 药水箭带 userData 还原药水效果 - self._dropItemDict(dim, pos, {"itemName": retItemName, "count": retCount, - "aux": retAux, "userData": retUserData}) + # 取箭属于"玩家主动获得", 走统一优先级(合并->主手->背包->掉落); + # 药水箭带 userData, 走不合并分支直接进主手/背包, 数据不丢 + self._giveItemDict(playerId, pos, dim, + {"itemName": retItemName, "count": retCount, + "aux": retAux, "userData": retUserData}) # 替换方块 if recipe.get("target"):