Added mach scaling and flow modification based on velocity and atmospheric curves.
Added mach scaling and flow modification based on velocity and atmospheric curves.
Atmospheric scale is now based on altitude in the editor.
Clamped altitude to the atmospheric depth of the body.
Clamped mach speed on the maximum usabled mach value of engines on vessel.

--- a/Documents/CHANGES.txt
+++ b/Documents/CHANGES.txt
@@ -1,3 +1,16 @@
+1.0.16.1, 26-04-2015, KSP Build #828
+    Merged Sarbian's mach adjustments.
+    Fixed bugs relating to thrust and atmosphere/velocity curves.
+    Changed the atmospheric slider on the Build Engineer to work based on altitude.
+    Changed the atmospheric slider to clamp to the maximum altitude for the selected body.
+    Changed the velocity slider to clamp to the maximum usable mach value for the current vessel.
+
+1.0.16.0, 25-04-2015, KSP Build #821
+    Fixed errors relating to KSP 1.0 update.
+    Fixed fuel simulation to account for new thrust system.
+    Fixed atmospheric engines to use the new velocity curve.
+    Fixed atmospheric readouts to work with the new atmospheric model.
+
 1.0.15.2, 13-02-2015
     Padishar's Fixes:
         Fixed: Calculation of per-stage resource mass.

--- a/KerbalEngineer/CelestialBodies.cs
+++ b/KerbalEngineer/CelestialBodies.cs
@@ -17,16 +17,12 @@
 //     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 // 
 
