public override void OnUpdate()
 {
     if (isDecoupled)
     {
         return;
     }
     if (engine == null)
     {
         return;
     }
     if (autoDecouple)
     {
         if (!wasRunning)
         {
             wasRunning = engine.GetCurrentThrust() > 0;
         }
         else
         {
             if (engine.GetCurrentThrust() <= 0)
             {
                 Decouple();
             }
         }
     }
 }
Ejemplo n.º 2
0
        public void FixedUpdate()
        {
            if (!HighLogic.LoadedSceneIsFlight || vessel.HoldPhysics || Time.timeSinceLevelLoad < 1.0f || !haveEngine)
            {
                return;
            }
            //Debug.Log("[ModuleEngineLife]: FixedUpdate()");
            double currentTime = Planetarium.GetUniversalTime();

            if (lastUpdateTime > 0)
            {
                float deltaTime = (float)(currentTime - lastUpdateTime);
                if (engine.EngineIgnited)
                {
                    timeActive += deltaTime * (engine.GetCurrentThrust() / engine.maxThrust);
                    if (failTime < 0)
                    {
                        InitEngineFailure();
                    }
                }
                runTimeDisplay = timeActive.ToString("0.0") + "s";// + " (" + failTime.ToString("0.0") + "s)";
                if (runTime > 0 && timeActive > runTime)
                {
                    runTimeDisplay += "!";
                }
                if (failTime > 0.0f && timeActive > failTime)
                {
                    engineStatusDisplay   = "Internal Failure";
                    engine.heatProduction = Math.Min(maxHeatProduction, baseHeatProduction * Math.Max(1, (timeActive - runTime) * failSeverity));
                }
            }
            lastUpdateTime = currentTime;
        }
