Exemplo n.º 1
0
        private static void ShowPopup(string modName)
        {
            string title = "Kerbalism compatibility notice";
            string msg   = Lib.Color($"{modName} has been detected in your game.\n\nFor it to be compatible with Kerbalism, the \"Unloaded Vessel Processing\" {modName} difficulty setting option has been automatically disabled.", Lib.Kolor.Yellow, true);

            PopupDialog.SpawnPopupDialog
            (
                new Vector2(0.5f, 0.5f),
                new Vector2(0.5f, 0.5f),
                new MultiOptionDialog(modName, msg, title, HighLogic.UISkin, 350f, new DialogGUIButton("OK", null, true)),
                false,
                HighLogic.UISkin,
                true,
                string.Empty
            );
        }
Exemplo n.º 2
0
        // transfer data between two vessels
        public static void Transfer(Vessel src, Vessel dst, bool samples)
        {
            double dataAmount  = 0.0;
            int    sampleSlots = 0;

            foreach (var drive in GetDrives(src, true))
            {
                dataAmount  += drive.FilesSize();
                sampleSlots += drive.SamplesSize();
            }

            if (dataAmount < double.Epsilon && (sampleSlots == 0 || !samples))
            {
                return;
            }

            var  allSrc   = GetDrives(src, true);
            bool allMoved = false;

            foreach (var a in allSrc)
            {
                if (Transfer(a, dst, samples))
                {
                    allMoved = true;
                    break;
                }
            }

            // inform the user
            if (allMoved)
            {
                Message.Post
                (
                    Lib.HumanReadableDataSize(dataAmount) + " " + Local.Science_ofdatatransfer,
                    Lib.BuildString(Local.Generic_FROM, " <b>", src.vesselName, "</b> ", Local.Generic_TO, " <b>", dst.vesselName, "</b>")
                );
            }
            else
            {
                Message.Post
                (
                    Lib.Color(Lib.BuildString("WARNING: not evering copied"), Lib.Kolor.Red, true),
                    Lib.BuildString(Local.Generic_FROM, " <b>", src.vesselName, "</b> ", Local.Generic_TO, " <b>", dst.vesselName, "</b>")
                );
            }
        }
Exemplo n.º 3
0
        static void Render_sample(Panel p, uint partId, Sample sample, Drive drive, bool short_strings)
        {
            // render experiment name
            string exp_label = Lib.BuildString
                               (
                "<b>",
                Lib.Ellipsis(sample.subjectData.ExperimentTitle, Styles.ScaleStringLength(short_strings ? 24 : 38)),
                "</b> <size=", Styles.ScaleInteger(10).ToString(), ">",
                Lib.Ellipsis(sample.subjectData.SituationTitle, Styles.ScaleStringLength((short_strings ? 32 : 62) - Lib.Ellipsis(sample.subjectData.ExperimentTitle, Styles.ScaleStringLength(short_strings ? 24 : 38)).Length)),
                "</size>"
                               );
            string exp_tooltip = Lib.BuildString
                                 (
                sample.subjectData.ExperimentTitle, "\n",
                Lib.Color(sample.subjectData.SituationTitle, Lib.Kolor.LightGrey)
                                 );

            double exp_value = sample.size * sample.subjectData.SciencePerMB;

            if (exp_value >= 0.1)
            {
                exp_tooltip = Lib.BuildString(exp_tooltip, "\n<b>", Lib.HumanReadableScience(exp_value, false), "</b>");
            }
            if (sample.mass > Double.Epsilon)
            {
                exp_tooltip = Lib.BuildString(exp_tooltip, "\n<b>", Lib.HumanReadableMass(sample.mass), "</b>");
            }
            if (!string.IsNullOrEmpty(sample.resultText))
            {
                exp_tooltip = Lib.BuildString(exp_tooltip, "\n", Lib.WordWrapAtLength(sample.resultText, 50));
            }

            p.AddContent(exp_label, Lib.HumanReadableSampleSize(sample.size), exp_tooltip, (Action)null, () => Highlighter.Set(partId, Color.cyan));
            p.AddRightIcon(sample.analyze ? Textures.lab_cyan : Textures.lab_black, Local.FILEMANAGER_analysis, () => { sample.analyze = !sample.analyze; }); //"Flag the file for analysis in a <b>laboratory</b>"
            p.AddRightIcon(Textures.toggle_red, Local.FILEMANAGER_Dumpsample, () =>                                                                           //"Dump the sample"
            {
                Lib.Popup(Local.FILEMANAGER_Warning_title,                                                                                                    //"Warning!"
                          Local.FILEMANAGER_DumpConfirm.Format(sample.subjectData.FullTitle),                                                                 //"Do you really want to dump <<1>>?",
                          new DialogGUIButton(Local.FILEMANAGER_DumpConfirm_button1, () => drive.Delete_sample(sample.subjectData)),                          //"Dump it"
                          new DialogGUIButton(Local.FILEMANAGER_DumpConfirm_button2, () => { }));                                                             //"Keep it"
            }
                           );
        }
        static bool Prefix(ModuleDataTransmitter __instance, ref string __result)
        {
            // Patch only if science is enabled
            if (!Features.Science)
            {
                return(true);
            }

            string text = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(__instance.antennaType.displayDescription());

            // Antenna type: direct
            string result = Localizer.Format("#autoLOC_7001005", text);

            // Antenna rating: 500km
            result += Localizer.Format("#autoLOC_7001006", Lib.HumanReadableDistance(__instance.antennaPower));
            result += "\n";

            var dsn1 = CommNet.CommNetScenario.RangeModel.GetMaximumRange(__instance.antennaPower, GameVariables.Instance.GetDSNRange(0f));
            var dsn2 = CommNet.CommNetScenario.RangeModel.GetMaximumRange(__instance.antennaPower, GameVariables.Instance.GetDSNRange(0.5f));
            var dsn3 = CommNet.CommNetScenario.RangeModel.GetMaximumRange(__instance.antennaPower, GameVariables.Instance.GetDSNRange(1f));

            result += Lib.BuildString(Localizer.Format("#autoLOC_236834"), " ", Lib.HumanReadableDistance(dsn1));
            result += Lib.BuildString(Localizer.Format("#autoLOC_236835"), " ", Lib.HumanReadableDistance(dsn2));
            result += Lib.BuildString(Localizer.Format("#autoLOC_236836"), " ", Lib.HumanReadableDistance(dsn3));

            double ec = __instance.DataResourceCost * __instance.DataRate;

            Specifics specs = new Specifics();

            specs.Add(Local.DataTransmitter_ECidle, Lib.Color(Lib.HumanReadableRate(ec * Settings.TransmitterPassiveEcFactor), Lib.Kolor.Orange));            //"EC (idle)"

            if (__instance.antennaType != AntennaType.INTERNAL)
            {
                specs.Add(Local.DataTransmitter_ECTX, Lib.Color(Lib.HumanReadableRate(ec * Settings.TransmitterActiveEcFactor), Lib.Kolor.Orange)); //"EC (transmitting)"
                specs.Add("");
                specs.Add(Local.DataTransmitter_Maxspeed, Lib.HumanReadableDataRate(__instance.DataRate));                                          //"Max. speed"
            }

            __result = Lib.BuildString(result, "\n\n", specs.Info());

            // don't call default implementation
            return(false);
        }
Exemplo n.º 5
0
        void Problem_storm(Vessel v, ref List <Texture2D> icons, ref List <string> tooltips)
        {
            if (Storm.Incoming(v))
            {
                icons.Add(Textures.storm_yellow);

                var bd  = Lib.IsSun(v.mainBody) ? v.KerbalismData().stormData : DB.Storm(Lib.GetParentPlanet(v.mainBody).name);
                var tti = bd.storm_time - Planetarium.GetUniversalTime();
                tooltips.Add(Lib.BuildString(Lib.Color(Local.Monitor_ejectionincoming, Lib.Kolor.Orange), "\n<i>", Local.Monitor_TimetoimpactCoronalmass, Lib.HumanReadableDuration(tti), "</i>"));                //"Coronal mass ejection incoming"Time to impact:
            }
            if (Storm.InProgress(v))
            {
                icons.Add(Textures.storm_red);

                var bd = Lib.IsSun(v.mainBody) ? v.KerbalismData().stormData : DB.Storm(Lib.GetParentPlanet(v.mainBody).name);
                var remainingDuration = bd.storm_time + bd.displayed_duration - Planetarium.GetUniversalTime();
                tooltips.Add(Lib.BuildString(Lib.Color(Local.Monitor_Solarstorminprogress, Lib.Kolor.Red), "\n<i>", Local.Monitor_SolarstormRemaining, Lib.HumanReadableDuration(remainingDuration), "</i>"));                //"Solar storm in progress"Remaining duration:
            }
        }