-#region Using Directives
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-#endregion
-
 namespace KerbalEngineer
 {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+
     /*
      * 
      * With thanks to Nathaniel R. Lewis (aka. Teknoman117) (linux.robotdude@gmail.com) for working out
@@ -36,8 +32,6 @@
 
     public static class CelestialBodies
     {
-        #region Constructors
-
         static CelestialBodies()
         {
             try
@@ -55,16 +49,8 @@
             }
         }
 
-        #endregion
-
-        #region Properties
-
         public static BodyInfo SelectedBody { get; private set; }
         public static BodyInfo SystemBody { get; private set; }
-
-        #endregion
-
-        #region Public Methods
 
         /// <summary>
         ///     Gets a body given a supplied body name.
@@ -89,7 +75,7 @@
         {
             try
             {
-                var body = GetBodyInfo(bodyName);
+                BodyInfo body = GetBodyInfo(bodyName);
                 if (body != null)
                 {
                     if (SelectedBody != null)
@@ -108,33 +94,26 @@
             return false;
         }
 
-        #endregion
-
-        #region Nested type: BodyInfo
-
         public class BodyInfo
         {
-            #region Constructors
-
             public BodyInfo(CelestialBody body, BodyInfo parent = null)
             {
                 try
                 {
                     // Set the body information.
-                    this.CelestialBody = body;
-                    this.Name = body.bodyName;
-                    this.Gravity = 9.81 * body.GeeASL;
-                    this.Atmosphere = body.atmosphere ? body.atmospherePressureSeaLevel : 0;
-                    this.Parent = parent;
+                    CelestialBody = body;
+                    Name = body.bodyName;
+                    Gravity = 9.81 * body.GeeASL;
+                    Parent = parent;
 
                     // Set orbiting bodies information.
-                    this.Children = new List<BodyInfo>();
-                    foreach (var orbitingBody in body.orbitingBodies)
-                    {
-                        this.Children.Add(new BodyInfo(orbitingBody, this));
-                    }
-
-                    this.SelectedDepth = 0;
+                    Children = new List<BodyInfo>();
+                    foreach (CelestialBody orbitingBody in body.orbitingBodies)
+                    {
+                        Children.Add(new BodyInfo(orbitingBody, this));
+                    }
+
+                    SelectedDepth = 0;
                 }
                 catch (Exception ex)
                 {
@@ -142,37 +121,28 @@
                 }
             }
 
-            #endregion
-
-            #region Properties
-
+            public CelestialBody CelestialBody { get; private set; }
+            public List<BodyInfo> Children { get; private set; }
+            public double Gravity { get; private set; }
             public string Name { get; private set; }
-            public double Gravity { get; private set; }
-            public double Atmosphere { get; private set; }
             public BodyInfo Parent { get; private set; }
-            public List<BodyInfo> Children { get; private set; }
-            public CelestialBody CelestialBody { get; private set; }
             public bool Selected { get; private set; }
             public int SelectedDepth { get; private set; }
 
-            #endregion
-
-            #region Public Methods
-
             public BodyInfo GetBodyInfo(string bodyName)
             {
                 try
                 {
                     // This is the searched body.
-                    if (String.Equals(this.Name, bodyName, StringComparison.CurrentCultureIgnoreCase))
+                    if (String.Equals(Name, bodyName, StringComparison.CurrentCultureIgnoreCase))
                     {
                         return this;
                     }
 
                     // Check to see if any of this bodies children are the searched body.
-                    foreach (var child in this.Children)
-                    {
-                        var body = child.GetBodyInfo(bodyName);
+                    foreach (BodyInfo child in Children)
+                    {
+                        BodyInfo body = child.GetBodyInfo(bodyName);
                         if (body != null)
                         {
                             return body;
@@ -188,33 +158,44 @@
                 return null;
             }
 
+            public double GetDensity(double altitude)
+            {
+                return CelestialBody.GetDensity(GetPressure(altitude), GetTemperature(altitude));
+            }
+
+            public double GetPressure(double altitude)
+            {
+                return CelestialBody.GetPressure(altitude);
+            }
+
+            public double GetTemperature(double altitude)
+            {
+                return CelestialBody.GetTemperature(altitude);
+            }
+
+            public double GetAtmospheres(double altitude)
+            {
+                return GetPressure(altitude) * PhysicsGlobals.KpaToAtmospheres;
+            }
+
             public void SetSelected(bool state, int depth = 0)
             {
-                this.Selected = state;
-                this.SelectedDepth = depth;
-                if (this.Parent != null)
-                {
-                    this.Parent.SetSelected(state, depth + 1);
-                }
-            }
-
-            #endregion
-
-            #region Debugging
+                Selected = state;
+                SelectedDepth = depth;
+                if (Parent != null)
+                {
+                    Parent.SetSelected(state, depth + 1);
+                }
+            }
 
             public override string ToString()
             {
-                var log = "\n" + this.Name +
-                          "\n\tGravity: " + this.Gravity +
-                          "\n\tAtmosphere: " + this.Atmosphere +
-                          "\n\tSelected: " + this.Selected;
-
-                return this.Children.Aggregate(log, (current, child) => current + "\n" + child);
-            }
-
-            #endregion
-        }
-
-        #endregion
+                string log = "\n" + Name +
+                             "\n\tGravity: " + Gravity +
+                             "\n\tSelected: " + Selected;
+
+                return Children.Aggregate(log, (current, child) => current + "\n" + child);
+            }
+        }
     }
 }

--- a/KerbalEngineer/Editor/BuildAdvanced.cs
+++ b/KerbalEngineer/Editor/BuildAdvanced.cs
@@ -37,10 +37,10 @@
     public class BuildAdvanced : MonoBehaviour
     {
         #region Fields
+        public static float Altitude = 500.0f;
 
         private GUIStyle areaSettingStyle;
         private GUIStyle areaStyle;
-        private float atmosphericPercentage = 1.0f;
         private float atmosphericMach;
         private GUIStyle bodiesButtonActiveStyle;
         private GUIStyle bodiesButtonStyle;
@@ -256,7 +256,7 @@
 
                 if (this.showAtmosphericDetails)
                 {
-                    SimManager.Atmosphere = CelestialBodies.SelectedBody.Atmosphere * 0.01d * this.atmosphericPercentage;
+                    SimManager.Atmosphere = CelestialBodies.SelectedBody.GetAtmospheres(Altitude);
                 }
                 else
                 {
@@ -296,9 +296,9 @@
         {
             GUILayout.BeginHorizontal();
             GUILayout.BeginVertical();
-            GUILayout.Label("Pressure: " + (this.atmosphericPercentage * 100.0f).ToString("F1") + "%", this.settingAtmoStyle, GUILayout.Width(125.0f * GuiDisplaySize.Offset));
+            GUILayout.Label("Altitude: " + (Altitude * 0.001f).ToString("F1") + "km", this.settingAtmoStyle, GUILayout.Width(125.0f * GuiDisplaySize.Offset));
             GUI.skin = HighLogic.Skin;
-            this.atmosphericPercentage = GUILayout.HorizontalSlider(this.atmosphericPercentage, 0, 1.0f);
+            Altitude = GUILayout.HorizontalSlider(Altitude, 0.0f, (float)(CelestialBodies.SelectedBody.CelestialBody.atmosphereDepth));
             GUI.skin = null;
             GUILayout.EndVertical();
 
@@ -307,7 +307,7 @@
             GUILayout.BeginVertical();
             GUILayout.Label("Mach: " + this.atmosphericMach.ToString("F1") + "m/s", this.settingAtmoStyle, GUILayout.Width(125.0f * GuiDisplaySize.Offset));
             GUI.skin = HighLogic.Skin;
-            this.atmosphericMach = GUILayout.HorizontalSlider(this.atmosphericMach, 0, 25f); // the game limits mach to 50 but I did not see curve with more than 25
+            atmosphericMach = GUILayout.HorizontalSlider(atmosphericMach, 0.0f, SimManager.LastStage.maxMach); // the game limits mach to 50 but I did not see curve with more than 25
             GUI.skin = null;
             GUILayout.EndVertical();
             GUILayout.EndHorizontal();

--- a/KerbalEngineer/Editor/BuildOverlayVessel.cs
+++ b/KerbalEngineer/Editor/BuildOverlayVessel.cs
@@ -188,7 +188,7 @@
 
             if (BuildAdvanced.Instance.ShowAtmosphericDetails)
             {
-                SimManager.Atmosphere = CelestialBodies.SelectedBody.Atmosphere * 0.01;
+                SimManager.Atmosphere = CelestialBodies.SelectedBody.GetAtmospheres(BuildAdvanced.Altitude);
             }
             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.15.2";
+        public const string AssemblyVersion = "1.0.16.1";
 
         #endregion
 

--- a/KerbalEngineer/Flight/Readouts/Surface/AtmosphericProcessor.cs
+++ b/KerbalEngineer/Flight/Readouts/Surface/AtmosphericProcessor.cs
@@ -48,7 +48,10 @@
         /// </summary>
         public static AtmosphericProcessor Instance
         {
-            get { return instance; }
+            get
+            {
+                return instance;
+            }
         }
 
         #endregion

--- a/KerbalEngineer/VesselSimulator/EngineSim.cs
+++ b/KerbalEngineer/VesselSimulator/EngineSim.cs
@@ -17,190 +17,84 @@
 //     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 System.Text;
-
-using UnityEngine;
-
-#endregion
-
 namespace KerbalEngineer.VesselSimulator
 {
+    using System;
+    using System.Collections.Generic;
+    using System.Text;
+    using Editor;
+    using Helpers;
+    using UnityEngine;
+
     public class EngineSim
     {
-        private readonly ResourceContainer resourceConsumptions = new ResourceContainer();
-
         public double actualThrust = 0;
+        public List<AppliedForce> appliedForces;
         public bool isActive = false;
         public double isp = 0;
         public PartSim partSim;
-        public List<AppliedForce> appliedForces;
+        public float maxMach;
 
         public double thrust = 0;
 
         // Add thrust vector to account for directional losses
         public Vector3 thrustVec;
+        private readonly ResourceContainer resourceConsumptions = new ResourceContainer();
 
         public EngineSim(PartSim theEngine,
-                         double atmosphere,
-                         double machNumber,
-                         float maxFuelFlow,
-                         float minFuelFlow,
-                         float thrustPercentage,
-                         Vector3 vecThrust,
-                         FloatCurve atmosphereCurve,
-                         bool atmChangeFlow,
-                         FloatCurve atmCurve,
-                         FloatCurve velCurve,
-                         float currentThrottle,
-                         float IspG,
-                         bool throttleLocked,
-                         List<Propellant> propellants,
-                         bool active,
-                         bool correctThrust,
-                         List<Transform> thrustTransforms)
+            double atmosphere,
+            float machNumber,
+            float maxFuelFlow,
+            float minFuelFlow,
+            float thrustPercentage,
+            Vector3 vecThrust,
+            FloatCurve atmosphereCurve,
+            bool atmChangeFlow,
+            FloatCurve atmCurve,
+            FloatCurve velCurve,
+            float currentThrottle,
+            bool throttleLocked,
+            List<Propellant> propellants,
+            bool active,
+            float resultingThrust,
+            List<Transform> thrustTransforms)
         {
             StringBuilder buffer = null;
-            //MonoBehaviour.print("Create EngineSim for " + theEngine.name);
-            //MonoBehaviour.print("maxThrust = " + maxThrust);
-            //MonoBehaviour.print("minThrust = " + minThrust);
-            //MonoBehaviour.print("thrustPercentage = " + thrustPercentage);
-            //MonoBehaviour.print("requestedThrust = " + requestedThrust);
-            //MonoBehaviour.print("velocity = " + velocity);
-
-            this.partSim = theEngine;
-
-            this.isActive = active;
-            //this.thrust = (maxThrust - minThrust) * (thrustPercentage / 100f) + minThrust;
-            //MonoBehaviour.print("thrust = " + thrust);
-
-            this.thrustVec = vecThrust;
-
-            double flowRate = 0d;
-            if (this.partSim.hasVessel)
-            {
-                //MonoBehaviour.print("hasVessel is true");
-
-                //this.actualThrust = this.isActive ? resultingThrust : 0.0;
-
-                this.isp = atmosphereCurve.Evaluate((float)atmosphere);
-
-                //if (this.isp == 0d)
-                //{
-                //    MonoBehaviour.print("Isp at " + this.partSim.part.staticPressureAtm + " is zero. Flow rate will be NaN");
-                //}
-
-
-                // correctThrust is less usefull now that the stock engines do it. Keep or remove.
-
-                //if (correctThrust && realIsp == 0)
-                //{
-                //    float ispsl = atmosphereCurve.Evaluate(0);
-                //    if (ispsl != 0)
-                //    {
-                //        this.thrust = this.thrust * this.isp / ispsl;
-                //    }
-                //    else
-                //    {
-                //        MonoBehaviour.print("Isp at sea level is zero. Unable to correct thrust.");
-                //    }
-                //    //MonoBehaviour.print("corrected thrust = " + thrust);
-                //}
-
-                //if (velocityCurve != null)
-                //{
-                //    this.thrust *= velocityCurve.Evaluate((float)velocity);
-                //    //MonoBehaviour.print("thrust at velocity = " + thrust);
-                //}
-                
-                float multiplier = 1;
-                if (atmChangeFlow)
-                {
-                    multiplier = (float)(partSim.part.atmDensity / 1.225);
-                    if (atmCurve != null)
-                    {
-                        multiplier = atmCurve.Evaluate(multiplier);
-                    }
-                    //MonoBehaviour.print("corrected thrust = " + thrust);
-                }
-                if (velCurve != null)
-                {
-                    multiplier *= velCurve.Evaluate((float)machNumber);
-                }
+
+            partSim = theEngine;
+            isActive = active;
+            thrustVec = vecThrust;
+
+            double flowRate = 0.0;
+            if (partSim.hasVessel)
+            {
+                float flowModifier = GetFlowModifier(atmChangeFlow, atmCurve, partSim.part.atmDensity, velCurve, machNumber, ref maxMach);
+                isp = atmosphereCurve.Evaluate((float)atmosphere);
+                thrust = GetThrust(Mathf.Lerp(minFuelFlow, maxFuelFlow, GetThrustPercent(thrustPercentage)) * flowModifier, isp);
+                actualThrust = isActive ? resultingThrust : 0.0;
 
                 if (throttleLocked)
                 {
-                    //MonoBehaviour.print("throttleLocked is true");
-                    //flowRate = this.thrust / (this.isp * 9.82);
-                    flowRate = Mathf.Lerp(minFuelFlow, maxFuelFlow, (thrustPercentage / 100f)) * multiplier;
+                    flowRate = GetFlowRate(thrust, isp);
                 }
                 else
                 {
-                    if (partSim.isLanded)
-                    {
-                        //MonoBehaviour.print("partSim.isLanded is true, mainThrottle = " + FlightInputHandler.state.mainThrottle);
-                        flowRate = Mathf.Lerp(minFuelFlow, maxFuelFlow, FlightInputHandler.state.mainThrottle * (thrustPercentage / 100f)) * multiplier;
+                    if (currentThrottle > 0.0f && partSim.isLanded == false)
+                    {
+                        flowRate = GetFlowRate(actualThrust, isp);
                     }
                     else
                     {
-                        if (currentThrottle > 0)
-                        {
-                            //MonoBehaviour.print("requestedThrust > 0");
-                            //flowRate = requestedThrust / (this.isp * 9.82) * multiplier;
-                            flowRate = Mathf.Lerp(minFuelFlow, maxFuelFlow, currentThrottle * (thrustPercentage / 100f)) * multiplier;
-                            
-                        }
-                        else
-                        {
-                            //MonoBehaviour.print("requestedThrust <= 0");
-                            flowRate = Mathf.Lerp(minFuelFlow, maxFuelFlow, (thrustPercentage / 100f)) * multiplier;
-                        }
+                        flowRate = GetFlowRate(thrust, isp);
                     }
                 }
             }
             else
             {
-                //MonoBehaviour.print("hasVessel is false");
-                this.isp = atmosphereCurve.Evaluate((float)atmosphere);
-                if (this.isp == 0d)
-                {
-                    MonoBehaviour.print("Isp at " + atmosphere + " is zero. Flow rate will be NaN");
-                }
-                //if (correctThrust)
-                //{
-                //    float ispsl = atmosphereCurve.Evaluate(0);
-                //    if (ispsl != 0)
-                //    {
-                //        this.thrust = this.thrust * this.isp / ispsl;
-                //    }
-                //    else
-                //    {
-                //        MonoBehaviour.print("Isp at sea level is zero. Unable to correct thrust.");
-                //    }
-                //    //MonoBehaviour.print("corrected thrust = " + thrust);
-                //}
-
-                float multiplier = 1;
-                if (atmChangeFlow)
-                {
-                    //multiplier = (float)(this.partSim.part.atmDensity / 1.225);
-                    multiplier = (float)atmosphere;    // technically wrong but the same for my Editor need
-                    if (atmCurve != null)
-                    {
-                        multiplier = atmCurve.Evaluate(multiplier);
-                    }
-                }
-
-                if (velCurve != null)
-                {
-                    multiplier *= velCurve.Evaluate((float)machNumber);
-                }
-
-                flowRate = Mathf.Lerp(minFuelFlow, maxFuelFlow, (thrustPercentage / 100f)) * multiplier;
+                float flowModifier = GetFlowModifier(atmChangeFlow, atmCurve, CelestialBodies.SelectedBody.GetDensity(BuildAdvanced.Altitude), velCurve, machNumber, ref maxMach);
+                isp = atmosphereCurve.Evaluate((float)atmosphere);
+                thrust = GetThrust(Mathf.Lerp(minFuelFlow, maxFuelFlow, GetThrustPercent(thrustPercentage)) * flowModifier, isp);
+                flowRate = GetFlowRate(thrust, isp);
             }
 
             if (SimManager.logOutput)
@@ -208,10 +102,6 @@
                 buffer = new StringBuilder(1024);
                 buffer.AppendFormat("flowRate = {0:g6}\n", flowRate);
             }
-            
-            thrust = flowRate * (isp * IspG);
-            // I did not look into the diff between those 2 so I made them equal...
-            actualThrust = thrust;
 
             float flowMass = 0f;
             foreach (Propellant propellant in propellants)
@@ -236,7 +126,7 @@
                 {
                     buffer.AppendFormat("Add consumption({0}, {1}:{2:d}) = {3:g6}\n", ResourceContainer.GetResourceName(propellant.id), theEngine.name, theEngine.partId, consumptionRate);
                 }
-                this.resourceConsumptions.Add(propellant.id, consumptionRate);
+                resourceConsumptions.Add(propellant.id, consumptionRate);
             }
 
             if (SimManager.logOutput)
@@ -246,7 +136,8 @@
 
             appliedForces = new List<AppliedForce>();
             double thrustPerThrustTransform = thrust / thrustTransforms.Count;
-            foreach (Transform thrustTransform in thrustTransforms) {
+            foreach (Transform thrustTransform in thrustTransforms)
+            {
                 Vector3d direction = thrustTransform.forward.normalized;
                 Vector3d position = thrustTransform.position;
                 appliedForces.Add(new AppliedForce(direction * thrustPerThrustTransform, position));
@@ -255,7 +146,64 @@
 
         public ResourceContainer ResourceConsumptions
         {
-            get { return this.resourceConsumptions; }
+            get
+            {
+                return resourceConsumptions;
+            }
+        }
+
+        public static double GetExhaustVelocity(double isp)
+        {
+            return isp * Units.GRAVITY;
+        }
+
+        public static float GetFlowModifier(bool atmChangeFlow, FloatCurve atmCurve, double atmDensity, FloatCurve velCurve, float machNumber, ref float maxMach)
+        {
+            float flowModifier = 1.0f;
+            if (atmChangeFlow)
+            {
+                flowModifier = (float)(atmDensity / 1.225);
+                if (atmCurve != null)
+                {
+                    flowModifier = atmCurve.Evaluate(flowModifier);
+                }
+            }
+            if (velCurve != null)
+            {
+                flowModifier = flowModifier * velCurve.Evaluate(machNumber);
+                maxMach = velCurve.maxTime;
+            }
+            if (flowModifier < float.Epsilon)
+            {
+                flowModifier = float.Epsilon;
+            }
+            return flowModifier;
+        }
+
+        public static double GetFlowRate(double thrust, double isp)
+        {
+            return thrust / GetExhaustVelocity(isp);
+        }
+
+        public static float GetThrottlePercent(float currentThrottle, float thrustPercentage)
+        {
+            return currentThrottle * GetThrustPercent(thrustPercentage);
+        }
+
+        public static double GetThrust(double flowRate, double isp)
+        {
+            return flowRate * GetExhaustVelocity(isp);
+        }
+
+        public static float GetThrustPercent(float thrustPercentage)
+        {
+            return thrustPercentage * 0.01f;
+        }
+
+        public void DumpEngineToBuffer(StringBuilder buffer, String prefix)
+        {
+            buffer.Append(prefix);
+            buffer.AppendFormat("[thrust = {0:g6}, actual = {1:g6}, isp = {2:g6}\n", thrust, actualThrust, isp);
         }
 
         public bool SetResourceDrains(List<PartSim> allParts, List<PartSim> allFuelLines, HashSet<PartSim> drainingParts)
@@ -265,17 +213,17 @@
             // A dictionary to hold a set of parts for each resource
             Dictionary<int, HashSet<PartSim>> sourcePartSets = new Dictionary<int, HashSet<PartSim>>();
 
-            foreach (int type in this.resourceConsumptions.Types)
+            foreach (int type in resourceConsumptions.Types)
             {
                 HashSet<PartSim> sourcePartSet = null;
                 switch (ResourceContainer.GetResourceFlowMode(type))
                 {
                     case ResourceFlowMode.NO_FLOW:
-                        if (this.partSim.resources[type] > SimManager.RESOURCE_MIN && this.partSim.resourceFlowStates[type] != 0)
+                        if (partSim.resources[type] > SimManager.RESOURCE_MIN && partSim.resourceFlowStates[type] != 0)
                         {
                             sourcePartSet = new HashSet<PartSim>();
                             //MonoBehaviour.print("SetResourceDrains(" + name + ":" + partId + ") setting sources to just this");
-                            sourcePartSet.Add(this.partSim);
+                            sourcePartSet.Add(partSim);
                         }
                         break;
 
@@ -295,15 +243,18 @@
                         break;
 
                     case ResourceFlowMode.STAGE_PRIORITY_FLOW:
-                        var stagePartSets = new Dictionary<int, HashSet<PartSim>>();
-                        var maxStage = -1;
+                        Dictionary<int, HashSet<PartSim>> stagePartSets = new Dictionary<int, HashSet<PartSim>>();
+                        int 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();
+                        foreach (PartSim aPartSim in allParts)
+                        {
+                            if (aPartSim.resources[type] <= SimManager.RESOURCE_MIN || aPartSim.resourceFlowStates[type] == 0)
+                            {
+                                continue;
+                            }
+
+                            int stage = aPartSim.DecouplerCount();
                             if (stage > maxStage)
                             {
                                 maxStage = stage;
@@ -317,7 +268,7 @@
                             sourcePartSet.Add(aPartSim);
                         }
 
-                        for (var i = 0; i <= maxStage; i++)
+                        for (int i = 0; i <= maxStage; i++)
                         {
                             HashSet<PartSim> stagePartSet;
                             if (stagePartSets.TryGetValue(i, out stagePartSet) && stagePartSet.Count > 0)
@@ -333,9 +284,9 @@
                         if (SimManager.logOutput)
                         {
                             log = new LogMsg();
-                            log.buf.AppendLine("Find " + ResourceContainer.GetResourceName(type) + " sources for " + this.partSim.name + ":" + this.partSim.partId);
-                        }
-                        sourcePartSet = this.partSim.GetSourceSet(type, allParts, visited, log, "");
+                            log.buf.AppendLine("Find " + ResourceContainer.GetResourceName(type) + " sources for " + partSim.name + ":" + partSim.partId);
+                        }
+                        sourcePartSet = partSim.GetSourceSet(type, allParts, visited, log, "");
                         if (SimManager.logOutput)
                         {
                             MonoBehaviour.print(log.buf);
@@ -343,7 +294,7 @@
                         break;
 
                     default:
-                        MonoBehaviour.print("SetResourceDrains(" + this.partSim.name + ":" + this.partSim.partId + ") Unexpected flow type for " + ResourceContainer.GetResourceName(type) + ")");
+                        MonoBehaviour.print("SetResourceDrains(" + partSim.name + ":" + partSim.partId + ") Unexpected flow type for " + ResourceContainer.GetResourceName(type) + ")");
                         break;
                 }
 
@@ -364,7 +315,7 @@
             }
 
             // If we don't have sources for all the needed resources then return false without setting up any drains
-            foreach (int type in this.resourceConsumptions.Types)
+            foreach (int type in resourceConsumptions.Types)
             {
                 if (!sourcePartSets.ContainsKey(type))
                 {
@@ -373,17 +324,17 @@
                         MonoBehaviour.print("No source of " + ResourceContainer.GetResourceName(type));
                     }
 
-                    this.isActive = false;
+                    isActive = false;
                     return false;
                 }
             }
 
             // Now we set the drains on the members of the sets and update the draining parts set
-            foreach (int type in this.resourceConsumptions.Types)
+            foreach (int type in resourceConsumptions.Types)
             {
                 HashSet<PartSim> sourcePartSet = sourcePartSets[type];
                 // Loop through the members of the set 
-                double amount = this.resourceConsumptions[type] / sourcePartSet.Count;
+                double amount = resourceConsumptions[type] / sourcePartSet.Count;
                 foreach (PartSim partSim in sourcePartSet)
                 {
                     if (SimManager.logOutput)
@@ -398,11 +349,5 @@
 
             return true;
         }
-
-        public void DumpEngineToBuffer(StringBuilder buffer, String prefix)
-        {
-            buffer.Append(prefix);
-            buffer.AppendFormat("[thrust = {0:g6}, actual = {1:g6}, isp = {2:g6}\n", this.thrust, this.actualThrust, this.isp);
-        }
     }
 }

--- a/KerbalEngineer/VesselSimulator/PartSim.cs
+++ b/KerbalEngineer/VesselSimulator/PartSim.cs
@@ -198,7 +198,7 @@
 
                         EngineSim engineSim = new EngineSim(this,
                             atmosphere,
-                            mach,
+                            (float)mach,
                             engine.maxFuelFlow,
                             engine.minFuelFlow,
                             engine.thrustPercentage,
@@ -208,11 +208,10 @@
                             engine.useAtmCurve ? engine.atmCurve : null,
                             engine.useVelCurve ? engine.velCurve : null,
                             engine.currentThrottle,
-                            engine.g,
                             engine.throttleLocked || fullThrust,
                             engine.propellants,
                             engine.isOperational,
-                            correctThrust,
+                            engine.resultingThrust,
                             engine.thrustTransforms);
                         allEngines.Add(engineSim);
                     }
@@ -233,7 +232,7 @@
 
                         EngineSim engineSim = new EngineSim(this,
                             atmosphere,
-                            mach,
+                            (float)mach,
                             engine.maxFuelFlow,
                             engine.minFuelFlow,
                             engine.thrustPercentage,
@@ -243,11 +242,10 @@
                             engine.useAtmCurve ? engine.atmCurve : null,
                             engine.useVelCurve ? engine.velCurve : null,
                             engine.currentThrottle,
-                            engine.g,
                             engine.throttleLocked || fullThrust,
                             engine.propellants,
                             engine.isOperational,
-                            correctThrust,
+                            engine.resultingThrust,
                             engine.thrustTransforms);
                         allEngines.Add(engineSim);
                     }

--- a/KerbalEngineer/VesselSimulator/SimManager.cs
+++ b/KerbalEngineer/VesselSimulator/SimManager.cs
@@ -22,6 +22,7 @@
     #region Using Directives
 
     using System;
+    using System.Collections.Generic;
     using System.Diagnostics;
     using System.Reflection;
     using System.Threading;
@@ -350,7 +351,16 @@
                     timer.Start();
                 }
 
-                var parts = HighLogic.LoadedSceneIsEditor ? EditorLogic.fetch.ship.parts : FlightGlobals.ActiveVessel.Parts;
+                List<Part> parts;
+                if (HighLogic.LoadedSceneIsEditor)
+                {
+                    parts = EditorLogic.fetch.ship.parts;
+                }
+                else
+                {
+                    parts = FlightGlobals.ActiveVessel.Parts;
+                    Atmosphere = FlightGlobals.ActiveVessel.staticPressurekPa * PhysicsGlobals.KpaToAtmospheres;
+                }
 
                 // Create the Simulation object in this thread
                 var sim = new Simulation();

--- a/KerbalEngineer/VesselSimulator/Simulation.cs
+++ b/KerbalEngineer/VesselSimulator/Simulation.cs
@@ -68,6 +68,7 @@
         private Vector3 vecStageDeltaV;
         private Vector3 vecThrust;
         private double mach;
+        private float maxMach;
         public String vesselName;
         public VesselType vesselType;
 
@@ -179,6 +180,11 @@
                 }
 
                 partId++;
+            }
+
+            for (int i = 0; i < allEngines.Count; ++i)
+            {
+                maxMach = Mathf.Max(maxMach, allEngines[i].maxMach);
             }
 
             this.UpdateActiveEngines();
@@ -548,6 +554,7 @@
                 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.totalPartCount = this.allParts.Count;
+                stage.maxMach = maxMach;
                 stages[this.currentStage] = stage;
 
                 // Now activate the next stage

--- a/KerbalEngineer/VesselSimulator/Stage.cs
+++ b/KerbalEngineer/VesselSimulator/Stage.cs
@@ -51,6 +51,7 @@
         public double resourceMass = 0.0;
         public double maxThrustTorque = 0.0;
         public double thrustOffsetAngle = 0.0;
+        public float maxMach = 0.0f;
 
         public void Dump()
         {

 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":15,
-		"BUILD":2
+		"PATCH":16,
+		"BUILD":1
 	},
 	"KSP_VERSION":
 	{
-		"MAJOR":0,
-		"MINOR":90,
+		"MAJOR":1,
+		"MINOR":0,
 		"PATCH":0
 	}
 }