From a7ebb5de9a18e66303ca7cfa636805cf919828fd Mon Sep 17 00:00:00 2001 From: Robert S Date: Fri, 15 Aug 2014 09:59:41 -0400 Subject: [PATCH] Rewriting fluid nodes and grids --- .../core/ResonantInduction.scala | 5 +- .../core/grid/fluid/TileTankNode.scala | 161 +++++----------- .../grid/fluid/distribution/TankNode.scala | 104 ----------- .../fluid/pressure/FluidPressureNode.scala | 176 ------------------ .../fluid/pressure/TilePressureNode.scala | 54 ------ .../core/prefab/LimitedTank.java | 50 +++++ .../core/prefab/NodeTank.java | 79 -------- .../core/prefab/node/NodePressure.java | 120 ++++++++++++ .../core/prefab/node/NodeTank.java | 167 +++++++++++++++++ .../core/prefab/{ => node}/TFluidNode.scala | 3 +- 10 files changed, 387 insertions(+), 532 deletions(-) delete mode 100644 src/main/scala/resonantinduction/core/grid/fluid/distribution/TankNode.scala delete mode 100644 src/main/scala/resonantinduction/core/grid/fluid/pressure/FluidPressureNode.scala delete mode 100644 src/main/scala/resonantinduction/core/grid/fluid/pressure/TilePressureNode.scala create mode 100644 src/main/scala/resonantinduction/core/prefab/LimitedTank.java delete mode 100644 src/main/scala/resonantinduction/core/prefab/NodeTank.java create mode 100644 src/main/scala/resonantinduction/core/prefab/node/NodePressure.java create mode 100644 src/main/scala/resonantinduction/core/prefab/node/NodeTank.java rename src/main/scala/resonantinduction/core/prefab/{ => node}/TFluidNode.scala (63%) diff --git a/src/main/scala/resonantinduction/core/ResonantInduction.scala b/src/main/scala/resonantinduction/core/ResonantInduction.scala index aea09fed3..8a0f1c30a 100644 --- a/src/main/scala/resonantinduction/core/ResonantInduction.scala +++ b/src/main/scala/resonantinduction/core/ResonantInduction.scala @@ -8,10 +8,9 @@ import net.minecraft.item.ItemStack import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.config.Configuration import org.modstats.{ModstatInfo, Modstats} -import resonant.engine.References +import resonant.engine.{References, ResonantEngine} import resonant.lib.config.ConfigHandler import resonant.lib.loadable.LoadableHandler -import resonant.lib.network.netty.PacketManager import resonantinduction.core.handler.TextureHookHandler import resonantinduction.core.resource.ResourceGenerator @@ -25,7 +24,7 @@ import scala.collection.convert.wrapAll._ object ResonantInduction { /** Packets */ - val packetHandler = new PacketManager(Reference.channel) + val packetHandler = ResonantEngine.instance.packetHandler val loadables = new LoadableHandler @SidedProxy(clientSide = "resonantinduction.core.ClientProxy", serverSide = "resonantinduction.core.CommonProxy") diff --git a/src/main/scala/resonantinduction/core/grid/fluid/TileTankNode.scala b/src/main/scala/resonantinduction/core/grid/fluid/TileTankNode.scala index 06ac4a256..f6c21a697 100644 --- a/src/main/scala/resonantinduction/core/grid/fluid/TileTankNode.scala +++ b/src/main/scala/resonantinduction/core/grid/fluid/TileTankNode.scala @@ -1,163 +1,94 @@ package resonantinduction.core.grid.fluid +import cpw.mods.fml.common.network.ByteBufUtils import io.netty.buffer.ByteBuf import net.minecraft.block.material.Material import net.minecraft.entity.player.EntityPlayer import net.minecraft.nbt.NBTTagCompound -import net.minecraft.network.Packet import net.minecraftforge.common.util.ForgeDirection import net.minecraftforge.fluids._ import resonant.content.prefab.java.TileAdvanced -import resonant.lib.network.ByteBufWrapper.ByteBufWrapper -import resonant.lib.network.discriminator.PacketType +import resonant.lib.network.discriminator.{PacketTile, PacketType} import resonant.lib.network.handle.{IPacketIDReceiver, TPacketIDSender} -import resonant.lib.network.netty.PacketManager -import resonant.lib.utility.FluidUtility -import resonantinduction.core.ResonantInduction -import resonantinduction.core.grid.fluid.distribution.TankNode +import resonantinduction.core.prefab.node.NodeTank import universalelectricity.api.core.grid.{INode, INodeProvider} -import universalelectricity.core.transform.vector.Vector3 /** * A prefab class for tiles that use the fluid network. * * @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 { - protected var tank: FluidTank = new FluidTank(1000); - protected var pressure = 0 + val PACKET_DESCRIPTION = 0 + val PACKET_RENDER = 1 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 - protected var markTankUpdate = false - protected final val tankSize = 0 - var tankNode : TankNode = new TankNode(this) + var tankNode : NodeTank = new NodeTank(this) - override def update() - { - super.update() + def getTank() : IFluidTank = tankNode - if (markTankUpdate) - { - sendTankUpdate - markTankUpdate = false - } - } + def getFluid() : FluidStack = getTank().getFluid - def getTank() : FluidTank = tank - - def getFluid() : FluidStack = tank.getFluid - - def getFluidCapacity() : Int = tank.getCapacity + def getFluidCapacity() : Int = getTank().getCapacity override def readFromNBT(nbt: NBTTagCompound) { super.readFromNBT(nbt) + tankNode.load(nbt) colorID = nbt.getInteger("colorID") - tank.readFromNBT(nbt.getCompoundTag("FluidTank")) } override def writeToNBT(nbt: NBTTagCompound) { super.writeToNBT(nbt) + tankNode.save(nbt) 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 { if (!world.isRemote) - ResonantInduction.packetHandler.sendToAll(PacketManager.request(this, TileTankNode.PACKET_RENDER.id)) - } - - def sendTankUpdate - { - if (!world.isRemote) - ResonantInduction.packetHandler.sendToAllAround(PacketManager.request(this, TileTankNode.PACKET_TANK.id), world, new Vector3(this), 60) - } - - def onFluidChanged() - { - if (!worldObj.isRemote) { - if (!FluidUtility.matchExact(prevStack, tank.getFluid) || ticks == 0) - { - markTankUpdate = true - prevStack = if (tank.getFluid != null) tank.getFluid.copy else null - } + val packet: PacketTile = new PacketTile(this); + packet <<< PACKET_RENDER + packet <<< colorID + packet <<< renderSides + sendPacket(packet) } } - 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) diff --git a/src/main/scala/resonantinduction/core/grid/fluid/distribution/TankNode.scala b/src/main/scala/resonantinduction/core/grid/fluid/distribution/TankNode.scala deleted file mode 100644 index d5b076263..000000000 --- a/src/main/scala/resonantinduction/core/grid/fluid/distribution/TankNode.scala +++ /dev/null @@ -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) -} \ No newline at end of file diff --git a/src/main/scala/resonantinduction/core/grid/fluid/pressure/FluidPressureNode.scala b/src/main/scala/resonantinduction/core/grid/fluid/pressure/FluidPressureNode.scala deleted file mode 100644 index 10327cd0c..000000000 --- a/src/main/scala/resonantinduction/core/grid/fluid/pressure/FluidPressureNode.scala +++ /dev/null @@ -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 - } -} \ No newline at end of file diff --git a/src/main/scala/resonantinduction/core/grid/fluid/pressure/TilePressureNode.scala b/src/main/scala/resonantinduction/core/grid/fluid/pressure/TilePressureNode.scala deleted file mode 100644 index 2bf2a6d3a..000000000 --- a/src/main/scala/resonantinduction/core/grid/fluid/pressure/TilePressureNode.scala +++ /dev/null @@ -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 - } -} \ No newline at end of file diff --git a/src/main/scala/resonantinduction/core/prefab/LimitedTank.java b/src/main/scala/resonantinduction/core/prefab/LimitedTank.java new file mode 100644 index 000000000..6cb2cd47f --- /dev/null +++ b/src/main/scala/resonantinduction/core/prefab/LimitedTank.java @@ -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); + } +} diff --git a/src/main/scala/resonantinduction/core/prefab/NodeTank.java b/src/main/scala/resonantinduction/core/prefab/NodeTank.java deleted file mode 100644 index 42f9942fb..000000000 --- a/src/main/scala/resonantinduction/core/prefab/NodeTank.java +++ /dev/null @@ -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 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 getConnections(Class 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); - } -} diff --git a/src/main/scala/resonantinduction/core/prefab/node/NodePressure.java b/src/main/scala/resonantinduction/core/prefab/node/NodePressure.java new file mode 100644 index 000000000..45eb5fbd6 --- /dev/null +++ b/src/main/scala/resonantinduction/core/prefab/node/NodePressure.java @@ -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 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 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; + } +} diff --git a/src/main/scala/resonantinduction/core/prefab/node/NodeTank.java b/src/main/scala/resonantinduction/core/prefab/node/NodeTank.java new file mode 100644 index 000000000..fe7d86d94 --- /dev/null +++ b/src/main/scala/resonantinduction/core/prefab/node/NodeTank.java @@ -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); + } +} diff --git a/src/main/scala/resonantinduction/core/prefab/TFluidNode.scala b/src/main/scala/resonantinduction/core/prefab/node/TFluidNode.scala similarity index 63% rename from src/main/scala/resonantinduction/core/prefab/TFluidNode.scala rename to src/main/scala/resonantinduction/core/prefab/node/TFluidNode.scala index 88469fc72..c59d7895b 100644 --- a/src/main/scala/resonantinduction/core/prefab/TFluidNode.scala +++ b/src/main/scala/resonantinduction/core/prefab/node/TFluidNode.scala @@ -1,5 +1,6 @@ -package resonantinduction.core.prefab +package resonantinduction.core.prefab.node +import resonantinduction.core.prefab.TFluidHandler import universalelectricity.api.core.grid.INodeProvider /**