// specifics support public Specifics Specs() { Specifics specs = new Specifics(); specs.add("Havest size", Lib.HumanReadableAmount(crop_size, " " + crop_resource)); specs.add("Harvest time", Lib.HumanReadableDuration(1.0 / crop_rate)); specs.add("Lighting tolerance", Lib.HumanReadableFlux(light_tolerance)); if (pressure_tolerance > double.Epsilon) { specs.add("Pressure tolerance", Lib.HumanReadablePressure(Sim.PressureAtSeaLevel() * pressure_tolerance)); } if (radiation_tolerance > double.Epsilon) { specs.add("Radiation tolerance", Lib.HumanReadableRadiation(radiation_tolerance)); } specs.add("Lamps EC rate", Lib.HumanReadableRate(ec_rate)); specs.add(string.Empty); specs.add("<color=#00ffff>Required resources</color>"); foreach (ModuleResource input in resHandler.inputResources) { specs.add(input.name, Lib.BuildString("<color=#ff0000>", Lib.HumanReadableRate(input.rate), "</color>")); } specs.add(string.Empty); specs.add("<color=#00ffff>By-products</color>"); foreach (ModuleResource output in resHandler.outputResources) { specs.add(output.name, Lib.BuildString("<color=#00ff00>", Lib.HumanReadableRate(output.rate), "</color>")); } return(specs); }
private static void RadiationLevels(CelestialBody body, out string inner, out string outer, out string pause) { // TODO cache this information in RadiationBody double rad = PreferencesStorm.Instance.externRadiation; var rbSun = Radiation.Info(FlightGlobals.Bodies[0]); rad += rbSun.radiation_pause; var rb = Radiation.Info(body); if (rb.inner_visible) inner = rb.model.has_inner ? "~" + Lib.HumanReadableRadiation(Math.Max(0, rad + rb.radiation_inner) / 3600.0) : "n/a"; else inner = "unknown"; if (rb.outer_visible) outer = rb.model.has_outer ? "~" + Lib.HumanReadableRadiation(Math.Max(0, rad + rb.radiation_outer) / 3600.0) : "n/a"; else outer = "unknown"; if (rb.pause_visible) pause = rb.model.has_pause ? "~" + Lib.HumanReadableRadiation(Math.Max(0, rad + rb.radiation_pause) / 3600.0) : "n/a"; else pause = "unknown"; }
// specifics support public Specifics Specs() { Specifics specs = new Specifics(); specs.Add("Harvest size", Lib.HumanReadableAmount(crop_size, " " + crop_resource)); specs.Add("Harvest time", Lib.HumanReadableDuration(1.0 / crop_rate)); specs.Add("Lighting tolerance", Lib.HumanReadableFlux(light_tolerance)); if (pressure_tolerance > double.Epsilon) { specs.Add("Pressure tolerance", Lib.HumanReadablePressure(Sim.PressureAtSeaLevel() * pressure_tolerance)); } if (radiation_tolerance > double.Epsilon) { specs.Add("Radiation tolerance", Lib.HumanReadableRadiation(radiation_tolerance)); } specs.Add("Lamps EC rate", Lib.HumanReadableRate(ec_rate)); specs.Add(string.Empty); specs.Add("<color=#00ffff>Required resources</color>"); // do we have combined WasteAtmosphere and CO2 Set_WACO2(); bool dis_WACO2 = false; foreach (ModuleResource input in resHandler.inputResources) { // combine WasteAtmosphere and CO2 if both exist if (WACO2 && (input.name == "WasteAtmosphere" || input.name == "CarbonDioxide")) { if (dis_WACO2) { continue; } ModuleResource sec; if (input.name == "WasteAtmosphere") { sec = resHandler.inputResources.Find(x => x.name.Contains("CarbonDioxide")); } else { sec = resHandler.inputResources.Find(x => x.name.Contains("WasteAtmosphere")); } specs.Add("CarbonDioxide", Lib.BuildString("<color=#ffaa00>", Lib.HumanReadableRate(input.rate + sec.rate), "</color>")); specs.Add("Crops can also use the CO2 in the atmosphere without a scrubber."); dis_WACO2 = true; } else { specs.Add(input.name, Lib.BuildString("<color=#ffaa00>", Lib.HumanReadableRate(input.rate), "</color>")); } } specs.Add(string.Empty); specs.Add("<color=#00ffff>By-products</color>"); foreach (ModuleResource output in resHandler.outputResources) { specs.Add(output.name, Lib.BuildString("<color=#00ff00>", Lib.HumanReadableRate(output.rate), "</color>")); } return(specs); }
// specifics support public Specifics Specs() { Specifics specs = new Specifics(); specs.add(radiation >= 0.0 ? "Radiation emitted" : "Active shielding", Lib.HumanReadableRadiation(Math.Abs(radiation))); if (ec_rate > double.Epsilon) { specs.add("EC/s", Lib.HumanReadableRate(ec_rate)); } return(specs); }
public static string RequirementText(string requirement) { var parts = Lib.Tokenize(requirement, ':'); var condition = parts[0]; string value = string.Empty; if (parts.Count > 1) { value = parts[1]; } switch (condition) { case "OrbitMinInclination": return(Lib.BuildString("Min. inclination ", value)); case "OrbitMaxInclination": return(Lib.BuildString("Max. inclination ", value)); case "OrbitMinEccentricity": return(Lib.BuildString("Min. eccentricity ", value)); case "OrbitMaxEccentricity": return(Lib.BuildString("Max. eccentricity ", value)); case "AltitudeMin": return(Lib.BuildString("Min. altitude ", Lib.HumanReadableRange(Double.Parse(value)))); case "AltitudeMax": return(Lib.BuildString("Max. altitude ", Lib.HumanReadableRange(Double.Parse(value)))); case "RadiationMin": return(Lib.BuildString("Min. radiation ", Lib.HumanReadableRadiation(Double.Parse(value)))); case "RadiationMax": return(Lib.BuildString("Max. radiation ", Lib.HumanReadableRadiation(Double.Parse(value)))); case "Body": return(value); case "TemperatureMin": return(Lib.BuildString("Min. temperature ", Lib.HumanReadableTemp(Double.Parse(value)))); case "TemperatureMax": return(Lib.BuildString("Max. temperature ", Lib.HumanReadableTemp(Double.Parse(value)))); case "CrewMin": return(Lib.BuildString("Min. crew ", value)); case "CrewMax": return(Lib.BuildString("Max. crew ", value)); case "CrewCapacityMin": return(Lib.BuildString("Min. crew capacity ", value)); case "CrewCapacityMax": return(Lib.BuildString("Max. crew capacity ", value)); case "VolumePerCrewMin": return(Lib.BuildString("Min. vol./crew ", value)); case "VolumePerCrewMax": return(Lib.BuildString("Max. vol./crew ", value)); default: return(Lib.SpacesOnCaps(condition)); } }
// get readings short text info public static string telemetry_content(Vessel v, vessel_info vi, string type) { switch (type) { case "temperature": return(Lib.HumanReadableTemp(vi.temperature)); case "radiation": return(Lib.HumanReadableRadiation(vi.radiation)); case "pressure": return(Lib.HumanReadablePressure(v.mainBody.GetPressure(v.altitude))); case "gravioli": return(vi.gravioli < 0.33 ? "nothing here" : vi.gravioli < 0.66 ? "almost one" : "WOW!"); } return(string.Empty); }
static void Render_habitat(Panel p, Vessel v, VesselData vd) { // if habitat feature is disabled, do not show the panel if (!Features.Habitat) { return; } // if vessel is unmanned, do not show the panel if (vd.CrewCount == 0) { return; } // render panel, add some content based on enabled features p.AddSection("HABITAT"); if (Features.Poisoning) { p.AddContent("co2 level", Lib.Color(vd.Poisoning > Settings.PoisoningThreshold, Lib.HumanReadablePerc(vd.Poisoning, "F2"), Lib.Kolor.Yellow)); } if (Features.Radiation && v.isEVA) { p.AddContent("radiation", Lib.HumanReadableRadiation(vd.EnvHabitatRadiation)); } if (!v.isEVA) { if (Features.Pressure) { p.AddContent("pressure", Lib.HumanReadablePressure(vd.Pressure * Sim.PressureAtSeaLevel())); } if (Features.Shielding) { p.AddContent("shielding", Habitat.Shielding_to_string(vd.Shielding)); } if (Features.LivingSpace) { p.AddContent("living space", Habitat.Living_space_to_string(vd.LivingSpace)); } if (Features.Comfort) { p.AddContent("comfort", vd.Comforts.Summary(), vd.Comforts.Tooltip()); } if (Features.Pressure) { p.AddContent("EVA's available", vd.EnvBreathable ? "infinite" : Lib.HumanReadableInteger(vd.Evas), vd.EnvBreathable ? "breathable atmosphere" : "approx (derived from stored N2)"); } } }
// get readings short text info public static string Telemetry_content(Vessel v, VesselData vd, string type) { switch (type) { case "temperature": return(Lib.HumanReadableTemp(vd.EnvTemperature)); case "radiation": return(Lib.HumanReadableRadiation(vd.EnvRadiation)); case "habitat_radiation": return(Lib.HumanReadableRadiation(HabitatRadiation(vd))); case "pressure": return(Lib.HumanReadablePressure(v.mainBody.GetPressure(v.altitude))); case "gravioli": return(vd.EnvGravioli < 0.33 ? Local.Sensor_shorttextinfo1 : vd.EnvGravioli < 0.66 ? Local.Sensor_shorttextinfo2 : Local.Sensor_shorttextinfo3); //"nothing here""almost one""WOW!" } return(string.Empty); }
// get readings tooltip public static string Telemetry_tooltip(Vessel v, VesselData vd, string type) { switch (type) { case "temperature": return(Lib.BuildString ( "<align=left />", String.Format("{0,-14}\t<b>{1}</b>\n", "solar flux", Lib.HumanReadableFlux(vd.EnvSolarFluxTotal)), String.Format("{0,-14}\t<b>{1}</b>\n", "albedo flux", Lib.HumanReadableFlux(vd.EnvAlbedoFlux)), String.Format("{0,-14}\t<b>{1}</b>", "body flux", Lib.HumanReadableFlux(vd.EnvBodyFlux)) )); case "radiation": return(string.Empty); case "habitat_radiation": return(Lib.BuildString ( "<align=left />", String.Format("{0,-14}\t<b>{1}</b>\n", "environment", Lib.HumanReadableRadiation(vd.EnvRadiation, false)), String.Format("{0,-14}\t<b>{1}</b>", "habitats", Lib.HumanReadableRadiation(HabitatRadiation(vd), false)) )); case "pressure": return(vd.EnvUnderwater ? "inside <b>ocean</b>" : vd.EnvInAtmosphere ? Lib.BuildString("inside <b>atmosphere</b> (", vd.EnvBreathable ? "breathable" : "not breathable", ")") : Sim.InsideThermosphere(v) ? "inside <b>thermosphere</b>" : Sim.InsideExosphere(v) ? "inside <b>exosphere</b>" : string.Empty); case "gravioli": return(Lib.BuildString ( "Gravioli detection events per-year: <b>", vd.EnvGravioli.ToString("F2"), "</b>\n\n", "<i>The elusive negative gravioli particle\nseems to be much harder to detect\n", "than expected. On the other\nhand there seems to be plenty\nof useless positive graviolis around.</i>" )); } return(string.Empty); }
private static void RadiationLevels(CelestialBody body, out string inner, out string outer, out string pause, out double activity, out double cycle) { // TODO cache this information somewhere var rb = Radiation.Info(body); double rad = Settings.ExternRadiation / 3600.0; var rbSun = Radiation.Info(Lib.GetParentSun(body)); rad += rbSun.radiation_pause; if (rb.inner_visible) { inner = rb.model.has_inner ? "~" + Lib.HumanReadableRadiation(Math.Max(0, rad + rb.radiation_inner)) : "n/a"; } else { inner = "unknown"; } if (rb.outer_visible) { outer = rb.model.has_outer ? "~" + Lib.HumanReadableRadiation(Math.Max(0, rad + rb.radiation_outer)) : "n/a"; } else { outer = "unknown"; } if (rb.pause_visible) { pause = rb.model.has_pause ? "∆" + Lib.HumanReadableRadiation(Math.Abs(rb.radiation_pause)) : "n/a"; } else { pause = "unknown"; } activity = -1; cycle = rb.solar_cycle; if (cycle > 0) { activity = rb.SolarActivity(); } }
public void Update() { // update ui Status = running ? Lib.HumanReadableRadiation(Math.Abs(radiation)) : "none"; Events["Toggle"].guiName = Lib.StatusToggle(Localizer.Format("#kerbalism-activeshield_Part_title").Replace("Shield", "shield"), running ? Localizer.Format("#KERBALISM_Generic_ACTIVE") : Localizer.Format("#KERBALISM_Generic_DISABLED")); //i'm lazy lol }
// specifics support public Specifics Specs() { Specifics specs = new Specifics(); specs.Add(radiation >= 0.0 ? Localizer.Format("#KERBALISM_Emitter_Emitted") : Localizer.Format("#KERBALISM_Emitter_ActiveShielding"), Lib.HumanReadableRadiation(Math.Abs(radiation))); if (ec_rate > double.Epsilon) { specs.Add("EC/s", Lib.HumanReadableRate(ec_rate)); } return(specs); }
// specifics support public Specifics Specs() { Specifics specs = new Specifics(); if (redundancy.Length > 0) { specs.Add("Redundancy", redundancy); } specs.Add("Repair", new CrewSpecs(repair).Info()); specs.Add(string.Empty); specs.Add("<color=#00ffff>Standard quality</color>"); if (mtbf > 0) { specs.Add("MTBF", Lib.HumanReadableDuration(EffectiveMTBF(false, mtbf))); } if (turnon_failure_probability > 0) { specs.Add("Ignition failures", Lib.HumanReadablePerc(turnon_failure_probability, "F1")); } if (rated_operation_duration > 0) { specs.Add("Rated burn duration", Lib.HumanReadableDuration(EffectiveDuration(false, rated_operation_duration))); } if (rated_ignitions > 0) { specs.Add("Rated ignitions", EffectiveIgnitions(false, rated_ignitions).ToString()); } if (mtbf > 0 && rated_radiation > 0) { specs.Add("Radiation rating", Lib.HumanReadableRadiation(rated_radiation / 3600.0)); } specs.Add(string.Empty); specs.Add("<color=#00ffff>High quality</color>"); if (extra_cost > double.Epsilon) { specs.Add("Extra cost", Lib.HumanReadableCost(extra_cost * part.partInfo.cost)); } if (extra_mass > double.Epsilon) { specs.Add("Extra mass", Lib.HumanReadableMass(extra_mass * part.partInfo.partPrefab.mass)); } if (mtbf > 0) { specs.Add("MTBF", Lib.HumanReadableDuration(EffectiveMTBF(true, mtbf))); } if (turnon_failure_probability > 0) { specs.Add("Ignition failures", Lib.HumanReadablePerc(turnon_failure_probability / Settings.QualityScale, "F1")); } if (rated_operation_duration > 0) { specs.Add("Rated burn duration", Lib.HumanReadableDuration(EffectiveDuration(true, rated_operation_duration))); } if (rated_ignitions > 0) { specs.Add("Rated ignitions", EffectiveIgnitions(true, rated_ignitions).ToString()); } if (mtbf > 0 && rated_radiation > 0) { specs.Add("Radiation rating", Lib.HumanReadableRadiation(Settings.QualityScale * rated_radiation / 3600.0)); } return(specs); }
public static void Body_info(this Panel p) { // only show in mapview if (!MapView.MapIsEnabled) { return; } // only show if there is a selected body and that body is not the sun CelestialBody body = Lib.MapViewSelectedBody(); if (body == null || (Lib.IsSun(body) && !Features.Radiation)) { return; } // calculate radiation at body surface double surfaceRadiation = Radiation.ComputeSurface(body, Sim.GammaTransparency(body, 0.0)); // for all bodies except sun(s) if (!Lib.IsSun(body)) { CelestialBody mainSun; Vector3d sun_dir; double sun_dist; double solar_flux = Sim.SolarFluxAtBody(body, false, out mainSun, out sun_dir, out sun_dist); solar_flux *= Sim.AtmosphereFactor(body, 0.7071); // calculate simulation values double albedo_flux = Sim.AlbedoFlux(body, body.position + sun_dir * body.Radius); double body_flux = Sim.BodyFlux(body, 0.0); double total_flux = solar_flux + albedo_flux + body_flux + Sim.BackgroundFlux(); double temperature = body.atmosphere ? body.GetTemperature(0.0) : Sim.BlackBodyTemperature(total_flux); // calculate night-side temperature double total_flux_min = Sim.AlbedoFlux(body, body.position - sun_dir * body.Radius) + body_flux + Sim.BackgroundFlux(); double temperature_min = Sim.BlackBodyTemperature(total_flux_min); // surface panel string temperature_str = body.atmosphere ? Lib.HumanReadableTemp(temperature) : Lib.BuildString(Lib.HumanReadableTemp(temperature_min), " / ", Lib.HumanReadableTemp(temperature)); p.AddSection(Local.BodyInfo_SURFACE); //"SURFACE" p.AddContent(Local.BodyInfo_temperature, temperature_str); //"temperature" p.AddContent(Local.BodyInfo_solarflux, Lib.HumanReadableFlux(solar_flux)); //"solar flux" if (Features.Radiation) { p.AddContent(Local.BodyInfo_radiation, Lib.HumanReadableRadiation(surfaceRadiation)); //"radiation" } // atmosphere panel if (body.atmosphere) { p.AddSection(Local.BodyInfo_ATMOSPHERE); //"ATMOSPHERE" p.AddContent(Local.BodyInfo_breathable, Sim.Breathable(body) ? Local.BodyInfo_breathable_yes : Local.BodyInfo_breathable_no); //"breathable""yes""no" p.AddContent(Local.BodyInfo_lightabsorption, Lib.HumanReadablePerc(1.0 - Sim.AtmosphereFactor(body, 0.7071))); //"light absorption" if (Features.Radiation) { p.AddContent(Local.BodyInfo_gammaabsorption, Lib.HumanReadablePerc(1.0 - Sim.GammaTransparency(body, 0.0))); //"gamma absorption" } } } // radiation panel if (Features.Radiation) { p.AddSection(Local.BodyInfo_RADIATION); //"RADIATION" string inner, outer, pause; double activity, cycle; RadiationLevels(body, out inner, out outer, out pause, out activity, out cycle); if (Storm.sun_observation_quality > 0.5 && activity > -1) { string title = Local.BodyInfo_solaractivity; //"solar activity" if (Storm.sun_observation_quality > 0.7) { title = Lib.BuildString(title, ": ", Lib.Color(Local.BodyInfo_stormcycle.Format(Lib.HumanReadableDuration(cycle)), Lib.Kolor.LightGrey)); // <<1>> cycle } p.AddContent(title, Lib.HumanReadablePerc(activity)); } if (Storm.sun_observation_quality > 0.8) { p.AddContent(Local.BodyInfo_radiationonsurface, Lib.HumanReadableRadiation(surfaceRadiation)); //"radiation on surface:" } p.AddContent(Lib.BuildString(Local.BodyInfo_innerbelt, " ", Lib.Color(inner, Lib.Kolor.LightGrey)), //"inner belt: " Radiation.show_inner ? Lib.Color(Local.BodyInfo_show, Lib.Kolor.Green) : Lib.Color(Local.BodyInfo_hide, Lib.Kolor.Red), string.Empty, () => p.Toggle(ref Radiation.show_inner)); //"show""hide" p.AddContent(Lib.BuildString(Local.BodyInfo_outerbelt, " ", Lib.Color(outer, Lib.Kolor.LightGrey)), //"outer belt: " Radiation.show_outer ? Lib.Color(Local.BodyInfo_show, Lib.Kolor.Green) : Lib.Color(Local.BodyInfo_hide, Lib.Kolor.Red), string.Empty, () => p.Toggle(ref Radiation.show_outer)); //"show""hide" p.AddContent(Lib.BuildString(Local.BodyInfo_magnetopause, " ", Lib.Color(pause, Lib.Kolor.LightGrey)), //"magnetopause: " Radiation.show_pause ? Lib.Color(Local.BodyInfo_show, Lib.Kolor.Green) : Lib.Color(Local.BodyInfo_hide, Lib.Kolor.Red), string.Empty, () => p.Toggle(ref Radiation.show_pause)); //"show""hide" } // explain the user how to toggle the BodyInfo window p.AddContent(string.Empty); p.AddContent("<i>" + Local.BodyInfo_BodyInfoToggleHelp.Format("<b>B</b>") + "</i>"); //"Press <<1>> to open this window again" // set metadata p.Title(Lib.BuildString(Lib.Ellipsis(body.bodyName, Styles.ScaleStringLength(24)), " ", Lib.Color(Local.BodyInfo_title, Lib.Kolor.LightGrey))); //"BODY INFO" }
public void Update() { // update ui Status = running ? Lib.HumanReadableRadiation(Math.Abs(radiation)) : "none"; Events["Toggle"].guiName = Lib.StatusToggle("Active shield", running ? "active" : "disabled"); }
// return the total environent radiation at position specified public static double Compute(Vessel v, Vector3d position, double gamma_transparency, double sunlight, out bool blackout, out bool magnetosphere, out bool inner_belt, out bool outer_belt, out bool interstellar, out double shieldedRadiation) { // prepare out parameters blackout = false; magnetosphere = false; inner_belt = false; outer_belt = false; interstellar = false; shieldedRadiation = 0.0; // no-op when Radiation is disabled if (!Features.Radiation) { return(0.0); } // store stuff Space gsm; Vector3 p; double D; double r; // accumulate radiation double radiation = 0.0; CelestialBody body = v.mainBody; while (body != null) { // Compute radiation values from overlapping 3d fields (belts + magnetospheres) RadiationBody rb = Info(body); RadiationModel mf = rb.model; // activity is [-0.15..1.05] var activity = rb.SolarActivity(false); if (mf.Has_field()) { // transform to local space once var scaled_position = ScaledSpace.LocalToScaledSpace(position); // generate radii-normalized GSM space gsm = Gsm_space(rb, true); // move the point in GSM space p = gsm.Transform_in(scaled_position); // accumulate radiation and determine pause/belt flags if (mf.has_inner) { D = mf.Inner_func(p); inner_belt |= D < 0; // allow for radiation field to grow/shrink with solar activity D -= activity * 0.25 / mf.inner_radius; r = RadiationInBelt(D, mf.inner_radius, rb.radiation_inner_gradient); radiation += r * rb.radiation_inner * (1 + activity * 0.3); } if (mf.has_outer) { D = mf.Outer_func(p); outer_belt |= D < 0; // allow for radiation field to grow/shrink with solar activity D -= activity * 0.25 / mf.outer_radius; r = RadiationInBelt(D, mf.outer_radius, rb.radiation_outer_gradient); radiation += r * rb.radiation_outer * (1 + activity * 0.3); } if (mf.has_pause) { gsm = Gsm_space(rb, false); p = gsm.Transform_in(scaled_position); D = mf.Pause_func(p); radiation += Lib.Clamp(D / -0.1332f, 0.0f, 1.0f) * rb.RadiationPause(); magnetosphere |= D < 0.0f && !Lib.IsSun(rb.body); //< ignore heliopause interstellar |= D > 0.0f && Lib.IsSun(rb.body); //< outside heliopause } } if (rb.radiation_surface > 0 && body != v.mainBody) { Vector3d direction; double distance; if (Sim.IsBodyVisible(v, position, body, v.KerbalismData().EnvVisibleBodies, out direction, out distance)) { var r0 = RadiationR0(rb); var r1 = DistanceRadiation(r0, distance); // clamp to max. surface radiation. when loading on a rescaled system, the vessel can appear to be within the sun for a few ticks radiation += Math.Min(r1, rb.radiation_surface); #if DEBUG_RADIATION if (v.loaded) { Lib.Log("Radiation " + v + " from surface of " + body + ": " + Lib.HumanReadableRadiation(radiation) + " gamma: " + Lib.HumanReadableRadiation(r1)); } #endif } } // avoid loops in the chain body = (body.referenceBody != null && body.referenceBody.referenceBody == body) ? null : body.referenceBody; } // add extern radiation radiation += Settings.ExternRadiation / 3600.0; #if DEBUG_RADIATION if (v.loaded) { Lib.Log("Radiation " + v + " extern: " + Lib.HumanReadableRadiation(radiation) + " gamma: " + Lib.HumanReadableRadiation(Settings.ExternRadiation)); } #endif // apply gamma transparency if inside atmosphere radiation *= gamma_transparency; #if DEBUG_RADIATION if (v.loaded) { Lib.Log("Radiation " + v + " after gamma: " + Lib.HumanReadableRadiation(radiation) + " transparency: " + gamma_transparency); } #endif // add surface radiation of the body itself if (Lib.IsSun(v.mainBody) && v.altitude < v.mainBody.Radius) { if (v.altitude > v.mainBody.Radius) { radiation += DistanceRadiation(RadiationR0(Info(v.mainBody)), v.altitude); } } #if DEBUG_RADIATION if (v.loaded) { Lib.Log("Radiation " + v + " from current main body: " + Lib.HumanReadableRadiation(radiation) + " gamma: " + Lib.HumanReadableRadiation(DistanceRadiation(RadiationR0(Info(v.mainBody)), v.altitude))); } #endif shieldedRadiation = radiation; // if there is a storm in progress if (Storm.InProgress(v)) { // inside a magnetopause (except heliosphere), blackout the signal // outside, add storm radiations modulated by sun visibility if (magnetosphere) { blackout = true; } else { var vd = v.KerbalismData(); var activity = Info(vd.EnvMainSun.SunData.body).SolarActivity(false) / 2.0; var strength = PreferencesRadiation.Instance.StormRadiation * sunlight * (activity + 0.5); radiation += strength; shieldedRadiation += vd.EnvHabitatInfo.AverageHabitatRadiation(strength); } } // add emitter radiation after atmosphere transparency var emitterRadiation = Emitter.Total(v); radiation += emitterRadiation; shieldedRadiation += emitterRadiation; #if DEBUG_RADIATION if (v.loaded) { Lib.Log("Radiation " + v + " after emitters: " + Lib.HumanReadableRadiation(radiation) + " shielded " + Lib.HumanReadableRadiation(shieldedRadiation)); } #endif // for EVAs, add the effect of nearby emitters if (v.isEVA) { var nearbyEmitters = Emitter.Nearby(v); radiation += nearbyEmitters; shieldedRadiation += nearbyEmitters; #if DEBUG_RADIATION if (v.loaded) { Lib.Log("Radiation " + v + " nearby emitters " + Lib.HumanReadableRadiation(nearbyEmitters)); } #endif } var passiveShielding = PassiveShield.Total(v); shieldedRadiation -= passiveShielding; #if DEBUG_RADIATION if (v.loaded) { Lib.Log("Radiation " + v + " passiveShielding " + Lib.HumanReadableRadiation(passiveShielding)); } if (v.loaded) { Lib.Log("Radiation " + v + " before clamp: " + Lib.HumanReadableRadiation(radiation) + " shielded " + Lib.HumanReadableRadiation(shieldedRadiation)); } #endif // clamp radiation to positive range // note: we avoid radiation going to zero by using a small positive value radiation = Math.Max(radiation, Nominal); shieldedRadiation = Math.Max(shieldedRadiation, Nominal); #if DEBUG_RADIATION if (v.loaded) { Lib.Log("Radiation " + v + " after clamp: " + Lib.HumanReadableRadiation(radiation) + " shielded " + Lib.HumanReadableRadiation(shieldedRadiation)); } #endif // return radiation return(radiation); }
public void Update() { // update ui Status = deployed ? Lib.BuildString("absorbing ", Lib.HumanReadableRadiation(Math.Abs(radiation))) : disabledTitle; Events["Toggle"].guiName = Lib.StatusToggle(title, deployed ? disengageActionTitle : engageActionTitle); }
public static void body_info(this Panel p) { // only show in mapview if (!MapView.MapIsEnabled) return; // only show if there is a selected body and that body is not the sun CelestialBody body = Lib.SelectedBody(); if (body == null || (body.flightGlobalsIndex == 0 && !Features.Radiation)) return; // shortcut CelestialBody sun = FlightGlobals.Bodies[0]; // for all bodies except the sun if (body != sun) { // calculate simulation values double atmo_factor = Sim.AtmosphereFactor(body, 0.7071); double gamma_factor = Sim.GammaTransparency(body, 0.0); double sun_dist = Sim.Apoapsis(Lib.PlanetarySystem(body)) - sun.Radius - body.Radius; Vector3d sun_dir = (sun.position - body.position).normalized; double solar_flux = Sim.SolarFlux(sun_dist) * atmo_factor; double albedo_flux = Sim.AlbedoFlux(body, body.position + sun_dir * body.Radius); double body_flux = Sim.BodyFlux(body, 0.0); double total_flux = solar_flux + albedo_flux + body_flux + Sim.BackgroundFlux(); double temperature = body.atmosphere ? body.GetTemperature(0.0) : Sim.BlackBodyTemperature(total_flux); // calculate night-side temperature double total_flux_min = Sim.AlbedoFlux(body, body.position - sun_dir * body.Radius) + body_flux + Sim.BackgroundFlux(); double temperature_min = Sim.BlackBodyTemperature(total_flux_min); // calculate radiation at body surface double radiation = Radiation.ComputeSurface(body, gamma_factor); // surface panel string temperature_str = body.atmosphere ? Lib.HumanReadableTemp(temperature) : Lib.BuildString(Lib.HumanReadableTemp(temperature_min), " / ", Lib.HumanReadableTemp(temperature)); p.section("SURFACE"); p.content("temperature", temperature_str); p.content("solar flux", Lib.HumanReadableFlux(solar_flux)); if (Features.Radiation) p.content("radiation", Lib.HumanReadableRadiation(radiation)); // atmosphere panel if (body.atmosphere) { p.section("ATMOSPHERE"); p.content("breathable", Sim.Breathable(body) ? "yes" : "no"); p.content("light absorption", Lib.HumanReadablePerc(1.0 - Sim.AtmosphereFactor(body, 0.7071))); if (Features.Radiation) p.content("gamma absorption", Lib.HumanReadablePerc(1.0 - Sim.GammaTransparency(body, 0.0))); } } // rendering panel if (Features.Radiation) { p.section("RENDERING"); p.content("inner belt", Radiation.show_inner ? "<color=green>show</color>" : "<color=red>hide</color>", string.Empty, () => p.toggle(ref Radiation.show_inner)); p.content("outer belt", Radiation.show_outer ? "<color=green>show</color>" : "<color=red>hide</color>", string.Empty, () => p.toggle(ref Radiation.show_outer)); p.content("magnetopause", Radiation.show_pause ? "<color=green>show</color>" : "<color=red>hide</color>", string.Empty, () => p.toggle(ref Radiation.show_pause)); } // explain the user how to toggle the BodyInfo window p.content(string.Empty); p.content("<i>Press <b>B</b> to open this window again</i>"); // set metadata p.title(Lib.BuildString(Lib.Ellipsis(body.bodyName, 24), " <color=#cccccc>BODY INFO</color>")); }
public void Update() { if (Lib.IsFlight()) { // enforce state // - required as things like Configure or AnimationGroup can re-enable broken modules if (broken) { foreach (PartModule m in modules) { m.enabled = false; m.isEnabled = false; } } Status = string.Empty; // update ui if (broken) { Status = critical ? Lib.Color("critical failure", Lib.Kolor.Red) : Lib.Color("malfunction", Lib.Kolor.Yellow); } else { if (PreferencesReliability.Instance.engineFailures && (rated_operation_duration > 0 || rated_ignitions > 0)) { if (rated_operation_duration > 0) { double effective_duration = EffectiveDuration(quality, rated_operation_duration); Status = Lib.BuildString("remaining burn: ", Lib.HumanReadableDuration(Math.Max(0, effective_duration - operation_duration))); } if (rated_ignitions > 0) { int effective_ignitions = EffectiveIgnitions(quality, rated_ignitions); Status = Lib.BuildString(Status, (string.IsNullOrEmpty(Status) ? "" : ", "), "ignitions: ", Math.Max(0, effective_ignitions - ignitions).ToString()); } } if (rated_radiation > 0) { var rated = quality ? rated_radiation * Settings.QualityScale : rated_radiation; var current = vessel.KerbalismData().EnvRadiation * 3600.0; if (rated < current) { Status = Lib.BuildString(Status, (string.IsNullOrEmpty(Status) ? "" : ", "), Lib.Color("taking radiation damage", Lib.Kolor.Orange)); } } } if (string.IsNullOrEmpty(Status)) { Status = "nominal"; } Events["Inspect"].active = !broken && !needMaintenance; Events["Repair"].active = repair_cs && (broken || needMaintenance) && !critical; if (needMaintenance) { Events["Repair"].guiName = Lib.BuildString("Service <b>", title, "</b>"); } RunningCheck(); // if it has failed, trigger malfunction var now = Planetarium.GetUniversalTime(); if (next > 0 && now > next && !broken) { #if DEBUG_RELIABILITY Lib.Log("Reliablity: breakdown for " + part.partInfo.title); #endif Break(); } // set highlight Highlight(part); } else { // update ui Events["Quality"].guiName = Lib.StatusToggle(Lib.BuildString("<b>", title, "</b> quality"), quality ? "high" : "standard"); Status = string.Empty; if (mtbf > 0 && PreferencesReliability.Instance.mtbfFailures) { double effective_mtbf = EffectiveMTBF(quality, mtbf); Status = Lib.BuildString(Status, (string.IsNullOrEmpty(Status) ? "" : ", "), "MTBF: ", Lib.HumanReadableDuration(effective_mtbf)); } if (rated_operation_duration > 0 && PreferencesReliability.Instance.engineFailures) { double effective_duration = EffectiveDuration(quality, rated_operation_duration); Status = Lib.BuildString(Status, (string.IsNullOrEmpty(Status) ? "" : ", "), "Burn time: ", Lib.HumanReadableDuration(effective_duration)); } if (rated_ignitions > 0 && PreferencesReliability.Instance.engineFailures) { int effective_ignitions = EffectiveIgnitions(quality, rated_ignitions); Status = Lib.BuildString(Status, (string.IsNullOrEmpty(Status) ? "" : ", "), "ignitions: ", effective_ignitions.ToString()); } if (rated_radiation > 0 && PreferencesReliability.Instance.mtbfFailures) { var r = quality ? rated_radiation * Settings.QualityScale : rated_radiation; Status = Lib.BuildString(Status, (string.IsNullOrEmpty(Status) ? "" : ", "), Lib.HumanReadableRadiation(r / 3600.0)); } } }
public void Update() { // update ui Status = running ? Lib.HumanReadableRadiation(Math.Abs(radiation)) : Local.Emitter_none; //"none" Events["Toggle"].guiName = Lib.StatusToggle(part.partInfo.title, running ? Local.Generic_ACTIVE : Local.Generic_DISABLED); }
public static string ReqValueFormat(Require req, object reqValue) { switch (req) { case Require.OrbitMinEccentricity: case Require.OrbitMaxEccentricity: case Require.OrbitMinArgOfPeriapsis: case Require.OrbitMaxArgOfPeriapsis: case Require.AtmosphereAltMin: case Require.AtmosphereAltMax: return(((double)reqValue).ToString("F2")); case Require.SunAngleMin: case Require.SunAngleMax: case Require.OrbitMinInclination: case Require.OrbitMaxInclination: return(Lib.HumanReadableAngle((double)reqValue)); case Require.TemperatureMin: case Require.TemperatureMax: return(Lib.HumanReadableTemp((double)reqValue)); case Require.AltitudeMin: case Require.AltitudeMax: case Require.AltAboveGroundMin: case Require.AltAboveGroundMax: case Require.MaxAsteroidDistance: return(Lib.HumanReadableDistance((double)reqValue)); case Require.RadiationMin: case Require.RadiationMax: return(Lib.HumanReadableRadiation((double)reqValue)); case Require.VolumePerCrewMin: case Require.VolumePerCrewMax: return(Lib.HumanReadableVolume((double)reqValue)); case Require.SurfaceSpeedMin: case Require.SurfaceSpeedMax: case Require.VerticalSpeedMin: case Require.VerticalSpeedMax: case Require.SpeedMin: case Require.SpeedMax: return(Lib.HumanReadableSpeed((double)reqValue)); case Require.DynamicPressureMin: case Require.DynamicPressureMax: case Require.StaticPressureMin: case Require.StaticPressureMax: case Require.AtmDensityMin: case Require.AtmDensityMax: return(Lib.HumanReadablePressure((double)reqValue)); case Require.CrewMin: case Require.CrewMax: case Require.CrewCapacityMin: case Require.CrewCapacityMax: case Require.AstronautComplexLevelMin: case Require.AstronautComplexLevelMax: case Require.TrackingStationLevelMin: case Require.TrackingStationLevelMax: case Require.MissionControlLevelMin: case Require.MissionControlLevelMax: case Require.AdministrationLevelMin: case Require.AdministrationLevelMax: return(((int)reqValue).ToString()); case Require.Module: return(KSPUtil.PrintModuleName((string)reqValue)); case Require.Part: return(PartLoader.getPartInfoByName((string)reqValue)?.title ?? (string)reqValue); default: return(string.Empty); } }
public static string RequirementText(string requirement) { var parts = Lib.Tokenize(requirement, ':'); var condition = parts[0]; string value = string.Empty; if (parts.Count > 1) { value = parts[1]; } switch (condition) { case "OrbitMinInclination": return(Lib.BuildString("Min. inclination ", value, "°")); case "OrbitMaxInclination": return(Lib.BuildString("Max. inclination ", value, "°")); case "OrbitMinEccentricity": return(Lib.BuildString("Min. eccentricity ", value)); case "OrbitMaxEccentricity": return(Lib.BuildString("Max. eccentricity ", value)); case "OrbitMinArgOfPeriapsis": return(Lib.BuildString("Min. argument of Pe ", value)); case "OrbitMaxArgOfPeriapsis": return(Lib.BuildString("Max. argument of Pe ", value)); case "AltitudeMin": return(Lib.BuildString("Min. altitude ", Lib.HumanReadableRange(Double.Parse(value)))); case "AltitudeMax": var v = Double.Parse(value); if (v >= 0) { return(Lib.BuildString("Max. altitude ", Lib.HumanReadableRange(v))); } return(Lib.BuildString("Min. depth ", Lib.HumanReadableRange(-v))); case "RadiationMin": return(Lib.BuildString("Min. radiation ", Lib.HumanReadableRadiation(Double.Parse(value)))); case "RadiationMax": return(Lib.BuildString("Max. radiation ", Lib.HumanReadableRadiation(Double.Parse(value)))); case "Body": return(PrettyBodyText(value)); case "TemperatureMin": return(Lib.BuildString("Min. temperature ", Lib.HumanReadableTemp(Double.Parse(value)))); case "TemperatureMax": return(Lib.BuildString("Max. temperature ", Lib.HumanReadableTemp(Double.Parse(value)))); case "CrewMin": return(Lib.BuildString("Min. crew ", value)); case "CrewMax": return(Lib.BuildString("Max. crew ", value)); case "CrewCapacityMin": return(Lib.BuildString("Min. crew capacity ", value)); case "CrewCapacityMax": return(Lib.BuildString("Max. crew capacity ", value)); case "VolumePerCrewMin": return(Lib.BuildString("Min. vol./crew ", Lib.HumanReadableVolume(double.Parse(value)))); case "VolumePerCrewMax": return(Lib.BuildString("Max. vol./crew ", Lib.HumanReadableVolume(double.Parse(value)))); case "MaxAsteroidDistance": return(Lib.BuildString("Max. asteroid distance ", Lib.HumanReadableRange(double.Parse(value)))); case "SunAngleMin": return(Lib.BuildString("Min. sun angle ", Lib.HumanReadableAngle(double.Parse(value)))); case "SunAngleMax": return(Lib.BuildString("Max. sun angle ", Lib.HumanReadableAngle(double.Parse(value)))); case "AtmosphereBody": return("Body with atmosphere"); case "AtmosphereAltMin": return(Lib.BuildString("Min. atmosphere altitude ", value)); case "AtmosphereAltMax": return(Lib.BuildString("Max. atmosphere altitude ", value)); case "SurfaceSpeedMin": return(Lib.BuildString("Min. surface speed ", Lib.HumanReadableSpeed(double.Parse(value)))); case "SurfaceSpeedMax": return(Lib.BuildString("Max. surface speed ", Lib.HumanReadableSpeed(double.Parse(value)))); case "VerticalSpeedMin": return(Lib.BuildString("Min. vertical speed ", Lib.HumanReadableSpeed(double.Parse(value)))); case "VerticalSpeedMax": return(Lib.BuildString("Max. vertical speed ", Lib.HumanReadableSpeed(double.Parse(value)))); case "SpeedMin": return(Lib.BuildString("Min. speed ", Lib.HumanReadableSpeed(double.Parse(value)))); case "SpeedMax": return(Lib.BuildString("Max. speed ", Lib.HumanReadableSpeed(double.Parse(value)))); case "DynamicPressureMin": return(Lib.BuildString("Min. dynamic pressure ", Lib.HumanReadablePressure(double.Parse(value)))); case "DynamicPressureMax": return(Lib.BuildString("Max. dynamic pressure ", Lib.HumanReadablePressure(double.Parse(value)))); case "StaticPressureMin": return(Lib.BuildString("Min. pressure ", Lib.HumanReadablePressure(double.Parse(value)))); case "StaticPressureMax": return(Lib.BuildString("Max. pressure ", Lib.HumanReadablePressure(double.Parse(value)))); case "AtmDensityMin": return(Lib.BuildString("Min. atm. density ", Lib.HumanReadablePressure(double.Parse(value)))); case "AtmDensityMax": return(Lib.BuildString("Max. atm. density ", Lib.HumanReadablePressure(double.Parse(value)))); case "AltAboveGroundMin": return(Lib.BuildString("Min. ground altitude ", Lib.HumanReadableRange(double.Parse(value)))); case "AltAboveGroundMax": return(Lib.BuildString("Max. ground altitude ", Lib.HumanReadableRange(double.Parse(value)))); case "MissionControlLevelMin": return(Lib.BuildString(ScenarioUpgradeableFacilities.GetFacilityName(SpaceCenterFacility.MissionControl), " level ", value)); case "MissionControlLevelMax": return(Lib.BuildString(ScenarioUpgradeableFacilities.GetFacilityName(SpaceCenterFacility.MissionControl), " max. level ", value)); case "AdministrationLevelMin": return(Lib.BuildString(ScenarioUpgradeableFacilities.GetFacilityName(SpaceCenterFacility.Administration), " level ", value)); case "AdministrationLevelMax": return(Lib.BuildString(ScenarioUpgradeableFacilities.GetFacilityName(SpaceCenterFacility.Administration), " max. level ", value)); case "TrackingStationLevelMin": return(Lib.BuildString(ScenarioUpgradeableFacilities.GetFacilityName(SpaceCenterFacility.TrackingStation), " level ", value)); case "TrackingStationLevelMax": return(Lib.BuildString(ScenarioUpgradeableFacilities.GetFacilityName(SpaceCenterFacility.TrackingStation), " max. level ", value)); case "AstronautComplexLevelMin": return(Lib.BuildString(ScenarioUpgradeableFacilities.GetFacilityName(SpaceCenterFacility.AstronautComplex), " level ", value)); case "AstronautComplexLevelMax": return(Lib.BuildString(ScenarioUpgradeableFacilities.GetFacilityName(SpaceCenterFacility.AstronautComplex), " max. level ", value)); case "Part": return(Lib.BuildString("Needs part ", value)); case "Module": return(Lib.BuildString("Needs module ", value)); default: return(Lib.SpacesOnCaps(condition)); } }
// get readings tooltip public static string Telemetry_tooltip(Vessel v, VesselData vd, string type) { switch (type) { case "temperature": return(Lib.BuildString ( "<align=left />", String.Format("{0,-14}\t<b>{1}</b>\n", Local.Sensor_solarflux, Lib.HumanReadableFlux(vd.EnvSolarFluxTotal)), //"solar flux" String.Format("{0,-14}\t<b>{1}</b>\n", Local.Sensor_albedoflux, Lib.HumanReadableFlux(vd.EnvAlbedoFlux)), //"albedo flux" String.Format("{0,-14}\t<b>{1}</b>", Local.Sensor_bodyflux, Lib.HumanReadableFlux(vd.EnvBodyFlux)) //"body flux" )); case "radiation": return(string.Empty); case "habitat_radiation": return(Lib.BuildString ( "<align=left />", String.Format("{0,-14}\t<b>{1}</b>\n", Local.Sensor_environment, Lib.HumanReadableRadiation(vd.EnvRadiation, false)), //"environment" String.Format("{0,-14}\t<b>{1}</b>", Local.Sensor_habitats, Lib.HumanReadableRadiation(HabitatRadiation(vd), false)) //"habitats" )); case "pressure": return(vd.EnvUnderwater ? Local.Sensor_insideocean //"inside <b>ocean</b>" : vd.EnvInAtmosphere ? Local.Sensor_insideatmosphere.Format(vd.EnvBreathable ? Local.Sensor_breathable : Local.Sensor_notbreathable) //"breathable""not breathable" //Lib.BuildString("inside <b>atmosphere</b> (", vd.EnvBreathable ? "breathable" : "not breathable", ")") : Sim.InsideThermosphere(v) ? Local.Sensor_insidethermosphere //"inside <b>thermosphere</b>"" : Sim.InsideExosphere(v) ? Local.Sensor_insideexosphere //"inside <b>exosphere</b>" : string.Empty); case "gravioli": return(Lib.BuildString ( Local.Sensor_Graviolidetection + " <b>" + vd.EnvGravioli.ToString("F2") + "</b>\n\n", //"Gravioli detection events per-year: "<i>", Local.Sensor_info1, "\n", //The elusive negative gravioli particle\nseems to be much harder to detect than expected. Local.Sensor_info2, "</i>" //" On the other\nhand there seems to be plenty\nof useless positive graviolis around." )); } return(string.Empty); }