public override void OnStart(StartState state) { if (Lib.DisableScenario(this)) { return; } if (Lib.IsEditor()) { return; } foreach (var module in part.Modules) { if (module.moduleName == "SCANsat" || module.moduleName == "ModuleSCANresourceScanner") { scanner = module; break; } } if (scanner == null) { return; } sensorType = Lib.ReflectionValue <int>(scanner, "sensorType"); expInfo = ScienceDB.GetExperimentInfo(experimentType); }
public ProtoExperimentDevice(Experiment prefab, ProtoPartSnapshot protoPart, ProtoPartModuleSnapshot protoModule, Vessel vessel) : base(prefab, protoPart, protoModule) { this.vessel = vessel; expInfo = ScienceDB.GetExperimentInfo(prefab.experiment_id); icon = new DeviceIcon(expInfo.SampleMass > 0f ? Textures.sample_scicolor : Textures.file_scicolor, "open experiment info", () => new ExperimentPopup(vessel, prefab, protoPart.flightID, prefab.part.partInfo.title, protoModule)); sb = new StringBuilder(); OnUpdate(); }
public void ParseIncludedExperiments() { foreach (string expId in includedExperimentsId) { ExperimentInfo includedInfo = ScienceDB.GetExperimentInfo(expId); if (includedInfo == null) { Lib.Log($"Experiment `{ExperimentId}` define a IncludedExperiment `{expId}`, but that experiment doesn't exist", Lib.LogLevel.Warning); continue; } // early prevent duplicated entries if (includedInfo.ExperimentId == ExperimentId || IncludedExperiments.Contains(includedInfo)) { continue; } IncludedExperiments.Add(includedInfo); } }
private static void UpdateResearchedFilter() { researchedExpInfos.Clear(); ExperimentInfo asteroidSample = ScienceDB.GetExperimentInfo("asteroidSample"); if (asteroidSample != null) { researchedExpInfos.Add(asteroidSample); } foreach (AvailablePart availablePart in PartLoader.LoadedPartsList) { // EVA kerbals have no tech required if (!string.IsNullOrEmpty(availablePart.TechRequired) && !ResearchAndDevelopment.PartModelPurchased(availablePart)) { continue; } List <Experiment> configureResearchedExperiments = new List <Experiment>(); foreach (PartModule partModule in availablePart.partPrefab.Modules) { if (partModule is Configure configure) { foreach (ConfigureSetup setup in configure.GetUnlockedSetups()) { foreach (ConfigureModule configureModule in setup.modules) { if (configureModule.type == "Experiment") { PartModule configuredModule = configure.Find_module(configureModule); if (configuredModule != null && configuredModule is Experiment configureExperiment) { configureResearchedExperiments.Add(configureExperiment); } } } } } } foreach (PartModule partModule in availablePart.partPrefab.Modules) { if (partModule is Experiment experiment) { if (researchedExpInfos.Contains(experiment.ExpInfo)) { continue; } bool isResearched = false; if (configureResearchedExperiments.Count > 0) { if (configureResearchedExperiments.Contains(experiment)) { isResearched = true; } } else { isResearched = true; } if (isResearched && experiment.Requirements.TestProgressionRequirements()) { researchedExpInfos.Add(experiment.ExpInfo); } } else if (partModule is ModuleScienceExperiment stockExperiment) { ExperimentInfo expInfo = ScienceDB.GetExperimentInfo(stockExperiment.experimentID); if (expInfo != null) { researchedExpInfos.Add(expInfo); } } #if !KSP15_16 else if (partModule is ModuleGroundExperiment groundExp) { ExperimentInfo expInfo = ScienceDB.GetExperimentInfo(groundExp.experimentId); if (expInfo != null) { researchedExpInfos.Add(expInfo); } } #endif } } // ROCs are always researched foreach (ExperimentInfo experimentInfo in ScienceDB.ExperimentInfos) { if (experimentInfo.IsROC) { researchedExpInfos.Add(experimentInfo); } } }
private static void UpdateVesselFilter() { vesselExpInfos.Clear(); bool hasROCScience = false; foreach (Part part in vesselParts) { foreach (PartModule partModule in part.Modules) { if (!partModule.enabled || !partModule.isEnabled) { continue; } if (partModule is Experiment experiment) { vesselExpInfos.Add(experiment.ExpInfo); } else if (partModule is ModuleScienceExperiment stockExperiment) { if (stockExperiment.experimentID == "ROCScience") { hasROCScience = true; } else { ExperimentInfo expInfo = ScienceDB.GetExperimentInfo(stockExperiment.experimentID); if (expInfo != null) { vesselExpInfos.Add(expInfo); } } } #if !KSP15_16 else if (partModule is ModuleInventoryPart inventory) { foreach (string inventoryPartName in inventory.InventoryPartsList) { Part groundPart = PartLoader.getPartInfoByName(inventoryPartName)?.partPrefab; if (groundPart == null) { continue; } foreach (PartModule groundmodule in groundPart.Modules) { if (groundmodule is ModuleGroundExperiment groundExp) { ExperimentInfo expInfo = ScienceDB.GetExperimentInfo(groundExp.experimentId); if (expInfo != null) { vesselExpInfos.Add(expInfo); } } } } } #endif } } if (hasROCScience) { foreach (ExperimentInfo experimentInfo in ScienceDB.ExperimentInfos) { if (experimentInfo.IsROC) { vesselExpInfos.Add(experimentInfo); } } } }
public static void BackgroundUpdate(Vessel vessel, ProtoPartSnapshot p, ProtoPartModuleSnapshot m, KerbalismScansat kerbalismScansat, Part part_prefab, VesselData vd, ResourceInfo ec, double elapsed_s) { List <ProtoPartModuleSnapshot> scanners = Cache.VesselObjectsCache <List <ProtoPartModuleSnapshot> >(vessel, "scansat_" + p.flightID); if (scanners == null) { scanners = Lib.FindModules(p, "SCANsat"); if (scanners.Count == 0) { scanners = Lib.FindModules(p, "ModuleSCANresourceScanner"); } Cache.SetVesselObjectsCache(vessel, "scansat_" + p.flightID, scanners); } if (scanners.Count == 0) { return; } var scanner = scanners[0]; bool is_scanning = Lib.Proto.GetBool(scanner, "scanning"); if (is_scanning && kerbalismScansat.ec_rate > double.Epsilon) { ec.Consume(kerbalismScansat.ec_rate * elapsed_s, ResourceBroker.Scanner); } if (!Features.Science) { if (is_scanning && ec.Amount < double.Epsilon) { SCANsat.StopScanner(vessel, scanner, part_prefab); is_scanning = false; // remember disabled scanner vd.scansat_id.Add(p.flightID); // give the user some feedback if (vd.cfg_ec) { Message.Post(Local.Scansat_sensordisabled.Format("<b>" + vessel.vesselName + "</b>")); //Lib.BuildString("SCANsat sensor was disabled on <<1>>) } } else if (vd.scansat_id.Contains(p.flightID)) { // if there is enough ec // note: comparing against amount in previous simulation step // re-enable at 25% EC if (ec.Level > 0.25) { // re-enable the scanner SCANsat.ResumeScanner(vessel, m, part_prefab); is_scanning = true; // give the user some feedback if (vd.cfg_ec) { Message.Post(Local.Scansat_sensorresumed.Format("<b>" + vessel.vesselName + "</b>")); //Lib.BuildString("SCANsat sensor resumed operations on <<1>>) } } } // forget active scanners if (is_scanning) { vd.scansat_id.Remove(p.flightID); } return; } // if(!Feature.Science) string body_name = Lib.Proto.GetString(m, "body_name"); int sensorType = (int)Lib.Proto.GetUInt(m, "sensorType"); double body_coverage = Lib.Proto.GetDouble(m, "body_coverage"); double warp_buffer = Lib.Proto.GetDouble(m, "warp_buffer"); double new_coverage = SCANsat.Coverage(sensorType, vessel.mainBody); if (body_name == vessel.mainBody.name && new_coverage < body_coverage) { // SCANsat sometimes reports a coverage of 0, which is wrong new_coverage = body_coverage; } if (vessel.mainBody.name != body_name) { body_name = vessel.mainBody.name; body_coverage = new_coverage; } else { double coverage_delta = new_coverage - body_coverage; body_coverage = new_coverage; if (is_scanning) { ExperimentInfo expInfo = ScienceDB.GetExperimentInfo(kerbalismScansat.experimentType); SubjectData subject = ScienceDB.GetSubjectData(expInfo, vd.VesselSituations.GetExperimentSituation(expInfo)); if (subject == null) { return; } double size = expInfo.DataSize * coverage_delta / 100.0; // coverage is 0-100% size += warp_buffer; if (size > double.Epsilon) { // store what we can foreach (var d in Drive.GetDrives(vd)) { var available = d.FileCapacityAvailable(); var chunk = Math.Min(size, available); if (!d.Record_file(subject, chunk, true)) { break; } size -= chunk; if (size < double.Epsilon) { break; } } } if (size > double.Epsilon) { // we filled all drives up to the brim but were unable to store everything if (warp_buffer < double.Epsilon) { // warp buffer is empty, so lets store the rest there warp_buffer = size; size = 0; } else { // warp buffer not empty. that's ok if we didn't get new data if (coverage_delta < double.Epsilon) { size = 0; } // else we're scanning too fast. stop. } } // we filled all drives up to the brim but were unable to store everything // cancel scanning and annoy the user if (size > double.Epsilon || ec.Amount < double.Epsilon) { warp_buffer = 0; SCANsat.StopScanner(vessel, scanner, part_prefab); vd.scansat_id.Add(p.flightID); if (vd.cfg_ec) { Message.Post(Local.Scansat_sensordisabled.Format("<b>" + vessel.vesselName + "</b>")); //Lib.BuildString("SCANsat sensor was disabled on <<1>>) } } } else if (vd.scansat_id.Contains(p.flightID)) { if (ec.Level >= 0.25 && (vd.DrivesFreeSpace / vd.DrivesCapacity > 0.9)) { SCANsat.ResumeScanner(vessel, scanner, part_prefab); vd.scansat_id.Remove(p.flightID); if (vd.cfg_ec) { Message.Post(Local.Scansat_sensorresumed.Format("<b>" + vessel.vesselName + "</b>")); //Lib.BuildString("SCANsat sensor resumed operations on <<1>>) } } } } Lib.Proto.Set(m, "warp_buffer", warp_buffer); Lib.Proto.Set(m, "body_coverage", body_coverage); Lib.Proto.Set(m, "body_name", body_name); }