RemoveAttachedParts now removes the specified parts from the fuel target list as well as the attach node list
RemoveAttachedParts now removes the specified parts from the fuel target list as well as the attach node list

--- a/KerbalEngineer/Editor/BuildAdvanced.cs
+++ b/KerbalEngineer/Editor/BuildAdvanced.cs
@@ -528,6 +528,11 @@
             GUILayout.EndHorizontal();
 
             GUILayout.BeginHorizontal();
+            GUILayout.Label("Verbose Simulation Log:");
+            SimManager.logOutput = GUILayout.Toggle(SimManager.logOutput, "ENABLED", buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
+            GUILayout.EndHorizontal();
+
+            GUILayout.BeginHorizontal();
             GUILayout.Label("Build Engineer Overlay:", settingStyle);
             BuildOverlay.Visible = GUILayout.Toggle(BuildOverlay.Visible, "VISIBLE", buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));
             BuildOverlayPartInfo.NamesOnly = GUILayout.Toggle(BuildOverlayPartInfo.NamesOnly, "NAMES ONLY", buttonStyle, GUILayout.Width(100.0f * GuiDisplaySize.Offset));

--- a/KerbalEngineer/Flight/Readouts/Surface/Latitude.cs
+++ b/KerbalEngineer/Flight/Readouts/Surface/Latitude.cs
@@ -20,6 +20,7 @@
 #region Using Directives
 
 using KerbalEngineer.Flight.Sections;
+using KerbalEngineer.Helpers;
 
 #endregion
 
@@ -43,7 +44,7 @@
 
         public override void Draw(SectionModule section)
         {
-            this.DrawLine(KSPUtil.PrintLatitude(FlightGlobals.ship_latitude), section.IsHud);
+            this.DrawLine(Units.ToAngleDMS(FlightGlobals.ship_latitude) + (FlightGlobals.ship_latitude < 0 ? " S" : " N"), section.IsHud);
         }
 
         #endregion

--- a/KerbalEngineer/Helpers/Units.cs
+++ b/KerbalEngineer/Helpers/Units.cs
@@ -85,6 +85,17 @@
         public static string ToAngle(double value, int decimals = 5)
         {
             return value.ToString("F" + decimals) + "°";
+        }
+
+        public static string ToAngleDMS(double value)
+        {
+            double absAngle = Math.Abs(value);
+            int deg = (int)Math.Floor(absAngle);
+            double rem = absAngle - deg;
+            int min = (int)Math.Floor(rem * 60);
+            rem -= ((double)min / 60);
+            int sec = (int)Math.Floor(rem * 3600);
+            return String.Format("{0:0}° {1:00}' {2:00}\"", deg, min, sec); 
         }
 
         public static string ToDistance(double value, int decimals = 1)

