From 3d846fd65a099aa9f1ad6f016540cd45ebef0984 Mon Sep 17 00:00:00 2001 From: Lazula <26179473+Lazula@users.noreply.github.com> Date: Sun, 29 Mar 2026 22:39:50 -0500 Subject: [PATCH] Add CanEat to support conditional edibility --- Common/Collectible/Collectible.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Common/Collectible/Collectible.cs b/Common/Collectible/Collectible.cs index eec659a4..69ad4ab7 100644 --- a/Common/Collectible/Collectible.cs +++ b/Common/Collectible/Collectible.cs @@ -1757,13 +1757,21 @@ public virtual bool OnHeldInteractCancel(float secondsUsed, ItemSlot slot, Entit return true; } + /// + /// Let items with nutrition decide if they're actually edible. Prevents oddities like showing an eating animation that does nothing. + /// For example, pies cannot be eaten unless they're both sliced and not raw even though they have nutrition properties. + /// + public virtual bool CanEat(ItemSlot slot, EntityAgent byEntity) + { + return !slot.Empty && GetNutritionProperties(byEntity?.World, slot.Itemstack, byEntity) != null; + } /// /// Tries to eat the contents in the slot, first call /// protected virtual void tryEatBegin(ItemSlot slot, EntityAgent byEntity, ref EnumHandHandling handling, string eatSound = "eat", int eatSoundRepeats = 1) { - if (!slot.Empty && GetNutritionProperties(byEntity.World, slot.Itemstack, byEntity) != null) + if (CanEat(slot, byEntity)) { byEntity.World.RegisterCallback((dt) => playEatSound(byEntity, eatSound, eatSoundRepeats), 500); @@ -1799,7 +1807,7 @@ protected void playEatSound(EntityAgent byEntity, string eatSound = "eat", int e /// protected virtual bool tryEatStep(float secondsUsed, ItemSlot slot, EntityAgent byEntity, ItemStack spawnParticleStack = null) { - if (GetNutritionProperties(byEntity.World, slot.Itemstack, byEntity) == null) return false; + if (!CanEat(slot, byEntity)) return false; Vec3d pos = byEntity.Pos.AheadCopy(0.4f).XYZ; pos.X += byEntity.LocalEyePos.X; @@ -1830,7 +1838,7 @@ protected virtual void tryEatStop(float secondsUsed, ItemSlot slot, EntityAgent { FoodNutritionProperties nutriProps = GetNutritionProperties(byEntity.World, slot.Itemstack, byEntity); - if (byEntity.World is IServerWorldAccessor && nutriProps != null && secondsUsed >= 0.95f) + if (byEntity.World is IServerWorldAccessor && nutriProps != null && CanEat(slot, byEntity) && secondsUsed >= 0.95f) { TransitionState state = UpdateAndGetTransitionState(api.World, slot, EnumTransitionType.Perish); float spoilState = state != null ? state.TransitionLevel : 0; @@ -2143,7 +2151,7 @@ public virtual WorldInteraction[] GetHeldInteractionHelp(ItemSlot inSlot) { WorldInteraction[] interactions; - if (GetNutritionProperties(api.World, inSlot.Itemstack, null) != null) + if (CanEat(inSlot, null)) { interactions = new WorldInteraction[] {