VOID_Core: Changing Core to save the skin preference as a string instead of an integer, and improving some of the fault detection around it.
VOID_Core: Changing Core to save the skin preference as a string instead of an integer, and improving some of the fault detection around it.

// //
// IntCollection.cs // IntCollection.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using System; using System;
   
namespace VOID namespace VOID
{ {
public class IntCollection : IVOID_SaveValue public class IntCollection
{ {
public static implicit operator long(IntCollection c) public static implicit operator long(IntCollection c)
{ {
return c.collection; return c.collection;
} }
   
protected long mask; protected long mask;
   
public long collection { get; protected set; } public long collection { get; protected set; }
public ushort maxCount { get; protected set; } public ushort maxCount { get; protected set; }
public ushort wordLength { get; protected set; } public ushort wordLength { get; protected set; }
   
public Type type { get { return typeof(long); } }  
public object AsType { get { return this.collection; } }  
   
public void SetValue(object v)  
{  
this.collection = (long)v;  
}  
   
public IntCollection (ushort wordLength = 4, long initialCollection = 0) public IntCollection (ushort wordLength = 4, long initialCollection = 0)
{ {
this.collection = initialCollection; this.collection = initialCollection;
this.wordLength = wordLength; this.wordLength = wordLength;
this.maxCount = (ushort)((sizeof(long) * 8 - 1) / wordLength); this.maxCount = (ushort)((sizeof(long) * 8 - 1) / wordLength);
this.mask = ((1 << this.wordLength) - 1); this.mask = ((1 << this.wordLength) - 1);
} }
   
public ushort this[int idx] public ushort this[int idx]
{ {
get { get {
if (idx < 0) { if (idx < 0) {
idx += this.maxCount; idx += this.maxCount;
} }
   
if (idx >= maxCount || idx < 0) { if (idx >= maxCount || idx < 0) {
throw new IndexOutOfRangeException (); throw new IndexOutOfRangeException ();
} }
   
idx *= wordLength; idx *= wordLength;
   
return (ushort)((this.collection & (this.mask << idx)) >> idx); return (ushort)((this.collection & (this.mask << idx)) >> idx);
} }
set { set {
Console.WriteLine (value); Console.WriteLine (value);
if (idx < 0) { if (idx < 0) {
idx += this.maxCount; idx += this.maxCount;
} }
   
if (idx >= maxCount || idx < 0) { if (idx >= maxCount || idx < 0) {
throw new IndexOutOfRangeException (); throw new IndexOutOfRangeException ();
} }
   
idx *= wordLength; idx *= wordLength;
   
long packvalue = value & this.mask; long packvalue = value & this.mask;
Console.WriteLine (packvalue); Console.WriteLine (packvalue);
   
this.collection &= ~(this.mask << idx); this.collection &= ~(this.mask << idx);
this.collection |= packvalue << idx; this.collection |= packvalue << idx;
} }
} }
} }
} }
   
   
file:a/VOID.csproj (deleted)
<?xml version="1.0" encoding="utf-8"?>  
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">  
<PropertyGroup>  
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>  
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>  
<ProductVersion>10.0.0</ProductVersion>  
<SchemaVersion>2.0</SchemaVersion>  
<ProjectGuid>{45ACC1CC-942C-4A66-BFC7-8BE375938B18}</ProjectGuid>  
<OutputType>Library</OutputType>  
<RootNamespace>VOID</RootNamespace>  
<AssemblyName>VOID</AssemblyName>  
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>  
</PropertyGroup>  
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">  
<DebugSymbols>true</DebugSymbols>  
<DebugType>full</DebugType>  
<Optimize>false</Optimize>  
<OutputPath>bin\Debug</OutputPath>  
<DefineConstants>DEBUG; TRACE</DefineConstants>  
<ErrorReport>prompt</ErrorReport>  
<WarningLevel>4</WarningLevel>  
<ConsolePause>false</ConsolePause>  
<CustomCommands>  
<CustomCommands>  
<Command type="AfterBuild" command="/usr/bin/cp -fv ${ProjectDir}/bin/Debug/VOID.dll /mnt/games/ssd/KSP_linux/GameData/VOID/Plugins/" />  
</CustomCommands>  
</CustomCommands>  
</PropertyGroup>  
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">  
<Optimize>true</Optimize>  
<OutputPath>bin\Release</OutputPath>  
<ErrorReport>prompt</ErrorReport>  
<WarningLevel>4</WarningLevel>  
<ConsolePause>false</ConsolePause>  
<DefineConstants>TRACE</DefineConstants>  
<CustomCommands>  
<CustomCommands>  
<Command type="AfterBuild" command="/usr/bin/cp -fv ${ProjectDir}/bin/Release/VOID.dll /mnt/games/ssd/KSP_linux/GameData/VOID/Plugins/" />  
</CustomCommands>  
</CustomCommands>  
</PropertyGroup>  
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />  
<ItemGroup>  
<Compile Include="Tools.cs" />  
<Compile Include="IVOID_Module.cs" />  
<Compile Include="VOIDFlightMaster.cs" />  
<Compile Include="VOID_Core.cs" />  
<Compile Include="VOID_Module.cs" />  
<Compile Include="VOID_HUD.cs" />  
<Compile Include="VOID_SaveValue.cs" />  
<Compile Include="VOID_Orbital.cs" />  
<Compile Include="VOID_SurfAtmo.cs" />  
<Compile Include="VOID_VesselInfo.cs" />  
<Compile Include="VOID_Transfer.cs" />  
<Compile Include="VOID_CBInfoBrowser.cs" />  
<Compile Include="VOID_Rendezvous.cs" />  
<Compile Include="VOID_VesselRegister.cs" />  
<Compile Include="VOID_DataLogger.cs" />  
<Compile Include="VOID_EditorCore.cs" />  
<Compile Include="VOID_EditorHUD.cs" />  
<Compile Include="IntCollection.cs" />  
</ItemGroup>  
<ItemGroup>  
<Reference Include="Assembly-CSharp">  
<HintPath>..\..\..\..\..\mnt\games-ssd\KSP_linux\KSP_Data\Managed\Assembly-CSharp.dll</HintPath>  
<Private>False</Private>  
</Reference>  
<Reference Include="UnityEngine">  
<HintPath>..\..\..\..\..\mnt\games-ssd\KSP_linux\KSP_Data\Managed\UnityEngine.dll</HintPath>  
<Private>False</Private>  
</Reference>  
<Reference Include="System">  
<HintPath>..\..\..\..\..\mnt\games-ssd\KSP_linux\KSP_Data\Managed\System.dll</HintPath>  
<Private>False</Private>  
</Reference>  
</ItemGroup>  
<ItemGroup>  
<ProjectReference Include="..\Engineer.Extensions\Engineer.Extensions.csproj">  
<Project>{2FCF882B-0771-4649-8D04-81D7AA76A486}</Project>  
<Name>Engineer.Extensions</Name>  
</ProjectReference>  
<ProjectReference Include="..\VesselSimulator\VesselSimulator.csproj">  
<Project>{30FD6C0B-D36E-462F-B0FF-F0FAC9C666CF}</Project>  
<Name>VesselSimulator</Name>  
</ProjectReference>  
</ItemGroup>  
<ProjectExtensions>  
<MonoDevelop>  
<Properties>  
<Policies>  
<StandardHeader Text=" &#xA; ${FileName}&#xA; &#xA; Author:&#xA; ${AuthorName} &lt;${AuthorEmail}&gt;&#xA;&#xA; Copyright (c) ${Year} ${CopyrightHolder}&#xA;&#xA; This program is free software: you can redistribute it and/or modify&#xA; it under the terms of the GNU General Public License as published by&#xA; the Free Software Foundation, either version 3 of the License, or&#xA; (at your option) any later version.&#xA;&#xA; This program is distributed in the hope that it will be useful,&#xA; but WITHOUT ANY WARRANTY; without even the implied warranty of&#xA; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&#xA; GNU General Public License for more details.&#xA;&#xA; You should have received a copy of the GNU General Public License&#xA; along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;." IncludeInNewFiles="True" />  
</Policies>  
</Properties>  
</MonoDevelop>  
</ProjectExtensions>  
</Project>  
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
// VOID - Vessel Orbital Information Display for Kerbal Space Program // VOID - Vessel Orbital Information Display for Kerbal Space Program
// Copyright (C) 2012 Iannic-ann-od // Copyright (C) 2012 Iannic-ann-od
// Copyright (C) 2013 Toadicus // Copyright (C) 2013 Toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
// Much, much credit to Younata, Adammada, Nivvydaskrl and to all the authors // Much, much credit to Younata, Adammada, Nivvydaskrl and to all the authors
// behind MechJeb, RemoteTech Relay Network, ISA MapSat, and Protractor for some // behind MechJeb, RemoteTech Relay Network, ISA MapSat, and Protractor for some
// invaluable functions and making your nicely written code available to learn from. // invaluable functions and making your nicely written code available to learn from.
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
// This software uses VesselSimulator and Engineer.Extensions from Engineer Redux. // This software uses VesselSimulator and Engineer.Extensions from Engineer Redux.
// Engineer Redux (c) 2013 cybutek // Engineer Redux (c) 2013 cybutek
// Used by permission. // Used by permission.
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
   
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityEngine; using UnityEngine;
using Engineer.VesselSimulator; using Engineer.VesselSimulator;
   
