VOID_Core: Power consumption will no longer persist when the core is 'powered off'. Thanks to Shad0wCatcher for the bughunting.
[VOID.git] / VOID_Core.cs
blob:a/VOID_Core.cs -> blob:b/VOID_Core.cs
  // VOID
// //
// VOID_Core.cs // VOID_Core.cs
// //
// Author: // Copyright © 2014, toadicus
// toadicus <> // All rights reserved.
// //
// Copyright (c) 2013 toadicus // Redistribution and use in source and binary forms, with or without modification,
  // are permitted provided that the following conditions are met:
// //
// This program is free software: you can redistribute it and/or modify // 1. Redistributions of source code must retain the above copyright notice,
// it under the terms of the GNU General Public License as published by // this list of conditions and the following disclaimer.
// 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, // 2. Redistributions in binary form must reproduce the above copyright notice,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // this list of conditions and the following disclaimer in the documentation and/or other
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // materials provided with the distribution.
// GNU General Public License for more details.  
// //
// You should have received a copy of the GNU General Public License // 3. Neither the name of the copyright holder nor the names of its contributors may be used
// along with this program. If not, see <http://www.gnu.org/licenses/>. // to endorse or promote products derived from this software without specific prior written permission.
  //
  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
  using Engineer.VesselSimulator;
  using KSP;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using KSP; using System.Text;
  using ToadicusTools;
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
{ {
  #region Singleton Members
/* /*
* Static Members * Static Members
* */ * */
protected static bool _initialized = false; protected static bool _initialized = false;
   
public static bool Initialized public static bool Initialized
{ {
get get
{ {
return _initialized; return _initialized;
} }
} }
   
protected static VOID_Core _instance; protected static VOID_Core _instance;
   
public static VOID_Core Instance public static VOID_Core Instance
{ {
get get
{ {
if (_instance == null) if (_instance == null)
{ {
_instance = new VOID_Core(); _instance = new VOID_Core();
_initialized = true; _initialized = true;
} }
return _instance; return _instance;
} }
} }
   
public static void Reset() public static void Reset()
{ {
_instance.StopGUI(); _instance.StopGUI();
  _instance.Dispose();
_instance = null; _instance = null;
_initialized = false; _initialized = false;
} }
  #endregion
public static double Constant_G = 6.674e-11;  
  public static readonly double Constant_G = 6.674e-11;
   
/* /*
* Fields * Fields
* */ * */
protected string VoidName = "VOID"; protected string VoidName = "VOID";
protected string VoidVersion = "0.9.20"; protected string VoidVersion;
   
protected bool _factoryReset = false; protected bool _factoryReset = false;
   
[AVOID_SaveValue("configValue")] [AVOID_SaveValue("configValue")]
protected VOID_SaveValue<int> configVersion = 1; protected VOID_SaveValue<int> configVersion = 1;
   
protected List<IVOID_Module> _modules = new List<IVOID_Module>(); protected List<IVOID_Module> _modules = new List<IVOID_Module>();
protected bool _modulesLoaded = false; protected bool _modulesLoaded = false;
   
[AVOID_SaveValue("mainWindowPos")] [AVOID_SaveValue("mainWindowPos")]
protected VOID_SaveValue<Rect> mainWindowPos = new Rect(475, 575, 10f, 10f); protected VOID_SaveValue<Rect> mainWindowPos = new Rect(475, 575, 10f, 10f);
[AVOID_SaveValue("mainGuiMinimized")] [AVOID_SaveValue("mainGuiMinimized")]
protected VOID_SaveValue<bool> mainGuiMinimized = false; protected VOID_SaveValue<bool> mainGuiMinimized = false;
   
[AVOID_SaveValue("configWindowPos")] [AVOID_SaveValue("configWindowPos")]
protected VOID_SaveValue<Rect> configWindowPos = new Rect(825, 625, 10f, 10f); protected VOID_SaveValue<Rect> configWindowPos = new Rect(825, 625, 10f, 10f);
[AVOID_SaveValue("configWindowMinimized")] [AVOID_SaveValue("configWindowMinimized")]
   
protected VOID_SaveValue<bool> configWindowMinimized = true; protected VOID_SaveValue<bool> configWindowMinimized = true;
[AVOID_SaveValue("VOIDIconPos")] [AVOID_SaveValue("VOIDIconPos")]
protected VOID_SaveValue<Rect> VOIDIconPos = new Rect(Screen.width / 2 - 200, Screen.height - 32, 32f, 32f); protected VOID_SaveValue<Rect> VOIDIconPos = new Rect(Screen.width / 2 - 200, Screen.height - 32, 32f, 32f);
   
protected Texture2D VOIDIconTexture; protected Texture2D VOIDIconTexture;
protected string VOIDIconOnActivePath; protected string VOIDIconOnActivePath;
protected string VOIDIconOnInactivePath; protected string VOIDIconOnInactivePath;
protected string VOIDIconOffActivePath; protected string VOIDIconOffActivePath;
protected string VOIDIconOffInactivePath; protected string VOIDIconOffInactivePath;
   
protected bool VOIDIconLocked = true; protected bool VOIDIconLocked = true;
   
protected GUIStyle iconStyle; protected GUIStyle iconStyle;
   
protected int windowBaseID = -96518722; protected int windowBaseID = -96518722;
protected int _windowID = 0; protected int _windowID = 0;
   
protected bool GUIStylesLoaded = false; protected bool GUIStylesLoaded = false;
protected Dictionary<string, GUIStyle> _LabelStyles = new Dictionary<string, GUIStyle>();  
  protected CelestialBody _homeBody;
   
[AVOID_SaveValue("togglePower")] [AVOID_SaveValue("togglePower")]
public VOID_SaveValue<bool> togglePower = true; public VOID_SaveValue<bool> togglePower = true;
public bool powerAvailable = true; public bool powerAvailable = true;
   
[AVOID_SaveValue("consumeResource")] [AVOID_SaveValue("consumeResource")]
protected VOID_SaveValue<bool> consumeResource = false; protected VOID_SaveValue<bool> consumeResource = false;
   
[AVOID_SaveValue("resourceName")] [AVOID_SaveValue("resourceName")]
protected VOID_SaveValue<string> resourceName = "ElectricCharge"; protected VOID_SaveValue<string> resourceName = "ElectricCharge";
   
[AVOID_SaveValue("resourceRate")] [AVOID_SaveValue("resourceRate")]
protected VOID_SaveValue<float> resourceRate = 0.2f; protected VOID_SaveValue<float> resourceRate = 0.2f;
   
[AVOID_SaveValue("updatePeriod")] [AVOID_SaveValue("updatePeriod")]
protected VOID_SaveValue<double> _updatePeriod = 1001f / 15000f; protected VOID_SaveValue<double> _updatePeriod = 1001f / 15000f;
protected float _updateTimer = 0f; protected float _updateTimer = 0f;
protected string stringFrequency; protected string stringFrequency;
   
  [AVOID_SaveValue("vesselSimActive")]
  protected VOID_SaveValue<bool> vesselSimActive;
   
// Vessel Type Housekeeping // Vessel Type Housekeeping
protected List<VesselType> _allVesselTypes = new List<VesselType>(); protected List<VesselType> _allVesselTypes = new List<VesselType>();
protected bool vesselTypesLoaded = false; protected bool vesselTypesLoaded = false;
public float saveTimer = 0; public float saveTimer = 0;
   
protected string defaultSkin = "KSP window 2"; protected string defaultSkin = "KSP window 2";
   
[AVOID_SaveValue("defaultSkin")] [AVOID_SaveValue("defaultSkin")]
protected VOID_SaveValue<string> _skinName; protected VOID_SaveValue<string> _skinName;
protected Dictionary<string, GUISkin> skin_list; protected int _skinIdx;
protected List<string> skinNames;  
  protected Dictionary<string, GUISkin> validSkins;
  protected string[] skinNames;
protected string[] forbiddenSkins = protected string[] forbiddenSkins =
{ {
"PlaqueDialogSkin", "PlaqueDialogSkin",
"FlagBrowserSkin", "FlagBrowserSkin",
"SSUITextAreaDefault", "SSUITextAreaDefault",
"ExperimentsDialogSkin", "ExperimentsDialogSkin",
"ExpRecoveryDialogSkin", "ExpRecoveryDialogSkin",
"KSP window 5", "KSP window 5",
"KSP window 6", "KSP window 6",
"PartTooltipSkin" "PartTooltipSkin",
  "KSCContextMenuSkin"
}; };
protected bool skinsLoaded = false; protected bool skinsLoaded = false;
   
public bool configDirty; public bool configDirty;
   
[AVOID_SaveValue("UseBlizzyToolbar")] [AVOID_SaveValue("UseBlizzyToolbar")]
protected VOID_SaveValue<bool> _UseToolbarManager; protected VOID_SaveValue<bool> _UseToolbarManager;
protected bool ToolbarManagerLoaded; internal IButton ToolbarButton;
internal ToolbarButtonWrapper ToolbarButton;  
  internal ApplicationLauncherButton AppLauncherButton;
   
/* /*
* Properties * Properties
* */ * */
public bool factoryReset public bool factoryReset
{ {
get get
{ {
return this._factoryReset; return this._factoryReset;
} }
} }
   
public List<IVOID_Module> Modules public List<IVOID_Module> Modules
{ {
get get
{ {
return this._modules; return this._modules;
} }
} }
   
public GUISkin Skin public GUISkin Skin
{ {
get get
{ {
if (!this.skinsLoaded || this._skinName == null) if (this.skinsLoaded)
{ {
return AssetBase.GetGUISkin(this.defaultSkin); try
} {
return this.skin_list[this._skinName]; return this.validSkins[this._skinName];
  }
  catch
  {
  }
  }
   
  return AssetBase.GetGUISkin(this.defaultSkin);
} }
} }
   
public int windowID public int windowID
{ {
get get
{ {
if (this._windowID == 0) if (this._windowID == 0)
{ {
this._windowID = this.windowBaseID; this._windowID = this.windowBaseID;
} }
return this._windowID++; return this._windowID++;
} }
} }
   
public Dictionary<string, GUIStyle> LabelStyles  
{  
get  
{  
return this._LabelStyles;  
}  
}  
   
public List<CelestialBody> allBodies public List<CelestialBody> allBodies
{ {
get get
{ {
return FlightGlobals.Bodies; return FlightGlobals.Bodies;
} }
} }
   
  public List<CelestialBody> sortedBodyList
  {
  get;
  private set;
  }
   
  public CelestialBody HomeBody
  {
  get
  {
  if (this._homeBody == null)
  {
  if (Planetarium.fetch != null)
  {
  this._homeBody = Planetarium.fetch.Home;
  }
  }
   
  return this._homeBody;
  }
  }
   
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;
} }
} }
   
  public Stage[] Stages
  {
  get;
  protected set;
  }
   
  public Stage LastStage
  {
  get;
  protected set;
  }
   
