fix exact choice shapeless recipes (#10973)
This commit is contained in:
parent
2df5bba16a
commit
44c3dd0d4c
1 changed files with 57 additions and 16 deletions
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue