blob: 723158ff8e9f3d2b106527efa5f634b2b6ae3330 [file] [log] [blame] [raw]
package li.cil.oc.common.tileentity
import cpw.mods.fml.relauncher.Side
import cpw.mods.fml.relauncher.SideOnly
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.api.network.Visibility
import li.cil.oc.common.EventHandler
import li.cil.oc.server.{PacketSender => ServerPacketSender}
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.ForgeDirection
class NetSplitter extends traits.Environment with traits.RedstoneAware with api.network.SidedEnvironment {
private final val SideCount = ForgeDirection.VALID_DIRECTIONS.length
_isOutputEnabled = true
val node = api.Network.newNode(this, Visibility.None).
create()
var isInverted = false
var openSides = Array.fill(SideCount)(false)
def compressSides = (ForgeDirection.VALID_DIRECTIONS, openSides).zipped.foldLeft(0)((acc, entry) => acc | (if (entry._2) entry._1.flag else 0)).toByte
def uncompressSides(byte: Byte) = ForgeDirection.VALID_DIRECTIONS.map(d => (d.flag & byte) != 0)
def isSideOpen(side: ForgeDirection) = side != ForgeDirection.UNKNOWN && {
val isOpen = openSides(side.ordinal())
if (isInverted) !isOpen else isOpen
}
def setSideOpen(side: ForgeDirection, value: Boolean): Unit = if (side != ForgeDirection.UNKNOWN && openSides(side.ordinal()) != value) {
openSides(side.ordinal()) = value
if (isServer) {
node.remove()
api.Network.joinOrCreateNetwork(this)
ServerPacketSender.sendNetSplitterState(this)
world.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, "tile.piston.out", 0.5f, world.rand.nextFloat() * 0.25f + 0.7f)
world.notifyBlocksOfNeighborChange(x, y, z, block)
}
else {
world.markBlockForUpdate(x, y, z)
}
}
// ----------------------------------------------------------------------- //
override def sidedNode(side: ForgeDirection) = if (isSideOpen(side)) node else null
@SideOnly(Side.CLIENT)
override def canConnect(side: ForgeDirection) = isSideOpen(side)
// ----------------------------------------------------------------------- //
override def canUpdate = false
override protected def initialize(): Unit = {
super.initialize()
EventHandler.scheduleServer(this)
}
// ----------------------------------------------------------------------- //
override protected def onRedstoneInputChanged(side: ForgeDirection, oldMaxValue: Int, newMaxValue: Int): Unit = {
super.onRedstoneInputChanged(side, oldMaxValue, newMaxValue)
val oldIsInverted = isInverted
isInverted = newMaxValue > 0
if (isInverted != oldIsInverted) {
if (isServer) {
node.remove()
api.Network.joinOrCreateNetwork(this)
ServerPacketSender.sendNetSplitterState(this)
world.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, "tile.piston.in", 0.5f, world.rand.nextFloat() * 0.25f + 0.7f)
}
else {
world.markBlockForUpdate(x, y, z)
}
}
}
override def readFromNBTForServer(nbt: NBTTagCompound): Unit = {
super.readFromNBTForServer(nbt)
isInverted = nbt.getBoolean(Settings.namespace + "isInverted")
openSides = uncompressSides(nbt.getByte(Settings.namespace + "openSides"))
}
override def writeToNBTForServer(nbt: NBTTagCompound): Unit = {
super.writeToNBTForServer(nbt)
nbt.setBoolean(Settings.namespace + "isInverted", isInverted)
nbt.setByte(Settings.namespace + "openSides", compressSides)
}
@SideOnly(Side.CLIENT) override
def readFromNBTForClient(nbt: NBTTagCompound): Unit = {
super.readFromNBTForClient(nbt)
isInverted = nbt.getBoolean(Settings.namespace + "isInverted")
openSides = uncompressSides(nbt.getByte(Settings.namespace + "openSides"))
}
override def writeToNBTForClient(nbt: NBTTagCompound): Unit = {
super.writeToNBTForClient(nbt)
nbt.setBoolean(Settings.namespace + "isInverted", isInverted)
nbt.setByte(Settings.namespace + "openSides", compressSides)
}
}