Exemplo n.º 6
0
  static void render_habitat(Panel p, Vessel v, vessel_info vi)
  {
    // if habitat feature is disabled, do not show the panel
    if (!Features.Habitat) return;

    // if vessel is unmanned, do not show the panel
    if (vi.crew_count == 0) return;

    // render panel, add some content based on enabled features
    p.section("HABITAT");
    if (Features.Poisoning) p.content("co2 level", Lib.Color(Lib.HumanReadablePerc(vi.poisoning, "F2"), vi.poisoning > Settings.PoisoningThreshold, "yellow"));
    if (!v.isEVA)
    {
      if (Features.Pressure) p.content("pressure", Lib.HumanReadablePressure(vi.pressure * Sim.PressureAtSeaLevel()));
      if (Features.Shielding) p.content("shielding", Habitat.shielding_to_string(vi.shielding));
      if (Features.LivingSpace) p.content("living space", Habitat.living_space_to_string(vi.living_space));
      if (Features.Comfort) p.content("comfort", vi.comforts.summary(), vi.comforts.tooltip());
    }
  }
Exemplo n.º 7
0
        public void StoreData()
        {
            // disable for dead eva kerbals
            Vessel v = FlightGlobals.ActiveVessel;

            if (v == null || EVA.IsDead(v))
            {
                return;
            }

            // transfer data
            if (!Drive.Transfer(v, drive, PreferencesScience.Instance.sampleTransfer || Lib.CrewCount(v) > 0))
            {
                Message.Post
                (
                    Lib.Color(Lib.BuildString("WARNING: not evering copied"), Lib.Kolor.Red, true),
                    Lib.BuildString("Storage is at capacity")
                );
            }
        }
Exemplo n.º 8
0
        static void Render_greenhouse(Panel p, VesselData vd)
        {
            // do nothing without greenhouses
            if (vd.Greenhouses.Count == 0)
            {
                return;
            }

            // panel section
            p.AddSection(Local.TELEMETRY_GREENHOUSE);            //"GREENHOUSE"

            // for each greenhouse
            for (int i = 0; i < vd.Greenhouses.Count; ++i)
            {
                var greenhouse = vd.Greenhouses[i];

                // state string
                string state = greenhouse.issue.Length > 0
                                  ? Lib.Color(greenhouse.issue, Lib.Kolor.Yellow)
                                  : greenhouse.growth >= 0.99
                                  ? Lib.Color(Local.TELEMETRY_readytoharvest, Lib.Kolor.Green) //"ready to harvest"
                                  : Local.TELEMETRY_growing;                                   //"growing"

                // tooltip with summary
                string tooltip = greenhouse.growth < 0.99 ? Lib.BuildString
                                 (
                    "<align=left />",
                    Local.TELEMETRY_timetoharvest, "\t<b>", Lib.HumanReadableDuration(greenhouse.tta), "</b>\n",        //"time to harvest"
                    Local.TELEMETRY_growth, "\t\t<b>", Lib.HumanReadablePerc(greenhouse.growth), "</b>\n",              //"growth"
                    Local.TELEMETRY_naturallighting, "\t<b>", Lib.HumanReadableFlux(greenhouse.natural), "</b>\n",      //"natural lighting"
                    Local.TELEMETRY_artificiallighting, "\t<b>", Lib.HumanReadableFlux(greenhouse.artificial), "</b>"   //"artificial lighting"
                                 ) : string.Empty;

                // render it
                p.AddContent(Lib.BuildString(Local.TELEMETRY_crop, " #", (i + 1).ToString()), state, tooltip);                //"crop"

                // issues too, why not
                p.AddRightIcon(greenhouse.issue.Length == 0 ? Textures.plant_white : Textures.plant_yellow, tooltip);
            }
        }
Exemplo n.º 9
0
        internal static double RecordData(ScienceData data, MetaData meta)
        {
            double remaining = data.dataAmount;

            foreach (var drive in Drive.GetDrives(meta.vessel.KerbalismData(), false))
            {
                var size = Math.Min(remaining, drive.FileCapacityAvailable());
                if (size > 0)
                {
                    drive.Record_file(meta.subjectData, size, true, true);
                    remaining -= size;
                }
            }

            if (remaining > 0)
            {
                Message.Post(
                    Lib.Color(Lib.BuildString(meta.subjectData.FullTitle, " stored partially"), Lib.Kolor.Orange),
                    "Not enough space on hard drive"
                    );
            }
            return(remaining);
        }
Exemplo n.º 10
0
        // add a message
        public static void Post(Severity severity, string text, string subtext = "")
        {
            // ignore the message if muted
            if (instance.muted)
            {
                return;
            }

            string title = "";

            switch (severity)
            {
            case Severity.relax: title = Lib.BuildString(Lib.Color(Local.Message_RELAX, Lib.Kolor.Green, true), "\n"); break;                          //"RELAX"

            case Severity.warning: title = Lib.BuildString(Lib.Color(Local.Message_WARNING, Lib.Kolor.Yellow, true), "\n"); Lib.StopWarp(); break;     //"WARNING"

            case Severity.danger: title = Lib.BuildString(Lib.Color(Local.Message_DANGER, Lib.Kolor.Red, true), "\n"); Lib.StopWarp(); break;          //"DANGER"

            case Severity.fatality: title = Lib.BuildString(Lib.Color(Local.Message_FATALITY, Lib.Kolor.Red, true), "\n"); Lib.StopWarp(); break;      //"FATALITY"

            case Severity.breakdown: title = Lib.BuildString(Lib.Color(Local.Message_BREAKDOWN, Lib.Kolor.Orange, true), "\n"); Lib.StopWarp(); break; //"BREAKDOWN"
            }
            if (subtext.Length == 0)
            {
                Post(Lib.BuildString(title, text));
            }
            else
            {
                Post(Lib.BuildString(title, text, "\n<i>", subtext, "</i>"));
            }
            all_logs.Add(new MessageObject
            {
                title = title,
                msg   = Lib.BuildString(text, "\n<i>", subtext, "</i>"),
            });
            TruncateLogs();
        }
            public string ConditionsToString()
            {
                ExpInfoSB.Length = 0;

                if (bodiesAllowed.Count > 0)
                {
                    ExpInfoSB.Append(Lib.Color(Local.Experimentinfo_Bodiesallowed + "\n", Lib.Kolor.Cyan, true));                    //Bodies allowed:
                    for (int i = bodiesAllowed.Count - 1; i >= 0; i--)
                    {
                        ExpInfoSB.Append(bodiesAllowed[i].Title);
                        if (i > 0)
                        {
                            ExpInfoSB.Append(", ");
                        }
                    }

                    if (bodiesNotAllowed.Count > 0)
                    {
                        ExpInfoSB.Append("\n");
                    }
                }

                if (bodiesNotAllowed.Count > 0)
                {
                    ExpInfoSB.Append(Lib.Color(Local.Experimentinfo_Bodiesnotallowed + "\n", Lib.Kolor.Cyan, true));                    //Bodies not allowed:
                    for (int i = bodiesNotAllowed.Count - 1; i >= 0; i--)
                    {
                        ExpInfoSB.Append(bodiesNotAllowed[i].Title);
                        if (i > 0)
                        {
                            ExpInfoSB.Append(", ");
                        }
                    }
                }

                return(ExpInfoSB.ToString());
            }
Exemplo n.º 12
0
        void Indicator_supplies(Panel p, Vessel v, VesselData vd)
        {
            List <string> tooltips     = new List <string>();
            uint          max_severity = 0;

            if (vd.CrewCount > 0)
            {
                foreach (Supply supply in Profile.supplies.FindAll(k => k.resource != "ElectricCharge"))
                {
                    ResourceInfo res       = ResourceCache.GetResource(v, supply.resource);
                    double       depletion = res.DepletionTime();

                    if (res.Capacity > double.Epsilon)
                    {
                        if (tooltips.Count == 0)
                        {
                            tooltips.Add(String.Format("<align=left /><b>{0,-18}\t" + Local.Monitor_level + "\t" + Local.Monitor_duration + "</b>", Local.Monitor_name));                                             //level"duration"name"
                        }
                        tooltips.Add(Lib.Color(
                                         String.Format("{0,-18}\t{1}\t{2}", supply.resource, Lib.HumanReadablePerc(res.Level), depletion <= double.Epsilon ? Local.Monitor_depleted : Lib.HumanReadableDuration(depletion)),               //"depleted"
                                         res.Level <= 0.005 ? Lib.Kolor.Red : res.Level <= supply.low_threshold ? Lib.Kolor.Orange : Lib.Kolor.None
                                         ));

                        uint severity = res.Level <= 0.005 ? 2u : res.Level <= supply.low_threshold ? 1u : 0;
                        max_severity = Math.Max(max_severity, severity);
                    }
                }
            }

            Texture2D image = max_severity == 2
                          ? Textures.box_red
                          : max_severity == 1
                          ? Textures.box_yellow
                          : Textures.box_white;

            p.AddRightIcon(image, string.Join("\n", tooltips.ToArray()));
        }
Exemplo n.º 13
0
 public static void PostMultipleRunsMessage(string title, string vesselName)
 {
     Message.Post(Lib.Color("yellow", "ALREADY RUNNING", true), "Can't start " + title + " a second time on vessel " + vesselName);
 }
