VOID_HUDAdvanced: Worked around a NaN Exception-spam issue.
VOID_HUDAdvanced: Worked around a NaN Exception-spam issue.

// VOID // VOID
// //
// VOID_Core.cs // VOID_Core.cs
// //
// Copyright © 2014, toadicus // Copyright © 2014, toadicus
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without modification, // Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met: // are permitted provided that the following conditions are met:
// //
// 1. Redistributions of source code must retain the above copyright notice, // 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. // this list of conditions and the following disclaimer.
// //
// 2. Redistributions in binary form must reproduce the above copyright notice, // 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 // this list of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution. // materials provided with the distribution.
// //
// 3. Neither the name of the copyright holder nor the names of its contributors may be used // 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. // 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, // 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 // 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, // 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 // 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, // 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 // 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. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
using Engineer.VesselSimulator; using Engineer.VesselSimulator;
using KSP; using KSP;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using ToadicusTools; using ToadicusTools;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_Core : VOID_Module, IVOID_Module public class VOID_Core : VOID_Module, IVOID_Module
{ {
#region Singleton Members #region Singleton Members
/* /*
* Static Members * Static Members
* */ * */
protected static bool _initialized = false; protected static bool _initialized = false;
   
public static bool Initialized public static bool Initialized
{ {
get get
{ {
return _initialized; return _initialized;
} }
} }
   
protected static VOID_Core _instance; protected static VOID_Core _instance;
   
public static VOID_Core Instance public static VOID_Core Instance
{ {
get get
{ {
if (_instance == null) if (_instance == null)
{ {
_instance = new VOID_Core(); _instance = new VOID_Core();
_initialized = true; _initialized = true;
} }
return _instance; return _instance;
} }
} }
   
public static void Reset() public static void Reset()
{ {
_instance.StopGUI(); _instance.StopGUI();
_instance.Dispose(); _instance.Dispose();
_instance = null; _instance = null;
_initialized = false; _initialized = false;
} }
#endregion #endregion
   
public static readonly double Constant_G = 6.674e-11; public static readonly double Constant_G = 6.674e-11;
   
/* /*
* Fields * Fields
* */ * */
protected string VoidName = "VOID"; protected string VoidName = "VOID";
protected string VoidVersion; protected string VoidVersion;
   
protected bool _factoryReset = false; protected bool _factoryReset = false;
   
[AVOID_SaveValue("configValue")] [AVOID_SaveValue("configValue")]
protected VOID_SaveValue<int> configVersion = 1; protected VOID_SaveValue<int> configVersion = 1;
   
protected List<IVOID_Module> _modules = new List<IVOID_Module>(); protected List<IVOID_Module> _modules = new List<IVOID_Module>();
protected bool _modulesLoaded = false; protected bool _modulesLoaded = false;
   
[AVOID_SaveValue("mainWindowPos")] [AVOID_SaveValue("mainWindowPos")]
protected VOID_SaveValue<Rect> mainWindowPos = new Rect(475, 575, 10f, 10f); protected VOID_SaveValue<Rect> mainWindowPos = new Rect(475, 575, 10f, 10f);
[AVOID_SaveValue("mainGuiMinimized")] [AVOID_SaveValue("mainGuiMinimized")]
protected VOID_SaveValue<bool> mainGuiMinimized = false; protected VOID_SaveValue<bool> mainGuiMinimized = false;
   
[AVOID_SaveValue("configWindowPos")] [AVOID_SaveValue("configWindowPos")]
protected VOID_SaveValue<Rect> configWindowPos = new Rect(825, 625, 10f, 10f); protected VOID_SaveValue<Rect> configWindowPos = new Rect(825, 625, 10f, 10f);
[AVOID_SaveValue("configWindowMinimized")] [AVOID_SaveValue("configWindowMinimized")]
   
protected VOID_SaveValue<bool> configWindowMinimized = true; protected VOID_SaveValue<bool> configWindowMinimized = true;
[AVOID_SaveValue("VOIDIconPos")] [AVOID_SaveValue("VOIDIconPos")]
protected VOID_SaveValue<Rect> VOIDIconPos = new Rect(Screen.width / 2 - 200, Screen.height - 32, 32f, 32f); protected VOID_SaveValue<Rect> VOIDIconPos = new Rect(Screen.width / 2 - 200, Screen.height - 32, 32f, 32f);
   
protected Texture2D VOIDIconTexture; protected Texture2D VOIDIconTexture;
protected string VOIDIconOnActivePath; protected string VOIDIconOnActivePath;
protected string VOIDIconOnInactivePath; protected string VOIDIconOnInactivePath;
protected string VOIDIconOffActivePath; protected string VOIDIconOffActivePath;
protected string VOIDIconOffInactivePath; protected string VOIDIconOffInactivePath;
   
protected bool VOIDIconLocked = true; protected bool VOIDIconLocked = true;
   
protected GUIStyle iconStyle; protected GUIStyle iconStyle;
   
protected int windowBaseID = -96518722; protected int windowBaseID = -96518722;
protected int _windowID = 0; protected int _windowID = 0;
   
protected bool GUIStylesLoaded = false; protected bool GUIStylesLoaded = false;
protected Dictionary<string, GUIStyle> _LabelStyles = new Dictionary<string, GUIStyle>(); protected Dictionary<string, GUIStyle> _LabelStyles = new Dictionary<string, GUIStyle>();
   
protected CelestialBody _Kerbin; protected CelestialBody _Kerbin;
   
[AVOID_SaveValue("togglePower")] [AVOID_SaveValue("togglePower")]
public VOID_SaveValue<bool> togglePower = true; public VOID_SaveValue<bool> togglePower = true;
public bool powerAvailable = true; public bool powerAvailable = true;
   
[AVOID_SaveValue("consumeResource")] [AVOID_SaveValue("consumeResource")]
protected VOID_SaveValue<bool> consumeResource = false; protected VOID_SaveValue<bool> consumeResource = false;
   
[AVOID_SaveValue("resourceName")] [AVOID_SaveValue("resourceName")]
protected VOID_SaveValue<string> resourceName = "ElectricCharge"; protected VOID_SaveValue<string> resourceName = "ElectricCharge";
   
[AVOID_SaveValue("resourceRate")] [AVOID_SaveValue("resourceRate")]
protected VOID_SaveValue<float> resourceRate = 0.2f; protected VOID_SaveValue<float> resourceRate = 0.2f;
   
[AVOID_SaveValue("updatePeriod")] [AVOID_SaveValue("updatePeriod")]
protected VOID_SaveValue<double> _updatePeriod = 1001f / 15000f; protected VOID_SaveValue<double> _updatePeriod = 1001f / 15000f;
protected float _updateTimer = 0f; protected float _updateTimer = 0f;
protected string stringFrequency; protected string stringFrequency;
   
[AVOID_SaveValue("vesselSimActive")] [AVOID_SaveValue("vesselSimActive")]
protected VOID_SaveValue<bool> vesselSimActive; protected VOID_SaveValue<bool> vesselSimActive;
   
// Vessel Type Housekeeping // Vessel Type Housekeeping
protected List<VesselType> _allVesselTypes = new List<VesselType>(); protected List<VesselType> _allVesselTypes = new List<VesselType>();
protected bool vesselTypesLoaded = false; protected bool vesselTypesLoaded = false;
public float saveTimer = 0; public float saveTimer = 0;
   
protected string defaultSkin = "KSP window 2"; protected string defaultSkin = "KSP window 2";
   
[AVOID_SaveValue("defaultSkin")] [AVOID_SaveValue("defaultSkin")]
protected VOID_SaveValue<string> _skinName; protected VOID_SaveValue<string> _skinName;
protected int _skinIdx; protected int _skinIdx;
   
protected Dictionary<string, GUISkin> validSkins; protected Dictionary<string, GUISkin> validSkins;
protected string[] skinNames; protected string[] skinNames;
protected string[] forbiddenSkins = protected string[] forbiddenSkins =
{ {
"PlaqueDialogSkin", "PlaqueDialogSkin",
"FlagBrowserSkin", "FlagBrowserSkin",
"SSUITextAreaDefault", "SSUITextAreaDefault",
"ExperimentsDialogSkin", "ExperimentsDialogSkin",
"ExpRecoveryDialogSkin", "ExpRecoveryDialogSkin",
"KSP window 5", "KSP window 5",
"KSP window 6", "KSP window 6",
"PartTooltipSkin" "PartTooltipSkin"
}; };
protected bool skinsLoaded = false; protected bool skinsLoaded = false;
   
public bool configDirty; public bool configDirty;
   
[AVOID_SaveValue("UseBlizzyToolbar")] [AVOID_SaveValue("UseBlizzyToolbar")]
protected VOID_SaveValue<bool> _UseToolbarManager; protected VOID_SaveValue<bool> _UseToolbarManager;
internal IButton ToolbarButton; internal IButton ToolbarButton;
   
internal ApplicationLauncherButton AppLauncherButton; internal ApplicationLauncherButton AppLauncherButton;
   
/* /*
* Properties * Properties
* */ * */
public bool factoryReset public bool factoryReset
{ {
get get
{ {
return this._factoryReset; return this._factoryReset;
} }
} }
   
public List<IVOID_Module> Modules public List<IVOID_Module> Modules
{ {
get get
{ {
return this._modules; return this._modules;
} }
} }
   
public GUISkin Skin public GUISkin Skin
{ {
get get
{ {
if (this.skinsLoaded) if (this.skinsLoaded)
{ {
try try
{ {
return this.validSkins[this._skinName]; return this.validSkins[this._skinName];
} }
catch catch
{ {
} }
} }
   
return AssetBase.GetGUISkin(this.defaultSkin); return AssetBase.GetGUISkin(this.defaultSkin);
} }
} }
   
public int windowID public int windowID
{ {
get get
{ {
if (this._windowID == 0) if (this._windowID == 0)
{ {
this._windowID = this.windowBaseID; this._windowID = this.windowBaseID;
} }
return this._windowID++; return this._windowID++;
} }
} }
   
public Dictionary<string, GUIStyle> LabelStyles public Dictionary<string, GUIStyle> LabelStyles
{ {
get get
{ {
return this._LabelStyles; return this._LabelStyles;
} }
} }
   
public List<CelestialBody> allBodies public List<CelestialBody> allBodies
{ {
get get
{ {
return FlightGlobals.Bodies; return FlightGlobals.Bodies;
} }
} }
   
public CelestialBody Kerbin public CelestialBody Kerbin
{ {
get get
{ {
if (this._Kerbin == null) if (this._Kerbin == null)
{ {
if (FlightGlobals.Bodies != null) if (FlightGlobals.Bodies != null)
{ {
this._Kerbin = FlightGlobals.Bodies.First(b => b.name == "Kerbin"); this._Kerbin = FlightGlobals.Bodies.First(b => b.name == "Kerbin");
} }
} }
   
return this._Kerbin; return this._Kerbin;
} }
} }
   
public List<VesselType> allVesselTypes public List<VesselType> allVesselTypes
{ {
get get
{ {
return this._allVesselTypes; return this._allVesselTypes;
} }
} }
   
public float updateTimer public float updateTimer
{ {
get get
{ {
return this._updateTimer; return this._updateTimer;
} }
} }
   
public double updatePeriod public double updatePeriod
{ {
get get
{ {
return this._updatePeriod; return this._updatePeriod;
} }
} }
   
protected IconState powerState protected IconState powerState
{ {
get get
{ {
if (this.togglePower && this.powerAvailable) if (this.togglePower && this.powerAvailable)
{ {
return IconState.PowerOn; return IconState.PowerOn;
} }
else else
{ {
return IconState.PowerOff; return IconState.PowerOff;
} }
   
} }
} }
   
protected IconState activeState protected IconState activeState
{ {
get get
{ {
if (this.mainGuiMinimized) if (this.mainGuiMinimized)
{ {
return IconState.Inactive; return IconState.Inactive;
} }
else else
{ {
return IconState.Active; return IconState.Active;
} }
   
} }
} }
   
protected bool UseToolbarManager protected bool UseToolbarManager
{ {
get get
{ {
return _UseToolbarManager & ToolbarManager.ToolbarAvailable; return _UseToolbarManager & ToolbarManager.ToolbarAvailable;
} }
set set
{ {
if (this._UseToolbarManager == value) if (this._UseToolbarManager == value)
{ {
return; return;
} }
   
if (value == false && this.ToolbarButton != null) if (value == false && this.ToolbarButton != null)
{ {
this.ToolbarButton.Destroy(); this.ToolbarButton.Destroy();
this.ToolbarButton = null; this.ToolbarButton = null;
} }
if (value == true) if (value == true)
{ {
if (this.AppLauncherButton != null) if (this.AppLauncherButton != null)
{ {
ApplicationLauncher.Instance.RemoveModApplication(this.AppLauncherButton); ApplicationLauncher.Instance.RemoveModApplication(this.AppLauncherButton);
this.AppLauncherButton = null; this.AppLauncherButton = null;
} }
   
this.InitializeToolbarButton(); this.InitializeToolbarButton();
} }
   
_UseToolbarManager.value = value; _UseToolbarManager.value = value;
} }
} }
   
protected virtual ApplicationLauncher.AppScenes appIconVisibleScenes protected virtual ApplicationLauncher.AppScenes appIconVisibleScenes
{ {
get get
{ {
return ApplicationLauncher.AppScenes.FLIGHT; return ApplicationLauncher.AppScenes.FLIGHT;
} }
} }
   
/* /*
* Methods * Methods
* */ * */
public override void DrawGUI() public override void DrawGUI()
{ {
this._windowID = this.windowBaseID; this._windowID = this.windowBaseID;
   
if (!this._modulesLoaded) if (!this._modulesLoaded)
{ {
this.LoadModulesOfType<IVOID_Module>(); this.LoadModulesOfType<IVOID_Module>();
} }
   
if (!this.skinsLoaded) if (!this.skinsLoaded)
{ {
this.LoadSkins(); this.LoadSkins();
} }
   
GUI.skin = this.Skin; GUI.skin = this.Skin;
   
if (!this.GUIStylesLoaded) if (!this.GUIStylesLoaded)
{ {
this.LoadGUIStyles(); this.LoadGUIStyles();
} }
   
if (!this.UseToolbarManager) if (!this.UseToolbarManager)
{ {
if (this.AppLauncherButton == null) if (this.AppLauncherButton == null)
{ {
this.InitializeAppLauncherButton(); this.InitializeAppLauncherButton();
} }
} }
else if (this.ToolbarButton == null) else if (this.ToolbarButton == null)
{ {
this.InitializeToolbarButton(); this.InitializeToolbarButton();
} }
   
if (!this.mainGuiMinimized) if (!this.mainGuiMinimized)
{ {
   
Rect _mainWindowPos = this.mainWindowPos; Rect _mainWindowPos = this.mainWindowPos;
   
_mainWindowPos = GUILayout.Window( _mainWindowPos = GUILayout.Window(
this.windowID, this.windowID,
_mainWindowPos, _mainWindowPos,
VOID_Tools.GetWindowHandler(this.VOIDMainWindow), VOID_Tools.GetWindowHandler(this.VOIDMainWindow),
string.Join(" ", new string[] { this.VoidName, this.VoidVersion }), string.Join(" ", new string[] { this.VoidName, this.VoidVersion }),
GUILayout.Width(250), GUILayout.Width(250),
GUILayout.Height(50) GUILayout.Height(50)
); );
   
_mainWindowPos = Tools.ClampRectToScreen(_mainWindowPos); _mainWindowPos = Tools.ClampRectToScreen(_mainWindowPos);
   
if (_mainWindowPos != this.mainWindowPos) if (_mainWindowPos != this.mainWindowPos)
{ {
this.mainWindowPos = _mainWindowPos; this.mainWindowPos = _mainWindowPos;
} }
} }
   
if (!this.configWindowMinimized && !this.mainGuiMinimized) if (!this.configWindowMinimized && !this.mainGuiMinimized)
{ {
Rect _configWindowPos = this.configWindowPos; Rect _configWindowPos = this.configWindowPos;
   
_configWindowPos = GUILayout.Window( _configWindowPos = GUILayout.Window(
this.windowID, this.windowID,
_configWindowPos, _configWindowPos,
VOID_Tools.GetWindowHandler(this.VOIDConfigWindow), VOID_Tools.GetWindowHandler(this.VOIDConfigWindow),
string.Join(" ", new string[] { this.VoidName, "Configuration" }), string.Join(" ", new string[] { this.VoidName, "Configuration" }),
GUILayout.Width(250), GUILayout.Width(250),
GUILayout.Height(50) GUILayout.Height(50)
); );
   
_configWindowPos = Tools.ClampRectToScreen(_configWindowPos); _configWindowPos = Tools.ClampRectToScreen(_configWindowPos);
   
if (_configWindowPos != this.configWindowPos) if (_configWindowPos != this.configWindowPos)
{ {
this.configWindowPos = _configWindowPos; this.configWindowPos = _configWindowPos;
} }
} }
} }
   
public void OnGUI() public virtual void OnGUI()
{ {
if (Event.current.type == EventType.Repaint) if (Event.current.type == EventType.Repaint)
{ {
return; return;
} }
   
/* /*
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"Event.current.type: {0}" + "Event.current.type: {0}" +
"\nthis.VOIDIconLocked: {1}" + "\nthis.VOIDIconLocked: {1}" +
"\nEvent.current.mousePosition: {2}" + "\nEvent.current.mousePosition: {2}" +
"\nVOIDIconPos: ({3}, {4}),({5}, {6})", "\nVOIDIconPos: ({3}, {4}),({5}, {6})",
Event.current.type, Event.current.type,
this.VOIDIconLocked, this.VOIDIconLocked,
Event.current.mousePosition, Event.current.mousePosition,
this.VOIDIconPos.value.xMin, this.VOIDIconPos.value.xMin,
this.VOIDIconPos.value.yMin, this.VOIDIconPos.value.yMin,
this.VOIDIconPos.value.xMax, this.VOIDIconPos.value.xMax,
this.VOIDIconPos.value.yMax this.VOIDIconPos.value.yMax
)); ));
*/ */
   
if (!this.VOIDIconLocked && if (!this.VOIDIconLocked &&
VOIDIconPos.value.Contains(Event.current.mousePosition) VOIDIconPos.value.Contains(Event.current.mousePosition)
&& Event.current.type == EventType.mouseDrag) && Event.current.type == EventType.mouseDrag)
{ {
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"Event.current.type: {0}" + "Event.current.type: {0}" +
"\ndelta.x: {1}; delta.y: {2}", "\ndelta.x: {1}; delta.y: {2}",
Event.current.type, Event.current.type,
Event.current.delta.x, Event.current.delta.x,
Event.current.delta.y Event.current.delta.y
)); ));
   
Rect tmp = new Rect(VOIDIconPos); Rect tmp = new Rect(VOIDIconPos);
   
tmp.x = Event.current.mousePosition.x - tmp.width / 2; tmp.x = Event.current.mousePosition.x - tmp.width / 2;
tmp.y = Event.current.mousePosition.y - tmp.height / 2; tmp.y = Event.current.mousePosition.y - tmp.height / 2;
   
if (tmp.x > Screen.width - tmp.width) if (tmp.x > Screen.width - tmp.width)
{ {
tmp.x = Screen.width - tmp.width; tmp.x = Screen.width - tmp.width;
} }
   
if (tmp.y > Screen.height - tmp.height) if (tmp.y > Screen.height - tmp.height)
{ {
tmp.y = Screen.height - tmp.height; tmp.y = Screen.height - tmp.height;
} }
   
VOIDIconPos = tmp; VOIDIconPos = tmp;
} }
} }
   
