コード例 #1
0
ファイル: ForScience.cs プロジェクト: MMaster/ForScience
        void RunScience()                    // this is primary business logic for finding and running valid experiments
        {
            if (GetExperimentList() == null) // hey, it can happen!
            {
                Debug.Log("[ForScience!] There are no experiments.");
            }
            else
            {
                foreach (ModuleScienceExperiment currentExperiment in GetExperimentList()) // loop through all the experiments onboard
                {
                    ScienceExperiment se = ResearchAndDevelopment.GetExperiment(currentExperiment.experimentID);
                    Debug.Log("[ForScience!] Checking experiment id: " + se.id + " title: " + se.experimentTitle + " unlocked: " + se.IsUnlocked()
                              + " isAvail: " + se.IsAvailableWhile(currentSituation(), currentBody()));

                    ScienceSubject ss = currentScienceSubject(se);
                    //Debug.Log("ScienceSubject experiment id: " + ss.id + " title: " + ss.title);

                    ModuleScienceExperiment me = currentExperiment;

                    /*Debug.Log("Module Experiment id: " + me.experimentID + " cooldown: " + me.cooldownToGo
                     + " collectable: " + me.dataIsCollectable + " deployed: " + me.Deployed + " enabled: " + me.isEnabled
                     + " rerunnable: " + me.IsRerunnable() + " module: " + me.moduleName + " objname: " + me.name
                     + " resettable: " + me.resettable + " resOnEVA: " + me.resettableOnEVA);*/

                    if (ActiveContainer().HasData(newScienceData(currentExperiment))) // skip data we already have onboard
                    {
                        Debug.Log("[ForScience!] Skipping: We already have that data onboard.");
                    }
                    else if (!surfaceSamplesUnlocked() && se.id == "surfaceSample") // check to see is surface samples are unlocked
                    {
                        Debug.Log("[ForScience!] Skipping: Surface Samples are not unlocked.");
                    }
                    else if (!me.IsRerunnable() && (!(me.resettable || me.resettableOnEVA) || !IsScientistOnBoard()))   // no cheating goo and materials here
                    {
                        Debug.Log("[ForScience!] Skipping: Experiment is not repeatable (and/or resettable).");
                    }
                    else if (!se.IsAvailableWhile(currentSituation(), currentBody())) // this experiement isn't available here so we skip it
                    {
                        Debug.Log("[ForScience!] Skipping: Experiment is not available for this situation/atmosphere.");
                    }
                    else if (me.useCooldown && me.cooldownToGo > 0)
                    {
                        Debug.Log("[ForScience!] Skipping: Experiment on cooldown for " + me.cooldownToGo + " seconds.");
                    }
                    else if (currentScienceValue(currentExperiment) < 0.1) // this experiment has no more value so we skip it
                    {
                        Debug.Log("[ForScience!] Skipping: No more science is available.");
                    }
                    else
                    {
                        Debug.Log("[ForScience!] Running experiment: " + ss.id);
                        ActiveContainer().AddData(newScienceData(currentExperiment)); //manually add data to avoid deployexperiment state issues
                    }
                }
            }
        }
コード例 #2
0
        public void doScience(CelestialBody planet)
        {
            Utilities.Log_Debug("Doing Science for {0}", planet.theName);
            ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(ExperimentID);

            Utilities.Log_Debug("Got experiment");
            string biome = "";

            biome = part.vessel.landedAt != string.Empty ? part.vessel.landedAt : ScienceUtil.GetExperimentBiome(planet, FlightGlobals.ship_latitude, FlightGlobals.ship_longitude);
            ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(experiment, ScienceUtil.GetExperimentSituation(vessel), planet, biome);

            Utilities.Log_Debug("Got subject");
            if (experiment.IsAvailableWhile(ScienceUtil.GetExperimentSituation(vessel), planet))
            {
                ScienceData data = new ScienceData(experiment.baseValue * subject.dataScale, xmitDataScalar, labBoostScalar, subject.id, subject.title, false, part.flightID);
                Utilities.Log_Debug("Got data");
                _scienceData.Add(data);
                Utilities.Log_Debug("Added Data");
                ScreenMessages.PostScreenMessage("Collected Science for " + planet.theName, 3f, ScreenMessageStyle.UPPER_CENTER);
                if (TSTProgressTracker.isActive)
                {
                    TSTProgressTracker.OnChemCamFire(planet, biome);
                }
            }
            updateAvailableEvents();
        }
