From 74d8d5bf624af0b6758754d00387612aee1aa080 Mon Sep 17 00:00:00 2001 From: esbraff Date: Wed, 6 May 2026 11:38:27 +0300 Subject: [PATCH 1/7] Fix drawer mods compatibility Creators-of-Create#10313 --- .../unpacking/DefaultUnpackingHandler.java | 74 ++++++------------- 1 file changed, 22 insertions(+), 52 deletions(-) diff --git a/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java b/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java index 65bab3b995..c36425e206 100644 --- a/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java +++ b/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java @@ -1,7 +1,16 @@ package com.simibubi.create.impl.unpacking; +import java.util.ArrayList; import java.util.List; +import com.simibubi.create.AllEntityTypes; + +import com.simibubi.create.content.logistics.box.PackageItem; +import com.simibubi.create.content.logistics.box.PackageStyles; + +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.phys.Vec3; + import org.jetbrains.annotations.Nullable; import com.simibubi.create.api.packager.unpacking.UnpackingHandler; @@ -31,63 +40,24 @@ public boolean unpack(Level level, BlockPos pos, BlockState state, Direction sid if (targetInv == null) return false; - if (!simulate) { - /* - * Some mods do not support slot-by-slot precision during simulate = false. - * Faulty interactions may lead to voiding of items, but the simulate pass should - * already have correctly identified there to be enough space for everything. - */ - for (ItemStack itemStack : items) - ItemHandlerHelper.insertItemStacked(targetInv, itemStack.copy(), false); - return true; - } - - for (int slot = 0; slot < targetInv.getSlots(); slot++) { - ItemStack itemInSlot = targetInv.getStackInSlot(slot); - int itemsAddedToSlot = 0; - - for (int boxSlot = 0; boxSlot < items.size(); boxSlot++) { - ItemStack toInsert = items.get(boxSlot); - if (toInsert.isEmpty()) - continue; + List remainderList = new ArrayList<>(); - if (targetInv.insertItem(slot, toInsert, true) - .getCount() == toInsert.getCount()) - continue; - - if (itemInSlot.isEmpty()) { - int maxStackSize = targetInv.getSlotLimit(slot); - if (maxStackSize < toInsert.getCount()) { - toInsert.shrink(maxStackSize); - toInsert = toInsert.copyWithCount(maxStackSize); - } else - items.set(boxSlot, ItemStack.EMPTY); - - itemInSlot = toInsert; - targetInv.insertItem(slot, toInsert, simulate); - continue; + for (ItemStack itemStack : items) { + var remainder = ItemHandlerHelper.insertItemStacked(targetInv, itemStack.copy(), simulate); + if (!remainder.isEmpty()) { + if (simulate) { + return false; + } else { + remainderList.add(remainder); } - - if (!ItemStack.isSameItemSameComponents(toInsert, itemInSlot)) - continue; - - int insertedAmount = toInsert.getCount() - targetInv.insertItem(slot, toInsert, simulate) - .getCount(); - int slotLimit = Math.min(itemInSlot.getMaxStackSize(), targetInv.getSlotLimit(slot)); - int insertableAmountWithPreviousItems = - Math.min(toInsert.getCount(), slotLimit - itemInSlot.getCount() - itemsAddedToSlot); - - int added = Math.min(insertedAmount, Math.max(0, insertableAmountWithPreviousItems)); - itemsAddedToSlot += added; - - items.set(boxSlot, toInsert.copyWithCount(toInsert.getCount() - added)); } } - for (ItemStack stack : items) { - if (!stack.isEmpty()) { - // something failed to be inserted - return false; + if (!simulate && !remainderList.isEmpty()) { + var itemPos = Vec3.atCenterOf(pos); + for (var itemStack : remainderList) { + var itemEntity = new ItemEntity(level, itemPos.x, itemPos.y, itemPos.z, itemStack); + level.addFreshEntity(itemEntity); } } From d1a00da647375ef67bac3e520f6383f644858d89 Mon Sep 17 00:00:00 2001 From: esbraff Date: Wed, 6 May 2026 11:47:38 +0300 Subject: [PATCH 2/7] Remove unused imports --- .../create/impl/unpacking/DefaultUnpackingHandler.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java b/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java index c36425e206..1efc5897f5 100644 --- a/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java +++ b/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java @@ -3,11 +3,6 @@ import java.util.ArrayList; import java.util.List; -import com.simibubi.create.AllEntityTypes; - -import com.simibubi.create.content.logistics.box.PackageItem; -import com.simibubi.create.content.logistics.box.PackageStyles; - import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.phys.Vec3; From 0df161235dfe5700f0e8c3ae9cc6a53e437b7279 Mon Sep 17 00:00:00 2001 From: esbraff Date: Mon, 11 May 2026 05:50:23 +0300 Subject: [PATCH 3/7] Fix incorrect handling of multiple similar item stacks --- .../unpacking/DefaultUnpackingHandler.java | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java b/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java index 1efc5897f5..50c53cca30 100644 --- a/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java +++ b/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.List; +import net.minecraft.network.chat.Component; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.phys.Vec3; @@ -37,17 +38,40 @@ public boolean unpack(Level level, BlockPos pos, BlockState state, Direction sid List remainderList = new ArrayList<>(); - for (ItemStack itemStack : items) { - var remainder = ItemHandlerHelper.insertItemStacked(targetInv, itemStack.copy(), simulate); - if (!remainder.isEmpty()) { + for (int boxSlot = 0; boxSlot < items.size(); boxSlot++) { + ItemStack boxItemStack = items.get(boxSlot); + if (boxItemStack.isEmpty()) + continue; + + int amountToInsert = 0; + // iterate over contents of the box and count similar items + for (int otherBoxSlot = boxSlot; otherBoxSlot < items.size(); otherBoxSlot++) { + ItemStack otherBoxItemStack = items.get(otherBoxSlot); + if (!ItemStack.isSameItemSameComponents(boxItemStack, otherBoxItemStack)) + continue; + + int stackSize = otherBoxItemStack.getCount(); + amountToInsert += stackSize; + items.set(otherBoxSlot, otherBoxItemStack.copyWithCount(0)); + } + + // compress similar items into one stack so that it's easier to work with + ItemStack itemToInsert = boxItemStack.copyWithCount(amountToInsert); + for (int invSlot = 0; invSlot < targetInv.getSlots(); invSlot++) { + itemToInsert = targetInv.insertItem(invSlot, itemToInsert.copy(), simulate); + } + + if (!itemToInsert.isEmpty()) { if (simulate) { return false; } else { - remainderList.add(remainder); + remainderList.add(itemToInsert); } } } + // if there's inconsistency between simulate on and off results there may be some leftover items + // so drop them on the ground if (!simulate && !remainderList.isEmpty()) { var itemPos = Vec3.atCenterOf(pos); for (var itemStack : remainderList) { From a21d518c0132e675f9995446ebbbf814131c9111 Mon Sep 17 00:00:00 2001 From: esbraff Date: Mon, 11 May 2026 06:08:32 +0300 Subject: [PATCH 4/7] Separate non-simulate behavior so that it handles incorrect storage behavior better --- .../unpacking/DefaultUnpackingHandler.java | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java b/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java index 50c53cca30..f30142c3be 100644 --- a/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java +++ b/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java @@ -36,7 +36,30 @@ public boolean unpack(Level level, BlockPos pos, BlockState state, Direction sid if (targetInv == null) return false; - List remainderList = new ArrayList<>(); + if (!simulate) { + List remainderList = new ArrayList<>(); + + for (ItemStack stack : items) { + ItemStack remainder = ItemHandlerHelper.insertItemStacked(targetInv, stack.copy(), false); + if (!remainder.isEmpty()) { + remainderList.add(remainder); + } + } + + /* + * Some mods may have inconsistency between simulate pass and actually pushing items + * and possibly yield some leftover items + */ + if (!remainderList.isEmpty()) { + var itemPos = Vec3.atCenterOf(pos); + for (var itemStack : remainderList) { + var itemEntity = new ItemEntity(level, itemPos.x, itemPos.y, itemPos.z, itemStack); + level.addFreshEntity(itemEntity); + } + } + + return true; + } for (int boxSlot = 0; boxSlot < items.size(); boxSlot++) { ItemStack boxItemStack = items.get(boxSlot); @@ -58,25 +81,11 @@ public boolean unpack(Level level, BlockPos pos, BlockState state, Direction sid // compress similar items into one stack so that it's easier to work with ItemStack itemToInsert = boxItemStack.copyWithCount(amountToInsert); for (int invSlot = 0; invSlot < targetInv.getSlots(); invSlot++) { - itemToInsert = targetInv.insertItem(invSlot, itemToInsert.copy(), simulate); + itemToInsert = targetInv.insertItem(invSlot, itemToInsert.copy(), true); } if (!itemToInsert.isEmpty()) { - if (simulate) { - return false; - } else { - remainderList.add(itemToInsert); - } - } - } - - // if there's inconsistency between simulate on and off results there may be some leftover items - // so drop them on the ground - if (!simulate && !remainderList.isEmpty()) { - var itemPos = Vec3.atCenterOf(pos); - for (var itemStack : remainderList) { - var itemEntity = new ItemEntity(level, itemPos.x, itemPos.y, itemPos.z, itemStack); - level.addFreshEntity(itemEntity); + return false; } } From 3360b79459e50eebc9899b9068d53636033dee06 Mon Sep 17 00:00:00 2001 From: esbraff Date: Mon, 11 May 2026 06:38:51 +0300 Subject: [PATCH 5/7] Improve simulate logic --- .../unpacking/DefaultUnpackingHandler.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java b/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java index f30142c3be..e23d726cb2 100644 --- a/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java +++ b/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java @@ -61,13 +61,15 @@ public boolean unpack(Level level, BlockPos pos, BlockState state, Direction sid return true; } + List compressedItems = new ArrayList<>(); + for (int boxSlot = 0; boxSlot < items.size(); boxSlot++) { ItemStack boxItemStack = items.get(boxSlot); if (boxItemStack.isEmpty()) continue; int amountToInsert = 0; - // iterate over contents of the box and count similar items + // iterate over contents of the package and count similar items for (int otherBoxSlot = boxSlot; otherBoxSlot < items.size(); otherBoxSlot++) { ItemStack otherBoxItemStack = items.get(otherBoxSlot); if (!ItemStack.isSameItemSameComponents(boxItemStack, otherBoxItemStack)) @@ -78,13 +80,27 @@ public boolean unpack(Level level, BlockPos pos, BlockState state, Direction sid items.set(otherBoxSlot, otherBoxItemStack.copyWithCount(0)); } - // compress similar items into one stack so that it's easier to work with - ItemStack itemToInsert = boxItemStack.copyWithCount(amountToInsert); - for (int invSlot = 0; invSlot < targetInv.getSlots(); invSlot++) { - itemToInsert = targetInv.insertItem(invSlot, itemToInsert.copy(), true); + // compress similar items into one stack, so that it's easier to work with + compressedItems.add(boxItemStack.copyWithCount(amountToInsert)); + } + + for (int invSlot = 0; invSlot < targetInv.getSlots(); invSlot++) { + for (int itemIndex = 0; itemIndex < compressedItems.size(); itemIndex++) { + ItemStack itemToInsert = compressedItems.get(itemIndex); + ItemStack remainder = targetInv.insertItem(invSlot, itemToInsert.copy(), true); + + compressedItems.set(itemIndex, remainder); + + // if there's remainder or inserted amount is equal to slot limit, + // then this slot is full, no need to check other items in the package + if (!remainder.isEmpty() || targetInv.getSlotLimit(invSlot) == itemToInsert.getCount()) { + break; + } } + } - if (!itemToInsert.isEmpty()) { + for (ItemStack stack : compressedItems) { + if (!stack.isEmpty()) { return false; } } From b627fa5570b0c526e0ea00531cbccdb20e5f2c7f Mon Sep 17 00:00:00 2001 From: esbraff Date: Mon, 11 May 2026 06:51:37 +0300 Subject: [PATCH 6/7] Fix handling filled slots --- .../create/impl/unpacking/DefaultUnpackingHandler.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java b/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java index e23d726cb2..f78bc334d4 100644 --- a/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java +++ b/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java @@ -85,15 +85,18 @@ public boolean unpack(Level level, BlockPos pos, BlockState state, Direction sid } for (int invSlot = 0; invSlot < targetInv.getSlots(); invSlot++) { + ItemStack itemInSlot = targetInv.getStackInSlot(invSlot); + for (int itemIndex = 0; itemIndex < compressedItems.size(); itemIndex++) { ItemStack itemToInsert = compressedItems.get(itemIndex); ItemStack remainder = targetInv.insertItem(invSlot, itemToInsert.copy(), true); compressedItems.set(itemIndex, remainder); - // if there's remainder or inserted amount is equal to slot limit, + // if there's remainder or new item amount is equal to slot limit, // then this slot is full, no need to check other items in the package - if (!remainder.isEmpty() || targetInv.getSlotLimit(invSlot) == itemToInsert.getCount()) { + if (!remainder.isEmpty() || + itemToInsert.getCount() + itemInSlot.getCount() == targetInv.getSlotLimit(invSlot)) { break; } } From 3ae33319ff4c2c11ba8a146b1933161d8e9008fd Mon Sep 17 00:00:00 2001 From: esbraff Date: Mon, 11 May 2026 16:41:45 +0300 Subject: [PATCH 7/7] Skip empty stacks during simulate insert, just in case --- .../create/impl/unpacking/DefaultUnpackingHandler.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java b/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java index f78bc334d4..d15b67bd6e 100644 --- a/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java +++ b/src/main/java/com/simibubi/create/impl/unpacking/DefaultUnpackingHandler.java @@ -89,6 +89,9 @@ public boolean unpack(Level level, BlockPos pos, BlockState state, Direction sid for (int itemIndex = 0; itemIndex < compressedItems.size(); itemIndex++) { ItemStack itemToInsert = compressedItems.get(itemIndex); + if (itemToInsert.isEmpty()) + continue; + ItemStack remainder = targetInv.insertItem(invSlot, itemToInsert.copy(), true); compressedItems.set(itemIndex, remainder);