private static ImpactScienceData createSpectralData(CelestialBody crashBody, Vessel crashVessel, uint flightID) { double crashVelocity = crashVessel.srf_velocity.magnitude; Log("Velocity=" + crashVelocity); float crashMasss = crashVessel.GetTotalMass() * 1000; double crashEnergy = 0.5 * crashMasss * crashVelocity * crashVelocity; //KE of crash ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment("ImpactSpectrometer"); String biome = ScienceUtil.GetExperimentBiome(crashBody, crashVessel.latitude, crashVessel.longitude); CBAttributeMapSO m = crashBody.BiomeMap; CBAttributeMapSO.MapAttribute[] atts = m.Attributes; ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(experiment, ExperimentSituations.InSpaceLow, crashBody, biome, biome); double science = subject.scienceCap; Log("Impact took place in " + biome + " at " + crashVessel.latitude + "," + crashVessel.longitude); String flavourText = "Impact at <<1>> on <<2>>"; science = Math.Max(0, science - subject.science); science /= subject.subjectValue; ImpactScienceData data = new ImpactScienceData(ImpactScienceData.DataTypes.Spectral, 0, biome, crashVessel.latitude, (float)(science * subject.dataScale), 1f, 0, subject.id, Localizer.Format(flavourText, biome, crashBody.GetDisplayName()), false, flightID); ScreenMessages.PostScreenMessage( Localizer.Format("#autoLOC_Screen_Spectrum", biome, crashBody.GetDisplayName()), 5.0f, ScreenMessageStyle.UPPER_RIGHT); return(data); }
private static ImpactScienceData createAsteroidSpectralData(CelestialBody crashBody, Vessel asteroid, Vessel crashVessel, uint flightID) { double crashVelocity = crashVessel.srf_velocity.magnitude; Log("Velocity=" + crashVelocity); float crashMasss = crashVessel.GetTotalMass() * 1000; double crashEnergy = 0.5 * crashMasss * crashVelocity * crashVelocity; //KE of crash ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment("AsteroidSpectometry"); ExperimentSituations situation = ScienceUtil.GetExperimentSituation(asteroid); ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(experiment, situation, asteroid.id.ToString(), asteroid.GetName(), crashBody, "", ""); double science = subject.scienceCap; Log("Impact took place in " + situation); String flavourText = "Impact at <<1>> on <<2>>"; science /= subject.subjectValue; ImpactScienceData data = new ImpactScienceData(0, asteroid.GetName(), (float)(science * subject.dataScale), 1f, 0, subject.id, Localizer.Format(flavourText, asteroid.GetName(), crashBody.GetDisplayName()), false, flightID); ScreenMessages.PostScreenMessage( Localizer.Format("#autoLOC_Screen_Asteroid", asteroid.GetName(), crashBody.GetDisplayName()), 5.0f, ScreenMessageStyle.UPPER_RIGHT); return(data); }
private static ImpactScienceData createSeismicData(CelestialBody crashBody, Vessel crashVessel, uint flightID) { double crashVelocity = crashVessel.srf_velocity.magnitude; Log("Velocity=" + crashVelocity); float crashMasss = crashVessel.GetTotalMass() * 1000; double crashEnergy = 0.5 * crashMasss * crashVelocity * crashVelocity; //KE of crash ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment("ImpactSeismometer"); ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(experiment, ExperimentSituations.SrfLanded, crashBody, "", ""); double science = translateKEToScience(crashEnergy, crashBody, subject); String flavourText = "Impact of <<1>> on <<2>>"; Log(" caluculated science =" + science); science = Math.Max(0.01, science - subject.science); Log("residual science =" + science); science /= subject.subjectValue; Log("divided science =" + science); ImpactScienceData data = new ImpactScienceData(ImpactScienceData.DataTypes.Seismic, (float)crashEnergy, null, crashVessel.latitude, (float)(science * subject.dataScale), 1f, 0, subject.id, Localizer.Format(flavourText, energyFormat(crashEnergy), crashBody.GetDisplayName()), false, flightID); ScreenMessages.PostScreenMessage( Localizer.Format("#autoLOC_Screen_Seismic", energyFormat(crashEnergy), crashBody.GetDisplayName()), 5.0f, ScreenMessageStyle.UPPER_RIGHT); return(data); }
private void updateRemainingData() { List <ScienceData> dataList = new List <ScienceData>(); if (HighLogic.LoadedSceneIsFlight && FlightGlobals.ready) { foreach (IScienceDataContainer container in FlightGlobals.ActiveVessel.FindPartModulesImplementing <IScienceDataContainer>()) { if (container.GetData() != null && container.GetData().Length > 0) { dataList.AddRange(container.GetData()); } } if (dataList.Count > 0) { foreach (ScienceData data in dataList) { DMScienceData DMData = getDMScience(data.title); if (DMData != null) { ScienceSubject sub = ResearchAndDevelopment.GetSubjectByID(data.subjectID); if (sub != null) { sub.scientificValue *= DMData.SciVal; sub.science = Math.Max(0f, Math.Min(sub.scienceCap, sub.scienceCap - (sub.scienceCap * sub.scientificValue))); } } } } } }
public void ScienceReceivedHandler(float science, ScienceSubject sub, ProtoVessel v, bool whoKnows) { PlayYourWay.Log("Received " + science + " science points"); if (science == 0) { return; } float funds = science * this.fundsMult; float rep = science * this.repMult; if (Funding.Instance != null) { Funding.Instance.AddFunds(funds, TransactionReasons.ScienceTransmission); PlayYourWay.Log("Added " + funds + " funds"); } if (Reputation.Instance != null) { Reputation.Instance.AddReputation(rep, TransactionReasons.ScienceTransmission); PlayYourWay.Log("Added " + rep + " reputation"); } this.queue.Enqueue(new ScienceReport(funds, rep, sub.title)); this.timer.Start(); }
public static double translateKEToScience(double crashEnergy, CelestialBody crashBody, ScienceSubject subject) { double referenceEnergy = getReferenceCrash(crashBody); float relativeScience = Math.Min((float)(Math.Sqrt(crashEnergy / referenceEnergy)), 1); return relativeScience * subject.scienceCap; }
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 void processScience(float science, ScienceSubject scienceSubject, ProtoVessel vessel, bool whoKnows) { if (isRBactive && RBWrapper.RBactualAPI.enabled) { if (scienceSubject.id.Contains("TarsierSpaceTech.SpaceTelescope")) { if (scienceSubject.title.Contains("Space Telescope picture of ")) { string bodyName = scienceSubject.title.Substring(27); var foundbodyentry = TSTMstStgs.Instance.RBCelestialBodies.FirstOrDefault(a => a.Key.theName == bodyName); if (foundbodyentry.Key != null) { try { processResearchBody(foundbodyentry.Key); } catch (Exception ex) { Utilities.Log("Processing of celestial body for ResearchBodies unexpectedly. Interface disabled. Ex: {0}", ex.Message); isRBactive = false; } } else { Utilities.Log("Failed to find ResearchBody {0} to process for ResearchBodies mod", bodyName); } } } } }
public bool StoreScience(ModuleScienceContainer container, ScienceSubject subject, float data) { if (container.capacity > 0 && container.GetScienceCount() >= container.capacity) { return(false); } if (container.GetStoredDataCount() != 0) { return(false); } float xmitValue = 0.85f; float labBoost = 0.1f; ScienceData new_data = new ScienceData(data, xmitValue, labBoost, subject.id, subject.title); if (container.AddData(new_data)) { return(true); } return(false); }
public static float GetNextReportValue(ScienceSubject subject, ScienceExperiment experiment, List <ScienceData> onboard, float xmitScalar = 1f) { var data = new ScienceData(experiment.baseValue * experiment.dataScale * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier, xmitScalar, 0f, subject.id, string.Empty); data.labBoost = ModuleScienceLab.GetBoostForVesselData(FlightGlobals.ActiveVessel, data); xmitScalar += data.labBoost; #if DEBUG //Log.Debug("GetNextReportValue for {0}, calculated labBoost of {1}", experiment.experimentTitle, data.labBoost); #endif if (onboard.Count == 0) { return(ResearchAndDevelopment.GetScienceValue(experiment.baseValue * experiment.dataScale, subject, xmitScalar) * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier); } float experimentValue = ResearchAndDevelopment.GetNextScienceValue(experiment.baseValue * experiment.dataScale, subject, xmitScalar) * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; if (onboard.Count == 1) { return(experimentValue); } // we'll have to estimate return(experimentValue / UnityEngine.Mathf.Pow(4f, onboard.Count - 1)); }
private void RecoveryWatcher(float sci, ScienceSubject sub, ProtoVessel pv, bool reverse) { if (HighLogic.LoadedScene == GameScenes.SPACECENTER || HighLogic.LoadedScene == GameScenes.TRACKSTATION) { float DMScience = sci; DMUtils.DebugLog("Science Data Recovered For {0} Science", sci); DMScienceData DMData = DMScienceScenario.SciScenario.getDMScience(sub.title); if (DMData != null) { float oldSciVal = 0f; if (sub.scienceCap != 0) { oldSciVal = Math.Max(0f, 1f - ((sub.science - sci) / sub.scienceCap)); } DMScience = sub.subjectValue * DMData.BaseValue * DMData.SciVal * oldSciVal; DMScienceScenario.SciScenario.submitDMScience(DMData, DMScience); } if (DMScience != sci) { float extraScience = sci - DMScience; Debug.LogWarning(string.Format("[DMagic Orbital Science] [Asteroid Science Retrieval] Remove {0} Science From R&D Center After Asteroid Calculations", extraScience)); DMUtils.DebugLog("Remove {0} Science From R&D Center: From {1} To {2}", extraScience, ResearchAndDevelopment.Instance.Science, ResearchAndDevelopment.Instance.Science - extraScience); ResearchAndDevelopment.Instance.AddScience(-1f * extraScience, TransactionReasons.ScienceTransmission); } } }
// credit science for the experiment subject specified public static double Credit(string subject_id, double size, bool transmitted, ProtoVessel pv) { // get science subject // - if null, we are in sandbox mode ScienceSubject subject = ResearchAndDevelopment.GetSubjectByID(subject_id); if (subject == null) { return(0.0); } // get science value // - the stock system 'degrade' science value after each credit, we don't float R = ResearchAndDevelopment.GetReferenceDataValue((float)size, subject); float S = subject.science; float C = subject.scienceCap; float credits = Mathf.Max(Mathf.Min(S + Mathf.Min(R, C), C) - S, 0.0f); // credit the science subject.science += credits; subject.scientificValue = ResearchAndDevelopment.GetSubjectValue(subject.science, subject); credits *= HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; ResearchAndDevelopment.Instance.AddScience(credits, transmitted ? TransactionReasons.ScienceTransmission : TransactionReasons.VesselRecovery); // fire game event // - this could be slow or a no-op, depending on the number of listeners // in any case, we are buffering the transmitting data and calling this // function only once in a while GameEvents.OnScienceRecieved.Fire(credits, subject, pv, false); // return amount of science credited return(credits); }
private void processScience(float science, ScienceSubject scienceSubject, ProtoVessel vessel, bool whoKnows) { if (isRBactive && RBWrapper.RBactualAPI.enabled) { if (scienceSubject.id.Contains("TarsierSpaceTech.SpaceTelescope")) { int index = scienceSubject.id.IndexOf("LookingAt"); if (index != -1) { string[] tmpIDelements = scienceSubject.id.Split('@'); string[] valuesasarray = { "LookingAt" }; string[] splitvars = tmpIDelements[1].Split(valuesasarray, StringSplitOptions.None); string bodyName = splitvars[1]; KeyValuePair <CelestialBody, RBWrapper.CelestialBodyInfo> foundbodyentry = TSTMstStgs.Instance.RBCelestialBodies.FirstOrDefault(a => a.Key.name == bodyName); if (foundbodyentry.Key != null) { try { processResearchBody(foundbodyentry.Key); } catch (Exception ex) { Utilities.Log("Processing of celestial body for ResearchBodies unexpectedly. Interface disabled. Ex: {0}", ex.Message); isRBactive = false; } } else { Utilities.Log("Failed to find ResearchBody {0} to process for ResearchBodies mod", bodyName); } } } } }
private void OnScienceReceived(float amount, ScienceSubject subject, ProtoVessel vessel, bool reverseEngineered) { // Check that the science is for home CelestialBody body = Science.GetCelestialBody(subject); if (body == null || !body.isHomeWorld) { return; } Biome biome = Science.GetBiome(subject); bool isKSC = biome != null && biome.IsKSC(); if (KSCScienceMultiplier > 0.0f && isKSC) { float delta = KSCScienceMultiplier * amount - amount; ResearchAndDevelopment.Instance.AddScience(delta, TransactionReasons.Strategies); CurrencyPopup.Instance.AddPopup(Currency.Science, delta, TransactionReasons.Strategies, Parent.Config.Title, true); } else if (nonKSCScienceMultiplier > 0.0f && !isKSC) { float delta = nonKSCScienceMultiplier * amount - amount; ResearchAndDevelopment.Instance.AddScience(delta, TransactionReasons.Strategies); CurrencyPopup.Instance.AddPopup(Currency.Science, delta, TransactionReasons.Strategies, Parent.Config.Title, true); } }
/// <summary> /// Gets the subject with the specified ID, or null if none is available. /// </summary> /// <param name="subjectID"></param> /// <param name="lowThreshold"></param> /// <param name="highThreshold"></param> /// <returns></returns> public static Fraction Get(string subjectID, float lowThreshold, float highThreshold) { if ((instance == null) || (ResearchAndDevelopment.Instance == null)) { return(Fraction.High); } if (instance.missingSubjects.Contains(subjectID)) { // We've already asked ResearchAndDevelopment about this subject ID, // and were already told that it's not there, so it means no science // on the subject has been reported yet and therefore full value is // available. return(Fraction.High); } // Okay, look it up. ScienceSubject subject = ResearchAndDevelopment.GetSubjectByID(subjectID); if (subject == null) { // Not available! Remember that fact and return high value. instance.missingSubjects.Add(subjectID); return(Fraction.High); } // Okay, science for this subject was previously reported. Return // the appropriate fraction. float value = ResearchAndDevelopment.GetSubjectValue(subject.science, subject); return(FractionOf(value, lowThreshold, highThreshold)); }
private void registerDMScience(DMAsteroidScience newAst, ScienceSubject sub) { if (HighLogic.CurrentGame.Mode == Game.Modes.SANDBOX) { return; } DMScienceData DMData = null; DMScienceData DMScience = DMScienceScenario.SciScenario.getDMScience(sub.title); if (DMScience != null) { sub.scientificValue *= DMScience.SciVal; DMData = DMScience; } if (DMData == null) { float astSciCap = exp.scienceCap * 25f; 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 = Math.Max(0f, Math.Min(sub.scienceCap, sub.scienceCap - (sub.scienceCap * sub.scientificValue))); }
internal static List <string> fetchBiome(CelestialBody b, ScienceExperiment exp, ExperimentSituations sit) { DMUtils.DebugLog("Searching For Biomes: Value Sensitive"); List <string> s = new List <string>(); if (b.BiomeMap == null || b.BiomeMap.Attributes == null) { DMUtils.DebugLog("No Biomes Present For Target Planet"); s.Add(""); return(s); } else { for (int j = 0; j < b.BiomeMap.Attributes.Length; j++) { string bName = b.BiomeMap.Attributes[j].name; ScienceSubject subB = ResearchAndDevelopment.GetSubjectByID(string.Format("{0}@{1}{2}{3}", exp.id, b.name, sit, bName.Replace(" ", ""))); if (subB == null) { s.Add(bName); continue; } else { if (subB.scientificValue > 0.5f) { s.Add(bName); } } } } DMUtils.DebugLog("Found Acceptable Biomes"); return(s); }
public static Biome GetBiome(ScienceSubject subject) { if (subject == null || ResearchAndDevelopment.Instance == null) { return(null); } Match m = Regex.Match(subject.id, @"@([A-Z][\w]+?)([A-Z].*)"); string celestialBody = m.Groups[1].Value; string sitAndBiome = m.Groups[2].Value; string biome = ""; while (!string.IsNullOrEmpty(sitAndBiome)) { try { Enum.Parse(typeof(ExperimentSituations), sitAndBiome); break; } catch { m = Regex.Match(sitAndBiome, @"(.*)([A-Z][\w&]*)$$"); sitAndBiome = m.Groups[1].Value; biome = m.Groups[2].Value + biome; } } return(string.IsNullOrEmpty(biome) ? null : new Biome(ConfigNodeUtil.ParseCelestialBodyValue(celestialBody), biome)); }
protected override bool generateScienceData() { ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment("ExpInterstellarTelescope"); if (experiment == null) { return(false); } if (science_awaiting_addition > 0) { result_title = "Infrared Telescope Experiment"; result_string = "Infrared telescope observations were recovered from the vicinity of " + vessel.mainBody.name + "."; transmit_value = science_awaiting_addition; recovery_value = science_awaiting_addition; data_size = science_awaiting_addition * 1.25f; xmit_scalar = 1; ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(experiment, ExperimentSituations.InSpaceHigh, vessel.mainBody, ""); subject.scienceCap = 167 * PluginHelper.getScienceMultiplier(vessel); //PluginHelper.getScienceMultiplier(vessel.mainBody.flightGlobalsIndex,false); ref_value = subject.scienceCap; science_data = new ScienceData(science_awaiting_addition, 1, 0, subject.id, "Infrared Telescope Data"); return(true); } return(false); }
protected void OnScienceReceived(float science, ScienceSubject subject, ProtoVessel protoVessel, bool reverseEngineered) { if (protoVessel == null || reverseEngineered) { LoggingUtil.LogVerbose(this, "OnScienceReceived: returning, protoVessel = " + (protoVessel == null ? "null" :protoVessel.vesselName) + ", reverseEng = " + reverseEngineered); return; } LoggingUtil.LogVerbose(this, "OnScienceReceived: " + subject.id + ", " + protoVessel.vesselID); // Check the given subject is okay foreach (string exp in experiment) { if (CheckSubject(exp, subject)) { if (HighLogic.LoadedScene == GameScenes.FLIGHT) { if ((RecoveryMethod(exp) & ScienceRecoveryMethod.Transmit) != 0) { recoveryDone[exp] = true; } } else { if ((RecoveryMethod(exp) & ScienceRecoveryMethod.Recover) != 0) { recoveryDone[exp] = true; } } } } UpdateDelegates(); CheckVessel(protoVessel.vesselRef); }
private void OnScienceReceived(float science, ScienceSubject subject, ProtoVessel vessel, bool reverseEngineered) { // If this is set, it means that the vessel recovery dialog is figuring out the science that was received if (reverseEngineered) { return; } Biome biome = Science.GetBiome(subject); if (biome == null || biome.IsKSC()) { return; } IEnumerable<ScienceSubject> subjects = ResearchAndDevelopment.GetSubjects().Where(ss => ss.id.Contains(biome.body.name)); if (explorationType == ExplorationType.Biome) { subjects = subjects.Where(ss => ss.id.Contains(biome.biome)); } float totalScience = subjects.Sum(ss => ss.science) * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; // The values will be the same if this is the first for the biome if (Math.Abs(totalScience - science) < 0.001) { Funding.Instance.AddFunds(rewardFunds, TransactionReasons.Strategies); string title = "Rewards from strategy '" + Parent.Title + "'"; string header = "Science from new " + ExplorationTypeNamePlural(explorationType) + ":\n"; string rewardMessage = " " + (explorationType == ExplorationType.Biome ? biome.ToString() : biome.body.name) + ": <color=#B4D455>£ " + rewardFunds.ToString("N0") + "</color>\n"; MessageSystem.Message message = MessageSystem.Instance.FindMessages(m => m.messageTitle == title).FirstOrDefault(); if (message == null) { MessageSystem.Instance.AddMessage(new MessageSystem.Message(title, header + rewardMessage, MessageSystemButton.MessageButtonColor.GREEN, MessageSystemButton.ButtonIcons.ACHIEVE)); } else { // Section doesn't exist if (!message.message.Contains(header)) { message.message += "\n" + header; message.message += rewardMessage; } // Section is second (last) else if (message.message.Contains("\n\n" + header)) { message.message += rewardMessage; } // Section is first else { message.message = message.message.Replace("\n\n", "\n" + rewardMessage); } message.IsRead = false; } } }
protected void OnExperimentDeployed(ScienceData scienceData) { Vessel vessel = FlightGlobals.ActiveVessel; if (vessel == null || scienceData == null || !ReadyToComplete()) { return; } LoggingUtil.LogVerbose(this, "OnExperimentDeployed: " + scienceData.subjectID + ", " + vessel.id); // Decide if this is a matching subject ScienceSubject subject = ResearchAndDevelopment.GetSubjectByID(scienceData.subjectID); foreach (string exp in experiment) { if (CheckSubject(exp, subject)) { matchingSubjects[exp] = subject; if (recoveryMethod == ScienceRecoveryMethod.None) { recoveryDone[exp] = true; } UpdateDelegates(); } } CheckVessel(vessel); }
public void CreateSubjectInRnD() { if (ExistsInRnD) { return; } Dictionary <string, ScienceSubject> subjectsDB; if (Science.GameHasRnD) { if (ResearchAndDevelopment.Instance == null) { return; } // get subjects dictionary using reflection subjectsDB = Lib.ReflectionValue <Dictionary <string, ScienceSubject> > ( ResearchAndDevelopment.Instance, "scienceSubjects" ); // try to get the subject, might be already created in some corner-case situations RnDSubject = ResearchAndDevelopment.GetSubjectByID(StockSubjectId); } else { subjectsDB = ScienceDB.sandboxSubjects; // try to get the subject, might be already created in some corner-case situations ScienceSubject savedSubject; if (subjectsDB.TryGetValue(StockSubjectId, out savedSubject)) { RnDSubject = savedSubject; } } if (RnDSubject != null) { Lib.Log("CreateSubjectInRnD : ScienceSubject " + StockSubjectId + "exists already, this should not be happening !"); } else { // create new subject RnDSubject = new ScienceSubject ( StockSubjectId, FullTitle, (float)ExpInfo.DataScale, (float)Situation.SituationMultiplier, (float)ScienceMaxValue ); // add it to RnD or sandbox DB subjectsDB.Add(StockSubjectId, RnDSubject); } SetAsPersistent(); }
protected bool generateScienceData() { Debug.Log("Generating Science Data"); ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(experimentID); if (experiment == null) { Debug.Log("Experiment is null"); return(false); } if (sciencetoadd > 0) { resultTitle = experiment.experimentTitle; resultString = "You keep a very close eye on one of the scoops, counting it's rotations carefully."; transmitValue = sciencetoadd; recoveryValue = sciencetoadd * 0.1f; dataSize = 100f; xmitDataScalar = 1f; ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(experiment, ScienceUtil.GetExperimentSituation(vessel), vessel.mainBody, ""); subject.scienceCap = 167 * getScienceMultiplier(vessel.mainBody.flightGlobalsIndex); refValue = subject.scienceCap; scienceData = new ScienceData(sciencetoadd, 1f, 1f, subject.id, "Anemometer Data"); return(true); } return(false); }
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 ExperimentSituations GetSituation(ScienceSubject subject) { if (subject == null || ResearchAndDevelopment.Instance == null) { return(ExperimentSituations.SrfLanded); } Match m = Regex.Match(subject.id, @"@[A-Z][\w]+?([A-Z].*)"); string sitAndBiome = m.Groups[1].Value; while (!string.IsNullOrEmpty(sitAndBiome)) { try { return((ExperimentSituations)Enum.Parse(typeof(ExperimentSituations), sitAndBiome)); } catch { m = Regex.Match(sitAndBiome, @"(.*)[A-Z][\w]*$"); sitAndBiome = m.Groups[1].Value; } } return(ExperimentSituations.SrfLanded); }
private bool dataOnboard(SEP_ExperimentHandler handler, int level) { float science = handler.currentMaxScience(level); if (science > handler.submittedData) { if (handler.GetScienceCount() > 0) { ScienceData dat = handler.GetData()[0]; ScienceSubject sub = ResearchAndDevelopment.GetSubjectByID(dat.subjectID); if (sub != null) { float d = dat.dataAmount / sub.dataScale; //SEP_Utilities.log("Science Data value check: {0:N2} - {1:N2}", logLevels.warning, science, d); if (science <= d) { return(true); } } else { return(true); } } return(false); } return(true); }
private void OnScienceReceived(float science, ScienceSubject subject, ProtoVessel vessel, bool flag) { Log.Detail("EventObserver::OnScienceReceived: " + science + ", flag=" + flag); if (vessel == null) { return; } HallOfFame halloffame = HallOfFame.Instance(); // halloffame.BeginArwardOfRibbons(); try { foreach (ProtoCrewMember kerbal in vessel.GetVesselCrew()) { // we want to check crew member only if (kerbal.IsCrew()) { halloffame.RecordScience(kerbal, science); CheckAchievementsForCrew(kerbal, false); } } } finally { // commit ribbons halloffame.EndArwardOfRibbons(); } }
/// <summary> /// Science transmission handler: computes the funds and reputation boni /// and awards them to the player. /// </summary> public void ScienceReceivedHandler(float science, ScienceSubject sub, ProtoVessel v, bool whoKnows) { ScienceFunding.Log("Received " + science + " science points"); // Don't bother for zero science if (science == 0) { return; } float funds = science * this.fundsMult; float rep = science * this.repMult; // Cannot award funds if it's not a career if (Funding.Instance != null) { Funding.Instance.AddFunds(funds, TransactionReasons.ScienceTransmission); ScienceFunding.Log("Added " + funds + " funds"); } // Cannot award reputation in sandbox if (Reputation.Instance != null) { Reputation.Instance.AddReputation(rep, TransactionReasons.ScienceTransmission); ScienceFunding.Log("Added " + rep + " reputation"); } // Add the new report to the queue, and also send the notification if the queue has reached its limit. this.queue.Enqueue(new ScienceReport(funds, rep, sub.title)); this.timer.Start(); }
protected override bool generateScienceData() { ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(experimentID); if (experiment == null) { return(false); } if (science_to_add > 0) { result_title = experiment.experimentTitle; result_string = "Science experiments were conducted in the vicinity of " + vessel.mainBody.name + "."; transmit_value = science_to_add; recovery_value = science_to_add; data_size = science_to_add * 1.25f; xmit_scalar = 1; ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(experiment, ScienceUtil.GetExperimentSituation(vessel), vessel.mainBody, ""); subject.scienceCap = 167 * PluginHelper.getScienceMultiplier(vessel.mainBody.flightGlobalsIndex, false); ref_value = subject.scienceCap; science_data = new ScienceData(science_to_add, 1, 0, subject.id, "Science Lab Data"); return(true); } return(false); }
private float GetCurrentScienceValue(ScienceExperiment experiment, ScienceSubject subject, List <ScienceData> storedData) { // get total value of science in experiment containers and the kerbalism data drive int numberOfExperimentsOnBoard = storedData.Count; if (numberOfExperimentsOnBoard == 0) { return(subject.science); } float potentialScience = subject.science + ResearchAndDevelopment.GetScienceValue(storedData.First().dataAmount, subject) * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; if (numberOfExperimentsOnBoard > 1) { float secondReport = ResearchAndDevelopment.GetNextScienceValue(experiment.baseValue * experiment.dataScale, subject) * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; potentialScience += secondReport; if (numberOfExperimentsOnBoard > 2) { for (int i = 3; i < numberOfExperimentsOnBoard; ++i) { potentialScience += secondReport / Mathf.Pow(4f, i - 2); } } } return(potentialScience); }
private void RecoveryWatcher(float sci, ScienceSubject sub, ProtoVessel pv, bool reverse) { if (HighLogic.LoadedScene == GameScenes.SPACECENTER || HighLogic.LoadedScene == GameScenes.TRACKSTATION) { float DMScience = sci; DMUtils.DebugLog("Science Data Recovered For {0} Science", sci); DMScienceData DMData = DMScienceScenario.SciScenario.getDMScience(sub.title); if (DMData != null) { float oldSciVal = 0f; if (sub.scienceCap != 0) oldSciVal = Math.Max(0f, 1f - ((sub.science - sci) / sub.scienceCap)); DMScience = sub.subjectValue * DMData.BaseValue * DMData.SciVal * oldSciVal; DMScienceScenario.SciScenario.submitDMScience(DMData, DMScience); } if (DMScience != sci) { float extraScience = sci - DMScience; Debug.LogWarning(string.Format("[DMagic Orbital Science] [Asteroid Science Retrieval] Remove {0} Science From R&D Center After Asteroid Calculations", extraScience)); DMUtils.DebugLog("Remove {0} Science From R&D Center: From {1} To {2}", extraScience, ResearchAndDevelopment.Instance.Science, ResearchAndDevelopment.Instance.Science - extraScience); ResearchAndDevelopment.Instance.AddScience(-1f * extraScience, TransactionReasons.ScienceTransmission); } } }
/// <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; }
private void scienceReceived(float sci, ScienceSubject sub, ProtoVessel pv, bool reverse) { if (HighLogic.LoadedSceneIsFlight) { DMScienceData DMData = DMScienceScenario.SciScenario.getDMScience(sub.title); if (DMData != null) DMScienceScenario.SciScenario.submitDMScience(DMData, sci); } }
public static double translateScienceToKE(double science, CelestialBody crashBody, ScienceSubject subject) { double referenceEnergy = getReferenceCrash(crashBody); Log("ReferenceCrash=" + referenceEnergy); double relativeScience = science / subject.scienceCap; Log("Science=" + science + " relative = " + relativeScience); double crashEnergy = relativeScience * relativeScience * referenceEnergy; Log("crashEnergy=" + crashEnergy); return crashEnergy; }
void OnScienceReceived(float value, ScienceSubject scienceSubject) { if (!scienceIsValid(scienceSubject)) { { Debug.Log("TinkerTech: received invalid science result:" + scienceSubject.title + "(" + value.ToString() + ") - removing " + value.ToString() + " from the pool"); ResearchAndDevelopment.Instance.AddScience(-value, TransactionReasons.Cheating); } } }
private bool scienceIsValid(ScienceSubject subject) { //KSC landing science invalid if (subject.IsFromSituation(ExperimentSituations.SrfLanded) && (subject.title.Contains("LaunchPad") || subject.title.Contains("Runway") || subject.title.Contains("KSC"))) return false; //splashed on non-water biome if (subject.IsFromSituation(ExperimentSituations.SrfSplashed) && subject.title.Contains("Kerbin") && !subject.title.Contains("Oceans")) return false; //"Landed" in Oceans if (subject.IsFromSituation(ExperimentSituations.SrfLanded) && subject.title.Contains("Kerbin") && subject.title.Contains("Oceans")) return false; return true; }
public static ExperimentSituations GetSituation(ScienceSubject subject) { if (subject == null || ResearchAndDevelopment.Instance == null) { return ExperimentSituations.SrfLanded; } Match m = Regex.Match(subject.id, @"@[A-Z][\w]+?([A-Z].*)"); string sitAndBiome = m.Groups[1].Value; while (!string.IsNullOrEmpty(sitAndBiome)) { try { return (ExperimentSituations)Enum.Parse(typeof(ExperimentSituations), sitAndBiome); } catch { m = Regex.Match(sitAndBiome, @"(.*)[A-Z][\w]*$"); sitAndBiome = m.Groups[1].Value; } } return ExperimentSituations.SrfLanded; }
/// <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 ScienceExperiment GetExperiment(ScienceSubject subject) { if (subject == null || ResearchAndDevelopment.Instance == null) { return null; } return ResearchAndDevelopment.GetExperiment(subject.id.Substring(0, subject.id.IndexOf("@"))); }
private void OnScienceReceived(float science, ScienceSubject subject, ProtoVessel vessel, bool reverseEngineered) { // If this is set, it means that the vessel recovery dialog is figuring out the science that was received if (reverseEngineered) { return; } Biome biome = Science.GetBiome(subject); if (biome == null || biome.IsKSC()) { return; } IEnumerable<ScienceSubject> subjects = ResearchAndDevelopment.GetSubjects().Where(ss => ss.id.Contains(biome.body.name)); if (explorationType == ExplorationType.Biome) { subjects = subjects.Where(ss => ss.id.Contains(biome.biome)); } float totalScience = subjects.Sum(ss => ss.science) * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; // The values will be the same if this is the first for the biome if (Math.Abs(totalScience - science) < 0.001) { Funding.Instance.AddFunds(rewardFunds, TransactionReasons.Strategies); string title = "Rewards from strategy '" + Parent.Title + "'"; string header = "Science from new " + ExplorationTypeNamePlural(explorationType) + ":\n"; string rewardMessage = " " + (explorationType == ExplorationType.Biome ? biome.ToString() : biome.body.name) + ": <color=#B4D455><sprite=2 tint=1> " + rewardFunds.ToString("N0") + "</color>\n"; MessageSystem.Message message = MessageSystem.Instance.FindMessages(m => m.messageTitle == title).FirstOrDefault(); if (message == null) { MessageSystem.Instance.AddMessage(new MessageSystem.Message(title, header + rewardMessage, MessageSystemButton.MessageButtonColor.GREEN, MessageSystemButton.ButtonIcons.ACHIEVE)); } else { // Section doesn't exist if (!message.message.Contains(header)) { message.message += "\n" + header; message.message += rewardMessage; } // Section is second (last) else if (message.message.Contains("\n\n" + header)) { message.message += rewardMessage; } // Section is first else { message.message = message.message.Replace("\n\n", "\n" + rewardMessage); } message.IsRead = false; } } }
private void registerDMScience(DMAsteroidScience newAst, ScienceSubject sub) { if (HighLogic.CurrentGame.Mode == Game.Modes.SANDBOX) return; DMScienceData DMData = null; DMScienceData DMScience = DMScienceScenario.SciScenario.getDMScience(sub.title); if (DMScience != null) { sub.scientificValue *= DMScience.SciVal; DMData = DMScience; } if (DMData == null) { float astSciCap = scienceExp.scienceCap * 40f; DMScienceScenario.SciScenario.RecordNewScience(sub.title, scienceExp.baseValue, 1f, 0f, astSciCap); sub.scientificValue = 1f; } sub.subjectValue = newAst.SciMult; sub.scienceCap = scienceExp.scienceCap * sub.subjectValue; sub.science = Math.Max(0f, Math.Min(sub.scienceCap, sub.scienceCap - (sub.scienceCap * sub.scientificValue))); }
private bool CheckSubject(string exp, ScienceSubject subject) { if (subject == null) { return false; } if (targetBody != null && !subject.id.Contains(targetBody.name)) { return false; } if (!string.IsNullOrEmpty(biome) && !subject.id.Contains(biome)) { return false; } if (situation != null && !subject.IsFromSituation(situation.Value)) { return false; } if (location != null) { if (location.Value == BodyLocation.Surface && !subject.IsFromSituation(ExperimentSituations.SrfSplashed) && !subject.IsFromSituation(ExperimentSituations.SrfLanded)) { return false; } if (location.Value == BodyLocation.Space && !subject.IsFromSituation(ExperimentSituations.InSpaceHigh) && !subject.IsFromSituation(ExperimentSituations.InSpaceLow)) { return false; } } if (!string.IsNullOrEmpty(exp) && !subject.id.Contains(exp)) { return false; } return true; }
private void ScienceRecieved( float V, ScienceSubject S, ProtoVessel P, bool F ) { // _logger.Trace( "Callback: ScienceRecieved" ); ScheduleExperimentUpdate( ); }
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; }
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.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 processScience(float science, ScienceSubject scienceSubject, ProtoVessel vessel, bool whoKnows) { if (isRBactive && RBWrapper.RBactualAPI.enabled) { if (scienceSubject.id.Contains("TarsierSpaceTech.SpaceTelescope")) { if (scienceSubject.title.Contains("Space Telescope picture of ")) { string bodyName = scienceSubject.title.Substring(27); var foundbodyentry = TSTMstStgs.Instance.RBCelestialBodies.FirstOrDefault(a => a.Key.theName == bodyName); if (foundbodyentry.Key != null) { try { processResearchBody(foundbodyentry.Key); } catch (Exception ex) { Utilities.Log("Processing of celestial body for ResearchBodies unexpectedly. Interface disabled. Ex: {0}" , ex.Message); isRBactive = false; } } else { Utilities.Log("Failed to find ResearchBody {0} to process for ResearchBodies mod" , bodyName); } } } } }
public static CelestialBody GetCelestialBody(ScienceSubject subject) { if (subject == null || ResearchAndDevelopment.Instance == null) { return null; } Match m = Regex.Match(subject.id, @"@([A-Z][\w]+?)([A-Z].*)"); string celestialBody = m.Groups[1].Value; return ConfigNodeUtil.ParseCelestialBodyValue(celestialBody); }
private void onScienceTransmit(float value, ScienceSubject sub, ProtoVessel pV, bool b) { if (pV == null) return; if (pV.vesselID == null) return; Notes_Container n = getNotes(pV.vesselID); if (n == null) return; if (n.Data == null) return; double time = Planetarium.GetUniversalTime(); Notes_ReceivedData o = new Notes_ReceivedData(sub, value, (int)time, n.Data); n.Data.addReturnedData(o); }
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); }
private bool DataInContainer(ScienceSubject ScienceSubject, ScienceData[] ScienceData) { foreach (ScienceData data in ScienceData) { if (ScienceSubject.id.Contains(data.subjectID)) { return true; } } return false; }
private void createScienceDMagic(ModuleScienceExperiment currentExperiment, ScienceSubject currentScienceSubject, float currentScienceValue) { var scienceData = new ScienceData(currentScienceValue, currentExperiment.xmitDataScalar, 0, currentScienceSubject.id, currentScienceSubject.title); try { currentExperiment.GetType().InvokeMember("deployEvent", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.IgnoreReturn | System.Reflection.BindingFlags.InvokeMethod, null, currentExperiment, null); } catch (Exception) { } if (!currentExperiment.rerunnable) { currentExperiment.SetInoperable(); GameEvents.OnExperimentDeployed.Fire(scienceData); } container.AddData(scienceData); }
public static Biome GetBiome(ScienceSubject subject) { if (subject == null || ResearchAndDevelopment.Instance == null) { return null; } Match m = Regex.Match(subject.id, @"@([A-Z][\w]+?)([A-Z].*)"); string celestialBody = m.Groups[1].Value; string sitAndBiome = m.Groups[2].Value; string biome = ""; while (!string.IsNullOrEmpty(sitAndBiome)) { try { Enum.Parse(typeof(ExperimentSituations), sitAndBiome); break; } catch { m = Regex.Match(sitAndBiome, @"(.*)([A-Z][\w&]*)$$"); sitAndBiome = m.Groups[1].Value; biome = m.Groups[2].Value + biome; } } return string.IsNullOrEmpty(biome) ? null : new Biome(ConfigNodeUtil.ParseCelestialBodyValue(celestialBody), biome); }
/// <summary> /// Updates the IsUnlocked, CompletedScience, TotalScience, OnboardScience, and IsComplete fields. /// </summary> /// <param name="onboardScience">The total onboard ScienceData.</param> public void Update( ScienceContext Sci ) { if( Sci.ScienceSubjects.ContainsKey( Id ) ) ScienceSubject = Sci.ScienceSubjects[ Id ]; else ScienceSubject = new ScienceSubject(ScienceExperiment, Situation.ExperimentSituation, Situation.Body.CelestialBody, Situation.SubBiome ?? Situation.Biome ?? string.Empty); IsUnlocked = UnlockedInstrumentList.IsUnlocked( ScienceExperiment.id ) && ( Situation.Body.Reached != null ); CompletedScience = ScienceSubject.science * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; TotalScience = ScienceSubject.scienceCap * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; IsComplete = CompletedScience > TotalScience || TotalScience - CompletedScience < 0.1; var multiplier = ScienceExperiment.baseValue / ScienceExperiment.scienceCap; OnboardScience = 0; if( Sci.OnboardScienceList.ContainsKey( ScienceSubject.id ) ) { var data = Sci.OnboardScienceList[ ScienceSubject.id ]; // var _logger = new Logger( "Experiment" ); // _logger.Trace( ScienceSubject.id + " found " + data.Count( ) + " items" ); foreach (var i in data) { var next = (TotalScience - (CompletedScience + OnboardScience)) * multiplier; OnboardScience += next; } } var AllCollectedScience = CompletedScience + OnboardScience; IsCollected = AllCollectedScience > TotalScience || TotalScience - AllCollectedScience < 0.1; }
private static void onScienceReceive(float data, ScienceSubject sub, ProtoVessel pv, bool b) { if (pv == null) return; if (sub == null) return; if (pv.vesselRef.mainBody == null) return; IEnumerable<KeyValuePair<Guid, Notes_CheckListItem>> notes = scienceNotes.Where(n => n.Value.Root.RootVessel.id == pv.vesselID); for (int i = 0; i < notes.Count(); i++) { Notes_CheckListItem n = notes.ElementAt(i).Value; if (n == null) continue; if (n.Data == null) continue; if (n.CheckType == Notes_CheckListType.scienceFromPlanet) { if (n.TargetBody == null) continue; if (!sub.IsFromBody(n.TargetBody)) continue; } n.Data -= data; switch (n.CheckType) { case Notes_CheckListType.science: n.Text = string.Format("Return {0:F0} more science data", n.Data); break; case Notes_CheckListType.scienceFromPlanet: n.Text = string.Format("Return {0:F0} more science data from {1}", n.Data, n.TargetBody.theName); break; } if (n.Data <= 0) n.setComplete(); } }
private IEnumerator Transmit(Callback callback = null) { RTLog.Notify("ModuleRTDataTransmitter::Transmit"); var msg = new ScreenMessage(String.Format("[{0}]: Starting Transmission...", part.partInfo.title), 4f, ScreenMessageStyle.UPPER_LEFT); var msgStatus = new ScreenMessage(String.Empty, 4.0f, ScreenMessageStyle.UPPER_LEFT); ScreenMessages.PostScreenMessage(msg); isBusy = true; while (scienceDataQueue.Any()) { var scienceData = scienceDataQueue[0]; var dataAmount = scienceData.dataAmount; scienceDataQueue.RemoveAt(0); scienceData.triggered = true; var subject = ResearchAndDevelopment.GetSubjectByID(scienceData.subjectID); if (subject == null) subject = new ScienceSubject("", "", 1, 0, 0); int packets = Mathf.CeilToInt(scienceData.dataAmount / PacketSize); RnDCommsStream commStream = null; if (ResearchAndDevelopment.Instance != null) { // pre-calculate the time interval - fix for x64 systems // workaround for issue #136 float time1 = Time.time; yield return new WaitForSeconds(PacketInterval); // get the delta time float x64PacketInterval = (Time.time - time1); RTLog.Notify("Changing RnDCommsStream timeout from {0} to {1}", PacketInterval, x64PacketInterval); //TODO (porting to 1.2): check if scienceData.baseTransmitValue alone or with scienceData.transmitBonus commStream = new RnDCommsStream(subject, scienceData.dataAmount, x64PacketInterval, scienceData.baseTransmitValue, false, ResearchAndDevelopment.Instance); } //StartCoroutine(SetFXModules_Coroutine(modules_progress, 0.0f)); float power = 0; while (packets > 0) { power += part.RequestResource("ElectricCharge", PacketResourceCost - power); if (power >= PacketResourceCost * 0.95) { GUIStatus = "Uploading Data..."; // remove some power due to transmission power -= PacketResourceCost; // transmitted size float frame = Math.Min(PacketSize, dataAmount); // subtract current packet size from data left to transmit // and clamp it to 1 digit precision to avoid large float precision error (#667) dataAmount -= frame; dataAmount = (float)Math.Round(dataAmount, 1); packets--; float progress = (scienceData.dataAmount - dataAmount) / scienceData.dataAmount; msgStatus.message = String.Format("[{0}]: Uploading Data... {1:P0}", part.partInfo.title, progress); ScreenMessages.PostScreenMessage(msgStatus); RTLog.Notify("[Transmitter]: Uploading Data... ({0}) - {1} Mits/sec. Packets to go: {2} - Other experiments waiting to transfer: {3}", scienceData.title, (PacketSize / PacketInterval).ToString("0.00"), packets, scienceDataQueue.Count); // if we've a defined callback parameter so skip to stream each packet if (commStream != null && callback == null) { RTLog.Notify( "[Transmitter]: PacketSize: {0}; Transmitted size (frame): {1}; Data left to transmit (dataAmount): {2}; Packets left (packets): {3}", PacketSize, frame, dataAmount, packets); // use try / catch to prevent NRE spamming in KSP code when RT is used with other mods. try { commStream.StreamData(frame, vessel.protoVessel); } catch (NullReferenceException nre) { RTLog.Notify("A problem occurred during science transmission: {0}", RTLogLevel.LVL2, nre); } // TODO: remove this when fixed in stock // Fix a problem in stock KSP (discovered in 1.1.3, and still here in 1.2.1) // issue #667 ; floating point error in RnDCommsStream.StreamData method when adding to dataIn private field // e.g scienceData.dataAmount is 10 but in the end RnDCommsStream.dataIn will be 9.999999, so the science never // gets registered to the ResearchAndDevelopment center. if (packets == 0) // check that we have no packet left to send. { // get the private field (dataIn) in RnDCommsStream. This field is subject to floating point rounding error // We handle this problem on our side. var dataIn = RTUtil.GetInstanceField(typeof(RnDCommsStream), commStream, "dataIn"); if (dataIn != null) { // check if we have a delta (e.g. 10 - 9.999999999 will give us a tiny delta) var delta = scienceData.dataAmount - (float) dataIn; RTLog.Notify("[Transmitter]: delta: {0}", delta); // the delta must be positive and less than this constant to push / transmit the remaining size. // This prevent us pushing packets with too much leftover to transmit (e.g if there was a connection loss). if ((delta > 0f) && (delta <= PacketRemainingSize)) { try { // we have a delta, try to send the remaining little bit of science commStream.StreamData(delta, vessel.protoVessel); } catch (NullReferenceException nre) { RTLog.Notify("A problem occurred during science transmission (delta): {0}", RTLogLevel.LVL2, nre); } } } else { RTLog.Notify("[Transmitter]: dataIn is null."); } } // end stock fix } else { RTLog.Notify("[Transmitter]: [DEBUG] commstream is null and no callback"); } } else { // not enough power msg.message = String.Format("<b><color=orange>[{0}]: Warning! Not Enough {1}!</color></b>", part.partInfo.title, RequiredResource); ScreenMessages.PostScreenMessage(msg); GUIStatus = String.Format("{0}/{1} {2}", power, PacketResourceCost, RequiredResource); } yield return new WaitForSeconds(PacketInterval); } // effectively inform the game that science has been transmitted GameEvents.OnTriggeredDataTransmission.Fire(scienceData, vessel, false); yield return new WaitForSeconds(PacketInterval * 2); } isBusy = false; msg.message = String.Format("[{0}]: Done!", part.partInfo.title); ScreenMessages.PostScreenMessage(msg); if (callback != null) callback.Invoke(); GUIStatus = "Idle"; }
public static ScienceSubject parse(this ConfigNode node, string name, ScienceSubject original) { if (!node.HasValue(name)) return original; ScienceSubject subject = original; string id = node.GetValue(name); subject = ResearchAndDevelopment.GetSubjectByID(id); if (subject != null) return subject; return original; }