Don't bother calling MB.print if LogMsg is empty when flushed
Don't bother calling MB.print if LogMsg is empty when flushed

--- a/Documents/CHANGES.txt
+++ b/Documents/CHANGES.txt
@@ -1,24 +1,38 @@
+1.0.17.1
+    Fixed: Synched the minimum simulation time sliders and stopped them from snapping back after 999ms. (saybur)
+
 1.0.17.0
     Added: 'Mach Number' readout under the 'Surface' category and included it on the default surface HUD.
+    Added: Stock sections in the Flight Engineer can now become HUDs.
     Added 'Thermal' readouts category including:
         Internal Flux
         Convection Flux
         Radiation Flux
         Critical Part Name
         Critical Part Temperature
-        Critical Part Percentage of Max Temperature
+        Critical Part Skin Temperature
+        Critical Part Thermal Percentage of Max Temperature
         Hottest Part Name
         Hottest Part Temperature
+        Hottest Part Skin Temperature
         Coldest Part Name
         Coldest Part Temperature
+        Coldest Part Skin Temperature
 
     Changed: Mach on the Build Engineer now accurate to 2 decimal places.
     Changed: Max mach in the Build Engineer defaults to 1.00 even when no jet engines are present.
     Changed: Increased eccentricity readout to 5 decimal places.  
     Changed: Implemented Sarbian's object pooling. 
+    Changed: The default selected body is now assigned via 'Planitarium.Home'.
+    Changed: HUDs to clamp fully inside the screen instead of allowing them to run off the edge by a certain amount.
     Fixed: Physically insignificant part mass is now associated with the parent part.
     Fixed: Longitude and Latitude readouts now use a KER formatter instead of Squad's incorrect implementation.
     Fixed: Possible null reference in the Rendezvous Processor.
+    Fixed: Fairing mass issues introduced with regards to simulation changes.
+    Fixed: Use of per-propellant fuel flow mode override.
+    Fixed: Burn times calculated for jet engines.
+    Fixed: Thrust issues introduced with Sarbian's simulation alterations.
+    Fixed: Issue where HUDs positioned close to the top/bottom of the screen could be pushed out of position.
 
 1.0.16.6, 02-05-15
     Fixed: Separately staged fairing mass jettisons are now calculated in the editor.

--- a/KerbalEngineer/Control/ControlCentre.cs
+++ b/KerbalEngineer/Control/ControlCentre.cs
@@ -142,7 +142,7 @@
             try
             {
                 GUI.skin = null;
-                this.position = GUILayout.Window(this.GetInstanceID(), this.position, this.Window, "KERBAL ENGINEER REDUX " + EngineerGlobals.AssemblyVersion + " - CONTROL CENTRE", HighLogic.Skin.window);
+                this.position = GUILayout.Window(this.GetInstanceID(), this.position, this.Window, "KERBAL ENGINEER REDUX " + EngineerGlobals.ASSEMBLY_VERSION + " - CONTROL CENTRE", HighLogic.Skin.window);
                 this.CentreWindow();
             }
             catch (Exception ex)

--- a/KerbalEngineer/Editor/BuildAdvanced.cs
+++ b/KerbalEngineer/Editor/BuildAdvanced.cs
@@ -215,7 +215,7 @@
                 }
 
                 // Change the window title based on whether in compact mode or not.
-                title = !compactMode ? "KERBAL ENGINEER REDUX " + EngineerGlobals.AssemblyVersion : "K.E.R. " + EngineerGlobals.AssemblyVersion;
+                title = !compactMode ? "KERBAL ENGINEER REDUX " + EngineerGlobals.ASSEMBLY_VERSION : "K.E.R. " + EngineerGlobals.ASSEMBLY_VERSION;
 
                 // Reset the window size when the staging or something else has changed.
                 stagesLength = stages.Length;
@@ -523,12 +523,12 @@
             GUILayout.EndHorizontal();
 
             GUILayout.BeginHorizontal();
-            GUILayout.Label("Simulate using vectored thrust values:");
+            GUILayout.Label("Simulate using vectored thrust values:", settingStyle);
             SimManager.vectoredThrust = GUILayout.Toggle(SimManager.vectoredThrust, "ENABLED", buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
             GUILayout.EndHorizontal();
 
             GUILayout.BeginHorizontal();
-            GUILayout.Label("Verbose Simulation Log:");
+            GUILayout.Label("Verbose Simulation Log:", settingStyle);
             SimManager.logOutput = GUILayout.Toggle(SimManager.logOutput, "ENABLED", buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
             GUILayout.EndHorizontal();
 
@@ -563,9 +563,9 @@
             }
             GUILayout.EndHorizontal();
 
-            GUILayout.Label("Minimum delay between simulations: " + SimManager.minSimTime.Milliseconds + "ms", settingStyle);
+            GUILayout.Label("Minimum delay between simulations: " + SimManager.minSimTime.TotalMilliseconds + "ms", settingStyle);
             GUI.skin = HighLogic.Skin;
-            SimManager.minSimTime = new TimeSpan(0, 0, 0, 0, (int)GUILayout.HorizontalSlider(SimManager.minSimTime.Milliseconds, 0, 2000.0f));
+            SimManager.minSimTime = TimeSpan.FromMilliseconds(GUILayout.HorizontalSlider((float)SimManager.minSimTime.TotalMilliseconds, 0, 2000.0f));
             GUI.skin = null;
         }
 

--- a/KerbalEngineer/EngineerGlobals.cs
+++ b/KerbalEngineer/EngineerGlobals.cs
@@ -1,7 +1,5 @@
 // 
-//     Kerbal Engineer Redux
-// 
-//     Copyright (C) 2014 CYBUTEK
+//     Copyright (C) 2015 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
@@ -17,42 +15,31 @@
 //     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 // 
 
