GithubHelp home page GithubHelp logo

Comments (4)

QPCrummer avatar QPCrummer commented on July 23, 2024

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

from carpet-autocraftingtable.

magneticflux- avatar magneticflux- commented on July 23, 2024

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.

from carpet-autocraftingtable.

magneticflux- avatar magneticflux- commented on July 23, 2024

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);

from carpet-autocraftingtable.

Nathdoesmath avatar Nathdoesmath commented on July 23, 2024

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

from carpet-autocraftingtable.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.