Skip to content

Commit

Permalink
Fix Custom Shapeless Custom Crafting Recipes
Browse files Browse the repository at this point in the history
Mojang implemented Shapeless different than Shaped

This made the Bukkit RecipeChoice API not work for Shapeless.

This reimplements vanilla logic using the same test logic as Shaped
  • Loading branch information
aikar committed Feb 28, 2019
1 parent 9bde06a commit ac5b19c
Showing 1 changed file with 58 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
From 270c7bb8936f603c5f8700598807bb20482ed4d8 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Fri, 18 Jan 2019 00:08:15 -0500
Subject: [PATCH] Fix Custom Shapeless Custom Crafting Recipes

Mojang implemented Shapeless different than Shaped

This made the Bukkit RecipeChoice API not work for Shapeless.

This reimplements vanilla logic using the same test logic as Shaped

diff --git a/src/main/java/net/minecraft/server/ShapelessRecipes.java b/src/main/java/net/minecraft/server/ShapelessRecipes.java
index 819b4ac2da..1dc9a1c93c 100644
--- a/src/main/java/net/minecraft/server/ShapelessRecipes.java
+++ b/src/main/java/net/minecraft/server/ShapelessRecipes.java
@@ -59,21 +59,32 @@ public class ShapelessRecipes implements IRecipe {
if (!(iinventory instanceof InventoryCrafting)) {
return false;
} else {
- AutoRecipeStackManager autorecipestackmanager = new AutoRecipeStackManager();
- int i = 0;
-
+ // Paper start - use RecipeItemStack.test
+ java.util.List<ItemStack> providedItems = new java.util.ArrayList<>();
for (int j = 0; j < iinventory.n(); ++j) {
for (int k = 0; k < iinventory.U_(); ++k) {
ItemStack itemstack = iinventory.getItem(k + j * iinventory.U_());

if (!itemstack.isEmpty()) {
- ++i;
- autorecipestackmanager.b(new ItemStack(itemstack.getItem()));
+ providedItems.add(itemstack.cloneItemStack());
}
}
}
-
- return i == this.ingredients.size() && autorecipestackmanager.a(this, (IntList) null);
+ java.util.List<RecipeItemStack> ingredients = new java.util.ArrayList<>(this.ingredients);
+
+ PROVIDED:
+ for (ItemStack provided : providedItems) {
+ for (Iterator<RecipeItemStack> itIngredient = ingredients.iterator(); itIngredient.hasNext(); ) {
+ RecipeItemStack ingredient = itIngredient.next();
+ if (ingredient.test(provided)) {
+ itIngredient.remove();
+ continue PROVIDED;
+ }
+ }
+ return false;
+ }
+ return ingredients.isEmpty();
+ // Paper end

This comment has been minimized.

Copy link
@liach

liach Feb 28, 2019

Unfortunately your logic here is incorrect as one ingredient can match to more than one items. MinecraftForge/MinecraftForge#4472 (comment)

This comment has been minimized.

Copy link
@aikar

aikar Feb 28, 2019

Author Member

@liach can you provide an example recipe that wont work correctly? can you discuss on discord?

This comment has been minimized.

Copy link
@liach

liach Feb 28, 2019

This comment has been minimized.

Copy link
@aikar

aikar Feb 28, 2019

Author Member

Per discussion on Discord, I updated the patch in 47c6e17

While this isn't 'perfect' in that it guarantees it'll always pass, it should reduce most occurences of it by sorting the ingredients and provided items in a way that harder to satisfy items are satisfied first and items you have more of are used before items you have less of.

if we ultimately have anyone complain about this, we can just update the patch to only use this alternate matching if the recipe has a Bukkit choice, but same overall 'flawed' problem can apply to bukkit recipes too.

but this change is required to support bukkit ExactChoice recipes.

}
}

--
2.20.1

0 comments on commit ac5b19c

Please sign in to comment.