Groundwork ahead of calculating power cost for network chains. Hasn't broken anything yet! exp
Groundwork ahead of calculating power cost for network chains. Hasn't broken anything yet!

--- a/ARConfiguration.cs
+++ b/ARConfiguration.cs
@@ -4,6 +4,7 @@
 // copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/
 
 using KSP;
+using KSP.UI.Screens;
 using System;
 using ToadicusTools.Extensions;
 using ToadicusTools.Text;

--- a/ARFlightController.cs
+++ b/ARFlightController.cs
@@ -29,6 +29,7 @@
 #pragma warning disable 1591
 
 using KSP;
+using KSP.UI.Screens;
 using System;
 using System.Collections.Generic;
 using ToadicusTools.Extensions;

--- a/ARMapRenderer.cs
+++ b/ARMapRenderer.cs
@@ -122,7 +122,7 @@
 				log.Clear();
 
 				log.AppendFormat("OnPreCull.\n");
-
+/* @ TODO: Fix
 				log.AppendFormat("\tMapView: Draw3DLines: {0}\n" +
 					"\tMapView.MapCamera.camera.fieldOfView: {1}\n" +
 					"\tMapView.MapCamera.Distance: {2}\n",
@@ -130,7 +130,7 @@
 					MapView.MapCamera.camera.fieldOfView,
 					MapView.MapCamera.Distance
 				);
-
+*/
 				log.AppendLine("FlightGlobals ready and Vessels list not null.");
 
 				IAntennaRelay relay;
@@ -213,20 +213,22 @@
 			}
 
 			LineRenderer renderer = this[relay.vessel.id];
-			Vector3d start = ScaledSpace.LocalToScaledSpace(relay.vessel.GetWorldPos3D());
+			Vector3 start = ScaledSpace.LocalToScaledSpace(relay.vessel.GetWorldPos3D());
 
 			float lineWidth;
 			float d = Screen.height / 2f + 0.01f;
 
 			if (MapView.Draw3DLines)
 			{
-				lineWidth = 0.005859375f * MapView.MapCamera.Distance;
+				lineWidth = 0.00833333333f * MapView.MapCamera.Distance;
 			}
 			else
 			{
-				lineWidth = 2f;
-
-				start = MapView.MapCamera.camera.WorldToScreenPoint(start);
+				lineWidth = 3f;
+
+				// TODO: No idea if this substitution is right.
+				// start = MapView.MapCamera.camera.WorldToScreenPoint(start);
+				start = PlanetariumCamera.Camera.WorldToScreenPoint(start);
 
 				start.z = start.z >= 0f ? d : -d;
 			}
@@ -241,7 +243,7 @@
 			relayStart = timer.ElapsedMilliseconds;
 			#endif
 
-			Vector3d nextPoint;
+			Vector3 nextPoint;
 
 			renderer.enabled = true;
 
@@ -296,7 +298,9 @@
 
 			if (!MapView.Draw3DLines)
 			{
-				nextPoint = MapView.MapCamera.camera.WorldToScreenPoint(nextPoint);
+				// TODO: No idea if this substitution is right.
+				// nextPoint = MapView.MapCamera.camera.WorldToScreenPoint(nextPoint);
+				nextPoint = PlanetariumCamera.Camera.WorldToScreenPoint(nextPoint);
 				nextPoint.z = nextPoint.z >= 0f ? d : -d;
 			}
 

--- a/AntennaRange.csproj
+++ b/AntennaRange.csproj
@@ -93,7 +93,12 @@
     </Reference>
     <Reference Include="UnityEngine">
       <HintPath>..\_KSPAssemblies\UnityEngine.dll</HintPath>
-      <Private>False</Private>
+    </Reference>
+    <Reference Include="KSPUtil">
+      <HintPath>..\_KSPAssemblies\KSPUtil.dll</HintPath>
+    </Reference>
+    <Reference Include="UnityEngine.UI">
+      <HintPath>..\_KSPAssemblies\UnityEngine.UI.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>

