营养系统
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 | 文件名 | 营养类型唯一标识。 |
display_name | string | 等于 id | 显示名。 |
min | double | 0 | 下限。 |
max | double | 100 | 上限。 |
default | double | 等于 min | 玩家初始值。 |
解析规则:
- 若
min大于max会自动纠正(取较小为 min、较大为 max)。 default会被截断到[min, max]。display_name为空时回退为 id。
默认 nutrition/fruit.yml 示例:
# 营养类型:水果
# 玩家营养值会被限制在 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 | item_source、item、source | 物品来源列表,任一命中即生效。 |
nutrition | — | 营养类型id: 增加值 映射。 |
actions | — | 命中后额外执行的 CoreLib 动作(可选)。 |
物品来源使用 CoreLib 物品来源前缀:minecraft-<id>、craftengine-<id>、itemsadder-<id>、nexo-<id>、mmoitems-<id>、neigeitems-<id>。若 item_sources 为空,或 nutrition 与 actions 同时为空,该规则被跳过。
nutrition:
food_sources:
- item_sources:
- minecraft-apple
- minecraft-sweet_berries
nutrition:
fruit: 20
- item_sources:
- minecraft-cake
- minecraft-cookie
nutrition:
sugar: 30
actions:
- 'playsound sound=entity.player.burp volume=1.0 pitch=1.0'进食触发链:玩家吃下物品 → CoreLib 识别物品来源 → 匹配 food_sources 规则 → 增加营养值(截断到 min~max)→ 执行规则动作 → 重新评估阈值。原版食物以及通过原版 food 组件实现的 CraftEngine、ItemsAdder、Nexo 食物都走原版进食事件;MMOItems、NeigeItems 通过软依赖单独接入,未安装时不影响运行。
阈值规则
阈值配置在 config.yml → nutrition.thresholds,分单类型(single)和组合(combo)两类。两类都采用边沿触发:达成时执行一次 actions,从满足跌回不足时执行一次 on_recover。
单类型阈值 single
逐个营养类型独立判定。
| 字段 | 别名 | 默认值 | 说明 |
|---|---|---|---|
id | — | single_<下标> | 规则 id。 |
types | type | [](空=全部类型) | 参与判定的营养类型。 |
value | — | 0 | 阈值。 |
compare | operator、op | >= | 比较运算符。 |
actions | on_meet、on_pass | [] | 达成时执行的动作。 |
on_recover | on_fail、recover_actions | [] | 跌回不足时执行的动作。 |
组合阈值 combo
统计达标的营养类型数量是否达到要求。
| 字段 | 别名 | 默认值 | 说明 |
|---|---|---|---|
id | — | combo_<下标> | 规则 id。 |
types | type | [](空=全部类型) | 参与统计的营养类型。 |
value | — | 0 | 每个类型达到该值才算"已达标"。 |
compare | operator、op | >= | 比较运算符。 |
required_count | count | 5 | 需要多少个类型同时达标才触发。 |
actions | on_meet、on_pass | [] | 达标数量满足时执行的动作。 |
on_recover | on_fail、recover_actions | [] | 达标数从满足跌回不足时执行的动作。 |
compare 支持的运算符:>=、>、<=、<、==、!=(也接受 gte、gt、lte、lt、eq、ne 等别名)。若 actions 与 on_recover 都为空,该规则被跳过。
反胃与持续 BUFF 的拼装方式
营养服务本身不写死反胃或 BUFF,而是依赖 CoreLib 循环动作拼装:
loopsync template=<模板> times=<次数> interval=<间隔> key=<唯一key> mode=replace stop_if_offline=true:在达成动作里启动循环(如周期性扣营养、周期性加 BUFF)。cancelloop key=<同一key>:在on_recover里取消循环。
循环模板需在 CoreLib 的 config.yml → action.loop.templates 下定义。下面是默认的"五大营养全满则反胃衰减"组合阈值示例:
nutrition:
thresholds:
combo:
- id: overeat
types: [] # 空=统计全部营养类型
value: 100 # 每类达到 100 算"已满"
compare: ">="
required_count: 5 # 5 类同时满才触发
actions:
- 'sendmessage text=<red>你吃得太撑了,开始反胃……'
- 'playsound sound=entity.player.burp volume=1.0 pitch=0.8'
- 'givepotioneffect type=NAUSEA level=1 duration=200'
- 'loopsync template=nutrition_decay times=999999 interval=40t key=nutrition_overeat:%player_name% mode=replace stop_if_offline=true'
on_recover:
- 'cancelloop key=nutrition_overeat:%player_name%'营养操作动作
营养增减、清空、重置、阈值复查与配方奖励动作由 EmakiCooking 注册到 CoreLib ActionRegistry,可在任意 CoreLib 动作链中使用。当前 Action ID 只使用规范名,不再注册旧别名;完整参数见 CoreLib 动作。
| 操作 | Action ID |
|---|---|
| 增加营养值 | emakicookingaddnutrition |
| 扣除营养值 | emakicookingremovenutrition |
| 设置营养值 | emakicookingsetnutrition |
| 清空营养值 | emakicookingclearnutrition |
| 重置营养值 | emakicookingresetnutrition |
| 复查阈值 | emakicookingrechecknutritionthreshold |
| 执行配方奖励 | emakicookingrunrecipereward |
命令与权限
持久化
- 路径:
plugins/EmakiCooking/data/nutrition/<玩家UUID>.yml,每个玩家一个文件。 - 保存时机:定时保存(
nutrition.save_interval_seconds,默认 300 秒,0表示只在退出或关服时保存)、玩家退出时落盘。 - 玩家加入时加载;重载后会给在线玩家补齐新增类型的默认值。
schema_version: 1
uuid: <玩家UUID>
name: <玩家名>
values:
fruit: 60
vegetable: 40
protein: 80
sugar: 20
grain: 50配置项一览
| 配置键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
nutrition.enabled | boolean | true | 营养系统总开关。 |
nutrition.save_interval_seconds | int | 300 | 定时落盘间隔(秒),0 表示仅退出或关服时保存。 |
nutrition.food_sources | list | 见上文 | 食物到营养的映射。 |
nutrition.thresholds.single | list | 见上文 | 单类型阈值规则。 |
nutrition.thresholds.combo | list | 见上文 | 组合阈值规则。 |
外部插件接入
营养相关的 Bukkit 事件见 事件 API:PlayerNutritionConsumeEvent(消费前,可取消)、NutritionThresholdChangeEvent(阈值达成/恢复,信息型)。