ceshi 1
This commit is contained in:
1 parent
9eb9edbb8a
commit
b768ff1555
10 files changed
+618
-15
No files matched your search
+163
-3
@@ -41,6 +41,21 @@ comp = serverApi.GetEngineCompFactory() # 组件工厂
|
||||
# ---- 继承 BlueFox 框架的系统基类 ----
|
||||
from ...BlueFoxTools.SpecialFunciton.BlueFoxSystem import BlueFoxServerSystem
|
||||
from ...BlueFoxTools.ToolsConfig import LevelId
|
||||
from ...BlueFoxTools.ModConfig import MOD_NAME
|
||||
|
||||
# ---- 汤锅盛出自定义事件名(与客户端 ClientFeatureDispatcher TAKEOUT_EVENT 一致) ----
|
||||
TAKEOUT_EVENT = "TakeoutRequest"
|
||||
|
||||
# ---- 盖饭/蛋炒饭 自定义事件名(与客户端 GAI_FAN_EVENT 一致) ----
|
||||
GAI_FAN_EVENT = "GaifanRequest"
|
||||
|
||||
# ---- 通用"手持物品右键方块表面"转换请求(与客户端 ITEM_USE_ON_REQUEST 一致).
|
||||
# 用于修复"客户端提前 ret=True 吞掉 ServerItemUseOnEvent 导致 itemUseOn 转换
|
||||
# 点无反应"的问题(盖饭同款). 客户端对所有走 handleItemUseOn 的白名单组合,
|
||||
# ret 掉放置预览后显式 Notify 本事件, 服务端按 itemName 路由到相应服务.
|
||||
# 与 GaifanRequest 的区别: 本事件覆盖全部 itemUseOn 转换(面食/汤锅/装盘/
|
||||
# 相邻放置/厨具蘸油/寿司/裹粉/种水稻), 而非仅盖饭. ----
|
||||
ITEM_USE_ON_REQUEST = "ItemUseOnRequest"
|
||||
|
||||
# ---- 方块实体数据组件(计时持久化:记录开始时间戳,重启后继续计时) ----
|
||||
blockEntityDataComp = comp.CreateBlockEntityData(LevelId)
|
||||
@@ -196,6 +211,20 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
||||
self.ListenForEvent(serverApi.GetEngineNamespace(),
|
||||
serverApi.GetEngineSystemName(),
|
||||
"ItemUseOnAfterServerEvent", self, self.OnItemPlaceAfter)
|
||||
# 7. TakeoutRequest —— 客户端拦截(碗/盘,汤锅/炒锅/油锅成品)放置预览后, 显式请求服务端盛出。
|
||||
# 客户端系统 ClientFeatureDispatcher 用 NotifyToServer(TAKEOUT_EVENT) 发送,
|
||||
# 服务端以 MOD_NAME + 客户端系统名 监听该自定义事件。
|
||||
self.ListenForEvent(MOD_NAME, "ClientFeatureDispatcher",
|
||||
TAKEOUT_EVENT, self, self.OnTakeoutRequest)
|
||||
# 8. GaifanRequest —— 客户端拦截(成品菜/米饭,米饭/成品菜)盖饭放置预览后, 显式请求转换。
|
||||
# 同盛出: 必须显式触发, 否则客户端 ret=True 吞掉 ServerItemUseOnEvent, 盖饭无反应。
|
||||
self.ListenForEvent(MOD_NAME, "ClientFeatureDispatcher",
|
||||
GAI_FAN_EVENT, self, self.OnGaifanRequest)
|
||||
# 9. ItemUseOnRequest —— 客户端拦截其余全部 itemUseOn 转换(面食/汤锅/装盘/相邻放置/
|
||||
# 厨具蘸油/寿司/裹粉/种水稻)的放置预览后, 显式请求服务端执行对应 handleItemUseOn。
|
||||
# (与 GaifanRequest 同机制, 统一覆盖全部 itemUseOn 转换)
|
||||
self.ListenForEvent(MOD_NAME, "ClientFeatureDispatcher",
|
||||
ITEM_USE_ON_REQUEST, self, self.OnItemUseOnRequest)
|
||||
|
||||
def UnListenEvent(self):
|
||||
self.UnListenForEvent(serverApi.GetEngineNamespace(),
|
||||
@@ -216,6 +245,12 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
||||
self.UnListenForEvent(serverApi.GetEngineNamespace(),
|
||||
serverApi.GetEngineSystemName(),
|
||||
"ItemUseOnAfterServerEvent", self, self.OnItemPlaceAfter)
|
||||
self.UnListenForEvent(MOD_NAME, "ClientFeatureDispatcher",
|
||||
TAKEOUT_EVENT, self, self.OnTakeoutRequest)
|
||||
self.UnListenForEvent(MOD_NAME, "ClientFeatureDispatcher",
|
||||
GAI_FAN_EVENT, self, self.OnGaifanRequest)
|
||||
self.UnListenForEvent(MOD_NAME, "ClientFeatureDispatcher",
|
||||
ITEM_USE_ON_REQUEST, self, self.OnItemUseOnRequest)
|
||||
|
||||
# ============================================================================
|
||||
# 主入口1:玩家右键方块 → 按 blockOwner 路由到右键服务
|
||||
@@ -232,8 +267,15 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
||||
服务返回 False = 当前组合无匹配规则 → 交还默认行为
|
||||
"""
|
||||
blockName = args.get("blockName")
|
||||
playerId = args.get("playerId")
|
||||
# 手持物品名(用于区分空手/木碗/盘子)
|
||||
try:
|
||||
_itemDict = self.getCarriedItem(playerId)
|
||||
_handItem = _itemDict.get("newItemName") if _itemDict else "NONE"
|
||||
except Exception:
|
||||
_handItem = "NONE"
|
||||
services = self.blockOwnerAll.get(blockName)
|
||||
print "[FD-BlockUse]", blockName, "svcs:", ([s.__class__.__name__ for s in services] if services else "NONE")
|
||||
print "[FD-BlockUse-ENTER]", "player:", playerId, "hand:", _handItem, "block:", blockName, "svcs:", ([s.__class__.__name__ for s in services] if services else "NONE")
|
||||
if not services:
|
||||
# 这个方块不属于任何已注册的功能 → 交给原版/其他模组处理
|
||||
return
|
||||
@@ -242,9 +284,10 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
||||
handled = service.handleBlockUse(args)
|
||||
if handled:
|
||||
args['cancel'] = True
|
||||
playerId = args.get("playerId")
|
||||
self._cancelItemUse[playerId] = True
|
||||
print "[FD-BlockUse-DONE]", "player:", playerId, "hand:", _handItem, "block:", blockName, "svc:", service.__class__.__name__, "-> cancel=True, _cancelItemUse=True"
|
||||
return
|
||||
print "[FD-BlockUse-NOMATCH]", "player:", playerId, "hand:", _handItem, "block:", blockName, "-> 无匹配规则, 放行"
|
||||
|
||||
# ============================================================================
|
||||
# 主入口2:手持物品右键方块表面 → 按 itemUseOnOwner 路由到右键服务
|
||||
@@ -269,6 +312,7 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
||||
# (与 OnItemTryUse 消费标记取消"吃/喝"是同一模式。)
|
||||
if self._cancelItemUse.pop(playerId, False):
|
||||
args['ret'] = True
|
||||
print "[FD-ItemUseOn-CONSUME-CANCEL]", "player:", playerId, "item:", args.get("itemName"), "block:", args.get("blockName"), "-> ret=True 取消放置"
|
||||
return
|
||||
|
||||
itemName = args.get("itemName")
|
||||
@@ -301,8 +345,18 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
||||
# 例外: 当前服务本身就在被点方块的归属列表里(如 食材裹粉: 面粉块归
|
||||
# ShicaiService+面食服务 管辖, 手持生食材右键它时放行给 handleItemUseOn
|
||||
# 处理) 则继续尝试。
|
||||
# 【额外例外】服务声明了 ownsItemUseOn(itemName, clickedName) 且返回 True,
|
||||
# 说明该(手持物品,被点方块)组合明确由本服务的 itemUseOn 规则处理(如炒锅盖饭:
|
||||
# 成品菜/米饭尽管也被"总食用"登记为右键吃方块, 但盖饭转换应仍走 itemUseOn)。
|
||||
# 此时不因被点方块归属别的服务而跳过, 否则盖饭永不被触发。
|
||||
if clickedName and owners and service not in owners:
|
||||
continue
|
||||
_owns = None
|
||||
try:
|
||||
_owns = service.ownsItemUseOn(itemName, clickedName)
|
||||
except Exception:
|
||||
_owns = None
|
||||
if not _owns:
|
||||
continue
|
||||
|
||||
handled = service.handleItemUseOn(args)
|
||||
if handled:
|
||||
@@ -348,11 +402,117 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
||||
return
|
||||
if not blockName:
|
||||
return
|
||||
print "[FD-Placed-AFTER]", "player:", playerId, "placedBlock:", blockName, "targetPos:", targetPos
|
||||
# 落点是计时源方块 → 带放置者启动(判断营火 + 谁放提示发给谁)
|
||||
service = self.timerOwner.get(blockName)
|
||||
if service and hasattr(service, "startTimer"):
|
||||
service.startTimer(dim, targetPos, blockName, playerId)
|
||||
|
||||
# ============================================================================
|
||||
# 主入口2.6:客户端显式触发的"盛出"请求(汤锅 take_out 专用,消闪方案)
|
||||
# ============================================================================
|
||||
|
||||
def OnTakeoutRequest(self, args):
|
||||
"""
|
||||
客户端 ClientFeatureDispatcher 在拦截(碗/盘, 汤锅成品)放置预览后,
|
||||
显式 NotifyToServer 发来的盛出请求。因为客户端已 ret=True 把该组合的
|
||||
ServerBlockUseEvent 吞掉(消闪), 所以盛出逻辑必须在这里手动补齐。
|
||||
|
||||
与服务器普通右键一致, 需要校验: 别再重复执行, 关键落在 handleTakeoutRequest
|
||||
里"落点仍是成品方块才执行"的守卫上(防客户端事件与服务端事件双份)。
|
||||
"""
|
||||
playerId = args.get("playerId")
|
||||
x, y, z = args.get("x"), args.get("y"), args.get("z")
|
||||
blockName = args.get("blockName")
|
||||
itemName = args.get("itemName")
|
||||
if not (playerId and x is not None and y is not None and z is not None and blockName):
|
||||
return
|
||||
try:
|
||||
dim = comp.CreateDimension(playerId).GetEntityDimensionId()
|
||||
except Exception:
|
||||
return
|
||||
services = self.blockOwnerAll.get(blockName)
|
||||
if not services:
|
||||
return
|
||||
for service in services:
|
||||
if hasattr(service, "handleTakeoutRequest"):
|
||||
# handleTakeoutRequest 内部已校验"落点仍是成品方块" + 冷却, 防双份。
|
||||
# 盛出后引擎"把手持碗/盘放到已变空锅"的多放置闪烁由客户端 CD(1.5秒)
|
||||
# 在客户端吞掉, 服务端不再设 _cancelItemUse(否则标记残留会吞掉玩家
|
||||
# 下一次真实的 ServerItemUseOnEvent, 影响其它操作)。
|
||||
service.handleTakeoutRequest(playerId, blockName, itemName, dim, (x, y, z))
|
||||
return
|
||||
print "[FD-TakeoutRequest-NO-HANDLER]", blockName
|
||||
|
||||
def OnGaifanRequest(self, args):
|
||||
"""
|
||||
客户端 ClientFeatureDispatcher 在拦截(成品菜/米饭,米饭/成品菜)放置预览后,
|
||||
显式 NotifyToServer 发来的盖饭/蛋炒饭转换请求。客户端已 ret=True 把该组合的
|
||||
ServerItemUseOnEvent 吞掉(消闪), 这里必须显式补齐转换逻辑(否则盖饭"点无反应")。
|
||||
构造 itemUseOn 所需的 args, 按 itemName 路由到 itemUseOn 服务(ChaoguoService)。
|
||||
"""
|
||||
playerId = args.get("playerId")
|
||||
x, y, z = args.get("x"), args.get("y"), args.get("z")
|
||||
itemName = args.get("itemName")
|
||||
if not (playerId and x is not None and y is not None and z is not None and itemName):
|
||||
return
|
||||
services = self.itemUseOnAll.get(itemName)
|
||||
if not services:
|
||||
print "[FD-GaifanRequest-NO-SVC]", itemName
|
||||
return
|
||||
# 复用服务端的 itemUseOn 参数结构(handleItemUseOn 读取 itemName/playerId/x/y/z)
|
||||
useOnArgs = {
|
||||
"itemName": itemName,
|
||||
"playerId": playerId,
|
||||
"entityId": playerId,
|
||||
"x": x, "y": y, "z": z,
|
||||
"blockName": args.get("blockName"),
|
||||
}
|
||||
for service in services:
|
||||
if hasattr(service, "handleItemUseOn"):
|
||||
# 盖饭是本方块原位转换成盖饭(消耗手持成品菜/米饭), 不是"放置手持方块",
|
||||
# 因此不设 _cancelItemUse —— 否则标记残留会吞掉玩家下一次真实的 itemUseOn.
|
||||
handled = service.handleItemUseOn(useOnArgs)
|
||||
if handled:
|
||||
return
|
||||
print "[FD-GaifanRequest-NO-HANDLER]", itemName
|
||||
|
||||
def OnItemUseOnRequest(self, args):
|
||||
"""
|
||||
客户端 ClientFeatureDispatcher 在拦截【所有走 handleItemUseOn 的 itemUseOn 转换】
|
||||
(面食/汤锅/装盘/相邻放置/厨具蘸油/寿司/裹粉/种水稻) 放置预览后, 显式 NotifyToServer
|
||||
发来的通用转换请求. 因为客户端已 ret=True 吞掉该组合的 ServerItemUseOnEvent(消闪),
|
||||
服务端原本会被吞掉的 itemUseOn 转换在这里补齐路由(与 OnGaifanRequest 同机制).
|
||||
|
||||
按 itemName 路由到 itemUseOnAll 里的服务(可能有多个, 如 裹粉Shicai + 原版放置Yuanban
|
||||
都处理 土豆/鸡肉/猪肉, 逐个 fallback, 第一个返回 True 的处理成功).
|
||||
注意: 各服务 handleItemUseOn 内部自带 checkCooldown(同坐标/同物品), 即使与真实的
|
||||
ServerItemUseOnEvent 重复触发, 冷却也会拦截第二次, 不会双重消耗/双重转换.
|
||||
"""
|
||||
playerId = args.get("playerId")
|
||||
x, y, z = args.get("x"), args.get("y"), args.get("z")
|
||||
itemName = args.get("itemName")
|
||||
if not (playerId and x is not None and y is not None and z is not None and itemName):
|
||||
return
|
||||
services = self.itemUseOnAll.get(itemName)
|
||||
if not services:
|
||||
print "[FD-ItemUseOnRequest-NO-SVC]", itemName
|
||||
return
|
||||
# 复用服务端的 itemUseOn 参数结构(handleItemUseOn 读取 itemName/playerId/x/y/z)
|
||||
useOnArgs = {
|
||||
"itemName": itemName,
|
||||
"playerId": playerId,
|
||||
"entityId": playerId,
|
||||
"x": x, "y": y, "z": z,
|
||||
"blockName": args.get("blockName"),
|
||||
}
|
||||
for service in services:
|
||||
if hasattr(service, "handleItemUseOn"):
|
||||
handled = service.handleItemUseOn(useOnArgs)
|
||||
if handled:
|
||||
return
|
||||
print "[FD-ItemUseOnRequest-NO-HANDLER]", itemName
|
||||
|
||||
# ============================================================================
|
||||
# 主入口3:拦截物品使用(防止喝药水/吃食物等默认行为)
|
||||
# ============================================================================
|
||||
|
||||
Reference in new issue
Block a user