public override OverlayTooltip TooltipContent(double latitude, double longitude, CelestialBody body)
        {
            var biome = ScanSatWrapper.Instance.GetBiome(longitude, latitude, body);
            var all   = Enum.GetValues(typeof(ExperimentSituations)).Cast <ExperimentSituations>()
                        .Select(situation => ResearchAndDevelopment.GetExperimentIDs().Select(ResearchAndDevelopment.GetExperiment)
                                .Where(x => x.biomeMask != 0 && x.situationMask != 0)
                                .Where(x => x.IsAvailableWhileFixed(situation, body))
                                .GroupBy(x => x.BiomeIsRelevantWhile(situation))
                                .SelectMany(x => x.Select(y => new { exp = y, subj = ResearchAndDevelopment.GetExperimentSubject(y, situation, body, x.Key ? biome.name : "") }))
                                .Select(x => new { value = ResearchAndDevelopment.GetScienceValue(x.exp.dataScale * x.exp.baseValue, x.subj), exp = x })
                                .Aggregate(new { str = "", total = 0f },
                                           (a, x) => new { str = a.str + " name: " + x.exp.exp.experimentTitle + " value: " + x.value, total = a.total + x.value },
                                           result => "Situation " + Enum.GetName(typeof(ExperimentSituations), situation) + " total: " + result.total + result.str))
                        .Aggregate("", (str, x) => str + x + "\n");
            var main = ResearchAndDevelopment.GetExperimentIDs().Select(ResearchAndDevelopment.GetExperiment)
                       .Where(x => x.biomeMask != 0 && x.situationMask != 0)
                       .Where(x => x.IsAvailableWhileFixed(_situation, body))
                       .GroupBy(x => x.BiomeIsRelevantWhile(_situation))
                       .SelectMany(x => x.Select(y => new { exp = y, subj = ResearchAndDevelopment.GetExperimentSubject(y, _situation, body, x.Key ? biome.name : "") }))
                       .Select(x => new { value = ResearchAndDevelopment.GetScienceValue(x.exp.dataScale * x.exp.baseValue, x.subj), exp = x })
                       .Aggregate(new { str = "", total = 0f },
                                  (a, x) => new { str = a.str + " name: " + x.exp.exp.experimentTitle + " value: " + x.value, total = a.total + x.value },
                                  result => "Situation " + Enum.GetName(typeof(ExperimentSituations), _situation) + " total: " + result.total + result.str);

            return(new OverlayTooltip(biome.name, new GUIContent(main + "\n\n" + all), new Vector2(500, 500)));
        }
        public static void RegisterMethods()
        {
            RegisterMethod(new Method <ScienceExperiment, string>("Name", e => e == null ? "" : e.experimentTitle));

            RegisterGlobalFunction(new Function <List <ScienceExperiment> >("AllExperiments", () => ResearchAndDevelopment.Instance == null ? new List <ScienceExperiment>() :
                                                                            ResearchAndDevelopment.GetExperimentIDs().Select <string, ScienceExperiment>(ResearchAndDevelopment.GetExperiment).ToList(), false));
            RegisterGlobalFunction(new Function <CelestialBody, List <ScienceExperiment> >("AvailableExperiments", (cb) => Util.Science.AvailableExperiments(cb).ToList(), false));
        }
Esempio n. 3
0
        public int RebuildObserverList()
        {
            observers.Clear();
            ScanInterface scanInterface = GetComponent <ScanInterface>();

            if (scanInterface == null)
            {
                Log.Error("ExperimentManager.RebuildObserverList: No ScanInterface component found"); // this is bad; things won't break if the scan interface
            }
            // construct the experiment observer list ...
            foreach (var expid in ResearchAndDevelopment.GetExperimentIDs())
            {
                if (expid != "evaReport" && expid != "surfaceSample") // special cases

                {
                    if (FlightGlobals.ActiveVessel.FindPartModulesImplementing <ModuleScienceExperiment>().Any(mse => mse.experimentID == expid))
                    {
                        observers.Add(new ExperimentObserver(vesselStorage, ProfileManager.ActiveProfile[expid], biomeFilter, scanInterface, expid));
                    }
                }
            }

            observers.Add(new SurfaceSampleObserver(vesselStorage, ProfileManager.ActiveProfile["surfaceSample"], biomeFilter, scanInterface));

            try
            {
                if (ProfileManager.ActiveProfile["evaReport"].Enabled)
                {
                    if (Settings.Instance.EvaReportOnTop)
                    {
                        observers = observers.OrderBy(obs => obs.ExperimentTitle).ToList();
                        observers.Insert(0, new EvaReportObserver(vesselStorage, ProfileManager.ActiveProfile["evaReport"], biomeFilter, scanInterface));
                    }
                    else
                    {
                        observers.Add(new EvaReportObserver(vesselStorage, ProfileManager.ActiveProfile["evaReport"], biomeFilter, scanInterface));
                        observers = observers.OrderBy(obs => obs.ExperimentTitle).ToList();
                    }
                }
                else
                {
                    observers = observers.OrderBy(obs => obs.ExperimentTitle).ToList();
                }
            }
            catch (NullReferenceException e)
            {
                Log.Error("ExperimentManager.RebuildObserverList: Active profile does not seem to have an \"evaReport\" entry; {0}", e);
            }

            watcher = UpdateObservers(); // to prevent any problems by rebuilding in the middle of enumeration
            OnObserversRebuilt();

            return(observers.Count);
        }
