获取逻辑
This commit is contained in:
1 parent
2b1d14ad78
commit
2d918f8c6f
2 files changed
+58
-29
No files matched your search
+53
-26
@@ -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):
|
||||
|
||||
+5
-3
@@ -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"):
|
||||
|
||||
Reference in new issue
Block a user