面食 3
This commit is contained in:
1 parent
4e7b9abee5
commit
052e4844b2
26 files changed
+1053
-41
No files matched your search
@@ -18,6 +18,8 @@ from xiangyemod.ziran.service.NaturalService import NaturalService
|
|||||||
from xiangyemod.ziran.service.NaturalTimerService import NaturalTimerService
|
from xiangyemod.ziran.service.NaturalTimerService import NaturalTimerService
|
||||||
from xiangyemod.shicai.service.ShicaiService import ShicaiService
|
from xiangyemod.shicai.service.ShicaiService import ShicaiService
|
||||||
from xiangyemod.shousi.service.ShousiService import ShousiService
|
from xiangyemod.shousi.service.ShousiService import ShousiService
|
||||||
|
from xiangyemod.mianshi.service.MianshiService import MianshiService
|
||||||
|
from xiangyemod.mianshi.service.MianshiTimerService import MianshiTimerService
|
||||||
|
|
||||||
if not serverApi.IsInServer():
|
if not serverApi.IsInServer():
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -0,0 +1,326 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
================================================================================
|
||||||
|
面食.甜食(xy_mianshi)转化规则数据
|
||||||
|
================================================================================
|
||||||
|
统一管理"面食.甜食"分类下的转化规则常量。只被
|
||||||
|
MianshiService / MianshiTimerService 读取, FeatureDispatcher 通过
|
||||||
|
方块名/物品名集合路由到对应服务。
|
||||||
|
|
||||||
|
【实现范围(对应 面食.甜食转化关系.txt 一~九组)】
|
||||||
|
面粉·面团: 加鸡蛋/加水/揉面/和面/擀面(擀面杖消耗返还)/切面/压饺子皮
|
||||||
|
饺子 : 加猪肉馅/青菜碎(双向组合)/捏合 -> 蒸笼蒸熟 -> 盘子取盘装水饺
|
||||||
|
包子 : 饺子皮转包子皮/加肉/塑形 -> 蒸笼蒸熟 -> 取出熟肉包子 -> 切/堆叠/递减
|
||||||
|
馍 : 生面饼烙制/菜刀切开/夹熟肉
|
||||||
|
煎饼卷 : 加菜/加熟牛肉/熟鳕鱼/土豆/卷制
|
||||||
|
竹筒饭 : 竹筒切开/装米(32)/加肉 -> 蒸笼蒸熟 -> 取出熟竹筒饭
|
||||||
|
面包 : 法棍/吐司/可颂/甜甜圈 堆叠份数 + 递减取走
|
||||||
|
面团胚料: 四种胚料右键循环转换 + 发酵 + 烤炉烘焙
|
||||||
|
甜点蛋糕: 木碗+面粉(加鸡蛋)面糊/烤熟/脱模/加奶油/蜂蜜/浆果/切分/布丁/舒芙蕾/蒸蛋奶
|
||||||
|
|
||||||
|
【计时(见 MianshiTimerService)】
|
||||||
|
发酵60秒 / 烤炉烘焙60秒(下方判定烤炉, 烤炉被打碎 -> 方块掉落+提示) / 蒸笼蒸熟60秒
|
||||||
|
|
||||||
|
【不实现(txt 已标 todo)】: 吃(熟肉包子/馍/煎饼卷/熟竹筒饭/蛋糕小块 右键吃)、
|
||||||
|
巧克力蛋糕系列、蛋糕半块拆两块
|
||||||
|
================================================================================
|
||||||
|
"""
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 一、物品(手持原料/工具)
|
||||||
|
# ============================================================================
|
||||||
|
EGG = "minecraft:egg" # 鸡蛋
|
||||||
|
WATER_BUCKET = "minecraft:water_bucket" # 水桶
|
||||||
|
EMPTY_BUCKET = "minecraft:bucket" # 空桶
|
||||||
|
CLEAVER = "rtdd:cleaver" # 菜刀
|
||||||
|
ROLLINGPIN = "rtdd:rollingpin" # 厨具擀面杖
|
||||||
|
PORK_FILLING = "rtdd:rawmeatball_0" # 生猪肉馅
|
||||||
|
BEEF_FILLING = "rtdd:rawmeatball_1" # 生牛肉馅
|
||||||
|
VEGGIE = "rtdd:vegetable" # 青菜碎
|
||||||
|
COOKED_BEEF = "minecraft:cooked_beef" # 熟牛肉(原版)
|
||||||
|
COOKED_PORK = "minecraft:cooked_porkchop" # 熟猪肉(原版)
|
||||||
|
COOKED_COD = "minecraft:cooked_cod" # 熟鳕鱼(原版)
|
||||||
|
POTATO = "minecraft:potato" # 土豆(原版)
|
||||||
|
BROWN_RICE = "rtdd:brownrice" # 大米(生米)
|
||||||
|
CREAM = "rtdd:cream_0" # 奶油
|
||||||
|
HONEY = "minecraft:honey_bottle" # 蜂蜜
|
||||||
|
BERRIES = "minecraft:sweet_berries" # 浆果
|
||||||
|
SUGAR = "minecraft:sugar" # 糖
|
||||||
|
PLATE = "rtdd:plate_0" # 盘子
|
||||||
|
BOWL = "rtdd:bowlasoup" # 木碗
|
||||||
|
STEAMER = "rtdd:steamer" # 蒸笼
|
||||||
|
OVEN = "rtdd:oven" # 烤炉
|
||||||
|
|
||||||
|
# 竹筒饭加肉: 接受原版常见生熟肉类(【待确认】具体肉类未定, 先放开常见肉)
|
||||||
|
MEAT_ITEMS = [
|
||||||
|
"minecraft:porkchop", "minecraft:cooked_porkchop",
|
||||||
|
"minecraft:chicken", "minecraft:cooked_chicken",
|
||||||
|
"minecraft:beef", "minecraft:cooked_beef",
|
||||||
|
"minecraft:mutton", "minecraft:cooked_mutton",
|
||||||
|
"minecraft:rabbit", "minecraft:cooked_rabbit",
|
||||||
|
]
|
||||||
|
|
||||||
|
# 包子加肉: 猪/牛肉馅
|
||||||
|
FILLING_ITEMS = [PORK_FILLING, BEEF_FILLING]
|
||||||
|
|
||||||
|
# 肉夹馍: 熟牛肉/熟猪肉
|
||||||
|
RICH_MEAT_ITEMS = [COOKED_BEEF, COOKED_PORK]
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 二、右键开关规则 (方块, 手持物品) -> 规则
|
||||||
|
# item=None 表示空手; target=替换方块; consume=消耗手持; give=给背包;
|
||||||
|
# dropItem=掉落物; action=特殊动作(take_steamer 蒸笼取出 / chop_smalldough
|
||||||
|
# 切小面团 / chop_noodles 切生面 / unmold_cake 蛋糕脱模)
|
||||||
|
# ============================================================================
|
||||||
|
SWITCH_RULES = [
|
||||||
|
# ---- 一、面粉·面团组 ----
|
||||||
|
{"block": "rtdd:farineblcok", "item": EGG,
|
||||||
|
"target": "rtdd:farineblock_1", "consume": 3, "tip": "§a面粉加了鸡蛋"},
|
||||||
|
{"block": "rtdd:farineblock_1", "item": WATER_BUCKET,
|
||||||
|
"target": "rtdd:farineblock_2", "consume": 1, "give": EMPTY_BUCKET,
|
||||||
|
"tip": "§a面粉加水, 水桶变空桶"},
|
||||||
|
{"block": "rtdd:rawdough_0", "item": None, "target": "rtdd:rawdough_1", "tip": "§a和面中…"},
|
||||||
|
{"block": "rtdd:rawdough_1", "item": None, "target": "rtdd:rawdough_2", "tip": "§a和面中…"},
|
||||||
|
{"block": "rtdd:rawdough_2", "item": None, "target": "rtdd:rawdough_3", "tip": "§a和面中…"},
|
||||||
|
{"block": "rtdd:rawdough_3", "item": None, "target": "rtdd:rawdough_4", "tip": "§a和面完成"},
|
||||||
|
{"block": "rtdd:rawdough_4", "item": CLEAVER, "action": "chop_smalldough",
|
||||||
|
"tip": "§a切出了8个小面团"},
|
||||||
|
{"block": "rtdd:dough_0", "item": ROLLINGPIN, "target": "rtdd:dough_1",
|
||||||
|
"consume": 1, "tip": "§a开始擀面(消耗1根擀面杖)"},
|
||||||
|
{"block": "rtdd:dough_1", "item": None, "target": "rtdd:dought_2", "tip": "§a擀面中…"},
|
||||||
|
{"block": "rtdd:dought_2", "item": None, "target": "rtdd:dought_3", "tip": "§a擀面中…"},
|
||||||
|
{"block": "rtdd:dought_3", "item": None, "target": "rtdd:dought_4", "tip": "§a擀面中…"},
|
||||||
|
{"block": "rtdd:dought_4", "item": None, "target": "rtdd:dought_5", "tip": "§a擀面中…"},
|
||||||
|
{"block": "rtdd:dought_5", "item": None, "target": "rtdd:dought_6", "tip": "§a擀面中…"},
|
||||||
|
{"block": "rtdd:dought_6", "item": None, "target": "rtdd:dought_7",
|
||||||
|
"give": ROLLINGPIN, "tip": "§a擀好了, 擀面杖返还"},
|
||||||
|
{"block": "rtdd:dought_7", "item": CLEAVER, "target": "rtdd:dought_8", "tip": "§a面饼切开"},
|
||||||
|
{"block": "rtdd:dought_8", "item": None, "target": "rtdd:dought_9", "tip": "§a转成可颂面胚"},
|
||||||
|
{"block": "rtdd:dought_8", "item": CLEAVER, "action": "chop_noodles",
|
||||||
|
"tip": "§a切出了生面"},
|
||||||
|
{"block": "rtdd:smalldough_0", "item": ROLLINGPIN, "target": "rtdd:smalldough_1",
|
||||||
|
"consume": 1, "tip": "§a开始擀小面团(消耗1根擀面杖)"},
|
||||||
|
{"block": "rtdd:smalldough_1", "item": None, "target": "rtdd:smalldough_2", "tip": "§a擀小面团中…"},
|
||||||
|
{"block": "rtdd:smalldough_2", "item": None, "target": "rtdd:smalldough_3", "tip": "§a擀小面团中…"},
|
||||||
|
{"block": "rtdd:smalldough_3", "item": None, "target": "rtdd:dumplings_0",
|
||||||
|
"give": ROLLINGPIN, "tip": "§a压成饺子皮, 擀面杖返还"},
|
||||||
|
|
||||||
|
# ---- 二、饺子组 ----
|
||||||
|
{"block": "rtdd:dumplings_0", "item": PORK_FILLING, "target": "rtdd:dumplings_1",
|
||||||
|
"tip": "§a饺子皮加了猪肉馅"},
|
||||||
|
{"block": "rtdd:dumplings_0", "item": VEGGIE, "target": "rtdd:dumplings_2",
|
||||||
|
"tip": "§a饺子皮加了青菜碎"},
|
||||||
|
{"block": "rtdd:dumplings_1", "item": VEGGIE, "target": "rtdd:dumplings_3",
|
||||||
|
"tip": "§a加了青菜碎"},
|
||||||
|
{"block": "rtdd:dumplings_2", "item": PORK_FILLING, "target": "rtdd:dumplings_3",
|
||||||
|
"tip": "§a加了猪肉馅"},
|
||||||
|
{"block": "rtdd:dumplings_3", "item": None, "target": "rtdd:dumplings_4",
|
||||||
|
"tip": "§a捏合成了生饺子"},
|
||||||
|
{"block": "rtdd:steamerdumplings_1", "item": PLATE, "action": "take_steamer",
|
||||||
|
"dropItem": "rtdd:plate_30", "consume": 1, "tip": "§a取出盘装水饺, 蒸笼归位"},
|
||||||
|
|
||||||
|
# ---- 三、包子组 ----
|
||||||
|
{"block": "rtdd:dumplings_0", "item": None, "target": "rtdd:baozipi",
|
||||||
|
"tip": "§a变成包子皮"},
|
||||||
|
{"block": "rtdd:baozipi", "item": PORK_FILLING, "target": "rtdd:roubao_1",
|
||||||
|
"tip": "§a包子皮加了肉馅"},
|
||||||
|
{"block": "rtdd:baozipi", "item": BEEF_FILLING, "target": "rtdd:roubao_1",
|
||||||
|
"tip": "§a包子皮加了肉馅"},
|
||||||
|
{"block": "rtdd:roubao_1", "item": None, "target": "rtdd:roubao_2", "tip": "§a塑形中…"},
|
||||||
|
{"block": "rtdd:roubao_2", "item": None, "target": "rtdd:roubaozi_3",
|
||||||
|
"tip": "§a塑形成生肉包子"},
|
||||||
|
{"block": "rtdd:baozilong_2", "item": None, "action": "take_steamer",
|
||||||
|
"dropItem": "rtdd:shouroubao", "tip": "§a取出熟肉包子, 蒸笼归位"},
|
||||||
|
{"block": "rtdd:shouroubao", "item": CLEAVER, "target": "rtdd:shoubaozi_2",
|
||||||
|
"tip": "§a切出半个"},
|
||||||
|
{"block": "rtdd:shoubaozi_2", "item": CLEAVER, "target": "rtdd:shoubaozi_3",
|
||||||
|
"tip": "§a切成1/4个"},
|
||||||
|
{"block": "rtdd:shoubaozi_2", "item": "rtdd:shouroubao", "target": "rtdd:shoubaozidui_2",
|
||||||
|
"consume": 1, "tip": "§a堆叠成两个"},
|
||||||
|
{"block": "rtdd:shoubaozidui_2", "item": "rtdd:shouroubao", "target": "rtdd:shoubaozidui_3",
|
||||||
|
"consume": 1, "tip": "§a堆叠成三个"},
|
||||||
|
{"block": "rtdd:shoubaozidui_3", "item": None, "target": "rtdd:shoubaozidui_2",
|
||||||
|
"dropItem": "rtdd:shouroubao", "tip": "§a取走一个"},
|
||||||
|
{"block": "rtdd:shoubaozidui_2", "item": None, "target": "rtdd:shoubaozi_2",
|
||||||
|
"dropItem": "rtdd:shouroubao", "tip": "§a取走一个"},
|
||||||
|
|
||||||
|
# ---- 四、馍·肉夹馍组 ----
|
||||||
|
{"block": "rtdd:roujiamo_0", "item": CLEAVER, "target": "rtdd:roujiamo_1",
|
||||||
|
"tip": "§a馍切开"},
|
||||||
|
{"block": "rtdd:roujiamo_1", "item": COOKED_BEEF, "target": "rtdd:roujiamo_2",
|
||||||
|
"tip": "§a夹入熟牛肉"},
|
||||||
|
{"block": "rtdd:roujiamo_1", "item": COOKED_PORK, "target": "rtdd:roujiamo_2",
|
||||||
|
"tip": "§a夹入熟猪肉"},
|
||||||
|
|
||||||
|
# ---- 五、煎饼卷组 ----
|
||||||
|
{"block": "rtdd:cooked_dought", "item": VEGGIE, "target": "rtdd:cookeddought_1",
|
||||||
|
"tip": "§a煎饼加了青菜碎"},
|
||||||
|
{"block": "rtdd:cookeddought_1", "item": COOKED_BEEF, "target": "rtdd:cookeddought_2",
|
||||||
|
"tip": "§a加入熟牛肉"},
|
||||||
|
{"block": "rtdd:cookeddought_2", "item": POTATO, "target": "rtdd:cookeddought_3",
|
||||||
|
"tip": "§a加入土豆"},
|
||||||
|
{"block": "rtdd:cookeddought_3", "item": None, "target": "rtdd:cookeddought_4",
|
||||||
|
"tip": "§a卷制中…"},
|
||||||
|
{"block": "rtdd:cookeddought_4", "item": None, "target": "rtdd:cookeddought_5",
|
||||||
|
"tip": "§a卷制中…"},
|
||||||
|
{"block": "rtdd:cookeddought_5", "item": None, "target": "rtdd:cookeddought_6",
|
||||||
|
"tip": "§a煎饼卷牛肉完成"},
|
||||||
|
{"block": "rtdd:cookeddought_1", "item": COOKED_COD, "target": "rtdd:cookedcoddought_2",
|
||||||
|
"tip": "§a加入熟鳕鱼"},
|
||||||
|
{"block": "rtdd:cookedcoddought_2", "item": POTATO, "target": "rtdd:cookedcoddought_3",
|
||||||
|
"tip": "§a加入土豆"},
|
||||||
|
{"block": "rtdd:cookedcoddought_3", "item": None, "target": "rtdd:cookedcoddought_4",
|
||||||
|
"tip": "§a卷制中…"},
|
||||||
|
{"block": "rtdd:cookedcoddought_4", "item": None, "target": "rtdd:cookedcoddought_5",
|
||||||
|
"tip": "§a卷制中…"},
|
||||||
|
{"block": "rtdd:cookedcoddought_5", "item": None, "target": "rtdd:cookedcoddought_6",
|
||||||
|
"tip": "§a煎饼卷鳕鱼完成"},
|
||||||
|
|
||||||
|
# ---- 六、竹筒饭组 ----
|
||||||
|
{"block": "rtdd:bamboo_0", "item": CLEAVER, "target": "rtdd:bamboo_1",
|
||||||
|
"tip": "§a竹筒切开"},
|
||||||
|
{"block": "rtdd:bamboo_1", "item": BROWN_RICE, "target": "rtdd:bamboo_2",
|
||||||
|
"consume": 32, "tip": "§a竹筒填满生大米"},
|
||||||
|
{"block": "rtdd:bamboo_7", "item": None, "action": "take_steamer",
|
||||||
|
"dropItem": "rtdd:bamboo_5", "tip": "§a取出熟竹筒饭, 蒸笼归位"},
|
||||||
|
|
||||||
|
# ---- 七、面包·烘焙组(堆叠/递减) ----
|
||||||
|
{"block": "rtdd:bread_1", "item": "rtdd:bread_1", "target": "rtdd:bread_1a",
|
||||||
|
"consume": 1, "tip": "§a堆叠成2份"},
|
||||||
|
{"block": "rtdd:bread_1a", "item": "rtdd:bread_1", "target": "rtdd:bread_1b",
|
||||||
|
"consume": 1, "tip": "§a堆叠成3份"},
|
||||||
|
{"block": "rtdd:bread_1b", "item": None, "target": "rtdd:bread_1a",
|
||||||
|
"dropItem": "rtdd:bread_1", "tip": "§a取走一个"},
|
||||||
|
{"block": "rtdd:bread_1a", "item": None, "target": "rtdd:bread_1",
|
||||||
|
"dropItem": "rtdd:bread_1", "tip": "§a取走一个"},
|
||||||
|
{"block": "rtdd:bread_2", "item": "rtdd:bread_2", "target": "rtdd:bread_2a",
|
||||||
|
"consume": 1, "tip": "§a堆叠成2份"},
|
||||||
|
{"block": "rtdd:bread_2a", "item": "rtdd:bread_2", "target": "rtdd:bread_2b",
|
||||||
|
"consume": 1, "tip": "§a堆叠成3份"},
|
||||||
|
{"block": "rtdd:bread_2b", "item": None, "target": "rtdd:bread_2a",
|
||||||
|
"dropItem": "rtdd:bread_2", "tip": "§a取走一个"},
|
||||||
|
{"block": "rtdd:bread_2a", "item": None, "target": "rtdd:bread_2",
|
||||||
|
"dropItem": "rtdd:bread_2", "tip": "§a取走一个"},
|
||||||
|
{"block": "rtdd:bread_3", "item": "rtdd:bread_3", "target": "rtdd:bread_3a",
|
||||||
|
"consume": 1, "tip": "§a堆叠成2份"},
|
||||||
|
{"block": "rtdd:bread_3a", "item": "rtdd:bread_3", "target": "rtdd:bread_3b",
|
||||||
|
"consume": 1, "tip": "§a堆叠成3份"},
|
||||||
|
{"block": "rtdd:bread_3b", "item": None, "target": "rtdd:bread_3a",
|
||||||
|
"dropItem": "rtdd:bread_3", "tip": "§a取走一个"},
|
||||||
|
{"block": "rtdd:bread_3a", "item": None, "target": "rtdd:bread_3",
|
||||||
|
"dropItem": "rtdd:bread_3", "tip": "§a取走一个"},
|
||||||
|
{"block": "rtdd:bread_4", "item": "rtdd:bread_4", "target": "rtdd:bread_4a",
|
||||||
|
"consume": 1, "tip": "§a堆叠成2个"},
|
||||||
|
{"block": "rtdd:bread_4a", "item": "rtdd:bread_4", "target": "rtdd:bread_4b",
|
||||||
|
"consume": 1, "tip": "§a堆叠成3个"},
|
||||||
|
{"block": "rtdd:bread_4b", "item": None, "target": "rtdd:bread_4a",
|
||||||
|
"dropItem": "rtdd:bread_4", "tip": "§a取走一个甜甜圈"},
|
||||||
|
{"block": "rtdd:bread_4a", "item": None, "target": "rtdd:bread_4",
|
||||||
|
"dropItem": "rtdd:bread_4", "tip": "§a取走一个甜甜圈"},
|
||||||
|
{"block": "rtdd:bread_4c", "item": CREAM, "target": "rtdd:bread_4",
|
||||||
|
"consume": 1, "tip": "§a甜甜圈涂了奶油"},
|
||||||
|
|
||||||
|
# ---- 八、面团·胚料组(右键循环转换) ----
|
||||||
|
{"block": "rtdd:dough_0", "item": None, "target": "rtdd:breaddough_1",
|
||||||
|
"tip": "§a转成法棍面胚"},
|
||||||
|
{"block": "rtdd:breaddough_1", "item": None, "target": "rtdd:breaddough_2",
|
||||||
|
"tip": "§a转成吐司面胚"},
|
||||||
|
{"block": "rtdd:breaddough_2", "item": None, "target": "rtdd:breaddough_4d",
|
||||||
|
"tip": "§a转成甜甜圈胚"},
|
||||||
|
{"block": "rtdd:breaddough_4d", "item": None, "target": "rtdd:dough_0",
|
||||||
|
"tip": "§a转回发酵面团"},
|
||||||
|
|
||||||
|
# ---- 九、甜点·蛋糕组 ----
|
||||||
|
{"block": "rtdd:cakebatterblock", "item": None, "action": "unmold_cake",
|
||||||
|
"tip": "§a脱模出蛋糕胚 + 木碗"},
|
||||||
|
{"block": "rtdd:cakebase", "item": CREAM, "target": "rtdd:cake_0",
|
||||||
|
"consume": 1, "tip": "§a做了奶油蛋糕"},
|
||||||
|
{"block": "rtdd:cakebase", "item": HONEY, "target": "rtdd:cake_1",
|
||||||
|
"consume": 1, "tip": "§a做了蜂蜜蛋糕"},
|
||||||
|
{"block": "rtdd:cakebase", "item": BERRIES, "target": "rtdd:cake_2",
|
||||||
|
"consume": 1, "tip": "§a做了浆果蛋糕"},
|
||||||
|
{"block": "rtdd:cake_1", "item": CLEAVER, "target": "rtdd:cake_1a",
|
||||||
|
"dropItem": "rtdd:cake_1d", "tip": "§a切下小块"},
|
||||||
|
{"block": "rtdd:cake_1a", "item": CLEAVER, "target": "rtdd:cake_1b",
|
||||||
|
"dropItem": "rtdd:cake_1d", "tip": "§a切下小块"},
|
||||||
|
{"block": "rtdd:cake_2", "item": CLEAVER, "target": "rtdd:cake_2a",
|
||||||
|
"dropItem": "rtdd:cake_2d", "tip": "§a切下小块"},
|
||||||
|
{"block": "rtdd:cake_2a", "item": CLEAVER, "target": "rtdd:cake_2b",
|
||||||
|
"dropItem": "rtdd:cake_2d", "tip": "§a切下小块"},
|
||||||
|
{"block": "rtdd:cake_1b", "item": CLEAVER, "action": "split_cake",
|
||||||
|
"dropItem": "rtdd:cake_1d", "tip": "§a半块切成两块小块"},
|
||||||
|
{"block": "rtdd:cake_2b", "item": CLEAVER, "action": "split_cake",
|
||||||
|
"dropItem": "rtdd:cake_2d", "tip": "§a半块切成两块小块"},
|
||||||
|
{"block": "rtdd:plate_35", "item": SUGAR, "target": "rtdd:cream_caramel",
|
||||||
|
"consume": 16, "tip": "§a做成焦糖布丁"},
|
||||||
|
{"block": "rtdd:plate_34", "item": CREAM, "target": "rtdd:creampastry_0",
|
||||||
|
"consume": 1, "tip": "§a做成舒芙蕾半成品"},
|
||||||
|
]
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 三、揉面/和面 连点计数(空手右键, 次数达标转换)
|
||||||
|
# ============================================================================
|
||||||
|
KNEAD_COUNTERS = {
|
||||||
|
"rtdd:farineblock_2": {"times": 2, "target": "rtdd:farineblock_3",
|
||||||
|
"tip": "§a揉面中…(%d/2)", "doneTip": "§a揉好了, 变成面粉块"},
|
||||||
|
"rtdd:farineblock_3": {"times": 3, "target": "rtdd:rawdough_0",
|
||||||
|
"tip": "§a和面中…(%d/3)", "doneTip": "§a和好面了, 变成生面团"},
|
||||||
|
}
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 四、手持物品右键方块表面规则 (itemUseOn)
|
||||||
|
# 生面饼右键烤炉 -> 烤炉上方放置 馍; 面粉(加鸡蛋)右键木碗 -> 木碗变蛋糕面糊
|
||||||
|
# ============================================================================
|
||||||
|
ITEM_USE_ON_RULES = [
|
||||||
|
{"item": "rtdd:dought_7", "surface": OVEN, "above": "rtdd:roujiamo_0",
|
||||||
|
"consume": 1, "tip": "§a烙制成了馍"},
|
||||||
|
{"item": "rtdd:farineblock_1", "surface": BOWL, "replace": "rtdd:cakebatterblock_0",
|
||||||
|
"consume": 1, "tip": "§a木碗变成了蛋糕面糊(生)"},
|
||||||
|
]
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 五、计时规则(供 MianshiTimerService)
|
||||||
|
# below: 下方方块判定列表(烤炉/蒸笼); dropOnBreak: 下方方块被打碎时该方块掉落+提示
|
||||||
|
# ============================================================================
|
||||||
|
TIMER_RULES = [
|
||||||
|
# 发酵(60秒, autoStart)
|
||||||
|
{"source": "rtdd:rawdough_4", "target": "rtdd:dough_0", "time": 60,
|
||||||
|
"autoStart": True, "doneTip": "§e面团发酵好了"},
|
||||||
|
{"source": "rtdd:breaddough_1", "target": "rtdd:breaddough_1a", "time": 60,
|
||||||
|
"autoStart": True, "doneTip": "§e法棍面胚发好了"},
|
||||||
|
# 蒸笼: 食物放蒸笼上 -> 蒸食物块(1秒) / 蒸熟(60秒)
|
||||||
|
{"source": "rtdd:dumplings_4", "target": "rtdd:steamerdumplings_0", "time": 1,
|
||||||
|
"below": [STEAMER], "autoStart": True},
|
||||||
|
{"source": "rtdd:roubaozi_3", "target": "rtdd:baozilong_1", "time": 1,
|
||||||
|
"below": [STEAMER], "autoStart": True},
|
||||||
|
{"source": "rtdd:bamboo_4", "target": "rtdd:bamboo_6", "time": 1,
|
||||||
|
"below": [STEAMER], "autoStart": True},
|
||||||
|
{"source": "rtdd:plate_34", "target": "rtdd:steamermilkandegg", "time": 1,
|
||||||
|
"below": [STEAMER], "autoStart": True},
|
||||||
|
{"source": "rtdd:steamerdumplings_0", "target": "rtdd:steamerdumplings_1", "time": 60,
|
||||||
|
"below": [STEAMER], "autoStart": True, "doneTip": "§e饺子蒸好了"},
|
||||||
|
{"source": "rtdd:baozilong_1", "target": "rtdd:baozilong_2", "time": 60,
|
||||||
|
"below": [STEAMER], "autoStart": True, "doneTip": "§e包子蒸好了"},
|
||||||
|
{"source": "rtdd:bamboo_6", "target": "rtdd:bamboo_7", "time": 60,
|
||||||
|
"below": [STEAMER], "autoStart": True, "doneTip": "§e竹筒饭蒸好了"},
|
||||||
|
{"source": "rtdd:steamermilkandegg", "target": "rtdd:steamermilkandegg_1", "time": 60,
|
||||||
|
"below": [STEAMER], "autoStart": True, "doneTip": "§e蒸牛奶鸡蛋好了"},
|
||||||
|
# 烤炉烘焙(60秒, 下方判定烤炉; 烤炉被打碎 -> 该方块掉落+提示)
|
||||||
|
{"source": "rtdd:breaddough_1a", "target": "rtdd:bread_1", "time": 60,
|
||||||
|
"below": [OVEN], "autoStart": True, "dropOnBreak": True, "doneTip": "§e法棍烤好了"},
|
||||||
|
{"source": "rtdd:breaddough_2", "target": "rtdd:bread_2", "time": 60,
|
||||||
|
"below": [OVEN], "autoStart": True, "dropOnBreak": True, "doneTip": "§e吐司烤好了"},
|
||||||
|
{"source": "rtdd:breaddough_4d", "target": "rtdd:bread_4c", "time": 60,
|
||||||
|
"below": [OVEN], "autoStart": True, "dropOnBreak": True, "doneTip": "§e甜甜圈胚烤好了"},
|
||||||
|
{"source": "rtdd:dought_9", "target": "rtdd:bread_3", "time": 60,
|
||||||
|
"below": [OVEN], "autoStart": True, "dropOnBreak": True, "doneTip": "§e可颂烤好了"},
|
||||||
|
{"source": "rtdd:cakebatterblock_0", "target": "rtdd:cakebatterblock", "time": 60,
|
||||||
|
"below": [OVEN], "autoStart": True, "dropOnBreak": True, "doneTip": "§e蛋糕面糊烤好了"},
|
||||||
|
{"source": "rtdd:plate_34", "target": "rtdd:plate_35", "time": 60,
|
||||||
|
"below": [OVEN], "autoStart": True, "dropOnBreak": True, "doneTip": "§e布丁半成品好了"},
|
||||||
|
{"source": "rtdd:creampastry_0", "target": "rtdd:souffle_0", "time": 60,
|
||||||
|
"below": [OVEN], "autoStart": True, "dropOnBreak": True, "doneTip": "§e舒芙蕾烤好了"},
|
||||||
|
]
|
||||||
|
|
||||||
|
# 烤炉烘焙掉落的提示语
|
||||||
|
BREAK_TIP = "§c烤炉被移走了, 烤制的方块掉落了!"
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
+337
@@ -0,0 +1,337 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
================================================================================
|
||||||
|
面食.甜食·右键转换引擎(服务端)
|
||||||
|
================================================================================
|
||||||
|
处理"面食.甜食"(xy_mianshi) 分类下的右键转换:
|
||||||
|
面粉·面团(和面/擀面/切分)、饺子、包子、馍、煎饼卷、竹筒饭、
|
||||||
|
面包堆叠/递减、面团胚料循环、甜点蛋糕(脱模/加料/切分)。
|
||||||
|
|
||||||
|
【事件监听在哪?】
|
||||||
|
本类【不】监听任何事件!
|
||||||
|
所有事件由 FeatureDispatcher 统一监听, 按 blockOwner/itemUseOnOwner
|
||||||
|
(多服务 fallback) 路由到本类 handleBlockUse / handleItemUseOn。
|
||||||
|
|
||||||
|
【本类怎么做】
|
||||||
|
handleBlockUse ← 入口:分发器转发右键方块事件
|
||||||
|
├─ _handleKnead ← 揉面/和面 连点计数(空手)
|
||||||
|
├─ _handleAction ← 特殊动作(蒸笼取出/切小面团/切生面/蛋糕脱模)
|
||||||
|
└─ handleSwitch ← 通用转换(加料/擀面/卷制/堆叠/递减/切分)
|
||||||
|
handleItemUseOn ← 入口:生面饼右键烤炉烙制 / 面粉(加鸡蛋)右键木碗做面糊
|
||||||
|
(通用工具) getCarriedItem / consumeItem / giveItem / dropItem / replaceBlock /
|
||||||
|
clearBlock / checkCooldown
|
||||||
|
================================================================================
|
||||||
|
"""
|
||||||
|
import time
|
||||||
|
import mod.server.extraServerApi as serverApi
|
||||||
|
|
||||||
|
# ---- 网易API基础对象 ----
|
||||||
|
ServerSystem = serverApi.GetServerSystemCls() # 服务端系统基类
|
||||||
|
comp = serverApi.GetEngineCompFactory() # 组件工厂
|
||||||
|
|
||||||
|
# ---- 继承 BlueFox 框架的系统基类(提供 CreateEngineItemEntity 等方法) ----
|
||||||
|
from ....BlueFoxTools.SpecialFunciton.BlueFoxSystem import BlueFoxServerSystem
|
||||||
|
from ....BlueFoxTools.ToolsConfig import LevelId
|
||||||
|
|
||||||
|
# ---- 只导入面食自己的数据库 ----
|
||||||
|
from ..MianshiData import (
|
||||||
|
CLEAVER, ROLLINGPIN, BOWL, OVEN,
|
||||||
|
MEAT_ITEMS, FILLING_ITEMS, RICH_MEAT_ITEMS,
|
||||||
|
SWITCH_RULES, KNEAD_COUNTERS, ITEM_USE_ON_RULES,
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---- 统一分发器 ----
|
||||||
|
from ...service.FeatureDispatcher import FeatureDispatcher
|
||||||
|
|
||||||
|
|
||||||
|
class MianshiService(BlueFoxServerSystem):
|
||||||
|
"""
|
||||||
|
面食.甜食·右键转换引擎
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, namespace, systemName):
|
||||||
|
super(MianshiService, self).__init__(namespace, systemName)
|
||||||
|
print "===== MianshiService init ====="
|
||||||
|
|
||||||
|
# ---- (方块, 手持物品) -> 规则: O(1) 查找 ----
|
||||||
|
self.recipes = {}
|
||||||
|
self.featureBlocks = set()
|
||||||
|
|
||||||
|
def add(rule):
|
||||||
|
block = rule["block"]
|
||||||
|
item = rule.get("item")
|
||||||
|
self.recipes[(block, item)] = rule
|
||||||
|
self.featureBlocks.add(block)
|
||||||
|
|
||||||
|
for r in SWITCH_RULES:
|
||||||
|
add(r)
|
||||||
|
|
||||||
|
# 竹筒饭加肉: (bamboo_2 + 任一肉类) -> bamboo_4
|
||||||
|
for meat in MEAT_ITEMS:
|
||||||
|
add({"block": "rtdd:bamboo_2", "item": meat,
|
||||||
|
"target": "rtdd:bamboo_4", "consume": 1, "tip": "§a竹筒加了肉"})
|
||||||
|
|
||||||
|
# 揉面/和面连点方块也要注册(空手右键路由)
|
||||||
|
for b in KNEAD_COUNTERS:
|
||||||
|
self.featureBlocks.add(b)
|
||||||
|
|
||||||
|
# ---- itemUseOn 映射: 手持物品 -> 规则 ----
|
||||||
|
self.itemUseOnMap = {}
|
||||||
|
for r in ITEM_USE_ON_RULES:
|
||||||
|
self.itemUseOnMap[r["item"]] = r
|
||||||
|
|
||||||
|
# ---- 揉面/和面计数 {(dim,x,y,z): n} ----
|
||||||
|
self.kneadCount = {}
|
||||||
|
|
||||||
|
# ---- 右键冷却表 ----
|
||||||
|
self.cooldown = {}
|
||||||
|
|
||||||
|
# ---- 注册到统一分发器 ----
|
||||||
|
FeatureDispatcher.register(self)
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 一、给 FeatureDispatcher 的接口
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def getFeatureBlocks(self):
|
||||||
|
"""返回本功能管辖的所有右键方块名集合"""
|
||||||
|
return self.featureBlocks
|
||||||
|
|
||||||
|
def getItemUseOnRules(self):
|
||||||
|
"""手持物品右键方块表面路由: 生面饼(烙制) / 面粉(加鸡蛋)(做面糊)"""
|
||||||
|
return {r["item"]: True for r in ITEM_USE_ON_RULES}
|
||||||
|
|
||||||
|
def handleBlockUse(self, args):
|
||||||
|
"""由 FeatureDispatcher 转发的右键方块入口"""
|
||||||
|
blockName = args.get("blockName")
|
||||||
|
playerId = args.get("playerId")
|
||||||
|
x, y, z = args.get("x"), args.get("y"), args.get("z")
|
||||||
|
pos = (x, y, z)
|
||||||
|
dim = comp.CreateDimension(playerId).GetEntityDimensionId()
|
||||||
|
key = (dim, x, y, z)
|
||||||
|
|
||||||
|
itemDict = self.getCarriedItem(playerId)
|
||||||
|
itemName = itemDict.get("newItemName") if itemDict else None
|
||||||
|
|
||||||
|
# ---- 揉面/和面: 空手右键连点 ----
|
||||||
|
if blockName in KNEAD_COUNTERS and (not itemName or itemName == "minecraft:air"):
|
||||||
|
return self._handleKnead(blockName, playerId, pos, dim, key)
|
||||||
|
|
||||||
|
# ---- 常规转换 ----
|
||||||
|
recipe = self.findRecipe(blockName, itemDict)
|
||||||
|
if not recipe:
|
||||||
|
return False
|
||||||
|
if not self.checkCooldown(key, 0.4):
|
||||||
|
return True
|
||||||
|
self.handleSwitch(recipe, playerId, pos, dim, itemDict)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def handleItemUseOn(self, args):
|
||||||
|
"""由 FeatureDispatcher 转发的"手持物品右键方块表面"入口:
|
||||||
|
1) 手持 生面饼 右键 烤炉 -> 烤炉上方放置 馍(烙制), 消耗1个生面饼
|
||||||
|
2) 手持 面粉(加鸡蛋) 右键 木碗 -> 木碗变 蛋糕面糊(生), 消耗1个
|
||||||
|
返回 True=处理了; False=不属本功能管(交还默认行为)。"""
|
||||||
|
itemName = args.get("itemName")
|
||||||
|
playerId = args.get("playerId") or args.get("entityId")
|
||||||
|
x, y, z = args.get("x"), args.get("y"), args.get("z")
|
||||||
|
dim = comp.CreateDimension(playerId).GetEntityDimensionId()
|
||||||
|
|
||||||
|
rule = self.itemUseOnMap.get(itemName)
|
||||||
|
if not rule:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 被点方块必须是规则要求的表面方块
|
||||||
|
try:
|
||||||
|
cur = comp.CreateBlockInfo(LevelId).GetBlockNew((x, y, z), dim)
|
||||||
|
if not cur or cur.get("name") != rule["surface"]:
|
||||||
|
return False
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not self.checkCooldown((dim, x, y, z), 0.4):
|
||||||
|
return True
|
||||||
|
|
||||||
|
itemDict = self.getCarriedItem(playerId)
|
||||||
|
if not itemDict:
|
||||||
|
return False
|
||||||
|
self.consumeItem(playerId, itemDict, rule.get("consume", 1))
|
||||||
|
|
||||||
|
if rule.get("above"):
|
||||||
|
# 在表面方块上方放置结果(烙制)
|
||||||
|
targetPos = (x, y + 1, z)
|
||||||
|
try:
|
||||||
|
cur = comp.CreateBlockInfo(LevelId).GetBlockNew(targetPos, dim)
|
||||||
|
if cur and cur.get("name") != "minecraft:air":
|
||||||
|
comp.CreateMsg(playerId).NotifyOneMessage(playerId, "§c上方被占, 无法烙制")
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
self.replaceBlock(targetPos, dim, rule["above"], playerId)
|
||||||
|
elif rule.get("replace"):
|
||||||
|
# 表面方块本身被替换(木碗变蛋糕面糊)
|
||||||
|
self.replaceBlock((x, y, z), dim, rule["replace"], playerId)
|
||||||
|
|
||||||
|
if rule.get("tip"):
|
||||||
|
comp.CreateMsg(playerId).NotifyOneMessage(playerId, rule["tip"])
|
||||||
|
return True
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 二、规则匹配(精确 + 空手 fallback)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def findRecipe(self, blockName, itemDict):
|
||||||
|
itemName = itemDict.get("newItemName") if itemDict else None
|
||||||
|
recipe = self.recipes.get((blockName, itemName))
|
||||||
|
if recipe:
|
||||||
|
return recipe
|
||||||
|
if not itemName or itemName == "minecraft:air":
|
||||||
|
return self.recipes.get((blockName, None))
|
||||||
|
return None
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 三、揉面/和面(空手右键连点)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def _handleKnead(self, blockName, playerId, pos, dim, key):
|
||||||
|
if not self.checkCooldown(key, 0.4):
|
||||||
|
return True
|
||||||
|
cfg = KNEAD_COUNTERS[blockName]
|
||||||
|
n = self.kneadCount.get(key, 0) + 1
|
||||||
|
if n >= cfg["times"]:
|
||||||
|
self.kneadCount.pop(key, None)
|
||||||
|
self.replaceBlock(pos, dim, cfg["target"], playerId)
|
||||||
|
comp.CreateMsg(playerId).NotifyOneMessage(playerId, cfg.get("doneTip", "§a完成"))
|
||||||
|
else:
|
||||||
|
self.kneadCount[key] = n
|
||||||
|
comp.CreateMsg(playerId).NotifyOneMessage(playerId, cfg["tip"] % n)
|
||||||
|
return True
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 四、通用转换执行
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def handleSwitch(self, recipe, playerId, pos, dim, itemDict):
|
||||||
|
# 消耗物品
|
||||||
|
if recipe.get("consume", 0) > 0:
|
||||||
|
self.consumeItem(playerId, itemDict, recipe["consume"])
|
||||||
|
# 替换方块
|
||||||
|
if recipe.get("target"):
|
||||||
|
self.replaceBlock(pos, dim, recipe["target"], playerId)
|
||||||
|
# 特殊动作(自行管理掉落, 避免与通用掉落重复)
|
||||||
|
action = recipe.get("action")
|
||||||
|
# 掉落物(切分/递减/取出) —— 无特殊动作时才走通用掉落
|
||||||
|
if recipe.get("dropItem") and not action:
|
||||||
|
self.dropItem(dim, pos, recipe["dropItem"])
|
||||||
|
# 给背包物品(水桶变空桶/擀面杖返还)
|
||||||
|
if recipe.get("give"):
|
||||||
|
self.giveItem(playerId, recipe["give"])
|
||||||
|
# 特殊动作
|
||||||
|
if action == "chop_smalldough":
|
||||||
|
self.clearBlock(pos, dim)
|
||||||
|
for _ in range(8):
|
||||||
|
self.dropItem(dim, pos, "rtdd:smalldough_0")
|
||||||
|
elif action == "chop_noodles":
|
||||||
|
self.clearBlock(pos, dim)
|
||||||
|
self.dropItem(dim, pos, "rtdd:noodles")
|
||||||
|
elif action == "unmold_cake":
|
||||||
|
# 蛋糕面糊(烤熟) 脱模 -> 蛋糕胚(方块) + 掉落 1 木碗
|
||||||
|
self.replaceBlock(pos, dim, "rtdd:cakebase", playerId)
|
||||||
|
self.dropItem(dim, pos, BOWL)
|
||||||
|
elif action == "split_cake":
|
||||||
|
# 半块蛋糕 菜刀拆分: 半块消失 -> 掉落两个对应小块
|
||||||
|
self.clearBlock(pos, dim)
|
||||||
|
for _ in range(2):
|
||||||
|
self.dropItem(dim, pos, recipe["dropItem"])
|
||||||
|
elif action == "take_steamer":
|
||||||
|
# 蒸笼取出: 蒸食物块 -> 变回空蒸笼 + 掉落成品
|
||||||
|
self.replaceBlock(pos, dim, "rtdd:steamer", playerId)
|
||||||
|
if recipe.get("dropItem"):
|
||||||
|
self.dropItem(dim, pos, recipe["dropItem"])
|
||||||
|
# 提示
|
||||||
|
if recipe.get("tip"):
|
||||||
|
comp.CreateMsg(playerId).NotifyOneMessage(playerId, recipe["tip"])
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 五、工具方法:获取玩家主手物品
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def getCarriedItem(self, playerId):
|
||||||
|
itemComp = comp.CreateItem(playerId)
|
||||||
|
return itemComp.GetPlayerItem(
|
||||||
|
serverApi.GetMinecraftEnum().ItemPosType.CARRIED, 0, True)
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 六、工具方法:给玩家物品
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def giveItem(self, playerId, itemName, count=1, aux=0):
|
||||||
|
try:
|
||||||
|
itemDict = {"itemName": itemName, "count": count, "auxValue": aux}
|
||||||
|
comp.CreateItem(playerId).SpawnItemToPlayerInv(itemDict, playerId)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 七、工具方法:消耗物品
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def consumeItem(self, playerId, itemDict, amount=1):
|
||||||
|
if itemDict is None:
|
||||||
|
return
|
||||||
|
count = itemDict.get("count", 0)
|
||||||
|
if count <= amount:
|
||||||
|
comp.CreateItem(playerId).SetEntityItem(
|
||||||
|
serverApi.GetMinecraftEnum().ItemPosType.CARRIED,
|
||||||
|
{"itemName": "minecraft:air", "count": 0, "auxValue": 0})
|
||||||
|
else:
|
||||||
|
itemDict["count"] = count - amount
|
||||||
|
comp.CreateItem(playerId).SetEntityItem(
|
||||||
|
serverApi.GetMinecraftEnum().ItemPosType.CARRIED,
|
||||||
|
{"itemName": itemDict["newItemName"],
|
||||||
|
"count": itemDict["count"],
|
||||||
|
"auxValue": itemDict.get("newAuxValue", 0),
|
||||||
|
"userData": itemDict.get("userData", {})})
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 八、工具方法:以掉落物形式生成物品
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def dropItem(self, dim, pos, itemName, count=1, aux=0):
|
||||||
|
try:
|
||||||
|
itemDict = {"itemName": itemName, "count": count, "auxValue": aux}
|
||||||
|
self.CreateEngineItemEntity(itemDict, dim, (pos[0], pos[1] + 0.5, pos[2]))
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 九、工具方法:替换方块 / 清空方块(保留 aux, 兼容定向变体)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def replaceBlock(self, pos, dim, newBlockName, playerId=None):
|
||||||
|
creator = playerId if playerId is not None else LevelId
|
||||||
|
aux = 0
|
||||||
|
try:
|
||||||
|
oldBlock = comp.CreateBlockInfo(creator).GetBlockNew(pos, dim)
|
||||||
|
aux = oldBlock.get("aux", 0)
|
||||||
|
except Exception:
|
||||||
|
aux = 0
|
||||||
|
comp.CreateBlockInfo(creator).SetBlockNew(
|
||||||
|
pos, blockDict={"name": newBlockName, "aux": aux},
|
||||||
|
oldBlockHandling=0, dimensionId=dim)
|
||||||
|
|
||||||
|
def clearBlock(self, pos, dim):
|
||||||
|
comp.CreateBlockInfo(LevelId).SetBlockNew(
|
||||||
|
pos, blockDict={"name": "minecraft:air", "aux": 0},
|
||||||
|
oldBlockHandling=0, dimensionId=dim)
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 十、工具方法:冷却检查
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def checkCooldown(self, key, cd=0.4):
|
||||||
|
now = time.time()
|
||||||
|
last = self.cooldown.get(key, 0)
|
||||||
|
if now - last < cd:
|
||||||
|
return False
|
||||||
|
self.cooldown[key] = now
|
||||||
|
return True
|
||||||
+259
@@ -0,0 +1,259 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
================================================================================
|
||||||
|
面食.甜食·计时转换引擎(服务端)
|
||||||
|
================================================================================
|
||||||
|
只处理"面食.甜食"(xy_mianshi) 分类下的【计时自动转换】:
|
||||||
|
发酵60秒(和面_4 -> 发酵后 / 法棍面胚_1 -> 发面)
|
||||||
|
蒸笼蒸熟60秒(食物放蒸笼上 1秒入蒸笼, 再60秒蒸熟)
|
||||||
|
烤炉烘焙60秒(下方判定烤炉: 胚料/面糊/蛋液 放烤炉上计时)
|
||||||
|
|
||||||
|
【与右键转换解耦】
|
||||||
|
右键转换(和面/擀面/加料/蒸笼取出等)在 MianshiService, 本类只负责计时。
|
||||||
|
|
||||||
|
【烤炉机制(用户指定)】
|
||||||
|
- 下方方块判定为 烤炉(oven) 才对该方块计时, 烤炉只做判断用
|
||||||
|
- 计时期间 烤炉被打碎 -> 终止计时, 烤炉上方方块 变成掉落物, 并给出提示
|
||||||
|
|
||||||
|
【下方判定】
|
||||||
|
below: 该方块的"正下方一格"必须是指定方块(烤炉/蒸笼)才计时
|
||||||
|
dropOnBreak: 下方判定失败且计时中 -> 方块掉落+提示(烤炉); 否则暂停(蒸笼)
|
||||||
|
|
||||||
|
【事件监听在哪?】
|
||||||
|
本类【不】监听任何事件!
|
||||||
|
ServerBlockEntityTickEvent 由 FeatureDispatcher 统一监听, 再按 timerOwner
|
||||||
|
路由到本类的 handleBlockEntityTick。计时用绝对时间戳写方块实体数据,
|
||||||
|
退出重进继续计时。
|
||||||
|
================================================================================
|
||||||
|
"""
|
||||||
|
import time
|
||||||
|
import mod.server.extraServerApi as serverApi
|
||||||
|
|
||||||
|
# ---- 网易API基础对象 ----
|
||||||
|
ServerSystem = serverApi.GetServerSystemCls() # 服务端系统基类
|
||||||
|
comp = serverApi.GetEngineCompFactory() # 组件工厂
|
||||||
|
|
||||||
|
# ---- 继承 BlueFox 框架的系统基类 ----
|
||||||
|
from ....BlueFoxTools.SpecialFunciton.BlueFoxSystem import BlueFoxServerSystem
|
||||||
|
from ....BlueFoxTools.ToolsConfig import LevelId
|
||||||
|
|
||||||
|
# ---- 方块实体数据组件(计时持久化: 开始时间戳+时长写进方块) ----
|
||||||
|
blockEntityDataComp = comp.CreateBlockEntityData(LevelId)
|
||||||
|
|
||||||
|
# ---- 只导入面食自己的数据库 ----
|
||||||
|
from ..MianshiData import TIMER_RULES, BREAK_TIP
|
||||||
|
|
||||||
|
# ---- 统一分发器 ----
|
||||||
|
from ...service.FeatureDispatcher import FeatureDispatcher
|
||||||
|
|
||||||
|
|
||||||
|
class MianshiTimerService(BlueFoxServerSystem):
|
||||||
|
"""
|
||||||
|
面食.甜食·计时转换引擎
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, namespace, systemName):
|
||||||
|
super(MianshiTimerService, self).__init__(namespace, systemName)
|
||||||
|
print "===== MianshiTimerService init ====="
|
||||||
|
|
||||||
|
# ---- 计时规则: source -> [规则...] (同一source可对应蒸笼/烤炉等不同下方) ----
|
||||||
|
self.timerMap = {}
|
||||||
|
for t in TIMER_RULES:
|
||||||
|
self.timerMap.setdefault(t["source"], []).append(t)
|
||||||
|
|
||||||
|
# ---- 注册到分发器的计时路由表 ----
|
||||||
|
FeatureDispatcher.registerTimer(self)
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 一、给 FeatureDispatcher 的接口
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def getTimerBlocks(self):
|
||||||
|
"""返回本功能的所有"计时源方块"集合(tick 路由用)"""
|
||||||
|
return set(self.timerMap.keys())
|
||||||
|
|
||||||
|
def handleBlockEntityTick(self, args):
|
||||||
|
"""由 FeatureDispatcher 转发的计时方块 tick 入口"""
|
||||||
|
dim = args.get("dimension")
|
||||||
|
pos = (args.get("posX"), args.get("posY"), args.get("posZ"))
|
||||||
|
blockName = args.get("blockName", "")
|
||||||
|
self._tickProcess(dim, pos, blockName)
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 二、启动计时(本模块 autoStart, 保留接口以便需要时外部触发)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def startTimer(self, dim, pos, blockName, playerId=None):
|
||||||
|
rules = self.timerMap.get(blockName)
|
||||||
|
if not rules:
|
||||||
|
return False
|
||||||
|
rule = self._pickRule(rules, dim, pos)
|
||||||
|
if not rule:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
data = blockEntityDataComp.GetBlockEntityData(dim, pos)
|
||||||
|
if data and data["rtdd_tid"] == blockName:
|
||||||
|
return False
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
self._writeTimerData(dim, pos, rule, playerId)
|
||||||
|
return True
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 三、tick 检查与到点转换
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def _pickRule(self, rules, dim, pos):
|
||||||
|
"""按"下方方块"匹配规则(蒸笼/烤炉等), 返回命中的规则; 无命中返回 None"""
|
||||||
|
belowPos = (pos[0], pos[1] - 1, pos[2])
|
||||||
|
try:
|
||||||
|
b = comp.CreateBlockInfo(LevelId).GetBlockNew(belowPos, dim)
|
||||||
|
belowName = b.get("name") if b else ""
|
||||||
|
except Exception:
|
||||||
|
belowName = ""
|
||||||
|
for rule in rules:
|
||||||
|
if belowName in rule.get("below", [belowName]):
|
||||||
|
return rule
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _tickProcess(self, dim, pos, blockName):
|
||||||
|
try:
|
||||||
|
rules = self.timerMap.get(blockName)
|
||||||
|
if not rules:
|
||||||
|
return
|
||||||
|
|
||||||
|
blockData = blockEntityDataComp.GetBlockEntityData(dim, pos)
|
||||||
|
if blockData is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
tid = blockData["rtdd_tid"]
|
||||||
|
except Exception:
|
||||||
|
tid = ""
|
||||||
|
if tid != blockName:
|
||||||
|
# autoStart: 计时源方块无计时数据且下方方块匹配时自动启动
|
||||||
|
if any(r.get("autoStart", True) for r in rules):
|
||||||
|
rule = self._pickRule(rules, dim, pos)
|
||||||
|
if rule:
|
||||||
|
self._writeTimerData(dim, pos, rule, None)
|
||||||
|
return
|
||||||
|
|
||||||
|
# 计时中: 按下方判定规则处理(烤炉被打碎 -> 掉落; 蒸笼移走 -> 暂停)
|
||||||
|
rule = self._pickRule(rules, dim, pos)
|
||||||
|
if rule is None:
|
||||||
|
self._handleBelowBroken(dim, pos, blockName, blockData, rules)
|
||||||
|
return
|
||||||
|
|
||||||
|
tstart = blockData["rtdd_tstart"]
|
||||||
|
tdur = blockData["rtdd_tdur"]
|
||||||
|
|
||||||
|
if time.time() - tstart >= tdur:
|
||||||
|
self._finishTimer(dim, pos, rule, blockData)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _handleBelowBroken(self, dim, pos, blockName, data, rules):
|
||||||
|
"""下方判定方块被打碎/移走:
|
||||||
|
- 烤炉(dropOnBreak): 终止计时 + 方块掉落 + 提示
|
||||||
|
- 蒸笼: 暂停计时(数据保留, 蒸笼回来继续)"""
|
||||||
|
rule = None
|
||||||
|
for r in rules:
|
||||||
|
if r.get("dropOnBreak"):
|
||||||
|
rule = r
|
||||||
|
break
|
||||||
|
if rule is None:
|
||||||
|
return # 蒸笼等: 暂停
|
||||||
|
# 烤炉被打碎: 方块掉落 + 变空气 + 终止计时 + 提示
|
||||||
|
self._clearTimerData(dim, pos)
|
||||||
|
self._dropBlockItem(dim, pos, blockName)
|
||||||
|
self._setAir(dim, pos)
|
||||||
|
self._notifyIfOnline(data.get("rtdd_tp"), BREAK_TIP)
|
||||||
|
|
||||||
|
def _finishTimer(self, dim, pos, rule, data):
|
||||||
|
try:
|
||||||
|
cur = comp.CreateBlockInfo(LevelId).GetBlockNew(pos, dim)
|
||||||
|
if cur and cur.get("name") != rule["source"]:
|
||||||
|
self._clearTimerData(dim, pos)
|
||||||
|
return
|
||||||
|
# 到点转换
|
||||||
|
self.replaceBlock(pos, dim, rule["target"], None)
|
||||||
|
self._clearTimerData(dim, pos)
|
||||||
|
if rule.get("doneTip"):
|
||||||
|
self._notifyIfOnline(data.get("rtdd_tp"), rule["doneTip"])
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 四、计时数据读写(存在方块实体数据里,重启不丢)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def _writeTimerData(self, dim, pos, recipe, playerId=None):
|
||||||
|
try:
|
||||||
|
blockData = blockEntityDataComp.GetBlockEntityData(dim, pos)
|
||||||
|
if blockData is None:
|
||||||
|
return
|
||||||
|
now = time.time()
|
||||||
|
blockData["rtdd_tid"] = recipe["source"]
|
||||||
|
blockData["rtdd_tstart"] = now
|
||||||
|
blockData["rtdd_tdur"] = recipe.get("time", 60)
|
||||||
|
blockData["rtdd_tp"] = playerId if playerId else ""
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _clearTimerData(self, dim, pos):
|
||||||
|
try:
|
||||||
|
blockData = blockEntityDataComp.GetBlockEntityData(dim, pos)
|
||||||
|
if blockData is None:
|
||||||
|
return
|
||||||
|
blockData["rtdd_tid"] = ""
|
||||||
|
blockData["rtdd_tstart"] = 0
|
||||||
|
blockData["rtdd_tdur"] = 0
|
||||||
|
blockData["rtdd_tp"] = ""
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 五、工具方法:完成/掉落提示
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def _notifyIfOnline(self, playerId, tip):
|
||||||
|
if not tip or not playerId:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
ids = comp.CreateGame(LevelId).GetAllPlayerIds()
|
||||||
|
if playerId in ids:
|
||||||
|
comp.CreateMsg(playerId).NotifyOneMessage(playerId, tip)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _dropBlockItem(self, dim, pos, blockName):
|
||||||
|
"""把当前方块以物品实体形式掉落(烤炉被打碎时)"""
|
||||||
|
try:
|
||||||
|
itemDict = {"itemName": blockName, "count": 1, "auxValue": 0}
|
||||||
|
self.CreateEngineItemEntity(itemDict, dim, (pos[0], pos[1] + 0.5, pos[2]))
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _setAir(self, dim, pos):
|
||||||
|
try:
|
||||||
|
comp.CreateBlockInfo(LevelId).SetBlockNew(
|
||||||
|
pos, blockDict={"name": "minecraft:air", "aux": 0},
|
||||||
|
oldBlockHandling=0, dimensionId=dim)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 六、工具方法:替换方块
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def replaceBlock(self, pos, dim, newBlockName, playerId=None):
|
||||||
|
creator = playerId if playerId is not None else LevelId
|
||||||
|
aux = 0
|
||||||
|
try:
|
||||||
|
oldBlock = comp.CreateBlockInfo(creator).GetBlockNew(pos, dim)
|
||||||
|
aux = oldBlock.get("aux", 0)
|
||||||
|
except Exception:
|
||||||
|
aux = 0
|
||||||
|
comp.CreateBlockInfo(creator).SetBlockNew(
|
||||||
|
pos, blockDict={"name": newBlockName, "aux": aux},
|
||||||
|
oldBlockHandling=0, dimensionId=dim)
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
+33
-23
@@ -59,6 +59,7 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
|||||||
# ---- 类级共享路由表(用类变量,任何实例都能读写) ----
|
# ---- 类级共享路由表(用类变量,任何实例都能读写) ----
|
||||||
blockOwner = {}
|
blockOwner = {}
|
||||||
blockSet = set()
|
blockSet = set()
|
||||||
|
blockOwnerAll = {} # 方块名 -> [服务...]: 同一方块可被多个服务注册(按注册顺序), 逐个 fallback
|
||||||
itemUseOnOwner = {}
|
itemUseOnOwner = {}
|
||||||
itemUseOnSet = set()
|
itemUseOnSet = set()
|
||||||
itemUseOnAll = {} # 物品名 -> [服务...]: 同一物品可被多个服务注册(按注册顺序), 逐个 fallback
|
itemUseOnAll = {} # 物品名 -> [服务...]: 同一物品可被多个服务注册(按注册顺序), 逐个 fallback
|
||||||
@@ -81,12 +82,14 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
|||||||
def register(cls, service):
|
def register(cls, service):
|
||||||
"""
|
"""
|
||||||
右键服务初始化时调用:把管辖的"右键方块"和"手持物品右键方块表面"注册进路由表。
|
右键服务初始化时调用:把管辖的"右键方块"和"手持物品右键方块表面"注册进路由表。
|
||||||
同一方块/物品只会归属最后一个注册的服务(一般不会冲突)。
|
同一方块/物品可被多个服务注册(如 面粉块: 食材裹粉去重 + 面食和面),
|
||||||
|
按注册顺序追加, OnBlockUse/OnItemUseOn 逐个 fallback(第一个返回 True 的处理)。
|
||||||
"""
|
"""
|
||||||
# 右键方块路由:方块名 → 服务
|
# 右键方块路由:方块名 → 服务列表
|
||||||
for block in service.getFeatureBlocks():
|
for block in service.getFeatureBlocks():
|
||||||
cls.blockOwner[block] = service
|
cls.blockOwner[block] = service
|
||||||
cls.blockSet.add(block)
|
cls.blockSet.add(block)
|
||||||
|
cls.blockOwnerAll.setdefault(block, []).append(service)
|
||||||
|
|
||||||
# 手持物品右键方块表面路由:物品名 → 服务
|
# 手持物品右键方块表面路由:物品名 → 服务
|
||||||
for itemName in service.getItemUseOnRules():
|
for itemName in service.getItemUseOnRules():
|
||||||
@@ -189,23 +192,27 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
|||||||
def OnBlockUse(self, args):
|
def OnBlockUse(self, args):
|
||||||
"""
|
"""
|
||||||
玩家右键方块时触发。
|
玩家右键方块时触发。
|
||||||
用被右键的方块名 O(1) 定位到唯一的功能服务,转发给它的 handleBlockUse。
|
用被右键的方块名 O(1) 定位到注册它的所有功能服务(blockOwnerAll, 按注册顺序),
|
||||||
|
逐个尝试 handleBlockUse, 第一个返回 True 的服务处理成功(多服务 fallback,
|
||||||
|
如 面粉块: 食材服务先试(裹粉去重, 空手无规则返回False) -> 面食服务和面)。
|
||||||
|
|
||||||
服务返回 True = 处理成功 → 取消默认行为,并标记拦截下一次物品使用
|
服务返回 True = 处理成功 → 取消默认行为,并标记拦截下一次物品使用
|
||||||
服务返回 False = 当前组合无匹配规则 → 交还默认行为
|
服务返回 False = 当前组合无匹配规则 → 交还默认行为
|
||||||
"""
|
"""
|
||||||
blockName = args.get("blockName")
|
blockName = args.get("blockName")
|
||||||
service = self.blockOwner.get(blockName)
|
services = self.blockOwnerAll.get(blockName)
|
||||||
print "[FD-BlockUse]", blockName, "svc:", (service.__class__.__name__ if service else "NONE")
|
print "[FD-BlockUse]", blockName, "svcs:", ([s.__class__.__name__ for s in services] if services else "NONE")
|
||||||
if not service:
|
if not services:
|
||||||
# 这个方块不属于任何已注册的功能 → 交给原版/其他模组处理
|
# 这个方块不属于任何已注册的功能 → 交给原版/其他模组处理
|
||||||
return
|
return
|
||||||
|
|
||||||
handled = service.handleBlockUse(args)
|
for service in services:
|
||||||
if handled:
|
handled = service.handleBlockUse(args)
|
||||||
args['cancel'] = True
|
if handled:
|
||||||
playerId = args.get("playerId")
|
args['cancel'] = True
|
||||||
self._cancelItemUse[playerId] = True
|
playerId = args.get("playerId")
|
||||||
|
self._cancelItemUse[playerId] = True
|
||||||
|
return
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# 主入口2:手持物品右键方块表面 → 按 itemUseOnOwner 路由到右键服务
|
# 主入口2:手持物品右键方块表面 → 按 itemUseOnOwner 路由到右键服务
|
||||||
@@ -229,7 +236,7 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
|||||||
print "[FD-ItemUseOn]", itemName, "svcs:", [s.__class__.__name__ for s in services]
|
print "[FD-ItemUseOn]", itemName, "svcs:", [s.__class__.__name__ for s in services]
|
||||||
|
|
||||||
playerId = args.get("playerId") or args.get("entityId")
|
playerId = args.get("playerId") or args.get("entityId")
|
||||||
# 被点方块(用于去重: 该方块归哪个右键服务管辖)
|
# 被点方块(用于去重: 该方块归哪些右键服务管辖)
|
||||||
clickedName = None
|
clickedName = None
|
||||||
try:
|
try:
|
||||||
dim = comp.CreateDimension(playerId).GetEntityDimensionId()
|
dim = comp.CreateDimension(playerId).GetEntityDimensionId()
|
||||||
@@ -239,15 +246,16 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
owners = self.blockOwnerAll.get(clickedName) if clickedName else None
|
||||||
for service in services:
|
for service in services:
|
||||||
# 被点方块属于某个"右键方块"服务的管辖(条箱/挂肉钩/锅具等) → 该方块右键由
|
# 被点方块属于某些"右键方块"服务的管辖(条箱/挂肉钩/锅具等) → 该方块右键由
|
||||||
# ServerBlockUseEvent 处理(放入/挂鱼/做菜), 跳过本服务的 itemUseOn,
|
# ServerBlockUseEvent 处理(放入/挂鱼/做菜), 跳过本服务的 itemUseOn,
|
||||||
# 避免与方块右键逻辑重复(如手持鲑鱼右键条箱应放入而非放置死鲑鱼)。
|
# 避免与方块右键逻辑重复(如手持鲑鱼右键条箱应放入而非放置死鲑鱼)。
|
||||||
# 例外: 被点方块的 owner 就是当前服务自己(如 食材裹粉: 面粉块归 ShicaiService
|
# 例外: 当前服务本身就在被点方块的归属列表里(如 食材裹粉: 面粉块归
|
||||||
# 管辖, 手持生食材右键它时放行给 handleItemUseOn 处理) 则继续尝试。
|
# ShicaiService+面食服务 管辖, 手持生食材右键它时放行给 handleItemUseOn
|
||||||
if clickedName and clickedName in self.blockOwner:
|
# 处理) 则继续尝试。
|
||||||
if self.blockOwner[clickedName] is not service:
|
if clickedName and owners and service not in owners:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
handled = service.handleItemUseOn(args)
|
handled = service.handleItemUseOn(args)
|
||||||
if handled:
|
if handled:
|
||||||
@@ -314,11 +322,13 @@ class FeatureDispatcher(BlueFoxServerSystem):
|
|||||||
blockName = args.get("fullName") or args.get("blockName")
|
blockName = args.get("fullName") or args.get("blockName")
|
||||||
args["blockName"] = blockName # 统一成 blockName 字段, 服务内部直接用
|
args["blockName"] = blockName # 统一成 blockName 字段, 服务内部直接用
|
||||||
|
|
||||||
# 1. 优先: 归属的右键服务实现了 handleDestroy → 交给服务处理
|
# 1. 优先: 归属的右键服务实现了 handleDestroy → 交给服务处理(逐个 fallback)
|
||||||
service = self.blockOwner.get(blockName)
|
services = self.blockOwnerAll.get(blockName)
|
||||||
if service and hasattr(service, "handleDestroy"):
|
if services:
|
||||||
if service.handleDestroy(args):
|
for service in services:
|
||||||
return
|
if hasattr(service, "handleDestroy"):
|
||||||
|
if service.handleDestroy(args):
|
||||||
|
return
|
||||||
|
|
||||||
# 2. 静态映射: 放置的死鱼/生鸡肉 → 原版生食材
|
# 2. 静态映射: 放置的死鱼/生鸡肉 → 原版生食材
|
||||||
itemName = self.DESTROY_DROP.get(blockName)
|
itemName = self.DESTROY_DROP.get(blockName)
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
"netease:block_entity": {
|
"netease:block_entity": {
|
||||||
"client_tick": false,
|
"client_tick": false,
|
||||||
"movable": false,
|
"movable": false,
|
||||||
"tick": false
|
"tick": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
"netease:block_entity": {
|
"netease:block_entity": {
|
||||||
"client_tick": false,
|
"client_tick": false,
|
||||||
"movable": false,
|
"movable": false,
|
||||||
"tick": false
|
"tick": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
"netease:block_entity": {
|
"netease:block_entity": {
|
||||||
"client_tick": false,
|
"client_tick": false,
|
||||||
"movable": false,
|
"movable": false,
|
||||||
"tick": false
|
"tick": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
"netease:block_entity": {
|
"netease:block_entity": {
|
||||||
"client_tick": false,
|
"client_tick": false,
|
||||||
"movable": false,
|
"movable": false,
|
||||||
"tick": false
|
"tick": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
"netease:block_entity": {
|
"netease:block_entity": {
|
||||||
"client_tick": false,
|
"client_tick": false,
|
||||||
"movable": false,
|
"movable": false,
|
||||||
"tick": false
|
"tick": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
"netease:block_entity": {
|
"netease:block_entity": {
|
||||||
"client_tick": false,
|
"client_tick": false,
|
||||||
"movable": false,
|
"movable": false,
|
||||||
"tick": false
|
"tick": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
"netease:block_entity": {
|
"netease:block_entity": {
|
||||||
"client_tick": false,
|
"client_tick": false,
|
||||||
"movable": false,
|
"movable": false,
|
||||||
"tick": false
|
"tick": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
"netease:block_entity": {
|
"netease:block_entity": {
|
||||||
"client_tick": false,
|
"client_tick": false,
|
||||||
"movable": false,
|
"movable": false,
|
||||||
"tick": false
|
"tick": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
"netease:block_entity": {
|
"netease:block_entity": {
|
||||||
"client_tick": false,
|
"client_tick": false,
|
||||||
"movable": false,
|
"movable": false,
|
||||||
"tick": false
|
"tick": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
"netease:block_entity": {
|
"netease:block_entity": {
|
||||||
"client_tick": false,
|
"client_tick": false,
|
||||||
"movable": false,
|
"movable": false,
|
||||||
"tick": false
|
"tick": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
"netease:block_entity": {
|
"netease:block_entity": {
|
||||||
"client_tick": false,
|
"client_tick": false,
|
||||||
"movable": false,
|
"movable": false,
|
||||||
"tick": false
|
"tick": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
"netease:block_entity": {
|
"netease:block_entity": {
|
||||||
"client_tick": false,
|
"client_tick": false,
|
||||||
"movable": false,
|
"movable": false,
|
||||||
"tick": false
|
"tick": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
"netease:block_entity": {
|
"netease:block_entity": {
|
||||||
"client_tick": false,
|
"client_tick": false,
|
||||||
"movable": false,
|
"movable": false,
|
||||||
"tick": false
|
"tick": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
"netease:block_entity": {
|
"netease:block_entity": {
|
||||||
"client_tick": false,
|
"client_tick": false,
|
||||||
"movable": false,
|
"movable": false,
|
||||||
"tick": false
|
"tick": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
"netease:block_entity": {
|
"netease:block_entity": {
|
||||||
"client_tick": false,
|
"client_tick": false,
|
||||||
"movable": false,
|
"movable": false,
|
||||||
"tick": false
|
"tick": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
"netease:block_entity": {
|
"netease:block_entity": {
|
||||||
"client_tick": false,
|
"client_tick": false,
|
||||||
"movable": false,
|
"movable": false,
|
||||||
"tick": false
|
"tick": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -564,3 +564,65 @@ FurnitureData+FurnitureService 实现, 注册到 FeatureDispatcher)
|
|||||||
category 由 xy_mianshi 改为 xy_jinyong, 从 面团·胚料(food_04_dough) 分组移除,
|
category 由 xy_mianshi 改为 xy_jinyong, 从 面团·胚料(food_04_dough) 分组移除,
|
||||||
面食txt 已归入禁用清单补记 (吐司面胚现仅 breaddough_2) [已调整]
|
面食txt 已归入禁用清单补记 (吐司面胚现仅 breaddough_2) [已调整]
|
||||||
|
|
||||||
|
|
||||||
|
########################################
|
||||||
|
【面食.甜食】(xy_mianshi) 2026-09-10 实现
|
||||||
|
########################################
|
||||||
|
实现于 xiangyemod/mianshi (MianshiData + MianshiService + MianshiTimerService, 注册到 FeatureDispatcher)
|
||||||
|
+ FeatureDispatcher 升级: 方块路由 blockOwner 改为多服务 fallback(blockOwnerAll),
|
||||||
|
与物品路由 itemUseOnAll 一致 (面粉块: 食材裹粉去重 + 面食和面 共管) [已实现]
|
||||||
|
+ 16个计时源方块 netease:block_entity tick 改为 true (发酵/蒸/烤炉)
|
||||||
|
|
||||||
|
一、面粉·面团组
|
||||||
|
- 面粉+鸡蛋x3 -> 面粉(加鸡蛋); +水桶(水桶变空桶) -> 面粉(加水) [已实现]
|
||||||
|
- 揉面(空手x2) -> 面粉块; 和面(空手x3) -> 生面团; 空手和面四级(和面_1~4) [已实现]
|
||||||
|
- 和面_4 计时60秒 -> 发酵后; 和面_4 + 菜刀 -> 掉落8个小面团 [已实现]
|
||||||
|
- 擀面链: 发酵后 手持擀面杖(消耗1根) -> 擀面_1, 空手逐级 -> 擀面_6 -> 生面饼(返还擀面杖) [已实现]
|
||||||
|
- 生面饼+菜刀 -> 面饼切开; 面饼切开 空手 -> 可颂胚 / +菜刀 -> 掉落生面 [已实现]
|
||||||
|
- 小面团链: 手持擀面杖(消耗1根) -> 擀面_1, 空手 -> 擀面_3 -> 饺子皮(返还擀面杖) [已实现]
|
||||||
|
|
||||||
|
二、饺子组
|
||||||
|
- 饺子皮 + 猪肉馅/青菜碎 双向组合 -> 饺子皮(猪肉馅加蔬菜) -> 生饺子(捏合) [已实现]
|
||||||
|
- 生饺子 放蒸笼上(下方蒸笼) 1秒入笼 -> 蒸笼(蒸饺子_生), 60秒 -> 熟 [已实现]
|
||||||
|
- 手持盘子(plate_0)右键熟 -> 掉落盘装水饺(plate_30) + 蒸笼归位 [已实现]
|
||||||
|
|
||||||
|
三、包子组
|
||||||
|
- 饺子皮 空手 -> 包子皮; +猪/牛肉馅 -> 包子皮(加肉); 捏合/塑形 -> 生肉包子 [已实现]
|
||||||
|
- 生肉包子 放蒸笼上 -> 蒸笼(包子_生), 60秒 -> 熟; 空手取出 熟肉包子 + 蒸笼归位 [已实现]
|
||||||
|
- 熟肉包子+菜刀 -> 半个 -> 1/4个; 手持熟肉包子堆叠(两个/三个); 空手递减取走(掉落1个) [已实现]
|
||||||
|
|
||||||
|
四、馍·肉夹馍组
|
||||||
|
- 生面饼 右键 烤炉(表面) -> 烤炉上方放置 馍 [已实现]
|
||||||
|
- 馍+菜刀 -> 馍(切开); +熟牛肉/熟猪肉 -> 肉夹馍 [已实现]
|
||||||
|
|
||||||
|
五、煎饼卷组
|
||||||
|
- 煎饼+青菜碎 -> 煎饼(加蔬菜); +熟牛肉/土豆 -> 煎饼卷牛肉(卷制3级); +熟鳕鱼/土豆 -> 煎饼卷鳕鱼 [已实现]
|
||||||
|
|
||||||
|
六、竹筒饭组
|
||||||
|
- 竹筒+菜刀 -> 竹筒(切开); +大米x32 -> 竹筒(加入米); +肉类 -> 竹筒(加入肉) [已实现]
|
||||||
|
- 竹筒(加入肉) 放蒸笼上 -> 蒸笼(竹筒饭_生), 60秒 -> 熟; 空手取出 熟竹筒饭 + 蒸笼归位 [已实现]
|
||||||
|
|
||||||
|
七、面包·烘焙组
|
||||||
|
- 法棍/吐司/可颂/甜甜圈: 手持整份右键堆叠(2份/3份); 空手递减取走(掉落1个) [已实现]
|
||||||
|
- 甜甜圈胚(烤熟)+奶油 -> 甜甜圈(成品1个) [已实现]
|
||||||
|
|
||||||
|
八、面团·胚料组
|
||||||
|
- 发酵后/法棍面胚_1/吐司面胚/甜甜圈胚(生) 空手右键循环转换 [已实现]
|
||||||
|
- 法棍面胚_1 60秒发酵 -> 发面; 发面/吐司面胚/甜甜圈胚(生)/可颂面胚 放烤炉上 60秒烘焙 -> 成品 [已实现]
|
||||||
|
|
||||||
|
九、甜点·蛋糕组
|
||||||
|
- 面粉(加鸡蛋) 右键 木碗 -> 蛋糕面糊(生); 放烤炉 60秒 -> 烤熟; 脱模 -> 蛋糕胚 + 掉落木碗 [已实现]
|
||||||
|
- 蛋糕胚+奶油/蜂蜜/浆果 -> 奶油/蜂蜜/浆果蛋糕; 菜刀切分(整块->3/4块->半块, 每次掉落小块) [已实现]
|
||||||
|
- 半块 菜刀拆分: 半块消失 + 掉落 2个 对应小块蛋糕 (蜂蜜cake_1b->2个cake_1d, 浆果cake_2b->2个cake_2d) [已实现]
|
||||||
|
- 蛋液半成品: 放烤炉 60秒 -> 布丁半成品; +糖x16 -> 焦糖布丁; +奶油 -> 舒芙蕾半成品;
|
||||||
|
舒芙蕾半成品 放烤炉 60秒 -> 舒芙蕾 [已实现]
|
||||||
|
- 蛋液半成品 放蒸笼上 -> 蒸笼(蒸牛奶鸡蛋_生), 60秒 -> 熟 [已实现]
|
||||||
|
|
||||||
|
【烤炉机制】下方判定为烤炉才对该方块计时(烤炉只做判断); 计时中烤炉被打碎 ->
|
||||||
|
终止计时 + 烤炉上方方块变掉落物 + 提示 [已实现]
|
||||||
|
【蒸笼机制】食物方块放在蒸笼(steamer)正上方(下方判定), 1秒入笼 -> 计时60秒 -> 熟;
|
||||||
|
取出时蒸笼归位 [已实现]
|
||||||
|
|
||||||
|
【留后】吃(熟肉包子/馍/煎饼卷/熟竹筒饭/蛋糕小块 右键吃)、巧克力蛋糕系列
|
||||||
|
见 全部功能没做什么.txt 面食节
|
||||||
|
|
||||||
@@ -216,3 +216,16 @@
|
|||||||
- 煮豆腐_熟 + 手持刀(cleaver)右键 -> 获得 豆腐(beancurd) 16个, 锅恢复空汤锅
|
- 煮豆腐_熟 + 手持刀(cleaver)右键 -> 获得 豆腐(beancurd) 16个, 锅恢复空汤锅
|
||||||
- 未做原因: 属汤锅分类, 汤锅代码整体尚未开发, 本次只做分类整理与转化文档
|
- 未做原因: 属汤锅分类, 汤锅代码整体尚未开发, 本次只做分类整理与转化文档
|
||||||
|
|
||||||
|
|
||||||
|
########################################
|
||||||
|
【面食.甜食】(xy_mianshi)
|
||||||
|
########################################
|
||||||
|
(主要转换已实现于 xiangyemod/mianshi, 见 全部功能做了什么.txt)
|
||||||
|
|
||||||
|
一、吃 (熟食 右键食用)
|
||||||
|
- 熟肉包子/馍/煎饼卷(牛肉/鳕鱼成品)/熟竹筒饭/蛋糕小块 均可 空手右键吃
|
||||||
|
- 未做原因: 食用部分由统一的"总食用功能"汇总实现, 本次不实现 (转化文档已用 todo 标注)
|
||||||
|
|
||||||
|
二、巧克力蛋糕系列 (蛋糕胚 + 巧克力)
|
||||||
|
-- 未做原因: 转化文档标注"巧克力暂不实现"
|
||||||
|
|
||||||
@@ -232,12 +232,13 @@ todo 熟竹筒饭 右键吃 (吃的操作后续实现)
|
|||||||
转换条件:[右键脱模, 掉落 1个蛋糕胚 + 1个木碗]
|
转换条件:[右键脱模, 掉落 1个蛋糕胚 + 1个木碗]
|
||||||
60. 蛋糕胚 + 奶油(食材) -> 奶油蛋糕
|
60. 蛋糕胚 + 奶油(食材) -> 奶油蛋糕
|
||||||
转换条件:[手持 奶油 右键]
|
转换条件:[手持 奶油 右键]
|
||||||
61. 蛋糕胚 + 蜂蜜 -> 蜂蜜蛋糕系列; 蛋糕胚 + 浆果 -> 浆果蛋糕系列; 蛋糕胚 + 巧克力 -> 巧克力蛋糕系列
|
61. 蛋糕胚 + 蜂蜜 -> 蜂蜜蛋糕系列; 奶油蛋糕 + 浆果 -> 浆果蛋糕系列; 蛋糕胚 + 巧克力 -> 巧克力蛋糕系列
|
||||||
转换条件:[手持 蜂蜜/浆果/巧克力 右键]
|
转换条件:[手持 蜂蜜/浆果/巧克力 右键]
|
||||||
todo 巧克力暂不实现
|
todo 巧克力暂不实现
|
||||||
62. 各蛋糕整块 -> 3/4块 -> 半块
|
62. 各蛋糕整块 -> 3/4块 -> 半块
|
||||||
转换条件:[手持 菜刀 右键切分, 每次掉落 1个 对应小块蛋糕]
|
转换条件:[手持 菜刀 右键切分, 每次掉落 1个 对应小块蛋糕]
|
||||||
todo 半块 菜刀 拆分 直接 掉落两个小块蛋糕
|
半块 -> 消失, 掉落两个对应小块蛋糕
|
||||||
|
转换条件:[手持 菜刀 右键拆分, 半块消失 + 掉落 2个 小块]
|
||||||
todo 各小块 空手右键 吃 (吃的操作后续实现)
|
todo 各小块 空手右键 吃 (吃的操作后续实现)
|
||||||
63. 蛋液半成品 -> 布丁半成品
|
63. 蛋液半成品 -> 布丁半成品
|
||||||
转换条件:[下方方块是 烤炉, 计时60秒]
|
转换条件:[下方方块是 烤炉, 计时60秒]
|
||||||
|
|||||||
Reference in new issue
Block a user