protected IconState powerState protected IconState powerState
{ {
get get
{ {
if (this.togglePower && this.powerAvailable) if (this.togglePower && this.powerAvailable)
{ {
return IconState.PowerOn; return IconState.PowerOn;
} }
else else
{ {
return IconState.PowerOff; return IconState.PowerOff;
} }
   
} }
} }
   
protected IconState activeState protected IconState activeState
{ {
get get
{ {
if (this.mainGuiMinimized) if (this.mainGuiMinimized)
{ {
return IconState.Inactive; return IconState.Inactive;
} }
else else
{ {
return IconState.Active; return IconState.Active;
} }
   
} }
} }
   
protected bool UseToolbarManager protected bool UseToolbarManager
{ {
get get
{ {
return _UseToolbarManager; return _UseToolbarManager & ToolbarManager.ToolbarAvailable;
} }
set set
{ {
if (this._UseToolbarManager == value) if (this._UseToolbarManager == value)
{ {
return; return;
} }
   
if (value == false && this.ToolbarManagerLoaded && this.ToolbarButton != null) if (value == false && this.ToolbarButton != null)
{ {
this.ToolbarButton.Destroy(); this.ToolbarButton.Destroy();
this.ToolbarButton = null; this.ToolbarButton = null;
} }
if (value == true && this.ToolbarManagerLoaded && this.ToolbarButton == null) if (value == true)
{ {
  if (this.AppLauncherButton != null)
  {
  ApplicationLauncher.Instance.RemoveModApplication(this.AppLauncherButton);
  this.AppLauncherButton = null;
  }
   
this.InitializeToolbarButton(); this.InitializeToolbarButton();
} }
   
this.SetIconTexture(this.powerState | this.activeState);  
   
_UseToolbarManager.value = value; _UseToolbarManager.value = value;
  }
  }
   
  protected virtual ApplicationLauncher.AppScenes appIconVisibleScenes
  {
  get
  {
  return ApplicationLauncher.AppScenes.FLIGHT;
} }
} }
   