コード例 #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 bool ExperimentAvailable(ScienceExperiment exp, ExperimentSituations sit, CelestialBody body)
        {
            if (!ExperimentAvailable(exp, body))
            {
                return(false);
            }

            if (!exp.IsAvailableWhile(sit, body))
            {
                return(false);
            }

            // Get the experiment rules
            ExperimentRules rules = GetExperimentRules(exp.id);

            // Check if surface samples have been unlocked
            if (rules.requireSurfaceSample)
            {
                if (ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.ResearchAndDevelopment) < 0.3f)
                {
                    return(false);
                }
            }

            // Check for EVA unlock
            if (rules.requireEVA)
            {
                if (!body.isHomeWorld || (sit != ExperimentSituations.SrfLanded && sit != ExperimentSituations.SrfSplashed))
                {
                    bool evaUnlocked = GameVariables.Instance.UnlockedEVA(ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.AstronautComplex));
                    if (!evaUnlocked)
                    {
                        return(false);
                    }
                }
            }

            if (rules.disallowHomeSurface)
            {
                if (body.isHomeWorld && sit == ExperimentSituations.SrfLanded || sit == ExperimentSituations.SrfSplashed)
                {
                    return(false);
                }
            }

            if (rules.disallowHomeFlying)
            {
                if (body.isHomeWorld && sit == ExperimentSituations.FlyingLow || sit == ExperimentSituations.FlyingHigh)
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #6
0
        private static bool ExperimentAvailable(ScienceExperiment exp, CelestialBody body)
        {
            if (exp == null || body == null)
            {
                return(false);
            }

            // Get the experiment rules
            ExperimentRules rules = GetExperimentRules(exp.id);

            if (rules.ignored)
            {
                return(false);
            }

            if (rules.requireAtmosphere && !body.atmosphere)
            {
                return(false);
            }

            if (rules.requireNoAtmosphere && body.atmosphere)
            {
                return(false);
            }

            if (rules.requireSurface && body.pqsController == null)
            {
                return(false);
            }

            if (rules.requireNoSurface && body.pqsController != null)
            {
                return(false);
            }

            if (rules.validBodies != null)
            {
                if (!rules.validBodies.Contains(body))
                {
                    return(false);
                }
            }

            // Filter out asteroid samples if not unlocked
            if (rules.requireAsteroidTracking)
            {
                if (!GameVariables.Instance.UnlockedSpaceObjectDiscovery(ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.TrackingStation)))
                {
                    return(false);
                }
            }

            return(allSituations.Any(sit => exp.IsAvailableWhile(sit, body)));
        }
コード例 #7
0
        static bool Prefix(ModuleComet __instance, ref ScienceExperiment ___experiment)
        {
            // Patch only if science is enabled
            if (!Features.Science)
            {
                return(true);
            }

            // stock ModuleAsteroid.performSampleExperiment code : get situation and check availablility
            ExperimentSituations experimentSituation = ScienceUtil.GetExperimentSituation(__instance.vessel);
            string message = string.Empty;

            if (!ScienceUtil.RequiredUsageExternalAvailable(__instance.vessel, FlightGlobals.ActiveVessel, (ExperimentUsageReqs)__instance.experimentUsageMask, ___experiment, ref message))
            {
                ScreenMessages.PostScreenMessage("<b><color=orange>" + message + "</color></b>", 6f, ScreenMessageStyle.UPPER_LEFT);
                return(false);
            }

            if (!___experiment.IsAvailableWhile(experimentSituation, __instance.vessel.mainBody))
            {
                ScreenMessages.PostScreenMessage(Localizer.Format("#autoLOC_230133", ___experiment.experimentTitle), 5f, ScreenMessageStyle.UPPER_CENTER);
                return(false);
            }

            // stock ModuleAsteroid.performSampleExperiment code : create subject
            ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(___experiment, experimentSituation, __instance.part.partInfo.name + __instance.part.flightID, __instance.part.partInfo.title, __instance.vessel.mainBody, string.Empty, string.Empty);

            // put the data on the EVA kerbal drive.
            if (FlightGlobals.ActiveVessel == null)
            {
                return(false);
            }
            double size  = ___experiment.baseValue * ___experiment.dataScale;
            Drive  drive = Drive.SampleDrive(FlightGlobals.ActiveVessel.KerbalismData(), size);

            if (drive != null)
            {
                double      mass        = size * Settings.AsteroidSampleMassPerMB;
                SubjectData subjectData = ScienceDB.GetSubjectDataFromStockId(subject.id, null, __instance.part.partInfo.title);
                drive.Record_sample(subjectData, size, mass, true);
                Message.Post(Lib.BuildString("<b><color=ffffff>", subject.title, "</color></b>\n", (mass * 1000.0).ToString("F1"), "<b><i> Kg of sample stored</i></b>"));
            }
            else
            {
                Message.Post("Not enough sample storage available");
            }

            // don't call TakeSampleEVAEvent() (this will also prevent the call to ModuleAsteroid.performSampleExperiment)
            return(false);
        }
