AntennaRange.cfg: Added isAntenna to the part prefab for all parts with ModuleLimitedDataTransmitters.
AntennaRange.cfg: Added isAntenna to the part prefab for all parts with ModuleLimitedDataTransmitters.

AntennaRelay.cs: Added a timer to prevent antennas from re-searching their nearest relay multiple times in a single transmission attempt.

Extensions.cs: Remove IsAntenna stuff because we want that to work without persistence data. Doesn't work yet.

ModuleLimitedDataTransmitter.cs:
* Changed DataRate to return a very tiny number if the antenna cannot transmit.
* Changed the transmission message to indictor if it is using a relay or not.
* Removed IsAntenna in favor of using the prefab... hopefully.

file:a/ARTools.cs -> file:b/ARTools.cs
--- a/ARTools.cs
+++ b/ARTools.cs
@@ -1,3 +1,20 @@
+// AntennaRange © 2014 toadicus
+//
+// AntennaRange provides incentive and requirements for the use of the various antenna parts.
+// Nominally, the breakdown is as follows:
+//
+//     Communotron 16 - Suitable up to Kerbalsynchronous Orbit
+//     Comms DTS-M1 - Suitable throughout the Kerbin subsystem
+//     Communotron 88-88 - Suitable throughout the Kerbol system.
+//
+// This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a
+// 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.
+
 using System;
 
 namespace AntennaRange
