コード例 #1
0
        private string BiomeString(ScienceExperiment experiment = null)
        {
            if (experiment != null && !experiment.BiomeIsRelevantWhile(ScienceUtil.GetExperimentSituation(vessel)))
            {
                return(string.Empty);
            }
            if (vessel == null || body == null)
            {
                return(string.Empty);
            }
            if (body.BiomeMap == null)
            {
                return(string.Empty);
            }
            var v = vessel.EVALadderVessel;

            if (!string.IsNullOrEmpty(v.landedAt))
            {
                return(Vessel.GetLandedAtString(v.landedAt));
            }
            else
            {
                return(ScienceUtil.GetExperimentBiome(body, v.latitude, v.longitude));
            }
        }
コード例 #2
0
        protected string CurrentBiome(ScienceExperiment baseExperiment)
        {
            if (!baseExperiment.BiomeIsRelevantWhile(ScienceUtil.GetExperimentSituation(FlightGlobals.ActiveVessel)))
            {
                return(string.Empty);
            }
            var currentVessel = FlightGlobals.ActiveVessel;
            var currentBody   = FlightGlobals.currentMainBody;

            if (currentVessel != null && currentBody != null)
            {
                if (currentVessel.isEVA)
                {
                    currentVessel = currentVessel.EVALadderVessel;
                }
                if (!string.IsNullOrEmpty(currentVessel.landedAt))
                {
                    //big thanks to xEvilReeperx for this one.
                    return(Vessel.GetLandedAtString(currentVessel.landedAt));
                }
                else
                {
                    return(ScienceUtil.GetExperimentBiome(currentBody, currentVessel.latitude, currentVessel.longitude));
                }
            }
            else
            {
                Log("currentVessel && currentBody == null");
            }
            return(string.Empty);
        }
コード例 #3
0
        //This method handles generating the surface or asteroid sample ScienceData
        private ScienceData sampleData(ModuleAsteroid m)
        {
            ScienceExperiment    exp = null;
            ScienceSubject       sub = null;
            ExperimentSituations expSit;
            ScienceData          data = null;
            string biome = "";

            if (m != null)
            {
                exp = asteroidExp;
            }
            else
            {
                exp = surfaceExp;
            }

            if (exp == null)
            {
                return(null);
            }

            expSit = ScienceUtil.GetExperimentSituation(vessel);

            if (exp.IsAvailableWhile(expSit, vessel.mainBody))
            {
                if (exp.BiomeIsRelevantWhile(expSit))
                {
                    if (!string.IsNullOrEmpty(vessel.landedAt))
                    {
                        biome = Vessel.GetLandedAtString(vessel.landedAt);
                    }
                    else
                    {
                        biome = ScienceUtil.GetExperimentBiome(vessel.mainBody, vessel.latitude, vessel.longitude);
                    }
                }

                if (m != null)
                {
                    sub = ResearchAndDevelopment.GetExperimentSubject(exp, expSit, m.part.partInfo.name + m.part.flightID, m.part.partInfo.title, vessel.mainBody, biome);
                }
                else
                {
                    sub = ResearchAndDevelopment.GetExperimentSubject(exp, expSit, vessel.mainBody, biome);
                }

                if (sub == null)
                {
                    return(null);
                }

                data = new ScienceData(exp.baseValue * exp.dataScale, this.xmitDataScalar, 0f, sub.id, sub.title, false, part.flightID);

                return(data);
            }

            return(null);
        }
コード例 #4
0
ファイル: Utils.cs プロジェクト: hemeac/L-Tech
        internal static bool CanRunExperiment(Vessel vessel, string expId, ref string msg)
        {
            msg = Localizer.Format("#autoLOC_LTech_Util_002");

            ScienceExperiment labExp = ResearchAndDevelopment.GetExperiment(expId);

            if (labExp.IsAvailableWhile((ExperimentSituations)vessel.situation, vessel.mainBody))
            {
                if (labExp.BiomeIsRelevantWhile((ExperimentSituations)vessel.situation))
                {
                    return(true);
                }
            }

            if (vessel.situation == Vessel.Situations.LANDED)
            {
                if (vessel.situation == Vessel.Situations.LANDED)
                {
                    return(true);
                }

                msg += Localizer.Format("#autoLOC_LTech_Util_003");
            }

            if (vessel.situation == Vessel.Situations.SPLASHED)
            {
                if (vessel.situation == Vessel.Situations.SPLASHED)
                {
                    return(true);
                }

                msg += Localizer.Format("#autoLOC_LTech_Util_004");
            }

            if (vessel.situation == Vessel.Situations.FLYING)
            {
                if (vessel.altitude <= vessel.orbit.referenceBody.atmosphereDepth)
                {
                    return(true);
                }

                msg += Localizer.Format("#autoLOC_LTech_Util_005");
            }

            if (vessel.situation == Vessel.Situations.ORBITING)
            {
                if (vessel.altitude > vessel.orbit.referenceBody.atmosphereDepth)
                {
                    return(true);
                }

                msg += Localizer.Format("#autoLOC_LTech_Util_006");
            }

            msg = msg.Remove(msg.Length - 2);
            return(false);
        }
