From a9099b604426691c39e4e1a41236baf9bf85adc8 Mon Sep 17 00:00:00 2001 From: wenhe <1046926120@qq.com> Date: Wed, 29 Jul 2026 16:03:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B9=E5=9D=97=E8=BD=AC=E6=8D=A2=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=20ceshi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ceshi/BlockSwitchData.py | 1291 +++++++++++++++++ .../ceshi/service/CookingService.py | 197 ++- 2 files changed, 1466 insertions(+), 22 deletions(-) create mode 100644 behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/ceshi/BlockSwitchData.py diff --git a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/ceshi/BlockSwitchData.py b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/ceshi/BlockSwitchData.py new file mode 100644 index 0000000..264baee --- /dev/null +++ b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/ceshi/BlockSwitchData.py @@ -0,0 +1,1291 @@ +# -*- coding: utf-8 -*- +""" +工具方块切换规则数据 +==================== +所有"右键方块→消耗物品→替换方块"的工具切换规则都在这里。 + +与 RecipeData.py 的关系: + RecipeData.py = 做菜配方(食材+锅 → 菜) + BlockSwitchData.py = 工具切换(箭桶、挂肉钩、水槽、盘子架、药水架、书柜等) + +CookingService 启动时会自动把两边的数据合并成一份字典,O(1) 查找。 + +字段说明: + source: 被右键的方块ID(必填) + item: 玩家手里必须拿的物品,None=空手也行 + target: 替换成什么方块 + consume: 消耗物品数量,0=不消耗(默认1) + giveItem: 额外给玩家什么物品,None=取回记录的物品 + type: "switch"=工具切换, "timer"=计时自动转换 + record: True=需要记录放入的物品,取回时原样返还 + recordType: "count"=记录一种物品+数量, "stack"=后放先取堆栈 + maxCount: 记录型最多存多少(箭桶32只、盘子架5个等) + time: 计时型转换需要多少秒 + tool: 特定工具要求(如"剑") +""" + +BLOCK_SWITCHES = [ + + # ============================================================ + # 一、箭桶 + # ============================================================ + { + "source": "rtdd:arrowbarrel_0", + "item": "minecraft:arrow", + "target": "rtdd:arrowbarrel_1", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "count", + "maxCount": 32, + "giveItem": None, + }, + { + "source": "rtdd:arrowbarrel_1", + "item": None, + "target": "rtdd:arrowbarrel_0", + "consume": 0, + "type": "switch", + "record": True, + "recordType": "count", + "giveItem": None, + }, + + # ============================================================ + # 二、纺纱机 + # ============================================================ + { + "source": "rtdd:b_110", + "item": None, + "target": "rtdd:spinner", + "consume": 0, + "type": "switch", + "giveItem": None, + }, + + # ============================================================ + # 三、售卖箱 → 鲑鱼箱 + # ============================================================ + { + "source": "rtdd:clothbox_1", + "item": "minecraft:salmon", + "target": "rtdd:b_30", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:clothbox_2", + "item": "minecraft:salmon", + "target": "rtdd:b_30", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:b_30", + "item": None, + "target": "rtdd:clothbox_2", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:salmon", + }, + + # ============================================================ + # 四、烧烤架 + # ============================================================ + { + "source": "rtdd:barbecuegrill_0", + "item": "minecraft:flint_and_steel", + "target": "rtdd:barbecuegrill_1", + "consume": 0, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:barbecuegrill_0", + "item": "minecraft:fire_charge", + "target": "rtdd:barbecuegrill_1", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:barbecuegrill_1", + "item": "minecraft:water_bucket", + "target": "rtdd:barbecuegrill_0", + "consume": 1, + "type": "switch", + "giveItem": "minecraft:bucket", + }, + + # ============================================================ + # 五、炉灶 + # ============================================================ + { + "source": "rtdd:stove", + "item": "rtdd:barwood", + "target": "rtdd:stove_1", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:stove", + "item": "rtdd:b_15", + "target": "rtdd:stove_1", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:stove_1", + "item": "minecraft:flint_and_steel", + "target": "rtdd:stove_2", + "consume": 0, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:stove_1", + "item": "minecraft:fire_charge", + "target": "rtdd:stove_2", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + + # ============================================================ + # 六、挂肉钩 - 牛 + # 正向:挂牛 → 拿剑切肉 → 切完回空钩 + # 逆向:右键退回死牛 + # ============================================================ + { + "source": "rtdd:meathook", + "item": "rtdd:dead_cow", + "target": "rtdd:cow_0", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:cow_0", + "item": "minecraft:iron_sword", + "target": "rtdd:cow_1", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:beef", + "tool": "sword", + }, + { + "source": "rtdd:cow_1", + "item": "minecraft:iron_sword", + "target": "rtdd:cow_2", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:beef", + "tool": "sword", + }, + { + "source": "rtdd:cow_2", + "item": "minecraft:iron_sword", + "target": "rtdd:cow_3", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:beef", + "tool": "sword", + }, + { + "source": "rtdd:cow_3", + "item": "minecraft:iron_sword", + "target": "rtdd:meathook", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:beef", + "tool": "sword", + }, + # 逆向退回 + { + "source": "rtdd:cow_3", + "item": None, + "target": "rtdd:cow_2", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:dead_cow", + }, + { + "source": "rtdd:cow_2", + "item": None, + "target": "rtdd:cow_1", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:dead_cow", + }, + { + "source": "rtdd:cow_1", + "item": None, + "target": "rtdd:cow_0", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:dead_cow", + }, + { + "source": "rtdd:cow_0", + "item": None, + "target": "rtdd:meathook", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:dead_cow", + }, + + # ============================================================ + # 七、晾干架 + # ============================================================ + { + "source": "rtdd:dryingrack", + "item": None, + "target": "rtdd:dryingrack_1", + "consume": 0, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:dryingrack_1", + "item": None, + "target": "rtdd:dryingrack_2", + "consume": 0, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:dryingrack_2", + "item": None, + "target": "rtdd:dryingrack", + "consume": 0, + "type": "switch", + "giveItem": None, + }, + + # ============================================================ + # 八、挂肉钩 - 鱼(生鱼晾干) + # ============================================================ + { + "source": "rtdd:meathook", + "item": "minecraft:fish", + "target": "rtdd:fish_1", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:fish_1", + "item": "minecraft:fish", + "target": "rtdd:fish_2", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + # 鱼_2 → 空钩: 时间自动转换,然后右键获得熟鱼 + { + "source": "rtdd:fish_2", + "item": None, + "target": "rtdd:meathook", + "consume": 0, + "type": "timer", + "time": 300, + "giveItem": "minecraft:cooked_fish", + }, + # 逆向退回 + { + "source": "rtdd:fish_2", + "item": None, + "target": "rtdd:fish_1", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:fish", + }, + { + "source": "rtdd:fish_1", + "item": None, + "target": "rtdd:meathook", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:fish", + }, + + # ============================================================ + # 九、挂肉钩 - 鳕鱼 + # ============================================================ + { + "source": "rtdd:meathook", + "item": "minecraft:cod", + "target": "rtdd:meathookcod_1", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:meathookcod_1", + "item": "minecraft:cod", + "target": "rtdd:meathookcod_2", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:meathookcod_2", + "item": None, + "target": "rtdd:meathookcoddry", + "consume": 0, + "type": "timer", + "time": 300, + "giveItem": None, + }, + { + "source": "rtdd:meathookcoddry", + "item": None, + "target": "rtdd:meathook", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:cooked_cod", + }, + # 逆向退回 + { + "source": "rtdd:meathookcod_2", + "item": None, + "target": "rtdd:meathookcod_1", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:cod", + }, + { + "source": "rtdd:meathookcod_1", + "item": None, + "target": "rtdd:meathook", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:cod", + }, + + # ============================================================ + # 十、挂肉钩 - 猪 + # ============================================================ + { + "source": "rtdd:meathook", + "item": "rtdd:dead_pig", + "target": "rtdd:pig_0", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:pig_0", + "item": "minecraft:iron_sword", + "target": "rtdd:pig_1", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:porkchop", + "tool": "sword", + }, + { + "source": "rtdd:pig_1", + "item": "minecraft:iron_sword", + "target": "rtdd:pig_2", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:porkchop", + "tool": "sword", + }, + { + "source": "rtdd:pig_2", + "item": "minecraft:iron_sword", + "target": "rtdd:pig_3", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:porkchop", + "tool": "sword", + }, + { + "source": "rtdd:pig_3", + "item": "minecraft:iron_sword", + "target": "rtdd:meathook", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:porkchop", + "tool": "sword", + }, + # 逆向退回 + { + "source": "rtdd:pig_3", + "item": None, + "target": "rtdd:pig_2", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:dead_pig", + }, + { + "source": "rtdd:pig_2", + "item": None, + "target": "rtdd:pig_1", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:dead_pig", + }, + { + "source": "rtdd:pig_1", + "item": None, + "target": "rtdd:pig_0", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:dead_pig", + }, + { + "source": "rtdd:pig_0", + "item": None, + "target": "rtdd:meathook", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:dead_pig", + }, + + # ============================================================ + # 十一、挂肉钩 - 羊 + # ============================================================ + { + "source": "rtdd:meathook", + "item": "rtdd:dead_sheep", + "target": "rtdd:sheep", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:sheep", + "item": "minecraft:iron_sword", + "target": "rtdd:sheep_1", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:mutton", + "tool": "sword", + }, + { + "source": "rtdd:sheep_1", + "item": "minecraft:iron_sword", + "target": "rtdd:sheep_2", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:mutton", + "tool": "sword", + }, + { + "source": "rtdd:sheep_2", + "item": "minecraft:iron_sword", + "target": "rtdd:sheep_3", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:mutton", + "tool": "sword", + }, + { + "source": "rtdd:sheep_3", + "item": "minecraft:iron_sword", + "target": "rtdd:meathook", + "consume": 0, + "type": "switch", + "giveItem": "minecraft:mutton", + "tool": "sword", + }, + # 逆向退回 + { + "source": "rtdd:sheep_3", + "item": None, + "target": "rtdd:sheep_2", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:dead_sheep", + }, + { + "source": "rtdd:sheep_2", + "item": None, + "target": "rtdd:sheep_1", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:dead_sheep", + }, + { + "source": "rtdd:sheep_1", + "item": None, + "target": "rtdd:sheep", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:dead_sheep", + }, + { + "source": "rtdd:sheep", + "item": None, + "target": "rtdd:meathook", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:dead_sheep", + }, + + # ============================================================ + # 十二、挂肉钩 - 鲑鱼晾晒系统 + # 路线A(只挂1条): 空钩 → 7(鲜) → 9(干) → 空钩 + # 路线B(挂2条): 空钩 → 7(鲜) → 8(鲜) → 10(干) → 9(干) → 空钩 + # ============================================================ + # —— 挂鱼 ---- + { + "source": "rtdd:meathook", + "item": "rtdd:killfish_0", + "target": "rtdd:hang_meat_hooks_1", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + # ---- 挂第二条 ---- + { + "source": "rtdd:hang_meat_hooks_1", + "item": "rtdd:killfish_0", + "target": "rtdd:hang_meat_hooks_2", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + # ---- 单条晾干 ---- + { + "source": "rtdd:hang_meat_hooks_1", + "item": None, + "target": "rtdd:hang_meat_hooks_3", + "consume": 0, + "type": "timer", + "time": 300, + "giveItem": None, + }, + # ---- 两条晾干 ---- + { + "source": "rtdd:hang_meat_hooks_2", + "item": None, + "target": "rtdd:hang_meat_hooks_4", + "consume": 0, + "type": "timer", + "time": 300, + "giveItem": None, + }, + # ---- 取走单条干 ---- + { + "source": "rtdd:hang_meat_hooks_3", + "item": None, + "target": "rtdd:meathook", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:dried_salmon", + }, + # ---- 取走第一条干(两条变一条) ---- + { + "source": "rtdd:hang_meat_hooks_4", + "item": None, + "target": "rtdd:hang_meat_hooks_3", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:dried_salmon", + }, + # ---- 退单条鲜 ---- + { + "source": "rtdd:hang_meat_hooks_1", + "item": None, + "target": "rtdd:meathook", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:killfish_0", + }, + # ---- 退一条鲜(两条变一条) ---- + { + "source": "rtdd:hang_meat_hooks_2", + "item": None, + "target": "rtdd:hang_meat_hooks_1", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:killfish_0", + }, + # ---- 退单条干 ---- + { + "source": "rtdd:hang_meat_hooks_3", + "item": None, + "target": "rtdd:meathook", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:killfish_0", + }, + # ---- 退一条干 ---- + { + "source": "rtdd:hang_meat_hooks_4", + "item": None, + "target": "rtdd:hang_meat_hooks_3", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:killfish_0", + }, + + # ============================================================ + # 十三、水槽系统 + # ============================================================ + # ---- 加水/取水 ---- + { + "source": "rtdd:flume_0", + "item": None, + "target": "rtdd:flume_1", + "consume": 0, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:flume_1", + "item": "minecraft:water_bucket", + "target": "rtdd:flume_0", + "consume": 1, + "type": "switch", + "giveItem": "minecraft:water_bucket", + }, + # ---- 放脏盘子 ---- + { + "source": "rtdd:flume_0", + "item": "rtdd:plate_0a", + "target": "rtdd:flume_2", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:flume_2", + "item": "rtdd:plate_0a", + "target": "rtdd:flume_3", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:flume_3", + "item": "rtdd:plate_0a", + "target": "rtdd:flume_4", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:flume_4", + "item": "rtdd:plate_0a", + "target": "rtdd:flume_5", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + # ---- 取回脏盘子 ---- + { + "source": "rtdd:flume_5", + "item": None, + "target": "rtdd:flume_4", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:plate_0a", + }, + { + "source": "rtdd:flume_4", + "item": None, + "target": "rtdd:flume_3", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:plate_0a", + }, + { + "source": "rtdd:flume_3", + "item": None, + "target": "rtdd:flume_2", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:plate_0a", + }, + { + "source": "rtdd:flume_2", + "item": None, + "target": "rtdd:flume_0", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:plate_0a", + }, + + # ============================================================ + # 十四、盘子架系统 + # ============================================================ + { + "source": "rtdd:trayracks_1", + "item": "rtdd:plate_0", + "target": "rtdd:trayracks_2", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:trayracks_2", + "item": "rtdd:plate_0", + "target": "rtdd:trayracks_3", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:trayracks_3", + "item": "rtdd:plate_0", + "target": "rtdd:trayracks_4", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:trayracks_4", + "item": "rtdd:plate_0", + "target": "rtdd:trayracks_5", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + { + "source": "rtdd:trayracks_5", + "item": "rtdd:plate_0", + "target": "rtdd:trayracks_6", + "consume": 1, + "type": "switch", + "giveItem": None, + }, + # ---- 取回盘子 ---- + { + "source": "rtdd:trayracks_6", + "item": None, + "target": "rtdd:trayracks_5", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:plate_0", + }, + { + "source": "rtdd:trayracks_5", + "item": None, + "target": "rtdd:trayracks_4", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:plate_0", + }, + { + "source": "rtdd:trayracks_4", + "item": None, + "target": "rtdd:trayracks_3", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:plate_0", + }, + { + "source": "rtdd:trayracks_3", + "item": None, + "target": "rtdd:trayracks_2", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:plate_0", + }, + { + "source": "rtdd:trayracks_2", + "item": None, + "target": "rtdd:trayracks_1", + "consume": 0, + "type": "switch", + "giveItem": "rtdd:plate_0", + }, + + # ============================================================ + # 十五、药水架系统(后放先取) + # ============================================================ + { + "source": "rtdd:lotion_0", + "item": "minecraft:potion", + "target": "rtdd:lotion_1", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 3, + "giveItem": None, + }, + { + "source": "rtdd:lotion_1", + "item": "minecraft:potion", + "target": "rtdd:lotion_2", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 3, + "giveItem": None, + }, + { + "source": "rtdd:lotion_2", + "item": "minecraft:potion", + "target": "rtdd:lotion_3", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 3, + "giveItem": None, + }, + # ---- 取回(后放先取) ---- + { + "source": "rtdd:lotion_3", + "item": None, + "target": "rtdd:lotion_2", + "consume": 0, + "type": "switch", + "record": True, + "recordType": "stack", + "giveItem": None, + }, + { + "source": "rtdd:lotion_2", + "item": None, + "target": "rtdd:lotion_1", + "consume": 0, + "type": "switch", + "record": True, + "recordType": "stack", + "giveItem": None, + }, + { + "source": "rtdd:lotion_1", + "item": None, + "target": "rtdd:lotion_0", + "consume": 0, + "type": "switch", + "record": True, + "recordType": "stack", + "giveItem": None, + }, + + # ============================================================ + # 十六、书柜系统(后放先取,14级) + # ============================================================ + # ---- 放书 ---- + { + "source": "rtdd:bookcase", + "item": "minecraft:book", + "target": "rtdd:bookcase_12", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase", + "item": "minecraft:enchanted_book", + "target": "rtdd:bookcase_12", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_12", + "item": "minecraft:book", + "target": "rtdd:bookcase_11", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_12", + "item": "minecraft:enchanted_book", + "target": "rtdd:bookcase_11", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_11", + "item": "minecraft:book", + "target": "rtdd:bookcase_10", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_11", + "item": "minecraft:enchanted_book", + "target": "rtdd:bookcase_10", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_10", + "item": "minecraft:book", + "target": "rtdd:bookcase_9", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_10", + "item": "minecraft:enchanted_book", + "target": "rtdd:bookcase_9", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_9", + "item": "minecraft:book", + "target": "rtdd:bookcase_8", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_9", + "item": "minecraft:enchanted_book", + "target": "rtdd:bookcase_8", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_8", + "item": "minecraft:book", + "target": "rtdd:bookcase_7", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_8", + "item": "minecraft:enchanted_book", + "target": "rtdd:bookcase_7", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_7", + "item": "minecraft:book", + "target": "rtdd:bookcase_6", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_7", + "item": "minecraft:enchanted_book", + "target": "rtdd:bookcase_6", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_6", + "item": "minecraft:book", + "target": "rtdd:bookcase_5", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_6", + "item": "minecraft:enchanted_book", + "target": "rtdd:bookcase_5", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_5", + "item": "minecraft:book", + "target": "rtdd:bookcase_4", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_5", + "item": "minecraft:enchanted_book", + "target": "rtdd:bookcase_4", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_4", + "item": "minecraft:book", + "target": "rtdd:b_196", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_4", + "item": "minecraft:enchanted_book", + "target": "rtdd:b_196", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:b_196", + "item": "minecraft:book", + "target": "rtdd:bookcase_3", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:b_196", + "item": "minecraft:enchanted_book", + "target": "rtdd:bookcase_3", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_3", + "item": "minecraft:book", + "target": "rtdd:bookcase_2", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_3", + "item": "minecraft:enchanted_book", + "target": "rtdd:bookcase_2", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_2", + "item": "minecraft:book", + "target": "rtdd:bookcase_1", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + { + "source": "rtdd:bookcase_2", + "item": "minecraft:enchanted_book", + "target": "rtdd:bookcase_1", + "consume": 1, + "type": "switch", + "record": True, + "recordType": "stack", + "maxCount": 13, + "giveItem": None, + }, + # ---- 取回书(后放先取) ---- + { + "source": "rtdd:bookcase_1", + "item": None, + "target": "rtdd:bookcase_2", + "consume": 0, + "type": "switch", + "record": True, + "recordType": "stack", + "giveItem": None, + }, + { + "source": "rtdd:bookcase_2", + "item": None, + "target": "rtdd:bookcase_3", + "consume": 0, + "type": "switch", + "record": True, + "recordType": "stack", + "giveItem": None, + }, + { + "source": "rtdd:bookcase_3", + "item": None, + "target": "rtdd:b_196", + "consume": 0, + "type": "switch", + "record": True, + "recordType": "stack", + "giveItem": None, + }, + { + "source": "rtdd:b_196", + "item": None, + "target": "rtdd:bookcase_4", + "consume": 0, + "type": "switch", + "record": True, + "recordType": "stack", + "giveItem": None, + }, + { + "source": "rtdd:bookcase_4", + "item": None, + "target": "rtdd:bookcase_5", + "consume": 0, + "type": "switch", + "record": True, + "recordType": "stack", + "giveItem": None, + }, + { + "source": "rtdd:bookcase_5", + "item": None, + "target": "rtdd:bookcase_6", + "consume": 0, + "type": "switch", + "record": True, + "recordType": "stack", + "giveItem": None, + }, + { + "source": "rtdd:bookcase_6", + "item": None, + "target": "rtdd:bookcase_7", + "consume": 0, + "type": "switch", + "record": True, + "recordType": "stack", + "giveItem": None, + }, + { + "source": "rtdd:bookcase_7", + "item": None, + "target": "rtdd:bookcase_8", + "consume": 0, + "type": "switch", + "record": True, + "recordType": "stack", + "giveItem": None, + }, + { + "source": "rtdd:bookcase_8", + "item": None, + "target": "rtdd:bookcase_9", + "consume": 0, + "type": "switch", + "record": True, + "recordType": "stack", + "giveItem": None, + }, + { + "source": "rtdd:bookcase_9", + "item": None, + "target": "rtdd:bookcase_10", + "consume": 0, + "type": "switch", + "record": True, + "recordType": "stack", + "giveItem": None, + }, + { + "source": "rtdd:bookcase_10", + "item": None, + "target": "rtdd:bookcase_11", + "consume": 0, + "type": "switch", + "record": True, + "recordType": "stack", + "giveItem": None, + }, + { + "source": "rtdd:bookcase_11", + "item": None, + "target": "rtdd:bookcase_12", + "consume": 0, + "type": "switch", + "record": True, + "recordType": "stack", + "giveItem": None, + }, + { + "source": "rtdd:bookcase_12", + "item": None, + "target": "rtdd:bookcase", + "consume": 0, + "type": "switch", + "record": True, + "recordType": "stack", + "giveItem": None, + }, +] \ No newline at end of file diff --git a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/ceshi/service/CookingService.py b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/ceshi/service/CookingService.py index f105c0f..31b93c1 100644 --- a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/ceshi/service/CookingService.py +++ b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/ceshi/service/CookingService.py @@ -50,6 +50,10 @@ blockEntityDataComp = comp.CreateBlockEntityData(LevelId) # RECIPES 是一个列表,每条配方是一个 dict,格式见 RecipeData.py 顶部注释 from ..RecipeData import RECIPES +# ---- 导入工具方块切换规则 ---- +# BLOCK_SWITCHES 是一个列表,每条规则是一个 dict,格式见 BlockSwitchData.py 顶部注释 +from ..BlockSwitchData import BLOCK_SWITCHES + # ================================================================================ # 工具函数:读取物品 userData 里的嵌套字段 @@ -107,17 +111,39 @@ class CookingService(BlueFoxServerSystem): 1. 内存(self.stirData)—— 快,关服就没了 2. 方块实体数据(blockEntityData)—— 慢一点,但关服重启后还在 每次操作都会同步更新两处,保证重启不丢进度 + + 【工具方块记录数据】 + switchRecord = { + (维度ID, x, y, z): { + "count": 整数, # recordType="count" 时记录数量(如箭桶里有多少箭) + "itemName": 字符串, # recordType="count" 时记录物品名(如"minecraft:arrow") + "stack": [物品信息列表], # recordType="stack" 时记录后进先出的物品堆 + } + } """ def __init__(self, namespace, systemName): """ - 初始化:清空翻炒数据、注册事件监听 + 初始化:清空翻炒数据、注册事件监听、构建统一配方字典 """ super(CookingService, self).__init__(namespace, systemName) print "===== CookingService init =====" self.stirData = {} # 内存中的翻炒数据字典 + self.switchRecord = {} # 工具方块的记录数据(箭桶数量、药水架顺序等) self.ListenEvent() # 注册游戏事件监听 + # ---- 构建统一配方字典(O(1) 查找) ---- + # 把 RECIPES(做菜配方)和 BLOCK_SWITCHES(工具切换规则)合并成一份字典 + # key = (方块名, 物品名),value = 配方dict + # 这样查找时不用遍历整个列表,直接 dict[key] 就能拿到,速度飞快 + self.allRecipes = {} + for recipe in RECIPES: + key = (recipe["source"], recipe.get("item")) + self.allRecipes[key] = recipe + for switch in BLOCK_SWITCHES: + key = (switch["source"], switch.get("item")) + self.allRecipes[key] = switch + def Destroy(self): """ 系统销毁时取消所有事件监听,防止内存泄漏 @@ -166,9 +192,9 @@ class CookingService(BlueFoxServerSystem): 流程: 1. 拿到被右键的方块名、玩家ID、方块坐标 2. 看玩家手里拿了什么物品 - 3. 拿着"方块名+手里物品名"去 RecipeData 里找匹配的配方 - 4. 找到配方后,判断是"需要翻炒"还是"直接替换"两种类型 - 5. 执行对应的做菜逻辑 + 3. 拿着"方块名+手里物品名"去统一字典里 O(1) 查找 + 4. 找到规则后,判断是"做菜配方"还是"工具切换"类型 + 5. 执行对应的逻辑 args 是网易API传过来的事件参数,包含: - blockName: 被右键的方块名字(如 "rtdd:wok") @@ -188,13 +214,24 @@ class CookingService(BlueFoxServerSystem): # itemDict 可能是 None(空手),也可能是 dict(手里有东西) # dict 格式:{"newItemName": "rtdd:spatula", "count": 1, "userData": {...}} - # ---- 第三步:查配方 ---- + # ---- 第三步:查配方(O(1) 字典查找) ---- recipe = self.findRecipe(blockName, itemDict) if not recipe: # 没找到匹配的配方 → 不是做菜操作,不拦截,让游戏正常处理 return - # ---- 第四步:加载翻炒进度(如果这个方块之前翻过的话) ---- + # ---- 第四步:判断是不是工具切换类型 ---- + recipeType = recipe.get("type", "cook") + # type="switch" 或 "timer" → 工具方块切换(箭桶、挂肉钩、水槽等) + # 没有 type 或 type="cook" → 做菜配方(炒锅、煎锅等) + + if recipeType == "switch" or recipeType == "timer": + self.handleSwitch(recipe, playerId, pos, dim, itemDict, key, blockName) + return + + # ---- 第五步:以下为做菜配方逻辑 ---- + + # ---- 加载翻炒进度(如果这个方块之前翻过的话) ---- # 先从内存取,内存没有就从方块实体数据加载(服务器重启后恢复) stirInfo = self.stirData.get(key, {}) if not stirInfo: @@ -202,7 +239,7 @@ class CookingService(BlueFoxServerSystem): if stirInfo: self.stirData[key] = stirInfo # 加载成功后写入内存缓存 - # ---- 第五步:根据配方类型判断 ---- + # ---- 根据配方类型判断 ---- # needFinished=True 的配方 → 需要先翻炒熟了才能操作(比如出锅) # needFinished=False 的配方 → 只能对没熟的进行操作(比如继续加油) if recipe.get("needFinished") is True and not stirInfo.get("finished"): @@ -212,7 +249,7 @@ class CookingService(BlueFoxServerSystem): # 配方要求"没熟",但当前状态是"已熟" → 不执行 return - # ---- 第六步:分发到不同的处理逻辑 ---- + # ---- 分发到不同的处理逻辑 ---- if recipe.get("stirCount"): # 这个配方有 stirCount 字段 → 需要翻炒,走翻炒流程 self.handleStir(key, recipe, playerId, pos, dim, itemDict) @@ -222,36 +259,152 @@ class CookingService(BlueFoxServerSystem): self.executeRecipe(recipe, playerId, pos, dim, itemDict, key) # ============================================================================ - # 配方匹配 + # 配方匹配(O(1) 字典查找) # ============================================================================ def findRecipe(self, blockName, itemDict): """ - 遍历 RECIPES 列表,找到第一个匹配的配方。 + 在统一字典中 O(1) 查找匹配的配方。 匹配条件: - 1. 配方的 source 字段 == 被右键的方块名(比如 "rtdd:wok") - 2. 如果配方指定了 item 字段,则玩家手里物品必须匹配 - 3. 如果配方 item 是 None,表示空手也能触发(比如点锅盖) + 1. 先精确匹配 (方块名, 物品名) + 2. 如果没找到,尝试匹配 (方块名, None) —— 空手也能触发的规则 返回:匹配到的配方 dict,找不到返回 None """ # 提取玩家手里物品的名字(空手时 itemName 为 None) itemName = itemDict.get("newItemName") if itemDict else None - for recipe in RECIPES: - # 条件1:方块名必须匹配 - if recipe["source"] != blockName: - continue - # 条件2:物品名必须匹配(None 表示不需要特定物品) - if recipe["item"] is not None and recipe["item"] != itemName: - continue - # 两个条件都满足 → 找到了 + # 精确匹配:(方块名, 物品名) + recipe = self.allRecipes.get((blockName, itemName)) + if recipe: + return recipe + + # 空手匹配:(方块名, None) + recipe = self.allRecipes.get((blockName, None)) + if recipe: return recipe - # 遍历完所有配方都没找到 return None + # ============================================================================ + # 工具方块切换处理 + # ============================================================================ + + def handleSwitch(self, recipe, playerId, pos, dim, itemDict, key, blockName): + """ + 处理工具方块的切换逻辑(箭桶、挂肉钩、水槽、盘子架、药水架、书柜等)。 + + 支持三种模式: + 1. recordType="count" → 记录一种物品+数量(如箭桶存箭) + 2. recordType="stack" → 后进先出堆栈(如药水架、书柜) + 3. 无 record → 纯切换,不记录(如挂肉钩直接换状态) + + 流程: + 1. 如果是计时型(type="timer"),直接替换方块,不消耗物品 + 2. 如果是切换型(type="switch"),根据 recordType 决定记录方式 + 3. 消耗物品、替换方块、更新记录 + """ + # ---- 如果规则指定了 tool,检查玩家手里是不是拿着指定工具 ---- + if recipe.get("tool"): + if not itemDict: + return + carriedItem = itemDict.get("newItemName", "") + # 简单判断:物品名是否包含工具名 + if recipe["tool"] not in carriedItem: + return + + # ---- 计时型:直接替换方块,不消耗物品,不记录 ---- + if recipe.get("type") == "timer": + if recipe.get("target"): + self.replaceBlock(pos, dim, recipe["target"], playerId) + return + + # ---- 切换型 ---- + # 获取当前方块的记录数据 + record = self.switchRecord.get(key) + + # ---- 正向操作:往方块里放东西(source == 被右键的方块) ---- + if recipe["source"] == blockName and recipe.get("item") is not None: + # 玩家手里有物品,往方块里放 + if recipe.get("record"): + if recipe.get("recordType") == "count": + # 数量记录型:只记录一种物品的总数 + if not record: + record = { + "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 + + 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 # 满了 + # 把物品信息压入堆栈 + record["stack"].append({ + "itemName": itemDict["newItemName"], + "count": itemDict.get("count", 1), + "auxValue": itemDict.get("newAuxValue", 0), + "userData": itemDict.get("userData", {}), + }) + self.switchRecord[key] = record + + # 消耗物品 + 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) + + return + + # ---- 逆向操作:从方块里取东西(空手右键或取回物品) ---- + if recipe["source"] == blockName and recipe.get("item") is None: + if recipe.get("record") and record: + if recipe.get("recordType") == "count": + # 数量记录型取回:给玩家对应的物品,数量-1 + if record["count"] > 0: + self.giveItem(playerId, record["itemName"]) + record["count"] -= 1 + if record["count"] <= 0: + self.switchRecord.pop(key, None) + else: + self.switchRecord[key] = record + + elif recipe.get("recordType") == "stack": + # 堆栈记录型取回:后进先出,取最后一个放的物品 + if record["stack"]: + topItem = record["stack"].pop() + comp.CreateItem(playerId).SpawnItemToPlayerInv( + {"itemName": topItem["itemName"], + "count": topItem["count"], + "auxValue": topItem["auxValue"], + "userData": topItem.get("userData", {})}, + playerId) + if not record["stack"]: + self.switchRecord.pop(key, None) + else: + self.switchRecord[key] = record + + # 替换方块 + if recipe.get("target"): + self.replaceBlock(pos, dim, recipe["target"], playerId) + + return + # ============================================================================ # 配方执行(普通替换类型) # ============================================================================