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; } }
/// <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()); }
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); }
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); }