Exemplo n.º 14
0
        public void Update()
        {
            var exp = Science.Experiment(experiment_id);

            // in flight
            if (Lib.IsFlight())
            {
                Vessel v = FlightGlobals.ActiveVessel;
                if (v == null || EVA.IsDead(v))
                {
                    return;
                }

                // get info from cache
                Vessel_info vi = Cache.VesselInfo(vessel);

                // do nothing if vessel is invalid
                if (!vi.is_valid)
                {
                    return;
                }

                var sampleSize = exp.max_amount;
                var eta        = data_rate < double.Epsilon || Done(exp, dataSampled) ? " done" : " " + Lib.HumanReadableCountdown((sampleSize - dataSampled) / data_rate);

                // update ui
                var title = Lib.Ellipsis(exp.name, Styles.ScaleStringLength(24));
                if (scienceValue > 0.1)
                {
                    title += " •<b>" + scienceValue.ToString("F1") + "</b>";
                }

                string statusString = string.Empty;
                switch (state)
                {
                case State.ISSUE: statusString = Lib.Color("yellow", issue); break;

                case State.RUNNING: statusString = Lib.HumanReadablePerc(dataSampled / sampleSize) + eta; break;

                case State.WAITING: statusString = "waiting" + eta; break;

                case State.STOPPED: statusString = "stopped"; break;
                }

                Events["Toggle"].guiName = Lib.StatusToggle(title, statusString);
                Events["Toggle"].active  = (prepare_cs == null || didPrepare);

                Events["Prepare"].guiName = Lib.BuildString("Prepare <b>", exp.name, "</b>");
                Events["Prepare"].active  = !didPrepare && prepare_cs != null && string.IsNullOrEmpty(last_subject_id);

                Events["Reset"].guiName = Lib.BuildString("Reset <b>", exp.name, "</b>");
                // we need a reset either if we have recorded data or did a setup
                bool resetActive = (reset_cs != null || prepare_cs != null) && !string.IsNullOrEmpty(last_subject_id);
                Events["Reset"].active = resetActive;

                if (issue.Length > 0 && hide_when_unavailable && issue != insufficient_storage)
                {
                    Events["Toggle"].active = false;
                }
            }
            // in the editor
            else if (Lib.IsEditor())
            {
                // update ui
                Events["Toggle"].guiName = Lib.StatusToggle(exp.name, recording ? "recording" : "stopped");
                Events["Reset"].active   = false;
                Events["Prepare"].active = false;
            }
        }
Exemplo n.º 15
0
        /// <summary>
        /// parts that have experiments can't get their module info (what is shown in the VAB tooltip) correctly setup
        /// because the ExperimentInfo database isn't available at loading time, so we recompile their info manually.
        /// </summary>
        public void SetupPrefabs()
        {
            if (PartLoader.LoadedPartsList == null)
            {
                Lib.Log("Dazed and confused: PartLoader.LoadedPartsList == null");
                return;
            }

            foreach (AvailablePart ap in PartLoader.LoadedPartsList)
            {
                if (ap == null || ap.partPrefab == null)
                {
                    Lib.Log("AvailablePart is null or without prefab: " + ap);
                    continue;
                }

                bool partHasExperimentModule = false;

                foreach (PartModule module in ap.partPrefab.Modules)
                {
                    if (module is Experiment expModule)
                    {
                        if (expModule.experiment_id == ExperimentId)
                        {
                            expModule.ExpInfo       = this;                       // works inside the ExperimentInfo ctor, but make sure it's called at the end of it.
                            partHasExperimentModule = true;

                            // get module info for the ExperimentInfo, once
                            if (string.IsNullOrEmpty(ModuleInfo))
                            {
                                ModuleInfo  = Lib.Color(Title, Lib.Kolor.Cyan, true);
                                ModuleInfo += "\n";
                                ModuleInfo += expModule.GetInfo();
                            }
                        }
                    }

                    if (!string.IsNullOrEmpty(ModuleInfo))
                    {
                        continue;
                    }

                    if (module is ModuleScienceExperiment stockExpModule)
                    {
                        if (stockExpModule.experimentID == ExperimentId)
                        {
                            ModuleInfo  = Lib.Color(Title, Lib.Kolor.Cyan, true);
                            ModuleInfo += "\nData size: ";
                            ModuleInfo += Lib.HumanReadableDataSize(DataSize);
                            if (stockExpModule.xmitDataScalar < Science.maxXmitDataScalarForSample)
                            {
                                ModuleInfo += "\nWill generate a sample.";
                                ModuleInfo += "\nSample size: ";
                                ModuleInfo += Lib.HumanReadableSampleSize(DataSize);
                            }
                            ModuleInfo += "\n\n";
                            ModuleInfo += Lib.Color("Situations:\n", Lib.Kolor.Cyan, true);

                            foreach (string s in AvailableSituations())
                            {
                                ModuleInfo += Lib.BuildString("• <b>", s, "</b>\n");
                            }

                            ModuleInfo += "\n";
                            ModuleInfo += stockExpModule.GetInfo();
                        }
                    }

#if !KSP15_16
                    else if (module is ModuleGroundExperiment groundExpModule)
                    {
                        if (groundExpModule.experimentId == ExperimentId)
                        {
                            ModuleInfo  = Lib.Color(Title, Lib.Kolor.Cyan, true);
                            ModuleInfo += "\nData size: ";
                            ModuleInfo += Lib.HumanReadableDataSize(DataSize);
                            ModuleInfo += "\n\n";
                            ModuleInfo += groundExpModule.GetInfo();
                        }
                    }
#endif
                }

                // special cases
                if (ExperimentId == "asteroidSample")
                {
                    ModuleInfo  = "Asteroid samples can be taken by kerbals on EVA";
                    ModuleInfo += "\nSample size: ";
                    ModuleInfo += Lib.HumanReadableSampleSize(DataSize);
                    ModuleInfo += "\nSample mass: ";
                    ModuleInfo += Lib.HumanReadableMass(DataSize * Settings.AsteroidSampleMassPerMB);
                }
#if !KSP15_16
                else if (IsROC)
                {
                    string        rocType = ExperimentId.Substring(ExperimentId.IndexOf('_') + 1);
                    ROCDefinition rocDef  = ROCManager.Instance.rocDefinitions.Find(p => p.type == rocType);
                    if (rocDef != null)
                    {
                        ModuleInfo  = Lib.Color(rocDef.displayName, Lib.Kolor.Cyan, true);
                        ModuleInfo += "\n- Analyse with a scanner arm";
                        ModuleInfo += "\n  Data size: ";
                        ModuleInfo += Lib.HumanReadableDataSize(DataSize);

                        if (rocDef.smallRoc)
                        {
                            ModuleInfo += "\n- Collectable on EVA as a sample";
                            ModuleInfo += "\nSample size: ";
                            ModuleInfo += Lib.HumanReadableSampleSize(DataSize);
                        }
                        else
                        {
                            ModuleInfo += "\n- Can't be collected on EVA";
                        }

                        foreach (RocCBDefinition body in rocDef.myCelestialBodies)
                        {
                            ModuleInfo += Lib.Color("\n\nFound on " + body.name + "'s :", Lib.Kolor.Cyan, true);
                            foreach (string biome in body.biomes)
                            {
                                ModuleInfo += "\n- ";
                                ModuleInfo += biome;
                            }
                        }
                    }
                }
#endif


                if (partHasExperimentModule && !ap.name.StartsWith("kerbalEVA"))
                {
                    ap.moduleInfos.Clear();
                    ap.resourceInfos.Clear();
                    try
                    {
                        Lib.ReflectionCall(PartLoader.Instance, "CompilePartInfo", new Type[] { typeof(AvailablePart), typeof(Part) }, new object[] { ap, ap.partPrefab });
                    }
                    catch (Exception ex)
                    {
                        Lib.Log("Could not patch the moduleInfo for part " + ap.name + " - " + ex.Message + "\n" + ex.StackTrace);
                    }
                }
            }
        }
Exemplo n.º 16
0
        static void Render_crew(Panel p, List <ProtoCrewMember> crew)
        {
            // do nothing if there isn't a crew, or if there are no rules
            if (crew.Count == 0 || Profile.rules.Count == 0)
            {
                return;
            }

            // panel section
            p.AddSection(Local.TELEMETRY_VITALS);            //"VITALS"

            // for each crew
            foreach (ProtoCrewMember kerbal in crew)
            {
                // get kerbal data from DB
                KerbalData kd = DB.Kerbal(kerbal.name);

                // analyze issues
                UInt32 health_severity = 0;
                UInt32 stress_severity = 0;

                // generate tooltip
                List <string> tooltips = new List <string>();
                foreach (Rule r in Profile.rules)
                {
                    // get rule data
                    RuleData rd = kd.Rule(r.name);

                    // add to the tooltip
                    tooltips.Add(Lib.BuildString("<b>", Lib.HumanReadablePerc(rd.problem / r.fatal_threshold), "</b>\t", r.title));

                    // analyze issue
                    if (rd.problem > r.danger_threshold)
                    {
                        if (!r.breakdown)
                        {
                            health_severity = Math.Max(health_severity, 2);
                        }
                        else
                        {
                            stress_severity = Math.Max(stress_severity, 2);
                        }
                    }
                    else if (rd.problem > r.warning_threshold)
                    {
                        if (!r.breakdown)
                        {
                            health_severity = Math.Max(health_severity, 1);
                        }
                        else
                        {
                            stress_severity = Math.Max(stress_severity, 1);
                        }
                    }
                }
                string tooltip = Lib.BuildString("<align=left />", String.Join("\n", tooltips.ToArray()));

                // generate kerbal name
                string name = kerbal.name.ToLower().Replace(" kerman", string.Empty);

                // render selectable title
                p.AddContent(Lib.Ellipsis(name, Styles.ScaleStringLength(30)), kd.disabled ? Lib.Color(Local.TELEMETRY_HYBERNATED, Lib.Kolor.Cyan) : string.Empty);                //"HYBERNATED"
                p.AddRightIcon(health_severity == 0 ? Textures.health_white : health_severity == 1 ? Textures.health_yellow : Textures.health_red, tooltip);
                p.AddRightIcon(stress_severity == 0 ? Textures.brain_white : stress_severity == 1 ? Textures.brain_yellow : Textures.brain_red, tooltip);
            }
        }
