bool CheckPartResources(MSSRB_Part part, bool max = true)
        {
            // Check the nextPart's resources and Modules
            // Check for the correct propellant and that it has the MSSRB_Fuel_Segment module
            // If so, add it to the segments list and accumulate some values for the motor
            // then update the propellant value amount in the fuel segment
            PartResourceList prl = part.Resources;
            PartModuleList   pml = part.Modules;

            if (prl.Contains(ModSegSRBs.Propellant) && pml.Contains <MSSRB_Fuel_Segment>())
            {
                Log.Info("CheckPartResources, " + ModSegSRBs.Propellant + " found, " + " MSSRB_Fuel_Segment found");
                MSSRB_Fuel_Segment moduleFuelSegment = pml["MSSRB_Fuel_Segment"] as MSSRB_Fuel_Segment;

                if (max)
                {
                    totalFuelMass += moduleFuelSegment.MaxSolidFuel();  // prl[ModSegSRBs.Propellant].maxAmount;
                }
                else
                {
                    totalFuelMass += prl[ModSegSRBs.Propellant].amount;
                }
                totalMaxThrust += moduleFuelSegment.GetMaxThrust();


                prl[ModSegSRBs.Propellant].amount         = moduleFuelSegment.MaxSolidFuel();
                prl[ModSegSRBs.BurnablePropellant].amount = 0;

                prl[ModSegSRBs.Propellant].maxAmount             =
                    prl[ModSegSRBs.BurnablePropellant].maxAmount = moduleFuelSegment.MaxSolidFuel();
                Log.Info("totalMaxThrust: " + totalMaxThrust + ", totalFuelMass: " + totalFuelMass);


                return(true);
            }
            else
            {
                Log.Info("CheckPartResources, no Propellant found");
                return(false);
            }
        }
        void Start()
        {
            nonThrustMotor = true;
            attNode        = this.part.FindAttachNode(attachNode);
            activated      = false;
#if true
            base.Events["Activate"].active    = false;
            base.Events["Activate"].guiActive = false;

            base.Events["Shutdown"].active    = false;
            base.Events["Shutdown"].guiActive = false;

            base.Fields["independentThrottle"].guiActive       = false;
            base.Fields["independentThrottle"].guiActiveEditor = false;

            base.Fields["independentThrottlePercentage"].guiActive       = false;
            base.Fields["independentThrottlePercentage"].guiActiveEditor = false;

            base.Fields["thrustPercentage"].guiActive       = false;
            base.Fields["thrustPercentage"].guiActiveEditor = false;

            Actions["ToggleThrottle"].active       = false;
            Actions["ToggleThrottle"].activeEditor = false;



            foreach (var e in Events)
            {
                Log.Info("Event: " + e.name + ", guiName = " + e.GUIName);
            }
            foreach (var a in Actions)
            {
                Log.Info("Action: " + a.name + ", guiName: " + a.guiName);
            }
#endif
            if (HighLogic.LoadedSceneIsFlight)
            {
                PartModuleList pml = part.Modules;
                if (pml.Contains <MSSRB_Fuel_Segment>())
                {
                    thisSegment = pml.GetModule <MSSRB_Fuel_Segment>();
                }

                if (attNode != null && attNode.attachedPart != null)
                {
                    pml = attNode.attachedPart.Modules;
                    if (pml != null)
                    {
                        if (pml.Contains <MSSRB_Fuel_Segment>())
                        {
                            attachedSegment = pml.GetModule <MSSRB_Fuel_Segment>();
                        }

                        if (pml.Contains <MSSRB_Endcap>())
                        {
                            attachedEndCap = pml.GetModule <MSSRB_Endcap>();
                        }

                        if (pml.Contains <MSSRB_Engine>())
                        {
                            attachedMotor = pml.GetModule <MSSRB_Engine>();
                        }
                    }
                }
            }
        }
        bool CheckPartResources(MSSRB_Part part)
        {
            // Check the nextPart's resources and Modules
            // Check for the correct propellant and that it has the MSSRB_Fuel_Segment module
            // If so, add it to the segments list and accumulate some values for the motor
            // then update the propellant value amount in the fuel segment
            PartResourceList prl = part.Resources;
            PartModuleList   pml = part.Modules;

            if (prl.Contains(ModSegSRBs.Propellant) && pml.Contains <MSSRB_Fuel_Segment>())
            {
                Log.Info("CheckPartResources, Part: " + part.partInfo.title + ", " + ModSegSRBs.Propellant + " found, " + " MSSRB_Fuel_Segment found");
                MSSRB_Fuel_Segment moduleFuelSegment = pml["MSSRB_Fuel_Segment"] as MSSRB_Fuel_Segment;
                segments.Add(new Segment(part, moduleFuelSegment.part.segmentHeight));
                totalFuelMass  += moduleFuelSegment.MaxSolidFuel(); // prl[ModSegSRBs.Propellant].maxAmount;
                totalMaxThrust += moduleFuelSegment.GetMaxThrust();
                Log.Info("CheckPartResources, moduleFuelSegment.part.segmentHeight: " + moduleFuelSegment.part.segmentHeight);
                totalSegmentHeight += moduleFuelSegment.part.segmentHeight;

                Log.Info("CheckPartResources, totalFuelMass: " + totalFuelMass + ", totalMaxThrust: " + totalMaxThrust + ", totalSegmentHeight: " + totalSegmentHeight);

                if (totalSegmentHeight > 0)
                {
                    invTotalSegmentHeight = 1 / totalSegmentHeight;
                }
                else
                {
                    invTotalSegmentHeight = 0;
                }

                moduleFuelSegment.baseEngine = this;

                if (CoM == null && HighLogic.LoadedSceneIsEditor)
                {
                    prl[ModSegSRBs.Propellant].amount        =
                        prl[ModSegSRBs.Propellant].maxAmount = 0;

                    prl[ModSegSRBs.BurnablePropellant].amount        =
                        prl[ModSegSRBs.BurnablePropellant].maxAmount = moduleFuelSegment.MaxSolidFuel();
                    Log.Info("(2) Propellant Setting part.amount = 0, BurnablePropellant maxAmount set to: " + prl[ModSegSRBs.BurnablePropellant].maxAmount);
                }
                else
                {
                    prl[ModSegSRBs.Propellant].amount        =
                        prl[ModSegSRBs.Propellant].maxAmount = moduleFuelSegment.MaxSolidFuel();

                    prl[ModSegSRBs.BurnablePropellant].amount        =
                        prl[ModSegSRBs.BurnablePropellant].maxAmount = 0;
                }

                Log.Info("totalMaxThrust: " + totalMaxThrust + ", totalFuelMass: " + totalFuelMass);

                // Set the baseEngine in the segment ends here, do it in a loop
                // because there can be either one or two ends
                foreach (var p in pml)
                {
                    if (p is MSSRB_SegmentEnds)
                    {
                        MSSRB_SegmentEnds mssrb = p as MSSRB_SegmentEnds;
                        mssrb.baseEngine      = this;
                        mssrb.maxThrust       = this.maxThrust;
                        mssrb.atmosphereCurve = this.atmosphereCurve;
                    }
                }

                return(true);
            }
            else
            {
                Log.Info("CheckPartResources, no Propellant found");
                return(false);
            }
        }
        void UpdateSegmentsInFlight()
        {
            if (brokenSRB)
            {
                Log.Info("UpdateSegmentsInFlight, part.Resources[ModSegSRBs.BurnablePropellant].amount: " + part.Resources[ModSegSRBs.BurnablePropellant].amount);
                Log.Info("UpdateSegmentsInFlight, part.Resources[ModSegSRBs.AbortedPropellant].amount: " + part.Resources[ModSegSRBs.AbortedPropellant].amount);
            }
            if (this.EngineIgnited && !brokenSRB)
            {
                if (failureChance > 0)
                {
                    if (!sickEngine && (UnityEngine.Random.Range(0f, 1f) <= failureChance || triggerEngineFailure))
                    {
                        ScreenMessages.PostScreenMessage("***** Warning ***** Warning ***** Warning *****", 5);
                        ScreenMessages.PostScreenMessage("***** SRB failure in progress *****", 5);

                        HighlightStack();
                        AudibleAlertCore.fetch.ActivateAlarm(5);

                        if (UnityEngine.Random.Range(0, 1f) <= HighLogic.CurrentGame.Parameters.CustomParams <MSSRB_1>().explosionChance)
                        {
                            // Part will explode in 5 seconds
                            explode = fEngRunTime;
                        }
                        else
                        {
                            // Start reducing thrust
                            sickEngine     = true;
                            heatProduction = 0;
                        }
                    }
                }
                if (explode > 0 && fEngRunTime - explode > 5)
                {
                    // Pick a part and destroy it
                    int i = UnityEngine.Random.Range(0, segments.Count - 1);
                    segments[i].part.explode();
                }
                if (sickEngine)
                {
                    engineHealth = Math.Max(0.1f, engineHealth - UnityEngine.Random.Range(0, 0.01f));
                }
#if THRUSTVARIABILITY
                if (engineHealth < oldEngineHealth || HighLogic.CurrentGame.Parameters.CustomParams <MSSRB_1>().hasThrustVariability)
#else
                if (engineHealth < oldEngineHealth)
#endif
                {
                    oldEngineHealth = engineHealth;
#if THRUSTVARIABILITY
                    if (HighLogic.CurrentGame.Parameters.CustomParams <MSSRB_1>().hasThrustVariability)
                    {
                        fEngRunTime += TimeWarp.fixedDeltaTime;
                        var v = HighLogic.CurrentGame.Parameters.CustomParams <MSSRB_1>().maxVariability *Mathf.Sin(fEngRunTime * Mathf.PI * 2 / ModSegSRBs.pressurePulseHertz);
                        Log.Info("ThrustVariability: " + v);
                        ChangeUsage(engineHealth, v);
                    }
                    else
#endif
                    {
                        ChangeUsage(engineHealth);
                    }
                }

                PartResource secondPartResource = null;

                totalFuelFlow = 0;

                double totalCurrentFuel = 0;
                double fuelFlow         = 0;
                double totalMaxFuel     = 0;
                var    maxFuelFlow      = getMaxFuelFlow(propellants[burnablePropIndx]) * Time.fixedDeltaTime - part.Resources[ModSegSRBs.BurnablePropellant].amount + 0.05f;


                for (int i = 0; i < segments.Count; i++)
                {
                    Segment            segment           = segments[i];
                    MSSRB_Fuel_Segment moduleFuelSegment = segment.part.Modules["MSSRB_Fuel_Segment"] as MSSRB_Fuel_Segment;
                    Log.Info("UpdateSegmentsInFlight, segmentheight: " + segment.segmentHeight);
                    if (segment.segmentHeight > 0)
                    {
                        fuelFlow = segment.segmentHeight * invTotalSegmentHeight * maxFuelFlow;

                        fuelFlow    *= engineHealth;
                        maxFuelFlow *= engineHealth;

                        PartResourceList prl = segment.part.Resources;
                        double           availableResource = Math.Min(fuelFlow, prl[ModSegSRBs.Propellant].amount);
                        prl[ModSegSRBs.Propellant].amount -= availableResource;
                        totalFuelFlow    += availableResource;
                        totalCurrentFuel += prl[ModSegSRBs.Propellant].amount;
                        totalMaxFuel     += prl[ModSegSRBs.Propellant].maxAmount;

                        if (((MSSRB_SegmentEnds)segment.part.Modules["MSSRB_SegmentEnds"]).EngineIgnited)
                        {
                            secondPartResource = segment.part.Resources[ModSegSRBs.BurnablePropellant];
                        }
                        else
                        {
                            secondPartResource = null;
                        }
                    }
                }

                totalFuelFlow *= Time.timeScale;
                if (totalFuelFlow > 0)
                {
                    if (secondPartResource != null)
                    {
                        double t = (secondPartResource.amount + totalFuelFlow + part.Resources[ModSegSRBs.BurnablePropellant].amount) / 2;
                        secondPartResource.amount =
                            part.Resources[ModSegSRBs.BurnablePropellant].amount = t;
                    }
                    else
                    {
                        // Update resources in the engine, and then update
                        // the maxAmount with the inverse of the percentage of fuel remaining
                        // This fools the game into showing the correct amount in the staging toolbar
                        part.Resources[ModSegSRBs.BurnablePropellant].amount += totalFuelFlow;
                    }
                    // Now update the maxAmount with the inverse of the percentage of fuel remaining
                    // This fools the game into showing the correct amount in the staging toolbar

                    part.Resources[ModSegSRBs.BurnablePropellant].maxAmount =
                        part.Resources[ModSegSRBs.BurnablePropellant].amount * totalFuelMass / (part.Resources[ModSegSRBs.BurnablePropellant].amount + totalCurrentFuel);
                    percentLeft = (float)(totalCurrentFuel / totalMaxFuel);
                }
            }
        }
        public void Start()
        {
            Log.Info("Start");
            part.RestoreVariant();
#if false
            SetThrustCurve(grainName, null);
#endif

            Events["TriggerEngineFailureEvent"].active   = HighLogic.CurrentGame.Parameters.CustomParams <MSSRB_1>().devMode;
            Actions["TriggerEngineFailureAction"].active = HighLogic.CurrentGame.Parameters.CustomParams <MSSRB_1>().devMode;

#if false
            foreach (var e in Events)
            {
                Log.Info("Event: " + e.name + ", guiName = " + e.guiName);
            }
            foreach (var a in Actions)
            {
                Log.Info("Action: " + a.name + ", guiName: " + a.guiName);
            }
            foreach (var f in Fields)
            {
                Log.Info("Field: " + f.name + ", guiName: " + f.guiName);
            }
#endif

            Fields["independentThrottle"].guiActive           =
                Fields["independentThrottle"].guiActiveEditor = false;
            Fields["thrustPercentage"].guiActive           =
                Fields["thrustPercentage"].guiActiveEditor = false;



            origAtmosphereCurve = atmosphereCurve;

            PartResourceDefinition prd = PartResourceLibrary.Instance.GetDefinition(ModSegSRBs.Propellant);
            density            = prd.density;
            densityInverse     = 1.0 / prd.density;
            fuelFlowMultiplier = densityInverse * Planetarium.fetch.fixedDeltaTime;

            phl = PartHighlighter.CreatePartHighlighter();
            if (phl)
            {
                highlightID = phl.CreateHighlightList();
            }
            if (highlightID >= 0)
            {
                UpdateHighlightColors();
            }

            PartModuleList pml = part.Modules;
            if (pml.Contains("MSSRB_Fuel_Segment"))
            {
                MSSRB_Fuel_Segment moduleFuelSegment = pml["MSSRB_Fuel_Segment"] as MSSRB_Fuel_Segment;
                part.segmentWidth = moduleFuelSegment.part.segmentWidth;
            }
            else
            {
                Log.Info("MSSRB_Engine, missing MSSRB_Fuel_Segment");
            }

            foreach (var p in propellants)
            {
                if (p.name == ModSegSRBs.BurnablePropellant)
                {
                    break;
                }
                burnablePropIndx++;
            }
            foreach (var p in propellants)
            {
                if (p.name == ModSegSRBs.Propellant)
                {
                    break;
                }
                propIndx++;
            }
            ModSegSRBs.GetExtraInfo(part.baseVariant, ref part.segmentHeight, ref part.segmentWidth);

            switch (HighLogic.LoadedScene)
            {
            case GameScenes.EDITOR:
                GameEvents.onEditorPartPicked.Add(onEditorPartPicked);
                GameEvents.onEditorPartPlaced.Add(onEditorPartPlaced);
                GameEvents.onEditorPartDeleted.Add(onEditorPartDeleted);
                GameEvents.onVariantApplied.Add(onEditorVariantApplied);
                ScheduleSegmentUpdate("Start");
                break;

            case GameScenes.FLIGHT:
                failureChance = HighLogic.CurrentGame.Parameters.CustomParams <MSSRB_1>().failureChance;
                if (this.vessel.situation <= Vessel.Situations.PRELAUNCH)
                {
                    UpdateSegments();
                    foreach (var s in segments)
                    {
                        /* PartModuleList */
                        pml = s.part.Modules;
                        MSSRB_Fuel_Segment moduleFuelSegment = pml["MSSRB_Fuel_Segment"] as MSSRB_Fuel_Segment;

                        PartResourceList prl = s.part.Resources;
                        if (prl.Contains(ModSegSRBs.Propellant))
                        {
                            //Log.Info("Segment: " + s.part.partInfo.title + " contains Propellant");
                            prl[ModSegSRBs.Propellant].amount = moduleFuelSegment.MaxSolidFuel();
                        }
                        if (prl.Contains(ModSegSRBs.BurnablePropellant))
                        {
                            prl[ModSegSRBs.BurnablePropellant].amount = 0;
                            //prl[ModSegSRBs.BurnablePropellant].amount = moduleFuelSegment.MaxSolidFuel();

                            //Log.Info("Segment: " + s.part.partInfo.title + " contains BurnablePropellant");
                        }
                    }
                }
                break;
            } // switch
        }