From a09b68814dc0668ddaf8bf7bc1d2fe39c482c723 Mon Sep 17 00:00:00 2001 From: DancingSnow <60736156+DancingSnow0517@users.noreply.github.com> Date: Fri, 7 Jun 2024 20:45:05 +0800 Subject: [PATCH] feat(BlockPattern): let autoBuild use itemHandler instead of PlayerInv (#1383) Co-authored-by: screret <68943070+screret@users.noreply.github.com> --- .../gtceu/api/pattern/BlockPattern.java | 52 +++++++++++++++---- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/pattern/BlockPattern.java b/src/main/java/com/gregtechceu/gtceu/api/pattern/BlockPattern.java index 1a1099fa0b..3478abbd30 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/pattern/BlockPattern.java +++ b/src/main/java/com/gregtechceu/gtceu/api/pattern/BlockPattern.java @@ -29,10 +29,16 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.phys.BlockHitResult; +import net.minecraftforge.common.capabilities.ForgeCapabilities; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.items.IItemHandler; +import com.mojang.datafixers.util.Pair; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import org.apache.commons.lang3.ArrayUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.lang.reflect.Array; import java.util.*; @@ -302,16 +308,15 @@ public void autoBuild(Player player, MultiblockState worldState) { // check inventory ItemStack found = null; - ItemStack originalItemStack = null; + int foundSlot = -1; + IItemHandler handler = null; if (!player.isCreative()) { - for (ItemStack itemStack : player.getInventory().items) { - if (candidates.stream().anyMatch( - candidate -> ItemStack.isSameItemSameTags(candidate, itemStack)) && - !itemStack.isEmpty() && itemStack.getItem() instanceof BlockItem) { - found = itemStack.copy(); - originalItemStack = itemStack; - break; - } + var foundHandler = getMatchStackWithHandler(candidates, + player.getCapability(ForgeCapabilities.ITEM_HANDLER)); + if (foundHandler != null) { + foundSlot = foundHandler.getFirst(); + handler = foundHandler.getSecond(); + found = handler.getStackInSlot(foundSlot).copy(); } } else { for (ItemStack candidate : candidates) { @@ -329,8 +334,8 @@ public void autoBuild(Player player, MultiblockState worldState) { InteractionResult interactionResult = itemBlock.place(context); if (interactionResult != InteractionResult.FAIL) { placeBlockPos.add(pos); - if (originalItemStack != null) { - originalItemStack.setCount(originalItemStack.getCount() - 1); + if (handler != null) { + handler.extractItem(foundSlot, 1, false); } } if (world.getBlockEntity(pos) instanceof IMachineBlockEntity machineBlockEntity) { @@ -642,4 +647,29 @@ private BlockPos setActualRelativeOffset(int x, int y, int z, Direction facing, } return new BlockPos(c1[0], c1[1], c1[2]); } + + @Nullable + private static Pair getMatchStackWithHandler( + List candidates, + LazyOptional cap) { + IItemHandler handler = cap.orElse(null); + if (handler == null) { + return null; + } + for (int i = 0; i < handler.getSlots(); i++) { + @NotNull + ItemStack stack = handler.getStackInSlot(i); + if (stack.isEmpty()) continue; + + @NotNull + LazyOptional stackCap = stack.getCapability(ForgeCapabilities.ITEM_HANDLER); + if (stackCap.isPresent()) { + return getMatchStackWithHandler(candidates, stackCap); + } else if (candidates.stream().anyMatch(candidate -> ItemStack.isSameItemSameTags(candidate, stack)) && + !stack.isEmpty() && stack.getItem() instanceof BlockItem) { + return Pair.of(i, handler); + } + } + return null; + } }