Exemplo n.º 17
0
        static void Render_supplies(Panel p, Vessel v, VesselData vd, VesselResources resources)
        {
            int supplies = 0;

            // for each supply
            foreach (Supply supply in Profile.supplies)
            {
                // get resource info
                ResourceInfo res = resources.GetResource(v, supply.resource);

                // only show estimate if the resource is present
                if (res.Capacity <= 1e-10)
                {
                    continue;
                }

                // render panel title, if not done already
                if (supplies == 0)
                {
                    p.AddSection(Local.TELEMETRY_SUPPLIES);                               //"SUPPLIES"
                }
                // determine label
                var    resource = PartResourceLibrary.Instance.resourceDefinitions[supply.resource];
                string label    = Lib.SpacesOnCaps(resource.displayName).ToLower();

                StringBuilder sb = new StringBuilder();

                sb.Append("<align=left />");
                if (res.AverageRate != 0.0)
                {
                    sb.Append(Lib.Color(res.AverageRate > 0.0,
                                        Lib.BuildString("+", Lib.HumanReadableRate(Math.Abs(res.AverageRate))), Lib.Kolor.PosRate,
                                        Lib.BuildString("-", Lib.HumanReadableRate(Math.Abs(res.AverageRate))), Lib.Kolor.NegRate,
                                        true));
                }
                else
                {
                    sb.Append("<b>");
                    sb.Append(Local.TELEMETRY_nochange);                    //no change
                    sb.Append("</b>");
                }

                if (res.AverageRate < 0.0 && res.Level < 0.0001)
                {
                    sb.Append(" <i>");
                    sb.Append(Local.TELEMETRY_empty);                    //(empty)
                    sb.Append("</i>");
                }
                else if (res.AverageRate > 0.0 && res.Level > 0.9999)
                {
                    sb.Append(" <i>");
                    sb.Append(Local.TELEMETRY_full);                    //(full)
                    sb.Append("</i>");
                }
                else
                {
                    sb.Append("   ");                  // spaces to prevent alignement issues
                }
                sb.Append("\t");
                sb.Append(res.Amount.ToString("F1"));
                sb.Append("/");
                sb.Append(res.Capacity.ToString("F1"));
                sb.Append(" (");
                sb.Append(res.Level.ToString("P0"));
                sb.Append(")");

                List <SupplyData.ResourceBrokerRate> brokers = vd.Supply(supply.resource).ResourceBrokers;
                if (brokers.Count > 0)
                {
                    sb.Append("\n<b>------------    \t------------</b>");
                    foreach (SupplyData.ResourceBrokerRate rb in brokers)
                    {
                        sb.Append("\n");
                        sb.Append(Lib.Color(rb.rate > 0.0,
                                            Lib.BuildString("+", Lib.HumanReadableRate(Math.Abs(rb.rate)), "   "), Lib.Kolor.PosRate,             // spaces to mitigate alignement issues
                                            Lib.BuildString("-", Lib.HumanReadableRate(Math.Abs(rb.rate)), "   "), Lib.Kolor.NegRate,             // spaces to mitigate alignement issues
                                            true));
                        sb.Append("\t");
                        sb.Append(rb.broker.Title);
                    }
                }

                string rate_tooltip = sb.ToString();

                // finally, render resource supply
                p.AddContent(label, Lib.HumanReadableDuration(res.DepletionTime()), rate_tooltip);
                ++supplies;
            }
        }
Exemplo n.º 18
0
        public static void TelemetryPanel(this Panel p, Vessel v)
        {
            // avoid corner-case when this is called in a lambda after scene changes
            v = FlightGlobals.FindVessel(v.id);

            // if vessel doesn't exist anymore, leave the panel empty
            if (v == null)
            {
                return;
            }

            // get vessel data
            VesselData vd = v.KerbalismData();

            // if not a valid vessel, leave the panel empty
            if (!vd.IsSimulated)
            {
                return;
            }

            // set metadata
            p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(20)), " ", Lib.Color(Local.TELEMETRY_title, Lib.Kolor.LightGrey)));            //"TELEMETRY"
            p.Width(Styles.ScaleWidthFloat(355.0f));
            p.paneltype = Panel.PanelType.telemetry;

            // time-out simulation
            if (p.Timeout(vd))
            {
                return;
            }

            // get resources
            VesselResources resources = ResourceCache.Get(v);

            // get crew
            var crew = Lib.CrewList(v);

            // draw the content
            Render_crew(p, crew);
            if (Features.Science)
            {
                Render_science(p, v, vd);
            }
            Render_greenhouse(p, vd);
            Render_supplies(p, v, vd, resources);
            Render_habitat(p, v, vd);
            Render_environment(p, v, vd);

            // collapse eva kerbal sections into one
            if (v.isEVA)
            {
                p.Collapse(Local.TELEMETRY_EVASUIT);                     //"EVA SUIT"
            }
        }
Exemplo n.º 19
0
        void Indicator_signal(Panel p, Vessel v, VesselData vd)
        {
            ConnectionInfo conn = vd.Connection;

            // signal strength
            var    strength   = Math.Ceiling(conn.strength * 10000) / 10000;
            string signal_str = strength > 0.001 ? Lib.HumanReadablePerc(strength, "F2") : Lib.Color(Lib.Italic(Local.Generic_NO), Lib.Kolor.Orange);

            // target name
            string target_str = conn.linked ? conn.target_name : Local.Generic_NONE;

            // transmitting info
            string comms_str;

            if (!conn.linked)
            {
                comms_str = Local.Generic_NOTHING;
            }
            else if (vd.filesTransmitted.Count == 0)
            {
                comms_str = Local.UI_telemetry;
            }
            else
            {
                comms_str = Lib.BuildString(vd.filesTransmitted.Count.ToString(), vd.filesTransmitted.Count > 1 ? " files" : " file");
            }

            // create tooltip
            string tooltip = Lib.BuildString
                             (
                "<align=left />",
                String.Format("{0,-14}\t<b>{1}</b>\n", Local.UI_DSNconnected, conn.linked ?
                              Lib.Color(Local.Generic_YES, Lib.Kolor.Green) : Lib.Color(Lib.Italic(Local.Generic_NO), Lib.Kolor.Orange)),
                String.Format("{0,-14}\t<b>{1}</b>\n", Local.UI_sciencerate, Lib.HumanReadableDataRate(conn.rate)),
                String.Format("{0,-14}\t<b>{1}</b>\n", Local.UI_strength, signal_str),
                String.Format("{0,-14}\t<b>{1}</b>\n", Local.UI_target, target_str),
                String.Format("{0,-14}\t<b>{1}</b>", Local.UI_transmitting, comms_str)
                             );

            // create icon status
            Texture2D image = Textures.signal_red;

            switch (conn.status)
            {
            case LinkStatus.direct_link:
                image = conn.strength > 0.05 ? Textures.signal_white : Textures.iconSwitch(Textures.signal_yellow, image);                           // or 5% signal strength
                break;

            case LinkStatus.indirect_link:
                image    = conn.strength > 0.05 ? Textures.signal_white : Textures.iconSwitch(Textures.signal_yellow, image);                        // or 5% signal strength
                tooltip += Lib.Color("\n" + Local.UI_Signalrelayed, Lib.Kolor.Yellow);
                break;

            case LinkStatus.plasma:
                tooltip += Lib.Color(Lib.Italic("\n" + Local.UI_Plasmablackout), Lib.Kolor.Red);
                break;

            case LinkStatus.storm:
                tooltip += Lib.Color(Lib.Italic("\n" + Local.UI_Stormblackout), Lib.Kolor.Red);
                break;
            }

            p.AddRightIcon(image, tooltip, () => UI.Open((p2) => p2.ConnMan(v)));
        }
