Added required parts of Smooth library
Added required parts of Smooth library

--- a/Documents/CHANGES.txt
+++ b/Documents/CHANGES.txt
@@ -1,4 +1,21 @@
-1.0.14.0,
+1.0.15.2, 13-02-2015
+    Padishar's Fixes:
+        Fixed: Calculation of per-stage resource mass.
+
+1.0.15.1, 13-02-2015
+    Rebuild
+    
+1.0.15.0, 08-02-2015
+    Padishar's Fixes:
+        Added: Support KIDS ISP thrust correction.
+        Fixed: Log spam for stage priority mode.
+        Fixed: Locked tanks preventing simulation from staging.
+        Fixed: No flow and all vessel modes to respect flow states.
+
+1.0.14.1, 28-12-2014
+    Fixed: Missing texture on the ER-7500 model.
+    
+1.0.14.0, 28-12-2014
     Added: Career mode that limits the Flight Engineer by:
         - Requiring an Engineer Kerbal of any level, or placement of an Engineer Chip or ER-7500 part.
         - Tracking station level 3 enables Flight Engineer everywhere.
@@ -13,6 +30,7 @@
     Changed: Editor Overlay Tabs start position moved over as to not overlap the parts menu.
     Fixed: Bug where STAGE_PRIORITY_FLOW resources would not be corrently disabled/enabled.
     Fixed: Issue with the formatting large Mass and Cost values.
+    Fixed: Error when loading the Engineer7500 part model.
 
 1.0.13.1, 16-12-2014
     Fixed: Issue with manoeuvre node readouts and low tier tracking station.

--- a/KerbalEngineer/Editor/BuildAdvanced.cs
+++ b/KerbalEngineer/Editor/BuildAdvanced.cs
@@ -133,6 +133,7 @@
                 this.bodiesList.DrawCallback = this.DrawBodiesList;
                 this.Load();
 
+                SimManager.UpdateModSettings();
                 SimManager.OnReady -= this.GetStageInfo;
                 SimManager.OnReady += this.GetStageInfo;
             }

--- a/KerbalEngineer/Editor/BuildOverlayVessel.cs
+++ b/KerbalEngineer/Editor/BuildOverlayVessel.cs
@@ -58,7 +58,7 @@
         #endregion
 
         #region Properties
-       
+
         public static bool Visible
         {
             get { return visible; }

--- 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.13.1";
+        public const string AssemblyVersion = "1.0.15.2";
 
         #endregion
 

--- a/KerbalEngineer/Flight/FlightEngineerCore.cs
+++ b/KerbalEngineer/Flight/FlightEngineerCore.cs
@@ -33,6 +33,7 @@
     using Sections;
     using Settings;
     using UnityEngine;
+    using VesselSimulator;
 
     #endregion
 
@@ -268,6 +269,9 @@
                 this.SectionWindows = new List<SectionWindow>();
                 this.SectionEditors = new List<SectionEditor>();
                 this.UpdatableModules = new List<IUpdatable>();
+
+                SimManager.UpdateModSettings();
+
                 Logger.Log("FlightEngineerCore->Awake");
             }
             catch (Exception ex)

--- a/KerbalEngineer/Helpers/Units.cs
+++ b/KerbalEngineer/Helpers/Units.cs
@@ -65,9 +65,9 @@
 
         public static string Cost(double value1, double value2, int decimals = 1)
         {
-            if (value1 >= 1e6 || value2 >= 1e6)
+            if (value1 >= 1000000.0 || value2 >= 1000000.0)
             {
-                return (value1 / 1000.0).ToString("N" + decimals) + " / " + (value2 / 1000.0f).ToString("N" + decimals) + "K";
+                return (value1 / 1000.0).ToString("N" + decimals) + " / " + (value2 / 1000.0).ToString("N" + decimals) + "K";
             }
             return value1.ToString("N" + decimals) + " / " + value2.ToString("N" + decimals);
         }
