Mekanism-tilera-Edition/common/mekanism/api/transmitters/DynamicNetwork.java
Ben Spiers 9755b47833 Universal cable support for accepting from UE machines. change *Network* to *TransmitterNetwork* in ITransmitter to avoid method name conflicts.
Not all IConductor methods are properly implemented, doesn't seem to cause problems in my testing. Could probably implement IElectricityNetwork in EnergyNetwork but this seems to work.
2013-08-27 00:18:12 +01:00

258 lines
6.5 KiB
Java

package mekanism.api.transmitters;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import mekanism.api.Object3D;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
public abstract class DynamicNetwork<A, N> implements ITransmitterNetwork<A, N>
{
public HashSet<ITransmitter<N>> transmitters = new HashSet<ITransmitter<N>>();
public Set<A> possibleAcceptors = new HashSet<A>();
public Map<A, ForgeDirection> acceptorDirections = new HashMap<A, ForgeDirection>();
protected int ticksSinceCreate = 0;
protected int ticksSinceSecond = 0;
protected boolean fixed = false;
protected abstract ITransmitterNetwork<A, N> create(ITransmitter<N>... varTransmitters);
protected abstract ITransmitterNetwork<A, N> create(Collection<ITransmitter<N>> collection);
protected abstract ITransmitterNetwork<A, N> create(Set<N> networks);
public void addAllTransmitters(Set<ITransmitter<N>> newTransmitters)
{
transmitters.addAll(newTransmitters);
}
@Override
public void removeTransmitter(ITransmitter<N> transmitter)
{
transmitters.remove(transmitter);
if(transmitters.size() == 0)
{
deregister();
}
}
@Override
public void register()
{
try {
ITransmitter<N> aTransmitter = transmitters.iterator().next();
if(aTransmitter instanceof TileEntity && !((TileEntity)aTransmitter).worldObj.isRemote)
{
TransmitterNetworkRegistry.getInstance().registerNetwork(this);
}
} catch(NoSuchElementException e) {}
}
@Override
public void deregister()
{
transmitters.clear();
TransmitterNetworkRegistry.getInstance().removeNetwork(this);
}
@Override
public int getSize()
{
return transmitters.size();
}
@Override
public int getAcceptorSize()
{
return possibleAcceptors.size();
}
@Override
public void tick()
{
if(!fixed)
{
++ticksSinceCreate;
if(ticksSinceCreate > 1200)
{
ticksSinceCreate = 0;
fixMessedUpNetwork(transmitters.iterator().next());
}
}
}
@Override
public void fixMessedUpNetwork(ITransmitter<N> transmitter)
{
if(transmitter instanceof TileEntity)
{
NetworkFinder finder = new NetworkFinder(((TileEntity)transmitter).getWorldObj(), getTransmissionType(), Object3D.get((TileEntity)transmitter));
List<Object3D> partNetwork = finder.exploreNetwork();
Set<ITransmitter<N>> newTransporters = new HashSet<ITransmitter<N>>();
for(Object3D node : partNetwork)
{
TileEntity nodeTile = node.getTileEntity(((TileEntity)transmitter).worldObj);
if(TransmissionType.checkTransmissionType(nodeTile, getTransmissionType(), (TileEntity) transmitter))
{
((ITransmitter<N>)nodeTile).removeFromTransmitterNetwork();
newTransporters.add((ITransmitter<N>)nodeTile);
}
}
ITransmitterNetwork<A, N> newNetwork = create(newTransporters);
newNetwork.refresh();
newNetwork.setFixed(true);
deregister();
}
}
@Override
public void split(ITransmitter<N> splitPoint)
{
if(splitPoint instanceof TileEntity)
{
removeTransmitter(splitPoint);
TileEntity[] connectedBlocks = new TileEntity[6];
boolean[] dealtWith = {false, false, false, false, false, false};
for(ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS)
{
TileEntity sideTile = Object3D.get((TileEntity)splitPoint).getFromSide(direction).getTileEntity(((TileEntity)splitPoint).worldObj);
if(sideTile != null)
{
connectedBlocks[Arrays.asList(ForgeDirection.values()).indexOf(direction)] = sideTile;
}
}
for(int countOne = 0; countOne < connectedBlocks.length; countOne++)
{
TileEntity connectedBlockA = connectedBlocks[countOne];
if(TransmissionType.checkTransmissionType(connectedBlockA, getTransmissionType()) && !dealtWith[countOne])
{
NetworkFinder finder = new NetworkFinder(((TileEntity)splitPoint).worldObj, getTransmissionType(), Object3D.get(connectedBlockA), Object3D.get((TileEntity)splitPoint));
List<Object3D> partNetwork = finder.exploreNetwork();
for(int countTwo = countOne + 1; countTwo < connectedBlocks.length; countTwo++)
{
TileEntity connectedBlockB = connectedBlocks[countTwo];
if(TransmissionType.checkTransmissionType(connectedBlockB, getTransmissionType()) && !dealtWith[countTwo])
{
if(partNetwork.contains(Object3D.get(connectedBlockB)))
{
dealtWith[countTwo] = true;
}
}
}
Set<ITransmitter<N>> newNetCables = new HashSet<ITransmitter<N>>();
for(Object3D node : finder.iterated)
{
TileEntity nodeTile = node.getTileEntity(((TileEntity)splitPoint).worldObj);
if(TransmissionType.checkTransmissionType(nodeTile, getTransmissionType()))
{
if(nodeTile != splitPoint)
{
newNetCables.add((ITransmitter<N>)nodeTile);
}
}
}
ITransmitterNetwork<A, N> newNetwork = create(newNetCables);
newNetwork.refresh();
}
}
deregister();
}
}
@Override
public void setFixed(boolean value)
{
fixed = value;
}
public static class NetworkFinder
{
public TransmissionType transmissionType;
public World worldObj;
public Object3D start;
public List<Object3D> iterated = new ArrayList<Object3D>();
public List<Object3D> toIgnore = new ArrayList<Object3D>();
public NetworkFinder(World world, TransmissionType type, Object3D location, Object3D... ignore)
{
worldObj = world;
start = location;
transmissionType = type;
if(ignore != null)
{
for (int i = 0; i < ignore.length; i++)
{
this.toIgnore.add(ignore[i]);
}
}
}
public void loopAll(Object3D location)
{
if(TransmissionType.checkTransmissionType(location.getTileEntity(worldObj), transmissionType))
{
iterated.add(location);
}
else
{
toIgnore.add(location);
}
for(ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS)
{
Object3D obj = location.getFromSide(direction);
if(!iterated.contains(obj) && !toIgnore.contains(obj))
{
TileEntity tileEntity = obj.getTileEntity(worldObj);
if(TransmissionType.checkTransmissionType(tileEntity, transmissionType, location.getTileEntity(worldObj)))
{
loopAll(obj);
}
}
}
}
public List<Object3D> exploreNetwork()
{
loopAll(start);
return iterated;
}
}
}