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);
        }
Beispiel #4
0
        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);
        }
Beispiel #8
0
 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);
        }
Beispiel #10
0
        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);
                 }
             }
         }
     }
 }
Beispiel #14
0
        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)));
        }
Beispiel #17
0
        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);
        }
Beispiel #20
0
        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);
        }
Beispiel #21
0
        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;
                }
            }
        }
Beispiel #22
0
        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);
        }
Beispiel #23
0
        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();
        }
Beispiel #24
0
        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);
        }
Beispiel #25
0
        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);
        }
Beispiel #27
0
        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);
        }
Beispiel #28
0
            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();
                }
            }
Beispiel #29
0
        /// <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();
        }
Beispiel #30
0
        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;
        }
Beispiel #38
0
        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);
            }
        }
        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";
        }
        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);
        }
        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;
        }