简体中文
营养系统
EmakiCooking 的营养系统如下: 玩家吃东西会累积不同类型的营养值, 达到或跌破阈值时触发你配好的动作
EmakiCooking 有一套类似膳食均衡的营养系统: 玩家进食会累积不同类型的营养值, 达到或跌破阈值时触发你自己配置的动作. 这套系统只提供机制 (增减值, 越过阈值时触发, 数据保存), 反胃, 持续 BUFF, 营养衰减这些具体玩法要你自己用 CoreLib 动作拼出来
基本信息
| 项目 | 值 |
|---|---|
| 总开关 | config.yml → nutrition.enabled (默认 true) |
| 类型定义目录 | nutrition/<id>.yml |
| 默认营养类型 | fruit, grain, protein, sugar, vegetable |
| 玩家数据 | data/nutrition/<玩家UUID>.yml |
| 主要权限 | emakicooking.nutrition.use, emakicooking.nutrition.admin |
营养类型定义
每个营养类型对应 nutrition/ 目录下的一个 .yml 文件, 文件名 (去掉 .yml) 作为 id 的默认值. 默认发布 5 个类型, 可任意增删
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
id | string | 否 | 文件名 (去 .yml) | — | 营养类型唯一标识 |
display_name | string | 否 | 等于 id | — | 显示名; 为空时回退为 id |
min | double | 否 | 0 | — | 下限 |
max | double | 否 | 100 | — | 上限 |
default | double | 否 | 等于 min | 截断到 [min, max] | 玩家初始值 |
解析规则:
- 若
min大于max会自动纠正 (取较小为 min, 较大为 max) default会被截断到[min, max]display_name为空时回退为 id
默认 nutrition/fruit.yml 示例:
yaml
# 营养类型: 水果
# 玩家营养值会被限制在 min ~ max 之间
id: fruit
display_name: "水果"
min: 0
max: 100
default: 0TIP
单类型阈值, 组合阈值, 达成/恢复动作, 食物到营养的映射都不在 nutrition/*.yml 里, 而是配置在 config.yml 的 nutrition: 段. nutrition/*.yml 只定义类型本身的这 5 个字段
食物到营养的映射
食物吃下后增加哪些营养, 配置在 config.yml → nutrition.food_sources (列表)
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
item_sources | list<string> | 否 | [] | CoreLib 物品来源简写 | 允许的物品来源列表. 与同级 matcher 取 AND, 两者都省略则该规则被跳过 |
matcher | object | 否 | 无 | 通用 matcher; 不得写物品源条件 | 组件 / PDC / Lore 等附加条件 |
nutrition | map<string,double> | 否 | {} | 营养类型id: 增加值 | 命中后增加的营养值. 与 actions 同时为空时该规则被跳过 |
actions | list<string> | 否 | [] | CoreLib 动作字符串 | 命中后额外执行的动作 |
item_sources 与 matcher 是同级并行字段, 判定取 AND: 两者都写时要同时成立才命中
物品来源使用 CoreLib 物品来源前缀: minecraft-<id>, craftengine-<id>, itemsadder-<id>, nexo-<id>, oraxen-<id>, mmoitems-<id>, neigeitems-<id>. 若 item_sources 与 matcher 同时为空, 或 nutrition 与 actions 同时为空, 该规则被跳过
yaml
nutrition:
food_sources:
- item_sources:
- minecraft-apple
- minecraft-sweet_berries
nutrition:
fruit: 20
- item_sources:
- minecraft-cake
- minecraft-cookie
nutrition:
sugar: 30
actions:
- 'play_sound sound=entity.player.burp volume=1.0 pitch=1.0'
# 只要没被改过名的蛋糕: 两个字段各写一半
- item_sources:
- minecraft-cake
matcher:
type: component
component: custom_name
operator: absent
nutrition:
sugar: 40进食触发链: 玩家吃下物品 → CoreLib 识别物品来源 → 匹配 food_sources 规则 → 增加营养值 (截断到 min~max) → 执行规则动作 → 重新评估阈值. 原版食物以及通过原版 food 组件实现的 CraftEngine, ItemsAdder, Nexo 食物都走原版进食事件; MMOItems, NeigeItems 通过软依赖单独接入, 未安装时不影响运行
阈值规则
阈值配置在 config.yml → nutrition.thresholds, 分单类型 (single) 和组合 (combo) 两类. 两类都在越过阈值的那一刻触发: 达成时执行一次 actions, 从满足跌回不足时执行一次 on_recover
单类型阈值 single
逐个营养类型独立判定
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
id | string | 否 | single_<下标> | — | 规则 id |
types | list<string> | 否 | [] (空=全部类型) | 已注册的营养类型 id | 参与判定的营养类型 |
value | double | 否 | 0 | — | 阈值 |
compare | string | 否 | >= | 见下方运算符表; 无法识别的值回退为 >= | 比较运算符 |
actions | list<string> | 否 | [] | CoreLib 动作字符串 | 达成时执行的动作 |
on_recover | list<string> | 否 | [] | CoreLib 动作字符串 | 跌回不足时执行的动作 |
组合阈值 combo
统计达标的营养类型数量是否达到要求
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
id | string | 否 | combo_<下标> | — | 规则 id |
types | list<string> | 否 | [] (空=全部类型) | 已注册的营养类型 id | 参与统计的营养类型 |
value | double | 否 | 0 | — | 每个类型达到该值才算"已达标" |
compare | string | 否 | >= | 见下方运算符表; 无法识别的值回退为 >= | 比较运算符 |
required_count | int | 否 | 5 | — (源码未校验, 非数字时按 5) | 需要多少个类型同时达标才触发 |
actions | list<string> | 否 | [] | CoreLib 动作字符串 | 达标数量满足时执行的动作 |
on_recover | list<string> | 否 | [] | CoreLib 动作字符串 | 达标数从满足跌回不足时执行的动作 |
compare 支持的运算符及其全部别名 (大小写不敏感, 无法识别的值回退为 >=):
| 运算符 | 可写形式 |
|---|---|
| 大于等于 | >=, gte, at_least, ge |
| 大于 | >, gt, greater |
| 小于等于 | <=, lte, at_most, le |
| 小于 | <, lt, less |
| 等于 | ==, =, eq, equal, equals |
| 不等于 | !=, <>, ne, not_equal |
若 actions 与 on_recover 都为空, 该规则被跳过
反胃与持续 BUFF 的拼装方式
营养服务本身不写死反胃或 BUFF, 而是依赖 CoreLib 循环动作拼装:
start_task sequence=<模板> times=<次数> interval=<间隔> key=<唯一key> on_conflict=replace stop_when_offline=true: 在达成动作里启动循环 (如周期性扣营养, 周期性加 BUFF)stop_task key=<同一key>: 在on_recover里取消循环
循环模板需在 CoreLib 的 config.yml → action.loop.templates 下定义. 下面是默认的"五大营养全满则反胃衰减"组合阈值示例:
yaml
nutrition:
thresholds:
combo:
- id: overeat
types: [] # 空=统计全部营养类型
value: 100 # 每类达到 100 算"已满"
compare: ">="
required_count: 5 # 5 类同时满才触发
actions:
- 'send_message text=<red>你吃得太撑了,开始反胃……'
- 'play_sound sound=entity.player.burp volume=1.0 pitch=0.8'
- 'give_potion_effect type=NAUSEA level=1 duration=200'
- 'start_task sequence=nutrition_decay times=999999 interval=40t key=nutrition_overeat:%player_name% on_conflict=replace stop_when_offline=true'
on_recover:
- 'stop_task key=nutrition_overeat:%player_name%'营养操作动作
营养增减, 清空, 重置, 阈值复查与配方奖励动作由 EmakiCooking 注册到 CoreLib 的动作注册表, 可在任意 CoreLib 动作链中使用. 当前 Action ID 只使用规范名, 不再注册旧别名; 完整参数见 CoreLib 动作
| 操作 | Action ID |
|---|---|
| 增加营养值 | cooking_add_nutrition |
| 扣除营养值 | cooking_remove_nutrition |
| 设置营养值 | cooking_set_nutrition |
| 清空营养值 | cooking_clear_nutrition |
| 重置营养值 | cooking_reset_nutrition |
| 复查阈值 | cooking_recheck_nutrition_threshold |
| 执行配方奖励 | cooking_run_recipe_reward |
命令与权限
持久化
- 路径:
plugins/EmakiCooking/data/nutrition/<玩家UUID>.yml, 每个玩家一个文件 - 保存时机: 定时保存 (
nutrition.save_interval_seconds, 默认 300 秒,0表示只在退出或关服时保存), 玩家退出时也会保存一次 - 玩家加入时加载; 重载后会给在线玩家补齐新增类型的默认值
yaml
schema_version: 1
uuid: <玩家UUID>
name: <玩家名>
nutrition:
fruit: 60
vegetable: 40
protein: 80
sugar: 20
grain: 50配置项一览
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
nutrition.enabled | boolean | 否 | true | true / false | 营养系统总开关 |
nutrition.save_interval_seconds | int | 否 | 300 | ≥ 0 (秒), 小于 0 按 0 | 定时保存的间隔, 0 表示仅退出或关服时保存 |
nutrition.food_sources | list<object> | 否 | 发货给出示例 | 见"食物到营养的映射" | 食物到营养的映射 |
nutrition.thresholds.single | list<object> | 否 | 发货给出示例 | 见"单类型阈值" | 单类型阈值规则 |
nutrition.thresholds.combo | list<object> | 否 | 发货给出示例 | 见"组合阈值" | 组合阈值规则 |
外部插件接入
营养相关的 Bukkit 事件见 事件 API: PlayerNutritionConsumeEvent (消费前, 可取消), NutritionThresholdChangeEvent (阈值达成/恢复, 信息型)