コード例 #8
0
        public void doScience(CelestialBody planet)
        {
            Utilities.Log_Debug("Doing Science for {0}", planet.name);
            ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(ExperimentID);

            Utilities.Log_Debug("Got experiment");
            ExperimentSituations situation = ScienceUtil.GetExperimentSituation(vessel);

            if (experiment.IsAvailableWhile(ScienceUtil.GetExperimentSituation(vessel), planet))
            {
                string biomeID        = "";
                string displaybiomeID = string.Empty;
                if (part.vessel.landedAt != string.Empty)
                {
                    biomeID        = Vessel.GetLandedAtString(part.vessel.landedAt);
                    displaybiomeID = Localizer.Format(part.vessel.displaylandedAt);
                }
                else
                {
                    biomeID        = ScienceUtil.GetExperimentBiome(planet, FlightGlobals.ship_latitude, FlightGlobals.ship_longitude);
                    displaybiomeID = ScienceUtil.GetBiomedisplayName(vessel.mainBody, biomeID);
                }
                ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(experiment, situation, planet, biomeID, displaybiomeID);
                Utilities.Log_Debug("Got subject");
                ScienceData data = new ScienceData(experiment.baseValue * subject.dataScale, xmitDataScalar, labBoostScalar, subject.id, subject.title, false, part.flightID);
                Utilities.Log_Debug("Got data");
                _scienceData.Add(data);
                Utilities.Log_Debug("Added Data");
                ScreenMessages.PostScreenMessage(Localizer.Format("#autoLOC_238419", part.partInfo.title, data.dataAmount.ToString(), subject.title), 8f, ScreenMessageStyle.UPPER_LEFT);
                ReviewDataItem(data);
                if (TSTProgressTracker.isActive)
                {
                    TSTProgressTracker.OnChemCamFire(planet, biomeID);
                }
            }
            else
            {
                ScreenMessages.PostScreenMessage(Localizer.Format("#autoLOC_238424", experiment.experimentTitle), 5f, ScreenMessageStyle.UPPER_CENTER);
            }
            updateAvailableEvents();
        }
コード例 #9
0
        /// <summary>
        /// True if all required resources are present
        /// </summary>
        public bool ReadyToDeploy(bool displayMessage = true)
        {
            for (int i = 0; i < requirementNames.Count; i++)
            {
                //float result = part.RequestResource(requirementNames[i], requirementAmounts[i]);
                double result = GetResourceAmount(requirementNames[i]);

                if (result < requirementAmounts[i] - 0.001)
                {
                    if (displayMessage)
                    {
                        ShoutToScreen("Experiment not finished yet!");
                    }

                    currentStatus = Status.Running;

                    return(false);
                }
            }

            ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(experimentID);

            if (!experiment.IsAvailableWhile(GetScienceSituation(vessel), vessel.mainBody))
            {
                if (displayMessage)
                {
                    ShoutToScreen("Can't perform experiment here.");
                }

                currentStatus = Status.BadLocation;

                return(false);
            }

            currentStatus = Status.Completed;

            return(true);
        }