コード例 #5
0
        private static IEnumerable <ScienceSubject> GetSubjects(ScienceExperiment experiment, CelestialBody body, Func <string, bool> biomeFilter, bool difficult)
        {
            IEnumerable <ExperimentSituations> situations = Enum.GetValues(typeof(ExperimentSituations)).Cast <ExperimentSituations>();

            // Set up the biome filter
            bool biomesFiltered = biomeFilter != null;

            if (biomeFilter == null)
            {
                biomeFilter = new Func <string, bool>(x => true);
            }

            IEnumerable <string> biomes = body.BiomeMap == null?Enumerable.Empty <string>() :
                                              body.BiomeMap.Attributes.Select(attr => attr.name.Replace(" ", string.Empty)).
                                              Where(biomeFilter);

            return(situations
                   .Where(sit => ExperimentAvailable(experiment, sit, body) &&
                          (sit != ExperimentSituations.SrfSplashed || body.ocean) &&
                          ((sit != ExperimentSituations.FlyingLow && sit != ExperimentSituations.FlyingHigh) || body.atmosphere))
                   .SelectMany <ExperimentSituations, ScienceSubject>(sit =>
            {
                if (experiment.BiomeIsRelevantWhile(sit))
                {
                    ExperimentRules rules = GetExperimentRules(experiment.id);

                    return biomes.Where(biome => !(BiomeTracker.IsDifficult(body, biome, sit) || experiment.id == "asteroidSample") ^ difficult)
                    .Select(biome => ScienceSubject(experiment, sit, body, biome))
                    .Union(body.isHomeWorld && !rules.disallowKSC && sit == ExperimentSituations.SrfLanded         // static KSC items can only be landed
                                ? Biome.KSCBiomes.Where(biomeFilter).Where(b => experiment.id == "asteroidSample" ^ !difficult).Select(
                               staticName =>
                               ScienceSubject(experiment, ExperimentSituations.SrfLanded, body, staticName))
                                        : Enumerable.Empty <ScienceSubject>());
                }
                else if (experiment.id.StartsWith("ROCScience") && biomesFiltered)
                {
                    ROCDefinition roc = ROCManager.Instance.rocDefinitions.Where(r => r.myCelestialBodies.Any(x => x.name == body.name) && experiment.id.Contains(r.type)).FirstOrDefault();
                    if (roc != null && roc.myCelestialBodies.First().biomes.Where(biomeFilter).Any())
                    {
                        return new ScienceSubject[] { ScienceSubject(experiment, sit, body, "") };
                    }
                    else
                    {
                        return Enumerable.Empty <ScienceSubject>();
                    }
                }
                else if (!biomesFiltered && !difficult)
                {
                    return new ScienceSubject[] { ScienceSubject(experiment, sit, body, "") };
                }
                else
                {
                    return Enumerable.Empty <ScienceSubject>();
                }
            }));
        }
コード例 #6
0
        ScienceSubject currentScienceSubject(ScienceExperiment experiment)
        {
            string fixBiome = string.Empty; // some biomes don't have 4th string, so we just put an empty in to compare strings later

            if (experiment.BiomeIsRelevantWhile(currentSituation()))
            {
                fixBiome = currentBiome();                                                                                // for those that do, we add it to the string
            }
            return(ResearchAndDevelopment.GetExperimentSubject(experiment, currentSituation(), currentBody(), fixBiome)); //ikr!, we pretty much did all the work already, jeez
        }
コード例 #7
0
        /// <summary>
        /// Get the subject ID to use for the vessel's current situation.
        /// </summary>
        /// <param name="experiment"></param>
        /// <param name="vessel"></param>
        /// <returns></returns>
        private static string GetSubjectId(ScienceExperiment experiment, Vessel vessel)
        {
            string celestialBodyName       = vessel.mainBody.name;
            ExperimentSituations situation = ScienceUtil.GetExperimentSituation(vessel);
            string biome = GetBiome(vessel);

            if (experiment.BiomeIsRelevantWhile(situation))
            {
                return(experiment.id + "@" + celestialBodyName + situation.ToString() + biome.Replace(" ", string.Empty));
            }
            else
            {
                return(experiment.id + "@" + celestialBodyName + situation.ToString());
            }
        }
コード例 #8
0
        private void RunExperiment(ScienceAIExperiment experiment, ExperimentSituations situation, ScienceAIVesselModule mod, Vessel v, String biome)
        {
            String            currentBiome = String.Empty;
            ScienceExperiment exp          = ResearchAndDevelopment.GetExperiment(experiment.experimentID);

            if (exp.BiomeIsRelevantWhile(situation))
            {
                currentBiome = v.landedAt != string.Empty ? v.landedAt : biome;
            }
            ScienceSubject subj = ResearchAndDevelopment.GetExperimentSubject(exp, situation, v.mainBody, currentBiome, null);

            if (((subj.scienceCap - subj.science) > 0.1 || mod.collectEmpty) && mod.results.Find(r => r.subjectID == subj.id) == null)
            {
                ScienceAIData result = new ScienceAIData(exp.baseValue * exp.dataScale, experiment.xmitDataScalar, 0f, subj.id, subj.title);
                mod.results.Add(result);

                if (experiment.rerunnable == false)
                {
                    experiment.inoperable = true;
                }
            }
        }
コード例 #9
0
        private static string currentBiome(ScienceExperiment e, Vessel v)
        {
            if (e == null)
            {
                return("");
            }

            if (v == null)
            {
                return("");
            }

            if (!e.BiomeIsRelevantWhile(ExperimentSituations.SrfLanded))
            {
                return("");
            }

            if (string.IsNullOrEmpty(v.landedAt))
            {
                return(ScienceUtil.GetExperimentBiome(v.mainBody, v.latitude, v.longitude));
            }

            return(Vessel.GetLandedAtString(v.landedAt));
        }
