public override void OnFixedUpdate() { if (scoopIsEnabled) { string atmospheric_resource_name = ORSAtmosphericResourceHandler.getAtmosphericResourceName(vessel.mainBody.flightGlobalsIndex, currentresource); if (atmospheric_resource_name != null) { double resourcedensity = PartResourceLibrary.Instance.GetDefinition(atmospheric_resource_name).density; double respcent = ORSAtmosphericResourceHandler.getAtmosphericResourceContent(vessel.mainBody.flightGlobalsIndex, currentresource); //double resourcedensity = PartResourceLibrary.Instance.GetDefinition(PluginHelper.atomspheric_resources_tocollect[currentresource]).density; //double respcent = PluginHelper.getAtmosphereResourceContent(vessel.mainBody.flightGlobalsIndex, currentresource); double airdensity = part.vessel.atmDensity / 1000; double powerrequirements = scoopair / 0.15f * 6f; double airspeed = part.vessel.srf_velocity.magnitude + 40.0; double air = airspeed * airdensity * scoopair / resourcedensity; if (respcent > 0 && vessel.altitude <= PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody)) { double scoopedAtm = air * respcent; float powerreceived = Math.Max(consumeFNResource(powerrequirements * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_MEGAJOULES), 0); float powerpcnt = (float)(powerreceived / powerrequirements / TimeWarp.fixedDeltaTime); //resflowf = (float)part.RequestResource(atmospheric_resource_name, -scoopedAtm * powerpcnt * TimeWarp.fixedDeltaTime); resflowf = (float)ORSHelper.fixedRequestResource(part, atmospheric_resource_name, -scoopedAtm * powerpcnt * TimeWarp.fixedDeltaTime); resflowf = -resflowf / TimeWarp.fixedDeltaTime; } } else { } } }
public static double getRadiationLevel(int refBody, double altitude, double lat) { lat = lat / 180 * Math.PI; CelestialBody crefbody = FlightGlobals.fetch.bodies[refBody]; CelestialBody crefkerbin = FlightGlobals.fetch.bodies[1]; double atmosphere = FlightGlobals.getStaticPressure(altitude, crefbody); double atmosphere_height = PluginHelper.getMaxAtmosphericAltitude(crefbody); double atmosphere_scaling = Math.Exp(-atmosphere); double mp = crefbody.Mass; double rp = crefbody.Radius; double rt = crefbody.rotationPeriod; double relmp = mp / crefkerbin.Mass; double relrp = rp / crefkerbin.Radius; double relrt = rt / crefkerbin.rotationPeriod; double peakbelt = 1.5 * crefkerbin.Radius * relrp; double peakbelt2 = 6 * crefkerbin.Radius * relrp; double altituded = altitude; double a = peakbelt / Math.Sqrt(2); double b = peakbelt2 / Math.Sqrt(2); double beltparticles = Math.Sqrt(2 / Math.PI) * Math.Pow(altituded, 2) * Math.Exp(-Math.Pow(altituded, 2) / (2.0 * Math.Pow(a, 2))) / (Math.Pow(a, 3)) + 0.9 * Math.Sqrt(2 / Math.PI) * Math.Pow(altituded, 2) * Math.Exp(-Math.Pow(altituded, 2) / (2.0 * Math.Pow(b, 2))) / (Math.Pow(b, 3)); beltparticles = beltparticles * relrp / relrt * 50.0; if (crefbody.flightGlobalsIndex == 0) { beltparticles = beltparticles / 1000; } beltparticles = beltparticles * Math.Abs(Math.Cos(lat)) * getSpecialMagneticFieldScaling(refBody) * atmosphere_scaling; return(beltparticles); }
protected override void pluginSpecificImpl() { if (resource_name == FNRESOURCE_CHARGED_PARTICLES) { flow_type = FNRESOURCE_FLOWTYPE_EVEN; } if (String.Equals(this.resource_name, FNResourceManager.FNRESOURCE_WASTEHEAT)) // passive dissip of waste heat - a little bit of this { double vessel_mass = my_vessel.GetTotalMass(); double passive_dissip = passive_temp_p4 * GameConstants.stefan_const * vessel_mass * 2.0; internl_power_extract += passive_dissip * TimeWarp.fixedDeltaTime; if (my_vessel.altitude <= PluginHelper.getMaxAtmosphericAltitude(my_vessel.mainBody)) // passive convection - a lot of this { double pressure = FlightGlobals.getStaticPressure(my_vessel.transform.position); double delta_temp = 20; double conv_power_dissip = pressure * delta_temp * vessel_mass * 2.0 * GameConstants.rad_const_h / 1e6 * TimeWarp.fixedDeltaTime; internl_power_extract += conv_power_dissip; } if (internl_power_extract < 0 && PluginHelper.isThermalDissipationDisabled()) // set buildup/dissip of waste heat to 0 if waste heat is disabled { internl_power_extract = 0; } } }
public override void OnFixedUpdate() { if (FlightGlobals.fetch != null) { if (!bIsEnabled) { strCollectingStatus = "Disabled"; strStarDist = UpdateDistanceInGUI(); // passes the distance to the GUI return; } if (vessel.altitude < (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody))) // won't collect in atmosphere { ScreenMessages.PostScreenMessage("Solar wind collection not possible in atmosphere", 10.0f, ScreenMessageStyle.LOWER_CENTER); strStarDist = UpdateDistanceInGUI(); strSolarWindConc = "0"; DisableCollector(); return; } strStarDist = UpdateDistanceInGUI(); // collect solar wind for a single frame CollectSolarWind(TimeWarp.fixedDeltaTime, false); // store current time in case vesel is unloaded fLastActiveTime = (float)Planetarium.GetUniversalTime(); } }
public static double GetBeltAntiparticles(this CelestialBody body, double altitude, double lat) { lat = (lat / 180 * Math.PI); CelestialBody crefkerbin = FlightGlobals.fetch.bodies[PluginHelper.REF_BODY_KERBIN]; double atmosphere_height = PluginHelper.getMaxAtmosphericAltitude(body); if (altitude <= atmosphere_height && body.flightGlobalsIndex != 0) { return(0); } double mp = body.Mass; double rp = body.Radius; double rt = body.rotationPeriod; double relmp = mp / crefkerbin.Mass; double relrp = rp / crefkerbin.Radius; double relrt = rt / crefkerbin.rotationPeriod; double peakbelt = 1.5 * crefkerbin.Radius * relrp; double altituded = ((double)altitude); double a = peakbelt / Math.Sqrt(2); double beltparticles = Math.Sqrt(2 / Math.PI) * Math.Pow(altituded, 2) * Math.Exp(-Math.Pow(altituded, 2) / (2.0 * Math.Pow(a, 2))) / (Math.Pow(a, 3)); beltparticles = beltparticles * relmp * relrp / relrt * 50.0; if (body.flightGlobalsIndex == 0) { beltparticles = beltparticles / 1000; } beltparticles = beltparticles * Math.Abs(Math.Cos(lat)) * body.specialMagneticFieldScaling(); return(beltparticles); }
public static double GetProtonRadiationLevel(this CelestialBody body, CelestialBody homeworld, double altitude, double lat) { lat = lat / 180 * Math.PI; double atmosphere = FlightGlobals.getStaticPressure(altitude, body) / 100; double atmosphere_height = PluginHelper.getMaxAtmosphericAltitude(body); double atmosphere_scaling = Math.Exp(-atmosphere); double mp = body.Mass; double rp = body.Radius; double rt = body.rotationPeriod; double relrp = rp / homeworld.Radius; double relrt = rt / homeworld.rotationPeriod; double peakbelt = body.GetPeakProtonBeltAltitude(homeworld, altitude, lat); double altituded = altitude; double a = peakbelt / Math.Sqrt(2); double beltparticles = Math.Sqrt(2 / Math.PI) * Math.Pow(altituded, 2) * Math.Exp(-Math.Pow(altituded, 2) / (2 * Math.Pow(a, 2))) / (Math.Pow(a, 3)); beltparticles = beltparticles * relrp / relrt * 50; if (body.flightGlobalsIndex == 0) { beltparticles = beltparticles / 1000; } beltparticles = beltparticles * Math.Abs(Math.Cos(lat)) * body.specialMagneticFieldScaling() * atmosphere_scaling; return(beltparticles); }
public static double GetElectronRadiationLevel(this CelestialBody body, double altitude, double lat) { lat = lat / 180 * Math.PI; CelestialBody crefkerbin = FlightGlobals.fetch.bodies[PluginHelper.REF_BODY_KERBIN]; double atmosphere = FlightGlobals.getStaticPressure(altitude, body) / 100; double atmosphere_height = PluginHelper.getMaxAtmosphericAltitude(body); double atmosphere_scaling = Math.Exp(-atmosphere); double mp = body.Mass; double rp = body.Radius; double rt = body.rotationPeriod; double relrp = rp / crefkerbin.Radius; double relrt = rt / crefkerbin.rotationPeriod; double peakbelt2 = body.GetPeakElectronBeltAltitude(altitude, lat); double altituded = altitude; double b = peakbelt2 / Math.Sqrt(2); double beltparticles = 0.9 * Math.Sqrt(2 / Math.PI) * Math.Pow(altituded, 2) * Math.Exp(-Math.Pow(altituded, 2) / (2.0 * Math.Pow(b, 2))) / (Math.Pow(b, 3)); beltparticles = beltparticles * relrp / relrt * 50.0; if (body.flightGlobalsIndex == 0) { beltparticles = beltparticles / 1000; } beltparticles = beltparticles * Math.Abs(Math.Cos(lat)) * body.specialMagneticFieldScaling() * atmosphere_scaling; return(beltparticles); }
public override void OnUpdate() { Events["ActivateCollector"].active = !bIsEnabled; // will activate the event (i.e. show the gui button) if the process is not enabled Events["DisableCollector"].active = bIsEnabled; // will show the button when the process IS enabled Fields["strReceivedPower"].guiActive = bIsEnabled; solarWindMolesPerSquareMeterPerSecond = CalculateSolarwindIonConcentration(part.vessel.solarFlux, solarCheatMultiplier, solarWindSpeed); interstellarDustMolesPerCubicMeter = CalculateInterstellarIonConcentration(interstellarCheatMultiplier); var dAtmosphereConcentration = CalculateCurrentAtmosphereConcentration(vessel); var dHydrogenParticleConcentration = CalculateCurrentHydrogenParticleConcentration(vessel); var dHeliumParticleConcentration = CalculateCurrentHeliumParticleConcentration(vessel); var dIonizedHydrogenConcentration = CalculateCurrentHydrogenIonsConcentration(vessel); var dIonizedHeliumConcentration = CalculateCurrentHeliumIonsConcentration(vessel); hydrogenMolarMassConcentrationPerSquareMeterPerSecond = bIonizing ? dHydrogenParticleConcentration : dIonizedHydrogenConcentration; heliumMolarMassConcentrationPerSquareMeterPerSecond = bIonizing ? dHeliumParticleConcentration: dIonizedHeliumConcentration; fSolarWindConcentrationPerSquareMeter = (float)solarWindMolesPerSquareMeterPerSecond; fInterstellarIonsConcentrationPerCubicMeter = (float)interstellarDustMolesPerCubicMeter; fAtmosphereConcentration = (float)dAtmosphereConcentration; fNeutralHydrogenConcentration = (float)dHydrogenParticleConcentration; fNeutralHeliumConcentration = (float)dHeliumParticleConcentration; fIonizedHydrogenConcentration = (float)dIonizedHydrogenConcentration; fIonizedHeliumConcentration = (float)dIonizedHeliumConcentration; magnetoSphereStrengthRatio = GetMagnetosphereRatio(vessel.altitude, PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody)); strMagnetoStrength = UpdateMagnetoStrengthInGui(); }
private void Window(int windowID) { bold_label = new GUIStyle(GUI.skin.label); bold_label.fontStyle = FontStyle.Bold; if (GUI.Button(new Rect(windowPosition.width - 20, 2, 18, 18), "x")) { render_window = false; } GUILayout.BeginVertical(); if (vessel.altitude < PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody)) { if (analysis_count > analysis_length) { GUILayout.BeginHorizontal(); GUILayout.Label("Gas", bold_label, GUILayout.Width(150)); GUILayout.Label("Abundance", bold_label, GUILayout.Width(150)); GUILayout.EndHorizontal(); GUILayout.Space(5); foreach (AtmosphericResource atmospheric_resource in AtmosphericResourceHandler.GetAtmosphericCompositionForBody(vessel.mainBody.flightGlobalsIndex).Values) { GUILayout.BeginHorizontal(); GUILayout.Label(atmospheric_resource.DisplayName, GUILayout.Width(150)); string resource_abundance_str; if (atmospheric_resource.ResourceAbundance > 0.001) { resource_abundance_str = (atmospheric_resource.ResourceAbundance * 100.0).ToString() + "%"; } else { if (atmospheric_resource.ResourceAbundance > 0.000001) { resource_abundance_str = (atmospheric_resource.ResourceAbundance * 1e6).ToString() + " ppm"; } else { resource_abundance_str = (atmospheric_resource.ResourceAbundance * 1e9).ToString() + " ppb"; } } GUILayout.Label(resource_abundance_str, GUILayout.Width(150)); GUILayout.EndHorizontal(); } } else { double percent_analysed = (double)analysis_count / analysis_length * 100; GUILayout.BeginHorizontal(); GUILayout.Label("Analysing...", GUILayout.Width(150)); GUILayout.Label(percent_analysed.ToString("0.00") + "%", GUILayout.Width(150)); GUILayout.EndHorizontal(); } } else { GUILayout.Label("--No Atmosphere to Sample--", GUILayout.ExpandWidth(true)); analysis_count = 0; } GUILayout.EndVertical(); GUI.DragWindow(); }
public override void OnFixedUpdate() { if (FlightGlobals.fetch != null) { if (!bIsEnabled) { strCollectingStatus = "Disabled"; strStarDist = UpdateDistanceInGUI(); // passes the distance to the GUI return; } // won't collect in atmosphere if (IsCollectLegal() == false) { DisableCollector(); return; } strStarDist = UpdateDistanceInGUI(); // collect solar wind for a single frame CollectSolarWind(TimeWarp.fixedDeltaTime, false); // store current time in case vesel is unloaded dLastActiveTime = Planetarium.GetUniversalTime(); // store current strength of the magnetic field in case vessel is unloaded dLastMagnetoStrength = GetMagnetosphereRatio(vessel.altitude, PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody)); // store current solar wind concentration in case vessel is unloaded dLastSolarConcentration = CalculateSolarWindConcentration(part.vessel.solarFlux); } }
public override void OnStart(PartModule.StartState state) { if (state == StartState.Editor) { return; // collecting won't work in editor } this.part.force_activate(); localStar = GetCurrentStar(); // get the part's animation anim = part.FindModelAnimators(animName).FirstOrDefault(); // this bit goes through parts that contain animations and disables the "Status" field in GUI so that it's less crowded List <ModuleAnimateGeneric> MAGlist = part.FindModulesImplementing <ModuleAnimateGeneric>(); foreach (ModuleAnimateGeneric MAG in MAGlist) { MAG.Fields["status"].guiActive = false; MAG.Fields["status"].guiActiveEditor = false; } // verify collector was enabled if (!bIsEnabled) { return; } // verify a timestamp is available if (dLastActiveTime == 0) { return; } // verify any power was available in previous state if (dLastPowerPercentage < 0.01) { return; } // verify altitude is not too low if (vessel.altitude < (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody))) { ScreenMessages.PostScreenMessage("Solar Wind Collection Error, vessel in atmosphere", 10, ScreenMessageStyle.LOWER_CENTER); return; } // if the part should be extended (from last time), go to the extended animation if (bIsExtended == true && anim != null) { anim[animName].normalizedTime = 1; } // calculate time difference since last time the vessel was active double dTimeDifference = (Planetarium.GetUniversalTime() - dLastActiveTime) * 55; // collect solar wind for entire duration CollectSolarWind(dTimeDifference, true); }
public static bool IsInAtmosphere(this Vessel vessel) { if (vessel.altitude <= PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody)) { return(true); } return(false); }
public void FixedUpdate() { if (HighLogic.LoadedSceneIsFlight) { ElectricEngineControllerFX.getAllPropellants().ForEach(prop => part.Effect(prop.ParticleFXName, 0)); // set all FX to zero if (current_propellant != null && attachedEngine != null) { updateISP(); List <ElectricEngineControllerFX> electric_engine_list = vessel.FindPartModulesImplementing <ElectricEngineControllerFX>(); int engine_count = electric_engine_list.Count; double total_max_thrust = evaluateMaxThrust(); double thrust_per_engine = total_max_thrust / (double)engine_count; double power_per_engine = Math.Min(0.5 * attachedEngine.currentThrottle * thrust_per_engine * current_propellant.IspMultiplier * baseISP / 1000.0 * 9.81, maxPower * current_propellant.Efficiency); double power_received = consumeFNResource(power_per_engine * TimeWarp.fixedDeltaTime / current_propellant.Efficiency, FNResourceManager.FNRESOURCE_MEGAJOULES) / TimeWarp.fixedDeltaTime; double heat_to_produce = power_received * (1.0 - current_propellant.Efficiency); double heat_production = supplyFNResource(heat_to_produce * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_WASTEHEAT) / TimeWarp.fixedDeltaTime; // update GUI Values electrical_consumption_f = (float)power_received; heat_production_f = (float)heat_production; // thrust values double thrust_ratio = power_per_engine > 0 ? Math.Min(power_received / power_per_engine, 1.0) : 1; double actual_max_thrust = current_propellant.Efficiency * 2000.0f * power_received / (current_propellant.IspMultiplier * baseISP * 9.81f * attachedEngine.currentThrottle); if (attachedEngine.currentThrottle > 0) { if (!double.IsNaN(actual_max_thrust) && !double.IsInfinity(actual_max_thrust)) { attachedEngine.maxThrust = Mathf.Max((float)actual_max_thrust, 0.00001f); } else { attachedEngine.maxThrust = 0.00001f; } float fx_ratio = Mathf.Min(electrical_consumption_f / maxPower, attachedEngine.finalThrust / attachedEngine.maxThrust); part.Effect(current_propellant.ParticleFXName, fx_ratio); } if (isupgraded) { List <PartResource> vacuum_resources = part.GetConnectedResources("VacuumPlasma").ToList(); double vacuum_plasma_needed = vacuum_resources.Sum(vc => vc.maxAmount - vc.amount); double vacuum_plasma_current = vacuum_resources.Sum(vc => vc.amount); if (vessel.altitude < PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody)) { part.RequestResource("VacuumPlasma", vacuum_plasma_current); } else { part.RequestResource("VacuumPlasma", -vacuum_plasma_needed); } } } } }
public void ActivateWarpDrive() { if (IsEnabled) { return; } Vessel vess = this.part.vessel; //float atmosphere_height = vess.mainBody.maxAtmosphereAltitude; if (vess.altitude <= PluginHelper.getMaxAtmosphericAltitude(vess.mainBody) && vess.mainBody.flightGlobalsIndex != 0) { ScreenMessages.PostScreenMessage("Cannot activate warp drive within the atmosphere!", 5.0f, ScreenMessageStyle.UPPER_CENTER); return; } var resources = new List <PartResource>(); part.GetConnectedResources(PartResourceLibrary.Instance.GetDefinition("ExoticMatter").id, resources); float electrical_current_available = 0; for (int i = 0; i < resources.Count; ++i) { electrical_current_available += (float)resources.ElementAt(i).amount; } if (electrical_current_available < megajoules_required * warp_factors[selected_factor]) { ScreenMessages.PostScreenMessage("Warp drive charging!", 5.0f, ScreenMessageStyle.UPPER_CENTER); return; } part.RequestResource("ExoticMatter", megajoules_required * warp_factors[selected_factor]); warp_sound.Play(); warp_sound.loop = true; //Orbit planetOrbit = vessel.orbit.referenceBody.orbit; Vector3d heading = part.transform.up; double temp1 = heading.y; heading.y = heading.z; heading.z = temp1; Vector3d position = vessel.orbit.pos; heading = heading * GameConstants.warpspeed * warp_factors[selected_factor]; heading_act = heading; serialisedwarpvector = ConfigNode.WriteVector(heading); vessel.GoOnRails(); vessel.orbit.UpdateFromStateVectors(position, vessel.orbit.vel + heading, vessel.orbit.referenceBody, Planetarium.GetUniversalTime()); vessel.GoOffRails(); IsEnabled = true; }
public void ActivateWarpDrive() { if (IsEnabled) { return; } isDeactivatingWarpDrive = false; Vessel vess = this.part.vessel; //float atmosphere_height = vess.mainBody.maxAtmosphereAltitude; if (vess.altitude <= PluginHelper.getMaxAtmosphericAltitude(vess.mainBody) && vess.mainBody.flightGlobalsIndex != 0) { ScreenMessages.PostScreenMessage("Cannot activate warp drive within the atmosphere!", 5.0f, ScreenMessageStyle.UPPER_CENTER); return; } List <PartResource> resources = part.GetConnectedResources(InterstellarResourcesConfiguration.Instance.ExoticMatter).ToList(); float exotic_matter_available = (float)resources.Sum(res => res.amount); var powerRequiredForWarp = megajoules_required * warp_factors[selected_factor]; if (exotic_matter_available < powerRequiredForWarp) { ScreenMessages.PostScreenMessage("Warp drive isn't fully charged yet for Warp!", 5.0f, ScreenMessageStyle.UPPER_CENTER); return; } var totalConsumedPower = PluginHelper.LimitedWarpTravel ? (0.5 * powerRequiredForWarp) + (exotic_matter_available - powerRequiredForWarp) : powerRequiredForWarp; part.RequestResource(InterstellarResourcesConfiguration.Instance.ExoticMatter, totalConsumedPower); warp_sound.Play(); warp_sound.loop = true; //Orbit planetOrbit = vessel.orbit.referenceBody.orbit; Vector3d heading = part.transform.up; double temp1 = heading.y; heading.y = heading.z; heading.z = temp1; Vector3d position = vessel.orbit.pos; heading = heading * GameConstants.warpspeed * warp_factors[selected_factor]; heading_act = heading; serialisedwarpvector = ConfigNode.WriteVector(heading); vessel.GoOnRails(); vessel.orbit.UpdateFromStateVectors(position, vessel.orbit.vel + heading, vessel.orbit.referenceBody, Planetarium.GetUniversalTime()); vessel.GoOffRails(); IsEnabled = true; }
public void ActivateWarpDrive() { if (IsEnabled) { return; } isDeactivatingWarpDrive = false; if (warpToMassRatio < 1) { ScreenMessages.PostScreenMessage("Not enough warp power to warp vessel", 5.0f, ScreenMessageStyle.UPPER_CENTER); return; } Vessel vess = this.part.vessel; if (vess.altitude <= PluginHelper.getMaxAtmosphericAltitude(vess.mainBody) && vess.mainBody.flightGlobalsIndex != 0) { ScreenMessages.PostScreenMessage("Cannot activate warp drive within the atmosphere!", 5.0f, ScreenMessageStyle.UPPER_CENTER); return; } double exotic_matter_available; double total_exotic_matter_available; part.GetConnectedResourceTotals(exoticResourceDefinition.id, out exotic_matter_available, out total_exotic_matter_available); if (exotic_matter_available < exotic_power_required) { ScreenMessages.PostScreenMessage("Warp drive isn't fully charged yet for Warp!", 5.0f, ScreenMessageStyle.UPPER_CENTER); return; } if (maximumWarpSpeedFactor < selected_factor) { selected_factor = minimumPowerAllowedFactor; } float new_warpfactor = engine_throtle[selected_factor]; currentPowerRequirementForWarp = GetPowerRequirementForWarp(new_warpfactor); if (!CheatOptions.InfiniteElectricity && currentPowerRequirementForWarp > getStableResourceSupply(FNResourceManager.FNRESOURCE_MEGAJOULES)) { ScreenMessages.PostScreenMessage("Warp power requirement is higher that maximum power supply!", 5.0f, ScreenMessageStyle.UPPER_CENTER); return; } IsCharging = false; initiateWarpTimeout = 10; }
public override void OnUpdate() { Events["ActivateCollector"].active = !bIsEnabled; // will activate the event (i.e. show the gui button) if the process is not enabled Events["DisableCollector"].active = bIsEnabled; // will show the button when the process IS enabled Fields["strReceivedPower"].guiActive = bIsEnabled; massConcentrationPerSquareMeterPerSecond = CalculateSolarWindConcentration(part.vessel.solarFlux); solarWindConcentration = (float)massConcentrationPerSquareMeterPerSecond; dMagnetoSphereStrengthRatio = GetMagnetosphereRatio(vessel.altitude, PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody)); strMagnetoStrength = UpdateMagnetoStrengthInGUI(); }
// checks if the vessel is not in atmosphere and if it can therefore collect solar wind. Could incorporate other checks if needed. private bool IsCollectLegal() { if (vessel.altitude < (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody)) / 2) // won't collect in atmosphere { ScreenMessages.PostScreenMessage("Solar wind collection not possible in low atmosphere", 10, ScreenMessageStyle.LOWER_CENTER); distanceToLocalStar = UpdateDistanceInGui(); fSolarWindConcentrationPerSquareMeter = 0; return(false); } else { return(true); } }
public void ActivateWarpDrive() { if (IsEnabled) { return; } isDeactivatingWarpDrive = false; if (warpToMassRatio < 1) { ScreenMessages.PostScreenMessage("Not enough warp power to warp vessel", 5.0f, ScreenMessageStyle.UPPER_CENTER); return; } Vessel vess = this.part.vessel; if (vess.altitude <= PluginHelper.getMaxAtmosphericAltitude(vess.mainBody) && vess.mainBody.flightGlobalsIndex != 0) { ScreenMessages.PostScreenMessage("Cannot activate warp drive within the atmosphere!", 5.0f, ScreenMessageStyle.UPPER_CENTER); return; } List <PartResource> resources = part.GetConnectedResources(InterstellarResourcesConfiguration.Instance.ExoticMatter).ToList(); float exotic_matter_available = (float)resources.Sum(res => res.amount); if (exotic_matter_available < exotic_power_required) { ScreenMessages.PostScreenMessage("Warp drive isn't fully charged yet for Warp!", 5.0f, ScreenMessageStyle.UPPER_CENTER); return; } if (maximumWarpSpeedFactor < selected_factor) { selected_factor = minimumPowerAllowedFactor; } float new_warpfactor = engine_throtle[selected_factor]; currentPowerRequirementForWarp = GetPowerRequirementForWarp(new_warpfactor); if (currentPowerRequirementForWarp > getStableResourceSupply(FNResourceManager.FNRESOURCE_MEGAJOULES)) { ScreenMessages.PostScreenMessage("Warp power requirement is higher that maximum power supply!", 5.0f, ScreenMessageStyle.UPPER_CENTER); return; } IsCharging = false; initiateWarpTimeout = 10; }
// checks if the vessel is not in atmosphere and if it can therefore collect solar wind. Could incorporate other checks if needed. private bool IsCollectLegal() { bool bCanCollect = false; if (vessel.altitude < (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody))) // won't collect in atmosphere { ScreenMessages.PostScreenMessage("Solar wind collection not possible in atmosphere", 10, ScreenMessageStyle.LOWER_CENTER); strStarDist = UpdateDistanceInGUI(); solarWindConcentration = 0; return(bCanCollect); } else { return(bCanCollect = true); } }
private void ScoopAthmosphere(double deltaTimeInSeconds, bool offlineCollecting) { string atmospheric_resource_name = ORSAtmosphericResourceHandler.getAtmosphericResourceName(vessel.mainBody.flightGlobalsIndex, currentresource); if (atmospheric_resource_name == null) { resflowf = 0.0f; return; } double resourcedensity = PartResourceLibrary.Instance.GetDefinition(atmospheric_resource_name).density; double respcent = ORSAtmosphericResourceHandler.getAtmosphericResourceContent(vessel.mainBody.flightGlobalsIndex, currentresource); //double resourcedensity = PartResourceLibrary.Instance.GetDefinition(PluginHelper.atomspheric_resources_tocollect[currentresource]).density; //double respcent = PluginHelper.getAtmosphereResourceContent(vessel.mainBody.flightGlobalsIndex, currentresource); double airdensity = (part.vessel.atmDensity + PluginHelper.MinAtmosphericAirDensity) / 1000.0; double powerrequirements = (scoopair / 0.15f) * 6f * (float)PluginHelper.PowerConsumptionMultiplier; double airspeed = part.vessel.srf_velocity.magnitude + 40.0; double air = airspeed * airdensity * scoopair / resourcedensity; if (respcent == 0 || vessel.altitude > (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody) * PluginHelper.MaxAtmosphericAltitudeMult)) { resflowf = 0.0f; return; } double scoopedAtm = air * respcent; float powerreceived = Math.Max(consumeFNResource(powerrequirements * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_MEGAJOULES), 0); last_power_percentage = offlineCollecting ? last_power_percentage : (float)(powerreceived / powerrequirements / TimeWarp.fixedDeltaTime); double resourceChange = scoopedAtm * last_power_percentage * deltaTimeInSeconds; if (offlineCollecting) { string numberformat = resourceChange > 100 ? "0" : "0.00"; ScreenMessages.PostScreenMessage("Atmospheric Scoop collected " + resourceChange.ToString(numberformat) + " " + atmospheric_resource_name, 10.0f, ScreenMessageStyle.LOWER_CENTER); } //resflowf = (float)part.RequestResource(atmospheric_resource_name, -scoopedAtm * powerpcnt * TimeWarp.fixedDeltaTime); resflowf = (float)ORSHelper.fixedRequestResource(part, atmospheric_resource_name, -resourceChange); resflowf = -resflowf / TimeWarp.fixedDeltaTime; }
protected override void pluginSpecificImpl() { if (String.Equals(this.resource_name, FNResourceManager.FNRESOURCE_WASTEHEAT) && !PluginHelper.IsThermalDissipationDisabled) { // passive dissip of waste heat - a little bit of this double vessel_mass = my_vessel.GetTotalMass(); double passive_dissip = passive_temp_p4 * GameConstants.stefan_const * vessel_mass * 2; internl_power_extract_fixed += passive_dissip * TimeWarp.fixedDeltaTime; if (my_vessel.altitude <= PluginHelper.getMaxAtmosphericAltitude(my_vessel.mainBody)) { // passive convection - a lot of this double pressure = FlightGlobals.getStaticPressure(my_vessel.transform.position) / 100; double delta_temp = 20; double conv_power_dissip = pressure * delta_temp * vessel_mass * 2.0 * GameConstants.rad_const_h / 1e6 * TimeWarp.fixedDeltaTime; internl_power_extract_fixed += conv_power_dissip; } } }
public void FixedUpdate() { if (!HighLogic.LoadedSceneIsFlight) { return; } UpdateIonisationAnimation(); if (FlightGlobals.fetch != null) { if (!bIsEnabled) { strCollectingStatus = "Disabled"; distanceToLocalStar = UpdateDistanceInGui(); // passes the distance to the GUI return; } // won't collect in atmosphere if (!IsCollectLegal()) { DisableCollector(); return; } distanceToLocalStar = UpdateDistanceInGui(); // collect solar wind for a single frame CollectSolarWind(TimeWarp.fixedDeltaTime, false); // store current time in case vesel is unloaded dLastActiveTime = Planetarium.GetUniversalTime(); // store current strength of the magnetic field in case vessel is unloaded dLastMagnetoStrength = GetMagnetosphereRatio(vessel.altitude, PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody)); // store current solar wind concentration in case vessel is unloaded dLastSolarConcentration = solarWindMolesPerSquareMeterPerSecond; //CalculateSolarWindConcentration(part.vessel.solarFlux); dLastHydrogenConcentration = hydrogenMolarMassConcentrationPerSquareMeterPerSecond; } }
public override void OnStart(PartModule.StartState state) { if (state == StartState.Editor) { return; // collecting won't work in editor } this.part.force_activate(); localStar = GetCurrentStar(); // verify collector was enabled if (!bIsEnabled) { return; } // verify a timestamp is available if (fLastActiveTime == 0) { return; } // verify any power was available in previous state if (fLastPowerPercentage < 0.01) { return; } // verify altitude is not too low if (vessel.altitude < (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody))) { ScreenMessages.PostScreenMessage("Error, vessel is in atmosphere", 10.0f, ScreenMessageStyle.LOWER_CENTER); return; } // calculate time difference since last time the vessel was active double dTimeDifference = (Planetarium.GetUniversalTime() - fLastActiveTime) * 55; // collect solar wind for entire duration CollectSolarWind(dTimeDifference, true); }
public override void OnUpdate() { Events["ActivateCollector"].active = !bIsEnabled; // will activate the event (i.e. show the gui button) if the process is not enabled Events["DisableCollector"].active = bIsEnabled; // will show the button when the process IS enabled Fields["strReceivedPower"].guiActive = bIsEnabled; UpdateIonisationAnimation(); var dSolarWindConcentration = CalculateSolarwindIonConcentration(part.vessel.solarFlux, solarCheatMultiplier); solarWindCollected = (float)dSolarWindConcentration; orbitalSpeed = part.vessel.obt_speed; var dInterstellarHydrogenConcentration = CalculateInterstellarIonConcentration(orbitalSpeed, interstellarCheatMultiplier); interstellarHydrogenCollected = (float)dInterstellarHydrogenConcentration; molarMassConcentrationPerSquareMeterPerSecond = dSolarWindConcentration + dInterstellarHydrogenConcentration; dMagnetoSphereStrengthRatio = GetMagnetosphereRatio(vessel.altitude, PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody)); strMagnetoStrength = UpdateMagnetoStrengthInGUI(); }
public static float getBeltAntiparticles(int refBody, float altitude, float lat) { lat = (float)(lat / 180 * Math.PI); CelestialBody crefbody = FlightGlobals.fetch.bodies[refBody]; CelestialBody crefkerbin = FlightGlobals.fetch.bodies[1]; double atmosphere_height = PluginHelper.getMaxAtmosphericAltitude(crefbody); if (altitude <= atmosphere_height && crefbody.flightGlobalsIndex != 0) { return(0); } double mp = crefbody.Mass; double rp = crefbody.Radius; double rt = crefbody.rotationPeriod; double relmp = mp / crefkerbin.Mass; double relrp = rp / crefkerbin.Radius; double relrt = rt / crefkerbin.rotationPeriod; double peakbelt = 1.5 * crefkerbin.Radius * relrp; double altituded = ((double)altitude); double a = peakbelt / Math.Sqrt(2); double beltparticles = Math.Sqrt(2 / Math.PI) * Math.Pow(altituded, 2) * Math.Exp(-Math.Pow(altituded, 2) / (2.0 * Math.Pow(a, 2))) / (Math.Pow(a, 3)); beltparticles = beltparticles * relmp * relrp / relrt * 50.0; if (crefbody.flightGlobalsIndex == 0) { beltparticles = beltparticles / 1000; } beltparticles = beltparticles * Math.Abs(Math.Cos(lat)) * getSpecialMagneticFieldScaling(refBody); return((float)beltparticles); }
private void ScoopAthmosphere(double deltaTimeInSeconds, bool offlineCollecting) { string ors_atmospheric_resource_name = AtmosphericResourceHandler.getAtmosphericResourceName(vessel.mainBody.flightGlobalsIndex, currentresource); string resourceDisplayName = AtmosphericResourceHandler.getAtmosphericResourceDisplayName(vessel.mainBody.flightGlobalsIndex, currentresource); if (ors_atmospheric_resource_name == null) { resflowf = 0; recievedPower = "error"; densityFractionOfUpperAthmosphere = "error"; return; } // map ors resource to kspi resource if (PluginHelper.OrsResourceMappings == null || !PluginHelper.OrsResourceMappings.TryGetValue(ors_atmospheric_resource_name, out resourceStoragename)) { resourceStoragename = ors_atmospheric_resource_name; } else if (!PartResourceLibrary.Instance.resourceDefinitions.Contains(resourceStoragename)) { resourceStoragename = ors_atmospheric_resource_name; } var definition = PartResourceLibrary.Instance.GetDefinition(resourceStoragename); if (definition == null) { return; } double resourcedensity = definition.density; double maxAltitudeAtmosphere = PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody); double upperAtmospherFraction = Math.Max(0, (vessel.altitude - maxAltitudeAtmosphere) / Math.Max(0.000001, maxAltitudeAtmosphere * PluginHelper.MaxAtmosphericAltitudeMult - maxAltitudeAtmosphere)); double upperatmosphereDensity = 1 - upperAtmospherFraction; double airDensity = part.vessel.atmDensity + (PluginHelper.MinAtmosphericAirDensity * upperatmosphereDensity); atmosphericDensity = airDensity.ToString("0.00000000"); var hydrogenTax = 0.4 * Math.Sin(upperAtmospherFraction * Math.PI * 0.5); var heliumTax = 0.2 * Math.Sin(upperAtmospherFraction * Math.PI); double rescourceFraction = (1.0 - hydrogenTax - heliumTax) * AtmosphericResourceHandler.getAtmosphericResourceContent(vessel.mainBody.flightGlobalsIndex, currentresource); // increase density hydrogen if (resourceDisplayName == "Hydrogen") { rescourceFraction += hydrogenTax; } else if (resourceDisplayName == "Helium") { rescourceFraction += heliumTax; } densityFractionOfUpperAthmosphere = (upperatmosphereDensity * 100).ToString("0.000") + "%"; rescourcePercentage = rescourceFraction * 100; if (rescourceFraction <= 0 || vessel.altitude > (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody) * PluginHelper.MaxAtmosphericAltitudeMult)) { resflowf = 0; recievedPower = "off"; densityFractionOfUpperAthmosphere = "too high"; rescourcePercentage = 0; return; } double airspeed = part.vessel.srf_velocity.magnitude + 40; double air = airspeed * (airDensity / 1000) * scoopair / resourcedensity; double scoopedAtm = air * rescourceFraction; double powerrequirementsMW = (scoopair / 0.15) * 6 * PluginHelper.PowerConsumptionMultiplier * powerReqMult; if (scoopedAtm > 0 && part.GetResourceSpareCapacity(resourceStoragename) > 0) { var powerRequest = powerrequirementsMW * TimeWarp.fixedDeltaTime; // calculate available power double powerreceivedMW = CheatOptions.InfiniteElectricity ? powerRequest : Math.Max(consumeFNResource(powerRequest, ResourceManager.FNRESOURCE_MEGAJOULES, TimeWarp.fixedDeltaTime), 0); double normalisedRevievedPowerMW = powerreceivedMW / TimeWarp.fixedDeltaTime; // if power requirement sufficiently low, retreive power from KW source if (powerrequirementsMW < 2 && normalisedRevievedPowerMW <= powerrequirementsMW) { var requiredKW = (powerrequirementsMW - normalisedRevievedPowerMW) * 1000; var recievedKW = part.RequestResource(ResourceManager.STOCK_RESOURCE_ELECTRICCHARGE, requiredKW * TimeWarp.fixedDeltaTime); powerreceivedMW += (recievedKW / 1000); } last_power_percentage = offlineCollecting ? last_power_percentage : powerreceivedMW / powerrequirementsMW / TimeWarp.fixedDeltaTime; } else { last_power_percentage = 0; powerrequirementsMW = 0; } recievedPower = powerrequirementsMW < 2 ? (last_power_percentage * powerrequirementsMW * 1000).ToString("0.0") + " KW / " + (powerrequirementsMW * 1000).ToString("0.0") + " KW" : (last_power_percentage * powerrequirementsMW).ToString("0.0") + " MW / " + powerrequirementsMW.ToString("0.0") + " MW"; double resourceChange = scoopedAtm * last_power_percentage * deltaTimeInSeconds; if (offlineCollecting) { string numberformat = resourceChange > 100 ? "0" : "0.00"; ScreenMessages.PostScreenMessage("Atmospheric Scoop collected " + resourceChange.ToString(numberformat) + " " + resourceStoragename, 10.0f, ScreenMessageStyle.LOWER_CENTER); } resflowf = part.RequestResource(resourceStoragename, -resourceChange); resflowf = -resflowf / TimeWarp.fixedDeltaTime; UpdateResourceFlow(); }
public override void OnStart(PartModule.StartState state) { Actions["ToggleToggleResourceAction"].guiName = Events["ToggleResource"].guiName = String.Format("Toggle Resource"); if (state == StartState.Editor) { return; } this.part.force_activate(); // verify if body has atmosphere at all if (!vessel.mainBody.atmosphere) { return; } // verify scoop was enabled if (!scoopIsEnabled) { return; } // verify a timestamp is available if (last_active_time == 0) { return; } // verify any power was avaialble in previous save if (last_power_percentage < 0.01) { return; } // verify altitude is not too high if (vessel.altitude > (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody) * PluginHelper.MaxAtmosphericAltitudeMult)) { ScreenMessages.PostScreenMessage("Vessel is too high for resource accumulation", 10, ScreenMessageStyle.LOWER_CENTER); return; } // verify altitude is not too low if (vessel.altitude < (PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody))) { ScreenMessages.PostScreenMessage("Vessel is too low for resource accumulation", 10, ScreenMessageStyle.LOWER_CENTER); return; } // verify eccentricity if (vessel.orbit.eccentricity > 0.1) { string message = "Eccentricity of " + vessel.orbit.eccentricity.ToString("0.0000") + " is too High for resource accumulations"; ScreenMessages.PostScreenMessage(message, 10.0f, ScreenMessageStyle.LOWER_CENTER); return; } // verify that an electric or Thermal engine is available with high enough ISP var highIspEngine = part.vessel.parts.Find(p => p.FindModulesImplementing <ElectricEngineControllerFX>().Any(e => e.baseISP > 4200) || p.FindModulesImplementing <ThermalNozzleController>().Any(e => e.AttachedReactor.CoreTemperature > 40000)); if (highIspEngine == null) { ScreenMessages.PostScreenMessage("No engine available, with high enough Isp and propelant switch ability to compensate for atmospheric drag", 10, ScreenMessageStyle.LOWER_CENTER); return; } // calcualte time past since last frame double time_diff = (Planetarium.GetUniversalTime() - last_active_time) * 55; // scoop athmosphere for entire durration ScoopAthmosphere(time_diff, true); }
// the main collecting function private void CollectSolarWind(double deltaTimeInSeconds, bool offlineCollecting) { var ionizationPowerCost = bIonizing ? ionRequirements * Math.Pow(powerPercentage * 0.01, 2) : 0; var magneticPowerCost = mwRequirements * Math.Pow(powerPercentage * 0.01, 2); var dPowerRequirementsMw = PluginHelper.PowerConsumptionMultiplier * (magneticPowerCost + ionizationPowerCost); // change the mwRequirements number in part config to change the power consumption // checks for free space in solar wind 'tanks' dSolarWindSpareCapacity = part.GetResourceSpareCapacity(solarWindResourceDefinition.name); dHydrogenSpareCapacity = part.GetResourceSpareCapacity(hydrogenResourceDefinition.name); if (offlineCollecting) { solarWindMolesPerSquareMeterPerSecond = dLastSolarConcentration; // if resolving offline collection, pass the saved value, because OnStart doesn't resolve the function at line 328 hydrogenMolarMassConcentrationPerSquareMeterPerSecond = dLastHydrogenConcentration; } if ((solarWindMolesPerSquareMeterPerSecond > 0 || hydrogenMolarMassConcentrationPerSquareMeterPerSecond > 0)) // && (dSolarWindSpareCapacity > 0 || dHydrogenSpareCapacity > 0)) { var requiredHeliumMass = TimeWarp.fixedDeltaTime * heliumRequirementTonPerSecond; var heliumGasRequired = requiredHeliumMass / helium4GasResourceDefinition.density; var receivedHeliumGas = part.RequestResource(helium4GasResourceDefinition.id, heliumGasRequired); var receivedHeliumGasMass = receivedHeliumGas * helium4GasResourceDefinition.density; var massHeliumMassShortage = (requiredHeliumMass - receivedHeliumGasMass); var lqdHeliumRequired = massHeliumMassShortage / lqdHelium4ResourceDefinition.density; var receivedLqdHelium = part.RequestResource(lqdHelium4ResourceDefinition.id, lqdHeliumRequired); var receiverLqdHeliumMass = receivedLqdHelium * lqdHelium4ResourceDefinition.density; var heliumRatio = Math.Min(1, requiredHeliumMass > 0 ? (receivedHeliumGasMass + receiverLqdHeliumMass) / requiredHeliumMass : 0); // calculate available power var revievedPowerMw = consumeFNResourcePerSecond(dPowerRequirementsMw * heliumRatio, ResourceManager.FNRESOURCE_MEGAJOULES); // if power requirement sufficiently low, retreive power from KW source if (dPowerRequirementsMw < 2 && revievedPowerMw <= dPowerRequirementsMw) { var requiredKw = (dPowerRequirementsMw - revievedPowerMw) * 1000; var receivedKw = part.RequestResource(ResourceManager.STOCK_RESOURCE_ELECTRICCHARGE, heliumRatio * requiredKw * TimeWarp.fixedDeltaTime) / TimeWarp.fixedDeltaTime; revievedPowerMw += (receivedKw * 0.001); } dLastPowerPercentage = offlineCollecting ? dLastPowerPercentage : (dPowerRequirementsMw > 0 ? revievedPowerMw / dPowerRequirementsMw : 0); // show in GUI strCollectingStatus = "Collecting solar wind"; } else { dLastHydrogenConcentration = 0; dLastPowerPercentage = 0; dPowerRequirementsMw = 0; } // set the GUI string to state the number of KWs received if the MW requirements were lower than 2, otherwise in MW strReceivedPower = dPowerRequirementsMw < 2 ? (dLastPowerPercentage * dPowerRequirementsMw * 1000).ToString("0.0") + " KW / " + (dPowerRequirementsMw * 1000).ToString("0.0") + " KW" : (dLastPowerPercentage * dPowerRequirementsMw).ToString("0.0") + " MW / " + dPowerRequirementsMw.ToString("0.0") + " MW"; // get the shielding effect provided by the magnetosphere magnetoSphereStrengthRatio = GetMagnetosphereRatio(vessel.altitude, PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody)); // if online collecting, get the old values instead (simplification for the time being) if (offlineCollecting) { magnetoSphereStrengthRatio = dLastMagnetoStrength; } if (Math.Abs(magnetoSphereStrengthRatio) < float.Epsilon) { dShieldedEffectiveness = 1; } else { dShieldedEffectiveness = (1 - magnetoSphereStrengthRatio); } effectiveSurfaceAreaInSquareMeter = surfaceArea + (magneticArea * powerPercentage * 0.01); effectiveSurfaceAreaInSquareKiloMeter = effectiveSurfaceAreaInSquareMeter * 1e-6; effectiveDiamterInKilometer = 2 * Math.Sqrt(effectiveSurfaceAreaInSquareKiloMeter / Math.PI); Vector3d solarDirectionVector = localStar.transform.position - vessel.transform.position; solarWindFactor = Math.Max(0, Vector3d.Dot(part.transform.up, solarDirectionVector.normalized)); solarwindProductionModifiers = collectMultiplier * effectiveness * dShieldedEffectiveness * dLastPowerPercentage * solarWindFactor; var solarWindGramCollectedPerSecond = solarWindMolesPerSquareMeterPerSecond * solarwindProductionModifiers * effectiveSurfaceAreaInSquareMeter * 1.9; var interstellarIonsConcentrationPerSquareMeter = vessel.obt_speed * interstellarDustMolesPerCubicMeter; var interstellarGramCollectedPerSecond = interstellarIonsConcentrationPerSquareMeter * effectiveSurfaceAreaInSquareMeter * 1.9; /** The first important bit. * This determines how much solar wind will be collected. Can be tweaked in part configs by changing the collector's effectiveness. * */ var dSolarDustResourceChange = (solarWindGramCollectedPerSecond + interstellarGramCollectedPerSecond) * deltaTimeInSeconds * 1e-6 / solarWindResourceDefinition.density; // if the vessel has been out of focus, print out the collected amount for the player if (offlineCollecting) { var strNumberFormat = dSolarDustResourceChange > 100 ? "0" : "0.000"; // let the player know that offline collecting worked ScreenMessages.PostScreenMessage("We collected " + dSolarDustResourceChange.ToString(strNumberFormat) + " units of " + solarWindResourceDefinition.name, 10, ScreenMessageStyle.LOWER_CENTER); } // this is the second important bit - do the actual change of the resource amount in the vessel dWindResourceFlow = -part.RequestResource(solarWindResourceDefinition.id, -dSolarDustResourceChange); var dHydrogenCollectedPerSecond = hydrogenMolarMassConcentrationPerSquareMeterPerSecond * effectiveSurfaceAreaInSquareMeter; var dHydrogenResourceChange = dHydrogenCollectedPerSecond * 1e-6 / hydrogenResourceDefinition.density; dHydrogenResourceFlow = -part.RequestResource(hydrogenResourceDefinition.id, -dHydrogenResourceChange); if (offlineCollecting) { var strNumberFormat = dHydrogenResourceChange > 100 ? "0" : "0.000"; // let the player know that offline collecting worked ScreenMessages.PostScreenMessage("We collected " + dHydrogenResourceChange.ToString(strNumberFormat) + " units of " + hydrogenResourceDefinition.name, 10, ScreenMessageStyle.LOWER_CENTER); } var dHeliumCollectedPerSecond = heliumMolarMassConcentrationPerSquareMeterPerSecond * effectiveSurfaceAreaInSquareMeter; var dHeliumResourceChange = dHeliumCollectedPerSecond * 1e-6 / helium4GasResourceDefinition.density; dHeliumResourceFlow = -part.RequestResource(helium4GasResourceDefinition.id, -dHeliumResourceChange); if (offlineCollecting) { var strNumberFormat = dHeliumResourceChange > 100 ? "0" : "0.000"; // let the player know that offline collecting worked ScreenMessages.PostScreenMessage("We collected " + dHeliumResourceFlow.ToString(strNumberFormat) + " units of " + helium4GasResourceDefinition.name, 10, ScreenMessageStyle.LOWER_CENTER); } var atmosphericGasKgPerSquareMeter = GetAtmosphericGasDensityKgPerCubicMeter(); var solarDustKgPerSquareMeter = solarWindMolesPerSquareMeterPerSecond * 1e-3 * 1.9; var interstellarDustKgPerSquareMeter = interstellarDustMolesPerCubicMeter * 1e-3 * 1.9; var atmosphericDragInNewton = vessel.obt_speed * atmosphericGasKgPerSquareMeter; var interstellarDustDragInNewton = vessel.obt_speed * interstellarDustKgPerSquareMeter; var maxOrbitalVesselDragInNewton = effectiveSurfaceAreaInSquareMeter * (atmosphericDragInNewton + interstellarDustDragInNewton); var dEffectiveOrbitalVesselDragInNewton = maxOrbitalVesselDragInNewton * (bIonizing ? 1 : 0.001); var solarwindDragInNewtonPerSquareMeter = solarWindSpeed * solarDustKgPerSquareMeter; var dSolarWindVesselForceInNewton = solarwindDragInNewtonPerSquareMeter * effectiveSurfaceAreaInSquareMeter; fSolarWindCollectedGramPerHour = (float)(solarWindGramCollectedPerSecond * 3600); fInterstellarIonsConcentrationPerSquareMeter = (float)interstellarIonsConcentrationPerSquareMeter; fInterstellarIonsCollectedGramPerHour = (float)interstellarGramCollectedPerSecond * 3600; fHydrogenCollectedGramPerHour = (float)dHydrogenCollectedPerSecond * 3600; fHeliumCollectedGramPerHour = (float)dHeliumCollectedPerSecond * 3600; fAtmosphereIonsKgPerSquareMeter = (float)atmosphericGasKgPerSquareMeter; fSolarWindKgPerSquareMeter = (float)solarDustKgPerSquareMeter; fInterstellarIonsKgPerSquareMeter = (float)interstellarDustKgPerSquareMeter; fAtmosphericDragInNewton = (float)atmosphericDragInNewton; fInterstellarDustDragInNewton = (float)interstellarDustDragInNewton; fMaxOrbitalVesselDragInNewton = (float)maxOrbitalVesselDragInNewton; fEffectiveOrbitalVesselDragInNewton = (float)dEffectiveOrbitalVesselDragInNewton; fSolarWindDragInNewtonPerSquareMeter = (float)solarwindDragInNewtonPerSquareMeter; fSolarWindVesselForceInNewton = (float)dSolarWindVesselForceInNewton; if (vessel.packed) { var totalVesselMassInKg = part.vessel.GetTotalMass() * 1000; if (totalVesselMassInKg <= 0) { return; } var universalTime = Planetarium.GetUniversalTime(); if (universalTime <= 0) { return; } var orbitalDragDeltaVv = TimeWarp.fixedDeltaTime * part.vessel.obt_velocity.normalized * -dEffectiveOrbitalVesselDragInNewton / totalVesselMassInKg; vessel.orbit.Perturb(orbitalDragDeltaVv, universalTime); var solarPushDeltaVv = TimeWarp.fixedDeltaTime * solarDirectionVector.normalized * -fSolarWindVesselForceInNewton / totalVesselMassInKg; vessel.orbit.Perturb(solarPushDeltaVv, universalTime); } else { var vesselRegitBody = part.vessel.GetComponent <Rigidbody>(); vesselRegitBody.AddForce(part.vessel.velocityD.normalized * -dEffectiveOrbitalVesselDragInNewton * 1e-3, ForceMode.Force); vesselRegitBody.AddForce(solarDirectionVector.normalized * -dSolarWindVesselForceInNewton * 1e-3, ForceMode.Force); } }
private string UpdateMagnetoStrengthInGui() { return((GetMagnetosphereRatio(vessel.altitude, PluginHelper.getMaxAtmosphericAltitude(vessel.mainBody)) * 100).ToString("F1")); }