Rewriting fluid nodes and grids
This commit is contained in:
parent
0f17ae4269
commit
a7ebb5de9a
10 changed files with 387 additions and 532 deletions
|
@ -8,10 +8,9 @@ import net.minecraft.item.ItemStack
|
||||||
import net.minecraftforge.common.MinecraftForge
|
import net.minecraftforge.common.MinecraftForge
|
||||||
import net.minecraftforge.common.config.Configuration
|
import net.minecraftforge.common.config.Configuration
|
||||||
import org.modstats.{ModstatInfo, Modstats}
|
import org.modstats.{ModstatInfo, Modstats}
|
||||||
import resonant.engine.References
|
import resonant.engine.{References, ResonantEngine}
|
||||||
import resonant.lib.config.ConfigHandler
|
import resonant.lib.config.ConfigHandler
|
||||||
import resonant.lib.loadable.LoadableHandler
|
import resonant.lib.loadable.LoadableHandler
|
||||||
import resonant.lib.network.netty.PacketManager
|
|
||||||
import resonantinduction.core.handler.TextureHookHandler
|
import resonantinduction.core.handler.TextureHookHandler
|
||||||
import resonantinduction.core.resource.ResourceGenerator
|
import resonantinduction.core.resource.ResourceGenerator
|
||||||
|
|
||||||
|
@ -25,7 +24,7 @@ import scala.collection.convert.wrapAll._
|
||||||
object ResonantInduction
|
object ResonantInduction
|
||||||
{
|
{
|
||||||
/** Packets */
|
/** Packets */
|
||||||
val packetHandler = new PacketManager(Reference.channel)
|
val packetHandler = ResonantEngine.instance.packetHandler
|
||||||
val loadables = new LoadableHandler
|
val loadables = new LoadableHandler
|
||||||
|
|
||||||
@SidedProxy(clientSide = "resonantinduction.core.ClientProxy", serverSide = "resonantinduction.core.CommonProxy")
|
@SidedProxy(clientSide = "resonantinduction.core.ClientProxy", serverSide = "resonantinduction.core.CommonProxy")
|
||||||
|
|
|
@ -1,163 +1,94 @@
|
||||||
package resonantinduction.core.grid.fluid
|
package resonantinduction.core.grid.fluid
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.network.ByteBufUtils
|
||||||
import io.netty.buffer.ByteBuf
|
import io.netty.buffer.ByteBuf
|
||||||
import net.minecraft.block.material.Material
|
import net.minecraft.block.material.Material
|
||||||
import net.minecraft.entity.player.EntityPlayer
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
import net.minecraft.nbt.NBTTagCompound
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
import net.minecraft.network.Packet
|
|
||||||
import net.minecraftforge.common.util.ForgeDirection
|
import net.minecraftforge.common.util.ForgeDirection
|
||||||
import net.minecraftforge.fluids._
|
import net.minecraftforge.fluids._
|
||||||
import resonant.content.prefab.java.TileAdvanced
|
import resonant.content.prefab.java.TileAdvanced
|
||||||
import resonant.lib.network.ByteBufWrapper.ByteBufWrapper
|
import resonant.lib.network.discriminator.{PacketTile, PacketType}
|
||||||
import resonant.lib.network.discriminator.PacketType
|
|
||||||
import resonant.lib.network.handle.{IPacketIDReceiver, TPacketIDSender}
|
import resonant.lib.network.handle.{IPacketIDReceiver, TPacketIDSender}
|
||||||
import resonant.lib.network.netty.PacketManager
|
import resonantinduction.core.prefab.node.NodeTank
|
||||||
import resonant.lib.utility.FluidUtility
|
|
||||||
import resonantinduction.core.ResonantInduction
|
|
||||||
import resonantinduction.core.grid.fluid.distribution.TankNode
|
|
||||||
import universalelectricity.api.core.grid.{INode, INodeProvider}
|
import universalelectricity.api.core.grid.{INode, INodeProvider}
|
||||||
import universalelectricity.core.transform.vector.Vector3
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A prefab class for tiles that use the fluid network.
|
* A prefab class for tiles that use the fluid network.
|
||||||
*
|
*
|
||||||
* @author DarkGuardsman
|
* @author DarkGuardsman
|
||||||
*/
|
*/
|
||||||
object TileTankNode extends Enumeration
|
|
||||||
{
|
|
||||||
final val PACKET_DESCRIPTION, PACKET_RENDER, PACKET_TANK = Value
|
|
||||||
}
|
|
||||||
|
|
||||||
class TileTankNode(material: Material) extends TileAdvanced(material) with INodeProvider with IFluidHandler with IPacketIDReceiver with TPacketIDSender
|
class TileTankNode(material: Material) extends TileAdvanced(material) with INodeProvider with IFluidHandler with IPacketIDReceiver with TPacketIDSender
|
||||||
{
|
{
|
||||||
protected var tank: FluidTank = new FluidTank(1000);
|
val PACKET_DESCRIPTION = 0
|
||||||
protected var pressure = 0
|
val PACKET_RENDER = 1
|
||||||
protected var colorID: Int = 0
|
protected var colorID: Int = 0
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy of the tank's content last time it updated
|
|
||||||
*/
|
|
||||||
protected var prevStack: FluidStack = null
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bitmask that handles connections for the renderer
|
|
||||||
*/
|
|
||||||
var renderSides: Byte = 0
|
var renderSides: Byte = 0
|
||||||
protected var markTankUpdate = false
|
|
||||||
protected final val tankSize = 0
|
|
||||||
|
|
||||||
var tankNode : TankNode = new TankNode(this)
|
var tankNode : NodeTank = new NodeTank(this)
|
||||||
|
|
||||||
override def update()
|
def getTank() : IFluidTank = tankNode
|
||||||
{
|
|
||||||
super.update()
|
|
||||||
|
|
||||||
if (markTankUpdate)
|
def getFluid() : FluidStack = getTank().getFluid
|
||||||
{
|
|
||||||
sendTankUpdate
|
|
||||||
markTankUpdate = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def getTank() : FluidTank = tank
|
def getFluidCapacity() : Int = getTank().getCapacity
|
||||||
|
|
||||||
def getFluid() : FluidStack = tank.getFluid
|
|
||||||
|
|
||||||
def getFluidCapacity() : Int = tank.getCapacity
|
|
||||||
|
|
||||||
override def readFromNBT(nbt: NBTTagCompound)
|
override def readFromNBT(nbt: NBTTagCompound)
|
||||||
{
|
{
|
||||||
super.readFromNBT(nbt)
|
super.readFromNBT(nbt)
|
||||||
|
tankNode.load(nbt)
|
||||||
colorID = nbt.getInteger("colorID")
|
colorID = nbt.getInteger("colorID")
|
||||||
tank.readFromNBT(nbt.getCompoundTag("FluidTank"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override def writeToNBT(nbt: NBTTagCompound)
|
override def writeToNBT(nbt: NBTTagCompound)
|
||||||
{
|
{
|
||||||
super.writeToNBT(nbt)
|
super.writeToNBT(nbt)
|
||||||
|
tankNode.save(nbt)
|
||||||
nbt.setInteger("colorID", colorID)
|
nbt.setInteger("colorID", colorID)
|
||||||
nbt.setTag("FluidTank", tank.writeToNBT(new NBTTagCompound))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override def write(buf: ByteBuf, id: Int)
|
|
||||||
{
|
|
||||||
super.write(buf, id)
|
|
||||||
|
|
||||||
if (id == TileTankNode.PACKET_DESCRIPTION.id)
|
|
||||||
{
|
|
||||||
buf <<< colorID
|
|
||||||
buf <<< renderSides
|
|
||||||
buf <<< tank
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (id == TileTankNode.PACKET_RENDER.id)
|
|
||||||
{
|
|
||||||
buf <<< colorID
|
|
||||||
buf <<< renderSides
|
|
||||||
}
|
|
||||||
else if (id == TileTankNode.PACKET_TANK.id)
|
|
||||||
{
|
|
||||||
buf <<< tank
|
|
||||||
buf <<< pressure
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override def read(buf: ByteBuf, id: Int, player: EntityPlayer, packet: PacketType) : Boolean =
|
|
||||||
{
|
|
||||||
if (world.isRemote)
|
|
||||||
{
|
|
||||||
if (id == TileTankNode.PACKET_DESCRIPTION.id)
|
|
||||||
{
|
|
||||||
colorID = buf.readInt
|
|
||||||
renderSides = buf.readByte
|
|
||||||
tank = buf.readTank()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
else if (id == TileTankNode.PACKET_RENDER.id)
|
|
||||||
{
|
|
||||||
colorID = buf.readInt
|
|
||||||
renderSides = buf.readByte
|
|
||||||
markRender
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
else if (id == TileTankNode.PACKET_TANK.id)
|
|
||||||
{
|
|
||||||
tank = buf.readTank()
|
|
||||||
pressure = buf.readInt
|
|
||||||
updateLight()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
override def getDescriptionPacket: Packet = ResonantInduction.packetHandler.toMCPacket(PacketManager.request(this, TileTankNode.PACKET_DESCRIPTION.id))
|
|
||||||
|
|
||||||
def sendRenderUpdate
|
def sendRenderUpdate
|
||||||
{
|
{
|
||||||
if (!world.isRemote)
|
if (!world.isRemote)
|
||||||
ResonantInduction.packetHandler.sendToAll(PacketManager.request(this, TileTankNode.PACKET_RENDER.id))
|
|
||||||
}
|
|
||||||
|
|
||||||
def sendTankUpdate
|
|
||||||
{
|
{
|
||||||
if (!world.isRemote)
|
val packet: PacketTile = new PacketTile(this);
|
||||||
ResonantInduction.packetHandler.sendToAllAround(PacketManager.request(this, TileTankNode.PACKET_TANK.id), world, new Vector3(this), 60)
|
packet <<< PACKET_RENDER
|
||||||
}
|
packet <<< colorID
|
||||||
|
packet <<< renderSides
|
||||||
def onFluidChanged()
|
sendPacket(packet)
|
||||||
{
|
|
||||||
if (!worldObj.isRemote)
|
|
||||||
{
|
|
||||||
if (!FluidUtility.matchExact(prevStack, tank.getFluid) || ticks == 0)
|
|
||||||
{
|
|
||||||
markTankUpdate = true
|
|
||||||
prevStack = if (tank.getFluid != null) tank.getFluid.copy else null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override def getNode(nodeType: Class[_ <: INode], from: ForgeDirection): INode = if(nodeType.isInstanceOf[TankNode]) return tankNode else null
|
override def getDescPacket() : PacketTile =
|
||||||
|
{
|
||||||
|
val packet: PacketTile = new PacketTile(this);
|
||||||
|
packet <<< PACKET_DESCRIPTION
|
||||||
|
packet <<< colorID
|
||||||
|
packet <<< renderSides
|
||||||
|
val tag : NBTTagCompound = new NBTTagCompound()
|
||||||
|
tankNode.save(tag)
|
||||||
|
packet <<< tag
|
||||||
|
sendPacket(packet)
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
override def read(buf: ByteBuf, id: Int, player: EntityPlayer, t: PacketType): Boolean =
|
||||||
|
{
|
||||||
|
if(id == PACKET_DESCRIPTION)
|
||||||
|
{
|
||||||
|
colorID = buf.readInt()
|
||||||
|
renderSides = buf.readByte()
|
||||||
|
tankNode.load(ByteBufUtils.readTag(buf))
|
||||||
|
}
|
||||||
|
else if(id == PACKET_RENDER)
|
||||||
|
{
|
||||||
|
colorID = buf.readInt()
|
||||||
|
renderSides = buf.readByte()
|
||||||
|
}
|
||||||
|
return tankNode.read(buf, id, player, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
override def getNode(nodeType: Class[_ <: INode], from: ForgeDirection): INode = if(nodeType.isInstanceOf[NodeTank]) return tankNode else null
|
||||||
|
|
||||||
override def drain(from: ForgeDirection, resource: FluidStack, doDrain: Boolean): FluidStack = tankNode.drain(from, resource, doDrain)
|
override def drain(from: ForgeDirection, resource: FluidStack, doDrain: Boolean): FluidStack = tankNode.drain(from, resource, doDrain)
|
||||||
|
|
||||||
|
|
|
@ -1,104 +0,0 @@
|
||||||
package resonantinduction.core.grid.fluid.distribution
|
|
||||||
|
|
||||||
import net.minecraft.nbt.NBTTagCompound
|
|
||||||
import net.minecraftforge.common.util.ForgeDirection
|
|
||||||
import net.minecraftforge.fluids.{Fluid, FluidStack, FluidTankInfo, IFluidHandler}
|
|
||||||
import resonant.lib.utility.WorldUtility
|
|
||||||
import resonantinduction.core.grid.MultipartNode
|
|
||||||
import universalelectricity.api.core.grid.{ISave, IGridNode, INodeProvider}
|
|
||||||
|
|
||||||
class TankNode(parent: INodeProvider) extends MultipartNode(parent) with IFluidHandler with ISave with IGridNode
|
|
||||||
{
|
|
||||||
var maxFlowRate: Int = 20
|
|
||||||
var maxPressure: Int = 100
|
|
||||||
|
|
||||||
//TODO: Do we actually call this?
|
|
||||||
private var pressure: Int = 0
|
|
||||||
var connectedSides: Byte = 0
|
|
||||||
|
|
||||||
def getMaxFlowRate: Int =
|
|
||||||
{
|
|
||||||
return maxFlowRate
|
|
||||||
}
|
|
||||||
|
|
||||||
def setPressure(newPressure: Int)
|
|
||||||
{
|
|
||||||
if (newPressure > 0)
|
|
||||||
{
|
|
||||||
pressure = Math.min(maxPressure, newPressure)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pressure = Math.max(-maxPressure, newPressure)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def getPressure(dir: ForgeDirection): Int =
|
|
||||||
{
|
|
||||||
return pressure
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recache the connections. This is the default connection implementation.
|
|
||||||
*/
|
|
||||||
override def doRecache
|
|
||||||
{
|
|
||||||
connections.clear
|
|
||||||
|
|
||||||
if (world != null && !world.isRemote)
|
|
||||||
{
|
|
||||||
val previousSides = connectedSides
|
|
||||||
connectedSides = 0
|
|
||||||
|
|
||||||
for (dir <- ForgeDirection.VALID_DIRECTIONS)
|
|
||||||
{
|
|
||||||
val tile = (position + dir).getTileEntity
|
|
||||||
|
|
||||||
if (tile.isInstanceOf[INodeProvider] && tile.asInstanceOf[INodeProvider].getNode(classOf[TankNode], dir.getOpposite).isInstanceOf[TankNode])
|
|
||||||
{
|
|
||||||
connections.put(tile.asInstanceOf[INodeProvider].getNode(classOf[TankNode], dir.getOpposite).asInstanceOf[TankNode], dir)
|
|
||||||
connectedSides = WorldUtility.setEnableSide(connectedSides, dir, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (previousSides != connectedSides)
|
|
||||||
{
|
|
||||||
//TODO: Check and fix
|
|
||||||
getGrid.reconstruct()
|
|
||||||
//onChange.apply()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override def canConnect(from: ForgeDirection, source: AnyRef): Boolean =
|
|
||||||
{
|
|
||||||
//TODO: Check this
|
|
||||||
return source.isInstanceOf[TankNode]
|
|
||||||
}
|
|
||||||
|
|
||||||
def getForwardTank : TankGrid = getGrid.asInstanceOf[TankGrid]
|
|
||||||
|
|
||||||
override protected def newGrid() = new TankGrid
|
|
||||||
|
|
||||||
def load(nbt: NBTTagCompound)
|
|
||||||
{
|
|
||||||
pressure = nbt.getInteger("pressure")
|
|
||||||
}
|
|
||||||
|
|
||||||
def save(nbt: NBTTagCompound)
|
|
||||||
{
|
|
||||||
nbt.setInteger("pressure", pressure)
|
|
||||||
}
|
|
||||||
|
|
||||||
override def drain(from: ForgeDirection, resource: FluidStack, doDrain: Boolean): FluidStack = getForwardTank.drain(from, resource, doDrain)
|
|
||||||
|
|
||||||
override def drain(from: ForgeDirection, maxDrain: Int, doDrain: Boolean): FluidStack = getForwardTank.drain(from, maxDrain, doDrain)
|
|
||||||
|
|
||||||
override def canFill(from: ForgeDirection, fluid: Fluid): Boolean = getForwardTank.canFill(from, fluid)
|
|
||||||
|
|
||||||
override def canDrain(from: ForgeDirection, fluid: Fluid): Boolean = getForwardTank.canDrain(from, fluid)
|
|
||||||
|
|
||||||
override def fill(from: ForgeDirection, resource: FluidStack, doFill: Boolean): Int = getForwardTank.fill(from, resource, doFill)
|
|
||||||
|
|
||||||
override def getTankInfo(from: ForgeDirection): Array[FluidTankInfo] = getForwardTank.getTankInfo(from)
|
|
||||||
}
|
|
|
@ -1,176 +0,0 @@
|
||||||
package resonantinduction.core.grid.fluid.pressure
|
|
||||||
|
|
||||||
import net.minecraftforge.common.util.ForgeDirection
|
|
||||||
import resonantinduction.core.grid.fluid.distribution.TankNode
|
|
||||||
import universalelectricity.api.core.grid.INodeProvider
|
|
||||||
|
|
||||||
import scala.collection.convert.wrapAll._
|
|
||||||
|
|
||||||
class FluidPressureNode(parent: INodeProvider) extends TankNode(parent)
|
|
||||||
{
|
|
||||||
protected var connectionMap: Byte = java.lang.Byte.parseByte("111111", 2)
|
|
||||||
private var pressure = 0
|
|
||||||
|
|
||||||
def setConnection(connectionMap: Byte): FluidPressureNode =
|
|
||||||
{
|
|
||||||
this.connectionMap = connectionMap
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
def setMaxFlowRate(flow : Int) {maxFlowRate = flow }
|
|
||||||
def setMaxPressure(p : Int) {maxPressure = p}
|
|
||||||
|
|
||||||
override def update(deltaTime: Double)
|
|
||||||
{
|
|
||||||
if (!world.isRemote)
|
|
||||||
{
|
|
||||||
updatePressure
|
|
||||||
distribute
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected def updatePressure()
|
|
||||||
{
|
|
||||||
var totalPressure = 0
|
|
||||||
val connectionSize = connections.size
|
|
||||||
var minPressure = 0
|
|
||||||
var maxPressure = 0
|
|
||||||
|
|
||||||
connections
|
|
||||||
.filterKeys(_.isInstanceOf[FluidPressureNode])
|
|
||||||
.map({ case (k: AnyRef, v: ForgeDirection) => (k.asInstanceOf[FluidPressureNode], v) })
|
|
||||||
.foreach
|
|
||||||
{
|
|
||||||
case (node: FluidPressureNode, dir: ForgeDirection) =>
|
|
||||||
{
|
|
||||||
val pressure = node.getPressure(dir.getOpposite)
|
|
||||||
minPressure = Math.min(pressure, minPressure)
|
|
||||||
maxPressure = Math.max(pressure, maxPressure)
|
|
||||||
totalPressure += pressure
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connectionSize == 0)
|
|
||||||
{
|
|
||||||
setPressure(0)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (minPressure < 0)
|
|
||||||
{
|
|
||||||
minPressure += 1
|
|
||||||
}
|
|
||||||
if (maxPressure > 0)
|
|
||||||
{
|
|
||||||
maxPressure -= 1
|
|
||||||
}
|
|
||||||
|
|
||||||
setPressure(Math.max(minPressure, Math.min(maxPressure, totalPressure / connectionSize + Integer.signum(totalPressure))))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def distribute
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
connections.foreach
|
|
||||||
{
|
|
||||||
case (obj: AnyRef, dir: ForgeDirection) =>
|
|
||||||
{
|
|
||||||
if (obj.isInstanceOf[FluidPressureNode])
|
|
||||||
{
|
|
||||||
val otherNode: FluidPressureNode = obj.asInstanceOf[FluidPressureNode]
|
|
||||||
val pressureA = getPressure(dir)
|
|
||||||
val pressureB = otherNode.getPressure(dir.getOpposite)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* High pressure from this node flows to low pressure nodes.
|
|
||||||
*/
|
|
||||||
if (pressureA >= pressureB)
|
|
||||||
{
|
|
||||||
val tankA = genericParent.getTank
|
|
||||||
if (tankA != null)
|
|
||||||
{
|
|
||||||
val fluidA: FluidStack = tankA.getFluid
|
|
||||||
if (fluidA != null)
|
|
||||||
{
|
|
||||||
val amountA: Int = fluidA.amount
|
|
||||||
if (amountA > 0)
|
|
||||||
{
|
|
||||||
val tankB: FluidTank = otherNode.genericParent.getTank
|
|
||||||
if (tankB != null)
|
|
||||||
{
|
|
||||||
val amountB: Int = tankB.getFluidAmount
|
|
||||||
var quantity: Int = Math.max(if (pressureA > pressureB) (pressureA - pressureB) * getMaxFlowRate else 0, Math.min((amountA - amountB) / 2, getMaxFlowRate))
|
|
||||||
quantity = Math.min(Math.min(quantity, tankB.getCapacity - amountB), amountA)
|
|
||||||
if (quantity > 0)
|
|
||||||
{
|
|
||||||
val drainStack: FluidStack = genericParent.drain(dir.getOpposite, quantity, false)
|
|
||||||
if (drainStack != null && drainStack.amount > 0)
|
|
||||||
{
|
|
||||||
genericParent.drain(dir.getOpposite, otherNode.genericParent.fill(dir, drainStack, true), true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (obj.isInstanceOf[IFluidHandler])
|
|
||||||
{
|
|
||||||
val fluidHandler: IFluidHandler = obj.asInstanceOf[IFluidHandler]
|
|
||||||
val pressure: Int = getPressure(dir)
|
|
||||||
val tankPressure: Int = if (fluidHandler.isInstanceOf[INodeProvider]) (fluidHandler.asInstanceOf[INodeProvider]).getNode(classOf[FluidPressureNode], dir.getOpposite).asInstanceOf[FluidPressureNode].getPressure(dir.getOpposite) else 0
|
|
||||||
val sourceTank = genericParent.getTank
|
|
||||||
val transferAmount: Int = (Math.max(pressure, tankPressure) - Math.min(pressure, tankPressure)) * getMaxFlowRate
|
|
||||||
if (pressure > tankPressure)
|
|
||||||
{
|
|
||||||
if (sourceTank.getFluidAmount > 0 && transferAmount > 0)
|
|
||||||
{
|
|
||||||
val drainStack: FluidStack = genericParent.drain(dir.getOpposite, transferAmount, false)
|
|
||||||
genericParent.drain(dir.getOpposite, fluidHandler.fill(dir.getOpposite, drainStack, true), true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (pressure < tankPressure)
|
|
||||||
{
|
|
||||||
if (transferAmount > 0)
|
|
||||||
{
|
|
||||||
val drainStack: FluidStack = fluidHandler.drain(dir.getOpposite, transferAmount, false)
|
|
||||||
if (drainStack != null)
|
|
||||||
{
|
|
||||||
fluidHandler.drain(dir.getOpposite, genericParent.fill(dir.getOpposite, drainStack, true), true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recache the connections. This is the default connection implementation.
|
|
||||||
*/
|
|
||||||
override def doRecache
|
|
||||||
{
|
|
||||||
connections.clear()
|
|
||||||
|
|
||||||
for (dir <- ForgeDirection.VALID_DIRECTIONS)
|
|
||||||
{
|
|
||||||
val tile = (position + dir).getTileEntity
|
|
||||||
|
|
||||||
if (tile.isInstanceOf[INodeProvider])
|
|
||||||
{
|
|
||||||
val check: FluidPressureNode = (tile.asInstanceOf[INodeProvider]).getNode(classOf[FluidPressureNode], dir.getOpposite).asInstanceOf[FluidPressureNode]
|
|
||||||
if (check != null && canConnect(dir, check) && check.canConnect(dir.getOpposite, this))
|
|
||||||
{
|
|
||||||
connections.put(check, dir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override def canConnect(from: ForgeDirection, source: AnyRef): Boolean =
|
|
||||||
{
|
|
||||||
return (source.isInstanceOf[FluidPressureNode]) && (connectionMap & (1 << from.ordinal)) != 0
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
package resonantinduction.core.grid.fluid.pressure
|
|
||||||
|
|
||||||
import net.minecraft.block.material.Material
|
|
||||||
import net.minecraftforge.common.util.ForgeDirection
|
|
||||||
import net.minecraftforge.fluids.{FluidStack, FluidTank, FluidTankInfo}
|
|
||||||
import resonantinduction.core.grid.fluid.TileTankNode
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A prefab class for tiles that use the fluid network.
|
|
||||||
*
|
|
||||||
* @author DarkGuardsman
|
|
||||||
*/
|
|
||||||
abstract class TilePressureNode(material: Material) extends TileTankNode(material)
|
|
||||||
{
|
|
||||||
|
|
||||||
override def fill(from: ForgeDirection, resource: FluidStack, doFill: Boolean): Int =
|
|
||||||
{
|
|
||||||
val fill: Int = tank.fill(resource, doFill)
|
|
||||||
onFluidChanged
|
|
||||||
return fill
|
|
||||||
}
|
|
||||||
|
|
||||||
override def drain(from: ForgeDirection, resource: FluidStack, doDrain: Boolean): FluidStack =
|
|
||||||
{
|
|
||||||
return drain(from, resource.amount, doDrain)
|
|
||||||
}
|
|
||||||
|
|
||||||
override def drain(from: ForgeDirection, maxDrain: Int, doDrain: Boolean): FluidStack =
|
|
||||||
{
|
|
||||||
val drain = tank.drain(maxDrain, doDrain)
|
|
||||||
onFluidChanged
|
|
||||||
return drain
|
|
||||||
}
|
|
||||||
|
|
||||||
override def getTankInfo(from: ForgeDirection): Array[FluidTankInfo] =
|
|
||||||
{
|
|
||||||
return Array[FluidTankInfo](tank.getInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
def getSubID: Int =
|
|
||||||
{
|
|
||||||
return this.colorID
|
|
||||||
}
|
|
||||||
|
|
||||||
def setSubID(id: Int)
|
|
||||||
{
|
|
||||||
this.colorID = id
|
|
||||||
}
|
|
||||||
|
|
||||||
def getPressureTank: FluidTank =
|
|
||||||
{
|
|
||||||
return tank
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package resonantinduction.core.prefab;
|
||||||
|
|
||||||
|
import net.minecraftforge.fluids.Fluid;
|
||||||
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
|
import net.minecraftforge.fluids.FluidTank;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version of the fluid tank that restricts input & output amounts
|
||||||
|
* @author Darkguardsman
|
||||||
|
*/
|
||||||
|
public class LimitedTank extends FluidTank
|
||||||
|
{
|
||||||
|
protected int maxInput;
|
||||||
|
protected int maxOutput;
|
||||||
|
|
||||||
|
public LimitedTank(int capacity)
|
||||||
|
{
|
||||||
|
this(capacity, capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LimitedTank(int capacity, int maxFluidMovement)
|
||||||
|
{
|
||||||
|
this(capacity, maxFluidMovement, maxFluidMovement);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LimitedTank(int capacity, int maxinput, int maxOutput)
|
||||||
|
{
|
||||||
|
super(capacity);
|
||||||
|
this.maxInput = maxinput;
|
||||||
|
this.maxOutput = maxOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int fill(FluidStack resource, boolean doFill)
|
||||||
|
{
|
||||||
|
if(resource != null)
|
||||||
|
{
|
||||||
|
FluidStack fluid = resource.copy();
|
||||||
|
fluid.amount = Math.max(fluid.amount, maxInput);
|
||||||
|
return super.fill(resource, doFill);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FluidStack drain(int maxDrain, boolean doDrain)
|
||||||
|
{
|
||||||
|
return super.drain(Math.max(maxDrain, maxOutput),doDrain);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,79 +0,0 @@
|
||||||
package resonantinduction.core.prefab;
|
|
||||||
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
import net.minecraftforge.common.util.ForgeDirection;
|
|
||||||
import net.minecraftforge.fluids.FluidTank;
|
|
||||||
import net.minecraftforge.fluids.IFluidHandler;
|
|
||||||
import universalelectricity.api.core.grid.IConnector;
|
|
||||||
import universalelectricity.api.core.grid.INode;
|
|
||||||
import universalelectricity.api.core.grid.INodeProvider;
|
|
||||||
import universalelectricity.core.grid.Node;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by robert on 8/14/2014.
|
|
||||||
*/
|
|
||||||
public class NodeTank extends FluidTank implements INode, IConnector {
|
|
||||||
|
|
||||||
protected INodeProvider parent = null;
|
|
||||||
protected Map<Object, ForgeDirection> connections = null;
|
|
||||||
|
|
||||||
public NodeTank(INodeProvider parent, int cap)
|
|
||||||
{
|
|
||||||
super(cap);
|
|
||||||
this.parent = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reconstruct()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deconstruct()
|
|
||||||
{
|
|
||||||
connections = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void recache()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<Object, ForgeDirection> getConnections(Class<? extends INode> node)
|
|
||||||
{
|
|
||||||
if(node.isAssignableFrom(getClass()))
|
|
||||||
{
|
|
||||||
return connections;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canConnect(ForgeDirection direction, Object object)
|
|
||||||
{
|
|
||||||
return connections != null && connections.containsKey(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update(double deltaTime) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(NBTTagCompound nbt)
|
|
||||||
{
|
|
||||||
super.readFromNBT(nbt);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void save(NBTTagCompound nbt)
|
|
||||||
{
|
|
||||||
super.writeToNBT(nbt);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
package resonantinduction.core.prefab.node;
|
||||||
|
|
||||||
|
import net.minecraftforge.common.util.ForgeDirection;
|
||||||
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
|
import net.minecraftforge.fluids.IFluidHandler;
|
||||||
|
import universalelectricity.api.core.grid.INodeProvider;
|
||||||
|
import universalelectricity.api.core.grid.IUpdate;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by robert on 8/15/2014.
|
||||||
|
*/
|
||||||
|
public class NodePressure extends NodeTank implements IUpdate
|
||||||
|
{
|
||||||
|
private int pressure = 0;
|
||||||
|
|
||||||
|
public NodePressure(INodeProvider parent)
|
||||||
|
{
|
||||||
|
super(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NodePressure(INodeProvider parent, int buckets)
|
||||||
|
{
|
||||||
|
super(parent, buckets);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(double deltaTime)
|
||||||
|
{
|
||||||
|
if (!world().isRemote)
|
||||||
|
{
|
||||||
|
updatePressure();
|
||||||
|
if(getFluid() != null) {
|
||||||
|
for (Map.Entry<Object, ForgeDirection> entry : connections.entrySet()) {
|
||||||
|
if (entry.getKey() instanceof INodeProvider && ((INodeProvider) entry.getKey()).getNode(NodePressure.class, entry.getValue().getOpposite()) instanceof NodePressure) {
|
||||||
|
NodePressure node = (NodePressure) ((INodeProvider) entry.getKey()).getNode(NodePressure.class, entry.getValue().getOpposite());
|
||||||
|
if (node.getPressure(entry.getValue().getOpposite()) <= getPressure(entry.getValue())) {
|
||||||
|
|
||||||
|
}
|
||||||
|
} else if (entry.getKey() instanceof INodeProvider && ((INodeProvider) entry.getKey()).getNode(NodeTank.class, entry.getValue().getOpposite()) instanceof NodeTank) {
|
||||||
|
NodeTank node = (NodeTank) ((INodeProvider) entry.getKey()).getNode(NodeTank.class, entry.getValue().getOpposite());
|
||||||
|
if (node.canFill(entry.getValue().getOpposite(), getFluid().getFluid()))
|
||||||
|
{
|
||||||
|
FluidStack stack = drain(Integer.MAX_VALUE, false);
|
||||||
|
int drained = node.fill(stack, true);
|
||||||
|
drain(drained, true);
|
||||||
|
}
|
||||||
|
} else if (entry.getKey() instanceof IFluidHandler)
|
||||||
|
{
|
||||||
|
if(((IFluidHandler) entry.getKey()).canFill(entry.getValue().getOpposite(), getFluid().getFluid()))
|
||||||
|
{
|
||||||
|
FluidStack stack = drain(Integer.MAX_VALUE, false);
|
||||||
|
int drained = ((IFluidHandler) entry.getKey()).fill(entry.getValue().getOpposite(), stack, true);
|
||||||
|
drain(drained, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canUpdate()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean continueUpdate()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updatePressure()
|
||||||
|
{
|
||||||
|
int totalPressure = 0;
|
||||||
|
int connectionSize = connections.size();
|
||||||
|
int minPressure = 0;
|
||||||
|
int maxPressure = 0;
|
||||||
|
|
||||||
|
for(Map.Entry<Object, ForgeDirection> entry : connections.entrySet())
|
||||||
|
{
|
||||||
|
if(entry.getKey() instanceof INodeProvider && ((INodeProvider) entry.getKey()).getNode(NodePressure.class, entry.getValue().getOpposite()) instanceof NodePressure)
|
||||||
|
{
|
||||||
|
NodePressure node = (NodePressure) ((INodeProvider) entry.getKey()).getNode(NodePressure.class, entry.getValue().getOpposite());
|
||||||
|
int pressure = node.getPressure(entry.getValue().getOpposite());
|
||||||
|
minPressure = Math.min(pressure, minPressure);
|
||||||
|
maxPressure = Math.max(pressure, maxPressure);
|
||||||
|
totalPressure += pressure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connectionSize == 0)
|
||||||
|
{
|
||||||
|
setPressure(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (minPressure < 0)
|
||||||
|
{
|
||||||
|
minPressure += 1;
|
||||||
|
}
|
||||||
|
if (maxPressure > 0)
|
||||||
|
{
|
||||||
|
maxPressure -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
setPressure(Math.max(minPressure, Math.min(maxPressure, totalPressure / connectionSize + Integer.signum(totalPressure))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPressure(ForgeDirection direction) {
|
||||||
|
return pressure;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPressure(int pressure) {
|
||||||
|
this.pressure = pressure;
|
||||||
|
}
|
||||||
|
}
|
167
src/main/scala/resonantinduction/core/prefab/node/NodeTank.java
Normal file
167
src/main/scala/resonantinduction/core/prefab/node/NodeTank.java
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
package resonantinduction.core.prefab.node;
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.network.ByteBufUtils;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraftforge.common.util.ForgeDirection;
|
||||||
|
import net.minecraftforge.fluids.*;
|
||||||
|
import resonant.engine.ResonantEngine;
|
||||||
|
import resonant.lib.network.discriminator.PacketTile;
|
||||||
|
import resonant.lib.network.discriminator.PacketType;
|
||||||
|
import resonant.lib.network.handle.IPacketIDReceiver;
|
||||||
|
import resonantinduction.core.prefab.LimitedTank;
|
||||||
|
import universalelectricity.api.core.grid.INodeProvider;
|
||||||
|
import universalelectricity.api.core.grid.ISave;
|
||||||
|
import universalelectricity.core.grid.node.NodeConnector;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple tank node designed to be implemented by any machine that can connect to other fluid based machines.
|
||||||
|
* @author Darkguardsman
|
||||||
|
*/
|
||||||
|
public class NodeTank extends NodeConnector implements IFluidTank, IFluidHandler, ISave, IPacketIDReceiver
|
||||||
|
{
|
||||||
|
FluidTank tank;
|
||||||
|
static final int PACKET_DESCRIPTION = 100, PACKET_TANK = 101;
|
||||||
|
|
||||||
|
public NodeTank(INodeProvider parent)
|
||||||
|
{
|
||||||
|
this(parent, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NodeTank(INodeProvider parent, int buckets)
|
||||||
|
{
|
||||||
|
super(parent);
|
||||||
|
tank = new LimitedTank(buckets * FluidContainerRegistry.BUCKET_VOLUME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidConnection(Object object)
|
||||||
|
{
|
||||||
|
return super.isValidConnection(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FluidStack getFluid()
|
||||||
|
{
|
||||||
|
return tank.getFluid();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFluidAmount()
|
||||||
|
{
|
||||||
|
return tank.getFluidAmount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCapacity()
|
||||||
|
{
|
||||||
|
return tank.getCapacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FluidTankInfo getInfo()
|
||||||
|
{
|
||||||
|
return tank.getInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int fill(FluidStack resource, boolean doFill)
|
||||||
|
{
|
||||||
|
return tank.fill(resource, doFill);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FluidStack drain(int maxDrain, boolean doDrain)
|
||||||
|
{
|
||||||
|
return tank.drain(maxDrain, doDrain);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
|
||||||
|
{
|
||||||
|
if(canConnect(from))
|
||||||
|
{
|
||||||
|
return fill(resource, doFill);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
|
||||||
|
{
|
||||||
|
if(canConnect(from) && resource != null && resource.isFluidEqual(getFluid()))
|
||||||
|
{
|
||||||
|
return drain(resource.amount, doDrain);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
|
||||||
|
{
|
||||||
|
if(canConnect(from))
|
||||||
|
{
|
||||||
|
return drain(maxDrain, doDrain);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canFill(ForgeDirection from, Fluid fluid)
|
||||||
|
{
|
||||||
|
return canConnect(from);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canDrain(ForgeDirection from, Fluid fluid)
|
||||||
|
{
|
||||||
|
return canConnect(from);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FluidTankInfo[] getTankInfo(ForgeDirection from)
|
||||||
|
{
|
||||||
|
return new FluidTankInfo[]{getInfo()};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(NBTTagCompound nbt)
|
||||||
|
{
|
||||||
|
tank.readFromNBT(nbt.getCompoundTag("tank"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void save(NBTTagCompound nbt)
|
||||||
|
{
|
||||||
|
nbt.setTag("tank", tank.writeToNBT(new NBTTagCompound()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean read(ByteBuf buf, int id, EntityPlayer player, PacketType type)
|
||||||
|
{
|
||||||
|
switch(id)
|
||||||
|
{
|
||||||
|
case PACKET_DESCRIPTION :
|
||||||
|
this.load(ByteBufUtils.readTag(buf));
|
||||||
|
break;
|
||||||
|
case PACKET_TANK:
|
||||||
|
this.tank.readFromNBT(ByteBufUtils.readTag(buf));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendTank()
|
||||||
|
{
|
||||||
|
ResonantEngine.instance.packetHandler.sendToAllAround(new PacketTile((int)x(), (int)y(), (int)z(), tank.writeToNBT(new NBTTagCompound())), this, 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendUpdate()
|
||||||
|
{
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
save(tag);
|
||||||
|
ResonantEngine.instance.packetHandler.sendToAllAround(new PacketTile((int)x(), (int)y(), (int)z(), tag), this, 64);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package resonantinduction.core.prefab
|
package resonantinduction.core.prefab.node
|
||||||
|
|
||||||
|
import resonantinduction.core.prefab.TFluidHandler
|
||||||
import universalelectricity.api.core.grid.INodeProvider
|
import universalelectricity.api.core.grid.INodeProvider
|
||||||
|
|
||||||
/**
|
/**
|
Loading…
Reference in a new issue