Mekanism-tilera-Edition/src/main/java/mekanism/common/FluidNetwork.java

493 lines
11 KiB
Java
Raw Normal View History

package mekanism.common;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import mekanism.api.Coord4D;
import mekanism.api.ListUtils;
import mekanism.api.transmitters.DynamicNetwork;
2013-12-21 01:12:33 +01:00
import mekanism.api.transmitters.IGridTransmitter;
import mekanism.api.transmitters.ITransmitterNetwork;
import mekanism.api.transmitters.TransmissionType;
import mekanism.common.util.PipeUtils;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.MinecraftForge;
2014-06-02 23:57:40 +02:00
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
2013-07-20 18:10:14 +02:00
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidHandler;
import cpw.mods.fml.common.FMLCommonHandler;
2014-06-02 23:57:40 +02:00
import cpw.mods.fml.common.eventhandler.Event;
2013-12-06 13:57:26 +01:00
public class FluidNetwork extends DynamicNetwork<IFluidHandler, FluidNetwork>
{
public int transferDelay = 0;
public boolean didTransfer;
public boolean prevTransfer;
public float fluidScale;
2013-12-18 00:20:18 +01:00
public Fluid refFluid;
2013-12-14 06:36:52 +01:00
public FluidStack fluidStored;
2013-12-18 00:20:18 +01:00
public int prevStored;
public int prevTransferAmount = 0;
2013-12-21 01:12:33 +01:00
public FluidNetwork(IGridTransmitter<FluidNetwork>... varPipes)
{
transmitters.addAll(Arrays.asList(varPipes));
updateCapacity();
register();
}
2013-12-21 01:12:33 +01:00
public FluidNetwork(Collection<IGridTransmitter<FluidNetwork>> collection)
{
transmitters.addAll(collection);
updateCapacity();
register();
}
public FluidNetwork(Set<FluidNetwork> networks)
{
for(FluidNetwork net : networks)
{
if(net != null)
{
2013-12-18 17:19:30 +01:00
if(FMLCommonHandler.instance().getEffectiveSide().isClient())
2013-11-29 19:04:39 +01:00
{
2013-12-18 17:19:30 +01:00
if(net.refFluid != null && net.fluidScale > fluidScale)
{
2013-12-18 17:19:30 +01:00
refFluid = net.refFluid;
fluidScale = net.fluidScale;
fluidStored = net.fluidStored;
2013-12-18 17:19:30 +01:00
net.fluidScale = 0;
net.refFluid = null;
net.fluidStored = null;
}
2013-12-18 17:19:30 +01:00
}
else {
if(net.fluidStored != null)
{
if(fluidStored == null)
{
fluidStored = net.fluidStored;
}
else {
fluidStored.amount += net.fluidStored.amount;
}
2013-12-18 17:19:30 +01:00
net.fluidStored = null;
}
}
addAllTransmitters(net.transmitters);
net.deregister();
}
}
2013-12-18 13:24:59 +01:00
fluidScale = getScale();
updateCapacity();
2014-06-19 15:18:41 +02:00
fullRefresh();
register();
}
@Override
protected synchronized void updateMeanCapacity()
{
int numCables = transmitters.size();
double sum = 0;
for(IGridTransmitter<FluidNetwork> pipe : transmitters)
{
sum += pipe.getCapacity();
}
meanCapacity = sum / (double)numCables;
}
@Override
public void onNetworksCreated(List<FluidNetwork> networks)
{
2013-12-18 17:19:30 +01:00
if(fluidStored != null && FMLCommonHandler.instance().getEffectiveSide().isServer())
{
int[] caps = new int[networks.size()];
int cap = 0;
for(FluidNetwork network : networks)
{
caps[networks.indexOf(network)] = network.getCapacity();
cap += network.getCapacity();
}
fluidStored.amount = Math.min(cap, fluidStored.amount);
int[] values = ListUtils.calcPercentInt(ListUtils.percent(caps), fluidStored.amount);
for(FluidNetwork network : networks)
{
int index = networks.indexOf(network);
if(values[index] > 0)
{
network.fluidStored = new FluidStack(fluidStored.getFluid(), values[index]);
network.fluidScale = network.getScale();
network.refFluid = fluidStored.getFluid();
}
}
}
fluidScale = 0;
fluidStored = null;
refFluid = null;
}
2013-12-14 06:36:52 +01:00
public synchronized int getFluidNeeded()
{
return getCapacity()-(fluidStored != null ? fluidStored.amount : 0);
}
2013-12-14 06:36:52 +01:00
public synchronized int tickEmit(FluidStack fluidToSend, boolean doTransfer)
{
2013-08-18 22:51:47 +02:00
List availableAcceptors = Arrays.asList(getAcceptors(fluidToSend).toArray());
Collections.shuffle(availableAcceptors);
2013-07-20 18:10:14 +02:00
int fluidSent = 0;
if(!availableAcceptors.isEmpty())
{
int divider = availableAcceptors.size();
2013-07-20 18:10:14 +02:00
int remaining = fluidToSend.amount % divider;
int sending = (fluidToSend.amount-remaining)/divider;
for(Object obj : availableAcceptors)
{
2013-12-14 06:36:52 +01:00
if(obj instanceof IFluidHandler)
{
2013-07-20 18:10:14 +02:00
IFluidHandler acceptor = (IFluidHandler)obj;
int currentSending = sending;
if(remaining > 0)
{
currentSending++;
remaining--;
}
2013-12-13 03:35:17 +01:00
fluidSent += acceptor.fill(acceptorDirections.get(acceptor).getOpposite(), new FluidStack(fluidToSend.fluidID, currentSending), doTransfer);
}
}
}
2013-07-20 18:10:14 +02:00
if(doTransfer && fluidSent > 0 && FMLCommonHandler.instance().getEffectiveSide().isServer())
{
didTransfer = true;
transferDelay = 2;
}
2013-07-20 18:10:14 +02:00
return fluidSent;
}
2013-12-14 06:36:52 +01:00
public synchronized int emit(FluidStack fluidToSend, boolean doTransfer)
{
if(fluidToSend == null || (fluidStored != null && fluidStored.getFluid() != fluidToSend.getFluid()))
{
return 0;
}
2013-12-14 06:36:52 +01:00
int toUse = Math.min(getFluidNeeded(), fluidToSend.amount);
2013-12-14 06:36:52 +01:00
if(doTransfer)
{
if(fluidStored == null)
{
fluidStored = fluidToSend.copy();
fluidStored.amount = toUse;
}
else {
fluidStored.amount += toUse;
}
}
2013-12-14 06:36:52 +01:00
return toUse;
}
@Override
2013-12-21 20:54:12 +01:00
public void onUpdate()
{
2013-12-21 20:54:12 +01:00
super.onUpdate();
if(FMLCommonHandler.instance().getEffectiveSide().isServer())
{
prevTransferAmount = 0;
if(transferDelay == 0)
{
didTransfer = false;
}
else {
transferDelay--;
}
2013-12-18 00:20:18 +01:00
int stored = fluidStored != null ? fluidStored.amount : 0;
2013-12-18 00:20:18 +01:00
if(stored != prevStored)
{
needsUpdate = true;
}
2013-12-18 00:20:18 +01:00
prevStored = stored;
if(didTransfer != prevTransfer || needsUpdate)
{
2013-12-18 00:20:18 +01:00
MinecraftForge.EVENT_BUS.post(new FluidTransferEvent(this, fluidStored, didTransfer));
needsUpdate = false;
}
prevTransfer = didTransfer;
2013-12-14 06:36:52 +01:00
if(fluidStored != null)
{
prevTransferAmount = tickEmit(fluidStored, true);
fluidStored.amount -= prevTransferAmount;
2014-03-16 01:05:26 +01:00
if(fluidStored != null && fluidStored.amount <= 0)
2013-12-14 06:36:52 +01:00
{
fluidStored = null;
}
}
}
}
@Override
public void clientTick()
{
super.clientTick();
2013-12-18 00:20:18 +01:00
fluidScale = Math.max(fluidScale, getScale());
if(didTransfer && fluidScale < 1)
{
2013-12-18 00:20:18 +01:00
fluidScale = Math.max(getScale(), Math.min(1, fluidScale+0.02F));
}
else if(!didTransfer && fluidScale > 0)
{
fluidScale = getScale();
if(fluidScale == 0)
{
2013-12-18 00:20:18 +01:00
fluidStored = null;
}
}
}
2013-08-18 22:51:47 +02:00
@Override
public synchronized Set<IFluidHandler> getAcceptors(Object... data)
{
2013-08-18 22:51:47 +02:00
FluidStack fluidToSend = (FluidStack)data[0];
2013-07-20 18:10:14 +02:00
Set<IFluidHandler> toReturn = new HashSet<IFluidHandler>();
for(IFluidHandler acceptor : possibleAcceptors.values())
{
if(acceptorDirections.get(acceptor) == null)
{
continue;
}
2013-07-20 18:10:14 +02:00
if(acceptor.canFill(acceptorDirections.get(acceptor).getOpposite(), fluidToSend.getFluid()))
{
toReturn.add(acceptor);
}
}
return toReturn;
}
2013-08-18 22:51:47 +02:00
@Override
public synchronized void refresh()
{
2013-12-21 01:12:33 +01:00
Set<IGridTransmitter<FluidNetwork>> iterPipes = (Set<IGridTransmitter<FluidNetwork>>)transmitters.clone();
Iterator it = iterPipes.iterator();
boolean networkChanged = false;
while(it.hasNext())
{
2013-12-21 01:12:33 +01:00
IGridTransmitter<FluidNetwork> conductor = (IGridTransmitter<FluidNetwork>)it.next();
if(conductor == null || conductor.getTile().isInvalid())
{
it.remove();
networkChanged = true;
transmitters.remove(conductor);
}
else {
conductor.setTransmitterNetwork(this);
}
}
if(networkChanged)
{
updateCapacity();
}
}
@Override
public synchronized void refresh(IGridTransmitter<FluidNetwork> transmitter)
{
IFluidHandler[] acceptors = PipeUtils.getConnectedAcceptors(transmitter.getTile());
clearAround(transmitter);
for(IFluidHandler acceptor : acceptors)
{
ForgeDirection side = ForgeDirection.getOrientation(Arrays.asList(acceptors).indexOf(acceptor));
if(side != null && acceptor != null && !(acceptor instanceof IGridTransmitter) && transmitter.canConnectToAcceptor(side, true))
{
possibleAcceptors.put(Coord4D.get((TileEntity)acceptor), acceptor);
acceptorDirections.put(acceptor, ForgeDirection.getOrientation(Arrays.asList(acceptors).indexOf(acceptor)));
}
}
}
2013-07-20 18:10:14 +02:00
public static class FluidTransferEvent extends Event
{
2013-07-20 18:10:14 +02:00
public final FluidNetwork fluidNetwork;
2013-12-18 00:20:18 +01:00
public final FluidStack fluidType;
public final boolean didTransfer;
2013-12-18 00:20:18 +01:00
public FluidTransferEvent(FluidNetwork network, FluidStack type, boolean did)
{
2013-07-20 18:10:14 +02:00
fluidNetwork = network;
fluidType = type;
didTransfer = did;
}
}
public float getScale()
{
return Math.min(1, (fluidStored == null || getCapacity() == 0 ? 0 : (float)fluidStored.amount/getCapacity()));
}
@Override
public String toString()
{
return "[FluidNetwork] " + transmitters.size() + " transmitters, " + possibleAcceptors.size() + " acceptors.";
2013-08-04 02:18:43 +02:00
}
@Override
protected FluidNetwork create(IGridTransmitter<FluidNetwork>... varTransmitters)
{
FluidNetwork network = new FluidNetwork(varTransmitters);
network.refFluid = refFluid;
if(fluidStored != null)
{
if(network.fluidStored == null)
{
network.fluidStored = fluidStored;
}
else {
network.fluidStored.amount += fluidStored.amount;
}
}
2013-12-18 13:24:59 +01:00
network.fluidScale = network.getScale();
2013-12-18 02:42:52 +01:00
fluidScale = 0;
refFluid = null;
fluidStored = null;
return network;
}
@Override
protected FluidNetwork create(Collection<IGridTransmitter<FluidNetwork>> collection)
{
FluidNetwork network = new FluidNetwork(collection);
network.refFluid = refFluid;
2013-12-18 17:19:30 +01:00
if(fluidStored != null)
{
if(network.fluidStored == null)
{
network.fluidStored = fluidStored;
}
else {
network.fluidStored.amount += fluidStored.amount;
}
}
network.updateCapacity();
2013-12-18 13:24:59 +01:00
network.fluidScale = network.getScale();
return network;
}
@Override
public boolean canMerge(List<ITransmitterNetwork<?, ?>> networks)
{
Fluid found = null;
for(ITransmitterNetwork<?, ?> network : networks)
{
if(network instanceof FluidNetwork)
{
FluidNetwork net = (FluidNetwork)network;
if(net.fluidStored != null)
{
if(found != null && found != net.fluidStored.getFluid())
{
return false;
}
found = net.fluidStored.getFluid();
}
}
}
return true;
}
@Override
protected FluidNetwork create(Set<FluidNetwork> networks)
{
return new FluidNetwork(networks);
}
@Override
public TransmissionType getTransmissionType()
{
return TransmissionType.FLUID;
}
@Override
public String getNeededInfo()
{
return (float)getFluidNeeded()/1000F + " buckets";
}
@Override
public String getStoredInfo()
{
return fluidStored != null ? fluidStored.getFluid().getLocalizedName(fluidStored) + " (" + fluidStored.amount + " mB)" : "None";
}
@Override
public String getFlowInfo()
{
return Integer.toString(prevTransferAmount) + " mB/t";
}
}