namespace VOID namespace VOID
{ {
[KSPAddon(KSPAddon.Startup.Flight, false)] [KSPAddon(KSPAddon.Startup.Flight, false)]
public class VOIDFlightMaster : MonoBehaviour public class VOIDFlightMaster : MonoBehaviour
{ {
protected VOID_Core Core; protected VOID_Core Core;
   
public void Awake() public void Awake()
{ {
Tools.PostDebugMessage ("VOIDFlightMaster: Waking up."); Tools.PostDebugMessage ("VOIDFlightMaster: Waking up.");
this.Core = (VOID_Core)VOID_Core.Instance; this.Core = (VOID_Core)VOID_Core.Instance;
this.Core.ResetGUI (); this.Core.ResetGUI ();
  SimManager.HardReset();
Tools.PostDebugMessage ("VOIDFlightMaster: Awake."); Tools.PostDebugMessage ("VOIDFlightMaster: Awake.");
} }
   
public void Update() public void Update()
{ {
if (!HighLogic.LoadedSceneIsFlight && this.Core != null) if (!HighLogic.LoadedSceneIsFlight && this.Core != null)
{ {
this.Core.SaveConfig (); this.Core.SaveConfig ();
this.Core = null; this.Core = null;
VOID_Core.Reset(); VOID_Core.Reset();
return; return;
} }
   
if (this.Core == null) if (this.Core == null)
{ {
this.Awake(); this.Awake();
} }
   
this.Core.Update (); this.Core.Update ();
   
if (this.Core.vessel != null)  
{  
SimManager.Instance.Gravity = VOID_Core.Instance.vessel.mainBody.gravParameter /  
Math.Pow(VOID_Core.Instance.vessel.mainBody.Radius, 2);  
SimManager.Instance.TryStartSimulation();  
}  
   
if (this.Core.factoryReset) if (this.Core.factoryReset)
{ {
KSP.IO.File.Delete<VOID_Core>("config.xml"); KSP.IO.File.Delete<VOID_Core>("config.xml");
this.Core = null; this.Core = null;
VOID_Core.Reset(); VOID_Core.Reset();
} }
} }
   
public void FixedUpdate() public void FixedUpdate()
{ {
if (this.Core == null || !HighLogic.LoadedSceneIsFlight) if (this.Core == null || !HighLogic.LoadedSceneIsFlight)
{ {
return; return;
} }
   
this.Core.FixedUpdate (); this.Core.FixedUpdate ();
} }
   
public void OnGUI() public void OnGUI()
{ {
if (this.Core == null) if (this.Core == null)
{ {
return; return;
} }
   
this.Core.OnGUI(); this.Core.OnGUI();
} }
} }
   
[KSPAddon(KSPAddon.Startup.EditorAny, false)] [KSPAddon(KSPAddon.Startup.EditorAny, false)]
public class VOIDEditorMaster : MonoBehaviour public class VOIDEditorMaster : MonoBehaviour
{ {
protected VOID_EditorCore Core; protected VOID_EditorCore Core;
   
public void Awake() public void Awake()
{ {
Tools.PostDebugMessage ("VOIDEditorMaster: Waking up."); Tools.PostDebugMessage ("VOIDEditorMaster: Waking up.");
this.Core = VOID_EditorCore.Instance; this.Core = VOID_EditorCore.Instance;
this.Core.ResetGUI (); this.Core.ResetGUI ();
  SimManager.HardReset();
Tools.PostDebugMessage ("VOIDEditorMaster: Awake."); Tools.PostDebugMessage ("VOIDEditorMaster: Awake.");
} }
   
public void Update() public void Update()
{ {
if (!HighLogic.LoadedSceneIsEditor && this.Core != null) if (!HighLogic.LoadedSceneIsEditor && this.Core != null)
{ {
this.Core.SaveConfig (); this.Core.SaveConfig ();
this.Core = null; this.Core = null;
VOID_EditorCore.Reset(); VOID_EditorCore.Reset();
return; return;
} }
   
if (this.Core == null) if (this.Core == null)
{ {
this.Awake(); this.Awake();
} }
   
this.Core.Update (); this.Core.Update ();
   
if (this.Core.factoryReset) if (this.Core.factoryReset)
{ {
KSP.IO.File.Delete<VOID_EditorCore>("config.xml"); KSP.IO.File.Delete<VOID_EditorCore>("config.xml");
this.Core = null; this.Core = null;
VOID_EditorCore.Reset(); VOID_EditorCore.Reset();
} }
} }
   
public void FixedUpdate() public void FixedUpdate()
{ {
if (this.Core == null || !HighLogic.LoadedSceneIsEditor) if (this.Core == null || !HighLogic.LoadedSceneIsEditor)
{ {
return; return;
} }
   
this.Core.FixedUpdate (); this.Core.FixedUpdate ();
} }
   
public void OnGUI() public void OnGUI()
{ {
if (this.Core == null) if (this.Core == null)
{ {
return; return;
} }
   
this.Core.OnGUI(); this.Core.OnGUI();
} }
} }
} }
   
// //
// VOID_Core.cs // VOID_Core.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;  
using KSP; using KSP;
using UnityEngine; using UnityEngine;
  using Engineer.VesselSimulator;
   
namespace VOID namespace VOID
{ {
public class VOID_Core : VOID_Module, IVOID_Module public class VOID_Core : VOID_Module, IVOID_Module
{ {
/* /*
* 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 = null; _instance = null;
_initialized = false; _initialized = false;
} }
   
public static double Constant_G = 6.674e-11; public static double Constant_G = 6.674e-11;
   
/* /*
* Fields * Fields
* */ * */
protected string VoidName = "VOID"; protected string VoidName = "VOID";
protected string VoidVersion = "0.9.11"; protected string VoidVersion = "0.9.14";
   
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 - 30, 30f, 30f); protected VOID_SaveValue<Rect> VOIDIconPos = new Rect(Screen.width / 2 - 200, Screen.height - 30, 30f, 30f);
protected Texture2D VOIDIconOff = new Texture2D(30, 30, TextureFormat.ARGB32, false); protected Texture2D VOIDIconOff = new Texture2D(30, 30, TextureFormat.ARGB32, false);
protected Texture2D VOIDIconOn = new Texture2D(30, 30, TextureFormat.ARGB32, false); protected Texture2D VOIDIconOn = new Texture2D(30, 30, TextureFormat.ARGB32, false);
protected Texture2D VOIDIconTexture; protected Texture2D VOIDIconTexture;
protected string VOIDIconOnPath = "VOID/Textures/void_icon_on"; protected string VOIDIconOnPath = "VOID/Textures/void_icon_on";
protected string VOIDIconOffPath = "VOID/Textures/void_icon_off"; protected string VOIDIconOffPath = "VOID/Textures/void_icon_off";
protected bool VOIDIconLocked = true; protected bool VOIDIconLocked = true;
   
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>();
   
[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;
   
// Celestial Body Housekeeping // Celestial Body Housekeeping
protected List<CelestialBody> _allBodies = new List<CelestialBody>(); protected List<CelestialBody> _allBodies = new List<CelestialBody>();
protected bool bodiesLoaded = false; protected bool bodiesLoaded = false;
   
// 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";
   
[AVOID_SaveValue("defaultSkin")] [AVOID_SaveValue("defaultSkin")]
protected VOID_SaveValue<string> defaultSkin = "KSP window 2"; protected VOID_SaveValue<string> _skinName;
protected int _skinIdx = int.MinValue; protected Dictionary<string, GUISkin> skin_list;
protected List<GUISkin> skin_list; protected List<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"
}; };
protected bool skinsLoaded = false; protected bool skinsLoaded = false;
   
public bool configDirty; public bool configDirty;
   
/* /*
* 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.skin_list == null || this._skinIdx < 0 || this._skinIdx > this.skin_list.Count) if (!this.skinsLoaded || this._skinName == null)
{ {
return AssetBase.GetGUISkin(this.defaultSkin); return AssetBase.GetGUISkin(this.defaultSkin);
} }
return this.skin_list[this._skinIdx]; return this.skin_list[this._skinName];
} }
} }
   
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 this._allBodies; return this._allBodies;
} }
} }
   
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;
} }
} }
   
/* /*
* Methods * Methods
* */ * */
protected VOID_Core() protected VOID_Core()
{ {
this._Name = "VOID Core"; this._Name = "VOID Core";
   
this._Active = true; this._Active = true;
   
this.VOIDIconOn = GameDatabase.Instance.GetTexture (this.VOIDIconOnPath, false); this.VOIDIconOn = GameDatabase.Instance.GetTexture (this.VOIDIconOnPath, false);
this.VOIDIconOff = GameDatabase.Instance.GetTexture (this.VOIDIconOffPath, false); this.VOIDIconOff = GameDatabase.Instance.GetTexture (this.VOIDIconOffPath, false);
   
this.LoadConfig (); this.LoadConfig ();
} }
   
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 Preload_BeforeUpdate() protected void Preload_BeforeUpdate()
{ {
if (!this.bodiesLoaded) if (!this.bodiesLoaded)
{ {
this.LoadAllBodies(); this.LoadAllBodies();
} }
   
if (!this.vesselTypesLoaded) if (!this.vesselTypesLoaded)
{ {
this.LoadVesselTypes(); this.LoadVesselTypes();
} }
} }
   
public void Update() public void Update()
{ {
this.Preload_BeforeUpdate (); this.Preload_BeforeUpdate ();
   
  if (this.vessel != null)
  {
  SimManager.Instance.Gravity = VOID_Core.Instance.vessel.mainBody.gravParameter /
  Math.Pow(VOID_Core.Instance.vessel.mainBody.Radius, 2);
  SimManager.Instance.TryStartSimulation();
  }
   
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 void FixedUpdate()
{ {
if (this.consumeResource && if (this.consumeResource &&
this.vessel.vesselType != VesselType.EVA && this.vessel.vesselType != VesselType.EVA &&
TimeWarp.deltaTime != 0 TimeWarp.deltaTime != 0
) )
{ {
float powerReceived = this.vessel.rootPart.RequestResource(this.resourceName, float powerReceived = this.vessel.rootPart.RequestResource(this.resourceName,
this.resourceRate * TimeWarp.fixedDeltaTime); this.resourceRate * TimeWarp.fixedDeltaTime);
if (powerReceived > 0) if (powerReceived > 0)
{ {
this.powerAvailable = true; this.powerAvailable = true;
} }
else else
{ {
this.powerAvailable = false; this.powerAvailable = false;
} }
} }
   
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();
} }
} }
   
protected void LoadSkins() protected void LoadSkins()
{ {
this.skin_list = AssetBase.FindObjectsOfTypeIncludingAssets(typeof(GUISkin)) this.skin_list = AssetBase.FindObjectsOfTypeIncludingAssets(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)
.ToList(); .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.skin_list.Count this.skin_list.Count
)); ));
   