@@ -135,9 +135,8 @@
                 return value.ToString("N" + decimals + 2) + "t";
             }
 
-                value *= 1000.0;
-                return value.ToString("N" + decimals) + "kg";
-
+            value *= 1000.0;
+            return value.ToString("N" + decimals) + "kg";
         }
 
         public static string ToMass(double value1, double value2, int decimals = 0)
@@ -146,11 +145,10 @@
             {
                 return value1.ToString("N" + decimals + 2) + " / " + value2.ToString("N" + decimals + 2) + "t";
             }
-   
-                value1 *= 1000.0;
-                value2 *= 1000.0;
-                return value1.ToString("N" + decimals) + " / " + value2.ToString("N" + decimals) + "kg";
-  
+
+            value1 *= 1000.0;
+            value2 *= 1000.0;
+            return value1.ToString("N" + decimals) + " / " + value2.ToString("N" + decimals) + "kg";
         }
 
         public static string ToPercent(double value, int decimals = 2)

--- /dev/null
+++ b/KerbalEngineer/Smooth/Delegates/Delegates.cs
@@ -1,1 +1,25 @@
+using System;
 
+namespace Smooth.Delegates {
+	public delegate void DelegateAction();
+	public delegate void DelegateAction<in T1>(T1 _1);
+	public delegate void DelegateAction<in T1, in T2>(T1 _1, T2 _2);
+	public delegate void DelegateAction<in T1, in T2, in T3>(T1 _1, T2 _2, T3 _3);
+	public delegate void DelegateAction<in T1, in T2, in T3, in T4>(T1 _1, T2 _2, T3 _3, T4 _4);
+	public delegate void DelegateAction<in T1, in T2, in T3, in T4, in T5>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5);
+	public delegate void DelegateAction<in T1, in T2, in T3, in T4, in T5, in T6>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6);
+	public delegate void DelegateAction<in T1, in T2, in T3, in T4, in T5, in T6, in T7>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7);
+	public delegate void DelegateAction<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8);
+	public delegate void DelegateAction<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9);
+
+	public delegate R DelegateFunc<out R>();
+	public delegate R DelegateFunc<in T1, out R>(T1 _1);
+	public delegate R DelegateFunc<in T1, in T2, out R>(T1 _1, T2 _2);
+	public delegate R DelegateFunc<in T1, in T2, in T3, out R>(T1 _1, T2 _2, T3 _3);
+	public delegate R DelegateFunc<in T1, in T2, in T3, in T4, out R>(T1 _1, T2 _2, T3 _3, T4 _4);
+	public delegate R DelegateFunc<in T1, in T2, in T3, in T4, in T5, out R>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5);
+	public delegate R DelegateFunc<in T1, in T2, in T3, in T4, in T5, in T6, out R>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6);
+	public delegate R DelegateFunc<in T1, in T2, in T3, in T4, in T5, in T6, in T7, out R>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7);
+	public delegate R DelegateFunc<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, out R>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8);
+	public delegate R DelegateFunc<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, out R>(T1 _1, T2 _2, T3 _3, T4 _4, T5 _5, T6 _6, T7 _7, T8 _8, T9 _9);
+}

--- /dev/null
+++ b/KerbalEngineer/Smooth/Dispose/Disposable.cs
@@ -1,1 +1,106 @@
+using System;
+using Smooth.Delegates;
+using Smooth.Pools;
 