Esempio n. 4
0
        protected bool ValidateExperiment(string experiment)
        {
            if (string.IsNullOrEmpty(experiment))
            {
                return(true);
            }

            if (!ResearchAndDevelopment.GetExperimentIDs().Contains(experiment))
            {
                throw new ArgumentException("Not a valid experiment!");
            }
            return(true);
        }
Esempio n. 5
0
 private void Setup()
 {
     settings = new Dictionary <string, ExperimentSettings>();
     try
     {
         List <string> experimentIDs = ResearchAndDevelopment.GetExperimentIDs();
         foreach (string current in experimentIDs)
         {
             settings.Add(current, new ExperimentSettings());
         }
     }
     catch (System.Exception ex)
     {
         Log.Debug("[ScienceAlert]:Profile '{1}' constructor exception: {0}", ex, string.IsNullOrEmpty(name) ? "(unnamed)" : name);
     }
 }
 protected new void OnGUI()
 {
     if (!adjustedSkin)
     {
         Skin.window.stretchHeight = true;
         List <string> experimentTitles = new List <string>();
         ResearchAndDevelopment.GetExperimentIDs().ForEach(id => experimentTitles.Add(ResearchAndDevelopment.GetExperiment(id).experimentTitle));
         Skin.button.fixedWidth = Mathf.Max(64f, experimentTitles.Max(title =>
         {
             float minWidth = 0f;
             float maxWidth = 0f;
             Skin.button.CalcMinMaxWidth(new GUIContent(title + " (123.4)"), out minWidth, out maxWidth);
             return(maxWidth);
         }));
         adjustedSkin = true;
     }
     base.OnGUI();
 }
Esempio n. 7
0
        //Attempts to inject the stuff that should have been in sciencedefs to begin with
        private void rdInject()
        {
            ScienceExperiment temp = null;

            try
            {
                List <String> ids = ResearchAndDevelopment.GetExperimentIDs();
                if (_debug)
                {
                    Debug.Log("(CB) Injecting experimental results...");
                }
                ScienceExperiment exp;
                foreach (String id in ids)
                {
                    exp = ResearchAndDevelopment.GetExperiment(id);
                    if (id.Equals("temperatureScan"))
                    {
                        temp = exp;
                    }
                    foreach (sciresult res in _resultList)
                    {
                        if (res.expid.Equals(id) && !exp.Results.ContainsKey(res.biome))
                        {
                            exp.Results.Add(res.biome, res.res);
                        }
                        // else
                        //if (_debug) Debug.Log(res.biome + " already exists for " + exp.experimentTitle);
                    }
                    if (_debug)
                    {
                        Debug.Log("(CB) " + exp.experimentTitle);
                    }
                    //foreach (String key in exp.Results.Keys)
                    //Debug.Log(key + " | " + exp.Results[key]);
                }
                Debug.Log("(CB) R&D injection complete.");
                rdInjected = true;
            }
            catch
            {
                Debug.Log("(CB) Error attempting R&D injection.");
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Some necessary setup shared between constructors
        /// </summary>
        private void Setup()
        {
            settings = new Dictionary <string, ProfileData.ExperimentSettings>();

            try
            {
                var expids = ResearchAndDevelopment.GetExperimentIDs();

                foreach (var id in expids)
                {
                    settings.Add(id, new ProfileData.ExperimentSettings());
                }
            }
            catch (Exception e)
            {
                // this is most likely to happen on GetExperimentIDs, which
                // will throw an exception if there are duplicate experiment
                // id entries
                Log.Error("Profile '{1}' constructor exception: {0}", e, string.IsNullOrEmpty(name) ? "(unnamed)" : name);
            }
        }
        public void OnProfileChanged()
        {
            if (ScienceAlertProfileManager.ActiveProfile == null)
            {
                return;
            }
            thresholdValue = ScienceAlertProfileManager.ActiveProfile.ScienceThreshold.ToString("F2", formatter);
            List <string> experimentIDs = ResearchAndDevelopment.GetExperimentIDs();
            IOrderedEnumerable <string> orderedEnumerable = from expid in experimentIDs
                                                            orderby ResearchAndDevelopment.GetExperiment(expid).experimentTitle
                                                            select expid;

            experimentIds.Clear();
            using (IEnumerator <string> enumerator = orderedEnumerable.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    string current = enumerator.Current;
                    experimentIds.Add(current, (int)System.Convert.ChangeType(ScienceAlertProfileManager.ActiveProfile[current].Filter,
                                                                              ScienceAlertProfileManager.ActiveProfile[current].Filter.GetTypeCode()));
                }
            }
        }
Esempio n. 10
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();
        }
    }