/* /*
* Methods * Methods
* */ * */
protected VOID_Core() public override void DrawGUI()
{ {
this._Name = "VOID Core"; this._windowID = this.windowBaseID;
   
this._Active.value = true; if (!this._modulesLoaded)
  {
this._skinName = this.defaultSkin; this.LoadModulesOfType<IVOID_Module>();
  }
this.VOIDIconOnActivePath = "VOID/Textures/void_icon_light_glow";  
this.VOIDIconOnInactivePath = "VOID/Textures/void_icon_dark_glow"; if (!this.skinsLoaded)
this.VOIDIconOffActivePath = "VOID/Textures/void_icon_light"; {
this.VOIDIconOffInactivePath = "VOID/Textures/void_icon_dark"; this.LoadSkins();
  }
this.UseToolbarManager = false;  
this.ToolbarManagerLoaded = false; GUI.skin = this.Skin;
   
this.LoadConfig(); if (!this.GUIStylesLoaded)
  {
this.SetIconTexture(this.powerState | this.activeState); this.LoadGUIStyles();
}  
  Tools.PostDebugMessage(
protected void LoadModulesOfType<T>() this,
{ "ToolbarAvailable: {0}, UseToobarManager: {1}",
var types = AssemblyLoader.loadedAssemblies ToolbarManager.ToolbarAvailable,
.Select(a => a.assembly.GetExportedTypes()) this.UseToolbarManager);
.SelectMany(t => t) }
.Where(v => typeof(T).IsAssignableFrom(v)  
&& !(v.IsInterface || v.IsAbstract) && if (!this.UseToolbarManager)
!typeof(VOID_Core).IsAssignableFrom(v) {
); if (this.AppLauncherButton == null)
  {
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(this,
"{0}: Found {1} modules to check.", "UseToolbarManager = false (ToolbarAvailable = {0}) and " +
this.GetType().Name, "AppLauncherButton is null, making AppLauncher button.",
types.Count() ToolbarManager.ToolbarAvailable
)); );
foreach (var voidType in types) this.InitializeAppLauncherButton();
{ }
if (!HighLogic.LoadedSceneIsEditor && }
typeof(IVOID_EditorModule).IsAssignableFrom(voidType)) else if (this.ToolbarButton == null)
{ {
continue; Tools.PostDebugMessage(this,
} "UseToolbarManager = true (ToolbarAvailable = {0}) and " +
  "ToolbarButton is null, making Toolbar button.",
Tools.PostDebugMessage(string.Format( ToolbarManager.ToolbarAvailable
"{0}: found Type {1}", );
this.GetType().Name,  
voidType.Name  
));  
   
this.LoadModule(voidType);  
}  
   
this._modulesLoaded = true;  
   
Tools.PostDebugMessage(string.Format(  
"{0}: Loaded {1} modules.",  
this.GetType().Name,  
this.Modules.Count  
));  
}  
   
protected void LoadModule(Type T)  
{  
var existingModules = this._modules.Where(mod => mod.GetType().Name == T.Name);  
if (existingModules.Any())  
{  
Tools.PostDebugMessage(string.Format(  
"{0}: refusing to load {1}: already loaded",  
this.GetType().Name,  
T.Name  
));  
return;  
}  
IVOID_Module module = Activator.CreateInstance(T) as IVOID_Module;  
module.LoadConfig();  
this._modules.Add(module);  
   
Tools.PostDebugMessage(string.Format(  
"{0}: loaded module {1}.",  
this.GetType().Name,  
T.Name  
));  
}  
   
protected void LoadSkins()  
{  
Tools.PostDebugMessage("AssetBase has skins: \n" +  
string.Join("\n\t",  
Resources.FindObjectsOfTypeAll(typeof(GUISkin))  
.Select(s => s.ToString())  
.ToArray()  
)  
);  
   
this.skin_list = Resources.FindObjectsOfTypeAll(typeof(GUISkin))  
.Where(s => !this.forbiddenSkins.Contains(s.name))  
.Select(s => s as GUISkin)  
.GroupBy(s => s.name)  
.Select(g => g.First())  
.ToDictionary(s => s.name);  
   
Tools.PostDebugMessage(string.Format(  
"{0}: loaded {1} GUISkins.",  
this.GetType().Name,  
this.skin_list.Count  
));  
   
this.skinNames = this.skin_list.Keys.ToList();  
this.skinNames.Sort();  
   
if (this._skinName == null || !this.skinNames.Contains(this._skinName))  
{  
this._skinName = this.defaultSkin;  
Tools.PostDebugMessage(string.Format(  
"{0}: resetting _skinIdx to default.",  
this.GetType().Name  
));  
}  
   
Tools.PostDebugMessage(string.Format(  
"{0}: _skinIdx = {1}.",  
this.GetType().Name,  
this._skinName.ToString()  
));  
   
this.skinsLoaded = true;  
}  
   
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"].normal.textColor = Color.white;  
this.LabelStyles["center"].alignment = TextAnchor.UpperCenter;  
   
this.LabelStyles["center_bold"] = new GUIStyle(GUI.skin.label);  
this.LabelStyles["center_bold"].normal.textColor = Color.white;  
this.LabelStyles["center_bold"].alignment = TextAnchor.UpperCenter;  
this.LabelStyles["center_bold"].fontStyle = FontStyle.Bold;  
   
