食物追踪系统
基本信息
| 属性 | 值 |
|---|---|
| 类型 | 食物追踪 + 里程碑奖励机制 |
| 触发条件 | 玩家食用有饥饿值的食物 |
| 核心数据 | AttachmentType<FoodList> on Player |
机制概述
Spice-of-Life: Carrot Edition 通过跟踪玩家吃过的不同种类食物,在达到里程碑(milestone)时奖励额外最大生命值( bonus hearts)。
食物记录
每次食用食物时,mod 会将食物的 Item 注册到玩家的 FoodList(通过 AttachmentType<FoodList> 挂在玩家身上)。FoodList 是一个 Set<FoodInstance>,按物品 ID 去重,同一种食物只记录一次。
FoodInstance 以 ResourceLocation 字符串形式序列化到 NBT,存储在玩家数据中。
里程碑与 hearts
玩家每吃够一定数量的不同食物,触发一个里程碑,获得固定数量的额外最大 hearts:
| 配置项 | 默认值 | 说明 |
|---|---|---|
| baseHearts | 10 | 起始 hearts 数 |
| heartsPerMilestone | 2 | 每个里程碑奖励的 hearts 数 |
| milestones | 5, 10, 15, 20, 25 | 里程碑阈值列表 |
里程碑 hearts 通过 AttributeModifier 应用到 Attributes.MAX_HEALTH:
healthPenalty = 2 * (baseHearts - 10)
addedHealthFromFood = milestonesAchieved * 2 * heartsPerMilestone
totalHealthModifier = healthPenalty + addedHealthFromFood
默认配置下:
- baseHearts = 10 → healthPenalty = 0
- 5 个里程碑 × 2 hearts = 最多 +10 hearts(20 颗心 → 30 颗心)
指令
/foodlist
Brigadier 指令,子命令:
| 子命令 | 描述 | 权限 |
|---|---|---|
/foodlist size |
显示当前食物数量和里程碑进度 | 所有玩家 |
/foodlist sync |
强制同步食物列表到客户端 | OP |
/foodlist clear [player] |
清空目标玩家的食物列表 | OP(目标非自己)或自我 |
接受可选 [player] 参数指定目标玩家,不指定则默认为自己。
配置
服务器配置(服务端)
| 配置项 | 默认值 | 说明 |
|---|---|---|
| baseHearts | 10 | 起始 hearts |
| heartsPerMilestone | 2 | 每里程碑 hearts 奖励 |
| milestones | [5,10,15,20,25] | 里程碑阈值 |
| blacklist | [] | 黑名单物品正则,命中不计入 |
| whitelist | [] | 白名单,填写后仅白名单物品计入 |
| minimumFoodValue | 1 | 食物最小饥饿值(半格),低于此值不计入 |
| shouldResetOnDeath | false | 死亡后重置食物列表 |
| limitProgressionToSurvival | false | 是否限制仅生存模式计入进度 |
客户端配置
| 配置项 | 默认值 | 说明 |
|---|---|---|
| shouldPlayMilestoneSounds | true | 里程碑时播放升级音效 |
| shouldSpawnIntermediateParticles | true | 尝试新食物时生成粒子(END_ROD) |
| shouldSpawnMilestoneParticles | true | 里程碑时生成粒子(HEART + HAPPY_VILLAGER) |
| isFoodTooltipEnabled | true | 食物提示栏显示是否已食用 |
| shouldShowProgressAboveHotbar | true | 里程碑消息显示在快捷栏上方还是聊天栏 |
| shouldShowUneatenFoods | true | 食物书中是否显示未食用食物 |
第三方集成
First Aid 兼容
MaxHealthHandler 检测 firstaid mod 是否加载(ModList.get().isLoaded("firstaid"))。如果加载,则禁用玩家血量重置逻辑(player.setHealth(1f)),避免 First Aid 的血量分配机制导致玩家死亡。