From 0e5633fcd04084cfdf7d34285a4bd3b36519c16c Mon Sep 17 00:00:00 2001 From: Robert S Date: Fri, 16 May 2014 12:03:09 -0400 Subject: [PATCH] Rewrote tank network in attempt to fix filling issue --- .../archaic/fluid/tank/TankNetwork.java | 218 ++++++++-------- .../archaic/fluid/tank/TileTank.java | 3 +- .../archaic/waila/WailaFluidTank.java | 10 +- .../core/fluid/FluidDistributionetwork.java | 1 - .../core/fluid/TileFluidDistribution.java | 236 +++++++++--------- .../core/fluid/TileFluidNode.java | 235 ++++++++--------- .../core/fluid/TilePressureNode.java | 2 +- 7 files changed, 360 insertions(+), 345 deletions(-) diff --git a/archaic/src/main/scala/resonantinduction/archaic/fluid/tank/TankNetwork.java b/archaic/src/main/scala/resonantinduction/archaic/fluid/tank/TankNetwork.java index 95a8a83f0..20fbccffb 100644 --- a/archaic/src/main/scala/resonantinduction/archaic/fluid/tank/TankNetwork.java +++ b/archaic/src/main/scala/resonantinduction/archaic/fluid/tank/TankNetwork.java @@ -1,8 +1,7 @@ package resonantinduction.archaic.fluid.tank; -import java.util.Comparator; import java.util.HashMap; -import java.util.PriorityQueue; +import java.util.LinkedList; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.fluids.FluidStack; @@ -10,118 +9,137 @@ import resonant.lib.utility.FluidUtility; import resonantinduction.core.fluid.FluidDistributionetwork; import resonantinduction.core.fluid.IFluidDistribution; -/** - * Network that handles connected tanks +/** Network that handles connected tanks * - * @author DarkGuardsman - */ + * @author DarkGuardsman */ public class TankNetwork extends FluidDistributionetwork { - public TankNetwork() - { - super(); - needsUpdate = true; - } + public TankNetwork() + { + super(); + needsUpdate = true; + } - @Override - public void update() - { - final FluidStack networkTankFluid = getTank().getFluid(); - int lowestY = 255, highestY = 0; + @Override + public void update() + { + final FluidStack networkTankFluid = getTank().getFluid(); + int lowestY = 255; + int highestY = 0; + int connectorCount = 0; + int totalFluid = networkTankFluid != null ? networkTankFluid.amount : 0; + boolean didChange = false; - if (getConnectors().size() > 0) - { - int totalFluid = networkTankFluid != null ? networkTankFluid.amount : 0; + //If we only have one tank only fill one tank + if (getConnectors().size() == 1) + { + IFluidDistribution tank = ((IFluidDistribution) getConnectors().toArray()[0]); + tank.getInternalTank().setFluid(networkTankFluid); + tank.onFluidChanged(); + } + else if (getConnectors().size() > 0) + { + if (networkTankFluid != null) + { + //If fluid is gaseous fill all tanks equally + if (networkTankFluid.getFluid().isGaseous()) + { + connectorCount = this.getConnectors().size(); + for (IFluidDistribution connector : this.getConnectors()) + { + FluidStack input = networkTankFluid.copy(); + input.amount = (totalFluid / connectorCount) + (totalFluid % connectorCount); + connector.getInternalTank().setFluid(null); + totalFluid -= connector.getInternalTank().fill(input, true); + connector.onFluidChanged(); - HashMap heightCount = new HashMap(); - PriorityQueue heightPriorityQueue = new PriorityQueue(1024, new Comparator() - { - @Override - public int compare(Object a, Object b) - { - if (networkTankFluid != null && networkTankFluid.getFluid().isGaseous()) - return 0; + if (connectorCount > 0) + connectorCount--; + } + } + else + { + HashMap> heightMap = new HashMap>(); - TileEntity wa = (TileEntity) a; - TileEntity wb = (TileEntity) b; - return wa.yCoord - wb.yCoord; - } - }); + //Build map of all tanks by their y level + for (IFluidDistribution connector : this.getConnectors()) + { + if (connector instanceof TileEntity) + { + LinkedList list = new LinkedList(); + int yCoord = ((TileEntity) connector).yCoord; - for (IFluidDistribution connector : this.getConnectors()) - { - if (connector instanceof TileEntity) - { - int yCoord = ((TileEntity) connector).yCoord; + if (yCoord < lowestY) + { + lowestY = yCoord; + } - if (yCoord < lowestY) - { - lowestY = yCoord; - } + if (yCoord > highestY) + { + highestY = yCoord; + } - if (yCoord > highestY) - { - highestY = yCoord; - } + if (heightMap.containsKey(yCoord)) + { + list = heightMap.get(yCoord); + } + list.add(connector); + heightMap.put(yCoord, list); + } + } - heightPriorityQueue.add(connector); - heightCount.put(yCoord, heightCount.containsKey(yCoord) ? heightCount.get(yCoord) + 1 : 1); - } - } + //Loop threw levels + for (int yLevel = lowestY; yLevel <= highestY; yLevel++) + { + if (heightMap.containsKey(yLevel)) + { + connectorCount = heightMap.get(yLevel).size(); - boolean didChange = false; + if (connectorCount <= 0) + continue; - while (!heightPriorityQueue.isEmpty()) - { - IFluidDistribution distributeNode = heightPriorityQueue.poll(); - int yCoord = ((TileEntity) distributeNode).yCoord; - int connectorCount = heightCount.get(yCoord); + //Loop threw tanks in each level + for (IFluidDistribution connector : heightMap.get(yLevel)) + { + //If tank is empty clear internal and move on + if (totalFluid <= 0) + { + connector.getInternalTank().setFluid(null); + connector.onFluidChanged(); + continue; + } - if (totalFluid <= 0) - { - distributeNode.getInternalTank().setFluid(null); - distributeNode.onFluidChanged(); - continue; - } + FluidStack input = networkTankFluid.copy(); + input.amount = (totalFluid / connectorCount) + (totalFluid % connectorCount); + connector.getInternalTank().setFluid(null); + totalFluid -= connector.getInternalTank().fill(input, true); + connector.onFluidChanged(); + + if (connectorCount > 1) + connectorCount--; - int fluidPer = totalFluid / connectorCount; - int deltaFluidAmount = fluidPer - distributeNode.getInternalTank().getFluidAmount(); + } + } + } + } + } + else + { + //In the cases the tank is empty just clear all tanks + //instead of doing additional logic that is wasting ticks + for (IFluidDistribution connector : this.getConnectors()) + { + connector.getInternalTank().setFluid(null); + connector.onFluidChanged(); + } + } + needsUpdate = false; + } + } - int current = distributeNode.getInternalTank().getFluidAmount(); - - if (deltaFluidAmount > 0) - { - int filled = distributeNode.getInternalTank().fill(FluidUtility.getStack(networkTankFluid, deltaFluidAmount), false); - distributeNode.getInternalTank().fill(FluidUtility.getStack(networkTankFluid, deltaFluidAmount / 10), true); - totalFluid -= current + filled; - } - else - { - FluidStack drain = distributeNode.getInternalTank().drain(Math.abs(deltaFluidAmount), false); - distributeNode.getInternalTank().drain(Math.abs(deltaFluidAmount / 10), true); - - if (drain != null) - totalFluid -= current - drain.amount; - } - - if (deltaFluidAmount != 0) - didChange = true; - - if (connectorCount > 1) - connectorCount--; - - heightCount.put(yCoord, connectorCount); - distributeNode.onFluidChanged(); - } - - if (!didChange) - needsUpdate = false; - } - } - - @Override - public TankNetwork newInstance() - { - return new TankNetwork(); - } + @Override + public TankNetwork newInstance() + { + return new TankNetwork(); + } } diff --git a/archaic/src/main/scala/resonantinduction/archaic/fluid/tank/TileTank.java b/archaic/src/main/scala/resonantinduction/archaic/fluid/tank/TileTank.java index ec62fcc2c..7c1233847 100644 --- a/archaic/src/main/scala/resonantinduction/archaic/fluid/tank/TileTank.java +++ b/archaic/src/main/scala/resonantinduction/archaic/fluid/tank/TileTank.java @@ -45,8 +45,7 @@ public class TileTank extends TileFluidDistribution implements IComparatorInputO public TileTank() { - super(UniversalElectricity.machine); - this.getInternalTank().setCapacity(VOLUME * FluidContainerRegistry.BUCKET_VOLUME); + super(UniversalElectricity.machine, VOLUME * FluidContainerRegistry.BUCKET_VOLUME); isOpaqueCube = false; normalRender = false; itemBlock = ItemBlockTank.class; diff --git a/archaic/src/main/scala/resonantinduction/archaic/waila/WailaFluidTank.java b/archaic/src/main/scala/resonantinduction/archaic/waila/WailaFluidTank.java index 86179a542..0b00bbbdb 100644 --- a/archaic/src/main/scala/resonantinduction/archaic/waila/WailaFluidTank.java +++ b/archaic/src/main/scala/resonantinduction/archaic/waila/WailaFluidTank.java @@ -23,15 +23,17 @@ public class WailaFluidTank implements IWailaDataProvider if (tile instanceof TileTank) { FluidTank tank = ((TileTank) tile).getInternalTank(); + FluidTank tankNetwork = ((TileTank) tile).getNetwork().getTank(); + if (tankNetwork != null && tankNetwork.getFluid() != null) + { + currenttip.add(LanguageUtility.getLocal("info.waila.tank.fluid") + " " + tankNetwork.getFluid().getFluid().getLocalizedName()); + currenttip.add(LanguageUtility.getLocal("info.waila.tank.vol") + " " + tankNetwork.getFluidAmount() + " / " + tank.getCapacity()); + } if (tank != null && tank.getFluid() != null) { currenttip.add(LanguageUtility.getLocal("info.waila.tank.fluid") + " " + tank.getFluid().getFluid().getLocalizedName()); currenttip.add(LanguageUtility.getLocal("info.waila.tank.vol") + " " + tank.getFluidAmount() + " / " + tank.getCapacity()); } - else - { - currenttip.add(LanguageUtility.getLocal("info.waila.tank.empty")); - } } return currenttip; } diff --git a/src/main/scala/resonantinduction/core/fluid/FluidDistributionetwork.java b/src/main/scala/resonantinduction/core/fluid/FluidDistributionetwork.java index 22b2610eb..f749f3424 100644 --- a/src/main/scala/resonantinduction/core/fluid/FluidDistributionetwork.java +++ b/src/main/scala/resonantinduction/core/fluid/FluidDistributionetwork.java @@ -85,7 +85,6 @@ public abstract class FluidDistributionetwork extends NodeNetwork