diff --git a/li/cil/oc/api/network/PoweredNode.scala b/li/cil/oc/api/network/PoweredNode.scala deleted file mode 100644 index 1f28880e3..000000000 --- a/li/cil/oc/api/network/PoweredNode.scala +++ /dev/null @@ -1,62 +0,0 @@ -package li.cil.oc.api.network - -import li.cil.oc.common.tileentity.PowerDistributor -import scala.collection.mutable.ArrayBuffer - - -trait PoweredNode extends Node { - var arrayBuffer = ArrayBuffer[PowerDistributor]() - var demand = 2 - - override def receive(message: Message): Option[Array[Any]] = { - message.name match { - case "system.connect" => { - message.source match { - case distributor: PowerDistributor => { - println("connect") - if (arrayBuffer.filter(p => p == distributor).isEmpty) { - arrayBuffer += distributor - distributor.connectNode(this, getDemand, getPriority) - } - } - case _ => - } - } - case "system.disconnect" => { - message.source match { - case distributor: PowerDistributor => { - println("connect") - if (arrayBuffer.contains(distributor)) { - arrayBuffer -= distributor - distributor.disconnectNode(this) - } - } - case _ => - } - } - case _ => - } - super.receive(message) - } - - def removeBuffer(distributor: PowerDistributor) = { - distributor.disconnectNode(this) - arrayBuffer -= distributor - } - - override protected def onDisconnect() { - - arrayBuffer.foreach(e => { - e.disconnectNode(this) - }) - super.onDisconnect() - } - - def getDemand: Int = 2 - - def getPriority: Int = 1 - - def updateDemand(demand: Int) { - arrayBuffer.foreach(e => e.updateDemand(this, getDemand)) - } -} diff --git a/li/cil/oc/api/network/Producer.scala b/li/cil/oc/api/network/Producer.scala new file mode 100644 index 000000000..857f57149 --- /dev/null +++ b/li/cil/oc/api/network/Producer.scala @@ -0,0 +1,30 @@ +package li.cil.oc.api.network + +trait Producer extends Receiver { + demand = 0 + + def powerDemand:Double= { + if (main != null) { + main.getDemand + } + else { + 0.0 + } + } + + def maxEnergy:Double= { + if (main != null) { + main.MAXENERGY + } + else { + 0.0 + } + + } + + def addEnergy(amount: Double) { + if (main != null) { + main.addEnergy(amount) + } + } +} diff --git a/li/cil/oc/api/network/Provider.scala b/li/cil/oc/api/network/Provider.scala new file mode 100644 index 000000000..93745dcd6 --- /dev/null +++ b/li/cil/oc/api/network/Provider.scala @@ -0,0 +1,188 @@ +package li.cil.oc.api.network + +import scala.collection.mutable +import net.minecraft.nbt.NBTTagCompound + + +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 load(nbt: NBTTagCompound) = { + super.load(nbt) + storedEnergy = nbt.getDouble("storedEnergy") + + } + + override def save(nbt: NBTTagCompound) = { + super.save(nbt) + nbt.setDouble("storedEnergy",storedEnergy) + + + } + + override def receive(message: Message): Option[Array[Any]] = { + 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. + } + } + super.receive(message) + + } + + /** + * Connect a reciever to the provider + * @param receiver + * @param amount + */ + def connectNode(receiver: Receiver, amount: Double) { + if (energyStorageList.filter(x => x.node == receiver).isEmpty) { + 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.unConnect() + updateNodes = true + } + } + + }) + if (isActive) + println("demand now (disc) " + energyDemand) + } + + override protected def onConnect() { + //check if other distributors already are in the network + searchMain() + super.onConnect() + } + + private var hasEnergy = false + override def update() { + super.update() + //check if is main + if (isActive) { + //if enough energy is available to supply all recievers + 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.connect()) + else + energyStorageList.foreach(storage=>storage.node.unConnect()) + 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) { + + } +} diff --git a/li/cil/oc/api/network/Receiver.scala b/li/cil/oc/api/network/Receiver.scala new file mode 100644 index 000000000..79240b2c7 --- /dev/null +++ b/li/cil/oc/api/network/Receiver.scala @@ -0,0 +1,141 @@ +package li.cil.oc.api.network + +import li.cil.oc.common.tileentity.PowerDistributor +import scala.collection.mutable +import net.minecraft.nbt.NBTTagCompound + + +trait Receiver extends Node { + var powerDistributors = mutable.Set[PowerDistributor]() + + private var _demand = 2.0 + + def demand = _demand + + def demand_=(value: Double) = { + + powerDistributors.foreach(e => e.updateDemand(this, value)) + _demand = value + } + + override def receive(message: Message): Option[Array[Any]] = { + message.name match { + case "system.connect" => { + message.source match { + case distributor: PowerDistributor => { + println("connect") + if (!powerDistributors.contains(distributor)) { + powerDistributors += distributor + distributor.connectNode(this, _demand) + } + } + case _ => + } + } + case "system.disconnect" => { + message.source match { + case distributor: PowerDistributor => { + println("connect") + if (powerDistributors.contains(distributor)) { + powerDistributors -= distributor + distributor.disconnectNode(this) + } + } + case _ => + } + } + case _ => + } + super.receive(message) + } + + + override protected def onDisconnect() { + super.onDisconnect() + powerDistributors.foreach(e => { + e.disconnectNode(this) + }) + + } + + + + def main: PowerDistributor = { + powerDistributors.find(p => p.isActive) match { + case Some(p: PowerDistributor) => p + case _ => null + } + + + } + override def load(nbt: NBTTagCompound) = { + super.load(nbt) + buffer = nbt.getDouble("buffer") + } + + override def save(nbt: NBTTagCompound) = { + super.save(nbt) + nbt.setDouble("buffer",buffer) + } + + private var buffer = 0.0 + private val maxBuffer = 100.0 + private var hasEnergy = false + private var isConnected = false + + override def update() { + super.update() + //if has enough energy to operate + if (isConnected) { + //increase buffer + if (maxBuffer > buffer + 1) + buffer += 1 + //notify if energy wasn't available before + if (!hasEnergy) { + hasEnergy = true + onPowerAvailable() + } + } + else { + //continue running until we are out of energy + if (buffer - demand < 0) { + if (hasEnergy) { + hasEnergy = false + onPowerLoss() + } + } else { + buffer -= demand + } + } + } + + /** + * called from the producer when he has enough energy to operate + */ + final def connect() { + isConnected = true + } + + /** + * Called from the producer when there is not enough energy to operate + */ + final def unConnect() { + isConnected = false + } + + /** + * Called when the receiver has enough power to operate. + */ + def onPowerAvailable() { + println("received energy") + } + + /** + * Called when the receiver has no power to operate. This can happen at a later time + * then unConnect was called, because of the internal capacity + */ + def onPowerLoss() { + println("no more energy") + } +} + diff --git a/li/cil/oc/common/tileentity/Computer.scala b/li/cil/oc/common/tileentity/Computer.scala index 8a04a45ac..edd026284 100644 --- a/li/cil/oc/common/tileentity/Computer.scala +++ b/li/cil/oc/common/tileentity/Computer.scala @@ -2,7 +2,7 @@ package li.cil.oc.common.tileentity import java.util.concurrent.atomic.AtomicBoolean import li.cil.oc.api.driver.Slot -import li.cil.oc.api.network.PoweredNode +import li.cil.oc.api.network.Receiver import li.cil.oc.client.{PacketSender => ClientPacketSender} import li.cil.oc.server.component import li.cil.oc.server.component.Redstone @@ -14,7 +14,7 @@ import net.minecraft.item.ItemStack import net.minecraft.nbt.NBTTagCompound import net.minecraftforge.common.ForgeDirection -class Computer(isClient: Boolean) extends Rotatable with component.Computer.Environment with ComponentInventory with Redstone with PoweredNode { +class Computer(isClient: Boolean) extends Rotatable with component.Computer.Environment with ComponentInventory with Redstone with Receiver { def this() = this(false) // ----------------------------------------------------------------------- // @@ -65,7 +65,7 @@ class Computer(isClient: Boolean) extends Rotatable with component.Computer.Envi override def updateEntity() = if (!worldObj.isRemote) { computer.update() - + update() if (hasChanged.get) worldObj.markTileEntityChunkModified(xCoord, yCoord, zCoord, this) if (isRunning != computer.isRunning) diff --git a/li/cil/oc/common/tileentity/PowerDistributor.scala b/li/cil/oc/common/tileentity/PowerDistributor.scala index bfc31d140..54b2eafdb 100644 --- a/li/cil/oc/common/tileentity/PowerDistributor.scala +++ b/li/cil/oc/common/tileentity/PowerDistributor.scala @@ -1,141 +1,30 @@ package li.cil.oc.common.tileentity -import li.cil.oc.api.network.{PoweredNode, Message, Visibility} -import scala.collection.mutable.ArrayBuffer +import li.cil.oc.api.network._ +import scala.collection.mutable +import net.minecraft.nbt.NBTTagCompound + +class PowerDistributor extends Rotatable with Provider { -class PowerDistributor extends Rotatable with PoweredNode { - - var isActive = true - var energyStorageList = ArrayBuffer[EnergyStorage]() - var energyDemand = 0 - demand = 1 + //MAXENERGY = 2000.0.toDouble override val name = "powerdistributor" override val visibility = Visibility.Network - - override def receive(message: Message): Option[Array[Any]] = { - - message.name match { - case "system.connect" => { - message.source match { - case distributor: PowerDistributor => - //if other powerDistributor connected and is active set inactive - if (message.source != this && distributor.isActive) { - isActive = false - - println("demand now (disabled) " + 0) - } - case _ => - } - } - case "power.find" => { - message.source match { - case distributor: PowerDistributor => - //received request from other distributor that is newly connected... set it to inactive - - if (isActive && message.source != this) { - distributor.isActive = false - } - case _ => - } - } - case "system.disconnect" => { - message.source match { - case distributor: PowerDistributor => - println("distri disc recieved") - if (distributor.isActive && distributor != this) { - isActive = true - network.foreach(_.sendToVisible(this, "power.find")) - - println("demand now (new main) " + energyDemand) - } - case _ => - } - - } - case _ => // Ignore. - } - super.receive(message) - - } - - def connectNode(node: PoweredNode, amount: Int, priority: Int) { - if (energyStorageList.filter(x => x.node == node).isEmpty) { - energyStorageList += new EnergyStorage(node, amount, priority) - energyDemand += amount - } - - if (isActive) - println("demand now (connect)" + energyDemand) - } - - /** - * Updates the demand of the node to the given value - * @param node - * @param demand - */ - def updateDemand(node: PoweredNode, demand: Int) { - energyStorageList.filter(n => n.node == node).foreach(n => { - energyDemand -= n.amount - energyDemand += demand - n.amount = demand - }) - if (isActive) - println("demand now (update)" + energyDemand) - } - - def disconnectNode(node: PoweredNode) { - energyStorageList.clone().foreach(e => { - if (e == null || node == null) { - println("something null") - - } - else if (e.node == node) { - energyStorageList -= e - energyDemand -= e.amount - } - - }) - if (isActive) - println("demand now (disc) " + energyDemand) - } - - override protected def onConnect() { - //check if other distributors already are in the network - network.foreach(_.sendToVisible(this, "power.find")) - super.onConnect() - } - - override protected def onDisconnect() { - println("disc distri other " + arrayBuffer.length) - super.onDisconnect() - energyStorageList.clone().foreach(e => { - - e.node.removeBuffer(this) - if (energyStorageList.contains(e)) { - - energyStorageList -= e - energyDemand -= e.amount - } - - }) - if (isActive) - println("demand now (close) " + energyDemand) - } - - override def updateEntity() { + override def updateEntity(){ super.updateEntity() - if (isActive) { - - } - //TODO remove energy + update() } - class EnergyStorage(var node: PoweredNode, var amount: Int, var priority: Int) { - + override def readFromNBT(nbt: NBTTagCompound) = { + super.readFromNBT(nbt) + load(nbt) } + override def writeToNBT(nbt: NBTTagCompound) = { + super.writeToNBT(nbt) + save(nbt) + } } diff --git a/li/cil/oc/common/tileentity/PowerSupply.scala b/li/cil/oc/common/tileentity/PowerSupply.scala index 76c72de8d..01339829e 100644 --- a/li/cil/oc/common/tileentity/PowerSupply.scala +++ b/li/cil/oc/common/tileentity/PowerSupply.scala @@ -1,7 +1,8 @@ package li.cil.oc.common.tileentity import net.minecraft.tileentity.TileEntity -import li.cil.oc.api.network.{PoweredNode, Visibility, Node} +import li.cil.oc.api.network._ + import net.minecraftforge.common.{ForgeDirection, MinecraftForge} import ic2.api.energy.event.{EnergyTileLoadEvent, EnergyTileUnloadEvent} import cpw.mods.fml.common.FMLCommonHandler @@ -19,46 +20,50 @@ import universalelectricity.core.electricity.ElectricityPack * Time: 20:37 * To change this template use File | Settings | File Templates. */ -class PowerSupply extends Rotatable with PoweredNode with IEnergySink with IPowerReceptor with IElectrical{ +class PowerSupply extends Rotatable with Producer with IEnergySink with IPowerReceptor with IElectrical { var addedToEnet = false - var powerHandler:PowerHandler = null + var powerHandler: PowerHandler = null + override val name = "powersupply" override val visibility = Visibility.Network - override def onChunkUnload(){ + override def onChunkUnload() { super.onChunkUnload() - onUnload() + onUnload() } - def onUnload(){ - if(addedToEnet){ + + def onUnload() { + if (addedToEnet) { MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this)) addedToEnet = false } } - override def updateEntity(){ - super.updateEntity() - if(!addedToEnet) { - onLoaded() - } - if(!FMLCommonHandler.instance.getEffectiveSide.isClient) - { - storedEnergy+=getPowerProvider().useEnergy(1,(MAXENERGY-storedEnergy).toFloat/5.0f,true)*5; - - } + override def updateEntity() { + super.updateEntity() + update() + if (!addedToEnet) { + onLoaded() } + if (!FMLCommonHandler.instance.getEffectiveSide.isClient) { + + addEnergy((getPowerProvider().useEnergy(1, powerDemand.toFloat / 5.0f, true) * 5).toDouble) + + } + } override def readFromNBT(nbt: NBTTagCompound) = { super.readFromNBT(nbt) getPowerProvider().readFromNBT(nbt) - storedEnergy = nbt.getDouble("storedEnergy") + } + override def writeToNBT(nbt: NBTTagCompound) = { super.writeToNBT(nbt) getPowerProvider().writeToNBT(nbt) - nbt.setDouble("storedEnergy",storedEnergy) + } @@ -73,9 +78,8 @@ class PowerSupply extends Rotatable with PoweredNode with IEnergySink with IPowe } } - var storedEnergy = 0.0; - var lastInjectedEnergy =0.0; - var MAXENERGY = 1000; + + var lastInjectedEnergy = 0.0 //IC2 stuff /** * Determine how much energy the sink accepts. @@ -86,11 +90,14 @@ class PowerSupply extends Rotatable with PoweredNode with IEnergySink with IPowe * * @return max accepted input in eu */ - override def demandedEnergyUnits: Double={ - val needed = MAXENERGY-storedEnergy - if(needed>lastInjectedEnergy||needed>MAXENERGY/2) - return needed/2 - 0 + override def demandedEnergyUnits: Double = { + + val needed = powerDemand + if (needed > lastInjectedEnergy || needed > (maxEnergy / 2.0)) { + return needed / 2 + } + 0.0 + } /** @@ -103,9 +110,9 @@ class PowerSupply extends Rotatable with PoweredNode with IEnergySink with IPowe * @param amount energy to be transferred * @return Energy not consumed (leftover) */ - override def injectEnergyUnits(directionFrom: ForgeDirection, amount: Double): Double ={ - lastInjectedEnergy = amount*2; - storedEnergy+=amount*2; + override def injectEnergyUnits(directionFrom: ForgeDirection, amount: Double): Double = { + lastInjectedEnergy = amount * 2.0 + addEnergy(amount * 2.0) 0 } @@ -119,7 +126,7 @@ class PowerSupply extends Rotatable with PoweredNode with IEnergySink with IPowe * * @return max safe input in eu */ - override def getMaxSafeInput: Int =Integer.MAX_VALUE + override def getMaxSafeInput: Int = Integer.MAX_VALUE /** * Determine if this acceptor can accept current from an adjacent emitter in a direction. @@ -146,21 +153,21 @@ class PowerSupply extends Rotatable with PoweredNode with IEnergySink with IPowe * @param side * @return */ - def getPowerReceiver(side: ForgeDirection): PowerHandler#PowerReceiver={ + def getPowerReceiver(side: ForgeDirection): PowerHandler#PowerReceiver = { - return getPowerProvider().getPowerReceiver + getPowerProvider().getPowerReceiver } - def getPowerProvider():PowerHandler= - { - if (powerHandler == null) - { + + def getPowerProvider(): PowerHandler = { + if (powerHandler == null) { powerHandler = new PowerHandler(this, PowerHandler.Type.STORAGE); if (powerHandler != null) { powerHandler.configure(1.0F, 320.0F, 800.0F, 640.0F); } } - return powerHandler; + powerHandler; } + /** * Call back from the PowerHandler that is called when the stored power exceeds the activation * power. @@ -169,11 +176,11 @@ class PowerSupply extends Rotatable with PoweredNode with IEnergySink with IPowe * * @param workProvider */ - def doWork(workProvider: PowerHandler){ + def doWork(workProvider: PowerHandler) { } - def getWorld: World=worldObj + def getWorld: World = worldObj /** * UE************************* @@ -188,15 +195,14 @@ class PowerSupply extends Rotatable with PoweredNode with IEnergySink with IPowe * @param doReceive If false, the charge will only be simulated. * @return Amount of energy that was accepted by the block. */ - def receiveElectricity(from: ForgeDirection, receive: ElectricityPack, doReceive: Boolean): Float={ - if (receive == null) return 0.0F; + def receiveElectricity(from: ForgeDirection, receive: ElectricityPack, doReceive: Boolean): Float = { + if (receive == null) return 0.0F - if (doReceive) - { - val energy = receive.getWatts() / 0.2F; - storedEnergy += energy; + if (doReceive) { + val energy = receive.getWatts / 0.2F + addEnergy(energy.toDouble) } - return receive.getWatts(); + receive.getWatts } /** @@ -208,28 +214,28 @@ class PowerSupply extends Rotatable with PoweredNode with IEnergySink with IPowe * @param doProvide If false, the charge will only be simulated. * @return Amount of energy that was given out by the block. */ - def provideElectricity(from: ForgeDirection, request: ElectricityPack, doProvide: Boolean): ElectricityPack =null + def provideElectricity(from: ForgeDirection, request: ElectricityPack, doProvide: Boolean): ElectricityPack = null /** * @return How much energy does this TileEntity want? */ - def getRequest(direction: ForgeDirection): Float ={ - val diff = Math.floor((MAXENERGY - storedEnergy) * 0.2F) - return diff.toFloat max 0 + def getRequest(direction: ForgeDirection): Float = { + val diff = Math.floor(powerDemand * 0.2F) + diff.toFloat max 0 } /** * @return How much energy does this TileEntity want to provide? */ - def getProvide(direction: ForgeDirection): Float = 0.0F + def getProvide(direction: ForgeDirection): Float = 0.0F /** * Gets the voltage of this TileEntity. * * @return The amount of volts. E.g 120v or 240v */ - def getVoltage: Float =120.0F + def getVoltage: Float = 120.0F - def canConnect(direction:ForgeDirection):Boolean = true + def canConnect(direction: ForgeDirection): Boolean = true } diff --git a/li/cil/oc/common/tileentity/Screen.scala b/li/cil/oc/common/tileentity/Screen.scala index 9854dacf9..f9bfefb30 100644 --- a/li/cil/oc/common/tileentity/Screen.scala +++ b/li/cil/oc/common/tileentity/Screen.scala @@ -1,13 +1,13 @@ package li.cil.oc.common.tileentity -import li.cil.oc.api.network.PoweredNode +import li.cil.oc.api.network.Receiver import li.cil.oc.client.gui import li.cil.oc.client.{PacketSender => ClientPacketSender} import li.cil.oc.common.component import li.cil.oc.server.{PacketSender => ServerPacketSender} import net.minecraft.nbt.NBTTagCompound -class Screen extends Rotatable with component.Screen.Environment with PoweredNode { +class Screen extends Rotatable with component.Screen.Environment with Receiver { var guiScreen: Option[gui.Screen] = None /**