RelayDatabase: ContainsKey now only checks relayDatabase. Also added some debugging lines to getVesselRelays.
RelayDatabase: ContainsKey now only checks relayDatabase. Also added some debugging lines to getVesselRelays.

--- a/AntennaRelay.cs
+++ b/AntennaRelay.cs
@@ -21,7 +21,7 @@
 
 namespace AntennaRange
 {
-	public class AntennaRelay : IAntennaRelay
+	public class AntennaRelay
 	{
 		// We don't have a Bard, so we'll hide Kerbin here.
 		protected CelestialBody Kerbin;
@@ -138,9 +138,10 @@
 					.ToList();
 
 			nearbyVessels.RemoveAll(v => v.vesselType == VesselType.Debris);
-
-			Tools.PostDebugMessage(string.Format(
-				"{0}: Non-debris vessels in range: {1}",
+			nearbyVessels.RemoveAll(v => v.vesselType == VesselType.Flag);
+
+			Tools.PostDebugMessage(string.Format(
+				"{0}: Non-debris, non-flag vessels in range: {1}",
 				this.GetType().Name,
 				nearbyVessels.Count
 				));

file:b/ChangeLog (new)
--- /dev/null
+++ b/ChangeLog
@@ -1,1 +1,7 @@
+2014-01-14  toadicus  <>
 
+	* ModuleLimitedDataTransmitter.cs: Added a ":" to the
+	  transmission communications for consistency with stock
+	  behavior.
+
+

--- a/ModuleLimitedDataTransmitter.cs
+++ b/ModuleLimitedDataTransmitter.cs
@@ -365,7 +365,7 @@
 
 				message.Append("[");
 				message.Append(base.part.partInfo.title);
-				message.Append("] ");
+				message.Append("]: ");
 
 				message.Append("Beginning transmission ");
 
@@ -417,11 +417,17 @@
 
 		public override string ToString()
 		{
-			return string.Format(
-				"{0} on {1}.",
-				this.part.partInfo.title,
-				vessel.name
-			);
+			StringBuilder msg = new StringBuilder();
+
+			msg.Append(this.part.partInfo.title);
+
+			if (vessel != null)
+			{
+				msg.Append(" on ");
+				msg.Append(vessel.name);
+			}
+
+			return msg.ToString();
 		}
 
 		// When debugging, it's nice to have a button that just tells you everything.

--- /dev/null
+++ b/Properties/AssemblyInfo.cs
@@ -1,1 +1,34 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
 
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+[assembly: AssemblyTitle("AntennaRange")]
+[assembly: AssemblyDescription("Enforce and Encourage Antenna Diversity")]
+[assembly: AssemblyCopyright("toadicus")]
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+[assembly: AssemblyVersion("0.6.2.*")]
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
+

--- /dev/null
+++ b/Properties/ChangeLog
@@ -1,1 +1,5 @@
+2014-01-14  toadicus  <>
 
+	* AssemblyInfo.cs: New AssemblyInfo file for reason.
+
+

--- a/ProtoAntennaRelay.cs
+++ b/ProtoAntennaRelay.cs
@@ -55,7 +55,11 @@
 			protected set;
 		}
 
-		public string Title
+		/// <summary>
+		/// Gets the underlying part's title.
+		/// </summary>
+		/// <value>The title.</value>
+		public string title
 		{
 			get
 			{
@@ -71,7 +75,7 @@
 				Tools.PostDebugMessage(string.Format(
 					"{0}: {1} on {2} cannot transmit: {3}",
 					this.GetType().Name,
-					this.Title,
+					this.title,
 					this.vessel.name,
 					Enum.GetName(typeof(PartStates), partState)
 				));
@@ -84,8 +88,8 @@
 		{
 			return string.Format(
 				"{0} on {1}.",
-				this.Title,
-				vessel.name
+				this.title,
+				this.protoPart.pVesselRef.vesselName
 			);
 		}
 

--- a/RelayDatabase.cs
+++ b/RelayDatabase.cs
@@ -16,8 +16,9 @@
 		/*
 		 * Static members
 		 * */
+		// Singleton storage
 		protected static RelayDatabase _instance;
-
+		// Gets the singleton
 		public static RelayDatabase Instance
 		{
 			get
@@ -38,26 +39,34 @@
 		/*
 		 * Fields
 		 * */
+		// Vessel.id-keyed hash table of Part.GetHashCode()-keyed tables of relay objects.
 		protected Dictionary<Guid, Dictionary<int, IAntennaRelay>> relayDatabase;
 
-		protected Dictionary<Guid, int> vesselPartCountDB;
+		// Vessel.id-keyed hash table of part counts, used for caching
+		protected Dictionary<Guid, int> vesselPartCountTable;
 
 		/*
 		 * Properties
 		 * */
+		// Gets the Part-hashed table of relays in a given vessel
 		public Dictionary<int, IAntennaRelay> this [Vessel vessel]
 		{
 			get
 			{
+				// If we don't have an entry for this vessel...
 				if (!this.ContainsKey(vessel.id))
 				{
+					// ...Generate an entry for this vessel.
 					this.AddVessel(vessel);
 				}
-				if (this.vesselPartCountDB[vessel.id] != vessel.Parts.Count)
-				{
+				// If our part count disagrees with the vessel's part count...
+				if (this.vesselPartCountTable[vessel.id] != vessel.Parts.Count)
+				{
+					// ...Update the our vessel in the cache
 					this.UpdateVessel(vessel);
 				}
 
+				// Return the Part-hashed table of relays for this vessel
 				return relayDatabase[vessel.id];
 			}
 		}
@@ -65,10 +74,14 @@
 		/* 
 		 * Methods
 		 * */
+		// Adds a vessel to the database
+		// The return for this function isn't used yet, but seems useful for potential future API-uses
 		public bool AddVessel(Vessel vessel)
 		{
+			// If this vessel is already here...
 			if (relayDatabase.ContainsKey(vessel.id))
 			{
+				// ...post an error
 				Debug.LogWarning(string.Format(
 					"{0}: Cannot add vessel '{1}' (id: {2}): Already in database.",
 					this.GetType().Name,
@@ -76,77 +89,96 @@
 					vessel.id
 				));
 
+				// ...and refuse to add
 				return false;
 			}
+			// otherwise, add the vessel to our tables...
 			else
 			{
+				// Build an empty table...
+				this.relayDatabase[vessel.id] = new Dictionary<int, IAntennaRelay>();
+
+				// Update the empty index
 				this.UpdateVessel(vessel);
 
+				// Return success
 				return true;
 			}
 		}
 
+		// Update the vessel's entry in the table
 		public void UpdateVessel(Vessel vessel)
 		{
+			// Squak if the database doesn't have the vessel
 			if (!relayDatabase.ContainsKey(vessel.id))
 			{
-				Tools.PostDebugMessage(string.Format(
+				throw new InvalidOperationException(string.Format(
 					"{0}: Update called vessel '{1}' (id: {2}) not in database: vessel will be added.",
 					this.GetType().Name,
 					vessel.name,
 					vessel.id
 				));
 			}
-			else
-			{
-				// Remove stuff?
-			}
-
-			this.relayDatabase[vessel.id] = this.getVesselRelays(vessel);
-			this.vesselPartCountDB[vessel.id] = vessel.Parts.Count;
-		}
-
+
+			Dictionary<int, IAntennaRelay> vesselTable = this.relayDatabase[vessel.id];
+
+			// Actually build and assign the table
+			this.getVesselRelays(vessel, ref vesselTable);
+			// Set the part count
+			this.vesselPartCountTable[vessel.id] = vessel.Parts.Count;
+		}
+
+		// Returns true if both the relayDatabase and the vesselPartCountDB contain the vessel id.
 		public bool ContainsKey(Guid key)
 		{
-			return (this.relayDatabase.ContainsKey(key) & this.vesselPartCountDB.ContainsKey(key));
-		}
-
+			return this.relayDatabase.ContainsKey(key);
+		}
+
+		// Returns true if both the relayDatabase and the vesselPartCountDB contain the vessel.
 		public bool ContainsKey(Vessel vessel)
 		{
 			return this.ContainsKey(vessel.id);
 		}
 
+		// Runs when a vessel is modified (or when we switch to one, to catch docking events)
 		public void onVesselWasModified(Vessel vessel)
 		{
+			// If we have this vessel in our cache...
 			if (this.ContainsKey(vessel))
 			{
-				if (this.vesselPartCountDB[vessel.id] != vessel.Parts.Count)
+				// If our part counts disagree (such as if a part has been added or broken off,
+				// or if we've just docked or undocked)...
+				if (this.vesselPartCountTable[vessel.id] != vessel.Parts.Count)
 				{
 					Tools.PostDebugMessage(string.Format(
-						"{0}: vessel '{1}' (id: {2}) was modified.",
+						"{0}: dirtying cache for vessel '{1}' (id: {2}).",
 						this.GetType().Name,
 						vessel.name,
 						vessel.id
 					));
 
-					this.vesselPartCountDB[vessel.id] = -1;
-				}
-			}
-		}
-
-		protected Dictionary<int, IAntennaRelay> getVesselRelays(Vessel vessel)
-		{
-			Dictionary<int, IAntennaRelay> relays;
-
-			if (this.ContainsKey(vessel))
-			{
-				relays = this.relayDatabase[vessel.id];
-				relays.Clear();
-			}
-			else
-			{
-				relays = new Dictionary<int, IAntennaRelay>();
-			}
+					// Dirty the cache (real vessels will never have negative part counts)
+					this.vesselPartCountTable[vessel.id] = -1;
+				}
+			}
+		}
+
+		// Runs when the player requests a scene change, such as when changing vessels or leaving flight.
+		public void onSceneChange(GameScenes scene)
+		{
+			// If the active vessel is a real thing...
+			if (FlightGlobals.ActiveVessel != null)
+			{
+				// ... dirty its cache
+				this.onVesselWasModified(FlightGlobals.ActiveVessel);
+			}
+		}
+
+		// Produce a Part-hashed table of relays for the given vessel
+		protected void getVesselRelays(Vessel vessel, ref Dictionary<int, IAntennaRelay> relays)
+		{
+			// We're going to completely regen this table, so dump the current contents.
+			relays.Clear();
 
 			Tools.PostDebugMessage(string.Format(
 				"{0}: Getting antenna relays from vessel {1}.",
@@ -162,14 +194,18 @@
 					vessel.name
 				));
 
-				// Gets a list of PartModules implementing IAntennaRelay
+				// Loop through the Parts in the Vessel...
 				foreach (Part part in vessel.Parts)
 				{
+					// ...loop through the PartModules in the Part...
 					foreach (PartModule module in part.Modules)
 					{
+						// ...if the module is a relay...
 						if (module is IAntennaRelay)
 						{
+							// ...add the module to the table
 							relays.Add(part.GetHashCode(), module as IAntennaRelay);
+							// ...neglect relay objects after the first in each part.
 							break;
 						}
 					}
@@ -180,23 +216,50 @@
 			{
 				Tools.PostDebugMessage(string.Format(
 					"{0}: vessel {1} is not loaded, searching for modules in prototype parts.",
-					"IAntennaRelay",
+					this.GetType().Name,
 					vessel.name
 				));
 
-				// Loop through the ProtoPartModuleSnapshots in this Vessel
+				// Loop through the ProtoPartModuleSnapshots in the Vessel...
 				foreach (ProtoPartSnapshot pps in vessel.protoVessel.protoPartSnapshots)
 				{
-					ProtoAntennaRelay protoRelay;
+					Tools.PostDebugMessage(string.Format(
+						"{0}: Searching in protopartsnapshot {1}",
+						this.GetType().Name,
+						pps
+					));
+
+					// ...Fetch the prefab, because it's more useful for what we're doing.
 					Part partPrefab = PartLoader.getPartInfoByName(pps.partName).partPrefab;
 
+					Tools.PostDebugMessage(string.Format(
+						"{0}: Got partPrefab {1} in protopartsnapshot {2}",
+						this.GetType().Name,
+						partPrefab,
+						pps
+					));
+
+					// ...loop through the PartModules in the prefab...
 					foreach (PartModule module in partPrefab.Modules)
 					{
+						Tools.PostDebugMessage(string.Format(
+							"{0}: Searching in partmodule {1}",
+							this.GetType().Name,
+							module
+						));
+
+						// ...if the module is a relay...
 						if (module is IAntennaRelay)
 						{
-							protoRelay =
-								new ProtoAntennaRelay(module as IAntennaRelay, pps);
-							relays.Add(pps.GetHashCode(), protoRelay);
+							Tools.PostDebugMessage(string.Format(
+								"{0}: partmodule {1} is antennarelay",
+								this.GetType().Name,
+								module
+							));
+
+							// ...build a new ProtoAntennaRelay and add it to the table
+							relays.Add(pps.GetHashCode(), new ProtoAntennaRelay(module as IAntennaRelay, pps));
+							// ...neglect relay objects after the first in each part.
 							break;
 						}
 					}
@@ -209,24 +272,27 @@
 				vessel.name,
 				relays.Count
 			));
-
-			// Return the list of IAntennaRelays
-			return relays;
-		}
-
+		}
+
+		// Construct the singleton
 		protected RelayDatabase()
 		{
+			// Initialize the databases
 			relayDatabase =	new Dictionary<Guid, Dictionary<int, IAntennaRelay>>();
-			vesselPartCountDB = new Dictionary<Guid, int>();
-
+			vesselPartCountTable = new Dictionary<Guid, int>();
+
+			// Subscribe to some events
 			GameEvents.onVesselWasModified.Add(this.onVesselWasModified);
 			GameEvents.onVesselChange.Add(this.onVesselWasModified);
+			GameEvents.onGameSceneLoadRequested.Add(this.onSceneChange);
 		}
 
 		~RelayDatabase()
 		{
+			// Unsubscribe from the events
 			GameEvents.onVesselWasModified.Remove(this.onVesselWasModified);
 			GameEvents.onVesselChange.Remove(this.onVesselWasModified);
+			GameEvents.onGameSceneLoadRequested.Remove(this.onSceneChange);
 
 			Tools.PostDebugMessage(this.GetType().Name + " destroyed.");
 		}