--- a/AntennaRelay.cs
+++ b/AntennaRelay.cs
@@ -30,6 +30,7 @@
 using System.Collections.Generic;
 using ToadicusTools.DebugTools;
 using ToadicusTools.Extensions;
+using UnityEngine;
 
 namespace AntennaRange
 {
@@ -183,6 +184,73 @@
 			get;
 			set;
 		}
+		/*
+		 * The next two functions overwrite the behavior of the stock functions and do not perform equivalently, except
+		 * in that they both return floats.  Here's some quick justification:
+		 * 
+		 * The stock implementation of GetTransmitterScore (which I cannot override) is:
+		 * 		Score = (1 + DataResourceCost) / DataRate
+		 * 
+		 * The stock DataRate and DataResourceCost are:
+		 * 		DataRate = packetSize / packetInterval
+		 * 		DataResourceCost = packetResourceCost / packetSize
+		 * 
+		 * So, the resulting score is essentially in terms of joules per byte per baud.  Rearranging that a bit, it
+		 * could also look like joule-seconds per byte per byte, or newton-meter-seconds per byte per byte.  Either way,
+		 * that metric is not a very reasonable one.
+		 * 
+		 * Two metrics that might make more sense are joules per byte or joules per byte per second.  The latter case
+		 * would look like:
+		 * 		DataRate = packetSize / packetInterval
+		 * 		DataResourceCost = packetResourceCost
+		 * 
+		 * The former case, which I've chosen to implement below, is:
+		 * 		DataRate = packetSize
+		 * 		DataResourceCost = packetResourceCost
+		 * 
+		 * So... hopefully that doesn't screw with anything else.
+		 * */
+		/// <summary>
+		/// Override ModuleDataTransmitter.DataRate to just return packetSize, because we want antennas to be scored in
+		/// terms of joules/byte
+		/// </summary>
+		public new float DataRate
+		{
+			get
+			{
+				this.RecalculateTransmissionRates();
+
+				if (this.CanTransmit())
+				{
+					return this.moduleRef.PacketSize;
+				}
+				else
+				{
+					return float.Epsilon;
+				}
+			}
+		}
+
+		/// <summary>
+		/// Override ModuleDataTransmitter.DataResourceCost to just return packetResourceCost, because we want antennas
+		/// to be scored in terms of joules/byte
+		/// </summary>
+		public new double DataResourceCost
+		{
+			get
+			{
+				this.RecalculateTransmissionRates();
+
+				if (this.CanTransmit())
+				{
+					return this.moduleRef.PacketResourceCost;
+				}
+				else
+				{
+					return float.PositiveInfinity;
+				}
+			}
+		}
 
 		/// <summary>
 		/// Determines whether this instance can transmit.
@@ -191,6 +259,40 @@
 		public virtual bool CanTransmit()
 		{
 			return this.canTransmit;
+		}
+
+		// Before transmission, set packetSize.  Per above, packet size increases with the inverse square of
+		// 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);
+
+				this.moduleRef.PacketSize = Mathf.Min(
+					this.moduleRef.BasePacketSize * rangeFactor,
+					this.moduleRef.BasePacketSize * this.moduleRef.MaxDataFactor
+				);
+			}
+
+			this.moduleRef.PacketSize *= this.moduleRef.PacketThrottle / 100f;
+
+			if (ARConfiguration.FixedPowerCost || this.CurrentLinkSqrDistance <= this.NominalLinkSqrDistance)
+			{
+				this.moduleRef.PacketResourceCost = 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;
 		}
 
 		/// <summary>

--- a/GameData/AntennaRange/AntennaRange.cfg
+++ b/GameData/AntennaRange/AntennaRange.cfg
@@ -104,7 +104,7 @@
 	}
 }
 