-#region Using Directives
-
-using System.IO;
-using System.Reflection;
-
-#endregion
-
 namespace KerbalEngineer
 {
-    public class EngineerGlobals
+    using System.IO;
+    using System.Reflection;
+
+    public static class EngineerGlobals
     {
-        #region Constants
-
         /// <summary>
         ///     Current version of the Kerbal Engineer assembly.
         /// </summary>
-        public const string AssemblyVersion = "1.0.16.6";
-
-        #endregion
-
-        #region Fields
+        public const string ASSEMBLY_VERSION = "1.0.17.0";
 
         private static string assemblyFile;
         private static string assemblyName;
         private static string assemblyPath;
-
-        #endregion
-
-        #region Properties
 
         /// <summary>
         ///     Gets the Kerbal Engineer assembly's path including the file name.
         /// </summary>
         public static string AssemblyFile
         {
-            get { return assemblyFile ?? (assemblyFile = Assembly.GetExecutingAssembly().Location); }
+            get
+            {
+                return assemblyFile ?? (assemblyFile = Assembly.GetExecutingAssembly().Location);
+            }
         }
 
         /// <summary>
@@ -60,7 +47,10 @@
         /// </summary>
         public static string AssemblyName
         {
-            get { return assemblyName ?? (assemblyName = new FileInfo(AssemblyFile).Name); }
+            get
+            {
+                return assemblyName ?? (assemblyName = new FileInfo(AssemblyFile).Name);
+            }
         }
 
         /// <summary>
@@ -68,9 +58,10 @@
         /// </summary>
         public static string AssemblyPath
         {
-            get { return assemblyPath ?? (assemblyPath = AssemblyFile.Replace(new FileInfo(AssemblyFile).Name, "")); }
+            get
+            {
+                return assemblyPath ?? (assemblyPath = AssemblyFile.Replace(new FileInfo(AssemblyFile).Name, ""));
+            }
         }
-
-        #endregion
     }
 }

--- a/KerbalEngineer/Extensions/PartExtensions.cs
+++ b/KerbalEngineer/Extensions/PartExtensions.cs
@@ -197,10 +197,10 @@
             return GetModule<ModuleEngines>(part);
         }
 
-        public static ModuleEnginesFX GetModuleEnginesFx(this Part part)
+/*        public static ModuleEnginesFX GetModuleEnginesFx(this Part part)
         {
             return GetModule<ModuleEnginesFX>(part);
-        }
+        }*/
 
         /// <summary>
         ///     Gets a ModuleGenerator typed PartModule.
@@ -221,19 +221,19 @@
         /// <summary>
         ///     Gets the current selected ModuleEnginesFX.
         /// </summary>
