bring back wireless redstone (cbe) support

closes #2987
This commit is contained in:
payonel 2019-11-12 23:57:25 -08:00
parent fb1ba7472f
commit 7cbbf132cf
8 changed files with 320 additions and 6 deletions

View File

@ -7,7 +7,6 @@ import appeng.api.util.AEPartLocation
import li.cil.oc._
import li.cil.oc.api.Network
import li.cil.oc.api.detail.ItemInfo
import li.cil.oc.common.item.traits
import li.cil.oc.api.internal.Colored
import li.cil.oc.api.internal.Rack
import li.cil.oc.api.internal.Server
@ -30,6 +29,7 @@ import li.cil.oc.common.recipe.Recipes
import li.cil.oc.common.tileentity.Robot
import li.cil.oc.common.tileentity.traits.power
import li.cil.oc.integration.Mods
import li.cil.oc.integration.util
import li.cil.oc.server.component.Keyboard
import li.cil.oc.server.machine.Callbacks
import li.cil.oc.server.machine.Machine
@ -140,6 +140,15 @@ object EventHandler {
}
}
def scheduleWirelessRedstone(rs: server.component.RedstoneWireless) {
if (SideTracker.isServer) pendingServer.synchronized {
pendingServer += (() => if (rs.node.network != null) {
util.WirelessRedstone.addReceiver(rs)
util.WirelessRedstone.updateOutput(rs)
})
}
}
@SubscribeEvent
def onAttachCapabilitiesItemStack(event: AttachCapabilitiesEvent[ItemStack]): Unit = {
if (!event.getCapabilities.containsKey(traits.Chargeable.KEY)) {
@ -182,7 +191,7 @@ object EventHandler {
}
@SubscribeEvent
def onServerTick(e: ServerTickEvent) = if (e.phase == TickEvent.Phase.START) {
def onServerTick(e: ServerTickEvent): Any = if (e.phase == TickEvent.Phase.START) {
pendingServer.synchronized {
val adds = pendingServer.toArray
pendingServer.clear()

View File

@ -37,6 +37,7 @@ object Mods {
val EnderStorage = new SimpleMod(IDs.EnderStorage)
val Thaumcraft = new SimpleMod(IDs.Thaumcraft)
val Charset = new SimpleMod(IDs.Charset)
val WirelessRedstoneCBE = new SimpleMod(IDs.WirelessRedstoneCBE)
// ----------------------------------------------------------------------- //
@ -56,6 +57,7 @@ object Mods {
integration.enderstorage.ModEnderStorage,
integration.thaumcraft.ModThaumcraft,
integration.charset.ModCharset,
integration.wrcbe.ModWRCBE,
// We go late to ensure all other mod integration is done, e.g. to
// allow properly checking if wireless redstone is present.
@ -102,6 +104,7 @@ object Mods {
final val EnderStorage = "enderstorage"
final val Thaumcraft = "thaumcraft"
final val Charset = "charset"
final val WirelessRedstoneCBE = "wrcbe"
}
// ----------------------------------------------------------------------- //

View File

@ -12,6 +12,7 @@ import li.cil.oc.common.item.Delegator
import li.cil.oc.common.tileentity.traits.BundledRedstoneAware
import li.cil.oc.common.tileentity.traits.RedstoneAware
import li.cil.oc.integration.util.BundledRedstone
import li.cil.oc.integration.util.WirelessRedstone
import li.cil.oc.server.component
import net.minecraft.item.ItemStack
@ -25,12 +26,17 @@ object DriverRedstoneCard extends Item with HostAware {
else {
val isAdvanced = tier(stack) == Tier.Two
val hasBundled = BundledRedstone.isAvailable && isAdvanced
val hasWireless = WirelessRedstone.isAvailable && isAdvanced
host match {
case redstone: BundledRedstoneAware if hasBundled =>
new component.Redstone.Bundled(redstone)
if (hasWireless) new component.Redstone.BundledWireless(redstone)
else new component.Redstone.Bundled(redstone)
case redstone: RedstoneAware =>
new component.Redstone.Vanilla(redstone)
case _ => null
if (hasWireless) new component.Redstone.VanillaWireless(redstone)
else new component.Redstone.Vanilla(redstone)
case _ =>
if (hasWireless) new component.Redstone.Wireless(host)
else null
}
}
@ -47,8 +53,10 @@ object DriverRedstoneCard extends Item with HostAware {
if (worksWith(stack)) {
val isAdvanced = tier(stack) == Tier.Two
val hasBundled = BundledRedstone.isAvailable && isAdvanced
val hasWireless = WirelessRedstone.isAvailable && isAdvanced
if (hasBundled) {
classOf[component.Redstone.Bundled]
if (hasWireless) classOf[component.Redstone.BundledWireless]
else classOf[component.Redstone.Bundled]
}
else {
classOf[component.Redstone.Vanilla]

View File

@ -0,0 +1,50 @@
package li.cil.oc.integration.util
import li.cil.oc.server.component.RedstoneWireless
import scala.collection.mutable
object WirelessRedstone {
val systems = mutable.Set.empty[WirelessRedstoneSystem]
def isAvailable: Boolean = systems.nonEmpty
def addReceiver(rs: RedstoneWireless) {
systems.foreach(system => try system.addReceiver(rs) catch {
case _: Throwable => // Ignore
})
}
def removeReceiver(rs: RedstoneWireless) {
systems.foreach(system => try system.removeReceiver(rs) catch {
case _: Throwable => // Ignore
})
}
def updateOutput(rs: RedstoneWireless) {
systems.foreach(system => try system.updateOutput(rs) catch {
case _: Throwable => // Ignore
})
}
def removeTransmitter(rs: RedstoneWireless) {
systems.foreach(system => try system.removeTransmitter(rs) catch {
case _: Throwable => // Ignore
})
}
def getInput(rs: RedstoneWireless): Boolean = systems.exists(_.getInput(rs))
trait WirelessRedstoneSystem {
def addReceiver(rs: RedstoneWireless)
def removeReceiver(rs: RedstoneWireless)
def updateOutput(rs: RedstoneWireless)
def removeTransmitter(rs: RedstoneWireless)
def getInput(rs: RedstoneWireless): Boolean
}
}

View File

@ -0,0 +1,13 @@
package li.cil.oc.integration.wrcbe
import li.cil.oc.integration.ModProxy
import li.cil.oc.integration.Mods
import li.cil.oc.integration.util.WirelessRedstone
object ModWRCBE extends ModProxy {
override def getMod: Mods.SimpleMod = Mods.WirelessRedstoneCBE
override def initialize() {
WirelessRedstone.systems += WirelessRedstoneCBE
}
}

View File

@ -0,0 +1,43 @@
package li.cil.oc.integration.wrcbe
import codechicken.wirelessredstone.manager.RedstoneEther
import li.cil.oc.integration.util.WirelessRedstone.WirelessRedstoneSystem
import li.cil.oc.server.component.RedstoneWireless
import scala.language.reflectiveCalls
object WirelessRedstoneCBE extends WirelessRedstoneSystem {
def addTransmitter(rs: RedstoneWireless) {
if (rs.wirelessOutput && rs.wirelessFrequency > 0) {
RedstoneEther.server.addTransmittingDevice(rs)
}
}
def removeTransmitter(rs: RedstoneWireless) {
if (rs.wirelessFrequency > 0) {
RedstoneEther.server.removeTransmittingDevice(rs)
}
}
def addReceiver(rs: RedstoneWireless) {
RedstoneEther.server.addReceivingDevice(rs)
if (rs.wirelessFrequency > 0) {
rs.wirelessInput = RedstoneEther.server.isFreqOn(rs.wirelessFrequency)
}
}
def removeReceiver(rs: RedstoneWireless) {
RedstoneEther.server.removeReceivingDevice(rs)
}
def updateOutput(rs: RedstoneWireless) {
if (rs.wirelessOutput) {
addTransmitter(rs)
}
else {
removeTransmitter(rs)
}
}
def getInput(rs: RedstoneWireless): Boolean = rs.wirelessInput
}

View File

@ -1,10 +1,16 @@
package li.cil.oc.server.component
import java.util
import li.cil.oc.Constants
import li.cil.oc.api.driver.DeviceInfo.{DeviceAttribute,DeviceClass}
import li.cil.oc.api.network.EnvironmentHost
import li.cil.oc.common.tileentity.traits.BundledRedstoneAware
import li.cil.oc.common.tileentity.traits.RedstoneAware
import li.cil.oc.server.component
import scala.collection.convert.WrapAsJava._
object Redstone {
class Vanilla(val redstone: EnvironmentHost with RedstoneAware)
@ -13,4 +19,23 @@ object Redstone {
class Bundled(val redstone: EnvironmentHost with BundledRedstoneAware)
extends component.RedstoneVanilla with component.RedstoneBundled
class Wireless(val redstone: EnvironmentHost)
extends component.RedstoneWireless
class VanillaWireless(val redstone: EnvironmentHost with RedstoneAware)
extends component.RedstoneVanilla with component.RedstoneWireless
class BundledWireless(val redstone: EnvironmentHost with BundledRedstoneAware)
extends component.RedstoneVanilla with component.RedstoneBundled with component.RedstoneWireless {
private final lazy val deviceInfo = Map(
DeviceAttribute.Class -> DeviceClass.Communication,
DeviceAttribute.Description -> "Combined redstone controller",
DeviceAttribute.Vendor -> Constants.DeviceInfo.DefaultVendor,
DeviceAttribute.Product -> "Rx900-M",
DeviceAttribute.Capacity -> "65536",
DeviceAttribute.Width -> "16"
)
override def getDeviceInfo: util.Map[String, String] = deviceInfo
}
}

View File

@ -0,0 +1,163 @@
package li.cil.oc.server.component
import codechicken.lib.vec.Vector3
import codechicken.wirelessredstone.api.WirelessReceivingDevice
import codechicken.wirelessredstone.api.WirelessTransmittingDevice
import li.cil.oc.Constants
import li.cil.oc.api.driver.DeviceInfo.DeviceAttribute
import li.cil.oc.api.driver.DeviceInfo.DeviceClass
import li.cil.oc.Settings
import li.cil.oc.api.driver.DeviceInfo
import li.cil.oc.api.network.EnvironmentHost
import li.cil.oc.api.machine.Arguments
import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context
import li.cil.oc.api.network._
import li.cil.oc.common.EventHandler
import li.cil.oc.common.tileentity.traits.RedstoneChangedEventArgs
import li.cil.oc.integration.Mods
import li.cil.oc.integration.util
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.fml.common.Optional
import scala.collection.convert.WrapAsJava._
@Optional.InterfaceList(Array(
new Optional.Interface(iface = "codechicken.wirelessredstone.api.WirelessReceivingDevice", modid = Mods.IDs.WirelessRedstoneCBE),
new Optional.Interface(iface = "codechicken.wirelessredstone.api.WirelessTransmittingDevice", modid = Mods.IDs.WirelessRedstoneCBE)
))
trait RedstoneWireless extends RedstoneSignaller with WirelessReceivingDevice with WirelessTransmittingDevice with DeviceInfo {
def redstone: EnvironmentHost
var wirelessFrequency = 0
var wirelessInput = false
var wirelessOutput = false
// ----------------------------------------------------------------------- //
private final lazy val deviceInfo = Map(
DeviceAttribute.Class -> DeviceClass.Communication,
DeviceAttribute.Description -> "Wireless redstone controller",
DeviceAttribute.Vendor -> Constants.DeviceInfo.DefaultVendor,
DeviceAttribute.Product -> "Rw400-M",
DeviceAttribute.Capacity -> "1",
DeviceAttribute.Width -> "1"
)
override def getDeviceInfo: java.util.Map[String, String] = deviceInfo
// ----------------------------------------------------------------------- //
@Callback(doc = """function():number -- Get the wireless redstone input.""")
def getWirelessInput(context: Context, args: Arguments): Array[AnyRef] = {
wirelessInput = util.WirelessRedstone.getInput(this)
result(wirelessInput)
}
@Callback(direct = true, doc = """function():boolean -- Get the wireless redstone output.""")
def getWirelessOutput(context: Context, args: Arguments): Array[AnyRef] = result(wirelessOutput)
@Callback(doc = """function(value:boolean):boolean -- Set the wireless redstone output.""")
def setWirelessOutput(context: Context, args: Arguments): Array[AnyRef] = {
val oldValue = wirelessOutput
val newValue = args.checkBoolean(0)
if (oldValue != newValue) {
wirelessOutput = newValue
util.WirelessRedstone.updateOutput(this)
if (Settings.get.redstoneDelay > 0)
context.pause(Settings.get.redstoneDelay)
}
result(oldValue)
}
@Callback(direct = true, doc = """function():number -- Get the currently set wireless redstone frequency.""")
def getWirelessFrequency(context: Context, args: Arguments): Array[AnyRef] = result(wirelessFrequency)
@Callback(doc = """function(frequency:number):number -- Set the wireless redstone frequency to use.""")
def setWirelessFrequency(context: Context, args: Arguments): Array[AnyRef] = {
val oldValue = wirelessFrequency
val newValue = args.checkInteger(0)
if (oldValue != newValue) {
util.WirelessRedstone.removeReceiver(this)
util.WirelessRedstone.removeTransmitter(this)
wirelessFrequency = newValue
wirelessInput = false
wirelessOutput = false
util.WirelessRedstone.addReceiver(this)
context.pause(0.5)
}
result(oldValue)
}
// ----------------------------------------------------------------------- //
@Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE)
override def updateDevice(frequency: Int, on: Boolean) {
if (frequency == wirelessFrequency && on != wirelessInput) {
wirelessInput = on
onRedstoneChanged(RedstoneChangedEventArgs(null, if (on) 0 else 1, if (on) 1 else 0))
}
}
@Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE)
override def getTransmitPos = new Vector3(redstone.xPosition, redstone.yPosition, redstone.zPosition)
@Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE)
override def getDimension: Int = redstone.world.provider.getDimension
@Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE)
override def getFreq: Int = wirelessFrequency
@Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE)
override def getAttachedEntity = null
// ----------------------------------------------------------------------- //
override def onConnect(node: Node) {
super.onConnect(node)
if (node == this.node) {
EventHandler.scheduleWirelessRedstone(this)
}
}
override def onDisconnect(node: Node) {
super.onDisconnect(node)
if (node == this.node) {
util.WirelessRedstone.removeReceiver(this)
util.WirelessRedstone.removeTransmitter(this)
wirelessOutput = false
wirelessFrequency = 0
}
}
// ----------------------------------------------------------------------- //
private final val WirelessFrequencyTag = "wirelessFrequency"
private final val WirelessInputTag = "wirelessInput"
private final val WirelessOutputTag = "wirelessOutput"
override def load(nbt: NBTTagCompound) {
super.load(nbt)
wirelessFrequency = nbt.getInteger(WirelessFrequencyTag)
wirelessInput = nbt.getBoolean(WirelessInputTag)
wirelessOutput = nbt.getBoolean(WirelessOutputTag)
}
override def save(nbt: NBTTagCompound) {
super.save(nbt)
nbt.setInteger(WirelessFrequencyTag, wirelessFrequency)
nbt.setBoolean(WirelessInputTag, wirelessInput)
nbt.setBoolean(WirelessOutputTag, wirelessOutput)
}
}