예제 #1
0
        /// <summary>
        /// Deserializes the alloy
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="resolver"></param>
        public void FromBytes(BinaryReader reader, IWorldAccessor resolver)
        {
            Code        = reader.ReadString();
            Ingredients = new CookingRecipeIngredient[reader.ReadInt32()];

            for (int i = 0; i < Ingredients.Length; i++)
            {
                Ingredients[i] = new CookingRecipeIngredient();
                Ingredients[i].FromBytes(reader, resolver.ClassRegistry);
                Ingredients[i].Resolve(resolver, "[FromBytes]");
            }

            //NameComponentOrder = reader.ReadIntArray();

            if (!reader.ReadBoolean())
            {
                Shape = new CompositeShape()
                {
                    Base = new AssetLocation(reader.ReadString())
                };
            }

            PerishableProps = new TransitionableProperties();
            PerishableProps.FromBytes(reader, resolver.ClassRegistry);

            //     CanBeServedInto = new JsonItemStack();
            //     CanBeServedInto.FromBytes(reader, resolver.ClassRegistry);
            //     CanBeServedInto.Resolve(resolver, "[FromBytes]");
        }
예제 #2
0
        public override void DoSmelt(IWorldAccessor world, ISlotProvider cookingSlotsProvider, ItemSlot inputSlot, ItemSlot outputSlot)
        {
            ItemStack[]   stacks = GetCookingStacks(cookingSlotsProvider);
            CookingRecipe recipe = GetMatchingCookingRecipe(world, stacks);

            Block     block       = world.GetBlock(CodeWithVariant("type", "cooked"));
            ItemStack outputStack = new ItemStack(block);

            if (recipe != null)
            {
                int quantityServings = recipe.GetQuantityServings(stacks);

                for (int i = 0; i < stacks.Length; i++)
                {
                    CookingRecipeIngredient ingred = recipe.GetIngrendientFor(stacks[i]);
                    ItemStack cookedStack          = ingred.GetMatchingStack(stacks[i])?.CookedStack?.ResolvedItemstack.Clone();
                    if (cookedStack != null)
                    {
                        stacks[i] = cookedStack;
                    }
                }

                // Carry over and set perishable properties
                TransitionableProperties cookedPerishProps = recipe.PerishableProps.Clone();
                cookedPerishProps.TransitionedStack.Resolve(world, "cooking container perished stack");

                CarryOverFreshness(api, cookingSlotsProvider.Slots, stacks, cookedPerishProps);

                for (int i = 0; i < stacks.Length; i++)
                {
                    stacks[i].StackSize /= quantityServings; // whats this good for? Probably doesn't do anything meaningful
                }



                // Disabled. Let's sacrifice mergability for letting players select how meals should look and be named like
                //stacks = stacks.OrderBy(stack => stack.Collectible.Code.ToShortString()).ToArray(); // Required so that different arrangments of ingredients still create mergable meal bowls

                ((BlockCookedContainer)block).SetContents(recipe.Code, quantityServings, outputStack, stacks);

                outputStack.Collectible.SetTemperature(world, outputStack, GetIngredientsTemperature(world, stacks));
                outputSlot.Itemstack = outputStack;
                inputSlot.Itemstack  = null;

                for (int i = 0; i < cookingSlotsProvider.Slots.Length; i++)
                {
                    cookingSlotsProvider.Slots[i].Itemstack = null;
                }
                return;
            }
        }
예제 #3
0
        /// <summary>
        /// Creates a deep copy of this object
        /// </summary>
        /// <returns></returns>
        public CookingRecipeIngredient Clone()
        {
            CookingRecipeIngredient ingredient = new CookingRecipeIngredient()
            {
                Code              = Code,
                MinQuantity       = MinQuantity,
                MaxQuantity       = MaxQuantity,
                PortionSizeLitres = PortionSizeLitres
            };

            ingredient.ValidStacks = new CookingRecipeStack[ValidStacks.Length];
            for (int i = 0; i < ValidStacks.Length; i++)
            {
                ingredient.ValidStacks[i] = ValidStacks[i].Clone();
            }

            return(ingredient);
        }
