318 lines
9 KiB
Java
318 lines
9 KiB
Java
|
package resonantinduction.mechanical.fluid.network;
|
||
|
|
||
|
import java.util.EnumSet;
|
||
|
import java.util.HashMap;
|
||
|
import java.util.Iterator;
|
||
|
|
||
|
import net.minecraft.tileentity.TileEntity;
|
||
|
import net.minecraft.world.World;
|
||
|
import net.minecraftforge.common.ForgeDirection;
|
||
|
import net.minecraftforge.fluids.FluidContainerRegistry;
|
||
|
import net.minecraftforge.fluids.FluidStack;
|
||
|
import net.minecraftforge.fluids.FluidTank;
|
||
|
import net.minecraftforge.fluids.FluidTankInfo;
|
||
|
import net.minecraftforge.fluids.IFluidHandler;
|
||
|
import resonantinduction.core.tilenetwork.INetworkPart;
|
||
|
import resonantinduction.core.tilenetwork.ITileNetwork;
|
||
|
import resonantinduction.core.tilenetwork.prefab.NetworkTileEntities;
|
||
|
import resonantinduction.core.tilenetwork.prefab.NetworkUpdateHandler;
|
||
|
import resonantinduction.mechanical.fluid.FluidCraftingHandler;
|
||
|
import resonantinduction.old.api.fluid.INetworkFluidPart;
|
||
|
import calclavia.lib.utility.FluidHelper;
|
||
|
|
||
|
public class NetworkFluidTiles extends NetworkTileEntities
|
||
|
{
|
||
|
/** Fluid Tanks that are connected to the network but not part of the network's main body */
|
||
|
public HashMap<IFluidHandler, EnumSet<ForgeDirection>> connctedFluidHandlers = new HashMap<IFluidHandler, EnumSet<ForgeDirection>>();
|
||
|
/** Collective storage tank of all fluid tile that make up this networks main body */
|
||
|
protected FluidTank sharedTank;
|
||
|
protected FluidTankInfo sharedTankInfo;
|
||
|
|
||
|
/** Has the collective tank been loaded yet */
|
||
|
protected boolean loadedLiquids = false;
|
||
|
|
||
|
static
|
||
|
{
|
||
|
NetworkUpdateHandler.registerNetworkClass("FluidTiles", NetworkFluidTiles.class);
|
||
|
}
|
||
|
|
||
|
public NetworkFluidTiles()
|
||
|
{
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
public NetworkFluidTiles(INetworkPart... parts)
|
||
|
{
|
||
|
super(parts);
|
||
|
}
|
||
|
|
||
|
/** Gets the collective tank of the network */
|
||
|
public FluidTank getNetworkTank()
|
||
|
{
|
||
|
if (this.sharedTank == null)
|
||
|
{
|
||
|
this.sharedTank = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME);
|
||
|
this.getNetworkTankInfo();
|
||
|
}
|
||
|
return this.sharedTank;
|
||
|
}
|
||
|
|
||
|
public FluidTankInfo getNetworkTankInfo()
|
||
|
{
|
||
|
if (this.sharedTankInfo == null)
|
||
|
{
|
||
|
this.sharedTankInfo = this.getNetworkTank().getInfo();
|
||
|
}
|
||
|
return this.sharedTankInfo;
|
||
|
}
|
||
|
|
||
|
public int fillNetworkTank(TileEntity source, FluidStack stack, boolean doFill)
|
||
|
{
|
||
|
if (!this.loadedLiquids)
|
||
|
{
|
||
|
this.load();
|
||
|
this.loadedLiquids = true;
|
||
|
}
|
||
|
if (!source.worldObj.isRemote && this.getNetworkTank() != null && stack != null)
|
||
|
{
|
||
|
int p = this.getNetworkTank().getFluidAmount();
|
||
|
int r = this.getNetworkTank().fill(stack, doFill);
|
||
|
// System.out.println((world.isRemote ? "Client" : "Server") + " Network Fill: B:" + p +
|
||
|
// " A:" + this.getNetworkTank().getFluidAmount());
|
||
|
if (doFill)
|
||
|
{
|
||
|
if (p != this.getNetworkTank().getFluidAmount())
|
||
|
{
|
||
|
this.sharedTankInfo = this.getNetworkTank().getInfo();
|
||
|
this.save();
|
||
|
}
|
||
|
}
|
||
|
return r;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
public FluidStack drainNetworkTank(World world, int volume, boolean doDrain)
|
||
|
{
|
||
|
|
||
|
if (!this.loadedLiquids)
|
||
|
{
|
||
|
this.load();
|
||
|
this.loadedLiquids = true;
|
||
|
}
|
||
|
FluidStack before = this.getNetworkTank().getFluid();
|
||
|
if (!world.isRemote && this.getNetworkTank() != null && before != null)
|
||
|
{
|
||
|
FluidStack drain = this.getNetworkTank().drain(volume, doDrain);
|
||
|
FluidStack after = this.getNetworkTank().getFluid();
|
||
|
// System.out.println((doDrain ? "" : "Fake") + " Network Drain for " + volume + " B:" +
|
||
|
// (before != null ? before.amount : 0) + " A:" + (after != null ? after.amount : 0) +
|
||
|
// " D:" + (drain != null ? drain.amount : 0));
|
||
|
if (doDrain)
|
||
|
{
|
||
|
// Has the tank changed any. If yes then update all info and do a client update
|
||
|
if (!before.isFluidEqual(after) || (before != null && after != null && before.amount != after.amount))
|
||
|
{
|
||
|
this.sharedTankInfo = this.getNetworkTank().getInfo();
|
||
|
this.save();
|
||
|
/*
|
||
|
* TODO do a client update from the network rather than each pipe updating
|
||
|
* itself.
|
||
|
* This will save on packet size but will increase the CPU load of the client
|
||
|
* since the client
|
||
|
* will need to do network calculations
|
||
|
*/
|
||
|
}
|
||
|
}
|
||
|
return drain;
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void save()
|
||
|
{
|
||
|
this.cleanUpMembers();
|
||
|
if (this.getNetworkTank().getFluid() != null && this.getMembers().size() > 0)
|
||
|
{
|
||
|
FluidStack stack = this.getNetworkTank().getFluid() == null ? null : this.getNetworkTank().getFluid().copy();
|
||
|
int membersFilled = 0;
|
||
|
|
||
|
for (INetworkPart par : this.getMembers())
|
||
|
{
|
||
|
// UPDATE FILL VOLUME
|
||
|
int fillVol = stack == null ? 0 : (stack.amount / (this.getMembers().size() - membersFilled));
|
||
|
|
||
|
if (par instanceof INetworkFluidPart)
|
||
|
{
|
||
|
// EMPTY TANK
|
||
|
((INetworkFluidPart) par).drainTankContent(0, Integer.MAX_VALUE, true);
|
||
|
// FILL TANK
|
||
|
if (stack != null)
|
||
|
{
|
||
|
stack.amount -= ((INetworkFluidPart) par).fillTankContent(0, FluidHelper.getStack(stack, fillVol), true);
|
||
|
membersFilled++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void load()
|
||
|
{
|
||
|
FluidStack stack = null;
|
||
|
this.cleanUpMembers();
|
||
|
for (INetworkPart par : this.getMembers())
|
||
|
{
|
||
|
if (par instanceof INetworkFluidPart)
|
||
|
{
|
||
|
if (((INetworkFluidPart) par).getTankInfo()[0] != null && ((INetworkFluidPart) par).getTankInfo()[0].fluid != null)
|
||
|
{
|
||
|
if (stack == null)
|
||
|
{
|
||
|
stack = ((INetworkFluidPart) par).getTankInfo()[0].fluid.copy();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
stack.amount += ((INetworkFluidPart) par).getTankInfo()[0].fluid.amount;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (stack != null && stack.amount > 0)
|
||
|
{
|
||
|
this.getNetworkTank().setFluid(stack);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.getNetworkTank().setFluid(null);
|
||
|
}
|
||
|
this.loadedLiquids = true;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean removeTile(TileEntity ent)
|
||
|
{
|
||
|
return super.removeTile(ent) || this.connctedFluidHandlers.remove(ent) != null;
|
||
|
}
|
||
|
|
||
|
/** Checks too see if the tileEntity is part of or connected too the network */
|
||
|
public boolean isConnected(TileEntity tileEntity)
|
||
|
{
|
||
|
return this.connctedFluidHandlers.containsKey(tileEntity);
|
||
|
}
|
||
|
|
||
|
public void addTank(ForgeDirection side, IFluidHandler tank)
|
||
|
{
|
||
|
if (this.connctedFluidHandlers.containsKey(tank))
|
||
|
{
|
||
|
EnumSet<ForgeDirection> d = this.connctedFluidHandlers.get(tank);
|
||
|
d.add(side);
|
||
|
this.connctedFluidHandlers.put(tank, d);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
EnumSet<ForgeDirection> d = EnumSet.noneOf(ForgeDirection.class);
|
||
|
d.add(side);
|
||
|
this.connctedFluidHandlers.put(tank, d);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean preMergeProcessing(ITileNetwork mergingNetwork, INetworkPart mergePoint)
|
||
|
{
|
||
|
if (mergingNetwork instanceof NetworkFluidTiles)
|
||
|
{
|
||
|
if (!((NetworkFluidTiles) mergingNetwork).loadedLiquids)
|
||
|
{
|
||
|
((NetworkFluidTiles) mergingNetwork).load();
|
||
|
}
|
||
|
if (!this.loadedLiquids)
|
||
|
{
|
||
|
this.load();
|
||
|
}
|
||
|
}
|
||
|
return super.preMergeProcessing(mergingNetwork, mergePoint);
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected void mergeDo(ITileNetwork network)
|
||
|
{
|
||
|
ITileNetwork newNetwork = NetworkUpdateHandler.createNewNetwork(NetworkUpdateHandler.getID(this.getClass()));
|
||
|
if (newNetwork != null)
|
||
|
{
|
||
|
if (newNetwork instanceof NetworkFluidTiles)
|
||
|
{
|
||
|
FluidStack one = this.getNetworkTank().getFluid();
|
||
|
FluidStack two = ((NetworkFluidTiles) network).getNetworkTank().getFluid();
|
||
|
|
||
|
this.getNetworkTank().setFluid(null);
|
||
|
((NetworkFluidTiles) network).getNetworkTank().setFluid(null);
|
||
|
|
||
|
((NetworkFluidTiles) newNetwork).getNetworkTank().setFluid(FluidCraftingHandler.mergeFluidStacks(one, two));
|
||
|
((NetworkFluidTiles) newNetwork).sharedTankInfo = ((NetworkFluidTiles) newNetwork).getNetworkTank().getInfo();
|
||
|
}
|
||
|
newNetwork.getMembers().addAll(this.getMembers());
|
||
|
newNetwork.getMembers().addAll(network.getMembers());
|
||
|
newNetwork.onCreated();
|
||
|
newNetwork.save();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
System.out.println("[NetworkFluidTiles] Failed to merge network due to the new network returned null");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void cleanUpMembers()
|
||
|
{
|
||
|
Iterator<INetworkPart> it = this.getMembers().iterator();
|
||
|
int capacity = 0;
|
||
|
while (it.hasNext())
|
||
|
{
|
||
|
INetworkPart part = it.next();
|
||
|
if (!this.isValidMember(part))
|
||
|
{
|
||
|
it.remove();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
part.setTileNetwork(this);
|
||
|
if (part instanceof INetworkFluidPart && ((INetworkFluidPart) part).getTankInfo()[0] != null)
|
||
|
{
|
||
|
capacity += ((INetworkFluidPart) part).getTankInfo()[0].capacity;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
this.getNetworkTank().setCapacity(capacity);
|
||
|
this.sharedTankInfo = this.getNetworkTank().getInfo();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean isValidMember(INetworkPart part)
|
||
|
{
|
||
|
return super.isValidMember(part) && part instanceof INetworkFluidPart;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public String toString()
|
||
|
{
|
||
|
return "FluidNetwork[" + this.hashCode() + "|parts:" + this.getMembers().size() + "]";
|
||
|
}
|
||
|
|
||
|
public String getNetworkFluid()
|
||
|
{
|
||
|
if (this.getNetworkTank() != null && this.getNetworkTank().getFluid() != null && this.getNetworkTank().getFluid().getFluid() != null)
|
||
|
{
|
||
|
int cap = this.getNetworkTank().getCapacity() / FluidContainerRegistry.BUCKET_VOLUME;
|
||
|
int vol = this.getNetworkTank().getFluid() != null ? (this.getNetworkTank().getFluid().amount / FluidContainerRegistry.BUCKET_VOLUME) : 0;
|
||
|
String name = this.getNetworkTank().getFluid().getFluid().getLocalizedName();
|
||
|
return String.format("%d/%d %S Stored", vol, cap, name);
|
||
|
}
|
||
|
return ("Empty");
|
||
|
}
|
||
|
}
|