ProtoAntennaRelay: Make ToString safer.
ProtoAntennaRelay: Make ToString safer.

--- a/ARMapRenderer.cs
+++ b/ARMapRenderer.cs
@@ -38,6 +38,8 @@
 	{
 		#region Fields
 		private Dictionary<Guid, LineRenderer> vesselLineRenderers;
+		private Dictionary<Guid, bool> vesselFrameCache;
+		private bool dumpBool;
 		#endregion
 
 		#region Properties
@@ -50,21 +52,27 @@
 					this.vesselLineRenderers = new Dictionary<Guid, LineRenderer>();
 				}
 
-				if (!this.vesselLineRenderers.ContainsKey(idx))
+				LineRenderer lr;
+
+				if (this.vesselLineRenderers.TryGetValue(idx, out lr))
+				{
+					return lr;
+				}
+				else
 				{
 					GameObject obj = new GameObject();
 					obj.layer = 31;
 
-					LineRenderer lr = obj.AddComponent<LineRenderer>();
-
-					lr.SetColors(Color.green, Color.green);
+					lr = obj.AddComponent<LineRenderer>();
+
+					// lr.SetColors(Color.green, Color.green);
 					lr.material = MapView.OrbitLinesMaterial;
-					lr.SetVertexCount(2);
+					// lr.SetVertexCount(2);
 
 					this.vesselLineRenderers[idx] = lr;
-				}
-
-				return this.vesselLineRenderers[idx];
+
+					return lr;
+				}
 			}
 		}
 		#endregion
@@ -75,6 +83,7 @@
 			if (ARConfiguration.PrettyLines)
 			{
 				this.vesselLineRenderers = new Dictionary<Guid, LineRenderer>();
+				this.vesselFrameCache = new Dictionary<Guid, bool>();
 			}
 		}
 
@@ -101,6 +110,8 @@
 					MapView.MapCamera.Distance
 				);
 
+				this.vesselFrameCache.Clear();
+
 				log.AppendLine("vesselFrameCache cleared.");
 
 				if (FlightGlobals.ready && FlightGlobals.Vessels != null)
@@ -112,6 +123,12 @@
 						if (vessel == null)
 						{
 							log.AppendFormat("Skipping vessel {0} altogether because it is null.\n");
+							continue;
+						}
+
+						if (this.vesselFrameCache.TryGetValue(vessel.id, out dumpBool))
+						{
+							log.AppendFormat("Skipping vessel {0} because it's already been processed this frame.");
 							continue;
 						}
 