if (this._skinIdx == int.MinValue) this.skinNames = this.skin_list.Keys.ToList();
{ this.skinNames.Sort();
this._skinIdx = this.skin_list.IndexOf(this.Skin);  
  if (this._skinName == null || !this.skinNames.Contains(this._skinName))
  {
  this._skinName = this.defaultSkin;
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"{0}: resetting _skinIdx to default.", "{0}: resetting _skinIdx to default.",
this.GetType().Name this.GetType().Name
)); ));
} }
   
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"{0}: _skinIdx = {1}.", "{0}: _skinIdx = {1}.",
this.GetType().Name, this.GetType().Name,
this._skinIdx.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"].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"].normal.textColor = Color.red;
  this.LabelStyles ["red"].alignment = TextAnchor.MiddleCenter;
   
this.GUIStylesLoaded = true; this.GUIStylesLoaded = true;
} }
   
protected void LoadAllBodies() protected void LoadAllBodies()
{ {
this._allBodies = FlightGlobals.Bodies; this._allBodies = FlightGlobals.Bodies;
this.bodiesLoaded = true; this.bodiesLoaded = 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 CheckAndSave() protected void CheckAndSave()
{ {
this.saveTimer += Time.deltaTime; this.saveTimer += Time.deltaTime;
   
if (this.saveTimer > 2f) if (this.saveTimer > 2f)
{ {
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
)); ));
   
if (!this.configDirty) if (!this.configDirty)
{ {
return; return;
} }
   
this.SaveConfig (); this.SaveConfig ();
this.saveTimer = 0; this.saveTimer = 0;
} }
} }
   
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 = "ON"; string str = "ON";
if (togglePower) str = "OFF"; if (togglePower) str = "OFF";
if (GUILayout.Button("Power " + str)) togglePower = !togglePower; if (GUILayout.Button("Power " + str)) togglePower = !togglePower;
} }
   
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
{ {
GUIStyle label_txt_red = new GUIStyle(GUI.skin.label); GUILayout.Label("-- POWER LOST --", this.LabelStyles["red"]);
label_txt_red.normal.textColor = Color.red;  
label_txt_red.alignment = TextAnchor.MiddleCenter;  
GUILayout.Label("-- POWER LOST --", label_txt_red);  
} }
   
this.configWindowMinimized = !GUILayout.Toggle (!this.configWindowMinimized, "Configuration"); this.configWindowMinimized = !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()
{ {
  int skinIdx;
   
  GUIContent _content;
   
if (HighLogic.LoadedSceneIsFlight) if (HighLogic.LoadedSceneIsFlight)
{ {
this.consumeResource = GUILayout.Toggle (this.consumeResource, "Consume Resources"); this.consumeResource = GUILayout.Toggle (this.consumeResource, "Consume Resources");
   
this.VOIDIconLocked = GUILayout.Toggle (this.VOIDIconLocked, "Lock Icon Position"); this.VOIDIconLocked = GUILayout.Toggle (this.VOIDIconLocked, "Lock Icon Position");
} }
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
   
GUILayout.Label("Skin:", GUILayout.ExpandWidth(false)); GUILayout.Label("Skin:", GUILayout.ExpandWidth(false));
   
GUIContent _content = new GUIContent(); _content = new GUIContent();
   
  if (skinNames.Contains(this._skinName))
  {
  skinIdx = skinNames.IndexOf(this._skinName);
  }
  else if (skinNames.Contains(this.defaultSkin))
  {
  skinIdx = skinNames.IndexOf(this.defaultSkin);
  }
  else
  {
  skinIdx = 0;
  }
   
_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._skinIdx--; skinIdx--;
if (this._skinIdx < 0) this._skinIdx = skin_list.Count - 1; if (skinIdx < 0) skinIdx = skinNames.Count - 1;
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._skinIdx, this._skinName,
this.skin_list.Count this.skin_list.Count
)); ));
} }
   
string skin_name = skin_list[this._skinIdx].name; _content.text = this.Skin.name;
_content.text = 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._skinIdx++; skinIdx++;
if (this._skinIdx >= skin_list.Count) this._skinIdx = 0; if (skinIdx >= skinNames.Count) skinIdx = 0;
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._skinIdx, this._skinName,
this.skin_list.Count this.skin_list.Count
)); ));
} }
   
