统一取回物品优先级(背包堆叠->主手->背包空位->掉落), 修正书柜/药水架整摞计数多给; 新增唱片分类; 调整遮阳布/旗帜碰撞箱

This commit is contained in:
Giao committed 2026-09-30 11:34:14 +08:00
1 parent ba44cc738f
commit 4c7bfcf7a5
28 files changed
+256 -201

No files matched your search

@@ -15,8 +15,10 @@
target: 转换成的目标方块
consume: 消耗数量(默认0, 即不消耗)
clearHand: True=清空主手全部物品(垃圾桶扔垃圾)
giveItem: 取回/取水时给玩家背包的物品名(直接进背包)
dropItem: 以掉落物形式给的物品 [{"name": "xx", "count": N}]
giveItem: 取回/取水时给玩家的物品名
(统一优先级: 背包同名堆叠 -> 主手(空) -> 背包空位 -> 掉落)
dropItem: 取回时给的物品列表 [{"name": "xx", "count": N}]
(与 giveItem 同走统一优先级, 空间不足才掉出来)
record: "count"=记录一种物品+数量(箭桶) / "stack"=后放先取堆栈(书柜),
记录写入方块实体数据(rtdd_swt/rtdd_swc/rtdd_swi/rtdd_swa/rtdd_sws),
退出重进不丢; 附魔以扁平ench字段([[附魔ID,等级],...])存储,
@@ -394,7 +394,7 @@ class FurnitureService(BlueFoxServerSystem):
pickedObj = _s
break
if pickedObj is not None:
self.giveItemObj(playerId, pickedObj) # 按持久化对象给(附魔保留)
self.giveItemObj(playerId, pickedObj, pos, dim) # 按持久化对象给(附魔保留)
else:
self.giveItemToPlayer(playerId, picked, 1, pos, dim, aux=0)
self.replaceBlock(pos, dim, target, playerId)
@@ -466,13 +466,17 @@ class FurnitureService(BlueFoxServerSystem):
oldRecord = self._loadRecord(pos, dim)
bookStack = list(oldRecord.get("stack") or []) if oldRecord else []
if recipe.get("item") is None:
# 取回: 后放先取, 弹栈, 以掉落物形式给玩家
# 取回: 后放先取(LIFO), 每条记录=1件, 走统一优先级给玩家
if not bookStack:
return
droppedBook = bookStack.pop()
elif itemDict:
# 放入: 压栈(扁平化物品信息, 附魔存ench字段, 取回时重建)
bookStack.append(self._toItemObj(itemDict))
# 每次只消耗 consume 个(书/药水均为1), 记录数量必须与消耗数一致;
# 否则手持整摞右键会"只消耗1件、却按整摞计数", 取出时凭空多给。
_putObj = self._toItemObj(itemDict)
_putObj["count"] = max(1, int(recipe.get("consume", 1)))
bookStack.append(_putObj)
# ---- 唱片机取回: 先读记录(此时方块还是有碟的) ----
discToDrop = None
@@ -509,23 +513,24 @@ class FurnitureService(BlueFoxServerSystem):
if recipe.get("discPut") and itemDict:
self._writeDiscData(dim, pos, itemDict)
# ---- 掉落物(书柜取书/唱片取回) ----
# ---- 取回物品(书柜取书/唱片取回/碗柜取碗) ----
# 统一走优先级: 背包同名堆叠 -> 主手(空) -> 背包空位 -> 都没地方才掉出来
if droppedBook is not None:
self._dropItemObj(dim, pos, droppedBook)
self.giveItemObj(playerId, droppedBook, pos, dim)
if discToDrop:
self._dropItemDict(dim, pos, discToDrop)
self._giveItemDict(playerId, pos, dim, discToDrop)
if recipe.get("dropItem"):
self.dropItems(dim, pos, recipe["dropItem"])
self.dropItems(dim, pos, recipe["dropItem"], playerId)
# ---- 掉落物形式(水槽取水/取脏盘子/盘子架取回等) ----
# 【根因C】获得物品一律改掉落物形式, 不再直接塞进背包
# ---- 给玩家物品(水槽取水/取脏盘子/盘子架取回等) ----
if recipe.get("giveItem"):
_gItem = recipe["giveItem"]
if isinstance(_gItem, dict):
self._dropItemDict(dim, pos, _gItem)
self._giveItemDict(playerId, pos, dim, _gItem)
else:
self._dropItemDict(dim, pos,
{"itemName": _gItem, "count": recipe.get("giveCount", 1), "auxValue": 0})
self._giveItemDict(playerId, pos, dim,
{"itemName": _gItem,
"count": recipe.get("giveCount", 1)})
# ============================================================================
# 五、方块记录:count/stack 读写(箭桶/书柜, 字段 rtdd_sw*)
@@ -557,6 +562,12 @@ class FurnitureService(BlueFoxServerSystem):
stack = parsed
except Exception:
stack = []
# 每条 stack 记录在设计上固定代表1件(方块链级数 == 存了几件),
# 历史版本误把整摞数量写进来, 统一归一成1: 否则取回(书柜/药水架)
# 或左键破坏时会凭空多给。归一后由调用方回写, 老存档自动修好。
for _s in stack:
if isinstance(_s, dict):
_s["count"] = 1
# None/异常/损坏数据一律按空堆栈处理, 保证不报错
return {"stack": stack}
return None
@@ -750,18 +761,34 @@ class FurnitureService(BlueFoxServerSystem):
""""给玩家物品": 统一走优先级(同类合并->主手->背包->掉落)"""
self.giveItemToPlayer(playerId, itemName, count, aux=aux, userData=userData)
def giveItemObj(self, playerId, itemObj):
"""按持久化物品对象给玩家(厨具架取回; 附魔书按扁平ench重建附魔)"""
def _giveItemDict(self, playerId, pos, dim, itemDict):
"""按统一优先级给玩家一个物品 dict(唱片取回/规则 giveItem 等)。
空间不足时由 giveItemToPlayer 用 pos/dim 掉落兜底; 数据异常则忽略。"""
try:
itemDict = {"itemName": itemObj["itemName"],
"count": itemObj.get("count", 1),
"auxValue": itemObj.get("aux", 0)}
self.giveItemToPlayer(
playerId,
itemDict["itemName"],
itemDict.get("count", 1),
pos, dim,
# 兼容两种 key: 调用处既有用 aux 也有用 auxValue
aux=itemDict.get("aux", itemDict.get("auxValue", 0)),
userData=itemDict.get("userData"))
except Exception:
pass
def giveItemObj(self, playerId, itemObj, pos=None, dim=None):
"""按持久化物品对象给玩家(厨具架取回/书柜取书; 附魔书按扁平ench重建附魔)
统一走优先级(同类合并->主手->背包), pos/dim 给定时空间不足才掉落。"""
try:
userData = None
ench = itemObj.get("ench")
if ench:
itemDict["userData"] = self._buildEnchUserData(ench)
userData = self._buildEnchUserData(ench)
elif itemObj.get("userData"):
itemDict["userData"] = itemObj["userData"]
comp.CreateItem(playerId).SpawnItemToPlayerInv(itemDict, playerId)
userData = itemObj["userData"]
self.giveItemToPlayer(playerId, itemObj["itemName"],
itemObj.get("count", 1), pos, dim,
aux=itemObj.get("aux", 0), userData=userData)
except Exception:
pass
@@ -833,21 +860,26 @@ class FurnitureService(BlueFoxServerSystem):
dimensionId=dim)
# ============================================================================
# 十一、工具方法:以掉落物形式生成物品(厨具架取回)
# 十一、工具方法:给玩家一组物品(碗柜取碗等),没有 playerId 时直接掉落
# ============================================================================
def dropItems(self, dim, pos, dropList):
def dropItems(self, dim, pos, dropList, playerId=None):
"""
dropList 格式:[{"name": "xxx", "count": N}, ...]
在方块上方生成掉落物实体, 让它自然掉到地上。
playerId 给出时走统一优先级(同类合并->主手->背包->掉落);
未给出时(方块被破坏等)直接在方块上方生成掉落物。
"""
for d in dropList:
itemDict = {
"itemName": d["name"],
"count": d.get("count", 1),
"auxValue": d.get("aux", 0),
}
self.CreateEngineItemEntity(itemDict, dim, (pos[0], pos[1] + 0.5, pos[2]))
if playerId is not None:
self.giveItemToPlayer(playerId, d["name"], d.get("count", 1),
pos, dim, aux=d.get("aux", 0))
else:
itemDict = {
"itemName": d["name"],
"count": d.get("count", 1),
"auxValue": d.get("aux", 0),
}
self.CreateEngineItemEntity(itemDict, dim, (pos[0], pos[1] + 0.5, pos[2]))
# ============================================================================
# 十二、工具方法:冷却检查