Esempio n. 1
0
 public Food(string name, decimal unitWeight, decimal unitPrice, EnumFoodCategory foodCategory)
 {
     this.name = name;
     this.unitWeight = unitWeight;
     this.unitPrice = unitPrice;
     this.foodCategory = foodCategory;
 }
Esempio n. 2
0
 public Food()
 {
     name = String.Empty;
     unitWeight = 0m;
     unitPrice = 0m;
     foodCategory = EnumFoodCategory.MixEater;
 }
Esempio n. 3
0
        public override void OnEntityReceiveSaturation(float saturation, EnumFoodCategory foodCat = EnumFoodCategory.Unknown, float saturationLossDelay = 10, float nutritionGainMultiplier = 1f)
        {
            float maxsat = MaxSaturation;
            bool  full   = Saturation >= maxsat;

            Saturation = Math.Min(maxsat, Saturation + saturation);

            switch (foodCat)
            {
            case EnumFoodCategory.Fruit:
                if (!full)
                {
                    FruitLevel = Math.Min(maxsat, FruitLevel + saturation / 2.5f * nutritionGainMultiplier);
                }
                SaturationLossDelayFruit = Math.Max(SaturationLossDelayFruit, saturationLossDelay);
                break;

            case EnumFoodCategory.Vegetable:
                if (!full)
                {
                    VegetableLevel = Math.Min(maxsat, VegetableLevel + saturation / 2.5f * nutritionGainMultiplier);
                }
                SaturationLossDelayVegetable = Math.Max(SaturationLossDelayVegetable, saturationLossDelay);
                break;

            case EnumFoodCategory.Protein:
                if (!full)
                {
                    ProteinLevel = Math.Min(maxsat, ProteinLevel + saturation / 2.5f * nutritionGainMultiplier);
                }
                SaturationLossDelayProtein = Math.Max(SaturationLossDelayProtein, saturationLossDelay);
                break;

            case EnumFoodCategory.Grain:
                if (!full)
                {
                    GrainLevel = Math.Min(maxsat, GrainLevel + saturation / 2.5f * nutritionGainMultiplier);
                }
                SaturationLossDelayGrain = Math.Max(SaturationLossDelayGrain, saturationLossDelay);
                break;

            case EnumFoodCategory.Dairy:
                if (!full)
                {
                    DairyLevel = Math.Min(maxsat, DairyLevel + saturation / 2.5f * nutritionGainMultiplier);
                }
                SaturationLossDelayDairy = Math.Max(SaturationLossDelayDairy, saturationLossDelay);
                break;
            }

            UpdateNutrientHealthBoost();
        }
