diff --git a/src/main/java/net/minecraftforge/items/wrapper/SidedInvWrapper.java b/src/main/java/net/minecraftforge/items/wrapper/SidedInvWrapper.java index 8b963f231a..f6266850af 100644 --- a/src/main/java/net/minecraftforge/items/wrapper/SidedInvWrapper.java +++ b/src/main/java/net/minecraftforge/items/wrapper/SidedInvWrapper.java @@ -8,18 +8,30 @@ package net.minecraftforge.items.wrapper; import net.minecraft.world.WorldlyContainer; import net.minecraft.world.item.ItemStack; import net.minecraft.core.Direction; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity; +import net.minecraft.world.level.block.entity.BrewingStandBlockEntity; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemHandlerHelper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.function.IntUnaryOperator; + public class SidedInvWrapper implements IItemHandlerModifiable { protected final WorldlyContainer inv; @Nullable protected final Direction side; + private final IntUnaryOperator slotLimit; + private final InsertLimit newStackInsertLimit; + private interface InsertLimit + { + int limitInsert(int wrapperSlot, int invSlot, ItemStack stack); + } + @SuppressWarnings("unchecked") public static LazyOptional[] create(WorldlyContainer inv, Direction... sides) { LazyOptional[] ret = new LazyOptional[sides.length]; @@ -34,6 +46,20 @@ public class SidedInvWrapper implements IItemHandlerModifiable { this.inv = inv; this.side = side; + + // A few special cases to account for canPlaceItem implementations attempting to limit specific inputs to 1, + // by returning false if there's already a contained item. This doesn't work with modded inserted sizes > 1. + // - Limit buckets to 1 in furnace fuel inputs. + // - Limit brewing stand "bottle" inputs to 1. + // Done using lambdas to avoid the overhead of instanceof checks in hot code. + if (inv instanceof BrewingStandBlockEntity) + this.slotLimit = wrapperSlot -> getSlot(inv, wrapperSlot, side) < 3 ? 1 : inv.getMaxStackSize(); + else + this.slotLimit = wrapperSlot -> inv.getMaxStackSize(); + if (inv instanceof AbstractFurnaceBlockEntity) + this.newStackInsertLimit = (wrapperSlot, invSlot, stack) -> invSlot == 1 && stack.is(Items.BUCKET) ? 1 : Math.min(stack.getMaxStackSize(), getSlotLimit(wrapperSlot)); + else + this.newStackInsertLimit = (wrapperSlot, invSlot, stack) -> Math.min(stack.getMaxStackSize(), getSlotLimit(wrapperSlot)); } public static int getSlot(WorldlyContainer inv, int slot, @Nullable Direction side) @@ -141,7 +167,8 @@ public class SidedInvWrapper implements IItemHandlerModifiable if (!inv.canPlaceItemThroughFace(slot1, stack, side) || !inv.canPlaceItem(slot1, stack)) return stack; - m = Math.min(stack.getMaxStackSize(), getSlotLimit(slot)); + m = newStackInsertLimit.limitInsert(slot, slot1, stack); + if (m < stack.getCount()) { // copy the stack to not modify the original one @@ -226,7 +253,7 @@ public class SidedInvWrapper implements IItemHandlerModifiable @Override public int getSlotLimit(int slot) { - return inv.getMaxStackSize(); + return slotLimit.applyAsInt(slot); } @Override