public static FoodNutritionProperties[] GetContentNutritionProperties(IWorldAccessor world, ItemSlot inSlot, ItemStack[] contentStacks, EntityAgent forEntity, bool mulWithStacksize = false, float nutritionMul = 1, float healthMul = 1) { List <FoodNutritionProperties> foodProps = new List <FoodNutritionProperties>(); if (contentStacks == null) { return(foodProps.ToArray()); } for (int i = 0; i < contentStacks.Length; i++) { if (contentStacks[i] == null) { continue; } CollectibleObject obj = contentStacks[i].Collectible; FoodNutritionProperties stackProps; if (obj.CombustibleProps != null && obj.CombustibleProps.SmeltedStack != null) { stackProps = obj.CombustibleProps.SmeltedStack.ResolvedItemstack.Collectible.GetNutritionProperties(world, obj.CombustibleProps.SmeltedStack.ResolvedItemstack, forEntity); } else { stackProps = obj.GetNutritionProperties(world, contentStacks[i], forEntity); } if (obj.Attributes?["nutritionPropsWhenInMeal"].Exists == true) { stackProps = obj.Attributes?["nutritionPropsWhenInMeal"].AsObject <FoodNutritionProperties>(); } if (stackProps == null) { continue; } float mul = mulWithStacksize ? contentStacks[i].StackSize : 1; FoodNutritionProperties props = stackProps.Clone(); DummySlot slot = new DummySlot(contentStacks[i], inSlot.Inventory); TransitionState state = contentStacks[i].Collectible.UpdateAndGetTransitionState(world, slot, EnumTransitionType.Perish); float spoilState = state != null ? state.TransitionLevel : 0; float satLossMul = GlobalConstants.FoodSpoilageSatLossMul(spoilState, slot.Itemstack, forEntity); float healthLoss = GlobalConstants.FoodSpoilageHealthLossMul(spoilState, slot.Itemstack, forEntity); props.Satiety *= satLossMul * nutritionMul * mul; props.Health *= healthLoss * healthMul * mul; foodProps.Add(props); } return(foodProps.ToArray()); }
private EnumFoodCategory getFoodCat(ItemStack stack) { FoodNutritionProperties props = stack.Collectible.NutritionProps; if (props == null) { props = stack.Collectible.CombustibleProps?.SmeltedStack?.ResolvedItemstack?.Collectible?.NutritionProps; } if (props != null) { return(props.FoodCategory); } return(EnumFoodCategory.Dairy); }
public string GetContentNutritionFacts(IWorldAccessor world, ItemSlot inSlotorFirstSlot, ItemStack[] contentStacks, EntityAgent forEntity, bool mulWithStacksize = false) { FoodNutritionProperties[] props = GetContentNutritionProperties(world, inSlotorFirstSlot, contentStacks, forEntity); Dictionary <EnumFoodCategory, float> totalSaturation = new Dictionary <EnumFoodCategory, float>(); float totalHealth = 0; for (int i = 0; i < props.Length; i++) { FoodNutritionProperties prop = props[i]; if (prop == null) { continue; } float sat = 0; totalSaturation.TryGetValue(prop.FoodCategory, out sat); DummySlot slot = new DummySlot(contentStacks[i], inSlotorFirstSlot.Inventory); TransitionState state = contentStacks[i].Collectible.UpdateAndGetTransitionState(api.World, slot, EnumTransitionType.Perish); float spoilState = state != null ? state.TransitionLevel : 0; float mul = mulWithStacksize ? contentStacks[i].StackSize : 1; float satLossMul = GlobalConstants.FoodSpoilageSatLossMul(spoilState, slot.Itemstack, forEntity); float healthLossMul = GlobalConstants.FoodSpoilageHealthLossMul(spoilState, slot.Itemstack, forEntity); totalHealth += prop.Health * healthLossMul * mul; totalSaturation[prop.FoodCategory] = (sat + prop.Satiety * satLossMul) * mul; } StringBuilder sb = new StringBuilder(); sb.AppendLine(Lang.Get("Nutrition Facts")); foreach (var val in totalSaturation) { sb.AppendLine("- " + Lang.Get("" + val.Key) + ": " + Math.Round(val.Value) + " sat."); } if (totalHealth != 0) { sb.AppendLine("- " + Lang.Get("Health: {0}{1} hp", totalHealth > 0 ? "+" : "", totalHealth)); } return(sb.ToString()); }
public string GetContentNutritionFacts(IWorldAccessor world, ItemStack[] contentStacks, Entity forEntity) { FoodNutritionProperties[] props = GetContentNutritionProperties(world, contentStacks, forEntity); Dictionary <EnumFoodCategory, float> totalSaturation = new Dictionary <EnumFoodCategory, float>(); float totalHealth = 0; for (int i = 0; i < props.Length; i++) { FoodNutritionProperties prop = props[i]; if (prop == null) { continue; } float sat = 0; totalSaturation.TryGetValue(prop.FoodCategory, out sat); totalHealth += prop.Health; totalSaturation[prop.FoodCategory] = sat + prop.Saturation; } StringBuilder sb = new StringBuilder(); sb.AppendLine("Nutrition Facts"); foreach (var val in totalSaturation) { sb.AppendLine("- " + Lang.Get("" + val.Key) + ": " + val.Value + " sat."); } if (totalHealth != 0) { sb.AppendLine("- " + Lang.Get("Health: {0}{1} hp", totalHealth > 0 ? "+" : "", totalHealth)); } return(sb.ToString()); }
/// <summary> /// Consumes a meal /// </summary> /// <param name="world"></param> /// <param name="eatingPlayer"></param> /// <param name="contentStacks"></param> /// <param name="recipeCode"></param> /// <param name="remainingServings"></param> /// <returns>Amount of servings left</returns> public virtual float Consume(IWorldAccessor world, IPlayer eatingPlayer, ItemSlot inSlot, ItemStack[] contentStacks, float remainingServings, bool mulwithStackSize) { float[] nmul = GetNutritionHealthMul(null, inSlot, eatingPlayer.Entity); FoodNutritionProperties[] multiProps = GetContentNutritionProperties(world, inSlot, contentStacks, eatingPlayer.Entity, mulwithStackSize, nmul[0], nmul[1]); if (multiProps == null) { return(remainingServings); } float totalHealth = 0; EntityBehaviorHunger ebh = eatingPlayer.Entity.GetBehavior <EntityBehaviorHunger>(); float satiablePoints = ebh.MaxSaturation - ebh.Saturation; float mealSatpoints = 0; for (int i = 0; i < multiProps.Length; i++) { FoodNutritionProperties nutriProps = multiProps[i]; if (nutriProps == null) { continue; } mealSatpoints += nutriProps.Satiety; } float servingsNeeded = GameMath.Clamp(satiablePoints / Math.Max(1, mealSatpoints), 0, 1); float servingsToEat = Math.Min(remainingServings, servingsNeeded); // Affect the players body temperature by eating meals with a larger temperature difference float temp = inSlot.Itemstack.Collectible.GetTemperature(world, inSlot.Itemstack); var bh = eatingPlayer.Entity.GetBehavior <EntityBehaviorBodyTemperature>(); if (bh != null && Math.Abs(temp - bh.CurBodyTemperature) > 10) { float intensity = Math.Min(1, (temp - bh.CurBodyTemperature) / 30f); bh.CurBodyTemperature += GameMath.Clamp(mealSatpoints * servingsToEat / 80f * intensity, 0, 5); } for (int i = 0; i < multiProps.Length; i++) { FoodNutritionProperties nutriProps = multiProps[i]; if (nutriProps == null) { continue; } float mul = servingsToEat; float sat = mul * nutriProps.Satiety; eatingPlayer.Entity.ReceiveSaturation(sat, nutriProps.FoodCategory, 10 + sat / 70f * 60f, 1f); if (nutriProps.EatenStack?.ResolvedItemstack != null) { if (eatingPlayer == null || !eatingPlayer.InventoryManager.TryGiveItemstack(nutriProps.EatenStack.ResolvedItemstack.Clone(), true)) { world.SpawnItemEntity(nutriProps.EatenStack.ResolvedItemstack.Clone(), eatingPlayer.Entity.SidedPos.XYZ); } } totalHealth += mul * nutriProps.Health; } if (totalHealth != 0) { eatingPlayer.Entity.ReceiveDamage(new DamageSource() { Source = EnumDamageSource.Internal, Type = totalHealth > 0 ? EnumDamageType.Heal : EnumDamageType.Poison }, Math.Abs(totalHealth)); } return(Math.Max(0, remainingServings - servingsToEat)); }
/// <summary> /// Consumes a meal /// </summary> /// <param name="world"></param> /// <param name="eatingPlayer"></param> /// <param name="contentStacks"></param> /// <param name="recipeCode"></param> /// <param name="remainingServings"></param> /// <returns>Amount of servings left</returns> public static float Consume(IWorldAccessor world, IPlayer eatingPlayer, ItemSlot inSlot, ItemStack[] contentStacks, float remainingServings, bool mulwithStackSize) { FoodNutritionProperties[] multiProps = GetContentNutritionProperties(world, inSlot, contentStacks, eatingPlayer.Entity); if (multiProps == null) { return(remainingServings); } float totalHealth = 0; EntityBehaviorHunger ebh = eatingPlayer.Entity.GetBehavior <EntityBehaviorHunger>(); float satiablePoints = ebh.MaxSaturation - ebh.Saturation; float mealSatpoints = 0; for (int i = 0; i < multiProps.Length; i++) { FoodNutritionProperties nutriProps = multiProps[i]; if (nutriProps == null) { continue; } mealSatpoints += nutriProps.Satiety * (mulwithStackSize ? contentStacks[i].StackSize : 1); } float servingsNeeded = GameMath.Clamp(satiablePoints / Math.Max(1, mealSatpoints), 0, 1); float servingsToEat = Math.Min(remainingServings, servingsNeeded); for (int i = 0; i < multiProps.Length; i++) { FoodNutritionProperties nutriProps = multiProps[i]; if (nutriProps == null) { continue; } float mul = servingsToEat * (mulwithStackSize ? contentStacks[i].StackSize : 1); float sat = mul * nutriProps.Satiety; eatingPlayer.Entity.ReceiveSaturation(sat, nutriProps.FoodCategory, 10 + sat / 70f * 60f, 1f); if (nutriProps.EatenStack?.ResolvedItemstack != null) { if (eatingPlayer == null || !eatingPlayer.InventoryManager.TryGiveItemstack(nutriProps.EatenStack.ResolvedItemstack.Clone(), true)) { world.SpawnItemEntity(nutriProps.EatenStack.ResolvedItemstack.Clone(), eatingPlayer.Entity.SidedPos.XYZ); } } totalHealth += mul * nutriProps.Health; } if (totalHealth != 0) { eatingPlayer.Entity.ReceiveDamage(new DamageSource() { Source = EnumDamageSource.Internal, Type = totalHealth > 0 ? EnumDamageType.Heal : EnumDamageType.Poison }, Math.Abs(totalHealth)); } return(Math.Max(0, remainingServings - servingsToEat)); }