Add combined internal storage to pipe network

Pipe networks can now store up to so much liquid in the network.
Though untested it should save, load,  merge, split the stored liquid
This commit is contained in:
Rseifert 2013-03-30 00:21:00 -04:00
parent 7aed9a4618
commit 72932508d4
3 changed files with 226 additions and 91 deletions

View file

@ -3,14 +3,16 @@ package fluidmech.common.machines.pipes;
import fluidmech.common.FluidMech; import fluidmech.common.FluidMech;
import hydraulic.api.ColorCode; import hydraulic.api.ColorCode;
import hydraulic.api.IColorCoded; import hydraulic.api.IColorCoded;
import hydraulic.api.IPipeConnection;
import hydraulic.api.IFluidNetworkPart; import hydraulic.api.IFluidNetworkPart;
import hydraulic.api.IPipeConnection;
import hydraulic.api.IReadOut; import hydraulic.api.IReadOut;
import hydraulic.core.liquidNetwork.HydraulicNetwork; import hydraulic.core.liquidNetwork.HydraulicNetwork;
import java.util.Random; import java.util.Random;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.INetworkManager; import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet250CustomPayload; import net.minecraft.network.packet.Packet250CustomPayload;
@ -93,6 +95,36 @@ public class TileEntityPipe extends TileEntityAdvanced implements ITankContainer
return PacketManager.getPacket(FluidMech.CHANNEL, this, this.renderConnection[0], this.renderConnection[1], this.renderConnection[2], this.renderConnection[3], this.renderConnection[4], this.renderConnection[5]); return PacketManager.getPacket(FluidMech.CHANNEL, this, this.renderConnection[0], this.renderConnection[1], this.renderConnection[2], this.renderConnection[3], this.renderConnection[4], this.renderConnection[5]);
} }
/**
* Reads a tile entity from NBT.
*/
@Override
public void readFromNBT(NBTTagCompound nbt)
{
super.readFromNBT(nbt);
LiquidStack liquid = new LiquidStack(0, 0, 0);
liquid.readFromNBT(nbt.getCompoundTag("stored"));
if (Item.itemsList[liquid.itemID] != null && liquid.amount > 0)
{
this.getNetwork().addFluidToNetwork(liquid, 0, true);
}
}
/**
* Writes a tile entity to NBT.
*/
@Override
public void writeToNBT(NBTTagCompound nbt)
{
super.writeToNBT(nbt);
LiquidStack stack = this.getNetwork().drainVolumeFromSystem(this.getNetwork().getVolumePerPart(), true);
if (stack != null)
{
nbt.setTag("stored", stack.writeToNBT(new NBTTagCompound()));
}
}
/** /**
* gets the current color mark of the pipe * gets the current color mark of the pipe
*/ */
@ -123,7 +155,7 @@ public class TileEntityPipe extends TileEntityAdvanced implements ITankContainer
boolean testNetwork = false; boolean testNetwork = false;
/* NORMAL OUTPUT */ /* NORMAL OUTPUT */
String string = this.getNetwork().pressureProduced + "p "; String string = this.getNetwork().pressureProduced + "p " + this.getNetwork().getStorageFluid() + " Extra";
/* DEBUG CODE */ /* DEBUG CODE */
if (testConnections) if (testConnections)
@ -325,4 +357,10 @@ public class TileEntityPipe extends TileEntityAdvanced implements ITankContainer
return worldObj.getBlockTileEntity(xCoord + dir.offsetX, yCoord + dir.offsetZ, zCoord + dir.offsetY) instanceof IFluidNetworkPart; return worldObj.getBlockTileEntity(xCoord + dir.offsetX, yCoord + dir.offsetZ, zCoord + dir.offsetY) instanceof IFluidNetworkPart;
} }
@Override
public int getTankSize()
{
return LiquidContainerRegistry.BUCKET_VOLUME * 2;
}
} }

View file