if (this.Skin.name != this.defaultSkin) if (this._skinName != skinNames[skinIdx])
{ {
this.defaultSkin = this.Skin.name; this._skinName = skinNames[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");
} }
   
public void OnGUI() public 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 override void DrawGUI() public override void DrawGUI()
{ {
if (!this._modulesLoaded) if (!this._modulesLoaded)
{ {
this.LoadModulesOfType<IVOID_Module> (); this.LoadModulesOfType<IVOID_Module> ();
} }
   
this._windowID = this.windowBaseID; this._windowID = this.windowBaseID;
   
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 ();
} }
   
this.VOIDIconTexture = this.VOIDIconOff; //icon off default this.VOIDIconTexture = this.VOIDIconOff; //icon off default
if (this.togglePower) this.VOIDIconTexture = this.VOIDIconOn; //or on if power_toggle==true if (this.togglePower) this.VOIDIconTexture = this.VOIDIconOn; //or on if power_toggle==true
if (GUI.Button(VOIDIconPos, VOIDIconTexture, new GUIStyle()) && this.VOIDIconLocked) if (GUI.Button(VOIDIconPos, VOIDIconTexture) && this.VOIDIconLocked)
{ {
this.mainGuiMinimized = !this.mainGuiMinimized; this.mainGuiMinimized = !this.mainGuiMinimized;
} }
   
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,
this.VOIDMainWindow, 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,
this.VOIDConfigWindow, 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 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 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;
} }
} }
} }
   
   
file:b/VOID_DataValue.cs (new)
  //
  // VOID_DataValue.cs
  //
  // Author:
  // toadicus <>
  //
  // Copyright (c) 2013 toadicus
  //
  // This program is free software: you can redistribute it and/or modify
  // it under the terms of the GNU General Public License as published by
  // the Free Software Foundation, either version 3 of the License, or
  // (at your option) any later version.
  //
  // This program is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  // GNU General Public License for more details.
  //
  // You should have received a copy of the GNU General Public License
  // along with this program. If not, see <http://www.gnu.org/licenses/>.
  using System;
  using UnityEngine;
 
  namespace VOID
  {
  public interface IVOID_DataValue
  {
  void Refresh();
  string ValueUnitString();
  void DoGUIHorizontal();
  }
 
  public class VOID_DataValue<T> : IVOID_DataValue
  {
  /*
  * Static Members
  * */
  public static implicit operator T(VOID_DataValue<T> v)
  {
  return (T)v.Value;
  }
 
  /*
  * Instance Members
  * */
  /*
  * Fields
  * */
  protected T cache;
  protected Func<T> ValueFunc;
 
  /*
  * Properties
  * */
  public string Label { get; protected set; }
  public string Units { get; protected set; }
 
  public T Value {
  get {
  return (T)this.cache;
  }
  }
 
  /*
  * Methods
  * */
  public VOID_DataValue(string Label, Func<T> ValueFunc, string Units = "")
  {
  this.Label = Label;
  this.Units = Units;
  this.ValueFunc = ValueFunc;
  }
 
  public void Refresh()
  {
  this.cache = this.ValueFunc.Invoke ();
  }
 
  public T GetFreshValue()
  {
  this.Refresh ();
  return (T)this.cache;
  }
 
  public string ValueUnitString() {
  return this.Value.ToString() + this.Units;
  }
 
  public virtual void DoGUIHorizontal()
  {
  GUILayout.BeginHorizontal (GUILayout.ExpandWidth (true));
  GUILayout.Label (this.Label + ":");
  GUILayout.FlexibleSpace ();
  GUILayout.Label (this.ValueUnitString(), GUILayout.ExpandWidth (false));
  GUILayout.EndHorizontal ();
  }
 
  public override string ToString()
  {
  return string.Format (
  "{0}: {1}{2}",
  this.Label,
  this.Value.ToString (),
  this.Units
  );
  }
  }
 
  internal interface IVOID_NumericValue
  {
  double ToDouble();
  string ToString(string format);
  string ToSIString(int digits, int MinMagnitude, int MaxMagnitude);
  }
 
  public abstract class VOID_NumValue<T> : VOID_DataValue<T>, IVOID_NumericValue
  {
  public VOID_NumValue(string Label, Func<T> ValueFunc, string Units = "") : base(Label, ValueFunc, Units) {}
 
  public abstract double ToDouble();
  public abstract string ToString(string Format);
  public abstract string ToSIString(int digits = 3, int MinMagnitude = 0, int MaxMagnitude = int.MaxValue);
 
  public abstract string ValueUnitString(string format);
 
  public virtual string ValueUnitString(int digits) {
  return Tools.MuMech_ToSI(this.ToDouble(), digits) + this.Units;
  }
 
  public virtual string ValueUnitString(int digits, int MinMagnitude, int MaxMagnitude)
  {
  return Tools.MuMech_ToSI(this.ToDouble(), digits, MinMagnitude, MaxMagnitude) + this.Units;
  }
 
  public virtual void DoGUIHorizontal(string format)
  {
  GUILayout.BeginHorizontal (GUILayout.ExpandWidth (true));
  GUILayout.Label (this.Label + ":");
  GUILayout.FlexibleSpace ();
  GUILayout.Label (this.ValueUnitString(format), GUILayout.ExpandWidth (false));
  GUILayout.EndHorizontal ();
  }
 
  public virtual int DoGUIHorizontal(int digits, bool precisionButton = true)
  {
  if (precisionButton)
  {
  return this.DoGUIHorizontalPrec(digits);
  }
 
  GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
  GUILayout.Label(this.Label + " (P" + digits + "):", GUILayout.ExpandWidth(true));
  GUILayout.FlexibleSpace();
  GUILayout.Label(this.ValueUnitString(digits), GUILayout.ExpandWidth(false));
  GUILayout.EndHorizontal();
 
  return digits;
  }
 
  public virtual int DoGUIHorizontalPrec(int digits)
  {
  float magnitude;
  float magLimit;
 
  magnitude = (float)Math.Log10(Math.Abs(this.ToDouble()));
 
  magLimit = Mathf.Max(magnitude, 6f);
  magLimit = Mathf.Round((float)Math.Ceiling(magLimit / 3f) * 3f);
 
  GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
  GUILayout.Label(this.Label + "ⁱ:", GUILayout.ExpandWidth(true));
  GUILayout.FlexibleSpace();
 
  GUILayout.Label(this.ValueUnitString(3, int.MinValue, (int)magnitude - digits), GUILayout.ExpandWidth(false));
  GUILayout.EndHorizontal();
 
  if (Event.current.type == EventType.mouseUp)
  {
  Rect lastRect = GUILayoutUtility.GetLastRect();
  if (lastRect.Contains(Event.current.mousePosition))
  {
  if (Event.current.button == 0)
  {
  digits = (digits + 3) % (int)magLimit;
  }
  else if (Event.current.button == 1)
  {
  digits = (digits - 3) % (int)magLimit;
  if (digits < 0)
  {
  digits = (int)magLimit - 3;
  }
  }
  }
  }
 
  return digits;
  }
  }
 
  public class VOID_DoubleValue : VOID_NumValue<double>, IVOID_NumericValue
  {
  public VOID_DoubleValue(string Label, Func<double> ValueFunc, string Units) : base(Label, ValueFunc, Units) {}
 
  public override double ToDouble ()
  {
  return this.Value;
  }
 
  public override string ToString(string format)
  {
  return string.Format (
  "{0}: {1}{2}",
  this.Label,
  this.Value.ToString (format),
  this.Units
  );
  }
 
  public override string ValueUnitString(string format) {
  return this.Value.ToString(format) + this.Units;
  }
 
  public override string ToSIString(int digits = 3, int MinMagnitude = 0, int MaxMagnitude = int.MaxValue)
  {
  return string.Format (
  "{0}{1}",
  Tools.MuMech_ToSI (this.Value, digits, MinMagnitude, MaxMagnitude),
  this.Units
  );
  }
  }
  public class VOID_FloatValue : VOID_NumValue<float>, IVOID_NumericValue
  {
  public VOID_FloatValue(string Label, Func<float> ValueFunc, string Units) : base(Label, ValueFunc, Units) {}
 
  public override double ToDouble ()
  {
  return (double)this.Value;
  }
 
  public override string ValueUnitString(string format) {
  return this.Value.ToString(format) + this.Units;
  }
 
  public override string ToString(string format)
  {
  return string.Format (
  "{0}: {1}{2}",
  this.Label,
  this.Value.ToString (format),
  this.Units
  );
  }
 
  public override string ToSIString(int digits = 3, int MinMagnitude = 0, int MaxMagnitude = int.MaxValue)
  {
  return string.Format (
  "{0}{1}",
  Tools.MuMech_ToSI ((double)this.Value, digits, MinMagnitude, MaxMagnitude),
  this.Units
  );
  }
  }
  public class VOID_IntValue : VOID_NumValue<int>, IVOID_NumericValue
  {
  public VOID_IntValue(string Label, Func<int> ValueFunc, string Units) : base(Label, ValueFunc, Units) {}
 
  public override double ToDouble ()
  {
  return (double)this.Value;
  }
 
  public override string ValueUnitString(string format) {
  return this.Value.ToString(format) + this.Units;
  }
 
  public override string ToString(string format)
  {
  return string.Format (
  "{0}: {1}{2}",
  this.Label,
  this.Value.ToString (format),
  this.Units
  );
  }
 
  public override string ToSIString(int digits = 3, int MinMagnitude = 0, int MaxMagnitude = int.MaxValue)
  {
  return string.Format (
  "{0}{1}",
  Tools.MuMech_ToSI ((double)this.Value, digits, MinMagnitude, MaxMagnitude),
  this.Units
  );
  }
  }
 
 
  public class VOID_StrValue : VOID_DataValue<string>
  {
  public VOID_StrValue(string Label, Func<string> ValueFunc) : base(Label, ValueFunc, "") {}
  }
  }
 
 
// //
// VOID_Hud.cs // VOID_Hud.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
   
using KSP; using KSP;
using UnityEngine; using UnityEngine;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
   
namespace VOID namespace VOID
{ {
public class VOID_HUD : VOID_Module, IVOID_Module public class VOID_HUD : VOID_Module, IVOID_Module
{ {
/* /*
* Fields * Fields
* */ * */
[AVOID_SaveValue("colorIndex")] [AVOID_SaveValue("colorIndex")]
protected VOID_SaveValue<int> _colorIndex = 0; protected VOID_SaveValue<int> _colorIndex = 0;
   
protected List<Color> textColors = new List<Color>(); protected List<Color> textColors = new List<Color>();
   
protected GUIStyle labelStyle;  
   
/* /*
* Properties * Properties
* */ * */
public int ColorIndex public int ColorIndex
{ {
get get
{ {
return this._colorIndex; return this._colorIndex;
} }
set set
{ {
if (this._colorIndex >= this.textColors.Count - 1) if (this._colorIndex >= this.textColors.Count - 1)
{ {
this._colorIndex = 0; this._colorIndex = 0;
return; return;
} }
   
this._colorIndex = value; this._colorIndex = value;
} }
} }
   
/* /*
* Methods * Methods
* */ * */
public VOID_HUD() : base() public VOID_HUD() : base()
{ {
this._Name = "Heads-Up Display"; this._Name = "Heads-Up Display";
   
this._Active = true; this._Active = true;
   
this.textColors.Add(Color.green); this.textColors.Add(Color.green);
this.textColors.Add(Color.black); this.textColors.Add(Color.black);
this.textColors.Add(Color.white); this.textColors.Add(Color.white);
this.textColors.Add(Color.red); this.textColors.Add(Color.red);
this.textColors.Add(Color.blue); this.textColors.Add(Color.blue);
this.textColors.Add(Color.yellow); this.textColors.Add(Color.yellow);
this.textColors.Add(Color.gray); this.textColors.Add(Color.gray);
this.textColors.Add(Color.cyan); this.textColors.Add(Color.cyan);
this.textColors.Add(Color.magenta); this.textColors.Add(Color.magenta);
   
this.labelStyle = new GUIStyle (); VOID_Core.Instance.LabelStyles["hud"] = new GUIStyle();
this.labelStyle.normal.textColor = this.textColors [this.ColorIndex]; VOID_Core.Instance.LabelStyles["hud"].normal.textColor = this.textColors [this.ColorIndex];
   
Tools.PostDebugMessage ("VOID_HUD: Constructed."); Tools.PostDebugMessage ("VOID_HUD: Constructed.");
} }
   
public override void DrawGUI() public override void DrawGUI()
{ {
GUI.skin = VOID_Core.Instance.Skin; GUI.skin = VOID_Core.Instance.Skin;
   
if (VOID_Core.Instance.powerAvailable) if (VOID_Core.Instance.powerAvailable)
{ {
labelStyle.normal.textColor = textColors [ColorIndex]; VOID_Core.Instance.LabelStyles["hud"].normal.textColor = textColors [ColorIndex];
   
GUI.Label ( GUI.Label (
new Rect ((Screen.width * .2083f), 0, 300f, 70f), new Rect ((Screen.width * .2083f), 0, 300f, 70f),
"Obt Alt: " + Tools.MuMech_ToSI (vessel.orbit.altitude) + "m" + "Obt Alt: " + Tools.MuMech_ToSI (vessel.orbit.altitude) + "m" +
" Obt Vel: " + Tools.MuMech_ToSI (vessel.orbit.vel.magnitude) + "m/s" + " Obt Vel: " + Tools.MuMech_ToSI (vessel.orbit.vel.magnitude) + "m/s" +
"\nAp: " + Tools.MuMech_ToSI (vessel.orbit.ApA) + "m" + "\nAp: " + Tools.MuMech_ToSI (vessel.orbit.ApA) + "m" +
" ETA " + Tools.ConvertInterval (vessel.orbit.timeToAp) + " ETA " + Tools.ConvertInterval (vessel.orbit.timeToAp) +
"\nPe: " + Tools.MuMech_ToSI (vessel.orbit.PeA) + "m" + "\nPe: " + Tools.MuMech_ToSI (vessel.orbit.PeA) + "m" +
" ETA " + Tools.ConvertInterval (vessel.orbit.timeToPe) + " ETA " + Tools.ConvertInterval (vessel.orbit.timeToPe) +
"\nInc: " + vessel.orbit.inclination.ToString ("F3") + "°", "\nInc: " + vessel.orbit.inclination.ToString ("F3") + "°" +
labelStyle); "\nPrimary: " + vessel.mainBody.bodyName,
  VOID_Core.Instance.LabelStyles["hud"]);
// Toadicus edit: Added "Biome: " line to surf/atmo HUD // Toadicus edit: Added "Biome: " line to surf/atmo HUD
GUI.Label ( GUI.Label (
new Rect ((Screen.width * .625f), 0, 300f, 90f), new Rect ((Screen.width * .625f), 0, 300f, 90f),
"Srf Alt: " + Tools.MuMech_ToSI (Tools.TrueAltitude (vessel)) + "m" + "Srf Alt: " + Tools.MuMech_ToSI (Tools.TrueAltitude (vessel)) + "m" +
" Srf Vel: " + Tools.MuMech_ToSI (vessel.srf_velocity.magnitude) + "m/s" + " Srf Vel: " + Tools.MuMech_ToSI (vessel.srf_velocity.magnitude) + "m/s" +
"\nVer: " + Tools.MuMech_ToSI (vessel.verticalSpeed) + "m/s" + "\nVer: " + Tools.MuMech_ToSI (vessel.verticalSpeed) + "m/s" +
" Hor: " + Tools.MuMech_ToSI (vessel.horizontalSrfSpeed) + "m/s" + " Hor: " + Tools.MuMech_ToSI (vessel.horizontalSrfSpeed) + "m/s" +
"\nLat: " + Tools.GetLatitudeString (vessel, "F3") + "\nLat: " + Tools.GetLatitudeString (vessel, "F3") +
" Lon: " + Tools.GetLongitudeString (vessel, "F3") + " Lon: " + Tools.GetLongitudeString (vessel, "F3") +
"\nHdg: " + Tools.MuMech_get_heading (vessel).ToString ("F2") + "° " + "\nHdg: " + Tools.MuMech_get_heading (vessel).ToString ("F2") + "° " +
Tools.get_heading_text (Tools.MuMech_get_heading (vessel)) + Tools.get_heading_text (Tools.MuMech_get_heading (vessel)) +
"\nBiome: " + Tools.Toadicus_GetAtt (vessel).name, "\nBiome: " + Tools.Toadicus_GetAtt (vessel).name,
labelStyle); VOID_Core.Instance.LabelStyles["hud"]);
} }
else else
{ {
labelStyle.normal.textColor = Color.red; VOID_Core.Instance.LabelStyles["hud"].normal.textColor = Color.red;
GUI.Label (new Rect ((Screen.width * .2083f), 0, 300f, 70f), "-- POWER LOST --", labelStyle); GUI.Label (new Rect ((Screen.width * .2083f), 0, 300f, 70f), "-- POWER LOST --", VOID_Core.Instance.LabelStyles["hud"]);
GUI.Label (new Rect ((Screen.width * .625f), 0, 300f, 70f), "-- POWER LOST --", labelStyle); GUI.Label (new Rect ((Screen.width * .625f), 0, 300f, 70f), "-- POWER LOST --", VOID_Core.Instance.LabelStyles["hud"]);
} }
} }
   
public override void DrawConfigurables() public override void DrawConfigurables()
{ {
if (GUILayout.Button ("Change HUD color", GUILayout.ExpandWidth (false))) if (GUILayout.Button ("Change HUD color", GUILayout.ExpandWidth (false)))
{ {
++this.ColorIndex; ++this.ColorIndex;
} }
} }
} }
} }
   
