blob: 573cba4bd9554f875dee281a4850105444fdde88 [file] [log] [blame] [raw]
package li.cil.oc.common.tileentity
import li.cil.oc.api.driver
import li.cil.oc.api.network.Node
import li.cil.oc.server.driver.Registry
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.nbt.NBTTagList
import net.minecraft.world.World
trait ComponentInventory extends Inventory with Node {
protected val components = Array.fill[Option[Node]](getSizeInventory)(None)
def world: World
// ----------------------------------------------------------------------- //
def installedMemory = inventory.foldLeft(0)((sum, stack) => sum + (stack match {
case Some(item) => Registry.driverFor(item) match {
case Some(driver: driver.Memory) => driver.amount(item)
case _ => 0
}
case _ => 0
}))
// ----------------------------------------------------------------------- //
override protected def onConnect() {
super.onConnect()
components collect {
case Some(node) => network.foreach(_.connect(this, node))
}
}
override protected def onDisconnect() {
super.onDisconnect()
components collect {
case Some(node) => node.network.foreach(_.remove(node))
}
}
// ----------------------------------------------------------------------- //
override abstract def readFromNBT(nbt: NBTTagCompound) = {
super.readFromNBT(nbt)
val list = nbt.getTagList("list")
for (i <- 0 until list.tagCount) {
val slotNbt = list.tagAt(i).asInstanceOf[NBTTagCompound]
val slot = slotNbt.getByte("slot")
if (slot >= 0 && slot < inventory.length) {
val item = ItemStack.loadItemStackFromNBT(slotNbt.getCompoundTag("item"))
inventory(slot) = Some(item)
components(slot) = Registry.driverFor(item) match {
case Some(driver) =>
driver.node(item) match {
case null => None
case node =>
node.readFromNBT(driver.nbt(item))
Some(node)
}
case _ => None
}
}
}
}
override abstract def writeToNBT(nbt: NBTTagCompound) = {
super.writeToNBT(nbt)
val list = new NBTTagList
inventory.zipWithIndex collect {
case (Some(stack), slot) => (stack, slot)
} foreach {
case (stack, slot) => {
val slotNbt = new NBTTagCompound
slotNbt.setByte("slot", slot.toByte)
components(slot) match {
case Some(node) =>
// We're guaranteed to have a driver for entries.
node.writeToNBT(Registry.driverFor(stack).get.nbt(stack))
case _ => // Nothing special to save.
}
val itemNbt = new NBTTagCompound
stack.writeToNBT(itemNbt)
slotNbt.setCompoundTag("item", itemNbt)
list.appendTag(slotNbt)
}
}
nbt.setTag("list", list)
}
// ----------------------------------------------------------------------- //
def getInventoryStackLimit = 1
override protected def onItemAdded(slot: Int, item: ItemStack) = if (!world.isRemote) {
Registry.driverFor(item) match {
case None => // No driver.
case Some(driver) => driver.node(item) match {
case null => // No node.
case node =>
components(slot) = Some(node)
node.readFromNBT(driver.nbt(item))
network.foreach(_.connect(this, node))
}
}
}
override protected def onItemRemoved(slot: Int, item: ItemStack) = if (!world.isRemote) {
// Uninstall component previously in that slot.
components(slot) match {
case Some(node) =>
// Note to self: we have to remove the node from the network *before*
// saving, to allow file systems to close their handles before they
// are saved (otherwise hard drives would restore all handles after
// being installed into a different computer, even!)
components(slot) = None
node.network.foreach(_.remove(node))
Registry.driverFor(item).foreach(driver => node.writeToNBT(driver.nbt(item)))
case _ => // Nothing to do.
}
}
}