Probably actually resolving by cost now.
Probably actually resolving by cost now.

--- a/ARFlightController.cs
+++ b/ARFlightController.cs
@@ -317,6 +317,7 @@
 
 					log.AppendFormat("\n\tDoing target search for useful relay {0}", relay);
 
+					relay.RecalculateTransmissionRates();
 					relay.FindNearestRelay();
 				}
 
@@ -333,6 +334,7 @@
 
 					log.AppendFormat("\nFinding nearest relay for active vessel relay {0}", relay);
 
+					relay.RecalculateTransmissionRates();
 					relay.FindNearestRelay();
 				}
 

--- a/AntennaRelay.cs
+++ b/AntennaRelay.cs
@@ -158,6 +158,42 @@
 		}
 
 		/// <summary>
+		/// Gets the current link resource rate in EC/MiT.
+		/// </summary>
+		/// <value>The current link resource rate in EC/MiT.</value>
+		public virtual double CurrentLinkResourceRate
+		{
+			get
+			{
+				return this.DataResourceCost;
+			}
+		}
+
+		public virtual double CurrentNetworkResourceRate
+		{
+			get
+			{
+				double totalRate = 0;
+
+				IAntennaRelay nextLink = this.moduleRef;
+
+				while (nextLink != null)
+				{
+					totalRate += nextLink.DataResourceCost;
+
+					if (nextLink.KerbinDirect)
+					{
+						break;
+					}
+
+					nextLink = nextLink.targetRelay;
+				}
+
+				return totalRate;
+			}
+		}
+
+		/// <summary>
 		/// Gets or sets the link status.
 		/// </summary>
 		public virtual ConnectionStatus LinkStatus
@@ -214,12 +250,10 @@
 		/// Override ModuleDataTransmitter.DataRate to just return packetSize, because we want antennas to be scored in
 		/// terms of joules/byte
 		/// </summary>