コード例 #10
0
        private static string currentDisplayBiome(ScienceExperiment e, Vessel v)
        {
            if (e == null)
            {
                return("");
            }

            if (v == null)
            {
                return("");
            }

            if (!e.BiomeIsRelevantWhile(ExperimentSituations.SrfLanded))
            {
                return("");
            }

            if (string.IsNullOrEmpty(v.displaylandedAt))
            {
                return(Localizer.Format(ScienceUtil.GetExperimentBiomeLocalized(v.mainBody, v.latitude, v.longitude)));
            }

            return(Localizer.Format(v.displaylandedAt));
        }
コード例 #11
0
 private string getBiomeForExperiment(ScienceExperiment experiment)
 {
     if (experiment.BiomeIsRelevantWhile(currentSituation))
       {
     Utilities.debug(modName, Utilities.LogMode.Debug, experiment.id + ": BiomeIsRelevantWhile: " + currentSituation);
     return currentBiome();
       }
       Utilities.debug(modName, Utilities.LogMode.Debug, experiment.id + ": BiomeIsNotRelevantWhile: " + currentSituation);
       return string.Empty;
 }
コード例 #12
0
        private static IEnumerable<ScienceSubject> GetSubjects(ScienceExperiment experiment, CelestialBody body, Func<string, bool> biomeFilter, bool difficult)
        {
            IEnumerable<ExperimentSituations> situations = Enum.GetValues(typeof(ExperimentSituations)).Cast<ExperimentSituations>();

            // Set up the biome filter
            bool biomesFiltered = biomeFilter != null;
            if (biomeFilter == null)
            {
                biomeFilter = new Func<string, bool>(x => true);
            }

            IEnumerable<string> biomes = body.BiomeMap == null ? Enumerable.Empty<string>() :
                body.BiomeMap.Attributes.Select(attr => attr.name.Replace(" ", string.Empty)).
                Where(biomeFilter);

            return situations
                .Where(sit => ExperimentAvailable(experiment, sit, body) &&
                    (sit != ExperimentSituations.SrfSplashed || body.ocean) &&
                    ((sit != ExperimentSituations.FlyingLow && sit != ExperimentSituations.FlyingHigh) || body.atmosphere))
                .SelectMany<ExperimentSituations, ScienceSubject>(sit =>
                {
                    if (experiment.BiomeIsRelevantWhile(sit))
                    {
                        return biomes.Where(biome => !(BiomeTracker.IsDifficult(body, biome, sit) || experiment.id == "asteroidSample") ^ difficult)
                            .Select(biome => ScienceSubject(experiment, sit, body, biome))
                            .Union(body.isHomeWorld && sit == ExperimentSituations.SrfLanded // static KSC items can only be landed
                                ? Biome.KSCBiomes.Where(biomeFilter).Where(b => experiment.id == "asteroidSample" ^ !difficult).Select(
                                    staticName =>
                                        ScienceSubject(experiment, ExperimentSituations.SrfLanded, body, staticName))
                                        : Enumerable.Empty<ScienceSubject>());
                    }
                    else if (!biomesFiltered && !difficult)
                    {
                        return new ScienceSubject[] { ScienceSubject(experiment, sit, body, "") };
                    }
                    else
                    {
                        return Enumerable.Empty<ScienceSubject>();
                    }
                });
        }
コード例 #13
0
        public virtual bool UpdateStatus(ExperimentSituations experimentSituation, out bool newReport)
        {
            newReport = false;

            if (FlightGlobals.ActiveVessel == null)
            {
                Available       = false;
                lastAvailableId = "";
                return(false);
            }

            if (!settings.Enabled || (requireControllable && !FlightGlobals.ActiveVessel.IsControllable))
            {
                Available       = false;
                lastAvailableId = "";
                return(false);
            }

            bool lastStatus = Available;
            var  vessel     = FlightGlobals.ActiveVessel;

            if (!storage.IsBusy && IsReadyOnboard)
            {
                // does this experiment even apply in the current situation?
                if (experiment.IsAvailableWhile(experimentSituation, vessel.mainBody))
                {
                    var biome = string.Empty;
                    if (experiment.BiomeIsRelevantWhile(experimentSituation))
                    {
                        // biome matters; check to make sure we have biome data available
                        if (scanInterface.HaveScanData(vessel.latitude, vessel.longitude, vessel.mainBody))
                        {
                            if (biomeFilter.GetBiome(vessel.latitude, vessel.longitude,
                                                     out biome))
                            {
                                lastBiomeQuery = biome;
                            }
                            else
                            {
                                biome = lastBiomeQuery; // use last good known value
                            }
                        }
                        else
                        {
                            // no biome data available
                            Available       = false;
                            lastAvailableId = "";
                            return(false);
                        }
                    }

                    try
                    {
                        var subject = ResearchAndDevelopment.GetExperimentSubject(experiment, experimentSituation,
                                                                                  vessel.mainBody, biome, null);
                        List <ScienceData> data = null;
                        float scienceTotal      = GetScienceTotal(subject, out data);

                        switch (settings.Filter)
                        {
                        case ExperimentSettings.FilterMethod.Unresearched:
                            // Fairly straightforward: total science + potential should be zero
                            Available = scienceTotal < 0.0005f;
                            break;

                        case ExperimentSettings.FilterMethod.NotMaxed:
                            // <98% of science cap
                            Available = scienceTotal < subject.scienceCap * 0.98f *
                                        HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier;
                            break;

                        case ExperimentSettings.FilterMethod.LessThanFiftyPercent:
                            Available = scienceTotal < subject.scienceCap * 0.5f *
                                        HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier;
                            break;

                        case ExperimentSettings.FilterMethod.LessThanNinetyPercent:
                            Available = scienceTotal < subject.scienceCap * 0.9f *
                                        HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier;
                            break;

                        default:     // this should NEVER occur, but nice to have a safety measure
                            // in place if I add a filter option and forget to add its logic
                            Log.Error("Unrecognized experiment filter!");
                            data = new List <ScienceData>();
                            break;
                        }

                        nextReportValue = subject.CalculateNextReport(experiment, data);
                        Available       = Available && nextReportValue > 0.01f;
                        Available       = Available && nextReportValue >
                                          ScienceAlertProfileManager.ActiveProfile.ScienceThreshold;

                        if (Available)
                        {
                            if (lastAvailableId != subject.id)
                            {
                                lastStatus =
                                    false;        // force a refresh, in case we're going from available -> available in different subject id
                                newReport = true; // we've available on a brand new report
                            }

                            lastAvailableId = subject.id;
                        }
                    }
                    catch (NullReferenceException e)
                    {
                        Log.Error(
                            "Failed to create {0} ScienceSubject. If you can manage to reproduce this error, let me know.",
                            experiment.id);
                        Log.Error("Exception was: {0}", e);
                        Available = lastStatus;
                    }
                }
                else
                {
                    Available = false;
                }
            }
            else
            {
                Available = false;  // no experiments ready
            }
            return(Available != lastStatus && Available);
        }
