diff --git a/assets/opencomputers/lua/rom/bin/redstone.lua b/assets/opencomputers/lua/rom/bin/redstone.lua index cd4c64b3d..86e46c644 100644 --- a/assets/opencomputers/lua/rom/bin/redstone.lua +++ b/assets/opencomputers/lua/rom/bin/redstone.lua @@ -4,12 +4,12 @@ if #args < 1 then return end -local side = rs.sides[args[1]] +local side = sides[args[1]] if not side then print("Invalid side.") end if type(side) == "string" then - side = rs.sides[side] + side = sides[side] end if #args > 1 then diff --git a/assets/opencomputers/lua/rom/lib/colors.lua b/assets/opencomputers/lua/rom/lib/colors.lua new file mode 100644 index 000000000..c85134941 --- /dev/null +++ b/assets/opencomputers/lua/rom/lib/colors.lua @@ -0,0 +1,32 @@ +local colors = { + [0] = "white", + [1] = "orange", + [2] = "magenta", + [3] = "lightBlue", + [4] = "yellow", + [5] = "lime", + [6] = "pink", + [7] = "gray", + [8] = "silver", + [9] = "cyan", + [10] = "purple", + [11] = "blue", + [12] = "brown", + [13] = "green", + [14] = "red", + [15] = "black" +} + +do + local keys = {} + for k in pairs(colors) do + table.insert(keys, k) + end + for _, k in pairs(keys) do + colors[colors[k]] = k + end +end + +------------------------------------------------------------------------------- + +_G.colors = colors diff --git a/assets/opencomputers/lua/rom/lib/keyboard.lua b/assets/opencomputers/lua/rom/lib/keyboard.lua index c22e8db5e..d2d950cc0 100644 --- a/assets/opencomputers/lua/rom/lib/keyboard.lua +++ b/assets/opencomputers/lua/rom/lib/keyboard.lua @@ -131,8 +131,14 @@ keyboard.keys = { } -- Create inverse mapping for name lookup. -for k, v in pairs(keyboard.keys) do - keyboard.keys[v] = k +do + local keys = {} + for k in pairs(keyboard.keys) do + table.insert(keys, k) + end + for _, k in pairs(keys) do + keyboard.keys[keyboard.keys[k]] = k + end end ------------------------------------------------------------------------------- diff --git a/assets/opencomputers/lua/rom/lib/sides.lua b/assets/opencomputers/lua/rom/lib/sides.lua index 7b884fe20..8c7d767ed 100644 --- a/assets/opencomputers/lua/rom/lib/sides.lua +++ b/assets/opencomputers/lua/rom/lib/sides.lua @@ -4,11 +4,16 @@ local sides = { [2] = "back", [3] = "front", [4] = "right", - [5] = "left" + [5] = "left", + + bottom = 0, + top = 1, + back = 2, + front = 3, + right = 4, + left = 5 } -for k, v in pairs(sides) do - sides[v] = k -end + sides.up = sides.top sides.down = sides.bottom diff --git a/li/cil/oc/common/block/Delegate.scala b/li/cil/oc/common/block/Delegate.scala index 9dc68f709..c7889cbd6 100644 --- a/li/cil/oc/common/block/Delegate.scala +++ b/li/cil/oc/common/block/Delegate.scala @@ -45,6 +45,8 @@ trait Delegate { def icon(side: ForgeDirection): Option[Icon] = None + def isBlockNormalCube(world: World, x: Int, y: Int, z: Int) = true + def isProvidingStrongPower(world: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection) = 0 def isProvidingWeakPower(world: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection) = 0 @@ -85,8 +87,6 @@ trait SpecialDelegate extends Delegate { // ----------------------------------------------------------------------- // - def isBlockNormalCube(world: World, x: Int, y: Int, z: Int) = true - def isBlockSolid(world: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection) = true def shouldSideBeRendered(world: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection) = diff --git a/li/cil/oc/common/block/Delegator.scala b/li/cil/oc/common/block/Delegator.scala index 21195c26c..acf822525 100644 --- a/li/cil/oc/common/block/Delegator.scala +++ b/li/cil/oc/common/block/Delegator.scala @@ -213,6 +213,12 @@ class Delegator[Child <: Delegate](id: Int) extends Block(id, Material.iron) { case _ => false } + override def isBlockNormalCube(world: World, x: Int, y: Int, z: Int) = + subBlock(world.getBlockMetadata(x, y, z)) match { + case Some(subBlock) => subBlock.isBlockNormalCube(world, x, y, z) + case _ => false + } + override def isProvidingStrongPower(world: IBlockAccess, x: Int, y: Int, z: Int, side: Int) = subBlock(world, x, y, z) match { case Some(subBlock) => subBlock.isProvidingStrongPower( @@ -333,12 +339,6 @@ class Delegator[Child <: Delegate](id: Int) extends Block(id, Material.iron) { class SimpleDelegator(id: Int) extends Delegator[SimpleDelegate](id) class SpecialDelegator(id: Int) extends Delegator[SpecialDelegate](id) { - override def isBlockNormalCube(world: World, x: Int, y: Int, z: Int) = - subBlock(world.getBlockMetadata(x, y, z)) match { - case Some(subBlock) => subBlock.isBlockNormalCube(world, x, y, z) - case _ => false - } - override def isBlockSolid(world: IBlockAccess, x: Int, y: Int, z: Int, side: Int) = subBlock(world.getBlockMetadata(x, y, z)) match { case Some(subBlock) => subBlock.isBlockSolid(world, x, y, z, ForgeDirection.getOrientation(side)) diff --git a/li/cil/oc/common/tileentity/Computer.scala b/li/cil/oc/common/tileentity/Computer.scala index 7e9a1bf05..87d956581 100644 --- a/li/cil/oc/common/tileentity/Computer.scala +++ b/li/cil/oc/common/tileentity/Computer.scala @@ -1,5 +1,7 @@ package li.cil.oc.common.tileentity +import cpw.mods.fml.common.Loader +import li.cil.oc.Config import li.cil.oc.api.Network import li.cil.oc.api.driver.Slot import li.cil.oc.client.{PacketSender => ClientPacketSender} @@ -9,11 +11,11 @@ import li.cil.oc.server.component.Redstone import li.cil.oc.server.driver import li.cil.oc.server.driver.Registry import li.cil.oc.server.{PacketSender => ServerPacketSender} +import mods.immibis.redlogic.api.wiring.IBundledEmitter import net.minecraft.entity.player.EntityPlayer import net.minecraft.item.ItemStack import net.minecraft.nbt.NBTTagCompound import net.minecraftforge.common.ForgeDirection -import li.cil.oc.Config class Computer(isClient: Boolean) extends Rotatable with ComputerEnvironment with ComponentInventory with Redstone { def this() = this(false) @@ -91,8 +93,10 @@ class Computer(isClient: Boolean) extends Rotatable with ComputerEnvironment wit } if (needsSaving) worldObj.markTileEntityChunkModified(xCoord, yCoord, zCoord, this) - if (isRunning != instance.isRunning) + if (isRunning != instance.isRunning) { + isOutputEnabled = hasRedstoneCard && instance.isRunning ServerPacketSender.sendComputerState(this, instance.isRunning) + } isRunning = instance.isRunning updateRedstoneInput() } @@ -134,7 +138,7 @@ class Computer(isClient: Boolean) extends Rotatable with ComputerEnvironment wit super.onInventoryChanged() if (!worldObj.isRemote) { instance.recomputeMemory() - isOutputEnabled = hasRedstoneCard + isOutputEnabled = hasRedstoneCard && instance.isRunning } } @@ -151,6 +155,24 @@ class Computer(isClient: Boolean) extends Rotatable with ComputerEnvironment wit global.ordinal()) } + protected def computeBundledInput(side: ForgeDirection) = { + val global = toGlobal(side) + if (Loader.isModLoaded("RedLogic")) { + worldObj.getBlockTileEntity( + xCoord + global.offsetX, + yCoord + global.offsetY, + zCoord + global.offsetZ) match { + case emitter: IBundledEmitter => + var strength: Array[Byte] = null + for (i <- -1 to 5 if strength == null) { + strength = emitter.getBundledCableStrength(i, global.getOpposite.ordinal()) + } + strength + case _ => null + } + } else null + } + override protected def onRedstoneInputChanged(side: ForgeDirection) { super.onRedstoneInputChanged(side) instance.signal("redstone_changed", side.ordinal()) diff --git a/li/cil/oc/server/component/Computer.scala b/li/cil/oc/server/component/Computer.scala index bdef9f9d9..0c9d01396 100644 --- a/li/cil/oc/server/component/Computer.scala +++ b/li/cil/oc/server/component/Computer.scala @@ -25,6 +25,7 @@ import scala.Some import scala.collection.convert.WrapAsScala._ import scala.collection.mutable import scala.math.ScalaNumber +import scala.runtime.BoxedUnit /** * Wrapper class for Lua states set up to behave like a pseudo-OS. @@ -565,7 +566,7 @@ class Computer(val owner: Computer.Environment) extends Persistable with Runnabl } def pushResult(lua: LuaState, value: AnyRef): Unit = value match { - case null | Unit => lua.pushNil() + case null | Unit | _: BoxedUnit => lua.pushNil() case value: java.lang.Boolean => lua.pushBoolean(value.booleanValue) case value: java.lang.Byte => lua.pushNumber(value.byteValue) case value: java.lang.Character => lua.pushString(String.valueOf(value)) diff --git a/li/cil/oc/server/component/Redstone.scala b/li/cil/oc/server/component/Redstone.scala index 2c13ce9b2..02f3994ee 100644 --- a/li/cil/oc/server/component/Redstone.scala +++ b/li/cil/oc/server/component/Redstone.scala @@ -1,15 +1,30 @@ package li.cil.oc.server.component +import cpw.mods.fml.common.Optional +import cpw.mods.fml.common.Optional.Interface import li.cil.oc.common.tileentity +import li.cil.oc.util.Persistable +import mods.immibis.redlogic.api.wiring._ import net.minecraft.nbt.{NBTTagByte, NBTTagList, NBTTagCompound} import net.minecraftforge.common.ForgeDirection -import li.cil.oc.util.Persistable -trait Redstone extends tileentity.Environment with Persistable { +@Optional.InterfaceList(Array( + new Interface(iface = "mods.immibis.redlogic.api.wiring.IConnectable", modid = "RedLogic"), + new Interface(iface = "mods.immibis.redlogic.api.wiring.IBundledEmitter", modid = "RedLogic"), + new Interface(iface = "mods.immibis.redlogic.api.wiring.IBundledUpdatable", modid = "RedLogic"), + new Interface(iface = "mods.immibis.redlogic.api.wiring.IRedstoneEmitter", modid = "RedLogic"), + new Interface(iface = "mods.immibis.redlogic.api.wiring.IRedstoneUpdatable", modid = "RedLogic") +)) +trait Redstone extends tileentity.Environment with Persistable +with IConnectable with IBundledEmitter with IBundledUpdatable with IRedstoneEmitter with IRedstoneUpdatable { private val _input = Array.fill[Byte](6)(-1) private val _output = Array.fill[Byte](6)(0) + private val _bundledInput = Array.fill[Array[Byte]](6)(Array.fill[Byte](16)(-1)) + + private val _bundledOutput = Array.fill[Array[Byte]](6)(Array.fill[Byte](16)(0)) + private var _isOutputEnabled = true private var _shouldUpdateInput = true @@ -23,18 +38,33 @@ trait Redstone extends tileentity.Environment with Persistable { for (i <- 0 until _output.length) { _output(i) = 0.toByte } + for (i <- 0 until _bundledOutput.length) { + for (j <- 0 until _bundledOutput(i).length) { + _bundledOutput(i)(j) = 0.toByte + } + } } onRedstoneOutputChanged(ForgeDirection.UNKNOWN) } this } - def input(side: ForgeDirection): Int = _input(side.ordinal()) + def input(side: ForgeDirection) = (_input(side.ordinal()) & 0xFF).toShort - def output(side: ForgeDirection): Int = _output(side.ordinal()) + def output(side: ForgeDirection) = (_output(side.ordinal()) & 0xFF).toShort - def output(side: ForgeDirection, value: Int): Unit = if (value != output(side)) { - _output(side.ordinal()) = (value max 0 min 15).toByte + def output(side: ForgeDirection, value: Short): Unit = if (value != output(side)) { + _output(side.ordinal()) = (value max 0 min 255).toByte + onRedstoneOutputChanged(side) + } + + def bundledInput(side: ForgeDirection, color: Int) = (_bundledInput(side.ordinal())(color) & 0xFF).toShort + + def bundledOutput(side: ForgeDirection, color: Int) = + (_bundledOutput(side.ordinal())(color) & 0xFF).toShort + + def bundledOutput(side: ForgeDirection, color: Int, value: Short): Unit = if (value != bundledOutput(side, color)) { + _bundledOutput(side.ordinal())(color) = (value max 0 min 255).toByte onRedstoneOutputChanged(side) } @@ -48,10 +78,19 @@ trait Redstone extends tileentity.Environment with Persistable { if (_shouldUpdateInput) { _shouldUpdateInput = false for (side <- ForgeDirection.VALID_DIRECTIONS) { - val oldInput = _input(side.ordinal()) - val newInput = computeInput(side) - _input(side.ordinal()) = newInput.toByte - if (oldInput >= 0 && _input(side.ordinal()) != oldInput) { + val (oldInput, oldBundledInput) = (_input(side.ordinal()), _bundledInput(side.ordinal())) + val (newInput, newBundledInput) = (computeInput(side), computeBundledInput(side)) + _input(side.ordinal()) = (newInput max 0 min 255).toByte + var changed = oldInput >= 0 && input(side) != oldInput + if (newBundledInput != null) for (i <- 0 until 16) { + changed = changed || oldBundledInput(i) != newBundledInput(i) + oldBundledInput(i) = newBundledInput(i) + } + else for (i <- 0 until 16) { + changed = changed || oldBundledInput(i) != 0.toByte + oldBundledInput(i) = 0.toByte + } + if (changed) { onRedstoneInputChanged(side) } } @@ -63,17 +102,29 @@ trait Redstone extends tileentity.Environment with Persistable { 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 + val inputNbt = nbt.getTagList("oc.rs.input") + for (i <- 0 until (_input.length min inputNbt.tagCount)) { + _input(i) = inputNbt.tagAt(i).asInstanceOf[NBTTagByte].data + } + + val outputNbt = nbt.getTagList("oc.rs.output") + for (i <- 0 until (_output.length min outputNbt.tagCount)) { + _output(i) = outputNbt.tagAt(i).asInstanceOf[NBTTagByte].data + } + + val bundledInputNbt = nbt.getTagList("oc.rs.bundledInput") + for (i <- 0 until (_bundledInput.length min bundledInputNbt.tagCount)) { + val bundleNbt = bundledInputNbt.tagAt(i).asInstanceOf[NBTTagList] + for (j <- 0 until (_bundledInput(i).length min bundleNbt.tagCount())) { + _bundledInput(i)(j) = bundleNbt.tagAt(j).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 + val bundledOutputNbt = nbt.getTagList("oc.rs.bundledOutput") + for (i <- 0 until (_bundledOutput.length min bundledOutputNbt.tagCount)) { + val bundleNbt = bundledOutputNbt.tagAt(i).asInstanceOf[NBTTagList] + for (j <- 0 until (_bundledOutput(i).length min bundleNbt.tagCount())) { + _bundledOutput(i)(j) = bundleNbt.tagAt(j).asInstanceOf[NBTTagByte].data } } } @@ -92,13 +143,55 @@ trait Redstone extends tileentity.Environment with Persistable { outputNbt.appendTag(new NBTTagByte(null, _output(i))) } nbt.setTag("oc.rs.output", outputNbt) + + val bundledInputNbt = new NBTTagList() + for (i <- 0 until _bundledInput.length) { + val bundleNbt = new NBTTagList() + for (j <- 0 until _bundledInput(i).length) { + bundleNbt.appendTag(new NBTTagByte(null, _bundledInput(i)(j))) + } + bundledInputNbt.appendTag(bundleNbt) + } + nbt.setTag("oc.rs.bundledInput", bundledInputNbt) + + val bundledOutputNbt = new NBTTagList() + for (i <- 0 until _bundledOutput.length) { + val bundleNbt = new NBTTagList() + for (j <- 0 until _bundledOutput(i).length) { + bundleNbt.appendTag(new NBTTagByte(null, _bundledOutput(i)(j))) + } + bundledOutputNbt.appendTag(bundleNbt) + } + nbt.setTag("oc.rs.bundledOutput", bundledOutputNbt) } // ----------------------------------------------------------------------- // protected def computeInput(side: ForgeDirection): Int + protected def computeBundledInput(side: ForgeDirection): Array[Byte] + protected def onRedstoneInputChanged(side: ForgeDirection) {} protected def onRedstoneOutputChanged(side: ForgeDirection) {} + + // ----------------------------------------------------------------------- // + + @Optional.Method(modid = "RedLogic") + def connects(wire: IWire, blockFace: Int, fromDirection: Int) = true + + @Optional.Method(modid = "RedLogic") + def connectsAroundCorner(wire: IWire, blockFace: Int, fromDirection: Int) = false + + @Optional.Method(modid = "RedLogic") + def getBundledCableStrength(blockFace: Int, toDirection: Int): Array[Byte] = _bundledOutput(toDirection) + + @Optional.Method(modid = "RedLogic") + def onBundledInputChanged() = checkRedstoneInputChanged() + + @Optional.Method(modid = "RedLogic") + def getEmittedSignalStrength(blockFace: Int, toDirection: Int): Short = _output(toDirection) + + @Optional.Method(modid = "RedLogic") + def onRedstoneInputChanged() = checkRedstoneInputChanged() } diff --git a/li/cil/oc/server/component/RedstoneCard.scala b/li/cil/oc/server/component/RedstoneCard.scala index 733e2cae3..6a2e463b3 100644 --- a/li/cil/oc/server/component/RedstoneCard.scala +++ b/li/cil/oc/server/component/RedstoneCard.scala @@ -1,7 +1,8 @@ package li.cil.oc.server.component +import cpw.mods.fml.common.Optional import li.cil.oc.api -import li.cil.oc.api.network.{LuaCallback, Context, Arguments, Visibility} +import li.cil.oc.api.network._ import net.minecraftforge.common.ForgeDirection class RedstoneCard extends ManagedComponent { @@ -11,7 +12,7 @@ class RedstoneCard extends ManagedComponent { @LuaCallback(value = "getInput", direct = true) def getInput(context: Context, args: Arguments): Array[AnyRef] = { - val side = args.checkInteger(0) + val side = checkSide(args, 0) node.network.node(context.address).host match { case redstone: Redstone => result(redstone.input(ForgeDirection.getOrientation(side))) @@ -21,7 +22,7 @@ class RedstoneCard extends ManagedComponent { @LuaCallback(value = "getOutput", direct = true) def getOutput(context: Context, args: Arguments): Array[AnyRef] = { - val side = args.checkInteger(0) + val side = checkSide(args, 0) node.network.node(context.address).host match { case redstone: Redstone => result(redstone.output(ForgeDirection.getOrientation(side))) @@ -31,13 +32,67 @@ class RedstoneCard extends ManagedComponent { @LuaCallback("setOutput") def setOutput(context: Context, args: Arguments): Array[AnyRef] = { - val side = args.checkInteger(0) - val value = args.checkInteger(1) + val side = checkSide(args, 0) + val value = args.checkInteger(1) max 0 min 15 node.network.node(context.address).host match { case redstone: Redstone => - redstone.output(ForgeDirection.getOrientation(side), value) + redstone.output(ForgeDirection.getOrientation(side), value.toShort) result(redstone.output(ForgeDirection.getOrientation(side))) case _ => result(false) } } + + @LuaCallback(value = "getBundledInput", direct = true) + @Optional.Method(modid = "RedLogic") + def getBundledInput(context: Context, args: Arguments): Array[AnyRef] = { + val side = checkSide(args, 0) + val color = checkColor(args, 1) + node.network.node(context.address).host match { + case redstone: Redstone => + result(redstone.bundledInput(ForgeDirection.getOrientation(side), color)) + case _ => result(0) + } + } + + @LuaCallback(value = "getBundledOutput", direct = true) + @Optional.Method(modid = "RedLogic") + def getBundledOutput(context: Context, args: Arguments): Array[AnyRef] = { + val side = checkSide(args, 0) + val color = checkColor(args, 1) + node.network.node(context.address).host match { + case redstone: Redstone => + result(redstone.bundledOutput(ForgeDirection.getOrientation(side), color)) + case _ => result(false) + } + } + + @LuaCallback("setBundledOutput") + @Optional.Method(modid = "RedLogic") + def setBundledOutput(context: Context, args: Arguments): Array[AnyRef] = { + val side = checkSide(args, 0) + val color = checkColor(args, 1) + val value = args.checkInteger(2) max 0 min 255 + node.network.node(context.address).host match { + case redstone: Redstone => + redstone.output(ForgeDirection.getOrientation(side), value.toShort) + result(redstone.bundledOutput(ForgeDirection.getOrientation(side), color, value.toShort)) + case _ => result(false) + } + } + + // ----------------------------------------------------------------------- // + + private def checkSide(args: Arguments, index: Int): Int = { + val side = args.checkInteger(index) + if (side < 0 || side > 5) + throw new IllegalArgumentException("invalid side") + side + } + + private def checkColor(args: Arguments, index: Int): Int = { + val color = args.checkInteger(index) + if (color < 0 || color > 15) + throw new IllegalArgumentException("invalid color") + color + } } diff --git a/li/cil/oc/server/network/Component.scala b/li/cil/oc/server/network/Component.scala index 12f6c95ef..4f254ac08 100644 --- a/li/cil/oc/server/network/Component.scala +++ b/li/cil/oc/server/network/Component.scala @@ -202,6 +202,7 @@ object Component { def isInteger(index: Int) = index >= 0 && index < count && (args(index) match { case value: java.lang.Integer => true + case value: java.lang.Double => true case _ => false }) diff --git a/mods/immibis/redlogic/api/wiring/IBundledEmitter.java b/mods/immibis/redlogic/api/wiring/IBundledEmitter.java new file mode 100644 index 000000000..485fdad02 --- /dev/null +++ b/mods/immibis/redlogic/api/wiring/IBundledEmitter.java @@ -0,0 +1,23 @@ +package mods.immibis.redlogic.api.wiring; + +/** + * Implemented by entities that can emit bundled cable signals. + */ +public interface IBundledEmitter { + /** + * Returns the current emitted bundled cable strength for each colour. + * The bytes are treated as having unsigned values from 0 to 255 - when extracting + * a value from the array, you need to convert it (value & 255). + * + * May return null, which is equivalent to returning an array with all values 0. + * + * Array indices are the same as the corresponding wool damage values. + * + * blockFace and toDirection are the same as the values passed to IRedstoneEmitter and IConnectable. + * blockFace can be -1 for freestanding wire connections. + * + * The return value will be used immediately, so the returned array may be overwritten + * by the next call to getBundledCableStrength. + */ + public byte[] getBundledCableStrength(int blockFace, int toDirection); +} diff --git a/mods/immibis/redlogic/api/wiring/IBundledUpdatable.java b/mods/immibis/redlogic/api/wiring/IBundledUpdatable.java new file mode 100644 index 000000000..72ad13511 --- /dev/null +++ b/mods/immibis/redlogic/api/wiring/IBundledUpdatable.java @@ -0,0 +1,8 @@ +package mods.immibis.redlogic.api.wiring; + +/** + * Implemented by tile entities that need to be notified when a connected bundled cable changes state. + */ +public interface IBundledUpdatable { + public void onBundledInputChanged(); +} diff --git a/mods/immibis/redlogic/api/wiring/IConnectable.java b/mods/immibis/redlogic/api/wiring/IConnectable.java new file mode 100644 index 000000000..4e5c51d1c --- /dev/null +++ b/mods/immibis/redlogic/api/wiring/IConnectable.java @@ -0,0 +1,47 @@ +package mods.immibis.redlogic.api.wiring; + +/** + * Interface implemented by tile entities which can connect to wires in specific ways. + * + * Note: Although wires implement IConnectable, do not use IConnectable to determine if a wire + * is connected to you, as IConnectable only exposes possible connections, and there are reasons + * for wires to not connect (e.g. if there is a microblock in the way). + * Use {@link IWire#wireConnectsInDirection(int, int)} to determine the actual connections of a wire. + */ +public interface IConnectable { + /** + * Called to check whether a wire connects to this block. + * @param wire The wire being checked. + * @param blockFace The face the wire is on in the block containing it. + * -1 when checking for jacketed wire connections. + * @param fromDirection The direction the wire block is in, relative to this block. + * @return True to allow the wire connection. + */ + public boolean connects(IWire wire, int blockFace, int fromDirection); + + /** + * Called to check whether a wire connects to this block from around a corner (actually an edge) + * + * Example: + * + *
+	 *   A#
+	 *    B
+	 * 
+ * In this situation, where A is the wire, # is a solid block and B is this block, X is right and Y is down, + * blockFace is -Y (up) and fromDirection is -X (left). + * + * Note this is different from: + *
+	 *   A
+	 *   #B
+	 * 
+ * where blockFace is -X and fromDirection is -Y. + * + * @param wire The wire being checked. + * @param blockFace The face of *this block* the edge is adjacent to. + * @param fromDirection The side the edge is on within that face. + * @return True to allow the wire connection. + */ + public boolean connectsAroundCorner(IWire wire, int blockFace, int fromDirection); +} diff --git a/mods/immibis/redlogic/api/wiring/IRedstoneEmitter.java b/mods/immibis/redlogic/api/wiring/IRedstoneEmitter.java new file mode 100644 index 000000000..294f06837 --- /dev/null +++ b/mods/immibis/redlogic/api/wiring/IRedstoneEmitter.java @@ -0,0 +1,14 @@ +package mods.immibis.redlogic.api.wiring; + +/** + * Implemented by tile entities that emit a full-strength red alloy signal. + */ +public interface IRedstoneEmitter { + /** + * toDirection and blockFace are the same as the ones passed to IConnectable. + * blockFace is -1 for freestanding wire connections. + * + * @return Signal strength from 0 to 255. + */ + public short getEmittedSignalStrength(int blockFace, int toDirection); +} diff --git a/mods/immibis/redlogic/api/wiring/IRedstoneUpdatable.java b/mods/immibis/redlogic/api/wiring/IRedstoneUpdatable.java new file mode 100644 index 000000000..f8b2d3eaa --- /dev/null +++ b/mods/immibis/redlogic/api/wiring/IRedstoneUpdatable.java @@ -0,0 +1,11 @@ +package mods.immibis.redlogic.api.wiring; + +/** + * Interface implemented by tile entities that receive redstone updates. + * Insulated wire does not cause block updates when it changes state. + * Tile entities that connect to insulated wire must implement this if they need notification of state changes. + * Bare red alloy wire causes block updates and does not call onRedstoneInputChanged. + */ +public interface IRedstoneUpdatable { + public void onRedstoneInputChanged(); +} diff --git a/mods/immibis/redlogic/api/wiring/IWire.java b/mods/immibis/redlogic/api/wiring/IWire.java new file mode 100644 index 000000000..d01069390 --- /dev/null +++ b/mods/immibis/redlogic/api/wiring/IWire.java @@ -0,0 +1,18 @@ +package mods.immibis.redlogic.api.wiring; + +/** + * Marker interface for wire tile entities. + * Other mods should not implement this, nor any sub-interface. + */ +public interface IWire { + /** + * blockFace can be -1 to check freestanding wire connections. + * @see mods.immibis.redlogic.api.wiring.IConnectable + */ + public boolean wireConnectsInDirection(int blockFace, int direction); + + /** + * Same as wireConnectsInDirection, but only checks for connections around an external corner. + */ + public boolean wireConnectsInDirectionAroundCorner(int blockFace, int direction); +}