Posted August 30, 20196 yr every time I shift click an item in my custom blocks inventory, "slotClick" gets stuck in a loop. at line 170 where "transferStackInSlot" is used, there is a for loop whose termination condition always returns true. the condition is (!itemstack7.isEmpty() && ItemStack.areItemsEqual(slot5.getStack(), itemstack7)). I'm guessing that the line (itemstack = itemstack7.copy();) is supposed to make (ItemStack.areItemsEqual(slot5.getStack(), itemstack7)) false, but its not. not sure how to proceed. any help is greatly appreciated. package com.Garrett.backtobasics.blocks; import com.google.common.collect.Sets; import mcp.MethodsReturnNonnullByDefault; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.container.ClickType; import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.Slot; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IWorldPosCallable; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.SlotItemHandler; import net.minecraftforge.items.wrapper.InvWrapper; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import static com.Garrett.backtobasics.blocks.ModBlocks.AUTO_MINER_CONTAINER; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.Set; public class AutoMinerContainer extends Container { private TileEntity tileEntity; private PlayerEntity playerEntity; private IItemHandler playerInventory; private static final Logger LOGGER = LogManager.getLogger(); private int dragMode = -1; private int dragEvent; private final Set<Slot> dragSlots = Sets.newHashSet(); public AutoMinerContainer(int windowId, World world, BlockPos pos, PlayerInventory PlayerInventory, PlayerEntity player) { super(AUTO_MINER_CONTAINER, windowId); tileEntity = world.getTileEntity(pos); this.playerEntity = player; this.playerInventory = new InvWrapper(PlayerInventory); tileEntity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).ifPresent(h -> { addSlot(new SlotItemHandler(h, 0, 82, 24)); // x and y positions should be multiples of 8 }); layoutPlayerInventorySlots(10, 70); } @Override public boolean canInteractWith(PlayerEntity playerIn) { return isWithinUsableDistance(IWorldPosCallable.of(tileEntity.getWorld(), tileEntity.getPos()), playerEntity, ModBlocks.AUTO_MINER); } private int addSlotRange(IItemHandler handler, int index, int x, int y, int amount, int dx) { for (int i = 0 ; i < amount ; i++) { addSlot(new SlotItemHandler(handler, index, x, y)); x += dx; index++; } return index; } private int addSlotBox(IItemHandler handler, int index, int x, int y, int horAmount, int dx, int verAmount, int dy) { for (int j = 0 ; j < verAmount ; j++) { index = addSlotRange(handler, index, x, y, horAmount, dx); y += dy; } return index; } private void layoutPlayerInventorySlots(int leftCol, int topRow) { // Player inventory addSlotBox(playerInventory, 9, leftCol, topRow, 9, 18, 3, 18); // Hotbar topRow += 58; addSlotRange(playerInventory, 0, leftCol, topRow, 9, 18); } @Nonnull @Override public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) { Slot slot = this.inventorySlots.get(index); return slot != null ? slot.getStack() : ItemStack.EMPTY; } @Override public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, PlayerEntity player) { ItemStack itemstack = ItemStack.EMPTY; PlayerInventory playerinventory = player.inventory; if (clickTypeIn == ClickType.QUICK_CRAFT) { int j1 = this.dragEvent; this.dragEvent = getDragEvent(dragType); if ((j1 != 1 || this.dragEvent != 2) && j1 != this.dragEvent) { this.resetDrag(); } else if (playerinventory.getItemStack().isEmpty()) { this.resetDrag(); } else if (this.dragEvent == 0) { this.dragMode = extractDragMode(dragType); if (isValidDragMode(this.dragMode, player)) { this.dragEvent = 1; this.dragSlots.clear(); } else { this.resetDrag(); } } else if (this.dragEvent == 1) { Slot slot7 = this.inventorySlots.get(slotId); ItemStack itemstack12 = playerinventory.getItemStack(); if (slot7 != null && canAddItemToSlot(slot7, itemstack12, true) && slot7.isItemValid(itemstack12) && (this.dragMode == 2 || itemstack12.getCount() > this.dragSlots.size()) && this.canDragIntoSlot(slot7)) { this.dragSlots.add(slot7); } } else if (this.dragEvent == 2) { if (!this.dragSlots.isEmpty()) { ItemStack itemstack9 = playerinventory.getItemStack().copy(); int k1 = playerinventory.getItemStack().getCount(); for(Slot slot8 : this.dragSlots) { ItemStack itemstack13 = playerinventory.getItemStack(); if (slot8 != null && canAddItemToSlot(slot8, itemstack13, true) && slot8.isItemValid(itemstack13) && (this.dragMode == 2 || itemstack13.getCount() >= this.dragSlots.size()) && this.canDragIntoSlot(slot8)) { ItemStack itemstack14 = itemstack9.copy(); int j3 = slot8.getHasStack() ? slot8.getStack().getCount() : 0; computeStackSize(this.dragSlots, this.dragMode, itemstack14, j3); int k3 = Math.min(itemstack14.getMaxStackSize(), slot8.getItemStackLimit(itemstack14)); if (itemstack14.getCount() > k3) { itemstack14.setCount(k3); } k1 -= itemstack14.getCount() - j3; slot8.putStack(itemstack14); } } itemstack9.setCount(k1); playerinventory.setItemStack(itemstack9); } this.resetDrag(); } else { this.resetDrag(); } } else if (this.dragEvent != 0) { this.resetDrag(); } else if ((clickTypeIn == ClickType.PICKUP || clickTypeIn == ClickType.QUICK_MOVE) && (dragType == 0 || dragType == 1)) { if (slotId == -999) { if (!playerinventory.getItemStack().isEmpty()) { if (dragType == 0) { player.dropItem(playerinventory.getItemStack(), true); playerinventory.setItemStack(ItemStack.EMPTY); } if (dragType == 1) { player.dropItem(playerinventory.getItemStack().split(1), true); } } } else if (clickTypeIn == ClickType.QUICK_MOVE) { if (slotId < 0) { return ItemStack.EMPTY; } Slot slot5 = this.inventorySlots.get(slotId); if (slot5 == null || !slot5.canTakeStack(player)) { return ItemStack.EMPTY; } for(ItemStack itemstack7 = this.transferStackInSlot(player, slotId); !itemstack7.isEmpty() && ItemStack.areItemsEqual(slot5.getStack(), itemstack7); itemstack7 = this.transferStackInSlot(player, slotId)) { LOGGER.info("for loop"); LOGGER.info( !itemstack7.isEmpty() && ItemStack.areItemsEqual(slot5.getStack(), itemstack7)); itemstack = itemstack7.copy(); } } else { if (slotId < 0) { return ItemStack.EMPTY; } Slot slot6 = this.inventorySlots.get(slotId); if (slot6 != null) { ItemStack itemstack8 = slot6.getStack(); ItemStack itemstack11 = playerinventory.getItemStack(); if (!itemstack8.isEmpty()) { itemstack = itemstack8.copy(); } if (itemstack8.isEmpty()) { if (!itemstack11.isEmpty() && slot6.isItemValid(itemstack11)) { int j2 = dragType == 0 ? itemstack11.getCount() : 1; if (j2 > slot6.getItemStackLimit(itemstack11)) { j2 = slot6.getItemStackLimit(itemstack11); } slot6.putStack(itemstack11.split(j2)); } } else if (slot6.canTakeStack(player)) { if (itemstack11.isEmpty()) { if (itemstack8.isEmpty()) { slot6.putStack(ItemStack.EMPTY); playerinventory.setItemStack(ItemStack.EMPTY); } else { int k2 = dragType == 0 ? itemstack8.getCount() : (itemstack8.getCount() + 1) / 2; playerinventory.setItemStack(slot6.decrStackSize(k2)); if (itemstack8.isEmpty()) { slot6.putStack(ItemStack.EMPTY); } slot6.onTake(player, playerinventory.getItemStack()); } } else if (slot6.isItemValid(itemstack11)) { if (areItemsAndTagsEqual(itemstack8, itemstack11)) { int l2 = dragType == 0 ? itemstack11.getCount() : 1; if (l2 > slot6.getItemStackLimit(itemstack11) - itemstack8.getCount()) { l2 = slot6.getItemStackLimit(itemstack11) - itemstack8.getCount(); } if (l2 > itemstack11.getMaxStackSize() - itemstack8.getCount()) { l2 = itemstack11.getMaxStackSize() - itemstack8.getCount(); } itemstack11.shrink(l2); itemstack8.grow(l2); } else if (itemstack11.getCount() <= slot6.getItemStackLimit(itemstack11)) { slot6.putStack(itemstack11); playerinventory.setItemStack(itemstack8); } } else if (itemstack11.getMaxStackSize() > 1 && areItemsAndTagsEqual(itemstack8, itemstack11) && !itemstack8.isEmpty()) { int i3 = itemstack8.getCount(); if (i3 + itemstack11.getCount() <= itemstack11.getMaxStackSize()) { itemstack11.grow(i3); itemstack8 = slot6.decrStackSize(i3); if (itemstack8.isEmpty()) { slot6.putStack(ItemStack.EMPTY); } slot6.onTake(player, playerinventory.getItemStack()); } } } slot6.onSlotChanged(); } } } else if (clickTypeIn == ClickType.SWAP && dragType >= 0 && dragType < 9) { Slot slot4 = this.inventorySlots.get(slotId); ItemStack itemstack6 = playerinventory.getStackInSlot(dragType); ItemStack itemstack10 = slot4.getStack(); if (!itemstack6.isEmpty() || !itemstack10.isEmpty()) { if (itemstack6.isEmpty()) { if (slot4.canTakeStack(player)) { playerinventory.setInventorySlotContents(dragType, itemstack10); //slot4.onSwapCraft(itemstack10.getCount()); slot4.putStack(ItemStack.EMPTY); slot4.onTake(player, itemstack10); } } else if (itemstack10.isEmpty()) { if (slot4.isItemValid(itemstack6)) { int l1 = slot4.getItemStackLimit(itemstack6); if (itemstack6.getCount() > l1) { slot4.putStack(itemstack6.split(l1)); } else { slot4.putStack(itemstack6); playerinventory.setInventorySlotContents(dragType, ItemStack.EMPTY); } } } else if (slot4.canTakeStack(player) && slot4.isItemValid(itemstack6)) { int i2 = slot4.getItemStackLimit(itemstack6); if (itemstack6.getCount() > i2) { slot4.putStack(itemstack6.split(i2)); slot4.onTake(player, itemstack10); if (!playerinventory.addItemStackToInventory(itemstack10)) { player.dropItem(itemstack10, true); } } else { slot4.putStack(itemstack6); playerinventory.setInventorySlotContents(dragType, itemstack10); slot4.onTake(player, itemstack10); } } } } else if (clickTypeIn == ClickType.CLONE && player.abilities.isCreativeMode && playerinventory.getItemStack().isEmpty() && slotId >= 0) { Slot slot3 = this.inventorySlots.get(slotId); if (slot3 != null && slot3.getHasStack()) { ItemStack itemstack5 = slot3.getStack().copy(); itemstack5.setCount(itemstack5.getMaxStackSize()); playerinventory.setItemStack(itemstack5); } } else if (clickTypeIn == ClickType.THROW && playerinventory.getItemStack().isEmpty() && slotId >= 0) { Slot slot2 = this.inventorySlots.get(slotId); if (slot2 != null && slot2.getHasStack() && slot2.canTakeStack(player)) { ItemStack itemstack4 = slot2.decrStackSize(dragType == 0 ? 1 : slot2.getStack().getCount()); slot2.onTake(player, itemstack4); player.dropItem(itemstack4, true); } } else if (clickTypeIn == ClickType.PICKUP_ALL && slotId >= 0) { Slot slot = this.inventorySlots.get(slotId); ItemStack itemstack1 = playerinventory.getItemStack(); if (!itemstack1.isEmpty() && (slot == null || !slot.getHasStack() || !slot.canTakeStack(player))) { int i = dragType == 0 ? 0 : this.inventorySlots.size() - 1; int j = dragType == 0 ? 1 : -1; for(int k = 0; k < 2; ++k) { for(int l = i; l >= 0 && l < this.inventorySlots.size() && itemstack1.getCount() < itemstack1.getMaxStackSize(); l += j) { Slot slot1 = this.inventorySlots.get(l); if (slot1.getHasStack() && canAddItemToSlot(slot1, itemstack1, true) && slot1.canTakeStack(player) && this.canMergeSlot(itemstack1, slot1)) { ItemStack itemstack2 = slot1.getStack(); if (k != 0 || itemstack2.getCount() != itemstack2.getMaxStackSize()) { int i1 = Math.min(itemstack1.getMaxStackSize() - itemstack1.getCount(), itemstack2.getCount()); ItemStack itemstack3 = slot1.decrStackSize(i1); itemstack1.grow(i1); if (itemstack3.isEmpty()) { slot1.putStack(ItemStack.EMPTY); } slot1.onTake(player, itemstack3); } } } } } this.detectAndSendChanges(); } return itemstack; } } [SOLUTION] I needed to implement transferStackInSlot correctly. I used ChestContainer#transferStackInSlot. // copied from ChestContainer @Nonnull @Override public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) { ItemStack itemstack = ItemStack.EMPTY; Slot slot = this.inventorySlots.get(index); if (slot != null && slot.getHasStack()) { ItemStack itemstack1 = slot.getStack(); itemstack = itemstack1.copy(); if (index == 0) { if (!this.mergeItemStack(itemstack1, 1, this.inventorySlots.size(), true)) { return ItemStack.EMPTY; } } else if (!this.mergeItemStack(itemstack1, 0, 1, false)) { return ItemStack.EMPTY; } if (itemstack1.isEmpty()) { slot.putStack(ItemStack.EMPTY); } else { slot.onSlotChanged(); } } return itemstack; } Edited August 31, 20196 yr by andGarrett found solution
August 30, 20196 yr 51 minutes ago, andGarrett said: public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) { Slot slot = this.inventorySlots.get(index); return slot != null ? slot.getStack() : ItemStack.EMPTY; } This is not a proper implementation. Look at the other containers for examples. Though it is very confusing. VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
August 31, 20196 yr Author 3 hours ago, Animefan8888 said: This is not a proper implementation. Look at the other containers for examples. Though it is very confusing. After some fiddling, I was able to use ChestContainer#transferStackInSlot. Check solution at the top of the post for what I did. good luck with the youtube tutorials btw.
August 31, 20196 yr 6 minutes ago, andGarrett said: good luck with the youtube tutorials btw. Thanks I'm gonna work on a couple maybe three episodes tomorrow. VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.