# -*- coding: utf-8 -*- """ ================================================================================ 右键拦截白名单数据(共享,客户端/服务端共用)—— 自动派生版 ================================================================================ 【作用】 统一管理"手持物品右键功能方块"时, 需要【提前取消该物品默认行为 (右键吃/放置)】的精确组合。客户端 ClientFeatureDispatcher 用它提前 cancel/ret 消除闪烁; 服务端 FeatureDispatcher 读同一份, 保持一致。 【为什么需要】 不精确拦截会造成两种问题: 1. 宽泛拦截(以前): 手持任意方块右键"任何功能方块"就取消放置 -> 正常放置失效 2. 不拦截: 手持南瓜派右键盘子时, 原版先触发"吃/放"前摇, 由服务端取消就"闪一下" 因此只对"手持的方块物品 与 被点的功能方块 存在右键转换关系"的组合拦截, 其余一律放行 (一一对应)。 【自动派生(核心)】 各功能分类的"右键转换"规则都写在各自的 *Data.py 里 (如 ChaoguoData 的 SWITCH_RULES / ITEM_USE_ON_RULES)。本模块在 import 时【直接读取这些 Data 模块的规则表】, 自动抽出所有 (手持方块物品, 被点功能方块) 的转换对。 —— 这样未来新增/修改任一菜谱, 白名单自动同步, 永不会漏、永不过时。 【集合】 ITEM_USE_ON_CANCEL : set of (手持item, 被点block) 仅这两者匹配才取消 ITEM_USE_ON_CANCEL_BY_ITEM : set of 手持item 只看手持item即可取消 SUSHI_BLOCKS : 寿司方块物品集合(用于交叉取消, 见说明) COATING_ITEMS : 裹粉生食材集合(右键面粉块时取消) ================================================================================ """ # ============================================================================ # 一、导入各功能分类"手持物品右键方块表面"的规则数据符号 # 只扫【ITEM_USE_ON_RULES】(surface 字段) —— 这些才走 ServerItemUseOnEvent # -> handleItemUseOn, 是客户端 ClientItemUseOnEvent 应拦截的组合。 # 注意: 绝对不要扫 SWITCH_RULES / *_SWITCHES 等(本体现在, 走 ServerBlockUseEvent # -> handleBlockUse), 若扫进来客户端拦截会吃掉整个右键, 导致"右键什么都不发生"。 # 注: 本项目无 __init__.py, 用与各 Service 相同的 `from ..XxxData import ...` # 直接导入符号, 而非 import 模块对象。 # ============================================================================ # 每个条目: (规则表内容) —— 规则表 list[dict], 字段含 "item" + "surface"/"source" _ALL_RULE_TABLES = [] def _collect_all(): """遍历 _ALL_RULE_TABLES, 汇总全部 (手持item, 被点surface方块) 组合。 只取 "surface"(手持物品右键方块表面) 与 "source"(盘子转换的被点方块), 不取 "block"(本体现在右键, 由服务端 handleBlockUse 处理)。""" pairs = set() for value in _ALL_RULE_TABLES: for rule in _as_list(value): if not isinstance(rule, dict): continue item = rule.get("item") if not item or not isinstance(item, basestring): continue if item.startswith("*"): continue for blkf in ("surface", "source"): blk = rule.get(blkf) if isinstance(blk, basestring) and blk: pairs.add((item, blk)) return pairs # ---- 面食.甜食: 手持生食/面饼/面粉 右键 烤炉/木碗/蒸笼 (itemUseOn) ---- try: from ..mianshi.MianshiData import ITEM_USE_ON_RULES as MIANSHI_USON _ALL_RULE_TABLES.append(MIANSHI_USON) except Exception: pass # ---- 炒锅: 盖饭双向 + 蛋炒饭 (itemUseOn, surface=米饭/成品菜) ---- try: from ..chaoguo.ChaoguoData import ITEM_USE_ON_RULES as CHAOGUO_USON _ALL_RULE_TABLES.append(CHAOGUO_USON) except Exception: pass # ---- 汤锅: 手持锅态汤右键 熟面条 (itemUseOn) ---- try: from ..tangguo.TangguoData import ITEM_USE_ON_RULES as TANGGUO_USON _ALL_RULE_TABLES.append(TANGGUO_USON) except Exception: pass # ---- 原版放置/盘子转换 (itemUseOn, surface=相邻放置 / source=盘子) ---- try: from ..yuanbanfangzhi.YuanbanData import ( ITEM_USE_ON_RULES as YUANBAN_USON, PLATE_RULES, ) _ALL_RULE_TABLES.append(YUANBAN_USON) _ALL_RULE_TABLES.append(PLATE_RULES) except Exception: pass # ============================================================================ # 二、从规则表派生 (手持方块物品, 被点功能方块) 转换对 # ============================================================================ def _as_list(value): """RICE_PLANT 这类是单个 dict, 规则表是 list[dict], 统一转成 list。""" if isinstance(value, list): return value if isinstance(value, dict): return [value] return [] # ============================================================================ # 三、自动派生 + 少量"非规则表内联转换"的手工补充 # ============================================================================ # ---- 由各 Data 规则表自动派生 ---- AUTO_CANCEL = _collect_all() # ---- Chuju 锅铲/油罐 inline 转换(在 ChujuService.handleItemUseOn 内联, 不在数据表) ---- # 手持 锅铲/带油锅铲 右键 油罐(oilcan)/炒锅(wok) 蘸油/还油/上油 -> 取消默认 CHUJU_INLINE_CANCEL = { ("rtdd:spatula", "rtdd:oilcan"), # 锅铲蘸油罐 ("rtdd:spatula_oil", "rtdd:oilcan"), # 带油锅铲还油罐 ("rtdd:spatula_oil", "rtdd:wok"), # 带油锅铲给炒锅上油 } AUTO_CANCEL |= CHUJU_INLINE_CANCEL # ============================================================================ # 四、寿司: 手持任何寿司方块物品 右键自家寿司方块 取消默认放置 # (寿司的堆叠/取走/转换规则在 ShousiService 内联构建, 不在 Data 表, # 故此处手工列出寿司方块物品集合, 交叉生成 (块, 块) 组合) # ============================================================================ SUSHI_BLOCKS = { "rtdd:sushi_0", "rtdd:sushi_1", "rtdd:codsushi_1", "rtdd:codsushi_2", "rtdd:codsushi_3", "rtdd:codsushi_4", "rtdd:codsushi_5", "rtdd:codsushi_6", "rtdd:salmonsushi_1", "rtdd:salmonsushi_2", "rtdd:salmonsushi_3", "rtdd:salmonsushi_4", "rtdd:salmonsushi_5", "rtdd:salmonsushi_6", "rtdd:fishsushi_1", "rtdd:fishsushi_2", "rtdd:fishsushi_3", "rtdd:fishsushi_4", "rtdd:fishsushi_5", "rtdd:fishmonsushi_6", "rtdd:nigirisushi", "rtdd:sushipile_0", "rtdd:sushipile_1", "rtdd:sushipile_2", "rtdd:sushipile_3", "rtdd:sushipile_4", "rtdd:sushipile_5", "rtdd:nigirisushifishcod", "rtdd:nigirisushicod_2", "rtdd:nigirisushicod_3", "rtdd:nigirisushifishsalmon_1", "rtdd:nigirisushisalnom_2", "rtdd:nigirisushisalnom_3", "rtdd:nigirisushifish_1", "rtdd:nigirisushifish_2", "rtdd:nigirisushifish_3", "rtdd:squid_sushi", "rtdd:squidsushi_2", "rtdd:squidsushi_3", } SUSHI_CANCEL = set( (held, block) for held in SUSHI_BLOCKS for block in SUSHI_BLOCKS ) # ============================================================================ # 五、裹粉(Shicai COATING_RULES 是 item->drop 结构, 无 floor 字段, 需手工指定被点面块) # ============================================================================ COATING_ITEMS = { "rtdd:sashimi", # 生鱼片 "rtdd:lobster", # 龙虾 "minecraft:porkchop", # 生猪肉 "minecraft:chicken", # 生鸡肉 "minecraft:potato", # 生土豆 } COATING_CANCEL = set( (item, "rtdd:farineblock_3") for item in COATING_ITEMS ) # ============================================================================ # 六、汇总: 精确组合 ITEM_USE_ON_CANCEL = 自动派生 ∪ 寿司交叉 ∪ 裹粉 # ============================================================================ ITEM_USE_ON_CANCEL = AUTO_CANCEL | SUSHI_CANCEL | COATING_CANCEL # ============================================================================ # 七、纯手持物品取消: 只看手持item (不做方块匹配) # ============================================================================ # ---- 原版相邻放置(YuanbanService ITEM_USE_ON_RULES) + 水稻种植(Natural RICE_PLANT) ---- # 手持这些"非方块食品/种子"右键任意方块表面, 都在相邻空位摆放对应切配方块。 # 它们本身不是可放置方块物品(放的是另一块), 但右键时会默认"吃/用", 需取消。 PLACE_ITEMS = { "minecraft:chicken", "minecraft:salmon", "minecraft:cod", "minecraft:fish", "minecraft:carrot", "minecraft:potato", "rtdd:qingcai", "rtdd:scallions", "rtdd:rice_seeds", # 稻谷: 右键耕地相邻放置水稻苗(RICE_PLANT) } # ---- 总食用 手持直接吃 (Shiyongfood TRY_USE_RULES) ---- EAT_ITEMS = { "rtdd:rice_balls", # 饭团 "rtdd:boiled_egg", # 水煮蛋 "rtdd:beancurd", # 豆腐 } ITEM_USE_ON_CANCEL_BY_ITEM = PLACE_ITEMS | EAT_ITEMS # ============================================================================ # 八、自检输出(便于调试/核对派生是否完整) # ============================================================================ if __name__ == "__main__": print "=== 自动派生转换对 数量:", len(AUTO_CANCEL), "===" for _it, _bk in sorted(AUTO_CANCEL): print " ", _it, "->", _bk