配方系统
EmakiCooking 的配方按工位分类存放在 plugins/EmakiCooking/recipes/<station>/。每类工位的交互不同,所以字段也不同:砧板按输入数量与切割次数,炒锅按翻炒与火候,烤炉按烘烤阶段,榨汁机按流体容量,发酵桶按时间阶段。
配方目录
| 目录 | 工位 | 典型玩法 |
|---|---|---|
recipes/chopping_board/ | 砧板 | 单输入,一次性接收主手整叠,按输入数量与切割次数产出切片或半成品。 |
recipes/wok/ | 炒锅 | 多输入,按火候、翻炒次数和容错决定结果。 |
recipes/grinder/ | 研磨机 | 输入材料,等待研磨时间后产出粉末。 |
recipes/steamer/ | 蒸锅 | 输入材料,按蒸制时间或链式步骤产出熟制品。 |
recipes/oven/ | 烤炉 | 单输入,按烘烤时间、完美火力比例和过烤阶段决定结果。 |
recipes/juicer/ | 榨汁机 | 单输入,多次压榨生成流体,再按容器容量盛取。 |
recipes/fermentation_barrel/ | 发酵桶 | 多输入,按发酵时间、提前收取和过度发酵决定结果。 |
当前推荐写法
当前默认资源统一使用 CoreLib Item Source 列表和结果分支结构:
result:
success:
outputs:
- item_sources:
- "minecraft-baked_potato"
amount: 1
actions:
- 'sendmessage text="<gold>料理完成。</gold>"'关键约定:
- 输入和输出优先写
item_sources列表,例如minecraft-carrot、minecraft-glass_bottle。 result.<branch>.outputs永远是列表,只有一个产物也写列表。result.<branch>.actions与outputs同级,位于同一个结果分支下。- 不再使用旧示例里的
output、result.output、result.outputs、result.actions、perfect_output、overbaked_output、fermentation.early_collect.output、fermentation.over_output。
通用字段
| 字段 | 必填 | 说明 |
|---|---|---|
id | 是 | 配方唯一 ID,建议与文件名一致。 |
display_name | 是 | 展示名称。支持 MiniMessage。 |
permission | 否 | 使用该配方所需权限;为空表示不限制。 |
condition | 否 | 完成或收取时评估的条件块,可配置 on_pass.actions、on_fail.actions 和 on_fail.block_output。 |
result.<branch>.outputs | 是 | 当前分支产物列表。 |
result.<branch>.actions | 否 | 当前分支产出时执行的动作列表。 |
结果分支
| 工位 | 常用结果分支 |
|---|---|
| 砧板 | success |
| 研磨机 | success |
| 蒸锅 | success,链式配方可按步骤继续处理。 |
| 炒锅 | success、undercooked、overcooked、invalid |
| 烤炉 | success、perfect、overbaked |
| 榨汁机 | success |
| 发酵桶 | success、early、over |
condition.on_fail.block_output 为 true 时,条件不满足会阻止产物输出;为 false 时仍可输出,但会执行失败动作。发酵桶在自动完成或破坏掉落等玩家可能离线的场景下,条件处理以源码运行时逻辑为准。
砧板示例
id: "cut_carrot"
display_name: "切制胡萝卜"
input:
item_sources:
- "minecraft-carrot"
amount: 2
cuts_required: 1
tool_damage: 1
result:
success:
outputs:
- item_sources:
- "minecraft-golden_carrot"
amount: 1
actions:
- 'sendmessage text="<green>砧板处理完成。</green>"'| 字段 | 说明 |
|---|---|
input.item_sources | 可匹配的输入来源。 |
input.amount | 每次完成切割需要并消耗的输入数量;未配置时按 1 处理。 |
cuts_required | 完成一轮切割所需点击次数。 |
tool_damage | 每次切割对工具造成的耐久损耗。 |
damage_override.chance | 覆盖 config.yml > stations.chopping_board.cut_damage.chance,即本配方切割时扣耐久的概率。 |
damage_override.value | 覆盖 config.yml > stations.chopping_board.cut_damage.value,即本配方每次扣除的耐久值。 |
damage_override 是可选段;未写时使用 config.yml 中的全局 cut_damage 设置。
砧板放入输入时会一次性接收玩家主手整叠,并在工位状态中累计数量;展示实体仍只显示 1 个物品。累计数量不足 input.amount 时不能开始切割。若设置 cuts_required: 1,玩家可以对已放入的一批食材连续完成多轮切割,无需每次重新放入 1 个输入。
炒锅示例
id: "example_recipe"
display_name: "简易炖菜"
ingredients:
- item_sources:
- "minecraft-carrot"
amount: 1
stir_rule: "1-3"
- item_sources:
- "minecraft-cooked_chicken"
amount: 1
stir_rule: "2-3"
heat_level: 1
stir_total:
min: 2
max: 5
fault_tolerance: 0
permission: "emakicooking.recipe.simple_stew"
condition:
type: all_of
entries:
- "%player_level% >= 5"
on_pass:
actions:
- 'sendmessage text="<green>厨艺达标,出锅成功。</green>"'
on_fail:
actions:
- 'sendmessage text="<red>厨艺等级不足,出锅失败。</red>"'
block_output: true
result:
success:
outputs:
- item_sources:
- "minecraft-rabbit_stew"
amount: 1
actions:
- 'sendmessage text="<green>成功出锅。</green>"'
undercooked:
outputs:
- item_sources:
- "minecraft-mushroom_stew"
amount: 1
actions: []
overcooked:
outputs:
- item_sources:
- "minecraft-dried_kelp"
amount: 1
actions: []
invalid:
outputs:
- item_sources:
- "minecraft-stone"
amount: 1
actions: []| 字段 | 说明 |
|---|---|
ingredients[].item_sources | 可匹配的食材来源。 |
ingredients[].amount | 需要数量。 |
ingredients[].stir_rule | 建议加入或翻炒区间,例如 1-3。 |
heat_level | 配方要求的火力等级。 |
stir_total.min/max | 有效总翻炒次数范围。 |
fault_tolerance | 允许错误次数。 |
研磨机示例
id: "bone_meal"
display_name: "骨粉研磨"
input:
item_sources:
- "minecraft-bone"
grind_time_seconds: 6
permission: "emakicooking.recipe.bone_meal"
result:
success:
outputs:
- item_sources:
- "minecraft-bone_meal"
amount: 3
actions:
- 'sendmessage text="<gray>研磨结束。</gray>"'| 字段 | 说明 |
|---|---|
input.item_sources | 可匹配的输入来源。 |
grind_time_seconds | 研磨所需秒数。研磨机按 config.yml > stations.grinder.check_delay_ticks 周期推进。 |
蒸锅示例
id: "steamed_cod"
display_name: "清蒸鳕鱼"
input:
item_sources:
- "minecraft-cod"
required_steam: 40
permission: "emakicooking.recipe.steamed_cod"
result:
success:
outputs:
- item_sources:
- "minecraft-cooked_cod"
amount: 1
actions:
- 'sendmessage text="<aqua>蒸制完成。</aqua>"'| 字段 | 说明 |
|---|---|
input.item_sources | 可匹配的输入来源。 |
required_steam | 完成该配方需要累计消耗的蒸汽量。 |
requires_previous_step | 可选。填写另一个蒸锅配方 ID,表示本配方是该配方的后续步骤,用于链式蒸制。 |
链式示例:recipes/steamer/chain_example_recipe.yml 用 requires_previous_step: "example_recipe" 把上一步产物接入下一步。
烤炉示例
id: "baked_potato"
display_name: "烤马铃薯"
input:
item_sources:
- "minecraft-potato"
bake_time_seconds: 20
baking:
perfect_heat:
min: 45
max: 60
perfect_required_ratio: 0.7
overbake_seconds: 10
permission: "emakicooking.recipe.baked_potato"
result:
success:
outputs:
- item_sources:
- "minecraft-baked_potato"
amount: 1
actions:
- 'sendmessage text="<gold>烤制完成。</gold>"'
perfect:
outputs:
- item_sources:
- "minecraft-golden_carrot"
amount: 1
overbaked:
outputs:
- item_sources:
- "minecraft-charcoal"
amount: 1烤炉会根据烘烤时间、处于完美火力区间的比例、以及完成后继续加热时间决定结果。高价值料理建议给玩家清楚展示火力和进度,避免“看不懂为什么过烤”。
榨汁机示例
id: "apple_juice"
display_name: "苹果汁"
input:
item_sources:
- "minecraft-apple"
presses_required: 5
fluid:
id: "apple_juice"
display_name: "苹果汁"
amount_ml: 180
container:
item_sources:
- "minecraft-glass_bottle"
serving_ml: 250
permission: "emakicooking.recipe.apple_juice"
result:
success:
outputs:
- item_sources:
- "minecraft-honey_bottle"
amount: 1
actions:
- 'sendmessage text="<aqua>榨汁完成。</aqua>"'一次压榨会向工位加入 fluid.amount_ml 的流体;盛取时消耗 container.serving_ml。例如默认苹果汁每次压榨 180ml,玻璃瓶盛取需要 250ml,所以玩家至少需要压榨两轮才可盛取一次。
发酵桶示例
id: "example_recipe"
display_name: "苹果酒"
inputs:
- item_sources:
- "minecraft-apple"
amount: 3
- item_sources:
- "minecraft-sugar"
amount: 1
fermentation_time_seconds: 300
fermentation:
early_collect:
min_progress_ratio: 0.5
over_time_seconds: 600
permission: "emakicooking.recipe.apple_cider"
condition:
type: all_of
entries:
- "%player_level% >= 3"
on_pass:
actions:
- 'sendmessage text="<green>发酵成熟。</green>"'
on_fail:
actions:
- 'sendmessage text="<yellow>发酵未满足额外条件。</yellow>"'
block_output: false
result:
success:
outputs:
- item_sources:
- "minecraft-honey_bottle"
amount: 1
actions:
- 'sendmessage text="<gold>发酵完成。</gold>"'
early:
outputs:
- item_sources:
- "minecraft-potion"
amount: 1
actions:
- 'sendmessage text="<yellow>提前收取了半发酵苹果饮。</yellow>"'
over:
outputs:
- item_sources:
- "minecraft-honey_bottle"
amount: 1
actions:
- 'sendmessage text="<gold>苹果酒已经继续转化为酸甜果醋。</gold>"'| 字段 | 说明 |
|---|---|
inputs | 发酵桶需要投入的多种材料。 |
fermentation_time_seconds | 正常完成发酵所需秒数。 |
fermentation.early_collect.min_progress_ratio | 允许提前收取的最低进度比例。 |
fermentation.over_time_seconds | 正常完成后继续放置多久进入过度发酵。 |
result.early.outputs | 提前收取产物。 |
result.over.outputs | 过度发酵产物。 |
result.success.outputs | 正常完成产物。 |
调试与验证
- 使用
/ecooking reload重载配方。 - 使用
/ecooking inspect hand检查手持物能否被 Item Source 识别。 - 每个配方至少测试:权限不足、材料不足、背包满、正确分支、失败分支、服务器重启后的工位状态。
- 炒锅额外测试
success、undercooked、overcooked、invalid。 - 烤炉额外测试普通完成、完美完成、过烤。
- 榨汁机额外测试流体不足、容器不匹配和不同流体混合。
- 发酵桶额外测试提前收取、正常完成和过度发酵。