From 4c219e2a1206225cff4b34669c00106b1c312991 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 1 Sep 2018 11:04:48 +1000 Subject: [PATCH] Expand Recipe API to allow multiple Materials per slot --- nms-patches/ShapedRecipes.patch | 17 ++++++++++++----- nms-patches/ShapelessRecipes.patch | 17 ++++++++++++----- .../craftbukkit/inventory/CraftRecipe.java | 11 +++++++++++ .../inventory/CraftShapedRecipe.java | 12 ++++++------ .../inventory/CraftShapelessRecipe.java | 10 +++++----- 5 files changed, 46 insertions(+), 21 deletions(-) diff --git a/nms-patches/ShapedRecipes.patch b/nms-patches/ShapedRecipes.patch index e13670426a..519a9f3523 100644 --- a/nms-patches/ShapedRecipes.patch +++ b/nms-patches/ShapedRecipes.patch @@ -1,17 +1,20 @@ --- a/net/minecraft/server/ShapedRecipes.java +++ b/net/minecraft/server/ShapedRecipes.java -@@ -13,6 +13,10 @@ +@@ -13,6 +13,13 @@ import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; +// CraftBukkit start ++import java.util.ArrayList; ++import java.util.List; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.inventory.CraftShapedRecipe; ++import org.bukkit.craftbukkit.util.CraftMagicNumbers; +// CraftBukkit end public class ShapedRecipes implements IRecipe { -@@ -32,6 +36,66 @@ +@@ -32,6 +39,70 @@ this.result = itemstack; } @@ -66,8 +69,12 @@ + for (RecipeItemStack list : this.items) { + list.buildChoices(); + if (list.choices.length > 0) { -+ net.minecraft.server.ItemStack stack = list.choices[0]; -+ recipe.setIngredient(c, org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(stack.getItem()), (list.choices.length) > 1 ? 32767 : 0); ++ List choices = new ArrayList<>(list.choices.length); ++ for (ItemStack i : list.choices) { ++ choices.add(CraftMagicNumbers.getMaterial(i.getItem())); ++ } ++ ++ recipe.setIngredient(c, new org.bukkit.inventory.RecipeChoice.MaterialChoice(choices)); + } + c++; + } @@ -78,7 +85,7 @@ public MinecraftKey getKey() { return this.key; } -@@ -302,11 +366,11 @@ +@@ -302,11 +373,11 @@ packetdataserializer.a(shapedrecipes.result); } diff --git a/nms-patches/ShapelessRecipes.patch b/nms-patches/ShapelessRecipes.patch index 0723cdf14d..8b7e92dd68 100644 --- a/nms-patches/ShapelessRecipes.patch +++ b/nms-patches/ShapelessRecipes.patch @@ -1,17 +1,20 @@ --- a/net/minecraft/server/ShapelessRecipes.java +++ b/net/minecraft/server/ShapelessRecipes.java -@@ -5,6 +5,10 @@ +@@ -5,6 +5,13 @@ import com.google.gson.JsonParseException; import it.unimi.dsi.fastutil.ints.IntList; import java.util.Iterator; +// CraftBukkit start ++import java.util.ArrayList; ++import java.util.List; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe; ++import org.bukkit.craftbukkit.util.CraftMagicNumbers; +// CraftBukkit end public class ShapelessRecipes implements IRecipe { -@@ -20,6 +24,22 @@ +@@ -20,6 +27,26 @@ this.ingredients = nonnulllist; } @@ -24,8 +27,12 @@ + + for (RecipeItemStack list : this.ingredients) { + list.buildChoices(); -+ net.minecraft.server.ItemStack stack = list.choices[0]; -+ recipe.addIngredient(org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(stack.getItem()), (list.choices.length) > 1 ? 32767 : 0); ++ ++ List choices = new ArrayList<>(list.choices.length); ++ for (ItemStack i : list.choices) { ++ choices.add(CraftMagicNumbers.getMaterial(i.getItem())); ++ } ++ recipe.addIngredient(new org.bukkit.inventory.RecipeChoice.MaterialChoice(choices)); + } + return recipe; + } @@ -34,7 +41,7 @@ public MinecraftKey getKey() { return this.key; } -@@ -127,11 +147,11 @@ +@@ -127,11 +154,11 @@ packetdataserializer.a(shapelessrecipes.result); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java index d3e03e2476..eec606b226 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java @@ -1,7 +1,18 @@ package org.bukkit.craftbukkit.inventory; +import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; +import org.bukkit.inventory.RecipeChoice; public interface CraftRecipe extends Recipe { + void addToCraftingManager(); + + default net.minecraft.server.RecipeItemStack toNMS(RecipeChoice bukkit) { + if (bukkit instanceof RecipeChoice.MaterialChoice) { + return new net.minecraft.server.RecipeItemStack(((RecipeChoice.MaterialChoice) bukkit).getChoices().stream().map((mat) -> new net.minecraft.server.RecipeItemStack.StackProvider(CraftItemStack.asNMSCopy(new ItemStack(mat))))); + } else { + throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit); + } + } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapedRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapedRecipe.java index f83593cb07..9e313cc418 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapedRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapedRecipe.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.inventory; import java.util.Map; -import java.util.stream.Stream; import net.minecraft.server.MinecraftServer; import net.minecraft.server.NonNullList; @@ -11,6 +10,7 @@ import net.minecraft.server.ShapedRecipes; import org.bukkit.NamespacedKey; import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.RecipeChoice; import org.bukkit.inventory.ShapedRecipe; public class CraftShapedRecipe extends ShapedRecipe implements CraftRecipe { @@ -34,11 +34,11 @@ public class CraftShapedRecipe extends ShapedRecipe implements CraftRecipe { ret.setGroup(recipe.getGroup()); String[] shape = recipe.getShape(); ret.shape(shape); - Map ingredientMap = recipe.getIngredientMap(); + Map ingredientMap = recipe.getChoiceMap(); for (char c : ingredientMap.keySet()) { - ItemStack stack = ingredientMap.get(c); + RecipeChoice stack = ingredientMap.get(c); if (stack != null) { - ret.setIngredient(c, stack.getType(), stack.getDurability()); + ret.setIngredient(c, stack); } } return ret; @@ -46,14 +46,14 @@ public class CraftShapedRecipe extends ShapedRecipe implements CraftRecipe { public void addToCraftingManager() { String[] shape = this.getShape(); - Map ingred = this.getIngredientMap(); + Map ingred = this.getChoiceMap(); int width = shape[0].length(); NonNullList data = NonNullList.a(shape.length * width, RecipeItemStack.a); for (int i = 0; i < shape.length; i++) { String row = shape[i]; for (int j = 0; j < row.length(); j++) { - data.set(i * width + j, new RecipeItemStack(Stream.of(new RecipeItemStack.StackProvider(CraftItemStack.asNMSCopy(ingred.get(row.charAt(j))))))); + data.set(i * width + j, toNMS(ingred.get(row.charAt(j)))); } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java index 28582da137..8e3446fc3c 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.inventory; import java.util.List; -import java.util.stream.Stream; import net.minecraft.server.MinecraftServer; import net.minecraft.server.NonNullList; @@ -11,6 +10,7 @@ import net.minecraft.server.ShapelessRecipes; import org.bukkit.NamespacedKey; import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.RecipeChoice; import org.bukkit.inventory.ShapelessRecipe; public class CraftShapelessRecipe extends ShapelessRecipe implements CraftRecipe { @@ -32,17 +32,17 @@ public class CraftShapelessRecipe extends ShapelessRecipe implements CraftRecipe } CraftShapelessRecipe ret = new CraftShapelessRecipe(recipe.getKey(), recipe.getResult()); ret.setGroup(recipe.getGroup()); - for (ItemStack ingred : recipe.getIngredientList()) { - ret.addIngredient(ingred.getType(), ingred.getDurability()); + for (RecipeChoice ingred : recipe.getChoiceList()) { + ret.addIngredient(ingred); } return ret; } public void addToCraftingManager() { - List ingred = this.getIngredientList(); + List ingred = this.getChoiceList(); NonNullList data = NonNullList.a(ingred.size(), RecipeItemStack.a); for (int i = 0; i < ingred.size(); i++) { - data.set(i, new RecipeItemStack(Stream.of(new RecipeItemStack.StackProvider(CraftItemStack.asNMSCopy(ingred.get(i)))))); + data.set(i, toNMS(ingred.get(i))); } MinecraftServer.getServer().getCraftingManager().a(new ShapelessRecipes(CraftNamespacedKey.toMinecraft(this.getKey()), this.getGroup(), CraftItemStack.asNMSCopy(this.getResult()), data));