diff --git a/src/main/scala/li/cil/oc/common/nanomachines/ControllerImpl.scala b/src/main/scala/li/cil/oc/common/nanomachines/ControllerImpl.scala index 61b7dd3e9..9618b3ac4 100644 --- a/src/main/scala/li/cil/oc/common/nanomachines/ControllerImpl.scala +++ b/src/main/scala/li/cil/oc/common/nanomachines/ControllerImpl.scala @@ -67,7 +67,7 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE override def receivePacket(packet: Packet, sender: WirelessEndpoint): Unit = { if (getLocalBuffer > 0 && commandDelay < 1 && !player.isDead) { val (dx, dy, dz) = ((sender.x + 0.5) - player.posX, (sender.y + 0.5) - player.posY, (sender.z + 0.5) - player.posZ) - val dSquared = dx * dx + dy * dy + dz * dz + val dSquared = Math.sqrt(dx * dx + dy * dy + dz * dz) if (dSquared <= CommandRange) packet.data.headOption match { case Some(header: Array[Byte]) if new String(header, Charsets.UTF_8) == "nanomachines" => val command = packet.data.drop(1).map { diff --git a/src/main/scala/li/cil/oc/common/nanomachines/provider/PotionProvider.scala b/src/main/scala/li/cil/oc/common/nanomachines/provider/PotionProvider.scala index 7b1283abe..96947572e 100644 --- a/src/main/scala/li/cil/oc/common/nanomachines/provider/PotionProvider.scala +++ b/src/main/scala/li/cil/oc/common/nanomachines/provider/PotionProvider.scala @@ -57,7 +57,7 @@ object PotionProvider extends ScalaProvider("c29e4eec-5a46-479a-9b3d-ad0f06da784 } override def update(): Unit = { - player.addPotionEffect(new PotionEffect(potion, Duration, amplifier(player))) + player.addPotionEffect(new PotionEffect(potion, Duration, if (Settings.get.enableNanomachinePfx) amplifier(player) else -1)) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Adapter.scala b/src/main/scala/li/cil/oc/common/tileentity/Adapter.scala index db0522e10..cae5dc1ad 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Adapter.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Adapter.scala @@ -81,7 +81,7 @@ class Adapter extends traits.Environment with traits.ComponentInventory with tra if (node != null && node.network != null) { val blockPos = getPos.offset(d) world.getTileEntity(blockPos) match { - case env: traits.Environment => + case _: traits.Environment => // Don't provide adaption for our stuffs. This is mostly to avoid // cables and other non-functional stuff popping up in the adapter // due to having a power interface. Might revisit this at some point, diff --git a/src/main/scala/li/cil/oc/common/tileentity/NetSplitter.scala b/src/main/scala/li/cil/oc/common/tileentity/NetSplitter.scala index befe371d3..e21a8e27f 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/NetSplitter.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/NetSplitter.scala @@ -1,8 +1,12 @@ package li.cil.oc.common.tileentity -import li.cil.oc.Settings -import li.cil.oc.api -import li.cil.oc.api.network.Visibility +import java.util + +import li.cil.oc.{Constants, Settings, api} +import li.cil.oc.api.driver.DeviceInfo +import li.cil.oc.api.driver.DeviceInfo.{DeviceAttribute, DeviceClass} +import li.cil.oc.api.machine.{Arguments, Callback, Context} +import li.cil.oc.api.network.{Node, Visibility} import li.cil.oc.common.EventHandler import li.cil.oc.common.tileentity.traits.RedstoneChangedEventArgs import li.cil.oc.server.{PacketSender => ServerPacketSender} @@ -13,36 +17,53 @@ import net.minecraft.util.SoundCategory import net.minecraftforge.fml.relauncher.Side import net.minecraftforge.fml.relauncher.SideOnly -class NetSplitter extends traits.Environment with traits.OpenSides with traits.RedstoneAware with api.network.SidedEnvironment { +import scala.collection.convert.WrapAsJava._ + +class NetSplitter extends traits.Environment with traits.OpenSides with traits.RedstoneAware with api.network.SidedEnvironment with DeviceInfo { + private lazy val deviceInfo: util.Map[String, String] = Map( + DeviceAttribute.Class -> DeviceClass.Network, + DeviceAttribute.Description -> "Ethernet controller", + DeviceAttribute.Vendor -> Constants.DeviceInfo.DefaultVendor, + DeviceAttribute.Product -> "NetSplits", + DeviceAttribute.Version -> "1.0", + DeviceAttribute.Width -> "6" + ) + + override def getDeviceInfo: util.Map[String, String] = deviceInfo + _isOutputEnabled = true - val node = api.Network.newNode(this, Visibility.None). + val node: Node = api.Network.newNode(this, Visibility.Network). + withComponent("net_splitter", Visibility.Network). create() var isInverted = false - override def isSideOpen(side: EnumFacing) = if (isInverted) !super.isSideOpen(side) else super.isSideOpen(side) + override def isSideOpen(side: EnumFacing): Boolean = if (isInverted) !super.isSideOpen(side) else super.isSideOpen(side) override def setSideOpen(side: EnumFacing, value: Boolean) { + val previous = isSideOpen(side) super.setSideOpen(side, value) - if (isServer) { - node.remove() - api.Network.joinOrCreateNetwork(this) - ServerPacketSender.sendNetSplitterState(this) - world.playSound(null, x + 0.5, y + 0.5, z + 0.5, SoundEvents.BLOCK_PISTON_EXTEND, SoundCategory.BLOCKS, 0.5f, world.rand.nextFloat() * 0.25f + 0.7f) - world.notifyNeighborsOfStateChange(getPos, getBlockType) - } - else { - world.notifyBlockUpdate(getPos, world.getBlockState(getPos), world.getBlockState(getPos), 3) + if (previous != isSideOpen(side)) { + if (isServer) { + node.remove() + api.Network.joinOrCreateNetwork(this) + ServerPacketSender.sendNetSplitterState(this) + world.playSound(null, x + 0.5, y + 0.5, z + 0.5, SoundEvents.BLOCK_PISTON_EXTEND, SoundCategory.BLOCKS, 0.5f, world.rand.nextFloat() * 0.25f + 0.7f) + world.notifyNeighborsOfStateChange(getPos, getBlockType) + } + else { + world.notifyBlockUpdate(getPos, world.getBlockState(getPos), world.getBlockState(getPos), 3) + } } } // ----------------------------------------------------------------------- // - override def sidedNode(side: EnumFacing) = if (isSideOpen(side)) node else null + override def sidedNode(side: EnumFacing): Node = if (isSideOpen(side)) node else null @SideOnly(Side.CLIENT) - override def canConnect(side: EnumFacing) = isSideOpen(side) + override def canConnect(side: EnumFacing): Boolean = isSideOpen(side) // ----------------------------------------------------------------------- // @@ -95,4 +116,53 @@ class NetSplitter extends traits.Environment with traits.OpenSides with traits.R super.writeToNBTForClient(nbt) nbt.setBoolean(IsInvertedTag, isInverted) } + + // component api + def currentStatus(): Array[Boolean] = { + val openSidesCopy = Array.fill(EnumFacing.VALUES.length)(false) + for (side <- EnumFacing.VALUES) { + openSidesCopy(side.ordinal()) = isSideOpen(side) + } + openSidesCopy + } + + def setSide(side: EnumFacing, state: Boolean): Boolean = { + val previous = isSideOpen(side) // isSideOpen uses inverter + setSideOpen(side, if (isInverted) !state else state) // but setSideOpen does not + previous != state + } + + @Callback(doc = "function(settings:table):table -- set open state (true/false) of all sides in an array; index by direction. Returns previous states") + def setSides(context: Context, args: Arguments): Array[AnyRef] = { + val settings = args.checkTable(0) + val previous = currentStatus() + for (side <- EnumFacing.VALUES) { + val ordinal = side.ordinal() + val value = if (settings.containsKey(ordinal)) { + settings.get(ordinal) match { + case v: Boolean => v + case _ => false + } + } else false + setSide(side, value) + } + result(previous) + } + + @Callback(direct = true, doc = "function():table -- Returns current open/close state of all sides in an array, indexed by direction.") + def getSides(context: Context, args: Arguments): Array[AnyRef] = result(currentStatus()) + + def setSideHelper(args: Arguments, value: Boolean): Array[AnyRef] = { + val sideIndex = args.checkInteger(0) + if (sideIndex < 0 || sideIndex > 5) + return result(Unit, "invalid direction") + val side = EnumFacing.getFront(sideIndex) + result(setSide(side, value)) + } + + @Callback(doc = "function(side: number):boolean -- Open the side, returns true if it changed to open.") + def open(context: Context, args: Arguments): Array[AnyRef] = setSideHelper(args, value = true) + + @Callback(doc = "function(side: number):boolean -- Close the side, returns true if it changed to close.") + def close(context: Context, args: Arguments): Array[AnyRef] = setSideHelper(args, value = false) } diff --git a/src/main/scala/li/cil/oc/server/network/Node.scala b/src/main/scala/li/cil/oc/server/network/Node.scala index dcca4b2dd..6bc30be3e 100644 --- a/src/main/scala/li/cil/oc/server/network/Node.scala +++ b/src/main/scala/li/cil/oc/server/network/Node.scala @@ -37,10 +37,10 @@ trait Node extends ImmutableNode { if (network == null) Iterable.empty[ImmutableNode].toSeq else network.neighbors(this) - // a node should be added to a network before it can connect to a node + // A node should be added to a network before it can connect to a node // but, sometimes other mods try to create nodes and connect them before - // the network is ready. we dont those things to crash here - // with typical nodes we are talking about components here + // the network is ready. We don't desire those things to crash here. + // With typical nodes we are talking about components here // which will be connected anyways when the network is created def connect(node: ImmutableNode): Unit = if (network != null) network.connect(this, node)