Пример #1
0
        void Indicator_EC(Panel p, Vessel v, Vessel_Info vi)
        {
            Resource_Info ec            = ResourceCache.Info(v, "ElectricCharge");
            Supply        supply        = Profile.supplies.Find(k => k.resource == "ElectricCharge");
            double        low_threshold = supply != null ? supply.low_threshold : 0.15;
            double        depletion     = ec.Depletion(vi.crew_count);

            string tooltip = Lib.BuildString
                             (
                "<align=left /><b>name\tlevel\tduration</b>\n",
                ec.level <= 0.005 ? "<color=#ff0000>" : ec.level <= low_threshold ? "<color=#ffff00>" : "<color=#cccccc>",
                "EC\t",
                Lib.HumanReadablePerc(ec.level), "\t",
                depletion <= double.Epsilon ? "depleted" : Lib.HumanReadableDuration(depletion),
                "</color>"
                             );

            Texture image = ec.level <= 0.005
        ? Icons.battery_red
        : ec.level <= low_threshold
        ? Icons.battery_yellow
        : Icons.battery_white;

            p.SetIcon(image, tooltip);
        }
Пример #2
0
        public void Update()
        {
            // in flight
            if (Lib.IsFlight())
            {
                // get info from cache
                Vessel_Info vi = Cache.VesselInfo(vessel);

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

                // update status
                Status = Telemetry_Content(vessel, vi, type);

                // if there is a pin animation
                if (pin.Length > 0)
                {
                    // still-play pin animation
                    pin_anim.Still(Telemetry_Pin(vessel, vi, type));
                }
            }
        }
Пример #3
0
        // return true if body is relevant to the player
        // - body: reference body of the planetary system
        static bool Body_is_Relevant(CelestialBody body)
        {
            // [disabled]
            // special case: home system is always relevant
            // note: we deal with the case of a planet mod setting homebody as a moon
            //if (body == Lib.PlanetarySystem(FlightGlobals.GetHomeBody())) return true;

            // for each vessel
            foreach (Vessel v in FlightGlobals.Vessels)
            {
                // if inside the system
                if (Lib.PlanetarySystem(v.mainBody) == body)
                {
                    // get info from the cache
                    Vessel_Info vi = Cache.VesselInfo(v);

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

                    // obey message config
                    if (!DB.Vessel(v).cfg_storm)
                    {
                        continue;
                    }

                    // body is relevant
                    return(true);
                }
            }
            return(false);
        }
Пример #4
0
        public static void FileMan(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 info from the cache
            Vessel_Info vi = Cache.VesselInfo(v);

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

            // set metadata
            p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, 20), " <color=#cccccc>FILE MANAGER</color>"));
            p.Width(320.0f);

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

            // get vessel drive
            Drive drive = DB.Vessel(v).drive;

            // draw data section
            p.SetSection("DATA");
            foreach (var pair in drive.files)
            {
                string filename = pair.Key;
                File   file     = pair.Value;
                Render_File(p, filename, file, drive);
            }
            if (drive.files.Count == 0)
            {
                p.SetContent("<i>no files</i>", string.Empty);
            }

            // draw samples section
            p.SetSection("SAMPLES");
            foreach (var pair in drive.samples)
            {
                string filename = pair.Key;
                Sample sample   = pair.Value;
                Render_Sample(p, filename, sample, drive);
            }
            if (drive.samples.Count == 0)
            {
                p.SetContent("<i>no samples</i>", string.Empty);
            }
        }
