carpet-autoCraftingTable icon indicating copy to clipboard operation
carpet-autoCraftingTable copied to clipboard

Recipes don't update with an item filter beneath the crafting table 1.4.56

Open QPCrummer opened this issue 2 years ago • 4 comments

When making an item filter beneath the autocrafting table, it will only accept the first recipe put into the table. From what it appear, it seems as if the first recipe is actually crafted and stored in the output slot, not allowing any other recipes to be crafted. 2022-01-16_19 34 48

This is not the case for a locked hopper under the crafting table. It works perfectly fine with that.

QPCrummer avatar Jan 17 '22 01:01 QPCrummer

It is the same issue mumbo jumbo has right here: https://youtu.be/n1WCEBdAfQ4?t=132

QPCrummer avatar Jan 17 '22 02:01 QPCrummer

The issue stems from the fact that the exact process by which hoppers extract items from inventories is a little confusing. These are the steps as I understand them:

  1. Get the output inventory of the thing above the hopper. (For the crafting table block entity, this is the whole inventory with the output slot first)
  2. For each slot in the output inventory do the following:
    1. Get the stack in the slot
    2. Make a copy of the stack verbatim
    3. Extract 1 item from slot (as its own, new, stack)
    4. Try to transfer (i.e. move, not copy) the entire new stack into the hopper's inventory
    5. If the new stack is now empty, we moved successfully: end the loop by returning true
    6. If the new stack still has items left, we couldn't move it: put the copy of the original stack in the inventory slot (this "undoes" the item being removed)
    7. Continue the loop with the next slot...
  3. If we're here, nothing could be moved. Return false

I think the best solution would be to "undo" a crafting operation if a copy of the last crafting outputs are put back in the output slot. AFAIK only hoppers can re-insert an item like this, so you wouldn't be able to exploit this to un-craft items somehow.

magneticflux- avatar Jan 21 '22 03:01 magneticflux-

Here's something scuffed to get started. It doesn't sync the inventory to the client properly though.

Index: src/main/java/carpet_autocraftingtable/CraftingTableBlockEntity.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/carpet_autocraftingtable/CraftingTableBlockEntity.java b/src/main/java/carpet_autocraftingtable/CraftingTableBlockEntity.java
--- a/src/main/java/carpet_autocraftingtable/CraftingTableBlockEntity.java	(revision 7f2188f67a179c0f47c15326e8a5942bcccb7fef)
+++ b/src/main/java/carpet_autocraftingtable/CraftingTableBlockEntity.java	(date 1642736048671)
@@ -21,8 +21,8 @@
 import net.minecraft.screen.ScreenHandler;
 import net.minecraft.text.Text;
 import net.minecraft.text.TranslatableText;
-import net.minecraft.util.collection.DefaultedList;
 import net.minecraft.util.ItemScatterer;
+import net.minecraft.util.collection.DefaultedList;
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.util.math.Direction;
 import net.minecraft.util.registry.Registry;
@@ -42,6 +42,7 @@
     public DefaultedList<ItemStack> inventory;
     public ItemStack output = ItemStack.EMPTY;
     private Recipe<?> lastRecipe;
+    public DefaultedList<ItemStack> lastInventory;
     private final List<AutoCraftingTableContainer> openContainers = new ArrayList<>();
 
     public CraftingTableBlockEntity(BlockPos pos, BlockState state) {  //this(BlockEntityType.BARREL);
@@ -54,6 +55,10 @@
 
     public static void init() { } // registers BE type
 
+    private static DefaultedList<ItemStack> copyInv(DefaultedList<ItemStack> original) {
+        return DefaultedList.copyOf(ItemStack.EMPTY, original.toArray(ItemStack[]::new));
+    }
+
     @Override
     public void writeNbt(NbtCompound tag) {
         super.writeNbt(tag);
@@ -120,7 +125,11 @@
         if (slot > 0) return this.inventory.get(slot - 1);
         if (!output.isEmpty()) return output;
         Optional<CraftingRecipe> recipe = getCurrentRecipe();
-        return recipe.map(craftingRecipe -> craftingRecipe.craft(craftingInventory)).orElse(ItemStack.EMPTY);
+        if (recipe.isPresent()) {
+            return recipe.get().craft(craftingInventory);
+        } else {
+            return ItemStack.EMPTY;
+        }
     }
 
     @Override
@@ -147,10 +156,17 @@
     @Override
     public void setStack(int slot, ItemStack stack) {
         if (slot == 0) {
-            output = stack;
-            return;
-        }
-        inventory.set(slot - 1, stack);
+            // "Undo" the last crafting operation; the right items were put back in the output slot by a hopper or something
+            if (stack.equals(lastRecipe.getOutput())) {
+                inventory = lastInventory;
+                output = ItemStack.EMPTY;
+                markDirty();
+            } else {
+                output = stack;
+            }
+        } else {
+            inventory.set(slot - 1, stack);
+        }
     }
 
     @Override
@@ -190,13 +206,14 @@
         if (this.world == null) return Optional.empty();
         Optional<CraftingRecipe> optionalRecipe = this.world.getRecipeManager().getFirstMatch(RecipeType.CRAFTING, craftingInventory, world);
         optionalRecipe.ifPresent(this::setLastRecipe);
+        lastInventory = copyInv(inventory); // Track the pre-crafted inventory to restore it later
         return optionalRecipe;
     }
 
     private ItemStack craft() {
         if (this.world == null) return ItemStack.EMPTY;
         Optional<CraftingRecipe> optionalRecipe = getCurrentRecipe();
-        if (!optionalRecipe.isPresent()) return ItemStack.EMPTY;
+        if (optionalRecipe.isEmpty()) return ItemStack.EMPTY;
         CraftingRecipe recipe = optionalRecipe.get();
         ItemStack result = recipe.craft(craftingInventory);
         DefaultedList<ItemStack> remaining = world.getRecipeManager().getRemainingStacks(RecipeType.CRAFTING, craftingInventory, world);

magneticflux- avatar Jan 21 '22 03:01 magneticflux-

Having this issue with my gold farm crafting system as well, joining so ik when it is fixed

Nathdoesmath avatar Sep 09 '22 11:09 Nathdoesmath