コード例 #14
0
        /// <summary>
        /// Returns true if the status just changed to available (so that
        /// ScienceAlert can play a sound when the experiment
        /// status changes)
        /// </summary>
        /// <returns></returns>
        public virtual bool UpdateStatus(ExperimentSituations experimentSituation, out bool newReport)
        {
            newReport = false;

            if (FlightGlobals.ActiveVessel == null)
            {
                Available       = false;
                lastAvailableId = "";
                Log.Debug("Observer.UpdateStatus: active vessel is null!");
                return(false);
            }

            if (!settings.Enabled ||
                (requireControllable && !FlightGlobals.ActiveVessel.IsControllable))
            {
                Available       = false;
                lastAvailableId = "";
                return(false);
            }


            bool lastStatus = Available;
            var  vessel     = FlightGlobals.ActiveVessel;

            if (!storage.IsBusy && IsReadyOnboard)
            {
                // does this experiment even apply in the current situation?
                if (experiment.IsAvailableWhile(experimentSituation, vessel.mainBody))
                {
                    var biome = string.Empty;

                    // note: apparently simply providing the biome name whether its
                    // relevant or not will result in the biome being INCORRECTLY applied
                    // to the experiment id.  This causes all kinds of confusion because
                    // R&D will report incorrect science values based on the wrong id
                    //
                    // Supplying an empty string if the biome doesn't matter seems to work
                    if (experiment.BiomeIsRelevantWhile(experimentSituation))
                    {
                        // biome matters; check to make sure we have biome data available
                        if (scanInterface.HaveScanData(vessel.latitude, vessel.longitude, vessel.mainBody))
                        {
                            if (biomeFilter.GetBiome(vessel.latitude * Mathf.Deg2Rad, vessel.longitude * Mathf.Deg2Rad, out biome))
                            {
                                lastBiomeQuery = biome;
                            }
                            else
                            {
                                biome = lastBiomeQuery; // use last good known value
                            }
                        }
                        else
                        { // no biome data available
                            Available       = false;
                            lastAvailableId = "";
                            return(false);
                        }
                    }

                    try
                    {
                        var subject             = ResearchAndDevelopment.GetExperimentSubject(experiment, experimentSituation, vessel.mainBody, biome);
                        List <ScienceData> data = null;
                        float scienceTotal      = GetScienceTotal(subject, out data);

                        switch (settings.Filter)
                        {
                        case ProfileData.ExperimentSettings.FilterMethod.Unresearched:
                            // Fairly straightforward: total science + potential should be zero
                            Available = scienceTotal < 0.0005f;
                            break;

                        case ProfileData.ExperimentSettings.FilterMethod.NotMaxed:
                            // <98% of science cap
                            Available = scienceTotal < subject.scienceCap * 0.98f * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier;
                            break;

                        case ProfileData.ExperimentSettings.FilterMethod.LessThanFiftyPercent:
                            // important note for these last two filters: we can only accurately
                            // predict science for up to two of the same reports. After that,
                            // it'll be highly overestimated
                            Available = scienceTotal < subject.scienceCap * 0.5f * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier;
                            break;

                        case ProfileData.ExperimentSettings.FilterMethod.LessThanNinetyPercent:
                            Available = scienceTotal < subject.scienceCap * 0.9f * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier;
                            break;

                        default:     // this should NEVER occur, but nice to have a safety measure
                            // in place if I add a filter option and forget to add its logic
                            Log.Error("Unrecognized experiment filter!");
                            data = new List <ScienceData>();
                            break;
                        }

                        // bugfix: also ensure the experiment will generate >0 science, else
                        //         we could produce alerts for reports that won't generate any science
                        //nextReportValue = CalculateNextReportValue(subject, experimentSituation, data);
                        nextReportValue = subject.CalculateNextReport(experiment, data);
                        Available       = Available && nextReportValue > 0.01f;

                        // check the science threshold
                        Available = Available && nextReportValue > ScienceAlertProfileManager.ActiveProfile.ScienceThreshold;



                        if (Available)
                        {
                            if (lastAvailableId != subject.id)
                            {
                                lastStatus = false; // force a refresh, in case we're going from available -> available in different subject id
                                newReport  = true;  // we've available on a brand new report
                            }

                            lastAvailableId = subject.id;

                            if (Available != lastStatus && Available)
                            {
                                Log.Normal("Experiment {0} just became available! Total potential science onboard currently: {1} (Cap is {2}, threshold is {3}, current sci is {4}, expected next report value: {5})", lastAvailableId, scienceTotal, subject.scienceCap * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier, settings.Filter, subject.science, nextReportValue);

                                //Log.Debug("Transmission value: {0}", CalculateTransmissionValue(subject));

#if DEBUG
                                if (GetNextOnboardExperimentModule() != null)
                                {
                                    Log.Debug("Transmission value: {0}", API.AlertUtil.GetNextReportValue(subject, experiment, data, GetNextOnboardExperimentModule().xmitDataScalar));
                                }
#endif

                                if (data.Count() > 0)
                                {
                                    Log.Debug("Raw dataAmount = {0}, nextScience = {1}", data.First().dataAmount, ResearchAndDevelopment.GetScienceValue(data.First().dataAmount, subject) * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier);
                                    Log.Debug("Total science value = {0}", GetScienceTotal(subject, out data));
                                }
                            }
                        }
                    } catch (NullReferenceException e)
                    {
                        // note to self: even with all the logging I did when
                        // I could sometimes reproduce the exception, nothing
                        // looked wrong except that biome string becomes null

                        Log.Error("Failed to create {0} ScienceSubject. If you can manage to reproduce this error, let me know.", experiment.id);
                        Log.Error("Exception was: {0}", e);
                        Available = lastStatus;
                    }
                }
                else
                {
                    // experiment isn't available under this situation
#if DEBUG
                    //if (GetNextOnboardExperimentModule())
                    //Log.Verbose("{0} is onboard but not applicable in this situation {1} (vessel situation {2})", ExperimentTitle, experimentSituation, vessel.situation);
#endif
                    Available = false;
                }
            }
            else
            {
                Available = false;  // no experiments ready
            }
            return(Available != lastStatus && Available);
        }
