AntennaRelay: Added tracking of first body to block line of sight.
AntennaRelay: Added tracking of first body to block line of sight.

--- a/ARFlightController.cs
+++ b/ARFlightController.cs
@@ -64,7 +64,7 @@
 		{
 			get
 			{
-				return ControlTypes.GROUPS_ALL | ControlTypes.STAGING | ControlTypes.SAS | ControlTypes.RCS;
+				return ControlTypes.ALL_SHIP_CONTROLS;
 			}
 		}
 
@@ -86,37 +86,59 @@
 		protected void Awake()
 		{
 			this.lockID = "ARConnectionRequired";
+
+			GameEvents.onGameSceneLoadRequested.Add(this.onSceneChangeRequested);
+			GameEvents.onVesselChange.Add(this.onVesselChange);
 		}
 
 		protected void FixedUpdate()
 		{
+			// If we are requiring a connection for control, the vessel does not have any adequately staffed pods,
+			// and the vessel does not have any connected relays...
 			if (
+				HighLogic.LoadedSceneIsFlight &&
 				requireConnectionForControl &&
 				this.vessel != null &&
+				this.vessel.vesselType != VesselType.EVA &&
 				!this.vessel.hasCrewCommand() &&
-				this.vessel.IsControllable
-			)
+				!this.vessel.HasConnectedRelay())
 			{
-				if (this.vessel.HasConnectedRelay())
+				// ...and if the controls are not currently locked...
+				if (currentControlLock == ControlTypes.None)
 				{
-					if (currentControlLock != ControlTypes.None)
-					{
-						InputLockManager.RemoveControlLock(this.lockID);
-					}
+					// ...lock the controls.
+					InputLockManager.SetControlLock(this.lockSet, this.lockID);
 				}
-				else
-				{
-					if (currentControlLock == ControlTypes.None)
-					{
-						InputLockManager.SetControlLock(this.lockSet, this.lockID);
-					}
-				}
+			}
+			// ...otherwise, if the controls are locked...
+			else if (currentControlLock != ControlTypes.None)
+			{
+				// ...unlock the controls.
+				InputLockManager.RemoveControlLock(this.lockID);
 			}
 		}
 
 		protected void Destroy()
 		{
+			InputLockManager.RemoveControlLock(this.lockID);
 
+			GameEvents.onGameSceneLoadRequested.Remove(this.onSceneChangeRequested);
+			GameEvents.onVesselChange.Remove(this.onVesselChange);
+		}
+		#endregion
+
+		#region Event Handlers
+		protected void onSceneChangeRequested(GameScenes scene)
+		{
+			if (scene != GameScenes.FLIGHT)
+			{
+				InputLockManager.RemoveControlLock(this.lockID);
+			}
+		}
+
+		protected void onVesselChange(Vessel vessel)
+		{
+			InputLockManager.RemoveControlLock(this.lockID);
 		}
 		#endregion
 	}

--- a/AntennaRelay.cs
+++ b/AntennaRelay.cs
@@ -40,6 +40,8 @@
 		// We don't have a Bard, so we'll hide Kerbin here.
 		protected CelestialBody Kerbin;
 
+		protected CelestialBody _firstOccludingBody;
+
 		protected IAntennaRelay _nearestRelayCache;
 		protected IAntennaRelay moduleRef;
 
@@ -82,6 +84,18 @@
 		}
 
 		/// <summary>
+		/// Gets the first occluding body.
+		/// </summary>
+		/// <value>The first occluding body.</value>
+		public CelestialBody firstOccludingBody
+		{
+			get
+			{
+				return this._firstOccludingBody;
+			}
+		}
+
+		/// <summary>
 		/// Gets the transmit distance.
 		/// </summary>
 		/// <value>The transmit distance.</value>
@@ -134,7 +148,11 @@
 		{
 			if (
 				this.transmitDistance > this.maxTransmitDistance ||
-				(requireLineOfSight && this.nearestRelay == null && !this.vessel.hasLineOfSightTo(this.Kerbin))
+				(
+					requireLineOfSight &&
+					this.nearestRelay == null &&
+					!this.vessel.hasLineOfSightTo(this.Kerbin, out this._firstOccludingBody)
+				)
 			)
 			{
 				return false;
@@ -170,6 +188,8 @@
 				this,
 				this.vessel.id
 			));
+
+			this._firstOccludingBody = null;
 
 			// Set this vessel as checked, so that we don't check it again.
 			RelayDatabase.Instance.CheckedVesselsTable[vessel.id] = true;
@@ -211,7 +231,7 @@
 				}
 
 				// Skip vessels to which we do not have line of sight.
-				if (requireLineOfSight && !this.vessel.hasLineOfSightTo(potentialVessel))
+				if (requireLineOfSight && !this.vessel.hasLineOfSightTo(potentialVessel, out this._firstOccludingBody))
 				{
 					Tools.PostDebugMessage(
 						this,

--- a/ModuleLimitedDataTransmitter.cs
+++ b/ModuleLimitedDataTransmitter.cs
@@ -300,6 +300,8 @@
 				base.packetResourceCost = this._basepacketResourceCost
 					* (float)Math.Pow (this.transmitDistance / this.nominalRange, 2);
 			}
+
+			base.packetResourceCost *= this.packetThrottle / 100f;
 		}
 
 		// Before transmission, set packetSize.  Per above, packet size increases with the inverse square of