Rewrote tank network in attempt to fix filling issue

This commit is contained in:
Robert S 2014-05-16 12:03:09 -04:00
parent 2a0d5454eb
commit 0e5633fcd0
7 changed files with 360 additions and 345 deletions

View file

@ -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,11 +9,9 @@ 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()
@ -27,31 +24,49 @@ public class TankNetwork extends FluidDistributionetwork
public void update()
{
final FluidStack networkTankFluid = getTank().getFluid();
int lowestY = 255, highestY = 0;
if (getConnectors().size() > 0)
{
int lowestY = 255;
int highestY = 0;
int connectorCount = 0;
int totalFluid = networkTankFluid != null ? networkTankFluid.amount : 0;
boolean didChange = false;
HashMap<Integer, Integer> heightCount = new HashMap<Integer, Integer>();
PriorityQueue<IFluidDistribution> heightPriorityQueue = new PriorityQueue<IFluidDistribution>(1024, new Comparator()
//If we only have one tank only fill one tank
if (getConnectors().size() == 1)
{
@Override
public int compare(Object a, Object b)
{
if (networkTankFluid != null && networkTankFluid.getFluid().isGaseous())
return 0;
TileEntity wa = (TileEntity) a;
TileEntity wb = (TileEntity) b;
return wa.yCoord - wb.yCoord;
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();
if (connectorCount > 0)
connectorCount--;
}
}
else
{
HashMap<Integer, LinkedList<IFluidDistribution>> heightMap = new HashMap<Integer, LinkedList<IFluidDistribution>>();
//Build map of all tanks by their y level
for (IFluidDistribution connector : this.getConnectors())
{
if (connector instanceof TileEntity)
{
LinkedList<IFluidDistribution> list = new LinkedList<IFluidDistribution>();
int yCoord = ((TileEntity) connector).yCoord;
if (yCoord < lowestY)
@ -64,57 +79,60 @@ public class TankNetwork extends FluidDistributionetwork
highestY = yCoord;
}
heightPriorityQueue.add(connector);
heightCount.put(yCoord, heightCount.containsKey(yCoord) ? heightCount.get(yCoord) + 1 : 1);
}
}
boolean didChange = false;
while (!heightPriorityQueue.isEmpty())
if (heightMap.containsKey(yCoord))
{
IFluidDistribution distributeNode = heightPriorityQueue.poll();
int yCoord = ((TileEntity) distributeNode).yCoord;
int connectorCount = heightCount.get(yCoord);
list = heightMap.get(yCoord);
}
list.add(connector);
heightMap.put(yCoord, list);
}
}
//Loop threw levels
for (int yLevel = lowestY; yLevel <= highestY; yLevel++)
{
if (heightMap.containsKey(yLevel))
{
connectorCount = heightMap.get(yLevel).size();
if (connectorCount <= 0)
continue;
//Loop threw tanks in each level
for (IFluidDistribution connector : heightMap.get(yLevel))
{
//If tank is empty clear internal and move on
if (totalFluid <= 0)
{
distributeNode.getInternalTank().setFluid(null);
distributeNode.onFluidChanged();
connector.getInternalTank().setFluid(null);
connector.onFluidChanged();
continue;
}
int fluidPer = totalFluid / connectorCount;
int deltaFluidAmount = fluidPer - distributeNode.getInternalTank().getFluidAmount();
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;
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--;
heightCount.put(yCoord, connectorCount);
distributeNode.onFluidChanged();
}
if (!didChange)
}
}
}
}
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;
}
}

View file

@ -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;

View file

@ -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;
}

View file

@ -85,7 +85,6 @@ public abstract class FluidDistributionetwork extends NodeNetwork<FluidDistribut
public int fill(IFluidDistribution source, ForgeDirection from, FluidStack resource, boolean doFill)
{
int prev = this.getTank().getFluidAmount();
int fill = this.getTank().fill(resource.copy(), doFill);
needsUpdate = true;
NetworkTickHandler.addNetwork(this);

View file

@ -9,16 +9,14 @@ import net.minecraftforge.fluids.FluidTankInfo;
import resonant.lib.utility.WorldUtility;
import universalelectricity.api.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 */
public abstract class TileFluidDistribution extends TileFluidNode implements IFluidDistribution
{
public TileFluidDistribution(Material material)
public TileFluidDistribution(Material material, int tankSize)
{
super(material);
super(material, tankSize);
}
protected Object[] connectedBlocks = new Object[6];
@ -113,12 +111,10 @@ public abstract class TileFluidDistribution extends TileFluidNode implements IFl
}
/**
* Checks to make sure the connection is valid to the tileEntity
/** Checks to make sure the connection is valid to the tileEntity
*
* @param tileEntity - the tileEntity being checked
* @param side - side the connection is too
*/
* @param side - side the connection is too */
public void validateConnectionSide(TileEntity tileEntity, ForgeDirection side)
{
if (!this.worldObj.isRemote)

View file

@ -16,18 +16,11 @@ import universalelectricity.api.vector.Vector3;
import com.google.common.io.ByteArrayDataInput;
/**
* A prefab class for tiles that use the fluid network.
/** A prefab class for tiles that use the fluid network.
*
* @author DarkGuardsman
*/
* @author DarkGuardsman */
public abstract class TileFluidNode extends TileBase implements IPacketReceiverWithID
{
public TileFluidNode(Material material)
{
super(material);
}
protected int pressure;
protected FluidTank tank;
@ -46,6 +39,14 @@ public abstract class TileFluidNode extends TileBase implements IPacketReceiverW
protected boolean markTankUpdate;
protected final int tankSize;
public TileFluidNode(Material material, int tankSize)
{
super(material);
this.tankSize = tankSize;
}
@Override
public void updateEntity()
{
@ -149,7 +150,7 @@ public abstract class TileFluidNode extends TileBase implements IPacketReceiverW
{
if (this.tank == null)
{
this.tank = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME);
this.tank = new FluidTank(this.tankSize);
}
return this.tank;
}

View file

@ -22,7 +22,7 @@ public abstract class TilePressureNode extends TileFluidNode implements IPressur
public TilePressureNode(Material material)
{
super(material);
super(material, 1000);
}
@Override