コード例 #15
0
 ScienceSubject currentScienceSubject(ScienceExperiment experiment)
 {
     string fixBiome = string.Empty; // some biomes don't have 4th string, so we just put an empty in to compare strings later
     if (experiment.BiomeIsRelevantWhile(currentSituation())) fixBiome = currentBiome();// for those that do, we add it to the string
     return ResearchAndDevelopment.GetExperimentSubject(experiment, currentSituation(), currentBody(), fixBiome);//ikr!, we pretty much did all the work already, jeez
 }
コード例 #16
0
        /// <summary>
        /// Performs actions on experiments. Run/Transfer/Review/Reset
        /// </summary>
        /// <param name="moduleScienceExperiment"></param>
        /// <returns>false if nothing is left to do, true otherwise</returns>
        private bool RunExperiment(ModuleScienceExperiment moduleScienceExperiment)
        {
            Log.Write($"  {moduleScienceExperiment.part.partInfo.title}/{moduleScienceExperiment.experiment.experimentTitle}");
            Log.Write($"    rerunnable:{moduleScienceExperiment.rerunnable} resettable:{moduleScienceExperiment.resettable} deployed:{moduleScienceExperiment.Deployed} inpoerable:{moduleScienceExperiment.Inoperable}");

            //			// If the experiment is already deployed but not yet handled, don't try to re-run it
            //			if (moduleScienceExperiment.Deployed && !moduleScienceExperiment.Inoperable)
            //				return false;

            // Filter by mode
            if (!moduleScienceExperiment.rerunnable)
            {
                switch (mode)
                {
                case Modes.RerunnableOnly:
                    Log.Write($"    We haven't unlocked the mode to run this experiment yet");
                    return(false);

                case Modes.RerunnableAndResettableWithScientist:
                    if (currentVessel.GetVesselCrew().Find(x => x.trait == "Scientist") == null)
                    {
                        Log.Write($"    We either need to unlock the next mode or bring a scientist along with us for this");
                        return(false);
                    }
                    break;
                }
            }

            //ScienceExperiment scienceExperiment = moduleScienceExperiment.experiment;
            ScienceExperiment scienceExperiment = ResearchAndDevelopment.GetExperiment(moduleScienceExperiment.experimentID);             // lookup from R&D instead of pulling from ModuleScienceExperiment.experiment becuase DMagic is misbehaving.

//			Log.Write($"Using science experiment:{1}[{5}] with biomeMask: {2} situationMask: {3} baseValue: {4}", scienceExperiment.id, scienceExperiment.biomeMask, scienceExperiment.situationMask, scienceExperiment.baseValue, scienceExperiment.experimentTitle);

            // Review data?
            if (moduleScienceExperiment.Deployed && !moduleScienceExperiment.Inoperable)
            {
                if (KerbalismAPI.KerbalismInstalled)
                {
                    Log.Write($"    Kerbalism installed, attempting to send science data straight to hard drive");

                    // file or sample? (as per kerbalisms definition)
                    bool sample = moduleScienceExperiment.xmitDataScalar < 0.666f;
                    Log.Write($"      {moduleScienceExperiment.experimentID} is a {(sample ? "sample" : "file")}");

                    ScienceData[] data = moduleScienceExperiment.GetDataUsingReflection();
                    for (int i = 0; i < data.Count(); i++)
                    {
                        Log.Write($"      Storing {data[i].subjectID} in hard drive");
                        if (sample)
                        {
                            KerbalismAPI.StoreSample(currentVessel, data[i].subjectID, data[i].dataAmount);
                        }
                        else
                        {
                            KerbalismAPI.StoreFile(currentVessel, data[i].subjectID, data[i].dataAmount);
                        }

                        // get rid of the data in the experiment now
                        Log.Write($"      Dumping {data[i].subjectID} from experiment");
                        moduleScienceExperiment.DumpDataUsingReflection(data[i]);
                    }
                }
                else
                {
                    Log.Write($"      Attempting to review data to force collection...");
                    moduleScienceExperiment.ReviewDataUsingReflection();
                }
                return(true);
            }

            // Reset inoperable experiments
            if (moduleScienceExperiment.resettable && moduleScienceExperiment.Inoperable)
            {
                Log.Write($"    Resetting experiment");
//				Log.Write($"Science AI is cleaning {scienceExperiment.experimentTitle}", DebugFormat.Screen, true);
                moduleScienceExperiment.ResetExperimentUsingReflection();
                return(true);
            }

            // check if we can even run this experiment now
            if (!scienceExperiment.IsAvailableWhile(currentSituation, currentVessel.mainBody))
            {
                Log.Write($"    Cannot run in {currentSituation} on {currentVessel.mainBody}.");
                return(false);
            }

            string experimentSpecificBiome = string.Empty;

            if (scienceExperiment.BiomeIsRelevantWhile(currentSituation))
            {
                experimentSpecificBiome = currentBiome;
            }

            // check science value of experiment based on what is returned to KSC R&D and what is presently stored on the vessel (including science containers and kerbalism data drives)
            ScienceSubject     subject = ResearchAndDevelopment.GetExperimentSubject(scienceExperiment, currentSituation, currentVessel.mainBody, experimentSpecificBiome, null);
            List <ScienceData> storedData;
            int numberOfExperimentsOnBoard = GetNumberOfExperimentsOnBoard(subject, out storedData);

            // Check for duplicate experiments
            if (numberOfExperimentsOnBoard > 0)
            {
                Log.Write($"    We already have this experiment on board");
                return(false);
            }

            float scienceValue = GetScienceValue(scienceExperiment, subject, storedData);

            if (scienceValue < 0.01)
            {
                Log.Write($"    Science value is too low ({scienceValue} science). Not running.");
                return(false);
            }

            // run the experiment
            Log.Write($"    Running experiment {moduleScienceExperiment.part.partInfo.title}/{moduleScienceExperiment.experiment.experimentTitle} for {scienceValue} science in biome {currentSituation.ToString()} {currentBiome}.");
            moduleScienceExperiment.DeployExperimentUsingReflection();

//			Log.Write($"<color=#BBBB00><b>Science AI</b></color>\nRunning <b>{scienceExperiment.experimentTitle}</b>\n<i>Hold onto your knickers!</i>", DebugFormat.Screen, true);

            return(true);
        }