public void Update() public virtual void Update()
{ {
this.LoadBeforeUpdate(); this.LoadBeforeUpdate();
   
if (this.vessel != null && this.vesselSimActive) if (this.vessel != null && this.vesselSimActive)
{ {
double radius = this.vessel.Radius(); double radius = this.vessel.Radius();
SimManager.Gravity = this.vessel.mainBody.gravParameter / SimManager.Gravity = this.vessel.mainBody.gravParameter /
(radius * radius); (radius * radius);
SimManager.minSimTime = (long)(this.updatePeriod * 1000); SimManager.minSimTime = (long)(this.updatePeriod * 1000);
SimManager.TryStartSimulation(); SimManager.TryStartSimulation();
} }
else if (!this.vesselSimActive) else if (!this.vesselSimActive)
{ {
SimManager.ClearResults(); SimManager.ClearResults();
} }
   
if (!this.guiRunning) if (!this.guiRunning)
{ {
this.StartGUI(); this.StartGUI();
} }
   
if (!HighLogic.LoadedSceneIsFlight && this.guiRunning) if (!HighLogic.LoadedSceneIsFlight && this.guiRunning)
{ {
this.StopGUI(); this.StopGUI();
} }
   
foreach (IVOID_Module module in this.Modules) foreach (IVOID_Module module in this.Modules)
{ {
if (!module.guiRunning && module.toggleActive) if (!module.guiRunning && module.toggleActive)
{ {
module.StartGUI(); module.StartGUI();
} }
if (module.guiRunning && !module.toggleActive || if (module.guiRunning && !module.toggleActive ||
!this.togglePower || !this.togglePower ||
!HighLogic.LoadedSceneIsFlight || !HighLogic.LoadedSceneIsFlight ||
this.factoryReset) this.factoryReset)
{ {
module.StopGUI(); module.StopGUI();
} }
   
if (module is IVOID_BehaviorModule) if (module is IVOID_BehaviorModule)
{ {
((IVOID_BehaviorModule)module).Update(); ((IVOID_BehaviorModule)module).Update();
} }
} }
   
this.CheckAndSave(); this.CheckAndSave();
this._updateTimer += Time.deltaTime; this._updateTimer += Time.deltaTime;
} }
   
public void FixedUpdate() public virtual void FixedUpdate()
{ {
bool newPowerState = this.powerAvailable; bool newPowerState = this.powerAvailable;
   
if (this.togglePower && this.consumeResource && if (this.togglePower && this.consumeResource &&
this.vessel.vesselType != VesselType.EVA && this.vessel.vesselType != VesselType.EVA &&
TimeWarp.deltaTime != 0) TimeWarp.deltaTime != 0)
{ {
float powerReceived = this.vessel.rootPart.RequestResource( float powerReceived = this.vessel.rootPart.RequestResource(
this.resourceName, this.resourceName,
this.resourceRate * TimeWarp.fixedDeltaTime this.resourceRate * TimeWarp.fixedDeltaTime
); );
   
if (powerReceived > 0) if (powerReceived > 0)
{ {
newPowerState = true; newPowerState = true;
} }
else else
{ {
newPowerState = false; newPowerState = false;
} }
   
if (this.powerAvailable != newPowerState) if (this.powerAvailable != newPowerState)
{ {
this.powerAvailable = newPowerState; this.powerAvailable = newPowerState;
this.SetIconTexture(this.powerState | this.activeState); this.SetIconTexture(this.powerState | this.activeState);
} }
} }
   
foreach (IVOID_BehaviorModule module in foreach (IVOID_BehaviorModule module in
this._modules.OfType<IVOID_BehaviorModule>().Where(m => !m.GetType().IsAbstract)) this._modules.OfType<IVOID_BehaviorModule>().Where(m => !m.GetType().IsAbstract))
{ {
module.FixedUpdate(); module.FixedUpdate();
} }
} }
   
public void ResetGUI() public void ResetGUI()
{ {
this.StopGUI(); this.StopGUI();
   
foreach (IVOID_Module module in this.Modules) foreach (IVOID_Module module in this.Modules)
{ {
module.StopGUI(); module.StopGUI();
module.StartGUI(); module.StartGUI();
} }
   
this.StartGUI(); this.StartGUI();
} }
   
public void VOIDMainWindow(int _) public void VOIDMainWindow(int _)
{ {
GUILayout.BeginVertical(); GUILayout.BeginVertical();
   
if (this.powerAvailable || HighLogic.LoadedSceneIsEditor) if (this.powerAvailable || HighLogic.LoadedSceneIsEditor)
{ {
if (!HighLogic.LoadedSceneIsEditor) if (!HighLogic.LoadedSceneIsEditor)
{ {
string str = string.Intern("ON"); string str = string.Intern("ON");
if (togglePower) if (togglePower)
str = string.Intern("OFF"); str = string.Intern("OFF");
if (GUILayout.Button("Power " + str)) if (GUILayout.Button("Power " + str))
{ {
togglePower.value = !togglePower; togglePower.value = !togglePower;
this.SetIconTexture(this.powerState | this.activeState); this.SetIconTexture(this.powerState | this.activeState);
} }
} }
   
if (togglePower || HighLogic.LoadedSceneIsEditor) if (togglePower || HighLogic.LoadedSceneIsEditor)
{ {
foreach (IVOID_Module module in this.Modules) foreach (IVOID_Module module in this.Modules)
{ {
module.toggleActive = GUILayout.Toggle(module.toggleActive, module.Name); module.toggleActive = GUILayout.Toggle(module.toggleActive, module.Name);
} }
} }
} }
else else
{ {
GUILayout.Label("-- POWER LOST --", this.LabelStyles["red"]); GUILayout.Label("-- POWER LOST --", this.LabelStyles["red"]);
} }
   
this.configWindowMinimized.value = !GUILayout.Toggle(!this.configWindowMinimized, "Configuration"); this.configWindowMinimized.value = !GUILayout.Toggle(!this.configWindowMinimized, "Configuration");
   
GUILayout.EndVertical(); GUILayout.EndVertical();
GUI.DragWindow(); GUI.DragWindow();
} }
   
public void VOIDConfigWindow(int _) public void VOIDConfigWindow(int _)
{ {
GUILayout.BeginVertical(); GUILayout.BeginVertical();
   
this.DrawConfigurables(); this.DrawConfigurables();
   
GUILayout.EndVertical(); GUILayout.EndVertical();
GUI.DragWindow(); GUI.DragWindow();
} }
   
public override void DrawConfigurables() public override void DrawConfigurables()
{ {
GUIContent _content; GUIContent _content;
   
if (HighLogic.LoadedSceneIsFlight) if (HighLogic.LoadedSceneIsFlight)
{ {
this.consumeResource.value = GUILayout.Toggle(this.consumeResource, "Consume Resources"); this.consumeResource.value = GUILayout.Toggle(this.consumeResource, "Consume Resources");
   
this.VOIDIconLocked = GUILayout.Toggle(this.VOIDIconLocked, "Lock Icon Position"); this.VOIDIconLocked = GUILayout.Toggle(this.VOIDIconLocked, "Lock Icon Position");
} }
   
this.UseToolbarManager = GUILayout.Toggle(this.UseToolbarManager, "Use Blizzy's Toolbar If Available"); this.UseToolbarManager = GUILayout.Toggle(this.UseToolbarManager, "Use Blizzy's Toolbar If Available");
   
this.vesselSimActive.value = GUILayout.Toggle(this.vesselSimActive.value, this.vesselSimActive.value = GUILayout.Toggle(this.vesselSimActive.value,
"Enable Engineering Calculations"); "Enable Engineering Calculations");
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
   
GUILayout.Label("Skin:", GUILayout.ExpandWidth(false)); GUILayout.Label("Skin:", GUILayout.ExpandWidth(false));
   
_content = new GUIContent(); _content = new GUIContent();
   
_content.text = "◄"; _content.text = "◄";
_content.tooltip = "Select previous skin"; _content.tooltip = "Select previous skin";
if (GUILayout.Button(_content, GUILayout.ExpandWidth(true))) if (GUILayout.Button(_content, GUILayout.ExpandWidth(true)))
{ {
this.GUIStylesLoaded = false; this.GUIStylesLoaded = false;
this._skinIdx--; this._skinIdx--;
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"{0}: new this._skinIdx = {1} :: skin_list.Count = {2}", "{0}: new this._skinIdx = {1} :: skin_list.Count = {2}",
this.GetType().Name, this.GetType().Name,
this._skinName, this._skinName,
this.validSkins.Count this.validSkins.Count
)); ));
} }
   
_content.text = this.Skin.name; _content.text = this.Skin.name;
_content.tooltip = "Current skin"; _content.tooltip = "Current skin";
GUILayout.Label(_content, this.LabelStyles["center"], GUILayout.ExpandWidth(true)); GUILayout.Label(_content, this.LabelStyles["center"], GUILayout.ExpandWidth(true));
   
