文档重写 厨具功能实现

This commit is contained in:
wenhe committed 2026-09-07 15:08:32 +08:00
1 parent f55386659b
commit 262b91ba08
28 files changed
+1038 -30

No files matched your search

@@ -12,6 +12,8 @@ from xiangyemod.yuanbanfangzhi.service.YuanbanService import YuanbanService
from xiangyemod.jiaju.service.FurnitureService import FurnitureService from xiangyemod.jiaju.service.FurnitureService import FurnitureService
from xiangyemod.yinliao.service.YinliaoService import YinliaoService from xiangyemod.yinliao.service.YinliaoService import YinliaoService
from xiangyemod.yinliao.service.YinliaoTimerService import YinliaoTimerService from xiangyemod.yinliao.service.YinliaoTimerService import YinliaoTimerService
from xiangyemod.chuju.service.ChujuService import ChujuService
from xiangyemod.chuju.service.ChujuTimerService import ChujuTimerService
if not serverApi.IsInServer(): if not serverApi.IsInServer():
pass pass
@@ -0,0 +1,121 @@
# -*- coding: utf-8 -*-
"""
================================================================================
厨具(xy_kitchenware)转化规则数据
================================================================================
统一管理"厨具"(xy_kitchenware) 分类下的转化规则常量。只被
ChujuService / ChujuTimerService 读取,FeatureDispatcher 通过方块名/物品名
集合路由到对应服务。
【本次实现的五大功能】
1) 炉灶 (stove + 木条 -> 加木条 -> 打火石/烈焰弹 -> 点燃) 纯右键
2) 丸子机 (面团 -> 鱿鱼须 -> 任意配料 -> 计时半熟 -> 计时熟 -> 盘子取) 右键+计时
3) 搅拌器 (肉/牛奶/蛋 分别搅打; 牛奶+蛋互通; 蛋+木碗=奶油; +盘子=蛋液) 纯右键
4) 石磨 (黄豆 -> 研磨旋转4次 -> 玻璃罐装油罐) 右键+计数
5) 蒸笼 (盖盖/掀盖 双向) 纯右键
【留后】(到具体菜品/分类时再实现, 本模块不处理)
- 盘子 plate_0 -> 脏盘子 plate_0a
- 油罐 oilcan -> 空油锅/炒锅上油 (18/18a)
- 锅铲 <-> 带油锅铲 上油 (19/19a/20)
- 蒸笼蒸熟 (13)
- 锅铲/锅勺/菜刀/擀面杖的具体用法 (21~24)
【计时说明】
丸子机 _3(加料完成) -> 30秒 -> _4(半熟) -> 30秒 -> _5(熟) 为两段连续计时,
autoStart=True: 方块变成计时源时会自动写入开始时间戳并启动。
计时方块需配置 netease:block_entity tick:true (meatballmaker_3/4 已改)。
================================================================================
"""
# ============================================================================
# 一、炉灶 (stove 空 -> stove_1 加木条 -> stove_2 点燃)
# ============================================================================
STOVE_RULES = [
{"source": "rtdd:stove", "item": "rtdd:b_15",
"target": "rtdd:stove_1", "consume": 4, "tip": "§a炉灶加好了木条"},
{"source": "rtdd:stove_1", "item": "minecraft:flint_and_steel",
"target": "rtdd:stove_2", "tip": "§a炉灶点燃了"},
{"source": "rtdd:stove_1", "item": "minecraft:fire_charge",
"target": "rtdd:stove_2", "consume": 1, "tip": "§a炉灶点燃了"},
]
# ============================================================================
# 二、丸子机 (meatballmaker_0 空 ~ _5 熟, 章鱼小丸子)
# _0+面团 -> _1 -> +鱿鱼须 -> _2 -> +任意配料 -> _3 -> 计时 -> _4 半熟
# -> 计时 -> _5 熟 -> +盘子 -> 章鱼小丸子(plate_40), 还原空
# ============================================================================
MEATBALLMAKER_RULES = [
{"source": "rtdd:meatballmaker_0", "item": "rtdd:dough_0",
"target": "rtdd:meatballmaker_1", "consume": 1, "tip": "§a加入面团"},
{"source": "rtdd:meatballmaker_1", "item": "rtdd:rawsquidwhiskersr",
"target": "rtdd:meatballmaker_2", "consume": 4, "tip": "§a加入鱿鱼须"},
{"source": "rtdd:meatballmaker_2", "item": "*any",
"target": "rtdd:meatballmaker_3", "consume": 1, "tip": "§a加入配料,开始烹制丸子"},
{"source": "rtdd:meatballmaker_5", "item": "rtdd:plate_0",
"target": "rtdd:meatballmaker_0", "consume": 1,
"dropItem": [{"name": "rtdd:plate_40", "count": 1}],
"tip": "§a取出了章鱼小丸子"},
]
# 丸子机计时: _3(加料完成) -> 30s -> _4(半熟) -> 30s -> _5(熟)
MEATBALL_TIMERS = [
{"source": "rtdd:meatballmaker_3", "target": "rtdd:meatballmaker_4",
"time": 30, "autoStart": True, "doneTip": "§e丸子半熟了"},
{"source": "rtdd:meatballmaker_4", "target": "rtdd:meatballmaker_5",
"time": 30, "autoStart": True, "doneTip": "§e丸子熟了!"},
]
# ============================================================================
# 三、搅拌器 (beater 空)
# 肉: beater -> beatermeat_0 -> beatermeat_1 -> 空手取肉馅(记住放的是猪/牛)
# 奶: beater -> beatermike_0/1/2 (每次1个牛奶桶, 返还空桶)
# 蛋: beater -> beater_custard_0/1/2 (每次1个鸡蛋)
# 互通: 牛奶_3(beatermike_2)+蛋 -> 鸡蛋牛奶(beater_eggsandmilk_0)
# 蛋_3(beater_custard_2)+奶 -> 鸡蛋牛奶(beater_eggsandmilk_0)
# 鸡蛋牛奶: _0 -> 空手搅打 -> _1 -> 空手搅打 -> _2 -> +盘子 -> 蛋液半成品(plate_34)
# 奶油: 蛋_3(beater_custard_2)+木碗 -> 奶油(cream_0), 还原空
# ============================================================================
# 原版生肉 -> 对应肉馅方块(取出时按放入的肉决定)
MEAT_ITEMS = {
"minecraft:porkchop": "rtdd:rawmeatball_0", # 生猪排 -> 生猪肉馅
"minecraft:beef": "rtdd:rawmeatball_1", # 生牛肉 -> 生牛肉馅
}
MILK_ITEM = "minecraft:milk_bucket" # 牛奶桶
BUCKET_ITEM = "minecraft:bucket" # 空桶(牛奶桶用掉返还)
EGG_ITEM = "minecraft:egg" # 鸡蛋
BOWL_ITEM = "rtdd:bowlasoup" # 木碗(取奶油)
PLATE_ITEM = "rtdd:plate_0" # 盘子(取蛋液半成品)
CREAM_ITEM = "rtdd:cream_0" # 奶油(蛋完成态+木碗取出)
EGG_CUSTARD_ITEM = "rtdd:plate_34" # 蛋液半成品(归面食.甜食/面团·胚料)
# 搅拌器全部方块态
BEATER_BLOCKS = [
"rtdd:beater",
"rtdd:beatermeat_0", "rtdd:beatermeat_1",
"rtdd:beatermike_0", "rtdd:beatermike_1", "rtdd:beatermike_2",
"rtdd:beater_custard_0", "rtdd:beater_custard_1", "rtdd:beater_custard_2",
"rtdd:beater_eggsandmilk_0", "rtdd:beater_eggsandmilk_1", "rtdd:beater_eggsandmilk_2",
]
# ============================================================================
# 四、石磨 (stonemill 空)
# + 黄豆(16个) -> 加入黄豆 -> 空手右键研磨(每次旋转90度) -> 4次完成
# -> + 玻璃罐 -> 油罐(oilcan), 还原空
# 研磨进度存方块实体数据 rtdd_mill (0=已放豆, 1~3=旋转中, 4=完成)
# ============================================================================
SOYBEAN_ITEM = "rtdd:soybean" # 黄豆
SOYBEAN_COUNT = 16 # 磨一次要16个黄豆
STONEMILL_GRIND_COUNT = 4 # 右键4次完成研磨
GLASS_TANK_ITEM = "rtdd:medicinetank" # 玻璃罐(取出油罐)
OIL_CAN_ITEM = "rtdd:oilcan" # 油罐(石磨产物)
# ============================================================================
# 五、蒸笼 (steamer 空 <-> steamercover 加盖) 双向
# ============================================================================
STEAMER_RULES = [
{"source": "rtdd:steamer", "item": None,
"target": "rtdd:steamercover", "tip": "§a蒸笼盖上了盖子"},
{"source": "rtdd:steamercover", "item": None,
"target": "rtdd:steamer", "tip": "§a蒸笼掀开了盖子"},
]
@@ -0,0 +1 @@
# -*- coding: utf-8 -*-
@@ -0,0 +1,554 @@
# -*- coding: utf-8 -*-
"""
================================================================================
厨具·右键转换引擎(服务端)
================================================================================
处理"厨具"(xy_kitchenware) 分类下的右键转换:
炉灶(加木条/点燃)、丸子机(放面团/放鱿鱼须/放配料/盘子取成品)、
搅拌器(肉/牛奶/蛋/鸡蛋牛奶/奶油/蛋液)、石磨(加黄豆/研磨/玻璃罐取油)、
蒸笼(盖盖/掀盖)。
【与计时转换解耦】
丸子机"加料完成 -> 半熟 -> 熟"的计时拆到 ChujuTimerService,
本类右键到计时源方块连锁后由计时服务自动启动(autoStart)。
【事件监听在哪?】
本类【不】监听任何事件!
所有事件由 FeatureDispatcher 统一监听, 按 blockOwner 路由到本类 handleBlockUse。
【本类怎么做(自上而下的方法系列)】
handleBlockUse ← 入口:分发器转发右键方块事件
├─ _handleBeater ← 搅拌器(多分支, 需记录放入的肉类型)
├─ _handleStonemill ← 石磨(黄豆/研磨旋转/玻璃罐取油)
└─ handleSwitch ← 炉灶/丸子机/蒸笼 的通用开关规则
(通用工具) getCarriedItem / consumeItem / giveItem / replaceBlock /
dropItems / 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
# ---- 方块实体数据组件(搅拌器肉类型/石磨研磨进度持久化) ----
blockEntityDataComp = comp.CreateBlockEntityData(LevelId)
# ---- 游戏组件(AddTimer 延迟写入 block entity 兜底) ----
gameComp = comp.CreateGame(LevelId)
# ---- 只导入厨具自己的数据库 ----
from ..ChujuData import (
STOVE_RULES, MEATBALLMAKER_RULES,
MEAT_ITEMS, MILK_ITEM, BUCKET_ITEM, EGG_ITEM,
BOWL_ITEM, PLATE_ITEM, CREAM_ITEM, EGG_CUSTARD_ITEM, BEATER_BLOCKS,
SOYBEAN_ITEM, SOYBEAN_COUNT, STONEMILL_GRIND_COUNT,
GLASS_TANK_ITEM, OIL_CAN_ITEM, STEAMER_RULES,
)
# ---- 统一分发器 ----
from ...service.FeatureDispatcher import FeatureDispatcher
class ChujuService(BlueFoxServerSystem):
"""
厨具·右键转换引擎
"""
def __init__(self, namespace, systemName):
super(ChujuService, self).__init__(namespace, systemName)
print "===== ChujuService init ====="
# ---- 通用开关规则字典 (炉灶/丸子机/蒸笼): (方块, 物品) -> 规则 ----
self.switchRecipes = {}
for r in STOVE_RULES + MEATBALLMAKER_RULES + STEAMER_RULES:
self.switchRecipes[(r["source"], r.get("item"))] = r
# ---- 本功能管辖的所有右键方块 ----
self.featureBlocks = set()
for r in STOVE_RULES + MEATBALLMAKER_RULES + STEAMER_RULES:
self.featureBlocks.add(r["source"])
for b in BEATER_BLOCKS:
self.featureBlocks.add(b)
self.featureBlocks.add("rtdd:stonemill")
# ---- 搅拌器方块集合(专用 handler) ----
self.beaterBlockSet = set(BEATER_BLOCKS)
# ---- 右键冷却表 ----
self.cooldown = {}
# ---- 注册到统一分发器 ----
FeatureDispatcher.register(self)
# ============================================================================
# 一、给 FeatureDispatcher 的接口
# ============================================================================
def getFeatureBlocks(self):
"""返回本功能管辖的所有方块名集合(右键路由用)"""
return self.featureBlocks
def getItemUseOnRules(self):
"""手持物品右键方块表面不需要单独路由, 返回空"""
return {}
def handleBlockUse(self, args):
"""
由 FeatureDispatcher 转发的右键方块入口。
返回 True = 本功能处理了这个右键(分发器取消默认行为)
返回 False = 当前组合没有匹配规则(交还默认行为)
"""
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
# ---- 搅拌器: 专用 handler ----
if blockName in self.beaterBlockSet:
return self._handleBeater(blockName, playerId, pos, dim, itemDict, itemName, key)
# ---- 石磨: 专用 handler ----
if blockName == "rtdd:stonemill":
return self._handleStonemill(playerId, pos, dim, itemDict, itemName, key)
# ---- 炉灶/丸子机/蒸笼: 通用 switch 规则 ----
recipe = self.findRecipe(blockName, itemDict)
if not recipe:
return False
if not self.checkCooldown(key, 0.5):
return True
self.handleSwitch(recipe, playerId, pos, dim, itemDict, key)
return True
# ============================================================================
# 二、通用规则匹配(精确 + *any)
# ============================================================================
def findRecipe(self, blockName, itemDict):
"""精确匹配 (方块, 物品); 其次 *any(丸子机 _2 手持任意物品)"""
itemName = itemDict.get("newItemName") if itemDict else None
recipe = self.switchRecipes.get((blockName, itemName))
if recipe:
return recipe
if itemName and itemName != "minecraft:air":
return self.switchRecipes.get((blockName, "*any"))
return None
# ============================================================================
# 三、通用开关规则执行(炉灶/丸子机/蒸笼)
# ============================================================================
def handleSwitch(self, recipe, playerId, pos, dim, itemDict, key):
"""消耗物品 → 替换方块 → 掉落/给物品 → 提示"""
# 数量检查(如炉灶加柴需4个木条, 丸子机加鱿鱼须需4个)
consume = recipe.get("consume", 0)
if consume > 1 and itemDict is not None:
if (itemDict.get("count") or 0) < consume:
comp.CreateMsg(playerId).NotifyOneMessage(
playerId, "§c数量不足,需要 %d 个" % consume)
return
# 消耗物品
if recipe.get("item") is not None and consume > 0:
self.consumeItem(playerId, itemDict, consume)
# 替换方块
if recipe.get("target"):
self.replaceBlock(pos, dim, recipe["target"], playerId)
# 掉落物
if recipe.get("dropItem"):
self.dropItems(dim, pos, recipe["dropItem"])
# 给背包物品
if recipe.get("giveItem"):
self.giveItem(playerId, recipe["giveItem"])
# 提示
if recipe.get("tip"):
comp.CreateMsg(playerId).NotifyOneMessage(playerId, recipe["tip"])
# ============================================================================
# 四、搅拌器(肉/牛奶/蛋/鸡蛋牛奶/奶油/蛋液)
# ============================================================================
def _handleBeater(self, blockName, playerId, pos, dim, itemDict, itemName, key):
# ---------- 空搅拌器:放入第一份食材 ----------
if blockName == "rtdd:beater":
if itemName in MEAT_ITEMS:
if not self.checkCooldown(key, 0.5):
return True
self.consumeItem(playerId, itemDict, 1)
self.replaceBlock(pos, dim, "rtdd:beatermeat_0", playerId)
self._writeMeat(dim, pos, itemName)
comp.CreateMsg(playerId).NotifyOneMessage(
playerId, "§a放入肉,再放一份搅打")
return True
if itemName == MILK_ITEM:
if not self.checkCooldown(key, 0.5):
return True
self.consumeItem(playerId, itemDict, 1)
self.giveItem(playerId, BUCKET_ITEM)
self.replaceBlock(pos, dim, "rtdd:beatermike_0", playerId)
comp.CreateMsg(playerId).NotifyOneMessage(playerId, "§a放入牛奶")
return True
if itemName == EGG_ITEM:
if not self.checkCooldown(key, 0.5):
return True
self.consumeItem(playerId, itemDict, 1)
self.replaceBlock(pos, dim, "rtdd:beater_custard_0", playerId)
comp.CreateMsg(playerId).NotifyOneMessage(playerId, "§a放入鸡蛋")
return True
return False
# ---------- 肉态: 再放一份同种肉 -> 搅打完成 ----------
if blockName == "rtdd:beatermeat_0":
meat = self._readMeat(pos, dim)
if itemName in MEAT_ITEMS and itemName == meat:
if not self.checkCooldown(key, 0.5):
return True
self.consumeItem(playerId, itemDict, 1)
self.replaceBlock(pos, dim, "rtdd:beatermeat_1", playerId)
self._writeMeat(dim, pos, meat)
comp.CreateMsg(playerId).NotifyOneMessage(
playerId, "§a搅打完成,空手取出肉馅")
return True
if itemName in MEAT_ITEMS and itemName != meat:
comp.CreateMsg(playerId).NotifyOneMessage(
playerId, "§c不能混入不同种类的肉")
return True
return False
if blockName == "rtdd:beatermeat_1":
if not itemName or itemName == "minecraft:air":
if not self.checkCooldown(key, 0.5):
return True
meat = self._readMeat(pos, dim)
meatball = MEAT_ITEMS.get(meat) if meat else None
if meatball:
self.dropItems(dim, pos, [{"name": meatball, "count": 1}])
self.replaceBlock(pos, dim, "rtdd:beater", playerId)
comp.CreateMsg(playerId).NotifyOneMessage(playerId, "§a取出了肉馅")
return True
return False
# ---------- 牛奶态: 继续加牛奶 -> 牛奶_3 ----------
if blockName in ("rtdd:beatermike_0", "rtdd:beatermike_1"):
if itemName == MILK_ITEM:
if not self.checkCooldown(key, 0.5):
return True
self.consumeItem(playerId, itemDict, 1)
self.giveItem(playerId, BUCKET_ITEM)
target = "rtdd:beatermike_1" if blockName == "rtdd:beatermike_0" \
else "rtdd:beatermike_2"
self.replaceBlock(pos, dim, target, playerId)
comp.CreateMsg(playerId).NotifyOneMessage(playerId, "§a继续搅打牛奶")
return True
return False
# 牛奶完成态(牛奶_3) + 蛋 -> 鸡蛋牛奶
if blockName == "rtdd:beatermike_2":
if itemName == EGG_ITEM:
if not self.checkCooldown(key, 0.5):
return True
self.consumeItem(playerId, itemDict, 1)
self.replaceBlock(pos, dim, "rtdd:beater_eggsandmilk_0", playerId)
comp.CreateMsg(playerId).NotifyOneMessage(
playerId, "§a加入鸡蛋,空手搅打做鸡蛋牛奶")
return True
return False
# ---------- 蛋态: 继续加蛋 -> 蛋_3 ----------
if blockName in ("rtdd:beater_custard_0", "rtdd:beater_custard_1"):
if itemName == EGG_ITEM:
if not self.checkCooldown(key, 0.5):
return True
self.consumeItem(playerId, itemDict, 1)
target = "rtdd:beater_custard_1" if blockName == "rtdd:beater_custard_0" \
else "rtdd:beater_custard_2"
self.replaceBlock(pos, dim, target, playerId)
if target == "rtdd:beater_custard_2":
comp.CreateMsg(playerId).NotifyOneMessage(
playerId, "§a蛋搅打完成,可加木碗取奶油或加牛奶做鸡蛋牛奶")
else:
comp.CreateMsg(playerId).NotifyOneMessage(playerId, "§a继续搅打鸡蛋")
return True
return False
# 蛋完成态(蛋_3): +木碗取奶油 / +牛奶做鸡蛋牛奶
if blockName == "rtdd:beater_custard_2":
if itemName == BOWL_ITEM:
if not self.checkCooldown(key, 0.5):
return True
self.consumeItem(playerId, itemDict, 1)
self.dropItems(dim, pos, [{"name": CREAM_ITEM, "count": 1}])
self.replaceBlock(pos, dim, "rtdd:beater", playerId)
comp.CreateMsg(playerId).NotifyOneMessage(playerId, "§a取出了奶油")
return True
if itemName == MILK_ITEM:
if not self.checkCooldown(key, 0.5):
return True
self.consumeItem(playerId, itemDict, 1)
self.giveItem(playerId, BUCKET_ITEM)
self.replaceBlock(pos, dim, "rtdd:beater_eggsandmilk_0", playerId)
comp.CreateMsg(playerId).NotifyOneMessage(
playerId, "§a加入牛奶,空手搅打做鸡蛋牛奶")
return True
return False
# ---------- 鸡蛋牛奶态: 空手搅打推进 1/2 -> 3 ----------
if blockName in ("rtdd:beater_eggsandmilk_0", "rtdd:beater_eggsandmilk_1"):
if not itemName or itemName == "minecraft:air":
if not self.checkCooldown(key, 0.5):
return True
target = "rtdd:beater_eggsandmilk_1" \
if blockName == "rtdd:beater_eggsandmilk_0" else "rtdd:beater_eggsandmilk_2"
self.replaceBlock(pos, dim, target, playerId)
if target == "rtdd:beater_eggsandmilk_2":
comp.CreateMsg(playerId).NotifyOneMessage(
playerId, "§a鸡蛋牛奶完成,可加盘子取蛋液")
else:
comp.CreateMsg(playerId).NotifyOneMessage(playerId, "§a搅打中…")
return True
return False
# 鸡蛋牛奶完成态 + 盘子 -> 蛋液半成品
if blockName == "rtdd:beater_eggsandmilk_2":
if itemName == PLATE_ITEM:
if not self.checkCooldown(key, 0.5):
return True
self.consumeItem(playerId, itemDict, 1)
self.dropItems(dim, pos, [{"name": EGG_CUSTARD_ITEM, "count": 1}])
self.replaceBlock(pos, dim, "rtdd:beater", playerId)
comp.CreateMsg(playerId).NotifyOneMessage(playerId, "§a取出了蛋液半成品")
return True
return False
return False
# ============================================================================
# 五、石磨(加黄豆 -> 研磨旋转 -> 玻璃罐取油罐)
# ============================================================================
def _handleStonemill(self, playerId, pos, dim, itemDict, itemName, key):
prog = self._readMill(pos, dim) # None=空, 0~3=研磨中, 4=完成
# ---- 空石磨 + 黄豆(16) -> 加入黄豆 ----
if prog is None:
if itemName == SOYBEAN_ITEM:
if (itemDict.get("count") or 0) < SOYBEAN_COUNT:
comp.CreateMsg(playerId).NotifyOneMessage(
playerId, "§c需要 %d 个黄豆" % SOYBEAN_COUNT)
return True
if not self.checkCooldown(key, 0.5):
return True
self.consumeItem(playerId, itemDict, SOYBEAN_COUNT)
self._writeMill(dim, pos, 0)
comp.CreateMsg(playerId).NotifyOneMessage(
playerId, "§a加入黄豆,空手右键研磨")
return True
return False
# ---- 研磨中: 空手右键旋转一次 ----
if 0 <= prog < STONEMILL_GRIND_COUNT:
if itemName and itemName != "minecraft:air":
return False
if not self.checkCooldown(key, 0.5):
return True
newProg = prog + 1
self._rotateMill(pos, dim)
self._writeMill(dim, pos, newProg)
if newProg >= STONEMILL_GRIND_COUNT:
comp.CreateMsg(playerId).NotifyOneMessage(
playerId, "§a研磨完成,可加玻璃罐取油")
else:
comp.CreateMsg(playerId).NotifyOneMessage(
playerId, "§a研磨中…(%d/%d)" % (newProg, STONEMILL_GRIND_COUNT))
return True
# ---- 完成: + 玻璃罐 -> 油罐 ----
if prog >= STONEMILL_GRIND_COUNT:
if itemName == GLASS_TANK_ITEM:
if not self.checkCooldown(key, 0.5):
return True
self.consumeItem(playerId, itemDict, 1)
self.dropItems(dim, pos, [{"name": OIL_CAN_ITEM, "count": 1}])
self._clearMill(dim, pos)
comp.CreateMsg(playerId).NotifyOneMessage(playerId, "§a取出了油罐")
return True
return False
return False
# ============================================================================
# 六、搅拌器肉类型 读/写(字段 rtdd_meat)
# ============================================================================
def _writeMeat(self, dim, pos, itemName):
try:
data = blockEntityDataComp.GetBlockEntityData(dim, pos)
if data is None:
gameComp.AddTimer(0.1, self._writeMeatDelayed, dim, pos, itemName)
return
data["rtdd_meat"] = str(itemName)
except Exception:
gameComp.AddTimer(0.1, self._writeMeatDelayed, dim, pos, itemName)
def _writeMeatDelayed(self, dim, pos, itemName):
try:
data = blockEntityDataComp.GetBlockEntityData(dim, pos)
if data is not None:
data["rtdd_meat"] = str(itemName)
except Exception:
pass
def _readMeat(self, pos, dim):
try:
data = blockEntityDataComp.GetBlockEntityData(dim, pos)
if data is None:
return None
return data["rtdd_meat"] or None
except Exception:
return None
# ============================================================================
# 七、石磨研磨进度 读/写(字段 rtdd_mill)
# ============================================================================
def _writeMill(self, dim, pos, prog):
try:
data = blockEntityDataComp.GetBlockEntityData(dim, pos)
if data is None:
gameComp.AddTimer(0.1, self._writeMillDelayed, dim, pos, prog)
return
data["rtdd_mill"] = int(prog)
except Exception:
gameComp.AddTimer(0.1, self._writeMillDelayed, dim, pos, prog)
def _writeMillDelayed(self, dim, pos, prog):
try:
data = blockEntityDataComp.GetBlockEntityData(dim, pos)
if data is not None:
data["rtdd_mill"] = int(prog)
except Exception:
pass
def _readMill(self, pos, dim):
try:
data = blockEntityDataComp.GetBlockEntityData(dim, pos)
if data is None:
return None
return data["rtdd_mill"]
except Exception:
return None
def _clearMill(self, dim, pos):
try:
data = blockEntityDataComp.GetBlockEntityData(dim, pos)
if data is not None:
data["rtdd_mill"] = -1
except Exception:
pass
def _rotateMill(self, pos, dim):
"""石磨旋转一次(aux + 1, 四方向回归)"""
try:
old = comp.CreateBlockInfo(LevelId).GetBlockNew(pos, dim)
aux = old.get("aux", 0)
comp.CreateBlockInfo(LevelId).SetBlockNew(
pos, blockDict={"name": "rtdd:stonemill", "aux": (aux + 1) % 4},
oldBlockHandling=0, dimensionId=dim)
except Exception:
pass
# ============================================================================
# 八、工具方法:获取玩家主手物品
# ============================================================================
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 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 dropItems(self, dim, pos, dropList):
for d in dropList:
itemDict = {
"itemName": d["name"],
"count": d.get("count", 1),
"auxValue": d.get("aux", 0),
}
self.CreateEngineItemEntity(itemDict, dim, (pos[0], pos[1] + 0.5, pos[2]))
# ============================================================================
# 十三、工具方法:冷却检查
# ============================================================================
def checkCooldown(self, key, cd=0.5):
now = time.time()
last = self.cooldown.get(key, 0)
if now - last < cd:
return False
self.cooldown[key] = now
return True
@@ -0,0 +1,202 @@
# -*- coding: utf-8 -*-
"""
================================================================================
厨具·计时转换引擎(服务端)
================================================================================
只处理"厨具"(xy_kitchenware) 分类下的【计时自动转换】:
丸子机(加料完成 meatballmaker_3) -> 30秒 -> 半熟(meatballmaker_4)
半熟(meatballmaker_4) -> 30秒 -> 熟(meatballmaker_5)
【与右键转换解耦】
右键转换(放面团/放鱿鱼须/放配料/盘子取成品)在 ChujuService,本类只负责计时。
丸子机为 autoStart=True:方块变成计时源时自动写入开始时间戳并启动,
因此 _3 -> _4 -> _5 两段连续计时无需右键服务显式调用 startTimer。
【计时怎么做到"退出游戏继续计时"】
不做倒计时,只记"开始时刻":
- 启动时把 开始时间戳(rtdd_tstart)+总时长(rtdd_tdur) 写进方块实体数据
- 每帧 tick 判断 当前时间-开始时刻 >= 总时长 -> 到点转换
- 时间戳是绝对时间(time.time()), 重启/离线真实时间仍在流逝, 剩余时间自然准确
【事件监听在哪?】
本类【不】监听任何事件!
ServerBlockEntityTickEvent 由 FeatureDispatcher 统一监听,再按 timerOwner
路由到本类的 handleBlockEntityTick。
【本类怎么做】
handleBlockEntityTick ← 入口:分发器转发 tick 事件
└─ _tickProcess ← 判断是否到点 / autoStart=True 自动补写开始时刻
└─ _finishTimer ← 到点执行转换 + 完成提示
================================================================================
"""
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 ..ChujuData import MEATBALL_TIMERS
# ---- 统一分发器 ----
from ...service.FeatureDispatcher import FeatureDispatcher
class ChujuTimerService(BlueFoxServerSystem):
"""
厨具·计时转换引擎
"""
def __init__(self, namespace, systemName):
super(ChujuTimerService, self).__init__(namespace, systemName)
print "===== ChujuTimerService init ====="
# ---- 收集计时型规则(source -> 规则) ----
self.meatballTimers = {t["source"]: t for t in MEATBALL_TIMERS}
# ---- 注册到分发器的计时路由表 ----
FeatureDispatcher.registerTimer(self)
# ============================================================================
# 一、给 FeatureDispatcher 的接口
# ============================================================================
def getTimerBlocks(self):
"""返回本功能的所有"计时源方块"集合(tick 路由用)"""
return set(self.meatballTimers.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):
recipe = self.meatballTimers.get(blockName)
if not recipe:
return False
try:
data = blockEntityDataComp.GetBlockEntityData(dim, pos)
if data and data["rtdd_tid"] == blockName:
return False
except Exception:
pass
self._writeTimerData(dim, pos, recipe, playerId)
return True
# ============================================================================
# 三、tick 检查与到点转换
# ============================================================================
def _tickProcess(self, dim, pos, blockName):
try:
recipe = self.meatballTimers.get(blockName)
if not recipe:
return
blockData = blockEntityDataComp.GetBlockEntityData(dim, pos)
if blockData is None:
return
try:
tid = blockData["rtdd_tid"]
except Exception:
tid = ""
if tid != blockName:
# 丸子机为 autoStart=True: 计时源方块无计时数据时自动启动
if recipe.get("autoStart", True):
self._writeTimerData(dim, pos, recipe, None)
return
tstart = blockData["rtdd_tstart"]
tdur = blockData["rtdd_tdur"]
if time.time() - tstart >= tdur:
self._finishTimer(dim, pos, recipe, blockData)
except Exception:
pass
def _finishTimer(self, dim, pos, recipe, data):
try:
cur = comp.CreateBlockInfo(LevelId).GetBlockNew(pos, dim)
if cur and cur.get("name") != recipe["source"]:
self._clearTimerData(dim, pos)
return
self.replaceBlock(pos, dim, recipe["target"], None)
self._clearTimerData(dim, pos)
if recipe.get("doneTip"):
self._notifyIfOnline(data["rtdd_tp"], recipe["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", 30)
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 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)
@@ -0,0 +1 @@
# -*- coding: utf-8 -*-
@@ -255,7 +255,10 @@ class AnimalService(BlueFoxServerSystem):
playerId 可为 None(计时回调时没有玩家),用 LevelId 创建组件。 playerId 可为 None(计时回调时没有玩家),用 LevelId 创建组件。
""" """
creator = playerId if playerId is not None else LevelId creator = playerId if playerId is not None else LevelId
if aux is None: if newBlockName == "minecraft:air":
# 空气没有方向变体,aux 必须强制为 0,否则方向方块(如粪便)无法被正常清空
aux = 0
elif aux is None:
try: try:
oldBlock = comp.CreateBlockInfo(creator).GetBlockNew(pos, dim) oldBlock = comp.CreateBlockInfo(creator).GetBlockNew(pos, dim)
aux = oldBlock.get("aux", 0) aux = oldBlock.get("aux", 0)
@@ -4,7 +4,7 @@
"description": { "description": {
"identifier": "rtdd:carrot_pile", "identifier": "rtdd:carrot_pile",
"register_to_creative_menu": true, "register_to_creative_menu": true,
"category": "xy_ingredients" "category": "xy_jinyong"
}, },
"components": { "components": {
"netease:aabb": { "netease:aabb": {
@@ -4,7 +4,7 @@
"description": { "description": {
"identifier": "rtdd:cookedeggsoup", "identifier": "rtdd:cookedeggsoup",
"register_to_creative_menu": true, "register_to_creative_menu": true,
"category": "xy_jinyong" "category": "xy_tangguo"
}, },
"components": { "components": {
"netease:aabb": { "netease:aabb": {
@@ -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
} }
} }
} }
@@ -4,7 +4,7 @@
"description": { "description": {
"identifier": "rtdd:raweggsoup", "identifier": "rtdd:raweggsoup",
"register_to_creative_menu": true, "register_to_creative_menu": true,
"category": "xy_jinyong" "category": "xy_tangguo"
}, },
"components": { "components": {
"netease:aabb": { "netease:aabb": {
@@ -66,7 +66,6 @@
"icon": "rtdd:potato_pile", "icon": "rtdd:potato_pile",
"list": [ "list": [
"rtdd:potato_pile", "rtdd:potato_pile",
"rtdd:carrot_pile",
"rtdd:b_40", "rtdd:b_40",
"rtdd:peachpile_0", "rtdd:peachpile_0",
"rtdd:orangepile_0", "rtdd:orangepile_0",
@@ -66,7 +66,8 @@
"rtdd:nigirisushisalnom_3", "rtdd:nigirisushisalnom_3",
"rtdd:squid_sushi", "rtdd:squid_sushi",
"rtdd:squidsushi_2", "rtdd:squidsushi_2",
"rtdd:squidsushi_3" "rtdd:squidsushi_3",
"rtdd:rice_balls"
] ]
}, },
{ {
@@ -167,6 +167,14 @@
"rtdd:norieggsoup_3" "rtdd:norieggsoup_3"
] ]
}, },
{
"group_name": "itemGroup.name.tangguo_boiledeggs",
"icon": "rtdd:cookedeggsoup",
"list": [
"rtdd:raweggsoup",
"rtdd:cookedeggsoup"
]
},
{ {
"group_name": "itemGroup.name.tangguo_tofu_fish", "group_name": "itemGroup.name.tangguo_tofu_fish",
"icon": "rtdd:tufusoupb", "icon": "rtdd:tufusoupb",
@@ -289,7 +297,8 @@
"rtdd:bowlofrice_2", "rtdd:bowlofrice_2",
"rtdd:bowlofrice_3", "rtdd:bowlofrice_3",
"rtdd:plate_30", "rtdd:plate_30",
"rtdd:plate_30a" "rtdd:plate_30a",
"rtdd:boiled_egg"
] ]
} }
] ]
@@ -5,7 +5,7 @@
"minecraft:max_stack_size": 64 "minecraft:max_stack_size": 64
}, },
"description": { "description": {
"category": "xy_food", "category": "xy_tangguo",
"identifier": "rtdd:boiled_egg" "identifier": "rtdd:boiled_egg"
} }
} }
@@ -5,7 +5,7 @@
"minecraft:max_stack_size": 64 "minecraft:max_stack_size": 64
}, },
"description": { "description": {
"category": "xy_food", "category": "xy_sushi",
"identifier": "rtdd:rice_balls" "identifier": "rtdd:rice_balls"
} }
} }
@@ -22,6 +22,7 @@
"itemGroup.name.tangguo_salmon", "itemGroup.name.tangguo_salmon",
"itemGroup.name.tangguo_egg_cod", "itemGroup.name.tangguo_egg_cod",
"itemGroup.name.tangguo_egg_lean", "itemGroup.name.tangguo_egg_lean",
"itemGroup.name.tangguo_boiledeggs",
"itemGroup.name.tangguo_tofu_fish", "itemGroup.name.tangguo_tofu_fish",
"itemGroup.name.tangguo_tofu", "itemGroup.name.tangguo_tofu",
"itemGroup.name.tangguo_chicken_mushroom", "itemGroup.name.tangguo_chicken_mushroom",
+4 -3
View File
@@ -643,7 +643,7 @@ itemGroup.tabrtdd=乡野工具
tile.rtdd:eggsoup.name=汤锅_42(蛋花汤) tile.rtdd:eggsoup.name=汤锅_42(蛋花汤)
tile.rtdd:orangepile.name=土豆堆_2(橘子堆)_禁用 tile.rtdd:orangepile.name=土豆堆_2(橘子堆)_禁用
tile.rtdd:dead_squid_1.name=死鱿鱼(切掉鱿鱼须) tile.rtdd:dead_squid_1.name=死鱿鱼(切掉鱿鱼须)
tile.rtdd:cookedeggsoup.name=汤锅_32(熟蛋汤)禁用 tile.rtdd:cookedeggsoup.name=汤锅_32(煮鸡蛋_熟)
tile.rtdd:oven.name=烤炉 tile.rtdd:oven.name=烤炉
tile.rtdd:ingotpile.name=铁锭堆_禁用 tile.rtdd:ingotpile.name=铁锭堆_禁用
tile.rtdd:sales_box_pumpkin.name=售卖盒(南瓜) tile.rtdd:sales_box_pumpkin.name=售卖盒(南瓜)
@@ -776,7 +776,7 @@ tile.rtdd:orangeicecreamplace.name=橘子冰沙
tile.rtdd:cloth_purple.name=紫色布料 tile.rtdd:cloth_purple.name=紫色布料
tile.rtdd:eggcodsoup_1.name=汤锅_39(蛋花鳕鱼汤_四分熟) tile.rtdd:eggcodsoup_1.name=汤锅_39(蛋花鳕鱼汤_四分熟)
tile.rtdd:roujiamosoup_0.name=汤锅_77(羊肉泡馍汤_生) tile.rtdd:roujiamosoup_0.name=汤锅_77(羊肉泡馍汤_生)
tile.rtdd:carrot_pile.name=胡萝卜堆 tile.rtdd:carrot_pile.name=胡萝卜堆_禁用
tile.rtdd:carrotsoup.name=汤锅_25(胡萝卜汤) tile.rtdd:carrotsoup.name=汤锅_25(胡萝卜汤)
tile.rtdd:firewood_2.name=柴火_2 tile.rtdd:firewood_2.name=柴火_2
tile.rtdd:rawricepot.name=汤锅_71(生米锅) tile.rtdd:rawricepot.name=汤锅_71(生米锅)
@@ -1055,7 +1055,7 @@ tile.rtdd:creampastry_0.name=舒芙蕾半成品
tile.rtdd:carrotandporkchop_1.name=炒锅_10(清炒猪排_熟) tile.rtdd:carrotandporkchop_1.name=炒锅_10(清炒猪排_熟)
tile.rtdd:flag.name=旗子_4(旗子) tile.rtdd:flag.name=旗子_4(旗子)
tile.rtdd:lron_fork.name=铁叉_2(铁叉)禁用 tile.rtdd:lron_fork.name=铁叉_2(铁叉)禁用
tile.rtdd:raweggsoup.name=汤锅_62(生蛋汤)禁用 tile.rtdd:raweggsoup.name=汤锅_62(煮鸡蛋_生)
tile.rtdd:icelollybox_2.name=冰棍盒(冰棍定型) tile.rtdd:icelollybox_2.name=冰棍盒(冰棍定型)
tile.rtdd:kitchenwarerackd_4.name=厨具架(菜刀+锅勺) tile.rtdd:kitchenwarerackd_4.name=厨具架(菜刀+锅勺)
tile.rtdd:flag_blue_lime_oblique.name=旗子_5(蓝石灰斜纹旗) tile.rtdd:flag_blue_lime_oblique.name=旗子_5(蓝石灰斜纹旗)
@@ -1094,6 +1094,7 @@ itemGroup.name.tangguo_cod=胡萝卜鳕鱼汤
itemGroup.name.tangguo_salmon=胡萝卜鲑鱼汤 itemGroup.name.tangguo_salmon=胡萝卜鲑鱼汤
itemGroup.name.tangguo_egg_cod=蛋花鳕鱼汤 itemGroup.name.tangguo_egg_cod=蛋花鳕鱼汤
itemGroup.name.tangguo_egg_lean=瘦肉蛋花汤 itemGroup.name.tangguo_egg_lean=瘦肉蛋花汤
itemGroup.name.tangguo_boiledeggs=煮鸡蛋
itemGroup.name.tangguo_tofu_fish=豆腐鲑鱼汤 itemGroup.name.tangguo_tofu_fish=豆腐鲑鱼汤
itemGroup.name.tangguo_tofu=豆腐汤 itemGroup.name.tangguo_tofu=豆腐汤
itemGroup.name.tangguo_chicken_mushroom=小鸡炖蘑菇 itemGroup.name.tangguo_chicken_mushroom=小鸡炖蘑菇
+1 -1
View File
@@ -52,7 +52,7 @@
6. 水稻(刚种下) -> 水稻(生长中) -> 水稻(成熟) 6. 水稻(刚种下) -> 水稻(生长中) -> 水稻(成熟)
转换条件:[水稻生长计时,逐级变化] 转换条件:[水稻生长计时,逐级变化]
机制: 计时生长,约60秒升一级,共两级成熟 机制: 计时生长,约60秒升一级,共两级成熟
(成熟水稻产出 大米(brownrice), 进入 乡野食材/谷物·米面, 供生米锅/米饭/竹筒饭等) (成熟水稻产出 大米(brownrice), 进入 乡野食材/谷物·米面, 经 汤锅 煮饭盛出后供 寿司(含饭团 rice_balls)/蛋炒饭, 生米供 竹筒饭 等)
======================================== ========================================
四、方块清单 四、方块清单
+2 -2
View File
@@ -78,7 +78,7 @@
10. 土豆堆 / 胡萝卜堆(b_40) / 桃子堆 / 橙子堆 / 苹果堆 / 鸡蛋堆 / 鲑鱼堆 / 鳕鱼堆 / 面包堆 10. 土豆堆 / 胡萝卜堆(b_40) / 桃子堆 / 橙子堆 / 苹果堆 / 鸡蛋堆 / 鲑鱼堆 / 鳕鱼堆 / 面包堆
转换条件:[静态堆叠食材,无独立转换] 转换条件:[静态堆叠食材,无独立转换]
说明: 各类"XX堆"集中到本组"食材堆"(含原鱼·海鲜的鲑鱼堆/鳕鱼堆、原谷物·米面的面包堆) 说明: 各类"XX堆"集中到本组"食材堆"(含原鱼·海鲜的鲑鱼堆/鳕鱼堆、原谷物·米面的面包堆)
- 鸡蛋堆(egg_pile)仍属食材堆, 供鸡窝/蛋液等使用 - 鸡蛋堆(egg_pile)仍属食材堆, 供鸡窝/蛋液/汤锅煮鸡蛋(raweggsoup)/蛋花汤(eggsoup)/炒锅煎蛋(cookedegg)等使用
======================================== ========================================
五、蔬果·水果(单个水果, 供榨汁/冰棍/炒冰) 五、蔬果·水果(单个水果, 供榨汁/冰棍/炒冰)
@@ -91,7 +91,7 @@
======================================== ========================================
12. 大米(brownrice) 12. 大米(brownrice)
转换条件:[静态食材,无独立转换](本次由Java版迁入,用于生米锅/米饭/竹筒饭/蛋炒饭; 转换条件:[静态食材,无独立转换](本次由Java版迁入,用于生米锅/米饭/竹筒饭/蛋炒饭;
米饭需先经 汤锅 煮熟盛出, 再做寿司/蛋炒饭等) 米饭需先经 汤锅 煮熟盛出, 再做寿司(含饭团 rice_balls)/蛋炒饭等)
13. 稻谷(riceseeds) 13. 稻谷(riceseeds)
转换条件:[静态食材,无独立转换](本次由Java版迁入, 水稻种子, 用于种植水稻/产出大米) 转换条件:[静态食材,无独立转换](本次由Java版迁入, 水稻种子, 用于种植水稻/产出大米)
+37
View File
@@ -353,3 +353,40 @@ FurnitureData+FurnitureService 实现, 注册到 FeatureDispatcher)
- 乡野食材: 8分组(含食材堆/蔬果·水果) + 新食材 + 切配半成品 - 乡野食材: 8分组(含食材堆/蔬果·水果) + 新食材 + 切配半成品
- 乡野自然: apple_leaves/tangerine/grapebushes/firewood/riceseedlings + 稻谷种植 [已重写] - 乡野自然: apple_leaves/tangerine/grapebushes/firewood/riceseedlings + 稻谷种植 [已重写]
########################################
【厨具】(xy_kitchenware) 2026-09-07
########################################
实现于 xiangyemod/chuju (ChujuData + ChujuService + ChujuTimerService, 注册到 FeatureDispatcher)
一、炉灶 (stove -> stove_1 -> stove_2)
- 加柴: 手持木条(b_15)右键空炉灶 → 加木条(stove_1), 消耗4个木条 [已实现]
- 点燃: 手持打火石(不消耗)/烈焰弹(消耗1)右键加木条 → 点燃(stove_2) [已实现]
二、丸子机 (meatballmaker_0~5, 章鱼小丸子)
- 放面团: 手持面团(dough_0)右键空丸子机 → 加入面团(meatballmaker_1), 消耗1个 [已实现]
- 放鱿鱼须: 手持鱿鱼须(rawsquidwhiskersr)右键 → 加入鱿鱼(meatballmaker_2), 消耗4个 [已实现]
- 放配料: 手持任意物品右键 → 加入配料(meatballmaker_3), 消耗1个 [已实现]
- 计时熟化: 加料完成(_3) 计时30秒 → 半熟(_4) 计时30秒 → 熟(_5)
(autoStart 自动启动, 绝对时间戳写方块实体数据, 退出重进继续计时) [已实现]
- 取成品: 手持盘子(plate_0)右键熟 → 掉落 章鱼小丸子_完整(plate_40) + 还原空 [已实现]
三、搅拌器 (beater 系列)
- 搅肉: 空+肉(生猪排/生牛肉) → 肉_1 → 肉_2(共消耗2个肉); 空手取出 生猪肉馅(rawmeatball_0)/
生牛肉馅(rawmeatball_1), 按放入肉的种类决定 [已实现]
- 搅奶: 空+牛奶桶 → 牛奶_1/2/3(每次消耗1牛奶桶, 返还空桶) [已实现]
- 搅蛋: 空+鸡蛋 → 蛋_1/2/3(共消耗3个鸡蛋) [已实现]
- 取奶油: 蛋完成态(beater_custard_2) + 木碗(消耗1) → 掉落 奶油(cream_0) + 还原空 [已实现]
- 鸡蛋牛奶: 牛奶_3+蛋 或 蛋_3+牛奶桶(返空桶) → 鸡蛋牛奶_1; 空手搅打 → 鸡蛋牛奶_3 [已实现]
- 取蛋液: 鸡蛋牛奶_3 + 盘子(消耗1) → 掉落 蛋液半成品(plate_34) + 还原空 [已实现]
四、石磨 (stonemill)
- 加黄豆: 手持黄豆(soybean)右键石磨 → 加入黄豆, 消耗16个 [已实现]
- 研磨: 空手右键旋转(每次90度), 4次回归完成; 进度存方块实体数据 rtdd_mill(退出重进不丢) [已实现]
- 取油罐: 研磨完成 + 玻璃罐(medicinetank, 消耗1) → 掉落 油罐(oilcan) + 石磨回空 [已实现]
五、蒸笼 (steamer <-> steamercover)
- 盖盖/掀盖: 空手右键双向切换 [已实现]
【留后】见 全部功能没做什么.txt 厨具节 (盘子→脏盘子、油罐⇄油锅/锅铲上油、蒸笼蒸熟、锅铲/锅勺/菜刀/擀面杖具体用法)
+22
View File
@@ -142,3 +142,25 @@
- 设想: 手持绷带右键回血 - 设想: 手持绷带右键回血
- 未做原因: 后续实现 (药物系统转化关系.txt 三、其他静态方块 todo 已标注) - 未做原因: 后续实现 (药物系统转化关系.txt 三、其他静态方块 todo 已标注)
########################################
【厨具】(xy_kitchenware)
########################################
一、盘子-变脏 (plate_0 -> plate_0a)
- 设想: 盘子装盛食物食用后变脏盘子
- 未做原因: 属于食物食用链路, 留到具体菜品/总食用功能实现 (厨具转化关系.txt 五、盘子)
二、油罐⇄油锅/锅铲上油 (oilcan -> 空油锅/炒锅)
- 涉及: 油罐取油耗尽变回玻璃罐(18)、油罐直接上油空炒锅→满油油锅(18a)、
锅铲<->带油锅铲(19/19a)、带油锅铲上油炒锅(20)
- 未做原因: 依赖油锅/炒锅(具体菜品)分类, 留到炒锅/油锅功能实现时做 (厨具转化关系.txt 六、七)
三、蒸笼-蒸熟 (steamercover + 生食 -> 熟)
- 涉及: 蒸饺子/蒸包子/蒸竹筒饭/蒸牛奶鸡蛋
- 未做原因: 蒸熟的具体食材都在面食.甜食分类, 留到面食.甜食实现时做 (厨具转化关系.txt 四)
四、手持厨具具体用法 (锅铲/锅勺/菜刀/擀面杖)
- 涉及: 锅铲翻炒炒锅(21)、锅勺翻煮汤锅(22)、菜刀切割食材半成品(23)、擀面杖擀面团(24)
- 未做原因: 均作用于具体分类(炒锅/汤锅/寿司/面食等), 留到各分类实现时做 (厨具转化关系.txt 七)
+20 -6
View File
@@ -29,10 +29,15 @@
转换条件:[手持 面团(面食.甜食) 右键 进行转换,消耗1个] 转换条件:[手持 面团(面食.甜食) 右键 进行转换,消耗1个]
机制: 手持面团右键, 消耗1个, 加入面团 机制: 手持面团右键, 消耗1个, 加入面团
4. 加入面团 -> 加入鱿鱼须 4. 加入面团 -> 加入鱿鱼
转换条件:[手持 鱿鱼须(乡野食材) 右键 进行转换] 转换条件:[手持 鱿鱼须(乡野食材) 右键 进行转换]
机制: 手持鱿鱼须右键, 消耗4个 机制: 手持鱿鱼须右键, 消耗4个
4b. 丸子机(加入鱿鱼) -> 丸子机(加入配料)
转换条件:[手持 任意物品 右键 进行转换, 消耗1个]
机制: 手持任意物品右键, 消耗1个, 加入配料(准备烹制, 计时自动开始)
5. 加入食材 -> 丸子机(半熟) -> 丸子机(熟) 5. 加入食材 -> 丸子机(半熟) -> 丸子机(熟)
转换条件:[计时自动转换] 转换条件:[计时自动转换]
机制: 计时约30秒升一级, 共两级变熟 机制: 计时约30秒升一级, 共两级变熟
@@ -56,15 +61,17 @@
转换条件:[手持 牛奶 右键 依次放入/搅打] 转换条件:[手持 牛奶 右键 依次放入/搅打]
机制: 手持牛奶右键, 消耗1个, 逐级搅打 机制: 手持牛奶右键, 消耗1个, 逐级搅打
9. beater(空) + 蛋 -> 蛋_1 -> 蛋_2 -> 蛋_3(beater_eggsandmilk 前段) 9. beater(空) + 蛋 -> 蛋_1 -> 蛋_2 -> 蛋_3(beater_custard_0~2)
转换条件:[手持 鸡蛋 右键 依次放入/搅打] 转换条件:[手持 鸡蛋 右键 依次放入/搅打]
机制: 手持鸡蛋右键, 消耗1个, 逐级搅打 机制: 手持鸡蛋右键, 消耗3个, 逐级搅打, 蛋_3为蛋完成态
9a. 蛋完成态(beater_custard_2) + 木碗 -> 奶油(cream_0)
转换条件:[手持 木碗(bowlasoup) 右键 进行转换, 不加入牛奶]
机制: 蛋完成态不加入牛奶, 手持木碗右键取出, 获得 奶油(cream_0, 乡野食材/调味·佐料)一份
10. 牛奶/蛋 互通到"鸡蛋牛奶"流程 (beater_eggsandmilk_0~2) 10. 牛奶/蛋 互通到"鸡蛋牛奶"流程 (beater_eggsandmilk_0~2)
转换条件:[牛奶_2 再放 蛋 / 蛋_3 再放 牛奶] 转换条件:[牛奶_3 再放 蛋 / 蛋_3 再放 牛奶]
机制: 不论先搅打牛奶还是先搅打蛋, 最后都要走进"鸡蛋牛奶"流程; 机制: 不论先搅打牛奶还是先搅打蛋, 最后都要走进"鸡蛋牛奶"流程;
提示按先加入的来提示另一个: 先牛奶就提示"加入蛋", 先蛋就提示"加入牛奶" 提示按先加入的来提示另一个: 先牛奶就提示"加入蛋", 先蛋就提示"加入牛奶"
若当前为蛋完成态(蛋_3), 提示语额外追加"用木碗可获得奶油一份"
11. beater_eggsandmilk_2(鸡蛋牛奶完成) -> 蛋液半成品(plate_34) 11. beater_eggsandmilk_2(鸡蛋牛奶完成) -> 蛋液半成品(plate_34)
转换条件:[手持 盘子(plate_0) 右键 进行转换] 转换条件:[手持 盘子(plate_0) 右键 进行转换]
机制: 手持盘子右键, 消耗1个盘子, 取出 蛋液半成品(plate_34, 归面食.甜食/面团·胚料组) 机制: 手持盘子右键, 消耗1个盘子, 取出 蛋液半成品(plate_34, 归面食.甜食/面团·胚料组)
@@ -107,10 +114,17 @@
18. oilcan(油罐) 取油耗尽 -> medicinetank(玻璃罐) 18. oilcan(油罐) 取油耗尽 -> medicinetank(玻璃罐)
转换条件:[油罐 取油使用次数扣到0] 转换条件:[油罐 取油使用次数扣到0]
机制: 油罐的油被取光(被锅铲取油16次)后, 变回 玻璃罐(medicinetank) 机制: 油罐的油被取光(被锅铲取油16次)后, 变回 玻璃罐(medicinetank)
18a. oilcan(油罐) 直接上油空炒锅 -> 满油油锅 + 空玻璃罐
转换条件:[手持 油罐(oilcan) 右键 空炒锅(rtdd:wok)]
机制: 手持油罐右键空炒锅, 消耗1个油罐, 获得1个空玻璃罐(medicinetank),
空炒锅(wok) 变为 满油油锅(oilpan, 添油锅)
(油罐直接上油 与 带油锅铲上油(第20条) 二者择一)
======================================== ========================================
七、手持厨具物品 七、手持厨具物品
======================================== ========================================
说明: 本节的物品形态变化(锅铲<->带油锅铲、油罐取油等)直接替换玩家手上的物品,
不要像方块交互那样以掉落物形式产出
19. spatula(锅铲) -> spatula_oil(带油锅铲) 19. spatula(锅铲) -> spatula_oil(带油锅铲)
转换条件:[手持 锅铲 右键 油罐(oilcan)] 转换条件:[手持 锅铲 右键 油罐(oilcan)]
机制: 锅铲右键油罐, 变为带油锅铲(附魔光效), 油罐使用次数-1 机制: 锅铲右键油罐, 变为带油锅铲(附魔光效), 油罐使用次数-1
+16 -5
View File
@@ -2,23 +2,24 @@
【寿司】(xy_sushi) 转化关系 【寿司】(xy_sushi) 转化关系
======================================== ========================================
说明(基于行为包实际方块清单重写): 说明(基于行为包实际方块清单重写):
- 寿司方块: sushi_0(干海带)、sushi_1(干海带加米饭) - 寿司方块: sushi_0(干海带/海苔)、sushi_1(干海带加米饭)
鳕鱼寿司(codsushi_1~6/codsushicubes_1/2)、鲑鱼寿司(salmonsushi_1~6/salmonsushicubes_1/2)、 鳕鱼寿司(codsushi_1~6/codsushicubes_1/2)、鲑鱼寿司(salmonsushi_1~6/salmonsushicubes_1/2)、
热带鱼寿司(fishsushi_1~5/fishsushicubes_1/2/fishmonsushi_6)、 热带鱼寿司(fishsushi_1~5/fishsushicubes_1/2/fishmonsushi_6)、
手握(nigirisushi 系列)、寿司堆(sushipile_0~5)、盘装(plate_27/28/29/42) 手握(nigirisushi 系列)、寿司堆(sushipile_0~5)、盘装(plate_27/28/29/42)
- 【米饭来源·逻辑严谨】寿司用"米饭"是熟米饭: 大米(brownrice, 食材) 经 汤锅 煮成生米锅, - 【米饭来源·逻辑严谨】寿司用"米饭"是熟米饭: 大米(brownrice, 食材) 经 汤锅 煮成生米锅,
计时煮熟, 木碗盛出为碗装米饭(bowlofrice), 才可用于做寿司。见 汤锅转化关系.txt 37~39 计时煮熟, 木碗盛出为碗装米饭(bowlofrice), 才可用于做寿司。见 汤锅转化关系.txt 37~39
竹筒饭用生大米(见 面食.甜食 竹筒饭组), 二者不要混淆 竹筒饭用生大米(见 面食.甜食 竹筒饭组), 二者不要混淆
- 制作规律: 干海带 -> 加米饭 -> 加鱼 -> 卷制 -> 切块 -> 堆叠/手握 - 制作规律: 海苔 -> 加米饭 -> 加鱼 -> 卷制 -> 切块 -> 堆叠/手握; 饭团由手握裹海苔而成
- 竹帘/菜刀: 卷制用 竹帘, 切块用 菜刀(cleaver, 厨具) - 竹帘/菜刀: 卷制用 竹帘, 切块用 菜刀(cleaver, 厨具)
- 已归入禁用: 切寿司(cutsushi) - 已归入禁用: 切寿司(cutsushi)
- 【饭团·新增】饭团(rice_balls) 由手握普通寿司裹海苔而成, 归 手握寿司组(sushi_05_nigiri)
======================================== ========================================
一、寿司·基础组 一、寿司·基础组
======================================== ========================================
1. sushi_0(干海带) -> sushi_1(干海带加米饭) 1. sushi_0(干海带/海苔) -> sushi_1(干海带加米饭)
转换条件:[手持 米饭(汤锅盛出的碗装米饭 bowlofrice) 右键, 消耗1个] 转换条件:[手持 米饭(汤锅盛出的碗装米饭 bowlofrice) 右键, 消耗1个]
机制: 铺上米饭(米饭来源见 汤锅转化关系.txt) 机制: 海苔上铺米饭(米饭来源见 汤锅转化关系.txt)
======================================== ========================================
二、鳕鱼寿司组 二、鳕鱼寿司组
@@ -49,7 +50,8 @@
======================================== ========================================
五、手握寿司组 五、手握寿司组
======================================== ========================================
(手握: sushi_1(加米饭) + 鱼 -> 手握一个 -> 两个 -> 三个) (手握: sushi_1(加米饭) + 鱼 -> 手握一个 -> 两个 -> 三个;
饭团(rice_balls) 亦归本组)
14. sushi_1 + 鳕鱼 -> nigirisushicod_2(一个) -> nigirisushicod_3(两个) 14. sushi_1 + 鳕鱼 -> nigirisushicod_2(一个) -> nigirisushicod_3(两个)
(nigirisushifishcod 为鳕鱼手握) (nigirisushifishcod 为鳕鱼手握)
15. sushi_1 + 鲑鱼 -> nigirisushisalnom_2(一个) -> nigirisushisalnom_3(两个) 15. sushi_1 + 鲑鱼 -> nigirisushisalnom_2(一个) -> nigirisushisalnom_3(两个)
@@ -73,3 +75,12 @@
- plate_29: 盘装寿司(手握鲑鱼三份+鲑鱼寿司) - plate_29: 盘装寿司(手握鲑鱼三份+鲑鱼寿司)
- plate_42: 盘装寿司(手握鱿鱼三份+热带鱼寿司) - plate_42: 盘装寿司(手握鱿鱼三份+热带鱼寿司)
机制: 成品摆盘方块, 由对应手握/卷寿司组合摆放而成, 无独立转换 机制: 成品摆盘方块, 由对应手握/卷寿司组合摆放而成, 无独立转换
========================================
八、饭团(新增)
========================================
物品: rice_balls(饭团)
21. 手握普通寿司(nigirisushi) + 海苔(sushi_0 干海带) -> rice_balls(饭团)
转换条件:[手持 海苔(干海带 sushi_0) 右键, 消耗1个]
机制: 米饭手握(手握普通寿司)裹上海苔, 捏成三角饭团, 掉落/获得饭团物品
(米饭来源见 汤锅转化关系.txt 米饭流程; 饭团归 手握寿司组 sushi_05_nigiri)
+26 -2
View File
@@ -9,6 +9,10 @@
- 出锅: 手持 木碗(bowlasoup, 厨具) 右键, 消耗1个, 获得碗装成品(bowla*) - 出锅: 手持 木碗(bowlasoup, 厨具) 右键, 消耗1个, 获得碗装成品(bowla*)
- 米饭流程: 大米(brownrice, 乡野食材) -> rawricepot(生米锅) -> ricepot_1~3(熟米饭) - 米饭流程: 大米(brownrice, 乡野食材) -> rawricepot(生米锅) -> ricepot_1~3(熟米饭)
-> 木碗盛出 bowlofrice(碗装米饭), 再用于 寿司(见 寿司转化关系.txt)/蛋炒饭(炒锅) -> 木碗盛出 bowlofrice(碗装米饭), 再用于 寿司(见 寿司转化关系.txt)/蛋炒饭(炒锅)
- 【鸡蛋·多用途联动】同一"鸡蛋"原料("鸡蛋堆 egg_pile"拆出或原版鸡蛋)贯穿三处:
-> 汤锅: 蛋花汤(eggsoup) / 煮鸡蛋(raweggsoup -> cookedeggsoup -> 水煮蛋)
-> 炒锅: 煎蛋(cookedegg, 炒锅转化关系.txt 第19条)
-> 厨具: 搅拌器蛋液(beater_eggsandmilk_*, 厨具转化关系.txt 三)
- 依赖: 灶台底座(炉灶点燃态); 食材来自 乡野食材分类 - 依赖: 灶台底座(炉灶点燃态); 食材来自 乡野食材分类
======================================== ========================================
@@ -77,8 +81,28 @@
寿司 干海带+米饭(寿司转化关系.txt) / 炒锅 蛋炒饭(炒锅转化关系.txt)) 寿司 干海带+米饭(寿司转化关系.txt) / 炒锅 蛋炒饭(炒锅转化关系.txt))
======================================== ========================================
五、出锅(熟汤羹 + 木碗 -> 碗装成品) 五、煮鸡蛋组(新增独立分组 itemGroup.name.tangguo_boiledeggs)
========================================
方块: raweggsoup(煮鸡蛋_生)、cookedeggsoup(煮鸡蛋_熟)
成品: boiled_egg(水煮蛋, 归 tangguo_finished 成品组)
- 本组由 禁用(xy_jinyong) 移回汤锅, 单独成组
40. stewedsoupwater(汤锅加水) + 鸡蛋 -> raweggsoup(煮鸡蛋_生)
转换条件:[手持 鸡蛋 右键, 消耗1个]
机制: 鸡蛋入锅, 变为生煮鸡蛋
41. raweggsoup(煮鸡蛋_生) -> cookedeggsoup(煮鸡蛋_熟)
转换条件:[计时约60秒变熟]
机制: 生煮鸡蛋计时煮熟
42. cookedeggsoup(煮鸡蛋_熟) + 木碗(bowlasoup) -> boiled_egg(水煮蛋)
转换条件:[手持 木碗 右键, 消耗1个木碗, 获得水煮蛋]
机制: 从锅中捞出煮熟的鸡蛋, 水煮蛋归成品菜组(与其它汤羹木碗出锅机制一致)
========================================
六、出锅(熟汤羹 + 木碗 -> 碗装成品)
======================================== ========================================
机制: 手持 木碗(bowlasoup, 厨具) 右键熟汤羹, 消耗1个木碗, 获得对应碗装成品 机制: 手持 木碗(bowlasoup, 厨具) 右键熟汤羹, 消耗1个木碗, 获得对应碗装成品
(各汤羹熟态出锅 -> bowla* 系列, 成品归 tangguo_finished 成品组) (各汤羹熟态出锅 -> bowla* 系列, 成品归 tangguo_finished 成品组;
水煮蛋(boiled_egg) 亦归 tangguo_finished 成品组)
- 豆腐汤熟态/鱿鱼汤熟态 方块当前为禁用分类 - 豆腐汤熟态/鱿鱼汤熟态 方块当前为禁用分类
+4
View File
@@ -8,6 +8,8 @@
- 出锅: 手持 盘子(plate_0) 右键, 消耗1个盘子, 获得成品菜(plate_* 归成品组) - 出锅: 手持 盘子(plate_0) 右键, 消耗1个盘子, 获得成品菜(plate_* 归成品组)
- 依赖: 灶台底座(炉灶点燃态 stove_2, 见 厨具转化关系.txt); 食材来自 乡野食材分类 - 依赖: 灶台底座(炉灶点燃态 stove_2, 见 厨具转化关系.txt); 食材来自 乡野食材分类
- 米饭: 蛋炒饭用 汤锅煮米木碗盛出的熟米饭(见 汤锅转化关系.txt) - 米饭: 蛋炒饭用 汤锅煮米木碗盛出的熟米饭(见 汤锅转化关系.txt)
- 鸡蛋联动: 生鸡蛋 -> 煎蛋(cookedegg) 用于蛋炒饭; 生鸡蛋另可 汤锅 煮鸡蛋(raweggsoup)/蛋花汤(eggsoup)
(鸡蛋来自 鸡蛋堆 egg_pile, 乡野食材; 炒锅煎蛋 与 汤锅煮鸡蛋 互不干扰, 同源不同处理)
======================================== ========================================
一、基础工具 一、基础工具
@@ -52,6 +54,7 @@
17. oilpan + 鲑鱼 -> cookingfish(煎鲑鱼_生) -> 熟 17. oilpan + 鲑鱼 -> cookingfish(煎鲑鱼_生) -> 熟
18. oilpan + 鱿鱼 -> cookingsquid(炒鱿鱼_生) -> 半熟 -> 熟 18. oilpan + 鱿鱼 -> cookingsquid(炒鱿鱼_生) -> 半熟 -> 熟
19. oilpan + 鸡蛋 -> cookedegg(煎蛋) 19. oilpan + 鸡蛋 -> cookedegg(煎蛋)
(鸡蛋同源: 还用于 汤锅 煮鸡蛋/蛋花汤, 见 汤锅转化关系.txt; 煎蛋为蛋炒饭前置)
======================================== ========================================
四、各菜谱(胡萝卜锅底/辣椒锅底 + 肉/鱼 -> 菜) 四、各菜谱(胡萝卜锅底/辣椒锅底 + 肉/鱼 -> 菜)
@@ -96,6 +99,7 @@
======================================== ========================================
48. cookedegg(煎蛋) + 米饭(汤锅盛出) -> riceegg_1(蛋炒饭_生) -> 翻炒3次 riceegg_2(熟) 48. cookedegg(煎蛋) + 米饭(汤锅盛出) -> riceegg_1(蛋炒饭_生) -> 翻炒3次 riceegg_2(熟)
+ 米饭 -> riceegg_3(蛋炒饭_加米饭_熟) + 米饭 -> riceegg_3(蛋炒饭_加米饭_熟)
(煎蛋来自第19条; 米饭来自 汤锅 大米煮饭盛出, 见 汤锅转化关系.txt 四)
49. riceegg_3 -> 蛋炒饭成品(bowlofriceegg) 49. riceegg_3 -> 蛋炒饭成品(bowlofriceegg)
======================================== ========================================
+1
View File
@@ -7,6 +7,7 @@
- 【擀面杖】: 擀面用 擀面杖(rollingpin_1/2/3, 本分类) 配合 厨具的 rollingpin, - 【擀面杖】: 擀面用 擀面杖(rollingpin_1/2/3, 本分类) 配合 厨具的 rollingpin,
加工中擀面杖会被消耗, 干完最后一步掉落返还(见 厨具转化关系.txt 七) 加工中擀面杖会被消耗, 干完最后一步掉落返还(见 厨具转化关系.txt 七)
- 【蛋液半成品】plate_34: 由 搅拌器(厨具) 鸡蛋牛奶流程 用盘子取出(见 厨具转化关系.txt 三) - 【蛋液半成品】plate_34: 由 搅拌器(厨具) 鸡蛋牛奶流程 用盘子取出(见 厨具转化关系.txt 三)
(鸡蛋同源: 另用于 汤锅 煮鸡蛋/蛋花汤、炒锅 煎蛋, 见 汤锅/炒锅转化关系.txt)
- 【米饭/大米区分】: 竹筒饭/生米锅用 生大米(brownrice); 蛋炒饭/寿司用 熟米饭(汤锅盛出) - 【米饭/大米区分】: 竹筒饭/生米锅用 生大米(brownrice); 蛋炒饭/寿司用 熟米饭(汤锅盛出)
- 【面团用途】: 面团(rawdough/dought 系列) 供 丸子机(厨具)/炒锅煎饼(炒锅) 使用 - 【面团用途】: 面团(rawdough/dought 系列) 供 丸子机(厨具)/炒锅煎饼(炒锅) 使用
- 【生面】noodles: 供 汤锅生面汤/炒锅意面(见 汤锅/炒锅转化关系.txt) - 【生面】noodles: 供 汤锅生面汤/炒锅意面(见 汤锅/炒锅转化关系.txt)