diff --git a/src/main/scala/li/cil/oc/common/block/Microcontroller.scala b/src/main/scala/li/cil/oc/common/block/Microcontroller.scala index 7397115b3..c4c475bcd 100644 --- a/src/main/scala/li/cil/oc/common/block/Microcontroller.scala +++ b/src/main/scala/li/cil/oc/common/block/Microcontroller.scala @@ -3,6 +3,7 @@ package li.cil.oc.common.block import java.util import li.cil.oc.Settings +import li.cil.oc.api import li.cil.oc.client.KeyBindings import li.cil.oc.common.Tier import li.cil.oc.common.item.data.MicrocontrollerData @@ -10,6 +11,7 @@ import li.cil.oc.common.tileentity import li.cil.oc.integration.util.NEI import li.cil.oc.integration.util.Wrench import li.cil.oc.util.BlockPosition +import li.cil.oc.util.InventoryUtils import li.cil.oc.util.Rarity import net.minecraft.entity.EntityLivingBase import net.minecraft.entity.player.EntityPlayer @@ -68,16 +70,32 @@ class Microcontroller(protected implicit val tileTag: ClassTag[tileentity.Microc override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer, side: ForgeDirection, hitX: Float, hitY: Float, hitZ: Float) = { - if (!player.isSneaking && !Wrench.holdsApplicableWrench(player, BlockPosition(x, y, z))) { - if (!world.isRemote) { - world.getTileEntity(x, y, z) match { - case mcu: tileentity.Microcontroller => - if (mcu.machine.isRunning) mcu.machine.stop() - else mcu.machine.start() - case _ => + if (!Wrench.holdsApplicableWrench(player, BlockPosition(x, y, z))) { + if (!player.isSneaking) { + if (!world.isRemote) { + world.getTileEntity(x, y, z) match { + case mcu: tileentity.Microcontroller => + if (mcu.machine.isRunning) mcu.machine.stop() + else mcu.machine.start() + case _ => + } } + true } - true + else if (api.Items.get(player.getHeldItem) == api.Items.get("eeprom")) { + if (!world.isRemote) { + world.getTileEntity(x, y, z) match { + case mcu: tileentity.Microcontroller => + val newEeprom = player.inventory.decrStackSize(player.inventory.currentItem, 1) + mcu.changeEEPROM(newEeprom) match { + case Some(oldEeprom) => InventoryUtils.addToPlayerInventory(oldEeprom, player) + case _ => + } + } + } + true + } + else false } else false } diff --git a/src/main/scala/li/cil/oc/common/item/EEPROM.scala b/src/main/scala/li/cil/oc/common/item/EEPROM.scala index e9959db44..1e3d5dc89 100644 --- a/src/main/scala/li/cil/oc/common/item/EEPROM.scala +++ b/src/main/scala/li/cil/oc/common/item/EEPROM.scala @@ -1,9 +1,13 @@ package li.cil.oc.common.item import li.cil.oc.Settings +import net.minecraft.entity.player.EntityPlayer import net.minecraft.item.ItemStack +import net.minecraft.world.World class EEPROM extends SimpleItem { + override def doesSneakBypassUse(world: World, x: Int, y: Int, z: Int, player: EntityPlayer): Boolean = true + override def getItemStackDisplayName(stack: ItemStack): String = { if (stack.hasTagCompound) { val tag = stack.getTagCompound diff --git a/src/main/scala/li/cil/oc/common/item/data/MicrocontrollerData.scala b/src/main/scala/li/cil/oc/common/item/data/MicrocontrollerData.scala index a8657920f..b61ec4aba 100644 --- a/src/main/scala/li/cil/oc/common/item/data/MicrocontrollerData.scala +++ b/src/main/scala/li/cil/oc/common/item/data/MicrocontrollerData.scala @@ -17,20 +17,26 @@ class MicrocontrollerData extends ItemData { var tier = Tier.One - var components = Array.empty[ItemStack] + var components = Array[ItemStack](null) var storedEnergy = 0 override def load(nbt: NBTTagCompound) { tier = nbt.getByte(Settings.namespace + "tier") components = nbt.getTagList(Settings.namespace + "components", NBT.TAG_COMPOUND). - toArray[NBTTagCompound].map(ItemUtils.loadStack) + toArray[NBTTagCompound].map(ItemUtils.loadStack).filter(_ != null) storedEnergy = nbt.getInteger(Settings.namespace + "storedEnergy") + + // Reserve slot for EEPROM if necessary, avoids having to resize the + // components array in the MCU tile entity, which isn't possible currently. + if (!components.exists(stack => api.Items.get(stack) == api.Items.get("eeprom"))) { + components :+= null + } } override def save(nbt: NBTTagCompound) { nbt.setByte(Settings.namespace + "tier", tier.toByte) - nbt.setNewTagList(Settings.namespace + "components", components.toIterable) + nbt.setNewTagList(Settings.namespace + "components", components.filter(_ != null).toIterable) nbt.setInteger(Settings.namespace + "storedEnergy", storedEnergy) } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Microcontroller.scala b/src/main/scala/li/cil/oc/common/tileentity/Microcontroller.scala index b33b7ae67..3e5efb0a6 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Microcontroller.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Microcontroller.scala @@ -221,7 +221,9 @@ class Microcontroller extends traits.PowerAcceptor with traits.Hub with traits.C nbt.setNewCompoundTag("info", info.save) } - override lazy val items = info.components.map(Option(_)) + override def items = info.components.map(Option(_)) + + override def updateItems(slot: Int, stack: ItemStack): Unit = info.components(slot) = stack override def getSizeInventory = info.components.length @@ -232,4 +234,19 @@ class Microcontroller extends traits.PowerAcceptor with traits.Hub with traits.C // Nope. override def decrStackSize(slot: Int, amount: Int) = null + + // For hotswapping EEPROMs. + def changeEEPROM(newEeprom: ItemStack) = { + val oldEepromIndex = info.components.indexWhere(api.Items.get(_) == api.Items.get("eeprom")) + if (oldEepromIndex >= 0) { + val oldEeprom = info.components(oldEepromIndex) + super.setInventorySlotContents(oldEepromIndex, newEeprom) + Some(oldEeprom) + } + else { + assert(info.components(getSizeInventory - 1) == null) + super.setInventorySlotContents(getSizeInventory - 1, newEeprom) + None + } + } }