static void render_sample(Panel p, string filename, Sample sample, Drive drive, bool short_strings) { // get experiment info ExperimentInfo exp = Science.experiment(filename); // render experiment name string exp_label = Lib.BuildString ( "<b>", Lib.Ellipsis(exp.name, Styles.ScaleStringLength(short_strings ? 24 : 38)), "</b> <size=", Styles.ScaleInteger(10).ToString(), ">", Lib.Ellipsis(exp.situation, Styles.ScaleStringLength((short_strings ? 32 : 62) - Lib.Ellipsis(exp.name, Styles.ScaleStringLength(short_strings ? 24 : 38)).Length)), "</size>" ); string exp_tooltip = Lib.BuildString ( exp.name, "\n", "<color=#aaaaaa>", exp.situation, "</color>" ); double exp_value = Science.value(filename, sample.size); if (exp_value > double.Epsilon) exp_tooltip = Lib.BuildString(exp_tooltip, "\n<b>", Lib.HumanReadableScience(exp_value), "</b>"); p.content(exp_label, Lib.HumanReadableDataSize(sample.size), exp_tooltip); p.icon(sample.analyze ? Icons.lab_cyan : Icons.lab_black, "Flag the file for analysis in a <b>laboratory</b>", () => { sample.analyze = !sample.analyze; }); p.icon(Icons.toggle_red, "Dump the sample", () => Lib.Popup ( "Warning!", Lib.BuildString("Do you really want to dump ", exp.fullname, "?"), new DialogGUIButton("Dump it", () => drive.samples.Remove(filename)), new DialogGUIButton("Keep it", () => { }) )); }
/// <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 static void Logman(this Panel p, Vessel v) { p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(40)), " <color=#cccccc>ALL LOGS</color>")); p.Width(Styles.ScaleWidthFloat(465.0f)); p.paneltype = Panel.PanelType.log; p.AddSection("LOGS"); if (Message.all_logs == null || Message.all_logs.Count == 0) { p.AddContent("<i>no logs</i>", string.Empty); } else { p.AddContent(String.Empty, String.Empty); //keeps it from bumping into the top for (int i = Message.all_logs.Count - 1; i >= 0; --i) //count backwards so most recent is first { Message.MessageObject log = Message.all_logs[i]; if (log.title != null) { p.AddContent(log.title.Replace("\n", " "), log.msg.Replace("\n", ". ")); } else { p.AddContent("<color=#DCDCDC><b>ALERT</b></color> ", log.msg.Replace("\n", ". ")); } if (Message.all_logs.Count > 1) { p.AddContent(String.Empty, String.Empty); //this avoids things flowing into each other. } } } }
public static void Logman(this Panel p, Vessel v) { p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(40)), " ", Lib.Color(Local.LogMan_ALLLOGS, Lib.Kolor.LightGrey))); //"ALL LOGS" p.Width(Styles.ScaleWidthFloat(465.0f)); p.paneltype = Panel.PanelType.log; p.AddSection(Local.LogMan_LOGS); //"LOGS" if (Message.all_logs == null || Message.all_logs.Count == 0) { p.AddContent("<i>" + Local.LogMan_nologs + "</i>", string.Empty); //no logs } else { p.AddContent(String.Empty, String.Empty); //keeps it from bumping into the top for (int i = Message.all_logs.Count - 1; i >= 0; --i) //count backwards so most recent is first { Message.MessageObject log = Message.all_logs[i]; if (log.title != null) { p.AddContent(log.title.Replace("\n", " "), log.msg.Replace("\n", ". ")); } else { p.AddContent(Lib.Color(Local.LogMan_ALERT, Lib.Kolor.Yellow), log.msg.Replace("\n", ". ")); //"ALERT " } if (Message.all_logs.Count > 1) { p.AddContent(String.Empty, String.Empty); //this avoids things flowing into each other. } } } }
static void Render_file(Panel p, string filename, File file, Drive drive, bool short_strings) { // get experiment info ExperimentInfo exp = Science.Experiment(filename); // render experiment name string exp_label = Lib.BuildString ( "<b>", Lib.Ellipsis(exp.name, Styles.ScaleStringLength(short_strings ? 24 : 38)), "</b> <size=", Styles.ScaleInteger(10).ToString(), ">", Lib.Ellipsis(exp.situation, Styles.ScaleStringLength((short_strings ? 32 : 62) - Lib.Ellipsis(exp.name, Styles.ScaleStringLength(short_strings ? 24 : 38)).Length)), "</size>" ); string exp_tooltip = Lib.BuildString ( exp.name, "\n", "<color=#aaaaaa>", exp.situation, "</color>" ); double exp_value = Science.Value(filename, file.size); if (exp_value > double.Epsilon) exp_tooltip = Lib.BuildString(exp_tooltip, "\n<b>", Lib.HumanReadableScience(exp_value), "</b>"); p.AddContent(exp_label, Lib.HumanReadableDataSize(file.size), exp_tooltip); p.AddIcon(file.send ? Icons.send_cyan : Icons.send_black, "Flag the file for transmission to <b>DSN</b>", () => { file.send = !file.send; }); p.AddIcon(Icons.toggle_red, "Delete the file", () => Lib.Popup ( "Warning!", Lib.BuildString("Do you really want to delete ", exp.fullname, "?"), new DialogGUIButton("Delete it", () => drive.files.Remove(filename)), new DialogGUIButton("Keep it", () => { }) )); }
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() && vd.group != filter) 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.header ( 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 void Failman(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 data VesselData vd = v.KerbalismData(); // if not a valid vessel, leave the panel empty if (!vd.IsSimulated) { return; } // set metadata p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(20)), " ", Lib.Color("Quality Management", Lib.Kolor.LightGrey))); p.Width(Styles.ScaleWidthFloat(355.0f)); p.paneltype = Panel.PanelType.failures; string section = string.Empty; // get devices List <ReliabilityInfo> devices = vd.ReliabilityStatus(); int deviceCount = 0; // for each device foreach (var ri in devices) { if (section != Group2Section(ri.group)) { section = Group2Section(ri.group); p.AddSection(section); } string status = StatusString(ri); // render device entry p.AddContent( label: ri.title, value: status, hover: () => Highlighter.Set(ri.partId, Color.blue)); deviceCount++; } // no devices case if (deviceCount == 0) { p.AddContent("<i>no quality info</i>"); } }
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 vessel data VesselData vd = v.KerbalismData(); // if not a valid vessel, leave the panel empty if (!vd.IsSimulated) { return; } // set metadata p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(20)), " ", Lib.Color(Local.TELEMETRY_title, Lib.Kolor.LightGrey))); //"TELEMETRY" p.Width(Styles.ScaleWidthFloat(355.0f)); p.paneltype = Panel.PanelType.telemetry; // time-out simulation if (p.Timeout(vd)) { return; } // get resources VesselResources resources = ResourceCache.Get(v); // get crew var crew = Lib.CrewList(v); // draw the content Render_crew(p, crew); if (Features.Science) { Render_science(p, v, vd); } Render_greenhouse(p, vd); Render_supplies(p, v, vd, resources); Render_habitat(p, v, vd); Render_environment(p, v, vd); // collapse eva kerbal sections into one if (v.isEVA) { p.Collapse(Local.TELEMETRY_EVASUIT); //"EVA SUIT" } }
/// <summary> /// Shows the Network status, ControlPath, Signal strength /// </summary> public static void ConnMan(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; } VesselData vd = v.KerbalismData(); // if not a valid vessel, leave the panel empty if (!vd.IsSimulated) { return; } // set metadata p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(40)), " ", Lib.Color(Local.ConnManager_title, Lib.Kolor.LightGrey))); //"CONNECTION MANAGER" p.Width(Styles.ScaleWidthFloat(365.0f)); p.paneltype = Panel.PanelType.connection; // time-out simulation if (!Lib.IsControlUnit(v) && p.Timeout(vd)) { return; } // draw ControlPath section p.AddSection(Local.ConnManager_CONTROLPATH); //"CONTROL PATH" if (vd.Connection.linked) { if (vd.Connection.control_path != null) { foreach (string[] hop in vd.Connection.control_path) { if (hop == null || hop.Length < 1) { continue; } string name = hop[0]; string value = hop.Length >= 2 ? hop[1] : ""; string tooltip = hop.Length >= 3 ? ("\n" + hop[2]) : ""; p.AddContent(name, value, tooltip); } } } else { p.AddContent("<i>" + Local.ConnManager_noconnection + "</i>", string.Empty); //no connection } }
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"); } }
static void Render_crew(Panel p, List<ProtoCrewMember> crew) { // do nothing if there isn't a crew, or if there are no rules if (crew.Count == 0 || Profile.rules.Count == 0) return; // panel section p.AddSection("VITALS"); // for each crew foreach (ProtoCrewMember kerbal in crew) { // get kerbal data from DB KerbalData kd = DB.Kerbal(kerbal.name); // analyze issues UInt32 health_severity = 0; UInt32 stress_severity = 0; // generate tooltip List<string> tooltips = new List<string>(); foreach (Rule r in Profile.rules) { // get rule data RuleData rd = kd.Rule(r.name); // add to the tooltip tooltips.Add(Lib.BuildString("<b>", Lib.HumanReadablePerc(rd.problem / r.fatal_threshold), "</b>\t", Lib.SpacesOnCaps(r.name).ToLower())); // analyze issue if (rd.problem > r.danger_threshold) { if (!r.breakdown) health_severity = Math.Max(health_severity, 2); else stress_severity = Math.Max(stress_severity, 2); } else if (rd.problem > r.warning_threshold) { if (!r.breakdown) health_severity = Math.Max(health_severity, 1); else stress_severity = Math.Max(stress_severity, 1); } } string tooltip = Lib.BuildString("<align=left />", String.Join("\n", tooltips.ToArray())); // generate kerbal name string name = kerbal.name.ToLower().Replace(" kerman", string.Empty); // render selectable title p.AddContent(Lib.Ellipsis(name, Styles.ScaleStringLength(30)), kd.disabled ? "<color=#00ffff>HYBERNATED</color>" : string.Empty); p.AddIcon(health_severity == 0 ? Icons.health_white : health_severity == 1 ? Icons.health_yellow : Icons.health_red, tooltip); p.AddIcon(stress_severity == 0 ? Icons.brain_white : stress_severity == 1 ? Icons.brain_yellow : Icons.brain_red, tooltip); } }
static void Render_file(Panel p, uint partId, string filename, File file, Drive drive, bool short_strings, Vessel v) { // get experiment info ExperimentInfo exp = Science.Experiment(filename); double rate = Cache.VesselInfo(v).connection.rate; // render experiment name string exp_label = Lib.BuildString ( "<b>", Lib.Ellipsis(exp.name, Styles.ScaleStringLength(short_strings ? 24 : 38)), "</b> <size=", Styles.ScaleInteger(10).ToString(), ">", Lib.Ellipsis(ExperimentInfo.Situation(filename), Styles.ScaleStringLength((short_strings ? 32 : 62) - Lib.Ellipsis(exp.name, Styles.ScaleStringLength(short_strings ? 24 : 38)).Length)), "</size>" ); string exp_tooltip = Lib.BuildString ( exp.name, "\n", "<color=#aaaaaa>", ExperimentInfo.Situation(filename), "</color>" ); double exp_value = Science.Value(filename, file.size); if (exp_value >= 0.1) { exp_tooltip = Lib.BuildString(exp_tooltip, "\n<b>", Lib.HumanReadableScience(exp_value), "</b>"); } if (rate > 0) { exp_tooltip = Lib.BuildString(exp_tooltip, "\n<i>" + Lib.HumanReadableDuration(file.size / rate) + "</i>"); } p.AddContent(exp_label, Lib.HumanReadableDataSize(file.size), exp_tooltip, (Action)null, () => Highlighter.Set(partId, Color.cyan)); bool send = drive.GetFileSend(filename); p.AddIcon(send ? Icons.send_cyan : Icons.send_black, "Flag the file for transmission to <b>DSN</b>", () => { drive.Send(filename, !send); }); p.AddIcon(Icons.toggle_red, "Delete the file", () => { Lib.Popup("Warning!", Lib.BuildString("Do you really want to delete ", exp.FullName(filename), "?"), new DialogGUIButton("Delete it", () => drive.Delete_file(filename, double.MaxValue, v.protoVessel)), new DialogGUIButton("Keep it", () => { })); } ); }
static void Render_sample(Panel p, uint partId, Sample sample, Drive drive, bool short_strings) { // render experiment name string exp_label = Lib.BuildString ( "<b>", Lib.Ellipsis(sample.subjectData.ExperimentTitle, Styles.ScaleStringLength(short_strings ? 24 : 38)), "</b> <size=", Styles.ScaleInteger(10).ToString(), ">", Lib.Ellipsis(sample.subjectData.SituationTitle, Styles.ScaleStringLength((short_strings ? 32 : 62) - Lib.Ellipsis(sample.subjectData.ExperimentTitle, Styles.ScaleStringLength(short_strings ? 24 : 38)).Length)), "</size>" ); string exp_tooltip = Lib.BuildString ( sample.subjectData.ExperimentTitle, "\n", Lib.Color(sample.subjectData.SituationTitle, Lib.Kolor.LightGrey) ); double exp_value = sample.size * sample.subjectData.SciencePerMB; if (exp_value >= 0.1) { exp_tooltip = Lib.BuildString(exp_tooltip, "\n<b>", Lib.HumanReadableScience(exp_value, false), "</b>"); } if (sample.mass > Double.Epsilon) { exp_tooltip = Lib.BuildString(exp_tooltip, "\n<b>", Lib.HumanReadableMass(sample.mass), "</b>"); } if (!string.IsNullOrEmpty(sample.resultText)) { exp_tooltip = Lib.BuildString(exp_tooltip, "\n", Lib.WordWrapAtLength(sample.resultText, 50)); } p.AddContent(exp_label, Lib.HumanReadableSampleSize(sample.size), exp_tooltip, (Action)null, () => Highlighter.Set(partId, Color.cyan)); p.AddRightIcon(sample.analyze ? Textures.lab_cyan : Textures.lab_black, Local.FILEMANAGER_analysis, () => { sample.analyze = !sample.analyze; }); //"Flag the file for analysis in a <b>laboratory</b>" p.AddRightIcon(Textures.toggle_red, Local.FILEMANAGER_Dumpsample, () => //"Dump the sample" { Lib.Popup(Local.FILEMANAGER_Warning_title, //"Warning!" Local.FILEMANAGER_DumpConfirm.Format(sample.subjectData.FullTitle), //"Do you really want to dump <<1>>?", new DialogGUIButton(Local.FILEMANAGER_DumpConfirm_button1, () => drive.Delete_sample(sample.subjectData)), //"Dump it" new DialogGUIButton(Local.FILEMANAGER_DumpConfirm_button2, () => { })); //"Keep it" } ); }
static void Render_sample(Panel p, uint partId, string filename, Sample sample, Drive drive, bool short_strings) { // get experiment info ExperimentInfo exp = Science.Experiment(filename); // render experiment name string exp_label = Lib.BuildString ( "<b>", Lib.Ellipsis(exp.name, Styles.ScaleStringLength(short_strings ? 24 : 38)), "</b> <size=", Styles.ScaleInteger(10).ToString(), ">", Lib.Ellipsis(ExperimentInfo.Situation(filename), Styles.ScaleStringLength((short_strings ? 32 : 62) - Lib.Ellipsis(exp.name, Styles.ScaleStringLength(short_strings ? 24 : 38)).Length)), "</size>" ); string exp_tooltip = Lib.BuildString ( exp.name, "\n", "<color=#aaaaaa>", ExperimentInfo.Situation(filename), "</color>" ); double exp_value = Science.Value(filename, sample.size); if (exp_value >= 0.1) { exp_tooltip = Lib.BuildString(exp_tooltip, "\n<b>", Lib.HumanReadableScience(exp_value), "</b>"); } if (sample.mass > Double.Epsilon) { exp_tooltip = Lib.BuildString(exp_tooltip, "\n<b>", Lib.HumanReadableMass(sample.mass), "</b>"); } p.AddContent(exp_label, Lib.HumanReadableSampleSize(sample.size), exp_tooltip, (Action)null, () => Highlighter.Set(partId, Color.cyan)); p.AddIcon(sample.analyze ? Icons.lab_cyan : Icons.lab_black, "Flag the file for analysis in a <b>laboratory</b>", () => { sample.analyze = !sample.analyze; }); p.AddIcon(Icons.toggle_red, "Dump the sample", () => { Lib.Popup("Warning!", Lib.BuildString("Do you really want to dump ", exp.FullName(filename), "?"), new DialogGUIButton("Dump it", () => drive.samples.Remove(filename)), new DialogGUIButton("Keep it", () => { })); } ); }
// to be called as window refresh function void window_body(Panel p) { // outside the editor if (!Lib.IsEditor()) { // if part doesn't exist anymore if (FlightGlobals.FindPartByID(part.flightID) == null) { return; } } // inside the editor else { // if the part doesn't exist anymore (eg: removed, user hit undo) if (GetInstanceID() == 0) { return; } } // for each selected setup for (int selected_i = 0; selected_i < selected.Count; ++selected_i) { // find index in unlocked setups for (int setup_i = 0; setup_i < unlocked.Count; ++setup_i) { if (unlocked[setup_i].name == selected[selected_i]) { // commit panel render_panel(p, unlocked[setup_i], selected_i, setup_i); } } } // set metadata p.title(Lib.BuildString("Configure <color=#cccccc>", Lib.Ellipsis(title, Styles.ScaleStringLength(40)), "</color>")); p.width(Styles.ScaleWidthFloat(300.0f)); }
void render_panel(Panel p, ConfigureSetup setup, int selected_i, int setup_i) { // generate details, just once // note: details were once elegantly serialized among all the other setup data, // see comment inside generate_details() to understand why this was necessary instead setup.generate_details(this); // render panel title // only allow reconfiguration if there are more setups than slots if (unlocked.Count <= selected.Count) { p.section(Lib.Ellipsis(setup.name, Styles.ScaleStringLength(70)), setup.desc); } else { p.section(Lib.Ellipsis(setup.name, Styles.ScaleStringLength(70)), setup.desc, () => change_setup(-1, selected_i, ref setup_i), () => change_setup(1, selected_i, ref setup_i)); } // render details foreach (var det in setup.details) { p.content(det.label, det.value); } }
/// <summary> /// Shows the Network status, ControlPath, Signal strength /// </summary> public static void ConnMan(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(40)), " <color=#cccccc>CONNECTION MANAGER</color>")); p.Width(Styles.ScaleWidthFloat(365.0f)); p.paneltype = Panel.PanelType.connection; // time-out simulation if (p.Timeout(vi)) { return; } // draw ControlPath section p.AddSection("CONTROL PATH"); if (vi.connection.linked) { if (RemoteTech.Enabled) { if (vi.connection.controlPath != null) { Guid i = v.id; foreach (Guid id in vi.connection.controlPath) { p.AddContent( Lib.Ellipsis(RemoteTech.GetSatelliteName(i) + " \\ " + RemoteTech.GetSatelliteName(id), 35), Lib.HumanReadablePerc(Math.Ceiling((1 - (RemoteTech.GetCommsDistance(i, id) / RemoteTech.GetCommsMaxDistance(i, id))) * 10000) / 10000, "F2"), "\nDistance: " + Lib.HumanReadableRange(RemoteTech.GetCommsDistance(i, id)) + "\nMax Distance: " + Lib.HumanReadableRange(RemoteTech.GetCommsMaxDistance(i, id))); i = id; } } } if (HighLogic.fetch.currentGame.Parameters.Difficulty.EnableCommNet) { foreach (CommLink link in v.connection.ControlPath) { double antennaPower = link.end.isHome ? link.start.antennaTransmit.power + link.start.antennaRelay.power : link.start.antennaTransmit.power; double signalStrength = 1 - ((link.start.position - link.end.position).magnitude / Math.Sqrt(antennaPower * link.end.antennaRelay.power)); signalStrength = (3 - (2 * signalStrength)) * Math.Pow(signalStrength, 2); p.AddContent( Lib.Ellipsis(Localizer.Format(link.end.name).Replace("Kerbin", "DSN"), 35), Lib.HumanReadablePerc(Math.Ceiling(signalStrength * 10000) / 10000, "F2"), "\nDistance: " + Lib.HumanReadableRange((link.start.position - link.end.position).magnitude) + "\nMax Distance: " + Lib.HumanReadableRange(Math.Sqrt((link.start.antennaTransmit.power + link.start.antennaRelay.power) * link.end.antennaRelay.power)) ); } } } else { p.AddContent("<i>no connection</i>", string.Empty); } }
/// <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 (!Lib.IsControlUnit(v) && p.Timeout(vi)) { return; } var drives = Drive.GetDriveParts(v); int filesCount = 0; double usedDataCapacity = 0; double totalDataCapacity = 0; int samplesCount = 0; int usedSlots = 0; int totalSlots = 0; double totalMass = 0; bool unlimitedData = false; bool unlimitedSamples = false; foreach (var idDrivePair in drives) { var drive = idDrivePair.Value; if (!drive.is_private) { usedDataCapacity += drive.FilesSize(); totalDataCapacity += drive.dataCapacity; unlimitedData |= drive.dataCapacity < 0; unlimitedSamples |= drive.sampleCapacity < 0; usedSlots += drive.SamplesSize(); totalSlots += drive.sampleCapacity; } filesCount += drive.files.Count; samplesCount += drive.samples.Count; foreach (var sample in drive.samples.Values) { totalMass += sample.mass; } } if (filesCount > 0 || totalDataCapacity > 0) { var title = "DATA " + Lib.HumanReadableDataSize(usedDataCapacity); if (!unlimitedData) { title += Lib.BuildString(" (", Lib.HumanReadablePerc((totalDataCapacity - usedDataCapacity) / totalDataCapacity), " available)"); } p.AddSection(title); foreach (var idDrivePair in drives) { uint partId = idDrivePair.Key; var drive = idDrivePair.Value; foreach (var pair in drive.files) { string filename = pair.Key; File file = pair.Value; Render_file(p, partId, filename, file, drive, short_strings && Lib.IsFlight(), v); } } if (filesCount == 0) { p.AddContent("<i>no files</i>", string.Empty); } } if (samplesCount > 0 || totalSlots > 0) { var title = "SAMPLES " + Lib.HumanReadableMass(totalMass) + " " + Lib.HumanReadableSampleSize(usedSlots); if (totalSlots > 0 && !unlimitedSamples) { title += ", " + Lib.HumanReadableSampleSize(totalSlots) + " available"; } p.AddSection(title); foreach (var idDrivePair in drives) { uint partId = idDrivePair.Key; var drive = idDrivePair.Value; foreach (var pair in drive.samples) { string samplename = pair.Key; Sample sample = pair.Value; Render_sample(p, partId, samplename, sample, drive, short_strings && Lib.IsFlight()); } } if (samplesCount == 0) { p.AddContent("<i>no samples</i>", string.Empty); } } }
public static void Devman(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 data VesselData vd = v.KerbalismData(); // if not a valid vessel, leave the panel empty if (!vd.IsSimulated) { return; } // set metadata p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(20)), Lib.Color("#KERBALISM_UI_devman", Lib.Kolor.LightGrey))); p.Width(Styles.ScaleWidthFloat(355.0f)); p.paneltype = Panel.PanelType.scripts; // time-out simulation if (!Lib.IsControlUnit(v) && p.Timeout(vd)) { return; } // get devices List <Device> devices = Computer.GetModuleDevices(v); int deviceCount = 0; // direct control if (script_index == 0) { // draw section title and desc p.AddSection ( Localizer.Format("#KERBALISM_UI_devices"), Description(), () => p.Prev(ref script_index, (int)ScriptType.last), () => p.Next(ref script_index, (int)ScriptType.last), false ); bool hasVesselDeviceSection = false; bool hasModuleDeviceSection = false; // for each device for (int i = devices.Count - 1; i >= 0; i--) { Device dev = devices[i]; dev.OnUpdate(); if (!dev.IsVisible) { continue; } // create vessel device section if necessary if (dev is VesselDevice) { if (!hasVesselDeviceSection) { p.AddSection("VESSEL DEVICES"); hasVesselDeviceSection = true; } } // create module device section if necessary else { if (!hasModuleDeviceSection) { p.AddSection("MODULE DEVICES"); hasModuleDeviceSection = true; } } if (dev.PartId != 0u) { p.AddContent(dev.DisplayName, dev.Status, dev.Tooltip, dev.Toggle, () => Highlighter.Set(dev.PartId, Color.cyan)); } else { p.AddContent(dev.DisplayName, dev.Status, dev.Tooltip, dev.Toggle); } if (dev.Icon != null) { p.SetLeftIcon(dev.Icon.texture, dev.Icon.tooltip, dev.Icon.onClick); } deviceCount++; } } // script editor else { // get script ScriptType script_type = (ScriptType)script_index; string script_name = script_type.ToString().Replace('_', ' ').ToUpper(); Script script = v.KerbalismData().computer.Get(script_type); // draw section title and desc p.AddSection ( script_name, Description(), () => p.Prev(ref script_index, (int)ScriptType.last), () => p.Next(ref script_index, (int)ScriptType.last) ); bool hasVesselDeviceSection = false; bool hasModuleDeviceSection = false; // for each device for (int i = devices.Count - 1; i >= 0; i--) { Device dev = devices[i]; dev.OnUpdate(); if (!dev.IsVisible) { continue; } // determine tribool state int state = !script.states.ContainsKey(dev.Id) ? -1 : !script.states[dev.Id] ? 0 : 1; // create vessel device section if necessary if (dev is VesselDevice) { if (!hasVesselDeviceSection) { p.AddSection("VESSEL DEVICES"); hasVesselDeviceSection = true; } } // create module device section if necessary else { if (!hasModuleDeviceSection) { p.AddSection("MODULE DEVICES"); hasModuleDeviceSection = true; } } // render device entry p.AddContent ( dev.DisplayName, state == -1 ? Lib.Color(Localizer.Format("#KERBALISM_UI_dontcare"), Lib.Kolor.DarkGrey) : Lib.Color(state == 0, Localizer.Format("#KERBALISM_Generic_OFF"), Lib.Kolor.Yellow, Localizer.Format("#KERBALISM_Generic_ON"), Lib.Kolor.Green), string.Empty, () => { switch (state) { case -1: script.Set(dev, true); break; case 0: script.Set(dev, null); break; case 1: script.Set(dev, false); break; } }, () => Highlighter.Set(dev.PartId, Color.cyan) ); deviceCount++; } } // no devices case if (deviceCount == 0) { p.AddContent("<i>no devices</i>"); } }
/// <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 VesselData vd = v.KerbalismData(); // if not a valid vessel, leave the panel empty if (!vd.IsSimulated) { return; } // set metadata p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(40)), " ", Lib.Color(Local.FILEMANAGER_title, Lib.Kolor.LightGrey))); //"FILE MANAGER" p.Width(Styles.ScaleWidthFloat(465.0f)); p.paneltype = Panel.PanelType.data; // time-out simulation if (!Lib.IsControlUnit(v) && p.Timeout(vd)) { return; } List <ObjectPair <uint, Drive> > drives = new List <ObjectPair <uint, Drive> >(); int filesCount = 0; double usedDataCapacity = 0; double totalDataCapacity = 0; int samplesCount = 0; int usedSlots = 0; int totalSlots = 0; double totalMass = 0; bool unlimitedData = false; bool unlimitedSamples = false; foreach (PartData partData in vd.PartDatas) { Drive drive = partData.Drive; if (drive == null) { continue; } drives.Add(new ObjectPair <uint, Drive>(partData.FlightId, drive)); if (!drive.is_private) { usedDataCapacity += drive.FilesSize(); totalDataCapacity += drive.dataCapacity; unlimitedData |= drive.dataCapacity < 0; unlimitedSamples |= drive.sampleCapacity < 0; usedSlots += drive.SamplesSize(); totalSlots += drive.sampleCapacity; } filesCount += drive.files.Count; samplesCount += drive.samples.Count; foreach (var sample in drive.samples.Values) { totalMass += sample.mass; } } if (filesCount > 0 || totalDataCapacity > 0) { var title = Local.FILEMANAGER_DataCapacity + " " + Lib.HumanReadableDataSize(usedDataCapacity); //"DATA " if (!unlimitedData) { title += Local.FILEMANAGER_DataAvailable.Format(Lib.HumanReadablePerc((totalDataCapacity - usedDataCapacity) / totalDataCapacity)); //Lib.BuildString(" (", Lib.HumanReadablePerc((totalDataCapacity - usedDataCapacity) / totalDataCapacity), " available)"); } p.AddSection(title); foreach (var drive in drives) { foreach (File file in drive.Value.files.Values) { Render_file(p, drive.Key, file, drive.Value, short_strings && Lib.IsFlight(), v); } } if (filesCount == 0) { p.AddContent("<i>" + Local.FILEMANAGER_nofiles + "</i>", string.Empty); //no files } } if (samplesCount > 0 || totalSlots > 0) { var title = Local.FILEMANAGER_SAMPLESMass.Format(Lib.HumanReadableMass(totalMass)) + " " + Lib.HumanReadableSampleSize(usedSlots); //"SAMPLES " + if (totalSlots > 0 && !unlimitedSamples) { title += ", " + Lib.HumanReadableSampleSize(totalSlots) + " " + Local.FILEMANAGER_SAMPLESAvailable; //available } p.AddSection(title); foreach (var drive in drives) { foreach (Sample sample in drive.Value.samples.Values) { Render_sample(p, drive.Key, sample, drive.Value, short_strings && Lib.IsFlight()); } } if (samplesCount == 0) { p.AddContent("<i>" + Local.FILEMANAGER_nosamples + "</i>", string.Empty); //no samples } } }
static void Render_file(Panel p, uint partId, File file, Drive drive, bool short_strings, Vessel v) { // render experiment name string exp_label = Lib.BuildString ( "<b>", Lib.Ellipsis(file.subjectData.ExperimentTitle, Styles.ScaleStringLength(short_strings ? 24 : 38)), "</b> <size=", Styles.ScaleInteger(10).ToString(), ">", Lib.Ellipsis(file.subjectData.SituationTitle, Styles.ScaleStringLength((short_strings ? 32 : 62) - Lib.Ellipsis(file.subjectData.ExperimentTitle, Styles.ScaleStringLength(short_strings ? 24 : 38)).Length)), "</size>" ); string exp_tooltip = Lib.BuildString ( file.subjectData.ExperimentTitle, "\n", Lib.Color(file.subjectData.SituationTitle, Lib.Kolor.LightGrey) ); double exp_value = file.size * file.subjectData.SciencePerMB; if (file.subjectData.ScienceRemainingToRetrieve > 0f && file.size > 0.0) { exp_tooltip = Lib.BuildString(exp_tooltip, "\n<b>", Lib.HumanReadableScience(exp_value, false), "</b>"); } if (file.transmitRate > 0.0) { if (file.size > 0.0) { exp_tooltip = Lib.Color(Lib.BuildString(exp_tooltip, "\n", Local.FILEMANAGER_TransmittingRate.Format(Lib.HumanReadableDataRate(file.transmitRate)), " : <i>", Lib.HumanReadableCountdown(file.size / file.transmitRate), "</i>"), Lib.Kolor.Cyan); //Transmitting at <<1>> } else { exp_tooltip = Lib.Color(Lib.BuildString(exp_tooltip, "\n", Local.FILEMANAGER_TransmittingRate.Format(Lib.HumanReadableDataRate(file.transmitRate))), Lib.Kolor.Cyan); //Transmitting at <<1>> } } else if (v.KerbalismData().Connection.rate > 0.0) { exp_tooltip = Lib.BuildString(exp_tooltip, "\n", Local.FILEMANAGER_Transmitduration, "<i>", Lib.HumanReadableDuration(file.size / v.KerbalismData().Connection.rate), "</i>"); //Transmit duration : } if (!string.IsNullOrEmpty(file.resultText)) { exp_tooltip = Lib.BuildString(exp_tooltip, "\n", Lib.WordWrapAtLength(file.resultText, 50)); } string size; if (file.transmitRate > 0.0) { if (file.size == 0.0) { size = Lib.Color(Lib.BuildString("↑ ", Lib.HumanReadableDataRate(file.transmitRate)), Lib.Kolor.Cyan); } else { size = Lib.Color(Lib.BuildString("↑ ", Lib.HumanReadableDataSize(file.size)), Lib.Kolor.Cyan); } } else { size = Lib.HumanReadableDataSize(file.size); } p.AddContent(exp_label, size, exp_tooltip, (Action)null, () => Highlighter.Set(partId, Color.cyan)); bool send = drive.GetFileSend(file.subjectData.Id); p.AddRightIcon(send ? Textures.send_cyan : Textures.send_black, Local.FILEMANAGER_send, () => { drive.Send(file.subjectData.Id, !send); }); //"Flag the file for transmission to <b>DSN</b>" p.AddRightIcon(Textures.toggle_red, Local.FILEMANAGER_Delete, () => //"Delete the file" { Lib.Popup(Local.FILEMANAGER_Warning_title, //"Warning!" Local.FILEMANAGER_DeleteConfirm.Format(file.subjectData.FullTitle), //Lib.BuildString(, "?"),//"Do you really want to delete <<1>>", new DialogGUIButton(Local.FILEMANAGER_DeleteConfirm_button1, () => drive.Delete_file(file.subjectData)), //"Delete it" new DialogGUIButton(Local.FILEMANAGER_DeleteConfirm_button2, () => { })); //"Keep it" } ); }
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.AddSection("SURFACE"); p.AddContent("temperature", temperature_str); p.AddContent("solar flux", Lib.HumanReadableFlux(solar_flux)); if (Features.Radiation) p.AddContent("radiation", Lib.HumanReadableRadiation(radiation)); // atmosphere panel if (body.atmosphere) { p.AddSection("ATMOSPHERE"); p.AddContent("breathable", Sim.Breathable(body) ? "yes" : "no"); p.AddContent("light absorption", Lib.HumanReadablePerc(1.0 - Sim.AtmosphereFactor(body, 0.7071))); if (Features.Radiation) p.AddContent("gamma absorption", Lib.HumanReadablePerc(1.0 - Sim.GammaTransparency(body, 0.0))); } } // radiation panel if (Features.Radiation) { p.AddSection("RADIATION"); string inner, outer, pause; RadiationLevels(body, out inner, out outer, out pause); p.AddContent(Lib.BuildString("inner belt: ", Lib.Color("#cccccc", inner)), Radiation.show_inner ? "<color=green>show</color>" : "<color=red>hide</color>", string.Empty, () => p.Toggle(ref Radiation.show_inner)); p.AddContent(Lib.BuildString("outer belt: ", Lib.Color("#cccccc", outer)), Radiation.show_outer ? "<color=green>show</color>" : "<color=red>hide</color>", string.Empty, () => p.Toggle(ref Radiation.show_outer)); p.AddContent(Lib.BuildString("magnetopause: ", Lib.Color("#cccccc", pause)), 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.AddContent(string.Empty); p.AddContent("<i>Press <b>B</b> to open this window again</i>"); // set metadata p.Title(Lib.BuildString(Lib.Ellipsis(body.bodyName, Styles.ScaleStringLength(24)), " <color=#cccccc>BODY INFO</color>")); }
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 static void Devman(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>" + Localizer.Format("#KERBALISM_UI_devman") + "</color>")); p.Width(Styles.ScaleWidthFloat(355.0f)); p.paneltype = Panel.PanelType.scripts; // time-out simulation if (!Lib.IsControlUnit(v) && p.Timeout(vi)) { return; } // get devices Dictionary <uint, Device> devices = Computer.Boot(v); int deviceCount = 0; // direct control if (script_index == 0) { // draw section title and desc p.AddSection ( Localizer.Format("#KERBALISM_UI_devices"), Description(), () => p.Prev(ref script_index, (int)ScriptType.last), () => p.Next(ref script_index, (int)ScriptType.last), true ); // for each device foreach (var pair in devices) { // render device entry Device dev = pair.Value; if (!dev.IsVisible()) { continue; } p.AddContent(dev.Name(), dev.Info(), string.Empty, dev.Toggle, () => Highlighter.Set(dev.Part(), Color.cyan)); deviceCount++; } } // script editor else { // get script ScriptType script_type = (ScriptType)script_index; string script_name = script_type.ToString().Replace('_', ' ').ToUpper(); Script script = DB.Vessel(v).computer.Get(script_type); // draw section title and desc p.AddSection ( script_name, Description(), () => p.Prev(ref script_index, (int)ScriptType.last), () => p.Next(ref script_index, (int)ScriptType.last), true ); // for each device foreach (var pair in devices) { Device dev = pair.Value; if (!dev.IsVisible()) { continue; } // determine tribool state int state = !script.states.ContainsKey(pair.Key) ? -1 : !script.states[pair.Key] ? 0 : 1; // render device entry p.AddContent ( dev.Name(), state == -1 ? "<color=#999999>" + Localizer.Format("#KERBALISM_UI_dontcare") + " </color>" : state == 0 ? "<color=red>" + Localizer.Format("#KERBALISM_Generic_OFF") + "</color>" : "<color=cyan>" + Localizer.Format("#KERBALISM_Generic_ON") + "</color>", string.Empty, () => { switch (state) { case -1: script.Set(dev, true); break; case 0: script.Set(dev, null); break; case 1: script.Set(dev, false); break; } }, () => Highlighter.Set(dev.Part(), Color.cyan) ); deviceCount++; } } // no devices case if (deviceCount == 0) { p.AddContent("<i>no devices</i>"); } }
public void Update() { var exp = Science.Experiment(experiment_id); // in flight if (Lib.IsFlight()) { Vessel v = FlightGlobals.ActiveVessel; if (v == null || EVA.IsDead(v)) { return; } // get info from cache Vessel_info vi = Cache.VesselInfo(vessel); // do nothing if vessel is invalid if (!vi.is_valid) { return; } var sampleSize = exp.max_amount; var eta = data_rate < double.Epsilon || Done(exp, dataSampled) ? " done" : " " + Lib.HumanReadableCountdown((sampleSize - dataSampled) / data_rate); // update ui var title = Lib.Ellipsis(exp.name, Styles.ScaleStringLength(24)); if (scienceValue > 0.1) { title += " •<b>" + scienceValue.ToString("F1") + "</b>"; } string statusString = string.Empty; switch (state) { case State.ISSUE: statusString = Lib.Color("yellow", issue); break; case State.RUNNING: statusString = Lib.HumanReadablePerc(dataSampled / sampleSize) + eta; break; case State.WAITING: statusString = "waiting" + eta; break; case State.STOPPED: statusString = "stopped"; break; } Events["Toggle"].guiName = Lib.StatusToggle(title, statusString); Events["Toggle"].active = (prepare_cs == null || didPrepare); Events["Prepare"].guiName = Lib.BuildString("Prepare <b>", exp.name, "</b>"); Events["Prepare"].active = !didPrepare && prepare_cs != null && string.IsNullOrEmpty(last_subject_id); Events["Reset"].guiName = Lib.BuildString("Reset <b>", exp.name, "</b>"); // we need a reset either if we have recorded data or did a setup bool resetActive = (reset_cs != null || prepare_cs != null) && !string.IsNullOrEmpty(last_subject_id); Events["Reset"].active = resetActive; if (issue.Length > 0 && hide_when_unavailable && issue != insufficient_storage) { Events["Toggle"].active = false; } } // in the editor else if (Lib.IsEditor()) { // update ui Events["Toggle"].guiName = Lib.StatusToggle(exp.name, recording ? "recording" : "stopped"); Events["Reset"].active = false; Events["Prepare"].active = false; } }
public static void config(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>VESSEL CONFIG</color>")); p.width(Styles.ScaleWidthFloat(355.0f)); p.paneltype = Panel.PanelType.config; // time-out simulation if (p.timeout(vi)) { return; } // get data from db VesselData vd = DB.Vessel(v); // toggle rendering string tooltip; if (Features.Reliability) { p.section("RENDERING"); } if (Features.Reliability) { tooltip = "Highlight failed components"; p.content("highlight malfunctions", string.Empty, tooltip); p.icon(vd.cfg_highlights ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.toggle(ref vd.cfg_highlights)); } // toggle messages p.section("MESSAGES"); tooltip = "Receive a message when\nElectricCharge level is low"; p.content("battery", string.Empty, tooltip); p.icon(vd.cfg_ec ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.toggle(ref vd.cfg_ec)); if (Features.Supplies) { tooltip = "Receive a message when\nsupply resources level is low"; p.content("supply", string.Empty, tooltip); p.icon(vd.cfg_supply ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.toggle(ref vd.cfg_supply)); } if (RemoteTech.Enabled() || HighLogic.fetch.currentGame.Parameters.Difficulty.EnableCommNet) { tooltip = "Receive a message when signal is lost or obtained"; p.content("signal", string.Empty, tooltip); p.icon(vd.cfg_signal ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.toggle(ref vd.cfg_signal)); } if (Features.Reliability) { tooltip = "Receive a message\nwhen a component fail"; p.content("reliability", string.Empty, tooltip); p.icon(vd.cfg_malfunction ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.toggle(ref vd.cfg_malfunction)); } if (Features.SpaceWeather) { tooltip = "Receive a message\nduring CME events"; p.content("storm", string.Empty, tooltip); p.icon(vd.cfg_storm ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.toggle(ref vd.cfg_storm)); } if (Features.Automation) { tooltip = "Receive a message when\nscripts are executed"; p.content("script", string.Empty, tooltip); p.icon(vd.cfg_script ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.toggle(ref vd.cfg_script)); } }
bool Render_vessel(Panel p, Vessel v, bool selected = false) { // 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); // 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(); // skip filtered vessels if (!Filter_match(v.vesselType, vd.group + " " + body_name + " " + vessel_name)) { return(false); } // 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()) ? 45 : 25)), "</b> <size=", Styles.ScaleInteger(9).ToString(), ">", Lib.Color("#cccccc", Lib.Ellipsis(body_name, Styles.ScaleStringLength(8))), "</size>"), string.Empty, () => { selected_id = selected_id != v.id ? v.id : Guid.Empty; } ); // vessel type icon if (!selected) { p.SetIcon(GetVesselTypeIcon(v.vesselType), v.vesselType.displayDescription(), () => { selected_id = selected_id != v.id ? v.id : Guid.Empty; }); } else { if (FlightGlobals.ActiveVessel != v) { if (Lib.IsFlight()) { p.SetIcon(GetVesselTypeIcon(v.vesselType), "Go to vessel!", () => Lib.Popup ("Warning!", Lib.BuildString("Do you really want go to ", vessel_name, " vessel?"), new DialogGUIButton("Go", () => { GotoVessel.JumpToVessel(v); }), new DialogGUIButton("Target", () => { GotoVessel.SetVesselAsTarget(v); }), new DialogGUIButton("Stay", () => { }))); } else { p.SetIcon(GetVesselTypeIcon(v.vesselType), "Go to vessel!", () => Lib.Popup ("Warning!", Lib.BuildString("Do you really want go to ", vessel_name, " vessel?"), new DialogGUIButton("Go", () => { GotoVessel.JumpToVessel(v); }), new DialogGUIButton("Stay", () => { }))); } } else { p.SetIcon(GetVesselTypeIcon(v.vesselType), v.vesselType.displayDescription(), () => { }); } } // 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 (API.Comm.handlers.Count > 0 || HighLogic.fetch.currentGame.Parameters.Difficulty.EnableCommNet) { Indicator_signal(p, v, vi); } // done return(true); }
public static void Config(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 vessel data VesselData vd = v.KerbalismData(); // if not a valid vessel, leave the panel empty if (!vd.IsSimulated) return; // set metadata p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(20)), " ", Lib.Color(Local.VESSELCONFIG_title, Lib.Kolor.LightGrey)));//"VESSEL CONFIG" p.Width(Styles.ScaleWidthFloat(355.0f)); p.paneltype = Panel.PanelType.config; // toggle rendering string tooltip; if (Features.Reliability) { p.AddSection(Local.VESSELCONFIG_RENDERING);//"RENDERING" } if (Features.Reliability) { tooltip = Local.VESSELCONFIG_Highlightfailed_desc;//"Highlight failed components" p.AddContent(Local.VESSELCONFIG_Highlightfailed, string.Empty, tooltip);//"highlight malfunctions" p.AddRightIcon(vd.cfg_highlights ? Textures.toggle_green : Textures.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_highlights)); } // toggle messages p.AddSection(Local.VESSELCONFIG_MESSAGES);//"MESSAGES" tooltip = Local.VESSELCONFIG_EClow;//"Receive a message when\nElectricCharge level is low" p.AddContent(Local.VESSELCONFIG_battery, string.Empty, tooltip);//"battery" p.AddRightIcon(vd.cfg_ec ? Textures.toggle_green : Textures.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_ec)); if (Features.Supplies) { tooltip = Local.VESSELCONFIG_Supplylow;//"Receive a message when\nsupply resources level is low" p.AddContent(Local.VESSELCONFIG_supply, string.Empty, tooltip);//"supply" p.AddRightIcon(vd.cfg_supply ? Textures.toggle_green : Textures.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_supply)); } if (API.Comm.handlers.Count > 0 || HighLogic.fetch.currentGame.Parameters.Difficulty.EnableCommNet) { tooltip = Local.VESSELCONFIG_Signallost;//"Receive a message when signal is lost or obtained" p.AddContent(Local.VESSELCONFIG_signal, string.Empty, tooltip);//"signal" p.AddRightIcon(vd.cfg_signal ? Textures.toggle_green : Textures.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_signal)); } if (Features.Reliability) { tooltip = Local.VESSELCONFIG_Componentfail;//"Receive a message\nwhen a component fail" p.AddContent(Local.VESSELCONFIG_reliability, string.Empty, tooltip);//"reliability" p.AddRightIcon(vd.cfg_malfunction ? Textures.toggle_green : Textures.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_malfunction)); } if (Features.SpaceWeather) { tooltip = Local.VESSELCONFIG_CMEevent;//"Receive a message\nduring CME events" p.AddContent(Local.VESSELCONFIG_storm, string.Empty, tooltip);//"storm" p.AddRightIcon(vd.cfg_storm ? Textures.toggle_green : Textures.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_storm)); } if (Features.Automation) { tooltip = Local.VESSELCONFIG_ScriptExe;//"Receive a message when\nscripts are executed" p.AddContent(Local.VESSELCONFIG_script, string.Empty, tooltip);//"script" p.AddRightIcon(vd.cfg_script ? Textures.toggle_green : Textures.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_script)); } }