-		public new float DataRate
+		public virtual float DataRate
 		{
 			get
 			{
-				this.RecalculateTransmissionRates();
-
 				if (this.CanTransmit())
 				{
 					return this.moduleRef.PacketSize;
@@ -235,12 +269,10 @@
 		/// Override ModuleDataTransmitter.DataResourceCost to just return packetResourceCost, because we want antennas
 		/// to be scored in terms of joules/byte
 		/// </summary>
-		public new double DataResourceCost
+		public virtual double DataResourceCost
 		{
 			get
 			{
-				this.RecalculateTransmissionRates();
-
 				if (this.CanTransmit())
 				{
 					return this.moduleRef.PacketResourceCost;
@@ -265,34 +297,100 @@
 		// distance.  packetSize maxes out at _basepacketSize * maxDataFactor.
 		public void RecalculateTransmissionRates()
 		{
-			if (!ARConfiguration.FixedPowerCost && this.CurrentLinkSqrDistance >= this.NominalLinkSqrDistance)
-			{
-				this.moduleRef.PacketSize = this.moduleRef.BasePacketSize;
-			}
-			else
-			{
-				float rangeFactor = (float)(this.NominalLinkSqrDistance / this.CurrentLinkSqrDistance);
+			float rangeFactor = (float)(this.NominalLinkSqrDistance / this.CurrentLinkSqrDistance);
+
+			if (ARConfiguration.FixedPowerCost)
+			{
+				this.moduleRef.PacketResourceCost = this.moduleRef.BasePacketResourceCost;
 
 				this.moduleRef.PacketSize = Mathf.Min(
 					this.moduleRef.BasePacketSize * rangeFactor,
 					this.moduleRef.BasePacketSize * this.moduleRef.MaxDataFactor
 				);
 			}
+			else
+			{
+				if (this.CurrentLinkSqrDistance > this.NominalLinkSqrDistance)
+				{
+					this.moduleRef.PacketSize = this.moduleRef.BasePacketSize;
+					this.moduleRef.PacketResourceCost = this.moduleRef.BasePacketResourceCost / rangeFactor;
+				}
+				else
+				{
+					this.moduleRef.PacketSize = Mathf.Min(
+						this.moduleRef.BasePacketSize * rangeFactor,
+						this.moduleRef.BasePacketSize * this.moduleRef.MaxDataFactor
+					);
+					this.moduleRef.PacketResourceCost = this.moduleRef.BasePacketResourceCost;
+				}
+			}
 
 			this.moduleRef.PacketSize *= this.moduleRef.PacketThrottle / 100f;
-
-			if (ARConfiguration.FixedPowerCost || this.CurrentLinkSqrDistance <= this.NominalLinkSqrDistance)
-			{
-				this.moduleRef.PacketResourceCost = this.moduleRef.BasePacketResourceCost;
+			this.moduleRef.PacketResourceCost *= this.moduleRef.PacketThrottle / 100f;
+		}
+
+		public double GetPotentialLinkCost(double currentSqrDistance, double nominalSqrDistance)
+		{
+			double cost;
+
+			float rangeFactor = (float)(nominalSqrDistance / currentSqrDistance);
+
+			if (ARConfiguration.FixedPowerCost || currentSqrDistance <= NominalLinkSqrDistance)
+			{
+				cost = this.moduleRef.BasePacketResourceCost;
 			}
 			else
 			{
-				float rangeFactor = (float)(this.CurrentLinkSqrDistance / this.NominalLinkSqrDistance);
-
-				this.moduleRef.PacketResourceCost = this.moduleRef.BasePacketResourceCost * rangeFactor;
-			}
-
-			this.moduleRef.PacketResourceCost *= this.moduleRef.PacketThrottle / 100f;
+				cost = this.moduleRef.BasePacketResourceCost / rangeFactor;
+			}
+
+			cost *= this.moduleRef.PacketThrottle / 100f;
+
+			return cost;
+		}
+
+		public double GetPotentialLinkCost(IAntennaRelay potentialTarget)
+		{
+			if (potentialTarget == null)
+			{
+				return double.PositiveInfinity;
+			}
+
+			double nominalSqrDistance;
+			if (ARConfiguration.UseAdditiveRanges)
+			{
+				nominalSqrDistance = this.nominalTransmitDistance * potentialTarget.nominalTransmitDistance;
+			}
+			else
+			{
+				nominalSqrDistance = this.nominalTransmitDistance * this.nominalTransmitDistance;
+			}
+
+			double currentSqrDistance = this.SqrDistanceTo(potentialTarget);
+
+			return GetPotentialLinkCost(currentSqrDistance, nominalSqrDistance);
+		}
+
+		public double GetPotentialLinkCost(CelestialBody body)
+		{
+			if (body == null || body != Kerbin)
+			{
+				return double.PositiveInfinity;
+			}
+
+			double nominalSqrDistance;
+			if (ARConfiguration.UseAdditiveRanges)
+			{
+				nominalSqrDistance = this.nominalTransmitDistance * ARConfiguration.KerbinNominalRange;
+			}
+			else
+			{
+				nominalSqrDistance = this.nominalTransmitDistance * this.nominalTransmitDistance;
+			}
+
+			double currentSqrDistance = this.SqrDistanceTo(body);
+
+			return GetPotentialLinkCost(currentSqrDistance, nominalSqrDistance);
 		}
 
 		/// <summary>
@@ -344,15 +442,12 @@
 			CelestialBody bodyOccludingBestOccludedRelay = null;
 			IAntennaRelay needle;
 
-			double nearestRelaySqrQuotient = double.PositiveInfinity;
-			double bestOccludedSqrQuotient = double.PositiveInfinity;
-
-			double potentialSqrDistance;
-			double maxLinkSqrDistance;
-			double potentialSqrQuotient;
-
-			double kerbinSqrDistance;
-			double kerbinSqrQuotient;
+			double cheapestRelayRate = double.PositiveInfinity;
+			double cheapestOccludedRelayRate = double.PositiveInfinity;
+
+			double potentialRelayRate;
+
+			double kerbinRelayRate = this.GetPotentialLinkCost(Kerbin);
 
 			bool isCircular;
 			int iterCount;
@@ -407,24 +502,8 @@
 				#endif
 
 				// Find the distance from here to the vessel...
-				log.Append("\n\tgetting distance to potential vessel");
-				potentialSqrDistance = this.SqrDistanceTo(potentialBestRelay);
-				log.Append("\n\tgetting best vessel relay");
-
-				log.Append("\n\tgetting max link distance to potential relay");
-
-				if (ARConfiguration.UseAdditiveRanges)
-				{
-					maxLinkSqrDistance = this.maxTransmitDistance * potentialBestRelay.maxTransmitDistance;
-				}
-				else
-				{
-					maxLinkSqrDistance = this.maxTransmitDistance * this.maxTransmitDistance;
-				}
-
-				log.AppendFormat("\n\tmax link distance: {0}", maxLinkSqrDistance);
-
-				potentialSqrQuotient = potentialSqrDistance / maxLinkSqrDistance;
+				log.Append("\n\tgetting cost to potential vessel");
+				potentialRelayRate = potentialBestRelay.CurrentNetworkResourceRate + this.GetPotentialLinkCost(potentialBestRelay);
 
 				#if BENCH
 				startLOSVesselTicks = performanceTimer.ElapsedTicks;
@@ -452,22 +531,21 @@
 					log.AppendFormat("\n\t\t\t{0}: Relay {1} not in line of sight.",
 						this.ToString(), potentialBestRelay);
 					
-					log.AppendFormat("\n\t\t\tpotentialSqrDistance: {0}", potentialSqrDistance);
-					log.AppendFormat("\n\t\t\tbestOccludedSqrQuotient: {0}", bestOccludedSqrQuotient);
-					log.AppendFormat("\n\t\t\tmaxTransmitSqrDistance: {0}", maxLinkSqrDistance);
+					log.AppendFormat("\n\t\t\tpotentialRelayRate: {0}", potentialRelayRate);
+					log.AppendFormat("\n\t\t\tcheapestOccludedRelayRate: {0}", cheapestOccludedRelayRate);
 
 					if (
-						(potentialSqrQuotient < bestOccludedSqrQuotient) &&
-						(potentialSqrQuotient <= 1d) &&
+						(potentialRelayRate < cheapestRelayRate) &&
+						this.IsInRangeOf(potentialBestRelay) &&
 						potentialBestRelay.CanTransmit()
 					)
 					{
-						log.Append("\n\t\t...vessel is close enough to and potentialBestRelay can transmit");
+						log.Append("\n\t\t...vessel is cheapest and close enough and potentialBestRelay can transmit");
 						log.AppendFormat("\n\t\t...{0} found new best occluded relay {1}", this, potentialBestRelay);
 
 						this.bestOccludedRelay = potentialBestRelay;
 						bodyOccludingBestOccludedRelay = fob;
-						bestOccludedSqrQuotient = potentialSqrQuotient;
+						cheapestOccludedRelayRate = potentialRelayRate;
 					}
 					else
 					{
@@ -494,10 +572,10 @@
 				/*
 				 * ...so that we can skip the vessel if it is further away than a vessel we've already checked.
 				 * */
-				if (potentialSqrQuotient > nearestRelaySqrQuotient)
+				if (potentialRelayRate > cheapestRelayRate)
 				{
 					
-					log.AppendFormat("\n\t{0}: Relay {1} discarded because it is farther than another the nearest relay.",
+					log.AppendFormat("\n\t{0}: Relay {1} discarded because it is more expensive than another the nearest relay.",
 						this.ToString(),
 						potentialBestRelay
 					);
@@ -563,13 +641,13 @@
 
 					if (!isCircular)
 					{
-						nearestRelaySqrQuotient = potentialSqrQuotient;
+						cheapestRelayRate = potentialRelayRate;
 						this.nearestRelay = potentialBestRelay;
 
-						log.AppendFormat("\n\t{0}: found new nearest relay {1} ({2}m²)",
+						log.AppendFormat("\n\t{0}: found new cheapest relay {1} ({2} EC/MiT)",
 							this.ToString(),
 							this.nearestRelay.ToString(),
-							Math.Sqrt(nearestRelaySqrQuotient)
+							Math.Sqrt(cheapestRelayRate)
 						);
 					}
 					else
@@ -597,30 +675,16 @@
 			#endif
 
 			CelestialBody bodyOccludingKerbin = null;
-
-			kerbinSqrDistance = this.vessel.DistanceTo(Kerbin) - Kerbin.Radius;
-			kerbinSqrDistance *= kerbinSqrDistance;
-
-			if (ARConfiguration.UseAdditiveRanges)
-			{
-				kerbinSqrQuotient = kerbinSqrDistance /
-					(this.maxTransmitDistance * ARConfiguration.KerbinRelayRange);
-			}
-			else
-			{
-				kerbinSqrQuotient = kerbinSqrDistance /
-					(this.maxTransmitDistance * this.maxTransmitDistance);
-			}
 
 			log.AppendFormat("\n{0} ({1}): Search done, figuring status.", this.ToString(), this.GetType().Name);
 			log.AppendFormat(
 				"\n{0}: nearestRelay={1} ({2})), bestOccludedRelay={3} ({4}), kerbinSqrDistance={5}m²)",
 				this,
 				this.nearestRelay == null ? "null" : this.nearestRelay.ToString(),
-				nearestRelaySqrQuotient,
+				cheapestRelayRate,
 				this.bestOccludedRelay == null ? "null" : this.bestOccludedRelay.ToString(),
-				bestOccludedSqrQuotient,
-				kerbinSqrDistance
+				cheapestOccludedRelayRate,
+				kerbinRelayRate
 			);
 			
 			#if BENCH
@@ -638,13 +702,12 @@
 				#endif
 				log.AppendFormat("\n\tKerbin LOS is blocked by {0}.", bodyOccludingKerbin.bodyName);
 
-				// nearestRelaySqrDistance will be infinity if all relays are occluded or none exist.
-				// Therefore, this will only be true if a valid relay is in range.
-				if (nearestRelaySqrQuotient <= 1d)
-				{
-					log.AppendFormat("\n\t\tCan transmit to nearby relay {0} ({1} <= {2}).",
-						this.nearestRelay == null ? "null" : this.nearestRelay.ToString(),
-						nearestRelaySqrQuotient, 1d);
+				// If we're in range of the "nearest" (actually cheapest) relay, use it.
+				if (this.IsInRangeOf(this.nearestRelay))
+				{
+					log.AppendFormat("\n\t\tCan transmit to nearby relay {0}).",
+						this.nearestRelay == null ? "null" : this.nearestRelay.ToString()
+					);
 
 					this.KerbinDirect = false;
 					this.canTransmit = true;
@@ -653,27 +716,27 @@
 				// If this isn't true, we can't transmit, but pick a second best of bestOccludedRelay and Kerbin anyway
 				else
 				{
-					log.AppendFormat("\n\t\tCan't transmit to nearby relay {0} ({1} > {2}).",
-						this.nearestRelay == null ? "null" : this.nearestRelay.ToString(),
-						nearestRelaySqrQuotient, 1d);
+					log.AppendFormat("\n\t\tCan't transmit to nearby relay {0}.",
+						this.nearestRelay == null ? "null" : this.nearestRelay.ToString()
+					);
 
 					this.canTransmit = false;
 
-					// If the best occluded relay is closer than Kerbin, check it against the nearest relay.
-					// Since bestOccludedSqrDistance is infinity if there are no occluded relays, this is safe
-					if (bestOccludedSqrQuotient < kerbinSqrQuotient)
-					{
-						log.AppendFormat("\n\t\t\tBest occluded relay is closer than Kerbin ({0} < {1})",
-							bestOccludedRelay, kerbinSqrDistance);
+					// If the best occluded relay is cheaper than Kerbin, check it against the nearest relay.
+					// Since cheapestOccludedRelayRate is infinity if there are no occluded relays, this is safe
+					if (cheapestOccludedRelayRate < kerbinRelayRate)
+					{
+						log.AppendFormat("\n\t\t\tBest occluded relay is cheaper than Kerbin ({0} < {1})",
+							cheapestOccludedRelayRate, kerbinRelayRate);
 						
 						this.KerbinDirect = false;
 
-						// If the nearest relay is closer than the best occluded relay, pick it.
-						// Since nearestRelaySqrDistane is infinity if there are no nearby relays, this is safe.
-						if (nearestRelaySqrQuotient < bestOccludedSqrQuotient)
+						// If the nearest relay is cheaper than the best occluded relay, pick it.
+						// Since cheapestRelayRate is infinity if there are no nearby relays, this is safe.
+						if (cheapestRelayRate < cheapestOccludedRelayRate)
 						{
-							log.AppendFormat("\n\t\t\t\t...but the nearest relay is closer ({0} < {1}), so picking it.",
-								nearestRelaySqrQuotient, bestOccludedSqrQuotient);
+							log.AppendFormat("\n\t\t\t\t...but the nearest relay is cheaper ({0} < {1}), so picking it.",
+								cheapestRelayRate, cheapestOccludedRelayRate);
 							
 							this.targetRelay = this.nearestRelay;
 							this.firstOccludingBody = null;
@@ -681,36 +744,37 @@
 						// Otherwise, target the best occluded relay.
 						else
 						{
-							log.AppendFormat("\n\t\t\t\t...and closer than the nearest relay ({0} >= {1}), so picking it.",
-								nearestRelaySqrQuotient, bestOccludedSqrQuotient);
+							log.AppendFormat("\n\t\t\t\t...and cheaper than the nearest relay ({0} >= {1}), so picking it.",
+								cheapestRelayRate, cheapestOccludedRelayRate);
 							
 							this.targetRelay = bestOccludedRelay;
 							this.firstOccludingBody = bodyOccludingBestOccludedRelay;
 						}
 					}
-					// Otherwise, check Kerbin against the nearest relay.
-					// Since we have LOS, blank the first occluding body.
+					// Otherwise, check Kerbin against the "nearest" (cheapest) relay.
 					else
 					{
-						log.AppendFormat("\n\t\t\tKerbin is closer than the best occluded relay ({0} >= {1})",
-							bestOccludedRelay, kerbinSqrDistance);
+						log.AppendFormat("\n\t\t\tKerbin is cheaper than the best occluded relay ({0} >= {1})",
+							cheapestOccludedRelayRate, kerbinRelayRate);
 						
-						// If the nearest relay is closer than Kerbin, pick it.
-						// Since nearestRelaySqrDistane is infinity if there are no nearby relays, this is safe.
-						if (nearestRelaySqrQuotient < kerbinSqrQuotient)
+						// If the "nearest" (cheapest) relay is cheaper than Kerbin, pick it.
+						// Since cheapestRelayRate is infinity if there are no nearby relays, this is safe.
+						if (cheapestRelayRate < kerbinRelayRate)
 						{
-							log.AppendFormat("\n\t\t\t\t...but the nearest relay is closer ({0} < {1}), so picking it.",
-								nearestRelaySqrQuotient, kerbinSqrQuotient);
-							
+							log.AppendFormat("\n\t\t\t\t...but the nearest relay is cheaper ({0} < {1}), so picking it.",
+								cheapestRelayRate, kerbinRelayRate);
+
+							// Since we have LOS, blank the first occluding body.
+							this.firstOccludingBody = null;
+
 							this.KerbinDirect = false;
-							this.firstOccludingBody = null;
 							this.targetRelay = this.nearestRelay;
 						}
 						// Otherwise, pick Kerbin.
 						else
 						{
-							log.AppendFormat("\n\t\t\t\t...and closer than the nearest relay ({0} >= {1}), so picking it.",
-								nearestRelaySqrQuotient, kerbinSqrQuotient);
+							log.AppendFormat("\n\t\t\t\t...and cheaper than the nearest relay ({0} >= {1}), so picking it.",
+								cheapestRelayRate, kerbinRelayRate);
 							
 							this.KerbinDirect = true;
 							this.firstOccludingBody = bodyOccludingKerbin;
@@ -728,21 +792,21 @@
 
 				log.AppendFormat("\n\tKerbin is in LOS.");
 
-				// If the nearest relay is closer than Kerbin and in range, transmit to it.
-				if (nearestRelaySqrQuotient <= 1d)
-				{
-					log.AppendFormat("\n\t\tCan transmit to nearby relay {0} ({1} <= {2}).",
-						this.nearestRelay == null ? "null" : this.nearestRelay.ToString(),
-						nearestRelaySqrQuotient, 1d);
+				// If the nearest relay is in range, we can transmit.
+				if (this.IsInRangeOf(this.nearestRelay))
+				{
+					log.AppendFormat("\n\t\tCan transmit to nearby relay {0} (in range).",
+						this.nearestRelay == null ? "null" : this.nearestRelay.ToString()
+					);
 
 					this.canTransmit = true;
 
 					// If the nearestRelay is closer than Kerbin, use it.
-					if (nearestRelaySqrQuotient < kerbinSqrQuotient)
+					if (cheapestRelayRate < kerbinRelayRate)
 					{
 						log.AppendFormat("\n\t\t\tPicking relay {0} over Kerbin ({1} < {2}).",
 							this.nearestRelay == null ? "null" : this.nearestRelay.ToString(),
-							nearestRelaySqrQuotient, kerbinSqrQuotient);
+							cheapestRelayRate, kerbinRelayRate);
 
 						this.KerbinDirect = false;
 						this.targetRelay = this.nearestRelay;
@@ -752,7 +816,7 @@
 					{
 						log.AppendFormat("\n\t\t\tBut picking Kerbin over nearby relay {0} ({1} >= {2}).",
 							this.nearestRelay == null ? "null" : this.nearestRelay.ToString(),
-							nearestRelaySqrQuotient, kerbinSqrQuotient);
+							cheapestRelayRate, kerbinRelayRate);
 
 						this.KerbinDirect = true;
 						this.targetRelay = null;
@@ -761,15 +825,14 @@
 				// If the nearest relay is out of range, we still need to check on Kerbin.
 				else
 				{
-					log.AppendFormat("\n\t\tCan't transmit to nearby relay {0} ({1} > {2}).",
-						this.nearestRelay == null ? "null" : this.nearestRelay.ToString(),
-							nearestRelaySqrQuotient, 1d);
+					log.AppendFormat("\n\t\tCheapest relay {0} is out of range.",
+						this.nearestRelay == null ? "null" : this.nearestRelay.ToString()
+					);
 
 					// If Kerbin is in range, use it.
-					if (kerbinSqrQuotient <= 1d)
-					{
-						log.AppendFormat("\n\t\t\tCan transmit to Kerbin ({0} <= {1}).",
-							kerbinSqrQuotient, 1d);
+					if (this.IsInRangeOf(Kerbin))
+					{
+						log.AppendFormat("\n\t\t\tCan transmit to Kerbin (in range).");
 
 						this.canTransmit = true;
 						this.KerbinDirect = true;
@@ -779,26 +842,25 @@
 					// Kerbin and bestOccludedRelay
 					else
 					{
-						log.AppendFormat("\n\t\t\tCan't transmit to Kerbin ({0} > {1}).",
-								kerbinSqrQuotient, 1d);
+						log.AppendFormat("\n\t\t\tCan't transmit to Kerbin (out of range).");
 
 						this.canTransmit = false;
 
-						// If the best occluded relay is closer than Kerbin, check it against the nearest relay.
+						// If the best occluded relay is cheaper than Kerbin, check it against the nearest relay.
 						// Since bestOccludedSqrDistance is infinity if there are no occluded relays, this is safe
-						if (bestOccludedSqrQuotient < kerbinSqrQuotient)
+						if (cheapestOccludedRelayRate < kerbinRelayRate)
 						{
 							log.AppendFormat("\n\t\t\tBest occluded relay is closer than Kerbin ({0} < {1})",
-								bestOccludedRelay, kerbinSqrDistance);
+								cheapestOccludedRelayRate, kerbinRelayRate);
 							
 							this.KerbinDirect = false;
 
 							// If the nearest relay is closer than the best occluded relay, pick it.
-							// Since nearestRelaySqrDistane is infinity if there are no nearby relays, this is safe.
-							if (nearestRelaySqrQuotient < bestOccludedSqrQuotient)
+							// Since cheapestRelayRate is infinity if there are no nearby relays, this is safe.
+							if (cheapestRelayRate < cheapestOccludedRelayRate)
 							{
-								log.AppendFormat("\n\t\t\t\t...but the nearest relay is closer ({0} < {1}), so picking it.",
-									nearestRelaySqrQuotient, bestOccludedSqrQuotient);
+								log.AppendFormat("\n\t\t\t\t...but the nearest relay is cheaper ({0} < {1}), so picking it.",
+									cheapestRelayRate, cheapestOccludedRelayRate);
 								
 								this.targetRelay = this.nearestRelay;
 								this.firstOccludingBody = null;
@@ -806,8 +868,8 @@
 							// Otherwise, target the best occluded relay.
 							else
 							{
-								log.AppendFormat("\n\t\t\t\t...and closer than the nearest relay ({0} >= {1}), so picking it.",
-									nearestRelaySqrQuotient, bestOccludedSqrQuotient);
+								log.AppendFormat("\n\t\t\t\t...and cheaper than the nearest relay ({0} >= {1}), so picking it.",
+									cheapestRelayRate, cheapestOccludedRelayRate);
 								
 								this.targetRelay = bestOccludedRelay;
 								this.firstOccludingBody = bodyOccludingBestOccludedRelay;
@@ -817,17 +879,17 @@
 						// Since we have LOS, blank the first occluding body.
 						else
 						{
-							log.AppendFormat("\n\t\t\tKerbin is closer than the best occluded relay ({0} >= {1})",
-								bestOccludedRelay, kerbinSqrDistance);
+							log.AppendFormat("\n\t\t\tKerbin is cheaper than the best occluded relay ({0} >= {1})",
+								cheapestOccludedRelayRate, kerbinRelayRate);
 							
 							this.firstOccludingBody = null;
 
-							// If the nearest relay is closer than Kerbin, pick it.
-							// Since nearestRelaySqrDistane is infinity if there are no nearby relays, this is safe.
-							if (nearestRelaySqrQuotient < kerbinSqrQuotient)
+							// If the nearest relay is cheaper than Kerbin, pick it.
+							// Since cheapestRelayRate is infinity if there are no nearby relays, this is safe.
+							if (cheapestRelayRate < kerbinRelayRate)
 							{
-								log.AppendFormat("\n\t\t\t\t...but the nearest relay is closer ({0} < {1}), so picking it.",
-									nearestRelaySqrQuotient, kerbinSqrQuotient);
+								log.AppendFormat("\n\t\t\t\t...but the nearest relay is cheaper ({0} < {1}), so picking it.",
+									cheapestRelayRate, kerbinRelayRate);
 								
 								this.KerbinDirect = false;
 								this.targetRelay = this.nearestRelay;
@@ -835,8 +897,8 @@
 							// Otherwise, pick Kerbin.
 							else
 							{
-								log.AppendFormat("\n\t\t\t\t...and closer than the nearest relay ({0} >= {1}), so picking it.",
-									nearestRelaySqrQuotient, kerbinSqrQuotient);
+								log.AppendFormat("\n\t\t\t\t...and cheaper than the nearest relay ({0} >= {1}), so picking it.",
+									cheapestRelayRate, kerbinRelayRate);
 								
 								this.KerbinDirect = true;
 								this.targetRelay = null;

--- a/GameData/AntennaRange/AntennaRange.cfg
+++ b/GameData/AntennaRange/AntennaRange.cfg
@@ -39,6 +39,8 @@
 
 @PART[longAntenna]:FOR[AntennaRange]:NEEDS[!RemoteTech]
 {
+	@TechRequired = start
+
 	@MODULE[ModuleDataTransmitter]
 	{
 		@name = ModuleLimitedDataTransmitter

--- a/IAntennaRelay.cs
+++ b/IAntennaRelay.cs
@@ -59,6 +59,18 @@
 		float MaxDataFactor { get; }
 
 		/// <summary>
+		/// Gets the data resource cost in EC/MiT.
+		/// </summary>
+		/// <value>The data resource cost in EC/MiT.</value>
+		double DataResourceCost { get; }
+
+		/// <summary>
+		/// Gets the current network resource rate in EC/MiT.
+		/// </summary>
+		/// <value>The current network resource rate in EC/MiT.</value>
+		double CurrentNetworkResourceRate { get; }
+
+		/// <summary>
 		/// Gets a value indicating whether this <see cref="AntennaRange.IAntennaRelay"/> Relay is communicating
 		/// directly with Kerbin.
 		/// </summary>
@@ -111,6 +123,11 @@
 		bool CanTransmit();
 
 		/// <summary>
+		/// Recalculates the transmission rates.
+		/// </summary>
+		void RecalculateTransmissionRates();
+
+		/// <summary>
 		/// Finds the nearest relay.
 		/// </summary>
 		void FindNearestRelay();

--- a/ModuleLimitedDataTransmitter.cs
+++ b/ModuleLimitedDataTransmitter.cs
@@ -56,12 +56,6 @@
 		private static GUIStyle partTooltipBodyStyle;
 		private static GUIStyle partTooltipHeaderStyle;
 
-		// Stores the packetResourceCost as defined in the .cfg file.
-		private float _basepacketResourceCost;
-
-		// Stores the packetSize as defined in the .cfg file.
-		private float _basepacketSize;
-
 		// Every antenna is a relay.
 		private AntennaRelay relay;
 
@@ -184,7 +178,7 @@
 				else
 				{
 					this.LogError("Vessel and/or part reference are null, returning null vessel.");
-					#if DEBUG
+					#if DEBUG && VERBOSE
 					this.LogError(new System.Diagnostics.StackTrace().ToString());
 					#endif
 					return null;
@@ -206,10 +200,8 @@
 
 		public float BasePacketSize
 		{
-			get
-			{
-				return this._basepacketSize;
-			}
+			get;
+			private set;
 		}
 
 		public float PacketResourceCost
@@ -226,10 +218,8 @@
 
 		public float BasePacketResourceCost
 		{
-			get
-			{
-				return this._basepacketResourceCost;
-			}
+			get;
+			private set;
 		}
 
 		public float PacketThrottle
@@ -326,6 +316,23 @@
 				}
 
 				return this.relay.CurrentLinkSqrDistance;
+			}
+		}
+
+		/// <summary>
+		/// Gets the current link resource rate in EC/MiT.
+		/// </summary>
+		/// <value>The current link resource rate in EC/MiT.</value>
+		public double CurrentLinkResourceRate
+		{
+			get
+			{
+				if (this.relay == null)
+				{
+					return double.PositiveInfinity;
+				}
+
+				return this.relay.CurrentLinkResourceRate;
 			}
 		}
 
@@ -417,19 +424,12 @@
 		{
 			get
 			{
-				if (this.relay != null)
-				{
-					this.relay.RecalculateTransmissionRates();
-				}
-
-				if (this.CanTransmit())
-				{
-					return this.packetSize;
-				}
-				else
-				{
-					return float.Epsilon;
-				}
+				if (this.relay == null)
+				{
+					return float.PositiveInfinity;
+				}
+
+				return this.relay.DataRate;
 			}
 		}
 
@@ -441,16 +441,25 @@
 		{
 			get
 			{
-				this.relay.RecalculateTransmissionRates();
-
-				if (this.CanTransmit())
-				{
-					return this.packetResourceCost;
-				}
-				else
-				{
-					return float.PositiveInfinity;
-				}
+				if (this.relay == null)
+				{
+					return double.PositiveInfinity;
+				}
+
+				return this.relay.DataResourceCost;
+			}
+		}
+
+		public double CurrentNetworkResourceRate
+		{
+			get
+			{
+				if (this.relay == null)
+				{
+					return double.PositiveInfinity;
+				}
+
+				return this.relay.CurrentNetworkResourceRate;
 			}
 		}
 
@@ -487,8 +496,8 @@
 		{
 			base.OnAwake();
 
-			this._basepacketSize = base.packetSize;
-			this._basepacketResourceCost = base.packetResourceCost;
+			this.BasePacketSize = base.packetSize;
+			this.BasePacketResourceCost = base.packetResourceCost;
 			this.moduleInfoContent = new GUIContent();
 
 			this.LogDebug("{0} loaded:\n" +
@@ -499,7 +508,7 @@
 				"maxDataFactor: {5}\n",
 				this,
 				base.packetSize,
-				this._basepacketResourceCost,
+				this.BasePacketResourceCost,
 				this.nominalTransmitDistance,
 				this.maxPowerFactor,
 				this.maxDataFactor
@@ -682,6 +691,14 @@
 			return this.relay.CanTransmit();
 		}
 
+		public void RecalculateTransmissionRates()
+		{
+			if (this.relay != null)
+			{
+				this.relay.RecalculateTransmissionRates();
+			}
+		}
+
 		/// <summary>
 		/// Finds the nearest relay.
 		/// </summary>
@@ -704,9 +721,6 @@
 				"TransmitData(List<ScienceData> dataQueue, Callback callback) called.  dataQueue.Count={0}",
 				dataQueue.Count
 			);
-			this.relay.RecalculateTransmissionRates();
-
-			this.FindNearestRelay();
 
 			if (this.CanTransmit())
 			{
@@ -815,10 +829,6 @@
 		/// </summary>
 		public new void StartTransmission()
 		{
-			this.FindNearestRelay();
-
-			this.relay.RecalculateTransmissionRates();
-
 			this.LogDebug(
 				"distance: " + this.CurrentLinkSqrDistance
 				+ " packetSize: " + this.packetSize
@@ -1013,8 +1023,8 @@
 		[KSPEvent (guiName = "Show Debug Info", active = true, guiActive = true)]
 		public void DebugInfo()
 		{
-			PreTransmit_SetPacketSize ();
-			PreTransmit_SetPacketResourceCost ();
+			if (this.relay != null)
+				this.relay.RecalculateTransmissionRates();
 
 			DebugPartModule.DumpClassObject(this);
 		}

--- a/RelayExtensions.cs
+++ b/RelayExtensions.cs
@@ -141,6 +141,56 @@
 		public static double SqrDistanceTo(this AntennaRelay relayOne, IAntennaRelay relayTwo)
 		{
 			return relayOne.vessel.sqrDistanceTo(relayTwo.vessel);
+		}
+
+		public static double MaxLinkSqrDistanceTo(this AntennaRelay relayOne, IAntennaRelay relayTwo)
+		{
+			if (ARConfiguration.UseAdditiveRanges)
+			{
+				return relayOne.maxTransmitDistance * relayTwo.maxTransmitDistance;
+			}
+			else
+			{
+				return relayOne.maxTransmitDistance * relayOne.maxTransmitDistance;
+			}
+		}
+
+		public static double MaxLinkSqrDistanceTo(this AntennaRelay relayOne, CelestialBody body)
+		{
+			if (body != AntennaRelay.Kerbin)
+			{
+				return 0d;
+			}
+
+			if (ARConfiguration.UseAdditiveRanges)
+			{
+				return relayOne.maxTransmitDistance * ARConfiguration.KerbinRelayRange;
+			}
+			else
+			{
+				return relayOne.maxTransmitDistance * relayOne.maxTransmitDistance;
+			}
+		}
+
+		public static bool IsInRangeOf(this AntennaRelay relayOne, IAntennaRelay relayTwo)
+		{
+			if (relayOne == null || relayTwo == null)
+			{
+				return false;
+			}
+
+			return relayOne.SqrDistanceTo(relayTwo) <= relayOne.MaxLinkSqrDistanceTo(relayTwo);
+		}
+
+
+		public static bool IsInRangeOf(this AntennaRelay relayOne, CelestialBody body)
+		{
+			if (relayOne == null || body == null)
+			{
+				return false;
+			}
+
+			return relayOne.SqrDistanceTo(body) <= relayOne.MaxLinkSqrDistanceTo(body);
 		}
 
 		/// <summary>