Пример #5
0
        public static double Evaluate(Vessel v, Vessel_Info vi, Vessel_Resources resources, List <string> modifiers)
        {
            double k = 1.0;

            foreach (string mod in modifiers)
            {
                switch (mod)
                {
                case "breathable":
                    k *= vi.breathable ? 0.0 : 1.0;
                    break;

                case "temperature":
                    k *= vi.temp_diff;
                    break;

                case "radiation":
                    k *= vi.radiation;
                    break;

                case "shielding":
                    k *= 1.0 - vi.shielding;
                    break;

                case "volume":
                    k *= vi.volume;
                    break;

                case "surface":
                    k *= vi.surface;
                    break;

                case "living_space":
                    k /= vi.living_space;
                    break;

                case "comfort":
                    k /= vi.comforts.factor;
                    break;

                case "pressure":
                    k *= vi.pressure > Settings.PressureThreshold ? 1.0 : Settings.PressureFactor;
                    break;

                case "poisoning":
                    k *= vi.poisoning > Settings.PoisoningThreshold ? 1.0 : Settings.PoisoningFactor;
                    break;

                case "per_capita":
                    k /= (double)Math.Max(vi.crew_count, 1);
                    break;

                default:
                    k *= resources.Info(v, mod).amount;
                    break;
                }
            }
            return(k);
        }
Пример #6
0
 void Problem_Sunlight(Vessel_Info info, ref List <Texture> icons, ref List <string> tooltips)
 {
     if (info.sunlight <= double.Epsilon)
     {
         icons.Add(Icons.sun_black);
         tooltips.Add("In shadow");
     }
 }
Пример #7
0
        public static void Update(Vessel v, Vessel_Info vi, VesselData vd, double elapsed_s)
        {
            // do nothing if storms are disabled
            if (!Features.SpaceWeather)
            {
                return;
            }

            // only consider vessels in interplanetary space
            if (v.mainBody.flightGlobalsIndex != 0)
            {
                return;
            }

            // skip unmanned vessels
            if (vi.crew_count == 0)
            {
                return;
            }

            // generate storm time if necessary
            if (vd.storm_time <= double.Epsilon)
            {
                vd.storm_time = Settings.StormMinTime + (Settings.StormMaxTime - Settings.StormMinTime) * Lib.RandomDouble();
            }

            // accumulate age
            vd.storm_age += elapsed_s * Storm_Frequency(vi.sun_dist);

            // if storm is over
            if (vd.storm_age > vd.storm_time && vd.storm_state == 2)
            {
                vd.storm_age   = 0.0;
                vd.storm_time  = 0.0;
                vd.storm_state = 0;

                // send message
                Message.Post(Severity.relax, Lib.BuildString("The solar storm around <b>", v.vesselName, "</b> is over"));
            }
            // if storm is in progress
            else if (vd.storm_age > vd.storm_time - Settings.StormDuration && vd.storm_state == 1)
            {
                vd.storm_state = 2;

                // send message
                Message.Post(Severity.danger, Lib.BuildString("The coronal mass ejection hit <b>", v.vesselName, "</b>"),
                             Lib.BuildString("Storm duration: ", Lib.HumanReadableDuration(TimeLeftCME(vd.storm_time, vd.storm_age))));
            }
            // if storm is incoming
            else if (vd.storm_age > vd.storm_time - Settings.StormDuration - Time_to_Impact(vi.sun_dist) && vd.storm_state == 0)
            {
                vd.storm_state = 1;

                // send message
                Message.Post(Severity.warning, Lib.BuildString("Our observatories report a coronal mass ejection directed toward <b>", v.vesselName, "</b>"),
                             Lib.BuildString("Time to impact: ", Lib.HumanReadableDuration(TimeBeforeCME(vd.storm_time, vd.storm_age))));
            }
        }
Пример #8
0
 public static bool Timeout(this Panel p, Vessel_Info vi)
 {
     if (!vi.connection.linked && vi.crew_count == 0)
     {
         p.SetHeader(msg[((int)Time.realtimeSinceStartup) % msg.Length]);
         return(true);
     }
     return(false);
 }
Пример #9
0
        // Monitoring all indicator to support life
        public static void Telemetry_Life(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 info from the cache
            Vessel_Info vi = Cache.VesselInfo(v);

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

            // set metadata
            p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, 20), " <color=#cccccc>TELEMETRY</color>"));

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

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

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

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

            // draw the content
            Render_Crew(p, crew);
            Render_Greenhouse(p, vi);
            Render_Supplies(p, v, vi, resources);
            Render_Habitat(p, v, vi);
            Render_Environment(p, v, vi);

            // collapse eva kerbal sections into one
            if (v.isEVA)
            {
                p.Collapse("EVA SUIT");
            }
        }