_content.text = "►"; _content.text = "►";
_content.tooltip = "Select next skin"; _content.tooltip = "Select next skin";
if (GUILayout.Button(_content, GUILayout.ExpandWidth(true))) if (GUILayout.Button(_content, GUILayout.ExpandWidth(true)))
{ {
this.GUIStylesLoaded = false; this.GUIStylesLoaded = false;
this._skinIdx++; this._skinIdx++;
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"{0}: new this._skinIdx = {1} :: skin_list.Count = {2}", "{0}: new this._skinIdx = {1} :: skin_list.Count = {2}",
this.GetType().Name, this.GetType().Name,
this._skinName, this._skinName,
this.validSkins.Count this.validSkins.Count
)); ));
} }
   
this._skinIdx %= this.skinNames.Length; this._skinIdx %= this.skinNames.Length;
if (this._skinIdx < 0) if (this._skinIdx < 0)
{ {
this._skinIdx += this.skinNames.Length; this._skinIdx += this.skinNames.Length;
} }
   
if (this._skinName != skinNames[this._skinIdx]) if (this._skinName != skinNames[this._skinIdx])
{ {
this._skinName.value = skinNames[this._skinIdx]; this._skinName.value = skinNames[this._skinIdx];
} }
   
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
GUILayout.Label("Update Rate (Hz):"); GUILayout.Label("Update Rate (Hz):");
if (this.stringFrequency == null) if (this.stringFrequency == null)
{ {
this.stringFrequency = (1f / this.updatePeriod).ToString(); this.stringFrequency = (1f / this.updatePeriod).ToString();
} }
this.stringFrequency = GUILayout.TextField(this.stringFrequency.ToString(), 5, GUILayout.ExpandWidth(true)); this.stringFrequency = GUILayout.TextField(this.stringFrequency.ToString(), 5, GUILayout.ExpandWidth(true));
// GUILayout.FlexibleSpace(); // GUILayout.FlexibleSpace();
if (GUILayout.Button("Apply")) if (GUILayout.Button("Apply"))
{ {
double updateFreq = 1f / this.updatePeriod; double updateFreq = 1f / this.updatePeriod;
double.TryParse(stringFrequency, out updateFreq); double.TryParse(stringFrequency, out updateFreq);
this._updatePeriod = 1 / updateFreq; this._updatePeriod = 1 / updateFreq;
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
foreach (IVOID_Module mod in this.Modules) foreach (IVOID_Module mod in this.Modules)
{ {
mod.DrawConfigurables(); mod.DrawConfigurables();
} }
   
this._factoryReset = GUILayout.Toggle(this._factoryReset, "Factory Reset"); this._factoryReset = GUILayout.Toggle(this._factoryReset, "Factory Reset");
} }
   
protected void LoadModulesOfType<T>() protected void LoadModulesOfType<T>()
{ {
var types = AssemblyLoader.loadedAssemblies var types = AssemblyLoader.loadedAssemblies
.Select(a => a.assembly.GetExportedTypes()) .Select(a => a.assembly.GetExportedTypes())
.SelectMany(t => t) .SelectMany(t => t)
.Where(v => typeof(T).IsAssignableFrom(v) .Where(v => typeof(T).IsAssignableFrom(v)
&& !(v.IsInterface || v.IsAbstract) && && !(v.IsInterface || v.IsAbstract) &&
!typeof(VOID_Core).IsAssignableFrom(v) !typeof(VOID_Core).IsAssignableFrom(v)
); );
   
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"{0}: Found {1} modules to check.", "{0}: Found {1} modules to check.",
this.GetType().Name, this.GetType().Name,
types.Count() types.Count()
)); ));
foreach (var voidType in types) foreach (var voidType in types)
{ {
if (!HighLogic.LoadedSceneIsEditor && if (!HighLogic.LoadedSceneIsEditor &&
typeof(IVOID_EditorModule).IsAssignableFrom(voidType)) typeof(IVOID_EditorModule).IsAssignableFrom(voidType))
{ {
continue; continue;
} }
   
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"{0}: found Type {1}", "{0}: found Type {1}",
this.GetType().Name, this.GetType().Name,
voidType.Name voidType.Name
)); ));
   
this.LoadModule(voidType); this.LoadModule(voidType);
} }
   
this._modulesLoaded = true; this._modulesLoaded = true;
   
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"{0}: Loaded {1} modules.", "{0}: Loaded {1} modules.",
this.GetType().Name, this.GetType().Name,
this.Modules.Count this.Modules.Count
)); ));
} }
   
protected void LoadModule(Type T) protected void LoadModule(Type T)
{ {
var existingModules = this._modules.Where(mod => mod.GetType().Name == T.Name); var existingModules = this._modules.Where(mod => mod.GetType().Name == T.Name);
if (existingModules.Any()) if (existingModules.Any())
{ {
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"{0}: refusing to load {1}: already loaded", "{0}: refusing to load {1}: already loaded",
this.GetType().Name, this.GetType().Name,
T.Name T.Name
)); ));
return; return;
} }
IVOID_Module module = Activator.CreateInstance(T) as IVOID_Module; IVOID_Module module = Activator.CreateInstance(T) as IVOID_Module;
module.LoadConfig(); module.LoadConfig();
this._modules.Add(module); this._modules.Add(module);
   
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"{0}: loaded module {1}.", "{0}: loaded module {1}.",
this.GetType().Name, this.GetType().Name,
T.Name T.Name
)); ));
} }
   
protected void LoadSkins() protected void LoadSkins()
{ {
Tools.PostDebugMessage("AssetBase has skins: \n" + Tools.PostDebugMessage("AssetBase has skins: \n" +
string.Join("\n\t", string.Join("\n\t",
Resources.FindObjectsOfTypeAll(typeof(GUISkin)) Resources.FindObjectsOfTypeAll(typeof(GUISkin))
.Select(s => s.ToString()) .Select(s => s.ToString())
.ToArray() .ToArray()
) )
); );
   
this.validSkins = Resources.FindObjectsOfTypeAll(typeof(GUISkin)) this.validSkins = Resources.FindObjectsOfTypeAll(typeof(GUISkin))
.Where(s => !this.forbiddenSkins.Contains(s.name)) .Where(s => !this.forbiddenSkins.Contains(s.name))
.Select(s => s as GUISkin) .Select(s => s as GUISkin)
.GroupBy(s => s.name) .GroupBy(s => s.name)
.Select(g => g.First()) .Select(g => g.First())
.ToDictionary(s => s.name); .ToDictionary(s => s.name);
   
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"{0}: loaded {1} GUISkins.", "{0}: loaded {1} GUISkins.",
this.GetType().Name, this.GetType().Name,
this.validSkins.Count this.validSkins.Count
)); ));
   
this.skinNames = this.validSkins.Keys.ToArray(); this.skinNames = this.validSkins.Keys.ToArray();
Array.Sort(this.skinNames); Array.Sort(this.skinNames);
   
int defaultIdx = int.MinValue; int defaultIdx = int.MinValue;
   
for (int i = 0; i < this.skinNames.Length; i++) for (int i = 0; i < this.skinNames.Length; i++)
{ {
if (this.skinNames[i] == this._skinName) if (this.skinNames[i] == this._skinName)
{ {
this._skinIdx = i; this._skinIdx = i;
} }
if (this.skinNames[i] == this.defaultSkin) if (this.skinNames[i] == this.defaultSkin)
{ {
defaultIdx = i; defaultIdx = i;
} }
if (this._skinIdx != int.MinValue && defaultIdx != int.MinValue) if (this._skinIdx != int.MinValue && defaultIdx != int.MinValue)
{ {
break; break;
} }
} }
   
if (this._skinIdx == int.MinValue) if (this._skinIdx == int.MinValue)
{ {
this._skinIdx = defaultIdx; this._skinIdx = defaultIdx;
} }
   
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"{0}: _skinIdx = {1}.", "{0}: _skinIdx = {1}.",
this.GetType().Name, this.GetType().Name,
this._skinName.ToString() this._skinName.ToString()
)); ));
   
this.skinsLoaded = true; this.skinsLoaded = true;
} }
   
protected void LoadGUIStyles() protected void LoadGUIStyles()
{ {
this.LabelStyles["link"] = new GUIStyle(GUI.skin.label); this.LabelStyles["link"] = new GUIStyle(GUI.skin.label);
this.LabelStyles["link"].fontStyle = FontStyle.Bold; this.LabelStyles["link"].fontStyle = FontStyle.Bold;
   
this.LabelStyles["center"] = new GUIStyle(GUI.skin.label); this.LabelStyles["center"] = new GUIStyle(GUI.skin.label);
this.LabelStyles["center"].normal.textColor = Color.white; this.LabelStyles["center"].normal.textColor = Color.white;
this.LabelStyles["center"].alignment = TextAnchor.UpperCenter; this.LabelStyles["center"].alignment = TextAnchor.UpperCenter;
   
this.LabelStyles["center_bold"] = new GUIStyle(GUI.skin.label); this.LabelStyles["center_bold"] = new GUIStyle(GUI.skin.label);
this.LabelStyles["center_bold"].normal.textColor = Color.white; this.LabelStyles["center_bold"].normal.textColor = Color.white;
this.LabelStyles["center_bold"].alignment = TextAnchor.UpperCenter; this.LabelStyles["center_bold"].alignment = TextAnchor.UpperCenter;
this.LabelStyles["center_bold"].fontStyle = FontStyle.Bold; this.LabelStyles["center_bold"].fontStyle = FontStyle.Bold;
   
this.LabelStyles["right"] = new GUIStyle(GUI.skin.label); this.LabelStyles["right"] = new GUIStyle(GUI.skin.label);
this.LabelStyles["right"].normal.textColor = Color.white; this.LabelStyles["right"].normal.textColor = Color.white;
this.LabelStyles["right"].alignment = TextAnchor.UpperRight; this.LabelStyles["right"].alignment = TextAnchor.UpperRight;
   
this.LabelStyles["red"] = new GUIStyle(GUI.skin.label); this.LabelStyles["red"] = new GUIStyle(GUI.skin.label);
this.LabelStyles["red"].normal.textColor = Color.red; this.LabelStyles["red"].normal.textColor = Color.red;
this.LabelStyles["red"].alignment = TextAnchor.MiddleCenter; this.LabelStyles["red"].alignment = TextAnchor.MiddleCenter;
   
this.iconStyle = new GUIStyle(GUI.skin.button); this.iconStyle = new GUIStyle(GUI.skin.button);
this.iconStyle.padding = new RectOffset(0, 0, 0, 0); this.iconStyle.padding = new RectOffset(0, 0, 0, 0);
// this.iconStyle.margin = new RectOffset(0, 0, 0, 0); // this.iconStyle.margin = new RectOffset(0, 0, 0, 0);
// this.iconStyle.contentOffset = new Vector2(0, 0); // this.iconStyle.contentOffset = new Vector2(0, 0);
this.iconStyle.overflow = new RectOffset(0, 0, 0, 0); this.iconStyle.overflow = new RectOffset(0, 0, 0, 0);
// this.iconStyle.border = new RectOffset(0, 0, 0, 0); // this.iconStyle.border = new RectOffset(0, 0, 0, 0);
   
this.GUIStylesLoaded = true; this.GUIStylesLoaded = true;
} }
   
protected void LoadVesselTypes() protected void LoadVesselTypes()
{ {
this._allVesselTypes = Enum.GetValues(typeof(VesselType)).OfType<VesselType>().ToList(); this._allVesselTypes = Enum.GetValues(typeof(VesselType)).OfType<VesselType>().ToList();
this.vesselTypesLoaded = true; this.vesselTypesLoaded = true;
} }
   
protected void LoadBeforeUpdate() protected void LoadBeforeUpdate()
{ {
if (!this.vesselTypesLoaded) if (!this.vesselTypesLoaded)
{ {
this.LoadVesselTypes(); this.LoadVesselTypes();
} }
} }
   
protected void InitializeToolbarButton() protected void InitializeToolbarButton()
{ {
// Do nothing if the Toolbar is not available. // Do nothing if the Toolbar is not available.
if (!ToolbarManager.ToolbarAvailable) if (!ToolbarManager.ToolbarAvailable)
{ {
return; return;
} }
   
this.ToolbarButton = ToolbarManager.Instance.add(this.VoidName, "coreToggle"); this.ToolbarButton = ToolbarManager.Instance.add(this.VoidName, "coreToggle");
this.ToolbarButton.Text = this.VoidName; this.ToolbarButton.Text = this.VoidName;
this.SetIconTexture(this.powerState | this.activeState); this.SetIconTexture(this.powerState | this.activeState);
   
this.ToolbarButton.Visibility = new GameScenesVisibility(GameScenes.EDITOR, GameScenes.FLIGHT, GameScenes.SPH); this.ToolbarButton.Visibility = new GameScenesVisibility(GameScenes.EDITOR, GameScenes.FLIGHT, GameScenes.SPH);
   
this.ToolbarButton.OnClick += this.ToolbarButton.OnClick +=
(e) => (e) =>
{ {
this.ToggleMainWindow(); this.ToggleMainWindow();
}; };
   
Tools.PostDebugMessage(string.Format("{0}: Toolbar Button initialized.", this.GetType().Name)); Tools.PostDebugMessage(string.Format("{0}: Toolbar Button initialized.", this.GetType().Name));
} }
   
protected void InitializeAppLauncherButton() protected void InitializeAppLauncherButton()
{ {
if (ApplicationLauncher.Ready) if (ApplicationLauncher.Ready)
{ {
this.AppLauncherButton = ApplicationLauncher.Instance.AddModApplication( this.AppLauncherButton = ApplicationLauncher.Instance.AddModApplication(
this.ToggleMainWindow, this.ToggleMainWindow, this.ToggleMainWindow, this.ToggleMainWindow,
this.appIconVisibleScenes, this.appIconVisibleScenes,
this.VOIDIconTexture this.VOIDIconTexture
); );
   
Tools.PostDebugMessage( Tools.PostDebugMessage(
this, this,
"AppLauncherButton initialized in {0}", "AppLauncherButton initialized in {0}",
Enum.GetName( Enum.GetName(
typeof(GameScenes), typeof(GameScenes),
HighLogic.LoadedScene HighLogic.LoadedScene
) )
); );
} }
} }
   
