diff --git a/li/cil/oc/Config.scala b/li/cil/oc/Config.scala index 9db3a3cdc..c9ca3b027 100644 --- a/li/cil/oc/Config.scala +++ b/li/cil/oc/Config.scala @@ -16,12 +16,14 @@ object Config { var bufferComputer = 16.0 var bufferConverter = 64.0 var bufferScreen = 16.0 + var bufferWireless = 32.0 var computerBaseCost = 1.0 / 20 var computerCpuTimeCost = 256.0 var screenFillCost = 1.0 / 180 var screenClearCost = 1.0 / 200 var screenCopyCost = 1.0 / 160 var screenSetCost = 1.0 / 20 + var wirelessRangePerPower = 8.0 // ----------------------------------------------------------------------- // @@ -101,15 +103,22 @@ object Config { setComment("Power settings, buffer sizes and power consumption.") bufferComputer = config.get("power", "bufferComputer", bufferComputer, "" + - "The buffer size for computers, i.e. how much power they store internally."). + "The buffer size for computers."). getDouble(bufferComputer) bufferConverter = config.get("power", "bufferConverter", bufferConverter, "" + - "The buffer size for converters, i.e. how much power they store internally."). + "The buffer size for converters."). getDouble(bufferConverter) bufferScreen = config.get("power", "bufferScreen", bufferScreen, "" + - "The buffer size for screens, i.e. how much power they store internally."). + "The buffer size for screens."). + getDouble(bufferScreen) + + bufferWireless = config.get("power", "bufferWireless", bufferWireless, "" + + "The buffer size for wireless network cards. Note that this effectively\n" + + "limits the maximum range of wireless communication, together with the\n" + + "`wirelessRangePerPower` setting: the maximum range is this times the\n" + + "range per power (so per default that's 32 * 8 = 256 blocks)."). getDouble(bufferScreen) computerBaseCost = config.get("power", "computerBaseCost", computerBaseCost, "" + @@ -136,6 +145,13 @@ object Config { "Power it takes to change a single pixel via the set command."). getDouble(screenSetCost) + wirelessRangePerPower = config.get("power", "wirelessRangePerPower", wirelessRangePerPower, "" + + "The range in blocks a wireless network card gains for each additional\n" + + "power it spends. In other words, the higher this value, the lower the\n" + + "cost of incrementing the signal strength.\n" + + "See also: `bufferWireless`"). + getDouble(wirelessRangePerPower) max 0 + // --------------------------------------------------------------------- // config.getCategory("server"). diff --git a/li/cil/oc/server/component/WirelessNetworkCard.scala b/li/cil/oc/server/component/WirelessNetworkCard.scala index 1e23d965e..f5d96b040 100644 --- a/li/cil/oc/server/component/WirelessNetworkCard.scala +++ b/li/cil/oc/server/component/WirelessNetworkCard.scala @@ -16,7 +16,7 @@ import scala.language.implicitConversions class WirelessNetworkCard(val owner: TileEntity) extends NetworkCard { override val node = api.Network.newNode(this, Visibility.Network). withComponent("modem", Visibility.Neighbors). - withConnector(Config.bufferComputer). + withConnector(Config.bufferWireless). create() var strength = 64.0 @@ -28,7 +28,7 @@ class WirelessNetworkCard(val owner: TileEntity) extends NetworkCard { @LuaCallback(value = "setStrength", direct = true) def setStrength(context: Context, args: Arguments): Array[AnyRef] = this.synchronized { - strength = args.checkDouble(0) + strength = args.checkDouble(0) max 0 result(strength) } @@ -37,24 +37,37 @@ class WirelessNetworkCard(val owner: TileEntity) extends NetworkCard { override def send(context: Context, args: Arguments) = this.synchronized { val address = args.checkString(0) val port = checkPort(args.checkInteger(1)) - for ((card, distance) <- WirelessNetwork.computeReachableFrom(this) - if card.node.address == address && card.openPorts.contains(port)) { - card.node.sendToReachable("computer.signal", - Seq("modem_message", node.address, Int.box(port), Double.box(distance)) ++ args.drop(2): _*) + if (strength > 0) { + checkPower() + for ((card, distance) <- WirelessNetwork.computeReachableFrom(this) + if card.node.address == address && card.openPorts.contains(port)) { + card.node.sendToReachable("computer.signal", + Seq("modem_message", node.address, Int.box(port), Double.box(distance)) ++ args.drop(2): _*) + } } super.send(context, args) } override def broadcast(context: Context, args: Arguments) = this.synchronized { val port = checkPort(args.checkInteger(0)) - for ((card, distance) <- WirelessNetwork.computeReachableFrom(this) - if card.openPorts.contains(port)) { - card.node.sendToReachable("computer.signal", - Seq("modem_message", node.address, Int.box(port), Double.box(distance)) ++ args.drop(2): _*) + if (strength > 0) { + checkPower() + for ((card, distance) <- WirelessNetwork.computeReachableFrom(this) + if card.openPorts.contains(port)) { + card.node.sendToReachable("computer.signal", + Seq("modem_message", node.address, Int.box(port), Double.box(distance)) ++ args.drop(2): _*) + } } super.broadcast(context, args) } + + private def checkPower() { + val rate = Config.wirelessRangePerPower + if (rate != 0 && !node.changeBuffer(-strength / rate)) + throw new Exception("not enough energy") + } + // ----------------------------------------------------------------------- // override def onConnect(node: Node) { @@ -136,13 +149,16 @@ object WirelessNetwork { def computeReachableFrom(card: WirelessNetworkCard) = { dimensions.get(dimension(card)) match { - case Some(set) if card.strength >= 1 => - set.range(offset(card, -card.strength), offset(card, card.strength)). + case Some(set) if card.strength > 0 => + val range = card.strength + 1 + set.range(offset(card, -range), offset(card, range)). map(_.card.get). filter(_ != card). map(zipWithDistance(card)). - filter(_._2 <= card.strength * card.strength). - map { case (c, distance) => (c, Math.sqrt(distance)) }. + filter(_._2 <= range * range). + map { + case (c, distance) => (c, Math.sqrt(distance)) + }. filter(isUnobstructed(card)) case _ => Iterable.empty[(WirelessNetworkCard, Double)] // Should not be possible. } @@ -203,7 +219,7 @@ object WirelessNetwork { hardness *= gap.toDouble / samples.toDouble // Remaining signal strength. - val strength = reference.strength - distance + val strength = reference.strength - gap // See if we have enough power to overcome the obstructions. strength > hardness