- Small code changes

- Fixed RecipeBook click not working
This commit is contained in:
derverdox 2024-03-21 16:57:10 +01:00
parent eedca5e3ab
commit 135b0d5cfa
3 changed files with 144 additions and 159 deletions

View file

@ -1,75 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: derverdox <mail.ysp@web.de>
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<ItemStack>, 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<ItemStack> 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<ItemStack> {
+ List<ItemStack> recipeBookExamples();
+ }
+ }
}

View file

@ -0,0 +1,94 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: derverdox <mail.ysp@web.de>
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<ItemStack> predicate, List<ItemStack> 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<ItemStack> 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<ItemStack>, 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<ItemStack> 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<ItemStack> predicate, java.util.Collection<ItemStack> 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<ItemStack> predicate();
+
+ /**
+ *
+ * @return
+ */
+ List<ItemStack> recipeBookExamples();
+ }
+ // Paper end - Adding PredicateChoice
}

View file

@ -1,11 +1,11 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: derverdox <mail.ysp@web.de>
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<C extends Container> implements Recipe<C> {
- 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<ItemStack> exactChoiceIds = new Object2IntOpenCustomHashMap<>(ItemStackLinkedSet.TYPE_AND_TAG);
@@ -24,6 +24,7 @@ public final class StackedContentsExtraMap {
private final Int2ObjectMap<ItemStack> idToExactChoice = new Int2ObjectOpenHashMap<>();
private final StackedContents contents;
public final Map<Ingredient, IntList> extraStackingIds = new IdentityHashMap<>();
+ public final List<Ingredient> predicateChoices = new ArrayList<>(); // Adding PredicateChoice
+ public final java.util.List<Ingredient> 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<ItemStack> {
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<ItemStack> {
@Nullable
public ItemStack[] itemStacks;
@Nullable
@@ -41,7 +44,13 @@ public final class Ingredient implements Predicate<ItemStack> {
private IntList stackingIds;
public boolean exact; // CraftBukkit
+ @Nullable public Predicate<org.bukkit.inventory.ItemStack> itemPredicate; // Paper - Adding PredicateChoice
public static final Codec<Ingredient> CODEC = Ingredient.codec(true);
public static final Codec<Ingredient> CODEC_NONEMPTY = Ingredient.codec(false);
-
+ // Paper start - Adding PredicateChoice
+ public Ingredient(RecipeChoice.PredicateChoice.ItemPredicate itemPredicate) {
+ List<org.bukkit.inventory.ItemStack> 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<? extends Ingredient.Value> entries) {
this.values = (Ingredient.Value[]) entries.toArray((i) -> {
return new Ingredient.Value[i];
@@ -70,6 +79,11 @@ public final class Ingredient implements Predicate<ItemStack> {
@@ -67,6 +67,11 @@ public final class Ingredient implements Predicate<ItemStack> {
} 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<ItemStack> {
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<C extends Container> {
@@ -71,7 +71,7 @@ public interface Recipe<C extends Container> {
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<org.bukkit.inventory.ItemStack> 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<org.bukkit.inventory.ItemStack> 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<org.bukkit.inventory.ItemStack> choices = new ArrayList<>(list.itemStacks.length);