@@ -159,71 +176,90 @@
 
 		private void SetRelayVertices(IAntennaRelay relay)
 		{
-			if (relay == null)
-			{
-				return;
-			}
+			Color lastColor = default(Color);
+			Color thisColor;
 
 			LineRenderer renderer = this[relay.vessel.id];
-
-			Vector3d start;
-			Vector3d end;
-
-			renderer.enabled = true;
-
-			if (!relay.CanTransmit())
-			{
-				renderer.SetColors(Color.red, Color.red);
+			Vector3d start = ScaledSpace.LocalToScaledSpace(relay.vessel.GetWorldPos3D());
+
+			float lineWidth;
+			float d = Screen.height / 2f + 0.01f;
+
+			if (MapView.Draw3DLines)
+			{
+				lineWidth = 0.005859375f * MapView.MapCamera.Distance;
 			}
 			else
 			{
-				if (relay.transmitDistance < relay.nominalTransmitDistance)
-				{
-					renderer.SetColors(Color.green, Color.green);
+				lineWidth = 2f;
+
+				start = MapView.MapCamera.camera.WorldToScreenPoint(start);
+
+				start.z = start.z >= 0f ? d : -d;
+			}
+
+			renderer.SetWidth(lineWidth, lineWidth);
+
+			renderer.SetPosition(0, start);
+
+			int idx = 0;
+
+			while (relay != null)
+			{
+				Vector3d nextPoint;
+
+				renderer.enabled = true;
+
+				if (!relay.CanTransmit())
+				{
+					thisColor = Color.red;
 				}
 				else
 				{
-					renderer.SetColors(Color.yellow, Color.yellow);
-				}
-			}
-
-			start = ScaledSpace.LocalToScaledSpace(relay.vessel.GetWorldPos3D());
-
-			if (relay.KerbinDirect)
-			{
-				end = ScaledSpace.LocalToScaledSpace(AntennaRelay.Kerbin.position);
-			}
-			else
-			{
-				if (relay.targetRelay == null)
-				{
-					return;
-				}
-				end = ScaledSpace.LocalToScaledSpace(relay.targetRelay.vessel.GetWorldPos3D());
-			}
-
-			float lineWidth;
-
-			if (MapView.Draw3DLines)
-			{
-				lineWidth = 0.005859375f * MapView.MapCamera.Distance;
-			}
-			else
-			{
-				lineWidth = 2f;
-
-				start = MapView.MapCamera.camera.WorldToScreenPoint(start);
-				end = MapView.MapCamera.camera.WorldToScreenPoint(end);
-
-				float d = Screen.height / 2f + 0.01f;
-				start.z = start.z >= 0f ? d : -d;
-				end.z = end.z >= 0f ? d : -d;
-			}
-
-			renderer.SetWidth(lineWidth, lineWidth);
-
-			renderer.SetPosition(0, start);
-			renderer.SetPosition(1, end);
+					if (relay.transmitDistance < relay.nominalTransmitDistance)
+					{
+						thisColor = Color.green;
+					}
+					else
+					{
+						thisColor = Color.yellow;
+					}
+				}
+
+				if (lastColor != default(Color) && thisColor != lastColor)
+				{
+					break;
+				}
+
+				lastColor = thisColor;
+				renderer.SetColors(thisColor, thisColor);
+
+				this.vesselFrameCache[relay.vessel.id] = true;
+
+				if (relay.KerbinDirect)
+				{
+					nextPoint = ScaledSpace.LocalToScaledSpace(AntennaRelay.Kerbin.position);
+					relay = null;
+				}
+				else
+				{
+					if (relay.targetRelay == null)
+					{
+						return;
+					}
+
+					nextPoint = ScaledSpace.LocalToScaledSpace(relay.targetRelay.vessel.GetWorldPos3D());
+					relay = relay.targetRelay;
+				}
+
+				if (!MapView.Draw3DLines)
+				{
+					nextPoint = MapView.MapCamera.camera.WorldToScreenPoint(nextPoint);
+					nextPoint.z = nextPoint.z >= 0f ? d : -d;
+				}
+
+				renderer.SetPosition(++idx, nextPoint);
+			}
 		}
 
 		public void Cleanup()
@@ -237,6 +273,11 @@
 				}
 				this.vesselLineRenderers.Clear();
 			}
+
+			if (this.vesselFrameCache != null && this.vesselFrameCache.Count > 0)
+			{
+				this.vesselFrameCache.Clear();
+			}
 		}
 	}
 }

--- a/ProtoAntennaRelay.cs
+++ b/ProtoAntennaRelay.cs
@@ -126,11 +126,16 @@
 		/// <returns>A <see cref="System.String"/> that represents the current <see cref="AntennaRange.ProtoAntennaRelay"/>.</returns>
 		public override string ToString()
 		{
-			return string.Format(
-				"{0} on {1}",
-				this.Title,
-				this.protoPart.pVesselRef.vesselName
-			);
+			System.Text.StringBuilder sb = new System.Text.StringBuilder();
+
+			sb.Append(this.Title);
+
+			if (this.protoPart != null && this.protoPart.pVesselRef != null)
+			{
+				sb.AppendFormat(" on {0}", this.protoPart.pVesselRef.vesselName);
+			}
+
+			return sb.ToString();
 		}
 
 		/// <summary>