コード例 #17
0
    public void Update()
    {
        if (Input.GetMouseButtonUp(0))
        {
            resizingWindow = false;
        }
        if (resizingWindow)
        {
            windowPosition.width  = Input.mousePosition.x - windowPosition.x + 10;
            windowPosition.height = (Screen.height - Input.mousePosition.y) - windowPosition.y + 10;
        }
        // using "while" for possibility to "break". So we dont have to use GOTO. using timer to skip frames.
        while (drawWindow && (lateUpdateTimer < Time.time || lateUpdateTimerCounter > 3))
        {
            lateUpdateTimer = Time.time + 1;

            ExperimentSituations experimentSituation = ScienceUtil.GetExperimentSituation(FlightGlobals.ActiveVessel);
            CelestialBody        mainbody            = FlightGlobals.ActiveVessel.mainBody;
            string biome;
            if (FlightGlobals.ActiveVessel.landedAt != string.Empty)
            {
                biome = FlightGlobals.ActiveVessel.landedAt;
            }
            else
            {
                biome = ScienceUtil.GetExperimentBiome(FlightGlobals.ActiveVessel.mainBody, FlightGlobals.ActiveVessel.latitude, FlightGlobals.ActiveVessel.longitude);
            }

            if (mainbody == lastMainBody && biome == lastBiome && lastExperimentSituation == experimentSituation && lateUpdateTimerCounter <= 3)
            {
                lateUpdateTimer = 0;
                lateUpdateTimerCounter++;
                break;
            }
            lateUpdateTimerCounter = 0;
            lastBiome               = biome;
            lastMainBody            = mainbody;
            lastExperimentSituation = experimentSituation;

            Output.Clear();
            OnShip.Clear();


            //List<ScienceExperiment> PossibleExperiments = new List<ScienceExperiment>();

            //Search for all Science Experiment Modules on vessel, Check experiment available and add in "Output" and "OnShip"
            foreach (ModuleScienceExperiment moduleScienceExperiment in FlightGlobals.ActiveVessel.FindPartModulesImplementing <ModuleScienceExperiment>())
            {
                string            firstExperimentId = moduleScienceExperiment.experimentID;
                ScienceExperiment scienceExperiment = ResearchAndDevelopment.GetExperiment(firstExperimentId);
                bool available = scienceExperiment.IsAvailableWhile(experimentSituation, mainbody);
                if (available)
                {
                    if (moduleScienceExperiment.Deployed)
                    {
                        foreach (ScienceData scienceData in moduleScienceExperiment.GetData())
                        {
                            ExperimentView experimentView = new ExperimentView(scienceData);
                            if (!Output.Contains(experimentView))
                            {
                                Output.Add(experimentView);
                            }
                            OnShip.Add(experimentView);
                        }
                    }
                    {
                        ScienceSubject scienceSubject = LibraryUtils.GetExperimentSubject(scienceExperiment, experimentSituation, mainbody, scienceExperiment.BiomeIsRelevantWhile(experimentSituation) ? biome : "");
                        ExperimentView experimentView = new ExperimentView(scienceSubject);
                        if (!Output.Contains(experimentView))
                        {
                            Output.Add(experimentView);
                        }
                    }
                }
            }

            // Check for Kerbals on board. That means we can also use "evaReport", "surfaceSample", "asteroidSample" in EVA.
            if (FlightGlobals.ActiveVessel.GetCrewCount() > 0)
            {
                {
                    string            firstExperimentId = "evaReport";
                    ScienceExperiment scienceExperiment = ResearchAndDevelopment.GetExperiment(firstExperimentId);
                    bool available = scienceExperiment.IsAvailableWhile(experimentSituation, mainbody);
                    if (available)
                    {
                        ScienceSubject scienceSubject = LibraryUtils.GetExperimentSubject(scienceExperiment, experimentSituation, mainbody, scienceExperiment.BiomeIsRelevantWhile(experimentSituation) ? biome : "");
                        ExperimentView experimentView = new ExperimentView(scienceSubject);
                        if (!Output.Contains(experimentView))
                        {
                            Output.Add(experimentView);
                        }
                    }
                }
                {
                    string            firstExperimentId = "surfaceSample";
                    ScienceExperiment scienceExperiment = ResearchAndDevelopment.GetExperiment(firstExperimentId);
                    bool available = scienceExperiment.IsAvailableWhile(experimentSituation, mainbody);
                    if (available)
                    {
                        ScienceSubject scienceSubject = LibraryUtils.GetExperimentSubject(scienceExperiment, experimentSituation, mainbody, scienceExperiment.BiomeIsRelevantWhile(experimentSituation) ? biome : "");
                        ExperimentView experimentView = new ExperimentView(scienceSubject);
                        if (!Output.Contains(experimentView))
                        {
                            Output.Add(experimentView);
                        }
                    }
                }

                // Find asteroid that could be used for science. (I hope it will not be too many asteroids, because of linear complexity of this code)
                ModuleAsteroid[] asteroids = FindObjectsOfType <ModuleAsteroid>();
                foreach (ModuleAsteroid asteroid in asteroids)
                {
                    Vector3 destination3   = asteroid.gameObject.transform.position - FlightGlobals.ActiveVessel.gameObject.transform.position;
                    float   unfocusedRange = asteroid.Events["TakeSampleEVAEvent"].unfocusedRange;
                    unfocusedRange *= unfocusedRange;
                    if (destination3.sqrMagnitude < unfocusedRange)
                    {
                        string            firstExperimentId = "asteroidSample";
                        ScienceExperiment scienceExperiment = ResearchAndDevelopment.GetExperiment(firstExperimentId);
                        bool available = scienceExperiment.IsAvailableWhile(experimentSituation, mainbody);
                        if (available)
                        {
                            string         asteroidname   = asteroid.part.partInfo.name + asteroid.part.flightID;
                            ScienceSubject scienceSubject = LibraryUtils.GetExperimentSubject(scienceExperiment, experimentSituation, asteroidname, "", mainbody, scienceExperiment.BiomeIsRelevantWhile(experimentSituation) ? biome : "");
                            ExperimentView experimentView = new ExperimentView(scienceSubject);
                            if (!Output.Contains(experimentView))
                            {
                                Output.Add(experimentView);
                            }
                        }
                    }
                }
            }
            //Search for all Science Containers on vessel and write all found experiments into OnShip list
            foreach (ModuleScienceContainer moduleScienceContainer in FlightGlobals.ActiveVessel.FindPartModulesImplementing <ModuleScienceContainer>())
            {
                foreach (ScienceData scienceData in moduleScienceContainer.GetData())
                {
                    ExperimentView experimentView = new ExperimentView(scienceData);
                    //if (!Output.Contains(experimentView))
                    Output.Add(experimentView);
                    OnShip.Add(experimentView);
                }
            }

            Output.Sort();
            break;
        }
    }
