Example #1
0
        /// <summary>
        /// Manages the true condition which enables the "Fill EVA" button.
        /// </summary>
        /// <returns></returns>
        private bool EnableFillButton()
        {
            var info = EVALifeSupportTracker.GetEVALSInfo(kerbal.name);

            return(info.ls_current < info.ls_max &&
                   !FlightGlobals.ActiveVessel.isEVA &&
                   fillButtonEnable);
        }
Example #2
0
        private static void FillEVAResource(string kerbalName)
        {
            // This works right now because the tracker updates live.
            // May break in the future.
            var    info        = EVALifeSupportTracker.GetEVALSInfo(kerbalName);
            double eva_request = info.ls_max - info.ls_current;

            Cons2LSModule module   = FlightGlobals.ActiveVessel.FindPartModuleImplementing <Cons2LSModule>();
            double        obtained = module.part.RequestResource(C.NAME_CONSUMABLES, C.CONS_PER_EVA_LS * eva_request);
            double        add      = obtained / C.CONS_PER_EVA_LS;

            EVALifeSupportTracker.AddEVAAmount(kerbalName, add, EVA_Resource.LifeSupport);

            Util.Log("    EVA Request  = " + eva_request);
            Util.Log("    Amt Obtained = " + obtained);
        }
        public void FixedUpdate()
        {
            // If part is unmanned, nothing to do
            if (part.protoModuleCrew.Count == 0)
            {
                showed_eva_warning = false;
                return;
            }

            // If vessel is below this altitude in an atmosphere with oxygen,
            // LifeSupport is irrelevant
            if (Util.BreathableAir(vessel))
            {
                return;
            }

            int crew_count = part.protoModuleCrew.Count;

            // How much lifesupport to request
            double ls_request = crew_count * C.LS_DRAIN_PER_SEC * TimeWarp.fixedDeltaTime;

            // Request resource based on rates defined by constants
            double ret_rs = part.RequestResource(C.NAME_LIFESUPPORT, ls_request, C.FLOWMODE_LIFESUPPORT);

            // If LifeSupport exists or is restored, reset EVA warning and return
            if (ret_rs > 0.0)
            {
                showed_eva_warning = false;
                return;
            }

            // Otherwise, begin deducting EVA LifeSupport
            if (!showed_eva_warning)
            {
                TimeWarp.SetRate(0, true);
                string vessel_name = vessel.isActiveVessel ? part.partInfo.title : vessel.vesselName;

                showed_eva_warning = true;
                Util.PostUpperMessage("Crew in " + vessel_name + " has run out of "
                                      + C.NAME_LIFESUPPORT + ",\n is consuming " + C.NAME_EVA_LIFESUPPORT, 1);
            }

            // Modify crew list in place
            int i = 0;

            while (i < part.protoModuleCrew.Count)
            {
                ProtoCrewMember kerbal = part.protoModuleCrew[i];

                double request = C.EVA_LS_DRAIN_PER_SEC * TimeWarp.fixedDeltaTime;

                double current_eva = EVALifeSupportTracker.AddEVAAmount(kerbal.name, -request, EVA_Resource.LifeSupport);

                if (current_eva + request > C.EVA_LS_30_SECONDS &&
                    current_eva <= C.EVA_LS_30_SECONDS)
                {
                    TimeWarp.SetRate(0, true);
                    Util.PostUpperMessage(kerbal.name + " has 30 seconds to live!", 1);
                    // Set to 30 seconds in case of large timewarp.
                    EVALifeSupportTracker.SetCurrentAmount(kerbal.name, C.EVA_LS_30_SECONDS, EVA_Resource.LifeSupport);
                }

                if (EVALifeSupportTracker.GetEVALSInfo(kerbal.name).ls_current < C.DOUBLE_MARGIN)
                {
                    Util.KillKerbal(this, kerbal);
                    continue;
                }

                i++;
            }
        }
