public override void OnFixedUpdate()
        {
            if (myAttachedEngine.isOperational && myAttachedEngine.currentThrottle > 0 && myAttachedReactor != null)
            {
                if (!myAttachedReactor.isActive())
                {
                    myAttachedReactor.enableIfPossible();
                }
                updateIspEngineParams();
                float  curve_eval_point = (float)Math.Min(FlightGlobals.getStaticPressure(vessel.transform.position), 1.0);
                float  currentIsp       = myAttachedEngine.atmosphereCurve.Evaluate(curve_eval_point);
                double ispratio         = currentIsp / maxISP;
                this.current_isp = currentIsp;
                // scale down thrust if it's attached to the wrong sized reactor
                float heat_exchanger_thrust_divisor = 1;
                if (radius > myAttachedReactor.getRadius())
                {
                    heat_exchanger_thrust_divisor = myAttachedReactor.getRadius() * myAttachedReactor.getRadius() / radius / radius;
                }
                else
                {
                    heat_exchanger_thrust_divisor = radius * radius / myAttachedReactor.getRadius() / myAttachedReactor.getRadius();
                }

                if (myAttachedReactor.getRadius() == 0 || radius == 0)
                {
                    heat_exchanger_thrust_divisor = 1;
                }
                // get the flameout safety limit
                atmospheric_limit = getAtmosphericLimit();
                double thrust_limit = myAttachedEngine.thrustPercentage / 100;
                if (currentpropellant_is_jet)
                {
                    int    pre_coolers_active = vessel.FindPartModulesImplementing <FNModulePreecooler>().Where(prc => prc.isFunctional()).Count();
                    int    intakes_open       = vessel.FindPartModulesImplementing <ModuleResourceIntake>().Where(mre => mre.intakeEnabled).Count();
                    double proportion         = Math.Pow((double)(intakes_open - pre_coolers_active) / (double)intakes_open, 0.1);
                    if (double.IsNaN(proportion) || double.IsInfinity(proportion))
                    {
                        proportion = 1;
                    }
                    part.temperature = (float)Math.Max((Math.Sqrt(vessel.srf_velocity.magnitude) * 20.0 / GameConstants.atmospheric_non_precooled_limit) * part.maxTemp * proportion, 1);
                }
                double thermal_power_received = consumeFNResource(assThermalPower * TimeWarp.fixedDeltaTime * myAttachedEngine.currentThrottle, FNResourceManager.FNRESOURCE_THERMALPOWER) / TimeWarp.fixedDeltaTime;
                consumeFNResource(thermal_power_received * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_WASTEHEAT);
                float  power_ratio     = 0.0f;
                double engineMaxThrust = 0.01;
                if (assThermalPower > 0)
                {
                    power_ratio     = (float)(thermal_power_received / assThermalPower);
                    engineMaxThrust = Math.Max(thrust_limit * 2000.0 * thermal_power_received / maxISP / g0 * heat_exchanger_thrust_divisor * ispratio / myAttachedEngine.currentThrottle, 0.01);
                }
                //print ("B: " + engineMaxThrust);
                // set up TWR limiter if on
                //double additional_thrust_compensator = myAttachedEngine.finalThrust / (myAttachedEngine.maxThrust * myAttachedEngine.currentThrottle);
                double engine_thrust = engineMaxThrust;
                // engine thrust fixed
                //print ("A: " + engine_thrust*myAttachedEngine.velocityCurve.Evaluate((float)vessel.srf_velocity.magnitude));
                if (!double.IsInfinity(engine_thrust) && !double.IsNaN(engine_thrust))
                {
                    if (isLFO)
                    {
                        myAttachedEngine.maxThrust = (float)(2.0 * engine_thrust);
                    }
                    else
                    {
                        myAttachedEngine.maxThrust = (float)engine_thrust;
                    }
                }
                else
                {
                    myAttachedEngine.maxThrust = 0.000001f;
                }

                // amount of fuel being used at max throttle with no atmospheric limits
                if (current_isp > 0)
                {
                    double vcurve_at_current_velocity = 1;
                    if (myAttachedEngine.useVelocityCurve)
                    {
                        vcurve_at_current_velocity = myAttachedEngine.velocityCurve.Evaluate((float)vessel.srf_velocity.magnitude);
                    }
                    fuel_flow_rate = engine_thrust / current_isp / g0 / 0.005 * TimeWarp.fixedDeltaTime;
                    if (vcurve_at_current_velocity > 0)
                    {
                        fuel_flow_rate = fuel_flow_rate / vcurve_at_current_velocity;
                    }
                }
            }
            else
            {
                if (myAttachedEngine.realIsp > 0)
                {
                    atmospheric_limit = getAtmosphericLimit();
                    double vcurve_at_current_velocity = 1;
                    if (myAttachedEngine.useVelocityCurve)
                    {
                        vcurve_at_current_velocity = myAttachedEngine.velocityCurve.Evaluate((float)vessel.srf_velocity.magnitude);
                    }
                    fuel_flow_rate = myAttachedEngine.maxThrust / myAttachedEngine.realIsp / g0 / 0.005 * TimeWarp.fixedDeltaTime / vcurve_at_current_velocity;
                }
                else
                {
                    fuel_flow_rate = 0;
                }

                if (currentpropellant_is_jet)
                {
                    part.temperature = 1;
                }

                if (myAttachedReactor == null && myAttachedEngine.isOperational && myAttachedEngine.currentThrottle > 0)
                {
                    myAttachedEngine.Events ["Shutdown"].Invoke();
                    ScreenMessages.PostScreenMessage("Engine Shutdown: No reactor attached!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                }
            }
            //tell static helper methods we are currently updating things
            static_updating  = true;
            static_updating2 = true;
        }
        public override void OnFixedUpdate()
        {
            activeCount++;
            nuclear_power         = 0;
            solar_power           = 0;
            displayed_solar_power = 0;
            if (IsEnabled && !relay)
            {
                double powerDraw = 0.0;

                try
                {
                    ORSResourceManager manager = getOvermanagerForResource(FNResourceManager.FNRESOURCE_MEGAJOULES).getManagerForVessel(vessel);
                    if (manager != null)
                    {
                        powerDraw = manager.PowerDraws.Where(pm => !(pm.Key is MicrowavePowerTransmitter && (pm.Key as MicrowavePowerTransmitter) == this)).Sum(pm => pm.Value);
                    }
                }
                catch (ArgumentNullException)
                {
                    powerDraw = 0.0;
                }

                foreach (FNGenerator generator in generators)
                {
                    if (generator.isActive())
                    {
                        FNThermalSource thermal_source = generator.getThermalSource();
                        if (thermal_source != null && !thermal_source.isVolatileSource() && thermal_source.isActive())
                        {
                            double output = generator.getMaxPowerOutput();
                            output -= powerDraw / (double)generators.Count(g => g.isActive() && g.getThermalSource().isActive());
                            output  = output * transmitPower / 100.0;
                            double gpower = consumeFNResource(output * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_MEGAJOULES);
                            nuclear_power += gpower * 1000 / TimeWarp.fixedDeltaTime;
                        }
                    }
                }

                foreach (ModuleDeployableSolarPanel panel in panels)
                {
                    double output          = panel.flowRate;
                    double spower          = part.RequestResource("ElectricCharge", output * TimeWarp.fixedDeltaTime);
                    double inv_square_mult = Math.Pow(Vector3d.Distance(FlightGlobals.Bodies[PluginHelper.REF_BODY_KERBIN].transform.position, FlightGlobals.Bodies[PluginHelper.REF_BODY_KERBOL].transform.position), 2) / Math.Pow(Vector3d.Distance(vessel.transform.position, FlightGlobals.Bodies[PluginHelper.REF_BODY_KERBOL].transform.position), 2);
                    displayed_solar_power += spower / TimeWarp.fixedDeltaTime;
                    //scale solar power to what it would be in Kerbin orbit for file storage
                    solar_power += spower / TimeWarp.fixedDeltaTime / inv_square_mult;
                }
            }

            if (double.IsInfinity(nuclear_power) || double.IsNaN(nuclear_power))
            {
                nuclear_power = 0;
            }

            if (double.IsInfinity(solar_power) || double.IsNaN(solar_power))
            {
                solar_power = 0;
            }

            if (activeCount % 1000 == 9)
            {
                ConfigNode config   = PluginHelper.getPluginSaveFile();
                string     vesselID = vessel.id.ToString();
                if (config.HasNode("VESSEL_MICROWAVE_POWER_" + vesselID))
                {
                    ConfigNode power_node = config.GetNode("VESSEL_MICROWAVE_POWER_" + vesselID);
                    if (power_node.HasValue("nuclear_power"))
                    {
                        power_node.SetValue("nuclear_power", MicrowavePowerTransmitter.getEnumeratedNuclearPowerForVessel(vessel).ToString("E"));
                    }
                    else
                    {
                        power_node.AddValue("nuclear_power", MicrowavePowerTransmitter.getEnumeratedNuclearPowerForVessel(vessel).ToString("E"));
                    }
                    if (power_node.HasValue("solar_power"))
                    {
                        power_node.SetValue("solar_power", MicrowavePowerTransmitter.getEnumeratedSolarPowerForVessel(vessel).ToString("E"));
                    }
                    else
                    {
                        power_node.AddValue("solar_power", MicrowavePowerTransmitter.getEnumeratedSolarPowerForVessel(vessel).ToString("E"));
                    }
                }
                else
                {
                    ConfigNode power_node = config.AddNode("VESSEL_MICROWAVE_POWER_" + vesselID);
                    power_node.AddValue("nuclear_power", MicrowavePowerTransmitter.getEnumeratedNuclearPowerForVessel(vessel).ToString("E"));
                    power_node.AddValue("solar_power", MicrowavePowerTransmitter.getEnumeratedSolarPowerForVessel(vessel).ToString("E"));
                }

                if (config.HasNode("VESSEL_MICROWAVE_RELAY_" + vesselID))
                {
                    ConfigNode relay_node = config.GetNode("VESSEL_MICROWAVE_RELAY_" + vesselID);
                    if (relay_node.HasValue("relay"))
                    {
                        relay_node.SetValue("relay", MicrowavePowerTransmitter.vesselIsRelay(vessel).ToString());
                    }
                    else
                    {
                        relay_node.AddValue("relay", MicrowavePowerTransmitter.vesselIsRelay(vessel).ToString());
                    }
                }
                else
                {
                    ConfigNode relay_node = config.AddNode("VESSEL_MICROWAVE_RELAY_" + vesselID);
                    relay_node.AddValue("relay", MicrowavePowerTransmitter.vesselIsRelay(vessel).ToString());
                }

                config.Save(PluginHelper.getPluginSaveFilePath());
            }
            activeCount++;
        }