blob: 445c3bd699c4ed6c97fd8e7c6995af7367094468 [file] [log] [blame] [raw]
package li.cil.oc.util
import net.minecraft.world.World
import net.minecraft.item.ItemStack
import net.minecraft.tileentity.TileEntityChest
import net.minecraft.block.Block
import net.minecraft.inventory.{IInventory, ISidedInventory}
import net.minecraft.entity.item.EntityMinecartContainer
import net.minecraft.util.AxisAlignedBB
import scala.collection.convert.WrapAsScala._
import net.minecraftforge.common.ForgeDirection
object InventoryUtils {
def tryDropIntoInventoryAt(stack: ItemStack, world: World, x: Int, y: Int, z: Int, side: ForgeDirection): Boolean = {
world.getBlockTileEntity(x, y, z) match {
case chest: TileEntityChest =>
val inventory = Block.chest.getInventory(world, chest.xCoord, chest.yCoord, chest.zCoord)
tryDropIntoInventory(stack, inventory, side)
case inventory: ISidedInventory =>
tryDropIntoInventory(stack, inventory, side)
case inventory: IInventory =>
tryDropIntoInventory(stack, inventory, side)
case _ =>
val mineCarts = world.getEntitiesWithinAABB(classOf[EntityMinecartContainer],
AxisAlignedBB.getBoundingBox(x, y, z, x + 1, y + 1, z + 1)).
map(_.asInstanceOf[EntityMinecartContainer])
for (inventory <- mineCarts if !inventory.isDead) {
if (tryDropIntoInventory(stack, inventory, side)) {
return true
}
}
false
}
}
def tryDropIntoInventory(stack: ItemStack, inventory: IInventory, side: ForgeDirection) = {
def isSideValidForSlot: (Int) => Boolean = inventory match {
case inventory: ISidedInventory => (slot) => inventory.canInsertItem(slot, stack, side.ordinal)
case _ => (slot) => true
}
var success = false
val maxStackSize = math.min(inventory.getInventoryStackLimit, stack.getMaxStackSize)
val shouldTryMerge = !stack.isItemStackDamageable && stack.getMaxStackSize > 1 && inventory.getInventoryStackLimit > 1
if (shouldTryMerge) {
for (slot <- 0 until inventory.getSizeInventory if stack.stackSize > 0 && inventory.isItemValidForSlot(slot, stack) && isSideValidForSlot(slot)) {
val existing = inventory.getStackInSlot(slot)
val shouldMerge = existing != null && existing.stackSize < maxStackSize &&
existing.isItemEqual(stack) && ItemStack.areItemStackTagsEqual(existing, stack)
if (shouldMerge) {
val space = maxStackSize - existing.stackSize
val amount = math.min(space, stack.stackSize)
assert(amount > 0)
success = true
existing.stackSize += amount
stack.stackSize -= amount
}
}
}
for (slot <- 0 until inventory.getSizeInventory if stack.stackSize > 0 && inventory.getStackInSlot(slot) == null && inventory.isItemValidForSlot(slot, stack) && isSideValidForSlot(slot)) {
val amount = math.min(maxStackSize, stack.stackSize)
inventory.setInventorySlotContents(slot, stack.splitStack(amount))
success = true
}
if (success) {
inventory.onInventoryChanged()
}
success
}
}