예제 #4
0
        public bool Matches(ItemStack[] inputStacks, ref int quantityServings)
        {
            List <ItemStack> inputStacksList = new List <ItemStack>(inputStacks);
            List <CookingRecipeIngredient> ingredientList = new List <CookingRecipeIngredient>(Ingredients);

            int totalOutputQuantity = 99999;

            int[] curQuantities = new int[ingredientList.Count];
            for (int i = 0; i < curQuantities.Length; i++)
            {
                curQuantities[i] = 0;
            }

            while (inputStacksList.Count > 0)
            {
                ItemStack inputStack = inputStacksList[0];
                inputStacksList.RemoveAt(0);
                if (inputStack == null)
                {
                    continue;
                }

                bool found = false;
                for (int i = 0; i < ingredientList.Count; i++)
                {
                    CookingRecipeIngredient ingred = ingredientList[i];

                    if (ingred.Matches(inputStack))
                    {
                        if (curQuantities[i] >= ingred.MaxQuantity)
                        {
                            continue;
                        }

                        totalOutputQuantity = Math.Min(totalOutputQuantity, inputStack.StackSize);
                        curQuantities[i]++;
                        found = true;
                        break;
                    }
                }

                // This input stack does not fit in this cooking recipe
                if (!found)
                {
                    return(false);
                }
            }

            // Any required ingredients left?
            for (int i = 0; i < ingredientList.Count; i++)
            {
                if (curQuantities[i] < ingredientList[i].MinQuantity)
                {
                    return(false);
                }
            }

            quantityServings = totalOutputQuantity;

            // Too many ingredients?
            for (int i = 0; i < inputStacks.Length; i++)
            {
                var stack = inputStacks[i];
                if (stack == null)
                {
                    continue;
                }

                int qportions = stack.StackSize;

                if (stack.Collectible.Attributes?["waterTightContainerProps"].Exists == true)
                {
                    var props = BlockLiquidContainerBase.GetContainableProps(stack);
                    qportions = (int)(stack.StackSize / props.ItemsPerLitre / GetIngrendientFor(stack).PortionSizeLitres);
                }

                if (qportions != quantityServings)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #5
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());
        }
예제 #6
0
        public MeshData GenFoodMixMesh(ItemStack[] contentStacks, CookingRecipe recipe, Vec3f foodTranslate)
        {
            MeshData          mergedmesh = null;
            MealTextureSource texSource  = new MealTextureSource(capi, textureSourceBlock);

            Shape shape = capi.Assets.TryGet("shapes/" + recipe.Shape.Base.Path + ".json").ToObject <Shape>();
            Dictionary <CookingRecipeIngredient, int> usedIngredQuantities = new Dictionary <CookingRecipeIngredient, int>();

            for (int i = 0; i < contentStacks.Length; i++)
            {
                texSource.ForStack = contentStacks[i];
                CookingRecipeIngredient ingred = recipe.GetIngrendientFor(
                    contentStacks[i],
                    usedIngredQuantities.Where(val => val.Key.MaxQuantity <= val.Value).Select(val => val.Key).ToArray()
                    );

                if (ingred == null)
                {
                    ingred = recipe.GetIngrendientFor(contentStacks[i]);
                }
                else
                {
                    int cnt = 0;
                    usedIngredQuantities.TryGetValue(ingred, out cnt);
                    cnt++;
                    usedIngredQuantities[ingred] = cnt;
                }

                if (ingred == null)
                {
                    continue;
                }


                MeshData meshpart;
                string[] selectiveElements = null;

                CookingRecipeStack recipestack = ingred.GetMatchingStack(contentStacks[i]);

                if (recipestack.ShapeElement != null)
                {
                    selectiveElements = new string[] { recipestack.ShapeElement }
                }
                ;
                texSource.customTextureMapping = recipestack.TextureMapping;

                capi.Tesselator.TesselateShape(
                    "mealpart", shape, out meshpart, texSource,
                    new Vec3f(recipe.Shape.rotateX, recipe.Shape.rotateY, recipe.Shape.rotateZ), 0, 0, null, selectiveElements
                    );

                if (mergedmesh == null)
                {
                    mergedmesh = meshpart;
                }
                else
                {
                    mergedmesh.AddMeshData(meshpart);
                }
            }

            if (foodTranslate != null)
            {
                mergedmesh.Translate(foodTranslate);
            }

            return(mergedmesh);
        }