Esempio n. 11
0
        public static void Init()
        {
            Lib.Log("ScienceDB init started");
            int    subjectCount = 0;
            double totalScience = 0.0;

            // get our extra defintions
            ConfigNode[] expDefNodes = GameDatabase.Instance.GetConfigNodes("EXPERIMENT_DEFINITION");

            // create our subject database
            // Note : GetExperimentIDs will force the creation of all ScienceExperiment objects,
            // no matter if the RnD instance is null or not because the ScienceExperiment dictionary is static.
            foreach (string experimentId in ResearchAndDevelopment.GetExperimentIDs())
            {
                if (experimentId == "recovery")
                {
                    continue;
                }

                ConfigNode kerbalismExpNode = null;
                foreach (ConfigNode expDefNode in expDefNodes)
                {
                    string id = string.Empty;
                    if (expDefNode.TryGetValue("id", ref id) && id == experimentId)
                    {
                        kerbalismExpNode = expDefNode.GetNode("KERBALISM_EXPERIMENT");                         // return null if not found
                        break;
                    }
                }

                ScienceExperiment stockDef = ResearchAndDevelopment.GetExperiment(experimentId);
                if (stockDef == null)
                {
                    Lib.Log("ScienceExperiment is null for experiment Id=" + experimentId + ", skipping...", Lib.LogLevel.Warning);
                    continue;
                }

                ExperimentInfo expInfo = new ExperimentInfo(stockDef, kerbalismExpNode);
                if (!experiments.ContainsKey(experimentId))
                {
                    experiments.Add(experimentId, expInfo);
                }
                if (!subjectByExpThenSituationId.ContainsKey(expInfo))
                {
                    subjectByExpThenSituationId.Add(expInfo, new Dictionary <int, SubjectData>());
                }

                for (int bodyIndex = 0; bodyIndex < FlightGlobals.Bodies.Count; bodyIndex++)
                {
                    CelestialBody body = FlightGlobals.Bodies[bodyIndex];

                    if (!expInfo.IgnoreBodyRestrictions && !expInfo.ExpBodyConditions.IsBodyAllowed(body))
                    {
                        continue;
                    }

                    // ScienceSituationUtils.validSituations is all situations in the enum, apart from the "None" value
                    foreach (ScienceSituation scienceSituation in ScienceSituationUtils.validSituations)
                    {
                        // test the ScienceExperiment situation mask
                        if (!scienceSituation.IsAvailableForExperiment(expInfo))
                        {
                            continue;
                        }

                        // don't add impossible body / situation combinations
                        if (!expInfo.IgnoreBodyRestrictions && !scienceSituation.IsAvailableOnBody(body))
                        {
                            continue;
                        }

                        // virtual biomes always have priority over normal biomes :
                        if (scienceSituation.IsVirtualBiomesRelevantForExperiment(expInfo))
                        {
                            foreach (VirtualBiome virtualBiome in expInfo.VirtualBiomes)
                            {
                                if (!virtualBiome.IsAvailableOnBody(body))
                                {
                                    continue;
                                }

                                SubjectData subjectData = null;
                                if (expInfo.HasDBSubjects)
                                {
                                    Situation situation = new Situation(bodyIndex, scienceSituation, (int)virtualBiome);
                                    subjectData = new SubjectData(expInfo, situation);
                                    subjectByExpThenSituationId[expInfo].Add(situation.Id, subjectData);
                                    knownStockSubjectsId.Add(subjectData.StockSubjectId);
                                    subjectCount++;
                                    totalScience += subjectData.ScienceMaxValue;
                                }

                                expBodiesSituationsBiomesSubject.AddSubject(expInfo, bodyIndex, scienceSituation, (int)virtualBiome, subjectData);
                            }
                        }
                        // if the biome mask says the situation is biome dependant :
                        else if (scienceSituation.IsBodyBiomesRelevantForExperiment(expInfo) && body.BiomeMap != null && body.BiomeMap.Attributes.Length > 1)
                        {
                            for (int biomeIndex = 0; biomeIndex < body.BiomeMap.Attributes.Length; biomeIndex++)
                            {
                                SubjectData subjectData = null;
                                if (expInfo.HasDBSubjects)
                                {
                                    Situation situation = new Situation(bodyIndex, scienceSituation, biomeIndex);
                                    subjectData = new SubjectData(expInfo, situation);
                                    subjectByExpThenSituationId[expInfo].Add(situation.Id, subjectData);
                                    knownStockSubjectsId.Add(subjectData.StockSubjectId);
                                    subjectCount++;
                                    totalScience += subjectData.ScienceMaxValue;
                                }

                                expBodiesSituationsBiomesSubject.AddSubject(expInfo, bodyIndex, scienceSituation, biomeIndex, subjectData);
                            }
                        }
                        // else generate the global, biome agnostic situation
                        else
                        {
                            SubjectData subjectData = null;
                            if (expInfo.HasDBSubjects)
                            {
                                Situation situation = new Situation(bodyIndex, scienceSituation);
                                subjectData = new SubjectData(expInfo, situation);
                                subjectByExpThenSituationId[expInfo].Add(situation.Id, subjectData);
                                knownStockSubjectsId.Add(subjectData.StockSubjectId);
                                subjectCount++;
                                totalScience += subjectData.ScienceMaxValue;
                            }

                            expBodiesSituationsBiomesSubject.AddSubject(expInfo, bodyIndex, scienceSituation, -1, subjectData);
                        }
                    }
                }
            }

            // cache that call
            IEnumerable <ExperimentInfo> experimentInfosCache = ExperimentInfos;

            // first parse all the IncludeExperiment configs
            foreach (ExperimentInfo experimentInfo in experimentInfosCache)
            {
                experimentInfo.ParseIncludedExperiments();
            }

            // then check for infinite recursion from bad configs
            List <ExperimentInfo> chainedExperiments = new List <ExperimentInfo>();

            foreach (ExperimentInfo experimentInfo in experimentInfosCache)
            {
                chainedExperiments.Clear();
                ExperimentInfo.CheckIncludedExperimentsRecursion(experimentInfo, chainedExperiments);
            }

            // now we are sure all the include experiment chains are valid
            foreach (ExperimentInfo experimentInfo in experimentInfosCache)
            {
                // populate the included experiments chains at the subject level
                foreach (KeyValuePair <int, SubjectData> subjectInfo in subjectByExpThenSituationId[experimentInfo])
                {
                    foreach (ExperimentInfo includedInfo in experimentInfo.IncludedExperiments)
                    {
                        SubjectData subjectToInclude = GetSubjectData(includedInfo, subjectInfo.Key);

                        if (subjectToInclude != null)
                        {
                            subjectInfo.Value.IncludedSubjects.Add(subjectToInclude);
                        }
                    }
                }

                // Get the experiment description that will be shown in the science archive by calling GetInfo() on the first found partmodule using it
                // TODO: this isn't ideal, if there are several modules with different values (ex : data rate, ec rate...), the archive info will use the first found one.
                // Ideally we should revamp the whole handling of that (because it's a mess from the partmodule side too)
                experimentInfo.CompileModuleInfos();
            }

            Lib.Log($"ScienceDB init done : {subjectCount} subjects found, total science points : {totalScience.ToString("F1")}");
        }
        /******************************************************************************
        *                    Implementation Details
        ******************************************************************************/

        protected override Rect Setup()
        {
            // position blocker in front of ApplicationLauncher buttons. The window is going to be drawn on
            // top of them regardless; this will just prevent us from accidentally interacting with them
            backstop.SetZ(ApplicationLauncher.Instance.anchor.transform.position.z - 50f);

            // culture setting
            Log.Normal("Configuring NumberFormatInfo for current locale");
            formatter = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone();
            formatter.CurrencySymbol        = string.Empty;
            formatter.CurrencyDecimalDigits = 2;
            formatter.NumberDecimalDigits   = 2;
            formatter.PercentDecimalDigits  = 2;


            audio = AudioPlayer.Audio;

            if (audio == null)
            {
                Log.Error("DraggableOptionsWindow: Failed to find AudioPlayer instance");
            }


            var rawIds    = ResearchAndDevelopment.GetExperimentIDs();
            var sortedIds = rawIds.OrderBy(expid => ResearchAndDevelopment.GetExperiment(expid).experimentTitle);

            Log.Debug("OptionsWindow: sorted {0} experiment IDs", sortedIds.Count());

            foreach (var id in sortedIds)
            {
                experimentIds.Add(id, (int)Convert.ChangeType(ProfileManager.ActiveProfile[id].Filter, ProfileManager.ActiveProfile[id].Filter.GetTypeCode()));
                Log.Debug("Settings: experimentId {0} has filter index {1}", id, experimentIds[id]);
            }

            /*
             *  Unresearched = 0,
             *  NotMaxed = 1,
             *  LessThanFiftyPercent = 2,
             *  LessThanNinetyPercent = 3
             */
            filterList.Add(new GUIContent("Unresearched"));
            filterList.Add(new GUIContent("Not maxed"));
            filterList.Add(new GUIContent("< 50% collected"));
            filterList.Add(new GUIContent("< 90% collected"));


            openButton   = ResourceUtil.GetEmbeddedTexture("ScienceAlert.Resources.btnOpen.png", false);
            saveButton   = ResourceUtil.GetEmbeddedTexture("ScienceAlert.Resources.btnSave.png", false);
            returnButton = ResourceUtil.GetEmbeddedTexture("ScienceAlert.Resources.btnReturn.png", false);
            deleteButton = ResourceUtil.GetEmbeddedTexture("ScienceAlert.Resources.btnDelete.png", false);
            renameButton = ResourceUtil.GetEmbeddedTexture("ScienceAlert.Resources.btnRename.png", false);

            var tex = ResourceUtil.GetEmbeddedTexture("ScienceAlert.Resources.btnExpand.png", false);

            if (tex == null)
            {
                Log.Error("Failed to retrieve expand button texture from stream");
            }
            else
            {
                Log.Debug("Collapse button texture loaded successfully");
                expandButton = tex;

                collapseButton = UnityEngine.Texture.Instantiate(expandButton) as Texture2D;
                ResourceUtil.FlipTexture(collapseButton, true, true);

                collapseButton.Compress(false);
                expandButton.Compress(false);
            }

            blackPixel.SetPixel(0, 0, Color.black); blackPixel.Apply();
            blackPixel.filterMode = FilterMode.Bilinear;

            whiteLabel = (GUISkin)GUISkin.Instantiate(Settings.Skin);
            whiteLabel.label.onNormal.textColor  = Color.white;
            whiteLabel.toggle.onNormal.textColor = Color.white;
            whiteLabel.label.onActive.textColor  = Color.white;

            submenu = OpenPane.None;
            Title   = "ScienceAlert Options";

            // smaller label for less important text hints
            miniLabelLeft                  = new GUIStyle(Skin.label);
            miniLabelLeft.fontSize         = 10;
            miniLabelLeft.normal.textColor = miniLabelLeft.onNormal.textColor = Color.white;

            miniLabelRight           = new GUIStyle(miniLabelLeft);
            miniLabelRight.alignment = TextAnchor.MiddleRight;

            miniLabelCenter           = new GUIStyle(miniLabelLeft);
            miniLabelCenter.alignment = TextAnchor.MiddleCenter;

            Settings.Instance.OnSave += OnAboutToSave;
            base.OnVisibilityChange  += OnVisibilityChanged;
            GameEvents.onVesselChange.Add(OnVesselChanged);

            LoadFrom(Settings.Instance.additional.GetNode("OptionsWindow") ?? new ConfigNode());

            return(new Rect(windowRect.x, windowRect.y, 324, Screen.height / 5 * 3));
        }