コード例 #10
0
        private static bool ExperimentAvailable(ScienceExperiment exp, ExperimentSituations sit, CelestialBody body)
        {
            if (!ExperimentAvailable(exp, body))
            {
                return false;
            }

            if (!exp.IsAvailableWhile(sit, body))
            {
                return false;
            }

            // Get the experiment rules
            ExperimentRules rules = GetExperimentRules(exp.id);

            // Check if surface samples have been unlocked
            if (rules.requireSurfaceSample)
            {
                if (ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.ResearchAndDevelopment) < 0.3f)
                {
                    return false;
                }
            }

            // Check for EVA unlock
            if (rules.requireEVA)
            {
                if (!body.isHomeWorld || (sit != ExperimentSituations.SrfLanded && sit != ExperimentSituations.SrfSplashed))
                {
                    bool evaUnlocked = GameVariables.Instance.UnlockedEVA(ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.AstronautComplex));
                    if (!evaUnlocked)
                    {
                        return false;
                    }
                }
            }

            if (rules.disallowHomeSurface)
            {
                if (body.isHomeWorld && sit == ExperimentSituations.SrfLanded || sit == ExperimentSituations.SrfSplashed)
                {
                    return false;
                }
            }

            if (rules.disallowHomeFlying)
            {
                if (body.isHomeWorld && sit == ExperimentSituations.FlyingLow || sit == ExperimentSituations.FlyingHigh)
                {
                    return false;
                }
            }

            return true;
        }
コード例 #11
0
        private static bool ExperimentAvailable(ScienceExperiment exp, CelestialBody body)
        {
            if (exp == null || body == null)
            {
                return false;
            }

            // Get the experiment rules
            ExperimentRules rules = GetExperimentRules(exp.id);

            if (rules.ignored)
            {
                return false;
            }

            if (rules.requireAtmosphere && !body.atmosphere)
            {
                return false;
            }

            if (rules.requireNoAtmosphere && body.atmosphere)
            {
                return false;
            }

            if (rules.requireSurface && body.pqsController == null)
            {
                return false;
            }

            if (rules.requireNoSurface && body.pqsController != null)
            {
                return false;
            }

            if (rules.validBodies != null)
            {
                if (!rules.validBodies.Contains(body))
                {
                    return false;
                }
            }

            // Filter out asteroid samples if not unlocked
            if (rules.requireAsteroidTracking)
            {
                if (!GameVariables.Instance.UnlockedSpaceObjectDiscovery(ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.TrackingStation)))
                {
                    return false;
                }
            }

            return allSituations.Any(sit => exp.IsAvailableWhile(sit, body));
        }
コード例 #12
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);
        }
コード例 #13
0
        private static bool ExperimentAvailable(ScienceExperiment exp, CelestialBody body)
        {
            if (exp == null || body == null)
            {
                return(false);
            }

            // Check if experiement is unlocked
            if (!exp.IsUnlocked())
            {
                return(false);
            }

            // Special Breaking Ground logic
            if (exp.id.StartsWith("ROCScience"))
            {
                if (!exp.id.Contains(body.name))
                {
                    return(false);
                }
            }

            // Get the experiment rules
            ExperimentRules rules = GetExperimentRules(exp.id);

            if (rules.ignored)
            {
                return(false);
            }

            if ((rules.requireAtmosphere || exp.requireAtmosphere) && !body.atmosphere)
            {
                return(false);
            }

            if ((rules.requireNoAtmosphere || exp.requireNoAtmosphere) && body.atmosphere)
            {
                return(false);
            }

            if (rules.requireSurface && body.pqsController == null)
            {
                return(false);
            }

            if (rules.requireNoSurface && body.pqsController != null)
            {
                return(false);
            }

            if (rules.sunOnly)
            {
                return(body == FlightGlobals.Bodies[0]);
            }

            // Filter out asteroid samples if not unlocked
            if (rules.requireAsteroidTracking)
            {
                if (!GameVariables.Instance.UnlockedSpaceObjectDiscovery(ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.TrackingStation)))
                {
                    return(false);
                }
            }

            return(allSituations.Any(sit => exp.IsAvailableWhile(sit, body)));
        }
