Version 1.2
--- a/ARConfiguration.cs
+++ b/ARConfiguration.cs
@@ -19,6 +19,20 @@
private Rect configWindowPos;
private IButton toolbarButton;
+
+ private KSP.IO.PluginConfiguration _config;
+ private KSP.IO.PluginConfiguration config
+ {
+ get
+ {
+ if (this._config == null)
+ {
+ this._config = KSP.IO.PluginConfiguration.CreateForType<AntennaRelay>();
+ }
+
+ return this._config;
+ }
+ }
public void Awake()
{
@@ -46,14 +60,10 @@
this.showConfigWindow = !this.showConfigWindow;
};
- var config = KSP.IO.PluginConfiguration.CreateForType<AntennaRelay>();
-
- config.load();
-
- this.configWindowPos = config.GetValue<Rect>("configWindowPos", this.configWindowPos);
- AntennaRelay.requireLineOfSight = config.GetValue<bool>("requireLineOfSight", false);
-
- config.save();
+ this.configWindowPos = this.LoadConfigValue("configWindowPos", this.configWindowPos);
+ AntennaRelay.requireLineOfSight = this.LoadConfigValue("requireLineOfSight", false);
+ ARFlightController.requireConnectionForControl =
+ this.LoadConfigValue("requireConnectionForControl", false);
}
if (this.showConfigWindow)
@@ -81,11 +91,27 @@
GUILayout.BeginVertical(GUILayout.ExpandHeight(true));
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
+
bool requireLineOfSight = GUILayout.Toggle(AntennaRelay.requireLineOfSight, "Require Line of Sight");
if (requireLineOfSight != AntennaRelay.requireLineOfSight)
{
AntennaRelay.requireLineOfSight = requireLineOfSight;
this.SaveConfigValue("requireLineOfSight", requireLineOfSight);
+ }
+
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
+
+ bool requireConnectionForControl =
+ GUILayout.Toggle(
+ ARFlightController.requireConnectionForControl,
+ "Require Connection for Probe Control"
+ );
+ if (requireConnectionForControl != ARFlightController.requireConnectionForControl)
+ {
+ ARFlightController.requireConnectionForControl = requireConnectionForControl;
+ this.SaveConfigValue("requireConnectionForControl", requireConnectionForControl);
}
GUILayout.EndHorizontal();
@@ -105,22 +131,18 @@
private T LoadConfigValue<T>(string key, T defaultValue)
{
- var config = KSP.IO.PluginConfiguration.CreateForType<AntennaRelay>();
-
- config.load();
+ this.config.load();
return config.GetValue(key, defaultValue);
}
private void SaveConfigValue<T>(string key, T value)
{
- var config = KSP.IO.PluginConfiguration.CreateForType<AntennaRelay>();
+ this.config.load();
- config.load();
+ this.config.SetValue(key, value);
- config.SetValue(key, value);
-
- config.save();
+ this.config.save();
}
}
}
--- a/ARFlightController.cs
+++ b/ARFlightController.cs
@@ -25,15 +25,122 @@
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+using KSP;
using System;
+using ToadicusTools;
+using UnityEngine;
namespace AntennaRange
{
- public class ARFlightController
+ [KSPAddon(KSPAddon.Startup.Flight, false)]
+ public class ARFlightController : MonoBehaviour
{
- public ARFlightController()
+ #region Static Members
+ public static bool requireConnectionForControl;
+ #endregion
+
+ #region Properties
+ public ControlTypes currentControlLock
{
+ get
+ {
+ if (this.lockID == string.Empty)
+ {
+ return ControlTypes.None;
+ }
+
+ return InputLockManager.GetControlLock(this.lockID);
+ }
}
+
+ public string lockID
+ {
+ get;
+ protected set;
+ }
+
+ public ControlTypes lockSet
+ {
+ get
+ {
+ return ControlTypes.ALL_SHIP_CONTROLS;
+ }
+ }
+
+ public Vessel vessel
+ {
+ get
+ {
+ if (FlightGlobals.ready && FlightGlobals.ActiveVessel != null)
+ {
+ return FlightGlobals.ActiveVessel;
+ }
+
+ return null;
+ }
+ }
+ #endregion
+
+ #region MonoBehaviour LifeCycle
+ 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.HasConnectedRelay())
+ {
+ // ...and if the controls are not currently locked...
+ if (currentControlLock == ControlTypes.None)
+ {
+ // ...lock the controls.
+ 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/AntennaRange.csproj
+++ b/AntennaRange.csproj
@@ -12,6 +12,7 @@
<ReleaseVersion>1.1</ReleaseVersion>
<SynchReleaseVersion>false</SynchReleaseVersion>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <UseMSBuildEngine>False</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug_win|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -87,20 +88,23 @@
</None>
</ItemGroup>
<ItemGroup>
+ <Reference Include="Assembly-CSharp">
+ <HintPath>..\_KSPAssemblies\Assembly-CSharp.dll</HintPath>
+ <Private>False</Private>
+ </Reference>
+ <Reference Include="System">
+ <HintPath>..\_KSPAssemblies\System.dll</HintPath>
+ <Private>False</Private>
+ </Reference>
+ <Reference Include="UnityEngine">
+ <HintPath>..\_KSPAssemblies\UnityEngine.dll</HintPath>
+ <Private>False</Private>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
<ProjectReference Include="..\ToadicusTools\ToadicusTools.csproj">
<Project>{D48A5542-6655-4149-BC27-B27DF0466F1C}</Project>
<Name>ToadicusTools</Name>
</ProjectReference>
</ItemGroup>
- <ItemGroup>
- <Reference Include="Assembly-CSharp">
- <HintPath>..\_KSPAssemblies\Assembly-CSharp.dll</HintPath>
- </Reference>
- <Reference Include="System">
- <HintPath>..\_KSPAssemblies\System.dll</HintPath>
- </Reference>
- <Reference Include="UnityEngine">
- <HintPath>..\_KSPAssemblies\UnityEngine.dll</HintPath>
- </Reference>
- </ItemGroup>
</Project>
--- 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
@@ -73,6 +73,9 @@
// and packetSize.
[KSPField(isPersistant = false)]
public float nominalRange;
+
+ [KSPField(isPersistant = false, guiActive = true, guiName = "Relay")]
+ public string UIrelayStatus;
[KSPField(isPersistant = false, guiActive = true, guiName = "Transmission Distance")]
public string UItransmitDistance;
@@ -300,6 +303,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
@@ -437,9 +442,27 @@
{
if (this.actionUIUpdate)
{
- this.UItransmitDistance = Tools.MuMech_ToSI(this.transmitDistance) + "m";
- this.UIpacketSize = this.CanTransmit() ? Tools.MuMech_ToSI(this.DataRate) + "MiT" : "N/A";
- this.UIpacketCost = this.CanTransmit() ? Tools.MuMech_ToSI(this.DataResourceCost) + "E" : "N/A";
+ if (this.CanTransmit())
+ {
+ this.UIrelayStatus = string.Intern("Connected");
+ this.UItransmitDistance = Tools.MuMech_ToSI(this.transmitDistance) + "m";
+ this.UIpacketSize = Tools.MuMech_ToSI(this.DataRate) + "MiT";
+ this.UIpacketCost = Tools.MuMech_ToSI(this.DataResourceCost) + "E";
+ }
+ else
+ {
+ if (this.relay.firstOccludingBody == null)
+ {
+ this.UIrelayStatus = string.Intern("Out of range");
+ }
+ else
+ {
+ this.UIrelayStatus = string.Format("Blocked by {0}", this.relay.firstOccludingBody.bodyName);
+ }
+ this.UImaxTransmitDistance = "N/A";
+ this.UIpacketSize = "N/A";
+ this.UIpacketCost = "N/A";
+ }
}
}
--- a/Properties/AssemblyInfo.cs
+++ b/Properties/AssemblyInfo.cs
@@ -37,7 +37,7 @@
// 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("1.1.*")]
+[assembly: AssemblyVersion("1.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)]
--- a/RelayExtensions.cs
+++ b/RelayExtensions.cs
@@ -76,6 +76,24 @@
{
return RelayDatabase.Instance[vessel].Values.ToList();
}
+
+ /// <summary>
+ /// Determines if the specified vessel has a connected relay.
+ /// </summary>
+ /// <returns><c>true</c> if the specified vessel has a connected relay; otherwise, <c>false</c>.</returns>
+ /// <param name="vessel"></param>
+ public static bool HasConnectedRelay(this Vessel vessel)
+ {
+ foreach (IAntennaRelay relay in RelayDatabase.Instance[vessel].Values)
+ {
+ if (relay.CanTransmit())
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
}