/// <summary> /// Creates a new instance of the Experiment class. /// </summary> /// <param name="experiment">The ScienceExperiment to be used.</param> /// <param name="situation">The Situation this experiment is valid in.</param> /// <param name="onboardScience">A collection of all onboard ScienceData.</param> public ScienceInstance( ScienceExperiment experiment, Situation situation, ScienceContext Sci ) { _experiment = experiment; _situation = situation; ScienceSubject = null; Update( Sci ); }
/// <summary> /// Creates a new instance of the Experiment class. /// </summary> /// <param name="experiment">The ScienceExperiment to be used.</param> /// <param name="situation">The Situation this experiment is valid in.</param> /// <param name="onboardScience">A collection of all onboard ScienceData.</param> public Experiment( ScienceExperiment experiment, Situation situation, Dictionary<string, List<ScienceData>> onboardScience, Dictionary<string, ScienceSubject> SciDict, UnlockedExperimentList AvailableExperiments ) { _experiment = experiment; _situation = situation; ScienceSubject = null; Update( onboardScience, SciDict, AvailableExperiments ); }
/// <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; }
internal DMScienceContainer(ScienceExperiment sciExp, int sciSitMask, int sciBioMask, DMScienceType Type, string sciPartID, string agentName, float Transmit) { sitMask = sciSitMask; bioMask = sciBioMask; exp = sciExp; sciPart = sciPartID; agent = agentName; type = Type; transmit = Transmit; }
private static void PrepareExternalModules(Item moduleNode, ModuleScienceExperiment moduleScienceExperiment, ScienceExperiment experiment) { if (moduleNode != null) { Type t = moduleScienceExperiment.GetType(); //var meth = t.GetMethod(""); //meth.Invoke(moduleScienceExperiment, new object[]{12, 2, 6}); var field = t.GetField(moduleNode.Biome); if (field != null) { var value = field.GetValue(moduleScienceExperiment); experiment.biomeMask = Convert.ToUInt32(value); } else { var property = t.GetProperty(moduleNode.Biome); if (property != null) { var value = property.GetValue(moduleScienceExperiment, null); experiment.biomeMask = Convert.ToUInt32(value); } } field = t.GetField(moduleNode.Situation); if (field != null) { var value = field.GetValue(moduleScienceExperiment); experiment.situationMask = Convert.ToUInt32(value); } else { var property = t.GetProperty(moduleNode.Situation); if (property != null) { var value = property.GetValue(moduleScienceExperiment, null); experiment.situationMask = Convert.ToUInt32(value); } } } }
protected override bool generateScienceData() { ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(experimentID); if (experiment == null) { return(false); } if (science_to_add > 0) { ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(experiment, ScienceUtil.GetExperimentSituation(vessel), vessel.mainBody, "", ""); if (subject == null) { return(false); } subject.subjectValue = PluginHelper.getScienceMultiplier(vessel); subject.scienceCap = 167 * subject.subjectValue; subject.dataScale = 1.25f; double remaining_base_science = (subject.scienceCap - subject.science) / subject.subjectValue; science_to_add = Math.Min(science_to_add, remaining_base_science); // transmission of zero data breaks the experiment result dialog box data_size = Math.Max(float.Epsilon, science_to_add * subject.dataScale); science_data = new ScienceData((float)data_size, 1, 0, subject.id, "Science Lab Data"); result_title = experiment.experimentTitle; result_string = this.nameStr + " " + getRandomExperimentResult(); recovery_value = science_to_add; transmit_value = recovery_value; xmit_scalar = 1; ref_value = subject.scienceCap; return(true); } return(false); }
public static ScienceSubject checkAndUpdateRelatedSubjects(SEP_ExperimentHandler handler, int level, float data, float submitted) { ScienceSubject subject = null; for (int i = 1; i <= level; i++) { ScienceExperiment exp = handler.getExperimentLevel(i); if (exp == null) { continue; } string biome = currentBiome(exp, handler.vessel); subject = ResearchAndDevelopment.GetExperimentSubject(exp, ExperimentSituations.SrfLanded, handler.vessel.mainBody, biome); subject.title = exp.experimentTitle + situationCleanup(handler.vessel.mainBody, ExperimentSituations.SrfLanded, biome); if (i == level) { subject.science = submitted * subject.subjectValue; } else { subject.science = data * subject.subjectValue; } if (subject.science > subject.scienceCap) { subject.science = subject.scienceCap; } subject.scientificValue = 1 - (subject.science / subject.scienceCap); //log("Related Subject Checked: ID {0} - Science Level {1:N0}", logLevels.warning, subject.id, subject.science); } return(subject); }
private List <string> PrepareSituationAndBiomes(ScienceExperiment experiment) { List <string> result = new List <string>(); foreach (KeyValuePair <ExperimentSituations, Func <bool, string> > situationTemplate in SituationHelper.SituationTemplates) { uint situationMask = experiment.situationMask; if (ROV_Present && experiment.situationMask == 64) { situationMask = 1; } bool flag = (situationMask & (uint)situationTemplate.Key) == (uint)situationTemplate.Key; //получаем чтото если текущая ситуация совпадает с заявленной Func <bool, string> dictValue = situationTemplate.Value; // получили делегат string preparedInfo = dictValue(flag); // вызвали делегат if (flag && (experiment.biomeMask & (uint)situationTemplate.Key) == (uint)situationTemplate.Key) { preparedInfo += _biomeDepending; } result.Add(preparedInfo); } return(result); }
/// <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); }
public override void OnStart(PartModule.StartState state) { if (!string.IsNullOrEmpty(animationName)) { anim = part.FindModelAnimators(animationName)[0]; } if (!string.IsNullOrEmpty(experimentID)) { surfaceExp = ResearchAndDevelopment.GetExperiment(experimentID); } asteroidExp = ResearchAndDevelopment.GetExperiment(asteroidExperimentID); if (!string.IsNullOrEmpty(experimentActionName)) { Events["DeployExperiment"].guiName = experimentActionName; Actions["DeployAction"].guiName = experimentActionName; Actions["DeployAction"].active = useActionGroups; } if (!string.IsNullOrEmpty(audioFile)) { newClip = GameDatabase.Instance.GetAudioClip(audioFile); if (newClip != null) { soundSource = part.gameObject.AddComponent <AudioSource>(); soundSource.rolloffMode = AudioRolloffMode.Logarithmic; soundSource.dopplerLevel = 0f; soundSource.maxDistance = 10f; soundSource.playOnAwake = false; soundSource.loop = false; soundSource.volume = GameSettings.SHIP_VOLUME; soundSource.clip = newClip; soundSource.Stop(); } else { Debug.LogError("[IRSurfaceSampler] Error locating audio file at location: " + audioFile); } } }
internal static List <ExperimentSituations> availableSituationsLimited(ScienceExperiment exp, int i, CelestialBody b) { DMUtils.DebugLog("Finding Situations"); List <ExperimentSituations> expSitList = new List <ExperimentSituations>(); if (((ExperimentSituations)i & ExperimentSituations.FlyingHigh) == ExperimentSituations.FlyingHigh && b.atmosphere) { expSitList.Add(ExperimentSituations.FlyingHigh); } if (((ExperimentSituations)i & ExperimentSituations.FlyingLow) == ExperimentSituations.FlyingLow && b.atmosphere) { expSitList.Add(ExperimentSituations.FlyingLow); } if (((ExperimentSituations)i & ExperimentSituations.InSpaceLow) == ExperimentSituations.InSpaceLow) { if (!exp.requireAtmosphere) { expSitList.Add(ExperimentSituations.InSpaceLow); } else if (b.atmosphere) { expSitList.Add(ExperimentSituations.InSpaceLow); } } if (((ExperimentSituations)i & ExperimentSituations.SrfLanded) == ExperimentSituations.SrfLanded && b.pqsController != null) { if (!exp.requireAtmosphere && exp.id != "dmbiodrillscan") { expSitList.Add(ExperimentSituations.SrfLanded); } else if (b.atmosphere) { expSitList.Add(ExperimentSituations.SrfLanded); } } DMUtils.DebugLog("Found {0} Valid Experimental Situations", expSitList.Count); return(expSitList); }
private void Report(ScienceExperiment experiment, float gain) { StringBuilder msg = new StringBuilder(); string[] template; if (System.IO.File.Exists(KEI_PLUGINDATA + experiment.id + ".msg")) //if (File.Exists<KEI>(experiment.id + ".msg")) { template = System.IO.File.ReadAllLines(KEI_PLUGINDATA + experiment.id + ".msg"); //template = File.ReadAllLines<KEI>(experiment.id + ".msg"); } else { //template = File.ReadAllLines<KEI>("unknownExperiment.msg"); template = System.IO.File.ReadAllLines(KEI_PLUGINDATA + "unknownExperiment.msg"); msg.AppendLine("TOP SECRET!"); msg.AppendLine("Project " + experiment.experimentTitle); msg.AppendLine("Eat this report after reading"); msg.AppendLine("And drink some coffee"); msg.AppendLine("****"); } foreach (var line in template) { msg.AppendLine(line); } msg.AppendLine(""); msg.AppendLine(string.Format("<color=#B4D455>Total science gain: {0}</color>", gain.ToString("0.00"))); MessageSystem.Message message = new MessageSystem.Message( "New Email", msg.ToString(), MessageSystemButton.MessageButtonColor.GREEN, MessageSystemButton.ButtonIcons.MESSAGE ); MessageSystem.Instance.AddMessage(message); }
public ExperimentObserver(StorageCache cache, ExperimentSettings expSettings, BiomeFilter filter, ScanInterface scanMapInterface, string expid) { settings = expSettings; biomeFilter = filter; requireControllable = true; if (scanMapInterface == null) { scanMapInterface = new DefaultScanInterface(); } scanInterface = scanMapInterface; experiment = ResearchAndDevelopment.GetExperiment(expid); if (experiment == null) { Log.Error("Failed to get experiment '{0}'", expid); } storage = cache; Rescan(); }
protected virtual void setup() { Events["deployEvent"].guiActive = showStartEvent; Events["retractEvent"].guiActive = showEndEvent; Events["toggleEvent"].guiActive = showToggleEvent; Events["deployEvent"].guiActiveUnfocused = Events["deployEvent"].externalToEVAOnly = deployExternal; Events["retractEvent"].guiActiveUnfocused = Events["retractEvent"].externalToEVAOnly = deployExternal; Events["toggleEvent"].guiActiveUnfocused = Events["toggleEvent"].externalToEVAOnly = deployExternal; Events["deployEvent"].guiName = startEventGUIName; Events["retractEvent"].guiName = endEventGUIName; Events["toggleEvent"].guiName = toggleEventGUIName; Events["CollectDataExternalEvent"].guiName = collectActionName; Events["ResetExperiment"].guiName = resetActionName; Events["DeployExperiment"].guiName = experimentActionName; Events["DeployExperiment"].unfocusedRange = interactionRange; Actions["deployAction"].guiName = startEventGUIName; Actions["retractAction"].guiName = endEventGUIName; Actions["toggleAction"].guiName = toggleEventGUIName; Actions["DeployAction"].guiName = experimentActionName; if (!string.IsNullOrEmpty(experimentID)) { exp = ResearchAndDevelopment.GetExperiment(experimentID); } }
private static string currentBiome(ScienceExperiment e, Vessel v) { if (e == null) { return(""); } if (v == null) { return(""); } if (!e.BiomeIsRelevantWhile(ExperimentSituations.SrfLanded)) { return(""); } if (string.IsNullOrEmpty(v.landedAt)) { return(ScienceUtil.GetExperimentBiome(v.mainBody, v.latitude, v.longitude)); } return(Vessel.GetLandedAtString(v.landedAt)); }
private void registerDMScience(DMAsteroidScience newAst, ScienceExperiment exp, ScienceSubject sub, ExperimentSituations expsit, string s) { DMScienceScenario.DMScienceData DMData = null; DMUtils.DebugLog("Checking for DM Data in list length: {0}", DMScienceScenario.SciScenario.recoveredScienceList.Count); foreach (DMScienceScenario.DMScienceData DMScience in DMScienceScenario.SciScenario.recoveredScienceList) { if (DMScience.title == sub.title) { DMUtils.DebugLog("found matching DM Data"); sub.scientificValue *= DMScience.scival; DMData = DMScience; break; } } if (DMData == null) { float astSciCap = exp.scienceCap * 40f; DMScienceScenario.SciScenario.RecordNewScience(sub.title, exp.baseValue, 1f, 0f, astSciCap); sub.scientificValue = 1f; } sub.subjectValue = newAst.sciMult; sub.scienceCap = exp.scienceCap * sub.subjectValue; sub.science = sub.scienceCap - (sub.scienceCap * sub.scientificValue); }
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 = P.partPrefab.FindModulesImplementing <ModuleScienceExperiment>( ); 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" ); }
private static string currentDisplayBiome(ScienceExperiment e, Vessel v) { if (e == null) { return(""); } if (v == null) { return(""); } if (!e.BiomeIsRelevantWhile(ExperimentSituations.SrfLanded)) { return(""); } if (string.IsNullOrEmpty(v.displaylandedAt)) { return(Localizer.Format(ScienceUtil.GetExperimentBiomeLocalized(v.mainBody, v.latitude, v.longitude))); } return(Localizer.Format(v.displaylandedAt)); }
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 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 IEnumerable<ScienceSubject> GetSubjects(ScienceExperiment experiment, CelestialBody body, Func<string, bool> biomeFilter, bool difficult) { IEnumerable<ExperimentSituations> situations = Enum.GetValues(typeof(ExperimentSituations)).Cast<ExperimentSituations>(); // Set up the biome filter bool biomesFiltered = biomeFilter != null; if (biomeFilter == null) { biomeFilter = new Func<string, bool>(x => true); } IEnumerable<string> biomes = body.BiomeMap == null ? Enumerable.Empty<string>() : body.BiomeMap.Attributes.Select(attr => attr.name.Replace(" ", string.Empty)). Where(biomeFilter); return situations .Where(sit => ExperimentAvailable(experiment, sit, body) && (sit != ExperimentSituations.SrfSplashed || body.ocean) && ((sit != ExperimentSituations.FlyingLow && sit != ExperimentSituations.FlyingHigh) || body.atmosphere)) .SelectMany<ExperimentSituations, ScienceSubject>(sit => { if (experiment.BiomeIsRelevantWhile(sit)) { return biomes.Where(biome => !(BiomeTracker.IsDifficult(body, biome, sit) || experiment.id == "asteroidSample") ^ difficult) .Select(biome => ScienceSubject(experiment, sit, body, biome)) .Union(body.isHomeWorld && sit == ExperimentSituations.SrfLanded // static KSC items can only be landed ? Biome.KSCBiomes.Where(biomeFilter).Where(b => experiment.id == "asteroidSample" ^ !difficult).Select( staticName => ScienceSubject(experiment, ExperimentSituations.SrfLanded, body, staticName)) : Enumerable.Empty<ScienceSubject>()); } else if (!biomesFiltered && !difficult) { return new ScienceSubject[] { ScienceSubject(experiment, sit, body, "") }; } else { return Enumerable.Empty<ScienceSubject>(); } }); }
private void setup() { Events["deployEvent"].guiActive = showStartEvent; Events["retractEvent"].guiActive = showEndEvent; Events["toggleEvent"].guiActive = showToggleEvent; Events["deployEvent"].guiName = startEventGUIName; Events["retractEvent"].guiName = endEventGUIName; Events["toggleEvent"].guiName = toggleEventGUIName; Events["CollectDataExternalEvent"].guiName = collectActionName; Events["ResetExperimentExternal"].guiName = resetActionName; Events["ResetExperiment"].guiName = resetActionName; Events["DeployExperiment"].guiName = experimentActionName; Events["DeployExperiment"].guiActiveUnfocused = externalDeploy; Events["DeployExperiment"].externalToEVAOnly = externalDeploy; Events["DeployExperiment"].unfocusedRange = interactionRange; Actions["deployAction"].guiName = startEventGUIName; Actions["retractAction"].guiName = endEventGUIName; Actions["toggleAction"].guiName = toggleEventGUIName; Actions["DeployAction"].guiName = experimentActionName; if (!string.IsNullOrEmpty(experimentID)) scienceExp = ResearchAndDevelopment.GetExperiment(experimentID); if (waitForAnimationTime == -1) { if (anim != null) waitForAnimationTime = anim[animationName].length / animSpeed; else waitForAnimationTime = 1; } if (labDataBoost == 0) labDataBoost = xmitDataScalar / 2; requiredPartList = parsePartStringList(requiredParts); requiredModuleList = parseModuleStringList(requiredModules); if (string.IsNullOrEmpty(requiredPartsMessage) && requiredPartList.Count > 0) { requiredPartsMessage = "The following parts are required to be on the vessel"; foreach (string s in requiredPartList) { requiredPartsMessage += ": " + s; } } if (string.IsNullOrEmpty(requiredModulesMessage) && requiredModuleList.Count > 0) { requiredModulesMessage = "The following part modules are required to be on the vessel"; foreach (string s in requiredModuleList) { requiredModulesMessage += ": " + s; } } }
private string getBiomeForExperiment(ScienceExperiment experiment) { if (experiment.BiomeIsRelevantWhile(currentSituation)) { Utilities.debug(modName, Utilities.LogMode.Debug, experiment.id + ": BiomeIsRelevantWhile: " + currentSituation); return currentBiome(); } Utilities.debug(modName, Utilities.LogMode.Debug, experiment.id + ": BiomeIsNotRelevantWhile: " + currentSituation); return string.Empty; }
private bool transmitData(SEP_ExperimentHandler exp, int level, float submittedData, float newData) { ScienceData data = SEP_Utilities.getScienceData(exp, exp.getExperimentLevel(level), level); if (exp.vessel.loaded) { IScienceDataTransmitter bestTransmitter = ScienceUtil.GetBestTransmitter(exp.vessel); if (bestTransmitter != null) { ScienceExperiment e = exp.getExperimentLevel(level); float transmitterCost = getLoadedTransmitterCost(bestTransmitter); float ecCost = newData * e.dataScale * transmitterCost; if (ecCost > SEP_Utilities.getTotalVesselEC(exp.vessel)) { if (!dataOnboard(exp, level)) { SEP_Utilities.log("Not enough power for transmissionon this vessel: {1}; saving data: {0}", logLevels.log, data.title, exp.vessel.vesselName); exp.addData(data); if (exp.host != null) { exp.host.Events["ReviewDataEvent"].active = true; exp.host.Events["TransferDataEvent"].active = exp.host.hasContainer; exp.host.Events["CollectData"].active = true; if (exp.host.Controller != null) { exp.host.Controller.setCollectEvent(); } } } return(false); } SEP_Utilities.log("Sending data to vessel comms: {0}", logLevels.log, data.title); bestTransmitter.TransmitData(new List <ScienceData> { data }); return(true); } else { if (!dataOnboard(exp, level)) { SEP_Utilities.log("No Comms Devices on this vessel: {1}. Cannot Transmit Data; saving data: {0}", logLevels.log, data.title, exp.vessel.vesselName); exp.addData(data); if (exp.host != null) { exp.host.Events["ReviewDataEvent"].active = true; exp.host.Events["TransferDataEvent"].active = exp.host.hasContainer; exp.host.Events["CollectData"].active = true; if (exp.host.Controller != null) { exp.host.Controller.setCollectEvent(); } } } return(false); } } else { List <ProtoPartSnapshot> transmitters = getProtoTransmitters(exp.vessel.protoVessel); float?transmitterCost = getBestTransmitterCost(transmitters); if (transmitterCost == null) { if (!dataOnboard(exp, level)) { SEP_Utilities.log("No Comms Devices on this vessel: {1}. Cannot Transmit Data; saving data: {0}", logLevels.log, data.title, exp.vessel.protoVessel.vesselName); exp.addData(data); } return(false); } //SEP_Utilities.log("Transmission Score: {0:N4}EC", logLevels.warning, transmitterCost); ScienceExperiment e = exp.getExperimentLevel(level); float ecCost = newData * e.dataScale * (float)transmitterCost; //SEP_Utilities.log("Transmission Cost: {0:N4}EC", logLevels.warning, ecCost); if (ecCost > SEP_Utilities.getTotalVesselEC(exp.vessel.protoVessel)) { if (!dataOnboard(exp, level)) { SEP_Utilities.log("Not enough electricity on this vessel: {1}. Cannot Transmit Data; saving data: {0}", logLevels.log, data.title, exp.vessel.protoVessel.vesselName); exp.addData(data); } return(false); } ScienceSubject sub = SEP_Utilities.checkAndUpdateRelatedSubjects(exp, level, newData, submittedData); if (sub == null) { return(false); } ResearchAndDevelopment.Instance.SubmitScienceData(newData * sub.dataScale, sub, 1, exp.vessel.protoVessel); if (exp.vessel.HasValidContractObjectives(new List <string> { "Generator" })) { consumeResources(exp.vessel.protoVessel, ecCost); } exp.submittedData += (newData - submittedData); return(true); } }
//Return a list of valid experiment situations based on the experiment parameters internal static List<ExperimentSituations> availableSituations(ScienceExperiment exp, int i, CelestialBody b) { List<ExperimentSituations> expSitList = new List<ExperimentSituations>(); if (((ExperimentSituations)i & ExperimentSituations.FlyingHigh) == ExperimentSituations.FlyingHigh && b.atmosphere) expSitList.Add(ExperimentSituations.FlyingHigh); if (((ExperimentSituations)i & ExperimentSituations.FlyingLow) == ExperimentSituations.FlyingLow && b.atmosphere) expSitList.Add(ExperimentSituations.FlyingLow); if (((ExperimentSituations)i & ExperimentSituations.InSpaceHigh) == ExperimentSituations.InSpaceHigh) { if (!exp.requireAtmosphere) expSitList.Add(ExperimentSituations.InSpaceHigh); else if (b.atmosphere) expSitList.Add(ExperimentSituations.InSpaceHigh); } if (((ExperimentSituations)i & ExperimentSituations.InSpaceLow) == ExperimentSituations.InSpaceLow) { if (!exp.requireAtmosphere) expSitList.Add(ExperimentSituations.InSpaceLow); else if (b.atmosphere) expSitList.Add(ExperimentSituations.InSpaceLow); } if (((ExperimentSituations)i & ExperimentSituations.SrfLanded) == ExperimentSituations.SrfLanded && b.pqsController != null) { if (!exp.requireAtmosphere && exp.id != "dmbiodrillscan") expSitList.Add(ExperimentSituations.SrfLanded); else if (b.atmosphere) expSitList.Add(ExperimentSituations.SrfLanded); } if (((ExperimentSituations)i & ExperimentSituations.SrfSplashed) == ExperimentSituations.SrfSplashed && b.ocean && b.pqsController != null) { if (!exp.requireAtmosphere) expSitList.Add(ExperimentSituations.SrfSplashed); else if (b.atmosphere) expSitList.Add(ExperimentSituations.SrfSplashed); } return expSitList; }
public Notes_Experiment(Notes_ExpPart r, ModuleScienceExperiment m, ScienceExperiment e, int limit = 1) { root = r; experimentModule = m; experiment = e; name = e.experimentTitle; dataLimit = limit; }
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())) fixBiome = currentBiome();// for those that do, we add it to the string return ResearchAndDevelopment.GetExperimentSubject(experiment, currentSituation(), currentBody(), fixBiome);//ikr!, we pretty much did all the work already, jeez }
internal void FinalizeExperiment() { Log.Info("FinalizeExperiment"); ScienceExperiment labExp = ResearchAndDevelopment.GetExperiment(activeExperiment.activeExpid); string displayBiome = ""; if (vessel.landedAt != string.Empty) { activeExperiment.biomeSit = Vessel.GetLandedAtString(vessel.landedAt); displayBiome = Localizer.Format(vessel.displaylandedAt); } else { activeExperiment.biomeSit = ScienceUtil.GetExperimentBiome(vessel.mainBody, vessel.latitude, vessel.longitude); displayBiome = ScienceUtil.GetBiomedisplayName(vessel.mainBody, activeExperiment.biomeSit); activeExperiment.biomeSit = ""; displayBiome = ""; } ModuleScienceExperiment exp = activeExperiment.mse; #if DEBUG var step = "Get Subject"; #endif ScienceSubject labSub = ResearchAndDevelopment.GetExperimentSubject(labExp, activeExperiment.expSit, vessel.mainBody, activeExperiment.biomeSit, displayBiome); //labSub.title = $"{labExp.experimentTitle}"; if (activeExperiment.biomeSit != "") { labSub.title = ScienceUtil.GenerateScienceSubjectTitle(labExp, activeExperiment.expSit, vessel.mainBody, activeExperiment.biomeSit, displayBiome); } else { labSub.title = ScienceUtil.GenerateScienceSubjectTitle(labExp, activeExperiment.expSit, vessel.mainBody); } //labSub.subjectValue *= labBoostScalar; labSub.scienceCap = labExp.scienceCap * labSub.subjectValue; #if DEBUG step = "Calculate Points"; #endif float sciencePoints = labExp.baseValue * labExp.dataScale; ScienceData labData = new ScienceData(sciencePoints, exp.xmitDataScalar, 0, labSub.id, labSub.title, false, vessel.rootPart.flightID); #if DEBUG step = "Add Experiment"; #endif _storedData.Add(labData); #if DEBUG step = "Show Dialog"; #endif Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_238419", vessel.rootPart.partInfo.title, labData.dataAmount, labSub.title)); ReviewDataItem(labData); expStatuses.Remove(activeExperiment.Key); activeExperiment = null; labData = null; }
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}"); } }
private bool isExperimentLimitReached(ModuleScienceExperiment currentExperiment, ScienceExperiment experiment, ScienceSubject currentScienceSubject, ref float currentScienceValue) { try { int experimentNumber, experimentLimit; if (int.TryParse(currentExperiment.GetType().GetField("experimentNumber").GetValue(currentExperiment).ToString(), out experimentNumber) && int.TryParse(currentExperiment.GetType().GetField("experimentLimit").GetValue(currentExperiment).ToString(), out experimentLimit)) { if ((experimentNumber >= experimentLimit) && experimentLimit >= 1) { Utilities.debug(modName, Utilities.LogMode.Log, "Experiment {0} can't be conducted cause the experimentLimit is reached!", experiment.id); return true; } else if (experimentNumber > 0) { addToContainer(currentScienceSubject.id, experimentNumber); currentScienceValue = Utilities.Science.getScienceValue(shipCotainsExperiments, experiment, currentScienceSubject); Utilities.debug(modName, Utilities.LogMode.Log, "Experiment is a DMagic Orbital Science experiment. Science value changed to: " + currentScienceValue); if (currentScienceValue < currentSettings.getFloat("scienceCutoff")) { Utilities.debug(modName, Utilities.LogMode.Log, "Experiment is a DMagic Orbital Science experiment. Science value droped below cutoff."); return true; } } } } catch (Exception) { } return false; }
private void getScienceSubjectAndValue(ScienceExperiment experiment, string biome, out ScienceSubject currentScienceSubject, out float currentScienceValue) { currentScienceSubject = ResearchAndDevelopment.GetExperimentSubject(experiment, currentSituation, currentBody, biome); currentScienceValue = Utilities.Science.getScienceValue(shipCotainsExperiments, experiment, currentScienceSubject); }
protected override bool generateScienceData() { ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment("FNSeismicProbeExperiment"); if (experiment == null) { return(false); } //ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(experiment, ExperimentSituations.SrfLanded, vessel.mainBody, "surface"); //if (subject == null) { // return false; //} //subject.scientificValue = 1; //subject.scienceCap = float.MaxValue; //subject.science = 1; //subject.subjectValue = 1; result_title = "Impactor Experiment"; result_string = "No useful seismic data has been recorded."; transmit_value = 0; recovery_value = 0; data_size = 0; xmit_scalar = 1; ref_value = 1; // science_data = new ScienceData(0, 1, 0, subject.id, "data"); ConfigNode config = PluginHelper.getPluginSaveFile(); if (config.HasNode("SEISMIC_SCIENCE_" + vessel.mainBody.name.ToUpper())) { ConfigNode planet_data = config.GetNode("SEISMIC_SCIENCE_" + vessel.mainBody.name.ToUpper()); foreach (ConfigNode probe_data in planet_data.nodes) { if (probe_data.name.Contains("IMPACT_")) { science_vess_ref = probe_data.name; bool transmitted = false; string vessel_name = ""; float distribution_factor = 0; if (probe_data.HasValue("transmitted")) { transmitted = bool.Parse(probe_data.GetValue("transmitted")); } if (probe_data.HasValue("vesselname")) { vessel_name = probe_data.GetValue("vesselname"); } if (probe_data.HasValue("distribution_factor")) { distribution_factor = float.Parse(probe_data.GetValue("distribution_factor")); } if (!transmitted) { ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(experiment, ExperimentSituations.SrfLanded, vessel.mainBody, vessel.mainBody.name + "'s surface."); if (subject == null) { return(false); } subject.subjectValue = PluginHelper.getScienceMultiplier(vessel); subject.scienceCap = 10 * experiment.baseValue * subject.subjectValue; float base_science = experiment.baseValue * distribution_factor; data_size = base_science * subject.dataScale; science_data = new ScienceData((float)data_size, 1f, 0f, subject.id, "Impactor Data"); result_string = vessel_name + " impacted into " + vessel.mainBody.name + " producing seismic activity. From this data, information on the structure of " + vessel.mainBody.name + "'s crust can be determined."; float science_amount = base_science * subject.subjectValue; recovery_value = science_amount * subject.scientificValue; transmit_value = recovery_value; ref_value = subject.scienceCap; return(true); } } } } return(false); }
public override void OnStart(PartModule.StartState state) { if (!string.IsNullOrEmpty(animationName)) Anim = part.FindModelAnimators(animationName)[0]; if (!string.IsNullOrEmpty(greenLight)) IndicatorAnim1 = part.FindModelAnimators(greenLight)[0]; if (!string.IsNullOrEmpty(yellowLight)) IndicatorAnim2 = part.FindModelAnimators(yellowLight)[0]; if (USScience && !string.IsNullOrEmpty(USBayAnimation)) USAnim = part.FindModelAnimators(USBayAnimation)[0]; if (!string.IsNullOrEmpty(experimentID)) exp = ResearchAndDevelopment.GetExperiment(experimentID); if (IsDeployed) { fullyDeployed = true; animator(0f, 1f, Anim, animationName); if (USScience) animator(0f, 1f, USAnim, USBayAnimation); } if (FlightGlobals.Bodies[16].bodyName != "Eeloo") FlightGlobals.Bodies[16].bodyName = asteroidBodyNameFixed; dishBase = part.FindModelTransform(baseTransformName); dish = part.FindModelTransform(transformName); dishArm = part.FindModelTransform(transformRotatorName); }
public extern ScienceSubject(ScienceExperiment exp, ExperimentSituations sit, string sourceUid, string sourceTitle, CelestialBody body, string biome = "");
private bool canConduct(ModuleScienceExperiment currentExperiment, ScienceExperiment experiment) { try { MethodInfo conductMethod = currentExperiment.GetType().BaseType.GetMethod("canConduct", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.InvokeMethod); if (conductMethod == null) { conductMethod = currentExperiment.GetType().GetMethod("canConduct", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.InvokeMethod); } if (conductMethod != null) { var conductResult = (bool)conductMethod.Invoke(currentExperiment, null); if (!conductResult) { Utilities.debug(modName, Utilities.LogMode.Debug, "Experiment {0} can't be conducted.", experiment.id); return false; } return true; } else { Utilities.debug(modName, Utilities.LogMode.Error, experiment.id + ": conductMethod == null"); } } catch (Exception e) { Utilities.debug(modName, Utilities.LogMode.Exception, e.Message); } return false; }
//public static void checkAndUpdateRelatedSubjects(ScienceSubject sub, float data) //{ // string s = sub.id.Substring(sub.id.Length - 1, 1); // int level = 0; // if (!int.TryParse(s, out level)) // return; // if (!sub.IsFromSituation(ExperimentSituations.SrfLanded)) // return; // string biome = getBiomeString(sub.id); // string exp = getExperimentString(sub.id, level); // if (string.IsNullOrEmpty(exp)) // return; // string body = getBodyString(sub.id); // if (string.IsNullOrEmpty(body)) // return; // CelestialBody Body= FlightGlobals.Bodies.FirstOrDefault(b => b.bodyName == body); // if (Body == null) // return; // for (int i = 1; i < level; i++) // { // string fullExp = exp + ((SEPExperiments)i).ToString(); // ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(fullExp); // if (experiment == null) // continue; // ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(experiment, ExperimentSituations.SrfLanded, Body, biome); // subject.title = experiment.experimentTitle + situationCleanup(Body, ExperimentSituations.SrfLanded, biome); // subject.science += (data / HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier); // if (subject.science > subject.scienceCap) // subject.science = subject.scienceCap; // subject.scientificValue = 1 - (subject.science / subject.scienceCap); // //log("Related Subject Checked From Event: ID {0} - Science Level {1:N0}", logLevels.warning, subject.id, subject.science); // } //} public static void checkAndUpdateRelatedSubjects(List <ScienceSubject> allSubs, ScienceSubject sub, float data) { data /= HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; if (data <= 0) { return; } if (!sub.IsFromSituation(ExperimentSituations.SrfLanded)) { return; } string biome = getBiomeString(sub.id); string exp = getExperimentFullString(sub.id); if (string.IsNullOrEmpty(exp)) { return; } int level = getExperimentLevel(exp); if (level == 0) { return; } exp = getExperimentStartString(exp, level); if (string.IsNullOrEmpty(exp)) { return; } string body = getBodyString(sub.id); if (string.IsNullOrEmpty(body)) { return; } CelestialBody Body = FlightGlobals.Bodies.FirstOrDefault(b => b.bodyName == body); if (Body == null) { return; } ScienceSubject subject = null; //log("Science Subject Parsed [{0}]: Level: {1} - Experiment: {2}", logLevels.warning, sub.id, level, exp); for (int i = 1; i <= 3; i++) { if (i == level) { continue; } string fullExp = exp + ((SEPExperiments)i).ToString(); ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(fullExp); if (experiment == null) { continue; } string id = string.Format("{0}@{1}{2}{3}", experiment.id, body, ExperimentSituations.SrfLanded, biome); if (allSubs.Any(a => a.id == id)) { subject = ResearchAndDevelopment.GetSubjectByID(id); //log("Subject ID Confirmed: Science Amount - {0:N2}", logLevels.warning, subject.science); } else { continue; } if (i < level) { subject.science = sub.science; if (subject.science > subject.scienceCap) { subject.science = subject.scienceCap; } subject.scientificValue = 1 - (subject.science / subject.scienceCap); } else { if (subject.science < sub.science) { subject.science = sub.science; if (subject.science > subject.scienceCap) { subject.science = subject.scienceCap; } subject.scientificValue = 1 - (subject.science / subject.scienceCap); } } //log("Related Subject Checked From Recovery: ID {0} - Science Level {1:N0}", logLevels.warning, subject.id, subject.science); } }
internal static List<string> fetchBiome(CelestialBody b, ScienceExperiment exp, ExperimentSituations sit) { List<string> s = new List<string>(); if (b.BiomeMap == null) { s.Add(""); return s; } else { for (int j = 0; j < b.BiomeMap.Attributes.Length; j++) { string bName = b.BiomeMap.Attributes[j].name; string subId = string.Format("{0}@{1}{2}{3}", exp.id, b.name, sit, bName.Replace(" ", "")); if (ResearchAndDevelopment.GetSubjects().Any(a => a.id == subId)) { ScienceSubject subB = ResearchAndDevelopment.GetSubjectByID(subId); if (subB.scientificValue > 0.5f) s.Add(bName); } else s.Add(bName); } } return s; }
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; }
// Much credit to a.g. as his source helped to figure out how to utilize the experiment and its data // https://github.com/angavrilov/ksp-surface-survey/blob/master/SurfaceSurvey.cs#L276 public void AnalyzeScienceSample () { if (rover.ScienceSpotReached) { ScienceExperiment sciExperiment = ResearchAndDevelopment.GetExperiment ("RoverScienceExperiment"); ScienceSubject sciSubject = ResearchAndDevelopment.GetExperimentSubject(sciExperiment, ExperimentSituations.SrfLanded, Vessel.mainBody, "", ""); // 20 science per data sciSubject.subjectValue = 20; sciSubject.scienceCap = BodyScienceCap; // Divide by 20 to convert to data form float sciData = (rover.scienceSpot.potentialScience) / sciSubject.subjectValue; Utilities.LogVerbose ("sciData (potential/20): " + sciData); // Apply multipliers if (rover.AnomalySpotReached) { Utilities.LogVerbose("analyzed science at anomaly"); if (!rover.anomaliesAnalyzed.Contains(rover.closestAnomaly.id)) { rover.anomaliesAnalyzed.Add(rover.closestAnomaly.id); Utilities.LogVerbose($"added anomaly id: {rover.closestAnomaly.id} to save!"); } } else { // if a normal spot, we shall apply factors Utilities.LogVerbose("analyzed science at science spot"); sciData = sciData * ScienceDecayScalar * BodyScienceScalar * scienceMaxRadiusBoost; } Utilities.LogVerbose("rover.scienceSpot.potentialScience: " + rover.scienceSpot.potentialScience); Utilities.LogVerbose("sciData (post scalar): " + sciData); Utilities.LogVerbose("scienceDecayScalar: " + ScienceDecayScalar); Utilities.LogVerbose("bodyScienceScalar: " + BodyScienceScalar); if (sciData > 0.1) { if (StoreScience (container, sciSubject, sciData)) { container.ReviewData (); amountOfTimesAnalyzed++; Utilities.LogVerbose ("Science retrieved! - " + sciData); } else { Utilities.Log ("Failed to add science to container!"); } } else { ScreenMessages.PostScreenMessage ("#LOC_RoverScience_GUI_ScienceTooLow", 5, ScreenMessageStyle.UPPER_CENTER); // Science value was too low - deleting data! } rover.scienceSpot.Reset (); } else { Utilities.LogVerbose ("Tried to analyze while not at spot?"); } }
private List<string> PrepareSituationAndBiomes(ScienceExperiment experiment) { var result = new List<string>(); foreach (var situationTemplate in SituationHelper.SituationTemplates) { var flag = (experiment.situationMask & (uint)(situationTemplate.Key)) == (uint)(situationTemplate.Key); //получаем чтото если текущая ситуация совпадает с заявленной var dictValue = situationTemplate.Value; // получили делегат var preparedInfo = dictValue(flag); // вызвали делегат if (flag && (experiment.biomeMask & (uint)(situationTemplate.Key)) == (uint)(situationTemplate.Key)) { preparedInfo += _biomeDepending; } result.Add(preparedInfo); } return result; }
private void setup() { Events["deployEvent"].guiActive = showStartEvent; Events["retractEvent"].guiActive = showEndEvent; Events["toggleEvent"].guiActive = showToggleEvent; Events["deployEvent"].guiName = startEventGUIName; Events["retractEvent"].guiName = endEventGUIName; Events["toggleEvent"].guiName = toggleEventGUIName; Events["CollectDataExternalEvent"].guiName = collectActionName; Events["ResetExperimentExternal"].guiName = resetActionName; Events["ResetExperiment"].guiName = resetActionName; Events["DeployExperiment"].guiName = experimentActionName; Events["DeployExperiment"].guiActiveUnfocused = externalDeploy; Events["DeployExperiment"].externalToEVAOnly = externalDeploy; Events["DeployExperiment"].unfocusedRange = interactionRange; Actions["deployAction"].guiName = startEventGUIName; Actions["retractAction"].guiName = endEventGUIName; Actions["toggleAction"].guiName = toggleEventGUIName; Actions["DeployAction"].guiName = experimentActionName; if (!primary) { primaryList = this.part.FindModulesImplementing<DMModuleScienceAnimate>(); if (primaryList.Count > 0) { foreach (DMModuleScienceAnimate DMS in primaryList) if (DMS.primary) primaryModule = DMS; } } if (USStock) enviroList = this.part.FindModulesImplementing<DMEnviroSensor>(); if (waitForAnimationTime == -1 && animSpeed != 0) waitForAnimationTime = anim[animationName].length / animSpeed; if (experimentID != null) { scienceExp = ResearchAndDevelopment.GetExperiment(experimentID); } if (FlightGlobals.Bodies[16].bodyName != "Eeloo") FlightGlobals.Bodies[16].bodyName = bodyNameFixed; labDataBoost = xmitDataScalar / 2; }
public override void OnStart(PartModule.StartState state) { if (!string.IsNullOrEmpty(animationName)) { Anim = part.FindModelAnimators(animationName)[0]; } if (!string.IsNullOrEmpty(greenLight)) { IndicatorAnim1 = part.FindModelAnimators(greenLight)[0]; } if (!string.IsNullOrEmpty(yellowLight)) { IndicatorAnim2 = part.FindModelAnimators(yellowLight)[0]; } if (USScience && !string.IsNullOrEmpty(USBayAnimation)) { USAnim = part.FindModelAnimators(USBayAnimation)[0]; } if (USTwoScience && !string.IsNullOrEmpty(RaySourceTransform)) { _raySource = part.FindModelTransform(RaySourceTransform); } if (!string.IsNullOrEmpty(experimentID)) { exp = ResearchAndDevelopment.GetExperiment(experimentID); } if (IsDeployed) { fullyDeployed = true; animator(0f, 1f, Anim, animationName); if (USScience) { animator(0f, 1f, USAnim, USBayAnimation); } } dishBase = part.FindModelTransform(baseTransformName); dish = part.FindModelTransform(transformName); dishArm = part.FindModelTransform(transformRotatorName); if (resHandler != null && resHandler.inputResources != null && resHandler.inputResources.Count > 0 && resHandler.inputResources[0].rate > 0) { useResources = true; } else { useResources = false; } if (FlightGlobals.Bodies.Count >= 17) { asteroidBodyNameFixed = FlightGlobals.Bodies[16].bodyName; } if (!HighLogic.LoadedSceneIsEditor) { findContainers(); } }
/// <summary> /// Gets the science subject for the given values. /// </summary> /// <param name="experiment">The science experiment</param> /// <param name="situation">The experimental situation</param> /// <param name="body">The celestial body</param> /// <param name="biome">The biome</param> /// <returns>The ScienceSubject</returns> public static ScienceSubject ScienceSubject(ScienceExperiment experiment, ExperimentSituations situation, CelestialBody body, string biome) { ScienceSubject defaultIfNotResearched = new ScienceSubject(experiment, situation, body, biome); return ResearchAndDevelopment.GetSubjects().SingleOrDefault(researched => defaultIfNotResearched.id == researched.id) ?? defaultIfNotResearched; }
public static ScienceData makeData(DMSeismometerValues sensor, float score, ScienceExperiment exp, string expID, bool seismometerOnly, bool asteroid) { if (sensor == null || exp == null || sensor.VesselRef == null || sensor.VesselRef.mainBody == null) { return(null); } Vessel v = sensor.VesselRef; CelestialBody body = v.mainBody; string biome = ((int)exp.biomeMask & (int)ExperimentSituations.SrfLanded) == 0 ? "" : ScienceUtil.GetExperimentBiome(body, v.latitude, v.longitude); DMAsteroidScience newAsteroid = null; if (asteroid) { newAsteroid = new DMAsteroidScience(); body = newAsteroid.Body; biome = newAsteroid.AType + newAsteroid.ASeed.ToString(); } ScienceSubject sub = ResearchAndDevelopment.GetExperimentSubject(exp, ExperimentSituations.SrfLanded, body, biome); if (sub == null) { Debug.LogError("[DM] Something Went Wrong Here; Null Seismometer Subject Returned; Please Report This On The KSP Forum With Output.log Data"); return(null); } float science = exp.baseValue * sub.dataScale * score; if (asteroid) { string b = newAsteroid.AType; string a = "a"; if (b == "Icy-Organic") { a = "an"; } string c = " asteroid"; if (b == "Comet") { c = ""; } body.bodyName = bodyNameFixed; DMUtils.OnAsteroidScience.Fire(newAsteroid.AClass, expID); sub.title = exp.experimentTitle + string.Format(" from the surface of {0} {1}{2}", a, b, c); registerDMScience(newAsteroid, exp, sub); } else { if (sub.science > 0) { sub.scientificValue = 1f; if (sub.science >= ((science / sub.dataScale) * sub.subjectValue)) { sub.scientificValue = 0f; } else { sub.scientificValue = 1 - ((sub.science / sub.subjectValue) / (science / sub.dataScale)); } } DMUtils.OnAnomalyScience.Fire(body, expID, biome); sub.title = exp.experimentTitle + string.Format(" from {0}'s {1}", body.theName, biome); } return(new ScienceData(science, 1f, 0, sub.id, sub.title, false, sensor.ID)); }
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 static void Init() { Lib.Log("ScienceDB init started"); int subjectCount = 0; double totalScience = 0.0; // get our extra defintions ConfigNode[] expDefNodes = GameDatabase.Instance.GetConfigNodes("EXPERIMENT_DEFINITION"); // create our subject database // Note : GetExperimentIDs will force the creation of all ScienceExperiment objects, // no matter if the RnD instance is null or not because the ScienceExperiment dictionary is static. foreach (string experimentId in ResearchAndDevelopment.GetExperimentIDs()) { if (experimentId == "recovery") { continue; } ConfigNode kerbalismExpNode = null; foreach (ConfigNode expDefNode in expDefNodes) { string id = string.Empty; if (expDefNode.TryGetValue("id", ref id) && id == experimentId) { kerbalismExpNode = expDefNode.GetNode("KERBALISM_EXPERIMENT"); // return null if not found break; } } ScienceExperiment stockDef = ResearchAndDevelopment.GetExperiment(experimentId); if (stockDef == null) { Lib.Log("ScienceExperiment is null for experiment Id=" + experimentId + ", skipping...", Lib.LogLevel.Warning); continue; } ExperimentInfo expInfo = new ExperimentInfo(stockDef, kerbalismExpNode); if (!experiments.ContainsKey(experimentId)) { experiments.Add(experimentId, expInfo); } if (!subjectByExpThenSituationId.ContainsKey(expInfo)) { subjectByExpThenSituationId.Add(expInfo, new Dictionary <int, SubjectData>()); } for (int bodyIndex = 0; bodyIndex < FlightGlobals.Bodies.Count; bodyIndex++) { CelestialBody body = FlightGlobals.Bodies[bodyIndex]; if (!expInfo.IgnoreBodyRestrictions && !expInfo.ExpBodyConditions.IsBodyAllowed(body)) { continue; } // ScienceSituationUtils.validSituations is all situations in the enum, apart from the "None" value foreach (ScienceSituation scienceSituation in ScienceSituationUtils.validSituations) { // test the ScienceExperiment situation mask if (!scienceSituation.IsAvailableForExperiment(expInfo)) { continue; } // don't add impossible body / situation combinations if (!expInfo.IgnoreBodyRestrictions && !scienceSituation.IsAvailableOnBody(body)) { continue; } // virtual biomes always have priority over normal biomes : if (scienceSituation.IsVirtualBiomesRelevantForExperiment(expInfo)) { foreach (VirtualBiome virtualBiome in expInfo.VirtualBiomes) { if (!virtualBiome.IsAvailableOnBody(body)) { continue; } SubjectData subjectData = null; if (expInfo.HasDBSubjects) { Situation situation = new Situation(bodyIndex, scienceSituation, (int)virtualBiome); subjectData = new SubjectData(expInfo, situation); subjectByExpThenSituationId[expInfo].Add(situation.Id, subjectData); knownStockSubjectsId.Add(subjectData.StockSubjectId); subjectCount++; totalScience += subjectData.ScienceMaxValue; } expBodiesSituationsBiomesSubject.AddSubject(expInfo, bodyIndex, scienceSituation, (int)virtualBiome, subjectData); } } // if the biome mask says the situation is biome dependant : else if (scienceSituation.IsBodyBiomesRelevantForExperiment(expInfo) && body.BiomeMap != null && body.BiomeMap.Attributes.Length > 1) { for (int biomeIndex = 0; biomeIndex < body.BiomeMap.Attributes.Length; biomeIndex++) { SubjectData subjectData = null; if (expInfo.HasDBSubjects) { Situation situation = new Situation(bodyIndex, scienceSituation, biomeIndex); subjectData = new SubjectData(expInfo, situation); subjectByExpThenSituationId[expInfo].Add(situation.Id, subjectData); knownStockSubjectsId.Add(subjectData.StockSubjectId); subjectCount++; totalScience += subjectData.ScienceMaxValue; } expBodiesSituationsBiomesSubject.AddSubject(expInfo, bodyIndex, scienceSituation, biomeIndex, subjectData); } } // else generate the global, biome agnostic situation else { SubjectData subjectData = null; if (expInfo.HasDBSubjects) { Situation situation = new Situation(bodyIndex, scienceSituation); subjectData = new SubjectData(expInfo, situation); subjectByExpThenSituationId[expInfo].Add(situation.Id, subjectData); knownStockSubjectsId.Add(subjectData.StockSubjectId); subjectCount++; totalScience += subjectData.ScienceMaxValue; } expBodiesSituationsBiomesSubject.AddSubject(expInfo, bodyIndex, scienceSituation, -1, subjectData); } } } } // cache that call IEnumerable <ExperimentInfo> experimentInfosCache = ExperimentInfos; // first parse all the IncludeExperiment configs foreach (ExperimentInfo experimentInfo in experimentInfosCache) { experimentInfo.ParseIncludedExperiments(); } // then check for infinite recursion from bad configs List <ExperimentInfo> chainedExperiments = new List <ExperimentInfo>(); foreach (ExperimentInfo experimentInfo in experimentInfosCache) { chainedExperiments.Clear(); ExperimentInfo.CheckIncludedExperimentsRecursion(experimentInfo, chainedExperiments); } // now we are sure all the include experiment chains are valid foreach (ExperimentInfo experimentInfo in experimentInfosCache) { // populate the included experiments chains at the subject level foreach (KeyValuePair <int, SubjectData> subjectInfo in subjectByExpThenSituationId[experimentInfo]) { foreach (ExperimentInfo includedInfo in experimentInfo.IncludedExperiments) { SubjectData subjectToInclude = GetSubjectData(includedInfo, subjectInfo.Key); if (subjectToInclude != null) { subjectInfo.Value.IncludedSubjects.Add(subjectToInclude); } } } // Get the experiment description that will be shown in the science archive by calling GetInfo() on the first found partmodule using it // TODO: this isn't ideal, if there are several modules with different values (ex : data rate, ec rate...), the archive info will use the first found one. // Ideally we should revamp the whole handling of that (because it's a mess from the partmodule side too) experimentInfo.CompileModuleInfos(); } Lib.Log($"ScienceDB init done : {subjectCount} subjects found, total science points : {totalScience.ToString("F1")}"); }
public static float CalculateNextReport(this ScienceSubject subject, ScienceExperiment experiment, System.Collections.Generic.List <ScienceData> onboard, float xmitScalar = 1f) { return(GetNextReportValue(subject, experiment, onboard, xmitScalar)); }
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); }
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(); } }
private void Report(ScienceExperiment experiment, float gain) { StringBuilder msg = new StringBuilder(); string[] template; if (File.Exists<KEI>(experiment.id + ".msg")) { template = File.ReadAllLines<KEI>(experiment.id + ".msg"); } else { template = File.ReadAllLines<KEI>("unknownExperiment.msg"); msg.AppendLine("Top Secret info! Project " + experiment.experimentTitle); msg.AppendLine("Eat after reading"); msg.AppendLine("And drink some coffee"); msg.AppendLine("****"); } foreach (var line in template) { msg.AppendLine(line); } msg.AppendLine(""); msg.AppendLine(string.Format("<color=#B4D455>Total science gain: {0}</color>", gain.ToString("0.00"))); MessageSystem.Message message = new MessageSystem.Message( "New Email", msg.ToString(), MessageSystemButton.MessageButtonColor.GREEN, MessageSystemButton.ButtonIcons.MESSAGE ); MessageSystem.Instance.AddMessage(message); }
private void PrepareSituationAndBiomes(ScienceExperiment experiment, string[] itemInfo) { var arr = Enum.GetValues(typeof (ExperimentSituations)); var arrIndexed = new List<ExperimentSituations>(); foreach (var type in arr) { arrIndexed.Add((ExperimentSituations)type); // пробежимся по всем элементам, возьмем его и преобразуем в объект ExperimentSituations } for (int i = 0; i < 6; i++) { var enumMember = FormatString(arrIndexed, i); if ((experiment.situationMask & (uint) (arrIndexed[i])) == (uint) (arrIndexed[i])) { itemInfo[i] = string.Concat(enumMember, "<b><color=green>V</color></b>"); if ((experiment.biomeMask & (uint) (arrIndexed[i])) == (uint) (arrIndexed[i])) { itemInfo[i] = string.Concat(itemInfo[i], " ", _biomeDepending); } } else { itemInfo[i] = string.Concat(enumMember, "<b><color=red>X</color></b>"); } } }
public static ScienceSubject GetExperimentSubject(ScienceExperiment experiment, ExperimentSituations situation, string sourceUId, string sourceTitle, CelestialBody body, string biome);
public ExperimentInfo(ScienceExperiment stockDef, ConfigNode expInfoNode) { // if we have a custom "KERBALISM_EXPERIMENT" definition for the experiment, load it, else just use an empty node to avoid nullrefs if (expInfoNode == null) { expInfoNode = new ConfigNode(); } this.stockDef = stockDef; ExperimentId = stockDef.id; // We have some custom handling for breaking ground ROC experiments IsROC = ExperimentId.StartsWith("ROCScience"); if (IsROC) { Title = "ROC: " + stockDef.experimentTitle; // group ROC together in the science archive (sorted by Title) } else { Title = stockDef.experimentTitle; } // A new bool field was added in 1.7 for serenity : applyScienceScale // if not specified, the default is `true`, which is the case for all non-serenity science defs // serenity ground experiments and ROCs have applyScienceScale = false. // for ground experiment, baseValue = science generated per hour // for ROC experiments, it doesn't change anything because they are all configured with baseValue = scienceCap if (this.stockDef.applyScienceScale) { DataSize = this.stockDef.baseValue * this.stockDef.dataScale; } else { DataSize = this.stockDef.scienceCap * this.stockDef.dataScale; } // load the included experiments ids in a string array, we will populate the list after // all ExperimentInfos are created. (can't do it here as they may not exist yet) includedExperimentsId = expInfoNode.GetValues("IncludeExperiment"); UnlockResourceSurvey = Lib.ConfigValue(expInfoNode, "UnlockResourceSurvey", false); SampleMass = Lib.ConfigValue(expInfoNode, "SampleMass", 0.0); IsSample = SampleMass > 0.0; if (IsSample) { // make sure we don't produce NaN values down the line because of odd/wrong configs if (DataSize <= 0.0) { Lib.Log(ExperimentId + " has DataSize=" + DataSize + ", your configuration is broken!", Lib.LogLevel.Warning); DataSize = 1.0; } MassPerMB = SampleMass / DataSize; } else { MassPerMB = 0.0; } // Patch stock science def restrictions as BodyAllowed/BodyNotAllowed restrictions if (!(expInfoNode.HasValue("BodyAllowed") || expInfoNode.HasValue("BodyNotAllowed"))) { if (IsROC) { // Parse the ROC definition name to find which body it's available on // This rely on the ROC definitions having the body name in the ExperimentId foreach (CelestialBody body in FlightGlobals.Bodies) { if (ExperimentId.IndexOf(body.name, StringComparison.OrdinalIgnoreCase) != -1) { expInfoNode.AddValue("BodyAllowed", body.name); break; } } } // parse the stock atmosphere restrictions into our own if (stockDef.requireAtmosphere) { expInfoNode.AddValue("BodyAllowed", "Atmospheric"); } else if (stockDef.requireNoAtmosphere) { expInfoNode.AddValue("BodyNotAllowed", "Atmospheric"); } } ExpBodyConditions = new BodyConditions(expInfoNode); foreach (string virtualBiomeStr in expInfoNode.GetValues("VirtualBiome")) { if (Enum.IsDefined(typeof(VirtualBiome), virtualBiomeStr)) { VirtualBiomes.Add((VirtualBiome)Enum.Parse(typeof(VirtualBiome), virtualBiomeStr)); } else { Lib.Log("Experiment definition `{0}` has unknown VirtualBiome={1}", Lib.LogLevel.Warning, ExperimentId, virtualBiomeStr); } } IgnoreBodyRestrictions = Lib.ConfigValue(expInfoNode, "IgnoreBodyRestrictions", false); uint situationMask = 0; uint biomeMask = 0; uint virtualBiomeMask = 0; // if defined, override stock situation / biome mask if (expInfoNode.HasValue("Situation")) { foreach (string situation in expInfoNode.GetValues("Situation")) { string[] sitAtBiome = situation.Split(new char[] { '@' }, StringSplitOptions.RemoveEmptyEntries); if (sitAtBiome.Length == 0 || sitAtBiome.Length > 2) { continue; } ScienceSituation scienceSituation = ScienceSituationUtils.ScienceSituationDeserialize(sitAtBiome[0]); if (scienceSituation != ScienceSituation.None) { situationMask += scienceSituation.BitValue(); if (sitAtBiome.Length == 2) { if (sitAtBiome[1].Equals("Biomes", StringComparison.OrdinalIgnoreCase)) { biomeMask += scienceSituation.BitValue(); } else if (sitAtBiome[1].Equals("VirtualBiomes", StringComparison.OrdinalIgnoreCase) && VirtualBiomes.Count > 0) { virtualBiomeMask += scienceSituation.BitValue(); } } } else { Lib.Log("Experiment definition `{0}` has unknown situation : `{1}`", Lib.LogLevel.Warning, ExperimentId, sitAtBiome[0]); } } } else { situationMask = stockDef.situationMask; biomeMask = stockDef.biomeMask; } if (situationMask == 0) { Lib.Log("Experiment definition `{0}` : `0` situationMask is unsupported, patching to `BodyGlobal`", Lib.LogLevel.Message, ExperimentId); situationMask = ScienceSituation.BodyGlobal.BitValue(); HasDBSubjects = false; } else { HasDBSubjects = !Lib.ConfigValue(expInfoNode, "IsGeneratingSubjects", false); } string error; uint stockSituationMask; uint stockBiomeMask; if (!ScienceSituationUtils.ValidateSituationBitMask(ref situationMask, biomeMask, out stockSituationMask, out stockBiomeMask, out error)) { Lib.Log("Experiment definition `{0}` is incorrect :\n{1}", Lib.LogLevel.Error, ExperimentId, error); } SituationMask = situationMask; BiomeMask = biomeMask; VirtualBiomeMask = virtualBiomeMask; stockDef.situationMask = stockSituationMask; stockDef.biomeMask = stockBiomeMask; }
private void configLoad() { //Load in global multipliers foreach (ConfigNode setNode in GameDatabase.Instance.GetConfigNodes("DM_CONTRACT_SETTINGS")) { if (setNode.GetValue("name") == "Contract Settings") { DMUtils.science = float.Parse(setNode.GetValue("Global_Science_Return")); DMUtils.reward = float.Parse(setNode.GetValue("Global_Fund_Reward")); DMUtils.forward = float.Parse(setNode.GetValue("Global_Fund_Forward")); DMUtils.penalty = float.Parse(setNode.GetValue("Global_Fund_Penalty")); DMUtils.deadline = float.Parse(setNode.GetValue("Global_Deadline")); DMUtils.maxSurvey = int.Parse(setNode.GetValue("Max_Survey")); DMUtils.maxAsteroid = int.Parse(setNode.GetValue("Max_Asteroid")); DMUtils.maxAnomaly = int.Parse(setNode.GetValue("Max_Anomaly")); DMUtils.maxMagnetic = int.Parse(setNode.GetValue("Max_Magnetic")); DMUtils.Logging("Contract Variables Set; Science Reward: {0} ; Completion Reward: {1} ; Forward Amount: {2} ; Penalty Amount: {3} ; Deadline Length: {4}", DMUtils.science, DMUtils.reward, DMUtils.forward, DMUtils.penalty, DMUtils.deadline); DMUtils.Logging("Max Contract Variables Set: Survey: {0} ; Asteroid: {1} ; Anomaly: {2} ; Magnetic: {3}", DMUtils.maxSurvey, DMUtils.maxAsteroid, DMUtils.maxAnomaly, DMUtils.maxMagnetic); break; } } //Load in experiment definitions foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("DM_CONTRACT_EXPERIMENT")) { string name, part, agent = ""; int sitMask, bioMask, type = 0; float transmit = 0; DMScienceContainer DMscience = null; ScienceExperiment exp = null; //Some apparently not impossible errors can cause deplicate experiments to be added to the R&D science experiment dictionary try { exp = ResearchAndDevelopment.GetExperiment(node.GetValue("experimentID")); } catch (Exception e) { Debug.LogError("[DM] Whoops. Something really wrong happened here; stopping this contract experiment from loading..." + e); continue; } if (exp != null) { name = node.GetValue("name"); if (!int.TryParse(node.GetValue("sitMask"), out sitMask)) { continue; } if (!int.TryParse(node.GetValue("bioMask"), out bioMask)) { continue; } if (!int.TryParse(node.GetValue("type"), out type)) { continue; } if (!float.TryParse(node.GetValue("xmitDataScalar"), out transmit)) { continue; } if (node.HasValue("part")) { part = node.GetValue("part"); } else { part = "None"; } if (node.HasValue("agent")) { agent = node.GetValue("agent"); } else { agent = "Any"; } if (DMUtils.whiteListed) { exp.situationMask = (uint)sitMask; } exp.biomeMask = (uint)bioMask; DMscience = new DMScienceContainer(exp, sitMask, bioMask, (DMScienceType)type, part, agent, transmit); if (((DMScienceType)type & DMScienceType.Surface) == DMScienceType.Surface && !DMUtils.availableScience[DMScienceType.Surface.ToString()].ContainsKey(name)) { DMUtils.availableScience[DMScienceType.Surface.ToString()].Add(name, DMscience); } if (((DMScienceType)type & DMScienceType.Aerial) == DMScienceType.Aerial && !DMUtils.availableScience[DMScienceType.Aerial.ToString()].ContainsKey(name)) { DMUtils.availableScience[DMScienceType.Aerial.ToString()].Add(name, DMscience); } if (((DMScienceType)type & DMScienceType.Space) == DMScienceType.Space && !DMUtils.availableScience[DMScienceType.Space.ToString()].ContainsKey(name)) { DMUtils.availableScience[DMScienceType.Space.ToString()].Add(name, DMscience); } if (((DMScienceType)type & DMScienceType.Biological) == DMScienceType.Biological && !DMUtils.availableScience[DMScienceType.Biological.ToString()].ContainsKey(name)) { DMUtils.availableScience[DMScienceType.Biological.ToString()].Add(name, DMscience); } if (((DMScienceType)type & DMScienceType.Asteroid) == DMScienceType.Asteroid && !DMUtils.availableScience[DMScienceType.Asteroid.ToString()].ContainsKey(name)) { DMUtils.availableScience[DMScienceType.Asteroid.ToString()].Add(name, DMscience); } if (((DMScienceType)type & DMScienceType.Anomaly) == DMScienceType.Anomaly && !DMUtils.availableScience[DMScienceType.Anomaly.ToString()].ContainsKey(name)) { DMUtils.availableScience[DMScienceType.Anomaly.ToString()].Add(name, DMscience); } if (!DMUtils.availableScience["All"].ContainsKey(name)) { DMUtils.availableScience["All"].Add(name, DMscience); } DMUtils.DebugLog("New Experiment: [{0}] Available For Contracts", name); } } DMUtils.Logging("Successfully Added {0} New Experiments To Contract List", DMUtils.availableScience["All"].Count); DMUtils.DebugLog("Successfully Added {0} New Surface Experiments To Contract List", DMUtils.availableScience[DMScienceType.Surface.ToString()].Count); DMUtils.DebugLog("Successfully Added {0} New Aerial Experiments To Contract List", DMUtils.availableScience[DMScienceType.Aerial.ToString()].Count); DMUtils.DebugLog("Successfully Added {0} New Orbital Experiments To Contract List", DMUtils.availableScience[DMScienceType.Space.ToString()].Count); DMUtils.DebugLog("Successfully Added {0} New Biological Experiments To Contract List", DMUtils.availableScience[DMScienceType.Biological.ToString()].Count); DMUtils.DebugLog("Successfully Added {0} New Asteroid Experiments To Contract List", DMUtils.availableScience[DMScienceType.Asteroid.ToString()].Count); DMUtils.DebugLog("Successfully Added {0} New Anomaly Experiments To Contract List", DMUtils.availableScience[DMScienceType.Anomaly.ToString()].Count); //Load in custom contract descriptions foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("DM_SCIENCE_STORY_DEF")) { foreach (ConfigNode storyNode in node.GetNodes("DM_SCIENCE_BACKSTORY")) { foreach (string st in storyNode.GetValues("generic")) { if (!string.IsNullOrEmpty(st)) { string story = st.Replace("[", "{"); story = story.Replace("]", "}"); DMUtils.backStory["generic"].Add(story); } } foreach (string so in storyNode.GetValues("survey")) { if (!string.IsNullOrEmpty(so)) { string story_o = so.Replace("[", "{"); story_o = story_o.Replace("]", "}"); DMUtils.backStory["survey"].Add(story_o); } } foreach (string sb in storyNode.GetValues("biological")) { if (!string.IsNullOrEmpty(sb)) { string story_b = sb.Replace("[", "{"); story_b = story_b.Replace("]", "}"); DMUtils.backStory["biological"].Add(story_b); } } foreach (string sb in storyNode.GetValues("asteroid")) { if (!string.IsNullOrEmpty(sb)) { string story_b = sb.Replace("[", "{"); story_b = story_b.Replace("]", "}"); DMUtils.backStory["asteroid"].Add(story_b); } } foreach (string sb in storyNode.GetValues("anomaly")) { if (!string.IsNullOrEmpty(sb)) { string story_b = sb.Replace("[", "{"); story_b = story_b.Replace("]", "}"); DMUtils.backStory["anomaly"].Add(story_b); } } foreach (string sb in storyNode.GetValues("magnetic")) { if (!string.IsNullOrEmpty(sb)) { string story_b = sb.Replace("[", "{"); story_b = story_b.Replace("]", "}"); DMUtils.backStory["magnetic"].Add(story_b); } } } } DMUtils.Logging("Added {0} New Generic Backstories; {1} New Survey Backstories; {2} New Biological Backstories; {3} New Asteroid Backstories; {4} New Anomaly Backstories; {5} New Magnetic Backstories To The List", DMUtils.backStory["generic"].Count, DMUtils.backStory["survey"].Count, DMUtils.backStory["biological"].Count, DMUtils.backStory["asteroid"].Count, DMUtils.backStory["anomaly"].Count, DMUtils.backStory["magnetic"].Count); }
public void addPartExperiment(ModuleScienceExperiment m, ScienceExperiment e) { Notes_Experiment exp = new Notes_Experiment(this, m, e, 1); if (!allExperiments.Contains(exp)) allExperiments.Add(exp); }