Skip to content

Instantly share code, notes, and snippets.

@Mordenkainen
Last active October 28, 2015 02:48
Show Gist options
  • Save Mordenkainen/e3bed90e969121ca5b8e to your computer and use it in GitHub Desktop.
Save Mordenkainen/e3bed90e969121ca5b8e to your computer and use it in GitHub Desktop.
// Much of this code was taken from EnderIO
// This should work for any IInventory or ISidedInventory
public int insert(ItemStack stack, TileEntity tile, ForgeDirection from) {
int numInserted = 0;
if(tile != null && tile instanceof IInventory && stack != null) {
int numToInsert = stack.stackSize;
int firstFreeSlot = -1;
int[] slots = getSlots(tile, from);
IInventory inv = getInventory((IInventory)tile);
ISidedInventory sidedInv = null;
if(tile instanceof ISidedInventory) {
sidedInv = (ISidedInventory)tile;
}
// Try to add to an existing stack in the inventory
for(int slot : slots) {
if(numToInsert <= 0) {
break;
}
if (sidedInv == null || sidedInv.canInsertItem(slot, stack, from.ordinal())) {
final ItemStack contents = inv.getStackInSlot(slot);
if (contents != null) {
if (ItemUtils.areStacksMergable(contents, stack)) {
final int freeSpace = Math.min(inv.getInventoryStackLimit(), contents.getMaxStackSize()) - contents.stackSize;
if (freeSpace > 0) {
final int noToInsert = Math.min(numToInsert, freeSpace);
final ItemStack toInsert = stack.copy();
toInsert.stackSize = contents.stackSize + noToInsert;
if (sidedInv != null || inv.isItemValidForSlot(slot, toInsert)) {
numInserted += noToInsert;
numToInsert -= noToInsert;
inv.setInventorySlotContents(slot, toInsert);
}
}
}
} else if (firstFreeSlot == -1) {
firstFreeSlot = slot;
}
}
}
// Try to insert into an empty slot
if (numToInsert > 0 && firstFreeSlot != -1) {
final ItemStack toInsert = stack.copy();
toInsert.stackSize = min(numToInsert, inv.getInventoryStackLimit(), toInsert.getMaxStackSize());
if (sidedInv != null || inv.isItemValidForSlot(firstFreeSlot, toInsert)) {
numInserted += toInsert.stackSize;
numToInsert -= toInsert.stackSize;
inv.setInventorySlotContents(firstFreeSlot, toInsert);
}
}
if (numInserted > 0) {
inv.markDirty();
}
}
return numInserted;
}
private static int[] getSlots(TileEntity tile, ForgeDirection from) {
if(tile instanceof ISidedInventory) {
return ((ISidedInventory)tile).getAccessibleSlotsFromSide(from.ordinal());
} else {
return Ints.toArray(ContiguousSet.create(Range.closed(0, getInventory((IInventory)tile).getSizeInventory() - 1), DiscreteDomain.integers()));
}
}
private static IInventory getInventory(IInventory inv) {
if (inv instanceof TileEntityChest) {
TileEntityChest chest = (TileEntityChest) inv;
TileEntityChest neighbour = null;
if (chest.adjacentChestXNeg != null) {
neighbour = chest.adjacentChestXNeg;
} else if (chest.adjacentChestXPos != null) {
neighbour = chest.adjacentChestXPos;
} else if (chest.adjacentChestZNeg != null) {
neighbour = chest.adjacentChestZNeg;
} else if (chest.adjacentChestZPos != null) {
neighbour = chest.adjacentChestZPos;
}
if (neighbour != null) {
return new InventoryLargeChest("", inv, neighbour);
}
}
return inv;
}
private static boolean validForSlot(IInventory inv, int slot, ForgeDirection from, ItemStack stack) {
if(inv instanceof ISidedInventory) {
return inv.isItemValidForSlot(slot, stack) && ((ISidedInventory)inv).canInsertItem(slot, stack, from.ordinal());
} else {
return inv.isItemValidForSlot(slot, stack);
}
}
private final static int min(int i1, int i2, int i3) {
return i1 < i2 ? (i1 < i3 ? i1 : i3) : (i2 < i3 ? i2 : i3);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment