Files
rtdd/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/service/InterceptData.py
T
2026-09-22 12:27:19 +08:00

293 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- 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 : 裹粉生食材集合(右键面粉块时取消)
================================================================================
"""
# ============================================================================
# 一、导入各功能分类的规则数据符号(纯常量, 无服务端 API 依赖, 客户端可安全 import)
# 逐个 try, 任一失败只跳过该模块, 不影响整体。
# 注: 本项目无 __init__.py, 用与各 Service 相同的 `from ..XxxData import ...`
# 直接导入符号, 而非 import 模块对象。
# ============================================================================
# 每个条目: (规则表内容) —— 规则表可能是 list[dict] 或单个 dict(RICE_PLANT)
_ALL_RULE_TABLES = []
def _collect_all():
"""遍历 _ALL_RULE_TABLES, 汇总全部 (item, block) 转换对。"""
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 ("block", "source", "surface"):
blk = rule.get(blkf)
if isinstance(blk, basestring) and blk:
pairs.add((item, blk))
return pairs
# ---- 面食.甜食: 和面/饺子/包子/馍/煎饼卷 + 手持生食右键蒸笼/烤炉/木碗 ----
try:
from ..mianshi.MianshiData import (
SWITCH_RULES as MIANSHI_SWITCH,
ITEM_USE_ON_RULES as MIANSHI_USON,
)
_ALL_RULE_TABLES.append(MIANSHI_SWITCH)
_ALL_RULE_TABLES.append(MIANSHI_USON)
except Exception:
pass
# ---- 炒锅: 盖饭双向 + 蛋炒饭 ----
try:
from ..chaoguo.ChaoguoData import (
SWITCH_RULES as CHAOGUO_SWITCH,
ITEM_USE_ON_RULES as CHAOGUO_USON,
)
_ALL_RULE_TABLES.append(CHAOGUO_SWITCH)
_ALL_RULE_TABLES.append(CHAOGUO_USON)
except Exception:
pass
# ---- 汤锅: 放入食材/出锅 + 手持锅态汤右键熟面条 ----
try:
from ..tangguo.TangguoData import (
SWITCH_RULES as TANGGUO_SWITCH,
ITEM_USE_ON_RULES as TANGGUO_USON,
)
_ALL_RULE_TABLES.append(TANGGUO_SWITCH)
_ALL_RULE_TABLES.append(TANGGUO_USON)
except Exception:
pass
# ---- 油锅: 倒油/放料/出锅 ----
try:
from ..youguo.YouguoData import SWITCH_RULES as YOUGUO_SWITCH
_ALL_RULE_TABLES.append(YOUGUO_SWITCH)
except Exception:
pass
# ---- 厨具: 炉灶加木条/丸子机加料取料/蒸笼 ----
try:
from ..chuju.ChujuData import (
STOVE_RULES, MEATBALLMAKER_RULES, STEAMER_RULES,
)
_ALL_RULE_TABLES.append(STOVE_RULES)
_ALL_RULE_TABLES.append(MEATBALLMAKER_RULES)
_ALL_RULE_TABLES.append(STEAMER_RULES)
except Exception:
pass
# ---- 食材: 裹粉(COATING 无 floor 字段, 手工补) / 肉馅按压 ----
try:
from ..shicai.ShicaiData import COATING_RULES, MEAT_PRESS_RULES
_ALL_RULE_TABLES.append(COATING_RULES)
_ALL_RULE_TABLES.append(MEAT_PRESS_RULES)
except Exception:
pass
# ---- 原版放置/盘子转换 ----
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
# ---- 乡野自然: 柴火堆叠 + 水稻种植 ----
try:
from ..ziran.NaturalData import FIREWOOD_RULES, NATURAL_SWITCHES, RICE_PLANT
_ALL_RULE_TABLES.append(FIREWOOD_RULES)
_ALL_RULE_TABLES.append(NATURAL_SWITCHES)
_ALL_RULE_TABLES.append(RICE_PLANT)
except Exception:
pass
# ---- 家具家私: 水槽放脏盘/盘子架放盘/碗柜放碗/火炉等 ----
try:
from ..jiaju.FurnitureData import (
ARROWBARREL_RULES, FLUME_RULES, TRAYRACKS_RULES, CUPBOARD_RULES,
BOOKCASE_RULES, POTIONRACK_RULES, RECORDPLAYER_RULES,
TRASHBIN_RULES, FIREPLACE_RULES,
)
for _t in (ARROWBARREL_RULES, FLUME_RULES, TRAYRACKS_RULES,
CUPBOARD_RULES, BOOKCASE_RULES, POTIONRACK_RULES,
RECORDPLAYER_RULES, TRASHBIN_RULES, FIREPLACE_RULES):
_ALL_RULE_TABLES.append(_t)
except Exception:
pass
# ---- 死亡生物: 挂肉钩挂死牛/死猪/死羊 + 菜刀切配 ----
try:
from ..siwangshengwu.DeadmobData import DEADMOB_SWITCHES
_ALL_RULE_TABLES.append(DEADMOB_SWITCHES)
except Exception:
pass
# ---- 烧烤: 支杆上杆(手持生肉/死猪右键支杆) ----
try:
from ..shaokao.BarbecueData import BARBECUE_SWITCHES
_ALL_RULE_TABLES.append(BARBECUE_SWITCHES)
except Exception:
pass
# ---- 市场贸易: 手持果蔬放入售卖箱/鱼桶 ----
try:
from ..shichangmaoyi.MarketData import MARKET_SWITCHES
_ALL_RULE_TABLES.append(MARKET_SWITCHES)
except Exception:
pass
# ---- 动物养殖: 放蛋/喂食(手持原版鸡蛋/种子/胡萝卜等) ----
try:
from ..dongwuyangzhi.AnimalData import ANIMAL_SWITCHES
_ALL_RULE_TABLES.append(ANIMAL_SWITCHES)
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