ModuleLimitedDataTransmitter: Manually calculating the right maximum range for tooltips, to get around the un-configured prefab state.
ModuleLimitedDataTransmitter: Manually calculating the right maximum range for tooltips, to get around the un-configured prefab state.

--- a/ARConfiguration.cs
+++ b/ARConfiguration.cs
@@ -145,13 +145,12 @@
 
 		public void Awake()
 		{
-			Tools.PostDebugMessage(this, "Waking up.");
+			this.LogDebug("Waking up.");
 
 			this.runningVersion = this.GetType().Assembly.GetName().Version;
 
 			this.showConfigWindow = false;
 			this.configWindowPos = new Rect(Screen.width / 4, Screen.height / 2, 180, 15);
-
 
 			this.configWindowPos = this.LoadConfigValue(WINDOW_POS_KEY, this.configWindowPos);
 
@@ -215,7 +214,7 @@
 
 			this.runOnce = true;
 
-			Tools.PostDebugMessage(this, "Awake.");
+			this.LogDebug("Awake.");
 		}
 
 		public void Update()
@@ -238,7 +237,7 @@
 			{
 				if (this.toolbarButton == null)
 				{
-					Tools.PostDebugMessage(this, "Toolbar available; initializing toolbar button.");
+					this.LogDebug("Toolbar available; initializing toolbar button.");
 
 					this.toolbarButton = ToolbarManager.Instance.add("AntennaRange", "ARConfiguration");
 					this.toolbarButton.Visibility = new GameScenesVisibility(GameScenes.SPACECENTER);
@@ -253,7 +252,7 @@
 			}
 			else if (this.appLauncherButton == null && ApplicationLauncher.Ready)
 			{
-				Tools.PostDebugMessage(this, "Toolbar available; initializing AppLauncher button.");
+				this.LogDebug("Toolbar available; initializing AppLauncher button.");
 
 				this.appLauncherButton = ApplicationLauncher.Instance.AddModApplication(
 					this.toggleConfigWindow,
@@ -439,8 +438,6 @@
 			{
 				tsLevel = ScenarioUpgradeableFacilities.protoUpgradeables["SpaceCenter/TrackingStation"]
 					.facilityRefs[0].FacilityLevel;
-			
-
 			}
 			else
 			{

--- a/ARMapRenderer.cs
+++ b/ARMapRenderer.cs
@@ -75,9 +75,7 @@
 
 					lr = obj.AddComponent<LineRenderer>();
 
-					// lr.SetColors(Color.green, Color.green);
 					lr.material = MapView.OrbitLinesMaterial;
-					// lr.SetVertexCount(2);
 
 					this.vesselLineRenderers[idx] = lr;
 

--- a/AntennaRelay.cs
+++ b/AntennaRelay.cs
@@ -264,12 +264,10 @@
 			this.KerbinDirect = true;
 
 			/*
-			 * Loop through all the vessels and exclude this vessel, vessels of the wrong type, and vessels that are too
-			 * far away.  When we find a candidate, get through its antennae for relays which have not been checked yet
-			 * and that can transmit.  Once we find a suitable candidate, assign it to nearestRelay for comparison
-			 * against future finds.
+			 * Loop through the useful relays as determined by ARFlightController and check each for line of sight and
+			 * distance, searching for the relay with the best distance/maxRange ratio that is in sight, in range, and
+			 * can transmit, also stashing the "best" relay outside of line of sight for failure report.
 			 * */
-			// Vessel potentialVessel;
 			IAntennaRelay potentialBestRelay;
 			CelestialBody fob;
 

--- a/GameData/AntennaRange/AntennaRange.cfg
+++ b/GameData/AntennaRange/AntennaRange.cfg
@@ -64,7 +64,7 @@
 	@MODULE[ModuleDataTransmitter]
 	{
 		@name = ModuleLimitedDataTransmitter
-		nominalRange = 3500000000
+		nominalRange = 3150000000
 		simpleRange = 18000000000
 		maxPowerFactor = 4
 		maxDataFactor = 8
@@ -87,7 +87,7 @@
 	{
 		@name = ModuleLimitedDataTransmitter
 		@packetResourceCost /= 1.414213
-		nominalRange = 10000000000
+		nominalRange = 9250000000
 		simpleRange = 56250000000
 		maxPowerFactor = 16
 		maxDataFactor = 2
@@ -108,7 +108,7 @@
 {
 	range = 800000
 	range = 200000000000
-	range = 2250000000000
+	range = 2000000000000
 }
 
 EVA_MODULE
@@ -116,6 +116,7 @@
 	name = ModuleLimitedDataTransmitter
 
 	nominalRange = 1389
+	simpleRange = 5000
 	maxPowerFactor = 1
 	maxDataFactor = 1
 

--- a/ModuleLimitedDataTransmitter.cs
+++ b/ModuleLimitedDataTransmitter.cs
@@ -46,7 +46,8 @@
 	/// 
 	/// <para>where D is the total transmission distance, P is the transmission power, and R is the data rate.</para>
 	/// </summary>
-	public class ModuleLimitedDataTransmitter : ModuleDataTransmitter, IScienceDataTransmitter, IAntennaRelay
+	public class ModuleLimitedDataTransmitter
+		: ModuleDataTransmitter, IScienceDataTransmitter, IAntennaRelay, IModuleInfo
 	{
 		// Stores the packetResourceCost as defined in the .cfg file.
 		private float _basepacketResourceCost;
@@ -59,6 +60,9 @@
 
 		// Sometimes we will need to communicate errors; this is how we do it.
 		private ScreenMessage ErrorMsg;
+
+		// Used in module info panes for part tooltips in the editor and R&D
+		private GUIContent moduleInfoContent;
 
 		/// <summary>
 		/// When additive ranges are enabled, the distance from Kerbin at which the antenna will perform exactly as
@@ -417,6 +421,7 @@
 
 			this._basepacketSize = base.packetSize;
 			this._basepacketResourceCost = base.packetResourceCost;
+			this.moduleInfoContent = new GUIContent();
 
 			Tools.PostDebugMessage(string.Format(
 				"{0} loaded:\n" +
@@ -442,10 +447,10 @@
 		{
 			base.OnStart (state);
 
+			this.maxTransmitDistance = Math.Sqrt(this.maxPowerFactor) * this.nominalTransmitDistance;
+
 			if (state >= StartState.PreLaunch)
 			{
-				this.maxTransmitDistance = Math.Sqrt(this.maxPowerFactor) * this.nominalTransmitDistance;
-
 				this.relay = new AntennaRelay(this);
 				this.relay.nominalTransmitDistance = this.nominalTransmitDistance;
 				this.relay.maxTransmitDistance = this.maxTransmitDistance;
@@ -474,6 +479,54 @@
 		}
 
 		/// <summary>
+		/// Gets the human-friendly module title.
+		/// </summary>
+		public string GetModuleTitle()
+		{
+			return "Comms Transceiver";
+		}
+
+		/// <summary>
+		/// Returns drawTooltipWidget as a callback for part tooltips.
+		/// </summary>
+		public Callback<Rect> GetDrawModulePanelCallback()
+		{
+			return this.drawTooltipWidget;
+		}
+
+		// Called by Squad's part tooltip system when drawing tooltips.
+		// HACK: Currently hacks around Squad's extraneous layout box, see KSPModders issue #5118
+		private void drawTooltipWidget(Rect rect)
+		{
+			this.moduleInfoContent.text = this.GetInfo();
+
+			GUIStyle style0 = PartListTooltips.fetch.tooltipSkin.customStyles[0];
+			GUIStyle style1 = PartListTooltips.fetch.tooltipSkin.customStyles[1];
+
+			float width = rect.width;
+			float orgHeight = rect.height;
+			float height = style0.CalcHeight(this.moduleInfoContent, width);
+
+			rect.height = height;
+
+			GUI.Box(rect, this.moduleInfoContent, style0);
+			GUI.Label(rect, this.GetModuleTitle(), style1);
+
+			GUILayout.Space(height - orgHeight
+				- style0.padding.bottom - style0.padding.top
+				- 2f * (style0.margin.bottom + style0.margin.top)
+			);
+		}
+
+		/// <summary>
+		/// Returns an empty string, because we don't really have a "primary field" like some modules do.
+		/// </summary>
+		public string GetPrimaryField()
+		{
+			return string.Empty;
+		}
+
+		/// <summary>
 		/// Override ModuleDataTransmitter.GetInfo to add nominal and maximum range to the VAB description.
 		/// </summary>
 		public override string GetInfo()
@@ -482,8 +535,24 @@
 			string text;
 
 			sb.Append(base.GetInfo());
-			sb.AppendFormat(Tools.SIFormatter, "Nominal Range: {0:S3}m\n", this.nominalTransmitDistance);
-			sb.AppendFormat(Tools.SIFormatter, "Maximum Range: {0:S3}m\n", this.maxTransmitDistance);
+
+			if (ARConfiguration.UseAdditiveRanges)
+			{
+				sb.AppendFormat(Tools.SIFormatter, "Nominal Range to Kerbin: {0:S3}m\n",
+					Math.Sqrt(this.nominalTransmitDistance * ARConfiguration.KerbinNominalRange)
+				);
+				sb.AppendFormat(Tools.SIFormatter, "Maximum Range to Kerbin: {0:S3}m",
+					Math.Sqrt(
+						this.nominalTransmitDistance * Math.Sqrt(this.maxPowerFactor) *
+						ARConfiguration.KerbinRelayRange
+					)
+				);
+			}
+			else
+			{
+				sb.AppendFormat(Tools.SIFormatter, "Nominal Range: {0:S3}m\n", this.nominalTransmitDistance);
+				sb.AppendFormat(Tools.SIFormatter, "Maximum Range: {0:S3}m", this.maxTransmitDistance);
+			}
 
 			text = sb.ToString();