Exemplo n.º 20
0
        public void Update()
        {
            // in flight
            if (Lib.IsFlight())
            {
                Vessel v = FlightGlobals.ActiveVessel;
                if (v == null || EVA.IsDead(v))
                {
                    return;
                }

                // get info from cache
                Vessel_info vi = Cache.VesselInfo(vessel);

                // do nothing if vessel is invalid
                if (!vi.is_valid)
                {
                    return;
                }

                var sampleSize      = (exp.scienceCap * exp.dataScale);
                var recordedPercent = Lib.HumanReadablePerc(dataSampled / sampleSize);
                var eta             = data_rate < double.Epsilon || dataSampled >= sampleSize ? " done" : " T-" + Lib.HumanReadableDuration((sampleSize - dataSampled) / data_rate);

                // update ui
                Events["Toggle"].guiName = Lib.StatusToggle(exp.experimentTitle, !recording ? "stopped"
                                                                            : Lib.Color(issue.Length > 0 ? "#ffff00":"", Lib.HumanReadablePerc(dataSampled / sampleSize) + "..."));
                Events["Toggle"].active = (prepare_cs == null || didPrepare);

                Events["Prepare"].guiName = Lib.BuildString("Prepare <b>", exp.experimentTitle, "</b>");
                Events["Prepare"].active  = !didPrepare && prepare_cs != null && string.IsNullOrEmpty(last_subject_id);

                Events["Reset"].guiName = Lib.BuildString("Reset <b>", exp.experimentTitle, "</b>");
                // we need a reset either if we have recorded data or did a setup
                bool resetActive = sample_mass < float.Epsilon && (reset_cs != null || prepare_cs != null) && !string.IsNullOrEmpty(last_subject_id);
                Events["Reset"].active = resetActive;

                Fields["ExperimentStatus"].guiName   = exp.experimentTitle;
                Fields["ExperimentStatus"].guiActive = true;

                if (issue.Length > 0)
                {
                    ExperimentStatus = Lib.BuildString("<color=#ffff00>", issue, "</color>");
                }
                else if (dataSampled > 0)
                {
                    string a = string.Empty;
                    string b = string.Empty;

                    if (sample_mass < float.Epsilon)
                    {
                        a = Lib.HumanReadableDataSize(dataSampled);
                        b = Lib.HumanReadableDataSize(sampleSize);
                    }
                    else
                    {
                        a = Lib.SampleSizeToSlots(dataSampled).ToString();
                        b = Lib.HumanReadableSampleSize(sampleSize);

                        if (remainingSampleMass > double.Epsilon)
                        {
                            b += " " + Lib.HumanReadableMass(remainingSampleMass) + " left";
                        }
                    }

                    ExperimentStatus = Lib.BuildString(a, "/", b, eta);
                }
                else
                {
                    var size = sample_mass < double.Epsilon ? Lib.HumanReadableDataSize(sampleSize) : Lib.HumanReadableSampleSize(sampleSize);
                    ExperimentStatus = Lib.BuildString("ready ", size, " in ", Lib.HumanReadableDuration(sampleSize / data_rate));
                }
            }
            // in the editor
            else if (Lib.IsEditor())
            {
                // update ui
                Events["Toggle"].guiName = Lib.StatusToggle(exp.experimentTitle, recording ? "recording" : "stopped");
                Events["Reset"].active   = false;
                Events["Prepare"].active = false;
            }
        }
Exemplo n.º 21
0
 public static void PostMultipleRunsMessage(string title)
 {
     Message.Post(Lib.Color("red", "ALREADY RUNNING", true), "Can't start " + title + " a second time on the same vessel");
 }
Exemplo n.º 22
0
        public static void Body_info(this Panel p)
        {
            // only show in mapview
            if (!MapView.MapIsEnabled)
            {
                return;
            }

            // only show if there is a selected body and that body is not the sun
            CelestialBody body = Lib.MapViewSelectedBody();

            if (body == null || (Lib.IsSun(body) && !Features.Radiation))
            {
                return;
            }

            // calculate radiation at body surface
            double surfaceRadiation = Radiation.ComputeSurface(body, Sim.GammaTransparency(body, 0.0));

            // for all bodies except sun(s)
            if (!Lib.IsSun(body))
            {
                CelestialBody mainSun;
                Vector3d      sun_dir;
                double        sun_dist;
                double        solar_flux = Sim.SolarFluxAtBody(body, false, out mainSun, out sun_dir, out sun_dist);
                solar_flux *= Sim.AtmosphereFactor(body, 0.7071);

                // calculate simulation values
                double albedo_flux = Sim.AlbedoFlux(body, body.position + sun_dir * body.Radius);
                double body_flux   = Sim.BodyFlux(body, 0.0);
                double total_flux  = solar_flux + albedo_flux + body_flux + Sim.BackgroundFlux();
                double temperature = body.atmosphere ? body.GetTemperature(0.0) : Sim.BlackBodyTemperature(total_flux);

                // calculate night-side temperature
                double total_flux_min  = Sim.AlbedoFlux(body, body.position - sun_dir * body.Radius) + body_flux + Sim.BackgroundFlux();
                double temperature_min = Sim.BlackBodyTemperature(total_flux_min);

                // surface panel
                string temperature_str = body.atmosphere
                                  ? Lib.HumanReadableTemp(temperature)
                                  : Lib.BuildString(Lib.HumanReadableTemp(temperature_min), " / ", Lib.HumanReadableTemp(temperature));
                p.AddSection(Local.BodyInfo_SURFACE);                                      //"SURFACE"
                p.AddContent(Local.BodyInfo_temperature, temperature_str);                 //"temperature"
                p.AddContent(Local.BodyInfo_solarflux, Lib.HumanReadableFlux(solar_flux)); //"solar flux"
                if (Features.Radiation)
                {
                    p.AddContent(Local.BodyInfo_radiation, Lib.HumanReadableRadiation(surfaceRadiation));                                    //"radiation"
                }
                // atmosphere panel
                if (body.atmosphere)
                {
                    p.AddSection(Local.BodyInfo_ATMOSPHERE);                                                                                      //"ATMOSPHERE"
                    p.AddContent(Local.BodyInfo_breathable, Sim.Breathable(body) ? Local.BodyInfo_breathable_yes : Local.BodyInfo_breathable_no); //"breathable""yes""no"
                    p.AddContent(Local.BodyInfo_lightabsorption, Lib.HumanReadablePerc(1.0 - Sim.AtmosphereFactor(body, 0.7071)));                //"light absorption"
                    if (Features.Radiation)
                    {
                        p.AddContent(Local.BodyInfo_gammaabsorption, Lib.HumanReadablePerc(1.0 - Sim.GammaTransparency(body, 0.0)));                                        //"gamma absorption"
                    }
                }
            }

            // radiation panel
            if (Features.Radiation)
            {
                p.AddSection(Local.BodyInfo_RADIATION);                //"RADIATION"

                string inner, outer, pause;
                double activity, cycle;
                RadiationLevels(body, out inner, out outer, out pause, out activity, out cycle);

                if (Storm.sun_observation_quality > 0.5 && activity > -1)
                {
                    string title = Local.BodyInfo_solaractivity;                    //"solar activity"

                    if (Storm.sun_observation_quality > 0.7)
                    {
                        title = Lib.BuildString(title, ": ", Lib.Color(Local.BodyInfo_stormcycle.Format(Lib.HumanReadableDuration(cycle)), Lib.Kolor.LightGrey));                        // <<1>> cycle
                    }

                    p.AddContent(title, Lib.HumanReadablePerc(activity));
                }

                if (Storm.sun_observation_quality > 0.8)
                {
                    p.AddContent(Local.BodyInfo_radiationonsurface, Lib.HumanReadableRadiation(surfaceRadiation));                    //"radiation on surface:"
                }

                p.AddContent(Lib.BuildString(Local.BodyInfo_innerbelt, " ", Lib.Color(inner, Lib.Kolor.LightGrey)),                                                                                           //"inner belt: "
                             Radiation.show_inner ? Lib.Color(Local.BodyInfo_show, Lib.Kolor.Green) : Lib.Color(Local.BodyInfo_hide, Lib.Kolor.Red), string.Empty, () => p.Toggle(ref Radiation.show_inner)); //"show""hide"
                p.AddContent(Lib.BuildString(Local.BodyInfo_outerbelt, " ", Lib.Color(outer, Lib.Kolor.LightGrey)),                                                                                           //"outer belt: "
                             Radiation.show_outer ? Lib.Color(Local.BodyInfo_show, Lib.Kolor.Green) : Lib.Color(Local.BodyInfo_hide, Lib.Kolor.Red), string.Empty, () => p.Toggle(ref Radiation.show_outer)); //"show""hide"
                p.AddContent(Lib.BuildString(Local.BodyInfo_magnetopause, " ", Lib.Color(pause, Lib.Kolor.LightGrey)),                                                                                        //"magnetopause: "
                             Radiation.show_pause ? Lib.Color(Local.BodyInfo_show, Lib.Kolor.Green) : Lib.Color(Local.BodyInfo_hide, Lib.Kolor.Red), string.Empty, () => p.Toggle(ref Radiation.show_pause)); //"show""hide"
            }

            // explain the user how to toggle the BodyInfo window
            p.AddContent(string.Empty);
            p.AddContent("<i>" + Local.BodyInfo_BodyInfoToggleHelp.Format("<b>B</b>") + "</i>");            //"Press <<1>> to open this window again"

            // set metadata
            p.Title(Lib.BuildString(Lib.Ellipsis(body.bodyName, Styles.ScaleStringLength(24)), " ", Lib.Color(Local.BodyInfo_title, Lib.Kolor.LightGrey)));            //"BODY INFO"
        }