-        public static ModuleEnginesFX GetModuleMultiModeEngine(this Part part)
-        {
-            ModuleEnginesFX moduleEngineFx;
+        public static ModuleEngines GetModuleMultiModeEngine(this Part part)
+        {
+            ModuleEngines moduleEngines;
             MultiModeEngine multiMod = GetModule<MultiModeEngine>(part);
             if (multiMod != null)
             {
                 string mode = multiMod.mode;
                 for (int i = 0; i < part.Modules.Count; ++i)
                 {
-                    moduleEngineFx = part.Modules[i] as ModuleEnginesFX;
-                    if (moduleEngineFx != null && moduleEngineFx.engineID == mode)
+                    moduleEngines = part.Modules[i] as ModuleEngines;
+                    if (moduleEngines != null && moduleEngines.engineID == mode)
                     {
-                        return moduleEngineFx;
+                        return moduleEngines;
                     }
                 }
             }
@@ -466,7 +466,7 @@
         /// </summary>
         public static bool IsEngine(this Part part)
         {
-            return HasModule<ModuleEngines>(part) || HasModule<ModuleEnginesFX>(part);
+            return HasModule<ModuleEngines>(part);
         }
 
         /// <summary>
@@ -549,7 +549,7 @@
         /// </summary>
         public static bool IsSolidRocket(this Part part)
         {
-            return (part.HasModule<ModuleEngines>() && part.GetModuleEngines().throttleLocked) || (part.HasModule<ModuleEnginesFX>() && part.GetModuleEnginesFx().throttleLocked);
+            return (part.HasModule<ModuleEngines>() && part.GetModuleEngines().throttleLocked);
         }
 
         public class ProtoModuleDecoupler

--- a/KerbalEngineer/Flight/DisplayStack.cs
+++ b/KerbalEngineer/Flight/DisplayStack.cs
@@ -214,7 +214,7 @@
         /// </summary>
         private void DrawControlBar()
         {
-            GUILayout.Label("FLIGHT ENGINEER " + EngineerGlobals.AssemblyVersion, this.titleStyle);
+            GUILayout.Label("FLIGHT ENGINEER " + EngineerGlobals.ASSEMBLY_VERSION, this.titleStyle);
 
             this.DrawControlBarButtons(SectionLibrary.StockSections);
             this.DrawControlBarButtons(SectionLibrary.CustomSections);

--- a/KerbalEngineer/Flight/Readouts/Miscellaneous/SimulationDelay.cs
+++ b/KerbalEngineer/Flight/Readouts/Miscellaneous/SimulationDelay.cs
@@ -51,7 +51,7 @@
             GUILayout.BeginHorizontal();
             GUILayout.Label("Sim Delay", this.NameStyle);
             GUI.skin = HighLogic.Skin;
-            SimManager.minSimTime = new TimeSpan(0, 0, 0, 0, (int)GUILayout.HorizontalSlider(SimManager.minSimTime.Milliseconds, 0, 1000.0f));
+            SimManager.minSimTime = TimeSpan.FromMilliseconds(GUILayout.HorizontalSlider((float)SimManager.minSimTime.TotalMilliseconds, 0, 2000.0f));
             GUI.skin = null;
             GUILayout.EndHorizontal();
         }

--- a/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/ManoeuvreProcessor.cs
+++ b/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/ManoeuvreProcessor.cs
@@ -63,6 +63,10 @@
 
         public static double NormalDeltaV { get; private set; }
 
+        public static double PostBurnAp { get; private set; }
+
+        public static double PostBurnPe { get; private set; }
+
         public static double ProgradeDeltaV { get; private set; }
 
         public static double RadialDeltaV { get; private set; }
@@ -110,6 +114,8 @@
             NormalDeltaV = deltaV.y;
             RadialDeltaV = deltaV.x;
             TotalDeltaV = node.GetBurnVector(FlightGlobals.ship_orbit).magnitude;
+            PostBurnAp = node.nextPatch != null ? node.nextPatch.ApA : 0;
+            PostBurnPe = node.nextPatch != null ? node.nextPatch.PeA : 0;
 
             UniversalTime = FlightGlobals.ActiveVessel.patchedConicSolver.maneuverNodes[0].UT;
             AngleToPrograde = FlightGlobals.ActiveVessel.patchedConicSolver.maneuverNodes[0].patch.GetAngleToPrograde(UniversalTime);

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/PostBurnApoapsis.cs
@@ -1,1 +1,69 @@
+// 
+//     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.ManoeuvreNode
+{
+    public class PostBurnApoapsis : ReadoutModule
+    {
+        #region Constructors
+
+        public PostBurnApoapsis()
+        {
+            this.Name = "Post-burn Apoapsis";
+            this.Category = ReadoutCategory.GetCategory("Orbital");
+            this.HelpString = String.Empty;
+            this.IsDefault = false;
+        }
+
+        #endregion
+
+        #region Methods: public
+
+        public override void Draw(SectionModule section)
+        {
+            if (!ManoeuvreProcessor.ShowDetails)
+            {
+                return;
+            }
+
+            this.DrawLine("Post-burn Apoapsis", ManoeuvreProcessor.PostBurnAp.ToDistance(), section.IsHud);
+        }
+
+        public override void Reset()
+        {
+            ManoeuvreProcessor.Reset();
+        }
+
+        public override void Update()
+        {
+            ManoeuvreProcessor.RequestUpdate();
+        }
+
+        #endregion
+    }
+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/ManoeuvreNode/PostBurnPeriapsis.cs
@@ -1,1 +1,69 @@
+// 
+//     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.ManoeuvreNode
+{
+    public class PostBurnPeriapsis : ReadoutModule
+    {
+        #region Constructors
+
+        public PostBurnPeriapsis()
+        {
+            this.Name = "Post-burn Periapsis";
+            this.Category = ReadoutCategory.GetCategory("Orbital");
+            this.HelpString = String.Empty;
+            this.IsDefault = false;
+        }
+
+        #endregion
+
+        #region Methods: public
+
+        public override void Draw(SectionModule section)
+        {
+            if (!ManoeuvreProcessor.ShowDetails)
+            {
+                return;
+            }
+
+            this.DrawLine("Post-burn Periapsis", ManoeuvreProcessor.PostBurnPe.ToDistance(), section.IsHud);
+        }
+
+        public override void Reset()
+        {
+            ManoeuvreProcessor.Reset();
+        }
+
+        public override void Update()
+        {
+            ManoeuvreProcessor.RequestUpdate();
+        }
+
+        #endregion
+    }
+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/SpeedAtApoapsis.cs
@@ -1,1 +1,68 @@
+// 
+//     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 KerbalEngineer.Extensions;
+
+#endregion
+
+namespace KerbalEngineer.Flight.Readouts.Orbital
+{
+    public class SpeedAtApoapsis : ReadoutModule
+    {
+        #region Constructors
+
+        public SpeedAtApoapsis()
+        {
+            this.Name = "Speed at Apoapsis";
+            this.Category = ReadoutCategory.GetCategory("Orbital");
+            this.HelpString = "Shows the orbital speed of the vessel when at apoapsis, the highest point of the orbit.";
+            this.IsDefault = false;
+        }
+
+        #endregion
+
+        #region Methods: public
+
+        public override void Draw(SectionModule section)
+        {
+            // Vis-viva: v^2 = GM(2/r - 1/a)
+            // All this is easily got from the ships orbit (and reference body)
+            String str;
+            Orbit orbit = FlightGlobals.ship_orbit;
+            if (orbit.eccentricity > 1.0)
+                str = "---m/s";
+            else
+            {
+                double speedsqr = orbit.referenceBody.gravParameter * ((2 / orbit.ApR) - (1 / orbit.semiMajorAxis));
+                if (Double.IsNaN(speedsqr) || speedsqr < 0)
+                    str = "---m/s";     // Don't think this is possible barring bugs in the Orbit class
+                else
+                    str = Math.Sqrt(speedsqr).ToSpeed();
+            }
+            this.DrawLine(str, section.IsHud);
+        }
+
+        #endregion
+    }
+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/SpeedAtPeriapsis.cs
@@ -1,1 +1,64 @@
+// 
+//     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 KerbalEngineer.Extensions;
+
+#endregion
+
+namespace KerbalEngineer.Flight.Readouts.Orbital
+{
+    public class SpeedAtPeriapsis : ReadoutModule
+    {
+        #region Constructors
+
+        public SpeedAtPeriapsis()
+        {
+            this.Name = "Speed at Periapsis";
+            this.Category = ReadoutCategory.GetCategory("Orbital");
+            this.HelpString = "Shows the orbital speed of the vessel when at periapsis, the lowest point of the orbit.";
+            this.IsDefault = false;
+        }
+
+        #endregion
+
+        #region Methods: public
+
+        public override void Draw(SectionModule section)
+        {
+            // Vis-viva: v^2 = GM(2/r - 1/a)
+            // All this is easily got from the ships orbit (and reference body)
+            String str;
+            Orbit orbit = FlightGlobals.ship_orbit;
+            double oneovera = (orbit.eccentricity == 1) ? 0 : (1 / orbit.semiMajorAxis);
+            double speedsqr = orbit.referenceBody.gravParameter * ((2 / orbit.PeR) - oneovera);
+            if (Double.IsNaN(speedsqr) || speedsqr < 0)
+                str = "---m/s";
+            else
+                str = Math.Sqrt(speedsqr).ToSpeed();
+            this.DrawLine(str, section.IsHud);
+        }
+
+        #endregion
+    }
+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/TimeToAtmosphere.cs
@@ -1,1 +1,99 @@
+// 
+//     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;
+
+#endregion
+
+namespace KerbalEngineer.Flight.Readouts.Orbital
+{
+    public class TimeToAtmosphere : ReadoutModule
+    {
+        //private LogMsg log = new LogMsg();
+        
+        #region Constructors
+
+        public TimeToAtmosphere()
+        {
+            this.Name = "Time to Atmosphere";
+            this.Category = ReadoutCategory.GetCategory("Orbital");
+            this.HelpString = "Shows the time until the vessel enters or leaves atmosphere.";
+            this.IsDefault = false;
+        }
+
+        #endregion
+
+        #region Methods: public
+
+        public override void Draw(SectionModule section)
+        {
+            String str;
+            Orbit orbit = FlightGlobals.ship_orbit;
+
+            if (orbit.referenceBody.atmosphere && orbit.PeA < orbit.referenceBody.atmosphereDepth)
+            {
+                double tA = orbit.TrueAnomalyAtRadius(orbit.referenceBody.atmosphereDepth + orbit.referenceBody.Radius);
+                //log.buf.AppendFormat("tA = {0}\n", tA);
+                double utTime = Planetarium.GetUniversalTime();
+                //log.buf.AppendFormat("utTime = {0}\n", utTime);
+                double timeAtRad1 = orbit.GetUTforTrueAnomaly(tA, orbit.period * 0.5);
+                //log.buf.AppendFormat("timeAtRad1 = {0}\n", timeAtRad1);
+                if (timeAtRad1 < utTime)
+                {
+                    timeAtRad1 += orbit.period;
+                    //log.buf.AppendFormat("timeAtRad1 = {0}\n", timeAtRad1);
+                }
+                double timeAtRad2 = orbit.GetUTforTrueAnomaly(-tA, orbit.period * 0.5);
+                //log.buf.AppendFormat("timeAtRad2 = {0}\n", timeAtRad2);
+                if (timeAtRad2 < utTime)
+                {
+                    timeAtRad2 += orbit.period;
+                    //log.buf.AppendFormat("timeAtRad2 = {0}\n", timeAtRad2);
+                }
+                double time = Math.Min(timeAtRad1, timeAtRad2) - utTime;
+                //log.buf.AppendFormat("time = {0}\n", time);
+
+                if (Double.IsNaN(time))
+                {
+                    str = "---s";
+                    //log.buf.AppendLine("time is NaN");
+                }
+                else
+                {
+                    str = TimeFormatter.ConvertToString(time);
+                    //log.buf.AppendFormat("str = {0}\n", str);
+                }
+            }
+            else
+            {
+                str = "---s";
+                //log.buf.AppendLine("no atmosphere or pe > atmosphere");
+            }
+
+            //log.Flush();
+            this.DrawLine(str, section.IsHud);
+        }
+
+        #endregion
+    }
+}

--- a/KerbalEngineer/Flight/Readouts/ReadoutLibrary.cs
+++ b/KerbalEngineer/Flight/Readouts/ReadoutLibrary.cs
@@ -1,6 +1,4 @@
 // 
-//     Kerbal Engineer Redux
-// 
 //     Copyright (C) 2015 CYBUTEK
 // 
 //     This program is free software: you can redistribute it and/or modify
@@ -93,6 +91,11 @@
                 readouts.Add(new NodeTimeToHalfBurn());
                 readouts.Add(new NodeAngleToPrograde());
                 readouts.Add(new NodeAngleToRetrograde());
+                readouts.Add(new PostBurnApoapsis());
+                readouts.Add(new PostBurnPeriapsis());
+                readouts.Add(new SpeedAtApoapsis());
+                readouts.Add(new SpeedAtPeriapsis());
+                readouts.Add(new TimeToAtmosphere());
 
                 // Surface
                 readouts.Add(new AltitudeSeaLevel());
@@ -171,11 +174,14 @@
                 readouts.Add(new RadiationFlux());
                 readouts.Add(new CriticalPart());
                 readouts.Add(new CriticalTemperature());
-                readouts.Add(new CriticalPercentage());
+                readouts.Add(new CriticalSkinTemperature());
+                readouts.Add(new CriticalThermalPercentage());
                 readouts.Add(new HottestPart());
                 readouts.Add(new HottestTemperature());
+                readouts.Add(new HottestSkinTemperature());
                 readouts.Add(new CoolestPart());
                 readouts.Add(new CoolestTemperature());
+                readouts.Add(new CoolestSkinTemperature());
 
                 // Misc
                 readouts.Add(new Separator());

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Thermal/CoolestSkinTemperature.cs
@@ -1,1 +1,53 @@
+// 
+//     Kerbal Engineer Redux
+// 
+//     Copyright (C) 2015 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.Thermal
+{
+    using Helpers;
+    using Sections;
+
+    public class CoolestSkinTemperature : ReadoutModule
+    {
+        public CoolestSkinTemperature()
+        {
+            Name = "Coolest Skin Temperature";
+            Category = ReadoutCategory.GetCategory("Thermal");
+            HelpString = string.Empty;
+            IsDefault = true;
+        }
+
+        public override void Draw(SectionModule section)
+        {
+            if (ThermalProcessor.ShowDetails)
+            {
+                DrawLine(Units.ToTemperature(ThermalProcessor.CoolestSkinTemperature, ThermalProcessor.CoolestSkinTemperatureMax), section.IsHud);
+            }
+        }
+
+        public override void Reset()
+        {
+            FlightEngineerCore.Instance.AddUpdatable(ThermalProcessor.Instance);
+        }
+
+        public override void Update()
+        {
+            ThermalProcessor.RequestUpdate();
+        }
+    }
+}

--- a/KerbalEngineer/Flight/Readouts/Thermal/CriticalPercentage.cs
+++ /dev/null
@@ -1,53 +1,1 @@
-// 
-//     Kerbal Engineer Redux
-// 
-//     Copyright (C) 2015 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.Thermal
-{
-    using Extensions;
-    using Sections;
-
-    public class CriticalPercentage : ReadoutModule
-    {
-        public CriticalPercentage()
-        {
-            Name = "Critical Percentage";
-            Category = ReadoutCategory.GetCategory("Thermal");
-            HelpString = string.Empty;
-            IsDefault = true;
-        }
-
-        public override void Draw(SectionModule section)
-        {
-            if (ThermalProcessor.ShowDetails)
-            {
-                DrawLine(ThermalProcessor.CriticalTemperaturePercentage.ToPercent(), section.IsHud);
-            }
-        }
-
-        public override void Reset()
-        {
-            FlightEngineerCore.Instance.AddUpdatable(ThermalProcessor.Instance);
-        }
-
-        public override void Update()
-        {
-            ThermalProcessor.RequestUpdate();
-        }
-    }
-}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Thermal/CriticalSkinTemperature.cs
@@ -1,1 +1,53 @@
+// 
+//     Kerbal Engineer Redux
+// 
+//     Copyright (C) 2015 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.Thermal
+{
+    using Helpers;
+    using Sections;
+
+    public class CriticalSkinTemperature : ReadoutModule
+    {
+        public CriticalSkinTemperature()
+        {
+            Name = "Critical Skin Temperature";
+            Category = ReadoutCategory.GetCategory("Thermal");
+            HelpString = string.Empty;
+            IsDefault = true;
+        }
+
+        public override void Draw(SectionModule section)
+        {
+            if (ThermalProcessor.ShowDetails)
+            {
+                DrawLine(Units.ToTemperature(ThermalProcessor.CriticalSkinTemperature, ThermalProcessor.CriticalSkinTemperatureMax), section.IsHud);
+            }
+        }
+
+        public override void Reset()
+        {
+            FlightEngineerCore.Instance.AddUpdatable(ThermalProcessor.Instance);
+        }
+
+        public override void Update()
+        {
+            ThermalProcessor.RequestUpdate();
+        }
+    }
+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Thermal/CriticalThermalPercentage.cs
@@ -1,1 +1,53 @@
+// 
+//     Kerbal Engineer Redux
+// 
+//     Copyright (C) 2015 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.Thermal
+{
+    using Extensions;
+    using Sections;
+
+    public class CriticalThermalPercentage : ReadoutModule
+    {
+        public CriticalThermalPercentage()
+        {
+            Name = "Critical Thermal Percentage";
+            Category = ReadoutCategory.GetCategory("Thermal");
+            HelpString = string.Empty;
+            IsDefault = true;
+        }
+
+        public override void Draw(SectionModule section)
+        {
+            if (ThermalProcessor.ShowDetails)
+            {
+                DrawLine(ThermalProcessor.CriticalTemperaturePercentage.ToPercent(), section.IsHud);
+            }
+        }
+
+        public override void Reset()
+        {
+            FlightEngineerCore.Instance.AddUpdatable(ThermalProcessor.Instance);
+        }
+
+        public override void Update()
+        {
+            ThermalProcessor.RequestUpdate();
+        }
+    }
+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Thermal/HottestSkinTemperature.cs
@@ -1,1 +1,53 @@
+// 
+//     Kerbal Engineer Redux
+// 
+//     Copyright (C) 2015 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.Thermal
+{
+    using Helpers;
+    using Sections;
+
+    public class HottestSkinTemperature : ReadoutModule
+    {
+        public HottestSkinTemperature()
+        {
+            Name = "Hottest Skin Temperature";
+            Category = ReadoutCategory.GetCategory("Thermal");
+            HelpString = string.Empty;
+            IsDefault = true;
+        }
+
+        public override void Draw(SectionModule section)
+        {
+            if (ThermalProcessor.ShowDetails)
+            {
+                DrawLine(Units.ToTemperature(ThermalProcessor.HottestSkinTemperature, ThermalProcessor.HottestSkinTemperatureMax), section.IsHud);
+            }
+        }
+
+        public override void Reset()
+        {
+            FlightEngineerCore.Instance.AddUpdatable(ThermalProcessor.Instance);
+        }
+
+        public override void Update()
+        {
+            ThermalProcessor.RequestUpdate();
+        }
+    }
+}

--- a/KerbalEngineer/Flight/Readouts/Thermal/ThermalProcessor.cs
+++ b/KerbalEngineer/Flight/Readouts/Thermal/ThermalProcessor.cs
@@ -1,6 +1,4 @@
 // 
-//     Kerbal Engineer Redux
-// 
 //     Copyright (C) 2015 CYBUTEK
 // 
 //     This program is free software: you can redistribute it and/or modify
@@ -19,6 +17,8 @@
 
 namespace KerbalEngineer.Flight.Readouts.Thermal
 {
+    using System;
+
     public class ThermalProcessor : IUpdatable, IUpdateRequest
     {
         private static readonly ThermalProcessor instance = new ThermalProcessor();
@@ -27,10 +27,16 @@
         {
             HottestTemperature = 0.0;
             HottestTemperatureMax = 0.0;
+            HottestSkinTemperature = 0.0;
+            HottestSkinTemperatureMax = 0.0;
             CoolestTemperature = 0.0;
             CoolestTemperatureMax = 0.0;
+            CoolestSkinTemperature = 0.0;
+            CoolestSkinTemperatureMax = 0.0;
             CriticalTemperature = 0.0;
             CriticalTemperatureMax = 0.0;
+            CriticalSkinTemperature = 0.0;
+            CriticalSkinTemperatureMax = 0.0;
             HottestPartName = string.Empty;
             CoolestPartName = string.Empty;
             CriticalPartName = string.Empty;
@@ -40,11 +46,19 @@
 
         public static string CoolestPartName { get; private set; }
 
+        public static double CoolestSkinTemperature { get; private set; }
+
+        public static double CoolestSkinTemperatureMax { get; private set; }
+
         public static double CoolestTemperature { get; private set; }
 
         public static double CoolestTemperatureMax { get; private set; }
 
         public static string CriticalPartName { get; private set; }
+
+        public static double CriticalSkinTemperature { get; private set; }
+
+        public static double CriticalSkinTemperatureMax { get; private set; }
 
         public static double CriticalTemperature { get; private set; }
 
@@ -53,6 +67,10 @@
         public static double CriticalTemperaturePercentage { get; private set; }
 
         public static string HottestPartName { get; private set; }
+
+        public static double HottestSkinTemperature { get; private set; }
+
+        public static double HottestSkinTemperatureMax { get; private set; }
 
         public static double HottestTemperature { get; private set; }
 
@@ -69,14 +87,8 @@
         public static double InternalFlux { get; private set; }
 
         public static double RadiationFlux { get; private set; }
+
         public static bool ShowDetails { get; private set; }
-
-        public bool UpdateRequested { get; set; }
-
-        public static void RequestUpdate()
-        {
-            instance.UpdateRequested = true;
-        }
 
         public void Update()
         {
@@ -92,8 +104,11 @@
             RadiationFlux = 0.0;
             InternalFlux = 0.0;
             HottestTemperature = 0.0;
+            HottestSkinTemperature = 0.0;
             CoolestTemperature = double.MaxValue;
+            CoolestSkinTemperature = double.MaxValue;
             CriticalTemperature = double.MaxValue;
+            CriticalSkinTemperature = double.MaxValue;
             CriticalTemperaturePercentage = 0.0;
             HottestPartName = string.Empty;
             CoolestPartName = string.Empty;
@@ -107,26 +122,40 @@
                 RadiationFlux = RadiationFlux + part.thermalRadiationFlux;
                 InternalFlux = InternalFlux + part.thermalInternalFluxPrevious;
 
-                if (part.temperature > HottestTemperature)
+                if (part.temperature > HottestTemperature || part.skinTemperature > HottestSkinTemperature)
                 {
                     HottestTemperature = part.temperature;
                     HottestTemperatureMax = part.maxTemp;
+                    HottestSkinTemperature = part.skinTemperature;
+                    HottestSkinTemperatureMax = part.skinMaxTemp;
                     HottestPartName = part.partInfo.title;
                 }
-                if (part.temperature < CoolestTemperature)
+                if (part.temperature < CoolestTemperature || part.skinTemperature < CoolestSkinTemperature)
                 {
                     CoolestTemperature = part.temperature;
                     CoolestTemperatureMax = part.maxTemp;
+                    CoolestSkinTemperature = part.skinTemperature;
+                    CoolestSkinTemperatureMax = part.skinMaxTemp;
                     CoolestPartName = part.partInfo.title;
                 }
-                if (part.temperature / part.maxTemp > CriticalTemperaturePercentage)
+
+                if (part.temperature / part.maxTemp > CriticalTemperaturePercentage || part.skinTemperature / part.skinMaxTemp > CriticalTemperaturePercentage)
                 {
                     CriticalTemperature = part.temperature;
                     CriticalTemperatureMax = part.maxTemp;
-                    CriticalTemperaturePercentage = part.temperature / part.maxTemp;
+                    CriticalSkinTemperature = part.skinTemperature;
+                    CriticalSkinTemperatureMax = part.skinMaxTemp;
+                    CriticalTemperaturePercentage = Math.Max(part.temperature / part.maxTemp, part.skinTemperature / part.skinMaxTemp);
                     CriticalPartName = part.partInfo.title;
                 }
             }
         }
+
+        public bool UpdateRequested { get; set; }
+
+        public static void RequestUpdate()
+        {
+            instance.UpdateRequested = true;
+        }
     }
 }

--- a/KerbalEngineer/Flight/Readouts/Vessel/DeltaVStaged.cs
+++ b/KerbalEngineer/Flight/Readouts/Vessel/DeltaVStaged.cs
@@ -30,13 +30,6 @@
 {
     public class DeltaVStaged : ReadoutModule
     {
-        #region Fields
-
-        private int numberOfStages;
-        private bool showing;
-
-        #endregion
-
         #region Constructors
 
         public DeltaVStaged()

--- a/KerbalEngineer/Flight/Readouts/Vessel/IntakeAirDemandSupply.cs
+++ b/KerbalEngineer/Flight/Readouts/Vessel/IntakeAirDemandSupply.cs
@@ -55,20 +55,11 @@
             var demand = 0.0;
             foreach (var part in FlightGlobals.ActiveVessel.Parts)
             {
-                if (part.Modules.Contains("ModuleEngines"))
+                for (int i = 0; i < part.Modules.Count; i++)
                 {
-                    var engine = part.Modules["ModuleEngines"] as ModuleEngines;
-                    if (engine.isOperational)
-                    {
-                        demand += engine.propellants
-                            .Where(p => p.name == "IntakeAir")
-                            .Sum(p => p.currentRequirement);
-                    }
-                }
-                if (part.Modules.Contains("ModuleEnginesFX"))
-                {
-                    var engine = part.Modules["ModuleEnginesFX"] as ModuleEnginesFX;
-                    if (engine.isOperational)
+                    PartModule partmod = part.Modules[i];
+                    var engine = partmod as ModuleEngines;
+                    if (engine != null && engine.isOperational)
                     {
                         demand += engine.propellants
                             .Where(p => p.name == "IntakeAir")

--- a/KerbalEngineer/Flight/Readouts/Vessel/Mass.cs
+++ b/KerbalEngineer/Flight/Readouts/Vessel/Mass.cs
@@ -28,12 +28,6 @@
 {
     public class Mass : ReadoutModule
     {
-        #region Fields
-
-        private bool showing;
-
-        #endregion
-
         #region Constructors
 
         public Mass()

--- a/KerbalEngineer/Flight/Sections/SectionEditor.cs
+++ b/KerbalEngineer/Flight/Sections/SectionEditor.cs
@@ -215,15 +215,18 @@
             this.ParentSection.Name = GUILayout.TextField(this.ParentSection.Name, this.textStyle);
             var isShowingInControlBar = !string.IsNullOrEmpty(this.ParentSection.Abbreviation);
             this.ParentSection.Abbreviation = GUILayout.TextField(this.ParentSection.Abbreviation, this.textStyle, GUILayout.Width(75.0f));
+
+            ParentSection.IsHud = GUILayout.Toggle(this.ParentSection.IsHud, "HUD", this.readoutButtonStyle, GUILayout.Width(50.0f));
+            if (ParentSection.IsHud)
+            {
+                this.ParentSection.IsHudBackground = GUILayout.Toggle(this.ParentSection.IsHudBackground, "BG", this.readoutButtonStyle, GUILayout.Width(50.0f));
+            }
+
             if (this.ParentSection.IsCustom)
             {
                 if (isShowingInControlBar && string.IsNullOrEmpty(this.ParentSection.Abbreviation))
                 {
                     DisplayStack.Instance.RequestResize();
-                }
-                if (this.ParentSection.IsHud = GUILayout.Toggle(this.ParentSection.IsHud, "HUD", this.readoutButtonStyle, GUILayout.Width(50.0f)))
-                {
-                    this.ParentSection.IsHudBackground = GUILayout.Toggle(this.ParentSection.IsHudBackground, "BG", this.readoutButtonStyle, GUILayout.Width(50.0f));
                 }
 
                 if (GUILayout.Button("DELETE SECTION", this.readoutButtonStyle, GUILayout.Width(150.0f)))

--- a/KerbalEngineer/Flight/Sections/SectionLibrary.cs
+++ b/KerbalEngineer/Flight/Sections/SectionLibrary.cs
@@ -72,9 +72,10 @@
             {
                 Name = "THERMAL",
                 Abbreviation = "HEAT",
-                ReadoutModules = ReadoutLibrary.GetCategory(ReadoutCategory.GetCategory("Thermal")).Where(r => r.IsDefault).ToList()
-            });
-
+                ReadoutModules = ReadoutLibrary.GetCategory(ReadoutCategory.GetCategory("Thermal")).Where(r => r.IsDefault).ToList(),
+                IsCustom = true
+            });
+            
             SectionModule hud1 = new SectionModule
             {
                 Name = "HUD 1",

--- a/KerbalEngineer/Flight/Sections/SectionWindow.cs
+++ b/KerbalEngineer/Flight/Sections/SectionWindow.cs
@@ -134,7 +134,11 @@
                                                    (!this.ParentSection.IsHud || this.ParentSection.IsEditorVisible) ? this.windowStyle
                                                        : this.ParentSection.IsHudBackground && this.ParentSection.LineCount > 0
                                                            ? this.hudWindowBgStyle
-                                                           : this.hudWindowStyle).ClampToScreen();
+                                                           : this.hudWindowStyle);
+
+            windowPosition = (ParentSection.IsHud) ? windowPosition.ClampInsideScreen() : windowPosition.ClampToScreen();
+
+
             this.ParentSection.FloatingPositionX = this.windowPosition.x;
             this.ParentSection.FloatingPositionY = this.windowPosition.y;
         }

--- a/KerbalEngineer/KerbalEngineer.csproj
+++ b/KerbalEngineer/KerbalEngineer.csproj
@@ -71,11 +71,21 @@
     <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\ManoeuvreNode\PostBurnApoapsis.cs" />
+    <Compile Include="Flight\Readouts\Orbital\ManoeuvreNode\PostBurnPeriapsis.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" />
     <Compile Include="Flight\Readouts\Orbital\CurrentSoi.cs" />
+    <Compile Include="Flight\Readouts\Orbital\SemiMajorAxis.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Flight\Readouts\Orbital\SpeedAtApoapsis.cs" />
+    <Compile Include="Flight\Readouts\Orbital\SpeedAtPeriapsis.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Flight\Readouts\Orbital\TimeToAtmosphere.cs" />
     <Compile Include="Flight\Readouts\Orbital\TrueAnomaly.cs" />
     <Compile Include="Flight\Readouts\Orbital\TimeToEquatorialAscendingNode.cs" />
     <Compile Include="Flight\Readouts\Orbital\TimeToEquatorialDescendingNode.cs" />
@@ -91,11 +101,14 @@
     <Compile Include="Flight\Readouts\Surface\HorizontalAcceleration.cs" />
     <Compile Include="Flight\Readouts\Surface\VerticalAcceleration.cs" />
     <Compile Include="Flight\Readouts\Surface\MachNumber.cs" />
+    <Compile Include="Flight\Readouts\Thermal\CoolestSkinTemperature.cs" />
     <Compile Include="Flight\Readouts\Thermal\CriticalPart.cs" />
     <Compile Include="Flight\Readouts\Thermal\CoolestPart.cs" />
     <Compile Include="Flight\Readouts\Thermal\CoolestTemperature.cs" />
-    <Compile Include="Flight\Readouts\Thermal\CriticalPercentage.cs" />
+    <Compile Include="Flight\Readouts\Thermal\CriticalThermalPercentage.cs" />
+    <Compile Include="Flight\Readouts\Thermal\CriticalSkinTemperature.cs" />
     <Compile Include="Flight\Readouts\Thermal\CriticalTemperature.cs" />
+    <Compile Include="Flight\Readouts\Thermal\HottestSkinTemperature.cs" />
     <Compile Include="Flight\Readouts\Thermal\InternalFlux.cs" />
     <Compile Include="Flight\Readouts\Thermal\RadiationFlux.cs" />
     <Compile Include="Flight\Readouts\Thermal\ConvectionFlux.cs" />
@@ -158,7 +171,6 @@
     <Compile Include="Flight\Readouts\Orbital\OrbitalPeriod.cs" />
     <Compile Include="Flight\Readouts\Orbital\OrbitalSpeed.cs" />
     <Compile Include="Flight\Readouts\Orbital\PeriapsisHeight.cs" />
-    <Compile Include="Flight\Readouts\Orbital\SemiMajorAxis.cs" />
     <Compile Include="Flight\Readouts\Orbital\SemiMinorAxis.cs" />
     <Compile Include="Flight\Readouts\Orbital\TimeToApoapsis.cs" />
     <Compile Include="Flight\Readouts\Orbital\TimeToPeriapsis.cs" />

--- a/KerbalEngineer/LogMsg.cs
+++ b/KerbalEngineer/LogMsg.cs
@@ -15,7 +15,8 @@
 
         public void Flush()
         {
-            MonoBehaviour.print(this.buf);
+            if (this.buf.Length > 0)
+                MonoBehaviour.print(this.buf);
             this.buf.Length = 0;
         }
     }

--- a/KerbalEngineer/Properties/AssemblyInfo.cs
+++ b/KerbalEngineer/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@
 // You can specify all the values or you can default the Build and Revision Numbers 
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion(KerbalEngineer.EngineerGlobals.AssemblyVersion)]
+[assembly: AssemblyVersion(KerbalEngineer.EngineerGlobals.ASSEMBLY_VERSION)]
 

--- a/KerbalEngineer/VesselSimulator/PartSim.cs
+++ b/KerbalEngineer/VesselSimulator/PartSim.cs
@@ -43,7 +43,6 @@
         public bool fuelCrossFeed;
         public List<PartSim> fuelTargets = new List<PartSim>();
         public bool hasModuleEngines;
-        public bool hasModuleEnginesFX;
         public bool hasMultiModeEngine;
 
         public bool hasVessel;
@@ -57,8 +56,7 @@
         public bool isNoPhysics;
         public bool isSepratron;
         public bool isFairing;
-        public bool localCorrectThrust;
-        public float moduleMass;
+        public float fairingMass;
         public int stageIndex;
         public String name;
         public String noCrossFeedNodeKey;
@@ -120,6 +118,7 @@
             partSim.isFuelLine = partSim.part.HasModule<CModuleFuelLine>();
             partSim.isFuelTank = partSim.part is FuelTank;
             partSim.isSepratron = partSim.IsSepratron();
+            partSim.isFairing = partSim.IsFairing(partSim.part);
             partSim.inverseStage = partSim.part.inverseStage;
             //MonoBehaviour.print("inverseStage = " + inverseStage);
 
@@ -148,7 +147,10 @@
                 if (log != null) log.buf.AppendLine("Using part.mass of " + partSim.part.mass);
             }
 
-            partSim.moduleMass = partSim.part.GetModuleMass((float)partSim.realMass);
+            if (partSim.isFairing)
+            {
+                partSim.fairingMass = partSim.part.GetModuleMass((float)partSim.realMass);
+            }
 
             for (int i = 0; i < partSim.part.Resources.Count; i++)
             {
@@ -180,10 +182,9 @@
             partSim.initialVesselName = partSim.part.initialVesselName;
 
             partSim.hasMultiModeEngine = partSim.part.HasModule<MultiModeEngine>();
-            partSim.hasModuleEnginesFX = partSim.part.HasModule<ModuleEnginesFX>();
             partSim.hasModuleEngines = partSim.part.HasModule<ModuleEngines>();
 
-            partSim.isEngine = partSim.hasMultiModeEngine || partSim.hasModuleEnginesFX || partSim.hasModuleEngines;
+            partSim.isEngine = partSim.hasMultiModeEngine || partSim.hasModuleEngines;
 
             if (log != null) log.buf.AppendLine("Created " + partSim.name + ". Decoupled in stage " + partSim.decoupledInStage);
 
@@ -208,7 +209,6 @@
 
         public void CreateEngineSims(List<EngineSim> allEngines, double atmosphere, double mach, bool vectoredThrust, bool fullThrust, LogMsg log)
         {
-            bool correctThrust = SimManager.DoesEngineUseCorrectedThrust(part);
             if (log != null)
             {
                 log.buf.AppendLine("CreateEngineSims for " + this.name);
@@ -217,20 +217,18 @@
                     PartModule partMod = this.part.Modules[i];
                     log.buf.AppendLine("Module: " + partMod.moduleName);
                 }
-
-                log.buf.AppendLine("correctThrust = " + correctThrust);
             }
 
             if (hasMultiModeEngine)
             {
-                // A multi-mode engine has multiple ModuleEnginesFX but only one is active at any point
-                // The mode of the engine is the engineID of the ModuleEnginesFX that is active
+                // A multi-mode engine has multiple ModuleEngines but only one is active at any point
+                // The mode of the engine is the engineID of the ModuleEngines that is active
                 string mode = part.GetModule<MultiModeEngine>().mode;
 
-                List<ModuleEnginesFX> engines = part.GetModules<ModuleEnginesFX>();
+                List<ModuleEngines> engines = part.GetModules<ModuleEngines>();
                 for (int i = 0; i < engines.Count; ++i)
                 {
-                    ModuleEnginesFX engine = engines[i];
+                    ModuleEngines engine = engines[i];
                     if (engine.engineID == mode)
                     {
                         if (log != null) log.buf.AppendLine("Module: " + engine.moduleName);
@@ -261,40 +259,37 @@
                     }
                 }
             }
-            else
-            {
-                if (hasModuleEngines)
-                {
-                    List<ModuleEngines> engines = part.GetModules<ModuleEngines>();
-                    for (int i = 0; i < engines.Count; ++i)
-                    {
-                        ModuleEngines engine = engines[i];
-                        if (log != null) log.buf.AppendLine("Module: " + engine.moduleName);
-
-                        Vector3 thrustvec = this.CalculateThrustVector(vectoredThrust ? engine.thrustTransforms : null, log);
-
-                        EngineSim engineSim = EngineSim.New(
-                            this,
-                            atmosphere,
-                            (float)mach,
-                            engine.maxFuelFlow,
-                            engine.minFuelFlow,
-                            engine.thrustPercentage,
-                            thrustvec,
-                            engine.atmosphereCurve,
-                            engine.atmChangeFlow,
-                            engine.useAtmCurve ? engine.atmCurve : null,
-                            engine.useVelCurve ? engine.velCurve : null,
-                            engine.currentThrottle,
-                            engine.g,
-                            engine.throttleLocked || fullThrust,
-                            engine.propellants,
-                            engine.isOperational,
-                            engine.resultingThrust,
-                            engine.thrustTransforms,
-                            log);
-                        allEngines.Add(engineSim);
-                    }
+            else if (hasModuleEngines)
+            {
+                List<ModuleEngines> engines = part.GetModules<ModuleEngines>();
+                for (int i = 0; i < engines.Count; ++i)
+                {
+                    ModuleEngines engine = engines[i];
+                    if (log != null) log.buf.AppendLine("Module: " + engine.moduleName);
+
+                    Vector3 thrustvec = this.CalculateThrustVector(vectoredThrust ? engine.thrustTransforms : null, log);
+
+                    EngineSim engineSim = EngineSim.New(
+                        this,
+                        atmosphere,
+                        (float)mach,
+                        engine.maxFuelFlow,
+                        engine.minFuelFlow,
+                        engine.thrustPercentage,
+                        thrustvec,
+                        engine.atmosphereCurve,
+                        engine.atmChangeFlow,
+                        engine.useAtmCurve ? engine.atmCurve : null,
+                        engine.useVelCurve ? engine.velCurve : null,
+                        engine.currentThrottle,
+                        engine.g,
+                        engine.throttleLocked || fullThrust,
+                        engine.propellants,
+                        engine.isOperational,
+                        engine.resultingThrust,
+                        engine.thrustTransforms,
+                        log);
+                    allEngines.Add(engineSim);
                 }
             }
 
@@ -421,9 +416,13 @@
                 mass += resources.GetResourceMass(resources.Types[i]);
             }
 
-            if (hasVessel == false && isFairing && inverseStage < currentStage)
-            {
-                mass = mass + moduleMass;
+            if (hasVessel == false && isFairing && currentStage > inverseStage)
+            {
+                mass += fairingMass;
+            }
+            else if (hasVessel && isFairing && currentStage <= inverseStage)
+            {
+                mass -= fairingMass;
             }
 
             return mass;

--- a/KerbalEngineer/VesselSimulator/Simulation.cs
+++ b/KerbalEngineer/VesselSimulator/Simulation.cs
@@ -75,7 +75,6 @@
         public String vesselName;
         public VesselType vesselType;
         private WeightedVectorAverager vectorAverager = new WeightedVectorAverager();
-        private static ModuleProceduralFairing moduleProceduralFairing;
 
         public Simulation()
         {

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