Made wrenching an Adapter's side turn it off.

For #1851.
No texture changes yet, but client sync is in place.
This commit is contained in:
Vexatos 2016-07-09 17:48:41 +02:00
parent 1fdd30ae72
commit c4fa6f157e
7 changed files with 122 additions and 27 deletions

View File

@ -42,6 +42,7 @@ object PacketHandler extends CommonPacketHandler {
override def dispatch(p: PacketParser) { override def dispatch(p: PacketParser) {
p.packetType match { p.packetType match {
case PacketType.AbstractBusState => onAbstractBusState(p) case PacketType.AbstractBusState => onAbstractBusState(p)
case PacketType.AdapterState => onAdapterState(p)
case PacketType.Analyze => onAnalyze(p) case PacketType.Analyze => onAnalyze(p)
case PacketType.ChargerState => onChargerState(p) case PacketType.ChargerState => onChargerState(p)
case PacketType.ClientLog => onClientLog(p) case PacketType.ClientLog => onClientLog(p)
@ -102,6 +103,14 @@ object PacketHandler extends CommonPacketHandler {
case _ => // Invalid packet. case _ => // Invalid packet.
} }
def onAdapterState(p: PacketParser) =
p.readTileEntity[Adapter]() match {
case Some(t) =>
t.openSides = t.uncompressSides(p.readByte())
t.world.markBlockForUpdate(t.x, t.y, t.z)
case _ => // Invalid packet.
}
def onAnalyze(p: PacketParser) { def onAnalyze(p: PacketParser) {
val address = p.readUTF() val address = p.readUTF()
if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_LCONTROL)) { if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_LCONTROL)) {

View File

@ -4,6 +4,7 @@ object PacketType extends Enumeration {
val val
// Server -> Client // Server -> Client
AbstractBusState, AbstractBusState,
AdapterState,
Analyze, Analyze,
ChargerState, ChargerState,
ClientLog, ClientLog,

View File

@ -2,7 +2,10 @@ package li.cil.oc.common.block
import li.cil.oc.common.GuiType import li.cil.oc.common.GuiType
import li.cil.oc.common.tileentity import li.cil.oc.common.tileentity
import li.cil.oc.integration.util.Wrench
import li.cil.oc.util.BlockPosition
import net.minecraft.block.Block import net.minecraft.block.Block
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.world.IBlockAccess import net.minecraft.world.IBlockAccess
import net.minecraft.world.World import net.minecraft.world.World
import net.minecraftforge.common.util.ForgeDirection import net.minecraftforge.common.util.ForgeDirection
@ -44,6 +47,22 @@ class Adapter extends SimpleBlock with traits.GUI {
case _ => // Ignore. case _ => // Ignore.
} }
override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer, side: ForgeDirection, hitX: Float, hitY: Float, hitZ: Float) = {
if (Wrench.holdsApplicableWrench(player, BlockPosition(x, y, z))) {
val sideToToggle = if (player.isSneaking) side.getOpposite else side
world.getTileEntity(x, y, z) match {
case adapter: tileentity.Adapter =>
if (!world.isRemote) {
val oldValue = adapter.openSides(sideToToggle.ordinal())
adapter.setSideOpen(sideToToggle, !oldValue)
}
true
case _ => false
}
}
else super.onBlockActivated(world, x, y, z, player, side, hitX, hitY, hitZ)
}
private val sides = Array( private val sides = Array(
ForgeDirection.NORTH, ForgeDirection.NORTH,
ForgeDirection.DOWN, ForgeDirection.DOWN,

View File

@ -13,6 +13,7 @@ import li.cil.oc.api.internal
import li.cil.oc.api.network.Analyzable import li.cil.oc.api.network.Analyzable
import li.cil.oc.api.network._ import li.cil.oc.api.network._
import li.cil.oc.common.Slot import li.cil.oc.common.Slot
import li.cil.oc.server.{PacketSender => ServerPacketSender}
import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
@ -23,7 +24,7 @@ import net.minecraftforge.common.util.ForgeDirection
import scala.collection.convert.WrapAsJava._ import scala.collection.convert.WrapAsJava._
import scala.collection.mutable import scala.collection.mutable
class Adapter extends traits.Environment with traits.ComponentInventory with Analyzable with internal.Adapter with DeviceInfo { class Adapter extends traits.Environment with traits.ComponentInventory with traits.OpenSides with Analyzable with internal.Adapter with DeviceInfo {
val node = api.Network.newNode(this, Visibility.Network).create() val node = api.Network.newNode(this, Visibility.Network).create()
private val blocks = Array.fill[Option[(ManagedEnvironment, api.driver.SidedBlock)]](6)(None) private val blocks = Array.fill[Option[(ManagedEnvironment, api.driver.SidedBlock)]](6)(None)
@ -43,6 +44,22 @@ class Adapter extends traits.Environment with traits.ComponentInventory with Ana
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override protected def defaultState = true
override def setSideOpen(side: ForgeDirection, value: Boolean) {
super.setSideOpen(side, value)
if (isServer) {
ServerPacketSender.sendAdapterState(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)
neighborChanged(side)
} else {
world.markBlockForUpdate(x, y, z)
}
}
// ----------------------------------------------------------------------- //
override def onAnalyze(player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = blocks collect { override def onAnalyze(player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = blocks collect {
case Some(((environment, _))) => environment.node case Some(((environment, _))) => environment.node
} }
@ -74,6 +91,14 @@ class Adapter extends traits.Environment with traits.ComponentInventory with Ana
Option(api.Driver.driverFor(world, x, y, z, d)) match { Option(api.Driver.driverFor(world, x, y, z, d)) match {
case Some(newDriver) => blocks(d.ordinal()) match { case Some(newDriver) => blocks(d.ordinal()) match {
case Some((oldEnvironment, driver)) => case Some((oldEnvironment, driver)) =>
if(!isSideOpen(d)) {
// Good bye.
blocks(d.ordinal()) = None
updatingBlocks -= oldEnvironment
blocksData(d.ordinal()) = None
node.disconnect(oldEnvironment.node)
return
}
if (newDriver != driver) { if (newDriver != driver) {
// This is... odd. Maybe moved by some other mod? First, clean up. // This is... odd. Maybe moved by some other mod? First, clean up.
blocks(d.ordinal()) = None blocks(d.ordinal()) = None
@ -92,7 +117,7 @@ class Adapter extends traits.Environment with traits.ComponentInventory with Ana
node.connect(environment.node) node.connect(environment.node)
} }
} // else: the more things change, the more they stay the same. } // else: the more things change, the more they stay the same.
case _ => case _ if isSideOpen(d) =>
// A challenger appears. Maybe. // A challenger appears. Maybe.
val environment = newDriver.createEnvironment(world, x, y, z, d) val environment = newDriver.createEnvironment(world, x, y, z, d)
if (environment != null) { if (environment != null) {

View File

@ -1,17 +1,14 @@
package li.cil.oc.common.tileentity package li.cil.oc.common.tileentity
import cpw.mods.fml.relauncher.Side import cpw.mods.fml.relauncher.{Side, SideOnly}
import cpw.mods.fml.relauncher.SideOnly import li.cil.oc.{Settings, api}
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.api.network.Visibility import li.cil.oc.api.network.Visibility
import li.cil.oc.common.EventHandler import li.cil.oc.common.EventHandler
import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.server.{PacketSender => ServerPacketSender}
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.ForgeDirection import net.minecraftforge.common.util.ForgeDirection
class NetSplitter extends traits.Environment with traits.RedstoneAware with api.network.SidedEnvironment { class NetSplitter extends traits.Environment with traits.OpenSides with traits.RedstoneAware with api.network.SidedEnvironment {
private final val SideCount = ForgeDirection.VALID_DIRECTIONS.length
_isOutputEnabled = true _isOutputEnabled = true
@ -20,19 +17,10 @@ class NetSplitter extends traits.Environment with traits.RedstoneAware with api.
var isInverted = false var isInverted = false
var openSides = Array.fill(SideCount)(false) override def isSideOpen(side: ForgeDirection) = if (isInverted) !super.isSideOpen(side) else super.isSideOpen(side)
def compressSides = (ForgeDirection.VALID_DIRECTIONS, openSides).zipped.foldLeft(0)((acc, entry) => acc | (if (entry._2) entry._1.flag else 0)).toByte override def setSideOpen(side: ForgeDirection, value: Boolean) {
super.setSideOpen(side, value)
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) { if (isServer) {
node.remove() node.remove()
api.Network.joinOrCreateNetwork(this) api.Network.joinOrCreateNetwork(this)
@ -83,25 +71,21 @@ class NetSplitter extends traits.Environment with traits.RedstoneAware with api.
override def readFromNBTForServer(nbt: NBTTagCompound): Unit = { override def readFromNBTForServer(nbt: NBTTagCompound): Unit = {
super.readFromNBTForServer(nbt) super.readFromNBTForServer(nbt)
isInverted = nbt.getBoolean(Settings.namespace + "isInverted") isInverted = nbt.getBoolean(Settings.namespace + "isInverted")
openSides = uncompressSides(nbt.getByte(Settings.namespace + "openSides"))
} }
override def writeToNBTForServer(nbt: NBTTagCompound): Unit = { override def writeToNBTForServer(nbt: NBTTagCompound): Unit = {
super.writeToNBTForServer(nbt) super.writeToNBTForServer(nbt)
nbt.setBoolean(Settings.namespace + "isInverted", isInverted) nbt.setBoolean(Settings.namespace + "isInverted", isInverted)
nbt.setByte(Settings.namespace + "openSides", compressSides)
} }
@SideOnly(Side.CLIENT) override @SideOnly(Side.CLIENT) override
def readFromNBTForClient(nbt: NBTTagCompound): Unit = { def readFromNBTForClient(nbt: NBTTagCompound): Unit = {
super.readFromNBTForClient(nbt) super.readFromNBTForClient(nbt)
isInverted = nbt.getBoolean(Settings.namespace + "isInverted") isInverted = nbt.getBoolean(Settings.namespace + "isInverted")
openSides = uncompressSides(nbt.getByte(Settings.namespace + "openSides"))
} }
override def writeToNBTForClient(nbt: NBTTagCompound): Unit = { override def writeToNBTForClient(nbt: NBTTagCompound): Unit = {
super.writeToNBTForClient(nbt) super.writeToNBTForClient(nbt)
nbt.setBoolean(Settings.namespace + "isInverted", isInverted) nbt.setBoolean(Settings.namespace + "isInverted", isInverted)
nbt.setByte(Settings.namespace + "openSides", compressSides)
} }
} }

View File

@ -0,0 +1,48 @@
package li.cil.oc.common.tileentity.traits
import cpw.mods.fml.relauncher.{Side, SideOnly}
import li.cil.oc.Settings
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.ForgeDirection
/**
* @author Vexatos
*/
trait OpenSides extends TileEntity {
protected def SideCount = ForgeDirection.VALID_DIRECTIONS.length
protected def defaultState: Boolean = false
var openSides = Array.fill(SideCount)(defaultState)
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 && openSides(side.ordinal())
def setSideOpen(side: ForgeDirection, value: Boolean): Unit = if (side != ForgeDirection.UNKNOWN && openSides(side.ordinal()) != value) {
openSides(side.ordinal()) = value
}
override def readFromNBTForServer(nbt: NBTTagCompound) {
super.readFromNBTForServer(nbt)
openSides = uncompressSides(nbt.getByte(Settings.namespace + "openSides"))
}
override def writeToNBTForServer(nbt: NBTTagCompound) {
super.writeToNBTForServer(nbt)
nbt.setByte(Settings.namespace + "openSides", compressSides)
}
@SideOnly(Side.CLIENT)
override def readFromNBTForClient(nbt: NBTTagCompound) {
super.readFromNBTForClient(nbt)
openSides = uncompressSides(nbt.getByte(Settings.namespace + "openSides"))
}
override def writeToNBTForClient(nbt: NBTTagCompound) {
super.writeToNBTForClient(nbt)
nbt.setByte(Settings.namespace + "openSides", compressSides)
}
}

View File

@ -32,6 +32,15 @@ object PacketSender {
pb.sendToPlayersNearTileEntity(t) pb.sendToPlayersNearTileEntity(t)
} }
def sendAdapterState(t: tileentity.Adapter): Unit = {
val pb = new SimplePacketBuilder(PacketType.AdapterState)
pb.writeTileEntity(t)
pb.writeByte(t.compressSides)
pb.sendToPlayersNearTileEntity(t)
}
def sendAnalyze(address: String, player: EntityPlayerMP) { def sendAnalyze(address: String, player: EntityPlayerMP) {
val pb = new SimplePacketBuilder(PacketType.Analyze) val pb = new SimplePacketBuilder(PacketType.Analyze)