获取逻辑

This commit is contained in:
wenhe committed 2026-09-30 11:57:35 +08:00
1 parent 2b1d14ad78
commit 2d918f8c6f
2 files changed
+58 -29

No files matched your search

@@ -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):
@@ -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"):