protected void ToggleMainWindow() protected void ToggleMainWindow()
{ {
this.mainGuiMinimized = !this.mainGuiMinimized; this.mainGuiMinimized = !this.mainGuiMinimized;
this.SetIconTexture(this.powerState | this.activeState); this.SetIconTexture(this.powerState | this.activeState);
} }
   
protected void SetIconTexture(IconState state) protected void SetIconTexture(IconState state)
{ {
switch (state) switch (state)
{ {
case (IconState.PowerOff | IconState.Inactive): case (IconState.PowerOff | IconState.Inactive):
this.SetIconTexture(this.VOIDIconOffInactivePath); this.SetIconTexture(this.VOIDIconOffInactivePath);
break; break;
case (IconState.PowerOff | IconState.Active): case (IconState.PowerOff | IconState.Active):
this.SetIconTexture(this.VOIDIconOffActivePath); this.SetIconTexture(this.VOIDIconOffActivePath);
break; break;
case (IconState.PowerOn | IconState.Inactive): case (IconState.PowerOn | IconState.Inactive):
this.SetIconTexture(this.VOIDIconOnInactivePath); this.SetIconTexture(this.VOIDIconOnInactivePath);
break; break;
case (IconState.PowerOn | IconState.Active): case (IconState.PowerOn | IconState.Active):
this.SetIconTexture(this.VOIDIconOnActivePath); this.SetIconTexture(this.VOIDIconOnActivePath);
break; break;
default: default:
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
   
protected void SetIconTexture(string texturePath) protected void SetIconTexture(string texturePath)
{ {
if (this.ToolbarButton != null) if (this.ToolbarButton != null)
{ {
this.ToolbarButton.TexturePath = texturePath; this.ToolbarButton.TexturePath = texturePath;
} }
   
this.VOIDIconTexture = GameDatabase.Instance.GetTexture(texturePath.Replace("icon", "appIcon"), false); this.VOIDIconTexture = GameDatabase.Instance.GetTexture(texturePath.Replace("icon", "appIcon"), false);
   
if (this.AppLauncherButton != null) if (this.AppLauncherButton != null)
{ {
this.AppLauncherButton.SetTexture(VOIDIconTexture); this.AppLauncherButton.SetTexture(VOIDIconTexture);
} }
} }
   
protected void CheckAndSave() protected void CheckAndSave()
{ {
this.saveTimer += Time.deltaTime; this.saveTimer += Time.deltaTime;
   
if (this.saveTimer > 2f) if (this.saveTimer > 2f)
{ {
if (!this.configDirty) if (!this.configDirty)
{ {
return; return;
} }
   
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"{0}: Time to save, checking if configDirty: {1}", "{0}: Time to save, checking if configDirty: {1}",
this.GetType().Name, this.GetType().Name,
this.configDirty this.configDirty
)); ));
   
this.SaveConfig(); this.SaveConfig();
this.saveTimer = 0; this.saveTimer = 0;
} }
} }
   
public override void LoadConfig() public override void LoadConfig()
{ {
base.LoadConfig(); base.LoadConfig();
   
foreach (IVOID_Module module in this.Modules) foreach (IVOID_Module module in this.Modules)
{ {
module.LoadConfig(); module.LoadConfig();
} }
} }
   
public void SaveConfig() public void SaveConfig()
{ {
var config = KSP.IO.PluginConfiguration.CreateForType<VOID_Core>(); var config = KSP.IO.PluginConfiguration.CreateForType<VOID_Core>();
config.load(); config.load();
   
this._SaveToConfig(config); this._SaveToConfig(config);
   
foreach (IVOID_Module module in this.Modules) foreach (IVOID_Module module in this.Modules)
{ {
module._SaveToConfig(config); module._SaveToConfig(config);
} }
   
config.save(); config.save();
   
this.configDirty = false; this.configDirty = false;
} }
   
protected VOID_Core() protected VOID_Core()
{ {
this._Name = "VOID Core"; this._Name = "VOID Core";
   
System.Version version = this.GetType().Assembly.GetName().Version; System.Version version = this.GetType().Assembly.GetName().Version;
   
this.VoidVersion = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.MajorRevision); this.VoidVersion = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.MajorRevision);
   
this.toggleActive = true; this.toggleActive = true;
   
this._skinName = this.defaultSkin; this._skinName = this.defaultSkin;
this._skinIdx = int.MinValue; this._skinIdx = int.MinValue;
   
this.VOIDIconOnInactivePath = "VOID/Textures/void_icon_light_glow"; this.VOIDIconOnInactivePath = "VOID/Textures/void_icon_light_glow";
this.VOIDIconOnActivePath = "VOID/Textures/void_icon_dark_glow"; this.VOIDIconOnActivePath = "VOID/Textures/void_icon_dark_glow";
this.VOIDIconOffInactivePath = "VOID/Textures/void_icon_light"; this.VOIDIconOffInactivePath = "VOID/Textures/void_icon_light";
this.VOIDIconOffActivePath = "VOID/Textures/void_icon_dark"; this.VOIDIconOffActivePath = "VOID/Textures/void_icon_dark";
   
this.vesselSimActive = true; this.vesselSimActive = true;
   
this.UseToolbarManager = false; this.UseToolbarManager = false;
   
this.LoadConfig(); this.LoadConfig();
   
this.SetIconTexture(this.powerState | this.activeState); this.SetIconTexture(this.powerState | this.activeState);
} }
   
public virtual void Dispose() public virtual void Dispose()
{ {
if (this.AppLauncherButton != null) if (this.AppLauncherButton != null)
{ {
ApplicationLauncher.Instance.RemoveModApplication(this.AppLauncherButton); ApplicationLauncher.Instance.RemoveModApplication(this.AppLauncherButton);
this.AppLauncherButton = null; this.AppLauncherButton = null;
} }
if (this.ToolbarButton != null) if (this.ToolbarButton != null)
{ {
this.ToolbarButton.Destroy(); this.ToolbarButton.Destroy();
this.ToolbarButton = null; this.ToolbarButton = null;
} }
} }
   
protected enum IconState protected enum IconState
{ {
PowerOff = 1, PowerOff = 1,
PowerOn = 2, PowerOn = 2,
Inactive = 4, Inactive = 4,
Active = 8 Active = 8
} }
} }
   