Пример #10
0
        // get readings value
        public static double Telemetry_Value(Vessel v, Vessel_Info vi, string type)
        {
            switch (type)
            {
            case "temperature":   return(vi.temperature);

            case "radiation":     return(vi.radiation);

            case "pressure":      return(v.mainBody.GetPressure(v.altitude));;

            case "gravioli":      return(vi.gravioli);
            }
            return(0.0);
        }
Пример #11
0
        // get readings value in [0,1] range, for pin animation
        public static double Telemetry_Pin(Vessel v, Vessel_Info vi, string type)
        {
            switch (type)
            {
            case "temperature":   return(Math.Min(vi.temperature / 11000.0, 1.0));

            case "radiation":     return(Math.Min(vi.radiation * 3600.0 / 11.0, 1.0));

            case "pressure":      return(Math.Min(v.mainBody.GetPressure(v.altitude) / Sim.PressureAtSeaLevel() / 11.0, 1.0));

            case "gravioli":      return(Math.Min(vi.gravioli, 1.0));
            }
            return(0.0);
        }
Пример #12
0
        // get readings short text info
        public static string Telemetry_Content(Vessel v, Vessel_Info vi, string type)
        {
            switch (type)
            {
            case "temperature":   return(Lib.HumanReadableTemp(vi.temperature));

            case "radiation":     return(Lib.HumanReadableRadiation(vi.radiation));

            case "pressure":      return(Lib.HumanReadablePressure(v.mainBody.GetPressure(v.altitude)));

            case "gravioli":      return(vi.gravioli < 0.33 ? "nothing here" : vi.gravioli < 0.66 ? "almost one" : "WOW!");
            }
            return(string.Empty);
        }
Пример #13
0
        void Problem_Poisoning(Vessel_Info info, ref List <Texture> icons, ref List <string> tooltips)
        {
            string poisoning_str = Lib.BuildString("CO2 level in internal atmosphere: <b>", Lib.HumanReadablePerc(info.poisoning), "</b>");

            if (info.poisoning >= 0.05)
            {
                icons.Add(Icons.recycle_red);
                tooltips.Add(poisoning_str);
            }
            else if (info.poisoning > 0.025)
            {
                icons.Add(Icons.recycle_yellow);
                tooltips.Add(poisoning_str);
            }
        }
Пример #14
0
        public static void Update(Vessel v, Vessel_Info vi, VesselData vd, double elapsed_s)
        {
            // do nothing if signal mechanic is disabled
            if (!Features.Signal && !Features.KCommNet)
            {
                return;
            }

            // get connection info
            ConnectionInfo conn = vi.connection;

            // maintain and send messages
            // - do not send messages for vessels without an antenna
            // - do not send messages during/after solar storms
            // - do not send messages for EVA kerbals
            if (conn.status != LinkStatus.no_antenna && !v.isEVA && v.situation != Vessel.Situations.PRELAUNCH)
            {
                if (!vd.msg_signal && !conn.linked)
                {
                    vd.msg_signal = true;
                    if (vd.cfg_signal && conn.status != LinkStatus.blackout)
                    {
                        string subtext = "Data transmission disabled";
                        if (vi.crew_count == 0)
                        {
                            switch (Settings.UnlinkedControl)
                            {
                            case UnlinkedCtrl.none: subtext = "Remote control disabled"; break;

                            case UnlinkedCtrl.limited: subtext = "Limited control available"; break;
                            }
                        }
                        Message.Post(Severity.warning, Lib.BuildString("Signal lost with <b>", v.vesselName, "</b>"), subtext);
                    }
                }
                else if (vd.msg_signal && conn.linked)
                {
                    vd.msg_signal = false;
                    if (vd.cfg_signal && !Storm.JustEnded(v, elapsed_s))
                    {
                        var path = conn.path;
                        Message.Post(Severity.relax, Lib.BuildString("<b>", v.vesselName, "</b> signal is back"),
                                     path.Count == 0 ? "We got a direct link with the space center" : Lib.BuildString("Relayed by <b>", path[path.Count - 1].vesselName, "</b>"));
                    }
                }
            }
        }