Exemplo n.º 23
0
        bool Render_vessel(Panel p, Vessel v, bool selected = false)
        {
            // get vessel info
            Vessel_info vi = Cache.VesselInfo(v);

            // skip invalid vessels
            if (!vi.is_valid)
            {
                return(false);
            }

            // get data from db
            VesselData vd = DB.Vessel(v);

            // get vessel crew
            List <ProtoCrewMember> crew = Lib.CrewList(v);

            // get vessel name
            string vessel_name = v.isEVA ? crew[0].name : v.vesselName;

            // get body name
            string body_name = v.mainBody.name.ToUpper();

            // skip filtered vessels
            if (!Filter_match(v.vesselType, vd.group + " " + body_name + " " + vessel_name))
            {
                return(false);
            }

            // render entry
            p.AddHeader
            (
                Lib.BuildString("<b>",
                                Lib.Ellipsis(vessel_name, Styles.ScaleStringLength(((page == MonitorPage.data || page == MonitorPage.log || selected_id == Guid.Empty) && !Lib.IsFlight()) ? 45 : 25)),
                                "</b> <size=", Styles.ScaleInteger(9).ToString(), ">", Lib.Color("#cccccc", Lib.Ellipsis(body_name, Styles.ScaleStringLength(8))), "</size>"),
                string.Empty,
                () => { selected_id = selected_id != v.id ? v.id : Guid.Empty; }
            );

            // vessel type icon
            if (!selected)
            {
                p.SetIcon(GetVesselTypeIcon(v.vesselType), v.vesselType.displayDescription(), () => { selected_id = selected_id != v.id ? v.id : Guid.Empty; });
            }
            else
            {
                if (FlightGlobals.ActiveVessel != v)
                {
                    if (Lib.IsFlight())
                    {
                        p.SetIcon(GetVesselTypeIcon(v.vesselType), "Go to vessel!", () => Lib.Popup
                                      ("Warning!",
                                      Lib.BuildString("Do you really want go to ", vessel_name, " vessel?"),
                                      new DialogGUIButton("Go", () => { GotoVessel.JumpToVessel(v); }),
                                      new DialogGUIButton("Target", () => { GotoVessel.SetVesselAsTarget(v); }),
                                      new DialogGUIButton("Stay", () => { })));
                    }
                    else
                    {
                        p.SetIcon(GetVesselTypeIcon(v.vesselType), "Go to vessel!", () => Lib.Popup
                                      ("Warning!",
                                      Lib.BuildString("Do you really want go to ", vessel_name, " vessel?"),
                                      new DialogGUIButton("Go", () => { GotoVessel.JumpToVessel(v); }),
                                      new DialogGUIButton("Stay", () => { })));
                    }
                }
                else
                {
                    p.SetIcon(GetVesselTypeIcon(v.vesselType), v.vesselType.displayDescription(), () => { });
                }
            }

            // problem indicator
            Indicator_problems(p, v, vi, crew);

            // battery indicator
            Indicator_ec(p, v, vi);

            // supply indicator
            if (Features.Supplies)
            {
                Indicator_supplies(p, v, vi);
            }

            // reliability indicator
            if (Features.Reliability)
            {
                Indicator_reliability(p, v, vi);
            }

            // signal indicator
            if (API.Comm.handlers.Count > 0 || HighLogic.fetch.currentGame.Parameters.Difficulty.EnableCommNet)
            {
                Indicator_signal(p, v, vi);
            }

            // done
            return(true);
        }