Ejemplo n.º 3
0
        public double GetTWR()
        {
            double twr = -1;

            if (engineModule != null)
            {
                double thrust = engineModule.GetCurrentThrust();
                if (thrust > 0)
                {
                    isRunning = true;
                    Part   p             = engineModule.part;
                    double partTotalMass = p.mass + p.GetModuleMass(p.mass) + p.GetResourceMass();
                    //double gravHeight = vessel.altitude + vessel.mainBody.Radius; //gravity force at this altitude (not in m/s^2)
                    //double gravForce = vessel.mainBody.gMagnitudeAtCenter / Math.Pow(gravHeight, 2); //accel down due to gravity in m/s^2

                    twr = thrust / (partTotalMass * vessel.graviticAcceleration.magnitude);
                }
                else if (triggerOnFlameout && isRunning) // engineModule.flameout not always set
                {
                    twr = 0;
                }
                isRunning = thrust > 0;
            }
            return(twr);
        }
        public void FixedUpdate()
        {
            if (HighLogic.LoadedSceneIsFlight)
            {
                receiver.Spherical(this.part, true, PowerLimiter, SurfaceArea, 1d, true, true, State, out State, out double recvPower);
                ReceivedPower = (float)Math.Round(recvPower, 1);
                AnimationState();

                double impulse = ReceivedPower * 1000f * partThrustMult / c;

                // adding heat to part's skin
                double heatModifier = HighLogic.CurrentGame.Parameters.CustomParams <BPSettings>().PercentHeat;
                this.part.AddSkinThermalFlux((float)((1 - Reflectivity) * ReceivedPower * ((heatModifier / 100) * 0.7)));
                SkinTemp = (float)Math.Round(this.part.skinTemperature, 1);

                // code related to the engine module
                double thrustMult = HighLogic.CurrentGame.Parameters.CustomParams <BPSettings>().photonthrust;
                float  Thrust     = (float)(impulse * Reflectivity * (engine.realIsp / 30592000) * thrustMult); // in N
                ThrustN = (float)Math.Round(engine.GetCurrentThrust() * 1000, 3);
                float percentThrust = Thrust / (engine.maxThrust * 1000);
                engine.thrustPercentage = Mathf.Clamp((float)Math.Round(percentThrust * 100, 3), 0f, 100f);

                this.vessel.GetConnectedResourceTotals(EChash, out double ECamount, out double maxAmount);
                if (ECamount / maxAmount < 0.01f)
                {
                    engine.thrustPercentage = 0f;
                }

                // replenishes photons resource
                int fuelId = engine.propellants[0].resourceDef.id;
                this.part.GetConnectedResourceTotals(fuelId, out double Fuelamount, out _);
                if (Fuelamount < 10d)
                {
                    this.part.RequestResource(fuelId, -100d); // increases quantity of the photons resource
                }

                ReceivedPower = Math.Abs(ReceivedPower);
            }
        }
        //This method runs every physics frame
        //============================================================================================================================================
        private void FixedUpdate()
        {
            //We can reduce compute times by testing only engines from a list rather than every part on the ship
            if (PartCount != FlightGlobals.ActiveVessel.parts.Count ()) {
                //Make a new list of Engines if the Part Count has changed since last frame
                ActiveEngines.Clear ();
                foreach (Part Engine in FlightGlobals.ActiveVessel.parts) {
                    if (Engine.Modules.Contains ("ModuleEngines") | Engine.Modules.Contains ("ModuleEnginesFX")) {
                        ActiveEngines.Add (Engine);
                    }
                }
                //Set Part count to current count
                PartCount = FlightGlobals.ActiveVessel.parts.Count ();
            }

            //Find Global Variables
            CurrentMach = Convert.ToSingle(FlightGlobals.ActiveVessel.mach);
            CurrentAtm = Convert.ToSingle (FlightGlobals.ActiveVessel.atmDensity);

            //Perform calculations for each engine
            foreach (Part SingleEngine in ActiveEngines) {
                //ModuleEngines
                //------------------------------------------------------------------------------------------------------------------------------
                if (SingleEngine.Modules.Contains ("ModuleEngines")) {
                    ModuleEngines ME1 = new ModuleEngines ();
                    ModuleEngines ME2 = new ModuleEngines ();
                    ME1 = SingleEngine.FindModulesImplementing<ModuleEngines> ().First ();
                    ME2 = SingleEngine.FindModulesImplementing<ModuleEngines> ().Last ();
                    //Do Calculations for Module 1 if it is operational
                    if (ME1.isOperational == true) {
                        //Jet engines use Atmosphere & Velocity Curves to modify performance at different altitudes/speeds.  Use these calculations for those engines, otherwise use base values from part cfg.
                        if (ME1.useAtmCurve == true && ME1.useVelCurve == true) {
                            //If the Thrust Multiplier from VelCurve * AtmCurve is more than 1, evaluate the curves and determine max thrust for that scenario.  Otherwise, use the base method and assume Max Thrust from cfg file.
                            if ((ME1.velCurve.Evaluate (CurrentMach) * ME1.atmCurve.Evaluate (CurrentAtm)) > 1) {
                                TotalCapableThrust = TotalCapableThrust + ((ME1.GetMaxThrust () * (ME1.thrustPercentage / 100)) * (ME1.velCurve.Evaluate (CurrentMach)) * (ME1.atmCurve.Evaluate (CurrentAtm)));
                            } else {
                                TotalCapableThrust = TotalCapableThrust + ((ME1.GetMaxThrust () * (ME1.thrustPercentage / 100)));
                            }
                            TotalCurrentThrust = TotalCurrentThrust + ME1.GetCurrentThrust ();
                        } else {
                            TotalCapableThrust = TotalCapableThrust + (ME1.GetMaxThrust () * (ME1.thrustPercentage / 100));
                            TotalCurrentThrust = TotalCurrentThrust + ME1.GetCurrentThrust ();
                        }
                    }
                    //If Module 2 is different from 1 (by engineID) do calculations for Module 2 if it is operational
                    if (ME1.engineID != ME2.engineID) {
                        if (ME2.isOperational == true) {
                            //Jet engines use Atmosphere & Velocity Curves to modify performance at different altitudes/speeds.  Use these calculations for those engines, otherwise use base values from part cfg.
                            if (ME2.useAtmCurve == true && ME2.useVelCurve == true) {
                                //If the Thrust Multiplier from VelCurve * AtmCurve is more than 1, evaluate the curves and determine max thrust for that scenario.  Otherwise, use the base method and assume Max Thrust from cfg file.
                                if ((ME2.velCurve.Evaluate (CurrentMach) * ME2.atmCurve.Evaluate (CurrentAtm)) > 1) {
                                    TotalCapableThrust = TotalCapableThrust + ((ME2.GetMaxThrust () * (ME2.thrustPercentage / 100)) * (ME2.velCurve.Evaluate (CurrentMach)) * (ME2.atmCurve.Evaluate (CurrentAtm)));
                                } else {
                                    TotalCapableThrust = TotalCapableThrust + ((ME2.GetMaxThrust () * (ME2.thrustPercentage / 100)));
                                }
                                TotalCurrentThrust = TotalCurrentThrust + ME2.GetCurrentThrust ();
                            } else {
                                TotalCapableThrust = TotalCapableThrust + (ME2.GetMaxThrust () * (ME2.thrustPercentage / 100));
                                TotalCurrentThrust = TotalCurrentThrust + ME2.GetCurrentThrust ();
                            }
                        }
                    }
                }
                //ModuleEnginesFX
                //------------------------------------------------------------------------------------------------------------------------------
                if (SingleEngine.Modules.Contains ("ModuleEnginesFX")) {
                    ModuleEnginesFX MEFX1 = new ModuleEnginesFX ();
                    ModuleEnginesFX MEFX2 = new ModuleEnginesFX ();
                    MEFX1 = SingleEngine.FindModulesImplementing<ModuleEnginesFX> ().First ();
                    MEFX2 = SingleEngine.FindModulesImplementing<ModuleEnginesFX> ().Last ();
                    //Do Calculations for Module 1 if it is operational
                    if (MEFX1.isOperational == true) {
                        //Jet engines use Atmosphere & Velocity Curves to modify performance at different altitudes/speeds.  Use these calculations for those engines, otherwise use base values from part cfg.
                        if (MEFX1.useAtmCurve == true && MEFX1.useVelCurve == true) {
                            //If the Thrust Multiplier from VelCurve * AtmCurve is more than 1, evaluate the curves and determine max thrust for that scenario.  Otherwise, use the base method and assume Max Thrust from cfg file.
                            if ((MEFX1.velCurve.Evaluate (CurrentMach) * MEFX1.atmCurve.Evaluate (CurrentAtm)) > 1) {
                                TotalCapableThrust = TotalCapableThrust + ((MEFX1.GetMaxThrust () * (MEFX1.thrustPercentage / 100)) * (MEFX1.velCurve.Evaluate (CurrentMach)) * (MEFX1.atmCurve.Evaluate (CurrentAtm)));
                            } else {
                                TotalCapableThrust = TotalCapableThrust + ((MEFX1.GetMaxThrust () * (MEFX1.thrustPercentage / 100)));
                            }
                            TotalCurrentThrust = TotalCurrentThrust + MEFX1.GetCurrentThrust ();
                        } else {
                            TotalCapableThrust = TotalCapableThrust + (MEFX1.GetMaxThrust () * (MEFX1.thrustPercentage / 100));
                            TotalCurrentThrust = TotalCurrentThrust + MEFX1.GetCurrentThrust ();
                        }
                    }
                    //If Module 2 is different from 1 (by engineID) do calculations for Module 2 if it is operational
                    if (MEFX1.engineID != MEFX2.engineID) {
                        if (MEFX2.isOperational == true) {
                            //Jet engines use Atmosphere & Velocity Curves to modify performance at different altitudes/speeds.  Use these calculations for those engines, otherwise use base values from part cfg.
                            if (MEFX2.useAtmCurve == true && MEFX2.useVelCurve == true) {
                                //If the Thrust Multiplier from VelCurve * AtmCurve is more than 1, evaluate the curves and determine max thrust for that scenario.  Otherwise, use the base method and assume Max Thrust from cfg file.
                                if ((MEFX2.velCurve.Evaluate (CurrentMach) * MEFX2.atmCurve.Evaluate (CurrentAtm)) > 1) {
                                    TotalCapableThrust = TotalCapableThrust + ((MEFX2.GetMaxThrust () * (MEFX2.thrustPercentage / 100)) * (MEFX2.velCurve.Evaluate (CurrentMach)) * (MEFX2.atmCurve.Evaluate (CurrentAtm)));
                                } else {
                                    TotalCapableThrust = TotalCapableThrust + ((MEFX2.GetMaxThrust () * (MEFX2.thrustPercentage / 100)));
                                }
                                TotalCurrentThrust = TotalCurrentThrust + MEFX2.GetCurrentThrust ();
                            } else {
                                TotalCapableThrust = TotalCapableThrust + (MEFX2.GetMaxThrust () * (MEFX2.thrustPercentage / 100));
                                TotalCurrentThrust = TotalCurrentThrust + MEFX2.GetCurrentThrust ();
                            }
                        }
                    }
                }
            }
            //Prevent Divide by 0 Errors
            if (TotalCapableThrust == 0) {
                TotalCapableThrust = 0.0001f;
            }
            //Not truly a percentage, gauge works between 0 and 1, NOT 0 and 100
            ThrustPercentage = ((TotalCurrentThrust / TotalCapableThrust));

            if (UseSplitNeedle == false) {
                //Gently Fade the alpha channel of the stock gauge so we can see TIM if it is near/behind
                if (FlightUIController.fetch.thr.rawValue >= ThrustPercentage) {
                    StockGaugeColor.a = Mathf.Max (Mathf.Min (((((FlightUIController.fetch.thr.rawValue - ThrustPercentage) - 0.015f) * 2.3f) + StockGaugeColorAlpha), 1.0f), StockGaugeColorAlpha);
                }
                if (FlightUIController.fetch.thr.rawValue <= ThrustPercentage) {
                    StockGaugeColor.a = Mathf.Max (Mathf.Min (((((FlightUIController.fetch.thr.rawValue - ThrustPercentage) + 0.015f) * -2.3f) + StockGaugeColorAlpha), 1.0f), StockGaugeColorAlpha);
                }
                StockGauge.transform.GetChild (0).renderer.material.color = StockGaugeColor;
                TIMGauge.transform.GetChild (0).renderer.material.color = TIMGaugeColor;
                //Render the StockGauge after TIM so that it shows in front of TIM
                StockGauge.transform.GetChild (0).renderer.material.renderQueue = TIMGauge.transform.GetChild (0).renderer.material.renderQueue + 1;
            }
            //Set Gauge to Calculated Value
            TIMGauge.setValue (ThrustPercentage);
            //Reset Thrust Values Each Compute Cycle
            TotalCapableThrust = 0;
            TotalCurrentThrust = 0;
        }
