diff --git a/src/main/java/com/simibubi/create/content/logistics/packager/AllUnpackingHandlers.java b/src/main/java/com/simibubi/create/content/logistics/packager/AllUnpackingHandlers.java index 056b958643..5613ab5c89 100644 --- a/src/main/java/com/simibubi/create/content/logistics/packager/AllUnpackingHandlers.java +++ b/src/main/java/com/simibubi/create/content/logistics/packager/AllUnpackingHandlers.java @@ -6,10 +6,15 @@ import com.simibubi.create.impl.unpacking.BasinUnpackingHandler; import com.simibubi.create.impl.unpacking.CrafterUnpackingHandler; +import com.simibubi.create.impl.unpacking.VanillaCrafterUnpackingHandler; + +import net.minecraft.world.level.block.Blocks; + public class AllUnpackingHandlers { public static void registerDefaults() { UnpackingHandler.REGISTRY.register(AllBlocks.BASIN.get(), BasinUnpackingHandler.INSTANCE); UnpackingHandler.REGISTRY.register(AllBlocks.CREATIVE_CRATE.get(), VoidingUnpackingHandler.INSTANCE); UnpackingHandler.REGISTRY.register(AllBlocks.MECHANICAL_CRAFTER.get(), CrafterUnpackingHandler.INSTANCE); + UnpackingHandler.REGISTRY.register(Blocks.CRAFTER, VanillaCrafterUnpackingHandler.INSTANCE); } } diff --git a/src/main/java/com/simibubi/create/impl/unpacking/CrafterUnpackingHandler.java b/src/main/java/com/simibubi/create/impl/unpacking/CrafterUnpackingHandler.java index 0de541f4ce..5bbd236d6c 100644 --- a/src/main/java/com/simibubi/create/impl/unpacking/CrafterUnpackingHandler.java +++ b/src/main/java/com/simibubi/create/impl/unpacking/CrafterUnpackingHandler.java @@ -24,7 +24,7 @@ public enum CrafterUnpackingHandler implements UnpackingHandler { @Override public boolean unpack(Level level, BlockPos pos, BlockState state, Direction side, List items, @Nullable PackageOrderWithCrafts orderContext, boolean simulate) { if (!PackageOrderWithCrafts.hasCraftingInformation(orderContext)) - return DEFAULT.unpack(level, pos, state, side, items, null, simulate); + return DEFAULT.unpack(level, pos, state, side, items, orderContext, simulate); // Get item placement List craftingContext = orderContext.getCraftingInformation(); 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..0847b3bc37 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,11 @@ package com.simibubi.create.impl.unpacking; +import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import com.simibubi.create.content.logistics.BigItemStack; + import org.jetbrains.annotations.Nullable; import com.simibubi.create.api.packager.unpacking.UnpackingHandler; @@ -37,8 +41,36 @@ public boolean unpack(Level level, BlockPos pos, BlockState state, Direction sid * 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); + if(orderContext != null && !orderContext.orderedStacks().isEmpty()) { + /* + * We check items from copy, but use order from orderContext. + * This way we ensure invalid data doesn't create any fake item + * */ + List copy = new ArrayList<>(items); + for (BigItemStack elem : orderContext.orderedStacks().stacks()) { + int remaining = elem.count; + + for (Iterator it = copy.iterator(); it.hasNext() && remaining > 0; ) { + ItemStack inCopy = it.next(); + + if (!ItemStack.isSameItemSameComponents(inCopy, elem.stack)) continue; + + int taken = Math.min(inCopy.getCount(), remaining); + inCopy.shrink(taken); + remaining -= taken; + + if (inCopy.isEmpty()) it.remove(); + } + + if (remaining < elem.count) { + ItemStack toInsert = elem.stack.copyWithCount(elem.count - remaining); + ItemHandlerHelper.insertItemStacked(targetInv, toInsert, false); + } + } + } else { + for (ItemStack itemStack : items) + ItemHandlerHelper.insertItemStacked(targetInv, itemStack.copy(), false); + } return true; } diff --git a/src/main/java/com/simibubi/create/impl/unpacking/VanillaCrafterUnpackingHandler.java b/src/main/java/com/simibubi/create/impl/unpacking/VanillaCrafterUnpackingHandler.java new file mode 100644 index 0000000000..08782dd231 --- /dev/null +++ b/src/main/java/com/simibubi/create/impl/unpacking/VanillaCrafterUnpackingHandler.java @@ -0,0 +1,66 @@ +package com.simibubi.create.impl.unpacking; + +import com.simibubi.create.api.packager.unpacking.UnpackingHandler; +import com.simibubi.create.content.logistics.BigItemStack; +import com.simibubi.create.content.logistics.stockTicker.PackageOrderWithCrafts; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.CrafterBlockEntity; +import net.minecraft.world.level.block.state.BlockState; + +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public enum VanillaCrafterUnpackingHandler implements UnpackingHandler { + INSTANCE; + + + @Override + public boolean unpack(Level level, BlockPos pos, BlockState state, Direction side, List items, @Nullable PackageOrderWithCrafts orderContext, boolean simulate) { + if (!PackageOrderWithCrafts.hasCraftingInformation(orderContext)) + return DEFAULT.unpack(level, pos, state, side, items, orderContext, simulate); + + List craftingContext = orderContext.getCraftingInformation(); + + BlockEntity be = level.getBlockEntity(pos); + if(!(be instanceof CrafterBlockEntity crafter)) + return false; + int max = Math.min(9, craftingContext.size()); + outer: for (int i = 0; i < max; i++) { + BigItemStack targetStack = craftingContext.get(i); + if (targetStack.stack.isEmpty()) + continue; + + if (crafter.isSlotDisabled(i)) + continue; + + if (!crafter.getItem(i).isEmpty()) + continue; + + for (ItemStack stack : items) { + if (ItemStack.isSameItemSameComponents(stack, targetStack.stack)) { + ItemStack toInsert = stack.copyWithCount(1); + if (crafter.canPlaceItem(i, toInsert)) { + if (!simulate) { + crafter.setItem(i, toInsert); + } + stack.shrink(1); + continue outer; + } + } + } + } + + for (ItemStack item : items) { + if (!item.isEmpty()) + return false; + } + + return true; + } +}