Esempio n. 13
0
        /// <summary>
        /// Gets an enumeration of all available experiments
        /// </summary>
        /// <returns></returns>
        public static IEnumerable <ScienceExperiment> AvailableExperiments()
        {
            if (ResearchAndDevelopment.Instance == null)
            {
                return(Enumerable.Empty <ScienceExperiment>());
            }

            IEnumerable <ScienceExperiment> experiments = ResearchAndDevelopment.GetExperimentIDs().Select <string, ScienceExperiment>(ResearchAndDevelopment.GetExperiment);

            // Build a mapping of experiment => parts
            if (experimentParts == null)
            {
                experimentParts = new Dictionary <string, List <AvailablePart> >();

                // Check the stock experiment
                foreach (KeyValuePair <AvailablePart, string> pair in PartLoader.Instance.parts.
                         Where(p => p.moduleInfos.Any(mod => experimentModules.Contains(mod.moduleName.Replace(" ", "")))).
                         SelectMany(p => p.partConfig.GetNodes("MODULE").
                                    Where(node => experimentModules.Contains(node.GetValue("name"))).
                                    Select(node => new KeyValuePair <AvailablePart, string>(p, node.GetValue("experimentID")))))
                {
                    if (!string.IsNullOrEmpty(pair.Value))
                    {
                        if (!experimentParts.ContainsKey(pair.Value))
                        {
                            experimentParts[pair.Value] = new List <AvailablePart>();
                        }
                        experimentParts[pair.Value].Add(pair.Key);
                    }
                }

                // Check for specific modules specified in configurator
                foreach (ExperimentRules rules in experiments.Select(exp => GetExperimentRules(exp.id)).Where(r => !string.IsNullOrEmpty(r.partModule)))
                {
                    if (!experimentParts.ContainsKey(rules.id))
                    {
                        experimentParts[rules.id] = new List <AvailablePart>();
                    }

                    string module = rules.partModule;
                    foreach (AvailablePart p in PartLoader.Instance.parts.Where(p => p.moduleInfos.Any(mod => mod.moduleName == module)))
                    {
                        experimentParts[rules.id].Add(p);
                    }
                }

                // Add part-specific rules
                foreach (ExperimentRules rules in experiments.Select(exp => GetExperimentRules(exp.id)).Where(r => r.part != null))
                {
                    if (!experimentParts.ContainsKey(rules.id))
                    {
                        experimentParts[rules.id] = new List <AvailablePart>();
                    }

                    foreach (string pname in rules.part)
                    {
                        foreach (AvailablePart p in PartLoader.Instance.parts.Where(p => p.name == pname))
                        {
                            LoggingUtil.LogVerbose(typeof(Science), "Adding entry for " + rules.id + " = " + p.name);
                            experimentParts[rules.id].Add(p);
                        }
                    }
                }

                // List out the partless experiments
                foreach (ScienceExperiment exp in experiments.Where(exp => GetExperimentRules(exp.id).partless))
                {
                    partlessExperiments[exp.id] = true;
                }
            }

            // Filter out anything tied to a part that isn't unlocked
            experiments = experiments.Where(exp => partlessExperiments.ContainsKey(exp.id) ||
                                            experimentParts.ContainsKey(exp.id) && experimentParts[exp.id].Any(ResearchAndDevelopment.PartTechAvailable));

            return(experiments);
        }
