This commit is contained in:
wenhe committed 2026-09-11 11:17:45 +08:00
1 parent 4e7b9abee5
commit 052e4844b2
26 files changed
+1053 -41

No files matched your search

@@ -59,6 +59,7 @@ class FeatureDispatcher(BlueFoxServerSystem):
# ---- 类级共享路由表(用类变量,任何实例都能读写) ----
blockOwner = {}
blockSet = set()
blockOwnerAll = {} # 方块名 -> [服务...]: 同一方块可被多个服务注册(按注册顺序), 逐个 fallback
itemUseOnOwner = {}
itemUseOnSet = set()
itemUseOnAll = {} # 物品名 -> [服务...]: 同一物品可被多个服务注册(按注册顺序), 逐个 fallback
@@ -81,12 +82,14 @@ class FeatureDispatcher(BlueFoxServerSystem):
def register(cls, service):
"""
右键服务初始化时调用:把管辖的"右键方块"和"手持物品右键方块表面"注册进路由表。
同一方块/物品只会归属最后一个注册的服务(一般不会冲突)。
同一方块/物品可被多个服务注册(如 面粉块: 食材裹粉去重 + 面食和面),
按注册顺序追加, OnBlockUse/OnItemUseOn 逐个 fallback(第一个返回 True 的处理)。
"""
# 右键方块路由:方块名 → 服务
# 右键方块路由:方块名 → 服务列表
for block in service.getFeatureBlocks():
cls.blockOwner[block] = service
cls.blockSet.add(block)
cls.blockOwnerAll.setdefault(block, []).append(service)
# 手持物品右键方块表面路由:物品名 → 服务
for itemName in service.getItemUseOnRules():
@@ -189,23 +192,27 @@ class FeatureDispatcher(BlueFoxServerSystem):
def OnBlockUse(self, args):
"""
玩家右键方块时触发。
用被右键的方块名 O(1) 定位到唯一的功能服务,转发给它的 handleBlockUse。
用被右键的方块名 O(1) 定位到注册它的所有功能服务(blockOwnerAll, 按注册顺序),
逐个尝试 handleBlockUse, 第一个返回 True 的服务处理成功(多服务 fallback,
如 面粉块: 食材服务先试(裹粉去重, 空手无规则返回False) -> 面食服务和面)。
服务返回 True = 处理成功 → 取消默认行为,并标记拦截下一次物品使用
服务返回 False = 当前组合无匹配规则 → 交还默认行为
"""
blockName = args.get("blockName")
service = self.blockOwner.get(blockName)
print "[FD-BlockUse]", blockName, "svc:", (service.__class__.__name__ if service else "NONE")
if not service:
services = self.blockOwnerAll.get(blockName)
print "[FD-BlockUse]", blockName, "svcs:", ([s.__class__.__name__ for s in services] if services else "NONE")
if not services:
# 这个方块不属于任何已注册的功能 → 交给原版/其他模组处理
return
handled = service.handleBlockUse(args)
if handled:
args['cancel'] = True
playerId = args.get("playerId")
self._cancelItemUse[playerId] = True
for service in services:
handled = service.handleBlockUse(args)
if handled:
args['cancel'] = True
playerId = args.get("playerId")
self._cancelItemUse[playerId] = True
return
# ============================================================================
# 主入口2:手持物品右键方块表面 → 按 itemUseOnOwner 路由到右键服务
@@ -229,7 +236,7 @@ class FeatureDispatcher(BlueFoxServerSystem):
print "[FD-ItemUseOn]", itemName, "svcs:", [s.__class__.__name__ for s in services]
playerId = args.get("playerId") or args.get("entityId")
# 被点方块(用于去重: 该方块归哪个右键服务管辖)
# 被点方块(用于去重: 该方块归哪些右键服务管辖)
clickedName = None
try:
dim = comp.CreateDimension(playerId).GetEntityDimensionId()
@@ -239,15 +246,16 @@ class FeatureDispatcher(BlueFoxServerSystem):
except Exception:
pass
owners = self.blockOwnerAll.get(clickedName) if clickedName else None
for service in services:
# 被点方块属于某个"右键方块"服务的管辖(条箱/挂肉钩/锅具等) → 该方块右键由
# 被点方块属于某些"右键方块"服务的管辖(条箱/挂肉钩/锅具等) → 该方块右键由
# ServerBlockUseEvent 处理(放入/挂鱼/做菜), 跳过本服务的 itemUseOn,
# 避免与方块右键逻辑重复(如手持鲑鱼右键条箱应放入而非放置死鲑鱼)。
# 例外: 被点方块的 owner 就是当前服务自己(如 食材裹粉: 面粉块归 ShicaiService
# 管辖, 手持生食材右键它时放行给 handleItemUseOn 处理) 则继续尝试。
if clickedName and clickedName in self.blockOwner:
if self.blockOwner[clickedName] is not service:
continue
# 例外: 当前服务本身就在被点方块的归属列表里(如 食材裹粉: 面粉块归
# ShicaiService+面食服务 管辖, 手持生食材右键它时放行给 handleItemUseOn
# 处理) 则继续尝试。
if clickedName and owners and service not in owners:
continue
handled = service.handleItemUseOn(args)
if handled:
@@ -314,11 +322,13 @@ class FeatureDispatcher(BlueFoxServerSystem):
blockName = args.get("fullName") or args.get("blockName")
args["blockName"] = blockName # 统一成 blockName 字段, 服务内部直接用
# 1. 优先: 归属的右键服务实现了 handleDestroy → 交给服务处理
service = self.blockOwner.get(blockName)
if service and hasattr(service, "handleDestroy"):
if service.handleDestroy(args):
return
# 1. 优先: 归属的右键服务实现了 handleDestroy → 交给服务处理(逐个 fallback)
services = self.blockOwnerAll.get(blockName)
if services:
for service in services:
if hasattr(service, "handleDestroy"):
if service.handleDestroy(args):
return
# 2. 静态映射: 放置的死鱼/生鸡肉 → 原版生食材
itemName = self.DESTROY_DROP.get(blockName)