package crazypants.enderio.conduit.power; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import com.enderio.core.common.util.BlockCoord; import crazypants.enderio.conduit.AbstractConduitNetwork; import crazypants.enderio.conduit.IConduitBundle; import crazypants.enderio.power.IPowerInterface; public class PowerConduitNetwork extends AbstractConduitNetwork<IPowerConduit, IPowerConduit> { // ---------------------------------------------------------------------- NetworkPowerManager powerManager; private final Map<ReceptorKey, ReceptorEntry> powerReceptors = new HashMap<ReceptorKey, ReceptorEntry>(); public PowerConduitNetwork() { super(IPowerConduit.class, IPowerConduit.class); } @Override public void init(IConduitBundle tile, Collection<IPowerConduit> connections, World world) { super.init(tile, connections, world); powerManager = new NetworkPowerManager(this, world); powerManager.receptorsChanged(); } @Override public void destroyNetwork() { for (IPowerConduit con : conduits) { con.setActive(false); } if(powerManager != null) { powerManager.onNetworkDestroyed(); } super.destroyNetwork(); } public NetworkPowerManager getPowerManager() { return powerManager; } @Override public void addConduit(IPowerConduit con) { super.addConduit(con); Set<ForgeDirection> externalDirs = con.getExternalConnections(); for (ForgeDirection dir : externalDirs) { IPowerInterface pr = con.getExternalPowerReceptor(dir); if(pr != null) { TileEntity te = con.getBundle().getEntity(); powerReceptorAdded(con, dir, te.xCoord + dir.offsetX, te.yCoord + dir.offsetY, te.zCoord + dir.offsetZ, pr); } } if(powerManager != null) { con.setActive(powerManager.isActive()); } } public void powerReceptorAdded(IPowerConduit powerConduit, ForgeDirection direction, int x, int y, int z, IPowerInterface powerReceptor) { if(powerReceptor == null) { return; } BlockCoord location = new BlockCoord(x, y, z); ReceptorKey key = new ReceptorKey(location, direction); ReceptorEntry re = powerReceptors.get(key); if(re == null) { re = new ReceptorEntry(powerReceptor, location, powerConduit, direction); powerReceptors.put(key, re); } if(powerManager != null) { powerManager.receptorsChanged(); } } public void powerReceptorRemoved(int x, int y, int z) { BlockCoord bc = new BlockCoord(x, y, z); List<ReceptorKey> remove = new ArrayList<ReceptorKey>(); for (ReceptorKey key : powerReceptors.keySet()) { if(key != null && key.coord.equals(bc)) { remove.add(key); } } for (ReceptorKey key : remove) { powerReceptors.remove(key); } powerManager.receptorsChanged(); } public Collection<ReceptorEntry> getPowerReceptors() { return powerReceptors.values(); } @Override public void doNetworkTick() { powerManager.applyRecievedPower(); } public static class ReceptorEntry { IPowerConduit emmiter; BlockCoord coord; ForgeDirection direction; IPowerInterface powerInterface; public ReceptorEntry(IPowerInterface powerReceptor, BlockCoord coord, IPowerConduit emmiter, ForgeDirection direction) { powerInterface = powerReceptor; this.coord = coord; this.emmiter = emmiter; this.direction = direction; } } private static class ReceptorKey { BlockCoord coord; ForgeDirection direction; ReceptorKey(BlockCoord coord, ForgeDirection direction) { this.coord = coord; this.direction = direction; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((coord == null) ? 0 : coord.hashCode()); result = prime * result + ((direction == null) ? 0 : direction.hashCode()); return result; } @Override public boolean equals(Object obj) { if(this == obj) { return true; } if(obj == null) { return false; } if(getClass() != obj.getClass()) { return false; } ReceptorKey other = (ReceptorKey) obj; if(coord == null) { if(other.coord != null) { return false; } } else if(!coord.equals(other.coord)) { return false; } if(direction != other.direction) { return false; } return true; } } }