this.LabelStyles["right"] = new GUIStyle(GUI.skin.label);  
this.LabelStyles["right"].normal.textColor = Color.white;  
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.iconStyle = new GUIStyle(GUI.skin.button);  
this.iconStyle.padding = new RectOffset(0, 0, 0, 0);  
// this.iconStyle.margin = new RectOffset(0, 0, 0, 0);  
// this.iconStyle.contentOffset = new Vector2(0, 0);  
this.iconStyle.overflow = new RectOffset(0, 0, 0, 0);  
// this.iconStyle.border = new RectOffset(0, 0, 0, 0);  
   
this.GUIStylesLoaded = true;  
}  
   
protected void LoadVesselTypes()  
{  
this._allVesselTypes = Enum.GetValues(typeof(VesselType)).OfType<VesselType>().ToList();  
this.vesselTypesLoaded = true;  
}  
   
protected void LoadBeforeUpdate()  
{  
if (!this.vesselTypesLoaded)  
{  
this.LoadVesselTypes();  
}  
}  
   
protected void LoadToolbarManager()  
{  
this.ToolbarManagerLoaded = ToolbarButtonWrapper.ToolbarManagerPresent;  
   
if (this.ToolbarManagerLoaded)  
{  
this.InitializeToolbarButton(); this.InitializeToolbarButton();
}  
}  
   
protected void InitializeToolbarButton()  
{  
this.ToolbarButton = ToolbarButtonWrapper.TryWrapToolbarButton(this.GetType().Name, "coreToggle");  
this.ToolbarButton.Text = this.VoidName;  
this.ToolbarButton.TexturePath = this.VOIDIconOffActivePath;  
if (this is VOID_EditorCore)  
{  
this.ToolbarButton.SetButtonVisibility(new GameScenes[] { GameScenes.EDITOR });  
}  
else  
{  
this.ToolbarButton.SetButtonVisibility(new GameScenes[] { GameScenes.FLIGHT });  
}  
this.ToolbarButton.AddButtonClickHandler(  
(e) =>  
{  
this.mainGuiMinimized = !this.mainGuiMinimized;  
this.SetIconTexture(this.powerState | this.activeState);  
}  
);  
}  
   
public void VOIDMainWindow(int _)  
{  
GUILayout.BeginVertical();  
   
if (this.powerAvailable || HighLogic.LoadedSceneIsEditor)  
{  
if (!HighLogic.LoadedSceneIsEditor)  
{  
string str = "ON";  
if (togglePower)  
str = "OFF";  
if (GUILayout.Button("Power " + str))  
{  
togglePower.value = !togglePower;  
this.SetIconTexture(this.powerState | this.activeState);  
}  
}  
   
if (togglePower || HighLogic.LoadedSceneIsEditor)  
{  
foreach (IVOID_Module module in this.Modules)  
{  
module.toggleActive = GUILayout.Toggle(module.toggleActive, module.Name);  
}  
}  
}  
else  
{  
GUILayout.Label("-- POWER LOST --", this.LabelStyles["red"]);  
}  
   
this.configWindowMinimized.value = !GUILayout.Toggle(!this.configWindowMinimized, "Configuration");  
   
GUILayout.EndVertical();  
GUI.DragWindow();  
}  
   
public void VOIDConfigWindow(int _)  
{  
GUILayout.BeginVertical();  
   
this.DrawConfigurables();  
   
GUILayout.EndVertical();  
GUI.DragWindow();  
}  
   
public override void DrawConfigurables()  
{  
int skinIdx;  
   
GUIContent _content;  
   
if (HighLogic.LoadedSceneIsFlight)  
{  
this.consumeResource.value = GUILayout.Toggle(this.consumeResource, "Consume Resources");  
   
this.VOIDIconLocked = GUILayout.Toggle(this.VOIDIconLocked, "Lock Icon Position");  
}  
   
this.UseToolbarManager = GUILayout.Toggle(this.UseToolbarManager, "Use Blizzy's Toolbar If Available");  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
   
GUILayout.Label("Skin:", GUILayout.ExpandWidth(false));  
   
_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.tooltip = "Select previous skin";  
if (GUILayout.Button(_content, GUILayout.ExpandWidth(true)))  
{  
this.GUIStylesLoaded = false;  
skinIdx--;  
if (skinIdx < 0)  
skinIdx = skinNames.Count - 1;  
Tools.PostDebugMessage(string.Format(  
"{0}: new this._skinIdx = {1} :: skin_list.Count = {2}",  
this.GetType().Name,  
this._skinName,  
this.skin_list.Count  
));  
}  
   
_content.text = this.Skin.name;  
_content.tooltip = "Current skin";  
GUILayout.Label(_content, this.LabelStyles["center"], GUILayout.ExpandWidth(true));  
   
_content.text = "►";  
_content.tooltip = "Select next skin";  
if (GUILayout.Button(_content, GUILayout.ExpandWidth(true)))  
{  
this.GUIStylesLoaded = false;  
skinIdx++;  
if (skinIdx >= skinNames.Count)  
skinIdx = 0;  
Tools.PostDebugMessage(string.Format(  
"{0}: new this._skinIdx = {1} :: skin_list.Count = {2}",  
this.GetType().Name,  
this._skinName,  
this.skin_list.Count  
));  
}  
   
if (this._skinName != skinNames[skinIdx])  
{  
this._skinName = skinNames[skinIdx];  
}  
   
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal();  
GUILayout.Label("Update Rate (Hz):");  
if (this.stringFrequency == null)  
{  
this.stringFrequency = (1f / this.updatePeriod).ToString();  
}  
this.stringFrequency = GUILayout.TextField(this.stringFrequency.ToString(), 5, GUILayout.ExpandWidth(true));  
// GUILayout.FlexibleSpace();  
if (GUILayout.Button("Apply"))  
{  
double updateFreq = 1f / this.updatePeriod;  
double.TryParse(stringFrequency, out updateFreq);  
this._updatePeriod = 1 / updateFreq;  
}  
GUILayout.EndHorizontal();  
   
foreach (IVOID_Module mod in this.Modules)  
{  
mod.DrawConfigurables();  
}  
   
this._factoryReset = GUILayout.Toggle(this._factoryReset, "Factory Reset");  
}  
   