+namespace Smooth.Dispose {
+
+#if UNITY_IOS || UNITY_PS3 || UNITY_XBOX360 || UNITY_WII
+
+	/// <summary>
+	/// Wrapper around a value that uses the IDisposable interface to dispose of the value.
+	/// 
+	/// On iOS, this is a struct to avoid compute_class_bitmap errors.
+	/// 
+	/// On other platforms, it is a pooled object to avoid boxing when disposed by a using block with the Unity compiler.
+	/// </summary>
+	public struct Disposable<T> : IDisposable {
+		/// <summary>
+		/// Borrows a wrapper for the specified value and disposal delegate.
+		/// </summary>
+		public static Disposable<T> Borrow(T value, DelegateAction<T> dispose) {
+			return new Disposable<T>(value, dispose);
+		}
+		
+		private readonly DelegateAction<T> dispose;
+
+		/// <summary>
+		/// The wrapped value.
+		/// </summary>
+		public readonly T value;
+
+		public Disposable(T value, DelegateAction<T> dispose) {
+			this.value = value;
+			this.dispose = dispose;
+		}
+		
+		/// <summary>
+		/// Relinquishes ownership of the wrapper and disposes the wrapped value.
+		/// </summary>
+		public void Dispose() {
+			dispose(value);
+		}
+		
+		/// <summary>
+		/// Relinquishes ownership of the wrapper and adds it to the disposal queue.
+		/// </summary>
+		public void DisposeInBackground() {
+			DisposalQueue.Enqueue(this);
+		}
+	}
+
+#else
+
+	/// <summary>
+	/// Wrapper around a value that uses the IDisposable interface to dispose of the value.
+	/// 
+	/// On IOS, this is a value type to avoid compute_class_bitmap errors.
+	/// 
+	/// On other platforms, it is a pooled object to avoid boxing when disposed by a using block with the Unity compiler.
+	/// </summary>
+	public class Disposable<T> : IDisposable {
+		private static readonly Pool<Disposable<T>> pool = new Pool<Disposable<T>>(
+			() => new Disposable<T>(),
+			wrapper => {
+				wrapper.dispose(wrapper.value);
+				wrapper.dispose = t => {};
+				wrapper.value = default(T);
+			}
+		);
+
+		/// <summary>
+		/// Borrows a wrapper for the specified value and disposal delegate.
+		/// </summary>
+		public static Disposable<T> Borrow(T value, DelegateAction<T> dispose) {
+			var wrapper = pool.Borrow();
+			wrapper.value = value;
+			wrapper.dispose = dispose;
+			return wrapper;
+		}
+
+		private DelegateAction<T> dispose;
+
+		/// <summary>
+		/// The wrapped value.
+		/// </summary>
+		public T value { get; private set; }
+		
+		private Disposable() {}
+
+		/// <summary>
+		/// Relinquishes ownership of the wrapper, disposes the wrapped value, and returns the wrapper to the pool.
+		/// </summary>
+		public void Dispose() {
+			pool.Release(this);
+		}
+
+		/// <summary>
+		/// Relinquishes ownership of the wrapper and adds it to the disposal queue.
+		/// </summary>
+		public void DisposeInBackground() {
+			DisposalQueue.Enqueue(this);
+		}
+	}
+
+#endif
+
+}

--- /dev/null
+++ b/KerbalEngineer/Smooth/Dispose/DisposalQueue.cs
@@ -1,1 +1,67 @@
+using UnityEngine;
+using System;
+using System.Collections.Generic;
+using System.Threading;
 