Пример #15
0
        // return vessel situation valid for specified experiment
        public static string Situation(Vessel v, string situations)
        {
            // shortcuts
            CelestialBody body = v.mainBody;
            Vessel_Info   vi   = Cache.VesselInfo(v);

            List <string> list = Lib.Tokenize(situations, ',');

            foreach (string sit in list)
            {
                bool b = false;
                switch (sit)
                {
                case "Surface": b = Lib.Landed(v); break;

                case "Atmosphere": b = body.atmosphere && v.altitude < body.atmosphereDepth; break;

                case "Ocean": b = body.ocean && v.altitude < 0.0; break;

                case "Space": b = body.flightGlobalsIndex != 0 && !Lib.Landed(v) && v.altitude > body.atmosphereDepth; break;

                case "AbsoluteZero": b = vi.temperature < 30.0; break;

                case "InnerBelt": b = vi.inner_belt; break;

                case "OuterBelt": b = vi.outer_belt; break;

                case "Magnetosphere": b = vi.magnetosphere; break;

                case "Thermosphere": b = vi.thermosphere; break;

                case "Exosphere": b = vi.exosphere; break;

                case "InterPlanetary": b = body.flightGlobalsIndex == 0 && !vi.interstellar; break;

                case "InterStellar": b = body.flightGlobalsIndex == 0 && vi.interstellar; break;
                }
                if (b)
                {
                    return(sit);
                }
            }
            return(string.Empty);
        }