コード例 #18
0
    public void GetSciData()
    {
        if (ResearchAndDevelopment.Instance == null)
        {
            return;
        }
        dataOutputList = new List <Experiment>();
        List <ScienceSubject> newExperiments = new List <ScienceSubject>();
        List <string>         exIds          = ResearchAndDevelopment.GetExperimentIDs();
        List <ScienceSubject> subjectslist   = ResearchAndDevelopment.GetSubjects();

        //I am glad this code runs only once! Too expensive!
        foreach (string id in exIds)
        {
            foreach (ExperimentSituations experimentSituation in Enum.GetValues(typeof(ExperimentSituations)))
            {
                foreach (CelestialBody body in FlightGlobals.Bodies)
                {
                    bool ocean = body.ocean;
                    if (ExperimentSituations.SrfSplashed == experimentSituation && !ocean)
                    {
                        continue;
                    }
                    if ((ExperimentSituations.FlyingHigh == experimentSituation || ExperimentSituations.FlyingLow == experimentSituation) && !body.atmosphere)
                    {
                        continue;
                    }
                    ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(id);
                    bool available = experiment.IsAvailableWhile(experimentSituation, body);
                    if (available)
                    {
                        bool shouldHaveBiome = experiment.BiomeIsRelevantWhile(experimentSituation);
                        if (shouldHaveBiome)
                        {
                            foreach (string biome in ResearchAndDevelopment.GetBiomeTags(body))
                            {
                                if (KSPScienceSettings.getBoolSetting("ShowOnlyKnownBiomes"))
                                {
                                    bool foundBiome = subjectslist.Any(subject => subject.id.Contains("@" + body.name) && subject.id.Contains(biome.Replace(" ", "")));
                                    if (!foundBiome)
                                    {
                                        continue;
                                    }
                                }
                                ScienceSubject ssj = new ScienceSubject(experiment, experimentSituation, body, biome);
                                if (id == "asteroidSample")
                                {
                                    ssj.scienceCap = experiment.scienceCap;
                                }
                                newExperiments.Add(ssj);
                            }
                            if (body.BiomeMap == null || body.BiomeMap.Attributes.Length == 0)
                            {
                                ScienceSubject ssj = new ScienceSubject(experiment, experimentSituation, body, "");
                                if (id == "asteroidSample")
                                {
                                    ssj.scienceCap = experiment.scienceCap;
                                }
                                newExperiments.Add(ssj);
                            }
                        }
                        else
                        {
                            ScienceSubject ssj = new ScienceSubject(experiment, experimentSituation, body, "");
                            if (id == "asteroidSample")
                            {
                                ssj.scienceCap = experiment.scienceCap;
                            }
                            newExperiments.Add(ssj);
                        }
                    }
                }
            }
        }


        foreach (ScienceSubject scienceSubject in subjectslist)
        {
            newExperiments.RemoveAll(subject => subject.id == scienceSubject.id);
            string     title      = scienceSubject.id;
            double     earned     = Math.Round(scienceSubject.science, 1);
            double     remain     = Math.Round(scienceSubject.scienceCap - scienceSubject.science, 1);
            string     body       = LibraryUtils.FindExperimentBody(scienceSubject.id.Split('@')[1]);
            string     type       = scienceSubject.id.Split('@')[0];
            Experiment experiment = new Experiment(title, earned, remain, body, type);
            dataOutputList.Add(experiment);
        }

        foreach (ScienceSubject newExperiment in newExperiments)
        {
            newExperiment.scientificValue = 1f;
            CelestialBody thisBody = FlightGlobals.Bodies.Find(celestialBody => newExperiment.id.Split('@')[1].StartsWith(celestialBody.name));
            Experiment    ex       = new Experiment(newExperiment.id, 0, Math.Round(newExperiment.scienceCap, 1), thisBody.name, newExperiment.id.Split('@')[0]);
            dataOutputList.Add(ex);
        }
        dataOutputList.Sort(SortByName);

        if (KSPScienceSettings.getBoolSetting("ShowOnlyKnownExperiments"))
        {
            allExperimentTypes = GetKnownExperimentTypes();
        }
        else
        {
            allExperimentTypes = GetAllExperimentTypes();
        }
    }