Esempio n. 14
0
        public static void Init()
        {
            Lib.Log("ScienceDB init started");
            int subjectCount = 0;

            // get our extra defintions
            ConfigNode[] expDefNodes = GameDatabase.Instance.GetConfigNodes("EXPERIMENT_DEFINITION");

            // create our subject database
            // Note : GetExperimentIDs will force the creation of all ScienceExperiment objects,
            // no matter if the RnD instance is null or not because the ScienceExperiment dictionary is static.
            foreach (string experimentId in ResearchAndDevelopment.GetExperimentIDs())
            {
                if (experimentId == "recovery")
                {
                    continue;
                }

                ConfigNode kerbalismExpNode = null;
                foreach (ConfigNode expDefNode in expDefNodes)
                {
                    string id = string.Empty;
                    if (expDefNode.TryGetValue("id", ref id) && id == experimentId)
                    {
                        kerbalismExpNode = expDefNode.GetNode("KERBALISM_EXPERIMENT");                         // return null if not found
                        break;
                    }
                }

                ScienceExperiment stockDef = ResearchAndDevelopment.GetExperiment(experimentId);
                if (stockDef == null)
                {
                    Lib.Log("ScienceExperiment is null for experiment Id=" + experimentId + ", skipping...", Lib.LogLevel.Warning);
                    continue;
                }

                ExperimentInfo expInfo = new ExperimentInfo(stockDef, kerbalismExpNode);
                if (!experiments.ContainsKey(experimentId))
                {
                    experiments.Add(experimentId, expInfo);
                }
                if (!subjectByExpThenSituationId.ContainsKey(expInfo))
                {
                    subjectByExpThenSituationId.Add(expInfo, new Dictionary <int, SubjectData>());
                }

                for (int bodyIndex = 0; bodyIndex < FlightGlobals.Bodies.Count; bodyIndex++)
                {
                    CelestialBody body = FlightGlobals.Bodies[bodyIndex];

                    if (!expInfo.IgnoreBodyRestrictions && !expInfo.ExpBodyConditions.IsBodyAllowed(body))
                    {
                        continue;
                    }

                    // ScienceSituationUtils.validSituations is all situations in the enum, apart from the "None" value
                    foreach (ScienceSituation scienceSituation in ScienceSituationUtils.validSituations)
                    {
                        // test the ScienceExperiment situation mask
                        if (!scienceSituation.IsAvailableForExperiment(expInfo))
                        {
                            continue;
                        }

                        // don't add impossible body / situation combinations
                        if (!expInfo.IgnoreBodyRestrictions && !scienceSituation.IsAvailableOnBody(body))
                        {
                            continue;
                        }

                        // virtual biomes always have priority over normal biomes :
                        if (scienceSituation.IsVirtualBiomesRelevantForExperiment(expInfo))
                        {
                            foreach (VirtualBiome virtualBiome in expInfo.VirtualBiomes)
                            {
                                if (!virtualBiome.IsAvailableOnBody(body))
                                {
                                    continue;
                                }

                                SubjectData subjectData = null;
                                if (expInfo.HasDBSubjects)
                                {
                                    Situation situation = new Situation(bodyIndex, scienceSituation, (int)virtualBiome);
                                    subjectData = new SubjectData(expInfo, situation);
                                    subjectByExpThenSituationId[expInfo].Add(situation.Id, subjectData);
                                    knownStockSubjectsId.Add(subjectData.StockSubjectId);
                                    subjectCount++;
                                }

                                expBodiesSituationsBiomesSubject.AddSubject(expInfo, bodyIndex, scienceSituation, (int)virtualBiome, subjectData);
                                bodiesSituationsBiomesSubjects.AddSubject(bodyIndex, scienceSituation, (int)virtualBiome, subjectData);
                            }
                        }
                        // if the biome mask says the situation is biome dependant :
                        else if (scienceSituation.IsBodyBiomesRelevantForExperiment(expInfo) && body.BiomeMap != null && body.BiomeMap.Attributes.Length > 1)
                        {
                            for (int biomeIndex = 0; biomeIndex < body.BiomeMap.Attributes.Length; biomeIndex++)
                            {
                                SubjectData subjectData = null;
                                if (expInfo.HasDBSubjects)
                                {
                                    Situation situation = new Situation(bodyIndex, scienceSituation, biomeIndex);
                                    subjectData = new SubjectData(expInfo, situation);
                                    subjectByExpThenSituationId[expInfo].Add(situation.Id, subjectData);
                                    knownStockSubjectsId.Add(subjectData.StockSubjectId);
                                    subjectCount++;
                                }

                                expBodiesSituationsBiomesSubject.AddSubject(expInfo, bodyIndex, scienceSituation, biomeIndex, subjectData);
                                bodiesSituationsBiomesSubjects.AddSubject(bodyIndex, scienceSituation, biomeIndex, subjectData);
                            }
                        }
                        // else generate the global, biome agnostic situation
                        else
                        {
                            SubjectData subjectData = null;
                            if (expInfo.HasDBSubjects)
                            {
                                Situation situation = new Situation(bodyIndex, scienceSituation);
                                subjectData = new SubjectData(expInfo, situation);
                                subjectByExpThenSituationId[expInfo].Add(situation.Id, subjectData);
                                knownStockSubjectsId.Add(subjectData.StockSubjectId);
                                subjectCount++;
                            }

                            expBodiesSituationsBiomesSubject.AddSubject(expInfo, bodyIndex, scienceSituation, -1, subjectData);
                            bodiesSituationsBiomesSubjects.AddSubject(bodyIndex, scienceSituation, -1, subjectData);
                        }
                    }
                }
            }

            Lib.Log("ScienceDB init done : " + subjectCount + " subjects found");
        }