コード例 #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
ファイル: Experiment.cs プロジェクト: lordcirth/Kerbalism-1
        private static string TestForIssues(Vessel v, ScienceExperiment exp, Resource_info ec, Experiment experiment, bool broken,
                                            double remainingSampleMass, bool didPrepare, bool isShrouded, string last_subject_id, out string subject_id)
        {
            var sit   = ScienceUtil.GetExperimentSituation(v);
            var biome = ScienceUtil.GetExperimentBiome(v.mainBody, v.latitude, v.longitude);

            subject_id = Science.Generate_subject(exp, v.mainBody, sit, biome);

            if (broken)
            {
                return("broken");
            }

            if (isShrouded && !experiment.allow_shrouded)
            {
                return("shrouded");
            }

            bool needsReset = experiment.crew_reset.Length > 0 &&
                              !string.IsNullOrEmpty(last_subject_id) && subject_id != last_subject_id;

            if (needsReset)
            {
                return("reset required");
            }

            if (ec.amount < double.Epsilon && experiment.ec_rate > double.Epsilon)
            {
                return("no <b>Electricity</b>");
            }

            if (!string.IsNullOrEmpty(experiment.crew_operate))
            {
                var cs = new CrewSpecs(experiment.crew_operate);
                if (!cs.Check(v))
                {
                    return(cs.Warning());
                }
            }

            if (!experiment.sample_collecting && remainingSampleMass < double.Epsilon && experiment.sample_mass > double.Epsilon)
            {
                return("depleted");
            }

            string situationIssue = Science.TestRequirements(experiment.requires, v);

            if (situationIssue.Length > 0)
            {
                return(Science.RequirementText(situationIssue));
            }

            if (!exp.IsAvailableWhile(sit, v.mainBody))
            {
                return("invalid situation");
            }

            if (!didPrepare && !string.IsNullOrEmpty(experiment.crew_prepare))
            {
                return("not prepared");
            }

            var    drive     = DB.Vessel(v).BestDrive();
            double available = experiment.sample_mass < float.Epsilon ? drive.FileCapacityAvailable() : drive.SampleCapacityAvailable();

            if (experiment.data_rate * Kerbalism.elapsed_s > available)
            {
                return("insufficient storage");
            }

            return(string.Empty);
        }
コード例 #16
0
        internal void DoScience(string expId)
        {
            string step = "Start";

            string reqResource = experiments[expId].neededResourceName;
            float  reqAmount   = 1;

            try
            {
                string msg = string.Empty;
                //Vessel ves = FlightGlobals.ActiveVessel;
                Part prt = FlightGlobals.ActiveVessel.rootPart;
                ModuleScienceExperiment exp = new ModuleScienceExperiment();
                if (experiments[expId].xmitDataScalar > 0)
                {
                    exp.xmitDataScalar = experiments[expId].xmitDataScalar;
                }
                Log.Info("DoScience, expId: " + expId + ", xmitDataScalar: " + exp.xmitDataScalar);

                // Checks
                step = "Check Boring";
                if (Utils.CheckBoring(vessel, true))
                {
                    return;
                }

                step = "Check CanRun";
                if (!Utils.CanRunExperiment(vessel, expId, ref msg))
                {
                    Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_LTech_Experiment_002", msg));
                    return;
                }

#if false
                step = "Check Insight";
                if (Utils.ResourceAvailable(prt, "Insight") < reqInsight)
                {
                    double current = Utils.ResourceAvailable(prt, "Insight");
                    double needed  = reqInsight - current;

                    Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_LTech_Experiment_003", (int)needed));
                    return;
                }
#endif

                step = "Check Resource";
                if (Utils.ResourceAvailable(prt, reqResource) < reqAmount)
                {
                    double current = Utils.ResourceAvailable(prt, reqResource);
                    double needed  = reqAmount - current;

                    Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_LTech_Experiment_004", (int)needed, reqResource));
                    return;
                }

                // Experiment
                step             = "Get Experiment";
                exp.experimentID = expId;
                ScienceExperiment labExp = ResearchAndDevelopment.GetExperiment(exp.experimentID);
                if (labExp == null)
                {
                    Log.Warning(Localizer.Format("#autoLOC_LTech_Experiment_005", exp.experimentID));
                    Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_LTech_Experiment_006"));
                    return;
                }

                step = "Get Situation";
                ExperimentSituations vesselSit = ScienceUtil.GetExperimentSituation(vessel);
                if (labExp.IsAvailableWhile(vesselSit, vessel.mainBody))
                {
                    step = "Get Biome";
                    string biome, displayBiome;
                    if (vessel.landedAt != string.Empty)
                    {
                        biome        = Vessel.GetLandedAtString(vessel.landedAt);
                        displayBiome = Localizer.Format(vessel.displaylandedAt);
                    }
                    else
                    {
                        biome        = ScienceUtil.GetExperimentBiome(vessel.mainBody, vessel.latitude, vessel.longitude);
                        displayBiome = ScienceUtil.GetBiomedisplayName(vessel.mainBody, biome);
                    }

                    Log.Info("DoScience, expId: " + expId +
                             "body: " + vessel.mainBody.bodyName +
                             ", ScienceUtil.GetExperimentSituation: " + ScienceUtil.GetExperimentSituation(vessel) +
                             ", biome: " + biome);

                    SetUpActiveExperiment(expId, biome, exp, reqResource);
#if false
                    activeExperiment = new ActiveExperiment(expId, vessel.mainBody.bodyName, ScienceUtil.GetExperimentSituation(vessel), biome, exp);

                    // need to add to
                    //                   internal ExperimentSituations vesselSit;
                    //                    internal string biome;
                    ExpStatus es = new ExpStatus(expId, activeExperiment.Key, vessel.mainBody.bodyName, ScienceUtil.GetExperimentSituation(vessel), biome,
                                                 reqResource, experiments[expId].resourceAmtRequired);
                    es.active = true;
                    expStatuses.Add(es.Key, es);
                    experimentStarted = true;
                    StartCoroutine(FixedUpdate2());
#endif
                }
                else
                {
                    Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_238424", labExp.experimentTitle));
                    Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_LTech_Experiment_007", vesselSit.displayDescription()));
                }

                step = "End";
            }
            catch (Exception ex)
            {
                Log.Error($"SkylabExperiment.DoScience at step \"{step}\";. Error: {ex}");
            }
        }
