blob: 1440bf67e0d1aa5a3d3cb7871f33d1434f5d9d34 [file] [log] [blame] [raw]
package li.cil.oc.api.power
import li.cil.oc.api.network.{Message, Node}
import net.minecraft.nbt.NBTTagCompound
import scala.collection.mutable
trait Provider extends Node {
var isActive = false
var updateNodes = false
var energyDemand = 0.0
var storedEnergy = 0.0
var MAXENERGY: Double = 2000.0
var energyStorageList = mutable.Set[EnergyStorage]()
override def receive(message: Message): Option[Array[Any]] = super.receive(message) orElse {
if (message.source != this) {
message.name match {
case "system.connect" => {
message.source match {
case distributor: Provider =>
//if other powerDistributor connected and is active set inactive
if (distributor.isActive) {
isActive = false
println("demand now (disabled) " + 0)
}
case _ =>
}
}
case "power.find" => {
message.source match {
case distributor: Provider =>
if (isActive) {
message.cancel()
return result(this)
}
case _ =>
}
}
case "system.disconnect" => {
message.source match {
case distributor: Provider =>
println("distri disc recieved")
if (distributor.isActive) {
searchMain()
}
case _ =>
}
}
case _ => // Ignore.
}
}
None
}
override protected def onConnect() {
//check if other distributors already are in the network
searchMain()
super.onConnect()
}
override abstract def readFromNBT(nbt: NBTTagCompound) = {
super.readFromNBT(nbt)
storedEnergy = nbt.getDouble("storedEnergy")
}
override abstract def writeToNBT(nbt: NBTTagCompound) = {
super.writeToNBT(nbt)
nbt.setDouble("storedEnergy", storedEnergy)
}
/**
* Connect a reciever to the provider
* @param receiver
* @param amount
*/
def connectNode(receiver: Receiver, amount: Double) {
if (!energyStorageList.exists(_.node == receiver)) {
energyStorageList += new EnergyStorage(receiver, amount)
energyDemand += amount
updateNodes = true
}
if (isActive)
println("demand now (connect)" + energyDemand)
}
/**
* Updates the demand of the node to the given value
* @param receiver
* @param demand
*/
def updateDemand(receiver: Receiver, demand: Double) {
energyStorageList.filter(n => n.node == receiver).foreach(n => {
energyDemand -= n.amount
energyDemand += demand
n.amount = demand
})
if (isActive)
println("demand now (update)" + energyDemand)
}
def disconnectNode(receiver: Receiver) {
energyStorageList.clone().foreach(e => {
if (e == null || receiver == null) {
println("something null")
}
else if (e.node == receiver) {
energyStorageList -= e
energyDemand -= e.amount
if (isActive) {
receiver.isReceivingPower = false
updateNodes = true
}
}
})
if (isActive)
println("demand now (disc) " + energyDemand)
}
private var hasEnergy = false
override def update() {
super.update()
//check if is main
if (isActive) {
//if enough energy is available to supply all receivers
if (storedEnergy > energyDemand) {
storedEnergy -= energyDemand
if (!hasEnergy)
updateNodes = true
hasEnergy = true
println("energy level now " + storedEnergy)
}
else {
if (hasEnergy)
updateNodes = true
hasEnergy = false
}
//if nodes must be updated send message to them
if (updateNodes) {
if (hasEnergy)
energyStorageList.foreach(storage => storage.node.isReceivingPower = true)
else
energyStorageList.foreach(storage => storage.node.isReceivingPower = false)
updateNodes = false
}
}
}
def getDemand = {
MAXENERGY - storedEnergy max 0.0
}
def addEnergy(amount: Double) {
storedEnergy += amount
}
def searchMain() {
network.foreach(_.sendToVisible(this, "power.find") match {
case Some(Array(powerDistributor: Provider)) => {
println("found other distri")
isActive = false
}
case _ => {
println("no other")
isActive = true
updateNodes = true
println("demand now (new main) " + energyDemand)
}
})
}
class EnergyStorage(var node: Receiver, var amount: Double)
}