public override bool RequirementMet(ConfiguredContract contract) { foreach (AvailablePart part in parts) { if (!ResearchAndDevelopment.PartModelPurchased(part)) { return(false); } } return(true); }
/// <inheritdoc /> public override ScienceSubject GetScienceSubject(ModuleScienceExperimentWrapper <T> baseExperimentWrapper) { var scienceExperiment = ResearchAndDevelopment.GetExperiment(baseExperimentWrapper.BaseObject.experimentID); Log($"{nameof(GetScienceSubject)} => changed from '{baseExperimentWrapper.BaseObject.experiment?.id ?? "null"}' to '{scienceExperiment.id}')"); var currentBiome = CurrentBiome(baseExperimentWrapper.experiment); var result = ResearchAndDevelopment.GetExperimentSubject(scienceExperiment, ScienceUtil.GetExperimentSituation(FlightGlobals.ActiveVessel), FlightGlobals.currentMainBody, currentBiome, ScienceUtil.GetBiomedisplayName(FlightGlobals.currentMainBody, currentBiome)); Log($"{nameof(GetScienceSubject)} results in '{result.id}' / '{result.title}'"); return(result); }
/// <summary> /// Replace for ResearchAndDevelopment.GetExperimentSubject function. Original function inserts new ScienceSubject in /// the database, but we do not want that. /// </summary> /// <param name="experiment"></param> /// <param name="situation"></param> /// <param name="sourceUId"></param> /// <param name="sourceTitle"></param> /// <param name="body"></param> /// <param name="biome"></param> /// <returns></returns> public static ScienceSubject GetExperimentSubject(ScienceExperiment experiment, ExperimentSituations situation, string sourceUId, string sourceTitle, CelestialBody body, string biome) { ScienceSubject scienceSubject = new ScienceSubject(experiment, situation, sourceUId, sourceTitle, body, biome); ScienceSubject subject = ResearchAndDevelopment.GetSubjectByID(scienceSubject.id); // this will cause error in log, but it is intended behavior. if (subject != null) { return(subject); } return(scienceSubject); }
/// <summary> /// Gets the subject with the specified ID as a floating-point fraction. /// </summary> /// <param name="subjectID"></param> /// <returns></returns> public static float Get(string subjectID) { if (ResearchAndDevelopment.Instance == null) { return(1); // it's a sandbox game } ScienceSubject subject = ResearchAndDevelopment.GetSubjectByID(subjectID); // subject will be null if we've never retrieved this science result before return((subject == null) ? 1 : ResearchAndDevelopment.GetSubjectValue(subject.science, subject)); }
public int RebuildObserverList() { observers.Clear(); ScanInterface scanInterface = GetComponent <ScanInterface>(); if (scanInterface == null) { Log.Error("ExperimentManager.RebuildObserverList: No ScanInterface component found"); // this is bad; things won't break if the scan interface } // construct the experiment observer list ... foreach (var expid in ResearchAndDevelopment.GetExperimentIDs()) { if (expid != "evaReport" && expid != "surfaceSample") // special cases { if (FlightGlobals.ActiveVessel.FindPartModulesImplementing <ModuleScienceExperiment>().Any(mse => mse.experimentID == expid)) { observers.Add(new ExperimentObserver(vesselStorage, ProfileManager.ActiveProfile[expid], biomeFilter, scanInterface, expid)); } } } observers.Add(new SurfaceSampleObserver(vesselStorage, ProfileManager.ActiveProfile["surfaceSample"], biomeFilter, scanInterface)); try { if (ProfileManager.ActiveProfile["evaReport"].Enabled) { if (Settings.Instance.EvaReportOnTop) { observers = observers.OrderBy(obs => obs.ExperimentTitle).ToList(); observers.Insert(0, new EvaReportObserver(vesselStorage, ProfileManager.ActiveProfile["evaReport"], biomeFilter, scanInterface)); } else { observers.Add(new EvaReportObserver(vesselStorage, ProfileManager.ActiveProfile["evaReport"], biomeFilter, scanInterface)); observers = observers.OrderBy(obs => obs.ExperimentTitle).ToList(); } } else { observers = observers.OrderBy(obs => obs.ExperimentTitle).ToList(); } } catch (NullReferenceException e) { Log.Error("ExperimentManager.RebuildObserverList: Active profile does not seem to have an \"evaReport\" entry; {0}", e); } watcher = UpdateObservers(); // to prevent any problems by rebuilding in the middle of enumeration OnObserversRebuilt(); return(observers.Count); }
public ProtoExperimentDevice(ProtoPartModuleSnapshot proto, Experiment prefab, uint part_id, string vessel_name, List <KeyValuePair <Experiment, ProtoPartModuleSnapshot> > allExperiments) { this.proto = proto; this.prefab = prefab; this.part_id = part_id; this.allExperiments = allExperiments; this.title = Lib.SpacesOnCaps(ResearchAndDevelopment.GetExperiment(prefab.experiment_id).experimentTitle).Replace("E V A", "EVA"); this.exp_name = (prefab.sample_mass < float.Epsilon ? "sensor" : "experiment") + ": " + title.ToLower(); this.vessel_name = vessel_name; }
protected void UnlockParts() { foreach (AvailablePart part in parts) { ProtoTechNode techNode = ResearchAndDevelopment.Instance.GetTechState(part.TechRequired); if (techNode == null || techNode.state != RDTech.State.Available) { ResearchAndDevelopment.AddExperimentalPart(part); } } }
protected void getResultsText() { List <string> results = new List <string>(); string situation = ScienceUtil.GetExperimentSituation(part.vessel).ToString(); ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(scienceLab.experimentID); if (experiment == null) { resultsText = "You've done some basic research."; return; } string resultKey; string biomeName = ""; CBAttributeMapSO.MapAttribute biome = Utils.GetCurrentBiome(this.part.vessel); if (biome != null) { biomeName = "'s " + biomeName; } this.WindowTitle = experiment.experimentTitle + " from " + this.part.vessel.mainBody.name + biomeName; foreach (string key in experiment.Results.Keys) { resultKey = key.Replace("*", ""); if (resultKey.Contains(situation)) { results.Add(experiment.Results[key]); } } if (results.Count == 0) { if (experiment.Results.ContainsKey("default")) { resultsText = experiment.Results["default"]; } else { resultsText = "You've done some basic research."; } return; } int resultIndex = UnityEngine.Random.Range(0, results.Count); if (resultIndex >= results.Count) { resultIndex = results.Count - 1; } resultsText = results[resultIndex]; }
bool AllUnlocked(HashSet <string> set) { foreach (string entry in set) { AvailablePart part = PartLoader.getPartInfoByName(entry); if (!(ResearchAndDevelopment.PartTechAvailable(part) && ResearchAndDevelopment.PartModelPurchased(part))) { return(false); } } return(true); }
public static void ResetScienceGains(Part part) { ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(kBiomeAnalysisID); //Kerbin low orbit has a science multiplier of 1. ScienceSubject subjectLEO = ResearchAndDevelopment.GetExperimentSubject(experiment, ExperimentSituations.InSpaceLow, FlightGlobals.GetHomeBody(), "", ""); //This ensures you can re-run the experiment. subjectLEO.science = 0f; subjectLEO.scientificValue = 1f; }
/// <summary> /// Determines if a part is available for the current game mode and researched techs. /// </summary> /// <param name="part">The part to be evaluated.</param> /// <returns>A value indicating if the part is available.</returns> private static bool GetPartAvailability(AvailablePart part) { var available = true; if ((HighLogic.CurrentGame.Mode == Game.Modes.CAREER) || (HighLogic.CurrentGame.Mode == Game.Modes.SCIENCE_SANDBOX)) { available = ResearchAndDevelopment.PartModelPurchased(part); } return(available); }
public override string Info() { var exp = ResearchAndDevelopment.GetExperiment(experiment.experiment_id); var sampleSize = (exp.scienceCap * exp.dataScale); var recordedPercent = Lib.HumanReadablePerc(experiment.dataSampled / sampleSize); var eta = experiment.data_rate < double.Epsilon || experiment.dataSampled >= sampleSize ? " done" : " T-" + Lib.HumanReadableDuration((sampleSize - experiment.dataSampled) / experiment.data_rate); return(!experiment.recording ? "<color=red>" + Localizer.Format("#KERBALISM_Generic_DISABLED") + " </color>" : experiment.issue.Length == 0 ? "<color=cyan>" + Lib.BuildString(recordedPercent, eta) + "</color>" : Lib.BuildString("<color=yellow>", experiment.issue.ToLower(), "</color>")); }
private void GainScience(List <ScienceExperiment> experiments, bool analyze) { // Let's get science objects in all KSC biomes foreach (var experiment in experiments.Where(x => x.IsAvailableWhile(ExperimentSituations.SrfLanded, HomeBody))) { float gain = 0.0f; foreach (var biome in kscBiomes) { ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject( experiment, ExperimentSituations.SrfLanded, HomeBody, biome, null ); if (subject.science < subject.scienceCap) { if (analyze) { gain += (subject.scienceCap - subject.science) * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; } else { // We want to get full science reward subject.subjectValue = 1.0f; gain += ResearchAndDevelopment.Instance.SubmitScienceData( subject.scienceCap * subject.dataScale, subject ); } } } if (gain >= 0.01f) { if (analyze) { availableExperiments.Add( new AvailableExperiment { experiment = experiment, possibleGain = gain, done = false } ); } else { Report(experiment, gain); } } } }
public override string DoScience(Vector3 TargetPosition, float scienceMultiplier, float FOV, Texture2D Screenshot) { Vessel TargetVessel = FlightGlobals.fetch.VesselTarget.GetVessel(); //If target is not an asteroid if (TargetVessel == null || TargetVessel.vesselType != VesselType.SpaceObject) { return(Type + ": Invalid target type!"); } //if target is not in telescope view else if (TargetPosition == new Vector3(-1, -1, 0)) { return(Type + ": Target not in scope field of view."); } else if (FOV > 0.5f) { return(Type + ": Scope not zoomed in far enough."); } else if (CactEyeAPI.CheckOccult(TargetVessel) != "") { return(Type + ": Target is occulted by another body."); } else { float SciencePoints = 0f; ExperimentID = "CactEyeAsteroid"; ScienceExperiment AsteroidExperiment = ResearchAndDevelopment.GetExperiment(ExperimentID); ScienceSubject AsteroidSubject = ResearchAndDevelopment.GetExperimentSubject(AsteroidExperiment, ExperimentSituations.InSpaceHigh, FlightGlobals.ActiveVessel.mainBody, "", ""); SciencePoints += AsteroidExperiment.baseValue * AsteroidExperiment.dataScale * maxScience; //These two lines cause a bug where the experiment gives an infinite supply of science points. //WideFieldSubject.scientificValue = 1f; //WideFieldSubject.science = 0f; if (CactEyeConfig.DebugMode) { Debug.Log("CactEye 2: SciencePoints: " + SciencePoints.ToString()); } //Different scopes have different multipliers for the science gains. SciencePoints *= scienceMultiplier; ScienceData Data = new ScienceData(SciencePoints, 1f, 0f, AsteroidSubject.id, Type + " " + FlightGlobals.activeTarget.name + " Observation"); StoredData.Add(Data); ReviewData(Data, Screenshot); return(""); } }
public string ContextRedirect(string destination) { foreach (string techName in techsRequired) { if (ResearchAndDevelopment.GetTechnologyState(techName) == RDTech.State.Unavailable) { return(fallbackPageName); } } return(redirectPages[destination]); }
// specifics support public Specifics Specs() { Specifics specs = new Specifics(); specs.add("slots", slots.ToString()); specs.add("reconfigure", new CrewSpecs(reconfigure).info()); specs.add(string.Empty); specs.add("setups:"); // organize setups by tech required, and add the ones without tech Dictionary <string, List <string> > org = new Dictionary <string, List <string> >(); foreach (ConfigureSetup setup in setups) { if (setup.tech.Length > 0) { if (!org.ContainsKey(setup.tech)) { org.Add(setup.tech, new List <string>()); } org[setup.tech].Add(setup.name); } else { specs.add(Lib.BuildString("• <b>", setup.name, "</b>")); } } // add setups grouped by tech foreach (var pair in org) { // shortcuts string tech_id = pair.Key; List <string> setup_names = pair.Value; // get tech title // note: non-stock technologies will return empty titles, so we use tech-id directly in that case string tech_title = ResearchAndDevelopment.GetTechnologyTitle(tech_id).ToLower(); tech_title = !string.IsNullOrEmpty(tech_title) ? tech_title : tech_id; // add tech name specs.add(string.Empty); specs.add(Lib.BuildString("<color=#00ffff>", tech_title, ":</color>")); // add setup names foreach (string setup_name in setup_names) { specs.add(Lib.BuildString("• <b>", setup_name, "</b>")); } } return(specs); }
ScienceSubject currentScienceSubject(ScienceExperiment experiment) { string fixBiome = string.Empty; // some biomes don't have 4th string, so we just put an empty in to compare strings later if (experiment.BiomeIsRelevantWhile(currentSituation())) { // for those that do, we add it to the string fixBiome = currentBiome(); } //ikr!, we pretty much did all the work already, jeez return(ResearchAndDevelopment.GetExperimentSubject(experiment, currentSituation(), mainBody, fixBiome)); }
private ScienceData makeScience(float boost) { ExperimentSituations vesselSituation = getSituation(); string biome = getBiome(vesselSituation); CelestialBody mainBody = vessel.mainBody; bool asteroids = false; //Check for asteroids and alter the biome and celestialbody values as necessary if (asteroidReports && (DMAsteroidScience.asteroidGrappled() || DMAsteroidScience.asteroidNear())) { newAsteroid = new DMAsteroidScience(); asteroids = true; mainBody = newAsteroid.body; biome = newAsteroid.aType + newAsteroid.aSeed.ToString(); } ScienceData data = null; ScienceExperiment exp = null; ScienceSubject sub = null; exp = ResearchAndDevelopment.GetExperiment(experimentID); if (exp == null) { Debug.LogError("[DM] Something Went Wrong Here; Null Experiment Returned; Please Report This On The KSP Forum With Output.log Data"); return(null); } sub = ResearchAndDevelopment.GetExperimentSubject(exp, vesselSituation, mainBody, biome); if (sub == null) { Debug.LogError("[DM] Something Went Wrong Here; Null Subject Returned; Please Report This On The KSP Forum With Output.log Data"); return(null); } if (asteroids) { DMUtils.OnAsteroidScience.Fire(newAsteroid.aClass, experimentID); sub.title = exp.experimentTitle + astCleanup(vesselSituation, newAsteroid.aType); registerDMScience(newAsteroid, exp, sub, vesselSituation, biome); mainBody.bodyName = bodyNameFixed; } else { DMUtils.OnAnomalyScience.Fire(mainBody, experimentID, biome); sub.title = exp.experimentTitle + situationCleanup(vesselSituation, biome); sub.subjectValue = fixSubjectValue(vesselSituation, sub.subjectValue, boost, mainBody); sub.scienceCap = exp.scienceCap * sub.subjectValue; } data = new ScienceData(exp.baseValue * sub.dataScale, xmitDataScalar, 0f, sub.id, sub.title); return(data); }
// return value of some data about a subject, in science credits public static double value(string subject_id, double size) { // get the subject // - will be null in sandbox ScienceSubject subject = ResearchAndDevelopment.GetSubjectByID(subject_id); // return value in science credits return(subject != null ? ResearchAndDevelopment.GetScienceValue((float)size, subject) * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier : 0.0); }
public void NewRecoveryFunctionTrackingStation() { selectedVessel = null; SpaceTracking trackingStation = (SpaceTracking)FindObjectOfType(typeof(SpaceTracking)); selectedVessel = trackingStation.SelectedVessel; if (selectedVessel == null) { Debug.Log("[KCT] Error! No Vessel selected."); return; } bool sph = (selectedVessel.IsRecoverable && selectedVessel.IsClearToSave() == ClearToSaveStatus.CLEAR); string reqTech = KCT_PresetManager.Instance.ActivePreset.generalSettings.VABRecoveryTech; bool vab = selectedVessel.IsRecoverable && selectedVessel.IsClearToSave() == ClearToSaveStatus.CLEAR && (selectedVessel.situation == Vessel.Situations.PRELAUNCH || string.IsNullOrEmpty(reqTech) || ResearchAndDevelopment.GetTechnologyState(reqTech) == RDTech.State.Available); int cnt = 2; if (sph) { cnt++; } if (vab) { cnt++; } DialogGUIBase[] options = new DialogGUIBase[cnt]; cnt = 0; if (sph) { options[cnt++] = new DialogGUIButton("Recover to SPH", RecoverToSPH); } if (vab) { options[cnt++] = new DialogGUIButton("Recover to VAB", RecoverToVAB); } options[cnt++] = new DialogGUIButton("Normal recovery", DoNormalRecovery); options[cnt] = new DialogGUIButton("Cancel", Cancel); MultiOptionDialog diag = new MultiOptionDialog("scrapVesselPopup", "Do you want KCT to do the recovery?", "Recover Vessel", null, options: options); PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), diag, false, HighLogic.UISkin); }
public void switchMode() { try { if (mode == "") { switchToRadiative(); } if (mode == "ablator") { switchFromAblator(); } switch (mode) { case "radiative": mode = "ablator"; if (techAblator == null || ResearchAndDevelopment.GetTechnologyState(techAblator) == RDTech.State.Available) { switchToAblator(); } else { switchMode(); } break; case "ablator": mode = "regenerative"; if (techRegenerative == null || ResearchAndDevelopment.GetTechnologyState(techRegenerative) == RDTech.State.Available) { switchToRegenerative(); } else { switchMode(); } break; case "regenerative": mode = "radiative"; switchToRadiative(); break; } } catch (Exception e) { Debug.LogError("[EngineCoolerModule]ERROR " + e); } GameEvents.onEditorShipModified.Fire(EditorLogic.fetch.ship); }
private void UpdateExperiments( ) { // var StartTime = DateTime.Now; _experiments.Clear( ); for (int x = 0; x < PartLoader.LoadedPartsList.Count; x++) { AvailablePart P = PartLoader.LoadedPartsList[x]; List <ModuleScienceExperiment> Modules; // In KSP 1.8.0, this can throw a NullReferenceException. try { if (P.partPrefab.Modules.Contains <ModuleScienceExperiment>()) { Modules = P.partPrefab.FindModulesImplementing <ModuleScienceExperiment>(); } else { continue; } } catch (NullReferenceException e) { _logger.Info(P.name + " threw NullReferenceException in " + e.TargetSite); continue; } for (int y = 0; y < Modules.Count; y++) { ModuleScienceExperiment Module = Modules[y]; if (Module != null) { if (Module.experimentID != null) { ScienceExperiment Experiment = ResearchAndDevelopment.GetExperiment(Module.experimentID); if (Experiment != null) { if (!_experiments.ContainsKey(Experiment)) { _experiments.Add(Experiment, Module); } } } } } } //_logger.Trace( "_experiments contains " + _experiments.Count.ToString( ) + " items" ); //var Elapsed = DateTime.Now - StartTime; //_logger.Trace( "UpdateExperiments Done - " + Elapsed.ToString( ) + "ms" ); }
ScienceData newScienceData(ModuleScienceExperiment currentExperiment) // construct our own science data for an experiment { ScienceExperiment se = ResearchAndDevelopment.GetExperiment(currentExperiment.experimentID); ScienceSubject ss = currentScienceSubject(se); return(new ScienceData( amount: se.baseValue *ss.dataScale, xmitValue: currentExperiment.xmitDataScalar, labBoost: 0f, id: ss.id, dataName: ss.title )); }
protected void checkForUpgrade() { //If the player hasn't unlocked the upgradeTech node yet, then hide the RCS functionality. if (ResearchAndDevelopment.Instance != null && !string.IsNullOrEmpty(techRequired)) { //If the tech node hasn't been researched yet then hide the switch capability if (ResearchAndDevelopment.GetTechnologyState(techRequired) != RDTech.State.Available) { Events["ToggleTemplate"].active = false; allowSwitch = false; } } }
private Dictionary <string, PartContent> GetAvailableContents() { var edct = new Dictionary <string, PartContent>(); foreach (AvailablePart avPart in PartLoader.LoadedPartsList) { if (ResearchAndDevelopment.PartModelPurchased(avPart)) { PartContent.Get(edct, avPart.name); } } return(edct); }
public static float NextScienceReportValue(ScienceSubject subject) { if (ResearchAndDevelopment.Instance == null || HighLogic.CurrentGame == null || subject == null) { return(0.0f); } ScienceExperiment experiment = GetExperiment(subject); return(ResearchAndDevelopment.GetScienceValue( experiment.baseValue * experiment.dataScale, subject) * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier); }
protected bool ValidateExperiment(string experiment) { if (string.IsNullOrEmpty(experiment)) { return(true); } if (!ResearchAndDevelopment.GetExperimentIDs().Contains(experiment)) { throw new ArgumentException("Not a valid experiment!"); } return(true); }
public override bool MeetRequirements() { AvailablePart ap = PartLoader.getPartInfoByName("Impact Spectrometer"); if (ap != null) { if (ResearchAndDevelopment.PartTechAvailable(ap)) { return(true); } } return(false); }
public bool checkExperiment(ModuleScienceExperiment exp, ExperimentSituations expSituation, CelestialBody lastBody, string curBiome) { bool a = !exp.Inoperable && !exp.Deployed && exp.experiment.IsAvailableWhile(expSituation, lastBody) && ResearchAndDevelopment.GetScienceValue( exp.experiment.baseValue * exp.experiment.dataScale, getExperimentSubject(exp.experiment, expSituation, lastBody, curBiome)) > 1f; if (HighLogic.CurrentGame.Mode == Game.Modes.CAREER && exp.experiment.id == "surfaceSample") { a = a && checkSurfaceSample(lastBody); } return(a); }
private void Start() { if (HighLogic.LoadedSceneIsEditor) { running = false; Destroy(gameObject); } if (!SEP_Utilities.partModulesLoaded) { SEP_Utilities.loadPartModules(); } if (!SEP_Utilities.antennaModulesLoaded) { SEP_Utilities.loadAntennaParts(); } if (!SEP_Utilities.spritesLoaded) { StartCoroutine(loadSprites()); } if (ResearchAndDevelopment.GetTechnologyState(transmissionNode) == RDTech.State.Available) { transmissionUpgrade = true; } else { transmissionUpgrade = false; } if (running) { Destroy(gameObject); } if (HighLogic.LoadedSceneIsFlight) { StartCoroutine(attachWindowListener()); } instance = this; running = true; usingCommNet = HighLogic.CurrentGame.Parameters.Difficulty.EnableCommNet; GameEvents.onLevelWasLoaded.Add(onReady); GameEvents.OnGameSettingsApplied.Add(onSettingsApplied); }