コード例 #17
0
        public System.Collections.IEnumerator UpdateStatus()
        {
            while (true)
            {
                Log.Info(part.partInfo.title + "updateStatus");
                double numEurekas     = GetResourceAmount(EUREKAS);
                double numEurekasMax  = GetResourceMaxAmount(EUREKAS);
                double numKuarqs      = GetResourceAmount(KUARQS);
                double numKuarqsMax   = GetResourceMaxAmount(KUARQS);
                double numBioproducts = GetResourceAmount(BIOPRODUCTS);
                int    sciCount       = GetScienceCount();
                Log.Info(part.partInfo.title + " finished: " + Finished());
                if (!Finished())
                {
                    Events["DeployExperiment"].active = false;
                    Events["StartExperiment"].active  = (!Inoperable && sciCount == 0 && numEurekasMax == 0 && numKuarqsMax == 0);
                }
                else
                {
                    Events["DeployExperiment"].active = true;
                    Events["StartExperiment"].active  = false;
                }
                var    subject   = ScienceHelper.getScienceSubject(experimentID, vessel);
                string subjectId = ((subject == null) ? "" : subject.id);
                if (subjectId != "" && last_subjectId != "" && last_subjectId != subjectId &&
                    (numEurekas > 0 || numKuarqs > 0 || (numBioproducts > 0 && sciCount == 0)))
                {
                    ScreenMessages.PostScreenMessage(Localizer.Format("#autoLOC_StatSci_screen_locchange", part.partInfo.title), 6, ScreenMessageStyle.UPPER_CENTER);
                    StopResearch();
                    StopResearch(BIOPRODUCTS);
                }
                last_subjectId = subjectId;
                if (sciCount > 0)
                {
                    StopResearch();
                    if (completed == 0)
                    {
                        completed = (float)Planetarium.GetUniversalTime();
                    }
                }
                if (numEurekas > 0)
                {
                    var eurekasModules = vessel.FindPartModulesImplementing <StationScienceModule>();
                    if (eurekasModules == null || eurekasModules.Count() < 1)
                    {
                        ScreenMessages.PostScreenMessage(Localizer.Format("#autoLOC_StatSci_screen_detatch", part.partInfo.title), 2, ScreenMessageStyle.UPPER_CENTER);
                    }
                }

                /*
                 * if (numKuarqs > 0)
                 * {
                 *  var kuarqModules = vessel.FindPartModulesImplementing<KuarqGenerator>();
                 *  if (kuarqModules == null || kuarqModules.Count() < 1)
                 *  {
                 *      stopResearch(KUARQS);
                 *  }
                 * }
                 */
                if (numBioproducts > 0 && Inoperable)
                {
                    StopResearch(BIOPRODUCTS);
                }
                if (requirements.ContainsKey(BIOPRODUCTS) && GetScienceCount() > 0 && numBioproducts < requirements[BIOPRODUCTS].amount)
                //if (bioproductsRequired > 0 && GetScienceCount() > 0 && numBioproducts < bioproductsRequired)
                {
                    ResetExperiment();
                }
#if false
                // make sure we keep updating while changes are possible
                if (currentStatus == Status.Running ||
                    currentStatus == Status.Completed ||
                    currentStatus == Status.BadLocation)
                {
                    ReadyToDeploy(false);
                }
#endif
                ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(experimentID);
                if (currentStatus == Status.Running && !experiment.IsAvailableWhile(GetScienceSituation(vessel), vessel.mainBody))
                {
                    ScreenMessages.PostScreenMessage(Localizer.Format("Can't perform experiment here."), 6, ScreenMessageStyle.UPPER_CENTER);
                    currentStatus = Status.BadLocation;
                }


                yield return(new UnityEngine.WaitForSeconds(1f));
            }
        }
