Added calls to UpdateModSettings in relevant places
Added calls to UpdateModSettings in relevant places

// //
// Kerbal Engineer Redux // Kerbal Engineer Redux
// //
// Copyright (C) 2014 CYBUTEK // Copyright (C) 2014 CYBUTEK
// //
// 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/>.
// //
   
namespace KerbalEngineer.Editor namespace KerbalEngineer.Editor
{ {
#region Using Directives #region Using Directives
   
using System; using System;
using System.Linq; using System.Linq;
using Extensions; using Extensions;
using Flight; using Flight;
using Helpers; using Helpers;
using Settings; using Settings;
using UIControls; using UIControls;
using UnityEngine; using UnityEngine;
using VesselSimulator; using VesselSimulator;
   
#endregion #endregion
   
[KSPAddon(KSPAddon.Startup.EditorAny, false)] [KSPAddon(KSPAddon.Startup.EditorAny, false)]
public class BuildAdvanced : MonoBehaviour public class BuildAdvanced : MonoBehaviour
{ {
#region Fields #region Fields
   
private GUIStyle areaSettingStyle; private GUIStyle areaSettingStyle;
private GUIStyle areaStyle; private GUIStyle areaStyle;
private float atmosphericPercentage = 1.0f; private float atmosphericPercentage = 1.0f;
private float atmosphericVelocity; private float atmosphericVelocity;
private GUIStyle bodiesButtonActiveStyle; private GUIStyle bodiesButtonActiveStyle;
private GUIStyle bodiesButtonStyle; private GUIStyle bodiesButtonStyle;
private DropDown bodiesList; private DropDown bodiesList;
private Rect bodiesListPosition; private Rect bodiesListPosition;
private GUIStyle buttonStyle; private GUIStyle buttonStyle;
private int compactCheck; private int compactCheck;
private bool compactCollapseRight; private bool compactCollapseRight;
private bool compactMode; private bool compactMode;
private float compactRight; private float compactRight;
private bool hasChanged; private bool hasChanged;
private GUIStyle infoStyle; private GUIStyle infoStyle;
private bool isEditorLocked; private bool isEditorLocked;
private int numberOfStages; private int numberOfStages;
private Rect position = new Rect(265.0f, 45.0f, 0, 0); private Rect position = new Rect(265.0f, 45.0f, 0, 0);
private GUIStyle settingAtmoStyle; private GUIStyle settingAtmoStyle;
private GUIStyle settingStyle; private GUIStyle settingStyle;
private bool showAllStages; private bool showAllStages;
private bool showAtmosphericDetails; private bool showAtmosphericDetails;
private bool showSettings; private bool showSettings;
private Stage[] stages; private Stage[] stages;
private GUIStyle titleStyle; private GUIStyle titleStyle;
private bool visible = true; private bool visible = true;
private GUIStyle windowStyle; private GUIStyle windowStyle;
   
#endregion #endregion
   
#region Properties #region Properties
   
/// <summary> /// <summary>
/// Gets the current instance if started or returns null. /// Gets the current instance if started or returns null.
/// </summary> /// </summary>
public static BuildAdvanced Instance { get; private set; } public static BuildAdvanced Instance { get; private set; }
   
/// <summary> /// <summary>
/// Gets and sets whether to show in compact mode. /// Gets and sets whether to show in compact mode.
/// </summary> /// </summary>
public bool CompactMode public bool CompactMode
{ {
get { return this.compactMode; } get { return this.compactMode; }
set { this.compactMode = value; } set { this.compactMode = value; }
} }
   
/// <summary> /// <summary>
/// Gets and sets whether to show all stages. /// Gets and sets whether to show all stages.
/// </summary> /// </summary>
public bool ShowAllStages public bool ShowAllStages
{ {
get { return this.showAllStages; } get { return this.showAllStages; }
set { this.showAllStages = value; } set { this.showAllStages = value; }
} }
   
/// <summary> /// <summary>
/// Gets and sets whether to use atmospheric details. /// Gets and sets whether to use atmospheric details.
/// </summary> /// </summary>
public bool ShowAtmosphericDetails public bool ShowAtmosphericDetails
{ {
get { return this.showAtmosphericDetails; } get { return this.showAtmosphericDetails; }
set { this.showAtmosphericDetails = value; } set { this.showAtmosphericDetails = value; }
} }
   
/// <summary> /// <summary>
/// Gets and sets whether to show the settings display. /// Gets and sets whether to show the settings display.
/// </summary> /// </summary>
public bool ShowSettings public bool ShowSettings
{ {
get { return this.showSettings; } get { return this.showSettings; }
set { this.showSettings = value; } set { this.showSettings = value; }
} }
   
/// <summary> /// <summary>
/// Gets and sets whether the display is enabled. /// Gets and sets whether the display is enabled.
/// </summary> /// </summary>
public bool Visible public bool Visible
{ {
get { return this.visible; } get { return this.visible; }
set { this.visible = value; } set { this.visible = value; }
} }
   
#endregion #endregion
   
#region Methods #region Methods
   
protected void Awake() protected void Awake()
{ {
try try
{ {
Instance = this; Instance = this;
this.bodiesList = this.gameObject.AddComponent<DropDown>(); this.bodiesList = this.gameObject.AddComponent<DropDown>();
this.bodiesList.DrawCallback = this.DrawBodiesList; this.bodiesList.DrawCallback = this.DrawBodiesList;
this.Load(); this.Load();
   
  SimManager.UpdateModSettings();
SimManager.OnReady -= this.GetStageInfo; SimManager.OnReady -= this.GetStageInfo;
SimManager.OnReady += this.GetStageInfo; SimManager.OnReady += this.GetStageInfo;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
   
/// <summary> /// <summary>
/// Saves the settings when this object is destroyed. /// Saves the settings when this object is destroyed.
/// </summary> /// </summary>
protected void OnDestroy() protected void OnDestroy()
{ {
try try
{ {
var handler = new SettingHandler(); var handler = new SettingHandler();
handler.Set("visible", this.visible); handler.Set("visible", this.visible);
handler.Set("windowPositionX", this.position.x); handler.Set("windowPositionX", this.position.x);
handler.Set("windowPositionY", this.position.y); handler.Set("windowPositionY", this.position.y);
handler.Set("compactMode", this.compactMode); handler.Set("compactMode", this.compactMode);
handler.Set("compactCollapseRight", this.compactCollapseRight); handler.Set("compactCollapseRight", this.compactCollapseRight);
handler.Set("showAllStages", this.showAllStages); handler.Set("showAllStages", this.showAllStages);
handler.Set("showAtmosphericDetails", this.showAtmosphericDetails); handler.Set("showAtmosphericDetails", this.showAtmosphericDetails);
handler.Set("showSettings", this.showSettings); handler.Set("showSettings", this.showSettings);
handler.Set("selectedBodyName", CelestialBodies.SelectedBody.Name); handler.Set("selectedBodyName", CelestialBodies.SelectedBody.Name);
handler.Save("BuildAdvanced.xml"); handler.Save("BuildAdvanced.xml");
GuiDisplaySize.OnSizeChanged -= this.OnSizeChanged; GuiDisplaySize.OnSizeChanged -= this.OnSizeChanged;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
   
protected void OnGUI() protected void OnGUI()
{ {
try try
{ {
if (!this.visible || EditorLogic.fetch == null || EditorLogic.fetch.ship.parts.Count == 0 || EditorLogic.fetch.editorScreen != EditorScreen.Parts) if (!this.visible || EditorLogic.fetch == null || EditorLogic.fetch.ship.parts.Count == 0 || EditorLogic.fetch.editorScreen != EditorScreen.Parts)
{ {
return; return;
} }
   
if (this.stages == null) if (this.stages == null)
{ {
return; return;
} }
   
// Change the window title based on whether in compact mode or not. // Change the window title based on whether in compact mode or not.
var title = !this.compactMode ? "KERBAL ENGINEER REDUX " + EngineerGlobals.AssemblyVersion : "K.E.R. " + EngineerGlobals.AssemblyVersion + (this.showAtmosphericDetails ? " (ATMOS.)" : String.Empty); var title = !this.compactMode ? "KERBAL ENGINEER REDUX " + EngineerGlobals.AssemblyVersion : "K.E.R. " + EngineerGlobals.AssemblyVersion + (this.showAtmosphericDetails ? " (ATMOS.)" : String.Empty);
   
// Reset the window size when the staging or something else has changed. // Reset the window size when the staging or something else has changed.
var stageCount = this.stages.Count(stage => this.showAllStages || stage.deltaV > 0); var stageCount = this.stages.Count(stage => this.showAllStages || stage.deltaV > 0);
if (this.hasChanged || stageCount != this.numberOfStages) if (this.hasChanged || stageCount != this.numberOfStages)
{ {
this.hasChanged = false; this.hasChanged = false;
this.numberOfStages = stageCount; this.numberOfStages = stageCount;
   
this.position.width = 0; this.position.width = 0;
this.position.height = 0; this.position.height = 0;
} }
   
GUI.skin = null; GUI.skin = null;
this.position = GUILayout.Window(this.GetInstanceID(), this.position, this.Window, title, this.windowStyle).ClampToScreen(); this.position = GUILayout.Window(this.GetInstanceID(), this.position, this.Window, title, this.windowStyle).ClampToScreen();
   
if (this.compactCheck > 0 && this.compactCollapseRight) if (this.compactCheck > 0 && this.compactCollapseRight)
{ {
this.position.x = this.compactRight - this.position.width; this.position.x = this.compactRight - this.position.width;
this.compactCheck--; this.compactCheck--;
} }
else if (this.compactCheck > 0) else if (this.compactCheck > 0)
{ {
this.compactCheck = 0; this.compactCheck = 0;
} }
   
// Check editor lock to manage click-through. // Check editor lock to manage click-through.
this.CheckEditorLock(); this.CheckEditorLock();
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
   
protected void Start() protected void Start()
{ {
try try
{ {
this.InitialiseStyles(); this.InitialiseStyles();
GuiDisplaySize.OnSizeChanged += this.OnSizeChanged; GuiDisplaySize.OnSizeChanged += this.OnSizeChanged;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
   
protected void Update() protected void Update()
{ {
try try
{ {
if (Input.GetKeyDown(KeyBinder.EditorShowHide)) if (Input.GetKeyDown(KeyBinder.EditorShowHide))
{ {
this.visible = !this.visible; this.visible = !this.visible;
if (!this.visible) if (!this.visible)
{ {
this.EditorLock(false); this.EditorLock(false);
} }
} }
   
if (!this.visible || EditorLogic.fetch == null || EditorLogic.fetch.ship.parts.Count == 0) if (!this.visible || EditorLogic.fetch == null || EditorLogic.fetch.ship.parts.Count == 0)
{ {
this.bodiesList.enabled = false; this.bodiesList.enabled = false;
return; return;
} }
   
// Configure the simulation parameters based on the selected reference body. // Configure the simulation parameters based on the selected reference body.
SimManager.Gravity = CelestialBodies.SelectedBody.Gravity; SimManager.Gravity = CelestialBodies.SelectedBody.Gravity;
   
if (this.showAtmosphericDetails) if (this.showAtmosphericDetails)
{ {
SimManager.Atmosphere = CelestialBodies.SelectedBody.Atmosphere * 0.01d * this.atmosphericPercentage; SimManager.Atmosphere = CelestialBodies.SelectedBody.Atmosphere * 0.01d * this.atmosphericPercentage;
} }
else else
{ {
SimManager.Atmosphere = 0; SimManager.Atmosphere = 0;
} }
   
SimManager.Velocity = this.atmosphericVelocity; SimManager.Velocity = this.atmosphericVelocity;
   
SimManager.RequestSimulation(); SimManager.RequestSimulation();
SimManager.TryStartSimulation(); SimManager.TryStartSimulation();
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex, "BuildAdvanced->Update"); Logger.Exception(ex, "BuildAdvanced->Update");
} }
} }
   
/// <summary> /// <summary>
/// Checks whether the editor should be locked to stop click-through. /// Checks whether the editor should be locked to stop click-through.
/// </summary> /// </summary>
private void CheckEditorLock() private void CheckEditorLock()
{ {
if ((this.position.MouseIsOver() || this.bodiesList.Position.MouseIsOver()) && !this.isEditorLocked) if ((this.position.MouseIsOver() || this.bodiesList.Position.MouseIsOver()) && !this.isEditorLocked)
{ {
this.EditorLock(true); this.EditorLock(true);
} }
else if (!this.position.MouseIsOver() && !this.bodiesList.Position.MouseIsOver() && this.isEditorLocked) else if (!this.position.MouseIsOver() && !this.bodiesList.Position.MouseIsOver() && this.isEditorLocked)
{ {
this.EditorLock(false); this.EditorLock(false);
} }
} }
   
/// <summary> /// <summary>
/// Draws the atmospheric settings. /// Draws the atmospheric settings.
/// </summary> /// </summary>
private void DrawAtmosphericDetails() private void DrawAtmosphericDetails()
{ {
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
GUILayout.BeginVertical(); GUILayout.BeginVertical();
GUILayout.Label("Pressure: " + (this.atmosphericPercentage * 100.0f).ToString("F1") + "%", this.settingAtmoStyle, GUILayout.Width(125.0f * GuiDisplaySize.Offset)); GUILayout.Label("Pressure: " + (this.atmosphericPercentage * 100.0f).ToString("F1") + "%", this.settingAtmoStyle, GUILayout.Width(125.0f * GuiDisplaySize.Offset));
GUI.skin = HighLogic.Skin; GUI.skin = HighLogic.Skin;
this.atmosphericPercentage = GUILayout.HorizontalSlider(this.atmosphericPercentage, 0, 1.0f); this.atmosphericPercentage = GUILayout.HorizontalSlider(this.atmosphericPercentage, 0, 1.0f);
GUI.skin = null; GUI.skin = null;
GUILayout.EndVertical(); GUILayout.EndVertical();
   
GUILayout.Space(5.0f); GUILayout.Space(5.0f);
   
GUILayout.BeginVertical(); GUILayout.BeginVertical();
GUILayout.Label("Velocity: " + this.atmosphericVelocity.ToString("F1") + "m/s", this.settingAtmoStyle, GUILayout.Width(125.0f * GuiDisplaySize.Offset)); GUILayout.Label("Velocity: " + this.atmosphericVelocity.ToString("F1") + "m/s", this.settingAtmoStyle, GUILayout.Width(125.0f * GuiDisplaySize.Offset));
GUI.skin = HighLogic.Skin; GUI.skin = HighLogic.Skin;
this.atmosphericVelocity = GUILayout.HorizontalSlider(this.atmosphericVelocity, 0, 2500f); this.atmosphericVelocity = GUILayout.HorizontalSlider(this.atmosphericVelocity, 0, 2500f);
GUI.skin = null; GUI.skin = null;
GUILayout.EndVertical(); GUILayout.EndVertical();
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
   
private void DrawBodiesList() private void DrawBodiesList()
{ {
if (CelestialBodies.SystemBody == CelestialBodies.SelectedBody) if (CelestialBodies.SystemBody == CelestialBodies.SelectedBody)
{ {
this.DrawBody(CelestialBodies.SystemBody); this.DrawBody(CelestialBodies.SystemBody);
} }
else else
{ {
foreach (var body in CelestialBodies.SystemBody.Children) foreach (var body in CelestialBodies.SystemBody.Children)
{ {
this.DrawBody(body); this.DrawBody(body);
} }
} }
} }
   
private void DrawBody(CelestialBodies.BodyInfo bodyInfo, int depth = 0) private void DrawBody(CelestialBodies.BodyInfo bodyInfo, int depth = 0)
{ {
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
GUILayout.Space(20.0f * depth); GUILayout.Space(20.0f * depth);
if (GUILayout.Button(bodyInfo.Children.Count > 0 ? bodyInfo.Name + " [" + bodyInfo.Children.Count + "]" : bodyInfo.Name, bodyInfo.Selected && bodyInfo.SelectedDepth == 0 ? this.bodiesButtonActiveStyle : this.bodiesButtonStyle)) if (GUILayout.Button(bodyInfo.Children.Count > 0 ? bodyInfo.Name + " [" + bodyInfo.Children.Count + "]" : bodyInfo.Name, bodyInfo.Selected && bodyInfo.SelectedDepth == 0 ? this.bodiesButtonActiveStyle : this.bodiesButtonStyle))
{ {
CelestialBodies.SetSelectedBody(bodyInfo.Name); CelestialBodies.SetSelectedBody(bodyInfo.Name);
this.bodiesList.Resize = true; this.bodiesList.Resize = true;
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
if (bodyInfo.Selected) if (bodyInfo.Selected)
{ {
foreach (var body in bodyInfo.Children) foreach (var body in bodyInfo.Children)
{ {
this.DrawBody(body, depth + 1); this.DrawBody(body, depth + 1);
} }
} }
} }
   
/// <summary> /// <summary>
/// Draws the burn time column. /// Draws the burn time column.
/// </summary> /// </summary>
private void DrawBurnTime() private void DrawBurnTime()
{ {
GUILayout.BeginVertical(GUILayout.Width(75.0f * GuiDisplaySize.Offset)); GUILayout.BeginVertical(GUILayout.Width(75.0f * GuiDisplaySize.Offset));
GUILayout.Label("BURN", this.titleStyle); GUILayout.Label("BURN", this.titleStyle);
foreach (var stage in this.stages) foreach (var stage in this.stages)
{ {
if (this.showAllStages || stage.deltaV > 0) if (this.showAllStages || stage.deltaV > 0)
{ {
GUILayout.Label(TimeFormatter.ConvertToString(stage.time), this.infoStyle); GUILayout.Label(TimeFormatter.ConvertToString(stage.time), this.infoStyle);
} }
} }
GUILayout.EndVertical(); GUILayout.EndVertical();
} }
   
/// <summary> /// <summary>
/// Draws the cost column. /// Draws the cost column.
/// </summary> /// </summary>
private void DrawCost() private void DrawCost()
{ {
GUILayout.BeginVertical(GUILayout.Width(110.0f * GuiDisplaySize.Offset)); GUILayout.BeginVertical(GUILayout.Width(110.0f * GuiDisplaySize.Offset));
GUILayout.Label("COST", this.titleStyle); GUILayout.Label("COST", this.titleStyle);
foreach (var stage in this.stages) foreach (var stage in this.stages)
{ {
if (this.showAllStages || stage.deltaV > 0) if (this.showAllStages || stage.deltaV > 0)
{ {
GUILayout.Label(Units.Cost(stage.cost, stage.totalCost), this.infoStyle); GUILayout.Label(Units.Cost(stage.cost, stage.totalCost), this.infoStyle);
} }
} }
GUILayout.EndVertical(); GUILayout.EndVertical();
} }
   
/// <summary> /// <summary>
/// Draws the deltaV column. /// Draws the deltaV column.
/// </summary> /// </summary>
private void DrawDeltaV() private void DrawDeltaV()
{ {
GUILayout.BeginVertical(GUILayout.Width(100.0f * GuiDisplaySize.Offset)); GUILayout.BeginVertical(GUILayout.Width(100.0f * GuiDisplaySize.Offset));
GUILayout.Label("DELTA-V", this.titleStyle); GUILayout.Label("DELTA-V", this.titleStyle);
foreach (var stage in this.stages) foreach (var stage in this.stages)
{ {
if (this.showAllStages || stage.deltaV > 0) if (this.showAllStages || stage.deltaV > 0)
{ {
GUILayout.Label(stage.deltaV.ToString("N0") + " / " + stage.inverseTotalDeltaV.ToString("N0") + "m/s", this.infoStyle); GUILayout.Label(stage.deltaV.ToString("N0") + " / " + stage.inverseTotalDeltaV.ToString("N0") + "m/s", this.infoStyle);
} }
} }
GUILayout.EndVertical(); GUILayout.EndVertical();
} }
   
/// <summary> /// <summary>
/// Draws the specific impluse column. /// Draws the specific impluse column.
/// </summary> /// </summary>
private void DrawIsp() private void DrawIsp()
{ {
GUILayout.BeginVertical(GUILayout.Width(75.0f * GuiDisplaySize.Offset)); GUILayout.BeginVertical(GUILayout.Width(75.0f * GuiDisplaySize.Offset));
GUILayout.Label("ISP", this.titleStyle); GUILayout.Label("ISP", this.titleStyle);
foreach (var stage in this.stages) foreach (var stage in this.stages)
{ {
if (this.showAllStages || stage.deltaV > 0) if (this.showAllStages || stage.deltaV > 0)
{ {
GUILayout.Label(stage.isp.ToString("F1") + "s", this.infoStyle); GUILayout.Label(stage.isp.ToString("F1") + "s", this.infoStyle);
} }
} }
GUILayout.EndVertical(); GUILayout.EndVertical();
} }
   
/// <summary> /// <summary>
/// Draws the mass column. /// Draws the mass column.
/// </summary> /// </summary>
private void DrawMass() private void DrawMass()
{ {
GUILayout.BeginVertical(GUILayout.Width(110.0f * GuiDisplaySize.Offset)); GUILayout.BeginVertical(GUILayout.Width(110.0f * GuiDisplaySize.Offset));
GUILayout.Label("MASS", this.titleStyle); GUILayout.Label("MASS", this.titleStyle);
foreach (var stage in this.stages) foreach (var stage in this.stages)
{ {
if (this.showAllStages || stage.deltaV > 0) if (this.showAllStages || stage.deltaV > 0)
{ {
GUILayout.Label(Units.ToMass(stage.mass, stage.totalMass), this.infoStyle); GUILayout.Label(Units.ToMass(stage.mass, stage.totalMass), this.infoStyle);
} }
} }
GUILayout.EndVertical(); GUILayout.EndVertical();
} }
   
/// <summary> /// <summary>
/// Draws the part count column. /// Draws the part count column.
/// </summary> /// </summary>
private void DrawPartCount() private void DrawPartCount()
{ {
GUILayout.BeginVertical(GUILayout.Width(50.0f * GuiDisplaySize.Offset)); GUILayout.BeginVertical(GUILayout.Width(50.0f * GuiDisplaySize.Offset));
GUILayout.Label("PARTS", this.titleStyle); GUILayout.Label("PARTS", this.titleStyle);
foreach (var stage in this.stages) foreach (var stage in this.stages)
{ {
if (this.showAllStages || stage.deltaV > 0) if (this.showAllStages || stage.deltaV > 0)
{ {
GUILayout.Label(stage.partCount + " / " + stage.totalPartCount, this.infoStyle); GUILayout.Label(stage.partCount + " / " + stage.totalPartCount, this.infoStyle);
} }
} }
GUILayout.EndVertical(); GUILayout.EndVertical();
} }
   
/// <summary> /// <summary>
/// Draws the settings panel. /// Draws the settings panel.
/// </summary> /// </summary>
private void DrawSettings() private void DrawSettings()
{ {
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
GUILayout.Label("Compact mode collapses to the:", this.settingStyle); GUILayout.Label("Compact mode collapses to the:", this.settingStyle);
this.compactCollapseRight = !GUILayout.Toggle(!this.compactCollapseRight, "LEFT", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset)); this.compactCollapseRight = !GUILayout.Toggle(!this.compactCollapseRight, "LEFT", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
this.compactCollapseRight = GUILayout.Toggle(this.compactCollapseRight, "RIGHT", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset)); this.compactCollapseRight = GUILayout.Toggle(this.compactCollapseRight, "RIGHT", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
GUILayout.Label("Simulate using vectored thrust values:"); GUILayout.Label("Simulate using vectored thrust values:");
SimManager.vectoredThrust = GUILayout.Toggle(SimManager.vectoredThrust, "ENABLED", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset)); SimManager.vectoredThrust = GUILayout.Toggle(SimManager.vectoredThrust, "ENABLED", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
GUILayout.Label("Build Engineer Overlay:", this.settingStyle); GUILayout.Label("Build Engineer Overlay:", this.settingStyle);
BuildOverlay.Visible = GUILayout.Toggle(BuildOverlay.Visible, "VISIBLE", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset)); BuildOverlay.Visible = GUILayout.Toggle(BuildOverlay.Visible, "VISIBLE", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
BuildOverlayPartInfo.NamesOnly = GUILayout.Toggle(BuildOverlayPartInfo.NamesOnly, "NAMES ONLY", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset)); BuildOverlayPartInfo.NamesOnly = GUILayout.Toggle(BuildOverlayPartInfo.NamesOnly, "NAMES ONLY", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
BuildOverlayPartInfo.ClickToOpen = GUILayout.Toggle(BuildOverlayPartInfo.ClickToOpen, "CLICK TO OPEN", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset)); BuildOverlayPartInfo.ClickToOpen = GUILayout.Toggle(BuildOverlayPartInfo.ClickToOpen, "CLICK TO OPEN", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
GUILayout.Label("Flight Engineer activation mode:", this.settingStyle); GUILayout.Label("Flight Engineer activation mode:", this.settingStyle);
FlightEngineerCore.IsCareerMode = GUILayout.Toggle(FlightEngineerCore.IsCareerMode, "CAREER", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset)); FlightEngineerCore.IsCareerMode = GUILayout.Toggle(FlightEngineerCore.IsCareerMode, "CAREER", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
FlightEngineerCore.IsCareerMode = !GUILayout.Toggle(!FlightEngineerCore.IsCareerMode, "PARTLESS", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset)); FlightEngineerCore.IsCareerMode = !GUILayout.Toggle(!FlightEngineerCore.IsCareerMode, "PARTLESS", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
GUILayout.Label("Flight Engineer Career Limitations:", this.settingStyle); GUILayout.Label("Flight Engineer Career Limitations:", this.settingStyle);
FlightEngineerCore.IsKerbalLimited = GUILayout.Toggle(FlightEngineerCore.IsKerbalLimited, "KERBAL", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset)); FlightEngineerCore.IsKerbalLimited = GUILayout.Toggle(FlightEngineerCore.IsKerbalLimited, "KERBAL", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
FlightEngineerCore.IsTrackingStationLimited = GUILayout.Toggle(FlightEngineerCore.IsTrackingStationLimited, "TRACKING", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset)); FlightEngineerCore.IsTrackingStationLimited = GUILayout.Toggle(FlightEngineerCore.IsTrackingStationLimited, "TRACKING", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
GUILayout.Label("GUI Size: " + GuiDisplaySize.Increment, this.settingStyle); GUILayout.Label("GUI Size: " + GuiDisplaySize.Increment, this.settingStyle);
if (GUILayout.Button("<", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset))) if (GUILayout.Button("<", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset)))
{ {
GuiDisplaySize.Increment--; GuiDisplaySize.Increment--;
} }
if (GUILayout.Button(">", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset))) if (GUILayout.Button(">", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset)))
{ {
GuiDisplaySize.Increment++; GuiDisplaySize.Increment++;
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.Label("Minimum delay between simulations: " + SimManager.minSimTime.Milliseconds + "ms", this.settingStyle); GUILayout.Label("Minimum delay between simulations: " + SimManager.minSimTime.Milliseconds + "ms", this.settingStyle);
GUI.skin = HighLogic.Skin; GUI.skin = HighLogic.Skin;
SimManager.minSimTime = new TimeSpan(0, 0, 0, 0, (int)GUILayout.HorizontalSlider(SimManager.minSimTime.Milliseconds, 0, 2000.0f)); SimManager.minSimTime = new TimeSpan(0, 0, 0, 0, (int)GUILayout.HorizontalSlider(SimManager.minSimTime.Milliseconds, 0, 2000.0f));
GUI.skin = null; GUI.skin = null;
} }
   
/// <summary> /// <summary>
/// Draws the stage number column. /// Draws the stage number column.
/// </summary> /// </summary>
private void DrawStageNumbers() private void DrawStageNumbers()
{ {
GUILayout.BeginVertical(GUILayout.Width(30.0f * GuiDisplaySize.Offset)); GUILayout.BeginVertical(GUILayout.Width(30.0f * GuiDisplaySize.Offset));
GUILayout.Label(string.Empty, this.titleStyle); GUILayout.Label(string.Empty, this.titleStyle);
foreach (var stage in this.stages) foreach (var stage in this.stages)
{ {
if (this.showAllStages || stage.deltaV > 0) if (this.showAllStages || stage.deltaV > 0)
{ {
GUILayout.Label("S" + stage.number, this.titleStyle); GUILayout.Label("S" + stage.number, this.titleStyle);
} }
} }
GUILayout.EndVertical(); GUILayout.EndVertical();
} }
   
/// <summary> /// <summary>
/// Draws the thrust column. /// Draws the thrust column.
/// </summary> /// </summary>
private void DrawThrust() private void DrawThrust()
{ {
GUILayout.BeginVertical(GUILayout.Width(75.0f * GuiDisplaySize.Offset)); GUILayout.BeginVertical(GUILayout.Width(75.0f * GuiDisplaySize.Offset));
GUILayout.Label("THRUST", this.titleStyle); GUILayout.Label("THRUST", this.titleStyle);
foreach (var stage in this.stages) foreach (var stage in this.stages)
{ {
if (this.showAllStages || stage.deltaV > 0) if (this.showAllStages || stage.deltaV > 0)
{ {
GUILayout.Label(stage.thrust.ToForce(), this.infoStyle); GUILayout.Label(stage.thrust.ToForce(), this.infoStyle);
} }
} }
GUILayout.EndVertical(); GUILayout.EndVertical();
} }
   
/// <summary> /// <summary>
/// Draws the torque column. /// Draws the torque column.
/// </summary> /// </summary>
private void DrawTorque() private void DrawTorque()
{ {
GUILayout.BeginVertical(GUILayout.Width(75.0f * GuiDisplaySize.Offset)); GUILayout.BeginVertical(GUILayout.Width(75.0f * GuiDisplaySize.Offset));
GUILayout.Label("TORQUE", this.titleStyle); GUILayout.Label("TORQUE", this.titleStyle);
foreach (var stage in this.stages) foreach (var stage in this.stages)
{ {
if (this.showAllStages || stage.deltaV > 0) if (this.showAllStages || stage.deltaV > 0)
{ {
GUILayout.Label(stage.maxThrustTorque.ToTorque(), this.infoStyle); GUILayout.Label(stage.maxThrustTorque.ToTorque(), this.infoStyle);
} }
} }
GUILayout.EndVertical(); GUILayout.EndVertical();
} }
   
/// <summary> /// <summary>
/// Drwas the thrust to weight ratio column. /// Drwas the thrust to weight ratio column.
/// </summary> /// </summary>
private void DrawTwr() private void DrawTwr()
{ {
GUILayout.BeginVertical(GUILayout.Width(100.0f * GuiDisplaySize.Offset)); GUILayout.BeginVertical(GUILayout.Width(100.0f * GuiDisplaySize.Offset));
GUILayout.Label("TWR (MAX)", this.titleStyle); GUILayout.Label("TWR (MAX)", this.titleStyle);
foreach (var stage in this.stages) foreach (var stage in this.stages)
{ {
if (this.showAllStages || stage.deltaV > 0) if (this.showAllStages || stage.deltaV > 0)
{ {
GUILayout.Label(stage.thrustToWeight.ToString("F2") + " (" + stage.maxThrustToWeight.ToString("F2") + ")", this.infoStyle); GUILayout.Label(stage.thrustToWeight.ToString("F2") + " (" + stage.maxThrustToWeight.ToString("F2") + ")", this.infoStyle);
} }
} }
GUILayout.EndVertical(); GUILayout.EndVertical();
} }
   
private void EditorLock(bool state) private void EditorLock(bool state)
{ {
if (state) if (state)
{ {
EditorLogic.fetch.Lock(true, true, true, "KER_BuildAdvanced"); EditorLogic.fetch.Lock(true, true, true, "KER_BuildAdvanced");
BuildOverlayPartInfo.Hidden = true; BuildOverlayPartInfo.Hidden = true;
this.isEditorLocked = true; this.isEditorLocked = true;
} }
else else
{ {
EditorLogic.fetch.Unlock("KER_BuildAdvanced"); EditorLogic.fetch.Unlock("KER_BuildAdvanced");
BuildOverlayPartInfo.Hidden = false; BuildOverlayPartInfo.Hidden = false;
this.isEditorLocked = false; this.isEditorLocked = false;
} }
} }
   
private void GetStageInfo() private void GetStageInfo()
{ {
this.stages = SimManager.Stages; this.stages = SimManager.Stages;
} }
   
/// <summary> /// <summary>
/// Initialises all the styles that are required. /// Initialises all the styles that are required.
/// </summary> /// </summary>
private void InitialiseStyles() private void InitialiseStyles()
{ {
this.windowStyle = new GUIStyle(HighLogic.Skin.window) this.windowStyle = new GUIStyle(HighLogic.Skin.window)
{ {
alignment = TextAnchor.UpperLeft alignment = TextAnchor.UpperLeft
}; };
   
this.areaStyle = new GUIStyle(HighLogic.Skin.box) this.areaStyle = new GUIStyle(HighLogic.Skin.box)
{ {
padding = new RectOffset(0, 0, 9, 0) padding = new RectOffset(0, 0, 9, 0)
}; };
   
this.areaSettingStyle = new GUIStyle(HighLogic.Skin.box) this.areaSettingStyle = new GUIStyle(HighLogic.Skin.box)
{ {
padding = new RectOffset(10, 10, 10, 10) padding = new RectOffset(10, 10, 10, 10)
}; };
   
this.buttonStyle = new GUIStyle(HighLogic.Skin.button) this.buttonStyle = new GUIStyle(HighLogic.Skin.button)
{ {
normal = normal =
{ {
textColor = Color.white textColor = Color.white
}, },
fontSize = (int)(11 * GuiDisplaySize.Offset), fontSize = (int)(11 * GuiDisplaySize.Offset),
fontStyle = FontStyle.Bold, fontStyle = FontStyle.Bold,
alignment = TextAnchor.MiddleCenter alignment = TextAnchor.MiddleCenter
}; };
   
this.titleStyle = new GUIStyle(HighLogic.Skin.label) this.titleStyle = new GUIStyle(HighLogic.Skin.label)
{ {
normal = normal =
{ {
textColor = Color.white textColor = Color.white
}, },
fontSize = (int)(11 * GuiDisplaySize.Offset), fontSize = (int)(11 * GuiDisplaySize.Offset),
fontStyle = FontStyle.Bold, fontStyle = FontStyle.Bold,
alignment = TextAnchor.MiddleCenter, alignment = TextAnchor.MiddleCenter,
stretchWidth = true, stretchWidth = true,
}; };
   
this.infoStyle = new GUIStyle(HighLogic.Skin.label) this.infoStyle = new GUIStyle(HighLogic.Skin.label)
{ {
fontSize = (int)(11 * GuiDisplaySize.Offset), fontSize = (int)(11 * GuiDisplaySize.Offset),
fontStyle = FontStyle.Bold, fontStyle = FontStyle.Bold,
alignment = TextAnchor.MiddleCenter, alignment = TextAnchor.MiddleCenter,
stretchWidth = true stretchWidth = true
}; };
   
this.settingStyle = new GUIStyle(this.titleStyle) this.settingStyle = new GUIStyle(this.titleStyle)
{ {
alignment = TextAnchor.MiddleLeft, alignment = TextAnchor.MiddleLeft,
stretchWidth = true, stretchWidth = true,
stretchHeight = true stretchHeight = true
}; };
   
this.settingAtmoStyle = new GUIStyle(this.titleStyle) this.settingAtmoStyle = new GUIStyle(this.titleStyle)
{ {
margin = new RectOffset(), margin = new RectOffset(),
padding = new RectOffset(), padding = new RectOffset(),
alignment = TextAnchor.UpperLeft alignment = TextAnchor.UpperLeft
}; };
   
this.bodiesButtonStyle = new GUIStyle(HighLogic.Skin.button) this.bodiesButtonStyle = new GUIStyle(HighLogic.Skin.button)
{ {
margin = new RectOffset(0, 0, 2, 0), margin = new RectOffset(0, 0, 2, 0),
padding = new RectOffset(5, 5, 5, 5), padding = new RectOffset(5, 5, 5, 5),
normal = normal =
{ {
textColor = Color.white textColor = Color.white
}, },
active = active =
{ {
textColor = Color.white textColor = Color.white
}, },
fontSize = (int)(11 * GuiDisplaySize.Offset), fontSize = (int)(11 * GuiDisplaySize.Offset),
fontStyle = FontStyle.Bold, fontStyle = FontStyle.Bold,
alignment = TextAnchor.MiddleCenter, alignment = TextAnchor.MiddleCenter,
fixedHeight = 20.0f fixedHeight = 20.0f
}; };
   
this.bodiesButtonActiveStyle = new GUIStyle(this.bodiesButtonStyle) this.bodiesButtonActiveStyle = new GUIStyle(this.bodiesButtonStyle)
{ {
normal = this.bodiesButtonStyle.onNormal, normal = this.bodiesButtonStyle.onNormal,
hover = this.bodiesButtonStyle.onHover hover = this.bodiesButtonStyle.onHover
}; };
} }
   
/// <summary> /// <summary>
/// Loads the settings when this object is created. /// Loads the settings when this object is created.
/// </summary> /// </summary>
private void Load() private void Load()
{ {
try try
{ {
var handler = SettingHandler.Load("BuildAdvanced.xml"); var handler = SettingHandler.Load("BuildAdvanced.xml");
handler.Get("visible", ref this.visible); handler.Get("visible", ref this.visible);
this.position.x = handler.Get("windowPositionX", this.position.x); this.position.x = handler.Get("windowPositionX", this.position.x);
this.position.y = handler.Get("windowPositionY", this.position.y); this.position.y = handler.Get("windowPositionY", this.position.y);
handler.Get("compactMode", ref this.compactMode); handler.Get("compactMode", ref this.compactMode);
handler.Get("compactCollapseRight", ref this.compactCollapseRight); handler.Get("compactCollapseRight", ref this.compactCollapseRight);
handler.Get("showAllStages", ref this.showAllStages); handler.Get("showAllStages", ref this.showAllStages);
handler.Get("showAtmosphericDetails", ref this.showAtmosphericDetails); handler.Get("showAtmosphericDetails", ref this.showAtmosphericDetails);
handler.Get("showSettings", ref this.showSettings); handler.Get("showSettings", ref this.showSettings);
CelestialBodies.SetSelectedBody(handler.Get("selectedBodyName", CelestialBodies.SelectedBody.Name)); CelestialBodies.SetSelectedBody(handler.Get("selectedBodyName", CelestialBodies.SelectedBody.Name));
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex, "BuildAdvanced->Load"); Logger.Exception(ex, "BuildAdvanced->Load");
} }
} }
   
private void OnSizeChanged() private void OnSizeChanged()
{ {
this.InitialiseStyles(); this.InitialiseStyles();
this.hasChanged = true; this.hasChanged = true;
} }
   
/// <summary> /// <summary>
/// Draws the OnGUI window. /// Draws the OnGUI window.
/// </summary> /// </summary>
private void Window(int windowId) private void Window(int windowId)
{ {
try try
{ {
// Draw the compact mode toggle. // Draw the compact mode toggle.
if (GUI.Toggle(new Rect(this.position.width - 70.0f * GuiDisplaySize.Offset, 5.0f, 65.0f * GuiDisplaySize.Offset, 20.0f), this.compactMode, "COMPACT", this.buttonStyle) != this.compactMode) if (GUI.Toggle(new Rect(this.position.width - 70.0f * GuiDisplaySize.Offset, 5.0f, 65.0f * GuiDisplaySize.Offset, 20.0f), this.compactMode, "COMPACT", this.buttonStyle) != this.compactMode)
{ {
this.hasChanged = true; this.hasChanged = true;
this.compactCheck = 2; this.compactCheck = 2;
this.compactRight = this.position.xMax; this.compactRight = this.position.xMax;
this.compactMode = !this.compactMode; this.compactMode = !this.compactMode;
} }
   
// When not in compact mode draw the 'All Stages' and 'Atmospheric' toggles. // When not in compact mode draw the 'All Stages' and 'Atmospheric' toggles.
if (!this.compactMode) if (!this.compactMode)
{ {
if (GUI.Toggle(new Rect(this.position.width - 143.0f * GuiDisplaySize.Offset, 5.0f, 70.0f * GuiDisplaySize.Offset, 20.0f), this.showSettings, "SETTINGS", this.buttonStyle) != this.showSettings) if (GUI.Toggle(new Rect(this.position.width - 143.0f * GuiDisplaySize.Offset, 5.0f, 70.0f * GuiDisplaySize.Offset, 20.0f), this.showSettings, "SETTINGS", this.buttonStyle) != this.showSettings)
{ {
this.hasChanged = true; this.hasChanged = true;
this.showSettings = !this.showSettings; this.showSettings = !this.showSettings;
} }
   
if (GUI.Toggle(new Rect(this.position.width - 226.0f * GuiDisplaySize.Offset, 5.0f, 80.0f * GuiDisplaySize.Offset, 20.0f), this.showAllStages, "ALL STAGES", this.buttonStyle) != this.showAllStages) if (GUI.Toggle(new Rect(this.position.width - 226.0f * GuiDisplaySize.Offset, 5.0f, 80.0f * GuiDisplaySize.Offset, 20.0f), this.showAllStages, "ALL STAGES", this.buttonStyle) != this.showAllStages)
{ {
this.hasChanged = true; this.hasChanged = true;
this.showAllStages = !this.showAllStages; this.showAllStages = !this.showAllStages;
} }
   
if (GUI.Toggle(new Rect(this.position.width - 324.0f * GuiDisplaySize.Offset, 5.0f, 95.0f * GuiDisplaySize.Offset, 20.0f), this.showAtmosphericDetails, "ATMOSPHERIC", this.buttonStyle) != this.showAtmosphericDetails) if (GUI.Toggle(new Rect(this.position.width - 324.0f * GuiDisplaySize.Offset, 5.0f, 95.0f * GuiDisplaySize.Offset, 20.0f), this.showAtmosphericDetails, "ATMOSPHERIC", this.buttonStyle) != this.showAtmosphericDetails)
{ {
this.hasChanged = true; this.hasChanged = true;
this.showAtmosphericDetails = !this.showAtmosphericDetails; this.showAtmosphericDetails = !this.showAtmosphericDetails;
} }
   
this.bodiesListPosition = new Rect(this.position.width - 452.0f * GuiDisplaySize.Offset, 5.0f, 125.0f * GuiDisplaySize.Offset, 20.0f); this.bodiesListPosition = new Rect(this.position.width - 452.0f * GuiDisplaySize.Offset, 5.0f, 125.0f * GuiDisplaySize.Offset, 20.0f);
this.bodiesList.enabled = GUI.Toggle(this.bodiesListPosition, this.bodiesList.enabled, "BODY: " + CelestialBodies.SelectedBody.Name.ToUpper(), this.buttonStyle); this.bodiesList.enabled = GUI.Toggle(this.bodiesListPosition, this.bodiesList.enabled, "BODY: " + CelestialBodies.SelectedBody.Name.ToUpper(), this.buttonStyle);
this.bodiesList.SetPosition(this.bodiesListPosition.Translate(this.position)); this.bodiesList.SetPosition(this.bodiesListPosition.Translate(this.position));
} }
   
// Draw the main informational display box. // Draw the main informational display box.
if (!this.compactMode) if (!this.compactMode)
{ {
GUILayout.BeginHorizontal(this.areaStyle); GUILayout.BeginHorizontal(this.areaStyle);
this.DrawStageNumbers(); this.DrawStageNumbers();
this.DrawPartCount(); this.DrawPartCount();
this.DrawCost(); this.DrawCost();
this.DrawMass(); this.DrawMass();
this.DrawIsp(); this.DrawIsp();
this.DrawThrust(); this.DrawThrust();
this.DrawTorque(); this.DrawTorque();
this.DrawTwr(); this.DrawTwr();
this.DrawDeltaV(); this.DrawDeltaV();
this.DrawBurnTime(); this.DrawBurnTime();
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
if (this.showAtmosphericDetails) if (this.showAtmosphericDetails)
{ {
GUILayout.BeginVertical(this.areaSettingStyle); GUILayout.BeginVertical(this.areaSettingStyle);
this.DrawAtmosphericDetails(); this.DrawAtmosphericDetails();
GUILayout.EndVertical(); GUILayout.EndVertical();
} }
   
if (this.showSettings) if (this.showSettings)
{ {
GUILayout.BeginVertical(this.areaSettingStyle); GUILayout.BeginVertical(this.areaSettingStyle);
this.DrawSettings(); this.DrawSettings();
GUILayout.EndVertical(); GUILayout.EndVertical();
} }
} }
else // Draw only a few details when in compact mode. else // Draw only a few details when in compact mode.
{ {
GUILayout.BeginHorizontal(this.areaStyle); GUILayout.BeginHorizontal(this.areaStyle);
this.DrawStageNumbers(); this.DrawStageNumbers();
this.DrawTwr(); this.DrawTwr();
this.DrawDeltaV(); this.DrawDeltaV();
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
   
GUI.DragWindow(); GUI.DragWindow();
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
   
#endregion #endregion
} }
} }
// //
// Kerbal Engineer Redux // Kerbal Engineer Redux
// //
// Copyright (C) 2014 CYBUTEK // Copyright (C) 2014 CYBUTEK
// //
// 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/>.
// //
   
#region Using Directives #region Using Directives
   
#endregion #endregion
   
namespace KerbalEngineer.Flight namespace KerbalEngineer.Flight
{ {
#region Using Directives #region Using Directives
   
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Extensions; using Extensions;
using Readouts; using Readouts;
using Sections; using Sections;
using Settings; using Settings;
using UnityEngine; using UnityEngine;
  using VesselSimulator;
   
#endregion #endregion
   
/// <summary> /// <summary>
/// Core management system for the Flight Engineer. /// Core management system for the Flight Engineer.
/// </summary> /// </summary>
[KSPAddon(KSPAddon.Startup.Flight, false)] [KSPAddon(KSPAddon.Startup.Flight, false)]
public sealed class FlightEngineerCore : MonoBehaviour public sealed class FlightEngineerCore : MonoBehaviour
{ {
#region Instance #region Instance
   
/// <summary> /// <summary>
/// Gets the current instance of FlightEngineerCore. /// Gets the current instance of FlightEngineerCore.
/// </summary> /// </summary>
public static FlightEngineerCore Instance { get; private set; } public static FlightEngineerCore Instance { get; private set; }
   
#endregion #endregion
   
#region Fields #region Fields
   
private static bool isCareerMode = true; private static bool isCareerMode = true;
private static bool isKerbalLimited = true; private static bool isKerbalLimited = true;
private static bool isTrackingStationLimited = true; private static bool isTrackingStationLimited = true;
   
#endregion #endregion
   
#region Constructors #region Constructors
   
static FlightEngineerCore() static FlightEngineerCore()
{ {
try try
{ {
var handler = SettingHandler.Load("FlightEngineerCore.xml"); var handler = SettingHandler.Load("FlightEngineerCore.xml");
handler.Get("isCareerMode", ref isCareerMode); handler.Get("isCareerMode", ref isCareerMode);
handler.Get("isKerbalLimited", ref isKerbalLimited); handler.Get("isKerbalLimited", ref isKerbalLimited);
handler.Get("isTrackingStationLimited", ref isTrackingStationLimited); handler.Get("isTrackingStationLimited", ref isTrackingStationLimited);
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
   
#endregion #endregion
   
#region Properties #region Properties
   
/// <summary> /// <summary>
/// Gets and sets whether to the Flight Engineer should be run using career limitations. /// Gets and sets whether to the Flight Engineer should be run using career limitations.
/// </summary> /// </summary>
public static bool IsCareerMode public static bool IsCareerMode
{ {
get { return isCareerMode; } get { return isCareerMode; }
set set
{ {
try try
{ {
if (isCareerMode != value) if (isCareerMode != value)
{ {
var handler = SettingHandler.Load("FlightEngineerCore.xml"); var handler = SettingHandler.Load("FlightEngineerCore.xml");
handler.Set("isCareerMode", value); handler.Set("isCareerMode", value);
handler.Save("FlightEngineerCore.xml"); handler.Save("FlightEngineerCore.xml");
} }
isCareerMode = value; isCareerMode = value;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
} }
   
/// <summary> /// <summary>
/// Gets whether the FlightEngineer should be displayed. /// Gets whether the FlightEngineer should be displayed.
/// </summary> /// </summary>
public static bool IsDisplayable public static bool IsDisplayable
{ {
get get
{ {
if (isCareerMode) if (isCareerMode)
{ {
if (isKerbalLimited && FlightGlobals.ActiveVessel.GetVesselCrew().Exists(c => c.experienceTrait.TypeName == "Engineer")) if (isKerbalLimited && FlightGlobals.ActiveVessel.GetVesselCrew().Exists(c => c.experienceTrait.TypeName == "Engineer"))
{ {
return true; return true;
} }
if (isTrackingStationLimited && ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.TrackingStation) == 1.0f) if (isTrackingStationLimited && ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.TrackingStation) == 1.0f)
{ {
return true; return true;
} }
return FlightGlobals.ActiveVessel.parts.Any(p => p.HasModule<FlightEngineerModule>()); return FlightGlobals.ActiveVessel.parts.Any(p => p.HasModule<FlightEngineerModule>());
} }
   
return true; return true;
} }
} }
   
/// <summary> /// <summary>
/// Gets and sets whether to the Flight Engineer should be kerbal limited. /// Gets and sets whether to the Flight Engineer should be kerbal limited.
/// </summary> /// </summary>
public static bool IsKerbalLimited public static bool IsKerbalLimited
{ {
get { return isKerbalLimited; } get { return isKerbalLimited; }
set set
{ {
try try
{ {
if (isKerbalLimited != value) if (isKerbalLimited != value)
{ {
var handler = SettingHandler.Load("FlightEngineerCore.xml"); var handler = SettingHandler.Load("FlightEngineerCore.xml");
handler.Set("isKerbalLimited", value); handler.Set("isKerbalLimited", value);
handler.Save("FlightEngineerCore.xml"); handler.Save("FlightEngineerCore.xml");
} }
isKerbalLimited = value; isKerbalLimited = value;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
} }
   
/// <summary> /// <summary>
/// Gets and sets whether to the Flight Engineer should be tracking station limited. /// Gets and sets whether to the Flight Engineer should be tracking station limited.
/// </summary> /// </summary>
public static bool IsTrackingStationLimited public static bool IsTrackingStationLimited
{ {
get { return isTrackingStationLimited; } get { return isTrackingStationLimited; }
set set
{ {
try try
{ {
if (isTrackingStationLimited != value) if (isTrackingStationLimited != value)
{ {
var handler = SettingHandler.Load("FlightEngineerCore.xml"); var handler = SettingHandler.Load("FlightEngineerCore.xml");
handler.Set("isTrackingStationLimited", value); handler.Set("isTrackingStationLimited", value);
handler.Save("FlightEngineerCore.xml"); handler.Save("FlightEngineerCore.xml");
} }
isTrackingStationLimited = value; isTrackingStationLimited = value;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
} }
   
/// <summary> /// <summary>
/// Gets the editor windows for sections with open editors. /// Gets the editor windows for sections with open editors.
/// </summary> /// </summary>
public List<SectionEditor> SectionEditors { get; private set; } public List<SectionEditor> SectionEditors { get; private set; }
   
/// <summary> /// <summary>
/// Gets the section windows for floating sections. /// Gets the section windows for floating sections.
/// </summary> /// </summary>
public List<SectionWindow> SectionWindows { get; private set; } public List<SectionWindow> SectionWindows { get; private set; }
   
/// <summary> /// <summary>
/// Gets the list of currently running updatable modules. /// Gets the list of currently running updatable modules.
/// </summary> /// </summary>
public List<IUpdatable> UpdatableModules { get; private set; } public List<IUpdatable> UpdatableModules { get; private set; }
   
#endregion #endregion
   
#region Methods #region Methods
   
/// <summary> /// <summary>
/// Creates a section editor, adds it to the FlightEngineerCore and returns a reference to it. /// Creates a section editor, adds it to the FlightEngineerCore and returns a reference to it.
/// </summary> /// </summary>
public SectionEditor AddSectionEditor(SectionModule section) public SectionEditor AddSectionEditor(SectionModule section)
{ {
try try
{ {
var editor = this.gameObject.AddComponent<SectionEditor>(); var editor = this.gameObject.AddComponent<SectionEditor>();
editor.ParentSection = section; editor.ParentSection = section;
editor.Position = new Rect(section.EditorPositionX, section.EditorPositionY, SectionEditor.Width, SectionEditor.Height); editor.Position = new Rect(section.EditorPositionX, section.EditorPositionY, SectionEditor.Width, SectionEditor.Height);
this.SectionEditors.Add(editor); this.SectionEditors.Add(editor);
return editor; return editor;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
return null; return null;
} }
} }
   
/// <summary> /// <summary>
/// Creates a section window, adds it to the FlightEngineerCore and returns a reference to it. /// Creates a section window, adds it to the FlightEngineerCore and returns a reference to it.
/// </summary> /// </summary>
public SectionWindow AddSectionWindow(SectionModule section) public SectionWindow AddSectionWindow(SectionModule section)
{ {
try try
{ {
var window = this.gameObject.AddComponent<SectionWindow>(); var window = this.gameObject.AddComponent<SectionWindow>();
window.ParentSection = section; window.ParentSection = section;
window.WindowPosition = new Rect(section.FloatingPositionX, section.FloatingPositionY, 0, 0); window.WindowPosition = new Rect(section.FloatingPositionX, section.FloatingPositionY, 0, 0);
this.SectionWindows.Add(window); this.SectionWindows.Add(window);
return window; return window;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
return null; return null;
} }
} }
   
/// <summary> /// <summary>
/// Adds an updatable object to be automatically updated every frame and will ignore duplicate objects. /// Adds an updatable object to be automatically updated every frame and will ignore duplicate objects.
/// </summary> /// </summary>
public void AddUpdatable(IUpdatable updatable) public void AddUpdatable(IUpdatable updatable)
{ {
try try
{ {
if (!this.UpdatableModules.Contains(updatable)) if (!this.UpdatableModules.Contains(updatable))
{ {
this.UpdatableModules.Add(updatable); this.UpdatableModules.Add(updatable);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
   
/// <summary> /// <summary>
/// Create base Flight Engineer child objects. /// Create base Flight Engineer child objects.
/// </summary> /// </summary>
private void Awake() private void Awake()
{ {
try try
{ {
Instance = this; Instance = this;
   
this.SectionWindows = new List<SectionWindow>(); this.SectionWindows = new List<SectionWindow>();
this.SectionEditors = new List<SectionEditor>(); this.SectionEditors = new List<SectionEditor>();
this.UpdatableModules = new List<IUpdatable>(); this.UpdatableModules = new List<IUpdatable>();
   
  SimManager.UpdateModSettings();
   
Logger.Log("FlightEngineerCore->Awake"); Logger.Log("FlightEngineerCore->Awake");
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
   
/// <summary> /// <summary>
/// Fixed update all required Flight Engineer objects. /// Fixed update all required Flight Engineer objects.
/// </summary> /// </summary>
private void FixedUpdate() private void FixedUpdate()
{ {
try try
{ {
SectionLibrary.FixedUpdate(); SectionLibrary.FixedUpdate();
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
   
/// <summary> /// <summary>
/// Force the destruction of child objects on core destruction. /// Force the destruction of child objects on core destruction.
/// </summary> /// </summary>
private void OnDestroy() private void OnDestroy()
{ {
try try
{ {
SectionLibrary.Save(); SectionLibrary.Save();
   
foreach (var window in this.SectionWindows) foreach (var window in this.SectionWindows)
{ {
print("[FlightEngineer]: Destroying Floating Window for " + window.ParentSection.Name); print("[FlightEngineer]: Destroying Floating Window for " + window.ParentSection.Name);
Destroy(window); Destroy(window);
} }
   
foreach (var editor in this.SectionEditors) foreach (var editor in this.SectionEditors)
{ {
print("[FlightEngineer]: Destroying Editor Window for " + editor.ParentSection.Name); print("[FlightEngineer]: Destroying Editor Window for " + editor.ParentSection.Name);
Destroy(editor); Destroy(editor);
} }
   
Logger.Log("FlightEngineerCore->OnDestroy"); Logger.Log("FlightEngineerCore->OnDestroy");
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
   
/// <summary> /// <summary>
/// Initialises the object's state on creation. /// Initialises the object's state on creation.
/// </summary> /// </summary>
private void Start() private void Start()
{ {
try try
{ {
SectionLibrary.Load(); SectionLibrary.Load();
ReadoutLibrary.Reset(); ReadoutLibrary.Reset();
Logger.Log("FlightEngineerCore->Start"); Logger.Log("FlightEngineerCore->Start");
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
   
/// <summary> /// <summary>
/// Update all required Flight Engineer objects. /// Update all required Flight Engineer objects.
/// </summary> /// </summary>
private void Update() private void Update()
{ {
try try
{ {
SectionLibrary.Update(); SectionLibrary.Update();
this.UpdateModules(); this.UpdateModules();
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
   
/// <summary> /// <summary>
/// Update all updatable modules. /// Update all updatable modules.
/// </summary> /// </summary>
private void UpdateModules() private void UpdateModules()
{ {
try try
{ {
foreach (var updatable in this.UpdatableModules) foreach (var updatable in this.UpdatableModules)
{ {
if (updatable is IUpdateRequest) if (updatable is IUpdateRequest)
{ {
var request = updatable as IUpdateRequest; var request = updatable as IUpdateRequest;
if (request.UpdateRequested) if (request.UpdateRequested)
{ {
updatable.Update(); updatable.Update();
request.UpdateRequested = false; request.UpdateRequested = false;
} }
} }
else else
{ {
updatable.Update(); updatable.Update();
} }
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
   
#endregion #endregion
} }
} }
// //
// Kerbal Engineer Redux // Kerbal Engineer Redux
// //
// Copyright (C) 2014 CYBUTEK // Copyright (C) 2014 CYBUTEK
// //
// 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/>.
// //
   
namespace KerbalEngineer.VesselSimulator namespace KerbalEngineer.VesselSimulator
{ {
#region Using Directives #region Using Directives
   
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
using UnityEngine; using UnityEngine;
   
#endregion #endregion
   
public class SimManager public class SimManager
{ {
#region Constants #region Constants
   
public const double RESOURCE_MIN = 0.0001; public const double RESOURCE_MIN = 0.0001;
   
#endregion #endregion
   
#region Fields #region Fields
   
public static bool dumpTree = false; public static bool dumpTree = false;
public static bool logOutput = false; public static bool logOutput = false;
public static TimeSpan minSimTime = new TimeSpan(0, 0, 0, 0, 150); public static TimeSpan minSimTime = new TimeSpan(0, 0, 0, 0, 150);
public static bool vectoredThrust = false; public static bool vectoredThrust = false;
private static readonly object locker = new object(); private static readonly object locker = new object();
private static readonly Stopwatch timer = new Stopwatch(); private static readonly Stopwatch timer = new Stopwatch();
   
private static bool bRequested; private static bool bRequested;
private static bool bRunning; private static bool bRunning;
private static TimeSpan delayBetweenSims; private static TimeSpan delayBetweenSims;
   
// Support for RealFuels using reflection to check localCorrectThrust without dependency // Support for RealFuels using reflection to check localCorrectThrust without dependency
   
private static bool hasCheckedForMods; private static bool hasCheckedForMods;
private static bool hasInstalledRealFuels; private static bool hasInstalledRealFuels;
private static FieldInfo RF_ModuleEngineConfigs_localCorrectThrust; private static FieldInfo RF_ModuleEngineConfigs_localCorrectThrust;
private static FieldInfo RF_ModuleHybridEngine_localCorrectThrust; private static FieldInfo RF_ModuleHybridEngine_localCorrectThrust;
private static FieldInfo RF_ModuleHybridEngines_localCorrectThrust; private static FieldInfo RF_ModuleHybridEngines_localCorrectThrust;
private static bool hasInstalledKIDS; private static bool hasInstalledKIDS;
private static MethodInfo KIDS_Utils_GetIspMultiplier; private static MethodInfo KIDS_Utils_GetIspMultiplier;
private static bool bKIDSThrustISP = false; private static bool bKIDSThrustISP = false;
#endregion #endregion
   
#region Delegates #region Delegates
   
public delegate void ReadyEvent(); public delegate void ReadyEvent();
   
#endregion #endregion
   
#region Events #region Events
   
public static event ReadyEvent OnReady; public static event ReadyEvent OnReady;
   
#endregion #endregion
   
#region Properties #region Properties
   
public static double Atmosphere { get; set; } public static double Atmosphere { get; set; }
   
public static double Gravity { get; set; } public static double Gravity { get; set; }
   
public static Stage LastStage { get; private set; } public static Stage LastStage { get; private set; }
   
public static Stage[] Stages { get; private set; } public static Stage[] Stages { get; private set; }
   
public static double Velocity { get; set; } public static double Velocity { get; set; }
   
public static String failMessage { get; private set; } public static String failMessage { get; private set; }
   
#endregion #endregion
   
#region Methods #region Methods
   
private static void CheckForMods() private static void CheckForMods()
{ {
hasCheckedForMods = true; hasCheckedForMods = true;
   
foreach (var assembly in AssemblyLoader.loadedAssemblies) foreach (var assembly in AssemblyLoader.loadedAssemblies)
{ {
MonoBehaviour.print("Assembly:" + assembly.assembly); MonoBehaviour.print("Assembly:" + assembly.assembly);
   
var name = assembly.assembly.ToString().Split(',')[0]; var name = assembly.assembly.ToString().Split(',')[0];
   
if (name == "RealFuels") if (name == "RealFuels")
{ {
MonoBehaviour.print("Found RealFuels mod"); MonoBehaviour.print("Found RealFuels mod");
   
var RF_ModuleEngineConfigs_Type = assembly.assembly.GetType("RealFuels.ModuleEngineConfigs"); var RF_ModuleEngineConfigs_Type = assembly.assembly.GetType("RealFuels.ModuleEngineConfigs");
if (RF_ModuleEngineConfigs_Type != null) if (RF_ModuleEngineConfigs_Type != null)
{ {
RF_ModuleEngineConfigs_localCorrectThrust = RF_ModuleEngineConfigs_Type.GetField("localCorrectThrust"); RF_ModuleEngineConfigs_localCorrectThrust = RF_ModuleEngineConfigs_Type.GetField("localCorrectThrust");
} }
   
var RF_ModuleHybridEngine_Type = assembly.assembly.GetType("RealFuels.ModuleHybridEngine"); var RF_ModuleHybridEngine_Type = assembly.assembly.GetType("RealFuels.ModuleHybridEngine");
if (RF_ModuleHybridEngine_Type != null) if (RF_ModuleHybridEngine_Type != null)
{ {
RF_ModuleHybridEngine_localCorrectThrust = RF_ModuleHybridEngine_Type.GetField("localCorrectThrust"); RF_ModuleHybridEngine_localCorrectThrust = RF_ModuleHybridEngine_Type.GetField("localCorrectThrust");
} }
   
var RF_ModuleHybridEngines_Type = assembly.assembly.GetType("RealFuels.ModuleHybridEngines"); var RF_ModuleHybridEngines_Type = assembly.assembly.GetType("RealFuels.ModuleHybridEngines");
if (RF_ModuleHybridEngines_Type != null) if (RF_ModuleHybridEngines_Type != null)
{ {
RF_ModuleHybridEngines_localCorrectThrust = RF_ModuleHybridEngines_Type.GetField("localCorrectThrust"); RF_ModuleHybridEngines_localCorrectThrust = RF_ModuleHybridEngines_Type.GetField("localCorrectThrust");
} }
   
hasInstalledRealFuels = true; hasInstalledRealFuels = true;
break; break;
} }
else if (name == "KerbalIspDifficultyScaler") else if (name == "KerbalIspDifficultyScaler")
{ {
var KIDS_Utils_Type = assembly.assembly.GetType("KerbalIspDifficultyScaler.KerbalIspDifficultyScalerUtils"); var KIDS_Utils_Type = assembly.assembly.GetType("KerbalIspDifficultyScaler.KerbalIspDifficultyScalerUtils");
if (KIDS_Utils_Type != null) if (KIDS_Utils_Type != null)
{ {
KIDS_Utils_GetIspMultiplier = KIDS_Utils_Type.GetMethod("GetIspMultiplier"); KIDS_Utils_GetIspMultiplier = KIDS_Utils_Type.GetMethod("GetIspMultiplier");
} }
   
hasInstalledKIDS = true; hasInstalledKIDS = true;
} }
} }
} }
   
public static bool DoesEngineUseCorrectedThrust(Part theEngine) public static bool DoesEngineUseCorrectedThrust(Part theEngine)
{ {
if (hasInstalledRealFuels) if (hasInstalledRealFuels)
{ {
// Look for any of the Real Fuels engine modules and call the relevant method to find out // Look for any of the Real Fuels engine modules and call the relevant method to find out
if (RF_ModuleEngineConfigs_localCorrectThrust != null && theEngine.Modules.Contains("ModuleEngineConfigs")) if (RF_ModuleEngineConfigs_localCorrectThrust != null && theEngine.Modules.Contains("ModuleEngineConfigs"))
{ {
var modEngineConfigs = theEngine.Modules["ModuleEngineConfigs"]; var modEngineConfigs = theEngine.Modules["ModuleEngineConfigs"];
if (modEngineConfigs != null) if (modEngineConfigs != null)
{ {
// Return the localCorrectThrust // Return the localCorrectThrust
return (bool)RF_ModuleEngineConfigs_localCorrectThrust.GetValue(modEngineConfigs); return (bool)RF_ModuleEngineConfigs_localCorrectThrust.GetValue(modEngineConfigs);
} }
} }
   
if (RF_ModuleHybridEngine_localCorrectThrust != null && theEngine.Modules.Contains("ModuleHybridEngine")) if (RF_ModuleHybridEngine_localCorrectThrust != null && theEngine.Modules.Contains("ModuleHybridEngine"))
{ {
var modHybridEngine = theEngine.Modules["ModuleHybridEngine"]; var modHybridEngine = theEngine.Modules["ModuleHybridEngine"];
if (modHybridEngine != null) if (modHybridEngine != null)
{ {
// Return the localCorrectThrust // Return the localCorrectThrust
return (bool)RF_ModuleHybridEngine_localCorrectThrust.GetValue(modHybridEngine); return (bool)RF_ModuleHybridEngine_localCorrectThrust.GetValue(modHybridEngine);
} }
} }
   
if (RF_ModuleHybridEngines_localCorrectThrust != null && theEngine.Modules.Contains("ModuleHybridEngines")) if (RF_ModuleHybridEngines_localCorrectThrust != null && theEngine.Modules.Contains("ModuleHybridEngines"))
{ {
var modHybridEngines = theEngine.Modules["ModuleHybridEngines"]; var modHybridEngines = theEngine.Modules["ModuleHybridEngines"];
if (modHybridEngines != null) if (modHybridEngines != null)
{ {
// Return the localCorrectThrust // Return the localCorrectThrust
return (bool)RF_ModuleHybridEngines_localCorrectThrust.GetValue(modHybridEngines); return (bool)RF_ModuleHybridEngines_localCorrectThrust.GetValue(modHybridEngines);
} }
} }
} }
   
if (hasInstalledKIDS) if (hasInstalledKIDS && HighLogic.LoadedSceneIsEditor)
{ {
return bKIDSThrustISP; return bKIDSThrustISP;
} }
   
return false; return false;
} }
   
public static void UpdateModSettings() public static void UpdateModSettings()
{ {
if (!hasCheckedForMods) if (!hasCheckedForMods)
{ {
CheckForMods(); CheckForMods();
} }
   
if (hasInstalledKIDS) if (hasInstalledKIDS)
{ {
// (out ispMultiplierVac, out ispMultiplierAtm, out extendToZeroIsp, out thrustCorrection, out ispCutoff, out thrustCutoff); // (out ispMultiplierVac, out ispMultiplierAtm, out extendToZeroIsp, out thrustCorrection, out ispCutoff, out thrustCutoff);
object[] parameters = new object[6]; object[] parameters = new object[6];
KIDS_Utils_GetIspMultiplier.Invoke(null, parameters); KIDS_Utils_GetIspMultiplier.Invoke(null, parameters);
bKIDSThrustISP = (bool)parameters[3]; bKIDSThrustISP = (bool)parameters[3];
} }
} }
   
public static String GetVesselTypeString(VesselType vesselType) public static String GetVesselTypeString(VesselType vesselType)
{ {
switch (vesselType) switch (vesselType)
{ {
case VesselType.Debris: case VesselType.Debris:
return "Debris"; return "Debris";
case VesselType.SpaceObject: case VesselType.SpaceObject:
return "SpaceObject"; return "SpaceObject";
case VesselType.Unknown: case VesselType.Unknown:
return "Unknown"; return "Unknown";
case VesselType.Probe: case VesselType.Probe:
return "Probe"; return "Probe";
case VesselType.Rover: case VesselType.Rover:
return "Rover"; return "Rover";
case VesselType.Lander: case VesselType.Lander:
return "Lander"; return "Lander";
case VesselType.Ship: case VesselType.Ship:
return "Ship"; return "Ship";
case VesselType.Station: case VesselType.Station:
return "Station"; return "Station";
case VesselType.Base: case VesselType.Base:
return "Base"; return "Base";
case VesselType.EVA: case VesselType.EVA:
return "EVA"; return "EVA";
case VesselType.Flag: case VesselType.Flag:
return "Flag"; return "Flag";
} }
return "Undefined"; return "Undefined";
} }
   
public static void RequestSimulation() public static void RequestSimulation()
{ {
if (!hasCheckedForMods) if (!hasCheckedForMods)
{ {
CheckForMods(); CheckForMods();
} }
   
lock (locker) lock (locker)
{ {
bRequested = true; bRequested = true;
if (!timer.IsRunning) if (!timer.IsRunning)
{ {
timer.Start(); timer.Start();
} }
} }
} }
   
public static bool ResultsReady() public static bool ResultsReady()
{ {
lock (locker) lock (locker)
{ {
return !bRunning; return !bRunning;
} }
} }
   
public static void TryStartSimulation() public static void TryStartSimulation()
{ {
lock (locker) lock (locker)
{ {
if (!bRequested || bRunning || (timer.Elapsed < delayBetweenSims && timer.Elapsed >= TimeSpan.Zero) || (!HighLogic.LoadedSceneIsEditor && FlightGlobals.ActiveVessel == null)) if (!bRequested || bRunning || (timer.Elapsed < delayBetweenSims && timer.Elapsed >= TimeSpan.Zero) || (!HighLogic.LoadedSceneIsEditor && FlightGlobals.ActiveVessel == null))
{ {
return; return;
} }
   
bRequested = false; bRequested = false;
timer.Reset(); timer.Reset();
} }
   
StartSimulation(); StartSimulation();
} }
   
private static void ClearResults() private static void ClearResults()
{ {
failMessage = ""; failMessage = "";
Stages = null; Stages = null;
LastStage = null; LastStage = null;
} }
   
private static void RunSimulation(object simObject) private static void RunSimulation(object simObject)
{ {
try try
{ {
Stages = (simObject as Simulation).RunSimulation(); Stages = (simObject as Simulation).RunSimulation();
if (Stages != null && Stages.Length > 0) if (Stages != null && Stages.Length > 0)
{ {
if (logOutput) if (logOutput)
{ {
foreach (var stage in Stages) foreach (var stage in Stages)
{ {
stage.Dump(); stage.Dump();
} }
} }
LastStage = Stages[Stages.Length - 1]; LastStage = Stages[Stages.Length - 1];
} }
} }
catch (Exception e) catch (Exception e)
{ {
MonoBehaviour.print("Exception in RunSimulation: " + e); MonoBehaviour.print("Exception in RunSimulation: " + e);
Logger.Exception(e); Logger.Exception(e);
Stages = null; Stages = null;
LastStage = null; LastStage = null;
failMessage = e.ToString(); failMessage = e.ToString();
} }
lock (locker) lock (locker)
{ {
timer.Stop(); timer.Stop();
#if TIMERS #if TIMERS
MonoBehaviour.print("Total simulation time: " + timer.ElapsedMilliseconds + "ms"); MonoBehaviour.print("Total simulation time: " + timer.ElapsedMilliseconds + "ms");
#else #else
if (logOutput) if (logOutput)
{ {
MonoBehaviour.print("Total simulation time: " + timer.ElapsedMilliseconds + "ms"); MonoBehaviour.print("Total simulation time: " + timer.ElapsedMilliseconds + "ms");
} }
#endif #endif
   
delayBetweenSims = minSimTime - timer.Elapsed; delayBetweenSims = minSimTime - timer.Elapsed;
if (delayBetweenSims < TimeSpan.Zero) if (delayBetweenSims < TimeSpan.Zero)
{ {
delayBetweenSims = TimeSpan.Zero; delayBetweenSims = TimeSpan.Zero;
} }
   
timer.Reset(); timer.Reset();
timer.Start(); timer.Start();
   
bRunning = false; bRunning = false;
if (OnReady != null) if (OnReady != null)
{ {
OnReady(); OnReady();
} }
} }
   
logOutput = false; logOutput = false;
} }
   
private static void StartSimulation() private static void StartSimulation()
{ {
try try
{ {
lock (locker) lock (locker)
{ {
bRunning = true; bRunning = true;
} }
   
ClearResults(); ClearResults();
   
lock (locker) lock (locker)
{ {
timer.Start(); timer.Start();
} }
   
var parts = HighLogic.LoadedSceneIsEditor ? EditorLogic.fetch.ship.parts : FlightGlobals.ActiveVessel.Parts; var parts = HighLogic.LoadedSceneIsEditor ? EditorLogic.fetch.ship.parts : FlightGlobals.ActiveVessel.Parts;
   
// Create the Simulation object in this thread // Create the Simulation object in this thread
var sim = new Simulation(); var sim = new Simulation();
   
// This call doesn't ever fail at the moment but we'll check and return a sensible error for display // This call doesn't ever fail at the moment but we'll check and return a sensible error for display
if (sim.PrepareSimulation(parts, Gravity, Atmosphere, Velocity, dumpTree, vectoredThrust)) if (sim.PrepareSimulation(parts, Gravity, Atmosphere, Velocity, dumpTree, vectoredThrust))
{ {
ThreadPool.QueueUserWorkItem(RunSimulation, sim); ThreadPool.QueueUserWorkItem(RunSimulation, sim);
} }
else else
{ {
failMessage = "PrepareSimulation failed"; failMessage = "PrepareSimulation failed";
lock (locker) lock (locker)
{ {
bRunning = false; bRunning = false;
} }
logOutput = false; logOutput = false;
} }
} }
catch (Exception e) catch (Exception e)
{ {
MonoBehaviour.print("Exception in StartSimulation: " + e); MonoBehaviour.print("Exception in StartSimulation: " + e);
Logger.Exception(e); Logger.Exception(e);
failMessage = e.ToString(); failMessage = e.ToString();
lock (locker) lock (locker)
{ {
bRunning = false; bRunning = false;
} }
logOutput = false; logOutput = false;
} }
dumpTree = false; dumpTree = false;
} }
   
#endregion #endregion
} }
} }