public override void DrawGUI()  
{  
this._windowID = this.windowBaseID;  
   
if (!this._modulesLoaded)  
{  
this.LoadModulesOfType<IVOID_Module>();  
}  
   
if (this.UseToolbarManager && !this.ToolbarManagerLoaded)  
{  
this.LoadToolbarManager();  
}  
   
if (!this.skinsLoaded)  
{  
this.LoadSkins();  
}  
   
GUI.skin = this.Skin;  
   
if (!this.GUIStylesLoaded)  
{  
this.LoadGUIStyles();  
}  
   
if (!(this.UseToolbarManager && this.ToolbarManagerLoaded))  
{  
if (GUI.Button(VOIDIconPos, VOIDIconTexture, this.iconStyle) && this.VOIDIconLocked)  
{  
this.mainGuiMinimized.value = !this.mainGuiMinimized;  
this.SetIconTexture(this.powerState | this.activeState);  
}  
} }
   
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, VOID_Tools.GetWindowHandler(this.VOIDMainWindow),
string.Join(" ", new string[] { this.VoidName, this.VoidVersion }), string.Join(" ", new string[] { this.VoidName, this.VoidVersion }),
GUILayout.Width(250), GUILayout.Width(250),
GUILayout.Height(50) GUILayout.Height(50)
); );
   
_mainWindowPos = Tools.ClampRectToScreen(_mainWindowPos); if (HighLogic.LoadedSceneIsEditor)
  {
  _mainWindowPos = Tools.ClampRectToEditorPad(_mainWindowPos);
  }
  else
  {
  _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, VOID_Tools.GetWindowHandler(this.VOIDConfigWindow),
string.Join(" ", new string[] { this.VoidName, "Configuration" }), string.Join(" ", new string[] { this.VoidName, "Configuration" }),
GUILayout.Width(250), GUILayout.Width(250),
GUILayout.Height(50) GUILayout.Height(50)
); );
   
_configWindowPos = Tools.ClampRectToScreen(_configWindowPos); if (HighLogic.LoadedSceneIsEditor)
  {
  _configWindowPos = Tools.ClampRectToEditorPad(_configWindowPos);
  }
  else
  {
  _configWindowPos = Tools.ClampRectToScreen(_configWindowPos);
  }
   
if (_configWindowPos != this.configWindowPos) if (_configWindowPos != this.configWindowPos)
{ {
this.configWindowPos = _configWindowPos; this.configWindowPos = _configWindowPos;
} }
} }
} }
   
public void OnGUI() public virtual void OnGUI()
{ {
if (Event.current.type == EventType.Repaint) if (Event.current.type == EventType.Repaint)
{ {
return; return;
} }
   
/* /*
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"Event.current.type: {0}" + "Event.current.type: {0}" +
"\nthis.VOIDIconLocked: {1}" + "\nthis.VOIDIconLocked: {1}" +
"\nEvent.current.mousePosition: {2}" + "\nEvent.current.mousePosition: {2}" +
"\nVOIDIconPos: ({3}, {4}),({5}, {6})", "\nVOIDIconPos: ({3}, {4}),({5}, {6})",
Event.current.type, Event.current.type,
this.VOIDIconLocked, this.VOIDIconLocked,
Event.current.mousePosition, Event.current.mousePosition,
this.VOIDIconPos.value.xMin, this.VOIDIconPos.value.xMin,
this.VOIDIconPos.value.yMin, this.VOIDIconPos.value.yMin,
this.VOIDIconPos.value.xMax, this.VOIDIconPos.value.xMax,
this.VOIDIconPos.value.yMax this.VOIDIconPos.value.yMax
)); ));
*/ */
   
if (!this.VOIDIconLocked && if (!this.VOIDIconLocked &&
VOIDIconPos.value.Contains(Event.current.mousePosition) VOIDIconPos.value.Contains(Event.current.mousePosition)
&& Event.current.type == EventType.mouseDrag) && Event.current.type == EventType.mouseDrag)
{ {
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"Event.current.type: {0}" + "Event.current.type: {0}" +
"\ndelta.x: {1}; delta.y: {2}", "\ndelta.x: {1}; delta.y: {2}",
Event.current.type, Event.current.type,
Event.current.delta.x, Event.current.delta.x,
Event.current.delta.y Event.current.delta.y
)); ));
   
Rect tmp = new Rect(VOIDIconPos); Rect tmp = new Rect(VOIDIconPos);
   
tmp.x = Event.current.mousePosition.x - tmp.width / 2; tmp.x = Event.current.mousePosition.x - tmp.width / 2;
tmp.y = Event.current.mousePosition.y - tmp.height / 2; tmp.y = Event.current.mousePosition.y - tmp.height / 2;
   
if (tmp.x > Screen.width - tmp.width) if (tmp.x > Screen.width - tmp.width)
{ {
tmp.x = Screen.width - tmp.width; tmp.x = Screen.width - tmp.width;
} }
   
if (tmp.y > Screen.height - tmp.height) if (tmp.y > Screen.height - tmp.height)
{ {
tmp.y = Screen.height - tmp.height; tmp.y = Screen.height - tmp.height;
} }
   
VOIDIconPos = tmp; VOIDIconPos = tmp;
} }
} }
   