예제 #7
0
        public MeshData GenFoodMixMesh(ItemStack[] contentStacks, CookingRecipe recipe, Vec3f foodTranslate)
        {
            MeshData          mergedmesh = null;
            MealTextureSource texSource  = new MealTextureSource(capi, mealtextureSourceBlock);

            var shapePath = recipe.Shape.Base.Clone().WithPathPrefixOnce("shapes/").WithPathAppendixOnce(".json");

            bool rotten = ContentsRotten(contentStacks);

            if (rotten)
            {
                shapePath = new AssetLocation("shapes/block/food/meal/rot.json");
            }

            Shape shape = capi.Assets.TryGet(shapePath).ToObject <Shape>();
            Dictionary <CookingRecipeIngredient, int> usedIngredQuantities = new Dictionary <CookingRecipeIngredient, int>();

            if (rotten)
            {
                capi.Tesselator.TesselateShape(
                    "mealpart", shape, out mergedmesh, texSource,
                    new Vec3f(recipe.Shape.rotateX, recipe.Shape.rotateY, recipe.Shape.rotateZ)
                    );
            }
            else
            {
                HashSet <string> drawnMeshes = new HashSet <string>();

                for (int i = 0; i < contentStacks.Length; i++)
                {
                    texSource.ForStack = contentStacks[i];
                    CookingRecipeIngredient ingred = recipe.GetIngrendientFor(
                        contentStacks[i],
                        usedIngredQuantities.Where(val => val.Key.MaxQuantity <= val.Value).Select(val => val.Key).ToArray()
                        );

                    if (ingred == null)
                    {
                        ingred = recipe.GetIngrendientFor(contentStacks[i]);
                    }
                    else
                    {
                        int cnt = 0;
                        usedIngredQuantities.TryGetValue(ingred, out cnt);
                        cnt++;
                        usedIngredQuantities[ingred] = cnt;
                    }

                    if (ingred == null)
                    {
                        continue;
                    }


                    MeshData meshpart;
                    string[] selectiveElements = null;

                    CookingRecipeStack recipestack = ingred.GetMatchingStack(contentStacks[i]);

                    if (recipestack.ShapeElement != null)
                    {
                        selectiveElements = new string[] { recipestack.ShapeElement }
                    }
                    ;
                    texSource.customTextureMapping = recipestack.TextureMapping;

                    if (drawnMeshes.Contains(recipestack.ShapeElement + recipestack.TextureMapping))
                    {
                        continue;
                    }
                    drawnMeshes.Add(recipestack.ShapeElement + recipestack.TextureMapping);

                    capi.Tesselator.TesselateShape(
                        "mealpart", shape, out meshpart, texSource,
                        new Vec3f(recipe.Shape.rotateX, recipe.Shape.rotateY, recipe.Shape.rotateZ), 0, 0, 0, null, selectiveElements
                        );

                    if (mergedmesh == null)
                    {
                        mergedmesh = meshpart;
                    }
                    else
                    {
                        mergedmesh.AddMeshData(meshpart);
                    }
                }
            }


            if (foodTranslate != null && mergedmesh != null)
            {
                mergedmesh.Translate(foodTranslate);
            }

            return(mergedmesh);
        }