Jump to content

[1.8] [SOLVED] Attempt to fix mergeItemstack isn't working


TrashCaster

Recommended Posts

I'm trying to fix an issue with the mergeItemstack method found in containers.

 

The issue is that if you lower the max stack size of a slot, it does NOT get considered when merging the stacks. I aimed to fix that, only to be faced with no change.

 

    @Override
    protected boolean mergeItemStack(ItemStack stack, int startIndex, int endIndex, boolean useEndIndex) {
        boolean flag1 = false;
        int k = startIndex;

        if (useEndIndex)
        {
            k = endIndex - 1;
        }

        Slot slot;
        ItemStack itemstack1;

        if (stack.isStackable())
        {
            while (stack.stackSize > 0 && (!useEndIndex && k < endIndex || useEndIndex && k >= startIndex))
            {
                slot = (Slot)this.inventorySlots.get(k);
                itemstack1 = slot.getStack();

                if (itemstack1 != null && itemstack1.getItem() == stack.getItem() && (!stack.getHasSubtypes() || stack.getMetadata() == itemstack1.getMetadata()) && ItemStack.areItemStackTagsEqual(stack, itemstack1))
                {
                    int l = itemstack1.stackSize + stack.stackSize;

                    int maxStack = Math.min(stack.getMaxStackSize(), slot.getSlotStackLimit());
                    System.out.println("Max stack of slot "+k+" is "+maxStack);
                    if (l <= maxStack)
                    {
                        stack.stackSize = 0;
                        itemstack1.stackSize = l;
                        slot.onSlotChanged();
                        flag1 = true;
                    }
                    else if (itemstack1.stackSize < maxStack)
                    {
                        stack.stackSize -= maxStack - itemstack1.stackSize;
                        itemstack1.stackSize = maxStack;
                        slot.onSlotChanged();
                        flag1 = true;
                    } else {
                    	stack.stackSize -= maxStack;
                    	itemstack1.stackSize = maxStack;
                        slot.onSlotChanged();
                        flag1 = true;
                    }
                }

                if (useEndIndex)
                {
                    --k;
                }
                else
                {
                    ++k;
                }
            }
        }

        if (stack.stackSize > 0)
        {
            if (useEndIndex)
            {
                k = endIndex - 1;
            }
            else
            {
                k = startIndex;
            }

            while (!useEndIndex && k < endIndex || useEndIndex && k >= startIndex)
            {
                slot = (Slot)this.inventorySlots.get(k);
                itemstack1 = slot.getStack();

                if (itemstack1 == null && slot.isItemValid(stack)) // Forge: Make sure to respect isItemValid in the slot.
                {
                    slot.putStack(stack.copy());
                    slot.onSlotChanged();
                    stack.stackSize = 0;
                    flag1 = true;
                    break;
                }

                if (useEndIndex)
                {
                    --k;
                }
                else
                {
                    ++k;
                }
            }
        }

        return flag1;
    }

 

The change I made is replacing occurrences of stack.getMaxStackSize() with a variable, and using Math.min to determine the lower stack max (either from the item type, or the slot max). This does not change a thing. I also added an additional else statement with a different operation to it. That didn't help either.

 

How can I go about fixing this? Note: The purpose of this is because I want to limit the slots to 1 item per slot (which I have designated without issue), but allow shift clicking the items in, thereby allowing an inventory to fill up all the slots, if need be.

 

The current effect is that it moves the itemstack to the slot, but only 1 (the maximum of that slot) is actually there. It should carry on through the other slots, filling them up, and then finally leaving any left over items where it was.

Link to comment
Share on other sites

I stole this from somewhere, I don't remember where.

 

	@Override
