From 756c38d1e41620427696b20415b27174d392910d Mon Sep 17 00:00:00 2001 From: md_5 <git@md-5.net> Date: Wed, 2 Jan 2019 15:56:21 +1100 Subject: [PATCH] Add RecipeChoice.ExactChoice API for NBT matches on ingredients --- nms-patches/FurnaceRecipe.patch | 13 ++------ nms-patches/RecipeItemStack.patch | 26 ++++++++++++++++ nms-patches/ShapedRecipes.patch | 18 +++++------ nms-patches/ShapelessRecipes.patch | 16 +++------- .../craftbukkit/inventory/CraftRecipe.java | 30 +++++++++++++++++++ 5 files changed, 71 insertions(+), 32 deletions(-) create mode 100644 nms-patches/RecipeItemStack.patch diff --git a/nms-patches/FurnaceRecipe.patch b/nms-patches/FurnaceRecipe.patch index ef5091f17e..e9b367f873 100644 --- a/nms-patches/FurnaceRecipe.patch +++ b/nms-patches/FurnaceRecipe.patch @@ -9,30 +9,23 @@ +import java.util.List; +import org.bukkit.craftbukkit.inventory.CraftFurnaceRecipe; +import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.inventory.CraftRecipe; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.inventory.Recipe; -+import org.bukkit.inventory.RecipeChoice; +// CraftBukkit end public class FurnaceRecipe implements IRecipe { -@@ -56,6 +66,23 @@ +@@ -56,6 +66,16 @@ return this.key; } + @Override + public Recipe toBukkitRecipe() { + CraftItemStack result = CraftItemStack.asCraftMirror(this.result); -+ RecipeItemStack list = this.ingredient; -+ list.buildChoices(); + -+ List<org.bukkit.Material> choices = new ArrayList<>(list.choices.length); -+ for (ItemStack i : list.choices) { -+ choices.add(CraftMagicNumbers.getMaterial(i.getItem())); -+ } -+ -+ CraftFurnaceRecipe recipe = new CraftFurnaceRecipe(CraftNamespacedKey.fromMinecraft(this.key), result, new RecipeChoice.MaterialChoice(choices), this.experience, this.cookingTime); ++ CraftFurnaceRecipe recipe = new CraftFurnaceRecipe(CraftNamespacedKey.fromMinecraft(this.key), result, CraftRecipe.toBukkit(this.ingredient), this.experience, this.cookingTime); + recipe.setGroup(this.group); + + return recipe; diff --git a/nms-patches/RecipeItemStack.patch b/nms-patches/RecipeItemStack.patch new file mode 100644 index 0000000000..e70da7f459 --- /dev/null +++ b/nms-patches/RecipeItemStack.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/server/RecipeItemStack.java ++++ b/net/minecraft/server/RecipeItemStack.java +@@ -28,6 +28,7 @@ + private final RecipeItemStack.Provider[] c; + public ItemStack[] choices; + private IntList e; ++ public boolean exact; // CraftBukkit + + public RecipeItemStack(Stream<? extends RecipeItemStack.Provider> stream) { + this.c = (RecipeItemStack.Provider[]) stream.filter(RecipeItemStack.b).toArray((i) -> { +@@ -59,6 +60,15 @@ + for (int j = 0; j < i; ++j) { + ItemStack itemstack1 = aitemstack[j]; + ++ // CraftBukkit start ++ if (exact) { ++ if (ItemStack.equals(itemstack, itemstack1)) { ++ return true; ++ } ++ ++ continue; ++ } ++ // CraftBukkit end + if (itemstack1.getItem() == itemstack.getItem()) { + return true; + } diff --git a/nms-patches/ShapedRecipes.patch b/nms-patches/ShapedRecipes.patch index b2b1e08087..1ec2b7d366 100644 --- a/nms-patches/ShapedRecipes.patch +++ b/nms-patches/ShapedRecipes.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/ShapedRecipes.java +++ b/net/minecraft/server/ShapedRecipes.java -@@ -12,6 +12,13 @@ +@@ -12,6 +12,15 @@ import java.util.Map; import java.util.Set; import java.util.Map.Entry; @@ -8,13 +8,15 @@ +import java.util.ArrayList; +import java.util.List; +import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.inventory.CraftRecipe; +import org.bukkit.craftbukkit.inventory.CraftShapedRecipe; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; ++import org.bukkit.inventory.RecipeChoice; +// CraftBukkit end public class ShapedRecipes implements IRecipe { -@@ -31,6 +38,70 @@ +@@ -31,6 +40,66 @@ this.result = itemstack; } @@ -67,15 +69,11 @@ + } + char c = 'a'; + for (RecipeItemStack list : this.items) { -+ list.buildChoices(); -+ if (list.choices.length > 0) { -+ List<org.bukkit.Material> 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)); ++ RecipeChoice choice = CraftRecipe.toBukkit(list); ++ if (choice != null) { ++ recipe.setIngredient(c, choice); + } ++ + c++; + } + return recipe; diff --git a/nms-patches/ShapelessRecipes.patch b/nms-patches/ShapelessRecipes.patch index 9e7a932a40..dfc03324a7 100644 --- a/nms-patches/ShapelessRecipes.patch +++ b/nms-patches/ShapelessRecipes.patch @@ -1,20 +1,18 @@ --- a/net/minecraft/server/ShapelessRecipes.java +++ b/net/minecraft/server/ShapelessRecipes.java -@@ -5,6 +5,13 @@ +@@ -5,6 +5,11 @@ 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.CraftRecipe; +import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe; -+import org.bukkit.craftbukkit.util.CraftMagicNumbers; +// CraftBukkit end public class ShapelessRecipes implements IRecipe { -@@ -20,6 +27,26 @@ +@@ -20,6 +25,20 @@ this.ingredients = nonnulllist; } @@ -26,13 +24,7 @@ + recipe.setGroup(this.group); + + for (RecipeItemStack list : this.ingredients) { -+ list.buildChoices(); -+ -+ List<org.bukkit.Material> 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)); ++ recipe.addIngredient(CraftRecipe.toBukkit(list)); + } + return recipe; + } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java index 3a704d1070..3309f32691 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java @@ -1,6 +1,11 @@ package org.bukkit.craftbukkit.inventory; +import com.google.common.base.Preconditions; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; import net.minecraft.server.RecipeItemStack; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; import org.bukkit.inventory.RecipeChoice; @@ -14,8 +19,33 @@ public interface CraftRecipe extends Recipe { return RecipeItemStack.a; } else if (bukkit instanceof RecipeChoice.MaterialChoice) { return new RecipeItemStack(((RecipeChoice.MaterialChoice) bukkit).getChoices().stream().map((mat) -> new net.minecraft.server.RecipeItemStack.StackProvider(CraftItemStack.asNMSCopy(new ItemStack(mat))))); + } else if (bukkit instanceof RecipeChoice.ExactChoice) { + RecipeItemStack stack = new RecipeItemStack(Stream.of(new net.minecraft.server.RecipeItemStack.StackProvider(CraftItemStack.asNMSCopy(((RecipeChoice.ExactChoice) bukkit).getItemStack())))); + stack.exact = true; + + return stack; } else { throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit); } } + + public static RecipeChoice toBukkit(RecipeItemStack list) { + list.buildChoices(); + + if (list.choices.length == 0) { + return null; + } + + if (list.exact) { + Preconditions.checkState(list.choices.length == 1, "Exact recipe must have 1 choice"); + return new RecipeChoice.ExactChoice(CraftItemStack.asBukkitCopy(list.choices[0])); + } + + List<org.bukkit.Material> choices = new ArrayList<>(list.choices.length); + for (net.minecraft.server.ItemStack i : list.choices) { + choices.add(CraftMagicNumbers.getMaterial(i.getItem())); + } + + return new RecipeChoice.MaterialChoice(choices); + } }