Example #4
0
        private void UpdateGUI()
        {
            drewgui = true;

            Vessel vessel    = FlightGlobals.ActiveVessel;
            int    crewCount = vessel.GetCrewCount();
            var    parts     = vessel.FindPartModulesImplementing <LifeSupportReportable>();

            // Update live Kerbal numbers
            foreach (LifeSupportReportable module in parts)
            {
                bool   empty;
                string timestr = module.ReportLifeSupport(out empty);

                if (emptyPartLabels.ContainsKey(module.part))
                {
                    emptyPartLabels[module.part].SetOptionText($"{ORANGE}{timestr}</color>");
                    continue;
                }

                foreach (ProtoCrewMember kerbal in module.part.protoModuleCrew)
                {
                    double evaLS = EVALifeSupportTracker.GetEVALSInfo(kerbal.name).ls_current;

                    if (compress)
                    {
                        if (!vessel.isEVA && !empty)
                        {
                            labelMap[kerbal.name].nameLabel.SetOptionText(labelMap[kerbal.name].compressNames[0]);
                            labelMap[kerbal.name].shipLS.SetOptionText(timestr);
                        }
                        else
                        {
                            labelMap[kerbal.name].nameLabel.SetOptionText(labelMap[kerbal.name].compressNames[1]);
                            string evastr = Util.DaysToString(evaLS / C.EVA_LS_DRAIN_PER_DAY);
                            labelMap[kerbal.name].shipLS.SetOptionText(evastr);
                        }
                    }
                    else
                    {
                        string evastr = Util.DaysToString(evaLS / C.EVA_LS_DRAIN_PER_DAY);
                        labelMap[kerbal.name].shipLS.SetOptionText(timestr);
                        labelMap[kerbal.name].evaLS.SetOptionText(evastr);
                    }

                    if (Config.DEBUG_SHOW_EVA)
                    {
                        var info = EVALifeSupportTracker.GetEVALSInfo(kerbal.name);
                        labelMap[kerbal.name].evaLS_Value.SetOptionText(info.ls_current.ToString());
                        labelMap[kerbal.name].evaProp.SetOptionText(info.prop_current.ToString());
                    }
                }
            }

            // Any Kerbals not found above are assumed KIA
            // Would be great to move this to a GameEvent
            // such as GameEvents.onKerbalRemoved()
            if (crewCount < labelMap.Count)
            {
                List <string> fullcrew = vessel.GetVesselCrew().ConvertAll(a => a.name);
                foreach (string name in labelMap.Keys.ToArray())
                {
                    if (!fullcrew.Contains(name))
                    {
                        labelMap[name].shipLS.SetOptionText("KIA");
                        labelMap[name].evaLS.SetOptionText("KIA");
                        labelMap.Remove(name);
                    }
                }
            }

            // Update status
            double curr, max;

            vessel.GetConnectedResourceTotals(lsID, out curr, out max);

            string statusOne; // Status (no crew/breathable/active)
            string statusTwo; // Remaining Consumables/EVA Life Support
            string lsActive;

            if (crewCount == 0)
            {
                lsActive = "No crew";
            }
            else if (Util.BreathableAir(vessel))
            {
                lsActive = "Breathable air";
            }
            else
            {
                lsActive = "ACTIVE";
            }
            statusOne = $"{(compress ? "" : "Status: ")}{lsActive}";

            if (FlightGlobals.ActiveVessel.isEVA)
            {
                vessel.GetConnectedResourceTotals(evapropID, out curr, out max);
                string prefix = "";
                string suffix = "</color>";
                if (curr < 0.5)
                {
                    prefix = C.GUI_HARDWARN_COLOR;
                }
                else if (curr < 1.0)
                {
                    prefix = C.GUI_LITEWARN_COLOR;
                }
                else
                {
                    suffix = "";
                }
                statusTwo = $"Propellant:  {prefix}{string.Format("{0:0.00}", curr)}{suffix}";
            }
            else
            {
                vessel.GetConnectedResourceTotals(consID, out curr, out max);
                double consDays = curr / C.CONS_PER_LS;
                statusTwo = $"{(compress ? "" : "Consumables:  ")}{Util.DaysToString(consDays)}";
            }

            statusLabel.SetOptionText($"{statusOne}\n{statusTwo}");
        }
        public override void OnStart(StartState state)
        {
            Util.Log("EVALifeSupportModule OnStart()");

            // Check if EVA Kerbal has exactly one ProtoCrewMember
            if (part.protoModuleCrew.Count == 0)
            {
                string msg = "0 PMCs found in EVA Kerbal: " + part.name;
                Util.Log(msg);
                throw new IndexOutOfRangeException(msg);
            }
            else if (part.protoModuleCrew.Count > 1)
            {
                Util.Log("Weird...multiple PMCs found in EVA Kerbal: " + part.name);
            }

            // To avoid conflicts with Unity variable "name"
            string kerbal_name = part.protoModuleCrew[0].name;

            PartResource ls_resource = null;

            foreach (PartResource pr in part.Resources)
            {
                if (pr.resourceName == C.NAME_EVA_LIFESUPPORT)
                {
                    ls_resource = pr;
                    break;
                }
            }

            // Kerbals assigned after this mod's installation should already be tracked,
            // but for Kerbals already in flight, add EVA LS according to current state
            // of astronaut complex
            EVALifeSupportTracker.AddKerbalToTracking(kerbal_name);

            if (ls_resource == null)
            {
                // If not found, add EVA LS resource to this PartModule.
                Util.Log("Adding " + C.NAME_EVA_LIFESUPPORT + " resource to " + part.name);

                var info = EVALifeSupportTracker.GetEVALSInfo(kerbal_name);

                ConfigNode resource_node = new ConfigNode("RESOURCE");
                resource_node.AddValue("name", C.NAME_EVA_LIFESUPPORT);
                resource_node.AddValue("amount", info.ls_current.ToString());
                resource_node.AddValue("maxAmount", info.ls_max.ToString());

                ls_resource = part.AddResource(resource_node);

                Util.Log("Added EVA LS resource to " + part.name);
            }
            else
            {
                // If found, this EVA is already active - deduct LS.
                Util.StartupRequest(this, C.NAME_EVA_LIFESUPPORT, C.EVA_LS_DRAIN_PER_SEC);

                if (ls_resource.amount < C.KILL_BUFFER)
                {
                    ls_resource.amount = C.KILL_BUFFER;
                }
                else if (ls_resource.amount < C.EVA_LS_30_SECONDS)
                {
                    Util.PostUpperMessage(kerbal_name + " has " + (int)(ls_resource.amount / C.EVA_LS_DRAIN_PER_SEC) + " seconds to live!", 1);
                }
            }

            PartResource prop_resource = part.Resources[C.NAME_EVA_PROPELLANT];

            // Necessary to override game's default behavior, which refills
            // EVA Propellant automatically every time EVA Kerbal is reset
            var eva_info = EVALifeSupportTracker.GetEVALSInfo(kerbal_name);

            prop_resource.maxAmount = eva_info.prop_max;
            prop_resource.amount    = eva_info.prop_current;

            // Will this add safety Propellant on every load?
            // Should only be added when Kerbal first leaves ship
            //
            // Confirmed (1.0.5). At the time of this comment, the Propellant
            // threshold is brutally low (0.1), so it's okay,
            // but this should be changed in the future.
            if (prop_resource.amount < C.EVA_PROP_SAFE_MIN)
            {
                prop_resource.amount = C.EVA_PROP_SAFE_MIN;
            }

            // If difficulty option "Immediate Level Up" is selected,
            // immediately set this Kerbal's EVA to new max
            if (this.vessel.CanUpdateEVAStat(Config.EVA_MAX_UPDATE))
            {
                ls_resource.maxAmount   = Util.MaxAllowedEVA(EVA_Resource.LifeSupport);
                prop_resource.maxAmount = Util.MaxAllowedEVA(EVA_Resource.Propellant);
            }

            base.OnStart(state);
        }