// //
// VOID_Module.cs // VOID_Module.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
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 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
* */ * */
public virtual bool toggleActive public virtual bool toggleActive
{ {
get get
{ {
return this._Active; return this._Active;
} }
set set
{ {
this._Active = value; this._Active = 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);
   
object fieldValue = field.GetValue(this); object fieldValue = field.GetValue(this);
   
bool convertBack = false; bool convertBack = false;
bool isIntCollection = false;  
if (fieldValue is IVOID_SaveValue) if (fieldValue is IVOID_SaveValue)
{ {
if (fieldValue is IntCollection) {  
isIntCollection = true;  
}  
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 (isIntCollection) { if (convertBack)
fieldValue = new IntCollection (4, (long)fieldValue);  
}  
else 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 = new Rect(Screen.width / 2, Screen.height / 2, 250f, 50f);
protected float defWidth = 250f; protected float defWidth = 250f;
protected float defHeight = 50f; protected float defHeight = 50f;
   
public abstract void ModuleWindow(int _); public virtual void ModuleWindow(int _)
  {
  if (VOID_Core.Instance.updateTimer - this.lastUpdate > VOID_Core.Instance.updatePeriod) {
  Tools.PostDebugMessage(string.Format(
  "{0}: refreshing VOID_DataValues.",
  this.GetType().Name
  ));
   
  foreach (var fieldinfo in this.GetType().GetFields(
  BindingFlags.Instance |
  BindingFlags.NonPublic |
  BindingFlags.Public |
  BindingFlags.FlattenHierarchy
  )) {
  Tools.PostDebugMessage(string.Format(
  "{0}: checking field {1}.",
  this.GetType().Name,
  fieldinfo.Name
  ));
   
  object field = null;
   
  try
  {
  field = fieldinfo.GetValue (this);
  }
  catch (NullReferenceException) {
  Tools.PostDebugMessage(string.Format(
  "{0}: caught NullReferenceException, could not get value for field {1}.",
  this.GetType().Name,
  fieldinfo.Name
  ));
  }
   
  if (field == null) {
  continue;
  }
   
  if (typeof(IVOID_DataValue).IsAssignableFrom (field.GetType ())) {
  Tools.PostDebugMessage(string.Format(
  "{0}: found field {1}.",
  this.GetType().Name,
  fieldinfo.Name
  ));
   
  (field as IVOID_DataValue).Refresh ();
   
  Tools.PostDebugMessage(string.Format(
  "{0}: refreshed field {1}.",
  this.GetType().Name,
  fieldinfo.Name
  ));
  }
  }
   
  this.lastUpdate = VOID_Core.Instance.updateTimer;
  }
  }
   
public override void DrawGUI() public override void DrawGUI()
{ {
  GUI.skin = VOID_Core.Instance.Skin;
   
Rect _Pos = this.WindowPos; Rect _Pos = this.WindowPos;
   
_Pos = GUILayout.Window( _Pos = GUILayout.Window(
VOID_Core.Instance.windowID, VOID_Core.Instance.windowID,
_Pos, _Pos,
this.ModuleWindow, 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;
VOID_Core.Instance.configDirty = true; VOID_Core.Instance.configDirty = true;
} }
} }
} }
} }
   
   
// //
// VOID_Orbital.cs // VOID_Orbital.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using KSP; using KSP;
using System; using System;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_Orbital : VOID_WindowModule public class VOID_Orbital : VOID_WindowModule
{ {
[AVOID_SaveValue("toggleExtended")] [AVOID_SaveValue("toggleExtended")]
protected VOID_SaveValue<bool> toggleExtended = false; protected VOID_SaveValue<bool> toggleExtended = false;
   
[AVOID_SaveValue("precisionValues")] [AVOID_SaveValue("precisionValues")]
protected IntCollection precisionValues = new IntCollection(4, 230584300921369395); protected long _precisionValues = 230584300921369395;
  protected IntCollection precisionValues;
protected double orbitAltitude;  
protected double orbitVelocity; protected VOID_StrValue primaryName = new VOID_StrValue (
protected double orbitApoAlt; VOIDLabels.void_primary,
protected double oribtPeriAlt; new Func<string> (() => VOID_Core.Instance.vessel.mainBody.name)
protected string timeToApo; );
protected string timeToPeri;  
protected double orbitInclination; protected VOID_DoubleValue orbitAltitude = new VOID_DoubleValue (
protected double gravityAccel; "Altitude (ASL)",
protected string orbitPeriod; new Func<double> (() => VOID_Core.Instance.vessel.orbit.altitude),
protected double semiMajorAxis; "m"
protected double eccentricity; );
protected double meanAnomaly;  
protected double trueAnomaly; protected VOID_DoubleValue orbitVelocity = new VOID_DoubleValue (
protected double eccAnomaly; VOIDLabels.void_velocity,
protected double longitudeAscNode; new Func<double> (() => VOID_Core.Instance.vessel.orbit.vel.magnitude),
protected double argumentPeriapsis; "m/s"
protected double localSiderealLongitude; );
   
  protected VOID_DoubleValue orbitApoAlt = new VOID_DoubleValue(
  VOIDLabels.void_apoapsis,
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.ApA),
  "m"
  );
   
  protected VOID_DoubleValue oribtPeriAlt = new VOID_DoubleValue(
  VOIDLabels.void_periapsis,
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.PeA),
  "m"
  );
   
  protected VOID_StrValue timeToApo = new VOID_StrValue(
  "Time to Apoapsis",
  new Func<string>(() => Tools.ConvertInterval(VOID_Core.Instance.vessel.orbit.timeToAp))
  );
   
  protected VOID_StrValue timeToPeri = new VOID_StrValue(
  "Time to Apoapsis",
  new Func<string>(() => Tools.ConvertInterval(VOID_Core.Instance.vessel.orbit.timeToPe))
  );
   
  protected VOID_DoubleValue orbitInclination = new VOID_DoubleValue(
  "Inclination",
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.inclination),
  "°"
  );
   
  protected VOID_DoubleValue gravityAccel = new VOID_DoubleValue(
  "Gravity",
  delegate()
  {
  double orbitRadius = VOID_Core.Instance.vessel.mainBody.Radius +
  VOID_Core.Instance.vessel.mainBody.GetAltitude(VOID_Core.Instance.vessel.findWorldCenterOfMass());
  return (VOID_Core.Constant_G * VOID_Core.Instance.vessel.mainBody.Mass) /
  Math.Pow(orbitRadius, 2);
  },
  "m/s²"
  );
   
  protected VOID_StrValue orbitPeriod = new VOID_StrValue(
  "Period",
  new Func<string>(() => Tools.ConvertInterval(VOID_Core.Instance.vessel.orbit.period))
  );
   
  protected VOID_DoubleValue semiMajorAxis = new VOID_DoubleValue(
  "Semi-Major Axis",
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.semiMajorAxis),
  "m"
  );
   
  protected VOID_DoubleValue eccentricity = new VOID_DoubleValue(
  "Eccentricity",
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.eccentricity),
  ""
  );
   
  protected VOID_DoubleValue meanAnomaly = new VOID_DoubleValue(
  "Mean Anomaly",
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.meanAnomaly * 180d / Math.PI),
  "°"
  );
   
  protected VOID_DoubleValue trueAnomaly = new VOID_DoubleValue(
  "True Anomaly",
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.trueAnomaly),
  "°"
  );
   
  protected VOID_DoubleValue eccAnomaly = new VOID_DoubleValue(
  "Eccentric Anomaly",
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.eccentricAnomaly * 180d / Math.PI),
  "°"
  );
   
  protected VOID_DoubleValue longitudeAscNode = new VOID_DoubleValue(
  "Long. Ascending Node",
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.LAN),
  "°"
  );
   
  protected VOID_DoubleValue argumentPeriapsis = new VOID_DoubleValue(
  "Argument of Periapsis",
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.argumentOfPeriapsis),
  "°"
  );
   
  protected VOID_DoubleValue localSiderealLongitude = new VOID_DoubleValue(
  "Local Sidereal Longitude",
  new Func<double>(() => Tools.FixDegreeDomain(
  VOID_Core.Instance.vessel.longitude + VOID_Core.Instance.vessel.orbit.referenceBody.rotationAngle)),
  "°"
  );
   
