代码测试 2026年7月30日 1
This commit is contained in:
1 parent
3c90a1c613
commit
842befe7dd
2 files changed
+155
-55
No files matched your search
+154
-54
@@ -41,10 +41,11 @@ from ...BlueFoxTools.SpecialFunciton.BlueFoxSystem import BlueFoxServerSystem
|
||||
from ...BlueFoxTools.ToolsConfig import LevelId
|
||||
|
||||
# ---- 方块实体数据组件 ----
|
||||
# 每个方块都可以存一点自定义数据(比如"翻炒了几次"),
|
||||
# 这个组件就是读写这些数据的。LevelId 是全局唯一的标识符,
|
||||
# 所有方块数据统一存在这个 LevelId 下,和之前的 Function.py 用同一个
|
||||
blockEntityDataComp = comp.CreateBlockEntityData(LevelId)
|
||||
# 每个方块都可以存一点自定义数据(比如"翻炒了几次")。
|
||||
# GetBlockEntityData / SetBlockEntityData 都在 BlockInfo 组件上。
|
||||
# 注意:CreateBlockEntityData 返回的组件只有 GetBlockEntityData(只读),
|
||||
# 没有 SetBlockEntityData,所以必须用 CreateBlockInfo。
|
||||
blockEntityDataComp = comp.CreateBlockInfo(LevelId)
|
||||
|
||||
# ---- 导入所有配方 ----
|
||||
# RECIPES 是一个列表,每条配方是一个 dict,格式见 RecipeData.py 顶部注释
|
||||
@@ -225,19 +226,18 @@ class CookingService(BlueFoxServerSystem):
|
||||
# type="switch" 或 "timer" → 工具方块切换(箭桶、挂肉钩、水槽等)
|
||||
# 没有 type 或 type="cook" → 做菜配方(炒锅、煎锅等)
|
||||
|
||||
# ---- 统一加载:把方块里的历史数据恢复到内存 ----
|
||||
# 不管是做菜还是工具切换,先把方块数据加载到内存,后面直接用
|
||||
self._loadBlockDataToMemory(key, playerId, pos, dim, recipe)
|
||||
|
||||
if recipeType == "switch" or recipeType == "timer":
|
||||
self.handleSwitch(recipe, playerId, pos, dim, itemDict, key, blockName)
|
||||
return
|
||||
|
||||
# ---- 第五步:以下为做菜配方逻辑 ----
|
||||
|
||||
# ---- 加载翻炒进度(如果这个方块之前翻过的话) ----
|
||||
# 先从内存取,内存没有就从方块实体数据加载(服务器重启后恢复)
|
||||
# 内存中已有数据(_loadBlockDataToMemory 已加载),直接用
|
||||
stirInfo = self.stirData.get(key, {})
|
||||
if not stirInfo:
|
||||
stirInfo = self.loadStirData(playerId, pos, dim, recipe)
|
||||
if stirInfo:
|
||||
self.stirData[key] = stirInfo # 加载成功后写入内存缓存
|
||||
|
||||
# ---- 根据配方类型判断 ----
|
||||
# needFinished=True 的配方 → 需要先翻炒熟了才能操作(比如出锅)
|
||||
@@ -321,12 +321,13 @@ class CookingService(BlueFoxServerSystem):
|
||||
return
|
||||
|
||||
# ---- 切换型 ----
|
||||
# 获取当前方块的记录数据
|
||||
# 内存中已有数据(_loadBlockDataToMemory 已加载),直接用
|
||||
record = self.switchRecord.get(key)
|
||||
|
||||
# ---- 正向操作:往方块里放东西(source == 被右键的方块) ----
|
||||
if recipe["source"] == blockName and recipe.get("item") is not None:
|
||||
# 玩家手里有物品,往方块里放
|
||||
needSave = False # 标记是否需要保存记录到方块
|
||||
if recipe.get("record"):
|
||||
if recipe.get("recordType") == "count":
|
||||
# 数量记录型:只记录一种物品的总数
|
||||
@@ -335,20 +336,18 @@ class CookingService(BlueFoxServerSystem):
|
||||
"count": 0,
|
||||
"itemName": itemDict["newItemName"],
|
||||
}
|
||||
self.switchRecord[key] = record
|
||||
# 检查是否满了
|
||||
maxCount = recipe.get("maxCount", 999)
|
||||
if record["count"] >= maxCount:
|
||||
return # 满了,不能再放
|
||||
# 记录物品+1
|
||||
record["count"] += 1
|
||||
self.switchRecord[key] = record
|
||||
needSave = True
|
||||
|
||||
elif recipe.get("recordType") == "stack":
|
||||
# 堆栈记录型:后进先出,记录每种物品的完整信息
|
||||
if not record:
|
||||
record = {"stack": []}
|
||||
self.switchRecord[key] = record
|
||||
maxCount = recipe.get("maxCount", 999)
|
||||
if len(record["stack"]) >= maxCount:
|
||||
return # 满了
|
||||
@@ -359,16 +358,20 @@ class CookingService(BlueFoxServerSystem):
|
||||
"auxValue": itemDict.get("newAuxValue", 0),
|
||||
"userData": itemDict.get("userData", {}),
|
||||
})
|
||||
self.switchRecord[key] = record
|
||||
needSave = True
|
||||
|
||||
# 消耗物品
|
||||
if recipe.get("consume", 1) > 0:
|
||||
self.consumeItem(playerId, itemDict, recipe.get("consume", 1))
|
||||
|
||||
# 替换方块
|
||||
# 替换方块(旧方块销毁,新方块出现)
|
||||
if recipe.get("target"):
|
||||
self.replaceBlock(pos, dim, recipe["target"], playerId)
|
||||
|
||||
# ★ 关键:替换完方块后再保存记录到新方块上,否则数据随旧方块一起销毁
|
||||
if needSave:
|
||||
self._saveRecord(key, playerId, pos, dim, record)
|
||||
|
||||
# 如果配方指定了给物品(如烧烤架浇水给桶)
|
||||
if recipe.get("giveItem"):
|
||||
self.giveItem(playerId, recipe["giveItem"])
|
||||
@@ -377,6 +380,9 @@ class CookingService(BlueFoxServerSystem):
|
||||
|
||||
# ---- 逆向操作:从方块里取东西(空手右键或取回物品) ----
|
||||
if recipe["source"] == blockName and recipe.get("item") is None:
|
||||
needSaveRecord = False # 是否需要保存记录
|
||||
needClearRecord = False # 是否需要清除记录
|
||||
|
||||
if recipe.get("record") and record:
|
||||
if recipe.get("recordType") == "count":
|
||||
# 数量记录型取回:给玩家对应的物品,数量-1
|
||||
@@ -384,9 +390,9 @@ class CookingService(BlueFoxServerSystem):
|
||||
self.giveItem(playerId, record["itemName"])
|
||||
record["count"] -= 1
|
||||
if record["count"] <= 0:
|
||||
self.switchRecord.pop(key, None)
|
||||
needClearRecord = True
|
||||
else:
|
||||
self.switchRecord[key] = record
|
||||
needSaveRecord = True
|
||||
|
||||
elif recipe.get("recordType") == "stack":
|
||||
# 堆栈记录型取回:后进先出,取最后一个放的物品
|
||||
@@ -399,18 +405,24 @@ class CookingService(BlueFoxServerSystem):
|
||||
"userData": topItem.get("userData", {})},
|
||||
playerId)
|
||||
if not record["stack"]:
|
||||
self.switchRecord.pop(key, None)
|
||||
needClearRecord = True
|
||||
else:
|
||||
self.switchRecord[key] = record
|
||||
needSaveRecord = True
|
||||
|
||||
# 如果配方直接指定了给什么物品(水槽、盘子架取回、挂肉钩退回等)
|
||||
if recipe.get("giveItem"):
|
||||
self.giveItem(playerId, recipe["giveItem"])
|
||||
|
||||
# 替换方块
|
||||
# 替换方块(旧方块销毁,新方块出现)
|
||||
if recipe.get("target"):
|
||||
self.replaceBlock(pos, dim, recipe["target"], playerId)
|
||||
|
||||
# ★ 关键:替换完方块后再保存/清除记录,否则数据随旧方块一起销毁
|
||||
if needClearRecord:
|
||||
self.clearSwitchRecord(key, playerId, pos, dim)
|
||||
elif needSaveRecord:
|
||||
self._saveRecord(key, playerId, pos, dim, record)
|
||||
|
||||
return
|
||||
|
||||
# ============================================================================
|
||||
@@ -475,7 +487,7 @@ class CookingService(BlueFoxServerSystem):
|
||||
- 熟了之后可以继续右键"出锅"(变成成品菜)
|
||||
|
||||
流程:
|
||||
1. 从内存或方块数据加载当前翻炒进度
|
||||
1. 从内存取翻炒进度(_loadBlockDataToMemory 已提前加载)
|
||||
2. 检查冷却时间,没冷却好就忽略
|
||||
3. 翻炒次数+1,更新进度
|
||||
4. 给玩家发进度提示("翻炒中... 3/10")
|
||||
@@ -483,17 +495,22 @@ class CookingService(BlueFoxServerSystem):
|
||||
"""
|
||||
now = time.time()
|
||||
|
||||
# ---- 第一步:加载或初始化翻炒数据 ----
|
||||
data = self.stirData.get(key) or self.loadStirData(playerId, pos, dim, recipe)
|
||||
# ---- 第一步:从内存取翻炒数据(入口已通过 _loadBlockDataToMemory 加载) ----
|
||||
data = self.stirData.get(key)
|
||||
if not data:
|
||||
# 全新的翻炒,初始化数据
|
||||
data = {
|
||||
"count": 0, # 从0次开始
|
||||
"lastTime": 0.0, # 上次翻的时间(初始为0,第一次翻不受冷却限制)
|
||||
"finished": False, # 还没熟
|
||||
"dropIfDone": recipe.get("dropIfDone", []), # 熟了拆掉掉什么
|
||||
"dropIfNot": recipe.get("dropIfNot", []), # 没熟拆掉掉什么
|
||||
"count": 0,
|
||||
"lastTime": 0.0,
|
||||
"finished": False,
|
||||
"dropIfDone": recipe.get("dropIfDone", []),
|
||||
"dropIfNot": recipe.get("dropIfNot", []),
|
||||
}
|
||||
else:
|
||||
# 兜底防止 None 值(方块数据可能不完整)
|
||||
for field, default in [("lastTime", 0.0), ("count", 0), ("finished", False)]:
|
||||
if data.get(field) is None:
|
||||
data[field] = default
|
||||
self.stirData[key] = data
|
||||
|
||||
# ---- 第二步:冷却检查 ----
|
||||
@@ -705,6 +722,61 @@ class CookingService(BlueFoxServerSystem):
|
||||
except:
|
||||
pass
|
||||
|
||||
# ============================================================================
|
||||
# 通用持久化帮手(避免重复的 try/except/Get/Set 写法)
|
||||
# ============================================================================
|
||||
|
||||
def _writeBlockData(self, dim, pos, **kwargs):
|
||||
"""
|
||||
通用方块实体数据写入:读 → 改 → 写。
|
||||
|
||||
把 saveStirData / clearStirData / saveSwitchRecord / clearSwitchRecord
|
||||
四个方法里重复的 try/except/GetBlockEntityData/SetBlockEntityData 抽出来,
|
||||
一行搞定,不用每次写一样的 try/except。
|
||||
"""
|
||||
try:
|
||||
blockData = blockEntityDataComp.GetBlockEntityData(dim, pos)
|
||||
if blockData is None:
|
||||
blockData = {}
|
||||
for key, value in kwargs.items():
|
||||
blockData[key] = value
|
||||
blockEntityDataComp.SetBlockEntityData(dim, pos, blockData)
|
||||
except Exception as e:
|
||||
print "[CookingService] _writeBlockData 写入失败: pos=%s dim=%s err=%s" % (pos, dim, str(e))
|
||||
|
||||
def _saveRecord(self, key, playerId, pos, dim, record):
|
||||
"""
|
||||
同时更新内存和方块实体数据中的工具方块记录。
|
||||
|
||||
替代原本重复出现的:
|
||||
self.switchRecord[key] = record
|
||||
self.saveSwitchRecord(playerId, pos, dim, record)
|
||||
"""
|
||||
self.switchRecord[key] = record
|
||||
self.saveSwitchRecord(playerId, pos, dim, record)
|
||||
|
||||
# ============================================================================
|
||||
# 统一数据加载入口(玩家右键方块时先把方块数据恢复到内存)
|
||||
# ============================================================================
|
||||
|
||||
def _loadBlockDataToMemory(self, key, playerId, pos, dim, recipe):
|
||||
"""
|
||||
在确定玩家右键命中了一个配方后,立刻把方块里存的历史数据加载到内存。
|
||||
|
||||
这样 handleStir / handleSwitch 里就不用各自加载了,
|
||||
直接从 self.stirData / self.switchRecord 取就行。
|
||||
|
||||
两个数据源互不干扰:翻炒数据用 stirData,工具切换记录用 switchRecord。
|
||||
"""
|
||||
if key not in self.stirData:
|
||||
stirInfo = self.loadStirData(playerId, pos, dim, recipe)
|
||||
if stirInfo:
|
||||
self.stirData[key] = stirInfo
|
||||
if key not in self.switchRecord:
|
||||
switchInfo = self.loadSwitchRecord(playerId, pos, dim)
|
||||
if switchInfo:
|
||||
self.switchRecord[key] = switchInfo
|
||||
|
||||
# ============================================================================
|
||||
# 翻炒数据持久化(存方块里,不存JSON文件)
|
||||
# ============================================================================
|
||||
@@ -742,40 +814,68 @@ class CookingService(BlueFoxServerSystem):
|
||||
|
||||
def saveStirData(self, playerId, pos, dim, data):
|
||||
"""
|
||||
把翻炒进度写入方块的实体数据。
|
||||
|
||||
每次翻炒后都调用一次,保证数据实时同步。
|
||||
用方括号 [] 直接赋值,网易API会自动保存到方块中。
|
||||
把翻炒进度写入方块实体数据。
|
||||
"""
|
||||
try:
|
||||
blockData = blockEntityDataComp.GetBlockEntityData(dim, pos)
|
||||
blockData["rtdd_sc"] = data["count"] # 保存翻炒次数
|
||||
blockData["rtdd_slt"] = data["lastTime"] # 保存最后翻炒时间
|
||||
blockData["rtdd_sf"] = data["finished"] # 保存是否熟了
|
||||
except:
|
||||
# 如果方块没有实体数据对象,忽略(下次加载会重新初始化)
|
||||
pass
|
||||
self._writeBlockData(dim, pos,
|
||||
rtdd_sc=data["count"],
|
||||
rtdd_slt=data["lastTime"],
|
||||
rtdd_sf=data["finished"])
|
||||
|
||||
def clearStirData(self, key, playerId, pos, dim):
|
||||
"""
|
||||
清除方块上的翻炒数据。
|
||||
|
||||
调用时机:
|
||||
- 方块被替换(比如炒锅变成了成品菜)
|
||||
- 方块被拆掉(玩家把锅拆了)
|
||||
|
||||
同时清除内存和方块实体数据。
|
||||
清除方块上的翻炒数据(内存+方块实体数据)。
|
||||
"""
|
||||
# 清除内存中的数据
|
||||
self.stirData.pop(key, None)
|
||||
# 清除方块实体数据(重置为初始值)
|
||||
self._writeBlockData(dim, pos, rtdd_sc=0, rtdd_slt=0.0, rtdd_sf=False)
|
||||
|
||||
# ============================================================================
|
||||
# 工具方块记录持久化(药水架、书柜、箭桶等)
|
||||
# ============================================================================
|
||||
|
||||
def saveSwitchRecord(self, playerId, pos, dim, record):
|
||||
"""
|
||||
把工具方块的记录数据写入方块实体数据。
|
||||
记录类型:count型(箭桶)→ rtdd_swt/swc/swi,stack型(书柜/药水架)→ rtdd_swt/sws
|
||||
"""
|
||||
if "count" in record:
|
||||
self._writeBlockData(dim, pos,
|
||||
rtdd_swt="count",
|
||||
rtdd_swc=record["count"],
|
||||
rtdd_swi=record.get("itemName", ""))
|
||||
elif "stack" in record:
|
||||
self._writeBlockData(dim, pos,
|
||||
rtdd_swt="stack",
|
||||
rtdd_sws=record["stack"])
|
||||
|
||||
def loadSwitchRecord(self, playerId, pos, dim):
|
||||
"""
|
||||
从方块实体数据里读取工具方块的记录数据。
|
||||
|
||||
返回:
|
||||
有数据 → {"count": N, "itemName": "xxx"} 或 {"stack": [...]}
|
||||
没有 → None
|
||||
"""
|
||||
try:
|
||||
blockData = blockEntityDataComp.GetBlockEntityData(dim, pos)
|
||||
blockData["rtdd_sc"] = 0
|
||||
blockData["rtdd_slt"] = 0.0
|
||||
blockData["rtdd_sf"] = False
|
||||
swt = blockData["rtdd_swt"] # 记录类型:"count" 或 "stack"
|
||||
if swt == "count":
|
||||
return {
|
||||
"count": blockData["rtdd_swc"],
|
||||
"itemName": blockData["rtdd_swi"],
|
||||
}
|
||||
elif swt == "stack":
|
||||
return {
|
||||
"stack": blockData["rtdd_sws"],
|
||||
}
|
||||
except:
|
||||
pass
|
||||
return None
|
||||
|
||||
def clearSwitchRecord(self, key, playerId, pos, dim):
|
||||
"""
|
||||
清除工具方块的记录数据(内存+方块实体数据)。
|
||||
"""
|
||||
self.switchRecord.pop(key, None)
|
||||
self._writeBlockData(dim, pos, rtdd_swt="", rtdd_swc=0, rtdd_swi="", rtdd_sws=[])
|
||||
|
||||
# ============================================================================
|
||||
# 拆方块处理
|
||||
|
||||
Reference in new issue
Block a user