Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

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.

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.

  • Author

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.

  • Author

Ok, for whatever reason, it stopped working. I have no idea why. It worked one time, and now it doesn't, and I haven't changed anything.

:o

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.

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...

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.