--- a/KerbalEngineer/VesselSimulator/PartSim.cs
+++ b/KerbalEngineer/VesselSimulator/PartSim.cs
@@ -398,7 +398,7 @@
         {
             foreach (int type in types)
             {
-                if (resources.HasType(type) && resourceFlowStates[type] != 0 && resources[type] > SimManager.RESOURCE_MIN)
+                if (resources.HasType(type) && resourceFlowStates[type] != 0 && resources[type] > SimManager.RESOURCE_PART_EMPTY_THRESH)
                 {
                     return false;
                 }
@@ -444,15 +444,13 @@
             if (visited.Contains(this))
             {
                 if (log != null)
-                {
                     log.buf.AppendLine(indent + "Returning empty set, already visited (" + name + ":" + partId + ")");
-                }
 
                 return;
             }
 
-            //if (log != null)
-            //    log.buf.AppendLine(indent + "Adding this to visited");
+            if (log != null)
+                log.buf.AppendLine(indent + "Adding this to visited");
 
             visited.Add(this);
 
@@ -465,26 +463,27 @@
             for (int i = 0; i < this.fuelTargets.Count; i++)
             {
                 PartSim partSim = this.fuelTargets[i];
-                if (visited.Contains(partSim))
-                {
-                    //if (log != null)
-                    //    log.buf.AppendLine(indent + "Fuel target already visited, skipping (" + partSim.name + ":" + partSim.partId + ")");
-                }
-                else
-                {
-                    //if (log != null)
-                    //    log.buf.AppendLine(indent + "Adding fuel target as source (" + partSim.name + ":" + partSim.partId + ")");
-
-                    partSim.GetSourceSet(type, allParts, visited, allSources, log, indent);
+                if (partSim != null)
+                {
+                    if (visited.Contains(partSim))
+                    {
+                        if (log != null)
+                            log.buf.AppendLine(indent + "Fuel target already visited, skipping (" + partSim.name + ":" + partSim.partId + ")");
+                    }
+                    else
+                    {
+                        if (log != null)
+                            log.buf.AppendLine(indent + "Adding fuel target as source (" + partSim.name + ":" + partSim.partId + ")");
+
+                        partSim.GetSourceSet(type, allParts, visited, allSources, log, indent);
+                    }
                 }
             }
 
             if (allSources.Count > lastCount)
             {
                 if (log != null)
-                {
                     log.buf.AppendLine(indent + "Returning " + (allSources.Count - lastCount) + " fuel target sources (" + this.name + ":" + this.partId + ")");
-                }
 
                 return;
             }
@@ -514,13 +513,13 @@
                             {
                                 if (visited.Contains(attachSim.attachedPartSim))
                                 {
-                                    //if (log != null)
-                                    //    log.buf.AppendLine(indent + "Attached part already visited, skipping (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");
+                                    if (log != null)
+                                        log.buf.AppendLine(indent + "Attached part already visited, skipping (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");
                                 }
                                 else
                                 {
-                                    //if (log != null)
-                                    //    log.buf.AppendLine(indent + "Adding attached part as source (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");
+                                    if (log != null)
+                                        log.buf.AppendLine(indent + "Adding attached part as source (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");
 
                                     attachSim.attachedPartSim.GetSourceSet(type, allParts, visited, allSources, log, indent);
                                 }
@@ -532,9 +531,7 @@
                 if (allSources.Count > lastCount)
                 {
                     if (log != null)
-                    {
                         log.buf.AppendLine(indent + "Returning " + (allSources.Count - lastCount) + " attached sources (" + this.name + ":" + this.partId + ")");
-                    }
 
                     return;
                 }
@@ -551,12 +548,15 @@
                     allSources.Add(this);
 
                     if (log != null)
-                    {
                         log.buf.AppendLine(indent + "Returning enabled tank as only source (" + name + ":" + partId + ")");
-                    }
                 }
 
                 return;
+            }
+            else
+            {
+                if (log != null)
+                    log.buf.AppendLine(indent + "Not fuel tank or disabled. HasType = " + resources.HasType(type) + "  FlowState = " + resourceFlowStates[type]);
             }
 
             // Rule 7: If the part is radially attached to another part and it is child of that part in the ship's tree structure, it scans its 
@@ -567,8 +567,8 @@
                 {
                     if (visited.Contains(parent))
                     {
-                        //if (log != null)
-                        //    log.buf.AppendLine(indent + "Parent part already visited, skipping (" + parent.name + ":" + parent.partId + ")");
+                        if (log != null)
+                            log.buf.AppendLine(indent + "Parent part already visited, skipping (" + parent.name + ":" + parent.partId + ")");
                     }
                     else
                     {
@@ -577,9 +577,7 @@
                         if (allSources.Count > lastCount)
                         {
                             if (log != null)
-                            {
                                 log.buf.AppendLine(indent + "Returning " + (allSources.Count  - lastCount) + " parent sources (" + this.name + ":" + this.partId + ")");
-                            }
 
                             return;
                         }
@@ -588,8 +586,8 @@
             }
 
             // Rule 8: If all preceding rules failed, part returns empty list.
-            //if (log != null)
-            //    log.buf.AppendLine(indent + "Returning empty set, no sources found (" + name + ":" + partId + ")");
+            if (log != null)
+                log.buf.AppendLine(indent + "Returning empty set, no sources found (" + name + ":" + partId + ")");
 
             return;
         }
@@ -609,6 +607,17 @@
                 if (partSims.Contains(attachSim.attachedPartSim))
                 {
                     attachSim.attachedPartSim = null;
+                }
+            }
+
+            // Loop through the fuel targets (fuel line sources)
+            for (int i = 0; i < this.fuelTargets.Count; i++)
+            {
+                PartSim fuelTargetSim = this.fuelTargets[i];
+                // If the part is in the set then "remove" it by clearing the PartSim reference
+                if (fuelTargetSim != null && partSims.Contains(fuelTargetSim))
+                {
+                    this.fuelTargets[i] = null;
                 }
             }
         }

--- a/KerbalEngineer/VesselSimulator/SimManager.cs
+++ b/KerbalEngineer/VesselSimulator/SimManager.cs
@@ -35,6 +35,7 @@
         #region Constants
 
         public const double RESOURCE_MIN = 0.0001;
+        public const double RESOURCE_PART_EMPTY_THRESH = 0.01;
 
         #endregion