Ejemplo n.º 1
0
        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());
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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());
        }
Ejemplo n.º 4
0
        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());
        }
Ejemplo n.º 5
0
        /// <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));
        }
Ejemplo n.º 6
0
        /// <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));
        }