Separately staged fairing mass jettisons are now calculated in the editor.
Separately staged fairing mass jettisons are now calculated in the editor.

--- a/KerbalEngineer/VesselSimulator/PartSim.cs
+++ b/KerbalEngineer/VesselSimulator/PartSim.cs
@@ -18,7 +18,6 @@
 // 
 
 #region Using Directives
-
 #endregion
 
 namespace KerbalEngineer.VesselSimulator
@@ -53,7 +52,10 @@
         public bool isLanded;
         public bool isNoPhysics;
         public bool isSepratron;
+        public bool isFairing;
         public bool localCorrectThrust;
+        public float moduleMass;
+        public int stageIndex;
         public String name;
         public String noCrossFeedNodeKey;
         public PartSim parent;
@@ -287,13 +289,18 @@
             return true;
         }
 
-        public double GetMass()
+        public double GetMass(int currentStage)
         {
             double mass = baseMass;
 
             for (int i = 0; i < resources.Types.Count; ++i)
             {
                 mass += resources.GetResourceMass(resources.Types[i]);
+            }
+
+            if (hasVessel == false && isFairing && inverseStage < currentStage)
+            {
+                mass = mass + moduleMass;
             }
 
             return mass;
@@ -478,6 +485,7 @@
             Reset(this);
 
             part = thePart;
+            hasVessel = (part.vessel != null);
             centerOfMass = thePart.transform.TransformPoint(thePart.CoMOffset);
             partId = id;
             name = part.partInfo.name;
@@ -495,30 +503,23 @@
             isFuelLine = part.HasModule<CModuleFuelLine>();
             isFuelTank = part is FuelTank;
             isSepratron = IsSepratron();
+            isFairing = IsFairing(part);
             inverseStage = part.inverseStage;
+            stageIndex = part.inStageIndex;
             //MonoBehaviour.print("inverseStage = " + inverseStage);
-
-            cost = part.GetCostWet();
 
             // Work out if the part should have no physical significance
             isNoPhysics = part.HasModule<LaunchClamp>();
-
             if (isNoPhysics == false)
             {
-                if (part.vessel != null)
-                {
-                    baseMass = part.mass;
-                }
-                else
-                {
-                    baseMass = part.mass + part.GetModuleMass(part.mass);
-                }
-            }
-
-            if (SimManager.logOutput)
-            {
-                MonoBehaviour.print((isNoPhysics ? "Ignoring" : "Using") + " part.mass of " + part.mass);
-            }
+                baseMass = part.mass;
+                if (hasVessel == false)
+                {
+                    moduleMass = part.GetModuleMass(part.mass);
+                }
+            }
+
+            cost = part.GetCostWet();
 
             for (int i = 0; i < part.Resources.Count; ++i)
             {
@@ -542,9 +543,6 @@
                 }
             }
 
-            startMass = GetMass();
-
-            hasVessel = (part.vessel != null);
             isLanded = hasVessel && part.vessel.Landed;
             if (hasVessel)
             {
@@ -558,6 +556,8 @@
             hasModuleEngines = part.HasModule<ModuleEngines>();
 
             isEngine = hasMultiModeEngine || hasModuleEnginesFX || hasModuleEngines;
+
+            startMass = GetMass(-1);
 
             if (SimManager.logOutput)
             {
@@ -723,6 +723,7 @@
             partSim.isLanded = false;
             partSim.isNoPhysics = false;
             partSim.isSepratron = false;
+            partSim.isFairing = false;
             partSim.localCorrectThrust = false;
             partSim.name = null;
             partSim.noCrossFeedNodeKey = null;
@@ -732,6 +733,8 @@
             partSim.partId = 0;
             partSim.vesselName = null;
             partSim.vesselType = VesselType.Base;
+            partSim.moduleMass = 0.0f;
+            partSim.stageIndex = 0;
         }
 
         private Vector3 CalculateThrustVector(List<Transform> thrustTransforms, LogMsg log)
@@ -799,6 +802,11 @@
                    thePart.HasModule<ModuleAnchoredDecoupler>();
         }
 
+        private bool IsFairing(Part thePart)
+        {
+            return thePart.HasModule<ModuleProceduralFairing>();
+        }
+
         private bool IsSepratron()
         {
             if (!part.ActivatesEvenIfDisconnected)

--- a/KerbalEngineer/VesselSimulator/Simulation.cs
+++ b/KerbalEngineer/VesselSimulator/Simulation.cs
@@ -75,6 +75,7 @@
         public String vesselName;
         public VesselType vesselType;
         private WeightedVectorAverager vectorAverager = new WeightedVectorAverager();
+        private static ModuleProceduralFairing moduleProceduralFairing;
 
         public Simulation()
         {
@@ -91,7 +92,7 @@
                 double mass = 0d;
 
                 for (int i = 0; i < allParts.Count; ++i) { 
-                    mass += allParts[i].GetMass();
+                    mass += allParts[i].GetMass(currentStage);
                 }
 
                 return mass;
@@ -107,7 +108,7 @@
                 for (int i = 0; i < allParts.Count; ++i)
                 {
                     PartSim partSim = allParts[i];
-                    vectorAverager.Add(partSim.centerOfMass, partSim.GetMass());
+                    vectorAverager.Add(partSim.centerOfMass, partSim.GetMass(currentStage));
                 }
 
                 return vectorAverager.Get();
@@ -372,7 +373,6 @@
 
             // Create the array of stages that will be returned
             Stage[] stages = new Stage[this.currentStage + 1];
-
 
             // Loop through the stages
             while (this.currentStage >= 0)
@@ -445,6 +445,11 @@
                         stage.cost += partSim.cost;
                         stage.mass += partSim.GetStartMass();
                     }
+
+                    if (partSim.hasVessel == false && partSim.isFairing && partSim.inverseStage == currentStage)
+                    {
+                        stage.mass += partSim.moduleMass;
+                    }
                 }
 
                 this.dontStageParts = dontStagePartsLists[this.currentStage];

 Binary files a/Output/KerbalEngineer/KerbalEngineer.dll and b/Output/KerbalEngineer/KerbalEngineer.dll differ