protected boolean mergeItemStack(ItemStack itemstack, int i, int j, boolean flag) {
	// The default implementation in Slot doesn't take into account the Slot.isItemValid() and Slot.getSlotStackLimit() values.
	// So here is a modified implementation. I have only modified the parts with a comment.

	boolean flag1 = false;
	int k = i;
	if (flag) {
		k = j - 1;
	}
	if (itemstack.isStackable()) {
		while (itemstack.stackSize > 0 && (!flag && k < j || flag && k >= i)) {
			Slot slot = (Slot)inventorySlots.get(k);
			ItemStack itemstack1 = slot.getStack();

			if (flag) {
				k--;
			}
			else {
				k++;
			}

			// Check if item is valid:
			if (!slot.isItemValid(itemstack)) {
				continue;
			}

			if (itemstack1 != null && itemstack1.getItem() == itemstack.getItem() && (!itemstack.getHasSubtypes() || itemstack.getItemDamage() == itemstack1.getItemDamage())
					&& ItemStack.areItemStackTagsEqual(itemstack, itemstack1)) {
				//ItemStack.areItemStacksEqual(par0ItemStack, par1ItemStack)
				//ItemStack.areItemStackTagsEqual(par0ItemStack, par1ItemStack)
				int i1 = itemstack1.stackSize + itemstack.stackSize;

				// Don't put more items than the slot can take:
				int maxItemsInDest = Math.min(itemstack1.getMaxStackSize(), slot.getSlotStackLimit());

				if (i1 <= maxItemsInDest) {
					itemstack.stackSize = 0;
					itemstack1.stackSize = i1;
					slot.onSlotChanged();
					flag1 = true;
				}
				else if (itemstack1.stackSize < maxItemsInDest) {
					itemstack.stackSize -= maxItemsInDest - itemstack1.stackSize;
					itemstack1.stackSize = maxItemsInDest;
					slot.onSlotChanged();
					flag1 = true;
				}
			}

		}
	}
	if (itemstack.stackSize > 0) {
		int l;
		if (flag) {
			l = j - 1;
		}
		else {
			l = i;
		}
		do {
			if ((flag || l >= j) && (!flag || l < i)) {
				break;
			}
			Slot slot1 = (Slot)inventorySlots.get(l);
			ItemStack itemstack2 = slot1.getStack();

			if (flag) {
				l--;
			}
			else {
				l++;
			}

			// Check if item is valid:
			if (!slot1.isItemValid(itemstack)) {
				continue;
			}

			if (itemstack2 == null) {

				// Don't put more items than the slot can take:
				int nbItemsInDest = Math.min(itemstack.stackSize, slot1.getSlotStackLimit());
				ItemStack itemStack1 = itemstack.copy();
				itemstack.stackSize -= nbItemsInDest;
				itemStack1.stackSize = nbItemsInDest;

				slot1.putStack(itemStack1);
				slot1.onSlotChanged();
				// itemstack.stackSize = 0;
				flag1 = true;
				break;
			}
		} while (true);
	}
	return flag1;
}

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

I stole this from somewhere, I don't remember where.

 

	@Override
protected boolean mergeItemStack(ItemStack itemstack, int i, int j, boolean flag) {
	// The default implementation in Slot doesn't take into account the Slot.isItemValid() and Slot.getSlotStackLimit() values.
	// So here is a modified implementation. I have only modified the parts with a comment.

	boolean flag1 = false;
	int k = i;
	if (flag) {
		k = j - 1;
	}
	if (itemstack.isStackable()) {
		while (itemstack.stackSize > 0 && (!flag && k < j || flag && k >= i)) {
			Slot slot = (Slot)inventorySlots.get(k);
			ItemStack itemstack1 = slot.getStack();

			if (flag) {
				k--;
			}
			else {
				k++;
			}

			// Check if item is valid:
			if (!slot.isItemValid(itemstack)) {
				continue;
			}

			if (itemstack1 != null && itemstack1.getItem() == itemstack.getItem() && (!itemstack.getHasSubtypes() || itemstack.getItemDamage() == itemstack1.getItemDamage())
					&& ItemStack.areItemStackTagsEqual(itemstack, itemstack1)) {
				//ItemStack.areItemStacksEqual(par0ItemStack, par1ItemStack)
				//ItemStack.areItemStackTagsEqual(par0ItemStack, par1ItemStack)
				int i1 = itemstack1.stackSize + itemstack.stackSize;

				// Don't put more items than the slot can take:
				int maxItemsInDest = Math.min(itemstack1.getMaxStackSize(), slot.getSlotStackLimit());

				if (i1 <= maxItemsInDest) {
					itemstack.stackSize = 0;
					itemstack1.stackSize = i1;
					slot.onSlotChanged();
					flag1 = true;
				}
				else if (itemstack1.stackSize < maxItemsInDest) {
					itemstack.stackSize -= maxItemsInDest - itemstack1.stackSize;
					itemstack1.stackSize = maxItemsInDest;
					slot.onSlotChanged();
					flag1 = true;
				}
			}

		}
	}
	if (itemstack.stackSize > 0) {
		int l;
		if (flag) {
			l = j - 1;
		}
		else {
			l = i;
		}
		do {
			if ((flag || l >= j) && (!flag || l < i)) {
				break;
			}
			Slot slot1 = (Slot)inventorySlots.get(l);
			ItemStack itemstack2 = slot1.getStack();

			if (flag) {
				l--;
			}
			else {
				l++;
			}

			// Check if item is valid:
			if (!slot1.isItemValid(itemstack)) {
				continue;
			}

			if (itemstack2 == null) {

				// Don't put more items than the slot can take:
				int nbItemsInDest = Math.min(itemstack.stackSize, slot1.getSlotStackLimit());
				ItemStack itemStack1 = itemstack.copy();
				itemstack.stackSize -= nbItemsInDest;
				itemStack1.stackSize = nbItemsInDest;

				slot1.putStack(itemStack1);
				slot1.onSlotChanged();
				// itemstack.stackSize = 0;
				flag1 = true;
				break;
			}
		} while (true);
	}
	return flag1;
}

 

AWESOME! Thank you SO much.

 

Maybe someone should submit a PR? I don't know why this was overlooked.

Link to comment
Share on other sites

Not sure. That's what I use in my container class.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.