void RunScience() // this is primary business logic for finding and running valid experiments { if (GetExperimentList() == null) // hey, it can happen! { Debug.Log("[ForScience!] There are no experiments."); } else { foreach (ModuleScienceExperiment currentExperiment in GetExperimentList()) // loop through all the experiments onboard { ScienceExperiment se = ResearchAndDevelopment.GetExperiment(currentExperiment.experimentID); Debug.Log("[ForScience!] Checking experiment id: " + se.id + " title: " + se.experimentTitle + " unlocked: " + se.IsUnlocked() + " isAvail: " + se.IsAvailableWhile(currentSituation(), currentBody())); ScienceSubject ss = currentScienceSubject(se); //Debug.Log("ScienceSubject experiment id: " + ss.id + " title: " + ss.title); ModuleScienceExperiment me = currentExperiment; /*Debug.Log("Module Experiment id: " + me.experimentID + " cooldown: " + me.cooldownToGo + " collectable: " + me.dataIsCollectable + " deployed: " + me.Deployed + " enabled: " + me.isEnabled + " rerunnable: " + me.IsRerunnable() + " module: " + me.moduleName + " objname: " + me.name + " resettable: " + me.resettable + " resOnEVA: " + me.resettableOnEVA);*/ if (ActiveContainer().HasData(newScienceData(currentExperiment))) // skip data we already have onboard { Debug.Log("[ForScience!] Skipping: We already have that data onboard."); } else if (!surfaceSamplesUnlocked() && se.id == "surfaceSample") // check to see is surface samples are unlocked { Debug.Log("[ForScience!] Skipping: Surface Samples are not unlocked."); } else if (!me.IsRerunnable() && (!(me.resettable || me.resettableOnEVA) || !IsScientistOnBoard())) // no cheating goo and materials here { Debug.Log("[ForScience!] Skipping: Experiment is not repeatable (and/or resettable)."); } else if (!se.IsAvailableWhile(currentSituation(), currentBody())) // this experiement isn't available here so we skip it { Debug.Log("[ForScience!] Skipping: Experiment is not available for this situation/atmosphere."); } else if (me.useCooldown && me.cooldownToGo > 0) { Debug.Log("[ForScience!] Skipping: Experiment on cooldown for " + me.cooldownToGo + " seconds."); } else if (currentScienceValue(currentExperiment) < 0.1) // this experiment has no more value so we skip it { Debug.Log("[ForScience!] Skipping: No more science is available."); } else { Debug.Log("[ForScience!] Running experiment: " + ss.id); ActiveContainer().AddData(newScienceData(currentExperiment)); //manually add data to avoid deployexperiment state issues } } } }
public void doScience(CelestialBody planet) { Utilities.Log_Debug("Doing Science for {0}", planet.theName); ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(ExperimentID); Utilities.Log_Debug("Got experiment"); string biome = ""; biome = part.vessel.landedAt != string.Empty ? part.vessel.landedAt : ScienceUtil.GetExperimentBiome(planet, FlightGlobals.ship_latitude, FlightGlobals.ship_longitude); ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(experiment, ScienceUtil.GetExperimentSituation(vessel), planet, biome); Utilities.Log_Debug("Got subject"); if (experiment.IsAvailableWhile(ScienceUtil.GetExperimentSituation(vessel), planet)) { ScienceData data = new ScienceData(experiment.baseValue * subject.dataScale, xmitDataScalar, labBoostScalar, subject.id, subject.title, false, part.flightID); Utilities.Log_Debug("Got data"); _scienceData.Add(data); Utilities.Log_Debug("Added Data"); ScreenMessages.PostScreenMessage("Collected Science for " + planet.theName, 3f, ScreenMessageStyle.UPPER_CENTER); if (TSTProgressTracker.isActive) { TSTProgressTracker.OnChemCamFire(planet, biome); } } updateAvailableEvents(); }
//This method handles generating the surface or asteroid sample ScienceData private ScienceData sampleData(ModuleAsteroid m) { ScienceExperiment exp = null; ScienceSubject sub = null; ExperimentSituations expSit; ScienceData data = null; string biome = ""; if (m != null) { exp = asteroidExp; } else { exp = surfaceExp; } if (exp == null) { return(null); } expSit = ScienceUtil.GetExperimentSituation(vessel); if (exp.IsAvailableWhile(expSit, vessel.mainBody)) { if (exp.BiomeIsRelevantWhile(expSit)) { if (!string.IsNullOrEmpty(vessel.landedAt)) { biome = Vessel.GetLandedAtString(vessel.landedAt); } else { biome = ScienceUtil.GetExperimentBiome(vessel.mainBody, vessel.latitude, vessel.longitude); } } if (m != null) { sub = ResearchAndDevelopment.GetExperimentSubject(exp, expSit, m.part.partInfo.name + m.part.flightID, m.part.partInfo.title, vessel.mainBody, biome); } else { sub = ResearchAndDevelopment.GetExperimentSubject(exp, expSit, vessel.mainBody, biome); } if (sub == null) { return(null); } data = new ScienceData(exp.baseValue * exp.dataScale, this.xmitDataScalar, 0f, sub.id, sub.title, false, part.flightID); return(data); } return(null); }
internal static bool CanRunExperiment(Vessel vessel, string expId, ref string msg) { msg = Localizer.Format("#autoLOC_LTech_Util_002"); ScienceExperiment labExp = ResearchAndDevelopment.GetExperiment(expId); if (labExp.IsAvailableWhile((ExperimentSituations)vessel.situation, vessel.mainBody)) { if (labExp.BiomeIsRelevantWhile((ExperimentSituations)vessel.situation)) { return(true); } } if (vessel.situation == Vessel.Situations.LANDED) { if (vessel.situation == Vessel.Situations.LANDED) { return(true); } msg += Localizer.Format("#autoLOC_LTech_Util_003"); } if (vessel.situation == Vessel.Situations.SPLASHED) { if (vessel.situation == Vessel.Situations.SPLASHED) { return(true); } msg += Localizer.Format("#autoLOC_LTech_Util_004"); } if (vessel.situation == Vessel.Situations.FLYING) { if (vessel.altitude <= vessel.orbit.referenceBody.atmosphereDepth) { return(true); } msg += Localizer.Format("#autoLOC_LTech_Util_005"); } if (vessel.situation == Vessel.Situations.ORBITING) { if (vessel.altitude > vessel.orbit.referenceBody.atmosphereDepth) { return(true); } msg += Localizer.Format("#autoLOC_LTech_Util_006"); } msg = msg.Remove(msg.Length - 2); return(false); }
private static bool ExperimentAvailable(ScienceExperiment exp, ExperimentSituations sit, CelestialBody body) { if (!ExperimentAvailable(exp, body)) { return(false); } if (!exp.IsAvailableWhile(sit, body)) { return(false); } // Get the experiment rules ExperimentRules rules = GetExperimentRules(exp.id); // Check if surface samples have been unlocked if (rules.requireSurfaceSample) { if (ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.ResearchAndDevelopment) < 0.3f) { return(false); } } // Check for EVA unlock if (rules.requireEVA) { if (!body.isHomeWorld || (sit != ExperimentSituations.SrfLanded && sit != ExperimentSituations.SrfSplashed)) { bool evaUnlocked = GameVariables.Instance.UnlockedEVA(ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.AstronautComplex)); if (!evaUnlocked) { return(false); } } } if (rules.disallowHomeSurface) { if (body.isHomeWorld && sit == ExperimentSituations.SrfLanded || sit == ExperimentSituations.SrfSplashed) { return(false); } } if (rules.disallowHomeFlying) { if (body.isHomeWorld && sit == ExperimentSituations.FlyingLow || sit == ExperimentSituations.FlyingHigh) { return(false); } } return(true); }
private static bool ExperimentAvailable(ScienceExperiment exp, CelestialBody body) { if (exp == null || body == null) { return(false); } // Get the experiment rules ExperimentRules rules = GetExperimentRules(exp.id); if (rules.ignored) { return(false); } if (rules.requireAtmosphere && !body.atmosphere) { return(false); } if (rules.requireNoAtmosphere && body.atmosphere) { return(false); } if (rules.requireSurface && body.pqsController == null) { return(false); } if (rules.requireNoSurface && body.pqsController != null) { return(false); } if (rules.validBodies != null) { if (!rules.validBodies.Contains(body)) { return(false); } } // Filter out asteroid samples if not unlocked if (rules.requireAsteroidTracking) { if (!GameVariables.Instance.UnlockedSpaceObjectDiscovery(ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.TrackingStation))) { return(false); } } return(allSituations.Any(sit => exp.IsAvailableWhile(sit, body))); }
static bool Prefix(ModuleComet __instance, ref ScienceExperiment ___experiment) { // Patch only if science is enabled if (!Features.Science) { return(true); } // stock ModuleAsteroid.performSampleExperiment code : get situation and check availablility ExperimentSituations experimentSituation = ScienceUtil.GetExperimentSituation(__instance.vessel); string message = string.Empty; if (!ScienceUtil.RequiredUsageExternalAvailable(__instance.vessel, FlightGlobals.ActiveVessel, (ExperimentUsageReqs)__instance.experimentUsageMask, ___experiment, ref message)) { ScreenMessages.PostScreenMessage("<b><color=orange>" + message + "</color></b>", 6f, ScreenMessageStyle.UPPER_LEFT); return(false); } if (!___experiment.IsAvailableWhile(experimentSituation, __instance.vessel.mainBody)) { ScreenMessages.PostScreenMessage(Localizer.Format("#autoLOC_230133", ___experiment.experimentTitle), 5f, ScreenMessageStyle.UPPER_CENTER); return(false); } // stock ModuleAsteroid.performSampleExperiment code : create subject ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(___experiment, experimentSituation, __instance.part.partInfo.name + __instance.part.flightID, __instance.part.partInfo.title, __instance.vessel.mainBody, string.Empty, string.Empty); // put the data on the EVA kerbal drive. if (FlightGlobals.ActiveVessel == null) { return(false); } double size = ___experiment.baseValue * ___experiment.dataScale; Drive drive = Drive.SampleDrive(FlightGlobals.ActiveVessel.KerbalismData(), size); if (drive != null) { double mass = size * Settings.AsteroidSampleMassPerMB; SubjectData subjectData = ScienceDB.GetSubjectDataFromStockId(subject.id, null, __instance.part.partInfo.title); drive.Record_sample(subjectData, size, mass, true); Message.Post(Lib.BuildString("<b><color=ffffff>", subject.title, "</color></b>\n", (mass * 1000.0).ToString("F1"), "<b><i> Kg of sample stored</i></b>")); } else { Message.Post("Not enough sample storage available"); } // don't call TakeSampleEVAEvent() (this will also prevent the call to ModuleAsteroid.performSampleExperiment) return(false); }
public void doScience(CelestialBody planet) { Utilities.Log_Debug("Doing Science for {0}", planet.name); ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(ExperimentID); Utilities.Log_Debug("Got experiment"); ExperimentSituations situation = ScienceUtil.GetExperimentSituation(vessel); if (experiment.IsAvailableWhile(ScienceUtil.GetExperimentSituation(vessel), planet)) { string biomeID = ""; string displaybiomeID = string.Empty; if (part.vessel.landedAt != string.Empty) { biomeID = Vessel.GetLandedAtString(part.vessel.landedAt); displaybiomeID = Localizer.Format(part.vessel.displaylandedAt); } else { biomeID = ScienceUtil.GetExperimentBiome(planet, FlightGlobals.ship_latitude, FlightGlobals.ship_longitude); displaybiomeID = ScienceUtil.GetBiomedisplayName(vessel.mainBody, biomeID); } ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(experiment, situation, planet, biomeID, displaybiomeID); Utilities.Log_Debug("Got subject"); ScienceData data = new ScienceData(experiment.baseValue * subject.dataScale, xmitDataScalar, labBoostScalar, subject.id, subject.title, false, part.flightID); Utilities.Log_Debug("Got data"); _scienceData.Add(data); Utilities.Log_Debug("Added Data"); ScreenMessages.PostScreenMessage(Localizer.Format("#autoLOC_238419", part.partInfo.title, data.dataAmount.ToString(), subject.title), 8f, ScreenMessageStyle.UPPER_LEFT); ReviewDataItem(data); if (TSTProgressTracker.isActive) { TSTProgressTracker.OnChemCamFire(planet, biomeID); } } else { ScreenMessages.PostScreenMessage(Localizer.Format("#autoLOC_238424", experiment.experimentTitle), 5f, ScreenMessageStyle.UPPER_CENTER); } updateAvailableEvents(); }
/// <summary> /// True if all required resources are present /// </summary> public bool ReadyToDeploy(bool displayMessage = true) { for (int i = 0; i < requirementNames.Count; i++) { //float result = part.RequestResource(requirementNames[i], requirementAmounts[i]); double result = GetResourceAmount(requirementNames[i]); if (result < requirementAmounts[i] - 0.001) { if (displayMessage) { ShoutToScreen("Experiment not finished yet!"); } currentStatus = Status.Running; return(false); } } ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(experimentID); if (!experiment.IsAvailableWhile(GetScienceSituation(vessel), vessel.mainBody)) { if (displayMessage) { ShoutToScreen("Can't perform experiment here."); } currentStatus = Status.BadLocation; return(false); } currentStatus = Status.Completed; return(true); }
private static bool ExperimentAvailable(ScienceExperiment exp, ExperimentSituations sit, CelestialBody body) { if (!ExperimentAvailable(exp, body)) { return false; } if (!exp.IsAvailableWhile(sit, body)) { return false; } // Get the experiment rules ExperimentRules rules = GetExperimentRules(exp.id); // Check if surface samples have been unlocked if (rules.requireSurfaceSample) { if (ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.ResearchAndDevelopment) < 0.3f) { return false; } } // Check for EVA unlock if (rules.requireEVA) { if (!body.isHomeWorld || (sit != ExperimentSituations.SrfLanded && sit != ExperimentSituations.SrfSplashed)) { bool evaUnlocked = GameVariables.Instance.UnlockedEVA(ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.AstronautComplex)); if (!evaUnlocked) { return false; } } } if (rules.disallowHomeSurface) { if (body.isHomeWorld && sit == ExperimentSituations.SrfLanded || sit == ExperimentSituations.SrfSplashed) { return false; } } if (rules.disallowHomeFlying) { if (body.isHomeWorld && sit == ExperimentSituations.FlyingLow || sit == ExperimentSituations.FlyingHigh) { return false; } } return true; }
private static bool ExperimentAvailable(ScienceExperiment exp, CelestialBody body) { if (exp == null || body == null) { return false; } // Get the experiment rules ExperimentRules rules = GetExperimentRules(exp.id); if (rules.ignored) { return false; } if (rules.requireAtmosphere && !body.atmosphere) { return false; } if (rules.requireNoAtmosphere && body.atmosphere) { return false; } if (rules.requireSurface && body.pqsController == null) { return false; } if (rules.requireNoSurface && body.pqsController != null) { return false; } if (rules.validBodies != null) { if (!rules.validBodies.Contains(body)) { return false; } } // Filter out asteroid samples if not unlocked if (rules.requireAsteroidTracking) { if (!GameVariables.Instance.UnlockedSpaceObjectDiscovery(ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.TrackingStation))) { return false; } } return allSituations.Any(sit => exp.IsAvailableWhile(sit, body)); }
public virtual bool UpdateStatus(ExperimentSituations experimentSituation, out bool newReport) { newReport = false; if (FlightGlobals.ActiveVessel == null) { Available = false; lastAvailableId = ""; return(false); } if (!settings.Enabled || (requireControllable && !FlightGlobals.ActiveVessel.IsControllable)) { Available = false; lastAvailableId = ""; return(false); } bool lastStatus = Available; var vessel = FlightGlobals.ActiveVessel; if (!storage.IsBusy && IsReadyOnboard) { // does this experiment even apply in the current situation? if (experiment.IsAvailableWhile(experimentSituation, vessel.mainBody)) { var biome = string.Empty; if (experiment.BiomeIsRelevantWhile(experimentSituation)) { // biome matters; check to make sure we have biome data available if (scanInterface.HaveScanData(vessel.latitude, vessel.longitude, vessel.mainBody)) { if (biomeFilter.GetBiome(vessel.latitude, vessel.longitude, out biome)) { lastBiomeQuery = biome; } else { biome = lastBiomeQuery; // use last good known value } } else { // no biome data available Available = false; lastAvailableId = ""; return(false); } } try { var subject = ResearchAndDevelopment.GetExperimentSubject(experiment, experimentSituation, vessel.mainBody, biome, null); List <ScienceData> data = null; float scienceTotal = GetScienceTotal(subject, out data); switch (settings.Filter) { case ExperimentSettings.FilterMethod.Unresearched: // Fairly straightforward: total science + potential should be zero Available = scienceTotal < 0.0005f; break; case ExperimentSettings.FilterMethod.NotMaxed: // <98% of science cap Available = scienceTotal < subject.scienceCap * 0.98f * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; break; case ExperimentSettings.FilterMethod.LessThanFiftyPercent: Available = scienceTotal < subject.scienceCap * 0.5f * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; break; case ExperimentSettings.FilterMethod.LessThanNinetyPercent: Available = scienceTotal < subject.scienceCap * 0.9f * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; break; default: // this should NEVER occur, but nice to have a safety measure // in place if I add a filter option and forget to add its logic Log.Error("Unrecognized experiment filter!"); data = new List <ScienceData>(); break; } nextReportValue = subject.CalculateNextReport(experiment, data); Available = Available && nextReportValue > 0.01f; Available = Available && nextReportValue > ScienceAlertProfileManager.ActiveProfile.ScienceThreshold; if (Available) { if (lastAvailableId != subject.id) { lastStatus = false; // force a refresh, in case we're going from available -> available in different subject id newReport = true; // we've available on a brand new report } lastAvailableId = subject.id; } } catch (NullReferenceException e) { Log.Error( "Failed to create {0} ScienceSubject. If you can manage to reproduce this error, let me know.", experiment.id); Log.Error("Exception was: {0}", e); Available = lastStatus; } } else { Available = false; } } else { Available = false; // no experiments ready } return(Available != lastStatus && Available); }
private static bool ExperimentAvailable(ScienceExperiment exp, CelestialBody body) { if (exp == null || body == null) { return(false); } // Check if experiement is unlocked if (!exp.IsUnlocked()) { return(false); } // Special Breaking Ground logic if (exp.id.StartsWith("ROCScience")) { if (!exp.id.Contains(body.name)) { return(false); } } // Get the experiment rules ExperimentRules rules = GetExperimentRules(exp.id); if (rules.ignored) { return(false); } if ((rules.requireAtmosphere || exp.requireAtmosphere) && !body.atmosphere) { return(false); } if ((rules.requireNoAtmosphere || exp.requireNoAtmosphere) && body.atmosphere) { return(false); } if (rules.requireSurface && body.pqsController == null) { return(false); } if (rules.requireNoSurface && body.pqsController != null) { return(false); } if (rules.sunOnly) { return(body == FlightGlobals.Bodies[0]); } // Filter out asteroid samples if not unlocked if (rules.requireAsteroidTracking) { if (!GameVariables.Instance.UnlockedSpaceObjectDiscovery(ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.TrackingStation))) { return(false); } } return(allSituations.Any(sit => exp.IsAvailableWhile(sit, body))); }
/// <summary> /// Returns true if the status just changed to available (so that /// ScienceAlert can play a sound when the experiment /// status changes) /// </summary> /// <returns></returns> public virtual bool UpdateStatus(ExperimentSituations experimentSituation, out bool newReport) { newReport = false; if (FlightGlobals.ActiveVessel == null) { Available = false; lastAvailableId = ""; Log.Debug("Observer.UpdateStatus: active vessel is null!"); return(false); } if (!settings.Enabled || (requireControllable && !FlightGlobals.ActiveVessel.IsControllable)) { Available = false; lastAvailableId = ""; return(false); } bool lastStatus = Available; var vessel = FlightGlobals.ActiveVessel; if (!storage.IsBusy && IsReadyOnboard) { // does this experiment even apply in the current situation? if (experiment.IsAvailableWhile(experimentSituation, vessel.mainBody)) { var biome = string.Empty; // note: apparently simply providing the biome name whether its // relevant or not will result in the biome being INCORRECTLY applied // to the experiment id. This causes all kinds of confusion because // R&D will report incorrect science values based on the wrong id // // Supplying an empty string if the biome doesn't matter seems to work if (experiment.BiomeIsRelevantWhile(experimentSituation)) { // biome matters; check to make sure we have biome data available if (scanInterface.HaveScanData(vessel.latitude, vessel.longitude, vessel.mainBody)) { if (biomeFilter.GetBiome(vessel.latitude * Mathf.Deg2Rad, vessel.longitude * Mathf.Deg2Rad, out biome)) { lastBiomeQuery = biome; } else { biome = lastBiomeQuery; // use last good known value } } else { // no biome data available Available = false; lastAvailableId = ""; return(false); } } try { var subject = ResearchAndDevelopment.GetExperimentSubject(experiment, experimentSituation, vessel.mainBody, biome); List <ScienceData> data = null; float scienceTotal = GetScienceTotal(subject, out data); switch (settings.Filter) { case ProfileData.ExperimentSettings.FilterMethod.Unresearched: // Fairly straightforward: total science + potential should be zero Available = scienceTotal < 0.0005f; break; case ProfileData.ExperimentSettings.FilterMethod.NotMaxed: // <98% of science cap Available = scienceTotal < subject.scienceCap * 0.98f * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; break; case ProfileData.ExperimentSettings.FilterMethod.LessThanFiftyPercent: // important note for these last two filters: we can only accurately // predict science for up to two of the same reports. After that, // it'll be highly overestimated Available = scienceTotal < subject.scienceCap * 0.5f * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; break; case ProfileData.ExperimentSettings.FilterMethod.LessThanNinetyPercent: Available = scienceTotal < subject.scienceCap * 0.9f * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; break; default: // this should NEVER occur, but nice to have a safety measure // in place if I add a filter option and forget to add its logic Log.Error("Unrecognized experiment filter!"); data = new List <ScienceData>(); break; } // bugfix: also ensure the experiment will generate >0 science, else // we could produce alerts for reports that won't generate any science //nextReportValue = CalculateNextReportValue(subject, experimentSituation, data); nextReportValue = subject.CalculateNextReport(experiment, data); Available = Available && nextReportValue > 0.01f; // check the science threshold Available = Available && nextReportValue > ScienceAlertProfileManager.ActiveProfile.ScienceThreshold; if (Available) { if (lastAvailableId != subject.id) { lastStatus = false; // force a refresh, in case we're going from available -> available in different subject id newReport = true; // we've available on a brand new report } lastAvailableId = subject.id; if (Available != lastStatus && Available) { Log.Normal("Experiment {0} just became available! Total potential science onboard currently: {1} (Cap is {2}, threshold is {3}, current sci is {4}, expected next report value: {5})", lastAvailableId, scienceTotal, subject.scienceCap * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier, settings.Filter, subject.science, nextReportValue); //Log.Debug("Transmission value: {0}", CalculateTransmissionValue(subject)); #if DEBUG if (GetNextOnboardExperimentModule() != null) { Log.Debug("Transmission value: {0}", API.AlertUtil.GetNextReportValue(subject, experiment, data, GetNextOnboardExperimentModule().xmitDataScalar)); } #endif if (data.Count() > 0) { Log.Debug("Raw dataAmount = {0}, nextScience = {1}", data.First().dataAmount, ResearchAndDevelopment.GetScienceValue(data.First().dataAmount, subject) * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier); Log.Debug("Total science value = {0}", GetScienceTotal(subject, out data)); } } } } catch (NullReferenceException e) { // note to self: even with all the logging I did when // I could sometimes reproduce the exception, nothing // looked wrong except that biome string becomes null Log.Error("Failed to create {0} ScienceSubject. If you can manage to reproduce this error, let me know.", experiment.id); Log.Error("Exception was: {0}", e); Available = lastStatus; } } else { // experiment isn't available under this situation #if DEBUG //if (GetNextOnboardExperimentModule()) //Log.Verbose("{0} is onboard but not applicable in this situation {1} (vessel situation {2})", ExperimentTitle, experimentSituation, vessel.situation); #endif Available = false; } } else { Available = false; // no experiments ready } return(Available != lastStatus && Available); }
private static string TestForIssues(Vessel v, ScienceExperiment exp, Resource_info ec, Experiment experiment, bool broken, double remainingSampleMass, bool didPrepare, bool isShrouded, string last_subject_id, out string subject_id) { var sit = ScienceUtil.GetExperimentSituation(v); var biome = ScienceUtil.GetExperimentBiome(v.mainBody, v.latitude, v.longitude); subject_id = Science.Generate_subject(exp, v.mainBody, sit, biome); if (broken) { return("broken"); } if (isShrouded && !experiment.allow_shrouded) { return("shrouded"); } bool needsReset = experiment.crew_reset.Length > 0 && !string.IsNullOrEmpty(last_subject_id) && subject_id != last_subject_id; if (needsReset) { return("reset required"); } if (ec.amount < double.Epsilon && experiment.ec_rate > double.Epsilon) { return("no <b>Electricity</b>"); } if (!string.IsNullOrEmpty(experiment.crew_operate)) { var cs = new CrewSpecs(experiment.crew_operate); if (!cs.Check(v)) { return(cs.Warning()); } } if (!experiment.sample_collecting && remainingSampleMass < double.Epsilon && experiment.sample_mass > double.Epsilon) { return("depleted"); } string situationIssue = Science.TestRequirements(experiment.requires, v); if (situationIssue.Length > 0) { return(Science.RequirementText(situationIssue)); } if (!exp.IsAvailableWhile(sit, v.mainBody)) { return("invalid situation"); } if (!didPrepare && !string.IsNullOrEmpty(experiment.crew_prepare)) { return("not prepared"); } var drive = DB.Vessel(v).BestDrive(); double available = experiment.sample_mass < float.Epsilon ? drive.FileCapacityAvailable() : drive.SampleCapacityAvailable(); if (experiment.data_rate * Kerbalism.elapsed_s > available) { return("insufficient storage"); } return(string.Empty); }
internal void DoScience(string expId) { string step = "Start"; string reqResource = experiments[expId].neededResourceName; float reqAmount = 1; try { string msg = string.Empty; //Vessel ves = FlightGlobals.ActiveVessel; Part prt = FlightGlobals.ActiveVessel.rootPart; ModuleScienceExperiment exp = new ModuleScienceExperiment(); if (experiments[expId].xmitDataScalar > 0) { exp.xmitDataScalar = experiments[expId].xmitDataScalar; } Log.Info("DoScience, expId: " + expId + ", xmitDataScalar: " + exp.xmitDataScalar); // Checks step = "Check Boring"; if (Utils.CheckBoring(vessel, true)) { return; } step = "Check CanRun"; if (!Utils.CanRunExperiment(vessel, expId, ref msg)) { Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_LTech_Experiment_002", msg)); return; } #if false step = "Check Insight"; if (Utils.ResourceAvailable(prt, "Insight") < reqInsight) { double current = Utils.ResourceAvailable(prt, "Insight"); double needed = reqInsight - current; Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_LTech_Experiment_003", (int)needed)); return; } #endif step = "Check Resource"; if (Utils.ResourceAvailable(prt, reqResource) < reqAmount) { double current = Utils.ResourceAvailable(prt, reqResource); double needed = reqAmount - current; Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_LTech_Experiment_004", (int)needed, reqResource)); return; } // Experiment step = "Get Experiment"; exp.experimentID = expId; ScienceExperiment labExp = ResearchAndDevelopment.GetExperiment(exp.experimentID); if (labExp == null) { Log.Warning(Localizer.Format("#autoLOC_LTech_Experiment_005", exp.experimentID)); Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_LTech_Experiment_006")); return; } step = "Get Situation"; ExperimentSituations vesselSit = ScienceUtil.GetExperimentSituation(vessel); if (labExp.IsAvailableWhile(vesselSit, vessel.mainBody)) { step = "Get Biome"; string biome, displayBiome; if (vessel.landedAt != string.Empty) { biome = Vessel.GetLandedAtString(vessel.landedAt); displayBiome = Localizer.Format(vessel.displaylandedAt); } else { biome = ScienceUtil.GetExperimentBiome(vessel.mainBody, vessel.latitude, vessel.longitude); displayBiome = ScienceUtil.GetBiomedisplayName(vessel.mainBody, biome); } Log.Info("DoScience, expId: " + expId + "body: " + vessel.mainBody.bodyName + ", ScienceUtil.GetExperimentSituation: " + ScienceUtil.GetExperimentSituation(vessel) + ", biome: " + biome); SetUpActiveExperiment(expId, biome, exp, reqResource); #if false activeExperiment = new ActiveExperiment(expId, vessel.mainBody.bodyName, ScienceUtil.GetExperimentSituation(vessel), biome, exp); // need to add to // internal ExperimentSituations vesselSit; // internal string biome; ExpStatus es = new ExpStatus(expId, activeExperiment.Key, vessel.mainBody.bodyName, ScienceUtil.GetExperimentSituation(vessel), biome, reqResource, experiments[expId].resourceAmtRequired); es.active = true; expStatuses.Add(es.Key, es); experimentStarted = true; StartCoroutine(FixedUpdate2()); #endif } else { Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_238424", labExp.experimentTitle)); Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_LTech_Experiment_007", vesselSit.displayDescription())); } step = "End"; } catch (Exception ex) { Log.Error($"SkylabExperiment.DoScience at step \"{step}\";. Error: {ex}"); } }
public System.Collections.IEnumerator UpdateStatus() { while (true) { Log.Info(part.partInfo.title + "updateStatus"); double numEurekas = GetResourceAmount(EUREKAS); double numEurekasMax = GetResourceMaxAmount(EUREKAS); double numKuarqs = GetResourceAmount(KUARQS); double numKuarqsMax = GetResourceMaxAmount(KUARQS); double numBioproducts = GetResourceAmount(BIOPRODUCTS); int sciCount = GetScienceCount(); Log.Info(part.partInfo.title + " finished: " + Finished()); if (!Finished()) { Events["DeployExperiment"].active = false; Events["StartExperiment"].active = (!Inoperable && sciCount == 0 && numEurekasMax == 0 && numKuarqsMax == 0); } else { Events["DeployExperiment"].active = true; Events["StartExperiment"].active = false; } var subject = ScienceHelper.getScienceSubject(experimentID, vessel); string subjectId = ((subject == null) ? "" : subject.id); if (subjectId != "" && last_subjectId != "" && last_subjectId != subjectId && (numEurekas > 0 || numKuarqs > 0 || (numBioproducts > 0 && sciCount == 0))) { ScreenMessages.PostScreenMessage(Localizer.Format("#autoLOC_StatSci_screen_locchange", part.partInfo.title), 6, ScreenMessageStyle.UPPER_CENTER); StopResearch(); StopResearch(BIOPRODUCTS); } last_subjectId = subjectId; if (sciCount > 0) { StopResearch(); if (completed == 0) { completed = (float)Planetarium.GetUniversalTime(); } } if (numEurekas > 0) { var eurekasModules = vessel.FindPartModulesImplementing <StationScienceModule>(); if (eurekasModules == null || eurekasModules.Count() < 1) { ScreenMessages.PostScreenMessage(Localizer.Format("#autoLOC_StatSci_screen_detatch", part.partInfo.title), 2, ScreenMessageStyle.UPPER_CENTER); } } /* * if (numKuarqs > 0) * { * var kuarqModules = vessel.FindPartModulesImplementing<KuarqGenerator>(); * if (kuarqModules == null || kuarqModules.Count() < 1) * { * stopResearch(KUARQS); * } * } */ if (numBioproducts > 0 && Inoperable) { StopResearch(BIOPRODUCTS); } if (requirements.ContainsKey(BIOPRODUCTS) && GetScienceCount() > 0 && numBioproducts < requirements[BIOPRODUCTS].amount) //if (bioproductsRequired > 0 && GetScienceCount() > 0 && numBioproducts < bioproductsRequired) { ResetExperiment(); } #if false // make sure we keep updating while changes are possible if (currentStatus == Status.Running || currentStatus == Status.Completed || currentStatus == Status.BadLocation) { ReadyToDeploy(false); } #endif ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(experimentID); if (currentStatus == Status.Running && !experiment.IsAvailableWhile(GetScienceSituation(vessel), vessel.mainBody)) { ScreenMessages.PostScreenMessage(Localizer.Format("Can't perform experiment here."), 6, ScreenMessageStyle.UPPER_CENTER); currentStatus = Status.BadLocation; } yield return(new UnityEngine.WaitForSeconds(1f)); } }
private bool canRunExperiment(ModuleScienceExperiment currentExperiment, ScienceExperiment experiment, float currentScienceValue, bool DMagic = false) { if (!DMagic) { if (!experiment.IsAvailableWhile(currentSituation, currentBody))// { //experiment.mask Utilities.debug(modName, Utilities.LogMode.Debug, currentExperiment.experimentID + ": Experiment isn't available in the current situation: " + currentSituation + "_" + currentBody + "_" + experiment.situationMask); return false; } if (currentExperiment.Inoperable)// { Utilities.debug(modName, Utilities.LogMode.Debug, currentExperiment.experimentID + ": Experiment is inoperable"); return false; } if (currentExperiment.Deployed)// { Utilities.debug(modName, Utilities.LogMode.Debug, currentExperiment.experimentID + ": Experiment is deployed"); return false; } } if (!currentExperiment.rerunnable && !currentSettings.getBool("runOneTimeScience")) { Utilities.debug(modName, Utilities.LogMode.Debug, currentExperiment.experimentID + ": Runing rerunable experiments is disabled"); return false; } if (currentScienceValue < currentSettings.getFloat("scienceCutoff")) { Utilities.debug(modName, Utilities.LogMode.Debug, currentExperiment.experimentID + ": Science value is less than cutoff threshold: " + currentScienceValue + "<" + currentSettings.getFloat("scienceCutoff")); return false; } if (!experiment.IsUnlocked()) { Utilities.debug(modName, Utilities.LogMode.Debug, currentExperiment.experimentID + ": Experiment is locked"); return false; } var ModuleAnimateGeneric = currentExperiment.part.FindModuleImplementing<ModuleAnimateGeneric>(); if (ModuleAnimateGeneric != null) { if (ModuleAnimateGeneric.status != "Locked") { Utilities.debug(modName, Utilities.LogMode.Debug, "Animation status isn't locked:" + ModuleAnimateGeneric.status + "_" + currentExperiment.part.name); return false; } } return true; }
public void Update() { if (Input.GetMouseButtonUp(0)) { resizingWindow = false; } if (resizingWindow) { windowPosition.width = Input.mousePosition.x - windowPosition.x + 10; windowPosition.height = (Screen.height - Input.mousePosition.y) - windowPosition.y + 10; } // using "while" for possibility to "break". So we dont have to use GOTO. using timer to skip frames. while (drawWindow && (lateUpdateTimer < Time.time || lateUpdateTimerCounter > 3)) { lateUpdateTimer = Time.time + 1; ExperimentSituations experimentSituation = ScienceUtil.GetExperimentSituation(FlightGlobals.ActiveVessel); CelestialBody mainbody = FlightGlobals.ActiveVessel.mainBody; string biome; if (FlightGlobals.ActiveVessel.landedAt != string.Empty) { biome = FlightGlobals.ActiveVessel.landedAt; } else { biome = ScienceUtil.GetExperimentBiome(FlightGlobals.ActiveVessel.mainBody, FlightGlobals.ActiveVessel.latitude, FlightGlobals.ActiveVessel.longitude); } if (mainbody == lastMainBody && biome == lastBiome && lastExperimentSituation == experimentSituation && lateUpdateTimerCounter <= 3) { lateUpdateTimer = 0; lateUpdateTimerCounter++; break; } lateUpdateTimerCounter = 0; lastBiome = biome; lastMainBody = mainbody; lastExperimentSituation = experimentSituation; Output.Clear(); OnShip.Clear(); //List<ScienceExperiment> PossibleExperiments = new List<ScienceExperiment>(); //Search for all Science Experiment Modules on vessel, Check experiment available and add in "Output" and "OnShip" foreach (ModuleScienceExperiment moduleScienceExperiment in FlightGlobals.ActiveVessel.FindPartModulesImplementing <ModuleScienceExperiment>()) { string firstExperimentId = moduleScienceExperiment.experimentID; ScienceExperiment scienceExperiment = ResearchAndDevelopment.GetExperiment(firstExperimentId); bool available = scienceExperiment.IsAvailableWhile(experimentSituation, mainbody); if (available) { if (moduleScienceExperiment.Deployed) { foreach (ScienceData scienceData in moduleScienceExperiment.GetData()) { ExperimentView experimentView = new ExperimentView(scienceData); if (!Output.Contains(experimentView)) { Output.Add(experimentView); } OnShip.Add(experimentView); } } { ScienceSubject scienceSubject = LibraryUtils.GetExperimentSubject(scienceExperiment, experimentSituation, mainbody, scienceExperiment.BiomeIsRelevantWhile(experimentSituation) ? biome : ""); ExperimentView experimentView = new ExperimentView(scienceSubject); if (!Output.Contains(experimentView)) { Output.Add(experimentView); } } } } // Check for Kerbals on board. That means we can also use "evaReport", "surfaceSample", "asteroidSample" in EVA. if (FlightGlobals.ActiveVessel.GetCrewCount() > 0) { { string firstExperimentId = "evaReport"; ScienceExperiment scienceExperiment = ResearchAndDevelopment.GetExperiment(firstExperimentId); bool available = scienceExperiment.IsAvailableWhile(experimentSituation, mainbody); if (available) { ScienceSubject scienceSubject = LibraryUtils.GetExperimentSubject(scienceExperiment, experimentSituation, mainbody, scienceExperiment.BiomeIsRelevantWhile(experimentSituation) ? biome : ""); ExperimentView experimentView = new ExperimentView(scienceSubject); if (!Output.Contains(experimentView)) { Output.Add(experimentView); } } } { string firstExperimentId = "surfaceSample"; ScienceExperiment scienceExperiment = ResearchAndDevelopment.GetExperiment(firstExperimentId); bool available = scienceExperiment.IsAvailableWhile(experimentSituation, mainbody); if (available) { ScienceSubject scienceSubject = LibraryUtils.GetExperimentSubject(scienceExperiment, experimentSituation, mainbody, scienceExperiment.BiomeIsRelevantWhile(experimentSituation) ? biome : ""); ExperimentView experimentView = new ExperimentView(scienceSubject); if (!Output.Contains(experimentView)) { Output.Add(experimentView); } } } // Find asteroid that could be used for science. (I hope it will not be too many asteroids, because of linear complexity of this code) ModuleAsteroid[] asteroids = FindObjectsOfType <ModuleAsteroid>(); foreach (ModuleAsteroid asteroid in asteroids) { Vector3 destination3 = asteroid.gameObject.transform.position - FlightGlobals.ActiveVessel.gameObject.transform.position; float unfocusedRange = asteroid.Events["TakeSampleEVAEvent"].unfocusedRange; unfocusedRange *= unfocusedRange; if (destination3.sqrMagnitude < unfocusedRange) { string firstExperimentId = "asteroidSample"; ScienceExperiment scienceExperiment = ResearchAndDevelopment.GetExperiment(firstExperimentId); bool available = scienceExperiment.IsAvailableWhile(experimentSituation, mainbody); if (available) { string asteroidname = asteroid.part.partInfo.name + asteroid.part.flightID; ScienceSubject scienceSubject = LibraryUtils.GetExperimentSubject(scienceExperiment, experimentSituation, asteroidname, "", mainbody, scienceExperiment.BiomeIsRelevantWhile(experimentSituation) ? biome : ""); ExperimentView experimentView = new ExperimentView(scienceSubject); if (!Output.Contains(experimentView)) { Output.Add(experimentView); } } } } } //Search for all Science Containers on vessel and write all found experiments into OnShip list foreach (ModuleScienceContainer moduleScienceContainer in FlightGlobals.ActiveVessel.FindPartModulesImplementing <ModuleScienceContainer>()) { foreach (ScienceData scienceData in moduleScienceContainer.GetData()) { ExperimentView experimentView = new ExperimentView(scienceData); //if (!Output.Contains(experimentView)) Output.Add(experimentView); OnShip.Add(experimentView); } } Output.Sort(); break; } }
/// <summary> /// Performs actions on experiments. Run/Transfer/Review/Reset /// </summary> /// <param name="moduleScienceExperiment"></param> /// <returns>false if nothing is left to do, true otherwise</returns> private bool RunExperiment(ModuleScienceExperiment moduleScienceExperiment) { Log.Write($" {moduleScienceExperiment.part.partInfo.title}/{moduleScienceExperiment.experiment.experimentTitle}"); Log.Write($" rerunnable:{moduleScienceExperiment.rerunnable} resettable:{moduleScienceExperiment.resettable} deployed:{moduleScienceExperiment.Deployed} inpoerable:{moduleScienceExperiment.Inoperable}"); // // If the experiment is already deployed but not yet handled, don't try to re-run it // if (moduleScienceExperiment.Deployed && !moduleScienceExperiment.Inoperable) // return false; // Filter by mode if (!moduleScienceExperiment.rerunnable) { switch (mode) { case Modes.RerunnableOnly: Log.Write($" We haven't unlocked the mode to run this experiment yet"); return(false); case Modes.RerunnableAndResettableWithScientist: if (currentVessel.GetVesselCrew().Find(x => x.trait == "Scientist") == null) { Log.Write($" We either need to unlock the next mode or bring a scientist along with us for this"); return(false); } break; } } //ScienceExperiment scienceExperiment = moduleScienceExperiment.experiment; ScienceExperiment scienceExperiment = ResearchAndDevelopment.GetExperiment(moduleScienceExperiment.experimentID); // lookup from R&D instead of pulling from ModuleScienceExperiment.experiment becuase DMagic is misbehaving. // Log.Write($"Using science experiment:{1}[{5}] with biomeMask: {2} situationMask: {3} baseValue: {4}", scienceExperiment.id, scienceExperiment.biomeMask, scienceExperiment.situationMask, scienceExperiment.baseValue, scienceExperiment.experimentTitle); // Review data? if (moduleScienceExperiment.Deployed && !moduleScienceExperiment.Inoperable) { if (KerbalismAPI.KerbalismInstalled) { Log.Write($" Kerbalism installed, attempting to send science data straight to hard drive"); // file or sample? (as per kerbalisms definition) bool sample = moduleScienceExperiment.xmitDataScalar < 0.666f; Log.Write($" {moduleScienceExperiment.experimentID} is a {(sample ? "sample" : "file")}"); ScienceData[] data = moduleScienceExperiment.GetDataUsingReflection(); for (int i = 0; i < data.Count(); i++) { Log.Write($" Storing {data[i].subjectID} in hard drive"); if (sample) { KerbalismAPI.StoreSample(currentVessel, data[i].subjectID, data[i].dataAmount); } else { KerbalismAPI.StoreFile(currentVessel, data[i].subjectID, data[i].dataAmount); } // get rid of the data in the experiment now Log.Write($" Dumping {data[i].subjectID} from experiment"); moduleScienceExperiment.DumpDataUsingReflection(data[i]); } } else { Log.Write($" Attempting to review data to force collection..."); moduleScienceExperiment.ReviewDataUsingReflection(); } return(true); } // Reset inoperable experiments if (moduleScienceExperiment.resettable && moduleScienceExperiment.Inoperable) { Log.Write($" Resetting experiment"); // Log.Write($"Science AI is cleaning {scienceExperiment.experimentTitle}", DebugFormat.Screen, true); moduleScienceExperiment.ResetExperimentUsingReflection(); return(true); } // check if we can even run this experiment now if (!scienceExperiment.IsAvailableWhile(currentSituation, currentVessel.mainBody)) { Log.Write($" Cannot run in {currentSituation} on {currentVessel.mainBody}."); return(false); } string experimentSpecificBiome = string.Empty; if (scienceExperiment.BiomeIsRelevantWhile(currentSituation)) { experimentSpecificBiome = currentBiome; } // check science value of experiment based on what is returned to KSC R&D and what is presently stored on the vessel (including science containers and kerbalism data drives) ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(scienceExperiment, currentSituation, currentVessel.mainBody, experimentSpecificBiome, null); List <ScienceData> storedData; int numberOfExperimentsOnBoard = GetNumberOfExperimentsOnBoard(subject, out storedData); // Check for duplicate experiments if (numberOfExperimentsOnBoard > 0) { Log.Write($" We already have this experiment on board"); return(false); } float scienceValue = GetScienceValue(scienceExperiment, subject, storedData); if (scienceValue < 0.01) { Log.Write($" Science value is too low ({scienceValue} science). Not running."); return(false); } // run the experiment Log.Write($" Running experiment {moduleScienceExperiment.part.partInfo.title}/{moduleScienceExperiment.experiment.experimentTitle} for {scienceValue} science in biome {currentSituation.ToString()} {currentBiome}."); moduleScienceExperiment.DeployExperimentUsingReflection(); // Log.Write($"<color=#BBBB00><b>Science AI</b></color>\nRunning <b>{scienceExperiment.experimentTitle}</b>\n<i>Hold onto your knickers!</i>", DebugFormat.Screen, true); return(true); }
public void GetSciData() { if (ResearchAndDevelopment.Instance == null) { return; } dataOutputList = new List <Experiment>(); List <ScienceSubject> newExperiments = new List <ScienceSubject>(); List <string> exIds = ResearchAndDevelopment.GetExperimentIDs(); List <ScienceSubject> subjectslist = ResearchAndDevelopment.GetSubjects(); //I am glad this code runs only once! Too expensive! foreach (string id in exIds) { foreach (ExperimentSituations experimentSituation in Enum.GetValues(typeof(ExperimentSituations))) { foreach (CelestialBody body in FlightGlobals.Bodies) { bool ocean = body.ocean; if (ExperimentSituations.SrfSplashed == experimentSituation && !ocean) { continue; } if ((ExperimentSituations.FlyingHigh == experimentSituation || ExperimentSituations.FlyingLow == experimentSituation) && !body.atmosphere) { continue; } ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(id); bool available = experiment.IsAvailableWhile(experimentSituation, body); if (available) { bool shouldHaveBiome = experiment.BiomeIsRelevantWhile(experimentSituation); if (shouldHaveBiome) { foreach (string biome in ResearchAndDevelopment.GetBiomeTags(body)) { if (KSPScienceSettings.getBoolSetting("ShowOnlyKnownBiomes")) { bool foundBiome = subjectslist.Any(subject => subject.id.Contains("@" + body.name) && subject.id.Contains(biome.Replace(" ", ""))); if (!foundBiome) { continue; } } ScienceSubject ssj = new ScienceSubject(experiment, experimentSituation, body, biome); if (id == "asteroidSample") { ssj.scienceCap = experiment.scienceCap; } newExperiments.Add(ssj); } if (body.BiomeMap == null || body.BiomeMap.Attributes.Length == 0) { ScienceSubject ssj = new ScienceSubject(experiment, experimentSituation, body, ""); if (id == "asteroidSample") { ssj.scienceCap = experiment.scienceCap; } newExperiments.Add(ssj); } } else { ScienceSubject ssj = new ScienceSubject(experiment, experimentSituation, body, ""); if (id == "asteroidSample") { ssj.scienceCap = experiment.scienceCap; } newExperiments.Add(ssj); } } } } } foreach (ScienceSubject scienceSubject in subjectslist) { newExperiments.RemoveAll(subject => subject.id == scienceSubject.id); string title = scienceSubject.id; double earned = Math.Round(scienceSubject.science, 1); double remain = Math.Round(scienceSubject.scienceCap - scienceSubject.science, 1); string body = LibraryUtils.FindExperimentBody(scienceSubject.id.Split('@')[1]); string type = scienceSubject.id.Split('@')[0]; Experiment experiment = new Experiment(title, earned, remain, body, type); dataOutputList.Add(experiment); } foreach (ScienceSubject newExperiment in newExperiments) { newExperiment.scientificValue = 1f; CelestialBody thisBody = FlightGlobals.Bodies.Find(celestialBody => newExperiment.id.Split('@')[1].StartsWith(celestialBody.name)); Experiment ex = new Experiment(newExperiment.id, 0, Math.Round(newExperiment.scienceCap, 1), thisBody.name, newExperiment.id.Split('@')[0]); dataOutputList.Add(ex); } dataOutputList.Sort(SortByName); if (KSPScienceSettings.getBoolSetting("ShowOnlyKnownExperiments")) { allExperimentTypes = GetKnownExperimentTypes(); } else { allExperimentTypes = GetAllExperimentTypes(); } }
public static bool IsAvailableWhileFixed(this ScienceExperiment experiment, ExperimentSituations situations, CelestialBody body) { return(experiment.IsAvailableWhile(situations, body) && !(experiment.experimentTitle == "Sample" && !(situations == ExperimentSituations.SrfLanded || situations == ExperimentSituations.SrfSplashed))); }