Removed .dll from version control.
--- /dev/null
+++ b/ARConfiguration.cs
@@ -1,1 +1,239 @@
-
+// AntennaRange © 2014 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/
+
+using KSP;
+using System;
+using ToadicusTools;
+using UnityEngine;
+
+namespace AntennaRange
+{
+ [KSPAddon(KSPAddon.Startup.SpaceCentre, false)]
+ public class ARConfiguration : MonoBehaviour
+ {
+ private bool showConfigWindow;
+ private Rect configWindowPos;
+
+ private IButton toolbarButton;
+ private ApplicationLauncherButton appLauncherButton;
+
+ private System.Version runningVersion;
+
+ 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()
+ {
+ Tools.PostDebugMessage(this, "Waking up.");
+
+ this.runningVersion = this.GetType().Assembly.GetName().Version;
+
+ this.showConfigWindow = false;
+ this.configWindowPos = new Rect(Screen.width / 4, Screen.height / 2, 180, 15);
+
+
+ this.configWindowPos = this.LoadConfigValue("configWindowPos", this.configWindowPos);
+
+ AntennaRelay.requireLineOfSight = this.LoadConfigValue("requireLineOfSight", false);
+
+ AntennaRelay.radiusRatio = (1 - this.LoadConfigValue("graceRatio", .05d));
+ AntennaRelay.radiusRatio *= AntennaRelay.radiusRatio;
+
+ ARFlightController.requireConnectionForControl =
+ this.LoadConfigValue("requireConnectionForControl", false);
+
+ ModuleLimitedDataTransmitter.fixedPowerCost = this.LoadConfigValue("fixedPowerCost", false);
+
+ GameEvents.onGameSceneLoadRequested.Add(this.onSceneChangeRequested);
+
+ Debug.Log(string.Format("{0} v{1} - ARConfiguration loaded!", this.GetType().Name, this.runningVersion));
+
+ Tools.PostDebugMessage(this, "Awake.");
+ }
+
+ public void OnGUI()
+ {
+ // Only runs once, if the Toolbar is available.
+ if (ToolbarManager.ToolbarAvailable)
+ {
+ if (this.toolbarButton == null)
+ {
+ Tools.PostDebugMessage(this, "Toolbar available; initializing toolbar button.");
+
+ this.toolbarButton = ToolbarManager.Instance.add("AntennaRange", "ARConfiguration");
+ this.toolbarButton.Visibility = new GameScenesVisibility(GameScenes.SPACECENTER);
+ this.toolbarButton.Text = "AR";
+ this.toolbarButton.TexturePath = "AntennaRange/Textures/toolbarIcon";
+ this.toolbarButton.TextColor = (Color)XKCDColors.Amethyst;
+ this.toolbarButton.OnClick += delegate(ClickEvent e)
+ {
+ this.toggleConfigWindow();
+ };
+ }
+ }
+ else if (this.appLauncherButton == null && ApplicationLauncher.Ready)
+ {
+ Tools.PostDebugMessage(this, "Toolbar available; initializing AppLauncher button.");
+
+ this.appLauncherButton = ApplicationLauncher.Instance.AddModApplication(
+ this.toggleConfigWindow,
+ this.toggleConfigWindow,
+ ApplicationLauncher.AppScenes.SPACECENTER,
+ GameDatabase.Instance.GetTexture(
+ "AntennaRange/Textures/appLauncherIcon",
+ false
+ )
+ );
+ }
+
+ if (this.showConfigWindow)
+ {
+ Rect configPos = GUILayout.Window(354163056,
+ this.configWindowPos,
+ this.ConfigWindow,
+ string.Format("AntennaRange {0}.{1}", this.runningVersion.Major, this.runningVersion.Minor),
+ GUILayout.ExpandHeight(true),
+ GUILayout.ExpandWidth(true)
+ );
+
+ configPos = Tools.ClampRectToScreen(configPos, 20);
+
+ if (configPos != this.configWindowPos)
+ {
+ this.configWindowPos = configPos;
+ this.SaveConfigValue("configWindowPos", this.configWindowPos);
+ }
+ }
+ }
+
+ public void ConfigWindow(int _)
+ {
+ 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();
+
+ GUILayout.BeginHorizontal();
+
+ bool fixedPowerCost = GUILayout.Toggle(ModuleLimitedDataTransmitter.fixedPowerCost, "Use Fixed Power Cost");
+ if (fixedPowerCost != ModuleLimitedDataTransmitter.fixedPowerCost)
+ {
+ ModuleLimitedDataTransmitter.fixedPowerCost = fixedPowerCost;
+ this.SaveConfigValue("fixedPowerCost", fixedPowerCost);
+ }
+
+ GUILayout.EndHorizontal();
+
+ if (requireLineOfSight)
+ {
+ GUILayout.BeginHorizontal();
+
+ double graceRatio = 1d - Math.Sqrt(AntennaRelay.radiusRatio);
+ double newRatio;
+
+ GUILayout.Label(string.Format("Line of Sight 'Fudge Factor': {0:P0}", graceRatio));
+
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal();
+
+ newRatio = GUILayout.HorizontalSlider((float)graceRatio, 0f, 1f, GUILayout.ExpandWidth(true));
+ newRatio = Math.Round(newRatio, 2);
+
+ if (newRatio != graceRatio)
+ {
+ AntennaRelay.radiusRatio = (1d - newRatio) * (1d - newRatio);
+ this.SaveConfigValue("graceRatio", newRatio);
+ }
+
+ GUILayout.EndHorizontal();
+ }
+
+ GUILayout.EndVertical();
+
+ GUI.DragWindow();
+ }
+
+ public void OnDestroy()
+ {
+ GameEvents.onGameSceneLoadRequested.Remove(this.onSceneChangeRequested);
+
+ if (this.toolbarButton != null)
+ {
+ this.toolbarButton.Destroy();
+ }
+
+ if (this.appLauncherButton != null)
+ {
+ ApplicationLauncher.Instance.RemoveModApplication(this.appLauncherButton);
+ }
+ }
+
+ protected void onSceneChangeRequested(GameScenes scene)
+ {
+ if (scene != GameScenes.SPACECENTER)
+ {
+ print("ARConfiguration: Requesting Destruction.");
+ MonoBehaviour.Destroy(this);
+ }
+ }
+
+ private void toggleConfigWindow()
+ {
+ this.showConfigWindow = !this.showConfigWindow;
+ }
+
+ private T LoadConfigValue<T>(string key, T defaultValue)
+ {
+ this.config.load();
+
+ return config.GetValue(key, defaultValue);
+ }
+
+ private void SaveConfigValue<T>(string key, T value)
+ {
+ this.config.load();
+
+ this.config.SetValue(key, value);
+
+ this.config.save();
+ }
+ }
+}
+
--- /dev/null
+++ b/ARFlightController.cs
@@ -1,1 +1,334 @@
-
+// AntennaRange
+//
+// ARFlightController.cs
+//
+// Copyright © 2014, toadicus
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be used
+// to endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// 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 System.Collections.Generic;
+using ToadicusTools;
+using UnityEngine;
+
+namespace AntennaRange
+{
+ [KSPAddon(KSPAddon.Startup.Flight, false)]
+ public class ARFlightController : MonoBehaviour
+ {
+ #region Static Members
+ public static bool requireConnectionForControl;
+ #endregion
+
+ #region Fields
+ protected Dictionary<ConnectionStatus, string> connectionTextures;
+ protected Dictionary<ConnectionStatus, Texture> appLauncherTextures;
+
+ protected IButton toolbarButton;
+
+ protected ApplicationLauncherButton appLauncherButton;
+ #endregion
+
+ #region Properties
+ public ConnectionStatus currentConnectionStatus
+ {
+ get;
+ protected set;
+ }
+
+ protected string currentConnectionTexture
+ {
+ get
+ {
+ return this.connectionTextures[this.currentConnectionStatus];
+ }
+ }
+
+ protected Texture currentAppLauncherTexture
+ {
+ get
+ {
+ return this.appLauncherTextures[this.currentConnectionStatus];
+ }
+ }
+
+ 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";
+
+ this.connectionTextures = new Dictionary<ConnectionStatus, string>();
+
+ this.connectionTextures[ConnectionStatus.None] = "AntennaRange/Textures/toolbarIconNoConnection";
+ this.connectionTextures[ConnectionStatus.Suboptimal] = "AntennaRange/Textures/toolbarIconSubOptimal";
+ this.connectionTextures[ConnectionStatus.Optimal] = "AntennaRange/Textures/toolbarIcon";
+
+ this.appLauncherTextures = new Dictionary<ConnectionStatus, Texture>();
+
+ this.appLauncherTextures[ConnectionStatus.None] =
+ GameDatabase.Instance.GetTexture("AntennaRange/Textures/appLauncherIconNoConnection", false);
+ this.appLauncherTextures[ConnectionStatus.Suboptimal] =
+ GameDatabase.Instance.GetTexture("AntennaRange/Textures/appLauncherIconSubOptimal", false);
+ this.appLauncherTextures[ConnectionStatus.Optimal] =
+ GameDatabase.Instance.GetTexture("AntennaRange/Textures/appLauncherIcon", false);
+
+ if (ToolbarManager.ToolbarAvailable)
+ {
+ this.toolbarButton = ToolbarManager.Instance.add("AntennaRange", "ARConnectionStatus");
+
+ this.toolbarButton.TexturePath = this.connectionTextures[ConnectionStatus.None];
+ this.toolbarButton.Text = "AntennaRange";
+ this.toolbarButton.Visibility = new GameScenesVisibility(GameScenes.FLIGHT);
+ this.toolbarButton.Enabled = false;
+ }
+
+ GameEvents.onGameSceneLoadRequested.Add(this.onSceneChangeRequested);
+ GameEvents.onVesselChange.Add(this.onVesselChange);
+ }
+
+ protected void FixedUpdate()
+ {
+ if (this.appLauncherButton == null && !ToolbarManager.ToolbarAvailable && ApplicationLauncher.Ready)
+ {
+ this.appLauncherButton = ApplicationLauncher.Instance.AddModApplication(
+ ApplicationLauncher.AppScenes.FLIGHT,
+ this.appLauncherTextures[ConnectionStatus.None]
+ );
+ }
+
+ Tools.DebugLogger log = Tools.DebugLogger.New(this);
+
+ VesselCommand availableCommand;
+
+ if (requireConnectionForControl)
+ {
+ availableCommand = this.vessel.CurrentCommand();
+ }
+ else
+ {
+ availableCommand = VesselCommand.Crew;
+ }
+
+ log.AppendFormat("availableCommand: {0}\n\t" +
+ "(availableCommand & VesselCommand.Crew) == VesselCommand.Crew: {1}\n\t" +
+ "(availableCommand & VesselCommand.Probe) == VesselCommand.Probe: {2}\n\t" +
+ "vessel.HasConnectedRelay(): {3}",
+ (int)availableCommand,
+ (availableCommand & VesselCommand.Crew) == VesselCommand.Crew,
+ (availableCommand & VesselCommand.Probe) == VesselCommand.Probe,
+ vessel.HasConnectedRelay()
+ );
+
+ // 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 &&
+ !(
+ (availableCommand & VesselCommand.Crew) == VesselCommand.Crew ||
+ (availableCommand & VesselCommand.Probe) == VesselCommand.Probe && 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);
+ }
+
+ if (
+ (this.toolbarButton != null || this.appLauncherButton != null) &&
+ HighLogic.LoadedSceneIsFlight &&
+ FlightGlobals.ActiveVessel != null
+ )
+ {
+ log.Append("Checking vessel relay status.\n");
+
+ List<ModuleLimitedDataTransmitter> relays =
+ FlightGlobals.ActiveVessel.getModulesOfType<ModuleLimitedDataTransmitter>();
+
+ log.AppendFormat("\t...found {0} relays\n", relays.Count);
+
+ bool vesselCanTransmit = false;
+ bool vesselHasOptimalRelay = false;
+
+ foreach (ModuleLimitedDataTransmitter relay in relays)
+ {
+ log.AppendFormat("\tvesselCanTransmit: {0}, vesselHasOptimalRelay: {1}\n",
+ vesselCanTransmit, vesselHasOptimalRelay);
+
+ log.AppendFormat("\tChecking relay {0}\n" +
+ "\t\tCanTransmit: {1}, transmitDistance: {2}, nominalRange: {3}\n",
+ relay,
+ relay.CanTransmit(),
+ relay.transmitDistance,
+ relay.nominalRange
+ );
+
+ bool relayCanTransmit = relay.CanTransmit();
+
+ if (!vesselCanTransmit && relayCanTransmit)
+ {
+ vesselCanTransmit = true;
+ }
+
+ if (!vesselHasOptimalRelay &&
+ relayCanTransmit &&
+ relay.transmitDistance <= (double)relay.nominalRange)
+ {
+ vesselHasOptimalRelay = true;
+ }
+
+ if (vesselCanTransmit && vesselHasOptimalRelay)
+ {
+ break;
+ }
+ }
+
+ log.AppendFormat("Done checking. vesselCanTransmit: {0}, vesselHasOptimalRelay: {1}\n",
+ vesselCanTransmit, vesselHasOptimalRelay);
+
+ if (vesselHasOptimalRelay)
+ {
+ this.currentConnectionStatus = ConnectionStatus.Optimal;
+ }
+ else if (vesselCanTransmit)
+ {
+ this.currentConnectionStatus = ConnectionStatus.Suboptimal;
+ }
+ else
+ {
+ this.currentConnectionStatus = ConnectionStatus.None;
+ }
+
+ log.AppendFormat("currentConnectionStatus: {0}, setting texture to {1}",
+ this.currentConnectionStatus, this.currentConnectionTexture);
+
+ if (this.toolbarButton != null)
+ {
+ this.toolbarButton.TexturePath = this.currentConnectionTexture;
+ }
+ if (this.appLauncherButton != null)
+ {
+ this.appLauncherButton.SetTexture(this.currentAppLauncherTexture);
+ }
+ }
+
+ log.Print();
+ }
+
+ protected void OnDestroy()
+ {
+ InputLockManager.RemoveControlLock(this.lockID);
+
+ if (this.toolbarButton != null)
+ {
+ this.toolbarButton.Destroy();
+ }
+
+ if (this.appLauncherButton != null)
+ {
+ ApplicationLauncher.Instance.RemoveModApplication(this.appLauncherButton);
+ this.appLauncherButton = null;
+ }
+
+ GameEvents.onGameSceneLoadRequested.Remove(this.onSceneChangeRequested);
+ GameEvents.onVesselChange.Remove(this.onVesselChange);
+
+ print("ARFlightController: Destroyed.");
+ }
+ #endregion
+
+ #region Event Handlers
+ protected void onSceneChangeRequested(GameScenes scene)
+ {
+ print("ARFlightController: Requesting Destruction.");
+ MonoBehaviour.Destroy(this);
+ }
+
+ protected void onVesselChange(Vessel vessel)
+ {
+ InputLockManager.RemoveControlLock(this.lockID);
+ }
+ #endregion
+
+ public enum ConnectionStatus
+ {
+ None,
+ Suboptimal,
+ Optimal
+ }
+ }
+}
+
--- a/ARTools.cs
+++ /dev/null
@@ -1,158 +1,1 @@
-// 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
-{
- 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)
- {
- if (HighLogic.LoadedScene > GameScenes.SPACECENTER)
- {
- debugmsg.message = Msg;
- ScreenMessages.PostScreenMessage(debugmsg, true);
- }
-
- KSPLog.print(Msg);
- }
-
- /*
- * MuMech_ToSI is a part of the MuMechLib library, © 2013 r4m0n, used under the GNU GPL version 3.
- * */
- public static string MuMech_ToSI(double d, int digits = 3, int MinMagnitude = 0, int MaxMagnitude = int.MaxValue)
- {
- float exponent = (float)Math.Log10(Math.Abs(d));
- exponent = UnityEngine.Mathf.Clamp(exponent, (float)MinMagnitude, (float)MaxMagnitude);
-
- if (exponent >= 0)
- {
- switch ((int)Math.Floor(exponent))
- {
- case 0:
- case 1:
- case 2:
- return d.ToString("F" + digits);
- case 3:
- case 4:
- case 5:
- return (d / 1e3).ToString("F" + digits) + "k";
- case 6:
- case 7:
- case 8:
- return (d / 1e6).ToString("F" + digits) + "M";
- case 9:
- case 10:
- case 11:
- return (d / 1e9).ToString("F" + digits) + "G";
- case 12:
- case 13:
- case 14:
- return (d / 1e12).ToString("F" + digits) + "T";
- case 15:
- case 16:
- case 17:
- return (d / 1e15).ToString("F" + digits) + "P";
- case 18:
- case 19:
- case 20:
- return (d / 1e18).ToString("F" + digits) + "E";
- case 21:
- case 22:
- case 23:
- return (d / 1e21).ToString("F" + digits) + "Z";
- default:
- return (d / 1e24).ToString("F" + digits) + "Y";
- }
- }
- else if (exponent < 0)
- {
- switch ((int)Math.Floor(exponent))
- {
- case -1:
- case -2:
- case -3:
- return (d * 1e3).ToString("F" + digits) + "m";
- case -4:
- case -5:
- case -6:
- return (d * 1e6).ToString("F" + digits) + "μ";
- case -7:
- case -8:
- case -9:
- return (d * 1e9).ToString("F" + digits) + "n";
- case -10:
- case -11:
- case -12:
- return (d * 1e12).ToString("F" + digits) + "p";
- case -13:
- case -14:
- case -15:
- return (d * 1e15).ToString("F" + digits) + "f";
- case -16:
- case -17:
- case -18:
- return (d * 1e18).ToString("F" + digits) + "a";
- case -19:
- case -20:
- case -21:
- return (d * 1e21).ToString("F" + digits) + "z";
- default:
- return (d * 1e24).ToString("F" + digits) + "y";
- }
- }
- else
- {
- return "0";
- }
- }
-
- public static T Min<T>(params T[] values) where T : IComparable<T>
- {
- if (values.Length < 2)
- {
- throw new ArgumentException("Min must be called with at least two arguments.");
- }
-
- IComparable<T> minValue = values[0];
-
- for (long i = 1; i < values.LongLength; i++)
- {
- IComparable<T> value = values[i];
-
- if (value.CompareTo((T)minValue) < 0)
- {
- minValue = value;
- }
- }
-
- return (T)minValue;
- }
-
- public static void Restart(this System.Diagnostics.Stopwatch stopwatch)
- {
- stopwatch.Reset();
- stopwatch.Start();
- }
- }
-}
-
-
--- a/AntennaRange.cfg
+++ /dev/null
@@ -1,50 +1,1 @@
-//
-// 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
- }
-}
-
--- /dev/null
+++ b/AntennaRange.csproj
@@ -1,1 +1,107 @@
-
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug_win</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{B36F2C11-962E-4A75-9F41-61AD56D11493}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <RootNamespace>AntennaRange</RootNamespace>
+ <AssemblyName>AntennaRange</AssemblyName>
+ <ReleaseVersion>1.3</ReleaseVersion>
+ <SynchReleaseVersion>false</SynchReleaseVersion>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <UseMSBuildEngine>False</UseMSBuildEngine>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug_win|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug</OutputPath>
+ <DefineConstants>DEBUG;TRACE;</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <ConsolePause>false</ConsolePause>
+ <CustomCommands>
+ <CustomCommands>
+ <Command type="AfterBuild" command="xcopy /y ${TargetFile} ${ProjectDir}\GameData\AntennaRange\" />
+ </CustomCommands>
+ </CustomCommands>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_win|AnyCPU' ">
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <ConsolePause>false</ConsolePause>
+ <CustomCommands>
+ <CustomCommands>
+ <Command type="AfterBuild" command="xcopy /y ${TargetFile} ${ProjectDir}\GameData\AntennaRange\" />
+ </CustomCommands>
+ </CustomCommands>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug_linux|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug</OutputPath>
+ <DefineConstants>DEBUG;TRACE;</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <ConsolePause>false</ConsolePause>
+ <CustomCommands>
+ <CustomCommands>
+ <Command type="AfterBuild" command="cp -afv ${TargetFile} ${ProjectDir}/GameData/${ProjectName}/" />
+ </CustomCommands>
+ </CustomCommands>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_linux|AnyCPU' ">
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CustomCommands>
+ <CustomCommands>
+ <Command type="AfterBuild" command="cp -afv ${TargetFile} ${ProjectDir}/GameData/${ProjectName}/" />
+ </CustomCommands>
+ </CustomCommands>
+ <ConsolePause>false</ConsolePause>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="IAntennaRelay.cs" />
+ <Compile Include="ModuleLimitedDataTransmitter.cs" />
+ <Compile Include="AntennaRelay.cs" />
+ <Compile Include="ProtoAntennaRelay.cs" />
+ <Compile Include="RelayDatabase.cs" />
+ <Compile Include="RelayExtensions.cs" />
+ <Compile Include="ARConfiguration.cs" />
+ <Compile Include="ARFlightController.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <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>
+ <None Include="GameData\AntennaRange\AntennaRange.cfg" />
+ <None Include="GameData\AntennaRange\ATM_AntennaRange.cfg" />
+ </ItemGroup>
+</Project>
--- a/AntennaRelay.cs
+++ b/AntennaRelay.cs
@@ -1,31 +1,48 @@
-// 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.
+// AntennaRange
+//
+// AntennaRelay.cs
+//
+// Copyright © 2014, toadicus
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be used
+// to endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// 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 System;
using System.Collections.Generic;
using System.Linq;
+using ToadicusTools;
namespace AntennaRange
{
public class AntennaRelay
{
+ public static bool requireLineOfSight;
+ public static double radiusRatio;
+
// We don't have a Bard, so we'll hide Kerbin here.
protected CelestialBody Kerbin;
+ protected CelestialBody _firstOccludingBody;
+
protected IAntennaRelay _nearestRelayCache;
protected IAntennaRelay moduleRef;
@@ -68,6 +85,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>
@@ -118,7 +147,14 @@
/// <returns><c>true</c> if this instance can transmit; otherwise, <c>false</c>.</returns>
public virtual bool CanTransmit()
{
- if (this.transmitDistance > this.maxTransmitDistance)
+ if (
+ this.transmitDistance > this.maxTransmitDistance ||
+ (
+ requireLineOfSight &&
+ this.nearestRelay == null &&
+ !this.vessel.hasLineOfSightTo(this.Kerbin, out this._firstOccludingBody, radiusRatio)
+ )
+ )
{
return false;
}
@@ -154,10 +190,12 @@
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;
- double nearestDistance = double.PositiveInfinity;
+ double nearestSqrDistance = double.PositiveInfinity;
IAntennaRelay _nearestRelay = null;
/*
@@ -169,14 +207,10 @@
foreach (Vessel potentialVessel in FlightGlobals.Vessels)
{
// Skip vessels that have already been checked for a nearest relay this pass.
- try
- {
- if (RelayDatabase.Instance.CheckedVesselsTable[potentialVessel.id])
- {
- continue;
- }
- }
- catch (KeyNotFoundException) { /* If the key doesn't exist, don't skip it. */}
+ if (RelayDatabase.Instance.CheckedVesselsTable.ContainsKey(potentialVessel.id))
+ {
+ continue;
+ }
// Skip vessels of the wrong type.
switch (potentialVessel.vesselType)
@@ -197,19 +231,42 @@
continue;
}
+ // Skip vessels to which we do not have line of sight.
+ if (requireLineOfSight &&
+ !this.vessel.hasLineOfSightTo(potentialVessel, out this._firstOccludingBody, radiusRatio))
+ {
+ Tools.PostDebugMessage(
+ this,
+ "Vessel {0} discarded because we do not have line of sight.",
+ potentialVessel.vesselName
+ );
+ continue;
+ }
+
// Find the distance from here to the vessel...
- double potentialDistance = (potentialVessel.GetWorldPos3D() - vessel.GetWorldPos3D()).magnitude;
+ double potentialSqrDistance = (potentialVessel.GetWorldPos3D() - vessel.GetWorldPos3D()).sqrMagnitude;
/*
* ...so that we can skip the vessel if it is further away than Kerbin, our transmit distance, or a
* vessel we've already checked.
* */
- if (potentialDistance > Tools.Min(this.maxTransmitDistance, nearestDistance, vessel.DistanceTo(Kerbin)))
- {
+ if (
+ potentialSqrDistance > Tools.Min(
+ this.maxTransmitDistance * this.maxTransmitDistance,
+ nearestSqrDistance,
+ this.vessel.sqrDistanceTo(Kerbin)
+ )
+ )
+ {
+ Tools.PostDebugMessage(
+ this,
+ "Vessel {0} discarded because it is out of range, or farther than another relay.",
+ potentialVessel.vesselName
+ );
continue;
}
- nearestDistance = potentialDistance;
+ nearestSqrDistance = potentialSqrDistance;
foreach (IAntennaRelay potentialRelay in potentialVessel.GetAntennaRelays())
{
@@ -249,6 +306,17 @@
// we hope it is safe enough.
this.Kerbin = FlightGlobals.Bodies.FirstOrDefault(b => b.name == "Kerbin");
}
+
+ static AntennaRelay()
+ {
+ var config = KSP.IO.PluginConfiguration.CreateForType<AntennaRelay>();
+
+ config.load();
+
+ AntennaRelay.requireLineOfSight = config.GetValue<bool>("requireLineOfSight", false);
+
+ config.save();
+ }
}
}
--- a/EventSniffer.cs
+++ /dev/null
@@ -1,207 +1,1 @@
-// AntennaRange © 2014 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/
-#if DEBUG
-using KSP;
-using System;
-using System.Text;
-using UnityEngine;
-
-namespace AntennaRange
-{
- [KSPAddon(KSPAddon.Startup.Flight, false)]
- public class EventSniffer : MonoBehaviour
- {
- public void Awake()
- {
- GameEvents.onSameVesselDock.Add(this.onSameVesselDockUndock);
- GameEvents.onSameVesselUndock.Add(this.onSameVesselDockUndock);
- GameEvents.onPartUndock.Add(this.onPartUndock);
- GameEvents.onUndock.Add(this.onReportEvent);
- GameEvents.onPartCouple.Add(this.onPartCouple);
- GameEvents.onPartJointBreak.Add(this.onPartJointBreak);
- }
-
- public void Destroy()
- {
- GameEvents.onSameVesselDock.Remove(this.onSameVesselDockUndock);
- GameEvents.onSameVesselUndock.Remove(this.onSameVesselDockUndock);
- GameEvents.onPartUndock.Remove(this.onPartUndock);
- GameEvents.onUndock.Remove(this.onReportEvent);
- GameEvents.onPartCouple.Remove(this.onPartCouple);
- GameEvents.onPartJointBreak.Remove(this.onPartJointBreak);
- }
-
- public void onSameVesselDockUndock(GameEvents.FromToAction<ModuleDockingNode, ModuleDockingNode> data)
- {
- this.FromModuleToModuleHelper(
- this.getStringBuilder(),
- new GameEvents.FromToAction<PartModule, PartModule>(data.from, data.to)
- );
- }
-
- public void onPartJointBreak(PartJoint joint)
- {
- this.PartJointHelper(this.getStringBuilder(), joint);
- }
-
- public void onPartUndock(Part part)
- {
- this.PartEventHelper(this.getStringBuilder(), part);
- }
-
- public void onReportEvent(EventReport data)
- {
- this.EventReportHelper(this.getStringBuilder(), data);
- }
-
- public void onPartCouple(GameEvents.FromToAction<Part, Part> data)
- {
- this.FromPartToPartHelper(this.getStringBuilder(), data);
- }
-
- internal void EventReportHelper(StringBuilder sb, EventReport data)
- {
- sb.Append("\n\tOrigin Part:");
- this.appendPartAncestry(sb, data.origin);
-
- sb.AppendFormat(
- "\n\tother: '{0}'" +
- "\n\tmsg: '{1}'" +
- "\n\tsender: '{2}'",
- data.other,
- data.msg,
- data.sender
- );
-
- Debug.Log(sb.ToString());
- }
-
- internal void PartEventHelper(StringBuilder sb, Part part)
- {
- this.appendPartAncestry(sb, part);
-
- Debug.Log(sb.ToString());
- }
-
- internal void FromPartToPartHelper(StringBuilder sb, GameEvents.FromToAction<Part, Part> data)
- {
- sb.Append("\n\tFrom:");
-
- this.appendPartAncestry(sb, data.from);
-
- sb.Append("\n\tTo:");
-
- this.appendPartAncestry(sb, data.to);
-
- Debug.Log(sb.ToString());
- }
-
- internal void FromModuleToModuleHelper(StringBuilder sb, GameEvents.FromToAction<PartModule, PartModule> data)
- {
- sb.Append("\n\tFrom:");
-
- this.appendModuleAncestry(sb, data.from);
-
- sb.Append("\n\tTo:");
-
- this.appendModuleAncestry(sb, data.to);
-
- Debug.Log(sb.ToString());
- }
-
- internal void PartJointHelper(StringBuilder sb, PartJoint joint)
- {
- sb.Append("PartJoint: ");
- if (joint != null)
- {
- sb.Append(joint);
- this.appendPartAncestry(sb, joint.Host);
- }
- else
- {
- sb.Append("null");
- }
-
- Debug.Log(sb.ToString());
- }
-
- internal StringBuilder appendModuleAncestry(StringBuilder sb, PartModule module, uint tabs = 1)
- {
- sb.Append('\n');
- for (ushort i=0; i < tabs; i++)
- {
- sb.Append('\t');
- }
- sb.Append("Module: ");
-
- if (module != null)
- {
- sb.Append(module.moduleName);
- this.appendPartAncestry(sb, module.part, tabs + 1u);
- }
- else
- {
- sb.Append("null");
- }
-
- return sb;
- }
-
- internal StringBuilder appendPartAncestry(StringBuilder sb, Part part, uint tabs = 1)
- {
- sb.Append('\n');
- for (ushort i=0; i < tabs; i++)
- {
- sb.Append('\t');
- }
- sb.Append("Part: ");
-
- if (part != null)
- {
- sb.AppendFormat("'{0}' ({1})", part.partInfo.title, part.partName);
- this.appendVessel(sb, part.vessel, tabs + 1u);
- }
- else
- {
- sb.Append("null");
- }
-
- return sb;
- }
-
- internal StringBuilder appendVessel(StringBuilder sb, Vessel vessel, uint tabs = 1)
- {
- sb.Append('\n');
- for (ushort i=0; i < tabs; i++)
- {
- sb.Append('\t');
- }
- sb.Append("Vessel: ");
-
- if (vessel != null)
- {
- sb.AppendFormat("'{0}' ({1})", vessel.vesselName, vessel.id);
- }
- else
- {
- sb.Append("null");
- }
-
- return sb;
- }
-
- internal StringBuilder getStringBuilder()
- {
- StringBuilder sb = new StringBuilder();
- sb.AppendFormat("{0}: called {1} ",
- this.GetType().Name,
- new System.Diagnostics.StackTrace().GetFrame(1).GetMethod().Name
- );
- return sb;
- }
- }
-}
-#endif
--- a/Extensions.cs
+++ /dev/null
@@ -1,92 +1,1 @@
-// 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;
-
-namespace AntennaRange
-{
- /*
- * A class of utility extensions for Vessels and Relays to help find a relay path back to Kerbin.
- * */
- public static class Extensions
- {
- /// <summary>
- /// Returns the distance between this Vessel and another Vessel.
- /// </summary>
- /// <param name="vesselOne">This <see cref="Vessel"/><see ></param>
- /// <param name="vesselTwo">Another <see cref="Vessel"/></param>
- public static double DistanceTo(this Vessel vesselOne, Vessel vesselTwo)
- {
- return (vesselOne.GetWorldPos3D() - vesselTwo.GetWorldPos3D()).magnitude;
- }
-
- /// <summary>
- /// Returns the distance between this Vessel and a CelestialBody
- /// </summary>
- /// <param name="vessel">This Vessel</param>
- /// <param name="body">A <see cref="CelestialBody"/></param>
- public static double DistanceTo(this Vessel vessel, CelestialBody body)
- {
- return (vessel.GetWorldPos3D() - body.position).magnitude;
- }
-
- /// <summary>
- /// Returns the distance between this IAntennaRelay and a Vessel
- /// </summary>
- /// <param name="relay">This <see cref="IAntennaRelay"/></param>
- /// <param name="Vessel">A <see cref="Vessel"/></param>
- public static double DistanceTo(this AntennaRelay relay, Vessel Vessel)
- {
- return relay.vessel.DistanceTo(Vessel);
- }
-
- /// <summary>
- /// Returns the distance between this IAntennaRelay and a CelestialBody
- /// </summary>
- /// <param name="relay">This <see cref="IAntennaRelay"/></param>
- /// <param name="body">A <see cref="CelestialBody"/></param>
- public static double DistanceTo(this AntennaRelay relay, CelestialBody body)
- {
- return relay.vessel.DistanceTo(body);
- }
-
- /// <summary>
- /// Returns the distance between this IAntennaRelay and another IAntennaRelay
- /// </summary>
- /// <param name="relayOne">This <see cref="IAntennaRelay"/></param>
- /// <param name="relayTwo">Another <see cref="IAntennaRelay"/></param>
- public static double DistanceTo(this AntennaRelay relayOne, IAntennaRelay relayTwo)
- {
- return relayOne.DistanceTo(relayTwo.vessel);
- }
-
- /// <summary>
- /// Returns all of the PartModules or ProtoPartModuleSnapshots implementing IAntennaRelay in this Vessel.
- /// </summary>
- /// <param name="vessel">This <see cref="Vessel"/></param>
- public static IEnumerable<IAntennaRelay> GetAntennaRelays (this Vessel vessel)
- {
- return RelayDatabase.Instance[vessel].Values.ToList();
- }
-
-
- }
-}
-
-
--- /dev/null
+++ b/GameData/AntennaRange/ATM_AntennaRange.cfg
@@ -1,1 +1,15 @@
-
+ACTIVE_TEXTURE_MANAGER_CONFIG
+{
+ folder = AntennaRange
+ enabled = true
+ OVERRIDES
+ {
+ AntennaRange/.*
+ {
+ compress = true
+ mipmaps = false
+ scale = 1
+ max_size = 0
+ }
+ }
+}
--- /dev/null
+++ b/GameData/AntennaRange/AntennaRange.cfg
@@ -1,1 +1,141 @@
+// AntennaRange
+//
+// AntennaRange.cfg
+//
+// Copyright © 2014, toadicus
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be used
+// to endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// 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.
+//
+// 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]:FOR[AntennaRange]:NEEDS[!RemoteTech2]
+{
+ @MODULE[ModuleDataTransmitter]
+ {
+ @name = ModuleLimitedDataTransmitter
+ nominalRange = 1500000
+ maxPowerFactor = 8
+ maxDataFactor = 4
+ }
+
+ MODULE
+ {
+ name = ModuleScienceContainer
+
+ dataIsCollectable = true
+ dataIsStorable = false
+
+ storageRange = 2
+ }
+}
+
+@PART[mediumDishAntenna]:FOR[AntennaRange]:NEEDS[!RemoteTech2]
+{
+ @MODULE[ModuleDataTransmitter]
+ {
+ @name = ModuleLimitedDataTransmitter
+ nominalRange = 30000000
+ maxPowerFactor = 8
+ maxDataFactor = 4
+ }
+
+ MODULE
+ {
+ name = ModuleScienceContainer
+
+ dataIsCollectable = true
+ dataIsStorable = false
+
+ storageRange = 2
+ }
+}
+
+@PART[commDish]:FOR[AntennaRange]:NEEDS[!RemoteTech2]
+{
+ @MODULE[ModuleDataTransmitter]
+ {
+ @name = ModuleLimitedDataTransmitter
+ nominalRange = 80000000000
+ maxPowerFactor = 8
+ maxDataFactor = 4
+ }
+
+ MODULE
+ {
+ name = ModuleScienceContainer
+
+ dataIsCollectable = true
+ dataIsStorable = false
+
+ storageRange = 2
+ }
+}
+
+EVA_MODULE
+{
+ name = ModuleLimitedDataTransmitter
+
+ nominalRange = 5000
+ maxPowerFactor = 8
+ maxDataFactor = 4
+
+ packetInterval = 0.5
+ packetSize = 2
+ packetResourceCost = .1
+
+ requiredResource = ElectricCharge
+}
+
+EVA_RESOURCE
+{
+ name = ElectricCharge
+ amount = 100
+ maxAmount = 100
+}
+
+@EVA_RESOURCE[ElectricCharge]:AFTER[AntennaRange]:NEEDS[TacLifeSupport]
+{
+ !name = DELETE
+}
+
+@SUBCATEGORY[*]:HAS[#title[Data?Transmitter]]:FOR[AntennaRange:]NEEDS[FilterExtensions]
+{
+ FILTER
+ {
+ CHECK
+ {
+ type = moduleName
+ value = ModuleLimitedDataTransmitter
+ }
+ }
+}
+
Binary files /dev/null and b/GameData/AntennaRange/Textures/appLauncherIcon.png differ
Binary files /dev/null and b/GameData/AntennaRange/Textures/appLauncherIconNoConnection.png differ
Binary files /dev/null and b/GameData/AntennaRange/Textures/appLauncherIconSubOptimal.png differ
Binary files /dev/null and b/GameData/AntennaRange/Textures/toolbarIcon.png differ
Binary files /dev/null and b/GameData/AntennaRange/Textures/toolbarIconNoConnection.png differ
Binary files /dev/null and b/GameData/AntennaRange/Textures/toolbarIconSubOptimal.png differ
--- a/IAntennaRelay.cs
+++ b/IAntennaRelay.cs
@@ -1,19 +1,30 @@
-// AntennaRange © 2014 toadicus
+// AntennaRange
//
-// AntennaRange provides incentive and requirements for the use of the various antenna parts.
-// Nominally, the breakdown is as follows:
+// IAntennaRelay.cs
//
-// Communotron 16 - Suitable up to Kerbalsynchronous Orbit
-// Comms DTS-M1 - Suitable throughout the Kerbin subsystem
-// Communotron 88-88 - Suitable throughout the Kerbol system.
+// Copyright © 2014, toadicus
+// All rights reserved.
//
-// 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/
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
//
-// This software uses the ModuleManager library © 2013 ialdabaoth, used under a Creative Commons Attribution-ShareAlike
-// 3.0 Uported License.
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
//
-// This software uses code from the MuMechLib library, © 2013 r4m0n, used under the GNU GPL version 3.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be used
+// to endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// 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;
--- a/ModuleLimitedDataTransmitter.cs
+++ b/ModuleLimitedDataTransmitter.cs
@@ -1,25 +1,37 @@
-// AntennaRange © 2014 toadicus
+// AntennaRange
//
-// AntennaRange provides incentive and requirements for the use of the various antenna parts.
-// Nominally, the breakdown is as follows:
+// ModuleLimitedDataTransmitter.cs
//
-// Communotron 16 - Suitable up to Kerbalsynchronous Orbit
-// Comms DTS-M1 - Suitable throughout the Kerbin subsystem
-// Communotron 88-88 - Suitable throughout the Kerbol system.
+// Copyright © 2014, toadicus
+// All rights reserved.
//
-// 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/
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
//
-// This software uses the ModuleManager library © 2013 ialdabaoth, used under a Creative Commons Attribution-ShareAlike
-// 3.0 Uported License.
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
//
-// This software uses code from the MuMechLib library, © 2013 r4m0n, used under the GNU GPL version 3.
-
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be used
+// to endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// 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 System.Collections.Generic;
using System.Linq;
using System.Text;
-using KSP;
+using ToadicusTools;
using UnityEngine;
namespace AntennaRange
@@ -42,6 +54,10 @@
* */
public class ModuleLimitedDataTransmitter : ModuleDataTransmitter, IScienceDataTransmitter, IAntennaRelay
{
+ // If true, use a fixed power cost at the configured value and degrade data rates instead of increasing power
+ // requirements.
+ public static bool fixedPowerCost;
+
// Stores the packetResourceCost as defined in the .cfg file.
protected float _basepacketResourceCost;
@@ -62,6 +78,9 @@
[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;
@@ -82,6 +101,16 @@
// The multipler on packetSize that defines the maximum data bandwidth of the antenna.
[KSPField(isPersistant = false)]
public float maxDataFactor;
+
+ [KSPField(
+ isPersistant = true,
+ guiName = "Packet Throttle",
+ guiUnits = "%",
+ guiActive = true,
+ guiActiveEditor = false
+ )]
+ [UI_FloatRange(maxValue = 100f, minValue = 2.5f, stepIncrement = 2.5f)]
+ public float packetThrottle;
protected bool actionUIUpdate;
@@ -195,34 +224,12 @@
public ModuleLimitedDataTransmitter () : base()
{
this.ErrorMsg = new ScreenMessage("", 4f, false, ScreenMessageStyle.UPPER_LEFT);
- }
-
- // At least once, when the module starts with a state on the launch pad or later, go find Kerbin.
- public override void OnStart (StartState state)
- {
- base.OnStart (state);
-
- if (state >= StartState.PreLaunch)
- {
- this.relay = new AntennaRelay(vessel);
- this.relay.maxTransmitDistance = this.maxTransmitDistance;
-
- this.UImaxTransmitDistance = Tools.MuMech_ToSI(this.maxTransmitDistance) + "m";
-
- GameEvents.onPartActionUICreate.Add(this.onPartActionUICreate);
- GameEvents.onPartActionUIDismiss.Add(this.onPartActionUIDismiss);
- }
- }
-
- // When the module loads, fetch the Squad KSPFields from the base. This is necessary in part because
- // overloading packetSize and packetResourceCostinto a property in ModuleLimitedDataTransmitter didn't
- // work.
- public override void OnLoad(ConfigNode node)
- {
- this.Fields.Load(node);
- base.Fields.Load(node);
-
- base.OnLoad (node);
+ this.packetThrottle = 100f;
+ }
+
+ public override void OnAwake()
+ {
+ base.OnAwake();
this._basepacketSize = base.packetSize;
this._basepacketResourceCost = base.packetResourceCost;
@@ -243,15 +250,39 @@
));
}
+ // At least once, when the module starts with a state on the launch pad or later, go find Kerbin.
+ public override void OnStart (StartState state)
+ {
+ base.OnStart (state);
+
+ if (state >= StartState.PreLaunch)
+ {
+ this.relay = new AntennaRelay(this);
+ this.relay.maxTransmitDistance = this.maxTransmitDistance;
+
+ this.UImaxTransmitDistance = Tools.MuMech_ToSI(this.maxTransmitDistance) + "m";
+
+ GameEvents.onPartActionUICreate.Add(this.onPartActionUICreate);
+ GameEvents.onPartActionUIDismiss.Add(this.onPartActionUIDismiss);
+ }
+ }
+
+ // When the module loads, fetch the Squad KSPFields from the base. This is necessary in part because
+ // overloading packetSize and packetResourceCostinto a property in ModuleLimitedDataTransmitter didn't
+ // work.
+ public override void OnLoad(ConfigNode node)
+ {
+ this.Fields.Load(node);
+ base.Fields.Load(node);
+
+ base.OnLoad (node);
+ }
+
// Post an error in the communication messages describing the reason transmission has failed. Currently there
// is only one reason for this.
protected void PostCannotTransmitError()
{
- string ErrorText = string.Format (
- "Unable to transmit: out of range! Maximum range = {0}m; Current range = {1}m.",
- Tools.MuMech_ToSI((double)this.maxTransmitDistance, 2),
- Tools.MuMech_ToSI((double)this.transmitDistance, 2)
- );
+ string ErrorText = string.Intern("Unable to transmit: no visible receivers in range!");
this.ErrorMsg.message = string.Format(
"<color='#{0}{1}{2}{3}'><b>{4}</b></color>",
@@ -272,31 +303,53 @@
// transmission fails (see CanTransmit).
protected void PreTransmit_SetPacketResourceCost()
{
- if (this.transmitDistance <= this.nominalRange)
+ if (fixedPowerCost || this.transmitDistance <= this.nominalRange)
{
base.packetResourceCost = this._basepacketResourceCost;
}
else
{
+ double rangeFactor = (this.transmitDistance / this.nominalRange);
+ rangeFactor *= rangeFactor;
+
base.packetResourceCost = this._basepacketResourceCost
- * (float)Math.Pow (this.transmitDistance / this.nominalRange, 2);
- }
+ * (float)rangeFactor;
+
+ Tools.PostDebugMessage(
+ this,
+ "Pretransmit: packet cost set to {0} before throttle (rangeFactor = {1}).",
+ base.packetResourceCost,
+ rangeFactor);
+ }
+
+ base.packetResourceCost *= this.packetThrottle / 100f;
}
// Before transmission, set packetSize. Per above, packet size increases with the inverse square of
// distance. packetSize maxes out at _basepacketSize * maxDataFactor.
protected void PreTransmit_SetPacketSize()
{
- if (this.transmitDistance >= this.nominalRange)
+ if (!fixedPowerCost && this.transmitDistance >= this.nominalRange)
{
base.packetSize = this._basepacketSize;
}
else
{
+ double rangeFactor = (this.nominalRange / this.transmitDistance);
+ rangeFactor *= rangeFactor;
+
base.packetSize = Math.Min(
- this._basepacketSize * (float)Math.Pow (this.nominalRange / this.transmitDistance, 2),
+ this._basepacketSize * (float)rangeFactor,
this._basepacketSize * this.maxDataFactor);
- }
+
+ Tools.PostDebugMessage(
+ this,
+ "Pretransmit: packet size set to {0} before throttle (rangeFactor = {1}).",
+ base.packetSize,
+ rangeFactor);
+ }
+
+ base.packetSize *= this.packetThrottle / 100f;
}
// Override ModuleDataTransmitter.GetInfo to add nominal and maximum range to the VAB description.
@@ -311,6 +364,11 @@
// Override ModuleDataTransmitter.CanTransmit to return false when transmission is not possible.
public new bool CanTransmit()
{
+ if (this.part == null || this.relay == null)
+ {
+ return false;
+ }
+
PartStates partState = this.part.State;
if (partState == PartStates.DEAD || partState == PartStates.DEACTIVATED)
{
@@ -330,12 +388,104 @@
// returns false.
public new void TransmitData(List<ScienceData> dataQueue)
{
+ this.PreTransmit_SetPacketSize();
+ this.PreTransmit_SetPacketResourceCost();
+
if (this.CanTransmit())
{
+ StringBuilder message = new StringBuilder();
+
+ message.Append("[");
+ message.Append(base.part.partInfo.title);
+ message.Append("]: ");
+
+ message.Append("Beginning transmission ");
+
+ if (this.relay.nearestRelay == null)
+ {
+ message.Append("directly to Kerbin.");
+ }
+ else
+ {
+ message.Append("via ");
+ message.Append(this.relay.nearestRelay);
+ }
+
+ ScreenMessages.PostScreenMessage(message.ToString(), 4f, ScreenMessageStyle.UPPER_LEFT);
+
base.TransmitData(dataQueue);
}
else
{
+ Tools.PostDebugMessage(this, "{0} unable to transmit during TransmitData.", this.part.partInfo.title);
+
+ var logger = Tools.DebugLogger.New(this);
+
+ foreach (ModuleScienceContainer scienceContainer in this.vessel.getModulesOfType<ModuleScienceContainer>())
+ {
+ logger.AppendFormat("Checking ModuleScienceContainer in {0}\n",
+ scienceContainer.part.partInfo.title);
+
+ if (
+ scienceContainer.capacity != 0 &&
+ scienceContainer.GetScienceCount() >= scienceContainer.capacity
+ )
+ {
+ logger.Append("\tInsufficient capacity, skipping.\n");
+ continue;
+ }
+
+ List<ScienceData> dataStored = new List<ScienceData>();
+
+ foreach (ScienceData data in dataQueue)
+ {
+ if (!scienceContainer.allowRepeatedSubjects && scienceContainer.HasData(data))
+ {
+ logger.Append("\tAlready contains subject and repeated subjects not allowed, skipping.\n");
+ continue;
+ }
+
+ logger.AppendFormat("\tAcceptable, adding data on subject {0}... ", data.subjectID);
+ if (scienceContainer.AddData(data))
+ {
+ logger.Append("done, removing from queue.\n");
+
+ dataStored.Add(data);
+ }
+ #if DEBUG
+ else
+ {
+ logger.Append("failed.\n");
+ }
+ #endif
+ }
+
+ dataQueue.RemoveAll(i => dataStored.Contains(i));
+
+ logger.AppendFormat("\t{0} data left in queue.", dataQueue.Count);
+ }
+
+ logger.Print();
+
+ if (dataQueue.Count > 0)
+ {
+ StringBuilder msg = new StringBuilder();
+
+ msg.Append('[');
+ msg.Append(this.part.partInfo.title);
+ msg.AppendFormat("]: {0} data items could not be saved: no space available in data containers.\n");
+ msg.Append("Data to be discarded:\n");
+
+ foreach (ScienceData data in dataQueue)
+ {
+ msg.AppendFormat("\n{0}\n", data.title);
+ }
+
+ ScreenMessages.PostScreenMessage(msg.ToString(), 4f, ScreenMessageStyle.UPPER_LEFT);
+
+ Tools.PostDebugMessage(msg.ToString());
+ }
+
this.PostCannotTransmitError ();
}
@@ -393,9 +543,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";
+ }
}
}
@@ -451,7 +619,8 @@
"DataRate: {9}\n" +
"DataResourceCost: {10}\n" +
"TransmitterScore: {11}\n" +
- "NearestRelay: {12}",
+ "NearestRelay: {12}\n" +
+ "Vessel ID: {13}",
this.name,
this._basepacketSize,
base.packetSize,
@@ -464,9 +633,31 @@
this.DataRate,
this.DataResourceCost,
ScienceUtil.GetTransmitterScore(this),
- this.relay.FindNearestRelay()
+ this.relay.FindNearestRelay(),
+ this.vessel.id
);
- ScreenMessages.PostScreenMessage (new ScreenMessage (msg, 4f, ScreenMessageStyle.UPPER_RIGHT));
+ Tools.PostDebugMessage(msg);
+ }
+
+ [KSPEvent (guiName = "Dump Vessels", active = true, guiActive = true)]
+ public void PrintAllVessels()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.Append("Dumping FlightGlobals.Vessels:");
+
+ foreach (Vessel vessel in FlightGlobals.Vessels)
+ {
+ sb.AppendFormat("\n'{0} ({1})'", vessel.vesselName, vessel.id);
+ }
+
+ Tools.PostDebugMessage(sb.ToString());
+ }
+
+ [KSPEvent (guiName = "Dump RelayDB", active = true, guiActive = true)]
+ public void DumpRelayDB()
+ {
+ RelayDatabase.Instance.Dump();
}
#endif
}
--- a/Properties/AssemblyInfo.cs
+++ b/Properties/AssemblyInfo.cs
@@ -1,21 +1,35 @@
-// AntennaRange © 2014 toadicus
+// AntennaRange
//
-// AntennaRange provides incentive and requirements for the use of the various antenna parts.
-// Nominally, the breakdown is as follows:
+// AssemblyInfo.cs
//
-// Communotron 16 - Suitable up to Kerbalsynchronous Orbit
-// Comms DTS-M1 - Suitable throughout the Kerbin subsystem
-// Communotron 88-88 - Suitable throughout the Kerbol system.
+// Copyright © 2014, toadicus
+// All rights reserved.
//
-// 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/
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
//
-// This software uses the ModuleManager library © 2013 ialdabaoth, used under a Creative Commons Attribution-ShareAlike
-// 3.0 Uported License.
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
//
-// This software uses code from the MuMechLib library, © 2013 r4m0n, used under the GNU GPL version 3.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be used
+// to endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// 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 System.Reflection;
using System.Runtime.CompilerServices;
+
+[assembly: KSPAssemblyDependency("ToadicusTools", 0, 0)]
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
@@ -25,10 +39,9 @@
// 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.3.*")]
+[assembly: AssemblyVersion("1.6.*")]
// 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("")]
-
--- a/ProtoAntennaRelay.cs
+++ b/ProtoAntennaRelay.cs
@@ -1,22 +1,35 @@
-// AntennaRange © 2014 toadicus
+// AntennaRange
//
-// AntennaRange provides incentive and requirements for the use of the various antenna parts.
-// Nominally, the breakdown is as follows:
+// ProtoAntennaRelay.cs
//
-// Communotron 16 - Suitable up to Kerbalsynchronous Orbit
-// Comms DTS-M1 - Suitable throughout the Kerbin subsystem
-// Communotron 88-88 - Suitable throughout the Kerbol system.
+// Copyright © 2014, toadicus
+// All rights reserved.
//
-// 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/
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
//
-// This software uses the ModuleManager library © 2013 ialdabaoth, used under a Creative Commons Attribution-ShareAlike
-// 3.0 Uported License.
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
//
-// This software uses code from the MuMechLib library, © 2013 r4m0n, used under the GNU GPL version 3.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be used
+// to endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// 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 System.Linq;
+using ToadicusTools;
namespace AntennaRange
{
--- a/RelayDatabase.cs
+++ b/RelayDatabase.cs
@@ -1,13 +1,36 @@
-// AntennaRange © 2014 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/
+// AntennaRange
+//
+// RelayDatabase.cs
+//
+// Copyright © 2014, toadicus
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be used
+// to endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// 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 System.Collections.Generic;
-using System.Linq;
using System.Text;
+using ToadicusTools;
using UnityEngine;
namespace AntennaRange
--- /dev/null
+++ b/RelayExtensions.cs
@@ -1,1 +1,100 @@
+// AntennaRange
+//
+// Extensions.cs
+//
+// Copyright © 2014, toadicus
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be used
+// to endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// 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 System;
+using System.Collections.Generic;
+using System.Linq;
+using ToadicusTools;
+
+namespace AntennaRange
+{
+ /*
+ * A class of utility extensions for Vessels and Relays to help find a relay path back to Kerbin.
+ * */
+ public static class RelayExtensions
+ {
+ /// <summary>
+ /// Returns the distance between this IAntennaRelay and a Vessel
+ /// </summary>
+ /// <param name="relay">This <see cref="IAntennaRelay"/></param>
+ /// <param name="Vessel">A <see cref="Vessel"/></param>
+ public static double DistanceTo(this AntennaRelay relay, Vessel Vessel)
+ {
+ return relay.vessel.DistanceTo(Vessel);
+ }
+
+ /// <summary>
+ /// Returns the distance between this IAntennaRelay and a CelestialBody
+ /// </summary>
+ /// <param name="relay">This <see cref="IAntennaRelay"/></param>
+ /// <param name="body">A <see cref="CelestialBody"/></param>
+ public static double DistanceTo(this AntennaRelay relay, CelestialBody body)
+ {
+ return relay.vessel.DistanceTo(body) - body.Radius;
+ }
+
+ /// <summary>
+ /// Returns the distance between this IAntennaRelay and another IAntennaRelay
+ /// </summary>
+ /// <param name="relayOne">This <see cref="IAntennaRelay"/></param>
+ /// <param name="relayTwo">Another <see cref="IAntennaRelay"/></param>
+ public static double DistanceTo(this AntennaRelay relayOne, IAntennaRelay relayTwo)
+ {
+ return relayOne.DistanceTo(relayTwo.vessel);
+ }
+
+ /// <summary>
+ /// Returns all of the PartModules or ProtoPartModuleSnapshots implementing IAntennaRelay in this Vessel.
+ /// </summary>
+ /// <param name="vessel">This <see cref="Vessel"/></param>
+ public static IEnumerable<IAntennaRelay> GetAntennaRelays (this Vessel vessel)
+ {
+ 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;
+ }
+ }
+}
+
+
Binary files /dev/null and b/toolbarIcon.xcf differ
Binary files /dev/null and b/toolbarIcon_24x24.xcf differ
Binary files /dev/null and b/toolbarIcon_38x38.xcf differ