Esempio n. 4
0
        public override string GetHeldItemName(ItemStack itemStack)
        {
            ItemStack[] cStacks = GetContents(api.World, itemStack);
            if (cStacks.Length <= 1)
            {
                return(Lang.Get("pie-empty"));
            }

            ItemStack cstack = cStacks[1];

            if (cstack == null)
            {
                return(Lang.Get("pie-empty"));
            }

            bool equal = true;

            for (int i = 2; equal && i < cStacks.Length - 1; i++)
            {
                if (cStacks[i] == null)
                {
                    continue;
                }

                equal &= cstack.Equals(api.World, cStacks[i], GlobalConstants.IgnoredStackAttributes);
                cstack = cStacks[i];
            }

            string state = Variant["state"];

            if (MealMeshCache.ContentsRotten(cStacks))
            {
                return(Lang.Get("pie-single-rotten"));
            }

            if (equal)
            {
                return(Lang.Get("pie-single-" + cstack.Collectible.Code.ToShortString() + "-" + state));
            }
            else
            {
                EnumFoodCategory fillingFoodCat =
                    cStacks[1].Collectible.NutritionProps?.FoodCategory
                    ?? cStacks[1].ItemAttributes?["nutritionPropsWhenInMeal"]?.AsObject <FoodNutritionProperties>()?.FoodCategory
                    ?? EnumFoodCategory.Vegetable
                ;

                return(Lang.Get("pie-mixed-" + fillingFoodCat.ToString().ToLowerInvariant() + "-" + state));
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Recieves the saturation from a food source.
        /// </summary>
        /// <param name="saturation">The amount of saturation recieved.</param>
        /// <param name="foodCat">The cat of food... err Category of food.</param>
        /// <param name="saturationLossDelay">The delay before the loss of saturation</param>
        public virtual void ReceiveSaturation(float saturation, EnumFoodCategory foodCat = EnumFoodCategory.Unknown, float saturationLossDelay = 10, float nutritionGainMultiplier = 1f)
        {
            if (!Alive)
            {
                return;
            }

            if (ShouldReceiveSaturation(saturation, foodCat, saturationLossDelay))
            {
                foreach (EntityBehavior behavior in SidedProperties.Behaviors)
                {
                    behavior.OnEntityReceiveSaturation(saturation, foodCat, saturationLossDelay, nutritionGainMultiplier);
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Gets the name for ingredients in regards to food.
        /// </summary>
        /// <param name="worldForResolve">The world to resolve in.</param>
        /// <param name="recipeCode">The recipe code.</param>
        /// <param name="stacks">The stacks of items to add.</param>
        /// <returns>The name of the food type.</returns>
        public string GetNameForIngredients(IWorldAccessor worldForResolve, string recipeCode, ItemStack[] stacks)
        {
            OrderedDictionary <ItemStack, int> quantitiesByStack = new OrderedDictionary <ItemStack, int>();

            quantitiesByStack = mergeStacks(worldForResolve, stacks);

            CookingRecipe recipe = worldForResolve.Api.GetCookingRecipes().FirstOrDefault(rec => rec.Code == recipeCode);

            if (recipeCode == null || recipe == null || quantitiesByStack.Count == 0)
            {
                return("unknown");
            }

            int           max                 = 1;
            string        MealFormat          = "meal";
            string        topping             = string.Empty;
            ItemStack     PrimaryIngredient   = null;
            ItemStack     SecondaryIngredient = null;
            List <string> OtherIngredients    = new List <string>();
            List <string> MashedNames         = new List <string>();
            List <string> GarnishedNames      = new List <string>();
            List <string> grainNames          = new List <string>();
            string        mainIngredients;
            string        everythingelse = "";



            switch (recipeCode)
            {
            case "soup":
            {
                max = 0;
                foreach (var val in quantitiesByStack)
                {
                    CookingRecipeIngredient ingred = recipe.GetIngrendientFor(val.Key);
                    if (val.Key.Collectible.Code.Path.Contains("waterportion"))
                    {
                        continue;
                    }
                    if (ingred?.Code == "topping")
                    {
                        topping = "honeyportion";
                        continue;
                    }


                    if (max < val.Value)
                    {
                        max = val.Value;
                        if (PrimaryIngredient != null)
                        {
                            SecondaryIngredient = PrimaryIngredient;
                        }
                        PrimaryIngredient = val.Key;
                    }
                    else
                    {
                        OtherIngredients.Add(ingredientName(val.Key, true));
                    }
                }

                if (max == 2)
                {
                    max = 3;
                }
                else if (max == 3)
                {
                    max = 4;
                }
                else
                {
                    max = 2;
                }

                break;
            }

            case "porridge":
            {
                max = 0;
                foreach (var val in quantitiesByStack)
                {
                    CookingRecipeIngredient ingred = recipe.GetIngrendientFor(val.Key);
                    if (getFoodCat(val.Key) == EnumFoodCategory.Grain)
                    {
                        max++;
                        if (PrimaryIngredient == null)
                        {
                            PrimaryIngredient = val.Key;
                        }
                        else if (SecondaryIngredient == null && val.Key != PrimaryIngredient)
                        {
                            SecondaryIngredient = val.Key;
                        }

                        continue;
                    }

                    if (ingred?.Code == "topping")
                    {
                        topping = "honeyportion";
                        continue;
                    }

                    MashedNames.Add(ingredientName(val.Key, true));
                }
                break;
            }

            case "meatystew":
            {
                max = 0;
                foreach (var val in quantitiesByStack)
                {
                    CookingRecipeIngredient ingred = recipe.GetIngrendientFor(val.Key);

                    EnumFoodCategory foodCat = getFoodCat(val.Key);

                    if (foodCat == EnumFoodCategory.Protein)
                    {
                        if (PrimaryIngredient == val.Key || SecondaryIngredient == val.Key)
                        {
                            continue;
                        }

                        if (PrimaryIngredient == null)
                        {
                            PrimaryIngredient = val.Key;
                        }
                        else if (SecondaryIngredient == null)
                        {
                            SecondaryIngredient = val.Key;
                        }
                        else
                        {
                            OtherIngredients.Add(ingredientName(val.Key, true));
                        }

                        max += val.Value;

                        continue;
                    }


                    if (ingred?.Code == "topping")
                    {
                        topping = "honeyportion";
                        continue;
                    }

                    OtherIngredients.Add(ingredientName(val.Key, true));
                }

                recipeCode = "stew";
                break;
            }

            case "vegetablestew":
            {
                max = 0;

                foreach (var val in quantitiesByStack)
                {
                    if (getFoodCat(val.Key) == EnumFoodCategory.Vegetable)
                    {
                        if (PrimaryIngredient == val.Key || SecondaryIngredient == val.Key)
                        {
                            continue;
                        }

                        if (PrimaryIngredient == null)
                        {
                            PrimaryIngredient = val.Key;
                        }
                        else if (SecondaryIngredient == null)
                        {
                            SecondaryIngredient = val.Key;
                        }
                        else
                        {
                            GarnishedNames.Add(ingredientName(val.Key, true));
                        }

                        max += val.Value;

                        continue;
                    }
                    GarnishedNames.Add(ingredientName(val.Key, true));
                }

                // Slightly ugly hack for soybean stew
                if (PrimaryIngredient == null)
                {
                    foreach (var val in quantitiesByStack)
                    {
                        //CookingRecipeIngredient ingred = recipe.GetIngrendientFor(val.Key); - whats this for?
                        PrimaryIngredient = val.Key;
                        max += val.Value;
                    }
                }

                recipeCode = "stew";
                break;
            }



            case "scrambledeggs":
            {
                max = 0;

                foreach (var val in quantitiesByStack)
                {
                    if (val.Key.Collectible.FirstCodePart() == "egg")
                    {
                        PrimaryIngredient = val.Key;
                        max += val.Value;
                        continue;
                    }

                    GarnishedNames.Add(ingredientName(val.Key, true));
                }


                recipeCode = "scrambledeggs";
                break;
            }


            case "jam":
            {
                ItemStack[] fruits = new ItemStack[2];
                int         i      = 0;
                foreach (var val in quantitiesByStack)
                {
                    if (val.Key.Collectible.NutritionProps?.FoodCategory == EnumFoodCategory.Fruit)
                    {
                        fruits[i++] = val.Key;
                        if (i == 2)
                        {
                            break;
                        }
                    }
                }

                if (fruits[1] != null)
                {
                    return(Lang.Get("mealname-mixedjam", fruits[0].GetName(), fruits[1].GetName()));
                }
                else
                {
                    string jamName          = fruits[0].Collectible.LastCodePart() + "-jam";
                    string jamNameLocalised = Lang.Get(jamName);
                    if (jamName != jamNameLocalised)
                    {
                        return(jamNameLocalised);
                    }
                    return(Lang.Get("mealname-singlejam", fruits[0].GetName()));
                }
            }
            }



            switch (max)
            {
            case 3:
                MealFormat += "-hearty-" + recipeCode;
                break;

            case 4:
                MealFormat += "-hefty-" + recipeCode;
                break;

            default:
                MealFormat += "-normal-" + recipeCode;
                break;
            }

            if (topping == "honeyportion")
            {
                MealFormat += "-honey";
            }
            //mealformat is done.  Time to do the main inredients.



            if (SecondaryIngredient != null && recipeCode != "scrambledeggs")
            {
                mainIngredients = Lang.Get("multi-main-ingredients-format", getMainIngredientName(PrimaryIngredient, recipeCode), getMainIngredientName(SecondaryIngredient, recipeCode, true));
            }
            else
            {
                mainIngredients = PrimaryIngredient == null ? "" : getMainIngredientName(PrimaryIngredient, recipeCode);
            }


            switch (recipeCode)
            {
            case "porridge":
                if (MashedNames.Count > 0)
                {
                    everythingelse = getMealAddsString("meal-adds-porridge-mashed", MashedNames);
                }
                else
                {
                    everythingelse = "";
                }
                break;

            case "stew":
                if (OtherIngredients.Count > 0)
                {
                    everythingelse = getMealAddsString("meal-adds-meatystew-boiled", OtherIngredients);
                }
                else if (GarnishedNames.Count > 0)
                {
                    everythingelse = getMealAddsString("meal-adds-vegetablestew-garnish", GarnishedNames);
                }
                else
                {
                    everythingelse = "";
                }
                break;

            case "scrambledeggs":
                if (GarnishedNames.Count > 0)
                {
                    everythingelse = getMealAddsString("meal-adds-vegetablestew-garnish", GarnishedNames);
                }
                return(Lang.Get(MealFormat, everythingelse).Trim().UcFirst());

            case "soup":
                if (OtherIngredients.Count > 0)
                {
                    everythingelse = getMealAddsString("meal-adds-generic", OtherIngredients);
                }
                break;
            }
            //everything else is done.

            return(Lang.Get(MealFormat, mainIngredients, everythingelse).Trim().UcFirst());
        }
Esempio n. 7
0
 /// <summary>
 /// Whether or not the target should recieve saturation.
 /// </summary>
 /// <param name="saturation">The amount of saturation recieved.</param>
 /// <param name="foodCat">The cat of food... err Category of food.</param>
 /// <param name="saturationLossDelay">The delay before the loss of saturation</param>
 public virtual bool ShouldReceiveSaturation(float saturation, EnumFoodCategory foodCat = EnumFoodCategory.Unknown, float saturationLossDelay = 10, float nutritionGainMultiplier = 1f)
 {
     return(true);
 }
Esempio n. 8
0
        private bool TryAddIngredientFrom(ItemSlot slot, IPlayer byPlayer = null)
        {
            var pieProps = slot.Itemstack.ItemAttributes?["inPieProperties"]?.AsObject <InPieProperties>(null, slot.Itemstack.Collectible.Code.Domain);

            if (pieProps == null)
            {
                if (byPlayer != null && capi != null)
                {
                    capi.TriggerIngameError(this, "notpieable", Lang.Get("This item can not be added to pies"));
                }
                return(false);
            }

            if (slot.StackSize < 2)
            {
                if (byPlayer != null && capi != null)
                {
                    capi.TriggerIngameError(this, "notpieable", Lang.Get("Need at least 2 items each"));
                }
                return(false);
            }

            var pieBlock = (inv[0].Itemstack.Block as BlockPie);

            if (pieBlock == null)
            {
                return(false);
            }

            ItemStack[] cStacks = pieBlock.GetContents(Api.World, inv[0].Itemstack);

            bool isFull     = cStacks[1] != null && cStacks[2] != null && cStacks[3] != null && cStacks[4] != null;
            bool hasFilling = cStacks[1] != null || cStacks[2] != null || cStacks[3] != null || cStacks[4] != null;

            if (isFull)
            {
                if (pieProps.PartType == EnumPiePartType.Crust)
                {
                    if (cStacks[5] == null)
                    {
                        cStacks[5] = slot.TakeOut(2);
                        pieBlock.SetContents(inv[0].Itemstack, cStacks);
                    }
                    else
                    {
                        ItemStack stack = inv[0].Itemstack;
                        stack.Attributes.SetInt("topCrustType", (stack.Attributes.GetInt("topCrustType") + 1) % 3);
                    }
                    return(true);
                }
                if (byPlayer != null && capi != null)
                {
                    capi.TriggerIngameError(this, "piefullfilling", Lang.Get("Can't add more filling - already completely filled pie"));
                }
                return(false);
            }

            if (pieProps.PartType != EnumPiePartType.Filling)
            {
                if (byPlayer != null && capi != null)
                {
                    capi.TriggerIngameError(this, "pieneedsfilling", Lang.Get("Need to add a filling next"));
                }
                return(false);
            }


            if (!hasFilling)
            {
                cStacks[1] = slot.TakeOut(2);
                pieBlock.SetContents(inv[0].Itemstack, cStacks);
                return(true);
            }

            var foodCats   = cStacks.Select(stack => stack?.Collectible.NutritionProps?.FoodCategory ?? stack?.ItemAttributes?["nutritionPropsWhenInMeal"]?.AsObject <FoodNutritionProperties>()?.FoodCategory ?? EnumFoodCategory.Vegetable).ToArray();
            var stackprops = cStacks.Select(stack => stack?.ItemAttributes["inPieProperties"]?.AsObject <InPieProperties>(null, stack.Collectible.Code.Domain)).ToArray();

            ItemStack        cstack  = slot.Itemstack;
            EnumFoodCategory foodCat = slot.Itemstack?.Collectible.NutritionProps?.FoodCategory ?? slot.Itemstack?.ItemAttributes?["nutritionPropsWhenInMeal"]?.AsObject <FoodNutritionProperties>()?.FoodCategory ?? EnumFoodCategory.Vegetable;

            bool equal         = true;
            bool foodCatEquals = true;

            for (int i = 1; equal && i < cStacks.Length - 1; i++)
            {
                if (cstack == null)
                {
                    continue;
                }

                equal         &= cStacks[i] == null || cstack.Equals(Api.World, cStacks[i], GlobalConstants.IgnoredStackAttributes);
                foodCatEquals &= cStacks[i] == null || foodCats[i] == foodCat;

                cstack  = cStacks[i];
                foodCat = foodCats[i];
            }

            int emptySlotIndex = 2 + (cStacks[2] != null ? 1 + (cStacks[3] != null ? 1 : 0) : 0);

            if (equal)
            {
                cStacks[emptySlotIndex] = slot.TakeOut(2);
                pieBlock.SetContents(inv[0].Itemstack, cStacks);
                return(true);
            }

            if (!foodCatEquals)
            {
                if (byPlayer != null && capi != null)
                {
                    capi.TriggerIngameError(this, "piefullfilling", Lang.Get("Can't mix fillings from different food categories"));
                }
                return(false);
            }
            else
            {
                if (!stackprops[1].AllowMixing)
                {
                    if (byPlayer != null && capi != null)
                    {
                        capi.TriggerIngameError(this, "piefullfilling", Lang.Get("You really want to mix these to ingredients?! That would taste horrible!"));
                    }
                    return(false);
                }

                cStacks[emptySlotIndex] = slot.TakeOut(2);
                pieBlock.SetContents(inv[0].Itemstack, cStacks);
                return(true);
            }
        }
Esempio n. 9
0
        public MeshData GetPieMesh(ItemStack pieStack, ModelTransform transform = null)
        {
            // Slot 0: Base dough
            // Slot 1: Filling
            // Slot 2: Crust dough

            nowTesselatingBlock = pieStack.Block as BlockPie;
            if (nowTesselatingBlock == null)
            {
                return(null);                              //This will occur if the pieStack changed to rot
            }
            contentStacks = nowTesselatingBlock.GetContents(capi.World, pieStack);

            int pieSize = pieStack.Attributes.GetInt("pieSize");


            // At this spot we have to determine the textures for "dough" and "filling"
            // Texture determination rules:
            // 1. dough is simple: first itemstack must be dough, take from attributes
            // 2. pie allows 4 items as fillings, but with specific mixing rules
            //    - berries/fruit can be mixed
            //    - vegetables can be mixed
            //    - meat can be mixed
            // no other mixing allowed

            // Thus we deduce: It's enough to test if
            // a) all 4 fillings are equal: Then use texture from inPieProperties from first one
            // b) Otherwise use hardcoded
            //    for item.NutritionProps.FoodCategory == Vegetable   => block/food/pie/fill-mixedvegetable.png
            //    for item.NutritionProps.FoodCategory == Protein   => block/food/pie/fill-mixedmeat.png
            //    for item.NutritionProps.FoodCategory == Fruit   => block/food/pie/fill-mixedfruit.png

            var stackprops = contentStacks.Select(stack => stack?.ItemAttributes?["inPieProperties"]?.AsObject <InPieProperties>(null, stack.Collectible.Code.Domain)).ToArray();

            int bakeLevel = pieStack.Attributes.GetInt("bakeLevel", 0);

            if (stackprops.Length == 0)
            {
                return(null);
            }


            ItemStack cstack = contentStacks[1];
            bool      equal  = true;

            for (int i = 2; equal && i < contentStacks.Length - 1; i++)
            {
                if (contentStacks[i] == null || cstack == null)
                {
                    continue;
                }

                equal &= cstack.Equals(capi.World, contentStacks[i], GlobalConstants.IgnoredStackAttributes);
                cstack = contentStacks[i];
            }


            if (ContentsRotten(contentStacks))
            {
                crustTextureLoc    = new AssetLocation("block/rot/rot");
                fillingTextureLoc  = new AssetLocation("block/rot/rot");
                topCrustTextureLoc = new AssetLocation("block/rot/rot");
            }
            else
            {
                if (stackprops[0] != null)
                {
                    crustTextureLoc      = stackprops[0].Texture.Clone();
                    crustTextureLoc.Path = crustTextureLoc.Path.Replace("{bakelevel}", "" + (bakeLevel + 1));
                    fillingTextureLoc    = new AssetLocation("block/transparent");
                }

                topCrustTextureLoc = new AssetLocation("block/transparent");
                if (stackprops[5] != null)
                {
                    topCrustTextureLoc      = stackprops[5].Texture.Clone();
                    topCrustTextureLoc.Path = topCrustTextureLoc.Path.Replace("{bakelevel}", "" + (bakeLevel + 1));
                }

                if (contentStacks[1] != null)
                {
                    EnumFoodCategory fillingFoodCat =
                        contentStacks[1].Collectible.NutritionProps?.FoodCategory
                        ?? contentStacks[1].ItemAttributes?["nutritionPropsWhenInMeal"]?.AsObject <FoodNutritionProperties>()?.FoodCategory
                        ?? EnumFoodCategory.Vegetable
                    ;

                    fillingTextureLoc = equal ? stackprops[1]?.Texture : pieMixedFillingTextures[(int)fillingFoodCat];
                }
            }


            int  fillLevel  = (contentStacks[1] != null ? 1 : 0) + (contentStacks[2] != null ? 1 : 0) + (contentStacks[3] != null ? 1 : 0) + (contentStacks[4] != null ? 1 : 0);
            bool isComplete = fillLevel == 4;

            AssetLocation shapeloc = isComplete ? pieShapeBySize[pieSize - 1] : pieShapeLocByFillLevel[fillLevel];

            shapeloc.WithPathAppendixOnce(".json").WithPathPrefixOnce("shapes/");
            Shape    shape = capi.Assets.TryGet(shapeloc).ToObject <Shape>();
            MeshData mesh;

            int topCrustType = pieStack.Attributes.GetInt("topCrustType");

            string[] topCrusts         = new string[] { "origin/base/top crust full/*", "origin/base/top crust square/*", "origin/base/top crust diagonal/*" };
            string[] selectiveElements = new string[] { "origin/base/crust regular/*", "origin/base/filling/*", "origin/base/base-quarter/*", "origin/base/fillingquarter/*", topCrusts[topCrustType] };

            capi.Tesselator.TesselateShape("pie", shape, out mesh, this, null, 0, 0, 0, null, selectiveElements);
            if (transform != null)
            {
                mesh.ModelTransform(transform);
            }

            return(mesh);
        }
Esempio n. 10
0
 /// <summary>
 /// The event fired when the entity recieves saturation.
 /// </summary>
 /// <param name="saturation">The amount of saturation recieved.</param>
 /// <param name="foodCat">The category of food recieved.</param>
 /// <param name="saturationLossDelay">The delay before the loss of saturation.</param>
 public virtual void OnEntityReceiveSaturation(float saturation, EnumFoodCategory foodCat = EnumFoodCategory.Unknown, float saturationLossDelay = 10, float nutritionGainMultiplier = 1f)
 {
 }