Ejemplo n.º 6
0
        // Physics update
        public void FixedUpdate() // FixedUpdate is also called while not staged
        {
            if (this.vessel is null || !isEnabled)
            {
                return;
            }

            kerbalismResourceChangeRequest.Clear();

            if (vesselChangedSOICountdown > 0)
            {
                vesselChangedSOICountdown--;
            }

            // Realtime mode
            if (!this.vessel.packed)
            {
                engineHasAnyMassLessPropellants = engine.propellants.Any(m => m.resourceDef.density == 0);

                // Update persistent thrust parameters if NOT transitioning from warp to realtime
                if (!warpToReal)
                {
                    UpdatePersistentParameters();
                }

                ratioHeadingVersusRequest = 0;

                if (!engineHasAnyMassLessPropellants)
                {
                    // Mass flow rate
                    var massFlowRate = IspPersistent > 0 ?  (engine.requestedThrottle * engine.maxThrust) / (IspPersistent * PhysicsGlobals.GravitationalAcceleration): 0;
                    // Change in mass over time interval dT
                    var deltaMass = massFlowRate * TimeWarp.fixedDeltaTime;
                    // Resource demand from propellants with mass
                    demandMass = densityAverage > 0 ? deltaMass / densityAverage : 0;

                    // Calculate resource demands
                    fuelDemands = CalculateDemands(demandMass);
                    // Apply resource demands & test for resource depletion
                    ApplyDemands(fuelDemands, ref propellantReqMetFactor);

                    // calculate maximum flow
                    var maxFuelFlow = IspPersistent > 0 ? engine.maxThrust / (IspPersistent * PhysicsGlobals.GravitationalAcceleration) : 0;
                    // adjust fuel flow
                    if (maxFuelFlow > 0)
                    {
                        engine.maxFuelFlow = (float)(maxFuelFlow * propellantReqMetFactor);
                    }
                    // update displayed thrust and fx
                    finalThrust = engine.currentThrottle * engine.maxThrust * propellantReqMetFactor;
                }
                else
                {
                    missingPowerCountdown = missingPowerCountdownSize;

                    propellantReqMetFactor = engine.propellantReqMet * 0.01f;

                    finalThrust = engine.GetCurrentThrust();
                }

                UpdatePropellantReqMetFactorQueue();

                UpdateFX(finalThrust);

                UpdateBuffers(fuelDemands);
            }
            else
            {
                if (ThrottlePersistent > 0 && IspPersistent > 0 && IsPersistentEngine && HasPersistentThrust)
                {
                    warpToReal = true; // Set to true for transition to realtime

                    if (vessel.IsControllable && HasPersistentHeadingEnabled)
                    {
                        ratioHeadingVersusRequest = engine.PersistHeading(TimeWarp.fixedDeltaTime, headingTolerance, vesselChangedSOICountdown > 0, ratioHeadingVersusRequest == 1);
                        if (ratioHeadingVersusRequest != 1)
                        {
                            finalThrust = 0;
                            return;
                        }
                    }
                    // Calculated requested thrust
                    var requestedThrust = engine.thrustPercentage * 0.01f * ThrottlePersistent * engine.maxThrust;
                    var UT       = Planetarium.GetUniversalTime(); // Universal time
                    var thrustUV = this.part.transform.up;         // Thrust direction unit vector
                    // Calculate deltaV vector & resource demand from propellants with mass
                    var deltaVV = CalculateDeltaVV(this.vessel.totalMass, TimeWarp.fixedDeltaTime, requestedThrust, IspPersistent, thrustUV, out demandMass);
                    // Calculate resource demands
                    fuelDemands = CalculateDemands(demandMass);
                    // Apply resource demands & test for resource depletion
                    ApplyDemands(fuelDemands, ref propellantReqMetFactor);

                    // Apply deltaV vector at UT & dT to orbit if resources not depleted
                    if (propellantReqMetFactor > 0)
                    {
                        finalThrust = requestedThrust * propellantReqMetFactor;
                        vessel.orbit.Perturb(deltaVV * propellantReqMetFactor, UT);
                    }

                    // Otherwise log warning and drop out of timewarp if throttle on & depleted
                    else if (ThrottlePersistent > 0)
                    {
                        finalThrust = 0;
                        Debug.Log("[PersistentThrust]: Thrust warp stopped - propellant depleted");
                        ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_PT_StoppedDepleted"), 5.0f, ScreenMessageStyle.UPPER_CENTER);
                        // Return to realtime
                        TimeWarp.SetRate(0, true);
                        if (!vessel.IsControllable)
                        {
                            ThrottlePersistent            = 0;
                            vessel.ctrlState.mainThrottle = 0;
                        }
                    }
                    else
                    {
                        finalThrust = 0;
                    }

                    UpdateFX(finalThrust);
                }
                else
                {
                    finalThrust = 0;
                    if (vessel.IsControllable && HasPersistentHeadingEnabled)
                    {
                        ratioHeadingVersusRequest = engine.PersistHeading(TimeWarp.fixedDeltaTime, headingTolerance, vesselChangedSOICountdown > 0);
                    }
                    UpdateFX(0);

                    UpdateBuffers(fuelDemands);
                }
            }
        }