-@PART[HighGainAntenna]:FOR[AntennaRange]:NEEDS[AsteroidDay,!RemoteTech]
+@PART[HighGainAntenna]:FOR[AntennaRange]:NEEDS[!RemoteTech]
 {
 	@TechRequired = electronics
 	@description = Repurposed for medium range probes, the HG-55 provdes high speed directional data transmission.

--- a/IAntennaRelay.cs
+++ b/IAntennaRelay.cs
@@ -46,6 +46,18 @@
 		/// </summary>
 		IAntennaRelay targetRelay { get; }
 
+		float PacketSize { get; set; }
+
+		float BasePacketSize { get; }
+
+		float PacketResourceCost { get; set; }
+
+		float BasePacketResourceCost { get; }
+
+		float PacketThrottle { get; }
+
+		float MaxDataFactor { get; }
+
 		/// <summary>
 		/// Gets a value indicating whether this <see cref="AntennaRange.IAntennaRelay"/> Relay is communicating
 		/// directly with Kerbin.
@@ -56,7 +68,6 @@
 		/// The link distance, in meters, at which this relay behaves nominally.
 		/// </summary>
 		double NominalLinkSqrDistance { get; }
-
 
 		/// <summary>
 		/// The link distance, in meters, beyond which this relay cannot operate.

--- a/ModuleLimitedDataTransmitter.cs
+++ b/ModuleLimitedDataTransmitter.cs
@@ -192,6 +192,62 @@
 			}
 		}
 
+		public float PacketSize
+		{
+			get
+			{
+				return this.packetSize;
+			}
+			set
+			{
+				this.packetSize = value;
+			}
+		}
+
+		public float BasePacketSize
+		{
+			get
+			{
+				return this._basepacketSize;
+			}
+		}
+
+		public float PacketResourceCost
+		{
+			get
+			{
+				return this.packetResourceCost;
+			}
+			set
+			{
+				this.packetResourceCost = value;
+			}
+		}
+
+		public float BasePacketResourceCost
+		{
+			get
+			{
+				return this._basepacketResourceCost;
+			}
+		}
+
+		public float PacketThrottle
+		{
+			get
+			{
+				return this.packetThrottle;
+			}
+		}
+
+		public float MaxDataFactor
+		{
+			get
+			{
+				return this.maxDataFactor;
+			}
+		}
+
 		/// <summary>
 		/// Gets the target <see cref="AntennaRange.IAntennaRelay"/>relay.
 		/// </summary>