@ -4,6 +4,7 @@ import universalelectricity.core.block.IConnectionProvider;
import hydraulic.core.liquidNetwork.HydraulicNetwork; import hydraulic.core.liquidNetwork.HydraulicNetwork;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection; import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.liquids.ITankContainer;
import net.minecraftforge.liquids.LiquidStack; import net.minecraftforge.liquids.LiquidStack;
/** /**
@ -11,7 +12,7 @@ import net.minecraftforge.liquids.LiquidStack;
* that doesn't change the over all network pressure. So pipes, gauges, tubes, buffers, decor * that doesn't change the over all network pressure. So pipes, gauges, tubes, buffers, decor
* blocks. * blocks.
*/ */
public interface IFluidNetworkPart extends IPipeConnection, IColorCoded, IConnectionProvider public interface IFluidNetworkPart extends IPipeConnection, IColorCoded, IConnectionProvider, ITankContainer
{ {
/** /**
* gets the devices pressure from a given side for input * gets the devices pressure from a given side for input
@ -41,4 +42,9 @@ public interface IFluidNetworkPart extends IPipeConnection, IColorCoded, IConnec
*/ */
public boolean onOverPressure(Boolean damageAllowed); public boolean onOverPressure(Boolean damageAllowed);
/**
* size of the pipes liquid storage ability
*/
public int getTankSize();
} }

View file

