void FromEVA(GameEvents.FromToAction <Part, Part> data) { String prop_name = Lib.EvaPropellantName(); // for each resource in the eva kerbal for (int i = 0; i < data.from.Resources.Count; ++i) { // get the resource PartResource res = data.from.Resources[i]; // add leftovers to the vessel data.to.RequestResource(res.resourceName, -res.amount); } // merge drives data Drive.Transfer(data.from.vessel, data.to.vessel, true); // forget vessel data DB.vessels.Remove(Lib.VesselID(data.from.vessel)); Drive.Purge(data.from.vessel); Cache.PurgeObjects(data.from.vessel); Cache.PurgeObjects(data.to.vessel); // execute script DB.Vessel(data.to.vessel).computer.Execute(data.to.vessel, ScriptType.eva_in); }
// execute a script public void execute(Vessel v, ScriptType type) { // do nothing if there is no EC left on the vessel resource_info ec = ResourceCache.Info(v, "ElectricCharge"); if (ec.amount <= double.Epsilon) { return; } // get the script Script script; if (scripts.TryGetValue(type, out script)) { // execute the script script.execute(boot(v)); // show message to the user // - unless the script is empty (can happen when being edited) if (script.states.Count > 0 && DB.Vessel(v).cfg_script) { Message.Post(Lib.BuildString("Script called on vessel <b>", v.vesselName, "</b>")); } } }
// return name of file being transmitted from vessel specified public static string transmitting(Vessel v, bool linked) { // never transmitting if science system is disabled if (!Features.Science) { return(string.Empty); } // not transmitting if unlinked if (!linked) { return(string.Empty); } // not transmitting if there is no ec left if (ResourceCache.Info(v, "ElectricCharge").amount <= double.Epsilon) { return(string.Empty); } // get vessel drive Drive drive = DB.Vessel(v).drive; // get first file flagged for transmission foreach (var p in drive.files) { if (p.Value.send) { return(p.Key); } } // no file flagged for transmission return(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 (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 override void OnStart(StartState state) { // don't break tutorial scenarios if (Lib.DisableScenario(this)) { return; } // set UI text Actions["Action"].guiName = Localizer.Format("#KERBALISM_Laboratory_Action"); Events["CleanExperiments"].guiName = Localizer.Format("#KERBALISM_Laboratory_Clean"); // do nothing in the editors and when compiling parts if (!Lib.IsFlight()) { return; } // parse crew specs researcher_cs = new CrewSpecs(researcher); var hardDrive = part.FindModuleImplementing <HardDrive>(); if (hardDrive != null) { drive = hardDrive.GetDrive(); } else { drive = DB.Vessel(vessel).BestDrive(); } }
// science container implementation public ScienceData[] GetData() { // get drive Drive drive = DB.Vessel(vessel).drive; // if not the preferred drive if (drive.location != part.flightID) { return(new ScienceData[0]); } // generate and return stock science data List <ScienceData> data = new List <ScienceData>(); foreach (var pair in drive.files) { File file = pair.Value; data.Add(new ScienceData((float)file.size, 1.0f, 1.0f, pair.Key, Science.experiment(pair.Key).fullname)); } foreach (var pair in drive.samples) { Sample sample = pair.Value; data.Add(new ScienceData((float)sample.size, 0.0f, 0.0f, pair.Key, Science.experiment(pair.Key).fullname)); } return(data.ToArray()); }
// analyze a sample static void analyze(Vessel v, string filename, double amount) { // get vessel drive Drive drive = DB.Vessel(v).drive; // get sample Sample sample = drive.samples[filename]; // analyze, and produce data amount = Math.Min(amount, sample.size); bool completed = amount >= sample.size - double.Epsilon; drive.delete_sample(filename, amount); drive.record_file(filename, amount); // if the analysis is completed if (completed) { // inform the user Message.Post ( Lib.BuildString("<color=cyan><b>ANALYSIS COMPLETED</b></color>\nOur laboratory on <b>", v.vesselName, "</b> analyzed <b>", Science.experiment(filename).name, "</b>"), "The results can be transmitted now" ); // record landmark event if (!Lib.Landed(v)) { DB.landmarks.space_analysis = true; } } }
// analyze a sample private static void Analyze(Vessel v, string filename, double amount) { // get vessel drive Drive drive = DB.Vessel(v).drive; // get sample Sample sample = drive.samples[filename]; // analyze, and produce data amount = Math.Min(amount, sample.size); bool completed = amount >= sample.size - double.Epsilon; drive.Delete_sample(filename, amount); drive.Record_file(filename, amount); // if the analysis is completed if (completed) { // inform the user Message.Post(Lib.BuildString(Lib.Color("cyan", Localizer.Format("#KERBALISM_Laboratory_Analysis"), true), "\n", Localizer.Format("#KERBALISM_Laboratory_Analyzed", Lib.Bold(v.vesselName), Lib.Bold(Science.Experiment(filename).name))), localized_results); // record landmark event if (!Lib.Landed(v)) { DB.landmarks.space_analysis = true; } } }
void render_menu(Vessel v) { const string tooltip = "\n<i>(middle-click to popout in a window)</i>"; VesselData vd = DB.Vessel(v); GUILayout.BeginHorizontal(Styles.entry_container); GUILayout.Label(new GUIContent(page == MonitorPage.telemetry ? " <color=#00ffff>INFO</color> " : " INFO ", Icons.small_info, "Telemetry readings" + tooltip), config_style); if (Lib.IsClicked()) page = MonitorPage.telemetry; else if (Lib.IsClicked(2)) UI.open((p) => p.telemetry(v)); if (Features.Science) { GUILayout.Label(new GUIContent(page == MonitorPage.data ? " <color=#00ffff>DATA</color> " : " DATA " , Icons.small_folder, "Stored files and samples" + tooltip), config_style); if (Lib.IsClicked()) page = MonitorPage.data; else if (Lib.IsClicked(2)) UI.open((p) => p.fileman(v)); } if (Features.Automation) { GUILayout.Label(new GUIContent(page == MonitorPage.scripts ? " <color=#00ffff>AUTO</color> " : " AUTO ", Icons.small_console, "Control and automate components" + tooltip), config_style); if (Lib.IsClicked()) page = MonitorPage.scripts; else if (Lib.IsClicked(2)) UI.open((p) => p.devman(v)); } GUILayout.Label(new GUIContent(page == MonitorPage.config ? " <color=#00ffff>CFG</color> " : " CFG ", Icons.small_config, "Configure the vessel" + tooltip), config_style); if (Lib.IsClicked()) page = MonitorPage.config; else if (Lib.IsClicked(2)) UI.open((p) => p.config(v)); GUILayout.Label(new GUIContent(" GROUP ", Icons.small_search, "Organize in groups"), config_style); vd.group = Lib.TextFieldPlaceholder("Kerbalism_group", vd.group, "NONE", group_style).ToUpper(); GUILayout.EndHorizontal(); GUILayout.Space(10.0f); }
// 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); }
// --- SCIENCE DATA --------------------------------------------------------- // return true if there is experiment data on the vessel public static bool HasData(Vessel v) { // stock science system if (!Features.Science) { // if vessel is loaded if (v.loaded) { // iterate over all science containers/experiments and return true if there is data return Lib.HasModule<IScienceDataContainer>(v, k => k.GetData().Length > 0); } // if not loaded else { // iterate over all science containers/experiments proto modules and return true if there is data return Lib.HasModule(v.protoVessel, "ModuleScienceContainer", k => k.moduleValues.GetNodes("ScienceData").Length > 0) || Lib.HasModule(v.protoVessel, "ModuleScienceExperiment", k => k.moduleValues.GetNodes("ScienceData").Length > 0); } } // our own science system else { return DB.Vessel(v).drive.files.Count > 0; } }
public static void FileMan(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, 20), " <color=#cccccc>FILE MANAGER</color>")); p.Width(320.0f); // time-out simulation if (p.Timeout(vi)) { return; } // get vessel drive Drive drive = DB.Vessel(v).drive; // draw data section p.SetSection("DATA"); foreach (var pair in drive.files) { string filename = pair.Key; File file = pair.Value; Render_File(p, filename, file, drive); } if (drive.files.Count == 0) { p.SetContent("<i>no files</i>", string.Empty); } // draw samples section p.SetSection("SAMPLES"); foreach (var pair in drive.samples) { string filename = pair.Key; Sample sample = pair.Value; Render_Sample(p, filename, sample, drive); } if (drive.samples.Count == 0) { p.SetContent("<i>no samples</i>", string.Empty); } }
// store a file on a vessel public static bool StoreFile(Vessel v, string subject_id, double amount) { if (!Cache.VesselInfo(v).is_valid) { return(false); } return(DB.Vessel(v).BestDrive(amount).Record_file(subject_id, amount)); }
// store a sample on a vessel public static bool StoreSample(Vessel v, string subject_id, double amount, double mass = 0) { if (!Cache.VesselInfo(v).is_valid) { return(false); } return(DB.Vessel(v).BestDrive(Lib.SampleSizeToSlots(amount)).Record_sample(subject_id, amount, mass)); }
// analyze a sample private static Status Analyze(Vessel v, string filename, double amount) { Sample sample = null; foreach (var d in DB.Vessel(v).drives.Values) { if (d.samples.ContainsKey(filename)) { sample = d.samples[filename]; } break; } var drive = DB.Vessel(v).BestDrive(amount); bool completed = sample == null; if (sample != null) { // analyze, and produce dataamount = Math.Min(amount, sample.size); completed = amount >= sample.size - double.Epsilon; bool recorded = drive.Record_file(filename, amount, false); if (recorded) { drive.Delete_sample(filename, amount); } else { Message.Post( Lib.Color("red", Lib.BuildString(Localizer.Format("#KERBALISM_Laboratory_Analysis"), " stopped")), "Not enough space on hard drive" ); return(Status.NO_STORAGE); } } // if the analysis is completed if (completed) { // inform the user Message.Post(Lib.BuildString(Lib.Color("cyan", Localizer.Format("#KERBALISM_Laboratory_Analysis"), true), "\n", Localizer.Format("#KERBALISM_Laboratory_Analyzed", Lib.Bold(v.vesselName), Lib.Bold(Science.Experiment(filename).name))), localized_results); if (PreferencesBasic.Instance.transmitScience) { drive.Transmit_file(filename); } // record landmark event if (!Lib.Landed(v)) { DB.landmarks.space_analysis = true; } } return(Status.RUNNING); }
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; }
// remove one experiment at random from the vessel public static void RemoveData(Vessel v) { // stock science system if (!Features.Science) { // if vessel is loaded if (v.loaded) { // get all science containers/experiments with data List<IScienceDataContainer> modules = Lib.FindModules<IScienceDataContainer>(v).FindAll(k => k.GetData().Length > 0); // remove a data sample at random if (modules.Count > 0) { IScienceDataContainer container = modules[Lib.RandomInt(modules.Count)]; ScienceData[] data = container.GetData(); container.DumpData(data[Lib.RandomInt(data.Length)]); } } // if not loaded else { // get all science containers/experiments with data var modules = new List<ProtoPartModuleSnapshot>(); modules.AddRange(Lib.FindModules(v.protoVessel, "ModuleScienceContainer").FindAll(k => k.moduleValues.GetNodes("ScienceData").Length > 0)); modules.AddRange(Lib.FindModules(v.protoVessel, "ModuleScienceExperiment").FindAll(k => k.moduleValues.GetNodes("ScienceData").Length > 0)); // remove a data sample at random if (modules.Count > 0) { ProtoPartModuleSnapshot container = modules[Lib.RandomInt(modules.Count)]; ConfigNode[] data = container.moduleValues.GetNodes("ScienceData"); container.moduleValues.RemoveNode(data[Lib.RandomInt(data.Length)]); } } } // our own science system else { // select a file at random and remove it Drive drive = DB.Vessel(v).drive; if (drive.files.Count > 0) //< it should always be the case { string filename = string.Empty; int i = Lib.RandomInt(drive.files.Count); foreach (var pair in drive.files) { if (i-- == 0) { filename = pair.Key; break; } } drive.files.Remove(filename); } } }
void Start() { // get dialog dialog = gameObject.GetComponentInParent <ExperimentsResultDialog>(); if (dialog == null) { Destroy(gameObject); return; } // prevent rendering dialog.gameObject.SetActive(false); // for each page // - some mod may collect multiple experiments at once while (dialog.pages.Count > 0) { // get page var page = dialog.pages[0]; // get science data ScienceData data = page.pageData; // collect and deduce all info necessary MetaData meta = new MetaData(data, page.host); // record data in the drive Drive drive = DB.Vessel(meta.vessel).drive; if (!meta.is_sample) { drive.Record_file(data.subjectID, data.dataAmount); } else { drive.Record_sample(data.subjectID, data.dataAmount); } // render experiment inoperable if necessary if (!meta.is_rerunnable) { meta.experiment.SetInoperable(); } // dump the data page.OnDiscardData(data); // inform the user Message.Post ( Lib.BuildString("<b>", Science.Experiment(data.subjectID).fullname, "</b> recorded"), !meta.is_rerunnable ? Localizer.Format("#KERBALISM_Science_inoperable") : string.Empty ); } // dismiss the dialog dialog.Dismiss(); }
// remove a sample from a vessel public static void RemoveSample(Vessel v, string subject_id, double amount) { if (!Cache.VesselInfo(v).is_valid) { return; } Drive drive = DB.Vessel(v).drive; drive.Delete_sample(subject_id, amount); }
// store a file on a vessel public static void StoreFile(Vessel v, string subject_id, double amount) { if (!Cache.VesselInfo(v).is_valid) { return; } Drive drive = DB.Vessel(v).drive; drive.Record_file(subject_id, amount); }
public static void KeyboardInput() { // mute/unmute messages with keyboard if (Input.GetKeyDown(KeyCode.Pause)) { if (!Message.IsMuted()) { Message.Post("Messages muted", "Be careful out there"); Message.Mute(); } else { Message.Unmute(); Message.Post("Messages unmuted"); } } // toggle body info window with keyboard if (MapView.MapIsEnabled && Input.GetKeyDown(KeyCode.B)) { UI.open(BodyInfo.body_info); } // call action scripts // - avoid creating vessel data for invalid vessels Vessel v = FlightGlobals.ActiveVessel; if (v != null && DB.vessels.ContainsKey(Lib.RootID(v))) { // get computer Computer computer = DB.Vessel(v).computer; // call scripts with 1-5 key if (Input.GetKeyDown(KeyCode.Alpha1) || Input.GetKeyDown(KeyCode.Keypad1)) { computer.execute(v, ScriptType.action1); } if (Input.GetKeyDown(KeyCode.Alpha2) || Input.GetKeyDown(KeyCode.Keypad2)) { computer.execute(v, ScriptType.action2); } if (Input.GetKeyDown(KeyCode.Alpha3) || Input.GetKeyDown(KeyCode.Keypad3)) { computer.execute(v, ScriptType.action3); } if (Input.GetKeyDown(KeyCode.Alpha4) || Input.GetKeyDown(KeyCode.Keypad4)) { computer.execute(v, ScriptType.action4); } if (Input.GetKeyDown(KeyCode.Alpha5) || Input.GetKeyDown(KeyCode.Keypad5)) { computer.execute(v, ScriptType.action5); } } }
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, 20), "</b> <size=9><color=#cccccc>", Lib.Ellipsis(body_name, 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 (Features.Signal) indicator_signal(p, v, vi); // done return true; }
// remove a sample from a vessel public static void RemoveSample(Vessel v, string subject_id, double amount) { if (!Cache.VesselInfo(v).is_valid) { return; } foreach (var d in DB.Vessel(v).drives.Values) { d.Delete_sample(subject_id, amount); } }
// return size of a sample in a vessel drive public static double SampleSize(Vessel v, string subject_id) { if (!Cache.VesselInfo(v).is_valid) { return(0.0); } Drive drive = DB.Vessel(v).drive; Sample sample; return(drive.samples.TryGetValue(subject_id, out sample) ? sample.size : 0.0); }
// transfer data between two vessels public static void Transfer(Vessel src, Vessel dst, bool samples = false) { double dataAmount = 0.0; int sampleSlots = 0; foreach (var drive in DB.Vessel(src).drives.Values) { dataAmount += drive.FilesSize(); sampleSlots += drive.SamplesSize(); } if (dataAmount < double.Epsilon && (sampleSlots == 0 || !samples)) { return; } // get drives var allSrc = DB.Vessel(src).drives.Values; var allDst = DB.Vessel(dst).drives.Values; bool allMoved = true; foreach (var a in allSrc) { bool aMoved = false; foreach (var b in allDst) { if (a.Move(b, samples)) { aMoved = true; break; } } allMoved &= aMoved; } // inform the user if (allMoved) { Message.Post ( Localizer.Format("#KERBALISM_Science_ofdatatransfer"), Lib.BuildString(Localizer.Format("#KERBALISM_Generic_FROM"), " <b>", src.vesselName, "</b> ", Localizer.Format("#KERBALISM_Generic_TO"), " <b>", dst.vesselName, "</b>") ); } else { Message.Post ( Lib.Color("red", Lib.BuildString("WARNING: not evering copied"), true), Lib.BuildString(Localizer.Format("#KERBALISM_Generic_FROM"), " <b>", src.vesselName, "</b> ", Localizer.Format("#KERBALISM_Generic_TO"), " <b>", dst.vesselName, "</b>") ); } }
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"); } }
// return true if a storm just ended // used to avoid sending 'signal is back' messages en-masse after the storm is over // - delta_time: time between calls to this function public static bool JustEnded(Vessel v, double delta_time) { // if in interplanetary space if (v.mainBody.flightGlobalsIndex == 0) { return(DB.Vessel(v).storm_age < delta_time * 2.0); } // if inside a planetary system else { return(DB.Body(Lib.PlanetarySystem(v.mainBody).name).storm_age < delta_time * 2.0); } }
// return true if a storm is in progress public static bool InProgress(Vessel v) { // if in interplanetary space if (v.mainBody.flightGlobalsIndex == 0) { return(DB.Vessel(v).storm_state == 2); } // if inside a planetary system else { return(DB.Body(Lib.PlanetarySystem(v.mainBody).name).storm_state == 2); } }
void Record(MetaData meta, ScienceData data, bool send) { // if amount is zero, warn the user and do nothing else if (data.dataAmount <= double.Epsilon) { Message.Post("There is no more useful data here"); return; } // if this is a sample and we are trying to send it, warn the user and do nothing else if (meta.is_sample && send) { Message.Post("We can't transmit a sample", "It needs to be recovered, or analyzed in a lab"); return; } // record data in the drive Drive drive = DB.Vessel(meta.vessel).drive; if (!meta.is_sample) { drive.Record_file(data.subjectID, data.dataAmount); } else { drive.Record_sample(data.subjectID, data.dataAmount); } // flag for sending if specified if (!meta.is_sample && send) { drive.Send(data.subjectID, true); } // render experiment inoperable if necessary if (!meta.is_rerunnable) { meta.experiment.SetInoperable(); } // dismiss the dialog and popups Dismiss(data); // inform the user Message.Post ( Lib.BuildString("<b>", Science.Experiment(data.subjectID).fullname, "</b> recorded"), !meta.is_rerunnable ? Localizer.Format("#KERBALISM_Science_inoperable") : string.Empty ); }
// return time left until CME is over public static double TimeLeftCME(Vessel v) { // if in interplanetary space if (v.mainBody.flightGlobalsIndex == 0) { VesselData vd = DB.Vessel(v); return(TimeLeftCME(vd.storm_time, vd.storm_age)); } // if inside a planetary system else { BodyData bd = DB.Body(Lib.PlanetarySystem(v.mainBody).name); return(TimeLeftCME(bd.storm_time, bd.storm_age)); } }