sending wireless network messages now costs power based on the used signal strength and range per power is configurable, as is the power buffer size of wireless network cards

This commit is contained in:
Florian Nücke 2013-11-08 20:45:31 +01:00
parent 35d8e07fc4
commit 1c34cdbe67
2 changed files with 50 additions and 18 deletions

View File

@ -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").

View File

@ -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