public void Update() public virtual void Update()
{ {
this.LoadBeforeUpdate(); this.LoadBeforeUpdate();
   
if (this.vessel != null) if (this.vessel != null && this.vesselSimActive)
{ {
SimManager.Instance.Gravity = VOID_Core.Instance.vessel.mainBody.gravParameter / Tools.PostDebugMessage(this, "Updating SimManager.");
Math.Pow(VOID_Core.Instance.vessel.mainBody.Radius, 2); this.UpdateSimManager();
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 virtual void FixedUpdate()
{ {
bool newPowerState = this.powerAvailable; bool newPowerState = this.powerAvailable;
   
if (this.togglePower && this.consumeResource && if (this.togglePower && this.consumeResource &&
this.vessel.vesselType != VesselType.EVA && this.vessel.vesselType != VesselType.EVA &&
TimeWarp.deltaTime != 0) TimeWarp.deltaTime != 0)
{ {
float powerReceived = this.vessel.rootPart.RequestResource( float powerReceived = this.vessel.rootPart.RequestResource(
this.resourceName, this.resourceName,
this.resourceRate * TimeWarp.fixedDeltaTime this.resourceRate * TimeWarp.fixedDeltaTime
); );
   
if (powerReceived > 0) if (powerReceived > 0)
{ {
newPowerState = true; newPowerState = true;
} }
else else
{ {
newPowerState = false; newPowerState = false;
} }
   
if (this.powerAvailable != newPowerState) if (this.powerAvailable != newPowerState)
{ {
this.powerAvailable = newPowerState; this.powerAvailable = newPowerState;
this.SetIconTexture(this.powerState | this.activeState); this.SetIconTexture(this.powerState | this.activeState);
} }
} }
   
foreach (IVOID_BehaviorModule module in foreach (IVOID_Module module in this.Modules)
this._modules.OfType<IVOID_BehaviorModule>().Where(m => !m.GetType().IsAbstract)) {
{ if (module is IVOID_BehaviorModule)
module.FixedUpdate(); {
  ((IVOID_BehaviorModule)module).FixedUpdate();
  }
  }
  }
   
  public void OnDestroy()
  {
  foreach (IVOID_Module module in this.Modules)
  {
  if (module is IVOID_BehaviorModule)
  {
  ((IVOID_BehaviorModule)module).OnDestroy();
  }
} }
} }
   
public void ResetGUI() public void ResetGUI()
{ {
this.StopGUI(); this.StopGUI();
   
foreach (IVOID_Module module in this.Modules) foreach (IVOID_Module module in this.Modules)
{ {
module.StopGUI(); module.StopGUI();
module.StartGUI(); module.StartGUI();
} }
   
this.StartGUI(); this.StartGUI();
  }
   
  public void VOIDMainWindow(int _)
  {
  GUILayout.BeginVertical();
   
  if (this.powerAvailable || HighLogic.LoadedSceneIsEditor)
  {
  if (!HighLogic.LoadedSceneIsEditor)
  {
  string str = string.Intern("ON");
  if (togglePower)
  str = string.Intern("OFF");
  if (GUILayout.Button("Power " + str))
  {
  togglePower.value = !togglePower;
  this.SetIconTexture(this.powerState | this.activeState);
  }
  }
   
  if (togglePower || HighLogic.LoadedSceneIsEditor)
  {
  foreach (IVOID_Module module in this.Modules)
  {
  module.toggleActive = GUILayout.Toggle(module.toggleActive, module.Name);
  }
  }
  }
  else
  {
  GUILayout.Label("-- POWER LOST --", VOID_Styles.labelRed);
  }
   
  this.configWindowMinimized.value = !GUILayout.Toggle(!this.configWindowMinimized, "Configuration");
   
  GUILayout.EndVertical();
  GUI.DragWindow();
  }
   
  public void VOIDConfigWindow(int _)
  {
  GUILayout.BeginVertical();
   
  this.DrawConfigurables();
   
  GUILayout.EndVertical();
  GUI.DragWindow();
  }
   
  public override void DrawConfigurables()
  {
  GUIContent _content;
   
  if (HighLogic.LoadedSceneIsFlight)
  {
  this.consumeResource.value = GUILayout.Toggle(this.consumeResource, "Consume Resources");
   
  this.VOIDIconLocked = GUILayout.Toggle(this.VOIDIconLocked, "Lock Icon Position");
  }
   
  this.UseToolbarManager = GUILayout.Toggle(this.UseToolbarManager, "Use Blizzy's Toolbar If Available");
   
  this.vesselSimActive.value = GUILayout.Toggle(this.vesselSimActive.value,
  "Enable Engineering Calculations");
   
  GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
   
  GUILayout.Label("Skin:", GUILayout.ExpandWidth(false));
   
  _content = new GUIContent();
   
  _content.text = "◄";
  _content.tooltip = "Select previous skin";
  if (GUILayout.Button(_content, GUILayout.ExpandWidth(true)))
  {
  this._skinIdx--;
  Tools.PostDebugMessage(string.Format(
  "{0}: new this._skinIdx = {1} :: skin_list.Count = {2}",
  this.GetType().Name,
  this._skinName,
  this.validSkins.Count
  ));
  }
   
  _content.text = this.Skin.name;
  _content.tooltip = "Current skin";
  GUILayout.Label(_content, VOID_Styles.labelCenter, GUILayout.ExpandWidth(true));
   
  _content.text = "►";
  _content.tooltip = "Select next skin";
  if (GUILayout.Button(_content, GUILayout.ExpandWidth(true)))
  {
  this._skinIdx++;
  Tools.PostDebugMessage(string.Format(
  "{0}: new this._skinIdx = {1} :: skin_list.Count = {2}",
  this.GetType().Name,
  this._skinName,
  this.validSkins.Count
  ));
  }
   
  this._skinIdx %= this.skinNames.Length;
  if (this._skinIdx < 0)
  {
  this._skinIdx += this.skinNames.Length;
  }
   
  if (this._skinName != skinNames[this._skinIdx])
  {
  this._skinName.value = skinNames[this._skinIdx];
  this.GUIStylesLoaded = false;
  }
   
  GUILayout.EndHorizontal();
   
  GUILayout.BeginHorizontal();
  GUILayout.Label("Update Rate (Hz):");
  if (this.stringFrequency == null)
  {
  this.stringFrequency = (1f / this.updatePeriod).ToString();
  }
  this.stringFrequency = GUILayout.TextField(this.stringFrequency.ToString(), 5, GUILayout.ExpandWidth(true));
   
  if (GUILayout.Button("Apply"))
  {
  double updateFreq = 1f / this.updatePeriod;
  double.TryParse(stringFrequency, out updateFreq);
  this._updatePeriod = 1 / updateFreq;
  }
  GUILayout.EndHorizontal();
   
  foreach (IVOID_Module mod in this.Modules)
  {
  mod.DrawConfigurables();
  }
   
  this._factoryReset = GUILayout.Toggle(this._factoryReset, "Factory Reset");
  }
   
  protected void UpdateSimManager()
  {
  if (SimManager.ResultsReady())
  {
  Tools.PostDebugMessage(this, "VesselSimulator results ready, setting Stages.");
   
  this.Stages = SimManager.Stages;
   
  if (this.Stages != null)
  {
  this.LastStage = this.Stages.Last();
  }
   
  if (HighLogic.LoadedSceneIsEditor)
  {
  SimManager.Gravity = VOID_Data.KerbinGee;
  }
  else
  {
  double radius = this.vessel.Radius();
  SimManager.Gravity = this.vessel.mainBody.gravParameter / (radius * radius);
  }
   
  SimManager.minSimTime = (long)(this.updatePeriod * 1000);
   
  SimManager.TryStartSimulation();
  }
  #if DEBUG
  else
  {
  Tools.PostDebugMessage(this, "VesselSimulator results not ready.");
  }
  #endif
  }
   
  protected void LoadModulesOfType<T>()
  {
  StringBuilder sb = new StringBuilder("Loading modules...");
  sb.AppendLine();
   
  foreach (AssemblyLoader.LoadedAssembly assy in AssemblyLoader.loadedAssemblies)
  {
  foreach (Type loadedType in assy.assembly.GetExportedTypes())
  {
  if (
  loadedType.IsInterface ||
  loadedType.IsAbstract ||
  !typeof(T).IsAssignableFrom(loadedType) ||
  this.GetType().IsAssignableFrom(loadedType)
  )
  {
  continue;
  }
   
  // HACK: This stops editor modules from loading in flight. It is a dirty hack and should be fixed.
  if (!HighLogic.LoadedSceneIsEditor && typeof(IVOID_EditorModule).IsAssignableFrom(loadedType))
  {
  continue;
  }
   
  sb.AppendFormat("Loading IVOID_Module type {0}...", loadedType.Name);
   
  try
  {
  this.LoadModule(loadedType);
  sb.AppendLine("Success.");
  }
  catch (Exception ex)
  {
  sb.AppendFormat("Failed, caught {0}", ex.GetType().Name);
  sb.AppendLine();
   
  #if DEBUG
  Debug.LogException(ex);
  #endif
  }
  }
  }
   
  this._modulesLoaded = true;
   
  sb.AppendFormat("Loaded {0} modules.", this.Modules.Count);
  sb.AppendLine();
  }
   
  protected void LoadModule(Type T)
  {
  var existingModules = this._modules.Where(mod => mod.GetType().Name == T.Name);
  if (existingModules.Any())
  {
  Tools.PostDebugMessage(string.Format(
  "{0}: refusing to load {1}: already loaded",
  this.GetType().Name,
  T.Name
  ));
  return;
  }
  IVOID_Module module = Activator.CreateInstance(T) as IVOID_Module;
  module.LoadConfig();
  this._modules.Add(module);
   
  Tools.PostDebugMessage(string.Format(
  "{0}: loaded module {1}.",
  this.GetType().Name,
  T.Name
  ));
  }
   
  protected void LoadSkins()
  {
  Tools.PostDebugMessage("AssetBase has skins: \n" +
  string.Join("\n\t",
  Resources.FindObjectsOfTypeAll(typeof(GUISkin))
  .Select(s => s.ToString())
  .ToArray()
  )
  );
   
  this.validSkins = Resources.FindObjectsOfTypeAll(typeof(GUISkin))
  .Where(s => !this.forbiddenSkins.Contains(s.name))
  .Select(s => s as GUISkin)
  .GroupBy(s => s.name)
  .Select(g => g.First())
  .ToDictionary(s => s.name);
   
  Tools.PostDebugMessage(string.Format(
  "{0}: loaded {1} GUISkins.",
  this.GetType().Name,
  this.validSkins.Count
  ));
   
  this.skinNames = this.validSkins.Keys.ToArray();
  Array.Sort(this.skinNames);
   
  int defaultIdx = int.MinValue;
   
  for (int i = 0; i < this.skinNames.Length; i++)
  {
  if (this.skinNames[i] == this._skinName)
  {
  this._skinIdx = i;
  }
  if (this.skinNames[i] == this.defaultSkin)
  {
  defaultIdx = i;
  }
  if (this._skinIdx != int.MinValue && defaultIdx != int.MinValue)
  {
  break;
  }
  }
   
  if (this._skinIdx == int.MinValue)
  {
  this._skinIdx = defaultIdx;
  }
   
  Tools.PostDebugMessage(string.Format(
  "{0}: _skinIdx = {1}.",
  this.GetType().Name,
  this._skinName.ToString()
  ));
   
  this.skinsLoaded = true;
  }
   
  protected void LoadGUIStyles()
  {
  VOID_Styles.OnSkinChanged();
   
  this.GUIStylesLoaded = true;
  }
   
  protected void LoadVesselTypes()
  {
  this._allVesselTypes = Enum.GetValues(typeof(VesselType)).OfType<VesselType>().ToList();
  this.vesselTypesLoaded = true;
  }
   
  protected void LoadBeforeUpdate()
  {
  if (!this.vesselTypesLoaded)
  {
  this.LoadVesselTypes();
  }
   
  if (this.sortedBodyList == null && FlightGlobals.Bodies != null && FlightGlobals.Bodies.Count > 0)
  {
  this.sortedBodyList = new List<CelestialBody>(FlightGlobals.Bodies);
  this.sortedBodyList.Sort(new CBListComparer());
  this.sortedBodyList.Reverse();
   
  Debug.Log(string.Format("sortedBodyList: {0}", string.Join("\n\t", this.sortedBodyList.Select(b => b.bodyName).ToArray())));
  }
   
  }
   
  protected void InitializeToolbarButton()
  {
  // Do nothing if (the Toolbar is not available.
  if (!ToolbarManager.ToolbarAvailable)
  {
  Tools.PostDebugMessage(this, "Refusing to make a ToolbarButton: ToolbarAvailable = false");
  return;
  }
   
  this.ToolbarButton = ToolbarManager.Instance.add(this.VoidName, "coreToggle");
  this.ToolbarButton.Text = this.VoidName;
  this.SetIconTexture(this.powerState | this.activeState);
   
  this.ToolbarButton.Visibility = new GameScenesVisibility(GameScenes.EDITOR, GameScenes.FLIGHT, GameScenes.SPH);
   
  this.ToolbarButton.OnClick +=
  (e) =>
  {
  this.ToggleMainWindow();
  };
   
  Tools.PostDebugMessage(string.Format("{0}: Toolbar Button initialized.", this.GetType().Name));
  }
   
  protected void InitializeAppLauncherButton()
  {
  if (ApplicationLauncher.Ready)
  {
  this.AppLauncherButton = ApplicationLauncher.Instance.AddModApplication(
  this.ToggleMainWindow, this.ToggleMainWindow,
  this.appIconVisibleScenes,
  this.VOIDIconTexture
  );
   
  Tools.PostDebugMessage(
  this,
  "AppLauncherButton initialized in {0}",
  Enum.GetName(
  typeof(GameScenes),
  HighLogic.LoadedScene
  )
  );
  }
  }
   
  protected void ToggleMainWindow()
  {
  this.mainGuiMinimized = !this.mainGuiMinimized;
  this.SetIconTexture(this.powerState | this.activeState);
} }
   
protected void SetIconTexture(IconState state) protected void SetIconTexture(IconState state)
{ {
switch (state) switch (state)
{ {
case (IconState.PowerOff | IconState.Inactive): case (IconState.PowerOff | IconState.Inactive):
this.SetIconTexture(this.VOIDIconOffInactivePath); this.SetIconTexture(this.VOIDIconOffInactivePath);
break; break;
case (IconState.PowerOff | IconState.Active): case (IconState.PowerOff | IconState.Active):
this.SetIconTexture(this.VOIDIconOffActivePath); this.SetIconTexture(this.VOIDIconOffActivePath);
break; break;
case (IconState.PowerOn | IconState.Inactive): case (IconState.PowerOn | IconState.Inactive):
this.SetIconTexture(this.VOIDIconOnInactivePath); this.SetIconTexture(this.VOIDIconOnInactivePath);
break; break;
case (IconState.PowerOn | IconState.Active): case (IconState.PowerOn | IconState.Active):
this.SetIconTexture(this.VOIDIconOnActivePath); this.SetIconTexture(this.VOIDIconOnActivePath);
break; break;
default: default:
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
   
protected void SetIconTexture(string texturePath) protected void SetIconTexture(string texturePath)
{ {
if (this.UseToolbarManager && this.ToolbarButton != null) if (this.ToolbarButton != null)
{ {
this.ToolbarButton.TexturePath = texturePath; this.ToolbarButton.TexturePath = texturePath;
} }
else  
{ this.VOIDIconTexture = GameDatabase.Instance.GetTexture(texturePath.Replace("icon", "appIcon"), false);
this.VOIDIconTexture = GameDatabase.Instance.GetTexture(texturePath, false);  
  if (this.AppLauncherButton != null)
  {
  this.AppLauncherButton.SetTexture(VOIDIconTexture);
} }
} }
   
protected void CheckAndSave() protected void CheckAndSave()
{ {
this.saveTimer += Time.deltaTime; this.saveTimer += Time.deltaTime;
   
if (this.saveTimer > 2f) if (this.saveTimer > 2f)
{ {
if (!this.configDirty) if (!this.configDirty)
{ {
return; return;
} }
   
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"{0}: Time to save, checking if configDirty: {1}", "{0}: Time to save, checking if configDirty: {1}",
this.GetType().Name, this.GetType().Name,
this.configDirty this.configDirty
)); ));
   
this.SaveConfig(); this.SaveConfig();
this.saveTimer = 0; this.saveTimer = 0;
} }
} }
   
public override void LoadConfig() public override void LoadConfig()
{ {
base.LoadConfig(); base.LoadConfig();
   
foreach (IVOID_Module module in this.Modules) foreach (IVOID_Module module in this.Modules)
{ {
module.LoadConfig(); module.LoadConfig();
} }
} }
   
public void SaveConfig() public void SaveConfig()
{ {
var config = KSP.IO.PluginConfiguration.CreateForType<VOID_Core>(); var config = KSP.IO.PluginConfiguration.CreateForType<VOID_Core>();
config.load(); config.load();
   
this._SaveToConfig(config); this._SaveToConfig(config);
   
foreach (IVOID_Module module in this.Modules) foreach (IVOID_Module module in this.Modules)
{ {
module._SaveToConfig(config); module._SaveToConfig(config);
} }
   
config.save(); config.save();
   
this.configDirty = false; this.configDirty = false;
} }
   
  protected VOID_Core()
  {
  this._Name = "VOID Core";
   
  System.Version version = this.GetType().Assembly.GetName().Version;
   
  this.VoidVersion = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.MajorRevision);
   
  this.toggleActive = true;
   
  this._skinName = this.defaultSkin;
  this._skinIdx = int.MinValue;
   
  this.VOIDIconOnInactivePath = "VOID/Textures/void_icon_light_glow";
  this.VOIDIconOnActivePath = "VOID/Textures/void_icon_dark_glow";
  this.VOIDIconOffInactivePath = "VOID/Textures/void_icon_light";
  this.VOIDIconOffActivePath = "VOID/Textures/void_icon_dark";
   
  this.vesselSimActive = true;
   
  this.UseToolbarManager = false;
   
  this.LoadConfig();
   
  this.SetIconTexture(this.powerState | this.activeState);
  }
   
  public virtual void Dispose()
  {
  if (this.AppLauncherButton != null)
  {
  ApplicationLauncher.Instance.RemoveModApplication(this.AppLauncherButton);
  this.AppLauncherButton = null;
  }
  if (this.ToolbarButton != null)
  {
  this.ToolbarButton.Destroy();
  this.ToolbarButton = null;
  }
  }
   
protected enum IconState protected enum IconState
{ {
PowerOff = 1, PowerOff = 1,
PowerOn = 2, PowerOn = 2,
Inactive = 4, Inactive = 4,
Active = 8 Active = 8
} }
} }
} }