public void Update() { // in flight if (Lib.IsFlight()) { // get info from cache Vessel_info vi = Cache.VesselInfo(vessel); // do nothing if vessel is invalid if (!vi.is_valid) { return; } // update status Status = Telemetry_content(vessel, vi, type); // if there is a pin animation if (pin.Length > 0) { // still-play pin animation pin_anim.Still(Telemetry_pin(vessel, vi, type)); } } }
static void Render_environment(Panel p, Vessel v, Vessel_info vi) { // don't show env panel in eva kerbals if (v.isEVA) return; // get all sensor readings HashSet<string> readings = new HashSet<string>(); if (v.loaded) { foreach (var s in Lib.FindModules<Sensor>(v)) { readings.Add(s.type); } } else { foreach (ProtoPartModuleSnapshot m in Lib.FindModules(v.protoVessel, "Sensor")) { readings.Add(Lib.Proto.GetString(m, "type")); } } readings.Remove(string.Empty); p.AddSection("ENVIRONMENT"); foreach (string type in readings) { p.AddContent(type, Sensor.Telemetry_content(v, vi, type), Sensor.Telemetry_tooltip(v, vi, type)); } if (readings.Count == 0) p.AddContent("<i>no sensors installed</i>"); }
static void Render_supplies(Panel p, Vessel v, Vessel_info vi, Vessel_resources resources) { // for each supply int supplies = 0; foreach (Supply supply in Profile.supplies) { // get resource info Resource_info res = resources.Info(v, supply.resource); // only show estimate if the resource is present if (res.amount <= 1e-10) continue; // render panel title, if not done already if (supplies == 0) p.AddSection("SUPPLIES"); // rate tooltip string rate_tooltip = Math.Abs(res.rate) >= 1e-10 ? Lib.BuildString ( res.rate > 0.0 ? "<color=#00ff00><b>" : "<color=#ffaa00><b>", Lib.HumanReadableRate(Math.Abs(res.rate)), "</b></color>" ) : string.Empty; // determine label string label = supply.resource == "ElectricCharge" ? "battery" : Lib.SpacesOnCaps(supply.resource).ToLower(); // finally, render resource supply p.AddContent(label, Lib.HumanReadableDuration(res.Depletion(vi.crew_count)), rate_tooltip); ++supplies; } }
void Indicator_problems(Panel p, Vessel v, Vessel_info vi, List<ProtoCrewMember> crew) { // store problems icons & tooltips List<Texture2D> problem_icons = new List<Texture2D>(); List<string> problem_tooltips = new List<string>(); // detect problems Problem_sunlight(vi, ref problem_icons, ref problem_tooltips); if (Features.SpaceWeather) Problem_storm(v, ref problem_icons, ref problem_tooltips); if (crew.Count > 0 && Profile.rules.Count > 0) Problem_kerbals(crew, ref problem_icons, ref problem_tooltips); if (crew.Count > 0 && Features.Radiation) Problem_radiation(vi, ref problem_icons, ref problem_tooltips); Problem_greenhouses(v, vi.greenhouses, ref problem_icons, ref problem_tooltips); if (Features.Poisoning) Problem_poisoning(vi, ref problem_icons, ref problem_tooltips); if (Features.Humidity) Problem_humidity(vi, ref problem_icons, ref problem_tooltips); // choose problem icon const UInt64 problem_icon_time = 3; Texture2D problem_icon = Icons.empty; if (problem_icons.Count > 0) { UInt64 problem_index = ((UInt64)Time.realtimeSinceStartup / problem_icon_time) % (UInt64)(problem_icons.Count); problem_icon = problem_icons[(int)problem_index]; } // generate problem icon p.AddIcon(problem_icon, String.Join("\n", problem_tooltips.ToArray())); }
void Indicator_ec(Panel p, Vessel v, Vessel_info vi) { #if !KSP170 && !KSP16 && !KSP15 && !KSP14 if (v.vesselType == VesselType.DeployedScienceController) { return; } #endif Resource_info ec = ResourceCache.Info(v, "ElectricCharge"); Supply supply = Profile.supplies.Find(k => k.resource == "ElectricCharge"); double low_threshold = supply != null ? supply.low_threshold : 0.15; double depletion = ec.Depletion(vi.crew_count); string tooltip = Lib.BuildString ( "<align=left /><b>name\tlevel\tduration</b>\n", ec.level <= 0.005 ? "<color=#ff0000>" : ec.level <= low_threshold ? "<color=#ffff00>" : "<color=#cccccc>", "EC\t", Lib.HumanReadablePerc(ec.level), "\t", depletion <= double.Epsilon ? "depleted" : Lib.HumanReadableDuration(depletion), "</color>" ); Texture2D image = ec.level <= 0.005 ? Icons.battery_red : ec.level <= low_threshold ? Icons.battery_yellow : Icons.battery_white; p.AddIcon(image, tooltip); }
// return true if body is relevant to the player // - body: reference body of the planetary system static bool Body_is_relevant(CelestialBody body) { // [disabled] // special case: home system is always relevant // note: we deal with the case of a planet mod setting homebody as a moon //if (body == Lib.PlanetarySystem(FlightGlobals.GetHomeBody())) return true; // for each vessel foreach (Vessel v in FlightGlobals.Vessels) { // if inside the system if (Lib.PlanetarySystem(v.mainBody) == body) { // get info from the cache Vessel_info vi = Cache.VesselInfo(v); // skip invalid vessels if (!vi.is_valid) continue; // obey message config if (!DB.Vessel(v).cfg_storm) continue; // body is relevant return true; } } return false; }
/// <summary> /// If short_strings parameter is true then the strings used for display of the data will be shorter when inflight. /// </summary> public static void Fileman(this Panel p, Vessel v, bool short_strings = false) { // avoid corner-case when this is called in a lambda after scene changes v = FlightGlobals.FindVessel(v.id); // if vessel doesn't exist anymore, leave the panel empty if (v == null) { return; } // get info from the cache Vessel_info vi = Cache.VesselInfo(v); // if not a valid vessel, leave the panel empty if (!vi.is_valid) { return; } // set metadata p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(40)), " <color=#cccccc>FILE MANAGER</color>")); p.Width(Styles.ScaleWidthFloat(465.0f)); p.paneltype = Panel.PanelType.data; // time-out simulation if (p.Timeout(vi)) { return; } // get vessel drive Drive drive = DB.Vessel(v).drive; // draw data section p.AddSection("DATA"); foreach (var pair in drive.files) { string filename = pair.Key; File file = pair.Value; Render_file(p, filename, file, drive, short_strings && Lib.IsFlight(), Cache.VesselInfo(v).connection.rate); } if (drive.files.Count == 0) { p.AddContent("<i>no files</i>", string.Empty); } // draw samples section p.AddSection("SAMPLES"); foreach (var pair in drive.samples) { string filename = pair.Key; Sample sample = pair.Value; Render_sample(p, filename, sample, drive, short_strings && Lib.IsFlight()); } if (drive.samples.Count == 0) { p.AddContent("<i>no samples</i>", string.Empty); } }
public void Update() { // in flight if (Lib.IsFlight()) { // get info from cache Vessel_info vi = Cache.VesselInfo(vessel); // do nothing if vessel is invalid if (!vi.is_valid) { return; } // update ui bool has_operator = operator_cs.Check(vessel); Events["Toggle"].guiName = Lib.StatusToggle(exp_name, !recording ? "stopped" : issue.Length == 0 ? "recording" : Lib.BuildString("<color=#ffff00>", issue, "</color>")); } // in the editor else if (Lib.IsEditor()) { // update ui Events["Toggle"].guiName = Lib.StatusToggle(exp_name, recording ? "recording" : "stopped"); } }
void Indicator_signal(Panel p, Vessel v, Vessel_info vi) { ConnectionInfo conn = vi.connection; bool remotetech = RemoteTech.Enabled; // signal strength or when using RemoteTech signal delay string signal_str = remotetech ? !conn.linked ? "----" : conn.strength > Double.Epsilon ? KSPUtil.dateTimeFormatter.PrintTimeStampCompact(conn.strength) : Localizer.Format("#KERBALISM_Generic_NONE") : Lib.HumanReadablePerc(conn.strength, "F2"); // target name string target_str = conn.linked ? conn.target_name : Localizer.Format("#KERBALISM_Generic_NONE"); // transmitting info string comms_str = conn.linked ? Localizer.Format("#KERBALISM_UI_telemetry") : Localizer.Format("#KERBALISM_Generic_NOTHING"); if (vi.transmitting.Length > 0) { ExperimentInfo exp = Science.Experiment(vi.transmitting); comms_str = exp.name; } // create tooltip string tooltip = Lib.BuildString ( "<align=left />", String.Format("{0,-14}\t<b>{1}</b>\n", Localizer.Format("#KERBALISM_UI_DSNconnected"), conn.linked ? Lib.Color("green", Localizer.Format("#KERBALISM_Generic_YES")) : Lib.Color("#ffaa00", Lib.Italic(Localizer.Format("#KERBALISM_Generic_NO")))), String.Format("{0,-14}\t<b>{1}</b>\n", Localizer.Format("#KERBALISM_UI_sciencerate"), Lib.HumanReadableDataRate(conn.rate)), String.Format("{0,-14}\t<b>{1}</b>\n", remotetech ? Localizer.Format("#KERBALISM_UI_delay") : Localizer.Format("#KERBALISM_UI_strength"), signal_str), String.Format("{0,-14}\t<b>{1}</b>\n", Localizer.Format("#KERBALISM_UI_target"), target_str), String.Format("{0,-14}\t<b>{1}</b>", Localizer.Format("#KERBALISM_UI_transmitting"), comms_str) ); // create icon status Texture2D image = Icons.signal_red; switch (conn.status) { case LinkStatus.direct_link: image = remotetech ? conn.strength < 15.0 ? Icons.signal_white : Icons.signal_yellow : // 15 seconds for RemoteTech signal delay conn.strength > 0.05 ? Icons.signal_white : Icons.signal_yellow; // or 5% signal strength break; case LinkStatus.indirect_link: image = remotetech ? conn.strength < 15.0 ? Icons.signal_white : Icons.signal_yellow : // 15 seconds for RemoteTech signal delay conn.strength > 0.05 ? Icons.signal_white : Icons.signal_yellow; // or 5% signal strength tooltip += Lib.Color("yellow", "\n" + Localizer.Format("#KERBALISM_UI_Signalrelayed")); break; case LinkStatus.plasma: tooltip += Lib.Color("red", Lib.Italic("\n" + Localizer.Format("#KERBALISM_UI_Plasmablackout"))); break; case LinkStatus.storm: tooltip += Lib.Color("red", Lib.Italic("\n" + Localizer.Format("#KERBALISM_UI_Stormblackout"))); break; } p.AddIcon(image, tooltip); }
public static void SetLocks(Vessel v, Vessel_info vi) { // lock controls for EVA death if (EVA.IsDead(v)) { InputLockManager.SetControlLock(ControlTypes.EVA_INPUT, "eva_dead_lock"); } }
void Problem_sunlight(Vessel_info info, ref List <Texture2D> icons, ref List <string> tooltips) { if (info.sunlight <= double.Epsilon) { icons.Add(Icons.sun_black); tooltips.Add("In shadow"); } }
bool Render_vessel(Panel p, Vessel v) { // get vessel info Vessel_info vi = Cache.VesselInfo(v); // skip invalid vessels if (!vi.is_valid) return false; // get data from db VesselData vd = DB.Vessel(v); // determine if filter must be shown show_filter |= vd.group.Length > 0 && vd.group != "NONE"; // skip filtered vessels if (Filtered() && !Filter_match(vd.group)) return false; // get resource handler Vessel_resources resources = ResourceCache.Get(v); // get vessel crew List<ProtoCrewMember> crew = Lib.CrewList(v); // get vessel name string vessel_name = v.isEVA ? crew[0].name : v.vesselName; // get body name string body_name = v.mainBody.name.ToUpper(); // render entry p.AddHeader ( Lib.BuildString("<b>", Lib.Ellipsis(vessel_name, Styles.ScaleStringLength(((page == MonitorPage.data || page == MonitorPage.log || selected_id == Guid.Empty) && !Lib.IsFlight()) ? 50 : 30)), "</b> <size=", Styles.ScaleInteger(9).ToString(), "><color=#cccccc>", Lib.Ellipsis(body_name, Styles.ScaleStringLength(8)), "</color></size>"), string.Empty, () => { selected_id = selected_id != v.id ? v.id : Guid.Empty; } ); // problem indicator Indicator_problems(p, v, vi, crew); // battery indicator Indicator_ec(p, v, vi); // supply indicator if (Features.Supplies) Indicator_supplies(p, v, vi); // reliability indicator if (Features.Reliability) Indicator_reliability(p, v, vi); // signal indicator if (RemoteTech.Enabled || HighLogic.fetch.currentGame.Parameters.Difficulty.EnableCommNet) Indicator_signal(p, v, vi); // done return true; }
public static bool Timeout(this Panel p, Vessel_info vi) { if (!vi.connection.linked && vi.crew_count == 0) { p.AddHeader(msg[((int)Time.realtimeSinceStartup) % msg.Length]); return(true); } return(false); }
void Indicator_signal(Panel p, Vessel v, Vessel_info vi) { ConnectionInfo conn = vi.connection; // signal strength string signal_str = conn.strength > Double.Epsilon ? Lib.HumanReadablePerc(Math.Ceiling(conn.strength * 10000) / 10000, "F2") : Lib.Color("#ffaa00", Lib.Italic(Localizer.Format("#KERBALISM_Generic_NO"))); // target name string target_str = conn.linked ? conn.target_name : Localizer.Format("#KERBALISM_Generic_NONE"); // transmitting info string comms_str = conn.linked ? Localizer.Format("#KERBALISM_UI_telemetry") : Localizer.Format("#KERBALISM_Generic_NOTHING"); if (vi.transmitting.Length > 0) { ExperimentInfo exp = Science.Experiment(vi.transmitting); comms_str = exp.name; } // create tooltip string tooltip = Lib.BuildString ( "<align=left />", String.Format("{0,-14}\t<b>{1}</b>\n", Localizer.Format("#KERBALISM_UI_DSNconnected"), conn.linked ? Lib.Color("green", Localizer.Format("#KERBALISM_Generic_YES")) : Lib.Color("#ffaa00", Lib.Italic(Localizer.Format("#KERBALISM_Generic_NO")))), String.Format("{0,-14}\t<b>{1}</b>\n", Localizer.Format("#KERBALISM_UI_sciencerate"), Lib.HumanReadableDataRate(conn.rate)), String.Format("{0,-14}\t<b>{1}</b>\n", Localizer.Format("#KERBALISM_UI_strength"), signal_str), String.Format("{0,-14}\t<b>{1}</b>\n", Localizer.Format("#KERBALISM_UI_target"), target_str), String.Format("{0,-14}\t<b>{1}</b>", Localizer.Format("#KERBALISM_UI_transmitting"), comms_str) ); // create icon status Texture2D image = Icons.signal_red; switch (conn.status) { case LinkStatus.direct_link: image = conn.strength > 0.05 ? Icons.signal_white : Icons.iconSwitch(Icons.signal_yellow, image); // or 5% signal strength break; case LinkStatus.indirect_link: image = conn.strength > 0.05 ? Icons.signal_white : Icons.iconSwitch(Icons.signal_yellow, image); // or 5% signal strength tooltip += Lib.Color("yellow", "\n" + Localizer.Format("#KERBALISM_UI_Signalrelayed")); break; case LinkStatus.plasma: tooltip += Lib.Color("red", Lib.Italic("\n" + Localizer.Format("#KERBALISM_UI_Plasmablackout"))); break; case LinkStatus.storm: tooltip += Lib.Color("red", Lib.Italic("\n" + Localizer.Format("#KERBALISM_UI_Stormblackout"))); break; } p.AddIcon(image, tooltip, () => UI.Open((p2) => p2.ConnMan(v))); }
// --- RADIATION ------------------------------------------------------------ // return amount of environment radiation at the position of the specified vessel public static double Radiation(Vessel v) { if (!Features.Radiation) { return(0.0); } Vessel_info vi = Cache.VesselInfo(v); return(vi.radiation); }
public void Execute(Vessel v, Vessel_info vi, Vessel_resources resources, double elapsed_s) { if (restricted) { ExecutePerPart(v, vi, resources, elapsed_s); } else { ExecuteVesselWide(v, vi, resources, elapsed_s); } }
private void ExecuteVesselWide(Vessel v, Vessel_info vi, Vessel_resources resources, double elapsed_s) { // evaluate modifiers // if a given PartModule has a larger than 1 capacity for a process, then the multiplication happens here // remember that when a process is enabled the units of process are stored in the PartModule as a pseudo-resource double k = Modifiers.Evaluate(v, vi, resources, modifiers); Resource_recipe recipe = new Resource_recipe((Part)null); ExecuteRecipe(k, resources, elapsed_s, recipe); }
public static void TelemetryPanel(this Panel p, Vessel v) { // avoid corner-case when this is called in a lambda after scene changes v = FlightGlobals.FindVessel(v.id); // if vessel doesn't exist anymore, leave the panel empty if (v == null) { return; } // get info from the cache Vessel_info vi = Cache.VesselInfo(v); // if not a valid vessel, leave the panel empty if (!vi.is_valid) { return; } // set metadata p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(20)), " <color=#cccccc>TELEMETRY</color>")); p.Width(Styles.ScaleWidthFloat(355.0f)); p.paneltype = Panel.PanelType.telemetry; // time-out simulation if (p.Timeout(vi)) { return; } // get vessel data VesselData vd = DB.Vessel(v); // get resources Vessel_resources resources = ResourceCache.Get(v); // get crew var crew = Lib.CrewList(v); // draw the content Render_crew(p, crew); Render_greenhouse(p, vi); Render_supplies(p, v, vi, resources); Render_habitat(p, v, vi); Render_environment(p, v, vi); // collapse eva kerbal sections into one if (v.isEVA) { p.Collapse("EVA SUIT"); } }
public static void Update(Vessel v, Vessel_info vi, VesselData vd, double elapsed_s) { // do nothing if storms are disabled if (!Features.SpaceWeather) return; // only consider vessels in interplanetary space if (v.mainBody.flightGlobalsIndex != 0) return; // skip unmanned vessels if (vi.crew_count == 0) return; // generate storm time if necessary if (vd.storm_time <= double.Epsilon) { vd.storm_time = PreferencesStorm.Instance.StormMinTime + (PreferencesStorm.Instance.StormMaxTime - PreferencesStorm.Instance.StormMinTime) * Lib.RandomDouble(); } // accumulate age vd.storm_age += elapsed_s * Storm_frequency(vi.sun_dist); // if storm is over if (vd.storm_age > vd.storm_time && vd.storm_state == 2) { vd.storm_age = 0.0; vd.storm_time = 0.0; vd.storm_state = 0; // send message Message.Post(Severity.relax, Lib.BuildString("The solar storm around <b>", v.vesselName, "</b> is over")); vd.msg_signal = false; // used to avoid sending 'signal is back' messages en-masse after the storm is over } // if storm is in progress else if (vd.storm_age > vd.storm_time - PreferencesStorm.Instance.StormDuration && vd.storm_state == 1) { vd.storm_state = 2; // send message Message.Post(Severity.danger, Lib.BuildString("The coronal mass ejection hit <b>", v.vesselName, "</b>"), Lib.BuildString("Storm duration: ", Lib.HumanReadableDuration(TimeLeftCME(vd.storm_time, vd.storm_age)))); } // if storm is incoming else if (vd.storm_age > vd.storm_time - PreferencesStorm.Instance.StormDuration - Time_to_impact(vi.sun_dist) && vd.storm_state == 0) { vd.storm_state = 1; // send message Message.Post(Severity.warning, Lib.BuildString("Our observatories report a coronal mass ejection directed toward <b>", v.vesselName, "</b>"), Lib.BuildString("Time to impact: ", Lib.HumanReadableDuration(TimeBeforeCME(vd.storm_time, vd.storm_age)))); } }
public static void Update(Vessel v) { // do nothing if not an eva kerbal if (!v.isEVA) return; // get KerbalEVA module KerbalEVA kerbal = Lib.FindModules<KerbalEVA>(v)[0]; Vessel_info vi = Cache.VesselInfo(v); // Stock KSP adds 5 units of monoprop to EVAs. We want to limit that amount // to whatever was available in the ship, so we don't magically create EVA prop out of nowhere if(Cache.HasVesselObjectsCache(v, "eva_prop")) { Lib.Log("### have eva_prop for " + v); var quantity = Cache.VesselObjectsCache<double>(v, "eva_prop"); Cache.RemoveVesselObjectsCache(v, "eva_prop"); Lib.Log("### adding " + quantity + " eva prop"); Lib.SetResource(kerbal.part, Lib.EvaPropellantName(), quantity, Lib.EvaPropellantCapacity()); } // get resource handler Resource_info ec = ResourceCache.Info(v, "ElectricCharge"); // determine if headlamps need ec // - not required if there is no EC capacity in eva kerbal (no ec supply in profile) // - not required if no EC cost for headlamps is specified (set by the user) bool need_ec = ec.capacity > double.Epsilon && Settings.HeadLampsCost > double.Epsilon; // consume EC for the headlamps if (need_ec && kerbal.lampOn) { ec.Consume(Settings.HeadLampsCost * Kerbalism.elapsed_s, "headlamp"); } // force the headlamps on/off HeadLamps(kerbal, kerbal.lampOn && (!need_ec || ec.amount > double.Epsilon)); // if dead if (IsDead(v)) { // enforce freezed state Freeze(kerbal); // disable modules DisableModules(kerbal); // remove plant flag action kerbal.flagItems = 0; } }
void Problem_poisoning(Vessel_info info, ref List<Texture2D> icons, ref List<string> tooltips) { string poisoning_str = Lib.BuildString("CO2 level in internal atmosphere: <b>", Lib.HumanReadablePerc(info.poisoning), "</b>"); if (info.poisoning >= Settings.PoisoningThreshold) { icons.Add(Icons.recycle_red); tooltips.Add(poisoning_str); } else if (info.poisoning > Settings.PoisoningThreshold / 1.25) { icons.Add(Icons.recycle_yellow); tooltips.Add(poisoning_str); } }
void Problem_humidity(Vessel_info info, ref List<Texture2D> icons, ref List<string> tooltips) { string humidity_str = Lib.BuildString("Humidity level in internal atmosphere: <b>", Lib.HumanReadablePerc(info.humidity), "</b>"); if (info.humidity >= Settings.HumidityThreshold) { icons.Add(Icons.recycle_red); tooltips.Add(humidity_str); } else if (info.humidity > Settings.HumidityThreshold / 1.25) { icons.Add(Icons.recycle_yellow); tooltips.Add(humidity_str); } }
// get readings value public static double Telemetry_value(Vessel v, Vessel_info vi, string type) { switch (type) { case "temperature": return(vi.temperature); case "radiation": return(vi.radiation); case "pressure": return(v.mainBody.GetPressure(v.altitude));; case "gravioli": return(vi.gravioli); } return(0.0); }
// get readings value in [0,1] range, for pin animation public static double Telemetry_pin(Vessel v, Vessel_info vi, string type) { switch (type) { case "temperature": return(Math.Min(vi.temperature / 11000.0, 1.0)); case "radiation": return(Math.Min(vi.radiation * 3600.0 / 11.0, 1.0)); case "pressure": return(Math.Min(v.mainBody.GetPressure(v.altitude) / Sim.PressureAtSeaLevel() / 11.0, 1.0)); case "gravioli": return(Math.Min(vi.gravioli, 1.0)); } return(0.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); }
static void Render_habitat(Panel p, Vessel v, Vessel_info vi) { // if habitat feature is disabled, do not show the panel if (!Features.Habitat) { return; } // if vessel is unmanned, do not show the panel if (vi.crew_count == 0) { return; } // render panel, add some content based on enabled features p.AddSection("HABITAT"); if (Features.Poisoning) { p.AddContent("co2 level", Lib.Color(Lib.HumanReadablePerc(vi.poisoning, "F2"), vi.poisoning > Settings.PoisoningThreshold, "yellow")); } if (!v.isEVA) { if (Features.Humidity) { p.AddContent("humidity", Lib.Color(Lib.HumanReadablePerc(vi.humidity, "F2"), vi.humidity > Settings.HumidityThreshold, "yellow")); } if (Features.Pressure) { p.AddContent("pressure", Lib.HumanReadablePressure(vi.pressure * Sim.PressureAtSeaLevel())); } if (Features.Shielding) { p.AddContent("shielding", Habitat.Shielding_to_string(vi.shielding)); } if (Features.LivingSpace) { p.AddContent("living space", Habitat.Living_space_to_string(vi.living_space)); } if (Features.Comfort) { p.AddContent("comfort", vi.comforts.Summary(), vi.comforts.Tooltip()); } if (Features.Pressure) { p.AddContent("EVA's available", vi.breathable ? "infinite" : Lib.HumanReadableInteger(vi.evas), vi.breathable ? "breathable atmosphere" : "approx (derived from stored N2)"); } } }
// return vessel situation valid for specified experiment public static string Situation(Vessel v, string situations) { // shortcuts CelestialBody body = v.mainBody; Vessel_info vi = Cache.VesselInfo(v); List <string> list = Lib.Tokenize(situations, ','); foreach (string sit in list) { bool b = false; switch (sit) { case "Surface": b = Lib.Landed(v); break; case "Atmosphere": b = body.atmosphere && v.altitude < body.atmosphereDepth; break; case "Ocean": b = body.ocean && v.altitude < 0.0; break; case "Space": b = body.flightGlobalsIndex != 0 && !Lib.Landed(v) && v.altitude > body.atmosphereDepth; break; case "AbsoluteZero": b = vi.temperature < 30.0; break; case "InnerBelt": b = vi.inner_belt; break; case "OuterBelt": b = vi.outer_belt; break; case "Magnetosphere": b = vi.magnetosphere; break; case "Thermosphere": b = vi.thermosphere; break; case "Exosphere": b = vi.exosphere; break; case "InterPlanetary": b = body.flightGlobalsIndex == 0 && !vi.interstellar; break; case "InterStellar": b = body.flightGlobalsIndex == 0 && vi.interstellar; break; } if (b) { return(sit); } } return(string.Empty); }
void Problem_radiation(Vessel_info info, ref List<Texture2D> icons, ref List<string> tooltips) { string radiation_str = Lib.BuildString(" (<i>", (info.radiation * 60.0 * 60.0).ToString("F3"), " rad/h)</i>"); if (info.radiation > 1.0 / 3600.0) { icons.Add(Icons.radiation_red); tooltips.Add(Lib.BuildString("Exposed to extreme radiation", radiation_str)); } else if (info.radiation > 0.15 / 3600.0) { icons.Add(Icons.radiation_yellow); tooltips.Add(Lib.BuildString("Exposed to intense radiation", radiation_str)); } else if (info.radiation > 0.0195 / 3600.0) { icons.Add(Icons.radiation_yellow); tooltips.Add(Lib.BuildString("Exposed to moderate radiation", radiation_str)); } }
public static Vessel_info VesselInfo(Vessel v) { // get vessel id UInt32 id = Lib.VesselID(v); // get the info from the cache, if it exist Vessel_info info; if (vessels.TryGetValue(id, out info)) return info; // compute vessel info info = new Vessel_info(v, id, next_inc++); // store vessel info in the cache vessels.Add(id, info); // return the vessel info return info; }
public static void Execute(Vessel v, Vessel_info vi, VesselData vd, Vessel_resources resources, double elapsed_s) { // execute all supplies foreach (Supply supply in supplies) { supply.Execute(v, vd, resources); } // execute all rules foreach (Rule rule in rules) { rule.Execute(v, vi, resources, elapsed_s); } // execute all processes foreach (Process process in processes) { process.Execute(v, vi, resources, elapsed_s); } }