Ejemplo n.º 7
0
        //This method runs every physics frame
        //============================================================================================================================================
        private void FixedUpdate()
        {
            //We can reduce compute times by testing only engines from a list rather than every part on the ship
            if (PartCount != FlightGlobals.ActiveVessel.parts.Count())
            {
                //Make a new list of Engines if the Part Count has changed since last frame
                ActiveEngines.Clear();
                foreach (Part Engine in FlightGlobals.ActiveVessel.parts)
                {
                    if (Engine.Modules.Contains("ModuleEngines") | Engine.Modules.Contains("ModuleEnginesFX"))
                    {
                        ActiveEngines.Add(Engine);
                    }
                }
                //Set Part count to current count
                PartCount = FlightGlobals.ActiveVessel.parts.Count();
            }

            //Find Global Variables
            CurrentMach = Convert.ToSingle(FlightGlobals.ActiveVessel.mach);
            CurrentAtm  = Convert.ToSingle(FlightGlobals.ActiveVessel.atmDensity);

            //Perform calculations for each engine
            foreach (Part SingleEngine in ActiveEngines)
            {
                //ModuleEngines
                //------------------------------------------------------------------------------------------------------------------------------
                if (SingleEngine.Modules.Contains("ModuleEngines"))
                {
                    ModuleEngines ME1 = new ModuleEngines();
                    ModuleEngines ME2 = new ModuleEngines();
                    ME1 = SingleEngine.FindModulesImplementing <ModuleEngines> ().First();
                    ME2 = SingleEngine.FindModulesImplementing <ModuleEngines> ().Last();
                    //Do Calculations for Module 1 if it is operational
                    if (ME1.isOperational == true)
                    {
                        //Jet engines use Atmosphere & Velocity Curves to modify performance at different altitudes/speeds.  Use these calculations for those engines, otherwise use base values from part cfg.
                        if (ME1.useAtmCurve == true && ME1.useVelCurve == true)
                        {
                            //If the Thrust Multiplier from VelCurve * AtmCurve is more than 1, evaluate the curves and determine max thrust for that scenario.  Otherwise, use the base method and assume Max Thrust from cfg file.
                            if ((ME1.velCurve.Evaluate(CurrentMach) * ME1.atmCurve.Evaluate(CurrentAtm)) > 1)
                            {
                                TotalCapableThrust = TotalCapableThrust + ((ME1.GetMaxThrust() * (ME1.thrustPercentage / 100)) * (ME1.velCurve.Evaluate(CurrentMach)) * (ME1.atmCurve.Evaluate(CurrentAtm)));
                            }
                            else
                            {
                                TotalCapableThrust = TotalCapableThrust + ((ME1.GetMaxThrust() * (ME1.thrustPercentage / 100)));
                            }
                            TotalCurrentThrust = TotalCurrentThrust + ME1.GetCurrentThrust();
                        }
                        else
                        {
                            TotalCapableThrust = TotalCapableThrust + (ME1.GetMaxThrust() * (ME1.thrustPercentage / 100));
                            TotalCurrentThrust = TotalCurrentThrust + ME1.GetCurrentThrust();
                        }
                    }
                    //If Module 2 is different from 1 (by engineID) do calculations for Module 2 if it is operational
                    if (ME1.engineID != ME2.engineID)
                    {
                        if (ME2.isOperational == true)
                        {
                            //Jet engines use Atmosphere & Velocity Curves to modify performance at different altitudes/speeds.  Use these calculations for those engines, otherwise use base values from part cfg.
                            if (ME2.useAtmCurve == true && ME2.useVelCurve == true)
                            {
                                //If the Thrust Multiplier from VelCurve * AtmCurve is more than 1, evaluate the curves and determine max thrust for that scenario.  Otherwise, use the base method and assume Max Thrust from cfg file.
                                if ((ME2.velCurve.Evaluate(CurrentMach) * ME2.atmCurve.Evaluate(CurrentAtm)) > 1)
                                {
                                    TotalCapableThrust = TotalCapableThrust + ((ME2.GetMaxThrust() * (ME2.thrustPercentage / 100)) * (ME2.velCurve.Evaluate(CurrentMach)) * (ME2.atmCurve.Evaluate(CurrentAtm)));
                                }
                                else
                                {
                                    TotalCapableThrust = TotalCapableThrust + ((ME2.GetMaxThrust() * (ME2.thrustPercentage / 100)));
                                }
                                TotalCurrentThrust = TotalCurrentThrust + ME2.GetCurrentThrust();
                            }
                            else
                            {
                                TotalCapableThrust = TotalCapableThrust + (ME2.GetMaxThrust() * (ME2.thrustPercentage / 100));
                                TotalCurrentThrust = TotalCurrentThrust + ME2.GetCurrentThrust();
                            }
                        }
                    }
                }
                //ModuleEnginesFX
                //------------------------------------------------------------------------------------------------------------------------------
                if (SingleEngine.Modules.Contains("ModuleEnginesFX"))
                {
                    ModuleEnginesFX MEFX1 = new ModuleEnginesFX();
                    ModuleEnginesFX MEFX2 = new ModuleEnginesFX();
                    MEFX1 = SingleEngine.FindModulesImplementing <ModuleEnginesFX> ().First();
                    MEFX2 = SingleEngine.FindModulesImplementing <ModuleEnginesFX> ().Last();
                    //Do Calculations for Module 1 if it is operational
                    if (MEFX1.isOperational == true)
                    {
                        //Jet engines use Atmosphere & Velocity Curves to modify performance at different altitudes/speeds.  Use these calculations for those engines, otherwise use base values from part cfg.
                        if (MEFX1.useAtmCurve == true && MEFX1.useVelCurve == true)
                        {
                            //If the Thrust Multiplier from VelCurve * AtmCurve is more than 1, evaluate the curves and determine max thrust for that scenario.  Otherwise, use the base method and assume Max Thrust from cfg file.
                            if ((MEFX1.velCurve.Evaluate(CurrentMach) * MEFX1.atmCurve.Evaluate(CurrentAtm)) > 1)
                            {
                                TotalCapableThrust = TotalCapableThrust + ((MEFX1.GetMaxThrust() * (MEFX1.thrustPercentage / 100)) * (MEFX1.velCurve.Evaluate(CurrentMach)) * (MEFX1.atmCurve.Evaluate(CurrentAtm)));
                            }
                            else
                            {
                                TotalCapableThrust = TotalCapableThrust + ((MEFX1.GetMaxThrust() * (MEFX1.thrustPercentage / 100)));
                            }
                            TotalCurrentThrust = TotalCurrentThrust + MEFX1.GetCurrentThrust();
                        }
                        else
                        {
                            TotalCapableThrust = TotalCapableThrust + (MEFX1.GetMaxThrust() * (MEFX1.thrustPercentage / 100));
                            TotalCurrentThrust = TotalCurrentThrust + MEFX1.GetCurrentThrust();
                        }
                    }
                    //If Module 2 is different from 1 (by engineID) do calculations for Module 2 if it is operational
                    if (MEFX1.engineID != MEFX2.engineID)
                    {
                        if (MEFX2.isOperational == true)
                        {
                            //Jet engines use Atmosphere & Velocity Curves to modify performance at different altitudes/speeds.  Use these calculations for those engines, otherwise use base values from part cfg.
                            if (MEFX2.useAtmCurve == true && MEFX2.useVelCurve == true)
                            {
                                //If the Thrust Multiplier from VelCurve * AtmCurve is more than 1, evaluate the curves and determine max thrust for that scenario.  Otherwise, use the base method and assume Max Thrust from cfg file.
                                if ((MEFX2.velCurve.Evaluate(CurrentMach) * MEFX2.atmCurve.Evaluate(CurrentAtm)) > 1)
                                {
                                    TotalCapableThrust = TotalCapableThrust + ((MEFX2.GetMaxThrust() * (MEFX2.thrustPercentage / 100)) * (MEFX2.velCurve.Evaluate(CurrentMach)) * (MEFX2.atmCurve.Evaluate(CurrentAtm)));
                                }
                                else
                                {
                                    TotalCapableThrust = TotalCapableThrust + ((MEFX2.GetMaxThrust() * (MEFX2.thrustPercentage / 100)));
                                }
                                TotalCurrentThrust = TotalCurrentThrust + MEFX2.GetCurrentThrust();
                            }
                            else
                            {
                                TotalCapableThrust = TotalCapableThrust + (MEFX2.GetMaxThrust() * (MEFX2.thrustPercentage / 100));
                                TotalCurrentThrust = TotalCurrentThrust + MEFX2.GetCurrentThrust();
                            }
                        }
                    }
                }
            }
            //Prevent Divide by 0 Errors
            if (TotalCapableThrust == 0)
            {
                TotalCapableThrust = 0.0001f;
            }
            //Not truly a percentage, gauge works between 0 and 1, NOT 0 and 100
            ThrustPercentage = ((TotalCurrentThrust / TotalCapableThrust));

            if (UseSplitNeedle == false)
            {
                //Gently Fade the alpha channel of the stock gauge so we can see TIM if it is near/behind
                if (FlightUIController.fetch.thr.rawValue >= ThrustPercentage)
                {
                    StockGaugeColor.a = Mathf.Max(Mathf.Min(((((FlightUIController.fetch.thr.rawValue - ThrustPercentage) - 0.015f) * 2.3f) + StockGaugeColorAlpha), 1.0f), StockGaugeColorAlpha);
                }
                if (FlightUIController.fetch.thr.rawValue <= ThrustPercentage)
                {
                    StockGaugeColor.a = Mathf.Max(Mathf.Min(((((FlightUIController.fetch.thr.rawValue - ThrustPercentage) + 0.015f) * -2.3f) + StockGaugeColorAlpha), 1.0f), StockGaugeColorAlpha);
                }
                StockGauge.transform.GetChild(0).renderer.material.color = StockGaugeColor;
                TIMGauge.transform.GetChild(0).renderer.material.color   = TIMGaugeColor;
                //Render the StockGauge after TIM so that it shows in front of TIM
                StockGauge.transform.GetChild(0).renderer.material.renderQueue = TIMGauge.transform.GetChild(0).renderer.material.renderQueue + 1;
            }
            //Set Gauge to Calculated Value
            TIMGauge.setValue(ThrustPercentage);
            //Reset Thrust Values Each Compute Cycle
            TotalCapableThrust = 0;
            TotalCurrentThrust = 0;
        }