electrodynamics/archive/java/resonantinduction/mechanical/fluid/network/NetworkFluidTiles.java
2014-01-11 17:44:07 +08:00

317 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");
}
}