@@ -361,7 +417,10 @@
 		{
 			get
 			{
-				this.PreTransmit_SetPacketSize();
+				if (this.relay != null)
+				{
+					this.relay.RecalculateTransmissionRates();
+				}
 
 				if (this.CanTransmit())
 				{
@@ -382,7 +441,7 @@
 		{
 			get
 			{
-				this.PreTransmit_SetPacketResourceCost();
+				this.relay.RecalculateTransmissionRates();
 
 				if (this.CanTransmit())
 				{
@@ -417,7 +476,7 @@
 		// Build ALL the objects.
 		public ModuleLimitedDataTransmitter () : base()
 		{
-			this.ErrorMsg = new ScreenMessage("", 4f, false, ScreenMessageStyle.UPPER_LEFT);
+			this.ErrorMsg = new ScreenMessage("", 4f, ScreenMessageStyle.UPPER_LEFT);
 			this.packetThrottle = 100f;
 		}
 
@@ -645,11 +704,9 @@
 				"TransmitData(List<ScienceData> dataQueue, Callback callback) called.  dataQueue.Count={0}",
 				dataQueue.Count
 			);
+			this.relay.RecalculateTransmissionRates();
 
 			this.FindNearestRelay();
-
-			this.PreTransmit_SetPacketSize();
-			this.PreTransmit_SetPacketResourceCost();
 
 			if (this.CanTransmit())
 			{
@@ -760,8 +817,7 @@
 		{
 			this.FindNearestRelay();
 
-			PreTransmit_SetPacketSize ();
-			PreTransmit_SetPacketResourceCost ();
+			this.relay.RecalculateTransmissionRates();
 
 			this.LogDebug(
 				"distance: " + this.CurrentLinkSqrDistance
@@ -921,47 +977,7 @@
 
 			this.LogDebug(this.ErrorMsg.message);
 
-			ScreenMessages.PostScreenMessage(this.ErrorMsg, false);
-		}
-
-		// Before transmission, set packetResourceCost.  Per above, packet cost increases with the square of
-		// distance.  packetResourceCost maxes out at _basepacketResourceCost * maxPowerFactor, at which point
-		// transmission fails (see CanTransmit).
-		private void PreTransmit_SetPacketResourceCost()
-		{
-			if (ARConfiguration.FixedPowerCost || this.CurrentLinkSqrDistance <= this.NominalLinkSqrDistance)
-			{
-				base.packetResourceCost = this._basepacketResourceCost;
-			}
-			else
-			{
-				float rangeFactor = (float)(this.CurrentLinkSqrDistance / this.NominalLinkSqrDistance);
-
-				base.packetResourceCost = this._basepacketResourceCost * rangeFactor;
-			}
-
-			base.packetResourceCost *= this.packetThrottle / 100f;
-		}
-
-		// Before transmission, set packetSize.  Per above, packet size increases with the inverse square of
-		// distance.  packetSize maxes out at _basepacketSize * maxDataFactor.
-		private void PreTransmit_SetPacketSize()
-		{
-			if (!ARConfiguration.FixedPowerCost && this.CurrentLinkSqrDistance >= this.NominalLinkSqrDistance)
-			{
-				base.packetSize = this._basepacketSize;
-			}
-			else
-			{
-				float rangeFactor = (float)(this.NominalLinkSqrDistance / this.CurrentLinkSqrDistance);
-
-				base.packetSize = Mathf.Min(
-					this._basepacketSize * rangeFactor,
-					this._basepacketSize * this.maxDataFactor
-				);
-			}
-
-			base.packetSize *= this.packetThrottle / 100f;
+			ScreenMessages.PostScreenMessage(this.ErrorMsg);
 		}
 
 		private string buildTransmitMessage()

--- a/ProtoAntennaRelay.cs
+++ b/ProtoAntennaRelay.cs
@@ -72,6 +72,102 @@
 			}
 		}
 
+		public float PacketSize
+		{
+			get
+			{
+				if (this.moduleRef == null)
+				{
+					return float.NaN;
+				}
+
+				return this.moduleRef.PacketSize;
+			}
+			set
+			{
+				if (this.moduleRef == null)
+				{
+					return;
+				}
+
+				this.moduleRef.PacketSize = value;
+			}
+		}
+
+		public float BasePacketSize
+		{
+			get
+			{
+				if (this.moduleRef == null)
+				{
+					return float.NaN;
+				}
+
+				return this.moduleRef.BasePacketSize;
+			}
+		}
+
+		public float PacketResourceCost
+		{
+			get
+			{
+				if (this.moduleRef == null)
+				{
+					return float.NaN;
+				}
+
+				return this.moduleRef.PacketResourceCost;
+			}
+			set
+			{
+				if (this.moduleRef == null)
+				{
+					return;
+				}
+
+				this.moduleRef.PacketResourceCost = value;
+			}
+		}
+
+		public float BasePacketResourceCost
+		{
+			get
+			{
+				if (this.moduleRef == null)
+				{
+					return float.NaN;
+				}
+
+				return this.moduleRef.BasePacketResourceCost;
+			}
+		}
+
+		public float PacketThrottle
+		{
+			get
+			{
+				if (this.moduleRef == null)
+				{
+					return float.NaN;
+				}
+
+				return this.moduleRef.PacketThrottle;
+			}
+		}
+
+		public float MaxDataFactor
+		{
+			get
+			{
+				if (this.moduleRef == null)
+				{
+					return float.NaN;
+				}
+
+				return this.moduleRef.MaxDataFactor;
+			}
+		}
+
 		/// <summary>
 		/// Gets the nominal transmit distance at which the Antenna behaves just as prescribed by Squad's config.
 		/// </summary>