Пример #1
0
        // 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);
        }
Пример #2
0
		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";
		}
Пример #3
0
        // 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);
        }
Пример #4
0
        // 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);
        }
Пример #5
0
        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));
            }
        }
Пример #6
0
        // 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);
        }
Пример #7
0
        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)");
                }
            }
        }
Пример #8
0
        // 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);
        }
Пример #9
0
        // 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);
        }
Пример #10
0
        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();
            }
        }
Пример #11
0
 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
 }
Пример #12
0
        // 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);
        }
Пример #13
0
        // 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);
        }
Пример #14
0
        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"
        }
Пример #15
0
 public void Update()
 {
     // update ui
     Status = running ? Lib.HumanReadableRadiation(Math.Abs(radiation)) : "none";
     Events["Toggle"].guiName = Lib.StatusToggle("Active shield", running ? "active" : "disabled");
 }
Пример #16
0
        // 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);
        }
Пример #17
0
 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);
 }
Пример #18
0
  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>"));
  }
Пример #19
0
        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));
                }
            }
        }
Пример #20
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);
 }
Пример #21
0
        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);
            }
        }
Пример #22
0
        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));
            }
        }
Пример #23
0
        // 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);
        }