Added calls to UpdateModSettings in relevant places
--- a/Documents/CHANGES.txt
+++ b/Documents/CHANGES.txt
@@ -1,4 +1,79 @@
-1.0.11.0
+1.0.14.1, 28-12-2014
+ Fixed: Missing texture on the ER-7500 model.
+
+1.0.14.0, 28-12-2014
+ Added: Career mode that limits the Flight Engineer by:
+ - Requiring an Engineer Kerbal of any level, or placement of an Engineer Chip or ER-7500 part.
+ - Tracking station level 3 enables Flight Engineer everywhere.
+
+ Added: New readouts to the orbital category:
+ - Mean Anomaly at Epoc
+
+ Added: New readouts to the miscellaneous category:
+ - System Time
+
+ Added: Editor Overlay Tab's X position is now changable in the BuildOverlay.xml settings file.
+ Changed: Editor Overlay Tabs start position moved over as to not overlap the parts menu.
+ Fixed: Bug where STAGE_PRIORITY_FLOW resources would not be corrently disabled/enabled.
+ Fixed: Issue with the formatting large Mass and Cost values.
+ Fixed: Error when loading the Engineer7500 part model.
+
+1.0.13.1, 16-12-2014
+ Fixed: Issue with manoeuvre node readouts and low tier tracking station.
+
+1.0.13.0, 16-12-2014
+ Updated for KSP version 0.90
+
+ Added: New readouts to the vessel category:
+ - Heading Rate
+ - Pitch Rate
+ - Roll Rate
+
+ Changed: Simulation to look for fuel lines that use CModuleFuelLine module.
+ Fixed: Editor Overlay now loads the saved visibility value properly.
+ Fixed: Altitude (Terrain) will no longer give a reading below sea level.
+ Fixed: Suicide burn now uses radar altitude that clamps to sea level.
+
+1.0.12.0, 01-12-2014
+ Added: Setting in Build Engineer to enable/disable vectored thrust calculations.
+ Added: Thrust torque field in Build Engineer (courtesy of mic_e).
+ Added: New readouts to the vessel category:
+ - Thrust Offset Angle (courtesy of mic_e)
+ - Thrust Torque (courtesy of mic_e)
+ - Part Count: stage/total
+ - Heading
+ - Pitch
+ - Roll
+
+ Added: New readouts to the surface category:
+ - Situation
+
+ Added: New readouts to the miscellaneous category:
+ - Vectored Thrust Toggle
+
+ Fixed: The category selection within the section editors now do not always reset back to 'Orbital'.
+ Fixed: Issue where the vessel simulation can sometimes permanently freeze.
+ Fixed: Issue where the vessel simulation would not show updates when the delay was set lower than the frame rate.
+
+1.0.11.3, 11-11-2014
+ Changed: Gravity measurements for Isp to 9.82.
+
+1.0.11.2, 10-11-2014
+ Changed: Gravity measurements for Isp calculations from 9.81 to 9.8066 for accuracy.
+ Changed: Manoeuvre node burn times are now more accurate.
+ Fixed: Bug in the manoeuvre node burn time calculations where it was not averaging acceleration correctly.
+
+1.0.11.1, 07-11-2014
+ Changed: Build Engineer now shows stage part count as well as total.
+ Changed: Build Overlay Vessel tab data:
+ DeltaV: stage / total
+ Mass: stage / total
+ TWR: start (max) <- shows for bottom stage only.
+ Parts: stage / total
+
+ Fixed: Issue with the vessel tab vanishing from the editor.
+
+1.0.11.0, 06-11-2014
Added: New readouts to the orbital category:
- Current SOI
- Manoeuvre Node DeltaV (Prograde)
@@ -15,6 +90,7 @@
Added: Readout help strings by ClassyJakey.
Fixed: Issue with separators in HUDs.
+ Fixed: Issue with HUDs with backgrounds that have no displayed lines.
Padishar's Fixes:
Fixed: Issue with multicouplers when attached to parent by bottom node.
--- a/KerbalEngineer/Editor/BuildAdvanced.cs
+++ b/KerbalEngineer/Editor/BuildAdvanced.cs
@@ -17,24 +17,22 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#region Using Directives
-
-using System;
-using System.Linq;
-
-using KerbalEngineer.Extensions;
-using KerbalEngineer.Flight;
-using KerbalEngineer.Helpers;
-using KerbalEngineer.Settings;
-using KerbalEngineer.UIControls;
-using KerbalEngineer.VesselSimulator;
-
-using UnityEngine;
-
-#endregion
-
namespace KerbalEngineer.Editor
{
+ #region Using Directives
+
+ using System;
+ using System.Linq;
+ using Extensions;
+ using Flight;
+ using Helpers;
+ using Settings;
+ using UIControls;
+ using UnityEngine;
+ using VesselSimulator;
+
+ #endregion
+
[KSPAddon(KSPAddon.Startup.EditorAny, false)]
public class BuildAdvanced : MonoBehaviour
{
@@ -124,7 +122,7 @@
#endregion
- #region Methods: protected
+ #region Methods
protected void Awake()
{
@@ -134,6 +132,10 @@
this.bodiesList = this.gameObject.AddComponent<DropDown>();
this.bodiesList.DrawCallback = this.DrawBodiesList;
this.Load();
+
+ SimManager.UpdateModSettings();
+ SimManager.OnReady -= this.GetStageInfo;
+ SimManager.OnReady += this.GetStageInfo;
}
catch (Exception ex)
{
@@ -171,17 +173,10 @@
{
try
{
- if (!this.visible || EditorLogic.fetch == null || EditorLogic.fetch.ship.parts.Count == 0 || EditorLogic.fetch.editorScreen != EditorLogic.EditorScreen.Parts)
+ if (!this.visible || EditorLogic.fetch == null || EditorLogic.fetch.ship.parts.Count == 0 || EditorLogic.fetch.editorScreen != EditorScreen.Parts)
{
return;
}
-
- if (SimManager.ResultsReady())
- {
- this.stages = SimManager.Stages;
- }
-
- SimManager.RequestSimulation();
if (this.stages == null)
{
@@ -269,6 +264,8 @@
}
SimManager.Velocity = this.atmosphericVelocity;
+
+ SimManager.RequestSimulation();
SimManager.TryStartSimulation();
}
catch (Exception ex)
@@ -276,10 +273,6 @@
Logger.Exception(ex, "BuildAdvanced->Update");
}
}
-
- #endregion
-
- #region Methods: private
/// <summary>
/// Checks whether the editor should be locked to stop click-through.
@@ -383,7 +376,7 @@
{
if (this.showAllStages || stage.deltaV > 0)
{
- GUILayout.Label(Units.Concat(stage.cost, stage.totalCost), this.infoStyle);
+ GUILayout.Label(Units.Cost(stage.cost, stage.totalCost), this.infoStyle);
}
}
GUILayout.EndVertical();
@@ -451,7 +444,7 @@
{
if (this.showAllStages || stage.deltaV > 0)
{
- GUILayout.Label(stage.partCount.ToString("N0"), this.infoStyle);
+ GUILayout.Label(stage.partCount + " / " + stage.totalPartCount, this.infoStyle);
}
}
GUILayout.EndVertical();
@@ -466,6 +459,11 @@
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, "RIGHT", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal();
+ GUILayout.Label("Simulate using vectored thrust values:");
+ SimManager.vectoredThrust = GUILayout.Toggle(SimManager.vectoredThrust, "ENABLED", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
@@ -477,8 +475,14 @@
GUILayout.BeginHorizontal();
GUILayout.Label("Flight Engineer activation mode:", this.settingStyle);
- FlightEngineerPartless.IsPartless = GUILayout.Toggle(FlightEngineerPartless.IsPartless, "PARTLESS", this.buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
- FlightEngineerPartless.IsPartless = !GUILayout.Toggle(!FlightEngineerPartless.IsPartless, "MODULE", 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));
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal();
+ GUILayout.Label("Flight Engineer Career Limitations:", this.settingStyle);
+ 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));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
@@ -493,9 +497,9 @@
}
GUILayout.EndHorizontal();
- GUILayout.Label("Minimum delay between simulations: " + SimManager.minSimTime + "ms", this.settingStyle);
+ GUILayout.Label("Minimum delay between simulations: " + SimManager.minSimTime.Milliseconds + "ms", this.settingStyle);
GUI.skin = HighLogic.Skin;
- SimManager.minSimTime = (long)GUILayout.HorizontalSlider(SimManager.minSimTime, 0, 2000.0f);
+ SimManager.minSimTime = new TimeSpan(0, 0, 0, 0, (int)GUILayout.HorizontalSlider(SimManager.minSimTime.Milliseconds, 0, 2000.0f));
GUI.skin = null;
}
@@ -528,6 +532,23 @@
if (this.showAllStages || stage.deltaV > 0)
{
GUILayout.Label(stage.thrust.ToForce(), this.infoStyle);
+ }
+ }
+ GUILayout.EndVertical();
+ }
+
+ /// <summary>
+ /// Draws the torque column.
+ /// </summary>
+ private void DrawTorque()
+ {
+ GUILayout.BeginVertical(GUILayout.Width(75.0f * GuiDisplaySize.Offset));
+ GUILayout.Label("TORQUE", this.titleStyle);
+ foreach (var stage in this.stages)
+ {
+ if (this.showAllStages || stage.deltaV > 0)
+ {
+ GUILayout.Label(stage.maxThrustTorque.ToTorque(), this.infoStyle);
}
}
GUILayout.EndVertical();
@@ -564,6 +585,11 @@
BuildOverlayPartInfo.Hidden = false;
this.isEditorLocked = false;
}
+ }
+
+ private void GetStageInfo()
+ {
+ this.stages = SimManager.Stages;
}
/// <summary>
@@ -738,6 +764,7 @@
this.DrawMass();
this.DrawIsp();
this.DrawThrust();
+ this.DrawTorque();
this.DrawTwr();
this.DrawDeltaV();
this.DrawBurnTime();
--- a/KerbalEngineer/Editor/BuildOverlay.cs
+++ b/KerbalEngineer/Editor/BuildOverlay.cs
@@ -19,17 +19,21 @@
#region Using Directives
-using System;
-
-using KerbalEngineer.Helpers;
-using KerbalEngineer.Settings;
-
-using UnityEngine;
+
#endregion
namespace KerbalEngineer.Editor
{
+ #region Using Directives
+
+ using System;
+ using Helpers;
+ using Settings;
+ using UnityEngine;
+
+ #endregion
+
[KSPAddon(KSPAddon.Startup.EditorAny, false)]
public class BuildOverlay : MonoBehaviour
{
@@ -191,16 +195,17 @@
#endregion
- #region Methods: public
+ #region Methods
public static void Load()
{
var handler = SettingHandler.Load("BuildOverlay.xml");
- handler.GetSet("visible", Visible);
+ Visible = handler.GetSet("visible", Visible);
BuildOverlayPartInfo.NamesOnly = handler.GetSet("namesOnly", BuildOverlayPartInfo.NamesOnly);
BuildOverlayPartInfo.ClickToOpen = handler.GetSet("clickToOpen", BuildOverlayPartInfo.ClickToOpen);
buildOverlayVessel.Open = handler.GetSet("vesselOpen", buildOverlayVessel.Open);
buildOverlayResources.Open = handler.GetSet("resourcesOpen", buildOverlayResources.Open);
+ buildOverlayVessel.WindowX = handler.GetSet("vesselWindowX", buildOverlayVessel.WindowX);
handler.Save("BuildOverlay.xml");
}
@@ -212,12 +217,9 @@
handler.Set("clickToOpen", BuildOverlayPartInfo.ClickToOpen);
handler.Set("vesselOpen", buildOverlayVessel.Open);
handler.Set("resourcesOpen", buildOverlayResources.Open);
+ handler.Set("vesselWindowX", buildOverlayVessel.WindowX);
handler.Save("BuildOverlay.xml");
}
-
- #endregion
-
- #region Methods: protected
protected void Awake()
{
--- a/KerbalEngineer/Editor/BuildOverlayPartInfo.cs
+++ b/KerbalEngineer/Editor/BuildOverlayPartInfo.cs
@@ -97,7 +97,7 @@
{
try
{
- if (!Visible || Hidden || EditorLogic.startPod == null || EditorLogic.fetch.editorScreen != EditorLogic.EditorScreen.Parts)
+ if (!Visible || Hidden || EditorLogic.RootPart == null || EditorLogic.fetch.editorScreen != EditorScreen.Parts)
{
return;
}
@@ -195,7 +195,7 @@
private void SetCostInfo()
{
- this.infoItems.Add(new PartInfoItem("Cost", Units.Concat(this.selectedPart.GetCostDry(), this.selectedPart.GetCostWet())));
+ this.infoItems.Add(new PartInfoItem("Cost", Units.ConcatF(this.selectedPart.GetCostDry(), this.selectedPart.GetCostWet())));
}
private void SetDecouplerInfo()
@@ -222,7 +222,7 @@
var engine = this.selectedPart.GetProtoModuleEngine();
this.infoItems.Add(new PartInfoItem("Thrust", Units.ToForce(engine.MinimumThrust, engine.MaximumThrust)));
- this.infoItems.Add(new PartInfoItem("Isp", Units.Concat(engine.GetSpecificImpulse(1.0f), engine.GetSpecificImpulse(0.0f)) + "s"));
+ this.infoItems.Add(new PartInfoItem("Isp", Units.ConcatF(engine.GetSpecificImpulse(1.0f), engine.GetSpecificImpulse(0.0f)) + "s"));
if (engine.Propellants.Count > 0)
{
this.infoItems.Add(new PartInfoItem("Propellants"));
@@ -291,7 +291,7 @@
}
var parachute = this.selectedPart.GetModule<ModuleParachute>();
- this.infoItems.Add(new PartInfoItem("Deployed Drag", Units.Concat(parachute.semiDeployedDrag, parachute.fullyDeployedDrag)));
+ this.infoItems.Add(new PartInfoItem("Deployed Drag", Units.ConcatF(parachute.semiDeployedDrag, parachute.fullyDeployedDrag)));
this.infoItems.Add(new PartInfoItem("Deployment Altitude", parachute.deployAltitude.ToDistance()));
this.infoItems.Add(new PartInfoItem("Deployment Pressure", parachute.minAirPressureToOpen.ToString("F2")));
}
@@ -305,7 +305,7 @@
var rcs = this.selectedPart.GetModule<ModuleRCS>();
this.infoItems.Add(new PartInfoItem("Thruster Power", rcs.thrusterPower.ToForce()));
- this.infoItems.Add(new PartInfoItem("Specific Impulse", Units.Concat(rcs.atmosphereCurve.Evaluate(1.0f), rcs.atmosphereCurve.Evaluate(0.0f)) + "s"));
+ this.infoItems.Add(new PartInfoItem("Specific Impulse", Units.ConcatF(rcs.atmosphereCurve.Evaluate(1.0f), rcs.atmosphereCurve.Evaluate(0.0f)) + "s"));
}
private void SetReactionWheelInfo()
@@ -317,9 +317,9 @@
var reactionWheel = this.selectedPart.GetModule<ModuleReactionWheel>();
this.infoItems.Add(new PartInfoItem("Reaction Wheel Torque"));
- this.infoItems.Add(new PartInfoItem("\tPitch", reactionWheel.PitchTorque.ToForce()));
- this.infoItems.Add(new PartInfoItem("\tRoll", reactionWheel.RollTorque.ToForce()));
- this.infoItems.Add(new PartInfoItem("\tYaw", reactionWheel.YawTorque.ToForce()));
+ this.infoItems.Add(new PartInfoItem("\tPitch", reactionWheel.PitchTorque.ToTorque()));
+ this.infoItems.Add(new PartInfoItem("\tRoll", reactionWheel.RollTorque.ToTorque()));
+ this.infoItems.Add(new PartInfoItem("\tYaw", reactionWheel.YawTorque.ToTorque()));
foreach (var resource in reactionWheel.inputResources)
{
this.infoItems.Add(new PartInfoItem("\t" + resource.name, resource.rate.ToRate()));
--- a/KerbalEngineer/Editor/BuildOverlayResources.cs
+++ b/KerbalEngineer/Editor/BuildOverlayResources.cs
@@ -70,7 +70,7 @@
{
try
{
- if (!BuildOverlay.Visible || this.resources.Count == 0 || EditorLogic.fetch.editorScreen != EditorLogic.EditorScreen.Parts)
+ if (!Visible || this.resources.Count == 0 || EditorLogic.fetch.editorScreen != EditorScreen.Parts)
{
return;
}
@@ -104,7 +104,7 @@
{
try
{
- if (!BuildOverlay.Visible)
+ if (!Visible)
{
return;
}
--- a/KerbalEngineer/Editor/BuildOverlayVessel.cs
+++ b/KerbalEngineer/Editor/BuildOverlayVessel.cs
@@ -19,20 +19,28 @@
#region Using Directives
-using System;
-using System.Collections.Generic;
-
-using KerbalEngineer.Extensions;
-using KerbalEngineer.VesselSimulator;
-
-using UnityEngine;
-
#endregion
namespace KerbalEngineer.Editor
{
+ #region Using Directives
+
+ using System;
+ using System.Collections.Generic;
+ using Helpers;
+ using UnityEngine;
+ using VesselSimulator;
+
+ #endregion
+
public class BuildOverlayVessel : MonoBehaviour
{
+ #region Constants
+
+ private const float Width = 175.0f;
+
+ #endregion
+
#region Fields
private static bool visible = true;
@@ -45,7 +53,7 @@
private GUIContent tabContent;
private Rect tabPosition;
private Vector2 tabSize;
- private Rect windowPosition = new Rect(300.0f, 0.0f, BuildOverlay.MinimumWidth, 0.0f);
+ private Rect windowPosition = new Rect(330.0f, 0.0f, Width, 0.0f);
#endregion
@@ -68,15 +76,34 @@
get { return this.windowPosition; }
}
- #endregion
-
- #region Methods: protected
+ public float WindowX
+ {
+ get { return this.windowPosition.x; }
+ set { this.windowPosition.x = value; }
+ }
+
+ #endregion
+
+ #region Methods
+
+ protected void Awake()
+ {
+ try
+ {
+ SimManager.OnReady -= this.GetStageInfo;
+ SimManager.OnReady += this.GetStageInfo;
+ }
+ catch (Exception ex)
+ {
+ Logger.Exception(ex);
+ }
+ }
protected void OnGUI()
{
try
{
- if (!Visible || EditorLogic.startPod == null || this.lastStage == null || EditorLogic.fetch.editorScreen != EditorLogic.EditorScreen.Parts)
+ if (!Visible || EditorLogic.RootPart == null || EditorLogic.fetch.editorScreen != EditorScreen.Parts)
{
return;
}
@@ -110,7 +137,7 @@
{
try
{
- if (!BuildOverlay.Visible || EditorLogic.startPod == null)
+ if (!Visible || EditorLogic.RootPart == null)
{
return;
}
@@ -128,9 +155,10 @@
}
}
- #endregion
-
- #region Methods: private
+ private void GetStageInfo()
+ {
+ this.lastStage = SimManager.LastStage;
+ }
private void SetSlidePosition()
{
@@ -144,6 +172,10 @@
}
this.windowPosition.y = Mathf.Lerp(Screen.height, Screen.height - this.windowPosition.height, this.openPercent);
+ if (this.windowPosition.width < Width)
+ {
+ this.windowPosition.width = Width;
+ }
this.tabPosition.width = this.tabSize.x;
this.tabPosition.height = this.tabSize.y;
this.tabPosition.x = this.windowPosition.x;
@@ -166,18 +198,13 @@
SimManager.RequestSimulation();
SimManager.TryStartSimulation();
- if (SimManager.ResultsReady())
- {
- this.lastStage = SimManager.LastStage;
- }
-
if (this.lastStage != null)
{
this.infoItems.Clear();
- this.infoItems.Add(new PartInfoItem("Delta-V", this.lastStage.totalDeltaV.ToString("N0") + "m/s"));
- this.infoItems.Add(new PartInfoItem("Mass", this.lastStage.totalMass.ToMass()));
- this.infoItems.Add(new PartInfoItem("TWR", this.lastStage.thrustToWeight.ToString("F2")));
- this.infoItems.Add(new PartInfoItem("Parts", this.lastStage.partCount.ToString("N0")));
+ this.infoItems.Add(new PartInfoItem("Delta-V", this.lastStage.deltaV.ToString("N0") + " / " + this.lastStage.totalDeltaV.ToString("N0") + "m/s"));
+ this.infoItems.Add(new PartInfoItem("Mass", Units.ToMass(this.lastStage.mass, this.lastStage.totalMass)));
+ this.infoItems.Add(new PartInfoItem("TWR", this.lastStage.thrustToWeight.ToString("F2") + " (" + this.lastStage.maxThrustToWeight.ToString("F2") + ")"));
+ this.infoItems.Add(new PartInfoItem("Parts", this.lastStage.partCount + " / " + this.lastStage.totalPartCount));
}
}
@@ -198,7 +225,7 @@
if (item.Value != null)
{
GUILayout.Label(item.Name + ":", BuildOverlay.NameStyle);
- GUILayout.Space(50.0f);
+ GUILayout.FlexibleSpace();
GUILayout.Label(item.Value, BuildOverlay.ValueStyle);
}
else
--- a/KerbalEngineer/EngineerGlobals.cs
+++ b/KerbalEngineer/EngineerGlobals.cs
@@ -33,7 +33,7 @@
/// <summary>
/// Current version of the Kerbal Engineer assembly.
/// </summary>
- public const string AssemblyVersion = "1.0.11";
+ public const string AssemblyVersion = "1.0.14.1";
#endregion
--- a/KerbalEngineer/Extensions/DoubleExtensions.cs
+++ b/KerbalEngineer/Extensions/DoubleExtensions.cs
@@ -29,6 +29,11 @@
{
#region Methods: public
+ public static double Clamp(this double value, double lower, double higher)
+ {
+ return value < lower ? lower : value > higher ? higher : value;
+ }
+
public static string ToAcceleration(this double value)
{
return Units.ToAcceleration(value);
@@ -42,6 +47,11 @@
public static string ToDistance(this double value)
{
return Units.ToDistance(value);
+ }
+
+ public static string ToTorque(this double value)
+ {
+ return Units.ToTorque(value);
}
public static string ToForce(this double value)
--- a/KerbalEngineer/Extensions/FloatExtensions.cs
+++ b/KerbalEngineer/Extensions/FloatExtensions.cs
@@ -49,6 +49,11 @@
return Units.ToForce(value);
}
+ public static string ToTorque(this float value)
+ {
+ return Units.ToTorque(value);
+ }
+
public static string ToMass(this float value)
{
return Units.ToMass(value);
--- a/KerbalEngineer/Extensions/PartExtensions.cs
+++ b/KerbalEngineer/Extensions/PartExtensions.cs
@@ -27,6 +27,8 @@
namespace KerbalEngineer.Extensions
{
+ using CompoundParts;
+
public static class PartExtensions
{
#region Methods: public
@@ -69,7 +71,7 @@
/// </summary>
public static double GetCostDry(this Part part)
{
- return part.partInfo.cost - GetResourceCostMax(part) + part.GetModuleCosts();
+ return part.partInfo.cost - GetResourceCostMax(part) + part.GetModuleCosts(0.0f);
}
/// <summary>
@@ -77,7 +79,7 @@
/// </summary>
public static double GetCostMax(this Part part)
{
- return part.partInfo.cost + part.GetModuleCosts();
+ return part.partInfo.cost + part.GetModuleCosts(0.0f);
}
/// <summary>
@@ -85,7 +87,7 @@
/// </summary>
public static double GetCostWet(this Part part)
{
- return part.partInfo.cost - GetResourceCostInverted(part) + part.GetModuleCosts();
+ return part.partInfo.cost - GetResourceCostInverted(part) + part.GetModuleCosts(0.0f);
}
/// <summary>
@@ -387,7 +389,7 @@
/// </summary>
public static bool IsFuelLine(this Part part)
{
- return (part is FuelLine);
+ return (HasModule<CModuleFuelLine>(part));
}
/// <summary>
--- a/KerbalEngineer/Flight/ActionMenu.cs
+++ b/KerbalEngineer/Flight/ActionMenu.cs
@@ -79,11 +79,11 @@
{
return;
}
- if (FlightEngineerCore.Instance != null && this.button.State == RUIToggleButton.ButtonState.DISABLED)
+ if (FlightEngineerCore.IsDisplayable && this.button.State == RUIToggleButton.ButtonState.DISABLED)
{
this.button.Enable();
}
- else if (FlightEngineerCore.Instance == null && this.button.State != RUIToggleButton.ButtonState.DISABLED)
+ else if (!FlightEngineerCore.IsDisplayable && this.button.State != RUIToggleButton.ButtonState.DISABLED)
{
this.button.Disable();
}
--- a/KerbalEngineer/Flight/ActionMenuGui.cs
+++ b/KerbalEngineer/Flight/ActionMenuGui.cs
@@ -132,7 +132,7 @@
{
try
{
- if (this.Hidden)
+ if (this.Hidden || !FlightEngineerCore.IsDisplayable)
{
return;
}
--- a/KerbalEngineer/Flight/DisplayStack.cs
+++ b/KerbalEngineer/Flight/DisplayStack.cs
@@ -33,6 +33,8 @@
namespace KerbalEngineer.Flight
{
+ using Upgradeables;
+
/// <summary>
/// Graphical controller for displaying stacked sections.
/// </summary>
@@ -150,7 +152,7 @@
{
try
{
- if (FlightEngineerCore.Instance == null)
+ if (!FlightEngineerCore.IsDisplayable)
{
return;
}
@@ -177,7 +179,7 @@
{
try
{
- if (FlightEngineerCore.Instance == null)
+ if (!FlightEngineerCore.IsDisplayable)
{
return;
}
--- a/KerbalEngineer/Flight/FlightEngineerCore.cs
+++ b/KerbalEngineer/Flight/FlightEngineerCore.cs
@@ -19,21 +19,28 @@
#region Using Directives
-using System;
-using System.Collections.Generic;
-
-using KerbalEngineer.Flight.Readouts;
-using KerbalEngineer.Flight.Sections;
-
-using UnityEngine;
-
#endregion
namespace KerbalEngineer.Flight
{
+ #region Using Directives
+
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using Extensions;
+ using Readouts;
+ using Sections;
+ using Settings;
+ using UnityEngine;
+ using VesselSimulator;
+
+ #endregion
+
/// <summary>
/// Core management system for the Flight Engineer.
/// </summary>
+ [KSPAddon(KSPAddon.Startup.Flight, false)]
public sealed class FlightEngineerCore : MonoBehaviour
{
#region Instance
@@ -45,7 +52,210 @@
#endregion
+ #region Fields
+
+ private static bool isCareerMode = true;
+ private static bool isKerbalLimited = true;
+ private static bool isTrackingStationLimited = true;
+
+ #endregion
+
#region Constructors
+
+ static FlightEngineerCore()
+ {
+ try
+ {
+ var handler = SettingHandler.Load("FlightEngineerCore.xml");
+ handler.Get("isCareerMode", ref isCareerMode);
+ handler.Get("isKerbalLimited", ref isKerbalLimited);
+ handler.Get("isTrackingStationLimited", ref isTrackingStationLimited);
+ }
+ catch (Exception ex)
+ {
+ Logger.Exception(ex);
+ }
+ }
+
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Gets and sets whether to the Flight Engineer should be run using career limitations.
+ /// </summary>
+ public static bool IsCareerMode
+ {
+ get { return isCareerMode; }
+ set
+ {
+ try
+ {
+ if (isCareerMode != value)
+ {
+ var handler = SettingHandler.Load("FlightEngineerCore.xml");
+ handler.Set("isCareerMode", value);
+ handler.Save("FlightEngineerCore.xml");
+ }
+ isCareerMode = value;
+ }
+ catch (Exception ex)
+ {
+ Logger.Exception(ex);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets whether the FlightEngineer should be displayed.
+ /// </summary>
+ public static bool IsDisplayable
+ {
+ get
+ {
+ if (isCareerMode)
+ {
+ if (isKerbalLimited && FlightGlobals.ActiveVessel.GetVesselCrew().Exists(c => c.experienceTrait.TypeName == "Engineer"))
+ {
+ return true;
+ }
+ if (isTrackingStationLimited && ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.TrackingStation) == 1.0f)
+ {
+ return true;
+ }
+ return FlightGlobals.ActiveVessel.parts.Any(p => p.HasModule<FlightEngineerModule>());
+ }
+
+ return true;
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets whether to the Flight Engineer should be kerbal limited.
+ /// </summary>
+ public static bool IsKerbalLimited
+ {
+ get { return isKerbalLimited; }
+ set
+ {
+ try
+ {
+ if (isKerbalLimited != value)
+ {
+ var handler = SettingHandler.Load("FlightEngineerCore.xml");
+ handler.Set("isKerbalLimited", value);
+ handler.Save("FlightEngineerCore.xml");
+ }
+ isKerbalLimited = value;
+ }
+ catch (Exception ex)
+ {
+ Logger.Exception(ex);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets whether to the Flight Engineer should be tracking station limited.
+ /// </summary>
+ public static bool IsTrackingStationLimited
+ {
+ get { return isTrackingStationLimited; }
+ set
+ {
+ try
+ {
+ if (isTrackingStationLimited != value)
+ {
+ var handler = SettingHandler.Load("FlightEngineerCore.xml");
+ handler.Set("isTrackingStationLimited", value);
+ handler.Save("FlightEngineerCore.xml");
+ }
+ isTrackingStationLimited = value;
+ }
+ catch (Exception ex)
+ {
+ Logger.Exception(ex);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the editor windows for sections with open editors.
+ /// </summary>
+ public List<SectionEditor> SectionEditors { get; private set; }
+
+ /// <summary>
+ /// Gets the section windows for floating sections.
+ /// </summary>
+ public List<SectionWindow> SectionWindows { get; private set; }
+
+ /// <summary>
+ /// Gets the list of currently running updatable modules.
+ /// </summary>
+ public List<IUpdatable> UpdatableModules { get; private set; }
+
+ #endregion
+
+ #region Methods
+
+ /// <summary>
+ /// Creates a section editor, adds it to the FlightEngineerCore and returns a reference to it.
+ /// </summary>
+ public SectionEditor AddSectionEditor(SectionModule section)
+ {
+ try
+ {
+ var editor = this.gameObject.AddComponent<SectionEditor>();
+ editor.ParentSection = section;
+ editor.Position = new Rect(section.EditorPositionX, section.EditorPositionY, SectionEditor.Width, SectionEditor.Height);
+ this.SectionEditors.Add(editor);
+ return editor;
+ }
+ catch (Exception ex)
+ {
+ Logger.Exception(ex);
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Creates a section window, adds it to the FlightEngineerCore and returns a reference to it.
+ /// </summary>
+ public SectionWindow AddSectionWindow(SectionModule section)
+ {
+ try
+ {
+ var window = this.gameObject.AddComponent<SectionWindow>();
+ window.ParentSection = section;
+ window.WindowPosition = new Rect(section.FloatingPositionX, section.FloatingPositionY, 0, 0);
+ this.SectionWindows.Add(window);
+ return window;
+ }
+ catch (Exception ex)
+ {
+ Logger.Exception(ex);
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Adds an updatable object to be automatically updated every frame and will ignore duplicate objects.
+ /// </summary>
+ public void AddUpdatable(IUpdatable updatable)
+ {
+ try
+ {
+ if (!this.UpdatableModules.Contains(updatable))
+ {
+ this.UpdatableModules.Add(updatable);
+ }
+ }
+ catch (Exception ex)
+ {
+ Logger.Exception(ex);
+ }
+ }
/// <summary>
/// Create base Flight Engineer child objects.
@@ -59,11 +269,58 @@
this.SectionWindows = new List<SectionWindow>();
this.SectionEditors = new List<SectionEditor>();
this.UpdatableModules = new List<IUpdatable>();
+
+ SimManager.UpdateModSettings();
+
Logger.Log("FlightEngineerCore->Awake");
}
catch (Exception ex)
{
- Logger.Exception(ex, "FlightEngineerCore->Awake");
+ Logger.Exception(ex);
+ }
+ }
+
+ /// <summary>
+ /// Fixed update all required Flight Engineer objects.
+ /// </summary>
+ private void FixedUpdate()
+ {
+ try
+ {
+ SectionLibrary.FixedUpdate();
+ }
+ catch (Exception ex)
+ {
+ Logger.Exception(ex);
+ }
+ }
+
+ /// <summary>
+ /// Force the destruction of child objects on core destruction.
+ /// </summary>
+ private void OnDestroy()
+ {
+ try
+ {
+ SectionLibrary.Save();
+
+ foreach (var window in this.SectionWindows)
+ {
+ print("[FlightEngineer]: Destroying Floating Window for " + window.ParentSection.Name);
+ Destroy(window);
+ }
+
+ foreach (var editor in this.SectionEditors)
+ {
+ print("[FlightEngineer]: Destroying Editor Window for " + editor.ParentSection.Name);
+ Destroy(editor);
+ }
+
+ Logger.Log("FlightEngineerCore->OnDestroy");
+ }
+ catch (Exception ex)
+ {
+ Logger.Exception(ex);
}
}
@@ -80,44 +337,6 @@
}
catch (Exception ex)
{
- Logger.Exception(ex, "FlightEngineerCore->Start");
- }
- }
-
- #endregion
-
- #region Properties
-
- /// <summary>
- /// Gets the section windows for floating sections.
- /// </summary>
- public List<SectionWindow> SectionWindows { get; private set; }
-
- /// <summary>
- /// Gets the editor windows for sections with open editors.
- /// </summary>
- public List<SectionEditor> SectionEditors { get; private set; }
-
- /// <summary>
- /// Gets the list of currently running updatable modules.
- /// </summary>
- public List<IUpdatable> UpdatableModules { get; private set; }
-
- #endregion
-
- #region Updating
-
- /// <summary>
- /// Fixed update all required Flight Engineer objects.
- /// </summary>
- private void FixedUpdate()
- {
- try
- {
- SectionLibrary.FixedUpdate();
- }
- catch (Exception ex)
- {
Logger.Exception(ex);
}
}
@@ -134,7 +353,7 @@
}
catch (Exception ex)
{
- Logger.Exception(ex, "FlightEngineerCore->Update");
+ Logger.Exception(ex);
}
}
@@ -164,102 +383,7 @@
}
catch (Exception ex)
{
- Logger.Exception(ex, "FlightEngineerCore->UpdateModules");
- }
- }
-
- #endregion
-
- #region Destruction
-
- /// <summary>
- /// Force the destruction of child objects on core destruction.
- /// </summary>
- private void OnDestroy()
- {
- try
- {
- SectionLibrary.Save();
-
- foreach (var window in this.SectionWindows)
- {
- print("[FlightEngineer]: Destroying Floating Window for " + window.ParentSection.Name);
- Destroy(window);
- }
-
- foreach (var editor in this.SectionEditors)
- {
- print("[FlightEngineer]: Destroying Editor Window for " + editor.ParentSection.Name);
- Destroy(editor);
- }
-
- Logger.Log("FlightEngineerCore->OnDestroy");
- }
- catch (Exception ex)
- {
- Logger.Exception(ex, "FlightEngineerCore->OnDestroy");
- }
- }
-
- #endregion
-
- #region Methods
-
- /// <summary>
- /// Creates a section window, adds it to the FlightEngineerCore and returns a reference to it.
- /// </summary>
- public SectionWindow AddSectionWindow(SectionModule section)
- {
- try
- {
- var window = this.gameObject.AddComponent<SectionWindow>();
- window.ParentSection = section;
- window.WindowPosition = new Rect(section.FloatingPositionX, section.FloatingPositionY, 0, 0);
- this.SectionWindows.Add(window);
- return window;
- }
- catch (Exception ex)
- {
- Logger.Exception(ex, "FlightEngineerCore->AddSectionWindow");
- return null;
- }
- }
-
- /// <summary>
- /// Creates a section editor, adds it to the FlightEngineerCore and returns a reference to it.
- /// </summary>
- public SectionEditor AddSectionEditor(SectionModule section)
- {
- try
- {
- var editor = this.gameObject.AddComponent<SectionEditor>();
- editor.ParentSection = section;
- editor.Position = new Rect(section.EditorPositionX, section.EditorPositionY, SectionEditor.Width, SectionEditor.Height);
- this.SectionEditors.Add(editor);
- return editor;
- }
- catch (Exception ex)
- {
- Logger.Exception(ex, "FlightEngineerCore->AddSectionEditor");
- return null;
- }
- }
-
- /// <summary>
- /// Adds an updatable object to be automatically updated every frame and will ignore duplicate objects.
- /// </summary>
- public void AddUpdatable(IUpdatable updatable)
- {
- try
- {
- if (!this.UpdatableModules.Contains(updatable))
- {
- this.UpdatableModules.Add(updatable);
- }
- }
- catch (Exception ex)
- {
- Logger.Exception(ex, "FlightEngineerCore->AddUpdatable");
+ Logger.Exception(ex);
}
}
--- a/KerbalEngineer/Flight/FlightEngineerModule.cs
+++ b/KerbalEngineer/Flight/FlightEngineerModule.cs
@@ -19,9 +19,6 @@
#region Using Directives
-using System;
-using System.Linq;
-
#endregion
namespace KerbalEngineer.Flight
@@ -29,73 +26,5 @@
/// <summary>
/// Module that can be attached to parts, giving them FlightEngineerCore management.
/// </summary>
- public sealed class FlightEngineerModule : PartModule
- {
- #region Fields
-
- /// <summary>
- /// Contains the current FlightEngineerCore through the lifespan of this part.
- /// </summary>
- private FlightEngineerCore flightEngineerCore;
-
- #endregion
-
- #region Updating
-
- /// <summary>
- /// Logic to create and destroy the FlightEngineerCore.
- /// </summary>
- private void Update()
- {
- try
- {
- if (!HighLogic.LoadedSceneIsFlight || FlightEngineerPartless.IsPartless)
- {
- return;
- }
-
- if (this.vessel == FlightGlobals.ActiveVessel)
- {
- // Checks for an existing instance of FlightEngineerCore, and if this part is the first part containing FlightEngineerModule within the vessel.
- if (flightEngineerCore == null && this.part == this.vessel.parts.FirstOrDefault(p => p.Modules.Contains("FlightEngineerModule")))
- {
- this.flightEngineerCore = this.gameObject.AddComponent<FlightEngineerCore>();
- }
- }
- else if (flightEngineerCore != null)
- {
- // Using DestroyImmediate to force early destruction and keep saving/loading in synch when switching vessels.
- DestroyImmediate(flightEngineerCore);
- }
- }
- catch (Exception ex)
- {
- Logger.Exception(ex, "FlightEngineerModule->Update");
- }
- }
-
- #endregion
-
- #region Destruction
-
- /// <summary>
- /// Force the destruction of the FlightEngineerCore on part destruction.
- /// </summary>
- private void OnDestroy()
- {
- try
- {
- if (flightEngineerCore != null)
- {
- DestroyImmediate(flightEngineerCore);
- }
- }
- catch (Exception ex)
- {
- Logger.Exception(ex, "FlightEngineerModule->OnDestroy");
- }
- }
-
- #endregion
- }
+ public class FlightEngineerModule : PartModule { }
}
--- a/KerbalEngineer/Flight/FlightEngineerPartless.cs
+++ /dev/null
@@ -1,101 +1,1 @@
-//
-// Kerbal Engineer Redux
-//
-// Copyright (C) 2014 CYBUTEK
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-//
-#region Using Directives
-
-using System;
-
-using KerbalEngineer.Settings;
-
-using UnityEngine;
-
-#endregion
-
-namespace KerbalEngineer.Flight
-{
- [KSPAddon(KSPAddon.Startup.Flight, false)]
- public class FlightEngineerPartless : MonoBehaviour
- {
- #region Fields
-
- private FlightEngineerCore flightEngineerCore;
-
- #endregion
-
- #region Initialisation
-
- static FlightEngineerPartless()
- {
- try
- {
- var handler = SettingHandler.Load("FlightEngineerPartless.xml");
- handler.Get("isPartless", ref isPartless);
- }
- catch (Exception ex)
- {
- Logger.Exception(ex, "FlightEngineerPartless->FlightEngineerPartless");
- }
- }
-
- private void Awake()
- {
- try
- {
- if (isPartless)
- {
- this.flightEngineerCore = this.gameObject.AddComponent<FlightEngineerCore>();
- }
- }
- catch (Exception ex)
- {
- Logger.Exception(ex, "FlightEngineerPartless->Awake");
- }
- }
-
- #endregion
-
- #region Properties
-
- private static bool isPartless = true;
-
- public static bool IsPartless
- {
- get { return isPartless; }
- set
- {
- try
- {
- if (isPartless != value)
- {
- var handler = SettingHandler.Load("FlightEngineerPartless.xml");
- handler.Set("isPartless", value);
- handler.Save("FlightEngineerPartless.xml");
- }
- isPartless = value;
- }
- catch (Exception ex)
- {
- Logger.Exception(ex, "FlightEngineerPartless->IsPartless");
- }
- }
- }
-
- #endregion
- }
-}
--- a/KerbalEngineer/Flight/Readouts/Miscellaneous/Separator.cs
+++ b/KerbalEngineer/Flight/Readouts/Miscellaneous/Separator.cs
@@ -34,7 +34,8 @@
{
#region Fields
- private readonly GUIStyle boxStyle;
+ private GUIStyle boxStyle;
+ private GUIStyle boxStyleHud;
#endregion
@@ -48,6 +49,26 @@
this.IsDefault = false;
this.Cloneable = true;
+ this.InitialiseStyles();
+
+ GuiDisplaySize.OnSizeChanged += this.InitialiseStyles;
+ }
+
+ #endregion
+
+ #region Methods: public
+
+ public override void Draw(SectionModule section)
+ {
+ GUILayout.Box(String.Empty, section.IsHud ? this.boxStyleHud : this.boxStyle);
+ }
+
+ #endregion
+
+ #region Methods: private
+
+ private void InitialiseStyles()
+ {
this.boxStyle = new GUIStyle
{
normal =
@@ -57,16 +78,11 @@
fixedHeight = 1.0f,
stretchWidth = true
};
- }
- #endregion
-
- #region Methods: public
-
- public override void Draw(SectionModule section)
- {
- GUILayout.Box(String.Empty, this.boxStyle);
- //GUI.DrawTexture(GUILayoutUtility.GetLastRect(), this.texture, ScaleMode.StretchToFill);
+ this.boxStyleHud = new GUIStyle(this.boxStyle)
+ {
+ margin = new RectOffset(0, 0, (int)(8 * GuiDisplaySize.Offset), 0)
+ };
}
#endregion
--- a/KerbalEngineer/Flight/Readouts/Miscellaneous/SimulationDelay.cs
+++ b/KerbalEngineer/Flight/Readouts/Miscellaneous/SimulationDelay.cs
@@ -28,6 +28,8 @@
namespace KerbalEngineer.Flight.Readouts.Miscellaneous
{
+ using System;
+
public class SimulationDelay : ReadoutModule
{
#region Constructors
@@ -49,7 +51,7 @@
GUILayout.BeginHorizontal();
GUILayout.Label("Sim Delay", this.NameStyle);
GUI.skin = HighLogic.Skin;
- SimManager.minSimTime = (long)GUILayout.HorizontalSlider(SimManager.minSimTime, 0, 1000.0f);
+ SimManager.minSimTime = new TimeSpan(0, 0, 0, 0, (int)GUILayout.HorizontalSlider(SimManager.minSimTime.Milliseconds, 0, 1000.0f));
GUI.skin = null;
GUILayout.EndHorizontal();
}
--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Miscellaneous/SystemTime.cs
@@ -1,1 +1,59 @@
+//
+// Kerbal Engineer Redux
+//
+// Copyright (C) 2014 CYBUTEK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+#region Using Directives
+
+using System;
+
+using KerbalEngineer.Flight.Sections;
+using KerbalEngineer.Helpers;
+
+using UnityEngine;
+
+#endregion
+
+namespace KerbalEngineer.Flight.Readouts.Miscellaneous
+{
+ public class SystemTime : ReadoutModule
+ {
+
+
+ #region Constructors
+
+ public SystemTime()
+ {
+ this.Name = "System Time";
+ this.Category = ReadoutCategory.GetCategory("Miscellaneous");
+ this.HelpString = String.Empty;
+ this.IsDefault = false;
+ }
+
+ #endregion
+
+ #region Methods: public
+
+ public override void Draw(SectionModule section)
+ {
+ this.DrawLine(DateTime.Now.ToLongTimeString(), section.IsHud);
+ }
+
+ #endregion
+
+ }
+}
--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Miscellaneous/VectoredThrustToggle.cs
@@ -1,1 +1,56 @@
+//
+// Kerbal Engineer Redux
+//
+// Copyright (C) 2014 CYBUTEK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+namespace KerbalEngineer.Flight.Readouts.Miscellaneous
+{
+ #region Using Directives
+
+ using Sections;
+ using UnityEngine;
+ using VesselSimulator;
+
+ #endregion
+
+ public class VectoredThrustToggle : ReadoutModule
+ {
+ #region Constructors
+
+ public VectoredThrustToggle()
+ {
+ this.Name = "Vectored Thrust";
+ this.Category = ReadoutCategory.GetCategory("Miscellaneous");
+ this.HelpString = "Shows a control that will allow you to adjust whether the vessel simulation should account for vectored thrust.";
+ this.IsDefault = false;
+ }
+
+ #endregion
+
+ #region Methods
+
+ public override void Draw(SectionModule section)
+ {
+ GUILayout.BeginHorizontal();
+ GUILayout.Label("Vectored Thrust: ", this.NameStyle);
+ SimManager.vectoredThrust = GUILayout.Toggle(SimManager.vectoredThrust, "ENABLED", this.ButtonStyle);
+ GUILayout.EndHorizontal();
+ }
+
+ #endregion
+ }
+}
--- a/KerbalEngineer/Flight/Readouts/Orbital/CurrentSoi.cs
+++ b/KerbalEngineer/Flight/Readouts/Orbital/CurrentSoi.cs
@@ -31,7 +31,7 @@
public class CurrentSoi : ReadoutModule
{
#region Constructors
-
+
public CurrentSoi()
{
this.Name = "Current SOI";
--- a/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/ManoeuvreProcessor.cs
+++ b/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/ManoeuvreProcessor.cs
@@ -47,6 +47,7 @@
public static double AvailableDeltaV { get; private set; }
public static double BurnTime { get; private set; }
+
public static int FinalStage { get; private set; }
public static double HalfBurnTime { get; private set; }
@@ -90,7 +91,11 @@
public void Update()
{
- if (FlightGlobals.ActiveVessel.patchedConicSolver.maneuverNodes.Count == 0 || !SimulationProcessor.ShowDetails)
+ // Extra tests for low level tracking station not supporting patched conics and maneuver nodes
+ if (FlightGlobals.ActiveVessel.patchedConicSolver == null ||
+ FlightGlobals.ActiveVessel.patchedConicSolver.maneuverNodes == null ||
+ FlightGlobals.ActiveVessel.patchedConicSolver.maneuverNodes.Count == 0 ||
+ !SimulationProcessor.ShowDetails)
{
ShowDetails = false;
return;
@@ -110,7 +115,7 @@
var burnTime = 0.0;
var midPointTime = 0.0;
- HasDeltaV = GetBurnTime((float)TotalDeltaV, ref burnTime, ref midPointTime);
+ HasDeltaV = GetBurnTime(TotalDeltaV, ref burnTime, ref midPointTime);
AvailableDeltaV = SimulationProcessor.LastStage.totalDeltaV;
BurnTime = burnTime;
@@ -123,47 +128,50 @@
#region Methods: private
- private static bool GetBurnTime(float deltaV, ref double burnTime, ref double midPointTime)
+ private static bool GetBurnTime(double deltaV, ref double burnTime, ref double midPointTime)
{
var setMidPoint = false;
- var deltaVMidPoint = deltaV * 0.5f;
+ var deltaVMidPoint = deltaV * 0.5;
- for (var i = SimulationProcessor.Stages.Length - 1; i >= 0; i--)
+ for (var i = SimulationProcessor.Stages.Length - 1; i > -1; i--)
{
var stage = SimulationProcessor.Stages[i];
- var stageDeltaV = (float)stage.deltaV;
+ var stageDeltaV = stage.deltaV;
+ var startMass = stage.totalMass;
ProcessStageDrain:
- if (deltaV <= Single.Epsilon)
+ if (deltaV <= Double.Epsilon)
{
- FinalStage = ++i;
- return true;
+ break;
}
- if (stageDeltaV <= Single.Epsilon)
+ if (stageDeltaV <= Double.Epsilon)
{
continue;
}
- float deltaVDrain;
+ FinalStage = i;
+
+ double deltaVDrain;
if (deltaVMidPoint > 0.0)
{
- deltaVDrain = Mathf.Clamp(deltaV, 0.0f, Mathf.Clamp(deltaVMidPoint, 0.0f, stageDeltaV));
+ deltaVDrain = deltaV.Clamp(0.0, stageDeltaV.Clamp(0.0, deltaVMidPoint));
deltaVMidPoint -= deltaVDrain;
- setMidPoint = deltaVMidPoint <= Single.Epsilon;
+ setMidPoint = deltaVMidPoint <= Double.Epsilon;
}
else
{
- deltaVDrain = Mathf.Clamp(deltaV, 0.0f, stageDeltaV);
+ deltaVDrain = deltaV.Clamp(0.0, stageDeltaV);
}
- var startMass = stage.totalMass - (stage.resourceMass * (1.0f - (stageDeltaV / stage.deltaV)));
- var endMass = startMass - (stage.resourceMass * (deltaVDrain / stageDeltaV));
- var minimumAcceleration = stage.thrust / startMass;
- var maximumAcceleration = stage.thrust / endMass;
+ var exhaustVelocity = stage.isp * 9.82;
+ var flowRate = stage.thrust / exhaustVelocity;
+ var endMass = Math.Exp(Math.Log(startMass) - deltaVDrain / exhaustVelocity);
+ var deltaMass = (startMass - endMass) * Math.Exp(-(deltaVDrain * 0.001) / exhaustVelocity);
+ burnTime += deltaMass / flowRate;
- burnTime += deltaVDrain / ((minimumAcceleration + maximumAcceleration) * 0.5);
deltaV -= deltaVDrain;
stageDeltaV -= deltaVDrain;
+ startMass -= deltaMass;
if (setMidPoint)
{
@@ -172,7 +180,7 @@
goto ProcessStageDrain;
}
}
- return false;
+ return deltaV <= Double.Epsilon;
}
#endregion
--- a/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeAngleToPrograde.cs
+++ b/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeAngleToPrograde.cs
@@ -51,7 +51,7 @@
return;
}
- this.DrawLine("Node Angle to Prograde", ManoeuvreProcessor.AngleToPrograde.ToAngle());
+ this.DrawLine("Node Angle to Prograde", ManoeuvreProcessor.AngleToPrograde.ToAngle(), section.IsHud);
}
public override void Reset()
--- a/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeAngleToRetrograde.cs
+++ b/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeAngleToRetrograde.cs
@@ -51,7 +51,7 @@
return;
}
- this.DrawLine("Node Angle to Retrograde", ManoeuvreProcessor.AngleToRetrograde.ToAngle());
+ this.DrawLine("Node Angle to Retrograde", ManoeuvreProcessor.AngleToRetrograde.ToAngle(), section.IsHud);
}
public override void Reset()
--- a/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeBurnTime.cs
+++ b/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeBurnTime.cs
@@ -51,7 +51,7 @@
return;
}
- this.DrawLine("Node Burn Time", TimeFormatter.ConvertToString(ManoeuvreProcessor.BurnTime));
+ this.DrawLine("Node Burn Time", TimeFormatter.ConvertToString(ManoeuvreProcessor.BurnTime), section.IsHud);
}
public override void Reset()
--- a/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeHalfBurnTime.cs
+++ b/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeHalfBurnTime.cs
@@ -51,7 +51,7 @@
return;
}
- this.DrawLine("Node Burn Time (½)", TimeFormatter.ConvertToString(ManoeuvreProcessor.HalfBurnTime));
+ this.DrawLine("Node Burn Time (½)", TimeFormatter.ConvertToString(ManoeuvreProcessor.HalfBurnTime), section.IsHud);
}
public override void Reset()
--- a/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeNormalDeltaV.cs
+++ b/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeNormalDeltaV.cs
@@ -51,7 +51,7 @@
return;
}
- this.DrawLine("Node DeltaV (Normal)", ManoeuvreProcessor.NormalDeltaV.ToSpeed());
+ this.DrawLine("Node DeltaV (Normal)", ManoeuvreProcessor.NormalDeltaV.ToSpeed(), section.IsHud);
}
public override void Reset()
--- a/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeProgradeDeltaV.cs
+++ b/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeProgradeDeltaV.cs
@@ -51,7 +51,7 @@
return;
}
- this.DrawLine("Node DeltaV (Prograde)", ManoeuvreProcessor.ProgradeDeltaV.ToSpeed());
+ this.DrawLine("Node DeltaV (Prograde)", ManoeuvreProcessor.ProgradeDeltaV.ToSpeed(), section.IsHud);
}
public override void Reset()
--- a/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeRadialDeltaV.cs
+++ b/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeRadialDeltaV.cs
@@ -51,7 +51,7 @@
return;
}
- this.DrawLine("Node DeltaV (Radial)", ManoeuvreProcessor.RadialDeltaV.ToSpeed());
+ this.DrawLine("Node DeltaV (Radial)", ManoeuvreProcessor.RadialDeltaV.ToSpeed(), section.IsHud);
}
public override void Reset()
--- a/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeTimeToHalfBurn.cs
+++ b/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeTimeToHalfBurn.cs
@@ -51,7 +51,7 @@
return;
}
- this.DrawLine("Time to Node Burn", TimeFormatter.ConvertToString(ManoeuvreProcessor.UniversalTime - ManoeuvreProcessor.HalfBurnTime - Planetarium.GetUniversalTime()));
+ this.DrawLine("Time to Node Burn", TimeFormatter.ConvertToString(ManoeuvreProcessor.UniversalTime - ManoeuvreProcessor.HalfBurnTime - Planetarium.GetUniversalTime()), section.IsHud);
}
public override void Reset()
--- a/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeTimeToManoeuvre.cs
+++ b/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeTimeToManoeuvre.cs
@@ -51,7 +51,7 @@
return;
}
- this.DrawLine("Time to Node", TimeFormatter.ConvertToString(ManoeuvreProcessor.UniversalTime - Planetarium.GetUniversalTime()));
+ this.DrawLine("Time to Node", TimeFormatter.ConvertToString(ManoeuvreProcessor.UniversalTime - Planetarium.GetUniversalTime()), section.IsHud);
}
public override void Reset()
--- a/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeTotalDeltaV.cs
+++ b/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/NodeTotalDeltaV.cs
@@ -51,7 +51,7 @@
return;
}
- this.DrawLine("Node DeltaV (Total)", ManoeuvreProcessor.TotalDeltaV.ToSpeed() + " (" + (ManoeuvreProcessor.HasDeltaV ? "S" + ManoeuvreProcessor.FinalStage : "X") + ")");
+ this.DrawLine("Node DeltaV (Total)", ManoeuvreProcessor.TotalDeltaV.ToSpeed() + " (" + (ManoeuvreProcessor.HasDeltaV ? "S" + ManoeuvreProcessor.FinalStage : "X") + ")", section.IsHud);
}
public override void Reset()
--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/MeanAnomalyAtEpoc.cs
@@ -1,1 +1,54 @@
+//
+// Kerbal Engineer Redux
+//
+// Copyright (C) 2014 CYBUTEK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+#region Using Directives
+
+using System;
+
+using KerbalEngineer.Extensions;
+using KerbalEngineer.Flight.Sections;
+
+#endregion
+
+namespace KerbalEngineer.Flight.Readouts.Orbital
+{
+ public class MeanAnomalyAtEpoc : ReadoutModule
+ {
+ #region Constructors
+
+ public MeanAnomalyAtEpoc()
+ {
+ this.Name = "Mean Anomaly at Epoc";
+ this.Category = ReadoutCategory.GetCategory("Orbital");
+ this.HelpString = String.Empty;
+ this.IsDefault = false;
+ }
+
+ #endregion
+
+ #region Methods: public
+
+ public override void Draw(SectionModule section)
+ {
+ this.DrawLine(FlightGlobals.ship_orbit.meanAnomalyAtEpoch.ToAngle(), section.IsHud);
+ }
+
+ #endregion
+ }
+}
--- a/KerbalEngineer/Flight/Readouts/ReadoutCategory.cs
+++ b/KerbalEngineer/Flight/Readouts/ReadoutCategory.cs
@@ -56,6 +56,7 @@
public static ReadoutCategory Selected { get; set; }
public string Description { get; set; }
+
public string Name { get; set; }
#endregion
--- a/KerbalEngineer/Flight/Readouts/ReadoutLibrary.cs
+++ b/KerbalEngineer/Flight/Readouts/ReadoutLibrary.cs
@@ -17,33 +17,31 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#region Using Directives
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-using KerbalEngineer.Flight.Readouts.Miscellaneous;
-using KerbalEngineer.Flight.Readouts.Orbital;
-using KerbalEngineer.Flight.Readouts.Orbital.ManoeuvreNode;
-using KerbalEngineer.Flight.Readouts.Rendezvous;
-using KerbalEngineer.Flight.Readouts.Surface;
-using KerbalEngineer.Flight.Readouts.Vessel;
-using KerbalEngineer.Settings;
-
-using AltitudeSeaLevel = KerbalEngineer.Flight.Readouts.Surface.AltitudeSeaLevel;
-using ApoapsisHeight = KerbalEngineer.Flight.Readouts.Orbital.ApoapsisHeight;
-using OrbitalPeriod = KerbalEngineer.Flight.Readouts.Orbital.OrbitalPeriod;
-using PeriapsisHeight = KerbalEngineer.Flight.Readouts.Orbital.PeriapsisHeight;
-using SemiMajorAxis = KerbalEngineer.Flight.Readouts.Orbital.SemiMajorAxis;
-using SemiMinorAxis = KerbalEngineer.Flight.Readouts.Orbital.SemiMinorAxis;
-using TimeToApoapsis = KerbalEngineer.Flight.Readouts.Orbital.TimeToApoapsis;
-using TimeToPeriapsis = KerbalEngineer.Flight.Readouts.Orbital.TimeToPeriapsis;
-
-#endregion
-
namespace KerbalEngineer.Flight.Readouts
{
+ #region Using Directives
+
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using Miscellaneous;
+ using Orbital;
+ using Orbital.ManoeuvreNode;
+ using Rendezvous;
+ using Settings;
+ using Surface;
+ using Vessel;
+ using AltitudeSeaLevel = Surface.AltitudeSeaLevel;
+ using ApoapsisHeight = Orbital.ApoapsisHeight;
+ using OrbitalPeriod = Orbital.OrbitalPeriod;
+ using PeriapsisHeight = Orbital.PeriapsisHeight;
+ using SemiMajorAxis = Orbital.SemiMajorAxis;
+ using SemiMinorAxis = Orbital.SemiMinorAxis;
+ using TimeToApoapsis = Orbital.TimeToApoapsis;
+ using TimeToPeriapsis = Orbital.TimeToPeriapsis;
+
+ #endregion
+
public static class ReadoutLibrary
{
#region Fields
@@ -66,6 +64,7 @@
ReadoutCategory.SetCategory("Vessel", "Vessel performance statistics.");
ReadoutCategory.SetCategory("Rendezvous", "Readouts for rendezvous manovoeures.");
ReadoutCategory.SetCategory("Miscellaneous", "Miscellaneous readouts.");
+ ReadoutCategory.Selected = ReadoutCategory.GetCategory("Orbital");
// Orbital
readouts.Add(new ApoapsisHeight());
@@ -86,6 +85,7 @@
readouts.Add(new ArgumentOfPeriapsis());
readouts.Add(new TrueAnomaly());
readouts.Add(new MeanAnomaly());
+ readouts.Add(new MeanAnomalyAtEpoc());
readouts.Add(new EccentricAnomaly());
readouts.Add(new SemiMajorAxis());
readouts.Add(new SemiMinorAxis());
@@ -132,6 +132,8 @@
readouts.Add(new Mass());
readouts.Add(new Thrust());
readouts.Add(new ThrustToWeight());
+ readouts.Add(new ThrustOffsetAngle());
+ readouts.Add(new ThrustTorque());
readouts.Add(new SurfaceThrustToWeight());
readouts.Add(new Acceleration());
readouts.Add(new SuicideBurnAltitude());
@@ -141,6 +143,13 @@
readouts.Add(new IntakeAirDemand());
readouts.Add(new IntakeAirSupply());
readouts.Add(new IntakeAirDemandSupply());
+ readouts.Add(new PartCount());
+ readouts.Add(new Heading());
+ readouts.Add(new Pitch());
+ readouts.Add(new Roll());
+ readouts.Add(new HeadingRate());
+ readouts.Add(new PitchRate());
+ readouts.Add(new RollRate());
// Rendezvous
readouts.Add(new TargetSelector());
@@ -162,12 +171,14 @@
readouts.Add(new Rendezvous.OrbitalPeriod());
readouts.Add(new Rendezvous.SemiMajorAxis());
readouts.Add(new Rendezvous.SemiMinorAxis());
-
+
// Misc
readouts.Add(new Separator());
readouts.Add(new GuiSizeAdjustor());
readouts.Add(new SimulationDelay());
readouts.Add(new TimeReference());
+ readouts.Add(new VectoredThrustToggle());
+ readouts.Add(new SystemTime());
LoadHelpStrings();
}
@@ -192,7 +203,7 @@
#endregion
- #region Methods: public
+ #region Methods
/// <summary>
/// Gets a list of readout modules which are associated with the specified category.
@@ -220,10 +231,6 @@
readout.Reset();
}
}
-
- #endregion
-
- #region Methods: private
/// <summary>
/// Loads the help strings from file.
--- a/KerbalEngineer/Flight/Readouts/ReadoutModule.cs
+++ b/KerbalEngineer/Flight/Readouts/ReadoutModule.cs
@@ -89,6 +89,11 @@
public bool IsDefault { get; set; }
/// <summary>
+ /// Gets the number of drawn lines.
+ /// </summary>
+ public int LineCount { get; private set; }
+
+ /// <summary>
/// Gets and sets the message style.
/// </summary>
public GUIStyle MessageStyle { get; set; }
@@ -139,6 +144,7 @@
public void LineCountEnd()
{
+ this.LineCount = this.lineCountEnd;
if (this.lineCountEnd.CompareTo(this.lineCountStart) < 0)
{
this.ResizeRequested = true;
--- a/KerbalEngineer/Flight/Readouts/Surface/AltitudeTerrain.cs
+++ b/KerbalEngineer/Flight/Readouts/Surface/AltitudeTerrain.cs
@@ -19,13 +19,17 @@
#region Using Directives
-using KerbalEngineer.Extensions;
-using KerbalEngineer.Flight.Sections;
-
#endregion
namespace KerbalEngineer.Flight.Readouts.Surface
{
+ #region Using Directives
+
+ using Extensions;
+ using Sections;
+
+ #endregion
+
public class AltitudeTerrain : ReadoutModule
{
#region Constructors
@@ -40,11 +44,18 @@
#endregion
- #region Methods: public
+ #region Methods
public override void Draw(SectionModule section)
{
- this.DrawLine((FlightGlobals.ship_altitude - FlightGlobals.ActiveVessel.terrainAltitude).ToDistance(), section.IsHud);
+ if (FlightGlobals.ActiveVessel.terrainAltitude > 0.0)
+ {
+ this.DrawLine((FlightGlobals.ship_altitude - FlightGlobals.ActiveVessel.terrainAltitude).ToDistance(), section.IsHud);
+ }
+ else
+ {
+ this.DrawLine((FlightGlobals.ship_altitude).ToDistance(), section.IsHud);
+ }
}
#endregion
--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Vessel/AttitudeProcessor.cs
@@ -1,1 +1,132 @@
+//
+// Kerbal Engineer Redux
+//
+// Copyright (C) 2014 CYBUTEK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+namespace KerbalEngineer.Flight.Readouts.Vessel
+{
+ #region Using Directives
+
+ using UnityEngine;
+
+ #endregion
+
+ public class AttitudeProcessor : IUpdatable, IUpdateRequest
+ {
+ #region Fields
+
+ private static readonly AttitudeProcessor instance = new AttitudeProcessor();
+
+ private Vector3 centreOfMass = Vector3.zero;
+
+ private double heading;
+ private double headingRate;
+ private Vector3 north = Vector3.zero;
+ private double pitch;
+ private double pitchRate;
+ private double previousHeading;
+ private double previousPitch;
+ private double previousRoll;
+ private double roll;
+ private double rollRate;
+ private Quaternion surfaceRotation;
+ private Vector3 up = Vector3.zero;
+
+ #endregion
+
+ #region Properties
+
+ public static double Heading
+ {
+ get { return instance.heading; }
+ }
+
+ public static double HeadingRate
+ {
+ get { return instance.headingRate; }
+ }
+
+ public static AttitudeProcessor Instance
+ {
+ get { return instance; }
+ }
+
+ public static double Pitch
+ {
+ get { return instance.pitch; }
+ }
+
+ public static double PitchRate
+ {
+ get { return instance.pitchRate; }
+ }
+
+ public static double Roll
+ {
+ get { return instance.roll; }
+ }
+
+ public static double RollRate
+ {
+ get { return instance.rollRate; }
+ }
+
+ public bool UpdateRequested { get; set; }
+
+ #endregion
+
+ #region Methods
+
+ public static void RequestUpdate()
+ {
+ instance.UpdateRequested = true;
+ }
+
+ public void Update()
+ {
+ this.surfaceRotation = this.GetSurfaceRotation();
+
+ this.previousHeading = this.heading;
+ this.previousPitch = this.pitch;
+ this.previousRoll = this.roll;
+
+ // This code was derived from MechJeb2's implementation for getting the vessel's surface relative rotation.
+ this.heading = this.surfaceRotation.eulerAngles.y;
+ this.pitch = this.surfaceRotation.eulerAngles.x > 180.0f
+ ? 360.0f - this.surfaceRotation.eulerAngles.x
+ : -this.surfaceRotation.eulerAngles.x;
+ this.roll = this.surfaceRotation.eulerAngles.z > 180.0f
+ ? this.surfaceRotation.eulerAngles.z - 360.0f
+ : this.surfaceRotation.eulerAngles.z;
+
+ this.headingRate = this.heading - this.previousHeading;
+ this.pitchRate = this.pitch - this.previousPitch;
+ this.rollRate = this.roll - this.previousRoll;
+ }
+
+ private Quaternion GetSurfaceRotation()
+ {
+ // This code was derived from MechJeb2's implementation for getting the vessel's surface relative rotation.
+ this.centreOfMass = FlightGlobals.ActiveVessel.findWorldCenterOfMass();
+ this.up = (this.centreOfMass - FlightGlobals.ActiveVessel.mainBody.position).normalized;
+ this.north = Vector3.Exclude(this.up, (FlightGlobals.ActiveVessel.mainBody.position + FlightGlobals.ActiveVessel.mainBody.transform.up * (float)FlightGlobals.ActiveVessel.mainBody.Radius) - this.centreOfMass).normalized;
+ return Quaternion.Inverse(Quaternion.Euler(90.0f, 0.0f, 0.0f) * Quaternion.Inverse(FlightGlobals.ActiveVessel.transform.rotation) * Quaternion.LookRotation(this.north, this.up));
+ }
+
+ #endregion
+ }
+}
--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Vessel/Heading.cs
@@ -1,1 +1,62 @@
+//
+// Kerbal Engineer Redux
+//
+// Copyright (C) 2014 CYBUTEK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+namespace KerbalEngineer.Flight.Readouts.Vessel
+{
+ #region Using Directives
+
+ using Helpers;
+ using Sections;
+
+ #endregion
+
+ public class Heading : ReadoutModule
+ {
+ #region Constructors
+
+ public Heading()
+ {
+ this.Name = "Heading";
+ this.Category = ReadoutCategory.GetCategory("Vessel");
+ this.HelpString = string.Empty;
+ this.IsDefault = false;
+ }
+
+ #endregion
+
+ #region Methods
+
+ public override void Draw(SectionModule section)
+ {
+ this.DrawLine(Units.ToAngle(AttitudeProcessor.Heading), section.IsHud);
+ }
+
+ public override void Reset()
+ {
+ FlightEngineerCore.Instance.AddUpdatable(AttitudeProcessor.Instance);
+ }
+
+ public override void Update()
+ {
+ AttitudeProcessor.RequestUpdate();
+ }
+
+ #endregion
+ }
+}
--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Vessel/HeadingRate.cs
@@ -1,1 +1,62 @@
+//
+// Kerbal Engineer Redux
+//
+// Copyright (C) 2014 CYBUTEK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+namespace KerbalEngineer.Flight.Readouts.Vessel
+{
+ #region Using Directives
+
+ using Helpers;
+ using Sections;
+
+ #endregion
+
+ public class HeadingRate : ReadoutModule
+ {
+ #region Constructors
+
+ public HeadingRate()
+ {
+ this.Name = "Heading Rate";
+ this.Category = ReadoutCategory.GetCategory("Vessel");
+ this.HelpString = string.Empty;
+ this.IsDefault = false;
+ }
+
+ #endregion
+
+ #region Methods
+
+ public override void Draw(SectionModule section)
+ {
+ this.DrawLine(Units.ToAngle(AttitudeProcessor.HeadingRate) + "/sec", section.IsHud);
+ }
+
+ public override void Reset()
+ {
+ FlightEngineerCore.Instance.AddUpdatable(AttitudeProcessor.Instance);
+ }
+
+ public override void Update()
+ {
+ AttitudeProcessor.RequestUpdate();
+ }
+
+ #endregion
+ }
+}
--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Vessel/PartCount.cs
@@ -1,1 +1,65 @@
+//
+// Kerbal Engineer Redux
+//
+// Copyright (C) 2014 CYBUTEK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+namespace KerbalEngineer.Flight.Readouts.Vessel
+{
+ #region Using Directives
+
+ using Helpers;
+ using Sections;
+
+ #endregion
+
+ public class PartCount : ReadoutModule
+ {
+ #region Constructors
+
+ public PartCount()
+ {
+ this.Name = "Part Count";
+ this.Category = ReadoutCategory.GetCategory("Vessel");
+ this.HelpString = string.Empty;
+ this.IsDefault = true;
+ }
+
+ #endregion
+
+ #region Methods
+
+ public override void Draw(SectionModule section)
+ {
+ if (SimulationProcessor.ShowDetails)
+ {
+ this.DrawLine(Units.ConcatF(SimulationProcessor.LastStage.partCount, SimulationProcessor.LastStage.totalPartCount), section.IsHud);
+ }
+ }
+
+ public override void Reset()
+ {
+ FlightEngineerCore.Instance.AddUpdatable(SimulationProcessor.Instance);
+ }
+
+ public override void Update()
+ {
+ SimulationProcessor.RequestUpdate();
+ }
+
+ #endregion
+ }
+}
--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Vessel/Pitch.cs
@@ -1,1 +1,62 @@
+//
+// Kerbal Engineer Redux
+//
+// Copyright (C) 2014 CYBUTEK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+namespace KerbalEngineer.Flight.Readouts.Vessel
+{
+ #region Using Directives
+
+ using Helpers;
+ using Sections;
+
+ #endregion
+
+ public class Pitch : ReadoutModule
+ {
+ #region Constructors
+
+ public Pitch()
+ {
+ this.Name = "Pitch";
+ this.Category = ReadoutCategory.GetCategory("Vessel");
+ this.HelpString = string.Empty;
+ this.IsDefault = false;
+ }
+
+ #endregion
+
+ #region Methods
+
+ public override void Draw(SectionModule section)
+ {
+ this.DrawLine(Units.ToAngle(AttitudeProcessor.Pitch), section.IsHud);
+ }
+
+ public override void Reset()
+ {
+ FlightEngineerCore.Instance.AddUpdatable(AttitudeProcessor.Instance);
+ }
+
+ public override void Update()
+ {
+ AttitudeProcessor.RequestUpdate();
+ }
+
+ #endregion
+ }
+}
--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Vessel/PitchRate.cs
@@ -1,1 +1,62 @@
+//
+// Kerbal Engineer Redux
+//
+// Copyright (C) 2014 CYBUTEK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+namespace KerbalEngineer.Flight.Readouts.Vessel
+{
+ #region Using Directives
+
+ using Helpers;
+ using Sections;
+
+ #endregion
+
+ public class PitchRate : ReadoutModule
+ {
+ #region Constructors
+
+ public PitchRate()
+ {
+ this.Name = "Pitch Rate";
+ this.Category = ReadoutCategory.GetCategory("Vessel");
+ this.HelpString = string.Empty;
+ this.IsDefault = false;
+ }
+
+ #endregion
+
+ #region Methods
+
+ public override void Draw(SectionModule section)
+ {
+ this.DrawLine(Units.ToAngle(AttitudeProcessor.PitchRate) + "/sec", section.IsHud);
+ }
+
+ public override void Reset()
+ {
+ FlightEngineerCore.Instance.AddUpdatable(AttitudeProcessor.Instance);
+ }
+
+ public override void Update()
+ {
+ AttitudeProcessor.RequestUpdate();
+ }
+
+ #endregion
+ }
+}
--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Vessel/Roll.cs
@@ -1,1 +1,62 @@
+//
+// Kerbal Engineer Redux
+//
+// Copyright (C) 2014 CYBUTEK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+namespace KerbalEngineer.Flight.Readouts.Vessel
+{
+ #region Using Directives
+
+ using Helpers;
+ using Sections;
+
+ #endregion
+
+ public class Roll : ReadoutModule
+ {
+ #region Constructors
+
+ public Roll()
+ {
+ this.Name = "Roll";
+ this.Category = ReadoutCategory.GetCategory("Vessel");
+ this.HelpString = string.Empty;
+ this.IsDefault = false;
+ }
+
+ #endregion
+
+ #region Methods
+
+ public override void Draw(SectionModule section)
+ {
+ this.DrawLine(Units.ToAngle(AttitudeProcessor.Roll), section.IsHud);
+ }
+
+ public override void Reset()
+ {
+ FlightEngineerCore.Instance.AddUpdatable(AttitudeProcessor.Instance);
+ }
+
+ public override void Update()
+ {
+ AttitudeProcessor.RequestUpdate();
+ }
+
+ #endregion
+ }
+}
--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Vessel/RollRate.cs
@@ -1,1 +1,62 @@
+//
+// Kerbal Engineer Redux
+//
+// Copyright (C) 2014 CYBUTEK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+namespace KerbalEngineer.Flight.Readouts.Vessel
+{
+ #region Using Directives
+
+ using Helpers;
+ using Sections;
+
+ #endregion
+
+ public class RollRate : ReadoutModule
+ {
+ #region Constructors
+
+ public RollRate()
+ {
+ this.Name = "Roll Rate";
+ this.Category = ReadoutCategory.GetCategory("Vessel");
+ this.HelpString = string.Empty;
+ this.IsDefault = false;
+ }
+
+ #endregion
+
+ #region Methods
+
+ public override void Draw(SectionModule section)
+ {
+ this.DrawLine(Units.ToAngle(AttitudeProcessor.RollRate) + "/sec", section.IsHud);
+ }
+
+ public override void Reset()
+ {
+ FlightEngineerCore.Instance.AddUpdatable(AttitudeProcessor.Instance);
+ }
+
+ public override void Update()
+ {
+ AttitudeProcessor.RequestUpdate();
+ }
+
+ #endregion
+ }
+}
--- a/KerbalEngineer/Flight/Readouts/Vessel/SimulationProcessor.cs
+++ b/KerbalEngineer/Flight/Readouts/Vessel/SimulationProcessor.cs
@@ -19,14 +19,19 @@
#region Using Directives
-using System;
-using KerbalEngineer.VesselSimulator;
#endregion
namespace KerbalEngineer.Flight.Readouts.Vessel
{
+ #region Using Directives
+
+ using System;
+ using VesselSimulator;
+
+ #endregion
+
public class SimulationProcessor : IUpdatable, IUpdateRequest
{
#region Instance
@@ -34,6 +39,15 @@
#region Fields
private static readonly SimulationProcessor instance = new SimulationProcessor();
+
+ #endregion
+
+ #region Constructors
+
+ static SimulationProcessor()
+ {
+ SimManager.OnReady += GetStageInfo;
+ }
#endregion
@@ -72,7 +86,13 @@
#endregion
- #region Methods: public
+ #region Methods
+
+ private static void GetStageInfo()
+ {
+ Stages = SimManager.Stages;
+ LastStage = SimManager.LastStage;
+ }
public static void RequestUpdate()
{
@@ -89,9 +109,6 @@
return;
}
- Stages = SimManager.Stages;
- LastStage = SimManager.LastStage;
-
if (Stages != null && LastStage != null)
{
ShowDetails = true;
@@ -104,9 +121,6 @@
FlightGlobals.ActiveVessel.mainBody.GetAltitude(FlightGlobals.ActiveVessel.CoM), 2);
SimManager.Velocity = FlightGlobals.ActiveVessel.srfSpeed;
}
-
- // Cybutek: We should be allowing this to be set too but not sure where you want to put the control
- //SimManager.vectoredThrust = vectoredThrust;
}
#endregion
--- a/KerbalEngineer/Flight/Readouts/Vessel/SuicideBurnProcessor.cs
+++ b/KerbalEngineer/Flight/Readouts/Vessel/SuicideBurnProcessor.cs
@@ -19,12 +19,18 @@
#region Using Directives
-using System;
+
#endregion
namespace KerbalEngineer.Flight.Readouts.Vessel
{
+ #region Using Directives
+
+ using System;
+
+ #endregion
+
public class SuicideBurnProcessor : IUpdatable, IUpdateRequest
{
#region Fields
@@ -55,7 +61,7 @@
#endregion
- #region Methods: public
+ #region Methods
public static void RequestUpdate()
{
@@ -79,7 +85,9 @@
this.gravity = FlightGlobals.currentMainBody.gravParameter / Math.Pow(FlightGlobals.currentMainBody.Radius, 2.0);
this.acceleration = SimulationProcessor.LastStage.thrust / SimulationProcessor.LastStage.totalMass;
- this.radarAltitude = FlightGlobals.ship_altitude - FlightGlobals.ActiveVessel.terrainAltitude;
+ this.radarAltitude = FlightGlobals.ActiveVessel.terrainAltitude > 0.0
+ ? FlightGlobals.ship_altitude - FlightGlobals.ActiveVessel.terrainAltitude
+ : FlightGlobals.ship_altitude;
DeltaV = Math.Sqrt((2 * this.gravity * this.radarAltitude) + Math.Pow(FlightGlobals.ship_verticalSpeed, 2.0));
Altitude = Math.Pow(DeltaV, 2.0) / (2.0 * this.acceleration);
--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Vessel/ThrustOffsetAngle.cs
@@ -1,1 +1,66 @@
+//
+// Kerbal Engineer Redux
+//
+// Copyright (C) 2014 CYBUTEK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+#region Using Directives
+
+using KerbalEngineer.Flight.Sections;
+using KerbalEngineer.Helpers;
+
+#endregion
+
+namespace KerbalEngineer.Flight.Readouts.Vessel
+{
+ public class ThrustOffsetAngle : ReadoutModule
+ {
+ #region Constructors
+
+ public ThrustOffsetAngle()
+ {
+ this.Name = "Thrust offset angle";
+ this.Category = ReadoutCategory.GetCategory("Vessel");
+ this.HelpString = "Thrust angle offset due to vessel asymmetries and gimballing";
+ this.IsDefault = true;
+ }
+
+ #endregion
+
+ #region Methods: public
+
+ public override void Draw(SectionModule section)
+ {
+ if (SimulationProcessor.ShowDetails)
+ {
+ this.DrawLine(Units.ToAngle(SimulationProcessor.LastStage.thrustOffsetAngle, 1), section.IsHud);
+ }
+ }
+
+ public override void Reset()
+ {
+ FlightEngineerCore.Instance.AddUpdatable(SimulationProcessor.Instance);
+ }
+
+ public override void Update()
+ {
+ SimulationProcessor.RequestUpdate();
+ }
+
+ #endregion
+ }
+}
+
--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Vessel/ThrustTorque.cs
@@ -1,1 +1,66 @@
+//
+// Kerbal Engineer Redux
+//
+// Copyright (C) 2014 CYBUTEK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+#region Using Directives
+
+using KerbalEngineer.Flight.Sections;
+using KerbalEngineer.Helpers;
+
+#endregion
+
+namespace KerbalEngineer.Flight.Readouts.Vessel
+{
+ public class ThrustTorque : ReadoutModule
+ {
+ #region Constructors
+
+ public ThrustTorque()
+ {
+ this.Name = "Thrust torque";
+ this.Category = ReadoutCategory.GetCategory("Vessel");
+ this.HelpString = "Thrust torque due to vessel asymmetries and gimballing";
+ this.IsDefault = true;
+ }
+
+ #endregion
+
+ #region Methods: public
+
+ public override void Draw(SectionModule section)
+ {
+ if (SimulationProcessor.ShowDetails)
+ {
+ this.DrawLine(Units.ToTorque(SimulationProcessor.LastStage.maxThrustTorque), section.IsHud);
+ }
+ }
+
+ public override void Reset()
+ {
+ FlightEngineerCore.Instance.AddUpdatable(SimulationProcessor.Instance);
+ }
+
+ public override void Update()
+ {
+ SimulationProcessor.RequestUpdate();
+ }
+
+ #endregion
+ }
+}
+
--- a/KerbalEngineer/Flight/Sections/SectionEditor.cs
+++ b/KerbalEngineer/Flight/Sections/SectionEditor.cs
@@ -119,7 +119,7 @@
try
{
this.InitialiseStyles();
- ReadoutCategory.Selected = ReadoutCategory.GetCategory("Orbital");
+ //ReadoutCategory.Selected = ReadoutCategory.GetCategory("Orbital");
RenderingManager.AddToPostDrawQueue(0, this.Draw);
}
catch (Exception ex)
--- a/KerbalEngineer/Flight/Sections/SectionModule.cs
+++ b/KerbalEngineer/Flight/Sections/SectionModule.cs
@@ -168,6 +168,11 @@
public bool IsVisible { get; set; }
/// <summary>
+ /// Gets the number of drawn readout lines.
+ /// </summary>
+ public int LineCount { get; private set; }
+
+ /// <summary>
/// Gets and sets the name of the section.
/// </summary>
public string Name { get; set; }
@@ -351,6 +356,7 @@
GUILayout.BeginVertical(this.boxStyle);
}
+ this.LineCount = 0;
if (this.ReadoutModules.Count > 0)
{
foreach (var readout in this.ReadoutModules)
@@ -358,11 +364,13 @@
readout.LineCountStart();
readout.Draw(this);
readout.LineCountEnd();
+ this.LineCount += readout.LineCount;
}
}
else
{
GUILayout.Label("No readouts are installed.", this.messageStyle);
+ this.LineCount = 1;
}
if (!this.IsHud)
--- a/KerbalEngineer/Flight/Sections/SectionWindow.cs
+++ b/KerbalEngineer/Flight/Sections/SectionWindow.cs
@@ -60,8 +60,8 @@
#region Fields
+ private GUIStyle hudWindowBgStyle;
private GUIStyle hudWindowStyle;
- private GUIStyle hudWindowBgStyle;
private GUIStyle windowStyle;
#endregion
@@ -118,7 +118,7 @@
/// </summary>
private void Draw()
{
- if (this.ParentSection == null || !this.ParentSection.IsVisible || (DisplayStack.Instance.Hidden && !this.ParentSection.IsHud))
+ if (this.ParentSection == null || !this.ParentSection.IsVisible || (DisplayStack.Instance.Hidden && !this.ParentSection.IsHud) || !FlightEngineerCore.IsDisplayable)
{
return;
}
@@ -130,9 +130,11 @@
this.resizeRequested = false;
}
GUI.skin = null;
- this.windowPosition = GUILayout.Window(this.windowId, this.windowPosition, this.Window, string.Empty,
- (!this.ParentSection.IsHud || this.ParentSection.IsEditorVisible) ? this.windowStyle
- : this.ParentSection.IsHudBackground ? this.hudWindowBgStyle : this.hudWindowStyle).ClampToScreen();
+ this.windowPosition = GUILayout.Window(this.windowId, this.windowPosition, this.Window, string.Empty,
+ (!this.ParentSection.IsHud || this.ParentSection.IsEditorVisible) ? this.windowStyle
+ : this.ParentSection.IsHudBackground && this.ParentSection.LineCount > 0
+ ? this.hudWindowBgStyle
+ : this.hudWindowStyle).ClampToScreen();
this.ParentSection.FloatingPositionX = this.windowPosition.x;
this.ParentSection.FloatingPositionY = this.windowPosition.y;
}
--- /dev/null
+++ b/KerbalEngineer/Helpers/Averager.cs
@@ -1,1 +1,67 @@
+//
+// Kerbal Engineer Redux
+//
+// Copyright (C) 2014 CYBUTEK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+using System;
+
+namespace KerbalEngineer
+{
+ public class VectorAverager
+ {
+ private Vector3d sum = Vector3d.zero;
+ private uint count = 0;
+
+ public void Add(Vector3d v) {
+ sum += v;
+ count += 1;
+ }
+
+ public Vector3d Get() {
+ if (count > 0) {
+ return sum / count;
+ } else {
+ return Vector3d.zero;
+ }
+ }
+ }
+
+ public class WeightedVectorAverager
+ {
+ private Vector3d sum = Vector3d.zero;
+ private double totalweight = 0;
+
+ public void Add(Vector3d v, double weight) {
+ sum += v * weight;
+ totalweight += weight;
+ }
+
+ public Vector3d Get() {
+ if (totalweight > 0) {
+ return sum / totalweight;
+ } else {
+ return Vector3d.zero;
+ }
+ }
+
+ public double GetTotalWeight() {
+ return totalweight;
+ }
+ }
+}
+
+
--- /dev/null
+++ b/KerbalEngineer/Helpers/ForceAccumulator.cs
@@ -1,1 +1,103 @@
+//
+// Kerbal Engineer Redux
+//
+// Copyright (C) 2014 CYBUTEK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+using System;
+using System.Collections.Generic;
+
+namespace KerbalEngineer
+{
+ // a (force, application point) tuple
+ public class AppliedForce
+ {
+ public Vector3d vector;
+ public Vector3d applicationPoint;
+
+ public AppliedForce(Vector3d vector, Vector3d applicationPoint) {
+ this.vector = vector;
+ this.applicationPoint = applicationPoint;
+ }
+ }
+
+ // This class was mostly adapted from FARCenterQuery, part of FAR, by ferram4, GPLv3
+ // https://github.com/ferram4/Ferram-Aerospace-Research/blob/master/FerramAerospaceResearch/FARCenterQuery.cs
+ // Also see https://en.wikipedia.org/wiki/Resultant_force
+
+ // It accumulates forces and their points of applications, and provides methods for
+ // calculating the effective torque at any position, as well as the minimum-torque net force application point.
+ //
+ // The latter is a non-trivial issue; there is a 1-dimensional line of physically-equivalent solutions parallel
+ // to the resulting force vector; the solution closest to the weighted average of force positions is chosen.
+ // In the case of non-parallel forces, there usually is an infinite number of such lines, all of which have
+ // some amount of residual torque. The line with the least amount of residual torque is chosen.
+ public class ForceAccumulator
+ {
+ // Total force.
+ private Vector3d totalForce = Vector3d.zero;
+ // Torque needed to compensate if force were applied at origin.
+ private Vector3d totalZeroOriginTorque = Vector3d.zero;
+
+ // Weighted average of force application points.
+ private WeightedVectorAverager avgApplicationPoint = new WeightedVectorAverager();
+
+ // Feed an force to the accumulator.
+ public void AddForce(Vector3d applicationPoint, Vector3d force)
+ {
+ totalForce += force;
+ totalZeroOriginTorque += Vector3d.Cross(applicationPoint, force);
+ avgApplicationPoint.Add(applicationPoint, force.magnitude);
+ }
+
+ public Vector3d GetAverageForceApplicationPoint() {
+ return avgApplicationPoint.Get();
+ }
+
+ public void AddForce(AppliedForce force) {
+ AddForce(force.applicationPoint, force.vector);
+ }
+
+ // Residual torque for given force application point.
+ public Vector3d TorqueAt(Vector3d origin)
+ {
+ return totalZeroOriginTorque - Vector3d.Cross(origin, totalForce);
+ }
+
+ // Total force vector.
+ public Vector3d GetTotalForce()
+ {
+ return totalForce;
+ }
+
+ // Returns the minimum-residual-torque force application point that is closest to origin.
+ // Note that TorqueAt(GetMinTorquePos()) is always parallel to totalForce.
+ public Vector3d GetMinTorqueForceApplicationPoint(Vector3d origin)
+ {
+ double fmag = totalForce.sqrMagnitude;
+ if (fmag <= 0) {
+ return origin;
+ }
+
+ return origin + Vector3d.Cross(totalForce, TorqueAt(origin)) / fmag;
+ }
+
+ public Vector3d GetMinTorqueForceApplicationPoint()
+ {
+ return GetMinTorqueForceApplicationPoint(avgApplicationPoint.Get());
+ }
+ }
+}
--- a/KerbalEngineer/Helpers/Units.cs
+++ b/KerbalEngineer/Helpers/Units.cs
@@ -17,26 +17,59 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#region Using Directives
-
-using System;
-
-#endregion
-
namespace KerbalEngineer.Helpers
{
+ #region Using Directives
+
+ using System;
+
+ #endregion
+
public static class Units
{
- #region Methods: public
+ #region Methods
- public static string Concat(double value1, double value2, int decimals = 1)
+ public static string Concat(int value1, int value2)
+ {
+ return value1 + " / " + value2;
+ }
+
+ public static string ConcatF(double value1, double value2, int decimals = 1)
{
return value1.ToString("F" + decimals) + " / " + value2.ToString("F" + decimals);
}
- public static string Concat(double value1, double value2, double value3, int decimals = 1)
+ public static string ConcatF(double value1, double value2, double value3, int decimals = 1)
{
return value1.ToString("F" + decimals) + " / " + value2.ToString("F" + decimals) + " / " + value3.ToString("F" + decimals);
+ }
+
+ public static string ConcatN(double value1, double value2, int decimals = 1)
+ {
+ return value1.ToString("N" + decimals) + " / " + value2.ToString("N" + decimals);
+ }
+
+ public static string ConcatN(double value1, double value2, double value3, int decimals = 1)
+ {
+ return value1.ToString("N" + decimals) + " / " + value2.ToString("N" + decimals) + " / " + value3.ToString("N" + decimals);
+ }
+
+ public static string Cost(double value, int decimals = 1)
+ {
+ if (value >= 1000000.0)
+ {
+ return (value / 1000.0).ToString("N" + decimals) + "K";
+ }
+ return value.ToString("N" + decimals);
+ }
+
+ public static string Cost(double value1, double value2, int decimals = 1)
+ {
+ if (value1 >= 1000000.0 || value2 >= 1000000.0)
+ {
+ return (value1 / 1000.0).ToString("N" + decimals) + " / " + (value2 / 1000.0).ToString("N" + decimals) + "K";
+ }
+ return value1.ToString("N" + decimals) + " / " + value2.ToString("N" + decimals);
}
public static string ToAcceleration(double value, int decimals = 2)
@@ -97,12 +130,22 @@
public static string ToMass(double value, int decimals = 0)
{
+ if (value >= 1000.0)
+ {
+ return value.ToString("N" + decimals + 2) + "t";
+ }
+
value *= 1000.0;
return value.ToString("N" + decimals) + "kg";
}
public static string ToMass(double value1, double value2, int decimals = 0)
{
+ if (value1 >= 1000.0f || value2 >= 1000.0f)
+ {
+ return value1.ToString("N" + decimals + 2) + " / " + value2.ToString("N" + decimals + 2) + "t";
+ }
+
value1 *= 1000.0;
value2 *= 1000.0;
return value1.ToString("N" + decimals) + " / " + value2.ToString("N" + decimals) + "kg";
@@ -133,6 +176,11 @@
return TimeFormatter.ConvertToString(value);
}
+ public static string ToTorque(double value)
+ {
+ return value.ToString((value < 100.0) ? (Math.Abs(value) < Double.Epsilon) ? "N0" : "N1" : "N0") + "kNm";
+ }
+
#endregion
}
}
--- a/KerbalEngineer/KerbalEngineer.csproj
+++ b/KerbalEngineer/KerbalEngineer.csproj
@@ -49,8 +49,9 @@
<Compile Include="Extensions\FloatExtensions.cs" />
<Compile Include="Extensions\OrbitExtensions.cs" />
<Compile Include="Flight\ActionMenuGui.cs" />
- <Compile Include="Flight\FlightEngineerPartless.cs" />
<Compile Include="Flight\Presets\Preset.cs" />
+ <Compile Include="Flight\Readouts\Miscellaneous\SystemTime.cs" />
+ <Compile Include="Flight\Readouts\Miscellaneous\VectoredThrustToggle.cs" />
<Compile Include="Flight\Readouts\Miscellaneous\TimeReference.cs" />
<Compile Include="Flight\Readouts\Miscellaneous\Separator.cs" />
<Compile Include="Flight\Readouts\Miscellaneous\GuiSizeAdjustor.cs" />
@@ -69,6 +70,7 @@
<Compile Include="Flight\Readouts\Orbital\ManoeuvreNode\NodeAngleToPrograde.cs" />
<Compile Include="Flight\Readouts\Orbital\ManoeuvreNode\NodeTotalDeltaV.cs" />
<Compile Include="Flight\Readouts\Orbital\ManoeuvreNode\NodeProgradeDeltaV.cs" />
+ <Compile Include="Flight\Readouts\Orbital\MeanAnomalyAtEpoc.cs" />
<Compile Include="Flight\Readouts\Orbital\MeanAnomaly.cs" />
<Compile Include="Flight\Readouts\Orbital\EccentricAnomaly.cs" />
<Compile Include="Flight\Readouts\Orbital\ArgumentOfPeriapsis.cs" />
@@ -87,7 +89,15 @@
<Compile Include="Flight\Readouts\Surface\Biome.cs" />
<Compile Include="Flight\Readouts\Surface\HorizontalAcceleration.cs" />
<Compile Include="Flight\Readouts\Surface\VerticalAcceleration.cs" />
+ <Compile Include="Flight\Readouts\Vessel\AttitudeProcessor.cs" />
<Compile Include="Flight\Readouts\Vessel\DeltaVCurrentTotal.cs" />
+ <Compile Include="Flight\Readouts\Vessel\PitchRate.cs" />
+ <Compile Include="Flight\Readouts\Vessel\HeadingRate.cs" />
+ <Compile Include="Flight\Readouts\Vessel\RollRate.cs" />
+ <Compile Include="Flight\Readouts\Vessel\Roll.cs" />
+ <Compile Include="Flight\Readouts\Vessel\Pitch.cs" />
+ <Compile Include="Flight\Readouts\Vessel\Heading.cs" />
+ <Compile Include="Flight\Readouts\Vessel\PartCount.cs" />
<Compile Include="Flight\Readouts\Vessel\SuicideBurnDeltaV.cs" />
<Compile Include="Flight\Readouts\Vessel\SuicideBurnAltitude.cs" />
<Compile Include="Flight\Readouts\Vessel\SuicideBurnDistance.cs" />
@@ -103,8 +113,12 @@
<Compile Include="Flight\Readouts\Vessel\SuicideBurnProcessor.cs" />
<Compile Include="Flight\Readouts\Vessel\SurfaceThrustToWeight.cs" />
<Compile Include="Flight\Readouts\Surface\Situation.cs" />
+ <Compile Include="Flight\Readouts\Vessel\ThrustOffsetAngle.cs" />
+ <Compile Include="Flight\Readouts\Vessel\ThrustTorque.cs" />
<Compile Include="GuiDisplaySize.cs" />
<Compile Include="Helpers\AngleHelper.cs" />
+ <Compile Include="Helpers\Averager.cs" />
+ <Compile Include="Helpers\ForceAccumulator.cs" />
<Compile Include="Helpers\TextureHelper.cs" />
<Compile Include="Helpers\Units.cs" />
<Compile Include="Helpers\TimeFormatter.cs" />
--- a/KerbalEngineer/VesselSimulator/EngineSim.cs
+++ b/KerbalEngineer/VesselSimulator/EngineSim.cs
@@ -38,6 +38,7 @@
public bool isActive = false;
public double isp = 0;
public PartSim partSim;
+ public List<AppliedForce> appliedForces;
public double thrust = 0;
@@ -58,7 +59,8 @@
bool throttleLocked,
List<Propellant> propellants,
bool active,
- bool correctThrust)
+ bool correctThrust,
+ List<Transform> thrustTransforms)
{
StringBuilder buffer = null;
//MonoBehaviour.print("Create EngineSim for " + theEngine.name);
@@ -116,14 +118,14 @@
if (throttleLocked)
{
//MonoBehaviour.print("throttleLocked is true");
- flowRate = this.thrust / (this.isp * 9.81d);
+ flowRate = this.thrust / (this.isp * 9.82);
}
else
{
if (this.partSim.isLanded)
{
//MonoBehaviour.print("partSim.isLanded is true, mainThrottle = " + FlightInputHandler.state.mainThrottle);
- flowRate = Math.Max(0.000001d, this.thrust * FlightInputHandler.state.mainThrottle) / (this.isp * 9.81d);
+ flowRate = Math.Max(0.000001d, this.thrust * FlightInputHandler.state.mainThrottle) / (this.isp * 9.82);
}
else
{
@@ -136,12 +138,12 @@
}
//MonoBehaviour.print("requestedThrust > 0");
- flowRate = requestedThrust / (this.isp * 9.81d);
+ flowRate = requestedThrust / (this.isp * 9.82);
}
else
{
//MonoBehaviour.print("requestedThrust <= 0");
- flowRate = this.thrust / (this.isp * 9.81d);
+ flowRate = this.thrust / (this.isp * 9.82);
}
}
}
@@ -174,7 +176,7 @@
//MonoBehaviour.print("thrust at velocity = " + thrust);
}
- flowRate = this.thrust / (this.isp * 9.81d);
+ flowRate = this.thrust / (this.isp * 9.82);
}
if (SimManager.logOutput)
@@ -212,6 +214,14 @@
if (SimManager.logOutput)
{
MonoBehaviour.print(buffer);
+ }
+
+ appliedForces = new List<AppliedForce>();
+ double thrustPerThrustTransform = thrust / thrustTransforms.Count;
+ foreach (Transform thrustTransform in thrustTransforms) {
+ Vector3d direction = thrustTransform.forward.normalized;
+ Vector3d position = thrustTransform.position;
+ appliedForces.Add(new AppliedForce(direction * thrustPerThrustTransform, position));
}
}
@@ -257,46 +267,36 @@
break;
case ResourceFlowMode.STAGE_PRIORITY_FLOW:
- {
- Dictionary<int, HashSet<PartSim>> stagePartSets = new Dictionary<int, HashSet<PartSim>>();
- int maxStage = -1;
- foreach (PartSim aPartSim in allParts)
- {
- if (aPartSim.resources[type] > SimManager.RESOURCE_MIN)
- {
- //int stage = aPartSim.decoupledInStage; // Use the number of the stage the tank is decoupled in
- int stage = aPartSim.DecouplerCount(); // Use the count of decouplers between tank and root
- if (stage > maxStage)
- {
- maxStage = stage;
- }
- if (stagePartSets.ContainsKey(stage))
- {
- sourcePartSet = stagePartSets[stage];
- }
- else
- {
- sourcePartSet = new HashSet<PartSim>();
- stagePartSets.Add(stage, sourcePartSet);
- }
-
- sourcePartSet.Add(aPartSim);
- }
- }
-
- while (maxStage >= 0)
- {
- if (stagePartSets.ContainsKey(maxStage))
- {
- if (stagePartSets[maxStage].Count() > 0)
- {
- sourcePartSet = stagePartSets[maxStage];
- break;
- }
- }
- maxStage--;
- }
- }
+ var stagePartSets = new Dictionary<int, HashSet<PartSim>>();
+ var maxStage = -1;
+
+ Logger.Log(type);
+ foreach (var aPartSim in allParts)
+ {
+ if (aPartSim.resources[type] <= SimManager.RESOURCE_MIN || aPartSim.resourceFlowStates[type] == 0) continue;
+
+ var stage = aPartSim.DecouplerCount();
+ if (stage > maxStage)
+ {
+ maxStage = stage;
+ }
+
+ if (!stagePartSets.TryGetValue(stage, out sourcePartSet))
+ {
+ sourcePartSet = new HashSet<PartSim>();
+ stagePartSets.Add(stage, sourcePartSet);
+ }
+ sourcePartSet.Add(aPartSim);
+ }
+
+ for (var i = 0; i <= maxStage; i++)
+ {
+ HashSet<PartSim> stagePartSet;
+ if (stagePartSets.TryGetValue(i, out stagePartSet) && stagePartSet.Count > 0)
+ {
+ sourcePartSet = stagePartSet;
+ }
+ }
break;
case ResourceFlowMode.STACK_PRIORITY_SEARCH:
--- a/KerbalEngineer/VesselSimulator/PartSim.cs
+++ b/KerbalEngineer/VesselSimulator/PartSim.cs
@@ -32,9 +32,12 @@
namespace KerbalEngineer.VesselSimulator
{
+ using CompoundParts;
+
public class PartSim
{
private readonly List<AttachNodeSim> attachNodes = new List<AttachNodeSim>();
+ public Vector3d centerOfMass;
public double baseMass = 0d;
public double cost;
public int decoupledInStage;
@@ -71,6 +74,7 @@
public PartSim(Part thePart, int id, double atmosphere, LogMsg log)
{
this.part = thePart;
+ this.centerOfMass = thePart.transform.TransformPoint(thePart.CoMOffset);
this.partId = id;
this.name = this.part.partInfo.name;
@@ -84,7 +88,7 @@
this.fuelCrossFeed = this.part.fuelCrossFeed;
this.noCrossFeedNodeKey = this.part.NoCrossFeedNodeKey;
this.decoupledInStage = this.DecoupledInStage(this.part);
- this.isFuelLine = this.part is FuelLine;
+ this.isFuelLine = this.part.HasModule<CModuleFuelLine>();
this.isFuelTank = this.part is FuelTank;
this.isSepratron = this.IsSepratron();
this.inverseStage = this.part.inverseStage;
@@ -206,7 +210,8 @@
engine.throttleLocked,
engine.propellants,
engine.isOperational,
- correctThrust);
+ correctThrust,
+ engine.thrustTransforms);
allEngines.Add(engineSim);
}
}
@@ -238,7 +243,8 @@
engine.throttleLocked,
engine.propellants,
engine.isOperational,
- correctThrust);
+ correctThrust,
+ engine.thrustTransforms);
allEngines.Add(engineSim);
}
}
@@ -268,7 +274,8 @@
engine.throttleLocked,
engine.propellants,
engine.isOperational,
- correctThrust);
+ correctThrust,
+ engine.thrustTransforms);
allEngines.Add(engineSim);
}
}
--- a/KerbalEngineer/VesselSimulator/SimManager.cs
+++ b/KerbalEngineer/VesselSimulator/SimManager.cs
@@ -17,251 +17,187 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#region Using Directives
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Reflection;
-using System.Threading;
-
-using UnityEngine;
-
-#endregion
-
namespace KerbalEngineer.VesselSimulator
{
+ #region Using Directives
+
+ using System;
+ using System.Diagnostics;
+ using System.Reflection;
+ using System.Threading;
+ using UnityEngine;
+
+ #endregion
+
public class SimManager
{
+ #region Constants
+
public const double RESOURCE_MIN = 0.0001;
+
+ #endregion
+
+ #region Fields
+
+ public static bool dumpTree = false;
+ public static bool logOutput = false;
+ public static TimeSpan minSimTime = new TimeSpan(0, 0, 0, 0, 150);
+ public static bool vectoredThrust = false;
+ private static readonly object locker = new object();
+ private static readonly Stopwatch timer = new Stopwatch();
private static bool bRequested;
private static bool bRunning;
- private static readonly Stopwatch timer = new Stopwatch();
- private static long delayBetweenSims;
-
- public static bool dumpTree = false;
- public static bool logOutput = false;
- public static bool vectoredThrust = false;
- public static long minSimTime = 150;
+ private static TimeSpan delayBetweenSims;
// Support for RealFuels using reflection to check localCorrectThrust without dependency
- private static bool hasCheckedForRealFuels;
+
+ private static bool hasCheckedForMods;
private static bool hasInstalledRealFuels;
-
- private static FieldInfo RF_ModuleEngineConfigs_locaCorrectThrust;
- private static FieldInfo RF_ModuleHybridEngine_locaCorrectThrust;
- private static FieldInfo RF_ModuleHybridEngines_locaCorrectThrust;
+ private static FieldInfo RF_ModuleEngineConfigs_localCorrectThrust;
+ private static FieldInfo RF_ModuleHybridEngine_localCorrectThrust;
+ private static FieldInfo RF_ModuleHybridEngines_localCorrectThrust;
+ private static bool hasInstalledKIDS;
+ private static MethodInfo KIDS_Utils_GetIspMultiplier;
+ private static bool bKIDSThrustISP = false;
+ #endregion
+
+ #region Delegates
+
+ public delegate void ReadyEvent();
+
+ #endregion
+
+ #region Events
+
+ public static event ReadyEvent OnReady;
+
+ #endregion
+
+ #region Properties
+
+ public static double Atmosphere { get; set; }
+
+ public static double Gravity { get; set; }
+
+ public static Stage LastStage { get; private set; }
+
public static Stage[] Stages { get; private set; }
- public static Stage LastStage { get; private set; }
+
+ public static double Velocity { get; set; }
+
public static String failMessage { get; private set; }
- public static double Gravity { get; set; }
- public static double Atmosphere { get; set; }
- public static double Velocity { get; set; }
-
- private static void GetRealFuelsTypes()
- {
- hasCheckedForRealFuels = true;
-
- foreach (AssemblyLoader.LoadedAssembly assembly in AssemblyLoader.loadedAssemblies)
+
+ #endregion
+
+ #region Methods
+
+ private static void CheckForMods()
+ {
+ hasCheckedForMods = true;
+
+ foreach (var assembly in AssemblyLoader.loadedAssemblies)
{
MonoBehaviour.print("Assembly:" + assembly.assembly);
- if (assembly.assembly.ToString().Split(',')[0] == "RealFuels")
+ var name = assembly.assembly.ToString().Split(',')[0];
+
+ if (name == "RealFuels")
{
MonoBehaviour.print("Found RealFuels mod");
- Type RF_ModuleEngineConfigs_Type = assembly.assembly.GetType("RealFuels.ModuleEngineConfigs");
+ var RF_ModuleEngineConfigs_Type = assembly.assembly.GetType("RealFuels.ModuleEngineConfigs");
if (RF_ModuleEngineConfigs_Type != null)
{
- RF_ModuleEngineConfigs_locaCorrectThrust = RF_ModuleEngineConfigs_Type.GetField("localCorrectThrust");
- }
-
- Type RF_ModuleHybridEngine_Type = assembly.assembly.GetType("RealFuels.ModuleHybridEngine");
+ RF_ModuleEngineConfigs_localCorrectThrust = RF_ModuleEngineConfigs_Type.GetField("localCorrectThrust");
+ }
+
+ var RF_ModuleHybridEngine_Type = assembly.assembly.GetType("RealFuels.ModuleHybridEngine");
if (RF_ModuleHybridEngine_Type != null)
{
- RF_ModuleHybridEngine_locaCorrectThrust = RF_ModuleHybridEngine_Type.GetField("localCorrectThrust");
- }
-
- Type RF_ModuleHybridEngines_Type = assembly.assembly.GetType("RealFuels.ModuleHybridEngines");
+ RF_ModuleHybridEngine_localCorrectThrust = RF_ModuleHybridEngine_Type.GetField("localCorrectThrust");
+ }
+
+ var RF_ModuleHybridEngines_Type = assembly.assembly.GetType("RealFuels.ModuleHybridEngines");
if (RF_ModuleHybridEngines_Type != null)
{
- RF_ModuleHybridEngines_locaCorrectThrust = RF_ModuleHybridEngines_Type.GetField("localCorrectThrust");
+ RF_ModuleHybridEngines_localCorrectThrust = RF_ModuleHybridEngines_Type.GetField("localCorrectThrust");
}
hasInstalledRealFuels = true;
break;
}
+ else if (name == "KerbalIspDifficultyScaler")
+ {
+ var KIDS_Utils_Type = assembly.assembly.GetType("KerbalIspDifficultyScaler.KerbalIspDifficultyScalerUtils");
+ if (KIDS_Utils_Type != null)
+ {
+ KIDS_Utils_GetIspMultiplier = KIDS_Utils_Type.GetMethod("GetIspMultiplier");
+ }
+
+ hasInstalledKIDS = true;
+ }
}
}
public static bool DoesEngineUseCorrectedThrust(Part theEngine)
{
- if (!hasInstalledRealFuels /*|| HighLogic.LoadedSceneIsFlight*/)
- {
- return false;
- }
-
- // Look for any of the Real Fuels engine modules and call the relevant method to find out
- if (RF_ModuleEngineConfigs_locaCorrectThrust != null && theEngine.Modules.Contains("ModuleEngineConfigs"))
- {
- PartModule modEngineConfigs = theEngine.Modules["ModuleEngineConfigs"];
- if (modEngineConfigs != null)
- {
- // Check the localCorrectThrust
- if ((bool)RF_ModuleEngineConfigs_locaCorrectThrust.GetValue(modEngineConfigs))
- {
- return true;
- }
- }
- }
-
- if (RF_ModuleHybridEngine_locaCorrectThrust != null && theEngine.Modules.Contains("ModuleHybridEngine"))
- {
- PartModule modHybridEngine = theEngine.Modules["ModuleHybridEngine"];
- if (modHybridEngine != null)
- {
- // Check the localCorrectThrust
- if ((bool)RF_ModuleHybridEngine_locaCorrectThrust.GetValue(modHybridEngine))
- {
- return true;
- }
- }
- }
-
- if (RF_ModuleHybridEngines_locaCorrectThrust != null && theEngine.Modules.Contains("ModuleHybridEngines"))
- {
- PartModule modHybridEngines = theEngine.Modules["ModuleHybridEngines"];
- if (modHybridEngines != null)
- {
- // Check the localCorrectThrust
- if ((bool)RF_ModuleHybridEngines_locaCorrectThrust.GetValue(modHybridEngines))
- {
- return true;
- }
- }
+ if (hasInstalledRealFuels)
+ {
+ // 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"))
+ {
+ var modEngineConfigs = theEngine.Modules["ModuleEngineConfigs"];
+ if (modEngineConfigs != null)
+ {
+ // Return the localCorrectThrust
+ return (bool)RF_ModuleEngineConfigs_localCorrectThrust.GetValue(modEngineConfigs);
+ }
+ }
+
+ if (RF_ModuleHybridEngine_localCorrectThrust != null && theEngine.Modules.Contains("ModuleHybridEngine"))
+ {
+ var modHybridEngine = theEngine.Modules["ModuleHybridEngine"];
+ if (modHybridEngine != null)
+ {
+ // Return the localCorrectThrust
+ return (bool)RF_ModuleHybridEngine_localCorrectThrust.GetValue(modHybridEngine);
+ }
+ }
+
+ if (RF_ModuleHybridEngines_localCorrectThrust != null && theEngine.Modules.Contains("ModuleHybridEngines"))
+ {
+ var modHybridEngines = theEngine.Modules["ModuleHybridEngines"];
+ if (modHybridEngines != null)
+ {
+ // Return the localCorrectThrust
+ return (bool)RF_ModuleHybridEngines_localCorrectThrust.GetValue(modHybridEngines);
+ }
+ }
+ }
+
+ if (hasInstalledKIDS && HighLogic.LoadedSceneIsEditor)
+ {
+ return bKIDSThrustISP;
}
return false;
}
- public static void RequestSimulation()
- {
- if (!hasCheckedForRealFuels)
- {
- GetRealFuelsTypes();
- }
-
- bRequested = true;
- if (!timer.IsRunning)
- {
- timer.Start();
- }
- }
-
- public static void TryStartSimulation()
- {
- if (bRequested && !bRunning && (HighLogic.LoadedSceneIsEditor || FlightGlobals.ActiveVessel != null) && timer.ElapsedMilliseconds > delayBetweenSims)
- {
- bRequested = false;
- timer.Reset();
- StartSimulation();
- }
- }
-
- public static bool ResultsReady()
- {
- return !bRunning;
- }
-
- private static void ClearResults()
- {
- failMessage = "";
- Stages = null;
- LastStage = null;
- }
-
- private static void StartSimulation()
- {
- try
- {
- bRunning = true;
- ClearResults();
- timer.Start();
-
- List<Part> parts = HighLogic.LoadedSceneIsEditor ? EditorLogic.SortedShipList : FlightGlobals.ActiveVessel.Parts;
-
- // Create the Simulation object in this thread
- Simulation sim = new Simulation();
-
- // 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))
- {
- ThreadPool.QueueUserWorkItem(RunSimulation, sim);
- }
- else
- {
- failMessage = "PrepareSimulation failed";
- bRunning = false;
- logOutput = false;
- }
- }
- catch (Exception e)
- {
- MonoBehaviour.print("Exception in StartSimulation: " + e);
- failMessage = e.ToString();
- bRunning = false;
- logOutput = false;
- }
- dumpTree = false;
- }
-
- private static void RunSimulation(object simObject)
- {
- try
- {
- Stages = (simObject as Simulation).RunSimulation();
- if (Stages != null)
- {
- if (logOutput)
- {
- foreach (Stage stage in Stages)
- {
- stage.Dump();
- }
- }
- LastStage = Stages.Last();
- }
- }
- catch (Exception e)
- {
- MonoBehaviour.print("Exception in RunSimulation: " + e);
- Stages = null;
- LastStage = null;
- failMessage = e.ToString();
- }
-
- timer.Stop();
-#if TIMERS
- MonoBehaviour.print("Total simulation time: " + timer.ElapsedMilliseconds + "ms");
-#else
- if (logOutput)
- {
- MonoBehaviour.print("Total simulation time: " + timer.ElapsedMilliseconds + "ms");
- }
-#endif
- delayBetweenSims = minSimTime - timer.ElapsedMilliseconds;
- if (delayBetweenSims < 0)
- {
- delayBetweenSims = 0;
- }
-
- timer.Reset();
- timer.Start();
-
- bRunning = false;
- logOutput = false;
+ public static void UpdateModSettings()
+ {
+ if (!hasCheckedForMods)
+ {
+ CheckForMods();
+ }
+
+ if (hasInstalledKIDS)
+ {
+ // (out ispMultiplierVac, out ispMultiplierAtm, out extendToZeroIsp, out thrustCorrection, out ispCutoff, out thrustCutoff);
+ object[] parameters = new object[6];
+ KIDS_Utils_GetIspMultiplier.Invoke(null, parameters);
+ bKIDSThrustISP = (bool)parameters[3];
+ }
}
public static String GetVesselTypeString(VesselType vesselType)
@@ -293,5 +229,161 @@
}
return "Undefined";
}
+
+ public static void RequestSimulation()
+ {
+ if (!hasCheckedForMods)
+ {
+ CheckForMods();
+ }
+
+ lock (locker)
+ {
+ bRequested = true;
+ if (!timer.IsRunning)
+ {
+ timer.Start();
+ }
+ }
+ }
+
+ public static bool ResultsReady()
+ {
+ lock (locker)
+ {
+ return !bRunning;
+ }
+ }
+
+ public static void TryStartSimulation()
+ {
+ lock (locker)
+ {
+ if (!bRequested || bRunning || (timer.Elapsed < delayBetweenSims && timer.Elapsed >= TimeSpan.Zero) || (!HighLogic.LoadedSceneIsEditor && FlightGlobals.ActiveVessel == null))
+ {
+ return;
+ }
+
+ bRequested = false;
+ timer.Reset();
+ }
+
+ StartSimulation();
+ }
+
+ private static void ClearResults()
+ {
+ failMessage = "";
+ Stages = null;
+ LastStage = null;
+ }
+
+ private static void RunSimulation(object simObject)
+ {
+ try
+ {
+ Stages = (simObject as Simulation).RunSimulation();
+ if (Stages != null && Stages.Length > 0)
+ {
+ if (logOutput)
+ {
+ foreach (var stage in Stages)
+ {
+ stage.Dump();
+ }
+ }
+ LastStage = Stages[Stages.Length - 1];
+ }
+ }
+ catch (Exception e)
+ {
+ MonoBehaviour.print("Exception in RunSimulation: " + e);
+ Logger.Exception(e);
+ Stages = null;
+ LastStage = null;
+ failMessage = e.ToString();
+ }
+ lock (locker)
+ {
+ timer.Stop();
+#if TIMERS
+ MonoBehaviour.print("Total simulation time: " + timer.ElapsedMilliseconds + "ms");
+#else
+ if (logOutput)
+ {
+ MonoBehaviour.print("Total simulation time: " + timer.ElapsedMilliseconds + "ms");
+ }
+#endif
+
+ delayBetweenSims = minSimTime - timer.Elapsed;
+ if (delayBetweenSims < TimeSpan.Zero)
+ {
+ delayBetweenSims = TimeSpan.Zero;
+ }
+
+ timer.Reset();
+ timer.Start();
+
+ bRunning = false;
+ if (OnReady != null)
+ {
+ OnReady();
+ }
+ }
+
+ logOutput = false;
+ }
+
+ private static void StartSimulation()
+ {
+ try
+ {
+ lock (locker)
+ {
+ bRunning = true;
+ }
+
+ ClearResults();
+
+ lock (locker)
+ {
+ timer.Start();
+ }
+
+ var parts = HighLogic.LoadedSceneIsEditor ? EditorLogic.fetch.ship.parts : FlightGlobals.ActiveVessel.Parts;
+
+ // Create the Simulation object in this thread
+ var sim = new Simulation();
+
+ // 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))
+ {
+ ThreadPool.QueueUserWorkItem(RunSimulation, sim);
+ }
+ else
+ {
+ failMessage = "PrepareSimulation failed";
+ lock (locker)
+ {
+ bRunning = false;
+ }
+ logOutput = false;
+ }
+ }
+ catch (Exception e)
+ {
+ MonoBehaviour.print("Exception in StartSimulation: " + e);
+ Logger.Exception(e);
+ failMessage = e.ToString();
+ lock (locker)
+ {
+ bRunning = false;
+ }
+ logOutput = false;
+ }
+ dumpTree = false;
+ }
+
+ #endregion
}
}
--- a/KerbalEngineer/VesselSimulator/Simulation.cs
+++ b/KerbalEngineer/VesselSimulator/Simulation.cs
@@ -30,10 +30,13 @@
namespace KerbalEngineer.VesselSimulator
{
+ using CompoundParts;
+ using Extensions;
+
public class Simulation
{
- private const double STD_GRAVITY = 9.81d;
- private const double SECONDS_PER_DAY = 86400d;
+ private const double STD_GRAVITY = 9.82;
+ private const double SECONDS_PER_DAY = 86400;
private readonly Stopwatch _timer = new Stopwatch();
private List<EngineSim> activeEngines;
private List<EngineSim> allEngines;
@@ -52,6 +55,7 @@
private List<Part> partList;
private double simpleTotalThrust;
private double stageStartMass;
+ private Vector3d stageStartCom;
private double stageTime;
private double stepEndMass;
private double stepStartMass;
@@ -59,6 +63,7 @@
private double totalStageFlowRate;
private double totalStageIspFlowRate;
private double totalStageThrust;
+ private ForceAccumulator totalStageThrustForce;
private Vector3 vecActualThrust;
private Vector3 vecStageDeltaV;
private Vector3 vecThrust;
@@ -74,7 +79,7 @@
}
}
- private double ShipStartMass
+ private double ShipMass
{
get
{
@@ -82,25 +87,25 @@
foreach (PartSim partSim in this.allParts)
{
- mass += partSim.GetStartMass();
+ mass += partSim.GetMass();
}
return mass;
}
}
- private double ShipMass
+ private Vector3d ShipCom
{
get
{
- double mass = 0d;
+ WeightedVectorAverager averager = new WeightedVectorAverager();
foreach (PartSim partSim in this.allParts)
{
- mass += partSim.GetMass();
- }
-
- return mass;
+ averager.Add(partSim.centerOfMass, partSim.GetMass());
+ }
+
+ return averager.Get();
}
}
@@ -190,10 +195,11 @@
{
foreach (PartSim partSim in this.allFuelLines)
{
- if ((partSim.part as FuelLine).target != null)
+ CModuleFuelLine fuelLine = partSim.part.GetModule<CModuleFuelLine>();
+ if (fuelLine.target != null)
{
PartSim targetSim;
- if (partSimLookup.TryGetValue((partSim.part as FuelLine).target, out targetSim))
+ if (partSimLookup.TryGetValue(fuelLine.target, out targetSim))
{
if (log != null)
{
@@ -262,6 +268,7 @@
{
MonoBehaviour.print("RunSimulation started");
}
+
this._timer.Start();
LogMsg log = null;
@@ -365,7 +372,10 @@
this.stageTime = 0d;
this.vecStageDeltaV = Vector3.zero;
+
this.stageStartMass = this.ShipMass;
+ this.stageStartCom = this.ShipCom;
+
this.stepStartMass = this.stageStartMass;
this.stepEndMass = 0;
@@ -381,6 +391,27 @@
stage.actualThrust = this.totalStageActualThrust;
stage.actualThrustToWeight = this.totalStageActualThrust / (this.stageStartMass * this.gravity);
+ // calculate torque and associates
+ stage.maxThrustTorque = this.totalStageThrustForce.TorqueAt(this.stageStartCom).magnitude;
+
+ // torque divided by thrust. imagine that all engines are at the end of a lever that tries to turn the ship.
+ // this numerical value, in meters, would represent the length of that lever.
+ double torqueLeverArmLength = (stage.thrust <= 0) ? 0 : stage.maxThrustTorque / stage.thrust;
+
+ // how far away are the engines from the CoM, actually?
+ double thrustDistance = (this.stageStartCom - this.totalStageThrustForce.GetAverageForceApplicationPoint()).magnitude;
+
+ // the combination of the above two values gives an approximation of the offset angle.
+ double sinThrustOffsetAngle = 0;
+ if (thrustDistance > 1e-7) {
+ sinThrustOffsetAngle = torqueLeverArmLength / thrustDistance;
+ if (sinThrustOffsetAngle > 1) {
+ sinThrustOffsetAngle = 1;
+ }
+ }
+
+ stage.thrustOffsetAngle = Math.Asin(sinThrustOffsetAngle) * 180 / Math.PI;
+
// Calculate the cost and mass of this stage and add all engines and tanks that are decoupled
// in the next stage to the dontStageParts list
foreach (PartSim partSim in this.allParts)
@@ -485,6 +516,10 @@
MonoBehaviour.print("stageStartMass = " + this.stageStartMass);
MonoBehaviour.print("stepStartMass = " + this.stepStartMass);
MonoBehaviour.print("StepEndMass = " + this.stepEndMass);
+ Logger.Log("exceeded loop count");
+ Logger.Log("stageStartMass = " + this.stageStartMass);
+ Logger.Log("stepStartMass = " + this.stepStartMass);
+ Logger.Log("StepEndMass = " + this.stepEndMass);
break;
}
@@ -512,7 +547,7 @@
// Zero stage time if more than a day (this should be moved into the window code)
stage.time = (this.stageTime < SECONDS_PER_DAY) ? this.stageTime : 0d;
stage.number = this.doingCurrent ? -1 : this.currentStage; // Set the stage number to -1 if doing current engines
- stage.partCount = this.allParts.Count;
+ stage.totalPartCount = this.allParts.Count;
stages[this.currentStage] = stage;
// Now activate the next stage
@@ -550,6 +585,7 @@
stages[i].totalMass += stages[j].mass;
stages[i].totalDeltaV += stages[j].deltaV;
stages[i].totalTime += stages[j].time;
+ stages[i].partCount = i > 0 ? stages[i].totalPartCount - stages[i - 1].totalPartCount : stages[i].totalPartCount;
}
// We also total up the deltaV for stage and all stages below
for (int j = i; j < stages.Length; j++)
@@ -643,6 +679,7 @@
this.totalStageActualThrust = 0d;
this.totalStageFlowRate = 0d;
this.totalStageIspFlowRate = 0d;
+ this.totalStageThrustForce = new ForceAccumulator();
// Loop through all the active engines totalling the thrust, actual thrust and mass flow rates
// The thrust is totalled as vectors
@@ -654,6 +691,10 @@
this.totalStageFlowRate += engine.ResourceConsumptions.Mass;
this.totalStageIspFlowRate += engine.ResourceConsumptions.Mass * engine.isp;
+
+ foreach (AppliedForce f in engine.appliedForces) {
+ this.totalStageThrustForce.AddForce(f);
+ }
}
//MonoBehaviour.print("vecThrust = " + vecThrust.ToString() + " magnitude = " + vecThrust.magnitude);
@@ -749,7 +790,6 @@
partSim.DumpPartToBuffer(buffer, "Decoupled part not empty => false: ");
MonoBehaviour.print(buffer);
}
-
return false;
}
--- a/KerbalEngineer/VesselSimulator/Stage.cs
+++ b/KerbalEngineer/VesselSimulator/Stage.cs
@@ -29,24 +29,28 @@
{
public class Stage
{
- public double actualThrust = 0f;
- public double actualThrustToWeight = 0f;
- public double cost = 0d;
- public double deltaV = 0f;
- public double inverseTotalDeltaV = 0f;
- public double isp = 0f;
- public double mass = 0f;
- public double maxThrustToWeight = 0f;
+ public double actualThrust = 0.0;
+ public double actualThrustToWeight = 0.0;
+ public double cost = 0.0;
+ public double deltaV = 0.0;
+ public double inverseTotalDeltaV = 0.0;
+ public double isp = 0.0;
+ public double mass = 0.0;
+ public double rcsMass = 0.0;
+ public double maxThrustToWeight = 0.0;
public int number = 0;
- public double thrust = 0f;
- public double thrustToWeight = 0f;
- public double time = 0f;
- public double totalCost = 0;
- public double totalDeltaV = 0f;
- public double totalMass = 0f;
- public double totalTime = 0f;
+ public double thrust = 0.0;
+ public double thrustToWeight = 0.0;
+ public double time = 0.0;
+ public double totalCost = 0.0;
+ public double totalDeltaV = 0.0;
+ public double totalMass = 0.0;
+ public double totalTime = 0.0;
+ public int totalPartCount = 0;
public int partCount = 0;
public double resourceMass = 0.0;
+ public double maxThrustTorque = 0.0;
+ public double thrustOffsetAngle = 0.0;
public void Dump()
{
@@ -64,6 +68,8 @@
str.AppendFormat("thrustToWeight: {0:g6}\n", this.thrustToWeight);
str.AppendFormat("maxTWR : {0:g6}\n", this.maxThrustToWeight);
str.AppendFormat("actualTWR : {0:g6}\n", this.actualThrustToWeight);
+ str.AppendFormat("ThrustTorque : {0:g6}\n", this.maxThrustTorque);
+ str.AppendFormat("ThrustOffset : {0:g6}\n", this.thrustOffsetAngle);
str.AppendFormat("deltaV : {0:g6}\n", this.deltaV);
str.AppendFormat("totalDeltaV : {0:g6}\n", this.totalDeltaV);
str.AppendFormat("invTotDeltaV : {0:g6}\n", this.inverseTotalDeltaV);
Binary files a/Output/KerbalEngineer/KerbalEngineer.dll and b/Output/KerbalEngineer/KerbalEngineer.dll differ
--- a/Output/KerbalEngineer/KerbalEngineer.version
+++ b/Output/KerbalEngineer/KerbalEngineer.version
@@ -5,13 +5,13 @@
{
"MAJOR":1,
"MINOR":0,
- "PATCH":11,
- "BUILD":0
+ "PATCH":14,
+ "BUILD":1
},
"KSP_VERSION":
{
"MAJOR":0,
- "MINOR":25,
+ "MINOR":90,
"PATCH":0
}
}
Binary files /dev/null and b/Output/KerbalEngineer/Parts/Engineer7500/model000.mbm differ
--- a/Output/KerbalEngineer/Parts/Engineer7500/part.cfg
+++ b/Output/KerbalEngineer/Parts/Engineer7500/part.cfg
@@ -7,7 +7,6 @@
// --- asset parameters ---
mesh = model.mu
- texture = model000.mbm
rescaleFactor = 0.8
PhysicsSignificance = 1
Binary files a/Output/KerbalEngineer/Parts/Engineer7500/textures/model000.mbm and /dev/null differ