箭袋 退出游戏后 无法获取 bug
This commit is contained in:
1 parent
e8a22d8cb3
commit
e38c2b4b38
2 files changed
+150
-7
No files matched your search
@@ -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",
|
||||
},
|
||||
|
||||
|
||||
|
||||
+137
-4
@@ -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)
|
||||
{"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)})
|
||||
Reference in new issue
Block a user