aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server
diff options
context:
space:
mode:
authorJake Potrebic <[email protected]>2024-07-17 12:48:31 -0700
committerGitHub <[email protected]>2024-07-17 12:48:31 -0700
commit44c3dd0d4c83cbfb8b41270c8d4ef0d1571e3925 (patch)
treeade9011897fdf52e7500b4656c522186c333dee3 /patches/server
parent2df5bba16adf61cf048b12908986aef944d11e75 (diff)
downloadPaper-44c3dd0d4c83cbfb8b41270c8d4ef0d1571e3925.tar.gz
Paper-44c3dd0d4c83cbfb8b41270c8d4ef0d1571e3925.zip
fix exact choice shapeless recipes (#10973)
Diffstat (limited to 'patches/server')
-rw-r--r--patches/server/0278-Improve-exact-choice-recipe-ingredients.patch73
1 files changed, 57 insertions, 16 deletions
diff --git a/patches/server/0278-Improve-exact-choice-recipe-ingredients.patch b/patches/server/0278-Improve-exact-choice-recipe-ingredients.patch
index 3f924dd8b8..9c0b7b8275 100644
--- a/patches/server/0278-Improve-exact-choice-recipe-ingredients.patch
+++ b/patches/server/0278-Improve-exact-choice-recipe-ingredients.patch
@@ -9,6 +9,7 @@ and shapeless recipes.
== AT ==
public net.minecraft.world.item.ItemStackLinkedSet TYPE_AND_TAG
public net.minecraft.world.entity.player.StackedContents put(II)V
+public net.minecraft.world.entity.player.StackedContents take(II)I
diff --git a/src/main/java/io/papermc/paper/inventory/recipe/RecipeBookExactChoiceRecipe.java b/src/main/java/io/papermc/paper/inventory/recipe/RecipeBookExactChoiceRecipe.java
new file mode 100644
@@ -48,12 +49,15 @@ index 0000000000000000000000000000000000000000..ef68600f6b59674ddea6c77f7e412902
+}
diff --git a/src/main/java/io/papermc/paper/inventory/recipe/StackedContentsExtraMap.java b/src/main/java/io/papermc/paper/inventory/recipe/StackedContentsExtraMap.java
new file mode 100644
-index 0000000000000000000000000000000000000000..2258d4556a1c608e2b0ece38471350646718eb19
+index 0000000000000000000000000000000000000000..568ba6aed2e74b8d84f4e82c1e785ef1587e2617
--- /dev/null
+++ b/src/main/java/io/papermc/paper/inventory/recipe/StackedContentsExtraMap.java
-@@ -0,0 +1,79 @@
+@@ -0,0 +1,109 @@
+package io.papermc.paper.inventory.recipe;
+
++import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
++import it.unimi.dsi.fastutil.ints.Int2IntMap;
++import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
@@ -68,13 +72,14 @@ index 0000000000000000000000000000000000000000..2258d4556a1c608e2b0ece3847135064
+import net.minecraft.world.entity.player.StackedContents;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.item.ItemStackLinkedSet;
++import net.minecraft.world.item.crafting.CraftingInput;
+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);
++ public final Object2IntMap<ItemStack> exactChoiceIds = new Object2IntOpenCustomHashMap<>(ItemStackLinkedSet.TYPE_AND_TAG);
+ private final Int2ObjectMap<ItemStack> idToExactChoice = new Int2ObjectOpenHashMap<>();
+ private final StackedContents contents;
+ public final Map<Ingredient, IntList> extraStackingIds = new IdentityHashMap<>();
@@ -120,6 +125,32 @@ index 0000000000000000000000000000000000000000..2258d4556a1c608e2b0ece3847135064
+ return this.idToExactChoice.get(id);
+ }
+
++ public Int2IntMap regularRemoved = new Int2IntArrayMap();
++ public void accountInput(final CraftingInput input) {
++ // similar logic to the CraftingInput constructor
++ for (final ItemStack item : input.items()) {
++ if (!item.isEmpty()) {
++ if (this.accountStack(item, 1)) {
++ // remove one of the items if it was added to the contents as a non-extra item
++ final int plainStackIdx = StackedContents.getStackingIndex(item);
++ if (this.contents.take(plainStackIdx, 1) == plainStackIdx) {
++ this.regularRemoved.put(plainStackIdx, 1);
++ }
++ }
++ }
++ }
++ }
++
++ public void resetExtras() {
++ // clear previous extra ids
++ for (final int extraId : this.exactChoiceIds.values()) {
++ this.contents.contents.remove(extraId);
++ }
++ for (final Int2IntMap.Entry entry : this.regularRemoved.int2IntEntrySet()) {
++ this.contents.put(entry.getIntKey(), entry.getIntValue());
++ }
++ }
++
+ public boolean accountStack(final ItemStack stack, final int count) {
+ if (!this.exactChoiceIds.isEmpty()) {
+ final int id = this.exactChoiceIds.getInt(stack);
@@ -143,14 +174,14 @@ index 0000000000000000000000000000000000000000..413dfa52760db393ad6a8b5341200ee7
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.framework.qual.DefaultQualifier;
diff --git a/src/main/java/net/minecraft/recipebook/ServerPlaceRecipe.java b/src/main/java/net/minecraft/recipebook/ServerPlaceRecipe.java
-index 0bd749af8014dd437229594ef6981a2ead803990..25acc13ba1adcc31a83f9cf29563760285f2ba7a 100644
+index 0bd749af8014dd437229594ef6981a2ead803990..6d1f9c15dc99917a2ac966ea38ef1970f4f0289c 100644
--- a/src/main/java/net/minecraft/recipebook/ServerPlaceRecipe.java
+++ b/src/main/java/net/minecraft/recipebook/ServerPlaceRecipe.java
@@ -31,6 +31,7 @@ public class ServerPlaceRecipe<I extends RecipeInput, R extends Recipe<I>> imple
this.inventory = entity.getInventory();
if (this.testClearGrid() || entity.isCreative()) {
this.stackedContents.clear();
-+ this.stackedContents.initialize(recipe.value()); // Paper - Improve exact choice recipe ingredients
++ this.stackedContents.initializeExtras(recipe.value(), null); // Paper - Improve exact choice recipe ingredients
entity.getInventory().fillStackedContents(this.stackedContents);
this.menu.fillCraftSlotsStackedContents(this.stackedContents);
if (this.stackedContents.canCraft(recipe.value(), null)) {
@@ -206,7 +237,7 @@ index 0bd749af8014dd437229594ef6981a2ead803990..25acc13ba1adcc31a83f9cf295637602
return -1;
} else {
diff --git a/src/main/java/net/minecraft/world/entity/player/StackedContents.java b/src/main/java/net/minecraft/world/entity/player/StackedContents.java
-index b11121e0846183ceeb7f4ad536aab2ee89ea9d26..0a58698dcd62adf3dc06a8c7dc782aada50409f5 100644
+index fa5576e41baec4b52c7ebb877924eb91d3775a2d..fcabf630ce1e4949d00f485a5bff66dd1e54a277 100644
--- a/src/main/java/net/minecraft/world/entity/player/StackedContents.java
+++ b/src/main/java/net/minecraft/world/entity/player/StackedContents.java
@@ -22,8 +22,10 @@ import net.minecraft.world.item.crafting.RecipeHolder;
@@ -228,13 +259,21 @@ index b11121e0846183ceeb7f4ad536aab2ee89ea9d26..0a58698dcd62adf3dc06a8c7dc782aad
this.put(i, j);
}
}
-@@ -83,6 +86,23 @@ public class StackedContents {
+@@ -83,6 +86,31 @@ public class StackedContents {
return itemId == 0 ? ItemStack.EMPTY : new ItemStack(Item.byId(itemId));
}
+ // Paper start - Improve exact choice recipe ingredients
-+ public void initialize(final Recipe<?> recipe) {
++ public void initializeExtras(final Recipe<?> recipe, @Nullable final net.minecraft.world.item.crafting.CraftingInput input) {
+ this.extrasMap = new io.papermc.paper.inventory.recipe.StackedContentsExtraMap(this, recipe);
++ if (input != null) this.extrasMap.accountInput(input);
++ }
++
++ public void resetExtras() {
++ if (this.extrasMap != null && !this.contents.isEmpty()) {
++ this.extrasMap.resetExtras();
++ }
++ this.extrasMap = null;
+ }
+
+ public static ItemStack fromStackingIndexWithExtras(final int itemId, @Nullable final StackedContents contents) {
@@ -252,7 +291,7 @@ index b11121e0846183ceeb7f4ad536aab2ee89ea9d26..0a58698dcd62adf3dc06a8c7dc782aad
public void clear() {
this.contents.clear();
}
-@@ -106,7 +126,7 @@ public class StackedContents {
+@@ -106,7 +134,7 @@ public class StackedContents {
this.data = new BitSet(this.ingredientCount + this.itemCount + this.ingredientCount + this.ingredientCount * this.itemCount);
for (int i = 0; i < this.ingredients.size(); i++) {
@@ -261,7 +300,7 @@ index b11121e0846183ceeb7f4ad536aab2ee89ea9d26..0a58698dcd62adf3dc06a8c7dc782aad
for (int j = 0; j < this.itemCount; j++) {
if (intList.contains(this.items[j])) {
-@@ -169,7 +189,7 @@ public class StackedContents {
+@@ -169,7 +197,7 @@ public class StackedContents {
IntCollection intCollection = new IntAVLTreeSet();
for (Ingredient ingredient : this.ingredients) {
@@ -270,7 +309,7 @@ index b11121e0846183ceeb7f4ad536aab2ee89ea9d26..0a58698dcd62adf3dc06a8c7dc782aad
}
IntIterator intIterator = intCollection.iterator();
-@@ -298,7 +318,7 @@ public class StackedContents {
+@@ -298,7 +326,7 @@ public class StackedContents {
for (Ingredient ingredient : this.ingredients) {
int j = 0;
@@ -279,7 +318,7 @@ index b11121e0846183ceeb7f4ad536aab2ee89ea9d26..0a58698dcd62adf3dc06a8c7dc782aad
j = Math.max(j, StackedContents.this.contents.get(k));
}
-@@ -309,5 +329,17 @@ public class StackedContents {
+@@ -309,5 +337,17 @@ public class StackedContents {
return i;
}
@@ -355,7 +394,7 @@ index 59372daacd6fef45373c0557ccebb6ff5f16f174..63cf2b66f51df68aa3f6d98c69368ce4
public ShapedRecipe(String group, CraftingBookCategory category, ShapedRecipePattern raw, ItemStack result) {
diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java
-index 62401d045245ec7e303ec526c09b5e6fa4c9f17b..5740296b55827f11c0029e89a86eaab1a24f560c 100644
+index 62401d045245ec7e303ec526c09b5e6fa4c9f17b..213ee4aa988dd4c2a5a7be99b1d13f67338e5209 100644
--- a/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java
+++ b/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java
@@ -19,7 +19,7 @@ import org.bukkit.craftbukkit.inventory.CraftRecipe;
@@ -375,7 +414,7 @@ index 62401d045245ec7e303ec526c09b5e6fa4c9f17b..5740296b55827f11c0029e89a86eaab1
}
// CraftBukkit start
-@@ -75,7 +76,16 @@ public class ShapelessRecipe implements CraftingRecipe {
+@@ -75,7 +76,18 @@ public class ShapelessRecipe implements CraftingRecipe {
}
public boolean matches(CraftingInput input, Level world) {
@@ -387,8 +426,10 @@ index 62401d045245ec7e303ec526c09b5e6fa4c9f17b..5740296b55827f11c0029e89a86eaab1
+ if (input.size() == 1 && this.ingredients.size() == 1) {
+ return this.ingredients.getFirst().test(input.getItem(0));
+ }
-+ input.stackedContents().initialize(this); // setup stacked contents for this recipe
-+ return input.stackedContents().canCraft(this, null);
++ input.stackedContents().initializeExtras(this, input); // setup stacked contents for this recipe
++ final boolean canCraft = input.stackedContents().canCraft(this, null);
++ input.stackedContents().resetExtras();
++ return canCraft;
+ // Paper end - unwrap ternary & better exact choice recipes
}