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++; }