public VOID_Orbital() public VOID_Orbital()
{ {
this._Name = "Orbital Information"; this._Name = "Orbital Information";
   
this.WindowPos.x = Screen.width - 520f; this.WindowPos.x = Screen.width - 520f;
this.WindowPos.y = 250f; this.WindowPos.y = 250f;
} }
   
public override void ModuleWindow(int _) public override void ModuleWindow(int _)
{ {
if (VOID_Core.Instance.updateTimer >= this.lastUpdate + VOID_Core.Instance.updatePeriod) base.ModuleWindow (_);
{  
this.lastUpdate = VOID_Core.Instance.updateTimer;  
   
this.orbitAltitude = vessel.orbit.altitude;  
this.orbitVelocity = vessel.orbit.vel.magnitude;  
this.orbitApoAlt = vessel.orbit.ApA;  
this.oribtPeriAlt = vessel.orbit.PeA;  
this.timeToApo = Tools.ConvertInterval(vessel.orbit.timeToAp);  
this.timeToPeri = Tools.ConvertInterval(vessel.orbit.timeToPe);  
this.orbitInclination = vessel.orbit.inclination;  
   
double orbitRadius = vessel.mainBody.Radius + vessel.mainBody.GetAltitude(vessel.findWorldCenterOfMass());  
this.gravityAccel = (VOID_Core.Constant_G * vessel.mainBody.Mass) / Math.Pow(orbitRadius, 2);  
   
this.orbitPeriod = Tools.ConvertInterval(vessel.orbit.period);  
this.semiMajorAxis = vessel.orbit.semiMajorAxis;  
this.eccentricity = vessel.orbit.eccentricity;  
this.meanAnomaly = vessel.orbit.meanAnomaly * 180d / Math.PI;  
this.trueAnomaly = vessel.orbit.trueAnomaly;  
this.eccAnomaly = vessel.orbit.eccentricAnomaly * 180d / Math.PI;  
this.longitudeAscNode = vessel.orbit.LAN;  
this.argumentPeriapsis = vessel.orbit.argumentOfPeriapsis;  
this.localSiderealLongitude =  
Tools.FixDegreeDomain(vessel.longitude + vessel.orbit.referenceBody.rotationAngle);  
}  
   
int idx = 0; int idx = 0;
   
GUILayout.BeginVertical(); GUILayout.BeginVertical();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.primaryName.DoGUIHorizontal ();
GUILayout.Label(VOIDLabels.void_primary + ":");  
GUILayout.FlexibleSpace(); this.precisionValues [idx]= (ushort)this.orbitAltitude.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.Label(vessel.mainBody.bodyName, GUILayout.ExpandWidth(false)); idx++;
GUILayout.EndHorizontal();  
  this.precisionValues [idx]= (ushort)this.orbitVelocity.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); idx++;
GUILayout.Label(VOIDLabels.void_altitude_asl + ":", GUILayout.ExpandWidth(true));  
GUILayout.FlexibleSpace(); this.precisionValues [idx]= (ushort)this.orbitApoAlt.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.Label( idx++;
Tools.MuMech_ToSI(this.orbitAltitude, this.precisionValues[idx]) + "m",  
GUILayout.ExpandWidth(false) this.timeToApo.DoGUIHorizontal();
);  
if (GUILayout.Button ("P")) { this.precisionValues [idx]= (ushort)this.oribtPeriAlt.DoGUIHorizontal (this.precisionValues [idx]);
this.precisionValues [idx] = (ushort)((this.precisionValues[idx] + 3) % 15); idx++;
}  
GUILayout.EndHorizontal(); this.timeToPeri.DoGUIHorizontal();
idx++;  
  this.orbitInclination.DoGUIHorizontal("F3");
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label(VOIDLabels.void_velocity + ":"); this.precisionValues [idx]= (ushort)this.gravityAccel.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.FlexibleSpace();  
GUILayout.Label(Tools.MuMech_ToSI(this.orbitVelocity, this.precisionValues [idx]) + "m/s", GUILayout.ExpandWidth(false));  
   
if (GUILayout.Button ("P")) {  
this.precisionValues [idx] = (ushort)((this.precisionValues[idx] + 3) % 15);  
}  
GUILayout.EndHorizontal();  
idx++;  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label(VOIDLabels.void_apoapsis + ":");  
GUILayout.FlexibleSpace();  
GUILayout.Label(Tools.MuMech_ToSI(this.orbitApoAlt, this.precisionValues [idx]) + "m", GUILayout.ExpandWidth(false));  
   
if (GUILayout.Button ("P")) {  
this.precisionValues [idx] = (ushort)((this.precisionValues[idx] + 3) % 15);  
}  
GUILayout.EndHorizontal();  
idx++;  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Time to Ap:");  
GUILayout.FlexibleSpace();  
GUILayout.Label(this.timeToApo, GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label(VOIDLabels.void_periapsis + ":");  
GUILayout.FlexibleSpace();  
GUILayout.Label(  
Tools.MuMech_ToSI(this.oribtPeriAlt, this.precisionValues [idx]) + "m",  
GUILayout.ExpandWidth(false)  
);  
   
if (GUILayout.Button ("P")) {  
this.precisionValues [idx] = (ushort)((this.precisionValues[idx] + 3) % 15);  
}  
GUILayout.EndHorizontal();  
idx++;  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Time to Pe:");  
GUILayout.FlexibleSpace();  
GUILayout.Label(this.timeToPeri, GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Inclination:");  
GUILayout.FlexibleSpace();  
GUILayout.Label(this.orbitInclination.ToString("F3") + "°", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Gravity:");  
GUILayout.FlexibleSpace();  
GUILayout.Label(  
Tools.MuMech_ToSI(gravityAccel, this.precisionValues[idx]) + "m/s²",  
GUILayout.ExpandWidth(false)  
);  
   
if (GUILayout.Button ("P")) {  
this.precisionValues [idx] = (ushort)((this.precisionValues[idx] + 3) % 15);  
}  
GUILayout.EndHorizontal();  
idx++; idx++;
   
this.toggleExtended = GUILayout.Toggle(this.toggleExtended, "Extended info"); this.toggleExtended = GUILayout.Toggle(this.toggleExtended, "Extended info");
   
if (this.toggleExtended) if (this.toggleExtended)
{ {
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.orbitPeriod.DoGUIHorizontal();
GUILayout.Label("Period:");  
GUILayout.FlexibleSpace(); this.precisionValues [idx]= (ushort)this.semiMajorAxis.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.Label(this.orbitPeriod, GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Semi-major axis:");  
GUILayout.FlexibleSpace();  
GUILayout.Label(  
Tools.MuMech_ToSI(this.semiMajorAxis, this.precisionValues [idx]) + "m",  
GUILayout.ExpandWidth(false)  
);  
   
if (GUILayout.Button ("P")) {  
this.precisionValues [idx] = (ushort)((this.precisionValues[idx] + 3) % 15);  
}  
GUILayout.EndHorizontal();  
idx++; idx++;
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.eccentricity.DoGUIHorizontal("F4");
GUILayout.Label("Eccentricity:");  
GUILayout.FlexibleSpace(); this.meanAnomaly.DoGUIHorizontal("F3");
GUILayout.Label(this.eccentricity.ToString("F4"), GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal(); this.trueAnomaly.DoGUIHorizontal("F3");
   
// Toadicus edit: convert mean anomaly into degrees. this.eccAnomaly.DoGUIHorizontal("F3");
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Mean anomaly:"); this.longitudeAscNode.DoGUIHorizontal("F3");
GUILayout.FlexibleSpace();  
GUILayout.Label(this.meanAnomaly.ToString("F3") + "°", GUILayout.ExpandWidth(false)); this.argumentPeriapsis.DoGUIHorizontal("F3");
GUILayout.EndHorizontal();  
  this.localSiderealLongitude.DoGUIHorizontal("F3");
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("True anomaly:");  
GUILayout.FlexibleSpace();  
GUILayout.Label(this.trueAnomaly.ToString("F3") + "°", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
// Toadicus edit: convert eccentric anomaly into degrees.  
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Eccentric anomaly:");  
GUILayout.FlexibleSpace();  
GUILayout.Label(this.eccAnomaly.ToString("F3") + "°", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Long. ascending node:");  
GUILayout.FlexibleSpace();  
GUILayout.Label(this.longitudeAscNode.ToString("F3") + "°", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Arg. of periapsis:");  
GUILayout.FlexibleSpace();  
GUILayout.Label(this.argumentPeriapsis.ToString("F3") + "°", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
// Toadicus edit: added local sidereal longitude.  
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Local Sidereal Longitude:");  
GUILayout.FlexibleSpace();  
GUILayout.Label(this.localSiderealLongitude.ToString("F3") + "°", VOID_Core.Instance.LabelStyles["right"]);  
GUILayout.EndHorizontal();  
} }
   
GUILayout.EndVertical(); GUILayout.EndVertical();
GUI.DragWindow(); GUI.DragWindow();
} }
   
  public override void LoadConfig ()
  {
  base.LoadConfig ();
   
  this.precisionValues = new IntCollection (4, this._precisionValues);
  }
   
  public override void _SaveToConfig (KSP.IO.PluginConfiguration config)
  {
  this._precisionValues = this.precisionValues.collection;
   
  base._SaveToConfig (config);
  }
} }
} }
   
   
// //
// VOID_Orbital.cs // VOID_Orbital.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using KSP; using KSP;
using System; using System;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_SurfAtmo : VOID_WindowModule public class VOID_SurfAtmo : VOID_WindowModule
{ {
  [AVOID_SaveValue("precisionValues")]
  protected long _precisionValues = 230584300921369395;
  protected IntCollection precisionValues;
   
  protected VOID_DoubleValue trueAltitude = new VOID_DoubleValue(
  "Altitude (true)",
  delegate()
  {
  double alt_true = VOID_Core.Instance.vessel.orbit.altitude - VOID_Core.Instance.vessel.terrainAltitude;
  // HACK: This assumes that on worlds with oceans, all water is fixed at 0 m,
  // and water covers the whole surface at 0 m.
  if (VOID_Core.Instance.vessel.terrainAltitude < 0 && VOID_Core.Instance.vessel.mainBody.ocean )
  alt_true = VOID_Core.Instance.vessel.orbit.altitude;
  return alt_true;
  },
  "m"
  );
   
  protected VOID_StrValue surfLatitude = new VOID_StrValue(
  "Latitude",
  new Func<string> (() => Tools.GetLatitudeString(VOID_Core.Instance.vessel))
  );
   
  protected VOID_StrValue surfLongitude = new VOID_StrValue(
  "Longitude",
  new Func<string> (() => Tools.GetLongitudeString(VOID_Core.Instance.vessel))
  );
   
  protected VOID_StrValue vesselHeading = new VOID_StrValue(
  "Heading",
  delegate()
  {
  double heading = Tools.MuMech_get_heading(VOID_Core.Instance.vessel);
  string cardinal = Tools.get_heading_text(heading);
   
  return string.Format(
  "{0}° {1}",
  heading.ToString("F2"),
  cardinal
  );
  }
  );
   
  protected VOID_DoubleValue terrainElevation = new VOID_DoubleValue(
  "Terrain elevation",
  new Func<double> (() => VOID_Core.Instance.vessel.terrainAltitude),
  "m"
  );
   
  protected VOID_DoubleValue surfVelocity = new VOID_DoubleValue(
  "Surface velocity",
  new Func<double> (() => VOID_Core.Instance.vessel.srf_velocity.magnitude),
  "m/s"
  );
   
  protected VOID_DoubleValue vertVelocity = new VOID_DoubleValue(
  "Vertical speed",
  new Func<double> (() => VOID_Core.Instance.vessel.verticalSpeed),
  "m/s"
  );
   
  protected VOID_DoubleValue horzVelocity = new VOID_DoubleValue(
  "Horizontal speed",
  new Func<double> (() => VOID_Core.Instance.vessel.horizontalSrfSpeed),
  "m/s"
  );
   
  protected VOID_FloatValue temperature = new VOID_FloatValue(
  "Temperature",
  new Func<float> (() => VOID_Core.Instance.vessel.flightIntegrator.getExternalTemperature()),
  "°C"
  );
   
  protected VOID_DoubleValue atmDensity = new VOID_DoubleValue (
  "Atmosphere Density",
  new Func<double> (() => VOID_Core.Instance.vessel.atmDensity * 1000f),
  "g/m³"
  );
   
  protected VOID_DoubleValue atmPressure = new VOID_DoubleValue (
  "Pressure",
  new Func<double> (() => VOID_Core.Instance.vessel.staticPressure),
  "atm"
  );
   
  protected VOID_FloatValue atmLimit = new VOID_FloatValue(
  "Atmosphere Limit",
  new Func<float> (() => VOID_Core.Instance.vessel.mainBody.maxAtmosphereAltitude),
  "m"
  );
   
  protected VOID_StrValue currBiome = new VOID_StrValue(
  "Biome",
  new Func<string> (() => Tools.Toadicus_GetAtt(VOID_Core.Instance.vessel).name)
  );
   
public VOID_SurfAtmo() public VOID_SurfAtmo()
{ {
this._Name = "Surface & Atmospheric Information"; this._Name = "Surface & Atmospheric Information";
   
this.WindowPos.x = Screen.width - 260f; this.WindowPos.x = Screen.width - 260f;
this.WindowPos.y = 85; this.WindowPos.y = 85;
} }
   
public override void ModuleWindow(int _) public override void ModuleWindow(int _)
{ {
  base.ModuleWindow (_);
   
  int idx = 0;
   
GUILayout.BeginVertical(); GUILayout.BeginVertical();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.precisionValues [idx]= (ushort)this.trueAltitude.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.Label("Altitude (true):"); idx++;
double alt_true = vessel.orbit.altitude - vessel.terrainAltitude;  
// HACK: This assumes that on worlds with oceans, all water is fixed at 0 m, and water covers the whole surface at 0 m.  
if (vessel.terrainAltitude < 0 && vessel.mainBody.ocean ) alt_true = vessel.orbit.altitude;  
GUILayout.Label(Tools.MuMech_ToSI(alt_true) + "m", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal ();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.surfLatitude.DoGUIHorizontal ();
GUILayout.Label("Latitude:");  
GUILayout.Label(Tools.GetLatitudeString(vessel), GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.surfLongitude.DoGUIHorizontal ();
GUILayout.Label("Longitude:");  
GUILayout.Label(Tools.GetLongitudeString(vessel), GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.vesselHeading.DoGUIHorizontal ();
GUILayout.Label("Heading:");  
GUILayout.Label(Tools.MuMech_get_heading(vessel).ToString("F2") + "° " + Tools.get_heading_text(Tools.MuMech_get_heading(vessel)), GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.precisionValues [idx]= (ushort)this.terrainElevation.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.Label("Terrain elevation:"); idx++;
GUILayout.Label(Tools.MuMech_ToSI(vessel.terrainAltitude) + "m", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.precisionValues [idx]= (ushort)this.surfVelocity.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.Label("Surface velocity:"); idx++;
GUILayout.Label(Tools.MuMech_ToSI(vessel.srf_velocity.magnitude) + "m/s", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.precisionValues [idx]= (ushort)this.vertVelocity.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.Label("Vertical speed:"); idx++;
GUILayout.Label(Tools.MuMech_ToSI(vessel.verticalSpeed) + "m/s", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.precisionValues [idx]= (ushort)this.horzVelocity.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.Label("Horizontal speed:"); idx++;
GUILayout.Label(Tools.MuMech_ToSI(vessel.horizontalSrfSpeed) + "m/s", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.temperature.DoGUIHorizontal ("F2");
GUILayout.Label("Temperature:");  
GUILayout.Label(vessel.flightIntegrator.getExternalTemperature().ToString("F2") + "° C", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.atmDensity.DoGUIHorizontal (3);
GUILayout.Label("Atmosphere density:");  
GUILayout.Label(Tools.MuMech_ToSI(vessel.atmDensity * 1000) + "g/m³", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.atmPressure.DoGUIHorizontal ("F2");
GUILayout.Label("Pressure:");  
GUILayout.Label(vessel.staticPressure.ToString("F2") + " atms", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.precisionValues [idx]= (ushort)this.atmLimit.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.Label("Atmosphere limit:"); idx++;
GUILayout.Label("≈ " + Tools.MuMech_ToSI(vessel.mainBody.maxAtmosphereAltitude) + "m", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
// Toadicus edit: added Biome // Toadicus edit: added Biome
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.currBiome.DoGUIHorizontal ();
GUILayout.Label("Biome:");  
GUILayout.Label(Tools.Toadicus_GetAtt(vessel).name, VOID_Core.Instance.LabelStyles["right"]);  
GUILayout.EndHorizontal();  
   
GUILayout.EndVertical(); GUILayout.EndVertical();
GUI.DragWindow(); GUI.DragWindow();
} }
   
  public override void LoadConfig ()
  {
  base.LoadConfig ();
   
  this.precisionValues = new IntCollection (4, this._precisionValues);
  }
   
  public override void _SaveToConfig (KSP.IO.PluginConfiguration config)
  {
  this._precisionValues = this.precisionValues.collection;
   
  base._SaveToConfig (config);
  }
} }
} }
// //
// VOID_Orbital.cs // VOID_Orbital.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using KSP; using KSP;
using System; using System;
  using System.Collections.Generic;
using UnityEngine; using UnityEngine;
  using Engineer.VesselSimulator;
   
namespace VOID namespace VOID
{ {
public class VOID_VesselInfo : VOID_WindowModule public class VOID_VesselInfo : VOID_WindowModule
{ {
[AVOID_SaveValue("toggleExtended")] [AVOID_SaveValue("toggleExtended")]
protected VOID_SaveValue<bool> toggleExtended = false; protected VOID_SaveValue<bool> toggleExtended = false;
   
public VOID_VesselInfo() protected VOID_DoubleValue geeForce = new VOID_DoubleValue(
  "G-force",
  new Func<double>(() => VOID_Core.Instance.vessel.geeForce),
  "gees"
  );
   
  protected VOID_IntValue partCount = new VOID_IntValue(
  "Parts",
  new Func<int>(() => VOID_Core.Instance.vessel.Parts.Count),
  ""
  );
   
  protected VOID_DoubleValue totalMass = new VOID_DoubleValue(
  "Total Mass",
  new Func<double>(() => VOID_Core.Instance.vessel.GetTotalMass()),
  "tons"
  );
   
  protected VOID_DoubleValue resourceMass = new VOID_DoubleValue(
  "Resource Mass",
  delegate()
  {
  double rscMass = 0;
  foreach (Part part in VOID_Core.Instance.vessel.Parts)
  {
  rscMass += part.GetResourceMass();
  }
  return rscMass;
  },
  "tons"
  );
   
  protected VOID_DoubleValue stageDeltaV = new VOID_DoubleValue(
  "DeltaV (Current Stage)",
  delegate()
  {
  if (SimManager.Instance.Stages == null ||
  SimManager.Instance.Stages.Length <= Staging.lastStage
  )
  return double.NaN;
  return SimManager.Instance.Stages[Staging.lastStage].deltaV;
  },
  "m/s"
  );
   
  protected VOID_DoubleValue totalDeltaV = new VOID_DoubleValue(
  "DeltaV (Total)",
  delegate()
  {
  if (SimManager.Instance.Stages == null)
  return double.NaN;
  return SimManager.Instance.LastStage.totalDeltaV;
  },
  "m/s"
  );
   
  protected VOID_FloatValue mainThrottle = new VOID_FloatValue(
  "Throttle",
  new Func<float>(() => VOID_Core.Instance.vessel.ctrlState.mainThrottle * 100f),
  "%"
  );
   
  protected VOID_StrValue currmaxThrust = new VOID_StrValue(
  "Thrust (curr/max)",
  delegate()
  {
  if (SimManager.Instance.Stages == null)
  return "N/A";
   
  double currThrust = SimManager.Instance.LastStage.actualThrust;
  double maxThrust = SimManager.Instance.LastStage.thrust;
   
  return string.Format(
  "{0} / {1}",
  currThrust.ToString("F1"),
  maxThrust.ToString("F1")
  );
  }
  );
   
  protected VOID_StrValue currmaxThrustWeight = new VOID_StrValue(
  "T:W (curr/max)",
  delegate()
  {
  if (SimManager.Instance.Stages == null)
  return "N/A";
   
  double currThrust = SimManager.Instance.LastStage.actualThrust;
  double maxThrust = SimManager.Instance.LastStage.thrust;
  double mass = VOID_Core.Instance.vessel.GetTotalMass();
  double gravity = VOID_Core.Instance.vessel.mainBody.gravParameter /
  Math.Pow(
  VOID_Core.Instance.vessel.mainBody.Radius + VOID_Core.Instance.vessel.altitude,
  2
  );
  double weight = mass * gravity;
   
  return string.Format(
  "{0} / {1}",
  (currThrust / weight).ToString("F2"),
  (maxThrust / weight).ToString("F2")
  );
  }
  );
   
  protected VOID_DoubleValue surfaceThrustWeight = new VOID_DoubleValue(
  "Max T:W @ surface",
  delegate()
  {
  if (SimManager.Instance.Stages == null)
  return double.NaN;
   
  double maxThrust = SimManager.Instance.LastStage.thrust;
  double mass = VOID_Core.Instance.vessel.GetTotalMass();
  double gravity = (VOID_Core.Constant_G * VOID_Core.Instance.vessel.mainBody.Mass) /
  Math.Pow(VOID_Core.Instance.vessel.mainBody.Radius, 2);
  double weight = mass * gravity;
   
  return maxThrust / weight;
  },
  ""
  );
   
  public VOID_VesselInfo() : base()
{ {
this._Name = "Vessel Information"; this._Name = "Vessel Information";
   
this.WindowPos.x = Screen.width - 260; this.WindowPos.x = Screen.width - 260;
this.WindowPos.y = 450; this.WindowPos.y = 450;
} }
   
public override void ModuleWindow(int _) public override void ModuleWindow(int _)
{ {
  base.ModuleWindow (_);
   
if ((TimeWarp.WarpMode == TimeWarp.Modes.LOW) || (TimeWarp.CurrentRate <= TimeWarp.MaxPhysicsRate)) if ((TimeWarp.WarpMode == TimeWarp.Modes.LOW) || (TimeWarp.CurrentRate <= TimeWarp.MaxPhysicsRate))
{ {
Engineer.VesselSimulator.SimManager.Instance.RequestSimulation(); SimManager.Instance.RequestSimulation();
} }
   
Engineer.VesselSimulator.Stage[] stages = Engineer.VesselSimulator.SimManager.Instance.Stages; Stage[] stages = SimManager.Instance.Stages;
   
GUILayout.BeginVertical(); GUILayout.BeginVertical();
   
GUILayout.Label(vessel.vesselName, VOID_Core.Instance.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); GUILayout.Label(
  vessel.vesselName,
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); VOID_Core.Instance.LabelStyles["center_bold"],
GUILayout.Label("G-force:"); GUILayout.ExpandWidth(true));
GUILayout.Label(vessel.geeForce.ToString("F2") + " gees", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal(); this.geeForce.DoGUIHorizontal ("F2");
   
int num_parts = 0; this.partCount.DoGUIHorizontal ();
double total_mass = vessel.GetTotalMass();  
double resource_mass = 0; this.totalMass.DoGUIHorizontal ("F1");
double max_thrust = 0;  
double final_thrust = 0; this.resourceMass.DoGUIHorizontal ("F1");
   
foreach (Part p in vessel.parts) this.stageDeltaV.DoGUIHorizontal (3, false);
{  
num_parts++; this.totalDeltaV.DoGUIHorizontal (3, false);
resource_mass += p.GetResourceMass();  
  this.mainThrottle.DoGUIHorizontal ("F0");
foreach (PartModule pm in p.Modules)  
{ this.currmaxThrust.DoGUIHorizontal ();
if ((pm.moduleName == "ModuleEngines") && ((p.State == PartStates.ACTIVE) || ((Staging.CurrentStage > Staging.lastStage) && (p.inverseStage == Staging.lastStage))))  
{ this.currmaxThrustWeight.DoGUIHorizontal ();
max_thrust += ((ModuleEngines)pm).maxThrust;  
final_thrust += ((ModuleEngines)pm).finalThrust; this.surfaceThrustWeight.DoGUIHorizontal ("F2");
}  
}  
}  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Parts:");  
GUILayout.Label(num_parts.ToString("F0"), GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Total mass:");  
GUILayout.Label(total_mass.ToString("F1") + " tons", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Resource mass:");  
GUILayout.Label(resource_mass.ToString("F1") + " tons", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
if (stages.Length > Staging.lastStage)  
{  
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("DeltaV (Current Stage):");  
GUILayout.Label(Tools.MuMech_ToSI(stages[Staging.lastStage].deltaV).ToString() + "m/s", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
}  
   
if (stages.Length > 0)  
{  
double totalDeltaV = 0d;  
   
for (int i = 0; i < stages.Length; ++i)  
{  
totalDeltaV += stages [i].deltaV;  
}  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("DeltaV (Total):");  
GUILayout.Label(Tools.MuMech_ToSI(totalDeltaV).ToString() + "m/s", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
}  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Throttle:");  
GUILayout.Label((vessel.ctrlState.mainThrottle * 100f).ToString("F0") + "%", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Thrust (curr/max):");  
GUILayout.Label(final_thrust.ToString("F1") + " / " + max_thrust.ToString("F1") + " kN", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
double gravity = vessel.mainBody.gravParameter / Math.Pow(vessel.mainBody.Radius + vessel.altitude, 2);  
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("T:W (curr/max):");  
GUILayout.Label((final_thrust / (total_mass * gravity)).ToString("F2") + " / " + (max_thrust / (total_mass * gravity)).ToString("F2"), GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
double g_ASL = (VOID_Core.Constant_G * vessel.mainBody.Mass) / Math.Pow(vessel.mainBody.Radius, 2);  
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Max T:W @ surface:");  
GUILayout.Label((max_thrust / (total_mass * g_ASL)).ToString("F2"), GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.EndVertical(); GUILayout.EndVertical();
GUI.DragWindow(); GUI.DragWindow();
} }
} }
} }