From: Andy Date: Thu, 24 Jul 2014 00:04:26 +0000 Subject: Throughout: Change in-module "_Active" references to "toggleActive" property. X-Git-Tag: 0.14 X-Git-Url: http://git.toad.homelinux.net/projects/VOID.git/commitdiff/b5e4d71 --- Throughout: Change in-module "_Active" references to "toggleActive" property. --- --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -39,7 +39,7 @@ // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". // The form "{Major}.{Minor}.*" will automatically update the build and revision, // and "{Major}.{Minor}.{Build}.*" will update just the revision. -[assembly: AssemblyVersion("0.11.0.*")] +[assembly: AssemblyVersion("0.13.*")] // The following attributes are used to specify the signing key for the assembly, // if desired. See the Mono documentation for more information about signing. //[assembly: AssemblyDelaySign(false)] --- a/VOID.csproj +++ b/VOID.csproj @@ -9,6 +9,7 @@ VOID VOID 65001 + False v3.5 AnyCPU 0.11 @@ -93,6 +94,9 @@ + + + --- a/VOID_CBInfoBrowser.cs +++ b/VOID_CBInfoBrowser.cs @@ -72,20 +72,20 @@ GUILayout.BeginVertical(GUILayout.Width(150)); - selectedBody1 = VOID_Core.Instance.allBodies[selectedBodyIdx1]; - selectedBody2 = VOID_Core.Instance.allBodies[selectedBodyIdx2]; + selectedBody1 = this.core.allBodies[selectedBodyIdx1]; + selectedBody2 = this.core.allBodies[selectedBodyIdx2]; GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); if (GUILayout.Button("<", GUILayout.ExpandWidth(false))) { selectedBodyIdx1--; - if (selectedBodyIdx1 < 0) selectedBodyIdx1 = VOID_Core.Instance.allBodies.Count - 1; - } - GUILayout.Label(VOID_Core.Instance.allBodies[selectedBodyIdx1].bodyName, VOID_Core.Instance.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); + if (selectedBodyIdx1 < 0) selectedBodyIdx1 = this.core.allBodies.Count - 1; + } + GUILayout.Label(this.core.allBodies[selectedBodyIdx1].bodyName, this.core.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); if (GUILayout.Button(">", GUILayout.ExpandWidth(false))) { selectedBodyIdx1++; - if (selectedBodyIdx1 > VOID_Core.Instance.allBodies.Count - 1) selectedBodyIdx1 = 0; + if (selectedBodyIdx1 > this.core.allBodies.Count - 1) selectedBodyIdx1 = 0; } GUILayout.EndHorizontal(); GUILayout.EndVertical(); @@ -95,13 +95,13 @@ if (GUILayout.Button("<", GUILayout.ExpandWidth(false))) { selectedBodyIdx2--; - if (selectedBodyIdx2 < 0) selectedBodyIdx2 = VOID_Core.Instance.allBodies.Count - 1; - } - GUILayout.Label(VOID_Core.Instance.allBodies[selectedBodyIdx2].bodyName, VOID_Core.Instance.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); + if (selectedBodyIdx2 < 0) selectedBodyIdx2 = this.core.allBodies.Count - 1; + } + GUILayout.Label(this.core.allBodies[selectedBodyIdx2].bodyName, this.core.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); if (GUILayout.Button(">", GUILayout.ExpandWidth(false))) { selectedBodyIdx2++; - if (selectedBodyIdx2 > VOID_Core.Instance.allBodies.Count - 1) selectedBodyIdx2 = 0; + if (selectedBodyIdx2 > this.core.allBodies.Count - 1) selectedBodyIdx2 = 0; } GUILayout.EndHorizontal(); GUILayout.EndVertical(); @@ -213,82 +213,82 @@ private void body_OP_show_orbital_info(CelestialBody body) { - if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - else GUILayout.Label((body.orbit.ApA / 1000).ToString("##,#") + "km", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - else GUILayout.Label(VOID_Tools.ConvertInterval(body.orbit.timeToAp), VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - else GUILayout.Label((body.orbit.PeA / 1000).ToString("##,#") + "km", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - else GUILayout.Label(VOID_Tools.ConvertInterval(body.orbit.timeToPe), VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - else GUILayout.Label((body.orbit.semiMajorAxis / 1000).ToString("##,#") + "km", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - else GUILayout.Label(body.orbit.eccentricity.ToString("F4") + "", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - else GUILayout.Label(VOID_Tools.ConvertInterval(body.orbit.period), VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - else GUILayout.Label(VOID_Tools.ConvertInterval(body.rotationPeriod), VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - else GUILayout.Label((body.orbit.orbitalSpeed / 1000).ToString("F2") + "km/s", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); + if (body.bodyName == "Sun") GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + else GUILayout.Label((body.orbit.ApA / 1000).ToString("##,#") + "km", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + if (body.bodyName == "Sun") GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + else GUILayout.Label(VOID_Tools.ConvertInterval(body.orbit.timeToAp), this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + if (body.bodyName == "Sun") GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + else GUILayout.Label((body.orbit.PeA / 1000).ToString("##,#") + "km", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + if (body.bodyName == "Sun") GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + else GUILayout.Label(VOID_Tools.ConvertInterval(body.orbit.timeToPe), this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + if (body.bodyName == "Sun") GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + else GUILayout.Label((body.orbit.semiMajorAxis / 1000).ToString("##,#") + "km", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + if (body.bodyName == "Sun") GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + else GUILayout.Label(body.orbit.eccentricity.ToString("F4") + "", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + if (body.bodyName == "Sun") GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + else GUILayout.Label(VOID_Tools.ConvertInterval(body.orbit.period), this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + if (body.bodyName == "Sun") GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + else GUILayout.Label(VOID_Tools.ConvertInterval(body.rotationPeriod), this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + if (body.bodyName == "Sun") GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + else GUILayout.Label((body.orbit.orbitalSpeed / 1000).ToString("F2") + "km/s", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); // Toadicus edit: convert mean anomaly into degrees. - if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - else GUILayout.Label((body.orbit.meanAnomaly * 180d / Math.PI).ToString("F3") + "°", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - else GUILayout.Label(body.orbit.trueAnomaly.ToString("F3") + "°", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); + if (body.bodyName == "Sun") GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + else GUILayout.Label((body.orbit.meanAnomaly * 180d / Math.PI).ToString("F3") + "°", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + if (body.bodyName == "Sun") GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + else GUILayout.Label(body.orbit.trueAnomaly.ToString("F3") + "°", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); // Toadicus edit: convert eccentric anomaly into degrees. - if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - else GUILayout.Label((body.orbit.eccentricAnomaly * 180d / Math.PI).ToString("F3") + "°", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - else GUILayout.Label(body.orbit.inclination.ToString("F3") + "°", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - else GUILayout.Label(body.orbit.LAN.ToString("F3") + "°", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - else GUILayout.Label(body.orbit.argumentOfPeriapsis.ToString("F3") + "°", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); + if (body.bodyName == "Sun") GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + else GUILayout.Label((body.orbit.eccentricAnomaly * 180d / Math.PI).ToString("F3") + "°", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + if (body.bodyName == "Sun") GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + else GUILayout.Label(body.orbit.inclination.ToString("F3") + "°", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + if (body.bodyName == "Sun") GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + else GUILayout.Label(body.orbit.LAN.ToString("F3") + "°", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + if (body.bodyName == "Sun") GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + else GUILayout.Label(body.orbit.argumentOfPeriapsis.ToString("F3") + "°", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + if (body.bodyName == "Sun") GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); else { string body_tidally_locked = "No"; if (body.tidallyLocked) body_tidally_locked = "Yes"; - GUILayout.Label(body_tidally_locked, VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); + GUILayout.Label(body_tidally_locked, this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); } } private void body_OP_show_physical_info(CelestialBody body) { - GUILayout.Label((body.Radius / 1000).ToString("##,#") + "km", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - GUILayout.Label(((Math.Pow((body.Radius), 2) * 4 * Math.PI) / 1000).ToString("0.00e+00") + "km²", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); + GUILayout.Label((body.Radius / 1000).ToString("##,#") + "km", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + GUILayout.Label((((body.Radius * body.Radius) * 4 * Math.PI) / 1000).ToString("0.00e+00") + "km²", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); // divide by 1000 to convert m to km - GUILayout.Label((((4d / 3) * Math.PI * Math.Pow(body.Radius, 3)) / 1000).ToString("0.00e+00") + "km³", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - GUILayout.Label(body.Mass.ToString("0.00e+00") + "kg", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - double p = body.Mass / (Math.Pow(body.Radius, 3) * (4d / 3) * Math.PI); - - GUILayout.Label(p.ToString("##,#") + "kg/m³", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - if (body.bodyName == "Sun") GUILayout.Label(Tools.MuMech_ToSI(body.sphereOfInfluence), VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - else GUILayout.Label(Tools.MuMech_ToSI(body.sphereOfInfluence), VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - GUILayout.Label(body.orbitingBodies.Count.ToString(), VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); + GUILayout.Label((((4d / 3) * Math.PI * (body.Radius * body.Radius * body.Radius)) / 1000).ToString("0.00e+00") + "km³", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + GUILayout.Label(body.Mass.ToString("0.00e+00") + "kg", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + double p = body.Mass / ((body.Radius * body.Radius * body.Radius) * (4d / 3) * Math.PI); + + GUILayout.Label(p.ToString("##,#") + "kg/m³", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + if (body.bodyName == "Sun") GUILayout.Label(Tools.MuMech_ToSI(body.sphereOfInfluence), this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + else GUILayout.Label(Tools.MuMech_ToSI(body.sphereOfInfluence), this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + GUILayout.Label(body.orbitingBodies.Count.ToString(), this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); //show # artificial satellites int num_art_sats = 0; @@ -297,31 +297,31 @@ if (v.mainBody == body && v.situation.ToString() == "ORBITING") num_art_sats++; } - GUILayout.Label(num_art_sats.ToString(), VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - - double g_ASL = (VOID_Core.Constant_G * body.Mass) / Math.Pow(body.Radius, 2); - - GUILayout.Label(Tools.MuMech_ToSI(g_ASL) + "m/s²", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); + GUILayout.Label(num_art_sats.ToString(), this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + + double g_ASL = (VOID_Core.Constant_G * body.Mass) / (body.Radius * body.Radius); + + GUILayout.Label(Tools.MuMech_ToSI(g_ASL) + "m/s²", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); if (body.atmosphere) { GUILayout.Label("≈ " + Tools.MuMech_ToSI(body.maxAtmosphereAltitude) + "m", - VOID_Core.Instance.LabelStyles["right"], + this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); string O2 = "No"; if (body.atmosphereContainsOxygen == true) O2 = "Yes"; - GUILayout.Label(O2, VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); + GUILayout.Label(O2, this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); } else { - GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); - GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); + GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); + GUILayout.Label("N/A", this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); } string ocean = "No"; if (body.ocean == true) ocean = "Yes"; - GUILayout.Label(ocean, VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true)); + GUILayout.Label(ocean, this.core.LabelStyles["right"], GUILayout.ExpandWidth(true)); } } } --- /dev/null +++ b/VOID_CareerStatus.cs @@ -1,1 +1,291 @@ - +// VOID +// +// VOID_CareerStatus.cs +// +// Copyright © 2014, toadicus +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +using KSP; +using System; +using System.Text; +using ToadicusTools; +using UnityEngine; + +namespace VOID +{ + public class VOID_CareerStatus : VOID_WindowModule + { + public static VOID_CareerStatus Instance + { + get; + private set; + } + + public static string formatDelta(double delta) + { + if (delta > 0) + { + return string.Format("{0:#,#.##}↑", delta); + } + else if (delta < 0) + { + return string.Format("{0:#,#.##}↓", delta); + } + else + { + return string.Intern("0"); + } + } + + public static string formatDelta(float delta) + { + return formatDelta((double)delta); + } + + private GUIContent fundsContent; + private GUIContent repContent; + private GUIContent scienceContent; + + private Texture2D fundsIconGreen; + private Texture2D fundsIconRed; + private Texture2D reputationIconGreen; + private Texture2D reputationIconRed; + private Texture2D scienceIcon; + + public override bool toggleActive + { + get + { + switch (HighLogic.CurrentGame.Mode) + { + case Game.Modes.CAREER: + case Game.Modes.SCIENCE_SANDBOX: + return base.toggleActive; + default: + return false; + } + } + set + { + switch (HighLogic.CurrentGame.Mode) + { + case Game.Modes.CAREER: + case Game.Modes.SCIENCE_SANDBOX: + base.toggleActive = value; + break; + default: + return; + } + } + } + + public double lastFundsChange + { + get; + private set; + } + + public float lastRepChange + { + get; + private set; + } + + public float lastScienceChange + { + get; + private set; + } + + public double currentFunds + { + get; + private set; + } + + public float currentReputation + { + get; + private set; + } + + public float currentScience + { + get; + private set; + } + + public override void ModuleWindow(int _) + { + GUILayout.BeginVertical(); + + GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); + GUILayout.Label(VOID_Data.fundingStatus.Label); + GUILayout.FlexibleSpace(); + this.fundsContent.text = VOID_Data.fundingStatus.Value; + GUILayout.Label(this.fundsContent, GUILayout.ExpandWidth(false)); + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); + GUILayout.Label(VOID_Data.reputationStatus.Label); + GUILayout.FlexibleSpace(); + this.repContent.text = VOID_Data.reputationStatus.Value; + GUILayout.Label(this.repContent, GUILayout.ExpandWidth(false)); + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); + GUILayout.Label(VOID_Data.scienceStatus.Label); + GUILayout.FlexibleSpace(); + this.scienceContent.text = VOID_Data.scienceStatus.Value; + GUILayout.Label(this.scienceContent, GUILayout.ExpandWidth(false)); + GUILayout.EndHorizontal(); + + GUILayout.EndVertical(); + + GUI.DragWindow(); + } + + private void onFundsChange(double newValue) + { + this.lastFundsChange = newValue - this.currentFunds; + this.currentFunds = newValue; + } + + private void onRepChange(float newValue) + { + this.lastRepChange = newValue - this.currentReputation; + this.currentReputation = newValue; + } + + private void onScienceChange(float newValue) + { + this.lastScienceChange = newValue - this.currentScience; + this.currentScience = newValue; + } + + /* + * MissionRecoveryDialog::fundsIconGreen.name: UiElements_05 + * MissionRecoveryDialog::fundsIconRed.name: UiElements_06 + * MissionRecoveryDialog::reputationIconGreen.name: UiElements_07 + * MissionRecoveryDialog::reputationIconRed.name: UiElements_08 + * MissionRecoveryDialog::scienceIcon.name: UiElements_12 + * */ + public VOID_CareerStatus() : base() + { + VOID_CareerStatus.Instance = this; + + this._Name = "Career Status"; + + GameEvents.OnFundsChanged.Add(this.onFundsChange); + GameEvents.OnReputationChanged.Add(this.onRepChange); + GameEvents.OnScienceChanged.Add(this.onScienceChange); + + bool texturesLoaded; + + texturesLoaded = IOTools.LoadTexture(out this.fundsIconGreen, "VOID/Textures/fundsgreen.png", 10, 18); + texturesLoaded &= IOTools.LoadTexture(out this.fundsIconRed, "VOID/Textures/fundsred.png", 10, 18); + texturesLoaded &= IOTools.LoadTexture(out this.reputationIconGreen, "VOID/Textures/repgreen.png", 16, 18); + texturesLoaded &= IOTools.LoadTexture(out this.reputationIconRed, "VOID/Textures/repred.png", 16, 18); + texturesLoaded &= IOTools.LoadTexture(out this.scienceIcon, "VOID/Textures/science.png", 16, 18); + + this.fundsContent = new GUIContent(); + this.repContent = new GUIContent(); + this.scienceContent = new GUIContent(); + + if (texturesLoaded) + { + this.fundsContent.image = this.fundsIconGreen; + this.repContent.image = this.reputationIconGreen; + this.scienceContent.image = this.scienceIcon; + } + + this.currentFunds = Funding.Instance != null ? Funding.Instance.Funds : double.NaN; + this.currentReputation = Reputation.Instance != null ? Reputation.Instance.reputation : float.NaN; + this.currentScience = ResearchAndDevelopment.Instance != null ? + ResearchAndDevelopment.Instance.Science : float.NaN; + } + + ~VOID_CareerStatus() + { + GameEvents.OnFundsChanged.Remove(this.onFundsChange); + GameEvents.OnReputationChanged.Remove(this.onRepChange); + GameEvents.OnScienceChanged.Remove(this.onScienceChange); + + VOID_CareerStatus.Instance = null; + } + } + + public static partial class VOID_Data + { + public static readonly VOID_StrValue fundingStatus = new VOID_StrValue( + string.Intern("Funds"), + delegate() + { + if (VOID_CareerStatus.Instance == null) + { + return string.Empty; + } + + return string.Format("{0} ({1})", + VOID_CareerStatus.Instance.currentFunds.ToString("#,#.##"), + VOID_CareerStatus.formatDelta(VOID_CareerStatus.Instance.lastFundsChange) + ); + } + ); + + public static readonly VOID_StrValue reputationStatus = new VOID_StrValue( + string.Intern("Reputation"), + delegate() + { + if (VOID_CareerStatus.Instance == null) + { + return string.Empty; + } + + return string.Format("{0} ({1})", + VOID_CareerStatus.Instance.currentReputation.ToString("#,#.##"), + VOID_CareerStatus.formatDelta(VOID_CareerStatus.Instance.lastRepChange) + ); + } + ); + + public static readonly VOID_StrValue scienceStatus = new VOID_StrValue( + string.Intern("Science"), + delegate() + { + if (VOID_CareerStatus.Instance == null) + { + return string.Empty; + } + + return string.Format("{0} ({1})", + VOID_CareerStatus.Instance.currentScience.ToString("#,#.##"), + VOID_CareerStatus.formatDelta(VOID_CareerStatus.Instance.lastScienceChange) + ); + } + ); + } +} + + --- a/VOID_Core.cs +++ b/VOID_Core.cs @@ -75,13 +75,13 @@ } #endregion - public static double Constant_G = 6.674e-11; + public static readonly double Constant_G = 6.674e-11; /* * Fields * */ protected string VoidName = "VOID"; - protected string VoidVersion = "0.11.0"; + protected string VoidVersion; protected bool _factoryReset = false; @@ -175,6 +175,8 @@ protected VOID_SaveValue _UseToolbarManager; internal IButton ToolbarButton; + internal ApplicationLauncherButton AppLauncherButton; + /* * Properties * */ @@ -333,6 +335,12 @@ } if (value == true) { + if (this.AppLauncherButton != null) + { + ApplicationLauncher.Instance.RemoveModApplication(this.AppLauncherButton); + this.AppLauncherButton = null; + } + this.InitializeToolbarButton(); } @@ -366,9 +374,9 @@ if (!this.UseToolbarManager) { - if (GUI.Button(VOIDIconPos, VOIDIconTexture, this.iconStyle) && this.VOIDIconLocked) - { - this.ToggleMainWindow(); + if (this.AppLauncherButton == null) + { + this.InitializeAppLauncherButton(); } } else if (this.ToolbarButton == null) @@ -384,7 +392,7 @@ _mainWindowPos = GUILayout.Window( this.windowID, _mainWindowPos, - this.VOIDMainWindow, + VOID_Tools.GetWindowHandler(this.VOIDMainWindow), string.Join(" ", new string[] { this.VoidName, this.VoidVersion }), GUILayout.Width(250), GUILayout.Height(50) @@ -405,7 +413,7 @@ _configWindowPos = GUILayout.Window( this.windowID, _configWindowPos, - this.VOIDConfigWindow, + VOID_Tools.GetWindowHandler(this.VOIDConfigWindow), string.Join(" ", new string[] { this.VoidName, "Configuration" }), GUILayout.Width(250), GUILayout.Height(50) @@ -480,8 +488,10 @@ if (this.vessel != null && this.vesselSimActive) { - SimManager.Gravity = VOID_Core.Instance.vessel.mainBody.gravParameter / - Math.Pow(VOID_Core.Instance.vessel.Radius(), 2); + double radius = this.vessel.Radius(); + SimManager.Gravity = this.vessel.mainBody.gravParameter / + (radius * radius); + SimManager.minSimTime = (long)(this.updatePeriod * 1000); SimManager.TryStartSimulation(); } else if (!this.vesselSimActive) @@ -899,6 +909,27 @@ }; 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, + HighLogic.LoadedScene.ToAppScenes(), + this.VOIDIconTexture + ); + + Tools.PostDebugMessage( + this, + "AppLauncherButton initialized in {0}", + Enum.GetName( + typeof(GameScenes), + HighLogic.LoadedScene + ) + ); + } } protected void ToggleMainWindow() @@ -935,7 +966,12 @@ this.ToolbarButton.TexturePath = texturePath; } - this.VOIDIconTexture = GameDatabase.Instance.GetTexture(texturePath, false); + this.VOIDIconTexture = GameDatabase.Instance.GetTexture(texturePath.Replace("icon", "appIcon"), false); + + if (this.AppLauncherButton != null) + { + this.AppLauncherButton.SetTexture(VOIDIconTexture); + } } protected void CheckAndSave() @@ -987,11 +1023,36 @@ this.configDirty = false; } + public void onSceneChangeRequested(GameScenes scene) + { + if (this.AppLauncherButton != null) + { + if (this is VOID_EditorCore) + { + if (!HighLogic.LoadedSceneIsEditor) + { + ApplicationLauncher.Instance.RemoveModApplication(this.AppLauncherButton); + } + } + else + { + if (!HighLogic.LoadedSceneIsFlight) + { + ApplicationLauncher.Instance.RemoveModApplication(this.AppLauncherButton); + } + } + } + } + protected VOID_Core() { this._Name = "VOID Core"; - this._Active.value = true; + 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; @@ -1025,7 +1086,14 @@ { get { - return VOID_Core.Instance; + if (HighLogic.LoadedSceneIsEditor) + { + return VOID_EditorCore.Instance; + } + else + { + return VOID_Core.Instance; + } } } --- a/VOID_DataLogger.cs +++ b/VOID_DataLogger.cs @@ -234,7 +234,7 @@ line += vessel.flightIntegrator.getExternalTemperature().ToString("F2") + ";"; //gravity double r_vessel = vessel.mainBody.Radius + vessel.mainBody.GetAltitude(vessel.findWorldCenterOfMass()); - double g_vessel = (VOID_Core.Constant_G * vessel.mainBody.Mass) / Math.Pow(r_vessel, 2); + double g_vessel = (VOID_Core.Constant_G * vessel.mainBody.Mass) / (r_vessel * r_vessel); line += g_vessel.ToString("F3") + ";"; //atm density line += (vessel.atmDensity * 1000).ToString("F3") + ";"; --- a/VOID_DataValue.cs +++ b/VOID_DataValue.cs @@ -70,6 +70,7 @@ get { if ( + HighLogic.LoadedSceneIsEditor || (VOID_Core.Instance.updateTimer - this.lastUpdate > VOID_Core.Instance.updatePeriod) || (this.lastUpdate > VOID_Core.Instance.updateTimer) ) @@ -103,7 +104,7 @@ return (T)this.cache; } - public string ValueUnitString() { + public virtual string ValueUnitString() { return this.Value.ToString() + this.Units; } @@ -145,7 +146,6 @@ { return v.ToSingle(); } - protected IFormatProvider formatProvider; @@ -325,6 +325,26 @@ { public VOID_StrValue(string Label, Func ValueFunc) : base(Label, ValueFunc, "") {} } + + public class VOID_Vector3dValue : VOID_DataValue + { + public VOID_Vector3dValue(string Label, Func ValueFunc, string Units) + : base(Label, ValueFunc, Units) + {} + + public string ToString(string format) + { + return string.Format("{0}: {1}{2}", + this.Label, + this.Value.ToString(format), + this.Units + ); + } + + public string ValueUnitString(string format) { + return this.Value.ToString(format) + this.Units; + } + } } --- a/VOID_EditorHUD.cs +++ b/VOID_EditorHUD.cs @@ -120,7 +120,7 @@ { this._Name = "Heads-Up Display"; - this._Active.value = true; + this.toggleActive = true; this.textColors.Add(Color.green); this.textColors.Add(Color.black); @@ -164,6 +164,8 @@ return; } + GUI.skin = this.core.Skin; + Rect hudPos = new Rect (hudLeft, 48, 300, 32); hudString = new StringBuilder(); --- a/VOID_HUD.cs +++ b/VOID_HUD.cs @@ -85,7 +85,7 @@ { this._Name = "Heads-Up Display"; - this._Active.value = true; + this.toggleActive = true; this._colorIndex = 0; @@ -118,9 +118,9 @@ leftHUD = new StringBuilder(); - VOID_Core.Instance.LabelStyles["hud"].alignment = TextAnchor.UpperRight; - - if (VOID_Core.Instance.powerAvailable) + this.core.LabelStyles["hud"].alignment = TextAnchor.UpperRight; + + if (this.core.powerAvailable) { leftHUD.AppendFormat("Primary: {0} Inc: {1}", VOID_Data.primaryName.ValueUnitString(), @@ -145,11 +145,11 @@ } else { - VOID_Core.Instance.LabelStyles["hud"].normal.textColor = Color.red; + this.core.LabelStyles["hud"].normal.textColor = Color.red; leftHUD.Append(string.Intern("-- POWER LOST --")); } - GUILayout.Label(leftHUD.ToString(), VOID_Core.Instance.LabelStyles["hud"], GUILayout.ExpandWidth(true)); + GUILayout.Label(leftHUD.ToString(), this.core.LabelStyles["hud"], GUILayout.ExpandWidth(true)); if (!this.positionsLocked) { @@ -165,9 +165,9 @@ rightHUD = new StringBuilder(); - VOID_Core.Instance.LabelStyles["hud"].alignment = TextAnchor.UpperLeft; - - if (VOID_Core.Instance.powerAvailable) + this.core.LabelStyles["hud"].alignment = TextAnchor.UpperLeft; + + if (this.core.powerAvailable) { rightHUD.AppendFormat("Biome: {0} Sit: {1}", VOID_Data.currBiome.ValueUnitString(), @@ -192,12 +192,12 @@ } else { - VOID_Core.Instance.LabelStyles["hud"].normal.textColor = Color.red; + this.core.LabelStyles["hud"].normal.textColor = Color.red; rightHUD.Append(string.Intern("-- POWER LOST --")); } - GUILayout.Label(rightHUD.ToString(), VOID_Core.Instance.LabelStyles["hud"], GUILayout.ExpandWidth(true)); + GUILayout.Label(rightHUD.ToString(), this.core.LabelStyles["hud"], GUILayout.ExpandWidth(true)); if (!this.positionsLocked) { @@ -209,12 +209,14 @@ public override void DrawGUI() { - if (!VOID_Core.Instance.LabelStyles.ContainsKey("hud")) - { - VOID_Core.Instance.LabelStyles["hud"] = new GUIStyle(GUI.skin.label); - } - - VOID_Core.Instance.LabelStyles["hud"].normal.textColor = textColors [ColorIndex]; + if (!this.core.LabelStyles.ContainsKey("hud")) + { + this.core.LabelStyles["hud"] = new GUIStyle(GUI.skin.label); + } + + this.core.LabelStyles["hud"].normal.textColor = textColors [ColorIndex]; + + GUI.skin = this.core.Skin; if ((TimeWarp.WarpMode == TimeWarp.Modes.LOW) || (TimeWarp.CurrentRate <= TimeWarp.MaxPhysicsRate)) { @@ -222,7 +224,7 @@ } this.leftHUDPos.value = GUI.Window( - VOID_Core.Instance.windowID, + this.core.windowID, this.leftHUDPos, this.leftHUDWindow, GUIContent.none, @@ -230,7 +232,7 @@ ); this.rightHUDPos.value = GUI.Window( - VOID_Core.Instance.windowID, + this.core.windowID, this.rightHUDPos, this.rightHUDWindow, GUIContent.none, @@ -261,7 +263,7 @@ { public static readonly VOID_StrValue expSituation = new VOID_StrValue( "Situation", - new Func (() => VOID_Core.Instance.vessel.GetExperimentSituation().HumanString()) + new Func (() => core.vessel.GetExperimentSituation().HumanString()) ); public static readonly VOID_DoubleValue vesselPitch = new VOID_DoubleValue( @@ -269,62 +271,6 @@ () => core.vessel.getSurfacePitch(), "°" ); - - public static readonly VOID_DoubleValue stageMassFlow = new VOID_DoubleValue( - "Stage Mass Flow", - delegate() - { - if (SimManager.LastStage == null) - { - return double.NaN; - } - - double stageIsp = SimManager.LastStage.isp; - double stageThrust = SimManager.LastStage.actualThrust; - - return stageThrust / (stageIsp * KerbinGee); - }, - "Mg/s" - ); - - public static readonly VOID_DoubleValue burnTimeCompleteAtNode = new VOID_DoubleValue( - "Full burn time to complete at node", - delegate() - { - if (SimManager.LastStage == null) - { - return double.NaN; - } - - double nextManeuverDV = core.vessel.patchedConicSolver.maneuverNodes[0].DeltaV.magnitude; - double stageThrust = SimManager.LastStage.actualThrust; - - return burnTime(nextManeuverDV, totalMass, stageMassFlow, stageThrust); - }, - "s" - ); - - public static readonly VOID_DoubleValue burnTimeHalfDoneAtNode = new VOID_DoubleValue( - "Full burn time to be half done at node", - delegate() - { - if (SimManager.LastStage == null) - { - return double.NaN; - } - - double nextManeuverDV = core.vessel.patchedConicSolver.maneuverNodes[0].DeltaV.magnitude / 2d; - double stageThrust = SimManager.LastStage.actualThrust; - - return burnTime(nextManeuverDV, totalMass, stageMassFlow, stageThrust); - }, - "s" - ); - - private static double burnTime(double deltaV, double initialMass, double massFlow, double thrust) - { - return initialMass / massFlow * (Math.Exp(deltaV * massFlow / thrust) - 1d); - } } } --- /dev/null +++ b/VOID_HUDAdvanced.cs @@ -1,1 +1,668 @@ - +// VOID +// +// VOID_HUD.cs +// +// Copyright © 2014, toadicus +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +using Engineer.VesselSimulator; +using KSP; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using ToadicusTools; +using UnityEngine; + +namespace VOID +{ + public class VOID_HUDAdvanced : VOID_Module, IVOID_Module + { + /* + * Fields + * */ + protected VOID_HUD primaryHUD; + + protected Rect leftHUDdefaultPos; + protected Rect rightHUDdefaultPos; + + [AVOID_SaveValue("leftHUDPos")] + protected VOID_SaveValue leftHUDPos; + [AVOID_SaveValue("rightHUDPos")] + protected VOID_SaveValue rightHUDPos; + + [AVOID_SaveValue("positionsLocked")] + protected VOID_SaveValue positionsLocked; + + /* + * Properties + * */ + public int ColorIndex + { + get + { + if (this.primaryHUD == null) + { + return 0; + } + + return this.primaryHUD.ColorIndex; + } + } + + /* + * Methods + * */ + public VOID_HUDAdvanced() : base() + { + this._Name = "Advanced Heads-Up Display"; + + this.toggleActive = true; + + this.leftHUDdefaultPos = new Rect( + Screen.width * .5f - (float)GameSettings.UI_SIZE * .25f - 300f, + Screen.height - 200f, + 300f, 90f + ); + this.leftHUDPos = new Rect(this.leftHUDdefaultPos); + + this.rightHUDdefaultPos = new Rect( + Screen.width * .5f + (float)GameSettings.UI_SIZE * .25f, + Screen.height - 200f, + 300f, 90f + ); + this.rightHUDPos = new Rect(this.rightHUDdefaultPos); + + this.positionsLocked = true; + + Tools.PostDebugMessage (this, "Constructed."); + } + + protected void leftHUDWindow(int id) + { + StringBuilder leftHUD; + + leftHUD = new StringBuilder(); + + this.core.LabelStyles["hud"].alignment = TextAnchor.UpperRight; + + if (this.core.powerAvailable) + { + leftHUD.AppendFormat( + string.Intern("Mass: {0}\n"), + VOID_Data.totalMass.ToSIString(2) + ); + + if (VOID_Data.vesselCrewCapacity > 0) + { + leftHUD.AppendFormat( + string.Intern("Crew: {0} / {1}\n"), + VOID_Data.vesselCrewCount.Value, + VOID_Data.vesselCrewCapacity.Value + ); + } + + leftHUD.AppendFormat( + string.Intern("Acc: {0} T:W: {1}\n"), + VOID_Data.vesselAccel.ToSIString(2), + VOID_Data.currThrustWeight.Value.ToString("f2") + ); + + leftHUD.AppendFormat( + string.Intern("Ang Vel: {0}\n"), + VOID_Data.vesselAngularVelocity.ToSIString(2) + ); + + if (VOID_Data.stageNominalThrust != 0d) + { + leftHUD.AppendFormat( + string.Intern("Thrust Offset: {0}\n"), + VOID_Data.vesselThrustOffset.Value.ToString("F1") + ); + } + } + else + { + this.core.LabelStyles["hud"].normal.textColor = Color.red; + leftHUD.Append(string.Intern("-- POWER LOST --")); + } + + GUILayout.Label(leftHUD.ToString(), this.core.LabelStyles["hud"], GUILayout.ExpandWidth(true)); + + if (!this.positionsLocked) + { + GUI.DragWindow(); + } + + GUI.BringWindowToBack(id); + } + + protected void rightHUDWindow(int id) + { + StringBuilder rightHUD; + + rightHUD = new StringBuilder(); + + this.core.LabelStyles["hud"].alignment = TextAnchor.UpperLeft; + + if (this.core.powerAvailable) + { + rightHUD.AppendFormat( + "Burn Δv (Rem/Tot): {0} / {1}\n", + VOID_Data.currManeuverDVRemaining.ValueUnitString("f2"), + VOID_Data.currManeuverDeltaV.ValueUnitString("f2") + ); + + if (VOID_Data.upcomingManeuverNodes > 1) + { + rightHUD.AppendFormat("Next Burn Δv: {0}\n", + VOID_Data.nextManeuverDeltaV.ValueUnitString("f2") + ); + } + + rightHUD.AppendFormat("Burn Time (Rem/Total): {0} / {1}\n", + VOID_Tools.ConvertInterval(VOID_Data.currentNodeBurnRemaining.Value), + VOID_Tools.ConvertInterval(VOID_Data.currentNodeBurnDuration.Value) + ); + + if (VOID_Data.burnTimeDoneAtNode.Value != string.Empty) + { + rightHUD.AppendFormat("{0} (done @ node)\n", + VOID_Data.burnTimeDoneAtNode.Value + ); + + rightHUD.AppendFormat("{0} (½ done @ node)", + VOID_Data.burnTimeHalfDoneAtNode.Value + ); + } + else + { + rightHUD.Append("Node is past"); + } + } + else + { + this.core.LabelStyles["hud"].normal.textColor = Color.red; + rightHUD.Append(string.Intern("-- POWER LOST --")); + } + + GUILayout.Label(rightHUD.ToString(), this.core.LabelStyles["hud"], GUILayout.ExpandWidth(true)); + + if (!this.positionsLocked) + { + GUI.DragWindow(); + } + + GUI.BringWindowToBack(id); + } + + public override void DrawGUI() + { + if (this.primaryHUD == null) + { + foreach (IVOID_Module module in this.core.Modules) + { + if (module is VOID_HUD) + { + this.primaryHUD = module as VOID_HUD; + } + } + } + else + { + if ((TimeWarp.WarpMode == TimeWarp.Modes.LOW) || (TimeWarp.CurrentRate <= TimeWarp.MaxPhysicsRate)) + { + SimManager.RequestSimulation(); + } + + this.leftHUDPos.value = GUI.Window( + this.core.windowID, + this.leftHUDPos, + VOID_Tools.GetWindowHandler(this.leftHUDWindow), + GUIContent.none, + GUIStyle.none + ); + + if (VOID_Data.upcomingManeuverNodes > 0) + { + this.rightHUDPos.value = GUI.Window( + this.core.windowID, + this.rightHUDPos, + VOID_Tools.GetWindowHandler(this.rightHUDWindow), + GUIContent.none, + GUIStyle.none + ); + } + } + } + + public override void DrawConfigurables() + { + this.positionsLocked = GUILayout.Toggle(this.positionsLocked, + string.Intern("Lock Advanced HUD Positions"), + GUILayout.ExpandWidth(false)); + } + } + + public static partial class VOID_Data + { + public static int upcomingManeuverNodes + { + get + { + if (core.vessel == null || + core.vessel.patchedConicSolver == null || + core.vessel.patchedConicSolver.maneuverNodes == null + ) + { + return 0; + } + + return core.vessel.patchedConicSolver.maneuverNodes.Count; + } + } + + public static readonly VOID_Vector3dValue vesselThrustOffset = new VOID_Vector3dValue( + "Thrust Offset", + delegate() + { + if (core.vessel == null) + { + return Vector3d.zero; + } + + List engineModules = core.vessel.getModulesOfType(); + + Vector3d thrustPos = Vector3d.zero; + Vector3d thrustDir = Vector3d.zero; + float thrust = 0; + + foreach (PartModule engine in engineModules) + { + float moduleThrust = 0; + + switch (engine.moduleName) + { + case "ModuleEngines": + case "ModuleEnginesFX": + break; + default: + continue; + } + + if (!engine.isEnabled) + { + continue; + } + + CenterOfThrustQuery cotQuery = new CenterOfThrustQuery(); + + if (engine is ModuleEngines) + { + ModuleEngines engineModule = engine as ModuleEngines; + + moduleThrust = engineModule.finalThrust; + + engineModule.OnCenterOfThrustQuery(cotQuery); + } + else // engine is ModuleEnginesFX + { + ModuleEnginesFX engineFXModule = engine as ModuleEnginesFX; + + moduleThrust = engineFXModule.finalThrust; + + engineFXModule.OnCenterOfThrustQuery(cotQuery); + } + + if (moduleThrust != 0d) + { + cotQuery.thrust = moduleThrust; + } + + thrustPos += cotQuery.pos * cotQuery.thrust; + thrustDir += cotQuery.dir * cotQuery.thrust; + thrust += cotQuery.thrust; + } + + if (thrust != 0) + { + thrustPos /= thrust; + thrustDir /= thrust; + } + + Transform vesselTransform = core.vessel.transform; + + thrustPos = vesselTransform.InverseTransformPoint(thrustPos); + thrustDir = vesselTransform.InverseTransformDirection(thrustDir); + + Vector3d thrustOffset = VectorTools.PointDistanceToLine( + thrustPos, thrustDir.normalized, core.vessel.findLocalCenterOfMass()); + + Tools.PostDebugMessage(typeof(VOID_Data), "vesselThrustOffset:\n" + + "\tthrustPos: {0}\n" + + "\tthrustDir: {1}\n" + + "\tthrustOffset: {2}\n" + + "\tvessel.CoM: {3}", + thrustPos, + thrustDir.normalized, + thrustOffset, + core.vessel.findWorldCenterOfMass() + ); + + return thrustOffset; + }, + "m" + ); + + public static readonly VOID_DoubleValue vesselAccel = new VOID_DoubleValue( + "Acceleration", + () => geeForce * KerbinGee, + "m/s²" + ); + + public static readonly VOID_IntValue vesselCrewCount = new VOID_IntValue( + "Crew Onboard", + delegate() + { + if (core.vessel != null) + { + return core.vessel.GetCrewCount(); + } + else + { + return 0; + } + }, + "" + ); + + public static readonly VOID_IntValue vesselCrewCapacity = new VOID_IntValue( + "Crew Capacity", + delegate() + { + if (core.vessel != null) + { + return core.vessel.GetCrewCapacity(); + } + else + { + return 0; + } + }, + "" + ); + + public static readonly VOID_DoubleValue vesselAngularVelocity = new VOID_DoubleValue( + "Angular Velocity", + delegate() + { + if (core.vessel != null) + { + return core.vessel.angularVelocity.magnitude; + } + else + { + return double.NaN; + } + }, + "rad/s" + ); + + public static readonly VOID_DoubleValue stageNominalThrust = new VOID_DoubleValue( + "Nominal Stage Thrust", + delegate() + { + if (SimManager.LastStage == null) + { + return double.NaN; + } + + if (SimManager.LastStage.actualThrust == 0d) + { + return SimManager.LastStage.thrust; + } + else + { + return SimManager.LastStage.actualThrust; + } + }, + "kN" + ); + + public static readonly VOID_DoubleValue stageMassFlow = new VOID_DoubleValue( + "Stage Mass Flow", + delegate() + { + if (SimManager.LastStage == null) + { + return double.NaN; + } + + double stageIsp = SimManager.LastStage.isp; + double stageThrust = stageNominalThrust; + + Tools.PostDebugMessage(typeof(VOID_Data), "calculating stageMassFlow from:\n" + + "\tstageIsp: {0}\n" + + "\tstageThrust: {1}\n" + + "\tKerbinGee: {2}\n", + stageIsp, + stageThrust, + KerbinGee + ); + + return stageThrust / (stageIsp * KerbinGee); + }, + "Mg/s" + ); + + public static readonly VOID_DoubleValue currManeuverDeltaV = new VOID_DoubleValue( + "Current Maneuver Delta-V", + delegate() + { + if (upcomingManeuverNodes > 0) + { + return core.vessel.patchedConicSolver.maneuverNodes[0].DeltaV.magnitude; + } + else + { + return double.NaN; + } + }, + "m/s" + ); + + public static readonly VOID_DoubleValue currManeuverDVRemaining = new VOID_DoubleValue( + "Remaining Maneuver Delta-V", + delegate() + { + if (upcomingManeuverNodes > 0) + { + return core.vessel.patchedConicSolver.maneuverNodes[0].GetBurnVector(core.vessel.orbit).magnitude; + } + else + { + return double.NaN; + } + }, + "m/s" + ); + + public static readonly VOID_DoubleValue nextManeuverDeltaV = new VOID_DoubleValue( + "Current Maneuver Delta-V", + delegate() + { + if (upcomingManeuverNodes > 1) + { + return core.vessel.patchedConicSolver.maneuverNodes[1].DeltaV.magnitude; + } + else + { + return double.NaN; + } + }, + "m/s" + ); + + public static readonly VOID_DoubleValue currentNodeBurnDuration = new VOID_DoubleValue( + "Total Burn Time", + delegate() + { + if (SimManager.LastStage == null || currManeuverDeltaV.Value == double.NaN) + { + return double.NaN; + } + + double stageThrust = stageNominalThrust; + + return burnTime(currManeuverDeltaV.Value, totalMass, stageMassFlow, stageThrust); + }, + "s" + ); + + public static readonly VOID_DoubleValue currentNodeBurnRemaining = new VOID_DoubleValue( + "Burn Time Remaining", + delegate() + { + if (SimManager.LastStage == null || currManeuverDVRemaining == double.NaN) + { + return double.NaN; + } + + double stageThrust = stageNominalThrust; + + return burnTime(currManeuverDVRemaining, totalMass, stageMassFlow, stageThrust); + }, + "s" + ); + + public static readonly VOID_DoubleValue currentNodeHalfBurnDuration = new VOID_DoubleValue( + "Half Burn Time", + delegate() + { + if (SimManager.LastStage == null || currManeuverDeltaV.Value == double.NaN) + { + return double.NaN; + } + + double stageThrust = stageNominalThrust; + + return burnTime(currManeuverDeltaV.Value / 2d, totalMass, stageMassFlow, stageThrust); + }, + "s" + ); + + public static readonly VOID_StrValue burnTimeDoneAtNode = new VOID_StrValue( + "Full burn time to be half done at node", + delegate() + { + if (SimManager.LastStage == null && upcomingManeuverNodes < 1) + { + return "N/A"; + } + + ManeuverNode node = core.vessel.patchedConicSolver.maneuverNodes[0]; + + if ((node.UT - Planetarium.GetUniversalTime()) < 0) + { + return string.Empty; + } + + double interval = (node.UT - currentNodeBurnDuration) - Planetarium.GetUniversalTime(); + + if (double.IsNaN(interval)) + { + return string.Intern("NaN"); + } + + int sign = Math.Sign(interval); + interval = Math.Abs(interval); + + string format; + + if (sign >= 0) + { + format = string.Intern("T - {0}"); + } + else + { + format = string.Intern("T + {0}"); + } + + return string.Format(format, VOID_Tools.ConvertInterval(interval)); + } + ); + + public static readonly VOID_StrValue burnTimeHalfDoneAtNode = new VOID_StrValue( + "Full burn time to be half done at node", + delegate() + { + if (SimManager.LastStage == null && upcomingManeuverNodes < 1) + { + return "N/A"; + } + + ManeuverNode node = core.vessel.patchedConicSolver.maneuverNodes[0]; + + if ((node.UT - Planetarium.GetUniversalTime()) < 0) + { + return string.Empty; + } + + double interval = (node.UT - currentNodeHalfBurnDuration) - Planetarium.GetUniversalTime(); + + int sign = Math.Sign(interval); + interval = Math.Abs(interval); + + string format; + + if (sign >= 0) + { + format = string.Intern("T - {0}"); + } + else + { + format = string.Intern("T + {0}"); + } + + return string.Format(format, VOID_Tools.ConvertInterval(interval)); + } + ); + + private static double burnTime(double deltaV, double initialMass, double massFlow, double thrust) + { + Tools.PostDebugMessage(typeof(VOID_Data), "calculating burnTime from:\n" + + "\tdeltaV: {0}\n" + + "\tinitialMass: {1}\n" + + "\tmassFlow: {2}\n" + + "\tthrust: {3}\n", + deltaV, + initialMass, + massFlow, + thrust + ); + return initialMass / massFlow * (Math.Exp(deltaV * massFlow / thrust) - 1d); + } + } +} + --- a/VOID_Module.cs +++ b/VOID_Module.cs @@ -51,6 +51,19 @@ /* * Properties * */ + protected virtual VOID_Core core + { + get + { + if (HighLogic.LoadedSceneIsEditor) + { + return VOID_EditorCore.Instance as VOID_Core; + } + + return VOID_Core.Instance; + } + } + public virtual bool toggleActive { get @@ -206,53 +219,18 @@ protected float defWidth = 250f; protected float defHeight = 50f; - public virtual void ModuleWindow(int _) - { -// if (VOID_Core.Instance.updateTimer - this.lastUpdate > VOID_Core.Instance.updatePeriod) { -// foreach (var fieldinfo in this.GetType().GetFields( -// BindingFlags.Instance | -// BindingFlags.NonPublic | -// BindingFlags.Public | -// BindingFlags.FlattenHierarchy -// )) -// { -// object field = null; -// -// try -// { -// field = fieldinfo.GetValue (this); -// } -// catch (NullReferenceException) { -// Tools.PostDebugMessage(string.Format( -// "{0}: caught NullReferenceException, could not get value for field {1}.", -// this.GetType().Name, -// fieldinfo.Name -// )); -// } -// -// if (field == null) { -// continue; -// } -// -// if (typeof(IVOID_DataValue).IsAssignableFrom (field.GetType ())) { -// (field as IVOID_DataValue).Refresh (); -// } -// } -// -// this.lastUpdate = VOID_Core.Instance.updateTimer; -// } - } + public abstract void ModuleWindow(int _); public override void DrawGUI() { - GUI.skin = VOID_Core.Instance.Skin; + GUI.skin = this.core.Skin; Rect _Pos = this.WindowPos; _Pos = GUILayout.Window( - VOID_Core.Instance.windowID, + this.core.windowID, _Pos, - this.ModuleWindow, + VOID_Tools.GetWindowHandler(this.ModuleWindow), this.Name, GUILayout.Width(this.defWidth), GUILayout.Height(this.defHeight) @@ -263,7 +241,7 @@ if (_Pos != this.WindowPos) { this.WindowPos = _Pos; - VOID_Core.Instance.configDirty = true; + this.core.configDirty = true; } } } --- a/VOID_Orbital.cs +++ b/VOID_Orbital.cs @@ -52,8 +52,6 @@ public override void ModuleWindow(int _) { - base.ModuleWindow (_); - int idx = 0; GUILayout.BeginVertical(); @@ -131,51 +129,51 @@ VOID_Localization.void_primary, delegate() { - if (VOID_Core.Instance.vessel == null) + if (core.vessel == null) { return string.Empty; } - return VOID_Core.Instance.vessel.mainBody.name; + return core.vessel.mainBody.name; } ); public static readonly VOID_DoubleValue orbitAltitude = new VOID_DoubleValue ( "Altitude (ASL)", - new Func (() => VOID_Core.Instance.vessel.orbit.altitude), + new Func (() => core.vessel.orbit.altitude), "m" ); public static readonly VOID_DoubleValue orbitVelocity = new VOID_DoubleValue ( VOID_Localization.void_velocity, - new Func (() => VOID_Core.Instance.vessel.orbit.vel.magnitude), + new Func (() => core.vessel.orbit.vel.magnitude), "m/s" ); public static readonly VOID_DoubleValue orbitApoAlt = new VOID_DoubleValue( VOID_Localization.void_apoapsis, - new Func(() => VOID_Core.Instance.vessel.orbit.ApA), + new Func(() => core.vessel.orbit.ApA), "m" ); public static readonly VOID_DoubleValue oribtPeriAlt = new VOID_DoubleValue( VOID_Localization.void_periapsis, - new Func(() => VOID_Core.Instance.vessel.orbit.PeA), + new Func(() => core.vessel.orbit.PeA), "m" ); public static readonly VOID_StrValue timeToApo = new VOID_StrValue( "Time to Apoapsis", - new Func(() => VOID_Tools.ConvertInterval(VOID_Core.Instance.vessel.orbit.timeToAp)) + new Func(() => VOID_Tools.ConvertInterval(core.vessel.orbit.timeToAp)) ); public static readonly VOID_StrValue timeToPeri = new VOID_StrValue( "Time to Periapsis", - new Func(() => VOID_Tools.ConvertInterval(VOID_Core.Instance.vessel.orbit.timeToPe)) + new Func(() => VOID_Tools.ConvertInterval(core.vessel.orbit.timeToPe)) ); public static readonly VOID_DoubleValue orbitInclination = new VOID_DoubleValue( "Inclination", - new Func(() => VOID_Core.Instance.vessel.orbit.inclination), + new Func(() => core.vessel.orbit.inclination), "°" ); @@ -183,65 +181,65 @@ "Gravity", delegate() { - double orbitRadius = VOID_Core.Instance.vessel.mainBody.Radius + - VOID_Core.Instance.vessel.mainBody.GetAltitude(VOID_Core.Instance.vessel.findWorldCenterOfMass()); - return (VOID_Core.Constant_G * VOID_Core.Instance.vessel.mainBody.Mass) / - Math.Pow(orbitRadius, 2); + double orbitRadius = core.vessel.mainBody.Radius + + core.vessel.mainBody.GetAltitude(core.vessel.findWorldCenterOfMass()); + return (VOID_Core.Constant_G * core.vessel.mainBody.Mass) / + (orbitRadius * orbitRadius); }, "m/s²" ); public static readonly VOID_StrValue orbitPeriod = new VOID_StrValue( "Period", - new Func(() => VOID_Tools.ConvertInterval(VOID_Core.Instance.vessel.orbit.period)) + new Func(() => VOID_Tools.ConvertInterval(core.vessel.orbit.period)) ); public static readonly VOID_DoubleValue semiMajorAxis = new VOID_DoubleValue( "Semi-Major Axis", - new Func(() => VOID_Core.Instance.vessel.orbit.semiMajorAxis), + new Func(() => core.vessel.orbit.semiMajorAxis), "m" ); public static readonly VOID_DoubleValue eccentricity = new VOID_DoubleValue( "Eccentricity", - new Func(() => VOID_Core.Instance.vessel.orbit.eccentricity), + new Func(() => core.vessel.orbit.eccentricity), "" ); public static readonly VOID_DoubleValue meanAnomaly = new VOID_DoubleValue( "Mean Anomaly", - new Func(() => VOID_Core.Instance.vessel.orbit.meanAnomaly * 180d / Math.PI), + new Func(() => core.vessel.orbit.meanAnomaly * 180d / Math.PI), "°" ); public static readonly VOID_DoubleValue trueAnomaly = new VOID_DoubleValue( "True Anomaly", - new Func(() => VOID_Core.Instance.vessel.orbit.trueAnomaly), + new Func(() => core.vessel.orbit.trueAnomaly), "°" ); public static readonly VOID_DoubleValue eccAnomaly = new VOID_DoubleValue( "Eccentric Anomaly", - new Func(() => VOID_Core.Instance.vessel.orbit.eccentricAnomaly * 180d / Math.PI), + new Func(() => core.vessel.orbit.eccentricAnomaly * 180d / Math.PI), "°" ); public static readonly VOID_DoubleValue longitudeAscNode = new VOID_DoubleValue( "Long. Ascending Node", - new Func(() => VOID_Core.Instance.vessel.orbit.LAN), + new Func(() => core.vessel.orbit.LAN), "°" ); public static readonly VOID_DoubleValue argumentPeriapsis = new VOID_DoubleValue( "Argument of Periapsis", - new Func(() => VOID_Core.Instance.vessel.orbit.argumentOfPeriapsis), + new Func(() => core.vessel.orbit.argumentOfPeriapsis), "°" ); public static readonly VOID_DoubleValue localSiderealLongitude = new VOID_DoubleValue( "Local Sidereal Longitude", new Func(() => VOID_Tools.FixDegreeDomain( - VOID_Core.Instance.vessel.longitude + VOID_Core.Instance.vessel.orbit.referenceBody.rotationAngle)), + core.vessel.longitude + core.vessel.orbit.referenceBody.rotationAngle)), "°" ); } --- a/VOID_Rendezvous.cs +++ b/VOID_Rendezvous.cs @@ -60,14 +60,14 @@ if (this.RegisterModule == null) { - this.RegisterModule = VOID_Core.Instance.Modules.Where(m => typeof(VOID_VesselRegister).IsAssignableFrom(m.GetType())).FirstOrDefault() as VOID_VesselRegister; + this.RegisterModule = this.core.Modules.Where(m => typeof(VOID_VesselRegister).IsAssignableFrom(m.GetType())).FirstOrDefault() as VOID_VesselRegister; } GUILayout.BeginVertical(); //display both //Show Target Info - GUILayout.Label("Target:", VOID_Core.Instance.LabelStyles["center_bold"]); + GUILayout.Label("Target:", this.core.LabelStyles["center_bold"]); if (FlightGlobals.fetch.VesselTarget != null) { //a KSP Target (body or vessel) is selected @@ -94,13 +94,13 @@ else { //no KSP Target selected - GUILayout.Label("No Target Selected", VOID_Core.Instance.LabelStyles["center_bold"]); + GUILayout.Label("No Target Selected", this.core.LabelStyles["center_bold"]); } //Show Vessel Register vessel info if (untoggleRegisterInfo == false && this.RegisterModule != default(IVOID_Module)) { - GUILayout.Label("Vessel Register:", VOID_Core.Instance.LabelStyles["center_bold"]); + GUILayout.Label("Vessel Register:", this.core.LabelStyles["center_bold"]); if (this.RegisterModule.selectedVessel != null) { rendezvessel = this.RegisterModule.selectedVessel; @@ -122,7 +122,7 @@ { //vesreg Vessel is null //targ = null; - GUILayout.Label("No Vessel Selected", VOID_Core.Instance.LabelStyles["center_bold"]); + GUILayout.Label("No Vessel Selected", this.core.LabelStyles["center_bold"]); } } @@ -130,7 +130,7 @@ GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.Label(" ", GUILayout.ExpandWidth(true)); - if (GUILayout.Button("Close", GUILayout.ExpandWidth(false))) this._Active = false; + if (GUILayout.Button("Close", GUILayout.ExpandWidth(false))) this.toggleActive = false; GUILayout.EndHorizontal(); GUILayout.EndVertical(); @@ -143,7 +143,7 @@ { //Display vessel rendezvous info GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); - GUILayout.Label(v.vesselName, VOID_Core.Instance.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); + GUILayout.Label(v.vesselName, this.core.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); GUILayout.EndHorizontal(); if (v.situation == Vessel.Situations.ESCAPING || v.situation == Vessel.Situations.FLYING || v.situation == Vessel.Situations.ORBITING || v.situation == Vessel.Situations.SUB_ORBITAL) @@ -193,7 +193,13 @@ GUILayout.Label(Tools.MuMech_ToSI((vessel.findWorldCenterOfMass() - v.findWorldCenterOfMass()).magnitude) + "m", GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); - //target_vessel_extended_orbital_info = GUILayout.Toggle(target_vessel_extended_orbital_info, "Extended info"); + // Toadicus edit: added local sidereal longitude. + GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); + GUILayout.Label("Local Sidereal Longitude:"); + GUILayout.Label(LSL.ToString("F3") + "°", this.core.LabelStyles["right"]); + GUILayout.EndHorizontal(); + + toggleExtendedOrbital.value = GUILayout.Toggle(toggleExtendedOrbital, "Extended info"); if (toggleExtendedOrbital) { @@ -238,12 +244,6 @@ GUILayout.Label("Arg. of periapsis:"); GUILayout.Label(v.orbit.argumentOfPeriapsis.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); - - // Toadicus edit: added local sidereal longitude. - GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); - GUILayout.Label("Local Sidereal Longitude:"); - GUILayout.Label(LSL.ToString("F3") + "°", VOID_Core.Instance.LabelStyles["right"]); - GUILayout.EndHorizontal(); } } else @@ -267,7 +267,7 @@ else if (cb != null && v == null) { //Display CelstialBody rendezvous info - GUILayout.Label(cb.bodyName, VOID_Core.Instance.LabelStyles["center_bold"]); + GUILayout.Label(cb.bodyName, this.core.LabelStyles["center_bold"]); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.Label("Ap/Pe:"); --- a/VOID_SurfAtmo.cs +++ b/VOID_SurfAtmo.cs @@ -49,8 +49,6 @@ public override void ModuleWindow(int _) { - base.ModuleWindow (_); - int idx = 0; GUILayout.BeginVertical(); @@ -113,11 +111,11 @@ "Altitude (true)", delegate() { - double alt_true = VOID_Core.Instance.vessel.orbit.altitude - VOID_Core.Instance.vessel.terrainAltitude; + double alt_true = core.vessel.orbit.altitude - core.vessel.terrainAltitude; // HACK: This assumes that on worlds with oceans, all water is fixed at 0 m, // and water covers the whole surface at 0 m. - if (VOID_Core.Instance.vessel.terrainAltitude < 0 && VOID_Core.Instance.vessel.mainBody.ocean ) - alt_true = VOID_Core.Instance.vessel.orbit.altitude; + if (core.vessel.terrainAltitude < 0 && core.vessel.mainBody.ocean ) + alt_true = core.vessel.orbit.altitude; return alt_true; }, "m" @@ -125,12 +123,12 @@ public static readonly VOID_StrValue surfLatitude = new VOID_StrValue( "Latitude", - new Func (() => VOID_Tools.GetLatitudeString(VOID_Core.Instance.vessel)) + new Func (() => VOID_Tools.GetLatitudeString(core.vessel)) ); public static readonly VOID_StrValue surfLongitude = new VOID_StrValue( "Longitude", - new Func (() => VOID_Tools.GetLongitudeString(VOID_Core.Instance.vessel)) + new Func (() => VOID_Tools.GetLongitudeString(core.vessel)) ); public static readonly VOID_StrValue vesselHeading = new VOID_StrValue( @@ -150,55 +148,55 @@ public static readonly VOID_DoubleValue terrainElevation = new VOID_DoubleValue( "Terrain elevation", - new Func (() => VOID_Core.Instance.vessel.terrainAltitude), + new Func (() => core.vessel.terrainAltitude), "m" ); public static readonly VOID_DoubleValue surfVelocity = new VOID_DoubleValue( "Surface velocity", - new Func (() => VOID_Core.Instance.vessel.srf_velocity.magnitude), + new Func (() => core.vessel.srf_velocity.magnitude), "m/s" ); public static readonly VOID_DoubleValue vertVelocity = new VOID_DoubleValue( "Vertical speed", - new Func (() => VOID_Core.Instance.vessel.verticalSpeed), + new Func (() => core.vessel.verticalSpeed), "m/s" ); public static readonly VOID_DoubleValue horzVelocity = new VOID_DoubleValue( "Horizontal speed", - new Func (() => VOID_Core.Instance.vessel.horizontalSrfSpeed), + new Func (() => core.vessel.horizontalSrfSpeed), "m/s" ); public static readonly VOID_FloatValue temperature = new VOID_FloatValue( "Temperature", - new Func (() => VOID_Core.Instance.vessel.flightIntegrator.getExternalTemperature()), + new Func (() => core.vessel.flightIntegrator.getExternalTemperature()), "°C" ); public static readonly VOID_DoubleValue atmDensity = new VOID_DoubleValue ( "Atmosphere Density", - new Func (() => VOID_Core.Instance.vessel.atmDensity * 1000f), + new Func (() => core.vessel.atmDensity * 1000f), "g/m³" ); public static readonly VOID_DoubleValue atmPressure = new VOID_DoubleValue ( "Pressure", - new Func (() => VOID_Core.Instance.vessel.staticPressure), + new Func (() => core.vessel.staticPressure), "atm" ); public static readonly VOID_FloatValue atmLimit = new VOID_FloatValue( "Atmosphere Limit", - new Func (() => VOID_Core.Instance.vessel.mainBody.maxAtmosphereAltitude), + new Func (() => core.vessel.mainBody.maxAtmosphereAltitude), "m" ); public static readonly VOID_StrValue currBiome = new VOID_StrValue( "Biome", - new Func (() => VOID_Tools.GetBiome(VOID_Core.Instance.vessel).name) + new Func (() => VOID_Tools.GetBiome(core.vessel).name) ); } --- /dev/null +++ b/VOID_TWR.cs @@ -1,1 +1,97 @@ +// VOID © 2014 toadicus +// +// This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a +// copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ +using KSP; +using System; +using System.Collections.Generic; +using System.Linq; +using ToadicusTools; +using UnityEngine; + +namespace VOID +{ + public class VOID_TWR : VOID_WindowModule + { + private List sortedBodyList; + + public VOID_TWR() : base() + { + this._Name = "IP Thrust-to-Weight Ratios"; + } + + public override void ModuleWindow(int _) + { + if ( + HighLogic.LoadedSceneIsEditor || + (TimeWarp.WarpMode == TimeWarp.Modes.LOW) || + (TimeWarp.CurrentRate <= TimeWarp.MaxPhysicsRate) + ) + { + Engineer.VesselSimulator.SimManager.RequestSimulation(); + } + + GUILayout.BeginVertical(); + + if (this.sortedBodyList == null) + { + if (FlightGlobals.Bodies != null && FlightGlobals.Bodies.Count > 0) + { + this.sortedBodyList = new List(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()))); + } + else + { + GUILayout.BeginHorizontal(); + GUILayout.Label("Unavailable."); + GUILayout.EndHorizontal(); + } + } + else + { + foreach (CelestialBody body in this.sortedBodyList) + { + GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); + + GUILayout.Label(body.bodyName); + GUILayout.FlexibleSpace(); + GUILayout.Label( + (VOID_Data.nominalThrustWeight.Value / body.GeeASL).ToString("0.0##"), + GUILayout.ExpandWidth(true) + ); + + GUILayout.EndHorizontal(); + } + } + + GUILayout.EndVertical(); + + GUI.DragWindow(); + } + } + + public class VOID_EditorTWR : VOID_TWR, IVOID_EditorModule {} + + public static partial class VOID_Data + { + public static readonly VOID_DoubleValue nominalThrustWeight = new VOID_DoubleValue( + "Thrust-to-Weight Ratio", + delegate() + { + if (HighLogic.LoadedSceneIsEditor || currThrustWeight.Value == 0d) + { + return maxThrustWeight.Value; + } + + return currThrustWeight.Value; + }, + "" + ); + } +} + + --- a/VOID_Tools.cs +++ b/VOID_Tools.cs @@ -28,12 +28,72 @@ using KSP; using System; +using System.Collections.Generic; +using ToadicusTools; using UnityEngine; namespace VOID { public static partial class VOID_Tools { + #region CelestialBody Utilities + public static bool hasAncestor(this CelestialBody bodyA, CelestialBody bodyB) + { + if (bodyA == null || bodyB == null) + { + return false; + } + + while (bodyA.orbitDriver != null) + { + if (bodyA.orbit.referenceBody == bodyB) + { + return true; + } + + bodyA = bodyA.orbit.referenceBody; + } + + return false; + } + + public static bool NearestRelatedParents(ref CelestialBody bodyA, ref CelestialBody bodyB) + { + if (bodyA == null || bodyB == null || bodyA.orbitDriver == null || bodyB.orbitDriver == null) + { + throw new ArgumentException(string.Concat( + "CelestialBody::FindRelatedParents: ", + "Neither body may be null, and both bodies must have orbits." + )); + } + + CelestialBody a, b; + + a = bodyA; + + while (bodyA.orbitDriver != null) + { + b = bodyB; + + while (b.orbitDriver != null) + { + if (a.orbit.referenceBody == b.orbit.referenceBody) + { + bodyA = a; + bodyB = b; + return true; + } + + b = b.orbit.referenceBody; + } + + a = a.orbit.referenceBody; + } + + return false; + } + #endregion + #region VESSEL_EXTENSIONS_SCIENCE public static CBAttributeMap.MapAttribute GetBiome(this Vessel vessel) { @@ -256,6 +316,43 @@ } #endregion + private static Dictionary functionCache; + public static UnityEngine.GUI.WindowFunction GetWindowHandler(Action func) + { + if (functionCache == null) + { + functionCache = new Dictionary(); + } + + int hashCode = func.GetHashCode(); + + if (!functionCache.ContainsKey(hashCode)) + { + functionCache[hashCode] = delegate (int id) + { + try + { + func(id); + } + #if DEBUG + catch (ArgumentException ex) + #else + catch (ArgumentException) + #endif + { + Debug.LogWarning( + string.Format("[{0}]: ArgumentException caught during window call.", func.Target.GetType().Name) + ); + /*#if DEBUG + Debug.LogException(ex); + #endif*/ + } + }; + } + + return functionCache[hashCode]; + } + /// /// Converts the interval given in seconds to a human-friendly /// time period in [years], [days], hours, minutes, and seconds. @@ -345,8 +442,14 @@ //transfer angles public static double Nivvy_CalcTransferPhaseAngle(double r_current, double r_target, double grav_param) { - double T_target = (2 * Math.PI) * Math.Sqrt(Math.Pow((r_target / 1000), 3) / (grav_param / 1000000000)); - double T_transfer = (2 * Math.PI) * Math.Sqrt(Math.Pow((((r_target / 1000) + (r_current / 1000)) / 2), 3) / (grav_param / 1000000000)); + r_target /= 1000; + r_current /= 1000; + grav_param /= 1000000000; + + double midpoint = (r_target + r_current) / 2; + + double T_target = (2 * Math.PI) * Math.Sqrt((r_target * r_target * r_target) / grav_param); + double T_transfer = (2 * Math.PI) * Math.Sqrt((midpoint * midpoint * midpoint) / grav_param); return 360 * (0.5 - (T_transfer / (2 * T_target))); } @@ -385,7 +488,7 @@ r = r1*r2 return math.sqrt(bar / r) */ - double foo = r2 * Math.Pow(v, 2) - 2 * mu; + double foo = r2 * (v * v) - 2 * mu; double bar = r1 * foo + (2 * r2 * mu); double r = r1 * r2; return Math.Sqrt(bar / r); @@ -407,9 +510,9 @@ return 180 - degrees */ double epsilon, h, ee, theta, degrees; - epsilon = (Math.Pow(v, 2) / 2) - (mu / r); + epsilon = ((v * v) / 2) - (mu / r); h = r * v * Math.Sin(angle); - ee = Math.Sqrt(1 + ((2 * epsilon * Math.Pow(h, 2)) / Math.Pow(mu, 2))); + ee = Math.Sqrt(1 + ((2 * epsilon * (h * h)) / (mu * mu))); theta = Math.Acos(1.0 / ee); degrees = theta * (180.0 / Math.PI); return 180 - degrees; @@ -765,6 +868,83 @@ return ""; } } + + public class CBListComparer : IComparer + { + public int Compare(CelestialBody bodyA, CelestialBody bodyB) + { + Tools.PostDebugMessage(this, "got bodyA: {0} & bodyB: {1}", bodyA, bodyB); + + if (bodyA == null && bodyB == null) + { + Tools.PostDebugMessage(this, "both bodies are null, returning 0"); + return 0; + } + if (bodyA == null) + { + Tools.PostDebugMessage(this, "bodyA is null, returning -1"); + return -1; + } + if (bodyB == null) + { + Tools.PostDebugMessage(this, "bodyB is null, returning 1"); + return 1; + } + + Tools.PostDebugMessage(this, "bodies are not null, carrying on"); + + if (object.ReferenceEquals(bodyA, bodyB)) + { + Tools.PostDebugMessage(this, "bodies are equal, returning 0"); + return 0; + } + + Tools.PostDebugMessage(this, "bodies are not equal, carrying on"); + + if (bodyA.orbitDriver == null) + { + Tools.PostDebugMessage(this, "bodyA.orbit is null (bodyA is the sun, returning 1"); + return 1; + } + if (bodyB.orbitDriver == null) + { + Tools.PostDebugMessage(this, "bodyB.orbit is null (bodyB is the sun, returning -1"); + return -1; + } + + Tools.PostDebugMessage(this, "orbits are not null, carrying on"); + + if (bodyA.orbit.referenceBody == bodyB.orbit.referenceBody) + { + Tools.PostDebugMessage(this, "bodies share a parent, comparing SMAs"); + return -bodyA.orbit.semiMajorAxis.CompareTo(bodyB.orbit.semiMajorAxis); + } + + Tools.PostDebugMessage(this, "orbits do not share a parent, carrying on"); + + if (bodyA.hasAncestor(bodyB)) + { + Tools.PostDebugMessage(this, "bodyA is a moon or sub-moon of bodyB, returning -1"); + return -1; + } + if (bodyB.hasAncestor(bodyA)) + { + Tools.PostDebugMessage(this, "bodyA is a moon or sub-moon of bodyB, returning 1"); + return 1; + } + + Tools.PostDebugMessage(this, "bodies do not have an obvious relationship, searching for one"); + + if (VOID_Tools.NearestRelatedParents(ref bodyA, ref bodyB)) + { + Tools.PostDebugMessage(this, "good relation {0} and {1}, comparing", bodyA.bodyName, bodyB.bodyName); + return this.Compare(bodyA, bodyB); + } + + Tools.PostDebugMessage(this, "bad relation {0} and {1}, giving up", bodyA.bodyName, bodyB.bodyName); + + return 0; + } + } } - --- a/VOID_VesselInfo.cs +++ b/VOID_VesselInfo.cs @@ -48,8 +48,6 @@ public override void ModuleWindow(int _) { - base.ModuleWindow (_); - if ((TimeWarp.WarpMode == TimeWarp.Modes.LOW) || (TimeWarp.CurrentRate <= TimeWarp.MaxPhysicsRate)) { SimManager.RequestSimulation(); @@ -59,7 +57,7 @@ GUILayout.Label( vessel.vesselName, - VOID_Core.Instance.LabelStyles["center_bold"], + core.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); VOID_Data.geeForce.DoGUIHorizontal ("F2"); @@ -68,7 +66,9 @@ VOID_Data.totalMass.DoGUIHorizontal ("F3"); - VOID_Data.resourceMass.DoGUIHorizontal ("F3"); + VOID_Data.stageResourceMass.DoGUIHorizontal("F2"); + + VOID_Data.resourceMass.DoGUIHorizontal("F2"); VOID_Data.stageDeltaV.DoGUIHorizontal (3, false); @@ -94,13 +94,13 @@ { public static readonly VOID_DoubleValue geeForce = new VOID_DoubleValue( "G-force", - new Func(() => VOID_Core.Instance.vessel.geeForce), + new Func(() => core.vessel.geeForce), "gees" ); public static readonly VOID_IntValue partCount = new VOID_IntValue( "Parts", - new Func(() => VOID_Core.Instance.vessel.Parts.Count), + new Func(() => core.vessel.Parts.Count), "" ); @@ -127,9 +127,34 @@ return double.NaN; } - return SimManager.LastStage.totalBaseMass; + return SimManager.LastStage.totalMass - SimManager.LastStage.totalBaseMass; }, "tons" + ); + + public static readonly VOID_DoubleValue stageResourceMass = new VOID_DoubleValue( + "Resource Mass (Stage)", + delegate() + { + if (SimManager.LastStage == null) + { + return double.NaN; + } + + return SimManager.LastStage.mass - SimManager.LastStage.baseMass; + }, + "tons" + ); + + public static readonly VOID_StrValue comboResourceMass = new VOID_StrValue( + "Resource Mass (curr / total)", + delegate() + { + return string.Format("{0} / {1}", + stageResourceMass.ValueUnitString("F3"), + resourceMass.ValueUnitString("F3") + ); + } ); public static readonly VOID_DoubleValue stageDeltaV = new VOID_DoubleValue( @@ -156,7 +181,7 @@ public static readonly VOID_FloatValue mainThrottle = new VOID_FloatValue( "Throttle", - new Func(() => VOID_Core.Instance.vessel.ctrlState.mainThrottle * 100f), + new Func(() => core.vessel.ctrlState.mainThrottle * 100f), "%" ); @@ -178,6 +203,34 @@ } ); + public static readonly VOID_DoubleValue currThrustWeight = new VOID_DoubleValue( + "T:W Ratio", + delegate() + { + if (SimManager.LastStage == null) + { + return double.NaN; + } + + return SimManager.LastStage.actualThrustToWeight; + }, + "" + ); + + public static readonly VOID_DoubleValue maxThrustWeight = new VOID_DoubleValue( + "T:W Ratio", + delegate() + { + if (SimManager.LastStage == null) + { + return double.NaN; + } + + return SimManager.LastStage.thrustToWeight; + }, + "" + ); + public static readonly VOID_StrValue currmaxThrustWeight = new VOID_StrValue( "T:W (curr/max)", delegate() @@ -185,35 +238,25 @@ if (SimManager.Stages == null || SimManager.LastStage == null) return "N/A"; - double currThrust = SimManager.LastStage.actualThrust; + return string.Format( + "{0} / {1}", + (VOID_Data.currThrustWeight.Value).ToString("F2"), + (VOID_Data.maxThrustWeight.Value).ToString("F2") + ); + } + ); + + public static readonly VOID_DoubleValue surfaceThrustWeight = new VOID_DoubleValue( + "Max T:W @ surface", + delegate() + { + if (SimManager.Stages == null || SimManager.LastStage == null) + return double.NaN; + double maxThrust = SimManager.LastStage.thrust; double mass = SimManager.LastStage.totalMass; - double gravity = VOID_Core.Instance.vessel.mainBody.gravParameter / - Math.Pow( - VOID_Core.Instance.vessel.mainBody.Radius + VOID_Core.Instance.vessel.altitude, - 2 - ); - double weight = mass * gravity; - - return string.Format( - "{0} / {1}", - (currThrust / weight).ToString("F2"), - (maxThrust / weight).ToString("F2") - ); - } - ); - - public static readonly VOID_DoubleValue surfaceThrustWeight = new VOID_DoubleValue( - "Max T:W @ surface", - delegate() - { - if (SimManager.Stages == null || SimManager.LastStage == null) - return double.NaN; - - double maxThrust = SimManager.LastStage.thrust; - double mass = SimManager.LastStage.totalMass; - double gravity = (VOID_Core.Constant_G * VOID_Core.Instance.vessel.mainBody.Mass) / - Math.Pow(VOID_Core.Instance.vessel.mainBody.Radius, 2); + double gravity = (VOID_Core.Constant_G * core.vessel.mainBody.Mass) / + (core.vessel.mainBody.Radius * core.vessel.mainBody.Radius); double weight = mass * gravity; return maxThrust / weight; @@ -231,7 +274,7 @@ currentAmount = 0d; currentRequirement = 0d; - foreach (Part part in VOID_Core.Instance.vessel.Parts) + foreach (Part part in core.vessel.Parts) { if (part.enabled) { --- a/VOID_VesselRegister.cs +++ b/VOID_VesselRegister.cs @@ -69,7 +69,7 @@ public override void ModuleWindow(int _) { - if (!VOID_Core.Instance.allVesselTypes.Any()) + if (!this.core.allVesselTypes.Any()) { return; } @@ -80,33 +80,33 @@ if (GUILayout.Button("<")) { selectedBodyIdx--; - if (selectedBodyIdx < 0) selectedBodyIdx = VOID_Core.Instance.allBodies.Count - 1; + if (selectedBodyIdx < 0) selectedBodyIdx = this.core.allBodies.Count - 1; } - GUILayout.Label(VOID_Core.Instance.allBodies[selectedBodyIdx].bodyName, VOID_Core.Instance.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); + GUILayout.Label(this.core.allBodies[selectedBodyIdx].bodyName, this.core.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); if (GUILayout.Button(">")) { selectedBodyIdx++; - if (selectedBodyIdx > VOID_Core.Instance.allBodies.Count - 1) selectedBodyIdx = 0; + if (selectedBodyIdx > this.core.allBodies.Count - 1) selectedBodyIdx = 0; } GUILayout.EndHorizontal(); - seletedBody = VOID_Core.Instance.allBodies[selectedBodyIdx]; + seletedBody = this.core.allBodies[selectedBodyIdx]; GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); if (GUILayout.Button("<")) { selectedVesselTypeIdx--; - if (selectedVesselTypeIdx < 0) selectedVesselTypeIdx = VOID_Core.Instance.allVesselTypes.Count - 1; + if (selectedVesselTypeIdx < 0) selectedVesselTypeIdx = this.core.allVesselTypes.Count - 1; } - GUILayout.Label(VOID_Core.Instance.allVesselTypes[selectedVesselTypeIdx].ToString(), VOID_Core.Instance.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); + GUILayout.Label(this.core.allVesselTypes[selectedVesselTypeIdx].ToString(), this.core.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); if (GUILayout.Button(">")) { selectedVesselTypeIdx++; - if (selectedVesselTypeIdx > VOID_Core.Instance.allVesselTypes.Count - 1) selectedVesselTypeIdx = 0; + if (selectedVesselTypeIdx > this.core.allVesselTypes.Count - 1) selectedVesselTypeIdx = 0; } GUILayout.EndHorizontal(); - selectedVesselType = VOID_Core.Instance.allVesselTypes[selectedVesselTypeIdx]; + selectedVesselType = this.core.allVesselTypes[selectedVesselTypeIdx]; GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); if (GUILayout.Button("Landed", GUILayout.ExpandWidth(true))) vesselSituation = "Landed"; @@ -116,7 +116,7 @@ GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.Label( VOID_Tools.UppercaseFirst(vesselSituation) + " " + selectedVesselType.ToString() + "s @ " + seletedBody.bodyName, - VOID_Core.Instance.LabelStyles["center"], + this.core.LabelStyles["center"], GUILayout.ExpandWidth(true)); GUILayout.EndHorizontal(); @@ -142,7 +142,7 @@ if (_selectedVessel != v) { _selectedVessel = v; //set clicked vessel as selected_vessel - this._Active.value = true; //turn bool on to open the window if closed + this.toggleActive = true; //turn bool on to open the window if closed } else {