public static partial class VOID_Data public static partial class VOID_Data
{ {
public static VOID_Core core public static VOID_Core core
{ {
get get
{ {
if (HighLogic.LoadedSceneIsEditor) if (HighLogic.LoadedSceneIsEditor)
{ {
return VOID_EditorCore.Instance; return VOID_EditorCore.Instance;
} }
else else
{ {
return VOID_Core.Instance; return VOID_Core.Instance;
} }
} }
} }
   
public static double KerbinGee public static double KerbinGee
{ {
get get
{ {
return core.Kerbin.gravParameter / (core.Kerbin.Radius * core.Kerbin.Radius); return core.Kerbin.gravParameter / (core.Kerbin.Radius * core.Kerbin.Radius);
} }
} }
} }
} }
   
   
// VOID // VOID
// //
// VOID_EditorCore.cs // VOID_EditorCore.cs
// //
// Copyright © 2014, toadicus // Copyright © 2014, toadicus
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without modification, // Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met: // are permitted provided that the following conditions are met:
// //
// 1. Redistributions of source code must retain the above copyright notice, // 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. // this list of conditions and the following disclaimer.
// //
// 2. Redistributions in binary form must reproduce the above copyright notice, // 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 // this list of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution. // materials provided with the distribution.
// //
// 3. Neither the name of the copyright holder nor the names of its contributors may be used // 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. // 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, // 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 // 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, // 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 // 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, // 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 // 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. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
using Engineer.VesselSimulator; using Engineer.VesselSimulator;
using KSP; using KSP;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using ToadicusTools; using ToadicusTools;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_EditorCore : VOID_Core public class VOID_EditorCore : VOID_Core
{ {
/* /*
* Static Members * Static Members
* */ * */
protected new static bool _initialized = false; protected new static bool _initialized = false;
public new static bool Initialized public new static bool Initialized
{ {
get get
{ {
return _initialized; return _initialized;
} }
} }
   
protected new static VOID_EditorCore _instance; protected new static VOID_EditorCore _instance;
public new static VOID_EditorCore Instance public new static VOID_EditorCore Instance
{ {
get get
{ {
if (_instance == null) if (_instance == null)
{ {
_instance = new VOID_EditorCore(); _instance = new VOID_EditorCore();
_initialized = true; _initialized = true;
} }
return _instance; return _instance;
} }
} }
   
public new static void Reset() public new static void Reset()
{ {
if (_initialized) if (_initialized)
{ {
_instance.StopGUI(); _instance.StopGUI();
_instance = null; _instance = null;
_initialized = false; _initialized = false;
} }
} }
   
protected override ApplicationLauncher.AppScenes appIconVisibleScenes protected override ApplicationLauncher.AppScenes appIconVisibleScenes
{ {
get get
{ {
return ApplicationLauncher.AppScenes.VAB | ApplicationLauncher.AppScenes.SPH; return ApplicationLauncher.AppScenes.VAB | ApplicationLauncher.AppScenes.SPH;
} }
} }
   
public VOID_EditorCore() : base() public VOID_EditorCore() : base()
{ {
this._Name = "VOID Editor Core"; this._Name = "VOID Editor Core";
} }
   
public new void OnGUI() {} public override void OnGUI() {}
   
public override void DrawGUI() public override void DrawGUI()
{ {
if (!this._modulesLoaded) if (!this._modulesLoaded)
{ {
this.LoadModulesOfType<IVOID_EditorModule>(); this.LoadModulesOfType<IVOID_EditorModule>();
} }
   
Rect _iconPos = Tools.DockToWindow (this.VOIDIconPos, this.mainWindowPos); Rect _iconPos = Tools.DockToWindow (this.VOIDIconPos, this.mainWindowPos);
   
_iconPos = Tools.ClampRectToScreen (_iconPos, (int)_iconPos.width, (int)_iconPos.height); _iconPos = Tools.ClampRectToScreen (_iconPos, (int)_iconPos.width, (int)_iconPos.height);
   
if (_iconPos != this.VOIDIconPos) if (_iconPos != this.VOIDIconPos)
{ {
this.VOIDIconPos = _iconPos; this.VOIDIconPos = _iconPos;
} }
   
base.DrawGUI(); base.DrawGUI();
} }
   
public new void Update() public override void Update()
{ {
foreach (IVOID_EditorModule module in this.Modules) foreach (IVOID_EditorModule module in this.Modules)
{ {
if (EditorLogic.startPod == null) if (EditorLogic.startPod == null)
{ {
module.StopGUI(); module.StopGUI();
continue; continue;
} }
if (HighLogic.LoadedSceneIsEditor && module.toggleActive && EditorLogic.SortedShipList.Any()) if (HighLogic.LoadedSceneIsEditor && module.toggleActive && EditorLogic.SortedShipList.Any())
{ {
module.StartGUI(); module.StartGUI();
} }
if (!HighLogic.LoadedSceneIsEditor || !module.toggleActive || !EditorLogic.SortedShipList.Any()) if (!HighLogic.LoadedSceneIsEditor || !module.toggleActive || !EditorLogic.SortedShipList.Any())
{ {
module.StopGUI(); module.StopGUI();
} }
} }
   
if (EditorLogic.startPod == null || !HighLogic.LoadedSceneIsEditor) if (EditorLogic.startPod == null || !HighLogic.LoadedSceneIsEditor)
{ {
this.StopGUI(); this.StopGUI();
return; return;
} }
else if (!this.guiRunning && HighLogic.LoadedSceneIsEditor) else if (!this.guiRunning && HighLogic.LoadedSceneIsEditor)
{ {
this.StartGUI(); this.StartGUI();
} }
   
if (EditorLogic.SortedShipList.Count > 0 && this.vesselSimActive) if (EditorLogic.SortedShipList.Count > 0 && this.vesselSimActive)
{ {
SimManager.Gravity = VOID_Data.KerbinGee; SimManager.Gravity = VOID_Data.KerbinGee;
SimManager.TryStartSimulation(); SimManager.TryStartSimulation();
} }
else if (!this.vesselSimActive) else if (!this.vesselSimActive)
{ {
SimManager.ClearResults(); SimManager.ClearResults();
} }
   
this.CheckAndSave (); this.CheckAndSave ();
} }
   
public new void FixedUpdate() {} public override void FixedUpdate() {}
} }
} }
   
   
// VOID // VOID
// //
// VOID_HUD.cs // VOID_HUD.cs
// //
// Copyright © 2014, toadicus // Copyright © 2014, toadicus
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without modification, // Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met: // are permitted provided that the following conditions are met:
// //
// 1. Redistributions of source code must retain the above copyright notice, // 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. // this list of conditions and the following disclaimer.
// //
// 2. Redistributions in binary form must reproduce the above copyright notice, // 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 // this list of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution. // materials provided with the distribution.
// //
// 3. Neither the name of the copyright holder nor the names of its contributors may be used // 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. // 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, // 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 // 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, // 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 // 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, // 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 // 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. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
using Engineer.VesselSimulator; using Engineer.VesselSimulator;
using KSP; using KSP;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using ToadicusTools; using ToadicusTools;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_HUDAdvanced : VOID_Module, IVOID_Module public class VOID_HUDAdvanced : VOID_Module, IVOID_Module
{ {
/* /*
* Fields * Fields
* */ * */
protected VOID_HUD primaryHUD; protected VOID_HUD primaryHUD;
   
protected Rect leftHUDdefaultPos; protected Rect leftHUDdefaultPos;
protected Rect rightHUDdefaultPos; protected Rect rightHUDdefaultPos;
   
[AVOID_SaveValue("leftHUDPos")] [AVOID_SaveValue("leftHUDPos")]
protected VOID_SaveValue<Rect> leftHUDPos; protected VOID_SaveValue<Rect> leftHUDPos;
[AVOID_SaveValue("rightHUDPos")] [AVOID_SaveValue("rightHUDPos")]
protected VOID_SaveValue<Rect> rightHUDPos; protected VOID_SaveValue<Rect> rightHUDPos;
   
[AVOID_SaveValue("positionsLocked")] [AVOID_SaveValue("positionsLocked")]
protected VOID_SaveValue<bool> positionsLocked; protected VOID_SaveValue<bool> positionsLocked;
   
/* /*
* Properties * Properties
* */ * */
public int ColorIndex public int ColorIndex
{ {
get get
{ {
if (this.primaryHUD == null) if (this.primaryHUD == null)
{ {
return 0; return 0;
} }
   
return this.primaryHUD.ColorIndex; return this.primaryHUD.ColorIndex;
} }
} }
   
/* /*
* Methods * Methods
* */ * */
public VOID_HUDAdvanced() : base() public VOID_HUDAdvanced() : base()
{ {
this._Name = "Advanced Heads-Up Display"; this._Name = "Advanced Heads-Up Display";
   
this.toggleActive = true; this.toggleActive = true;
   
this.leftHUDdefaultPos = new Rect( this.leftHUDdefaultPos = new Rect(
Screen.width * .5f - (float)GameSettings.UI_SIZE * .25f - 300f, Screen.width * .5f - (float)GameSettings.UI_SIZE * .25f - 300f,
Screen.height - 200f, Screen.height - 200f,
300f, 90f 300f, 90f
); );
this.leftHUDPos = new Rect(this.leftHUDdefaultPos); this.leftHUDPos = new Rect(this.leftHUDdefaultPos);
   
this.rightHUDdefaultPos = new Rect( this.rightHUDdefaultPos = new Rect(
Screen.width * .5f + (float)GameSettings.UI_SIZE * .25f, Screen.width * .5f + (float)GameSettings.UI_SIZE * .25f,
Screen.height - 200f, Screen.height - 200f,
300f, 90f 300f, 90f
); );
this.rightHUDPos = new Rect(this.rightHUDdefaultPos); this.rightHUDPos = new Rect(this.rightHUDdefaultPos);
   
this.positionsLocked = true; this.positionsLocked = true;
   
Tools.PostDebugMessage (this, "Constructed."); Tools.PostDebugMessage (this, "Constructed.");
} }
   
protected void leftHUDWindow(int id) protected void leftHUDWindow(int id)
{ {
StringBuilder leftHUD; StringBuilder leftHUD;
   
leftHUD = new StringBuilder(); leftHUD = new StringBuilder();
   
this.core.LabelStyles["hud"].alignment = TextAnchor.UpperRight; this.core.LabelStyles["hud"].alignment = TextAnchor.UpperRight;
   
if (this.core.powerAvailable) if (this.core.powerAvailable)
{ {
leftHUD.AppendFormat( leftHUD.AppendFormat(
string.Intern("Mass: {0}\n"), string.Intern("Mass: {0}\n"),
VOID_Data.totalMass.ToSIString(2) VOID_Data.totalMass.ToSIString(2)
); );
   
if (VOID_Data.vesselCrewCapacity > 0) if (VOID_Data.vesselCrewCapacity > 0)
{ {
leftHUD.AppendFormat( leftHUD.AppendFormat(
string.Intern("Crew: {0} / {1}\n"), string.Intern("Crew: {0} / {1}\n"),
VOID_Data.vesselCrewCount.Value, VOID_Data.vesselCrewCount.Value,
VOID_Data.vesselCrewCapacity.Value VOID_Data.vesselCrewCapacity.Value
); );
} }
   
leftHUD.AppendFormat( leftHUD.AppendFormat(
string.Intern("Acc: {0} T:W: {1}\n"), string.Intern("Acc: {0} T:W: {1}\n"),
VOID_Data.vesselAccel.ToSIString(2), VOID_Data.vesselAccel.ToSIString(2),
VOID_Data.currThrustWeight.Value.ToString("f2") VOID_Data.currThrustWeight.Value.ToString("f2")
); );
   
leftHUD.AppendFormat( leftHUD.AppendFormat(
string.Intern("Ang Vel: {0}\n"), string.Intern("Ang Vel: {0}\n"),
VOID_Data.vesselAngularVelocity.ToSIString(2) VOID_Data.vesselAngularVelocity.ToSIString(2)
); );
   
if (VOID_Data.stageNominalThrust != 0d) if (VOID_Data.stageNominalThrust != 0d)
{ {
leftHUD.AppendFormat( leftHUD.AppendFormat(
string.Intern("Thrust Offset: {0}\n"), string.Intern("Thrust Offset: {0}\n"),
VOID_Data.vesselThrustOffset.Value.ToString("F1") VOID_Data.vesselThrustOffset.Value.ToString("F1")
); );
} }
} }
else else
{ {
this.core.LabelStyles["hud"].normal.textColor = Color.red; this.core.LabelStyles["hud"].normal.textColor = Color.red;
leftHUD.Append(string.Intern("-- POWER LOST --")); leftHUD.Append(string.Intern("-- POWER LOST --"));
} }
   
GUILayout.Label(leftHUD.ToString(), this.core.LabelStyles["hud"], GUILayout.ExpandWidth(true)); GUILayout.Label(leftHUD.ToString(), this.core.LabelStyles["hud"], GUILayout.ExpandWidth(true));
   
if (!this.positionsLocked) if (!this.positionsLocked)
{ {
GUI.DragWindow(); GUI.DragWindow();
} }
   
GUI.BringWindowToBack(id); GUI.BringWindowToBack(id);
} }
   
protected void rightHUDWindow(int id) protected void rightHUDWindow(int id)
{ {
StringBuilder rightHUD; StringBuilder rightHUD;
   
rightHUD = new StringBuilder(); rightHUD = new StringBuilder();
   
this.core.LabelStyles["hud"].alignment = TextAnchor.UpperLeft; this.core.LabelStyles["hud"].alignment = TextAnchor.UpperLeft;
   
if (this.core.powerAvailable) if (this.core.powerAvailable)
{ {
rightHUD.AppendFormat( rightHUD.AppendFormat(
"Burn Δv (Rem/Tot): {0} / {1}\n", "Burn Δv (Rem/Tot): {0} / {1}\n",
VOID_Data.currManeuverDVRemaining.ValueUnitString("f2"), VOID_Data.currManeuverDVRemaining.ValueUnitString("f2"),
VOID_Data.currManeuverDeltaV.ValueUnitString("f2") VOID_Data.currManeuverDeltaV.ValueUnitString("f2")
); );
   
if (VOID_Data.upcomingManeuverNodes > 1) if (VOID_Data.upcomingManeuverNodes > 1)
{ {
rightHUD.AppendFormat("Next Burn Δv: {0}\n", rightHUD.AppendFormat("Next Burn Δv: {0}\n",
VOID_Data.nextManeuverDeltaV.ValueUnitString("f2") VOID_Data.nextManeuverDeltaV.ValueUnitString("f2")
); );
} }
   
rightHUD.AppendFormat("Burn Time (Rem/Total): {0} / {1}\n", rightHUD.AppendFormat("Burn Time (Rem/Total): {0} / {1}\n",
VOID_Tools.ConvertInterval(VOID_Data.currentNodeBurnRemaining.Value), VOID_Tools.ConvertInterval(VOID_Data.currentNodeBurnRemaining.Value),
VOID_Tools.ConvertInterval(VOID_Data.currentNodeBurnDuration.Value) VOID_Tools.ConvertInterval(VOID_Data.currentNodeBurnDuration.Value)
); );
   
if (VOID_Data.burnTimeDoneAtNode.Value != string.Empty) if (VOID_Data.burnTimeDoneAtNode.Value != string.Empty)
{ {
rightHUD.AppendFormat("{0} (done @ node)\n", rightHUD.AppendFormat("{0} (done @ node)\n",
VOID_Data.burnTimeDoneAtNode.Value VOID_Data.burnTimeDoneAtNode.Value
); );
   
rightHUD.AppendFormat("{0} (½ done @ node)", rightHUD.AppendFormat("{0} (½ done @ node)",
VOID_Data.burnTimeHalfDoneAtNode.Value VOID_Data.burnTimeHalfDoneAtNode.Value
); );
} }
else else
{ {
rightHUD.Append("Node is past"); rightHUD.Append("Node is past");
} }
} }
else else
{ {
this.core.LabelStyles["hud"].normal.textColor = Color.red; this.core.LabelStyles["hud"].normal.textColor = Color.red;
rightHUD.Append(string.Intern("-- POWER LOST --")); rightHUD.Append(string.Intern("-- POWER LOST --"));
} }
   
GUILayout.Label(rightHUD.ToString(), this.core.LabelStyles["hud"], GUILayout.ExpandWidth(true)); GUILayout.Label(rightHUD.ToString(), this.core.LabelStyles["hud"], GUILayout.ExpandWidth(true));
   
if (!this.positionsLocked) if (!this.positionsLocked)
{ {
GUI.DragWindow(); GUI.DragWindow();
} }
   
GUI.BringWindowToBack(id); GUI.BringWindowToBack(id);
} }
   
public override void DrawGUI() public override void DrawGUI()
{ {
if (this.primaryHUD == null) if (this.primaryHUD == null)
{ {
foreach (IVOID_Module module in this.core.Modules) foreach (IVOID_Module module in this.core.Modules)
{ {
if (module is VOID_HUD) if (module is VOID_HUD)
{ {
this.primaryHUD = module as VOID_HUD; this.primaryHUD = module as VOID_HUD;
} }
} }
} }
else else
{ {
if ((TimeWarp.WarpMode == TimeWarp.Modes.LOW) || (TimeWarp.CurrentRate <= TimeWarp.MaxPhysicsRate)) if ((TimeWarp.WarpMode == TimeWarp.Modes.LOW) || (TimeWarp.CurrentRate <= TimeWarp.MaxPhysicsRate))
{ {
SimManager.RequestSimulation(); SimManager.RequestSimulation();
} }
   
this.leftHUDPos.value = GUI.Window( this.leftHUDPos.value = GUI.Window(
this.core.windowID, this.core.windowID,
this.leftHUDPos, this.leftHUDPos,
VOID_Tools.GetWindowHandler(this.leftHUDWindow), VOID_Tools.GetWindowHandler(this.leftHUDWindow),
GUIContent.none, GUIContent.none,
GUIStyle.none GUIStyle.none
); );
   
if (VOID_Data.upcomingManeuverNodes > 0) if (VOID_Data.upcomingManeuverNodes > 0)
{ {
this.rightHUDPos.value = GUI.Window( this.rightHUDPos.value = GUI.Window(
this.core.windowID, this.core.windowID,
this.rightHUDPos, this.rightHUDPos,
VOID_Tools.GetWindowHandler(this.rightHUDWindow), VOID_Tools.GetWindowHandler(this.rightHUDWindow),
GUIContent.none, GUIContent.none,
GUIStyle.none GUIStyle.none
); );
} }
} }
} }
   
public override void DrawConfigurables() public override void DrawConfigurables()
{ {
this.positionsLocked = GUILayout.Toggle(this.positionsLocked, this.positionsLocked = GUILayout.Toggle(this.positionsLocked,
string.Intern("Lock Advanced HUD Positions"), string.Intern("Lock Advanced HUD Positions"),
GUILayout.ExpandWidth(false)); GUILayout.ExpandWidth(false));
} }
} }
   