コード例 #18
0
        private bool canRunExperiment(ModuleScienceExperiment currentExperiment, ScienceExperiment experiment, float currentScienceValue, bool DMagic = false)
        {
            if (!DMagic)
              {
            if (!experiment.IsAvailableWhile(currentSituation, currentBody))//
            {
              //experiment.mask
              Utilities.debug(modName, Utilities.LogMode.Debug, currentExperiment.experimentID + ": Experiment isn't available in the current situation: " + currentSituation + "_" + currentBody + "_" + experiment.situationMask);
              return false;
            }
            if (currentExperiment.Inoperable)//
            {
              Utilities.debug(modName, Utilities.LogMode.Debug, currentExperiment.experimentID + ": Experiment is inoperable");
              return false;
            }
            if (currentExperiment.Deployed)//
            {
              Utilities.debug(modName, Utilities.LogMode.Debug, currentExperiment.experimentID + ": Experiment is deployed");
              return false;
            }
              }
              if (!currentExperiment.rerunnable && !currentSettings.getBool("runOneTimeScience"))
              {
            Utilities.debug(modName, Utilities.LogMode.Debug, currentExperiment.experimentID + ": Runing rerunable experiments is disabled");
            return false;
              }
              if (currentScienceValue < currentSettings.getFloat("scienceCutoff"))
              {
            Utilities.debug(modName, Utilities.LogMode.Debug, currentExperiment.experimentID + ": Science value is less than cutoff threshold: " + currentScienceValue + "<" + currentSettings.getFloat("scienceCutoff"));
            return false;
              }
              if (!experiment.IsUnlocked())
              {
            Utilities.debug(modName, Utilities.LogMode.Debug, currentExperiment.experimentID + ": Experiment is locked");
            return false;
              }

              var ModuleAnimateGeneric = currentExperiment.part.FindModuleImplementing<ModuleAnimateGeneric>();
              if (ModuleAnimateGeneric != null)
              {
            if (ModuleAnimateGeneric.status != "Locked")
            {
              Utilities.debug(modName, Utilities.LogMode.Debug, "Animation status isn't locked:" + ModuleAnimateGeneric.status + "_" + currentExperiment.part.name);
              return false;
            }
              }
              return true;
        }
コード例 #19
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;
        }
    }
コード例 #20
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);
        }
コード例 #21
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();
        }
    }
コード例 #22
0
 public static bool IsAvailableWhileFixed(this ScienceExperiment experiment, ExperimentSituations situations, CelestialBody body)
 {
     return(experiment.IsAvailableWhile(situations, body) &&
            !(experiment.experimentTitle == "Sample" &&
              !(situations == ExperimentSituations.SrfLanded || situations == ExperimentSituations.SrfSplashed)));
 }