blob: 0e0c1c280d1e44a08c62bc6309c1fc44817d5cb3 [file] [log] [blame] [raw]
package li.cil.oc.server.component
import li.cil.oc.api.network.Message
import li.cil.oc.common.tileentity
import net.minecraft.nbt.{NBTTagByte, NBTTagList, NBTTagCompound}
import net.minecraftforge.common.ForgeDirection
trait Redstone extends tileentity.Environment with tileentity.Persistable {
private val _input = Array.fill[Byte](6)(-1)
private val _output = Array.fill[Byte](6)(0)
private var _isOutputEnabled = true
private var _shouldUpdateInput = true
def isOutputEnabled = _isOutputEnabled
def isOutputEnabled_=(value: Boolean) = {
if (value != isOutputEnabled) {
_isOutputEnabled = value
if (!isOutputEnabled) {
for (i <- 0 until _output.length) {
_output(i) = 0.toByte
}
}
onRedstoneOutputChanged(ForgeDirection.UNKNOWN)
}
this
}
def input(side: ForgeDirection): Int
def output(side: ForgeDirection): Int = _output(side.ordinal())
def output(side: ForgeDirection, value: Int): Unit = if (value != output(side)) {
_output(side.ordinal()) = (value max 0 min 15).toByte
onRedstoneOutputChanged(side)
}
def checkRedstoneInputChanged() {
_shouldUpdateInput = true
}
// ----------------------------------------------------------------------- //
def update() {
if (_shouldUpdateInput) {
_shouldUpdateInput = false
for (side <- ForgeDirection.VALID_DIRECTIONS) {
val oldInput = _input(side.ordinal())
val newInput = input(side)
_input(side.ordinal()) = newInput.toByte
if (oldInput >= 0 && _input(side.ordinal()) != oldInput) {
onRedstoneInputChanged(side)
}
}
}
}
override def onMessage(message: Message) =
message.data match {
case Array(side: ForgeDirection) if message.name == "redstone.input" && side != ForgeDirection.UNKNOWN =>
Array(Int.box(_input(side.ordinal())))
case Array(side: ForgeDirection) if message.name == "redstone.output" && side != ForgeDirection.UNKNOWN =>
Array(Int.box(output(side)))
case Array(side: ForgeDirection, value: Integer) if message.name == "redstone.output=" && side != ForgeDirection.UNKNOWN =>
output(side, value)
Array(Boolean.box(true))
case _ => super.onMessage(message)
}
// ----------------------------------------------------------------------- //
override def load(nbt: NBTTagCompound) = {
super.load(nbt)
if (nbt.hasKey("oc.rs.input")) {
val inputNbt = nbt.getTagList("oc.rs.input")
for (i <- 0 until (_input.length min inputNbt.tagCount)) {
_input(i) = inputNbt.tagAt(i).asInstanceOf[NBTTagByte].data
}
}
if (nbt.hasKey("oc.rs.output")) {
val outputNbt = nbt.getTagList("oc.rs.output")
for (i <- 0 until (_output.length min outputNbt.tagCount)) {
_output(i) = outputNbt.tagAt(i).asInstanceOf[NBTTagByte].data
}
}
}
override def save(nbt: NBTTagCompound) = {
super.save(nbt)
val inputNbt = new NBTTagList()
for (i <- 0 until _input.length) {
inputNbt.appendTag(new NBTTagByte(null, _input(i)))
}
nbt.setTag("oc.rs.input", inputNbt)
val outputNbt = new NBTTagList()
for (i <- 0 until _output.length) {
outputNbt.appendTag(new NBTTagByte(null, _output(i)))
}
nbt.setTag("oc.rs.output", outputNbt)
}
// ----------------------------------------------------------------------- //
protected def onRedstoneInputChanged(side: ForgeDirection) {}
protected def onRedstoneOutputChanged(side: ForgeDirection) {}
}