Пример #16
0
        void Indicator_Supplies(Panel p, Vessel v, Vessel_Info vi)
        {
            List <string> tooltips     = new List <string>();
            uint          max_severity = 0;

            if (vi.crew_count > 0)
            {
                foreach (Supply supply in Profile.supplies.FindAll(k => k.resource != "ElectricCharge"))
                {
                    Resource_Info res       = ResourceCache.Info(v, supply.resource);
                    double        depletion = res.Depletion(vi.crew_count);

                    if (res.capacity > double.Epsilon)
                    {
                        if (tooltips.Count == 0)
                        {
                            tooltips.Add("<align=left /><b>name\t\tlevel\tduration</b>");
                        }

                        tooltips.Add(Lib.BuildString
                                     (
                                         res.level <= 0.005 ? "<color=#ff0000>" : res.level <= supply.low_threshold ? "<color=#ffff00>" : "<color=#cccccc>",
                                         supply.resource,
                                         supply.resource != "Ammonia" ? "\t\t" : "\t", //< hack: make ammonia fit damn it
                                         Lib.HumanReadablePerc(res.level), "\t",
                                         depletion <= double.Epsilon ? "depleted" : Lib.HumanReadableDuration(depletion),
                                         "</color>"
                                     ));

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

            Texture image = max_severity == 2
        ? Icons.box_red
        : max_severity == 1
        ? Icons.box_yellow
        : Icons.box_white;

            p.SetIcon(image, string.Join("\n", tooltips.ToArray()));
        }
Пример #17
0
        public static Vessel_Info VesselInfo(Vessel v)
        {
            // get vessel id
            UInt32 id = Lib.VesselID(v);

            // get the info from the cache, if it exist
            if (vessels.TryGetValue(id, out Vessel_Info info))
            {
                return(info);
            }

            // compute vessel info
            info = new Vessel_Info(v, id, next_inc++);

            // store vessel info in the cache
            vessels.Add(id, info);

            return(info);
        }
Пример #18
0
        void Problem_Radiation(Vessel_Info info, ref List <Texture> icons, ref List <string> tooltips)
        {
            string radiation_str = Lib.BuildString(" (<i>", (info.radiation * 60.0 * 60.0).ToString("F3"), " rad/h)</i>");

            if (info.radiation > 1.0 / 3600.0)
            {
                icons.Add(Icons.radiation_red);
                tooltips.Add(Lib.BuildString("Exposed to extreme radiation", radiation_str));
            }
            else if (info.radiation > 0.15 / 3600.0)
            {
                icons.Add(Icons.radiation_yellow);
                tooltips.Add(Lib.BuildString("Exposed to intense radiation", radiation_str));
            }
            else if (info.radiation > 0.0195 / 3600.0)
            {
                icons.Add(Icons.radiation_yellow);
                tooltips.Add(Lib.BuildString("Exposed to moderate radiation", radiation_str));
            }
        }
Пример #19
0
        public static void Execute(Vessel v, Vessel_Info vi, VesselData vd, Vessel_Resources resources, double elapsed_s)
        {
            // execute all supplies
            foreach (Supply supply in supplies)
            {
                supply.Execute(v, vd, resources);
            }

            // execute all rules
            foreach (Rule rule in rules)
            {
                rule.Execute(v, vi, resources, elapsed_s);
            }

            // execute all processes
            foreach (Process process in processes)
            {
                process.Execute(v, vi, resources, elapsed_s);
            }
        }
Пример #20
0
        public static void SetLocks(Vessel v, Vessel_Info vi)
        {
            // lock controls for EVA death
            if (EVA.IsDead(v))
            {
                InputLockManager.SetControlLock(ControlTypes.EVA_INPUT, "eva_dead_lock");
            }

            // lock controls for probes without signal
            if (vi.is_valid && !vi.connection.linked && vi.crew_count == 0 && Settings.UnlinkedControl != UnlinkedCtrl.full)
            {
                // choose no controls, or only full/zero throttle and staging
                ControlTypes ctrl = Settings.UnlinkedControl == UnlinkedCtrl.none
          ? ControlTypes.ALL_SHIP_CONTROLS
          : ControlTypes.PARTIAL_SHIP_CONTROLS;

                InputLockManager.SetControlLock(ctrl, "no_signal_lock");
                FlightInputHandler.state.mainThrottle = 0.0f;
            }
        }
Пример #21
0
        public void Execute(Vessel v, Vessel_Info vi, Vessel_Resources resources, double elapsed_s)
        {
            // evaluate modifiers
            double k = Modifiers.Evaluate(v, vi, resources, modifiers);

            // only execute processes if necessary
            if (k > double.Epsilon)
            {
                // prepare recipe
                Resource_Recipe recipe = new Resource_Recipe();
                foreach (var p in inputs)
                {
                    recipe.Input(p.Key, p.Value * k * elapsed_s);
                }
                foreach (var p in outputs)
                {
                    recipe.Output(p.Key, p.Value * k * elapsed_s, dump.Check(p.Key));
                }
                resources.Transform(recipe);
            }
        }
Пример #22
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.SetSection("HABITAT");
            if (Features.Poisoning)
            {
                p.SetContent("co2 level", Lib.Color(Lib.HumanReadablePerc(vi.poisoning, "F2"), vi.poisoning > Settings.PoisoningThreshold, "yellow"));
            }
            if (!v.isEVA)
            {
                if (Features.Pressure)
                {
                    p.SetContent("pressure", Lib.HumanReadablePressure(vi.pressure * Sim.PressureAtSeaLevel()));
                }
                if (Features.Shielding)
                {
                    p.SetContent("shielding", Lib.HumanReadableShielding(vi.shielding));
                }
                if (Features.LivingSpace)
                {
                    p.SetContent("living space", Habitat.Living_Space_to_String(vi.living_space));
                }
                if (Features.Comfort)
                {
                    p.SetContent("comfort", vi.comforts.Summary(), vi.comforts.Tooltip());
                }
            }
        }
Пример #23
0
        static void Render_Greenhouse(Panel p, Vessel_Info vi)
        {
            // do nothing without greenhouses
            if (vi.greenhouses.Count == 0)
            {
                return;
            }

            // panel section
            p.SetSection("GREENHOUSE");

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

                // state string
                string state = greenhouse.issue.Length > 0
          ? Lib.BuildString("<color=yellow>", greenhouse.issue, "</color>")
          : greenhouse.growth >= 0.99
          ? "<color=green>ready to harvest</color>"
          : "growing";

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

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

                // issues too, why not
                p.SetIcon(greenhouse.issue.Length == 0 ? Icons.plant_white : Icons.plant_yellow, tooltip);
            }
        }
Пример #24
0
        static void Render_Supplies(Panel p, Vessel v, Vessel_Info vi, Vessel_Resources resources)
        {
            // for each supply
            int supplies = 0;

            foreach (Supply supply in Profile.supplies)
            {
                // get resource info
                Resource_Info res = resources.Info(v, supply.resource);

                // only show estimate if the resource is present
                if (res.amount <= double.Epsilon)
                {
                    continue;
                }

                // render panel title, if not done already
                if (supplies == 0)
                {
                    p.SetSection("SUPPLIES");
                }

                // rate tooltip
                string rate_tooltip = Math.Abs(res.rate) >= 1e-10 ? Lib.BuildString
                                      (
                    res.rate > 0.0 ? "<color=#00ff00><b>" : "<color=#ff0000><b>",
                    Lib.HumanReadableRate(Math.Abs(res.rate)),
                    "</b></color>"
                                      ) : string.Empty;

                // determine label
                string label = supply.resource == "ElectricCharge"
          ? "battery"
          : Lib.SpacesOnCaps(supply.resource).ToLower();

                // finally, render resource supply
                p.SetContent(label, Lib.HumanReadableDuration(res.Depletion(vi.crew_count)), rate_tooltip);
                ++supplies;
            }
        }
Пример #25
0
        void Indicator_Problems(Panel p, Vessel v, Vessel_Info vi, List <ProtoCrewMember> crew)
        {
            // store problems icons & tooltips
            List <Texture> problem_icons    = new List <Texture>();
            List <string>  problem_tooltips = new List <string>();

            // detect problems
            Problem_Sunlight(vi, ref problem_icons, ref problem_tooltips);
            if (Features.SpaceWeather)
            {
                Problem_Storm(v, ref problem_icons, ref problem_tooltips);
            }
            if (crew.Count > 0 && Profile.rules.Count > 0)
            {
                Problem_Kerbals(crew, ref problem_icons, ref problem_tooltips);
            }
            if (crew.Count > 0 && Features.Radiation)
            {
                Problem_Radiation(vi, ref problem_icons, ref problem_tooltips);
            }
            Problem_Greenhouses(v, vi.greenhouses, ref problem_icons, ref problem_tooltips);
            if (Features.Poisoning)
            {
                Problem_Poisoning(vi, ref problem_icons, ref problem_tooltips);
            }

            // choose problem icon
            const UInt64 problem_icon_time = 3;
            Texture      problem_icon      = Icons.empty;

            if (problem_icons.Count > 0)
            {
                UInt64 problem_index = ((UInt64)Time.realtimeSinceStartup / problem_icon_time) % (UInt64)(problem_icons.Count);
                problem_icon = problem_icons[(int)problem_index];
            }

            // generate problem icon
            p.SetIcon(problem_icon, String.Join("\n", problem_tooltips.ToArray()));
        }
Пример #26
0
        void Indicator_Reliability(Panel p, Vessel v, Vessel_Info vi)
        {
            Texture image;
            string  tooltip;

            if (!vi.malfunction)
            {
                image   = Icons.wrench_white;
                tooltip = string.Empty;
            }
            else if (!vi.critical)
            {
                image   = Icons.wrench_yellow;
                tooltip = "Malfunctions";
            }
            else
            {
                image   = Icons.wrench_red;
                tooltip = "Critical failures";
            }

            p.SetIcon(image, tooltip);
        }
Пример #27
0
        static void Render_Environment(Panel p, Vessel v, Vessel_Info vi)
        {
            // don't show env panel in eva kerbals
            if (v.isEVA)
            {
                return;
            }

            // get all sensor readings
            HashSet <string> readings = new HashSet <string>();

            if (v.loaded)
            {
                foreach (var s in Lib.FindModules <Sensor>(v))
                {
                    readings.Add(s.type);
                }
            }
            else
            {
                foreach (ProtoPartModuleSnapshot m in Lib.FindModules(v.protoVessel, "Sensor"))
                {
                    readings.Add(Lib.Proto.GetString(m, "type"));
                }
            }
            readings.Remove(string.Empty);

            p.SetSection("ENVIRONMENT");
            foreach (string type in readings)
            {
                p.SetContent(type, Sensor.Telemetry_Content(v, vi, type), Sensor.Telemetry_Tooltip(v, vi, type));
            }
            if (readings.Count == 0)
            {
                p.SetContent("<i>no sensors installed</i>");
            }
        }
Пример #28
0
        // get readings tooltip
        public static string Telemetry_Tooltip(Vessel v, Vessel_Info vi, string type)
        {
            switch (type)
            {
            case "temperature":
                return(Lib.BuildString
                       (
                           "<align=left />",
                           "solar flux\t<b>", Lib.HumanReadableFlux(vi.solar_flux), "</b>\n",
                           "albedo flux\t<b>", Lib.HumanReadableFlux(vi.albedo_flux), "</b>\n",
                           "body flux\t<b>", Lib.HumanReadableFlux(vi.body_flux), "</b>"
                       ));

            case "radiation":
                return(string.Empty);

            case "pressure":
                return(vi.underwater
            ? "inside <b>ocean</b>"
            : vi.atmo_factor < 1.0
            ? Lib.BuildString("inside <b>atmosphere</b> (", vi.breathable ? "breathable" : "not breathable", ")")
            : Sim.InsideThermosphere(v)
            ? "inside <b>thermosphere</b>"
            : Sim.InsideExosphere(v)
            ? "inside <b>exosphere</b>"
            : string.Empty);

            case "gravioli":
                return(Lib.BuildString
                       (
                           "Gravioli detection events per-year: <b>", vi.gravioli.ToString("F2"), "</b>\n\n",
                           "<i>The elusive negative gravioli particle\nseem to be much harder to detect\n",
                           "than expected. On the other\nside there seems to be plenty\nof useless positive graviolis around.</i>"
                       ));
            }
            return(string.Empty);
        }
Пример #29
0
        // show warning message when a vessel cross a radiation belt
        public static void BeltWarnings(Vessel v, Vessel_Info vi, VesselData vd)
        {
            // if radiation is enabled
            if (Features.Radiation)
            {
                // we only show the warning for manned vessels, or for all vessels the first time its crossed
                bool must_warn = vi.crew_count > 0 || !DB.landmarks.belt_crossing;

                // are we inside a belt
                bool inside_belt = vi.inner_belt || vi.outer_belt;

                // show the message
                if (inside_belt && !vd.msg_belt && must_warn)
                {
                    Message.Post(Lib.BuildString("<b>", v.vesselName, "</b> is crossing <i>", v.mainBody.bodyName, " radiation belt</i>"), "Exposed to extreme radiation");
                    vd.msg_belt = true;
                }
                else if (!inside_belt && vd.msg_belt)
                {
                    // no message after crossing the belt
                    vd.msg_belt = false;
                }

                // record first belt crossing
                if (inside_belt)
                {
                    DB.landmarks.belt_crossing = true;
                }

                // record first heliopause crossing
                if (vi.interstellar)
                {
                    DB.landmarks.heliopause_crossing = true;
                }
            }
        }
Пример #30
0
 public static bool HasVesselInfo(Vessel v, out Vessel_Info vi) => vessels.TryGetValue(Lib.VesselID(v), out vi);