Esempio n. 15
0
        /// <summary>
        /// Recreates all ExperimentObservers. This is done so that we never have any ExperimentObservers
        /// that watch for experiments that the current Vessel doesn't have, except in special cases like
        /// EVA reports or surface samples.
        /// </summary>
        /// <returns>Number of observers created</returns>
        public int RebuildObserverList()
        {
            Log.Normal("Rebuilding observer list");

            observers.Clear();
            ScanInterface scanInterface = GetComponent <ScanInterface>();

            if (scanInterface == null)
            {
                Log.Error("ExperimentManager.RebuildObserverList: No ScanInterface component found"); // this is bad; things won't break if the scan interface
            }
            // is the default but there should always be a ScanInterface-type
            // script attached to this GO

            // construct the experiment observer list ...
            foreach (var expid in ResearchAndDevelopment.GetExperimentIDs())
            {
                if (expid != "evaReport" && expid != "surfaceSample") // special cases
                {
                    if (ResearchAndDevelopment.GetExperiment(expid).situationMask == 0 && ResearchAndDevelopment.GetExperiment(expid).biomeMask == 0)
                    {   // we can't monitor this experiment, so no need to clutter the
                        // ui with it
                        Log.Verbose("Experiment '{0}' cannot be monitored due to zero'd situation and biome flag masks.", ResearchAndDevelopment.GetExperiment(expid).experimentTitle);
                    }
                    else if (FlightGlobals.ActiveVessel.FindPartModulesImplementing <ModuleScienceExperiment>().Any(mse => mse.experimentID == expid))
                    {
                        // only add this observer if at least one applicable experiment is onboard
                        observers.Add(new ExperimentObserver(vesselStorage, ProfileManager.ActiveProfile[expid], biomeFilter, scanInterface, expid));
                    }
                }
            }

            // surfaceSample is a special case: it's technically available on any
            // crewed vessel
            observers.Add(new SurfaceSampleObserver(vesselStorage, ProfileManager.ActiveProfile["surfaceSample"], biomeFilter, scanInterface));


            // evaReport is a special case.  It technically exists on any crewed
            // vessel.  That vessel won't report it normally though, unless
            // the vessel is itself an eva'ing Kerbal.  Since there are conditions
            // that would result in the experiment no longer being available
            // (kerbal dies, user goes out on eva and switches back to ship, and
            // so on) I think it's best we separate it out into its own
            // Observer type that will account for these changes and any others
            // that might not necessarily trigger a VesselModified event
            try
            {
                if (ProfileManager.ActiveProfile["evaReport"].Enabled)
                {
                    if (Settings.Instance.EvaReportOnTop)
                    {
                        observers = observers.OrderBy(obs => obs.ExperimentTitle).ToList();
                        observers.Insert(0, new EvaReportObserver(vesselStorage, ProfileManager.ActiveProfile["evaReport"], biomeFilter, scanInterface));
                    }
                    else
                    {
                        observers.Add(new EvaReportObserver(vesselStorage, ProfileManager.ActiveProfile["evaReport"], biomeFilter, scanInterface));
                        observers = observers.OrderBy(obs => obs.ExperimentTitle).ToList();
                    }
                }
                else
                {
                    observers = observers.OrderBy(obs => obs.ExperimentTitle).ToList();
                }
            }
            catch (NullReferenceException e)
            {
                // this is another one of those things that should never happen but if they did
                // it'd be in a quiet "why isn't this list sorted?" way
                Log.Error("ExperimentManager.RebuildObserverList: Active profile does not seem to have an \"evaReport\" entry; {0}", e);
            }

            watcher = UpdateObservers(); // to prevent any problems by rebuilding in the middle of enumeration
            OnObserversRebuilt();

            return(observers.Count);
        }
 private void SetExperiments(ExperimentSituations situations)
 {
     _experiments = ResearchAndDevelopment.GetExperimentIDs().Select(ResearchAndDevelopment.GetExperiment)
                    .Where(x => x.biomeMask != 0 && x.situationMask != 0)
                    .Where(x => x.IsAvailableWhileFixed(situations, _body)).ToList();
 }