Exemplo n.º 24
0
        // analyze a sample
        private static Status Analyze(Vessel v, SubjectData subject, double amount)
        {
            Sample sample      = null;
            Drive  sampleDrive = null;

            foreach (var d in Drive.GetDrives(v, true))
            {
                if (d.samples.ContainsKey(subject) && d.samples[subject].analyze)
                {
                    sample      = d.samples[subject];
                    sampleDrive = d;
                    break;
                }
            }

            bool completed = false;

            if (sample != null)
            {
                completed = amount > sample.size;
                amount    = Math.Min(amount, sample.size);
            }

            Drive fileDrive = Drive.FileDrive(v.KerbalismData(), amount);

            if (fileDrive == null)
            {
                return(Status.NO_STORAGE);
            }

            if (sample != null)
            {
                bool recorded = fileDrive.Record_file(subject, amount, false);

                double massRemoved = 0.0;
                if (recorded)
                {
                    massRemoved = sampleDrive.Delete_sample(subject, amount);
                }
                else
                {
                    Message.Post(
                        Lib.Color(Lib.BuildString(Localizer.Format("#KERBALISM_Laboratory_Analysis"), " stopped"), Lib.Kolor.Red),
                        "Not enough space on hard drive"
                        );

                    return(Status.NO_STORAGE);
                }

                // return sample mass to experiment if needed
                if (massRemoved > 0.0)
                {
                    RestoreSampleMass(v, subject, massRemoved);
                }
            }

            // if the analysis is completed
            if (completed)
            {
                if (!PreferencesScience.Instance.analyzeSamples)
                {
                    // only inform the user if auto-analyze is turned off
                    // otherwise we could be spamming "Analysis complete" messages
                    Message.Post(Lib.BuildString(Lib.Color(Localizer.Format("#KERBALISM_Laboratory_Analysis"), Lib.Kolor.Science, true), "\n",
                                                 Localizer.Format("#KERBALISM_Laboratory_Analyzed", Lib.Bold(v.vesselName), Lib.Bold(subject.FullTitle))), localized_results);
                }

                if (PreferencesScience.Instance.transmitScience)
                {
                    fileDrive.Send(subject.Id, true);
                }

                // record landmark event
                if (!Lib.Landed(v))
                {
                    DB.landmarks.space_analysis = true;
                }
            }

            return(Status.RUNNING);
        }
        /// <summary>
        /// parts that have experiments can't get their module info (what is shown in the VAB tooltip) correctly setup
        /// because the ExperimentInfo database isn't available at loading time, so we recompile their info manually.
        /// </summary>
        public void CompileModuleInfos()
        {
            if (PartLoader.LoadedPartsList == null)
            {
                Lib.Log("Dazed and confused: PartLoader.LoadedPartsList == null");
                return;
            }

            foreach (AvailablePart ap in PartLoader.LoadedPartsList)
            {
                if (ap == null || ap.partPrefab == null)
                {
                    Lib.Log("AvailablePart is null or without prefab: " + ap);
                    continue;
                }

                foreach (PartModule module in ap.partPrefab.Modules)
                {
                    if (module is Experiment expModule)
                    {
                        // don't show configurable experiments
                        if (!expModule.isConfigurable && expModule.experiment_id == ExperimentId)
                        {
                            expModule.ExpInfo = this;

                            // get module info for the ExperimentInfo, once
                            if (string.IsNullOrEmpty(ModuleInfo))
                            {
                                ModuleInfo  = Lib.Color(Title, Lib.Kolor.Cyan, true);
                                ModuleInfo += "\n";
                                ModuleInfo += expModule.GetInfo();
                            }
                        }
                    }

                    if (!string.IsNullOrEmpty(ModuleInfo))
                    {
                        continue;
                    }

                    if (module is ModuleScienceExperiment stockExpModule)
                    {
                        if (stockExpModule.experimentID == ExperimentId)
                        {
                            ModuleInfo  = Lib.Color(Title, Lib.Kolor.Cyan, true);
                            ModuleInfo += "\n" + Local.Experimentinfo_Datasize + ": ";                         //Data size
                            ModuleInfo += Lib.HumanReadableDataSize(DataSize);
                            if (stockExpModule.xmitDataScalar < Science.maxXmitDataScalarForSample)
                            {
                                ModuleInfo += "\n" + Local.Experimentinfo_generatesample;                              //Will generate a sample.
                                ModuleInfo += "\n" + Local.Experimentinfo_Samplesize + " ";                            //Sample size:
                                ModuleInfo += Lib.HumanReadableSampleSize(DataSize);
                            }
                            ModuleInfo += "\n\n";
                            ModuleInfo += Lib.Color(Local.Experimentinfo_Situations, Lib.Kolor.Cyan, true);                            //"Situations:\n"

                            foreach (string s in AvailableSituations())
                            {
                                ModuleInfo += Lib.BuildString("• <b>", s, "</b>\n");
                            }

                            ModuleInfo += "\n";
                            ModuleInfo += stockExpModule.GetInfo();
                        }
                    }
                    else if (module is ModuleGroundExperiment groundExpModule)
                    {
                        if (groundExpModule.experimentId == ExperimentId)
                        {
                            ModuleInfo  = Lib.Color(Title, Lib.Kolor.Cyan, true);
                            ModuleInfo += "\n" + Local.Experimentinfo_Datasize + ": ";                            //Data size
                            ModuleInfo += Lib.HumanReadableDataSize(DataSize);
                            ModuleInfo += "\n\n";
                            ModuleInfo += groundExpModule.GetInfo();
                        }
                    }
                }

                // special cases
                if (ExperimentId == "asteroidSample" || ExperimentId.StartsWith("cometSample_", StringComparison.Ordinal))
                {
                    ModuleInfo  = Local.Experimentinfo_Asteroid;                   //"Asteroid samples can be taken by kerbals on EVA"
                    ModuleInfo += "\n" + Local.Experimentinfo_Samplesize + " ";    //Sample size:
                    ModuleInfo += Lib.HumanReadableSampleSize(DataSize);
                    ModuleInfo += "\n" + Local.Experimentinfo_Samplemass + " ";    //Sample mass:
                    ModuleInfo += Lib.HumanReadableMass(DataSize * Settings.AsteroidSampleMassPerMB);
                }
                else if (IsROC)
                {
                    string        rocType = ExperimentId.Substring(ExperimentId.IndexOf('_') + 1);
                    ROCDefinition rocDef  = ROCManager.Instance.rocDefinitions.Find(p => p.type == rocType);
                    if (rocDef != null)
                    {
                        ModuleInfo  = Lib.Color(rocDef.displayName, Lib.Kolor.Cyan, true);
                        ModuleInfo += "\n- " + Local.Experimentinfo_scannerarm;                        //Analyse with a scanner arm
                        ModuleInfo += "\n  " + Local.Experimentinfo_Datasize + ": ";                   //Data size
                        ModuleInfo += Lib.HumanReadableDataSize(DataSize);

                        if (rocDef.smallRoc)
                        {
                            ModuleInfo += "\n- " + Local.Experimentinfo_smallRoc;                            //Collectable on EVA as a sample"
                            ModuleInfo += "\n" + Local.Experimentinfo_Samplesize + " ";                      //Sample size:
                            ModuleInfo += Lib.HumanReadableSampleSize(DataSize);
                        }
                        else
                        {
                            ModuleInfo += "\n- " + Local.Experimentinfo_smallRoc2;                          //Can't be collected on EVA
                        }

                        foreach (RocCBDefinition body in rocDef.myCelestialBodies)
                        {
                            ModuleInfo += Lib.Color("\n\n" + Local.Experimentinfo_smallRoc3.Format(body.name), Lib.Kolor.Cyan, true);                            //"Found on <<1>>'s :"
                            foreach (string biome in body.biomes)
                            {
                                ModuleInfo += "\n- ";
                                ModuleInfo += biome;
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 26
0
        void Indicator_signal(Panel p, Vessel v, Vessel_info vi)
        {
            ConnectionInfo conn       = vi.connection;
            bool           remotetech = RemoteTech.Enabled;

            // signal strength or when using RemoteTech signal delay
            string signal_str = remotetech ?
                                !conn.linked ? "----" : conn.strength > Double.Epsilon ? KSPUtil.dateTimeFormatter.PrintTimeStampCompact(conn.strength) : Localizer.Format("#KERBALISM_Generic_NONE") :
                                Lib.HumanReadablePerc(conn.strength, "F2");

            // target name
            string target_str = conn.linked ? conn.target_name : Localizer.Format("#KERBALISM_Generic_NONE");

            // transmitting info
            string comms_str = conn.linked ? Localizer.Format("#KERBALISM_UI_telemetry") : Localizer.Format("#KERBALISM_Generic_NOTHING");

            if (vi.transmitting.Length > 0)
            {
                ExperimentInfo exp = Science.Experiment(vi.transmitting);
                comms_str = exp.name;
            }

            // create tooltip
            string tooltip = Lib.BuildString
                             (
                "<align=left />",
                String.Format("{0,-14}\t<b>{1}</b>\n", Localizer.Format("#KERBALISM_UI_DSNconnected"), conn.linked ?
                              Lib.Color("green", Localizer.Format("#KERBALISM_Generic_YES")) : Lib.Color("#ffaa00", Lib.Italic(Localizer.Format("#KERBALISM_Generic_NO")))),
                String.Format("{0,-14}\t<b>{1}</b>\n", Localizer.Format("#KERBALISM_UI_sciencerate"), Lib.HumanReadableDataRate(conn.rate)),
                String.Format("{0,-14}\t<b>{1}</b>\n", remotetech ? Localizer.Format("#KERBALISM_UI_delay") : Localizer.Format("#KERBALISM_UI_strength"), signal_str),
                String.Format("{0,-14}\t<b>{1}</b>\n", Localizer.Format("#KERBALISM_UI_target"), target_str),
                String.Format("{0,-14}\t<b>{1}</b>", Localizer.Format("#KERBALISM_UI_transmitting"), comms_str)
                             );

            // create icon status
            Texture2D image = Icons.signal_red;

            switch (conn.status)
            {
            case LinkStatus.direct_link:
                image = remotetech ? conn.strength <15.0 ? Icons.signal_white : Icons.signal_yellow :                               // 15 seconds for RemoteTech signal delay
                                                    conn.strength> 0.05 ? Icons.signal_white : Icons.signal_yellow;                 // or 5% signal strength
                break;

            case LinkStatus.indirect_link:
                image = remotetech ? conn.strength <15.0 ? Icons.signal_white: Icons.signal_yellow :                                // 15 seconds for RemoteTech signal delay
                                                    conn.strength> 0.05 ? Icons.signal_white : Icons.signal_yellow;                 // or 5% signal strength
                tooltip += Lib.Color("yellow", "\n" + Localizer.Format("#KERBALISM_UI_Signalrelayed"));
                break;

            case LinkStatus.plasma:
                tooltip += Lib.Color("red", Lib.Italic("\n" + Localizer.Format("#KERBALISM_UI_Plasmablackout")));
                break;

            case LinkStatus.storm:
                tooltip += Lib.Color("red", Lib.Italic("\n" + Localizer.Format("#KERBALISM_UI_Stormblackout")));
                break;
            }

            p.AddIcon(image, tooltip);
        }
Exemplo n.º 27
0
        public void FixedUpdate()
        {
            if (scanner == null)
            {
                return;
            }
            if (!Features.Science)
            {
                return;
            }

            IsScanning = SCANsat.IsScanning(scanner);
            double new_coverage = SCANsat.Coverage(sensorType, vessel.mainBody);

            if (body_name == vessel.mainBody.name && new_coverage < body_coverage)
            {
                // SCANsat sometimes reports a coverage of 0, which is wrong
                new_coverage = body_coverage;
            }

            if (vessel.mainBody.name != body_name)
            {
                body_name     = vessel.mainBody.name;
                body_coverage = new_coverage;
            }
            else
            {
                double coverage_delta = new_coverage - body_coverage;
                body_coverage = new_coverage;
                var vd = DB.Vessel(vessel);

                if (IsScanning)
                {
                    Science.Generate_subject(experimentType, vessel);
                    var    subject_id = Science.Generate_subject_id(experimentType, vessel);
                    var    exp        = Science.Experiment(subject_id);
                    double size       = exp.max_amount * coverage_delta / 100.0;               // coverage is 0-100%
                    size += warp_buffer;

                    size = Drive.StoreFile(vessel, subject_id, size);
                    if (size > double.Epsilon)
                    {
                        // we filled all drives up to the brim but were unable to store everything
                        if (warp_buffer < double.Epsilon)
                        {
                            // warp buffer is empty, so lets store the rest there
                            warp_buffer = size;
                            size        = 0;
                        }
                        else
                        {
                            // warp buffer not empty. that's ok if we didn't get new data
                            if (coverage_delta < double.Epsilon)
                            {
                                size = 0;
                            }
                            // else we're scanning too fast. stop.
                        }

                        // cancel scanning and annoy the user
                        if (size > double.Epsilon)
                        {
                            warp_buffer = 0;
                            StopScan();
                            vd.scansat_id.Add(part.flightID);
                            Message.Post(Lib.Color("red", "Scanner halted", true), "Scanner halted on <b>" + vessel.vesselName + "</b>. No storage left on vessel.");
                        }
                    }
                }
                else if (vd.scansat_id.Contains(part.flightID))
                {
                    var vi = Cache.VesselInfo(vessel);
                    if (vi.free_capacity / vi.total_capacity > 0.9)                    // restart when 90% of capacity is available
                    {
                        StartScan();
                        vd.scansat_id.Remove(part.flightID);
                        if (vd.cfg_ec)
                        {
                            Message.Post(Lib.BuildString("SCANsat sensor resumed operations on <b>", vessel.vesselName, "</b>"));
                        }
                    }
                }
            }
        }
Exemplo n.º 28
0
        public void Update()
        {
            // reset panel
            panel.Clear();

            if (Lib.IsDevBuild)
            {
                panel.AddHeader(Lib.Color("KERBALISM DEV BUILD " + Lib.KerbalismDevBuild, Lib.Kolor.Orange));
            }

            // get vessel
            selected_v = selected_id == Guid.Empty ? null : FlightGlobals.FindVessel(selected_id);

            // if nothing is selected, or if the selected vessel doesn't exist
            // anymore, or if it has become invalid for whatever reason
            if (selected_v == null || !selected_v.KerbalismIsValid())
            {
                // forget the selected vessel, if any
                selected_id = Guid.Empty;

                // used to detect when no vessels are in list
                bool setup = false;

                // draw active vessel if any
                if (FlightGlobals.ActiveVessel != null)
                {
                    setup |= Render_vessel(panel, FlightGlobals.ActiveVessel);
                }

                // for each vessel
                foreach (Vessel v in FlightGlobals.Vessels)
                {
                    // skip active vessel
                    if (v == FlightGlobals.ActiveVessel)
                    {
                        continue;
                    }

                    // draw the vessel
                    setup |= Render_vessel(panel, v);
                }

                // empty vessel case
                if (!setup)
                {
                    panel.AddHeader("<i>" + Local.Monitor_novessels + "</i>");                 //no vessels
                }
            }
            // if a vessel is selected
            else
            {
                // header act as title
                Render_vessel(panel, selected_v, true);

                // update page content
                switch (page)
                {
                case MonitorPage.telemetry: panel.TelemetryPanel(selected_v); break;

                case MonitorPage.data: panel.Fileman(selected_v, true); break;                          // Using short_strings parameter to stop overlapping when inflight.

                case MonitorPage.scripts: panel.Devman(selected_v); break;

                case MonitorPage.config: panel.Config(selected_v); break;

                case MonitorPage.log: panel.Logman(selected_v); break;

                case MonitorPage.failures: panel.Failman(selected_v); break;
                }
            }
        }
Exemplo n.º 29
0
        void Indicator_signal(Panel p, Vessel v, Vessel_info vi)
        {
            ConnectionInfo conn = vi.connection;

            // signal strength
            string signal_str = conn.strength > Double.Epsilon ? Lib.HumanReadablePerc(Math.Ceiling(conn.strength * 10000) / 10000, "F2") : Lib.Color("#ffaa00", Lib.Italic(Localizer.Format("#KERBALISM_Generic_NO")));

            // target name
            string target_str = conn.linked ? conn.target_name : Localizer.Format("#KERBALISM_Generic_NONE");

            // transmitting info
            string comms_str = conn.linked ? Localizer.Format("#KERBALISM_UI_telemetry") : Localizer.Format("#KERBALISM_Generic_NOTHING");

            if (vi.transmitting.Length > 0)
            {
                ExperimentInfo exp = Science.Experiment(vi.transmitting);
                comms_str = exp.name;
            }

            // create tooltip
            string tooltip = Lib.BuildString
                             (
                "<align=left />",
                String.Format("{0,-14}\t<b>{1}</b>\n", Localizer.Format("#KERBALISM_UI_DSNconnected"), conn.linked ?
                              Lib.Color("green", Localizer.Format("#KERBALISM_Generic_YES")) : Lib.Color("#ffaa00", Lib.Italic(Localizer.Format("#KERBALISM_Generic_NO")))),
                String.Format("{0,-14}\t<b>{1}</b>\n", Localizer.Format("#KERBALISM_UI_sciencerate"), Lib.HumanReadableDataRate(conn.rate)),
                String.Format("{0,-14}\t<b>{1}</b>\n", Localizer.Format("#KERBALISM_UI_strength"), signal_str),
                String.Format("{0,-14}\t<b>{1}</b>\n", Localizer.Format("#KERBALISM_UI_target"), target_str),
                String.Format("{0,-14}\t<b>{1}</b>", Localizer.Format("#KERBALISM_UI_transmitting"), comms_str)
                             );

            // create icon status
            Texture2D image = Icons.signal_red;

            switch (conn.status)
            {
            case LinkStatus.direct_link:
                image = conn.strength > 0.05 ? Icons.signal_white : Icons.iconSwitch(Icons.signal_yellow, image);                           // or 5% signal strength
                break;

            case LinkStatus.indirect_link:
                image    = conn.strength > 0.05 ? Icons.signal_white : Icons.iconSwitch(Icons.signal_yellow, image);                        // or 5% signal strength
                tooltip += Lib.Color("yellow", "\n" + Localizer.Format("#KERBALISM_UI_Signalrelayed"));
                break;

            case LinkStatus.plasma:
                tooltip += Lib.Color("red", Lib.Italic("\n" + Localizer.Format("#KERBALISM_UI_Plasmablackout")));
                break;

            case LinkStatus.storm:
                tooltip += Lib.Color("red", Lib.Italic("\n" + Localizer.Format("#KERBALISM_UI_Stormblackout")));
                break;
            }

            p.AddIcon(image, tooltip, () => UI.Open((p2) => p2.ConnMan(v)));
        }
Exemplo n.º 30
0
        void Render_menu(Vessel v)
        {
            VesselData vd = v.KerbalismData();

            GUILayout.BeginHorizontal(Styles.entry_container);
            GUILayout.Label(new GUIContent(Lib.Color(page == MonitorPage.telemetry, " " + Local.Monitor_INFO, Lib.Kolor.Green, Lib.Kolor.None, true), Textures.small_info, Local.Monitor_INFO_desc + Local.Monitor_tooltip), config_style);            //INFO"Telemetry readings"
            if (Lib.IsClicked())
            {
                page = MonitorPage.telemetry;
            }
            else if (Lib.IsClicked(2))
            {
                if (UI.window.PanelType == Panel.PanelType.telemetry)
                {
                    UI.window.Close();
                }
                else
                {
                    UI.Open((p) => p.TelemetryPanel(v));
                }
            }
            if (Features.Science)
            {
                GUILayout.Label(new GUIContent(Lib.Color(page == MonitorPage.data, " " + Local.Monitor_DATA, Lib.Kolor.Green, Lib.Kolor.None, true), Textures.small_folder, Local.Monitor_DATA_desc + Local.Monitor_tooltip), config_style);                //DATA"Stored files and samples"
                if (Lib.IsClicked())
                {
                    page = MonitorPage.data;
                }
                else if (Lib.IsClicked(2))
                {
                    if (UI.window.PanelType == Panel.PanelType.data)
                    {
                        UI.window.Close();
                    }
                    else
                    {
                        UI.Open((p) => p.Fileman(v));
                    }
                }
            }
            if (Features.Automation)
            {
                GUILayout.Label(new GUIContent(Lib.Color(page == MonitorPage.scripts, " " + Local.Monitor_AUTO, Lib.Kolor.Green, Lib.Kolor.None, true), Textures.small_console, Local.Monitor_AUTO_desc + Local.Monitor_tooltip), config_style);                //AUTO"Control and automate components"
                if (Lib.IsClicked())
                {
                    page = MonitorPage.scripts;
                }
                else if (Lib.IsClicked(2))
                {
                    if (UI.window.PanelType == Panel.PanelType.scripts)
                    {
                        UI.window.Close();
                    }
                    else
                    {
                        UI.Open((p) => p.Devman(v));
                    }
                }
            }
            if (Features.Reliability)
            {
                GUILayout.Label(new GUIContent(Lib.Color(page == MonitorPage.failures, " " + Local.Monitor_FAILURES, Lib.Kolor.Green, Lib.Kolor.None, true), Textures.small_wrench, Local.Monitor_FAILURES_desc + Local.Monitor_tooltip), config_style);                //FAILURES"See failures and maintenance state"
                if (Lib.IsClicked())
                {
                    page = MonitorPage.failures;
                }
                else if (Lib.IsClicked(2))
                {
                    if (UI.window.PanelType == Panel.PanelType.failures)
                    {
                        UI.window.Close();
                    }
                    else
                    {
                        UI.Open((p) => p.Failman(v));
                    }
                }
            }
            if (PreferencesMessages.Instance.stockMessages != true)
            {
                GUILayout.Label(new GUIContent(Lib.Color(page == MonitorPage.log, " " + Local.Monitor_LOG, Lib.Kolor.Green, Lib.Kolor.None, true), Textures.small_notes, Local.Monitor_LOG_desc + Local.Monitor_tooltip), config_style);                //LOG"See previous notifications"
                if (Lib.IsClicked())
                {
                    page = MonitorPage.log;
                }
                else if (Lib.IsClicked(2))
                {
                    if (UI.window.PanelType == Panel.PanelType.log)
                    {
                        UI.window.Close();
                    }
                    else
                    {
                        UI.Open((p) => p.Logman(v));
                    }
                }
            }
            GUILayout.Label(new GUIContent(Lib.Color(page == MonitorPage.config, " " + Local.Monitor_CFG, Lib.Kolor.Green, Lib.Kolor.None, true), Textures.small_config, Local.Monitor_CFG_desc + Local.Monitor_tooltip), config_style);            //CFG"Configure the vessel"
            if (Lib.IsClicked())
            {
                page = MonitorPage.config;
            }
            else if (Lib.IsClicked(2))
            {
                if (UI.window.PanelType == Panel.PanelType.config)
                {
                    UI.window.Close();
                }
                else
                {
                    UI.Open((p) => p.Config(v));
                }
            }
            GUILayout.EndHorizontal();
            GUILayout.Space(Styles.ScaleFloat(10.0f));
        }