コード例 #19
0
ファイル: Science.cs プロジェクト: lordcirth/Kerbalism-1
        // create a new subject entry in the RnD
        // - experiment: experiment_id
        // - situation: an arbitrary situation, can insert biome at the end
        // - body: celestial body involved
        // - biome: biome involved, or empty
        // - multiplier: science multiplier for the body/situation
        public static string Generate_subject(ScienceExperiment experiment, CelestialBody body, ExperimentSituations sit, string biome)
        {
            // generate subject id
            string subject_id = Lib.BuildString(experiment.id, "@", body.name, sit + (experiment.BiomeIsRelevantWhile(sit) ? biome : ""));

            // in sandbox, do nothing else
            if (ResearchAndDevelopment.Instance == null)
            {
                return(subject_id);
            }

            // if the subject id was never added to RnD
            if (ResearchAndDevelopment.GetSubjectByID(subject_id) == null)
            {
                // get subjects container using reflection
                // - we tried just changing the subject.id instead, and
                //   it worked but the new id was obviously used only after
                //   putting RnD through a serialization->deserialization cycle
                var subjects = Lib.ReflectionValue <Dictionary <string, ScienceSubject> >
                               (
                    ResearchAndDevelopment.Instance,
                    "scienceSubjects"
                               );

                float multiplier = Multiplier(body, sit);
                var   cap        = multiplier * experiment.baseValue;

                // create new subject
                ScienceSubject subject = new ScienceSubject
                                         (
                    subject_id,
                    Lib.BuildString(experiment.experimentTitle, " (", Lib.SpacesOnCaps(sit + biome), ")"),
                    experiment.dataScale,
                    multiplier,
                    cap
                                         );

                // add it to RnD
                subjects.Add(subject_id, subject);
            }

            return(subject_id);
        }