public static partial class VOID_Data public static partial class VOID_Data
{ {
public static int upcomingManeuverNodes public static int upcomingManeuverNodes
{ {
get get
{ {
if (core.vessel == null || if (core.vessel == null ||
core.vessel.patchedConicSolver == null || core.vessel.patchedConicSolver == null ||
core.vessel.patchedConicSolver.maneuverNodes == null core.vessel.patchedConicSolver.maneuverNodes == null
) )
{ {
return 0; return 0;
} }
   
return core.vessel.patchedConicSolver.maneuverNodes.Count; return core.vessel.patchedConicSolver.maneuverNodes.Count;
} }
} }
   
public static readonly VOID_Vector3dValue vesselThrustOffset = new VOID_Vector3dValue( public static readonly VOID_Vector3dValue vesselThrustOffset = new VOID_Vector3dValue(
"Thrust Offset", "Thrust Offset",
delegate() delegate()
{ {
if (core.vessel == null) if (core.vessel == null)
{ {
return Vector3d.zero; return Vector3d.zero;
} }
   
List<PartModule> engineModules = core.vessel.getModulesOfType<PartModule>(); List<PartModule> engineModules = core.vessel.getModulesOfType<PartModule>();
   
Vector3d thrustPos = Vector3d.zero; Vector3d thrustPos = Vector3d.zero;
Vector3d thrustDir = Vector3d.zero; Vector3d thrustDir = Vector3d.zero;
float thrust = 0; float thrust = 0;
   
foreach (PartModule engine in engineModules) foreach (PartModule engine in engineModules)
{ {
float moduleThrust = 0; float moduleThrust = 0;
   
switch (engine.moduleName) switch (engine.moduleName)
{ {
case "ModuleEngines": case "ModuleEngines":
case "ModuleEnginesFX": case "ModuleEnginesFX":
break; break;
default: default:
continue; continue;
} }
   
if (!engine.isEnabled) if (!engine.isEnabled)
{ {
continue; continue;
} }
   
CenterOfThrustQuery cotQuery = new CenterOfThrustQuery(); CenterOfThrustQuery cotQuery = new CenterOfThrustQuery();
   
if (engine is ModuleEngines) if (engine is ModuleEngines)
{ {
ModuleEngines engineModule = engine as ModuleEngines; ModuleEngines engineModule = engine as ModuleEngines;
   
moduleThrust = engineModule.finalThrust; moduleThrust = engineModule.finalThrust;
   
engineModule.OnCenterOfThrustQuery(cotQuery); engineModule.OnCenterOfThrustQuery(cotQuery);
} }
else // engine is ModuleEnginesFX else // engine is ModuleEnginesFX
{ {
ModuleEnginesFX engineFXModule = engine as ModuleEnginesFX; ModuleEnginesFX engineFXModule = engine as ModuleEnginesFX;
   
moduleThrust = engineFXModule.finalThrust; moduleThrust = engineFXModule.finalThrust;
   
engineFXModule.OnCenterOfThrustQuery(cotQuery); engineFXModule.OnCenterOfThrustQuery(cotQuery);
} }
   
if (moduleThrust != 0d) if (moduleThrust != 0d)
{ {
cotQuery.thrust = moduleThrust; cotQuery.thrust = moduleThrust;
} }
   
thrustPos += cotQuery.pos * cotQuery.thrust; thrustPos += cotQuery.pos * cotQuery.thrust;
thrustDir += cotQuery.dir * cotQuery.thrust; thrustDir += cotQuery.dir * cotQuery.thrust;
thrust += cotQuery.thrust; thrust += cotQuery.thrust;
} }
   
if (thrust != 0) if (thrust != 0)
{ {
thrustPos /= thrust; thrustPos /= thrust;
thrustDir /= thrust; thrustDir /= thrust;
} }
   
Transform vesselTransform = core.vessel.transform; Transform vesselTransform = core.vessel.transform;
   
thrustPos = vesselTransform.InverseTransformPoint(thrustPos); thrustPos = vesselTransform.InverseTransformPoint(thrustPos);
thrustDir = vesselTransform.InverseTransformDirection(thrustDir); thrustDir = vesselTransform.InverseTransformDirection(thrustDir);
   
Vector3d thrustOffset = VectorTools.PointDistanceToLine( Vector3d thrustOffset = VectorTools.PointDistanceToLine(
thrustPos, thrustDir.normalized, core.vessel.findLocalCenterOfMass()); thrustPos, thrustDir.normalized, core.vessel.findLocalCenterOfMass());
   
Tools.PostDebugMessage(typeof(VOID_Data), "vesselThrustOffset:\n" + Tools.PostDebugMessage(typeof(VOID_Data), "vesselThrustOffset:\n" +
"\tthrustPos: {0}\n" + "\tthrustPos: {0}\n" +
"\tthrustDir: {1}\n" + "\tthrustDir: {1}\n" +
"\tthrustOffset: {2}\n" + "\tthrustOffset: {2}\n" +
"\tvessel.CoM: {3}", "\tvessel.CoM: {3}",
thrustPos, thrustPos,
thrustDir.normalized, thrustDir.normalized,
thrustOffset, thrustOffset,
core.vessel.findWorldCenterOfMass() core.vessel.findWorldCenterOfMass()
); );
   
return thrustOffset; return thrustOffset;
}, },
"m" "m"
); );
   
public static readonly VOID_DoubleValue vesselAccel = new VOID_DoubleValue( public static readonly VOID_DoubleValue vesselAccel = new VOID_DoubleValue(
"Acceleration", "Acceleration",
() => geeForce * KerbinGee, () => geeForce * KerbinGee,
"m/s²" "m/s²"
); );
   
public static readonly VOID_IntValue vesselCrewCount = new VOID_IntValue( public static readonly VOID_IntValue vesselCrewCount = new VOID_IntValue(
"Crew Onboard", "Crew Onboard",
delegate() delegate()
{ {
if (core.vessel != null) if (core.vessel != null)
{ {
return core.vessel.GetCrewCount(); return core.vessel.GetCrewCount();
} }
else else
{ {
return 0; return 0;
} }
}, },
"" ""
); );
   
public static readonly VOID_IntValue vesselCrewCapacity = new VOID_IntValue( public static readonly VOID_IntValue vesselCrewCapacity = new VOID_IntValue(
"Crew Capacity", "Crew Capacity",
delegate() delegate()
{ {
if (core.vessel != null) if (core.vessel != null)
{ {
return core.vessel.GetCrewCapacity(); return core.vessel.GetCrewCapacity();
} }
else else
{ {
return 0; return 0;
} }
}, },
"" ""
); );
   
public static readonly VOID_DoubleValue vesselAngularVelocity = new VOID_DoubleValue( public static readonly VOID_DoubleValue vesselAngularVelocity = new VOID_DoubleValue(
"Angular Velocity", "Angular Velocity",
delegate() delegate()
{ {
if (core.vessel != null) if (core.vessel != null)
{ {
return core.vessel.angularVelocity.magnitude; return core.vessel.angularVelocity.magnitude;
} }
else else
{ {
return double.NaN; return double.NaN;
} }
}, },
"rad/s" "rad/s"
); );
   
public static readonly VOID_DoubleValue stageNominalThrust = new VOID_DoubleValue( public static readonly VOID_DoubleValue stageNominalThrust = new VOID_DoubleValue(
"Nominal Stage Thrust", "Nominal Stage Thrust",
delegate() delegate()
{ {
if (SimManager.LastStage == null) if (SimManager.LastStage == null)
{ {
return double.NaN; return double.NaN;
} }
   
if (SimManager.LastStage.actualThrust == 0d) if (SimManager.LastStage.actualThrust == 0d)
{ {
return SimManager.LastStage.thrust; return SimManager.LastStage.thrust;
} }
else else
{ {
return SimManager.LastStage.actualThrust; return SimManager.LastStage.actualThrust;
} }
}, },
"kN" "kN"
); );
   
public static readonly VOID_DoubleValue stageMassFlow = new VOID_DoubleValue( public static readonly VOID_DoubleValue stageMassFlow = new VOID_DoubleValue(
"Stage Mass Flow", "Stage Mass Flow",
delegate() delegate()
{ {
if (SimManager.LastStage == null) if (SimManager.LastStage == null)
{ {
return double.NaN; return double.NaN;
} }
   
double stageIsp = SimManager.LastStage.isp; double stageIsp = SimManager.LastStage.isp;
double stageThrust = stageNominalThrust; double stageThrust = stageNominalThrust;
   
Tools.PostDebugMessage(typeof(VOID_Data), "calculating stageMassFlow from:\n" + Tools.PostDebugMessage(typeof(VOID_Data), "calculating stageMassFlow from:\n" +
"\tstageIsp: {0}\n" + "\tstageIsp: {0}\n" +
"\tstageThrust: {1}\n" + "\tstageThrust: {1}\n" +
"\tKerbinGee: {2}\n", "\tKerbinGee: {2}\n",
stageIsp, stageIsp,
stageThrust, stageThrust,
KerbinGee KerbinGee
); );
   
return stageThrust / (stageIsp * KerbinGee); return stageThrust / (stageIsp * KerbinGee);
}, },
"Mg/s" "Mg/s"
); );
   
public static readonly VOID_DoubleValue currManeuverDeltaV = new VOID_DoubleValue( public static readonly VOID_DoubleValue currManeuverDeltaV = new VOID_DoubleValue(
"Current Maneuver Delta-V", "Current Maneuver Delta-V",
delegate() delegate()
{ {
if (upcomingManeuverNodes > 0) if (upcomingManeuverNodes > 0)
{ {
return core.vessel.patchedConicSolver.maneuverNodes[0].DeltaV.magnitude; return core.vessel.patchedConicSolver.maneuverNodes[0].DeltaV.magnitude;
} }
else else
{ {
return double.NaN; return double.NaN;
} }
}, },
"m/s" "m/s"
); );
   
public static readonly VOID_DoubleValue currManeuverDVRemaining = new VOID_DoubleValue( public static readonly VOID_DoubleValue currManeuverDVRemaining = new VOID_DoubleValue(
"Remaining Maneuver Delta-V", "Remaining Maneuver Delta-V",
delegate() delegate()
{ {
if (upcomingManeuverNodes > 0) if (upcomingManeuverNodes > 0)
{ {
return core.vessel.patchedConicSolver.maneuverNodes[0].GetBurnVector(core.vessel.orbit).magnitude; return core.vessel.patchedConicSolver.maneuverNodes[0].GetBurnVector(core.vessel.orbit).magnitude;
} }
else else
{ {
return double.NaN; return double.NaN;
} }
}, },
"m/s" "m/s"
); );
   
public static readonly VOID_DoubleValue nextManeuverDeltaV = new VOID_DoubleValue( public static readonly VOID_DoubleValue nextManeuverDeltaV = new VOID_DoubleValue(
"Current Maneuver Delta-V", "Current Maneuver Delta-V",
delegate() delegate()
{ {
if (upcomingManeuverNodes > 1) if (upcomingManeuverNodes > 1)
{ {
return core.vessel.patchedConicSolver.maneuverNodes[1].DeltaV.magnitude; return core.vessel.patchedConicSolver.maneuverNodes[1].DeltaV.magnitude;
} }
else else
{ {
return double.NaN; return double.NaN;
} }
}, },
"m/s" "m/s"
); );
   
public static readonly VOID_DoubleValue currentNodeBurnDuration = new VOID_DoubleValue( public static readonly VOID_DoubleValue currentNodeBurnDuration = new VOID_DoubleValue(
"Total Burn Time", "Total Burn Time",
delegate() delegate()
{ {
if (SimManager.LastStage == null || currManeuverDeltaV.Value == double.NaN) if (SimManager.LastStage == null || currManeuverDeltaV.Value == double.NaN)
{ {
return double.NaN; return double.NaN;
} }
double stageThrust = stageNominalThrust; double stageThrust = stageNominalThrust;
   
return burnTime(currManeuverDeltaV.Value, totalMass, stageMassFlow, stageThrust); return burnTime(currManeuverDeltaV.Value, totalMass, stageMassFlow, stageThrust);
}, },
"s" "s"
); );
   
public static readonly VOID_DoubleValue currentNodeBurnRemaining = new VOID_DoubleValue( public static readonly VOID_DoubleValue currentNodeBurnRemaining = new VOID_DoubleValue(
"Burn Time Remaining", "Burn Time Remaining",
delegate() delegate()
{ {
if (SimManager.LastStage == null || currManeuverDVRemaining == double.NaN) if (SimManager.LastStage == null || currManeuverDVRemaining == double.NaN)
{ {
return double.NaN; return double.NaN;
} }
   
double stageThrust = stageNominalThrust; double stageThrust = stageNominalThrust;
   
return burnTime(currManeuverDVRemaining, totalMass, stageMassFlow, stageThrust); return burnTime(currManeuverDVRemaining, totalMass, stageMassFlow, stageThrust);
}, },
"s" "s"
); );
   
public static readonly VOID_DoubleValue currentNodeHalfBurnDuration = new VOID_DoubleValue( public static readonly VOID_DoubleValue currentNodeHalfBurnDuration = new VOID_DoubleValue(
"Half Burn Time", "Half Burn Time",
delegate() delegate()
{ {
if (SimManager.LastStage == null || currManeuverDeltaV.Value == double.NaN) if (SimManager.LastStage == null || currManeuverDeltaV.Value == double.NaN)
{ {
return double.NaN; return double.NaN;
} }
   
double stageThrust = stageNominalThrust; double stageThrust = stageNominalThrust;
   
return burnTime(currManeuverDeltaV.Value / 2d, totalMass, stageMassFlow, stageThrust); return burnTime(currManeuverDeltaV.Value / 2d, totalMass, stageMassFlow, stageThrust);
}, },
"s" "s"
); );
   
public static readonly VOID_StrValue burnTimeDoneAtNode = new VOID_StrValue( public static readonly VOID_StrValue burnTimeDoneAtNode = new VOID_StrValue(
"Full burn time to be half done at node", "Full burn time to be half done at node",
delegate() delegate()
{ {
if (SimManager.LastStage == null && upcomingManeuverNodes < 1) if (SimManager.LastStage == null && upcomingManeuverNodes < 1)
{ {
return "N/A"; return "N/A";
} }
   
ManeuverNode node = core.vessel.patchedConicSolver.maneuverNodes[0]; ManeuverNode node = core.vessel.patchedConicSolver.maneuverNodes[0];
   
if ((node.UT - Planetarium.GetUniversalTime()) < 0) if ((node.UT - Planetarium.GetUniversalTime()) < 0)
{ {
return string.Empty; return string.Empty;
} }
   
double interval = (node.UT - currentNodeBurnDuration) - Planetarium.GetUniversalTime(); double interval = (node.UT - currentNodeBurnDuration) - Planetarium.GetUniversalTime();
   
if (double.IsNaN(interval)) if (double.IsNaN(interval))
{ {
return string.Intern("NaN"); return string.Intern("NaN");
} }
   
int sign = Math.Sign(interval); int sign = Math.Sign(interval);
interval = Math.Abs(interval); interval = Math.Abs(interval);
   
string format; string format;
   
if (sign >= 0) if (sign >= 0)
{ {
format = string.Intern("T - {0}"); format = string.Intern("T - {0}");
} }
else else
{ {
format = string.Intern("T + {0}"); format = string.Intern("T + {0}");
} }
   
return string.Format(format, VOID_Tools.ConvertInterval(interval)); return string.Format(format, VOID_Tools.ConvertInterval(interval));
} }
); );
   
public static readonly VOID_StrValue burnTimeHalfDoneAtNode = new VOID_StrValue( public static readonly VOID_StrValue burnTimeHalfDoneAtNode = new VOID_StrValue(
"Full burn time to be half done at node", "Full burn time to be half done at node",
delegate() delegate()
{ {
if (SimManager.LastStage == null && upcomingManeuverNodes < 1) if (SimManager.LastStage == null && upcomingManeuverNodes < 1)
{ {
return "N/A"; return "N/A";
} }
   
ManeuverNode node = core.vessel.patchedConicSolver.maneuverNodes[0]; ManeuverNode node = core.vessel.patchedConicSolver.maneuverNodes[0];
   
if ((node.UT - Planetarium.GetUniversalTime()) < 0) if ((node.UT - Planetarium.GetUniversalTime()) < 0)
{ {
return string.Empty; return string.Empty;
} }
   
double interval = (node.UT - currentNodeHalfBurnDuration) - Planetarium.GetUniversalTime(); double interval = (node.UT - currentNodeHalfBurnDuration) - Planetarium.GetUniversalTime();
   
  if (double.IsNaN(interval))
  {
  return string.Intern("NaN");
  }
   
int sign = Math.Sign(interval); int sign = Math.Sign(interval);
interval = Math.Abs(interval); interval = Math.Abs(interval);
   
string format; string format;
   
if (sign >= 0) if (sign >= 0)
{ {
format = string.Intern("T - {0}"); format = string.Intern("T - {0}");
} }
else else
{ {
format = string.Intern("T + {0}"); format = string.Intern("T + {0}");
} }
   
return string.Format(format, VOID_Tools.ConvertInterval(interval)); return string.Format(format, VOID_Tools.ConvertInterval(interval));
} }
); );
   
private static double burnTime(double deltaV, double initialMass, double massFlow, double thrust) private static double burnTime(double deltaV, double initialMass, double massFlow, double thrust)
{ {
Tools.PostDebugMessage(typeof(VOID_Data), "calculating burnTime from:\n" + Tools.PostDebugMessage(typeof(VOID_Data), "calculating burnTime from:\n" +
"\tdeltaV: {0}\n" + "\tdeltaV: {0}\n" +
"\tinitialMass: {1}\n" + "\tinitialMass: {1}\n" +
"\tmassFlow: {2}\n" + "\tmassFlow: {2}\n" +
"\tthrust: {3}\n", "\tthrust: {3}\n",
deltaV, deltaV,
initialMass, initialMass,
massFlow, massFlow,
thrust thrust
); );
return initialMass / massFlow * (Math.Exp(deltaV * massFlow / thrust) - 1d); return initialMass / massFlow * (Math.Exp(deltaV * massFlow / thrust) - 1d);
} }
} }
} }
   
