Create

Create

86M Downloads

Basin breaks ItemHandlerHelper.insertItem's simulation mode

StevenDoesStuffs opened this issue ยท 0 comments

commented

Describe the Bug

When attempting to insert into a basin using ItemHandlerHelper.insertItem, simulating an insert will return a different result than actually doing the insert.

Reproduction Steps

Many mods use ItemHandlerHelper.insertItem with simulate=true.
For example, XNet relies heavily on insertItem being accurate, and items will disappear if it's not (see McJtyMods/XNet#522).
Pretty pipes will always try to send a full stack of items, and when the basin can't take it the items backtrack to their source.

Expected Result

ItemHandlerHelper.insertItem should return the correct result when simulating. This is kinda tricky since you can't actually modify ItemHandlerHelper, only the basin's implementation of IItemHandler. However, It'd be really nice to have compatibility since it's a part of forge many mods rely on.

Screenshots and Videos

No response

Crash Report or Log

No response

Operating System

Arch Linux

Mod Version

0.3.2g

Minecraft Version

1.16.5

Forge Version

36.2.34

Other Mods

No response

Additional Context

The culprit is this piece of code in BasinInventory:

public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
    for(int i = 0; i < this.getSlots(); ++i) {
        if (i != slot && ItemHandlerHelper.canItemStacksStack(stack, this.inv.getStackInSlot(i))) {
            return stack;
        }
    }
    return super.insertItem(slot, stack, simulate);
}

Take a look at ItemHandlerHelper.insertItem:

public static ItemStack insertItem(IItemHandler dest, @Nonnull ItemStack stack, boolean simulate)
{
    if (dest == null || stack.isEmpty())
        return stack;

    for (int i = 0; i < dest.getSlots(); i++)
    {
        stack = dest.insertItem(i, stack, simulate);
        if (stack.isEmpty())
        {
            return ItemStack.EMPTY;
        }
    }

    return stack;
}

Suppose we are attempting to insert a full stack (64) of some item. Running insertItem with simulate=true, the loop sees that it can insert 16 (max slot size for BasinInventory) items into 4 different slots, so it reports that it can insert the entire stack.
In reality, once the first 16 items are inserted, it can't insert the same type of item into any of the other slots, so it can only insert 16 items from that stack instead of 64.