@@ -5,7 +22,7 @@
 	public static class Tools
 	{
 		private static ScreenMessage debugmsg = new ScreenMessage("", 2f, ScreenMessageStyle.UPPER_RIGHT);
-
+		// Function that posts messages to the screen and the log when DEBUG is defined.
 		[System.Diagnostics.Conditional("DEBUG")]
 		public static void PostDebugMessage(string Msg)
 		{

--- a/AntennaRange.cfg
+++ b/AntennaRange.cfg
@@ -1,50 +1,55 @@
-//

-// AntennaRange © 2013 toadicus

-// 

-// This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a

-// 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.

-//

-// Specifications:

-// nominalRange:	The distance from Kerbin at which the antenna will perform exactly as prescribed by packetResourceCost

-// 					and packetSize.

-// maxPowerFactor:	The multiplier on packetResourceCost that defines the maximum power output of the antenna.  When the

-//					power cost exceeds packetResourceCost * maxPowerFactor, transmission will fail.

-// maxDataFactor:	The multipler on packetSize that defines the maximum data bandwidth of the antenna.

-// 

-

-@PART[longAntenna]

-{

-	@MODULE[ModuleDataTransmitter]

-	{

-		@name = ModuleLimitedDataTransmitter

-		nominalRange = 1500000

-		maxPowerFactor = 8

-		maxDataFactor = 4

-	}

-}

-

-@PART[mediumDishAntenna]

-{

-	@MODULE[ModuleDataTransmitter]

-	{

-		@name = ModuleLimitedDataTransmitter

-		nominalRange = 30000000

-		maxPowerFactor = 8

-		maxDataFactor = 4

-	}

-}

-

-@PART[commDish]

-{

-	@MODULE[ModuleDataTransmitter]

-	{

-		@name = ModuleLimitedDataTransmitter

-		nominalRange = 80000000000

-		maxPowerFactor = 8

-		maxDataFactor = 4

-	}

-}

+//
+// AntennaRange © 2013 toadicus
+// 
+// This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a
+// 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.
+//
+// Specifications:
+// nominalRange:	The distance from Kerbin at which the antenna will perform exactly as prescribed by packetResourceCost
+// 					and packetSize.
+// maxPowerFactor:	The multiplier on packetResourceCost that defines the maximum power output of the antenna.  When the
+//					power cost exceeds packetResourceCost * maxPowerFactor, transmission will fail.
+// maxDataFactor:	The multipler on packetSize that defines the maximum data bandwidth of the antenna.
+// 
 
+@PART[longAntenna]
+{
+	@MODULE[ModuleDataTransmitter]
+	{
+		@name = ModuleLimitedDataTransmitter
+		nominalRange = 1500000
+		maxPowerFactor = 8
+		maxDataFactor = 4
+	}
+}
+
+@PART[mediumDishAntenna]
+{
+	@MODULE[ModuleDataTransmitter]
+	{
+		@name = ModuleLimitedDataTransmitter
+		nominalRange = 30000000
+		maxPowerFactor = 8
+		maxDataFactor = 4
+	}
+}
+
+@PART[commDish]
+{
+	@MODULE[ModuleDataTransmitter]
+	{
+		@name = ModuleLimitedDataTransmitter
+		nominalRange = 80000000000
+		maxPowerFactor = 8
+		maxDataFactor = 4
+	}
+}
+
+@PART[*]:HAS[MODULE[ModuleLimitedDataTransmitter]]:Final
+{
+	isAntenna = True
+}
+

--- a/AntennaRelay.cs
+++ b/AntennaRelay.cs
@@ -1,3 +1,20 @@
+// AntennaRange © 2014 toadicus
+//
+// AntennaRange provides incentive and requirements for the use of the various antenna parts.
+// Nominally, the breakdown is as follows:
+//
+//     Communotron 16 - Suitable up to Kerbalsynchronous Orbit
+//     Comms DTS-M1 - Suitable throughout the Kerbin subsystem
+//     Communotron 88-88 - Suitable throughout the Kerbol system.
+//
+// This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a
+// 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.
+
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -8,6 +25,9 @@
 	{
 		// We don't have a Bard, so we'll hide Kerbin here.
 		protected CelestialBody Kerbin;
+
+		protected System.Diagnostics.Stopwatch searchTimer;
+		protected long millisecondsBetweenSearches;
 
 		/// <summary>
 		/// Gets the parent Vessel.
@@ -96,6 +116,19 @@
 		/// <returns>The nearest relay or null, if no relays in range.</returns>
 		public IAntennaRelay FindNearestRelay()
 		{
+			if (this.searchTimer.IsRunning && this.searchTimer.ElapsedMilliseconds < this.millisecondsBetweenSearches)
+			{
+				return this.nearestRelay;
+			}
+
+			if (this.searchTimer.IsRunning)
+			{
+				this.searchTimer.Stop();
+				this.searchTimer.Reset();
+			}
+
+			this.searchTimer.Start();
+
 			// Set this relay as checked, so that we don't check it again.
 			this.relayChecked = true;
 
@@ -177,9 +210,8 @@
 		public override string ToString()
 		{
 			return string.Format(
-				"Antenna relay on vessel {0} (range to relay: {1}m)",
-				vessel,
-				Tools.MuMech_ToSI(transmitDistance)
+				"Antenna relay on vessel {0}.",
+				vessel
 			);
 		}
 
@@ -190,6 +222,9 @@
 		public AntennaRelay(Vessel v)
 		{
 			this.vessel = v;
+
+			this.searchTimer = new System.Diagnostics.Stopwatch();
+			this.millisecondsBetweenSearches = 5000;
 
 			// HACK: This might not be safe in all circumstances, but since AntennaRelays are not built until Start,
 			// we hope it is safe enough.

--- a/Extensions.cs
+++ b/Extensions.cs
@@ -1,3 +1,20 @@
+// AntennaRange © 2014 toadicus
+//
+// AntennaRange provides incentive and requirements for the use of the various antenna parts.
+// Nominally, the breakdown is as follows:
+//
+//     Communotron 16 - Suitable up to Kerbalsynchronous Orbit
+//     Comms DTS-M1 - Suitable throughout the Kerbin subsystem
+//     Communotron 88-88 - Suitable throughout the Kerbol system.
+//
+// This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a
+// 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.
+
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -98,14 +115,14 @@
 				Transmitters = new List<IAntennaRelay>();
 
 				// Loop through the ProtoPartModuleSnapshots in this Vessel
-				foreach (ProtoPartModuleSnapshot ms in vessel.protoVessel.protoPartSnapshots.SelectMany(ps => ps.modules))
+				foreach (ProtoPartSnapshot pps in vessel.protoVessel.protoPartSnapshots)
 				{
-					// If they are antennas...
-					if (ms.IsAntenna())
-					{
-						// ...add a new ProtoAntennaRelay wrapper to the list.
-						Transmitters.Add(new ProtoAntennaRelay(ms, vessel));
-					}
+					Transmitters.AddRange(
+						PartLoader.getPartInfoByName(pps.partName)
+						.partPrefab
+						.Modules
+						.OfType<IAntennaRelay>()
+					);
 				}
 			}
 
@@ -119,21 +136,6 @@
 			// Return the list of IAntennaRelays
 			return Transmitters;
 		}
-
-		// Returns true if this PartModule contains a True IsAntenna field, false otherwise.
-		public static bool IsAntenna (this PartModule module)
-		{
-			return module.Fields.GetValue<bool> ("IsAntenna");
-		}
-
-		// Returns true if this ProtoPartModuleSnapshot contains a persistent True IsAntenna field, false otherwise
-		public static bool IsAntenna(this ProtoPartModuleSnapshot protomodule)
-		{
-			bool result;
-
-			return Boolean.TryParse (protomodule.moduleValues.GetValue ("IsAntenna") ?? "False", out result)
-				? result : false;
-		}
 	}
 }
 

--- a/IAntennaRelay.cs
+++ b/IAntennaRelay.cs
@@ -1,3 +1,20 @@
+// AntennaRange © 2014 toadicus
+//
+// AntennaRange provides incentive and requirements for the use of the various antenna parts.
+// Nominally, the breakdown is as follows:
+//
+//     Communotron 16 - Suitable up to Kerbalsynchronous Orbit
+//     Comms DTS-M1 - Suitable throughout the Kerbin subsystem
+//     Communotron 88-88 - Suitable throughout the Kerbol system.
+//
+// This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a
+// 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.
+
 using KSP;
 using System;
 

--- a/ModuleLimitedDataTransmitter.cs
+++ b/ModuleLimitedDataTransmitter.cs
@@ -1,22 +1,20 @@
-/*
- * AntennaRange © 2013 toadicus
- * 
- * AntennaRange provides incentive and requirements for the use of the various antenna parts.
- * Nominally, the breakdown is as follows:
- * 
- *     Communotron 16 - Suitable up to Kerbalsynchronous Orbit
- *     Comms DTS-M1 - Suitable throughout the Kerbin subsystem
- *     Communotron 88-88 - Suitable throughout the Kerbol system.
- * 
- * This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a
- * 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.
- * 
- */
+// AntennaRange © 2014 toadicus
+//
+// AntennaRange provides incentive and requirements for the use of the various antenna parts.
+// Nominally, the breakdown is as follows:
+//
+//     Communotron 16 - Suitable up to Kerbalsynchronous Orbit
+//     Comms DTS-M1 - Suitable throughout the Kerbin subsystem
+//     Communotron 88-88 - Suitable throughout the Kerbol system.
+//
+// This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a
+// 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.
+
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -43,10 +41,6 @@
 	 * */
 	public class ModuleLimitedDataTransmitter : ModuleDataTransmitter, IScienceDataTransmitter, IAntennaRelay
 	{
-		// Call this an antenna so that you don't have to.
-		[KSPField(isPersistant = true)]
-		protected bool IsAntenna;
-
 		// Stores the packetResourceCost as defined in the .cfg file.
 		protected float _basepacketResourceCost;
 
@@ -78,10 +72,6 @@
 		// The multipler on packetSize that defines the maximum data bandwidth of the antenna.
 		[KSPField(isPersistant = false)]
 		public float maxDataFactor;
-
-		// This field exists to get saved to the persistence file so that relays can be found on unloaded Vessels.
-		[KSPField(isPersistant = true)]
-		protected float ARmaxTransmitDistance;
 
 		/*
 		 * Properties
@@ -109,7 +99,7 @@
 		{
 			get
 			{
-				return this.ARmaxTransmitDistance;
+				return Mathf.Sqrt (this.maxPowerFactor) * this.nominalRange;
 			}
 		}
 
@@ -146,7 +136,15 @@
 			get
 			{
 				this.PreTransmit_SetPacketSize();
-				return this.packetSize;
+
+				if (this.CanTransmit())
+				{
+					return this.packetSize;
+				}
+				else
+				{
+					return float.Epsilon;
+				}
 			}
 		}
 
@@ -214,9 +212,6 @@
 		{
 			this.Fields.Load(node);
 			base.Fields.Load(node);
-
-			this.ARmaxTransmitDistance = Mathf.Sqrt (this.maxPowerFactor) * this.nominalRange;
-			this.IsAntenna = true;
 
 			base.OnLoad (node);
 
@@ -245,7 +240,7 @@
 		{
 			string ErrorText = string.Format (
 				"Unable to transmit: out of range!  Maximum range = {0}m; Current range = {1}m.",
-				Tools.MuMech_ToSI((double)this.ARmaxTransmitDistance, 2),
+				Tools.MuMech_ToSI((double)this.maxTransmitDistance, 2),
 				Tools.MuMech_ToSI((double)this.transmitDistance, 2)
 				);
 
@@ -291,7 +286,7 @@
 		{
 			string text = base.GetInfo();
 			text += "Nominal Range: " + Tools.MuMech_ToSI((double)this.nominalRange, 2) + "m\n";
-			text += "Maximum Range: " + Tools.MuMech_ToSI((double)this.ARmaxTransmitDistance, 2) + "m\n";
+			text += "Maximum Range: " + Tools.MuMech_ToSI((double)this.maxTransmitDistance, 2) + "m\n";
 			return text;
 		}
 
@@ -336,18 +331,20 @@
 
 			if (this.CanTransmit())
 			{
-				this.ErrorMsg.message = "Beginning transmission ";
+				string message;
+
+				message = "Beginning transmission ";
 
 				if (this.relay.nearestRelay == null)
 				{
-					this.ErrorMsg.message += "directly to Kerbin.";
+					message += "directly to Kerbin.";
 				}
 				else
 				{
-					this.ErrorMsg.message += "via relay " + this.relay.nearestRelay;
-				}
-
-				ScreenMessages.PostScreenMessage(this.ErrorMsg);
+					message += "via relay " + this.relay.nearestRelay;
+				}
+
+				ScreenMessages.PostScreenMessage(message, 4f, ScreenMessageStyle.UPPER_LEFT);
 
 				base.StartTransmission();
 			}
@@ -384,7 +381,7 @@
 				base.packetSize,
 				this._basepacketResourceCost,
 				base.packetResourceCost,
-				this.ARmaxTransmitDistance,
+				this.maxTransmitDistance,
 				this.transmitDistance,
 				this.nominalRange,
 				this.CanTransmit(),

--- a/ProtoAntennaRelay.cs
+++ b/ProtoAntennaRelay.cs
@@ -1,4 +1,22 @@
+// AntennaRange © 2014 toadicus
+//
+// AntennaRange provides incentive and requirements for the use of the various antenna parts.
+// Nominally, the breakdown is as follows:
+//
+//     Communotron 16 - Suitable up to Kerbalsynchronous Orbit
+//     Comms DTS-M1 - Suitable throughout the Kerbin subsystem
+//     Communotron 88-88 - Suitable throughout the Kerbol system.
+//
+// This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a
+// 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.
+
 using System;
+using System.Linq;
 
 namespace AntennaRange
 {
@@ -8,7 +26,11 @@
 	 * */
 	public class ProtoAntennaRelay : AntennaRelay, IAntennaRelay
 	{
-		protected ProtoPartModuleSnapshot snapshot;
+		// Stores the proto module.
+		protected ProtoPartModuleSnapshot protoModule;
+
+		// Stores the proto part, which seems silly because all we need is the name.
+		protected Part partPrefab;
 
 		/// <summary>
 		/// The maximum distance at which this transmitter can operate.
@@ -18,9 +40,7 @@
 		{
 			get
 			{
-				double result;
-				Double.TryParse(snapshot.moduleValues.GetValue ("ARmaxTransmitDistance") ?? "0", out result);
-				return (float)result;
+				return this.partPrefab.Modules.OfType<ModuleLimitedDataTransmitter>().First().maxTransmitDistance;
 			}
 		}
 
@@ -34,18 +54,18 @@
 			get
 			{
 				bool result;
-				Boolean.TryParse(this.snapshot.moduleValues.GetValue("relayChecked"), out result);
+				Boolean.TryParse(this.protoModule.moduleValues.GetValue("relayChecked"), out result);
 				return result;
 			}
 			protected set
 			{
-				if (this.snapshot.moduleValues.HasValue("relayChecked"))
+				if (this.protoModule.moduleValues.HasValue("relayChecked"))
 				{
-					this.snapshot.moduleValues.SetValue("relayChecked", value.ToString ());
+					this.protoModule.moduleValues.SetValue("relayChecked", value.ToString ());
 				}
 				else
 				{
-					this.snapshot.moduleValues.AddValue("relayChecked", value);
+					this.protoModule.moduleValues.AddValue("relayChecked", value);
 				}
 			}
 		}
@@ -55,9 +75,10 @@
 		/// </summary>
 		/// <param name="ms">The ProtoPartModuleSnapshot to wrap</param>
 		/// <param name="vessel">The parent Vessel</param>
-		public ProtoAntennaRelay(ProtoPartModuleSnapshot ms, Vessel vessel) : base(vessel)
+		public ProtoAntennaRelay(ProtoPartModuleSnapshot ppms, ProtoPartSnapshot pps, Vessel vessel) : base(vessel)
 		{
-			this.snapshot = ms;
+			this.protoModule = ppms;
+			this.partPrefab = PartLoader.getPartInfoByName(pps.partName).partPrefab;
 		}
 	}
 }