// VOID // VOID
// //
// VOID_Module.cs // VOID_Module.cs
// //
// Copyright © 2014, toadicus // Copyright © 2014, toadicus
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without modification, // Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met: // are permitted provided that the following conditions are met:
// //
// 1. Redistributions of source code must retain the above copyright notice, // 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. // this list of conditions and the following disclaimer.
// //
// 2. Redistributions in binary form must reproduce the above copyright notice, // 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 // this list of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution. // materials provided with the distribution.
// //
// 3. Neither the name of the copyright holder nor the names of its contributors may be used // 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. // 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, // 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 // 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, // 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 // 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, // 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 // 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. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using ToadicusTools; using ToadicusTools;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public abstract class VOID_Module : IVOID_Module public abstract class VOID_Module : IVOID_Module
{ {
/* /*
* Fields * Fields
* */ * */
[AVOID_SaveValue("Active")] [AVOID_SaveValue("Active")]
protected VOID_SaveValue<bool> _Active = false; protected VOID_SaveValue<bool> _Active = false;
protected bool _Running = false; protected bool _Running = false;
   
protected string _Name; protected string _Name;
   
protected float lastUpdate = 0; protected float lastUpdate = 0;
   
/* /*
* Properties * Properties
* */ * */
protected virtual VOID_Core core protected virtual VOID_Core core
{ {
get get
{ {
if (HighLogic.LoadedSceneIsEditor) if (HighLogic.LoadedSceneIsEditor)
{ {
return VOID_EditorCore.Instance as VOID_Core; return VOID_EditorCore.Instance as VOID_Core;
} }
   
return VOID_Core.Instance; return VOID_Core.Instance;
} }
} }
   
public virtual bool toggleActive public virtual bool toggleActive
{ {
get get
{ {
return this._Active; return this._Active;
} }
set set
{ {
this._Active.value = value; this._Active.value = value;
} }
} }
   
public virtual bool guiRunning public virtual bool guiRunning
{ {
get get
{ {
return this._Running; return this._Running;
} }
} }
   
public virtual string Name public virtual string Name
{ {
get get
{ {
return this._Name; return this._Name;
} }
} }
   
public virtual Vessel vessel public virtual Vessel vessel
{ {
get get
{ {
return FlightGlobals.ActiveVessel; return FlightGlobals.ActiveVessel;
} }
} }
   
/* /*
* Methods * Methods
* */ * */
public void StartGUI() public void StartGUI()
{ {
if (!this.toggleActive || this.guiRunning) if (!this.toggleActive || this.guiRunning)
{ {
return; return;
} }
   
Tools.PostDebugMessage (string.Format("Adding {0} to the draw queue.", this.GetType().Name)); Tools.PostDebugMessage (string.Format("Adding {0} to the draw queue.", this.GetType().Name));
RenderingManager.AddToPostDrawQueue (3, this.DrawGUI); RenderingManager.AddToPostDrawQueue (3, this.DrawGUI);
this._Running = true; this._Running = true;
} }
   
public void StopGUI() public void StopGUI()
{ {
if (!this.guiRunning) if (!this.guiRunning)
{ {
return; return;
} }
Tools.PostDebugMessage (string.Format("Removing {0} from the draw queue.", this.GetType().Name)); Tools.PostDebugMessage (string.Format("Removing {0} from the draw queue.", this.GetType().Name));
RenderingManager.RemoveFromPostDrawQueue (3, this.DrawGUI); RenderingManager.RemoveFromPostDrawQueue (3, this.DrawGUI);
this._Running = false; this._Running = false;
} }
   
public abstract void DrawGUI(); public abstract void DrawGUI();
   
public virtual void DrawConfigurables() {} public virtual void DrawConfigurables() {}
   
public virtual void LoadConfig() public virtual void LoadConfig()
{ {
var config = KSP.IO.PluginConfiguration.CreateForType<VOID_Core> (); var config = KSP.IO.PluginConfiguration.CreateForType<VOID_Core> ();
config.load (); config.load ();
   
foreach (var field in this.GetType().GetFields( foreach (var field in this.GetType().GetFields(
BindingFlags.NonPublic | BindingFlags.NonPublic |
BindingFlags.Public | BindingFlags.Public |
BindingFlags.Instance | BindingFlags.Instance |
BindingFlags.FlattenHierarchy BindingFlags.FlattenHierarchy
)) ))
{ {
object[] attrs = field.GetCustomAttributes(typeof(AVOID_SaveValue), false); object[] attrs = field.GetCustomAttributes(typeof(AVOID_SaveValue), false);
   
if (attrs.Length == 0) { if (attrs.Length == 0) {
continue; continue;
} }
   
AVOID_SaveValue attr = attrs.FirstOrDefault () as AVOID_SaveValue; AVOID_SaveValue attr = attrs.FirstOrDefault () as AVOID_SaveValue;
   
string fieldName = string.Format("{0}_{1}", this.GetType().Name, attr.Name); string fieldName = string.Format("{0}_{1}", this.GetType().Name, attr.Name);
   
Tools.PostDebugMessage(string.Format("{0}: Loading field {1}.", this.GetType().Name, fieldName)); Tools.PostDebugMessage(string.Format("{0}: Loading field {1}.", this.GetType().Name, fieldName));
   
object fieldValue = field.GetValue(this); object fieldValue = field.GetValue(this);
   
bool convertBack = false; bool convertBack = false;
if (fieldValue is IVOID_SaveValue) if (fieldValue is IVOID_SaveValue)
{ {
fieldValue = (fieldValue as IVOID_SaveValue).AsType; fieldValue = (fieldValue as IVOID_SaveValue).AsType;
convertBack = true; convertBack = true;
} }
   
fieldValue = config.GetValue(fieldName, fieldValue); fieldValue = config.GetValue(fieldName, fieldValue);
   
if (convertBack) if (convertBack)
{ {
Type type = typeof(VOID_SaveValue<>).MakeGenericType (fieldValue.GetType ()); Type type = typeof(VOID_SaveValue<>).MakeGenericType (fieldValue.GetType ());
IVOID_SaveValue convertValue = Activator.CreateInstance (type) as IVOID_SaveValue; IVOID_SaveValue convertValue = Activator.CreateInstance (type) as IVOID_SaveValue;
convertValue.SetValue (fieldValue); convertValue.SetValue (fieldValue);
fieldValue = convertValue; fieldValue = convertValue;
} }
   
field.SetValue (this, fieldValue); field.SetValue (this, fieldValue);
   
Tools.PostDebugMessage(string.Format("{0}: Loaded field {1}.", this.GetType().Name, fieldName)); Tools.PostDebugMessage(string.Format("{0}: Loaded field {1}.", this.GetType().Name, fieldName));
} }
} }
   
public virtual void _SaveToConfig(KSP.IO.PluginConfiguration config) public virtual void _SaveToConfig(KSP.IO.PluginConfiguration config)
{ {
foreach (var field in this.GetType().GetFields( foreach (var field in this.GetType().GetFields(
BindingFlags.Instance | BindingFlags.Instance |
BindingFlags.NonPublic | BindingFlags.NonPublic |
BindingFlags.Public | BindingFlags.Public |
BindingFlags.FlattenHierarchy BindingFlags.FlattenHierarchy
)) ))
{ {
object[] attrs = field.GetCustomAttributes(typeof(AVOID_SaveValue), false); object[] attrs = field.GetCustomAttributes(typeof(AVOID_SaveValue), false);
   
if (attrs.Length == 0) { if (attrs.Length == 0) {
continue; continue;
} }
   
AVOID_SaveValue attr = attrs.FirstOrDefault () as AVOID_SaveValue; AVOID_SaveValue attr = attrs.FirstOrDefault () as AVOID_SaveValue;
   
string fieldName = string.Format("{0}_{1}", this.GetType().Name, attr.Name); string fieldName = string.Format("{0}_{1}", this.GetType().Name, attr.Name);
   
object fieldValue = field.GetValue(this); object fieldValue = field.GetValue(this);
   
if (fieldValue is IVOID_SaveValue) if (fieldValue is IVOID_SaveValue)
{ {
fieldValue = (fieldValue as IVOID_SaveValue).AsType; fieldValue = (fieldValue as IVOID_SaveValue).AsType;
} }
   
config.SetValue(fieldName, fieldValue); config.SetValue(fieldName, fieldValue);
   
Tools.PostDebugMessage(string.Format("{0}: Saved field {1}.", this.GetType().Name, fieldName)); Tools.PostDebugMessage(string.Format("{0}: Saved field {1}.", this.GetType().Name, fieldName));
} }
} }
} }
   
