New module: VOID_HUDAdvanced. Kinda ugly right now.
[VOID.git] / VOID_HUDAdvanced.cs
blob:a/VOID_HUDAdvanced.cs -> blob:b/VOID_HUDAdvanced.cs
--- a/VOID_HUDAdvanced.cs
+++ b/VOID_HUDAdvanced.cs
@@ -78,12 +78,20 @@
 		{
 			this._Name = "Advanced Heads-Up Display";
 
-			this._Active.value = true;
-
-			this.leftHUDdefaultPos = new Rect(Screen.width * .375f - 300f, Screen.height * .5f, 300f, 90f);
+			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 * .625f, Screen.height * .5f, 300f, 90f);
+			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;
@@ -97,9 +105,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(
 					string.Intern("Mass: {0}\n"),
@@ -122,17 +130,25 @@
 				);
 
 				leftHUD.AppendFormat(
-					string.Intern("Ang Vel: {0}"),
+					string.Intern("Ang Vel: {0}\n"),
 					VOID_Data.vesselAngularVelocity.ToSIString(2)
 				);
-			}
-			else
-			{
-				VOID_Core.Instance.LabelStyles["hud"].normal.textColor = Color.red;
+
+				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(), VOID_Core.Instance.LabelStyles["hud"], GUILayout.ExpandWidth(true));
+			GUILayout.Label(leftHUD.ToString(), this.core.LabelStyles["hud"], GUILayout.ExpandWidth(true));
 
 			if (!this.positionsLocked)
 			{
@@ -148,9 +164,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(
 					"Burn Δv (Rem/Tot): {0} / {1}\n",
@@ -170,21 +186,28 @@
 					VOID_Tools.ConvertInterval(VOID_Data.currentNodeBurnDuration.Value)
 				);
 
-				rightHUD.AppendFormat("Start T - {0} (done @ node)\n",
-					VOID_Data.burnTimeDoneAtNode.Value
-				);
-
-				rightHUD.AppendFormat("Start T - {0} (½ done @ node)",
-					VOID_Data.burnTimeHalfDoneAtNode.Value
-				);
-			}
-			else
-			{
-				VOID_Core.Instance.LabelStyles["hud"].normal.textColor = Color.red;
+				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(), VOID_Core.Instance.LabelStyles["hud"], GUILayout.ExpandWidth(true));
+			GUILayout.Label(rightHUD.ToString(), this.core.LabelStyles["hud"], GUILayout.ExpandWidth(true));
 
 			if (!this.positionsLocked)
 			{
@@ -198,7 +221,7 @@
 		{
 			if (this.primaryHUD == null)
 			{
-				foreach (IVOID_Module module in VOID_Core.Instance.Modules)
+				foreach (IVOID_Module module in this.core.Modules)
 				{
 					if (module is VOID_HUD)
 					{
@@ -214,9 +237,9 @@
 				}
 
 				this.leftHUDPos.value = GUI.Window(
-					VOID_Core.Instance.windowID,
+					this.core.windowID,
 					this.leftHUDPos,
-					this.leftHUDWindow,
+					VOID_Tools.GetWindowHandler(this.leftHUDWindow),
 					GUIContent.none,
 					GUIStyle.none
 				);
@@ -224,9 +247,9 @@
 				if (VOID_Data.upcomingManeuverNodes > 0)
 				{
 					this.rightHUDPos.value = GUI.Window(
-						VOID_Core.Instance.windowID,
+						this.core.windowID,
 						this.rightHUDPos,
-						this.rightHUDWindow,
+						VOID_Tools.GetWindowHandler(this.rightHUDWindow),
 						GUIContent.none,
 						GUIStyle.none
 					);
@@ -237,7 +260,7 @@
 		public override void DrawConfigurables()
 		{
 			this.positionsLocked = GUILayout.Toggle(this.positionsLocked,
-				string.Intern("Lock HUDAdvanced Positions"),
+				string.Intern("Lock Advanced HUD Positions"),
 				GUILayout.ExpandWidth(false));
 		}
 	}
@@ -260,23 +283,25 @@
 			}
 		}
 
-		public static readonly VOID_DoubleValue vesselThrustOffset = new VOID_DoubleValue(
+		public static readonly VOID_Vector3dValue vesselThrustOffset = new VOID_Vector3dValue(
 			"Thrust Offset",
 			delegate()
 		{
 			if (core.vessel == null)
 			{
-				return double.NaN;
+				return Vector3d.zero;
 			}
 
 			List<PartModule> engineModules = core.vessel.getModulesOfType<PartModule>();
 
 			Vector3d thrustPos = Vector3d.zero;
 			Vector3d thrustDir = Vector3d.zero;
-			double thrust = 0;
+			float thrust = 0;
 
 			foreach (PartModule engine in engineModules)
 			{
+				float moduleThrust = 0;
+
 				switch (engine.moduleName)
 				{
 					case "ModuleEngines":
@@ -297,13 +322,22 @@
 				{
 					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;
@@ -311,11 +345,32 @@
 				thrust += cotQuery.thrust;
 			}
 
-			if (thrust > 0)
+			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"
 		);
@@ -323,7 +378,7 @@
 		public static readonly VOID_DoubleValue vesselAccel = new VOID_DoubleValue(
 			"Acceleration",
 			() => geeForce * KerbinGee,
-			"m/s"
+			"m/s²"
 		);
 
 		public static readonly VOID_IntValue vesselCrewCount = new VOID_IntValue(
@@ -378,18 +433,18 @@
 			"Nominal Stage Thrust",
 			delegate()
 		{
-			if (SimManager.LastStage == null)
+			if (core.LastStage == null)
 			{
 				return double.NaN;
 			}
 
-			if (SimManager.LastStage.actualThrust == 0d)
-			{
-				return SimManager.LastStage.thrust;
-			}
-			else
-			{
-				return SimManager.LastStage.actualThrust;
+			if (core.LastStage.actualThrust == 0d)
+			{
+				return core.LastStage.thrust;
+			}
+			else
+			{
+				return core.LastStage.actualThrust;
 			}
 		},
 			"kN"
@@ -399,12 +454,12 @@
 			"Stage Mass Flow",
 			delegate()
 			{
-				if (SimManager.LastStage == null)
+				if (core.LastStage == null)
 				{
 					return double.NaN;
 				}
 
-			double stageIsp = SimManager.LastStage.isp;
+			double stageIsp = core.LastStage.isp;
 			double stageThrust = stageNominalThrust;
 
 			Tools.PostDebugMessage(typeof(VOID_Data), "calculating stageMassFlow from:\n" +
@@ -473,7 +528,7 @@
 			"Total Burn Time",
 			delegate()
 			{
-				if (SimManager.LastStage == null || currManeuverDeltaV.Value == double.NaN)
+				if (core.LastStage == null || currManeuverDeltaV.Value == double.NaN)
 				{
 					return double.NaN;
 				}
@@ -489,7 +544,7 @@
 			"Burn Time Remaining",
 			delegate()
 			{
-				if (SimManager.LastStage == null || currManeuverDVRemaining == double.NaN)
+				if (core.LastStage == null || currManeuverDVRemaining == double.NaN)
 				{
 					return double.NaN;
 				}
@@ -505,7 +560,7 @@
 			"Half Burn Time",
 			delegate()
 		{
-			if (SimManager.LastStage == null || currManeuverDeltaV.Value == double.NaN)
+			if (core.LastStage == null || currManeuverDeltaV.Value == double.NaN)
 			{
 				return double.NaN;
 			}
@@ -521,14 +576,40 @@
 			"Full burn time to be half done at node",
 			delegate()
 		{
-			if (SimManager.LastStage == null && upcomingManeuverNodes < 1)
+			if (core.LastStage == null && upcomingManeuverNodes < 1)
 			{
 				return "N/A";
 			}
 
 			ManeuverNode node = core.vessel.patchedConicSolver.maneuverNodes[0];
 
-			return VOID_Tools.ConvertInterval((node.UT - currentNodeBurnDuration) - Planetarium.GetUniversalTime());
+			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));
 		}
 		);
 
@@ -536,14 +617,40 @@
 			"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];
-
-			return VOID_Tools.ConvertInterval((node.UT - currentNodeHalfBurnDuration) - Planetarium.GetUniversalTime());
+			if (core.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();
+
+			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));
 			}
 		);