+namespace Smooth.Dispose {
+
+	/// <summary>
+	/// Queues pooled resources for cleanup by a background thread.
+	/// 
+	/// By default, the disposal thread is woken up at the end of LateUpdate, when there is likely to be free CPU time available while GPU operations are in progress.
+	/// 
+	/// Various pools may be locked and unlocked while resources are released, potentially causing contention if pooled resources are borrowed during the disposal process.
+	/// 
+	/// Advanced users who are using pools from the main thread during the rendering phase may want to customize the point in the Unity event loop when the queue lock is pulsed, potentially pulsing from a Camera event.
+	/// </summary>
+	public static class DisposalQueue {
+		private static readonly object queueLock = new object();
+		private static Queue<IDisposable> enqueue = new Queue<IDisposable>();
+		private static Queue<IDisposable> dispose = new Queue<IDisposable>();
+
+		/// <summary>
+		/// Adds the specified item to the disposal queue.
+		/// </summary>
+		public static void Enqueue(IDisposable item) {
+			lock (queueLock) {
+				enqueue.Enqueue(item);
+			}
+		}
+
+		/// <summary>
+		/// Pulses the queue lock, potentially waking up the disposal thread.
+		/// </summary>
+		public static void Pulse() {
+			lock (queueLock) {
+				Monitor.Pulse(queueLock);
+			}
+		}
+
+		private static void Dispose() {
+			while (true) {
+				lock (queueLock) {
+					while (enqueue.Count == 0) {
+						Monitor.Wait(queueLock);
+					}
+					var t = enqueue;
+					enqueue = dispose;
+					dispose = t;
+				}
+				while (dispose.Count > 0) {
+					try {
+						dispose.Dequeue().Dispose();
+					} catch (ThreadAbortException) {
+					} catch (Exception e) {
+						Debug.LogError(e);
+					}
+				}
+			}
+		}
+
+		static DisposalQueue() {
+			new Thread(new ThreadStart(Dispose)).Start();
+			new GameObject(typeof(SmoothDisposer).Name).AddComponent<SmoothDisposer>();
+		}
+	}
+}
+

--- /dev/null
+++ b/KerbalEngineer/Smooth/Dispose/SmoothDisposer.cs
@@ -1,1 +1,21 @@
+using UnityEngine;
+using System;
+using Smooth.Dispose;
 
+public class SmoothDisposer : MonoBehaviour {
+	private static SmoothDisposer instance;
+
+	private void Awake() {
+		if (instance) {
+			Debug.LogWarning("Only one " + GetType().Name + " should exist at a time, instantiated by the " + typeof(DisposalQueue).Name + " class.");
+			Destroy(this);
+		} else {
+			instance = this;
+			DontDestroyOnLoad(this);
+		}
+	}
+	
+	private void LateUpdate() {
+		DisposalQueue.Pulse();
+	}
+}

--- /dev/null
+++ b/KerbalEngineer/Smooth/Pools/Pool.cs
@@ -1,1 +1,60 @@
+using System;
+using System.Collections.Generic;
+using Smooth.Delegates;
+using Smooth.Dispose;
 
+namespace Smooth.Pools {
+	/// <summary>
+	/// Pool that lends values of type T.
+	/// </summary>
+	public class Pool<T> {
+		private readonly Stack<T> values = new Stack<T>();
+
+		private readonly DelegateFunc<T> create;
+		private readonly DelegateAction<T> reset;
+		private readonly DelegateAction<T> release;
+
+		private Pool() {}
+		
+		/// <summary>
+		/// Creates a new pool with the specified value creation and reset delegates.
+		/// </summary>
+		public Pool(DelegateFunc<T> create, DelegateAction<T> reset) {
+			this.create = create;
+			this.reset = reset;
+			this.release = Release;
+		}
+
+		/// <summary>
+		/// Borrows a value from the pool.
+		/// </summary>
+		public T Borrow() {
+			lock (values) {
+				return values.Count > 0 ? values.Pop() : create();
+			}
+		}
+		
+		/// <summary>
+		/// Relinquishes ownership of the specified value and returns it to the pool.
+		/// </summary>
+		public void Release(T value) {
+			reset(value);
+			lock (values) {
+				values.Push(value);
+			}
+		}
+
+		/// <summary>
+		/// Borrows a wrapped value from the pool.
+		/// </summary>
+		public Disposable<T> BorrowDisposable() {
+			return Disposable<T>.Borrow(Borrow(), release);
+		}
+
+        public int Count()
+	    {
+	        return values.Count;
+	    }
+
+	}
+}