public abstract class VOID_WindowModule : VOID_Module public abstract class VOID_WindowModule : VOID_Module
{ {
[AVOID_SaveValue("WindowPos")] [AVOID_SaveValue("WindowPos")]
protected Rect WindowPos = new Rect(Screen.width / 2, Screen.height / 2, 250f, 50f); protected Rect WindowPos;
protected float defWidth = 250f; protected float defWidth;
protected float defHeight = 50f; protected float defHeight;
   
  public VOID_WindowModule() : base()
  {
  this.defWidth = 250f;
  this.defHeight = 50f;
   
  this.WindowPos = new Rect(Screen.width / 2, Screen.height / 2, this.defWidth, this.defHeight);
  }
   
public abstract void ModuleWindow(int _); public abstract void ModuleWindow(int _);
   
public override void DrawGUI() public override void DrawGUI()
{ {
GUI.skin = this.core.Skin; GUI.skin = this.core.Skin;
   
Rect _Pos = this.WindowPos; Rect _Pos = this.WindowPos;
   
_Pos = GUILayout.Window( _Pos = GUILayout.Window(
this.core.windowID, this.core.windowID,
_Pos, _Pos,
VOID_Tools.GetWindowHandler(this.ModuleWindow), VOID_Tools.GetWindowHandler(this.ModuleWindow),
this.Name, this.Name,
GUILayout.Width(this.defWidth), GUILayout.Width(this.defWidth),
GUILayout.Height(this.defHeight) GUILayout.Height(this.defHeight)
); );
   
_Pos = Tools.ClampRectToScreen (_Pos); _Pos = Tools.ClampRectToScreen (_Pos);
   
if (_Pos != this.WindowPos) if (_Pos != this.WindowPos)
{ {
this.WindowPos = _Pos; this.WindowPos = _Pos;
this.core.configDirty = true; this.core.configDirty = true;
} }
} }
} }
} }
   
   
// VOID // VOID
// //
// VOID_Transfer.cs // VOID_Transfer.cs
// //
// Copyright © 2014, toadicus // Copyright © 2014, toadicus
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without modification, // Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met: // are permitted provided that the following conditions are met:
// //
// 1. Redistributions of source code must retain the above copyright notice, // 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. // this list of conditions and the following disclaimer.
// //
// 2. Redistributions in binary form must reproduce the above copyright notice, // 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 // this list of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution. // materials provided with the distribution.
// //
// 3. Neither the name of the copyright holder nor the names of its contributors may be used // 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. // 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, // 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 // 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, // 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 // 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, // 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 // 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. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
using KSP; using KSP;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using ToadicusTools; using ToadicusTools;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_Transfer : VOID_WindowModule public class VOID_Transfer : VOID_WindowModule
{ {
protected List<CelestialBody> selectedBodies = new List<CelestialBody>(); protected List<CelestialBody> selectedBodies = new List<CelestialBody>();
   
public VOID_Transfer() public VOID_Transfer() : base()
{ {
this._Name = "Transfer Angle Information"; this._Name = "Transfer Angle Information";
   
this.WindowPos.x = 475; this.WindowPos.x = 475;
this.WindowPos.y = 85; this.WindowPos.y = 85;
this.defWidth = 315; this.defWidth = 315;
} }
   
public override void ModuleWindow(int _) public override void ModuleWindow(int _)
{ {
GUILayout.BeginVertical(); GUILayout.BeginVertical();
   
if (vessel.mainBody.name == "Sun") //Vessel is orbiting the Sun if (vessel.mainBody.name == "Sun") //Vessel is orbiting the Sun
{ {
foreach (CelestialBody body in vessel.mainBody.orbitingBodies) foreach (CelestialBody body in vessel.mainBody.orbitingBodies)
{ {
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (GUILayout.Button(body.bodyName)) if (GUILayout.Button(body.bodyName))
{ {
//add or remove this body to this list of bodies to display more info on //add or remove this body to this list of bodies to display more info on
if (selectedBodies.Contains(body)) selectedBodies.Remove(body); if (selectedBodies.Contains(body)) selectedBodies.Remove(body);
else selectedBodies.Add(body); else selectedBodies.Add(body);
} }
GUILayout.Label("Inclined " + body.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label("Inclined " + body.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
if (selectedBodies.Contains(body)) if (selectedBodies.Contains(body))
{ {
VOID_Tools.display_transfer_angles_SUN2PLANET(body, vessel); //show phase angles for each selected body VOID_Tools.display_transfer_angles_SUN2PLANET(body, vessel); //show phase angles for each selected body
tad_targeting(body); //display Set/Unset Target button for each selected body tad_targeting(body); //display Set/Unset Target button for each selected body
} }
} }
} }
else if (vessel.mainBody.referenceBody.name == "Sun") //Vessel is orbiting a planet else if (vessel.mainBody.referenceBody.name == "Sun") //Vessel is orbiting a planet
{ {
foreach (CelestialBody body in vessel.mainBody.referenceBody.orbitingBodies) foreach (CelestialBody body in vessel.mainBody.referenceBody.orbitingBodies)
{ {
if (body.name != vessel.mainBody.name) // show other planets if (body.name != vessel.mainBody.name) // show other planets
{ {
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (GUILayout.Button(body.bodyName)) if (GUILayout.Button(body.bodyName))
{ {
//add or remove this body to this list of bodies to display more info on //add or remove this body to this list of bodies to display more info on
if (selectedBodies.Contains(body)) selectedBodies.Remove(body); if (selectedBodies.Contains(body)) selectedBodies.Remove(body);
else selectedBodies.Add(body); else selectedBodies.Add(body);
} }
GUILayout.Label("Inclined " + body.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label("Inclined " + body.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
if (selectedBodies.Contains(body)) if (selectedBodies.Contains(body))
{ {
VOID_Tools.display_transfer_angles_PLANET2PLANET(body, vessel); VOID_Tools.display_transfer_angles_PLANET2PLANET(body, vessel);
tad_targeting(body); //display Set/Unset Target button tad_targeting(body); //display Set/Unset Target button
} }
} }
} }
foreach (CelestialBody body in vessel.mainBody.orbitingBodies) // show moons foreach (CelestialBody body in vessel.mainBody.orbitingBodies) // show moons
{ {
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (GUILayout.Button(body.bodyName)) if (GUILayout.Button(body.bodyName))
{ {
//add or remove this body to this list of bodies to display more info on //add or remove this body to this list of bodies to display more info on
if (selectedBodies.Contains(body)) selectedBodies.Remove(body); if (selectedBodies.Contains(body)) selectedBodies.Remove(body);
else selectedBodies.Add(body); else selectedBodies.Add(body);
} }
GUILayout.Label("Inclined " + body.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label("Inclined " + body.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
if (selectedBodies.Contains(body)) if (selectedBodies.Contains(body))
{ {
VOID_Tools.display_transfer_angles_PLANET2MOON(body, vessel); VOID_Tools.display_transfer_angles_PLANET2MOON(body, vessel);
tad_targeting(body); //display Set/Unset Target button tad_targeting(body); //display Set/Unset Target button
} }
} }
} }
else if (vessel.mainBody.referenceBody.referenceBody.name == "Sun") // Vessel is orbiting a moon else if (vessel.mainBody.referenceBody.referenceBody.name == "Sun") // Vessel is orbiting a moon
{ {
foreach (CelestialBody body in vessel.mainBody.referenceBody.orbitingBodies) foreach (CelestialBody body in vessel.mainBody.referenceBody.orbitingBodies)
{ {
if (body.name != vessel.mainBody.name) // show other moons if (body.name != vessel.mainBody.name) // show other moons
{ {
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (GUILayout.Button(body.bodyName)) if (GUILayout.Button(body.bodyName))
{ {
//add or remove this body to this list of bodies to display more info on //add or remove this body to this list of bodies to display more info on
if (selectedBodies.Contains(body)) selectedBodies.Remove(body); if (selectedBodies.Contains(body)) selectedBodies.Remove(body);
else selectedBodies.Add(body); else selectedBodies.Add(body);
} }
GUILayout.Label("Inclined " + body.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label("Inclined " + body.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
if (selectedBodies.Contains(body)) if (selectedBodies.Contains(body))
{ {
VOID_Tools.display_transfer_angles_MOON2MOON(body, vessel); VOID_Tools.display_transfer_angles_MOON2MOON(body, vessel);
tad_targeting(body); //display Set/Unset Target button tad_targeting(body); //display Set/Unset Target button
} }
} }
} }
} }
GUILayout.EndVertical(); GUILayout.EndVertical();
GUI.DragWindow(); GUI.DragWindow();
} }
   
private void tad_targeting(CelestialBody body) private void tad_targeting(CelestialBody body)
{ {
//Target Set/Unset buttons //Target Set/Unset buttons
if (FlightGlobals.fetch.VesselTarget == null || (FlightGlobals.fetch.VesselTarget != null && FlightGlobals.fetch.VesselTarget.GetVessel() == null)) if (FlightGlobals.fetch.VesselTarget == null || (FlightGlobals.fetch.VesselTarget != null && FlightGlobals.fetch.VesselTarget.GetVessel() == null))
{ {
//No TGT set or TGT is a Body //No TGT set or TGT is a Body
if ((CelestialBody)FlightGlobals.fetch.VesselTarget != body) if ((CelestialBody)FlightGlobals.fetch.VesselTarget != body)
{ {
if (GUILayout.Button("Set Target", GUILayout.ExpandWidth(false))) if (GUILayout.Button("Set Target", GUILayout.ExpandWidth(false)))
{ {
FlightGlobals.fetch.SetVesselTarget(body); FlightGlobals.fetch.SetVesselTarget(body);
Tools.PostDebugMessage("[VOID] KSP Target set to CelestialBody " + body.bodyName); Tools.PostDebugMessage("[VOID] KSP Target set to CelestialBody " + body.bodyName);
} }
} }
else if ((CelestialBody)FlightGlobals.fetch.VesselTarget == body) else if ((CelestialBody)FlightGlobals.fetch.VesselTarget == body)
{ {
if (GUILayout.Button("Unset Target", GUILayout.ExpandWidth(false))) if (GUILayout.Button("Unset Target", GUILayout.ExpandWidth(false)))
{ {
FlightGlobals.fetch.SetVesselTarget(null); FlightGlobals.fetch.SetVesselTarget(null);
Tools.PostDebugMessage("[VOID] KSP Target set to null"); Tools.PostDebugMessage("[VOID] KSP Target set to null");
} }
} }
} }
else if (FlightGlobals.fetch.VesselTarget == null || (FlightGlobals.fetch.VesselTarget != null && FlightGlobals.fetch.VesselTarget.GetVessel() != null)) else if (FlightGlobals.fetch.VesselTarget == null || (FlightGlobals.fetch.VesselTarget != null && FlightGlobals.fetch.VesselTarget.GetVessel() != null))
{ {
//No TGT or TGT is a vessel //No TGT or TGT is a vessel
if (GUILayout.Button("Set Target", GUILayout.ExpandWidth(false))) if (GUILayout.Button("Set Target", GUILayout.ExpandWidth(false)))
{ {
FlightGlobals.fetch.SetVesselTarget(body); FlightGlobals.fetch.SetVesselTarget(body);
Tools.PostDebugMessage("[VOID] KSP Target set to CelestialBody " + body.bodyName); Tools.PostDebugMessage("[VOID] KSP Target set to CelestialBody " + body.bodyName);
} }
} }
} }
} }
} }
   
   
// VOID // VOID
// //
// VOID_VesselRegister.cs // VOID_VesselRegister.cs
// //
// Copyright © 2014, toadicus // Copyright © 2014, toadicus
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without modification, // Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met: // are permitted provided that the following conditions are met:
// //
// 1. Redistributions of source code must retain the above copyright notice, // 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. // this list of conditions and the following disclaimer.
// //
// 2. Redistributions in binary form must reproduce the above copyright notice, // 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 // this list of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution. // materials provided with the distribution.
// //
// 3. Neither the name of the copyright holder nor the names of its contributors may be used // 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. // 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, // 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 // 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, // 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 // 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, // 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 // 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. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
using KSP; using KSP;
using System; using System;
using System.Linq; using System.Linq;
using ToadicusTools; using ToadicusTools;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_VesselRegister : VOID_WindowModule public class VOID_VesselRegister : VOID_WindowModule
{ {
[AVOID_SaveValue("selectedBodyIdx")] [AVOID_SaveValue("selectedBodyIdx")]
protected VOID_SaveValue<int> selectedBodyIdx = 0; protected VOID_SaveValue<int> selectedBodyIdx = 0;
protected CelestialBody seletedBody; protected CelestialBody seletedBody;
   
[AVOID_SaveValue("selectedVesselTypeIdx")] [AVOID_SaveValue("selectedVesselTypeIdx")]
protected VOID_SaveValue<int> selectedVesselTypeIdx = 0; protected VOID_SaveValue<int> selectedVesselTypeIdx = 0;
protected VesselType selectedVesselType; protected VesselType selectedVesselType;
   
protected string vesselSituation = "Orbiting"; protected string vesselSituation = "Orbiting";
   
protected Vector2 selectorScrollPos = new Vector2(); protected Vector2 selectorScrollPos = new Vector2();
   
protected Vessel _selectedVessel; protected Vessel _selectedVessel;
   
public Vessel selectedVessel public Vessel selectedVessel
{ {
get get
{ {
return this._selectedVessel; return this._selectedVessel;
} }
} }
   
public VOID_VesselRegister() public VOID_VesselRegister() : base()
{ {
this._Name = "Vessel Register"; this._Name = "Vessel Register";
   
this.WindowPos.x = 845; this.WindowPos.x = 845;
this.WindowPos.y = 275; this.WindowPos.y = 275;
this.defHeight = 375; this.defHeight = 375;
} }
   
public override void ModuleWindow(int _) public override void ModuleWindow(int _)
{ {
if (!this.core.allVesselTypes.Any()) if (!this.core.allVesselTypes.Any())
{ {
return; return;
} }
   
GUILayout.BeginVertical(); GUILayout.BeginVertical();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (GUILayout.Button("<")) if (GUILayout.Button("<"))
{ {
selectedBodyIdx--; selectedBodyIdx--;
if (selectedBodyIdx < 0) selectedBodyIdx = this.core.allBodies.Count - 1; if (selectedBodyIdx < 0) selectedBodyIdx = this.core.allBodies.Count - 1;
} }
GUILayout.Label(this.core.allBodies[selectedBodyIdx].bodyName, this.core.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); GUILayout.Label(this.core.allBodies[selectedBodyIdx].bodyName, this.core.LabelStyles["center_bold"], GUILayout.ExpandWidth(true));
if (GUILayout.Button(">")) if (GUILayout.Button(">"))
{ {
selectedBodyIdx++; selectedBodyIdx++;
if (selectedBodyIdx > this.core.allBodies.Count - 1) selectedBodyIdx = 0; if (selectedBodyIdx > this.core.allBodies.Count - 1) selectedBodyIdx = 0;
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
seletedBody = this.core.allBodies[selectedBodyIdx]; seletedBody = this.core.allBodies[selectedBodyIdx];
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (GUILayout.Button("<")) if (GUILayout.Button("<"))
{ {
selectedVesselTypeIdx--; selectedVesselTypeIdx--;
if (selectedVesselTypeIdx < 0) selectedVesselTypeIdx = this.core.allVesselTypes.Count - 1; if (selectedVesselTypeIdx < 0) selectedVesselTypeIdx = this.core.allVesselTypes.Count - 1;
} }
GUILayout.Label(this.core.allVesselTypes[selectedVesselTypeIdx].ToString(), this.core.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); GUILayout.Label(this.core.allVesselTypes[selectedVesselTypeIdx].ToString(), this.core.LabelStyles["center_bold"], GUILayout.ExpandWidth(true));
if (GUILayout.Button(">")) if (GUILayout.Button(">"))
{ {
selectedVesselTypeIdx++; selectedVesselTypeIdx++;
if (selectedVesselTypeIdx > this.core.allVesselTypes.Count - 1) selectedVesselTypeIdx = 0; if (selectedVesselTypeIdx > this.core.allVesselTypes.Count - 1) selectedVesselTypeIdx = 0;
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
selectedVesselType = this.core.allVesselTypes[selectedVesselTypeIdx]; selectedVesselType = this.core.allVesselTypes[selectedVesselTypeIdx];
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (GUILayout.Button("Landed", GUILayout.ExpandWidth(true))) vesselSituation = "Landed"; if (GUILayout.Button("Landed", GUILayout.ExpandWidth(true))) vesselSituation = "Landed";
if (GUILayout.Button("Orbiting", GUILayout.ExpandWidth(true))) vesselSituation = "Orbiting"; if (GUILayout.Button("Orbiting", GUILayout.ExpandWidth(true))) vesselSituation = "Orbiting";
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label( GUILayout.Label(
VOID_Tools.UppercaseFirst(vesselSituation) + " " + selectedVesselType.ToString() + "s @ " + seletedBody.bodyName, VOID_Tools.UppercaseFirst(vesselSituation) + " " + selectedVesselType.ToString() + "s @ " + seletedBody.bodyName,
this.core.LabelStyles["center"], this.core.LabelStyles["center"],
GUILayout.ExpandWidth(true)); GUILayout.ExpandWidth(true));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
selectorScrollPos = GUILayout.BeginScrollView(selectorScrollPos, false, false); selectorScrollPos = GUILayout.BeginScrollView(selectorScrollPos, false, false);
   
foreach (Vessel v in FlightGlobals.Vessels) foreach (Vessel v in FlightGlobals.Vessels)
{ {
if (v != vessel && v.vesselType == selectedVesselType && v.mainBody == seletedBody) if (v != vessel && v.vesselType == selectedVesselType && v.mainBody == seletedBody)
{ {
if ((vesselSituation == "Landed" && if ((vesselSituation == "Landed" &&
(v.situation == Vessel.Situations.LANDED || (v.situation == Vessel.Situations.LANDED ||
v.situation == Vessel.Situations.PRELAUNCH || v.situation == Vessel.Situations.PRELAUNCH ||
v.situation == Vessel.Situations.SPLASHED)) || v.situation == Vessel.Situations.SPLASHED)) ||
(vesselSituation == "Orbiting" && (vesselSituation == "Orbiting" &&
(v.situation == Vessel.Situations.ESCAPING || (v.situation == Vessel.Situations.ESCAPING ||
v.situation == Vessel.Situations.FLYING || v.situation == Vessel.Situations.FLYING ||
v.situation == Vessel.Situations.ORBITING || v.situation == Vessel.Situations.ORBITING ||
v.situation == Vessel.Situations.SUB_ORBITAL)) v.situation == Vessel.Situations.SUB_ORBITAL))
) )
{ {
if (GUILayout.Button(v.vesselName, GUILayout.ExpandWidth(true))) if (GUILayout.Button(v.vesselName, GUILayout.ExpandWidth(true)))
{ {
if (_selectedVessel != v) if (_selectedVessel != v)
{ {
_selectedVessel = v; //set clicked vessel as selected_vessel _selectedVessel = v; //set clicked vessel as selected_vessel
this.toggleActive = true; //turn bool on to open the window if closed this.toggleActive = true; //turn bool on to open the window if closed
} }
else else
{ {
_selectedVessel = null; _selectedVessel = null;
} }
} }
} }
} }
} }
   
GUILayout.EndScrollView(); GUILayout.EndScrollView();
   
GUILayout.EndVertical(); GUILayout.EndVertical();
   
GUI.DragWindow(); GUI.DragWindow();
} }
} }
} }