diff --git a/patches/api/0462-Adding-PredicateChoice-to-Paper-API.patch b/patches/api/0462-Adding-PredicateChoice-to-Paper-API.patch deleted file mode 100644 index b29a15784e..0000000000 --- a/patches/api/0462-Adding-PredicateChoice-to-Paper-API.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: derverdox -Date: Mon, 4 Dec 2023 01:54:38 +0100 -Subject: [PATCH] Adding PredicateChoice to Paper API - - -diff --git a/src/main/java/org/bukkit/inventory/RecipeChoice.java b/src/main/java/org/bukkit/inventory/RecipeChoice.java -index 523818cbb0d6c90481ec97123e7fe0e2ff4eea14..6b9bbead57166d7622cf31b96c252d56fafc05fb 100644 ---- a/src/main/java/org/bukkit/inventory/RecipeChoice.java -+++ b/src/main/java/org/bukkit/inventory/RecipeChoice.java -@@ -233,4 +233,64 @@ public interface RecipeChoice extends Predicate, Cloneable { - return "ExactChoice{" + "choices=" + choices + '}'; - } - } -+ -+ /** -+ * Represents a choice that matches when the item predicate is fulfilled. -+ */ -+ public static class PredicateChoice implements RecipeChoice { -+ private final ItemPredicate itemPredicate; -+ -+ public PredicateChoice(ItemPredicate itemPredicate) { -+ Preconditions.checkArgument(itemPredicate != null, "itemPredicate"); -+ Preconditions.checkArgument(!itemPredicate.recipeBookExamples().isEmpty(), "Must have at least one template"); -+ this.itemPredicate = itemPredicate; -+ } -+ -+ @Override -+ public final boolean test(final ItemStack stack) { -+ return itemPredicate.test(stack); -+ } -+ -+ @Override -+ public @NotNull ItemStack getItemStack() { -+ ItemStack stack = new ItemStack(itemPredicate.recipeBookExamples().get(0)); -+ // For compat -+ if (itemPredicate.recipeBookExamples().size() > 1) { -+ stack.setDurability(Short.MAX_VALUE); -+ } -+ -+ return stack; -+ } -+ -+ @Override -+ public PredicateChoice clone() { -+ return new PredicateChoice(new ItemPredicate() { -+ @Override -+ public List recipeBookExamples() { -+ return List.copyOf(itemPredicate.recipeBookExamples()); -+ } -+ -+ @Override -+ public boolean test(final ItemStack stack) { -+ return itemPredicate.test(stack); -+ } -+ }); -+ } -+ -+ public ItemPredicate getItemPredicate() { -+ return itemPredicate; -+ } -+ -+ @Override -+ public boolean equals(final Object o) { -+ if (this == o) return true; -+ if (o == null || getClass() != o.getClass()) return false; -+ PredicateChoice that = (PredicateChoice) o; -+ return Objects.equals(itemPredicate, that.itemPredicate); -+ } -+ -+ public static interface ItemPredicate extends Predicate { -+ List recipeBookExamples(); -+ } -+ } - } diff --git a/patches/api/0469-Adding-PredicateChoice.patch b/patches/api/0469-Adding-PredicateChoice.patch new file mode 100644 index 0000000000..270a2f57d3 --- /dev/null +++ b/patches/api/0469-Adding-PredicateChoice.patch @@ -0,0 +1,94 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: derverdox +Date: Thu, 21 Mar 2024 16:54:14 +0100 +Subject: [PATCH] - Adding PredicateChoice + + +diff --git a/src/main/java/org/bukkit/inventory/PredicateChoiceImpl.java b/src/main/java/org/bukkit/inventory/PredicateChoiceImpl.java +new file mode 100644 +index 0000000000000000000000000000000000000000..927917f9a875595e2ff0626cbda03a08b7e6e166 +--- /dev/null ++++ b/src/main/java/org/bukkit/inventory/PredicateChoiceImpl.java +@@ -0,0 +1,38 @@ ++package org.bukkit.inventory; ++ ++import org.jetbrains.annotations.NotNull; ++import java.util.List; ++import java.util.function.Predicate; ++ ++/** ++ * Package private implementation for {@link org.bukkit.inventory.RecipeChoice.PredicateChoice} ++ * @param predicate - The Item predicate ++ * @param choices - The recipe book choices ++ */ ++record PredicateChoiceImpl(Predicate predicate, List choices) implements RecipeChoice.PredicateChoice { ++ @Override ++ public @NotNull ItemStack getItemStack() { ++ ItemStack stack = new ItemStack(choices.get(0)); ++ // For compat ++ if (choices.size() > 1) { ++ stack.setDurability(Short.MAX_VALUE); ++ return stack; ++ } ++ return stack; ++ } ++ ++ @Override ++ public @NotNull RecipeChoice clone() { ++ return new PredicateChoiceImpl(predicate, recipeBookExamples()); ++ } ++ ++ @Override ++ public boolean test(@NotNull final ItemStack itemStack) { ++ return predicate.test(itemStack); ++ } ++ ++ @Override ++ public List recipeBookExamples() { ++ return List.copyOf(choices); ++ } ++} +diff --git a/src/main/java/org/bukkit/inventory/RecipeChoice.java b/src/main/java/org/bukkit/inventory/RecipeChoice.java +index db8bcc66bdc4bedfffb4705db6338eda4c0ad29a..e331040030c484ad63444a0ee4e42790d639115e 100644 +--- a/src/main/java/org/bukkit/inventory/RecipeChoice.java ++++ b/src/main/java/org/bukkit/inventory/RecipeChoice.java +@@ -233,4 +233,39 @@ public interface RecipeChoice extends Predicate, Cloneable { + return "ExactChoice{" + "choices=" + choices + '}'; + } + } ++ // Paper start - Adding PredicateChoice ++ /** ++ * Represents a choice that matches when the item predicate is fulfilled. ++ */ ++ ++ interface PredicateChoice extends RecipeChoice { ++ static PredicateChoice create(@NotNull Predicate predicate, ItemStack... recipeBookExamples){ ++ Objects.requireNonNull(predicate, "The item predicate cannot be null!"); ++ Objects.requireNonNull(predicate, "The mustHaveRecipeBookExample cannot be null!"); ++ if(recipeBookExamples.length == 0) ++ throw new IllegalArgumentException("Please provide at least one recipe book example item!"); ++ return new PredicateChoiceImpl(predicate, List.of(recipeBookExamples)); ++ } ++ ++ static PredicateChoice create(@NotNull Predicate predicate, java.util.Collection recipeBookExamples){ ++ Objects.requireNonNull(predicate, "The item predicate cannot be null!"); ++ Objects.requireNonNull(predicate, "The mustHaveRecipeBookExample cannot be null!"); ++ if(recipeBookExamples.isEmpty()) ++ throw new IllegalArgumentException("Please provide at least one recipe book example item!"); ++ return new PredicateChoiceImpl(predicate, List.copyOf(recipeBookExamples)); ++ } ++ ++ /** ++ * Returns the Item predicate ++ * @return - The item predicate ++ */ ++ Predicate predicate(); ++ ++ /** ++ * ++ * @return ++ */ ++ List recipeBookExamples(); ++ } ++ // Paper end - Adding PredicateChoice + } diff --git a/patches/server/1056-Adding-PredicateChoice-to-Paper-API.patch b/patches/server/1056-Adding-PredicateChoice.patch similarity index 58% rename from patches/server/1056-Adding-PredicateChoice-to-Paper-API.patch rename to patches/server/1056-Adding-PredicateChoice.patch index c84359246a..de1dce9621 100644 --- a/patches/server/1056-Adding-PredicateChoice-to-Paper-API.patch +++ b/patches/server/1056-Adding-PredicateChoice.patch @@ -1,11 +1,11 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: derverdox -Date: Mon, 4 Dec 2023 01:54:37 +0100 -Subject: [PATCH] Adding PredicateChoice to Paper API +Date: Thu, 21 Mar 2024 16:54:14 +0100 +Subject: [PATCH] - Adding PredicateChoice diff --git a/src/main/java/io/papermc/paper/inventory/recipe/RecipeBookExactChoiceRecipe.java b/src/main/java/io/papermc/paper/inventory/recipe/RecipeBookExactChoiceRecipe.java -index 2a2f8327a5bd3983a3a13fd663beb98906f27312..a4b4d8fe73a5d626906ed859abbdee9591263645 100644 +index 2a2f8327a5bd3983a3a13fd663beb98906f27312..684cbfa8d93dc9af8c3442c0ba4ac81f27899af1 100644 --- a/src/main/java/io/papermc/paper/inventory/recipe/RecipeBookExactChoiceRecipe.java +++ b/src/main/java/io/papermc/paper/inventory/recipe/RecipeBookExactChoiceRecipe.java @@ -6,25 +6,28 @@ import net.minecraft.world.item.crafting.Recipe; @@ -13,137 +13,107 @@ index 2a2f8327a5bd3983a3a13fd663beb98906f27312..a4b4d8fe73a5d626906ed859abbdee95 public abstract class RecipeBookExactChoiceRecipe implements Recipe { - private boolean hasExactIngredients; -+ private boolean hasSpecialIngredients; ++ private boolean hasSpecialIngredients; // Paper - Adding PredicateChoice protected final void checkExactIngredients() { // skip any special recipes if (this.isSpecial()) { - this.hasExactIngredients = false; -+ this.hasSpecialIngredients = false; ++ this.hasSpecialIngredients = false; // Paper - Adding PredicateChoice return; } for (final Ingredient ingredient : this.getIngredients()) { - if (!ingredient.isEmpty() && ingredient.exact) { +- if (!ingredient.isEmpty() && ingredient.exact) { - this.hasExactIngredients = true; ++ // Paper start - Adding PredicateChoice ++ if (!ingredient.isEmpty() && (ingredient.exact || ingredient.itemPredicate != null)) { + this.hasSpecialIngredients = true; -+ return; -+ } else if (!ingredient.isEmpty() && ingredient.getItemPredicate() != null) { -+ this.hasSpecialIngredients = true; ++ // Paper end - Adding PredicateChoice return; } } - this.hasExactIngredients = false; -+ this.hasSpecialIngredients = false; ++ this.hasSpecialIngredients = false; // Paper - Adding PredicateChoice } @Override - public final boolean hasExactIngredients() { - return this.hasExactIngredients; +- } ++ // Paper start - Adding PredicateChoice + public final boolean hasSpecialIngredients() { + return this.hasSpecialIngredients; - } ++ } // Paper end - Adding PredicateChoice } diff --git a/src/main/java/io/papermc/paper/inventory/recipe/StackedContentsExtraMap.java b/src/main/java/io/papermc/paper/inventory/recipe/StackedContentsExtraMap.java -index 63db0b843c5bd11f979e613ba6cfac9d9da956bb..63a161ca3c228263d71d2da86b92970a13d28181 100644 +index 63db0b843c5bd11f979e613ba6cfac9d9da956bb..7c4780ab634a06ca3a362356443079f5d70558aa 100644 --- a/src/main/java/io/papermc/paper/inventory/recipe/StackedContentsExtraMap.java +++ b/src/main/java/io/papermc/paper/inventory/recipe/StackedContentsExtraMap.java -@@ -7,7 +7,9 @@ import it.unimi.dsi.fastutil.ints.IntComparators; - import it.unimi.dsi.fastutil.ints.IntList; - import it.unimi.dsi.fastutil.objects.Object2IntMap; - import it.unimi.dsi.fastutil.objects.Object2IntOpenCustomHashMap; -+import java.util.ArrayList; - import java.util.IdentityHashMap; -+import java.util.List; - import java.util.Map; - import java.util.concurrent.atomic.AtomicInteger; - import net.minecraft.core.registries.BuiltInRegistries; -@@ -18,12 +20,12 @@ import net.minecraft.world.item.crafting.Ingredient; - import net.minecraft.world.item.crafting.Recipe; - - public final class StackedContentsExtraMap { -- - private final AtomicInteger idCounter = new AtomicInteger(BuiltInRegistries.ITEM.size()); // start at max vanilla stacked contents idx - private final Object2IntMap exactChoiceIds = new Object2IntOpenCustomHashMap<>(ItemStackLinkedSet.TYPE_AND_TAG); +@@ -24,6 +24,7 @@ public final class StackedContentsExtraMap { private final Int2ObjectMap idToExactChoice = new Int2ObjectOpenHashMap<>(); private final StackedContents contents; public final Map extraStackingIds = new IdentityHashMap<>(); -+ public final List predicateChoices = new ArrayList<>(); // Adding PredicateChoice ++ public final java.util.List predicateChoices = new java.util.ArrayList<>(); // Paper - Adding PredicateChoice public StackedContentsExtraMap(final StackedContents contents, final Recipe recipe) { this.exactChoiceIds.defaultReturnValue(-1); -@@ -32,7 +34,7 @@ public final class StackedContentsExtraMap { +@@ -32,7 +33,7 @@ public final class StackedContentsExtraMap { } private void initialize(final Recipe recipe) { - if (recipe.hasExactIngredients()) { -+ if (recipe.hasSpecialIngredients()) { ++ if (recipe.hasSpecialIngredients()) { // Paper - Adding PredicateChoice for (final Ingredient ingredient : recipe.getIngredients()) { if (!ingredient.isEmpty() && ingredient.exact) { final net.minecraft.world.item.ItemStack[] items = ingredient.getItems(); -@@ -47,6 +49,11 @@ public final class StackedContentsExtraMap { +@@ -47,6 +48,12 @@ public final class StackedContentsExtraMap { idList.sort(IntComparators.NATURAL_COMPARATOR); this.extraStackingIds.put(ingredient, idList); } -+ // Adding PredicateChoice -+ else if(!ingredient.isEmpty() && ingredient.getItemPredicate() != null){ ++ // Paper start - Adding PredicateChoice ++ else if (!ingredient.isEmpty() && ingredient.itemPredicate != null) { + this.predicateChoices.add(ingredient); + this.extraStackingIds.put(ingredient, new IntArrayList()); // fill id list when accounting stacks + } ++ // Paper end - Adding PredicateChoice } } } -@@ -67,6 +74,16 @@ public final class StackedContentsExtraMap { +@@ -67,6 +74,18 @@ public final class StackedContentsExtraMap { } public boolean accountStack(final ItemStack stack, final int count) { ++ // Paper start - Adding PredicateChoice + // We are adding items that pass the predicate test. -+ for(final Ingredient predicateChoice : this.predicateChoices){ -+ if(predicateChoice.test(stack)){ -+ boolean isStackTypeRegistered = this.exactChoiceIds.getInt(stack) > -1; ++ for (final Ingredient predicateChoice : this.predicateChoices) { ++ if (predicateChoice.itemPredicate != null && predicateChoice.itemPredicate.test(stack.getBukkitStack())) { + final int id = this.registerExact(stack); + // We only want to add the stacking id to the list one time -+ if(!isStackTypeRegistered) ++ if (id != -1) { + this.extraStackingIds.get(predicateChoice).add(id); ++ } + } + } ++ // Paper end - Adding PredicateChoice if (!this.exactChoiceIds.isEmpty()) { final int id = this.exactChoiceIds.getInt(stack); if (id >= 0) { diff --git a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java -index 06fe5b056d78d42cdf78437eeabe1786d596b7f8..d98201d34c5863a9c1588d64aa0e72b1529a980c 100644 +index 7c29750e534eae4266bf7a63c50e3827401d6569..6159c071cd6f104483df878b0968b5e6a17a69aa 100644 --- a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java +++ b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java -@@ -29,11 +29,14 @@ import net.minecraft.world.entity.player.StackedContents; - import net.minecraft.world.item.Item; - import net.minecraft.world.item.ItemStack; - import net.minecraft.world.level.ItemLike; -+import org.bukkit.craftbukkit.inventory.CraftItemStack; -+import org.bukkit.inventory.RecipeChoice; - - public final class Ingredient implements Predicate { - - public static final Ingredient EMPTY = new Ingredient(Stream.empty()); - private final Ingredient.Value[] values; -+ @Nullable private RecipeChoice.PredicateChoice.ItemPredicate itemPredicate; // Paper +@@ -36,9 +36,9 @@ public final class Ingredient implements Predicate { @Nullable - public ItemStack[] itemStacks; - @Nullable -@@ -41,7 +44,13 @@ public final class Ingredient implements Predicate { + private IntList stackingIds; public boolean exact; // CraftBukkit ++ @Nullable public Predicate itemPredicate; // Paper - Adding PredicateChoice public static final Codec CODEC = Ingredient.codec(true); public static final Codec CODEC_NONEMPTY = Ingredient.codec(false); - -+ // Paper start - Adding PredicateChoice -+ public Ingredient(RecipeChoice.PredicateChoice.ItemPredicate itemPredicate) { -+ List bukkitChoices = itemPredicate.recipeBookExamples(); -+ this.itemPredicate = itemPredicate; -+ this.values = bukkitChoices.stream().map(CraftItemStack::asNMSCopy).map(ItemValue::new).toArray(Value[]::new); -+ } -+ // Paper end - Adding PredicateChoice public Ingredient(Stream entries) { this.values = (Ingredient.Value[]) entries.toArray((i) -> { return new Ingredient.Value[i]; -@@ -70,6 +79,11 @@ public final class Ingredient implements Predicate { +@@ -67,6 +67,11 @@ public final class Ingredient implements Predicate { } else if (this.isEmpty()) { return itemstack.isEmpty(); } else { @@ -155,35 +125,24 @@ index 06fe5b056d78d42cdf78437eeabe1786d596b7f8..d98201d34c5863a9c1588d64aa0e72b1 ItemStack[] aitemstack = this.getItems(); int i = aitemstack.length; -@@ -269,4 +283,10 @@ public final class Ingredient implements Predicate { - return Collections.singleton(this.item); - } - } -+ // Paper start - Adding PredicateChoice -+ @Nullable -+ public RecipeChoice.PredicateChoice.ItemPredicate getItemPredicate() { -+ return itemPredicate; -+ } -+ // Paper end - Adding PredicateChoice - } diff --git a/src/main/java/net/minecraft/world/item/crafting/Recipe.java b/src/main/java/net/minecraft/world/item/crafting/Recipe.java -index 80387cd1bee2bd4c024073cee74222828f9f2c17..6fbbf255fe061943b72324d1484c7b9e885f8535 100644 +index e2d6c8ed586ef429cc712139e501df696ed10f6e..840ae57544e4f5c6e8a1bddd8cd1a09efb06625e 100644 --- a/src/main/java/net/minecraft/world/item/crafting/Recipe.java +++ b/src/main/java/net/minecraft/world/item/crafting/Recipe.java -@@ -67,7 +67,7 @@ public interface Recipe { +@@ -71,7 +71,7 @@ public interface Recipe { org.bukkit.inventory.Recipe toBukkitRecipe(org.bukkit.NamespacedKey id); // CraftBukkit // Paper start - improved exact choice recipes - default boolean hasExactIngredients() { -+ default boolean hasSpecialIngredients() { ++ default boolean hasSpecialIngredients() { // Paper start - Adding PredicateChoice return false; } // Paper end diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java -index 13d25d118eb4d3ef35a4cdfb9bbde9ed83f6c04b..8b308da84b59c04e0b80d419d4eea602f01abcbf 100644 +index 6ba29875d78ede4aa7978ff689e588f7fed11528..b2bba76d8ebc0bd8a4404c19c8dc93cbb75e3142 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java -@@ -30,7 +30,13 @@ public interface CraftRecipe extends Recipe { +@@ -29,7 +29,15 @@ public interface CraftRecipe extends Recipe { } else if (bukkit instanceof RecipeChoice.ExactChoice) { stack = new Ingredient(((RecipeChoice.ExactChoice) bukkit).getChoices().stream().map((mat) -> new net.minecraft.world.item.crafting.Ingredient.ItemValue(CraftItemStack.asNMSCopy(mat)))); stack.exact = true; @@ -191,21 +150,28 @@ index 13d25d118eb4d3ef35a4cdfb9bbde9ed83f6c04b..8b308da84b59c04e0b80d419d4eea602 + } + // Paper start - Adding PredicateChoice + else if(bukkit instanceof RecipeChoice.PredicateChoice predicateChoice){ -+ stack = new Ingredient(predicateChoice.getItemPredicate()); ++ List bukkitChoices = predicateChoice.recipeBookExamples(); ++ stack = new Ingredient(bukkitChoices.stream().map(CraftItemStack::asNMSCopy).map(Ingredient.ItemValue::new)); ++ stack.itemPredicate = predicateChoice.predicate(); + } + // Paper end - Adding PredicateChoice + else { throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit); } -@@ -48,7 +54,10 @@ public interface CraftRecipe extends Recipe { +@@ -47,7 +55,15 @@ public interface CraftRecipe extends Recipe { if (list.itemStacks.length == 0) { return null; } - + // Paper start - Adding PredicateChoice -+ if(list.getItemPredicate() != null) -+ return new RecipeChoice.PredicateChoice(list.getItemPredicate()); ++ if(list.itemPredicate != null) { ++ List choices = new ArrayList<>(list.itemStacks.length); ++ for (net.minecraft.world.item.ItemStack i : list.itemStacks) { ++ choices.add(CraftItemStack.asBukkitCopy(i)); ++ } ++ return RecipeChoice.PredicateChoice.create(list.itemPredicate, choices); ++ } + // Paper end - Adding PredicateChoice if (list.exact) { List choices = new ArrayList<>(list.itemStacks.length);