@ -2,6 +2,7 @@ package hydraulic.core.liquidNetwork;
import hydraulic.api.ColorCode; import hydraulic.api.ColorCode;
import hydraulic.api.IFluidNetworkPart; import hydraulic.api.IFluidNetworkPart;
import hydraulic.core.path.PathfinderCheckerPipes;
import hydraulic.helpers.connectionHelper; import hydraulic.helpers.connectionHelper;
import java.util.ArrayList; import java.util.ArrayList;
@ -15,7 +16,9 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection; import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.liquids.ILiquidTank; import net.minecraftforge.liquids.ILiquidTank;
import net.minecraftforge.liquids.ITankContainer; import net.minecraftforge.liquids.ITankContainer;
import net.minecraftforge.liquids.LiquidContainerRegistry;
import net.minecraftforge.liquids.LiquidStack; import net.minecraftforge.liquids.LiquidStack;
import net.minecraftforge.liquids.LiquidTank;
import universalelectricity.core.block.IConnectionProvider; import universalelectricity.core.block.IConnectionProvider;
import universalelectricity.core.path.Pathfinder; import universalelectricity.core.path.Pathfinder;
import universalelectricity.core.path.PathfinderChecker; import universalelectricity.core.path.PathfinderChecker;
@ -46,6 +49,8 @@ public class HydraulicNetwork
public double pressureLoad = 0; public double pressureLoad = 0;
/* IS IT PROCESSING AN ADD LIQUID EVENT */ /* IS IT PROCESSING AN ADD LIQUID EVENT */
private boolean processingRequest = false; private boolean processingRequest = false;
/* COMBINED TEMP STORAGE FOR ALL PIPES IN THE NETWORK */
private LiquidTank combinedStorage = new LiquidTank(LiquidContainerRegistry.BUCKET_VOLUME);
public HydraulicNetwork(ColorCode color, IFluidNetworkPart... parts) public HydraulicNetwork(ColorCode color, IFluidNetworkPart... parts)
{ {
@ -123,6 +128,47 @@ public class HydraulicNetwork
this.pressureLoads.remove(tileEntity); this.pressureLoads.remove(tileEntity);
} }
/**
* Removes a tileEntity from any of the valid lists
*/
public void removeEntity(TileEntity ent)
{
if (fluidTanks.contains(ent))
{
fluidTanks.remove(ent);
}
}
/**
* Adds a tileEntity to the list if its valid
*/
public void addEntity(ITankContainer ent)
{
if (ent == null)
{
return;
}
if (ent instanceof IFluidNetworkPart)
{
this.addNetworkPart((IFluidNetworkPart) ent);
}
if (!fluidTanks.contains(ent))
{
fluidTanks.add(ent);
}
}
public void addNetworkPart(IFluidNetworkPart newConductor)
{
this.cleanConductors();
if (newConductor.getColor() == this.color && !fluidParts.contains(newConductor))
{
fluidParts.add(newConductor);
newConductor.setNetwork(this);
}
}
/** /**
* @param ignoreTiles The TileEntities to ignore during this calculation. Null will make it not * @param ignoreTiles The TileEntities to ignore during this calculation. Null will make it not
* ignore any. * ignore any.
@ -195,24 +241,31 @@ public class HydraulicNetwork
public int addFluidToNetwork(LiquidStack stack, double pressure, boolean doFill) public int addFluidToNetwork(LiquidStack stack, double pressure, boolean doFill)
{ {
int used = 0; int used = 0;
if (!this.processingRequest && stack != null && canAcceptLiquid(stack))
if (!this.processingRequest && stack != null && color.isValidLiquid(stack))
{ {
if (this.combinedStorage.getLiquid() != null && !stack.isLiquidEqual(this.combinedStorage.getLiquid()))
{
// TODO cause mixing
}
if (stack.amount > this.getMaxFlow(stack)) if (stack.amount > this.getMaxFlow(stack))
{ {
stack = new LiquidStack(stack.itemID, this.getMaxFlow(stack), stack.itemMeta); stack = new LiquidStack(stack.itemID, this.getMaxFlow(stack), stack.itemMeta);
} }
/* Main fill target to try to fill with the stack */ /* Main fill target to try to fill with the stack */
ITankContainer fillTarget = null; ITankContainer primaryFill = null;
int volume = Integer.MAX_VALUE; int volume = Integer.MAX_VALUE;
ForgeDirection fillDir = ForgeDirection.UNKNOWN; ForgeDirection fillDir = ForgeDirection.UNKNOWN;
/* Secondary fill target if the main target is not found */ /* Secondary fill target if the main target is not found */
ITankContainer otherFillTarget = null; ITankContainer secondayFill = null;
int mostFill = 0; int mostFill = 0;
ForgeDirection otherFillDir = ForgeDirection.UNKNOWN; ForgeDirection otherFillDir = ForgeDirection.UNKNOWN;
boolean found = false; boolean found = false;
/* FIND THE FILL TARGET FROM THE LIST OF FLUID RECIEVERS */
for (ITankContainer tankContainer : fluidTanks) for (ITankContainer tankContainer : fluidTanks)
{ {
if (tankContainer instanceof TileEntity) if (tankContainer instanceof TileEntity)
@ -224,30 +277,29 @@ public class HydraulicNetwork
if (connectedTiles[i] instanceof IFluidNetworkPart && ((IFluidNetworkPart) connectedTiles[i]).getNetwork() == this) if (connectedTiles[i] instanceof IFluidNetworkPart && ((IFluidNetworkPart) connectedTiles[i]).getNetwork() == this)
{ {
ForgeDirection dir = ForgeDirection.getOrientation(i).getOpposite(); ForgeDirection dir = ForgeDirection.getOrientation(i).getOpposite();
ILiquidTank storage = tankContainer.getTank(dir, stack); ILiquidTank targetTank = tankContainer.getTank(dir, stack);
int fill = tankContainer.fill(dir, stack, false); int fill = tankContainer.fill(dir, stack, false);
/*
* if the TileEntity uses the getTank method /* USE GET TANK FROM SIDE METHOD FIRST */
*/ if (targetTank != null)
if (storage != null)
{ {
LiquidStack stored = storage.getLiquid(); LiquidStack stackStored = targetTank.getLiquid();
if (stored == null) if (stackStored == null)
{ {
fillTarget = tankContainer; primaryFill = tankContainer;
found = true; found = true;
fillDir = dir; fillDir = dir;
break; break;
} }
else if (stored.amount < volume) else if (stackStored.amount < targetTank.getCapacity() && stackStored.amount < volume)
{ {
fillTarget = tankContainer; primaryFill = tankContainer;
volume = stored.amount; volume = stackStored.amount;
} }
} }/* USE FILL METHOD IF GET TANK == NULL */
else if (fill > 0 && fill > mostFill) else if (fill > 0 && fill > mostFill)
{ {
otherFillTarget = tankContainer; secondayFill = tankContainer;
mostFill = fill; mostFill = fill;
otherFillDir = dir; otherFillDir = dir;
} }
@ -258,21 +310,38 @@ public class HydraulicNetwork
{ {
break; break;
} }
if (stack == null || stack.amount <= 0)
{
return used;
}
}// End of tank finder }// End of tank finder
if (doFill)
if (primaryFill != null)
{ {
if (fillTarget != null) used = primaryFill.fill(fillDir, stack, doFill);
}
else if (secondayFill != null)
{
used = secondayFill.fill(fillDir, stack, doFill);
}
else if (this.combinedStorage.getLiquid() == null || this.combinedStorage.getLiquid().amount < this.combinedStorage.getCapacity())
{
used = this.combinedStorage.fill(stack, doFill);
System.out.println("Network Target");
}
/* IF THE COMBINED STORAGE OF THE PIPES HAS LIQUID MOVE IT FIRST */
if (this.combinedStorage.getLiquid() != null && this.combinedStorage.getLiquid().amount > 0)
{
System.out.println("Pulling from combined");
if (this.combinedStorage.getLiquid().amount >= used)
{ {
used = fillTarget.fill(fillDir, stack, true); used = 0;
this.combinedStorage.drain(stack.amount, doFill);
} }
else if (otherFillTarget != null) else
{ {
used = otherFillTarget.fill(fillDir, stack, true); int pUsed = stack.amount;
used = Math.min(used, Math.max(stack.amount - this.combinedStorage.getLiquid().amount, 0));
this.combinedStorage.drain(pUsed - used, doFill);
} }
} }
} }
this.processingRequest = false; this.processingRequest = false;
@ -301,51 +370,6 @@ public class HydraulicNetwork
return flow; return flow;
} }
/**
* can this network can accept the liquid type
*/
private boolean canAcceptLiquid(LiquidStack stack)
{
return color.isValidLiquid(stack);
}
/**
* Removes a tileEntity from any of the valid lists
*/
public void removeEntity(TileEntity ent)
{
if (fluidTanks.contains(ent))
{
fluidTanks.remove(ent);
}
}
/**
* Adds a tileEntity to the list if its valid
*/
public void addEntity(ITankContainer ent)
{
if (ent == null || ent instanceof IFluidNetworkPart)
{
return;
}
if (!fluidTanks.contains(ent))
{
fluidTanks.add(ent);
}
}
public void addNetworkPart(IFluidNetworkPart newConductor, ColorCode code)
{
this.cleanConductors();
if (code == this.color && !fluidParts.contains(newConductor))
{
fluidParts.add(newConductor);
newConductor.setNetwork(this);
}
}
public void cleanConductors() public void cleanConductors()
{ {
for (int i = 0; i < fluidParts.size(); i++) for (int i = 0; i < fluidParts.size(); i++)
@ -391,6 +415,7 @@ public class HydraulicNetwork
public void cleanUpConductors() public void cleanUpConductors()
{ {
Iterator it = this.fluidParts.iterator(); Iterator it = this.fluidParts.iterator();
int capacity = 0;
while (it.hasNext()) while (it.hasNext())
{ {
@ -411,8 +436,10 @@ public class HydraulicNetwork
else else
{ {
conductor.setNetwork(this); conductor.setNetwork(this);
capacity += conductor.getTankSize();
} }
} }
this.combinedStorage.setCapacity(capacity);
} }
/** /**
@ -448,15 +475,43 @@ public class HydraulicNetwork
{ {
if (network != null && network != this && network.color == this.color) if (network != null && network != this && network.color == this.color)
{ {
HydraulicNetwork newNetwork = new HydraulicNetwork(this.color); if (this.combinedStorage.getLiquid() != null && network.combinedStorage.getLiquid() != null && !this.combinedStorage.getLiquid().isLiquidEqual(network.combinedStorage.getLiquid()))
{
this.causingMixing(this.combinedStorage.getLiquid(), network.combinedStorage.getLiquid());
}
else
{
LiquidStack stack = new LiquidStack(0, 0, 0);
if (this.combinedStorage.getLiquid() != null && network.combinedStorage.getLiquid() != null && this.combinedStorage.getLiquid().isLiquidEqual(network.combinedStorage.getLiquid()))
{
stack = this.combinedStorage.getLiquid();
stack.amount += network.combinedStorage.getLiquid().amount;
}
else if (this.combinedStorage.getLiquid() == null && network.combinedStorage.getLiquid() != null)
{
stack = network.combinedStorage.getLiquid();
}
else if (this.combinedStorage.getLiquid() != null && network.combinedStorage.getLiquid() == null)
{
stack = this.combinedStorage.getLiquid();
}
HydraulicNetwork newNetwork = new HydraulicNetwork(this.color);
newNetwork.getFluidNetworkParts().addAll(this.getFluidNetworkParts()); newNetwork.getFluidNetworkParts().addAll(this.getFluidNetworkParts());
newNetwork.getFluidNetworkParts().addAll(network.getFluidNetworkParts()); newNetwork.getFluidNetworkParts().addAll(network.getFluidNetworkParts());
newNetwork.cleanUpConductors(); newNetwork.cleanUpConductors();
newNetwork.combinedStorage.setLiquid(stack);
}
} }
} }
public void causingMixing(LiquidStack stack, LiquidStack stack2)
{
// TODO cause mixing of liquids based on types and volume. Also apply damage to pipes/parts
// as needed
}
public void splitNetwork(IConnectionProvider splitPoint) public void splitNetwork(IConnectionProvider splitPoint)
{ {
if (splitPoint instanceof TileEntity) if (splitPoint instanceof TileEntity)
@ -475,22 +530,18 @@ public class HydraulicNetwork
if (connectedBlockA instanceof IConnectionProvider) if (connectedBlockA instanceof IConnectionProvider)
{ {
for (int ii = 0; ii < connectedBlocks.length; ii++) for (int pipeCount = 0; pipeCount < connectedBlocks.length; pipeCount++)
{ {
final TileEntity connectedBlockB = connectedBlocks[ii]; final TileEntity connectedBlockB = connectedBlocks[pipeCount];
if (connectedBlockA != connectedBlockB && connectedBlockB instanceof IConnectionProvider) if (connectedBlockA != connectedBlockB && connectedBlockB instanceof IConnectionProvider)
{ {
Pathfinder finder = new PathfinderChecker((IConnectionProvider) connectedBlockB, splitPoint); Pathfinder finder = new PathfinderCheckerPipes((IConnectionProvider) connectedBlockB, splitPoint);
finder.init((IConnectionProvider) connectedBlockA); finder.init((IConnectionProvider) connectedBlockA);
if (finder.results.size() > 0) if (finder.results.size() > 0)
{ {
/** /* STILL CONNECTED SOMEWHERE ELSE */
* The connections A and B are still intact elsewhere. Set all
* references of wire connection into one network.
*/
for (IConnectionProvider node : finder.iteratedNodes) for (IConnectionProvider node : finder.iteratedNodes)
{ {
if (node instanceof IFluidNetworkPart) if (node instanceof IFluidNetworkPart)
@ -504,12 +555,9 @@ public class HydraulicNetwork
} }
else else
{ {
/** /* NO LONGER CONNECTED ELSE WHERE SO SPLIT AND REFRESH */
* The connections A and B are not connected anymore. Give both of
* them a new network.
*/
HydraulicNetwork newNetwork = new HydraulicNetwork(this.color); HydraulicNetwork newNetwork = new HydraulicNetwork(this.color);
int parts = 0;
for (IConnectionProvider node : finder.iteratedNodes) for (IConnectionProvider node : finder.iteratedNodes)
{ {
if (node instanceof IFluidNetworkPart) if (node instanceof IFluidNetworkPart)
@ -517,11 +565,18 @@ public class HydraulicNetwork
if (node != splitPoint) if (node != splitPoint)
{ {
newNetwork.getFluidNetworkParts().add((IFluidNetworkPart) node); newNetwork.getFluidNetworkParts().add((IFluidNetworkPart) node);
parts++;
} }
} }
} }
newNetwork.cleanUpConductors(); newNetwork.cleanUpConductors();
LiquidStack stack = this.combinedStorage.getLiquid();
if (stack != null)
{
newNetwork.combinedStorage.setLiquid(new LiquidStack(stack.itemID, parts * this.getVolumePerPart(), stack.itemMeta));
}
} }
} }
} }
@ -530,9 +585,45 @@ public class HydraulicNetwork
} }
} }
/**
* gets the amount of liquid stored in each part in the system
*/
public int getVolumePerPart()
{
int volumePerPart = 0;
LiquidStack stack = this.combinedStorage.getLiquid();
if (stack != null)
{
volumePerPart = this.combinedStorage.getLiquid().amount / this.fluidParts.size();
}
return volumePerPart;
}
/**
* Drain a set volume from the system
*/
public LiquidStack drainVolumeFromSystem(int volume, boolean doDrain)
{
LiquidStack stack = null;
if (this.combinedStorage.getLiquid() != null)
{
stack = this.combinedStorage.drain(this.getVolumePerPart(), doDrain);
}
return stack;
}
@Override @Override
public String toString() public String toString()
{ {
return "hydraulicNetwork[" + this.hashCode() + "|parts:" + this.fluidParts.size() + "]"; return "HydraulicNetwork[" + this.hashCode() + "|parts:" + this.fluidParts.size() + "]";
}
public String getStorageFluid()
{
if (combinedStorage.getLiquid() == null)
{
return "Zero";
}
return String.format("%d/%d %S Stored", combinedStorage.getLiquid().amount / LiquidContainerRegistry.BUCKET_VOLUME, combinedStorage.getCapacity() / LiquidContainerRegistry.BUCKET_VOLUME, LiquidHandler.getName(this.combinedStorage.getLiquid()));
} }
} }