Added MuMech_ToSI to pretty up the ranges when we report them to users.
Added MuMech_ToSI to pretty up the ranges when we report them to users.

--- a/AntennaRange.cs
+++ b/AntennaRange.cs
@@ -12,6 +12,8 @@
  * copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/
  * 
  * This software uses the ModuleManager library © 2013 ialdabaoth, used under a Creative Commons Attribution-ShareAlike 3.0 Uported License.
+ * 
+ * This software uses code from the MuMechLib library, © 2013 r4m0n, used under the GNU GPL version 3.
  * 
  */
 
@@ -79,24 +81,51 @@
 		[KSPField(isPersistant = false)]
 		public float maxDataFactor;
 
+
+		/*
+		 * 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.
+		 * */
 		// Override ModuleDataTransmitter.DataRate to just return packetSize, because we want antennas to be scored in
-		// terms of watts/byte
-		// HACK: This seems a little wrong; joules/byte sounds better, but it favors the larger antenna always.
+		// terms of joules/byte
 		public new float DataRate
 		{
 			get
 			{
+				PreTransmit_SetPacketSize();
 				return this.packetSize;
 			}
 		}
 
 		// Override ModuleDataTransmitter.DataResourceCost to just return packetResourceCost, because we want antennas
-		// to be scored in terms of watts/byte
-		// HACK: This seems a little wrong; joules/byte sounds better, but it favors the larger antenna always.
+		// to be scored in terms of joules/byte
 		public new float DataResourceCost
 		{
 			get
 			{
+				PreTransmit_SetPacketResourceCost();
 				return this.packetResourceCost;
 			}
 		}
@@ -160,12 +189,12 @@
 		{
 			string ErrorText = string.Format (
 				"Unable to transmit: out of range!  Maximum range = {0}; Current range = {1}.",
-				this.maxTransmitDistance,
-				this.transmitDistance);
+				Tools.MuMech_ToSI((double)this.maxTransmitDistance),
+				Tools.MuMech_ToSI((double)this.transmitDistance));
 			ScreenMessages.PostScreenMessage (new ScreenMessage (ErrorText, 4f, ScreenMessageStyle.UPPER_LEFT));
 		}
 
-		// Before transmission, set packetResourceCost.  Per above, packet size increases with the square of
+		// 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).
 		protected void PreTransmit_SetPacketResourceCost()
@@ -201,8 +230,8 @@
 		public override string GetInfo()
 		{
 			string text = base.GetInfo();
-			text += "Nominal Range: " + this.nominalRange.ToString() + "\n";
-			text += "Maximum Range: " + this.maxTransmitDistance.ToString() + "\n";
+			text += "Nominal Range: " + Tools.MuMech_ToSI((double)this.nominalRange) + "\n";
+			text += "Maximum Range: " + Tools.MuMech_ToSI((double)this.maxTransmitDistance) + "\n";
 			return text;
 		}
 
@@ -315,7 +344,96 @@
 				KSPLog.print(Msg);
 			}
 		}
+
+		/*
+		 * MuMech_ToSI is a part of the MuMechLib library, © 2013 r4m0n, used under the GNU GPL version 3.
+		 * */
+		public static string MuMech_ToSI(double d, int digits = 3, int MinMagnitude = 0, int MaxMagnitude = int.MaxValue)
+		{
+			float exponent = (float)Math.Log10(Math.Abs(d));
+			exponent = UnityEngine.Mathf.Clamp(exponent, (float)MinMagnitude, (float)MaxMagnitude);
+
+			if (exponent >= 0)
+			{
+				switch ((int)Math.Floor(exponent))
+				{
+					case 0:
+						case 1:
+						case 2:
+						return d.ToString("F" + digits);
+						case 3:
+						case 4:
+						case 5:
+						return (d / 1e3).ToString("F" + digits) + "k";
+						case 6:
+						case 7:
+						case 8:
+						return (d / 1e6).ToString("F" + digits) + "M";
+						case 9:
+						case 10:
+						case 11:
+						return (d / 1e9).ToString("F" + digits) + "G";
+						case 12:
+						case 13:
+						case 14:
+						return (d / 1e12).ToString("F" + digits) + "T";
+						case 15:
+						case 16:
+						case 17:
+						return (d / 1e15).ToString("F" + digits) + "P";
+						case 18:
+						case 19:
+						case 20:
+						return (d / 1e18).ToString("F" + digits) + "E";
+						case 21:
+						case 22:
+						case 23:
+						return (d / 1e21).ToString("F" + digits) + "Z";
+						default:
+						return (d / 1e24).ToString("F" + digits) + "Y";
+				}
+			}
+			else if (exponent < 0)
+			{
+				switch ((int)Math.Floor(exponent))
+				{
+					case -1:
+						case -2:
+						case -3:
+						return (d * 1e3).ToString("F" + digits) + "m";
+						case -4:
+						case -5:
+						case -6:
+						return (d * 1e6).ToString("F" + digits) + "μ";
+						case -7:
+						case -8:
+						case -9:
+						return (d * 1e9).ToString("F" + digits) + "n";
+						case -10:
+						case -11:
+						case -12:
+						return (d * 1e12).ToString("F" + digits) + "p";
+						case -13:
+						case -14:
+						case -15:
+						return (d * 1e15).ToString("F" + digits) + "f";
+						case -16:
+						case -17:
+						case -18:
+						return (d * 1e18).ToString("F" + digits) + "a";
+						case -19:
+						case -20:
+						case -21:
+						return (d * 1e21).ToString("F" + digits) + "z";
+						default:
+						return (d * 1e24).ToString("F" + digits) + "y";
+				}
+			}
+			else
+			{
+				return "0";
+			}
+		}
 	}
 }
 
-