--- a/KerbalEngineer/VesselSimulator/EngineSim.cs
+++ b/KerbalEngineer/VesselSimulator/EngineSim.cs
@@ -243,7 +243,7 @@
                 switch (ResourceContainer.GetResourceFlowMode(type))
                 {
                     case ResourceFlowMode.NO_FLOW:
-                        if (this.partSim.resources[type] > SimManager.RESOURCE_MIN)
+                        if (this.partSim.resources[type] > SimManager.RESOURCE_MIN && this.partSim.resourceFlowStates[type] != 0)
                         {
                             sourcePartSet = new HashSet<PartSim>();
                             //MonoBehaviour.print("SetResourceDrains(" + name + ":" + partId + ") setting sources to just this");
@@ -254,7 +254,7 @@
                     case ResourceFlowMode.ALL_VESSEL:
                         foreach (PartSim aPartSim in allParts)
                         {
-                            if (aPartSim.resources[type] > SimManager.RESOURCE_MIN)
+                            if (aPartSim.resources[type] > SimManager.RESOURCE_MIN && aPartSim.resourceFlowStates[type] != 0)
                             {
                                 if (sourcePartSet == null)
                                 {
@@ -270,7 +270,7 @@
                         var stagePartSets = new Dictionary<int, HashSet<PartSim>>();
                         var maxStage = -1;
 
-                        Logger.Log(type);
+                        //Logger.Log(type);
                         foreach (var aPartSim in allParts)
                         {
                             if (aPartSim.resources[type] <= SimManager.RESOURCE_MIN || aPartSim.resourceFlowStates[type] == 0) continue;

--- a/KerbalEngineer/VesselSimulator/PartSim.cs
+++ b/KerbalEngineer/VesselSimulator/PartSim.cs
@@ -677,6 +677,19 @@
             return time;
         }
 
+        public bool EmptyOf(HashSet<int> types)
+        {
+            foreach (int type in types)
+            {
+                if (this.resources.HasType(type) && this.resourceFlowStates[type] != 0 && (double)this.resources[type] > SimManager.RESOURCE_MIN)
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
         public int DecouplerCount()
         {
             int count = 0;

--- a/KerbalEngineer/VesselSimulator/SimManager.cs
+++ b/KerbalEngineer/VesselSimulator/SimManager.cs
@@ -46,17 +46,20 @@
         private static readonly object locker = new object();
         private static readonly Stopwatch timer = new Stopwatch();
 
-        // Support for RealFuels using reflection to check localCorrectThrust without dependency
-
-        private static FieldInfo RF_ModuleEngineConfigs_locaCorrectThrust;
-        private static FieldInfo RF_ModuleHybridEngine_locaCorrectThrust;
-        private static FieldInfo RF_ModuleHybridEngines_locaCorrectThrust;
         private static bool bRequested;
         private static bool bRunning;
         private static TimeSpan delayBetweenSims;
-        private static bool hasCheckedForRealFuels;
+
+        // Support for RealFuels using reflection to check localCorrectThrust without dependency
+
+        private static bool hasCheckedForMods;
         private static bool hasInstalledRealFuels;
-
+        private static FieldInfo RF_ModuleEngineConfigs_localCorrectThrust;
+        private static FieldInfo RF_ModuleHybridEngine_localCorrectThrust;
+        private static FieldInfo RF_ModuleHybridEngines_localCorrectThrust;
+        private static bool hasInstalledKIDS;
+        private static MethodInfo KIDS_Utils_GetIspMultiplier;
+        private static bool bKIDSThrustISP = false;
         #endregion
 
         #region Delegates
@@ -89,54 +92,112 @@
 
         #region Methods
 
+        private static void CheckForMods()
+        {
+            hasCheckedForMods = true;
+
+            foreach (var assembly in AssemblyLoader.loadedAssemblies)
+            {
+                MonoBehaviour.print("Assembly:" + assembly.assembly);
+
+                var name = assembly.assembly.ToString().Split(',')[0];
+
+                if (name == "RealFuels")
+                {
+                    MonoBehaviour.print("Found RealFuels mod");
+
+                    var RF_ModuleEngineConfigs_Type = assembly.assembly.GetType("RealFuels.ModuleEngineConfigs");
+                    if (RF_ModuleEngineConfigs_Type != null)
+                    {
+                        RF_ModuleEngineConfigs_localCorrectThrust = RF_ModuleEngineConfigs_Type.GetField("localCorrectThrust");
+                    }
+
+                    var RF_ModuleHybridEngine_Type = assembly.assembly.GetType("RealFuels.ModuleHybridEngine");
+                    if (RF_ModuleHybridEngine_Type != null)
+                    {
+                        RF_ModuleHybridEngine_localCorrectThrust = RF_ModuleHybridEngine_Type.GetField("localCorrectThrust");
+                    }
+
+                    var RF_ModuleHybridEngines_Type = assembly.assembly.GetType("RealFuels.ModuleHybridEngines");
+                    if (RF_ModuleHybridEngines_Type != null)
+                    {
+                        RF_ModuleHybridEngines_localCorrectThrust = RF_ModuleHybridEngines_Type.GetField("localCorrectThrust");
+                    }
+
+                    hasInstalledRealFuels = true;
+                    break;
+                }
+                else if (name == "KerbalIspDifficultyScaler")
+                {
+                    var KIDS_Utils_Type = assembly.assembly.GetType("KerbalIspDifficultyScaler.KerbalIspDifficultyScalerUtils");
+                    if (KIDS_Utils_Type != null)
+                    {
+                        KIDS_Utils_GetIspMultiplier = KIDS_Utils_Type.GetMethod("GetIspMultiplier");
+                    }
+
+                    hasInstalledKIDS = true;
+                }
+            }
+        }
+
         public static bool DoesEngineUseCorrectedThrust(Part theEngine)
         {
-            if (!hasInstalledRealFuels /*|| HighLogic.LoadedSceneIsFlight*/)
-            {
-                return false;
-            }
-
-            // Look for any of the Real Fuels engine modules and call the relevant method to find out
-            if (RF_ModuleEngineConfigs_locaCorrectThrust != null && theEngine.Modules.Contains("ModuleEngineConfigs"))
-            {
-                var modEngineConfigs = theEngine.Modules["ModuleEngineConfigs"];
-                if (modEngineConfigs != null)
-                {
-                    // Check the localCorrectThrust
-                    if ((bool)RF_ModuleEngineConfigs_locaCorrectThrust.GetValue(modEngineConfigs))
-                    {
-                        return true;
-                    }
-                }
-            }
-
-            if (RF_ModuleHybridEngine_locaCorrectThrust != null && theEngine.Modules.Contains("ModuleHybridEngine"))
-            {
-                var modHybridEngine = theEngine.Modules["ModuleHybridEngine"];
-                if (modHybridEngine != null)
-                {
-                    // Check the localCorrectThrust
-                    if ((bool)RF_ModuleHybridEngine_locaCorrectThrust.GetValue(modHybridEngine))
-                    {
-                        return true;
-                    }
-                }
-            }
-
-            if (RF_ModuleHybridEngines_locaCorrectThrust != null && theEngine.Modules.Contains("ModuleHybridEngines"))
-            {
-                var modHybridEngines = theEngine.Modules["ModuleHybridEngines"];
-                if (modHybridEngines != null)
-                {
-                    // Check the localCorrectThrust
-                    if ((bool)RF_ModuleHybridEngines_locaCorrectThrust.GetValue(modHybridEngines))
-                    {
-                        return true;
-                    }
-                }
+            if (hasInstalledRealFuels)
+            {
+                // Look for any of the Real Fuels engine modules and call the relevant method to find out
+                if (RF_ModuleEngineConfigs_localCorrectThrust != null && theEngine.Modules.Contains("ModuleEngineConfigs"))
+                {
+                    var modEngineConfigs = theEngine.Modules["ModuleEngineConfigs"];
+                    if (modEngineConfigs != null)
+                    {
+                        // Return the localCorrectThrust
+                        return (bool)RF_ModuleEngineConfigs_localCorrectThrust.GetValue(modEngineConfigs);
+                    }
+                }
+
+                if (RF_ModuleHybridEngine_localCorrectThrust != null && theEngine.Modules.Contains("ModuleHybridEngine"))
+                {
+                    var modHybridEngine = theEngine.Modules["ModuleHybridEngine"];
+                    if (modHybridEngine != null)
+                    {
+                        // Return the localCorrectThrust
+                        return (bool)RF_ModuleHybridEngine_localCorrectThrust.GetValue(modHybridEngine);
+                    }
+                }
+
+                if (RF_ModuleHybridEngines_localCorrectThrust != null && theEngine.Modules.Contains("ModuleHybridEngines"))
+                {
+                    var modHybridEngines = theEngine.Modules["ModuleHybridEngines"];
+                    if (modHybridEngines != null)
+                    {
+                        // Return the localCorrectThrust
+                        return (bool)RF_ModuleHybridEngines_localCorrectThrust.GetValue(modHybridEngines);
+                    }
+                }
+            }
+
+            if (hasInstalledKIDS && HighLogic.LoadedSceneIsEditor)
+            {
+                return bKIDSThrustISP;
             }
 
             return false;
+        }
+
+        public static void UpdateModSettings()
+        {
+            if (!hasCheckedForMods)
+            {
+                CheckForMods();
+            }
+
+            if (hasInstalledKIDS)
+            {
+                // (out ispMultiplierVac, out ispMultiplierAtm, out extendToZeroIsp, out thrustCorrection, out ispCutoff, out thrustCutoff);
+                object[] parameters = new object[6];
+                KIDS_Utils_GetIspMultiplier.Invoke(null, parameters);
+                bKIDSThrustISP = (bool)parameters[3];
+            }
         }
 
         public static String GetVesselTypeString(VesselType vesselType)
@@ -171,9 +232,9 @@
 
         public static void RequestSimulation()
         {
-            if (!hasCheckedForRealFuels)
-            {
-                GetRealFuelsTypes();
+            if (!hasCheckedForMods)
+            {
+                CheckForMods();
             }
 
             lock (locker)
@@ -215,42 +276,6 @@
             failMessage = "";
             Stages = null;
             LastStage = null;
-        }
-
-        private static void GetRealFuelsTypes()
-        {
-            hasCheckedForRealFuels = true;
-
-            foreach (var assembly in AssemblyLoader.loadedAssemblies)
-            {
-                MonoBehaviour.print("Assembly:" + assembly.assembly);
-
-                if (assembly.assembly.ToString().Split(',')[0] == "RealFuels")
-                {
-                    MonoBehaviour.print("Found RealFuels mod");
-
-                    var RF_ModuleEngineConfigs_Type = assembly.assembly.GetType("RealFuels.ModuleEngineConfigs");
-                    if (RF_ModuleEngineConfigs_Type != null)
-                    {
-                        RF_ModuleEngineConfigs_locaCorrectThrust = RF_ModuleEngineConfigs_Type.GetField("localCorrectThrust");
-                    }
-
-                    var RF_ModuleHybridEngine_Type = assembly.assembly.GetType("RealFuels.ModuleHybridEngine");
-                    if (RF_ModuleHybridEngine_Type != null)
-                    {
-                        RF_ModuleHybridEngine_locaCorrectThrust = RF_ModuleHybridEngine_Type.GetField("localCorrectThrust");
-                    }
-
-                    var RF_ModuleHybridEngines_Type = assembly.assembly.GetType("RealFuels.ModuleHybridEngines");
-                    if (RF_ModuleHybridEngines_Type != null)
-                    {
-                        RF_ModuleHybridEngines_locaCorrectThrust = RF_ModuleHybridEngines_Type.GetField("localCorrectThrust");
-                    }
-
-                    hasInstalledRealFuels = true;
-                    break;
-                }
-            }
         }
 
         private static void RunSimulation(object simObject)

--- a/KerbalEngineer/VesselSimulator/Simulation.cs
+++ b/KerbalEngineer/VesselSimulator/Simulation.cs
@@ -531,7 +531,7 @@
 
                 // Store the magnitude of the deltaV vector
                 stage.deltaV = this.vecStageDeltaV.magnitude;
-                stage.resourceMass = this.stepStartMass - this.stepEndMass;
+                stage.resourceMass = this.stageStartMass - this.stepEndMass;
 
                 // Recalculate effective stage isp from the stage deltaV (flip the standard deltaV calculation around)
                 // Note: If the mass doesn't change then this is a divide by zero
@@ -783,7 +783,7 @@
                     }
                     //buffer.AppendFormat("isSepratron = {0}\n", partSim.isSepratron ? "true" : "false");
 
-                    if (!partSim.isSepratron && !partSim.Resources.EmptyOf(this.drainingResources))
+                    if (!partSim.isSepratron && !partSim.EmptyOf(this.drainingResources))
                     {
                         if (SimManager.logOutput)
                         {

--- a/KerbalEngineer/VesselSimulator/Stage.cs
+++ b/KerbalEngineer/VesselSimulator/Stage.cs
@@ -29,27 +29,28 @@
 {
     public class Stage
     {
-        public double actualThrust = 0f;
-        public double actualThrustToWeight = 0f;
-        public double cost = 0d;
-        public double deltaV = 0f;
-        public double inverseTotalDeltaV = 0f;
-        public double isp = 0f;
-        public double mass = 0f;
-        public double maxThrustToWeight = 0f;
+        public double actualThrust = 0.0;
+        public double actualThrustToWeight = 0.0;
+        public double cost = 0.0;
+        public double deltaV = 0.0;
+        public double inverseTotalDeltaV = 0.0;
+        public double isp = 0.0;
+        public double mass = 0.0;
+        public double rcsMass = 0.0;
+        public double maxThrustToWeight = 0.0;
         public int number = 0;
-        public double thrust = 0f;
-        public double thrustToWeight = 0f;
-        public double time = 0f;
-        public double totalCost = 0;
-        public double totalDeltaV = 0f;
-        public double totalMass = 0f;
-        public double totalTime = 0f;
+        public double thrust = 0.0;
+        public double thrustToWeight = 0.0;
+        public double time = 0.0;
+        public double totalCost = 0.0;
+        public double totalDeltaV = 0.0;
+        public double totalMass = 0.0;
+        public double totalTime = 0.0;
         public int totalPartCount = 0;
         public int partCount = 0;
         public double resourceMass = 0.0;
-        public double maxThrustTorque = 0f;
-        public double thrustOffsetAngle = 0f;
+        public double maxThrustTorque = 0.0;
+        public double thrustOffsetAngle = 0.0;
 
         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,8 +5,8 @@
 	{
 		"MAJOR":1,
 		"MINOR":0,
-		"PATCH":13,
-		"BUILD":1
+		"PATCH":15,
+		"BUILD":2
 	},
 	"KSP_VERSION":
 	{

 Binary files /dev/null and b/Output/KerbalEngineer/Parts/Engineer7500/model000.mbm differ
--- a/Output/KerbalEngineer/Parts/Engineer7500/part.cfg
+++ b/Output/KerbalEngineer/Parts/Engineer7500/part.cfg
@@ -7,7 +7,6 @@
 	
 	// --- asset parameters ---
 	mesh = model.mu
-	texture = model000.mbm
 	rescaleFactor = 0.8
 
 	PhysicsSignificance = 1

 Binary files a/Output/KerbalEngineer/Parts/Engineer7500/textures/model000.mbm and /dev/null differ