Пример #1
0
        private void CheckEVAKerbals()
        {
            if (!HighLogic.LoadedSceneIsFlight)
            {
                return;
            }

            var vList = GetNearbyVessels(2000, false, FlightGlobals.ActiveVessel, false);

            foreach (var v in vList.Where(v => v.isEVA))
            {
                if (v.mainBody == FlightGlobals.GetHomeBody())
                {
                    if (v.altitude < LifeSupportScenario.Instance.settings.GetSettings().HomeWorldAltitude)
                    {
                        continue;
                    }
                }

                var c = v.GetVesselCrew().First();
                //Check their status.
                var k = LifeSupportManager.Instance.FetchKerbal(c);
                if (v.missionTime > LifeSupportScenario.Instance.settings.GetSettings().EVATime)
                {
                    print("Applying EVA Effect");
                    ApplyEVAEffect(k, c, v,
                                   LifeSupportManager.isVet(k.KerbalName)
                            ? LifeSupportScenario.Instance.settings.GetSettings().EVAEffectVets
                            : LifeSupportScenario.Instance.settings.GetSettings().EVAEffect);
                }
            }
        }
Пример #2
0
 private void UpdateStatus(VesselSupplyStatus v)
 {
     v.RecyclerMultiplier  = (float)LifeSupportManager.GetRecyclerMultiplier(vessel);
     v.ExtraHabSpace       = (float)LifeSupportManager.CalculateVesselHabExtraTime(vessel);
     v.VesselHabMultiplier = (float)LifeSupportManager.CalculateVesselHabMultiplier(vessel, _currentCrew);
     LifeSupportManager.Instance.TrackVessel(v);
 }
Пример #3
0
        private ConversionRecipe GenerateLSRecipe()
        {
            //This is where the rubber hits the road.  Let us see if we can
            //keep our Kerbals cozy and warm.
            var recipe      = new ConversionRecipe();
            var numCrew     = part.protoModuleCrew.Count;
            var recPercent  = LifeSupportManager.GetRecyclerMultiplier(part.vessel);
            var ecAmount    = LifeSupportSetup.Instance.LSConfig.ECAmount;
            var supAmount   = LifeSupportSetup.Instance.LSConfig.SupplyAmount;
            var scrapAmount = LifeSupportSetup.Instance.LSConfig.WasteAmount;
            var repAmount   = LifeSupportSetup.Instance.LSConfig.ReplacementPartAmount;

            if (part.Resources.Contains("ReplacementParts"))
            {
                recipe.Inputs.Add(new ResourceRatio {
                    FlowMode = "ALL_VESSEL", Ratio = repAmount * numCrew, ResourceName = "ReplacementParts", DumpExcess = false
                });
            }

            var supRatio   = supAmount * numCrew * recPercent;
            var mulchRatio = scrapAmount * numCrew * recPercent;

            recipe.Inputs.Add(new ResourceRatio {
                FlowMode = "ALL_VESSEL", Ratio = ecAmount * numCrew, ResourceName = "ElectricCharge", DumpExcess = true
            });
            recipe.Inputs.Add(new ResourceRatio {
                FlowMode = "ALL_VESSEL", Ratio = supRatio, ResourceName = "Supplies", DumpExcess = true
            });
            recipe.Outputs.Add(new ResourceRatio {
                FlowMode = "ALL_VESSEL", Ratio = mulchRatio, ResourceName = "Mulch", DumpExcess = true
            });
            return(recipe);
        }
        private void UpdateStatus(VesselSupplyStatus supplyStatus)
        {
            var now = Planetarium.GetUniversalTime();

            if (_lastUpdate < ResourceUtilities.FLOAT_TOLERANCE)
            {
                _lastUpdate = now;
            }

            // Give converters time to catch up before we start using calculated values
            bool fullRefresh = false;

            if (now > _lastUpdate + 5d)
            {
                fullRefresh = true;
                _lastUpdate = now;
            }

            var calcRecyclerMultiplier = (float)LifeSupportManager.GetRecyclerMultiplier(vessel);
            var calcHabTime            = (float)LifeSupportManager.CalculateVesselHabExtraTime(vessel);
            var calcHabMultiplier      = (float)LifeSupportManager.CalculateVesselHabMultiplier(vessel, _currentCrewCount);

            // If we're the active vessel, and we're past easing, use calculated values.
            //  Otherwise, use the cache.
            var useCalculated = fullRefresh && vessel.id == FlightGlobals.ActiveVessel.id;

            //Start with intelligent defaults.
            if (supplyStatus.RecyclerMultiplier < ResourceUtilities.FLOAT_TOLERANCE)
            {
                supplyStatus.RecyclerMultiplier = 1f;
            }
            if (calcRecyclerMultiplier < ResourceUtilities.FLOAT_TOLERANCE)
            {
                calcRecyclerMultiplier = 1f;
            }

            //And take the lowest (non-zero)
            if (useCalculated || calcRecyclerMultiplier < supplyStatus.RecyclerMultiplier)
            {
                supplyStatus.RecyclerMultiplier = calcRecyclerMultiplier;
            }

            //Hab we want the best ones.
            if (useCalculated || calcHabTime > supplyStatus.ExtraHabSpace)
            {
                supplyStatus.ExtraHabSpace = calcHabTime;
            }

            if (useCalculated || calcHabMultiplier > supplyStatus.VesselHabMultiplier)
            {
                supplyStatus.VesselHabMultiplier = calcHabMultiplier;
            }

            LifeSupportManager.Instance.TrackVessel(supplyStatus);
        }
Пример #5
0
        internal void ComputeEc(double ecTimeLeft, ProtoCrewMember c)
        {
            var noEcEffect = LifeSupportManager.GetNoECEffect(c.name);

            ECLabel = GetRemainingTimeWithGraceLabel(
                ecTimeLeft,
                LifeSupportScenario.Instance.settings.GetSettings().ECTime,
                LifeSupportMonitor.EcGraceTimeDisplay,
                "out of EC",
                noEcEffect);
        }
Пример #6
0
        private void UpdateStatus(VesselSupplyStatus v)
        {
            if (_lastUpdate < ResourceUtilities.FLOAT_TOLERANCE)
            {
                _lastUpdate = Planetarium.GetUniversalTime();
            }

            bool fullRefresh = false;

            if (Planetarium.GetUniversalTime() > _lastUpdate + 5d) //A reasonable time for easing in everything
            {
                fullRefresh = true;
                _lastUpdate = Planetarium.GetUniversalTime();
            }

            var newRecMult = (float)LifeSupportManager.GetRecyclerMultiplier(vessel);
            var newSpace   = (float)LifeSupportManager.CalculateVesselHabExtraTime(vessel);
            var newHabMult = (float)LifeSupportManager.CalculateVesselHabMultiplier(vessel, _currentCrew);
            //If we're the active vessel, and we're past easing, we always take calc values.
            //Otherwise, let's use the cache.
            var useCur = fullRefresh && vessel.id == FlightGlobals.ActiveVessel.id;

            //Start with intelligent defaults.
            if (v.RecyclerMultiplier < ResourceUtilities.FLOAT_TOLERANCE)
            {
                v.RecyclerMultiplier = 1f;
            }
            if (newRecMult < ResourceUtilities.FLOAT_TOLERANCE)
            {
                newRecMult = 1f;
            }
            //And take the lowest (non-zero)
            if (useCur || newRecMult < v.RecyclerMultiplier)
            {
                v.RecyclerMultiplier = newRecMult;
            }

            //Hab we want the best ones.
            if (useCur || newSpace > v.ExtraHabSpace)
            {
                v.ExtraHabSpace = newSpace;
            }

            if (useCur || newHabMult > v.VesselHabMultiplier)
            {
                v.VesselHabMultiplier = newHabMult;
            }

            LifeSupportManager.Instance.TrackVessel(v);
        }
Пример #7
0
        internal void ComputeSupply(double vesselSuppliesTimeLeft, ProtoCrewMember c)
        {
            var noSupplyEffect = LifeSupportManager.GetNoSupplyEffect(c.name);

            if (noSupplyEffect > 0)
            {
                UpdateEarliestExpiration(vesselSuppliesTimeLeft);
            }
            SupplyLabel = GetRemainingTimeWithGraceLabel(
                vesselSuppliesTimeLeft,
                LifeSupportScenario.Instance.settings.GetSettings().SupplyTime,
                LifeSupportMonitor.SuppliesGraceTimeDisplay,
                "starving",
                noSupplyEffect);
        }
        private void CheckEVA(Vessel evaKerbal)
        {
            if (IsAtHomeForEva(evaKerbal))
            {
                return;
            }

            var kerbal = evaKerbal.GetVesselCrew()[0];
            //Check their status.
            var kerbalStatus = LifeSupportManager.Instance.FetchKerbal(kerbal);

            if (evaKerbal.missionTime > LifeSupportScenario.Instance.settings.GetSettings().EVATime)
            {
                var effect = LifeSupportManager.GetEVAExcessEffect(kerbalStatus.KerbalName);
                ApplyEVAEffect(kerbalStatus, kerbal, evaKerbal, effect);
            }
        }
        private bool CheckHabSideEffects(LifeSupportStatus trackedKerbal)
        {
            var now     = Planetarium.GetUniversalTime();
            var habTime = LifeSupportManager.GetTotalHabTime(VesselStatus, vessel);

            if (trackedKerbal.LastAtHome < 1)
            {
                trackedKerbal.LastAtHome = now;
            }
            if (habTime + trackedKerbal.LastAtHome > trackedKerbal.MaxOffKerbinTime)
            {
                trackedKerbal.MaxOffKerbinTime = habTime + trackedKerbal.LastAtHome;
            }

            LifeSupportManager.Instance.TrackKerbal(trackedKerbal);

            return(now > trackedKerbal.MaxOffKerbinTime || (now - trackedKerbal.TimeEnteredVessel) > habTime);
        }
Пример #10
0
        private bool CheckHabSideEffects(LifeSupportStatus kStat)
        {
            var habTime = LifeSupportManager.GetTotalHabTime(VesselStatus, vessel);

            if (kStat.LastAtHome < 1)
            {
                kStat.LastAtHome = Planetarium.GetUniversalTime();
            }
            if (habTime + kStat.LastAtHome > kStat.MaxOffKerbinTime)
            {
                kStat.MaxOffKerbinTime = habTime + kStat.LastAtHome;
            }

            LifeSupportManager.Instance.TrackKerbal(kStat);

            if (Planetarium.GetUniversalTime() > kStat.MaxOffKerbinTime || (Planetarium.GetUniversalTime() - kStat.TimeEnteredVessel) > habTime)
            {
                return(true);
            }
            return(false);
        }
Пример #11
0
        internal void ComputeHome(ProtoCrewMember c, LifeSupportStatus cls)
        {
            var crewHomeString  = "indefinite";
            var lblHome         = "6FFF00";
            var useHabPenalties = LifeSupportManager.GetNoHomeEffect(c.name) > 0;

            if (useHabPenalties)
            {
                var homeTimeLeft = cls.MaxOffKerbinTime - Planetarium.GetUniversalTime();
                UpdateEarliestExpiration(homeTimeLeft);

                var isScout    = c.HasEffect("ExplorerSkill") && homeTimeLeft >= LifeSupportScenario.Instance.settings.GetSettings().ScoutHabTime;
                var isPermaHab = homeTimeLeft >= LifeSupportScenario.Instance.settings.GetSettings().PermaHabTime;

                if (isScout || isPermaHab)
                {
                    crewHomeString = "indefinite";
                }
                else if (homeTimeLeft < 0)
                {
                    lblHome        = "FF5E5E";
                    crewHomeString = "expired";
                }
                else
                {
                    crewHomeString = LifeSupportUtilities.SmartDurationDisplay(homeTimeLeft);
                    var secondsPerDay = LifeSupportUtilities.SecondsPerDay();
                    if (homeTimeLeft < secondsPerDay * 30) //15 days
                    {
                        lblHome = "FFE100";
                    }
                    if (homeTimeLeft < secondsPerDay * 15)
                    {
                        lblHome = "FFAE00";
                    }
                }
            }
            HomeLabel = String.Format("<color=#{0}>{1}</color>", lblHome, crewHomeString);
        }
        public void FixedUpdate()
        {
            if (!HighLogic.LoadedSceneIsFlight || vessel == null || !vessel.loaded)
            {
                return;
            }

            if (vessel.isEVA)
            {
                CheckEVA(vessel);
                return;
            }

            if (_partCount != vessel.parts.Count)
            {
                if (_partCount > 0)
                {
                    _isStatusRefreshRequired = true;
                }
                _partCount = vessel.parts.Count;
            }

            if (_isDirty)
            {
                _isDirty = false;
                UpdateVesselInfo();
                UpdateStatus();
            }

            var now = Planetarium.GetUniversalTime();

            if (_currentCrewCount == 0)
            {
                VesselStatus.VesselName  = vessel.vesselName;
                VesselStatus.NumCrew     = vessel.GetCrewCount();
                VesselStatus.CrewCap     = vessel.GetCrewCapacity();
                VesselStatus.LastECCheck = now;
                VesselStatus.LastFeeding = now;
                VesselStatus.LastUpdate  = now;

                LifeSupportManager.Instance.TrackVessel(VesselStatus);
                LastUpdateTime = now;

                return;
            }

            try
            {
                bool isLongLoop = false;
                var  offKerbin  = !LifeSupportManager.IsOnKerbin(vessel);
                CheckVesselId();

                // Check our time
                double deltaTime = GetDeltaTime();
                bool   isCatchup = deltaTime / 2 > TimeWarp.fixedDeltaTime;

                if (deltaTime < ResourceUtilities.FLOAT_TOLERANCE * 10)
                {
                    return;
                }

                if (now >= _lastProcessingTime + _checkInterval)
                {
                    isLongLoop          = true;
                    _lastProcessingTime = now;
                }

                VesselStatus.LastUpdate = now;
                VesselStatus.VesselName = vessel.vesselName;
                VesselStatus.NumCrew    = vessel.GetCrewCount();
                VesselStatus.CrewCap    = vessel.GetCrewCapacity();

                if (isLongLoop)
                {
                    CheckForDeadKerbals();
                }

                if (_currentCrewCount > 0)
                {
                    //Guard clause
                    if (_crewPart == null)
                    {
                        UpdateVesselInfo();
                    }

                    //we will add a bit of a fudge factor for supplies
                    var tolerance = deltaTime / 2f;

                    //nom nom nom!
                    ConverterResults resultSupply = Converter.ProcessRecipe(deltaTime, SupplyRecipe, _crewPart, null, 1f);
                    ConverterResults resultEC     = Converter.ProcessRecipe(deltaTime, ECRecipe, _crewPart, null, 1f);

                    #region Long Loop - Crew
                    if (isLongLoop)
                    {
                        //Ensure status is current
                        UpdateStatus();

                        var habTime = LifeSupportManager.GetTotalHabTime(VesselStatus, vessel);

                        if (_oldHabChecksum < ResourceUtilities.FLOAT_TOLERANCE)
                        {
                            _oldHabChecksum = LifeSupportManager.GetHabChecksum(VesselStatus, vessel);
                        }

                        var newHabChecksum = LifeSupportManager.GetHabChecksum(VesselStatus, vessel);
                        if (Math.Abs(_oldHabChecksum - newHabChecksum) > ResourceUtilities.FLOAT_TOLERANCE)
                        {
                            Debug.Log("[USI-LS] Vessel situation changed, refreshing life support");
                            _isStatusRefreshRequired = true;
                            _oldHabChecksum          = newHabChecksum;
                        }

                        var crewRoster = vessel.GetVesselCrew();
                        var count      = crewRoster.Count;
                        for (int i = 0; i < count; ++i)
                        {
                            var  crewMember        = crewRoster[i];
                            bool isGrouchyHab      = false;
                            bool isGrouchySupplies = false;
                            bool isGrouchyEC       = false;
                            bool isScout           = crewMember.HasEffect("ExplorerSkill") && habTime >= LifeSupportScenario.Instance.settings.GetSettings().ScoutHabTime;
                            bool isPermaHab        = habTime >= LifeSupportScenario.Instance.settings.GetSettings().PermaHabTime;
                            bool isHomeWorld       = CheckIfHomeWorld() && habTime >= LifeSupportScenario.Instance.settings.GetSettings().ScoutHabTime&& vessel.LandedOrSplashed;

                            // Get the crew member's life support stats
                            var trackedKerbal = LifeSupportManager.Instance.FetchKerbal(crewMember);

                            // Update life support stats
                            if (_isStatusRefreshRequired)
                            {
                                trackedKerbal.TimeEnteredVessel = now;
                                _isStatusRefreshRequired        = false;
                                LifeSupportManager.Instance.TrackKerbal(trackedKerbal);
                            }

                            // Update Hab effects
                            if (!offKerbin || isScout || isHomeWorld || isPermaHab)
                            {
                                trackedKerbal.TimeEnteredVessel = now;
                                trackedKerbal.LastAtHome        = now;
                                trackedKerbal.MaxOffKerbinTime  = habTime + trackedKerbal.LastAtHome;
                            }
                            else
                            {
                                if (vessel.id.ToString() != trackedKerbal.CurrentVesselId)
                                {
                                    if (vessel.id.ToString() != trackedKerbal.PreviousVesselId)
                                    {
                                        trackedKerbal.TimeEnteredVessel = now;
                                    }

                                    trackedKerbal.PreviousVesselId = trackedKerbal.CurrentVesselId;
                                    trackedKerbal.CurrentVesselId  = vessel.id.ToString();
                                    LifeSupportManager.Instance.TrackKerbal(trackedKerbal);
                                }

                                isGrouchyHab = CheckHabSideEffects(trackedKerbal);
                            }

                            // Update Supplies effects
                            if (offKerbin && (deltaTime - resultSupply.TimeFactor > tolerance))
                            {
                                isGrouchySupplies = CheckSupplySideEffects(trackedKerbal);
                            }
                            else if (deltaTime >= ResourceUtilities.FLOAT_TOLERANCE)
                            {
                                //All is well
                                trackedKerbal.LastMeal   = LastUpdateTime;
                                VesselStatus.LastFeeding = LastUpdateTime;
                            }

                            // Update ElectricCharge effects
                            if (offKerbin && (deltaTime - resultEC.TimeFactor > tolerance))
                            {
                                isGrouchyEC = CheckECSideEffects(trackedKerbal);
                            }
                            else if (deltaTime >= ResourceUtilities.FLOAT_TOLERANCE)
                            {
                                //All is well
                                trackedKerbal.LastEC     = LastUpdateTime;
                                VesselStatus.LastECCheck = LastUpdateTime;
                            }

                            trackedKerbal.LastUpdate = now;

                            var isAnyGrouch = isGrouchyEC || isGrouchyHab || isGrouchySupplies;
                            if (isGrouchyEC && !isCatchup)
                            {
                                ApplyEffect(
                                    trackedKerbal,
                                    crewMember,
                                    LifeSupportManager.GetNoECEffect(trackedKerbal.KerbalName),
                                    "power loss");
                            }
                            else if (isGrouchySupplies && !isCatchup)
                            {
                                ApplyEffect(
                                    trackedKerbal,
                                    crewMember,
                                    LifeSupportManager.GetNoSupplyEffect(trackedKerbal.KerbalName),
                                    "lack of supplies");
                            }
                            else if (isGrouchyHab && !isCatchup)
                            {
                                ApplyEffect(
                                    trackedKerbal,
                                    crewMember,
                                    LifeSupportManager.GetNoHomeEffect(trackedKerbal.KerbalName),
                                    "homesickness");
                            }
                            else if (crewMember.experienceTrait.Config.Name != trackedKerbal.OldTrait && !isAnyGrouch)
                            {
                                RemoveGrouchiness(crewMember, trackedKerbal);
                            }

                            LifeSupportManager.Instance.TrackKerbal(trackedKerbal);
                        }
                    }
                    #endregion - Crew

                    var remainingSupplies = ResourceBroker.AmountAvailable(
                        _crewPart,
                        "Supplies",
                        deltaTime,
                        ResourceFlowMode.ALL_VESSEL);
                    var remainingBattery = ResourceBroker.AmountAvailable(
                        _crewPart,
                        "ElectricCharge",
                        deltaTime,
                        ResourceFlowMode.ALL_VESSEL);
                    var suppliesConsumption    = LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount;
                    var electricityConsumption = LifeSupportScenario.Instance.settings.GetSettings().ECAmount;

                    VesselStatus.SuppliesLeft = remainingSupplies / suppliesConsumption / _currentCrewCount / VesselStatus.RecyclerMultiplier;
                    VesselStatus.ECLeft       = remainingBattery / electricityConsumption / _currentCrewCount;
                }
                else
                {
                    VesselStatus.LastECCheck = now;
                    VesselStatus.LastFeeding = now;
                    VesselStatus.LastUpdate  = now;
                }

                LifeSupportManager.Instance.TrackVessel(VesselStatus);
            }
            catch (Exception ex)
            {
                print(string.Format("ERROR {0} IN ModuleLifeSupport", ex.Message));
            }
        }
Пример #13
0
        public void FixedUpdate()
        {
            if (!HighLogic.LoadedSceneIsFlight || vessel == null)
            {
                return;
            }
            if (!vessel.loaded)
            {
                return;
            }
            if (vessel.isEVA)
            {
                CheckEVA(vessel);
                return;
            }

            if (_partCount != vessel.parts.Count)
            {
                if (_partCount > 0)
                {
                    refreshVesselTime = true;
                }
                _partCount = vessel.parts.Count;
            }


            if (isDirty)
            {
                isDirty = false;
                UpdateVesselInfo();
                UpdateStatus();
            }

            if (_currentCrew == 0)
            {
                VesselStatus.VesselName  = vessel.vesselName;
                VesselStatus.NumCrew     = vessel.GetCrewCount();
                VesselStatus.CrewCap     = vessel.GetCrewCapacity();
                VesselStatus.LastECCheck = Planetarium.GetUniversalTime();
                VesselStatus.LastFeeding = Planetarium.GetUniversalTime();
                VesselStatus.LastUpdate  = Planetarium.GetUniversalTime();
                LifeSupportManager.Instance.TrackVessel(VesselStatus);
                LastUpdateTime = Planetarium.GetUniversalTime();
                return;
            }

            try
            {
                bool isLongLoop = false;
                var  offKerbin  = !LifeSupportManager.IsOnKerbin(vessel);
                CheckVesselId();

                //Check our time
                double deltaTime = GetDeltaTime();
                bool   isCatchup = deltaTime / 2 > TimeWarp.fixedDeltaTime;

                if (deltaTime < ResourceUtilities.FLOAT_TOLERANCE * 10)
                {
                    return;
                }

                if (Planetarium.GetUniversalTime() >= _lastProcessingTime + _checkInterval)
                {
                    isLongLoop          = true;
                    _lastProcessingTime = Planetarium.GetUniversalTime();
                }

                VesselStatus.LastUpdate = Planetarium.GetUniversalTime();
                VesselStatus.VesselName = vessel.vesselName;
                VesselStatus.NumCrew    = vessel.GetCrewCount();
                VesselStatus.CrewCap    = vessel.GetCrewCapacity();
                if (isLongLoop)
                {
                    CheckForDeadKerbals();
                }

                if (_currentCrew > 0)
                {
                    //Guard clause
                    if (_crewPart == null)
                    {
                        UpdateVesselInfo();
                    }

                    //we will add a bit of a fudge factor for supplies
                    var tolerance = deltaTime / 2f;
                    //nom nom nom!
                    ConverterResults resultSupply = ResConverter.ProcessRecipe(deltaTime, SupplyRecipe, _crewPart, null,
                                                                               1f);
                    ConverterResults resultEC = ResConverter.ProcessRecipe(deltaTime, ECRecipe, _crewPart, null, 1f);

                    #region Long Loop - Crew
                    if (isLongLoop)
                    {
                        //Ensure status is current
                        UpdateStatus();
                        var vCrew   = vessel.GetVesselCrew();
                        var count   = vCrew.Count;
                        var habTime = LifeSupportManager.GetTotalHabTime(VesselStatus, vessel);
                        for (int i = 0; i < count; ++i)
                        {
                            var  c                 = vCrew[i];
                            bool isGrouchyHab      = false;
                            bool isGrouchySupplies = false;
                            bool isGrouchyEC       = false;
                            bool isScout           = c.HasEffect("ExplorerSkill") && habTime >= LifeSupportScenario.Instance.settings.GetSettings().ScoutHabTime;
                            bool isPermaHab        = habTime >= LifeSupportScenario.Instance.settings.GetSettings().PermaHabTime;
                            bool isHomeWorld       = CheckIfHomeWorld() && habTime >= LifeSupportScenario.Instance.settings.GetSettings().ScoutHabTime&& vessel.LandedOrSplashed;
                            //Fetch them from the queue
                            var k = LifeSupportManager.Instance.FetchKerbal(c);
                            //Update our stuff
                            if (refreshVesselTime)
                            {
                                k.TimeEnteredVessel = Planetarium.GetUniversalTime();
                                refreshVesselTime   = false;
                                LifeSupportManager.Instance.TrackKerbal(k);
                            }
                            //First - Hab effects.
                            if (!offKerbin || isScout || isHomeWorld || isPermaHab)
                            {
                                k.LastAtHome        = Planetarium.GetUniversalTime();
                                k.MaxOffKerbinTime  = habTime + k.LastAtHome;
                                k.TimeEnteredVessel = Planetarium.GetUniversalTime();
                            }
                            else
                            {
                                if (vessel.id.ToString() != k.CurrentVesselId)
                                {
                                    if (vessel.id.ToString() != k.PreviousVesselId)
                                    {
                                        k.TimeEnteredVessel = Planetarium.GetUniversalTime();
                                    }

                                    k.PreviousVesselId = k.CurrentVesselId;
                                    k.CurrentVesselId  = vessel.id.ToString();
                                    LifeSupportManager.Instance.TrackKerbal(k);
                                }
                                isGrouchyHab = CheckHabSideEffects(k);
                            }


                            //Second - Supply
                            if (offKerbin && (deltaTime - resultSupply.TimeFactor > tolerance))
                            {
                                isGrouchySupplies = CheckSupplySideEffects(k);
                            }
                            else if (deltaTime >= ResourceUtilities.FLOAT_TOLERANCE)
                            {
                                //All is well
                                k.LastMeal = LastUpdateTime;
                                VesselStatus.LastFeeding = LastUpdateTime;
                            }

                            //Third - EC
                            if (offKerbin && (deltaTime - resultEC.TimeFactor > tolerance))
                            {
                                isGrouchyEC = CheckECSideEffects(k);
                            }
                            else if (deltaTime >= ResourceUtilities.FLOAT_TOLERANCE)
                            {
                                //All is well
                                k.LastEC = LastUpdateTime;
                                VesselStatus.LastECCheck = LastUpdateTime;
                            }


                            k.LastUpdate = Planetarium.GetUniversalTime();
                            var isAnyGrouch = isGrouchyEC || isGrouchyHab || isGrouchySupplies;

                            if (isGrouchyEC && !isCatchup)
                            {
                                ApplyEffect(k, c,
                                            LifeSupportManager.GetNoECEffect(k.KerbalName),
                                            "power loss");
                            }
                            else if (isGrouchySupplies && !isCatchup)
                            {
                                ApplyEffect(k, c,
                                            LifeSupportManager.GetNoSupplyEffect(k.KerbalName),
                                            "lack of supplies");
                            }
                            else if (isGrouchyHab && !isCatchup)
                            {
                                ApplyEffect(k, c,
                                            LifeSupportManager.GetNoHomeEffect(k.KerbalName),
                                            "homesickness");
                            }
                            else if (c.experienceTrait.Title != k.OldTrait && !isAnyGrouch)
                            {
                                RemoveGrouchiness(c, k);
                            }
                            LifeSupportManager.Instance.TrackKerbal(k);
                        }
                    }
                    #endregion - Crew

                    var supAmount = _resBroker.AmountAvailable(_crewPart, "Supplies", deltaTime,
                                                               ResourceFlowMode.ALL_VESSEL);
                    var ecAmount = _resBroker.AmountAvailable(_crewPart, "ElectricCharge", deltaTime,
                                                              ResourceFlowMode.ALL_VESSEL);
                    VesselStatus.SuppliesLeft = supAmount /
                                                LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount /
                                                _currentCrew /
                                                VesselStatus.RecyclerMultiplier;
                    VesselStatus.ECLeft = ecAmount / LifeSupportScenario.Instance.settings.GetSettings().ECAmount /
                                          _currentCrew;
                }
                else
                {
                    VesselStatus.LastECCheck = Planetarium.GetUniversalTime();
                    VesselStatus.LastFeeding = Planetarium.GetUniversalTime();
                    VesselStatus.LastUpdate  = Planetarium.GetUniversalTime();
                }
                LifeSupportManager.Instance.TrackVessel(VesselStatus);
            }
            catch (Exception ex)
            {
                print(String.Format("ERROR {0} IN ModuleLifeSupport", ex.Message));
            }
        }
Пример #14
0
        private List <LifeSupportVesselDisplayStat> UpdateGUIStats()
        {
            var useHabPenalties = (LifeSupportSetup.Instance.LSConfig.NoHomeEffectVets +
                                   LifeSupportSetup.Instance.LSConfig.NoHomeEffect > 0);

            LifeSupportManager.Instance.UpdateVesselStats();

            var statList = new List <LifeSupportVesselDisplayStat>();

            var checkVessels = new List <Guid>();

            foreach (var v in FlightGlobals.Vessels.Where(v => v.isEVA))
            {
                checkVessels.Add(v.id);
            }


            foreach (var vslId in checkVessels)
            {
                var vsl = FlightGlobals.Vessels.FirstOrDefault(v => v.id == vslId);
                if (vsl == null)
                {
                    continue;
                }

                var lblColor = "FFD966";
                var vstat    = new LifeSupportVesselDisplayStat();
                vstat.VesselName = String.Format("<color=#{0}>{1}</color>", lblColor, vsl.vesselName);
                vstat.LastUpdate = vsl.missionTime;
                var sitString = "(EVA)";

                var remEVATime = LifeSupportSetup.Instance.LSConfig.EVATime - vsl.missionTime;
                var timeString = LifeSupportUtilities.SecondsToKerbinTime(Math.Max(0, remEVATime));

                if (remEVATime > 0)
                {
                    vstat.SummaryLabel = String.Format(
                        "<color=#3DB1FF>{0}/{1} - </color><color=#9EE4FF>{2}</color><color=#3DB1FF> time remaining</color>"
                        , vsl.mainBody.bodyName
                        , sitString
                        , timeString.Substring(timeString.IndexOf(':') + 1));
                }
                else
                {
                    vstat.SummaryLabel = "<color=#FF8585>EVA Time Expired</color>";
                }

                vstat.crew = new List <LifeSupportCrewDisplayStat>();
                statList.Add(vstat);
            }

            var vesselList = new List <VesselSupplyStatus>();

            vesselList.AddRange(LifeSupportManager.Instance.VesselSupplyInfo);


            foreach (var vsl in vesselList)
            {
                var    vstat      = new LifeSupportVesselDisplayStat();
                Vessel thisVessel = FlightGlobals.Vessels.First(v => v.id.ToString() == vsl.VesselId);
                double supmult    = LifeSupportSetup.Instance.LSConfig.SupplyAmount * Convert.ToDouble(vsl.NumCrew) * vsl.RecyclerMultiplier;
                var    supPerDay  = (21600 * supmult);
                var    estFood    = supmult * (Planetarium.GetUniversalTime() - vsl.LastFeeding);
                var    habTime    = LifeSupportManager.GetTotalHabTime(vsl);
                var    supAmount  = GetSuppliesInVessel(thisVessel);
                if (supAmount == 0)
                {
                    supAmount = Math.Max(0, (vsl.SuppliesLeft * supmult) - estFood);
                }

                var lblColor = "ACFF40";
                if (Planetarium.GetUniversalTime() - vsl.LastUpdate > 2)
                {
                    lblColor = "C4C4C4";
                }
                vstat.VesselName = String.Format("<color=#{0}>{1}</color>", lblColor, vsl.VesselName);
                vstat.LastUpdate = vsl.LastUpdate;
                var sitString = "Orbiting";
                if (thisVessel.Splashed || thisVessel.heightFromTerrain < 1000)
                {
                    sitString = "Splashed";
                }
                if (thisVessel.Landed || thisVessel.heightFromTerrain < 1000)
                {
                    sitString = "Landed";
                }

                var habString = "indefinite";
                if (useHabPenalties)
                {
                    habString = LifeSupportUtilities.SecondsToKerbinTime(habTime, true);
                }
                vstat.SummaryLabel = String.Format("<color=#3DB1FF>{0}/{1} - </color><color=#9EE4FF>{2:0}</color><color=#3DB1FF> supplies (</color><color=#9EE4FF>{3:0.0}</color><color=#3DB1FF>/day) hab for </color><color=#9EE4FF>{4}</color>"
                                                   , thisVessel.mainBody.bodyName
                                                   , sitString
                                                   , supAmount
                                                   , supPerDay
                                                   , habString);
                vstat.crew = new List <LifeSupportCrewDisplayStat>();

                foreach (var c in thisVessel.GetVesselCrew())
                {
                    var cStat = new LifeSupportCrewDisplayStat();
                    var cls   = LifeSupportManager.Instance.FetchKerbal(c);
                    cStat.CrewName = String.Format("<color=#FFFFFF>{0} ({1})</color>", c.name, c.experienceTrait.Title.Substring(0, 1));

                    var snacksLeft = supAmount / supPerDay * 60 * 60 * 6;
                    if (supAmount <= ResourceUtilities.FLOAT_TOLERANCE && !LifeSupportManager.IsOnKerbin(thisVessel))
                    {
                        snacksLeft = cls.LastMeal - Planetarium.GetUniversalTime();
                    }

                    var lblSup = "6FFF00";
                    if (snacksLeft < 60 * 60 * 6 * 15) //15 days
                    {
                        lblSup = "FFE100";
                    }
                    if (snacksLeft < 0)
                    {
                        lblSup = "FFAE00";
                    }
                    if (snacksLeft < -60 * 60 * 6 * 15)
                    {
                        lblSup = "FF5E5E";
                    }
                    cStat.SupplyLabel = String.Format("<color=#{0}>{1}</color>", lblSup, LifeSupportUtilities.SecondsToKerbinTime(snacksLeft));
                    var timeLeft = Math.Min(cls.MaxOffKerbinTime - Planetarium.GetUniversalTime(), habTime - (Planetarium.GetUniversalTime() - cls.TimeEnteredVessel));

                    var lblHab = "6FFF00";
                    if (timeLeft < 60 * 60 * 6 * 15) //15 days
                    {
                        lblHab = "FFE100";
                    }
                    if (timeLeft < 0)
                    {
                        lblHab = "FFAE00";
                    }
                    if (timeLeft < -60 * 60 * 6 * 15)
                    {
                        lblHab = "FF5E5E";
                    }
                    var crewHabString = "indefinite";
                    if (useHabPenalties)
                    {
                        crewHabString = LifeSupportUtilities.SecondsToKerbinTime(timeLeft);
                    }
                    cStat.HabLabel = String.Format("<color=#{0}>{1}</color>", lblHab, crewHabString);
                    vstat.crew.Add(cStat);
                }
                statList.Add(vstat);
            }

            return(statList);
        }
Пример #15
0
        public void FixedUpdate()
        {
            if (!HighLogic.LoadedSceneIsFlight || vessel == null)
            {
                return;
            }
            if (!vessel.loaded)
            {
                return;
            }

            if (isDirty)
            {
                isDirty = false;
                UpdateVesselInfo();
                UpdateStatus();
            }

            if (_currentCrew == 0)
            {
                return;
            }

            try
            {
                bool isLongLoop = false;
                var  offKerbin  = !LifeSupportManager.IsOnKerbin(vessel);
                UnlockTins();
                CheckVesselId();

                //Check our time
                double deltaTime = GetDeltaTime();

                if (deltaTime < ResourceUtilities.FLOAT_TOLERANCE * 10)
                {
                    return;
                }

                if (Planetarium.GetUniversalTime() >= _lastProcessingTime + _checkInterval)
                {
                    isLongLoop          = true;
                    _lastProcessingTime = Planetarium.GetUniversalTime();
                }

                VesselStatus.LastUpdate = Planetarium.GetUniversalTime();
                VesselStatus.VesselName = vessel.vesselName;
                VesselStatus.NumCrew    = vessel.GetCrewCount();
                VesselStatus.CrewCap    = vessel.GetCrewCapacity();
                if (isLongLoop)
                {
                    CheckForDeadKerbals();
                }

                if (_currentCrew > 0)
                {
                    //Guard clause
                    if (_crewPart == null)
                    {
                        UpdateVesselInfo();
                    }

                    //we will add a bit of a fudge factor for supplies
                    var tolerance = deltaTime / 2f;
                    //nom nom nom!
                    ConverterResults resultSupply = ResConverter.ProcessRecipe(deltaTime, SupplyRecipe, _crewPart, null, 1f);
                    ConverterResults resultEC     = ResConverter.ProcessRecipe(deltaTime, ECRecipe, _crewPart, null, 1f);

                    foreach (var c in vessel.GetVesselCrew())
                    {
                        bool isGrouchyHab      = false;
                        bool isGrouchySupplies = false;
                        bool isGrouchyEC       = false;
                        //Fetch them from the queue
                        var k = LifeSupportManager.Instance.FetchKerbal(c);
                        //Update our stuff

                        #region Long Loop - Crew
                        if (isLongLoop)
                        {
                            //Ensure status is current
                            UpdateStatus();
                            //First - Hab effects.
                            if (LifeSupportManager.IsOnKerbin(vessel))
                            {
                                k.LastAtHome        = Planetarium.GetUniversalTime();
                                k.MaxOffKerbinTime  = 648000;
                                k.TimeEnteredVessel = Planetarium.GetUniversalTime();
                            }
                            else
                            {
                                if (vessel.id.ToString() != k.CurrentVesselId)
                                {
                                    if (vessel.id.ToString() != k.PreviousVesselId)
                                    {
                                        k.TimeEnteredVessel = Planetarium.GetUniversalTime();
                                    }

                                    k.PreviousVesselId = k.CurrentVesselId;
                                    k.CurrentVesselId  = vessel.id.ToString();
                                }
                            }
                            isGrouchyHab = CheckHabSideEffects(k);

                            //Second - Supply
                            if (offKerbin && (deltaTime - resultSupply.TimeFactor > tolerance))
                            {
                                isGrouchySupplies = CheckSupplySideEffects(k);
                            }
                            else if (deltaTime >= ResourceUtilities.FLOAT_TOLERANCE)
                            {
                                //All is well
                                k.LastMeal = LastUpdateTime;
                                VesselStatus.LastFeeding = LastUpdateTime;
                            }

                            //Third - EC
                            //Second - Supply
                            if (offKerbin && (deltaTime - resultEC.TimeFactor > tolerance))
                            {
                                isGrouchyEC = CheckECSideEffects(k);
                            }
                            else if (deltaTime >= ResourceUtilities.FLOAT_TOLERANCE)
                            {
                                //All is well
                                k.LastEC = LastUpdateTime;
                                VesselStatus.LastECCheck = LastUpdateTime;
                            }


                            k.LastUpdate = Planetarium.GetUniversalTime();

                            if (isGrouchyEC)
                            {
                                ApplyEffect(k, c,
                                            LifeSupportManager.isVet(k.KerbalName)
                                        ? LifeSupportScenario.Instance.settings.GetSettings().NoSupplyEffectVets
                                        : LifeSupportScenario.Instance.settings.GetSettings().NoSupplyEffect);
                            }
                            else if (isGrouchySupplies)
                            {
                                ApplyEffect(k, c,
                                            LifeSupportManager.isVet(k.KerbalName)
                                        ? LifeSupportScenario.Instance.settings.GetSettings().NoSupplyEffectVets
                                        : LifeSupportScenario.Instance.settings.GetSettings().NoSupplyEffect);
                            }
                            else if (isGrouchyHab)
                            {
                                ApplyEffect(k, c,
                                            LifeSupportManager.isVet(k.KerbalName)
                                        ? LifeSupportScenario.Instance.settings.GetSettings().NoHomeEffectVets
                                        : LifeSupportScenario.Instance.settings.GetSettings().NoHomeEffect);
                            }
                            else if (c.experienceTrait.Title != k.OldTrait)
                            {
                                RemoveGrouchiness(c, k);
                            }
                            LifeSupportManager.Instance.TrackKerbal(k);
                        }
                        #endregion - Crew
                        var supAmount = _resBroker.AmountAvailable(_crewPart, "Supplies", deltaTime, ResourceFlowMode.ALL_VESSEL);
                        var ecAmount  = _resBroker.AmountAvailable(_crewPart, "ElectricCharge", deltaTime, ResourceFlowMode.ALL_VESSEL);
                        VesselStatus.SuppliesLeft = supAmount / LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount /
                                                    _currentCrew /
                                                    VesselStatus.RecyclerMultiplier;
                        VesselStatus.ECLeft = ecAmount / LifeSupportScenario.Instance.settings.GetSettings().ECAmount /
                                              _currentCrew;
                    }
                }
                LifeSupportManager.Instance.TrackVessel(VesselStatus);
            }
            catch (Exception ex)
            {
                print(String.Format("ERROR {0} IN ModuleLifeSupport", ex.Message));
            }
        }
Пример #16
0
        private void UpdateGUIInfo(ShipConstruct ship)
        {
            ResetValues();
            if (EditorLogic.fetch != null)
            {
                foreach (var part in EditorLogic.fetch.ship.parts)
                {
                    maxCrew += part.CrewCapacity;
                }

                var dialog = KSP.UI.CrewAssignmentDialog.Instance;

                if (dialog != null)
                {
                    VesselCrewManifest manifest = dialog.GetManifest();
                    if (manifest != null)
                    {
                        curCrew = manifest.CrewCount;
                    }
                }


                foreach (var part in EditorLogic.fetch.ship.parts)
                {
                    var hab = part.Modules.GetModule <ModuleHabitation>();
                    if (hab != null)
                    {
                        var conList = part.Modules.GetModules <BaseConverter>();
                        var bayList = part.Modules.GetModules <ModuleSwappableConverter>();
                        if (bayList == null || bayList.Count == 0)
                        {
                            habs.Add(hab);
                            //Certain modules, in addition to crew capacity, have living space.
                            extraHabTime += hab.KerbalMonths;
                            //Some modules act more as 'multipliers', dramatically extending a hab's workable lifespan.
                            habMult += hab.HabMultiplier * Math.Min(1, hab.CrewCapacity / Math.Max(curCrew, 1));
                        }
                        else
                        {
                            foreach (var bay in bayList)
                            {
                                var con = conList[bay.currentLoadout] as ModuleHabitation;
                                if (con != null)
                                {
                                    habs.Add(con);
                                    extraHabTime += con.KerbalMonths;
                                    habMult      += con.HabMultiplier * Math.Min(1, con.CrewCapacity / Math.Max(curCrew, 1));
                                }
                            }
                        }
                    }
                    if (part.Resources.Contains("Supplies"))
                    {
                        supplies += part.Resources["Supplies"].amount;
                    }
                    if (part.Resources.Contains("ElectricCharge"))
                    {
                        batteryAmount += part.Resources["ElectricCharge"].maxAmount;
                    }
                }


                totalHabSpace = (LifeSupportScenario.Instance.settings.GetSettings().BaseHabTime *maxCrew) + extraHabTime;
                //A Kerbal month is 30 six-hour Kerbin days.
                totalHabMult     = habMult * LifeSupportScenario.Instance.settings.GetSettings().HabMultiplier *LifeSupportUtilities.SecondsPerMonth();
                totalBatteryTime = batteryAmount / LifeSupportScenario.Instance.settings.GetSettings().ECAmount;
                totalSupplyTime  = supplies / LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount;

                if (EditorLogic.fetch.ship.parts.Count > 0)
                {
                    foreach (var p in EditorLogic.fetch.ship.parts)
                    {
                        var rec = p.Modules.GetModule <ModuleLifeSupportRecycler>();
                        if (rec != null)
                        {
                            var conList = p.Modules.GetModules <BaseConverter>();
                            var bayList = p.Modules.GetModules <ModuleSwappableConverter>();
                            if (bayList == null || bayList.Count == 0)
                            {
                                recyclers.Add(rec);
                            }
                            else
                            {
                                foreach (var bay in bayList)
                                {
                                    var con = conList[bay.currentLoadout] as ModuleLifeSupportRecycler;
                                    if (con != null)
                                    {
                                        recyclers.Add(con);
                                    }
                                }
                            }
                        }
                    }
                    var recyclerMultiplier_curCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, curCrew);
                    var recyclerMultiplier_maxCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, maxCrew);

                    supply_curCrew = LifeSupportUtilities.SecondsToKerbinTime(
                        totalSupplyTime /
                        Math.Max(1, curCrew) /
                        recyclerMultiplier_curCrew
                        );
                    supply_maxCrew = LifeSupportUtilities.SecondsToKerbinTime(
                        totalSupplyTime /
                        Math.Max(1, maxCrew) /
                        recyclerMultiplier_maxCrew
                        );

                    hab_curCrew = LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, curCrew) * totalHabMult);
                    hab_maxCrew = LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, maxCrew) * totalHabMult);
                }
            }
        }
Пример #17
0
        private List <LifeSupportVesselDisplayStat> UpdateGUIStats()
        {
            var secondsPerDay   = GameSettings.KERBIN_TIME ? (21600) : (86400);
            var useHabPenalties = (LifeSupportScenario.Instance.settings.GetSettings().NoHomeEffectVets +
                                   LifeSupportScenario.Instance.settings.GetSettings().NoHomeEffect > 0);

            LifeSupportManager.Instance.UpdateVesselStats();

            var statList = new List <LifeSupportVesselDisplayStat>();

            var checkVessels = new List <Guid>();

            foreach (var v in FlightGlobals.Vessels.Where(v => v.isEVA))
            {
                checkVessels.Add(v.id);
            }


            foreach (var vslId in checkVessels)
            {
                var vsl = FlightGlobals.Vessels.FirstOrDefault(v => v.id == vslId);
                if (vsl == null)
                {
                    continue;
                }

                var lblColor = "FFD966";
                var vstat    = new LifeSupportVesselDisplayStat();
                vstat.VesselName = String.Format("<color=#{0}>{1}</color>", lblColor, vsl.vesselName);
                vstat.LastUpdate = vsl.missionTime;
                var sitString = "(EVA)";

                var remEVATime = LifeSupportScenario.Instance.settings.GetSettings().EVATime - vsl.missionTime;
                var timeString = LifeSupportUtilities.SecondsToKerbinTime(Math.Max(0, remEVATime));

                if (remEVATime > 0)
                {
                    vstat.SummaryLabel = String.Format(
                        "<color=#3DB1FF>{0}/{1} - </color><color=#9EE4FF>{2}</color><color=#3DB1FF> time remaining</color>"
                        , vsl.mainBody.bodyName
                        , sitString
                        , timeString.Substring(timeString.IndexOf(':') + 1));
                }
                else
                {
                    vstat.SummaryLabel = "<color=#FF8585>EVA Time Expired</color>";
                }

                vstat.crew = new List <LifeSupportCrewDisplayStat>();
                statList.Add(vstat);
            }

            var vesselList = new List <VesselSupplyStatus>();

            vesselList.AddRange(LifeSupportManager.Instance.VesselSupplyInfo);


            foreach (var vsl in vesselList)
            {
                var    vstat      = new LifeSupportVesselDisplayStat();
                Vessel thisVessel = FlightGlobals.Vessels.First(v => v.id.ToString() == vsl.VesselId);
                double supmult    = LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount *Convert.ToDouble(vsl.NumCrew) * vsl.RecyclerMultiplier;
                var    supPerDay  = secondsPerDay * supmult;
                var    estFood    = supmult * (Planetarium.GetUniversalTime() - vsl.LastFeeding);

                double ecmult   = LifeSupportScenario.Instance.settings.GetSettings().ECAmount *Convert.ToDouble(vsl.NumCrew);
                var    ecPerDay = secondsPerDay * ecmult;
                var    estEC    = ecmult * (Planetarium.GetUniversalTime() - vsl.LastECCheck);

                int numSharedHabVessels = 0;
                var habTime             = LifeSupportManager.GetTotalHabTime(vsl, out numSharedHabVessels);

                var supAmount = GetResourceInVessel(thisVessel, "Supplies");
                if (supAmount == 0)
                {
                    supAmount = Math.Max(0, (vsl.SuppliesLeft * supmult) - estFood);
                }

                var ecAmount = GetResourceInVessel(thisVessel, "ElectricCharge");
                if (ecAmount == 0)
                {
                    ecAmount = Math.Max(0, (vsl.ECLeft * ecmult) - estEC);
                }

                bool isOldData = Planetarium.GetUniversalTime() - vsl.LastUpdate > 2;
                var  lblColor  = isOldData ? "C4C4C4" : "ACFF40";

                vstat.VesselName = String.Format("<color=#{0}>{1}</color>", lblColor, vsl.VesselName);
                vstat.VesselId   = vsl.VesselId;
                vstat.LastUpdate = vsl.LastUpdate;
                var sitString = "Orbiting";


                thisVessel.checkSplashed();
                if (thisVessel.Splashed)
                {
                    sitString = "Splashed";
                }
                thisVessel.checkLanded();
                if (thisVessel.Landed)
                {
                    sitString = "Landed";
                }

                var habString = "indefinite";
                if (useHabPenalties)
                {
                    habString = LifeSupportUtilities.SecondsToKerbinTime(habTime, true);
                }
                vstat.SummaryLabel = String.Format(
                    "<color=#3DB1FF>{0}/{1} - </color><color=#9EE4FF>{2:0}</color><color=#3DB1FF> supplies (</color><color=#9EE4FF>{3:0.0}</color><color=#3DB1FF>/day) hab for </color><color=#9EE4FF>{4}</color>"
                    , thisVessel.mainBody.bodyName
                    , sitString
                    , supAmount
                    , supPerDay
                    , habString);
                vstat.crew = new List <LifeSupportCrewDisplayStat>();
                if (useHabPenalties)
                {
                    vstat.SummaryLabel += String.Format(
                        "<color=#3DB1FF> (</color><color=#9EE4FF>{0}</color><color=#3DB1FF> {1} shared within </color><color=#9EE4FF>{2}</color><color=#3DB1FF>m)</color>",
                        isOldData ? "?" : numSharedHabVessels.ToString(),
                        numSharedHabVessels == 1 ? "vessel" : "vessels",
                        LifeSupportScenario.Instance.settings.GetSettings().HabRange);
                }

                foreach (var c in thisVessel.GetVesselCrew())
                {
                    var cStat = new LifeSupportCrewDisplayStat();
                    var cls   = LifeSupportManager.Instance.FetchKerbal(c);
                    cStat.CrewName = String.Format("<color=#FFFFFF>{0} ({1})</color>", c.name, c.experienceTrait.Title.Substring(0, 1));

                    var ecLeft = (ecAmount / ecPerDay * secondsPerDay) + LifeSupportScenario.Instance.settings.GetSettings().ECTime;
                    if (ecAmount <= LifeSupportScenario.Instance.settings.GetSettings().ECAmount&& !LifeSupportManager.IsOnKerbin(thisVessel))
                    {
                        ecLeft = cls.LastEC - Planetarium.GetUniversalTime() + LifeSupportScenario.Instance.settings.GetSettings().ECTime;
                    }
                    var lblECTime = LifeSupportUtilities.SecondsToKerbinTime(ecLeft);

                    var lblEC = "6FFF00";
                    if (ecLeft < LifeSupportScenario.Instance.settings.GetSettings().ECTime)
                    {
                        lblEC = "FFE100";
                    }
                    if (ecLeft < LifeSupportScenario.Instance.settings.GetSettings().ECTime / 2)
                    {
                        lblEC = "FFAE00";
                    }
                    if (ecLeft <= ResourceUtilities.FLOAT_TOLERANCE)
                    {
                        lblEC     = "FF5E5E";
                        lblECTime = "expired";
                    }
                    cStat.ECLabel = String.Format("<color=#{0}>{1}</color>", lblEC, lblECTime);


                    var snacksLeft = (supAmount / supPerDay * secondsPerDay) + LifeSupportScenario.Instance.settings.GetSettings().SupplyTime;
                    if (supAmount <= LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount&& !LifeSupportManager.IsOnKerbin(thisVessel))
                    {
                        snacksLeft = cls.LastMeal - Planetarium.GetUniversalTime() + LifeSupportScenario.Instance.settings.GetSettings().SupplyTime;
                    }

                    var lblSupTime = LifeSupportUtilities.SecondsToKerbinTime(snacksLeft);

                    var lblSup = "6FFF00";
                    if (snacksLeft < LifeSupportScenario.Instance.settings.GetSettings().SupplyTime)
                    {
                        lblSup = "FFE100";
                    }
                    if (snacksLeft < LifeSupportScenario.Instance.settings.GetSettings().SupplyTime / 2)
                    {
                        lblSup = "FFAE00";
                    }
                    if (snacksLeft <= ResourceUtilities.FLOAT_TOLERANCE)
                    {
                        lblSup     = "FF5E5E";
                        lblSupTime = "expired";
                    }
                    cStat.SupplyLabel = String.Format("<color=#{0}>{1}</color>", lblSup, lblSupTime);


                    var habTimeLeft  = habTime - (Planetarium.GetUniversalTime() - cls.TimeEnteredVessel);
                    var homeTimeLeft = cls.MaxOffKerbinTime - Planetarium.GetUniversalTime();

                    var crewHabString  = "indefinite";
                    var crewHomeString = "indefinite";
                    var lblHab         = "6FFF00";
                    var lblHome        = "6FFF00";

                    if (useHabPenalties)
                    {
                        crewHomeString = LifeSupportUtilities.SecondsToKerbinTime(homeTimeLeft);
                        crewHabString  = LifeSupportUtilities.SecondsToKerbinTime(habTimeLeft);
                    }



                    if (habTimeLeft < secondsPerDay * 30)
                    {
                        lblHab = "FFE100";
                    }
                    if (habTimeLeft < secondsPerDay * 15)
                    {
                        lblHab = "FFAE00";
                    }
                    if (habTimeLeft < 0)
                    {
                        lblHab        = "FF5E5E";
                        crewHabString = "expired";
                    }
                    cStat.HabLabel = String.Format("<color=#{0}>{1}</color>", lblHab, crewHabString);

                    if (homeTimeLeft < secondsPerDay * 30) //15 days
                    {
                        lblHome = "FFE100";
                    }
                    if (homeTimeLeft < secondsPerDay * 15)
                    {
                        lblHome = "FFAE00";
                    }
                    if (homeTimeLeft < 0)
                    {
                        lblHome        = "FF5E5E";
                        crewHomeString = "expired";
                    }
                    cStat.HomeLabel = String.Format("<color=#{0}>{1}</color>", lblHome, crewHomeString);


                    vstat.crew.Add(cStat);
                }
                statList.Add(vstat);
            }

            return(statList);
        }
Пример #18
0
        public void FixedUpdate()
        {
            if (!HighLogic.LoadedSceneIsFlight)
            {
                return;
            }

            try
            {
                bool isLongLoop = false;
                var  offKerbin  = !LifeSupportManager.IsOnKerbin(part.vessel);
                UnlockTins();
                CheckVesselId();

                //Check our time
                double deltaTime = GetDeltaTime();

                if (deltaTime < ResourceUtilities.FLOAT_TOLERANCE * 10)
                {
                    return;
                }

                if (Planetarium.GetUniversalTime() >= _lastProcessingTime + _checkInterval)
                {
                    isLongLoop          = true;
                    _lastProcessingTime = Planetarium.GetUniversalTime();
                }



                var v = LifeSupportManager.Instance.FetchVessel(part.vessel.id.ToString());
                v.LastUpdate = Planetarium.GetUniversalTime();
                v.VesselName = part.vessel.vesselName;
                v.NumCrew    = part.vessel.GetCrewCount();
                v.CrewCap    = part.vessel.GetCrewCapacity();
                if (isLongLoop)
                {
                    v.RecyclerMultiplier = (float)LifeSupportManager.GetRecyclerMultiplier(part.vessel);
                    CheckForDeadKerbals();
                }

                if (part.protoModuleCrew.Count > 0)
                {
                    #region Long loop - Vessel
                    //Only check effects periodically, this is for performance reasons.
                    if (isLongLoop)
                    {
                        //Update Hab info

                        var habMulti = CalculateVesselHabMultiplier(part.vessel, v.NumCrew);
                        var habTime  = CalculateVesselHabExtraTime(part.vessel);
                        var totParts = 0d;
                        var maxParts = 0d;


                        v.ExtraHabSpace       = habTime;
                        v.VesselHabMultiplier = habMulti;
                        //We also have to temper this with whether or not these parts are worn out.
                        if (part.Resources.Contains("ReplacementParts"))
                        {
                            var res = part.Resources["ReplacementParts"];
                            totParts = res.amount;
                            maxParts = res.maxAmount;
                        }

                        //Worn out parts have a corresponding negative effect.
                        if (maxParts > 0)
                        {
                            v.VesselHabMultiplier *= (totParts / maxParts);
                            v.ExtraHabSpace       *= (totParts / maxParts);
                            if (totParts < 1)
                            {
                                wearPercent = "Broken!";
                            }
                            else
                            {
                                wearPercent = String.Format("{0:0.00}%", (1d - (totParts / maxParts)) * 100);
                            }
                        }
                        else
                        {
                            wearPercent = "Like New";
                        }
                    }
                    #endregion
                    //we will add a bit of a fudge factor for supplies
                    var tolerance = deltaTime / 2f;
                    //nom nom nom!
                    ConverterResults resultSupply = ResConverter.ProcessRecipe(deltaTime, SupplyRecipe, part, this, 1f);
                    ConverterResults resultEC     = ResConverter.ProcessRecipe(deltaTime, ECRecipe, part, this, 1f);

                    foreach (var c in part.protoModuleCrew)
                    {
                        bool isGrouchyHab      = false;
                        bool isGrouchySupplies = false;
                        bool isGrouchyEC       = false;
                        //Fetch them from the queue
                        var k = LifeSupportManager.Instance.FetchKerbal(c);
                        //Update our stuff

                        #region Long Loop - Crew
                        if (isLongLoop)
                        {
                            //First - Hab effects.
                            if (LifeSupportManager.IsOnKerbin(part.vessel))
                            {
                                k.LastAtHome        = Planetarium.GetUniversalTime();
                                k.MaxOffKerbinTime  = 648000;
                                k.TimeEnteredVessel = Planetarium.GetUniversalTime();
                            }
                            else
                            {
                                if (part.vessel.id.ToString() != k.CurrentVesselId)
                                {
                                    if (part.vessel.id.ToString() != k.PreviousVesselId)
                                    {
                                        k.TimeEnteredVessel = Planetarium.GetUniversalTime();
                                    }

                                    k.PreviousVesselId = k.CurrentVesselId;
                                    k.CurrentVesselId  = part.vessel.id.ToString();
                                }
                            }
                            isGrouchyHab = CheckHabSideEffects(k, v);

                            //Second - Supply
                            if (offKerbin && (deltaTime - resultSupply.TimeFactor > tolerance))
                            {
                                isGrouchySupplies = CheckSupplySideEffects(k);
                            }
                            else if (deltaTime >= ResourceUtilities.FLOAT_TOLERANCE)
                            {
                                //All is well
                                k.LastMeal    = lastUpdateTime;
                                v.LastFeeding = lastUpdateTime;
                            }

                            //Third - EC
                            //Second - Supply
                            if (offKerbin && (deltaTime - resultEC.TimeFactor > tolerance))
                            {
                                isGrouchyEC = CheckECSideEffects(k);
                            }
                            else if (deltaTime >= ResourceUtilities.FLOAT_TOLERANCE)
                            {
                                //All is well
                                k.LastEC      = lastUpdateTime;
                                v.LastECCheck = lastUpdateTime;
                            }


                            k.LastUpdate = Planetarium.GetUniversalTime();

                            if (isGrouchyEC)
                            {
                                ApplyEffect(k, c,
                                            LifeSupportManager.isVet(k.KerbalName)
                                        ? LifeSupportScenario.Instance.settings.GetSettings().NoSupplyEffectVets
                                        : LifeSupportScenario.Instance.settings.GetSettings().NoSupplyEffect);
                            }
                            else if (isGrouchySupplies)
                            {
                                ApplyEffect(k, c,
                                            LifeSupportManager.isVet(k.KerbalName)
                                        ? LifeSupportScenario.Instance.settings.GetSettings().NoSupplyEffectVets
                                        : LifeSupportScenario.Instance.settings.GetSettings().NoSupplyEffect);
                            }
                            else if (isGrouchyHab)
                            {
                                ApplyEffect(k, c,
                                            LifeSupportManager.isVet(k.KerbalName)
                                        ? LifeSupportScenario.Instance.settings.GetSettings().NoHomeEffectVets
                                        : LifeSupportScenario.Instance.settings.GetSettings().NoHomeEffect);
                            }
                            else if (c.experienceTrait.Title != k.OldTrait)
                            {
                                RemoveGrouchiness(c, k);
                            }
                            LifeSupportManager.Instance.TrackKerbal(k);
                        }
                        #endregion - Crew
                        var supAmount = _resBroker.AmountAvailable(part, "Supplies", deltaTime, ResourceFlowMode.ALL_VESSEL);
                        var ecAmount  = _resBroker.AmountAvailable(part, "ElectricCharge", deltaTime, ResourceFlowMode.ALL_VESSEL);
                        v.SuppliesLeft = supAmount / LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount /
                                         part.vessel.GetCrewCount() /
                                         v.RecyclerMultiplier;
                        v.ECLeft = ecAmount / LifeSupportScenario.Instance.settings.GetSettings().ECAmount /
                                   part.vessel.GetCrewCount();
                    }
                }
                LifeSupportManager.Instance.TrackVessel(v);
            }
            catch (Exception ex)
            {
                print(String.Format("ERROR {0} IN ModuleLifeSupport", ex.Message));
            }
        }
Пример #19
0
        private void GenerateWindow()
        {
            GUILayout.BeginVertical();
            scrollPos = GUILayout.BeginScrollView(scrollPos, _scrollStyle, GUILayout.Width(600), GUILayout.Height(350));
            GUILayout.BeginVertical();

            var useHabPenalties = (LifeSupportSetup.Instance.LSConfig.NoHomeEffectVets +
                                   LifeSupportSetup.Instance.LSConfig.NoHomeEffect > 0);

            if (EditorLogic.fetch != null)
            {
                var curCrew       = 0;
                var maxCrew       = 0;
                var supplies      = 0d;
                var extraHabTime  = 0d;
                var habMult       = 1d;
                var batteryAmount = 0d;

                foreach (var part in EditorLogic.fetch.ship.parts)
                {
                    maxCrew += part.CrewCapacity;
                }

                CMAssignmentDialog dialog = CMAssignmentDialog.Instance;
                if (dialog != null)
                {
                    VesselCrewManifest manifest = dialog.GetManifest();
                    if (manifest != null)
                    {
                        foreach (PartCrewManifest pcm in manifest)
                        {
                            int partCrewCount = pcm.GetPartCrew().Count(c => c != null);
                            if (partCrewCount > 0)
                            {
                                curCrew += partCrewCount;
                            }
                        }
                    }
                }

                foreach (var part in EditorLogic.fetch.ship.parts)
                {
                    var hab = part.Modules.GetModules <ModuleHabitation>().FirstOrDefault();
                    if (hab != null)
                    {
                        //Certain modules, in addition to crew capacity, have living space.
                        extraHabTime += hab.KerbalMonths;
                        //Some modules act more as 'multipliers', dramatically extending a hab's workable lifespan.
                        habMult += hab.HabMultiplier * Math.Min(1, (hab.CrewCapacity / curCrew));
                    }

                    if (part.Resources.Contains("Supplies"))
                    {
                        supplies += part.Resources["Supplies"].amount;
                    }
                    if (part.Resources.Contains("ElectricCharge"))
                    {
                        batteryAmount += part.Resources["ElectricCharge"].maxAmount;
                    }
                }


                var totalHabSpace = (LifeSupportSetup.Instance.LSConfig.BaseHabTime * maxCrew) + extraHabTime;
                //A Kerbal month is 30 six-hour Kerbin days.
                var totalHabMult = habMult * LifeSupportSetup.Instance.LSConfig.HabMultiplier * 60d * 60d * 6d * 30d;

                var totalBatteryTime = batteryAmount / LifeSupportSetup.Instance.LSConfig.ECAmount;
                var totalSupplyTime  = supplies / LifeSupportSetup.Instance.LSConfig.SupplyAmount;

                if (EditorLogic.fetch.ship.parts.Count > 0)
                {
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("Crew", _labelStyle, GUILayout.Width(90));
                    GUILayout.Label("Supplies", _labelStyle, GUILayout.Width(160));
                    GUILayout.Label("Batteries", _labelStyle, GUILayout.Width(160));
                    GUILayout.Label("Habitation", _labelStyle, GUILayout.Width(160));
                    GUILayout.EndHorizontal();

                    GUILayout.BeginHorizontal();
                    GUILayout.Label("Current (" + curCrew + ")", _labelStyle, GUILayout.Width(90));
                    GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalSupplyTime / Math.Max(1, curCrew) / LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, curCrew)), _labelStyle,
                                    GUILayout.Width(160));
                    GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalBatteryTime / Math.Max(1, curCrew)), _labelStyle,
                                    GUILayout.Width(160));
                    if (useHabPenalties)
                    {
                        GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, curCrew) * totalHabMult), _labelStyle,
                                        GUILayout.Width(160));
                    }
                    else
                    {
                        GUILayout.Label("indefinite", _labelStyle, GUILayout.Width(160));
                    }
                    GUILayout.EndHorizontal();

                    GUILayout.BeginHorizontal();
                    GUILayout.Label("Max (" + maxCrew + ")", _labelStyle, GUILayout.Width(90));
                    GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalSupplyTime / Math.Max(1, maxCrew) / LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, maxCrew)), _labelStyle,
                                    GUILayout.Width(160));
                    GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalBatteryTime / Math.Max(1, maxCrew)), _labelStyle,
                                    GUILayout.Width(160));
                    if (useHabPenalties)
                    {
                        GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, maxCrew) * totalHabMult), _labelStyle,
                                        GUILayout.Width(160));
                    }
                    else
                    {
                        GUILayout.Label("indefinite", _labelStyle, GUILayout.Width(160));
                    }
                    GUILayout.EndHorizontal();
                }
            }
            GUILayout.EndVertical();
            GUILayout.EndScrollView();
            GUILayout.EndVertical();
            GUI.DragWindow();
        }
Пример #20
0
        private LifeSupportVesselDisplayStat GetVesselStats(VesselSupplyStatus vsl)
        {
            var secondsPerDay   = GameSettings.KERBIN_TIME ? (21600) : (86400);
            var useHabPenalties = (LifeSupportScenario.Instance.settings.GetSettings().NoHomeEffectVets +
                                   LifeSupportScenario.Instance.settings.GetSettings().NoHomeEffect > 0);

            Vessel thisVessel = FlightGlobals.Vessels.Find(v => v.id.ToString() == vsl.VesselId);
            var    vstat      = new LifeSupportVesselDisplayStat();
            bool   isOldData  = Planetarium.GetUniversalTime() - vsl.LastUpdate > 2;
            var    lblColor   = isOldData ? "C4C4C4" : "ACFF40";

            vstat.VesselName = String.Format("<color=#{0}>{1}</color>", lblColor, vsl.VesselName);
            vstat.VesselId   = vsl.VesselId;
            vstat.LastUpdate = vsl.LastUpdate;
            var situationString = GetSituationString(thisVessel);

            double suppliesPerSecond = LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount *Convert.ToDouble(vsl.NumCrew) * vsl.RecyclerMultiplier;
            var    suppliesPerDay    = secondsPerDay * suppliesPerSecond;
            var    supAmount         = GetResourceInVessel(thisVessel, "Supplies");
            var    suppliesTimeLeft  = (suppliesPerSecond > ResourceUtilities.FLOAT_TOLERANCE) ? (supAmount / suppliesPerSecond) : 0;

            if (supAmount == 0)
            {
                var suppliesConsumedSinceLastCheck = suppliesPerSecond * (Planetarium.GetUniversalTime() - vsl.LastFeeding);
                supAmount        = Math.Max(0, (vsl.SuppliesLeft * suppliesPerSecond) - suppliesConsumedSinceLastCheck);
                suppliesTimeLeft = (vsl.SuppliesLeft - (Planetarium.GetUniversalTime() - vsl.LastFeeding));
            }

            double ecPerSecond = LifeSupportScenario.Instance.settings.GetSettings().ECAmount *Convert.ToDouble(vsl.NumCrew);
            var    ecAmount    = GetResourceInVessel(thisVessel, "ElectricCharge");
            var    ecTimeLeft  = (ecPerSecond > ResourceUtilities.FLOAT_TOLERANCE) ? (ecAmount / ecPerSecond) : 0;

            if (ecAmount == 0)
            {
                var ecConsumedSinceLastCheck = ecPerSecond * (Planetarium.GetUniversalTime() - vsl.LastECCheck);
                ecAmount   = Math.Max(0, (vsl.ECLeft * ecPerSecond) - ecConsumedSinceLastCheck);
                ecTimeLeft = (vsl.ECLeft - (Planetarium.GetUniversalTime() - vsl.LastECCheck));
            }

            int numSharedHabVessels = 0;
            var habTime             = LifeSupportManager.GetTotalHabTime(vsl, thisVessel, out numSharedHabVessels);

            var habString = "indefinite";

            if (useHabPenalties)
            {
                habString = LifeSupportUtilities.DurationDisplay(habTime, LifeSupportUtilities.TimeFormatLength.Short);
            }
            vstat.SummaryLabel = String.Format(
                "<color=#3DB1FF>{0}/{1} - </color><color=#9EE4FF>{2:0}</color><color=#3DB1FF> supplies (</color><color=#9EE4FF>{3:0.0}</color><color=#3DB1FF>/day) hab for </color><color=#9EE4FF>{4}</color>"
                , thisVessel.mainBody.bodyName
                , situationString
                , supAmount
                , suppliesPerDay
                , habString);
            vstat.crew = new List <LifeSupportCrewDisplayStat>();
            if (useHabPenalties)
            {
                vstat.SummaryLabel += String.Format(
                    "<color=#3DB1FF> (</color><color=#9EE4FF>{0}</color><color=#3DB1FF> {1} shared within </color><color=#9EE4FF>{2}</color><color=#3DB1FF>m)</color>",
                    isOldData ? "?" : numSharedHabVessels.ToString(),
                    numSharedHabVessels == 1 ? "vessel" : "vessels",
                    LifeSupportScenario.Instance.settings.GetSettings().HabRange);
            }

            foreach (var c in thisVessel.GetVesselCrew())
            {
                var crewStat = GetCrewStat(c, thisVessel, suppliesTimeLeft, ecTimeLeft, ecAmount, habTime);
                vstat.crew.Add(crewStat);
            }
            vstat.crew = vstat.crew.OrderBy(crewStat => crewStat.EarliestExpiration).ToList();
            if (vstat.crew.Any())
            {
                vstat.EarliestExpiration = vstat.crew.First().EarliestExpiration;
            }
            return(vstat);
        }
Пример #21
0
        private void UpdateGUIInfo(ShipConstruct ship)
        {
            ResetValues();
            if (EditorLogic.fetch != null)
            {
                var parts = EditorLogic.fetch.ship.parts;
                var count = parts.Count;
                for (int i = 0; i < count; ++i)
                {
                    var part = parts[i];
                    maxCrew += part.CrewCapacity;
                }

                var dialog = KSP.UI.CrewAssignmentDialog.Instance;

                if (dialog != null)
                {
                    VesselCrewManifest manifest = dialog.GetManifest();
                    if (manifest != null)
                    {
                        curCrew = manifest.CrewCount;
                    }
                }

                for (int i = 0; i < count; ++i)
                {
                    var part        = parts[i];
                    var swapOptions = part.FindModulesImplementing <AbstractSwapOption>();
                    var bays        = part.FindModulesImplementing <USI_SwappableBay>();
                    if (swapOptions != null && bays != null && swapOptions.Count > 0 && bays.Count > 0)
                    {
                        for (int x = 0; x < bays.Count; x++)
                        {
                            var bay     = bays[x];
                            var loadout = swapOptions[bay.currentLoadout] as USILS_HabitationSwapOption;
                            if (loadout != null)
                            {
                                habs.Add(loadout);
                                //Certain modules, in addition to crew capacity, have living space.
                                extraHabTime += loadout.BaseKerbalMonths;
                                //Some modules act more as 'multipliers', dramatically extending a hab's workable lifespan.
                                habMult += loadout.BaseHabMultiplier * Math.Min(1, loadout.CrewCapacity / Math.Max(curCrew, 1));
                            }
                        }
                    }
                    if (part.Resources.Contains("ColonySupplies"))
                    {
                        colonySupplies += part.Resources["ColonySupplies"].amount;
                    }
                    if (part.Resources.Contains("Fertilizer"))
                    {
                        fertilizer += part.Resources["Fertilizer"].amount;
                    }
                    if (part.Resources.Contains("Supplies"))
                    {
                        supplies += part.Resources["Supplies"].amount;
                    }
                    if (part.Resources.Contains("ElectricCharge"))
                    {
                        batteryAmount += part.Resources["ElectricCharge"].maxAmount;
                    }
                }

                totalHabSpace = (LifeSupportScenario.Instance.settings.GetSettings().BaseHabTime *maxCrew) + extraHabTime;
                //A Kerbal month is 30 six-hour Kerbin days.
                totalHabMult        = habMult * LifeSupportScenario.Instance.settings.GetSettings().HabMultiplier *LifeSupportUtilities.SecondsPerMonth();
                totalBatteryTime    = batteryAmount / LifeSupportScenario.Instance.settings.GetSettings().ECAmount;
                totalSupplyTime     = supplies / LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount;
                totalFertilizerTime = fertilizer * 10 / LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount;

                if (EditorLogic.fetch.ship.parts.Count > 0)
                {
                    for (int i = 0; i < count; ++i)
                    {
                        var part        = parts[i];
                        var swapOptions = part.FindModulesImplementing <AbstractSwapOption>();
                        var bays        = part.FindModulesImplementing <USI_SwappableBay>();
                        if (swapOptions != null && bays != null && swapOptions.Count > 0 && bays.Count > 0)
                        {
                            for (int x = 0; x < bays.Count; x++)
                            {
                                var bay     = bays[x];
                                var loadout = swapOptions[bay.currentLoadout] as USILS_LifeSupportRecyclerSwapOption;
                                if (loadout != null)
                                {
                                    this.recyclers.Add(loadout);
                                }
                            }
                        }
                    }
                    var recyclerMultiplier_curCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, curCrew);
                    var recyclerMultiplier_maxCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, maxCrew);

                    supply_curCrew = LifeSupportUtilities.DurationDisplay(
                        totalSupplyTime /
                        Math.Max(1, curCrew) /
                        recyclerMultiplier_curCrew
                        );
                    supply_maxCrew = LifeSupportUtilities.DurationDisplay(
                        totalSupplyTime /
                        Math.Max(1, maxCrew) /
                        recyclerMultiplier_maxCrew
                        );

                    hab_curCrew = LifeSupportUtilities.DurationDisplay(totalHabSpace / Math.Max(1, curCrew) * totalHabMult);
                    hab_maxCrew = LifeSupportUtilities.DurationDisplay(totalHabSpace / Math.Max(1, maxCrew) * totalHabMult);

                    supplyExt_curCrew = LifeSupportUtilities.DurationDisplay(
                        (totalSupplyTime + totalFertilizerTime) /
                        Math.Max(1, curCrew) /
                        recyclerMultiplier_curCrew
                        );
                    supplyExt_maxCrew = LifeSupportUtilities.DurationDisplay(
                        (totalSupplyTime + totalFertilizerTime) /
                        Math.Max(1, maxCrew) /
                        recyclerMultiplier_maxCrew
                        );
                    //Standard is half a colony supply per hour, or 0.000139 per second.
                    var csupPerSecond = 0.000139d;
                    habExt_curCrew = LifeSupportUtilities.DurationDisplay((totalHabSpace / Math.Max(1, curCrew) * totalHabMult) + (colonySupplies / csupPerSecond / curCrew));
                    habExt_maxCrew = LifeSupportUtilities.DurationDisplay((totalHabSpace / Math.Max(1, maxCrew) * totalHabMult) + (colonySupplies / csupPerSecond / maxCrew));
                }
            }
        }
Пример #22
0
        private LifeSupportCrewDisplayStat GetCrewStat(ProtoCrewMember c, Vessel vessel, double vesselSuppliesTimeLeft, double vesselEcTimeLeft, double vesselEcAmount, double vesselHabTime)
        {
            var cls = LifeSupportManager.Instance.FetchKerbal(c);

            //Guard clause in case we just changed vessels
            if (cls.CurrentVesselId != vessel.id.ToString() &&
                cls.PreviousVesselId != vessel.id.ToString())
            {
                cls.PreviousVesselId  = cls.CurrentVesselId;
                cls.CurrentVesselId   = vessel.id.ToString();
                cls.TimeEnteredVessel = Planetarium.GetUniversalTime();
                LifeSupportManager.Instance.TrackKerbal(cls);
            }

            // not sure this is correct or needed
            var ecTimeLeft = vesselEcTimeLeft;

            if (vesselEcAmount <= LifeSupportScenario.Instance.settings.GetSettings().ECAmount&& !LifeSupportManager.IsOnKerbin(vessel))
            {
                ecTimeLeft = cls.LastEC - Planetarium.GetUniversalTime();
            }

            var cStat = new LifeSupportCrewDisplayStat();

            cStat.CrewName = GetCrewNameLabel(c, cls);
            cStat.ComputeEc(ecTimeLeft, c);
            cStat.ComputeSupply(vesselSuppliesTimeLeft, c);
            cStat.ComputeHab(vesselHabTime, c, cls);
            cStat.ComputeHome(c, cls);

            LifeSupportManager.Instance.TrackKerbal(cls);
            return(cStat);
        }
Пример #23
0
        public void FixedUpdate()
        {
            if (part.protoModuleCrew.Count == 0)
            {
                return;
            }

            if (Planetarium.GetUniversalTime() < _lastProcessingTime + _checkInterval)
            {
                return;
            }

            _lastProcessingTime = Planetarium.GetUniversalTime();

            UnlockTins();
            //Check our time
            double deltaTime = GetDeltaTime();

            if (deltaTime < ResourceUtilities.FLOAT_TOLERANCE)
            {
                return;
            }

            ConverterResults result = ResConverter.ProcessRecipe(deltaTime, LifeSupportRecipe, part, this, 1f);

            var v = LifeSupportManager.Instance.FetchVessel(part.vessel.id.ToString());

            v.LastUpdate         = Planetarium.GetUniversalTime();
            v.VesselName         = part.vessel.vesselName;
            v.NumCrew            = part.vessel.GetCrewCount();
            v.RecyclerMultiplier = (float)LifeSupportManager.GetRecyclerMultiplier(part.vessel);
            v.CrewCap            = part.vessel.GetCrewCapacity();

            CheckForDeadKerbals();

            //Update Hab info
            var habMulti = 0d;
            var habTime  = 0d;
            var totParts = 0d;
            var maxParts = 0d;
            var habMods  = part.vessel.FindPartModulesImplementing <ModuleHabitation>();

            foreach (var hab in habMods)
            {
                //Next.  Certain modules, in addition to crew capacity, have living space.
                habTime += hab.KerbalMonths;
                //Lastly.  Some modules act more as 'multipliers', dramatically extending a hab's workable lifespan.
                habMulti += (hab.HabMultiplier * Math.Min(1, hab.CrewCapacity / v.NumCrew));
            }

            v.ExtraHabSpace       = habTime;
            v.VesselHabMultiplier = habMulti;
            //We also have to temper this with whether or not these parts are worn out.
            if (part.Resources.Contains("ReplacementParts"))
            {
                var res = part.Resources["ReplacementParts"];
                totParts = res.amount;
                maxParts = res.maxAmount;
            }
            //Worn out parts have a corresponding negative effect.
            if (maxParts > 0)
            {
                v.VesselHabMultiplier *= (totParts / maxParts);
                v.ExtraHabSpace       *= (totParts / maxParts);
                if (totParts < 1)
                {
                    wearPercent = "Broken!";
                }
                else
                {
                    wearPercent = String.Format("{0:0.00}%", (1d - (totParts / maxParts)) * 100);
                }
            }
            else
            {
                wearPercent = "Like New";
            }

            //we will add a bit of a fudge factor for supplies
            var tolerance = deltaTime / 2f;


            foreach (var c in part.protoModuleCrew)
            {
                bool isGrouchyHab      = false;
                bool isGrouchySupplies = false;

                //Fetch them from the queue
                var k = LifeSupportManager.Instance.FetchKerbal(c);
                //Update our stuff

                //First - Hab effects.
                if (LifeSupportManager.IsOnKerbin(part.vessel))
                {
                    k.LastOnKerbin      = Planetarium.GetUniversalTime();
                    k.MaxOffKerbinTime  = Planetarium.GetUniversalTime() + 972000000;
                    k.TimeEnteredVessel = Planetarium.GetUniversalTime();
                }
                else
                {
                    if (part.vessel.id.ToString() != k.LastVesselId)
                    {
                        k.LastVesselId      = part.vessel.id.ToString();
                        k.TimeEnteredVessel = Planetarium.GetUniversalTime();
                    }
                }
                isGrouchyHab = CheckHabSideEffects(k, v);

                //Second - Supply
                if (!LifeSupportManager.IsOnKerbin(part.vessel) && (deltaTime - result.TimeFactor > tolerance))
                {
                    isGrouchySupplies = CheckSupplySideEffects(k);
                }
                else
                {
                    //All is well
                    k.LastMeal    = lastUpdateTime;
                    v.LastFeeding = lastUpdateTime;
                }

                k.LastUpdate = Planetarium.GetUniversalTime();
                if (!isGrouchyHab && !isGrouchySupplies)
                {
                    RemoveGrouchiness(c, k);
                }

                if (deltaTime < _checkInterval * 2)
                {
                    if (isGrouchyHab)
                    {
                        ApplyEffect(k, c,
                                    LifeSupportManager.isVet(k.KerbalName)
                                ? LifeSupportSetup.Instance.LSConfig.NoHomeEffectVets
                                : LifeSupportSetup.Instance.LSConfig.NoHomeEffect);
                    }
                    if (isGrouchySupplies)
                    {
                        ApplyEffect(k, c,
                                    LifeSupportManager.isVet(k.KerbalName)
                                ? LifeSupportSetup.Instance.LSConfig.NoSupplyEffectVets
                                : LifeSupportSetup.Instance.LSConfig.NoSupplyEffect);
                    }
                }


                LifeSupportManager.Instance.TrackKerbal(k);
                var supAmpunt = _resBroker.AmountAvailable(part, "Supplies", deltaTime, "ALL_VESSEL");
                v.SuppliesLeft = supAmpunt / LifeSupportSetup.Instance.LSConfig.SupplyAmount /
                                 part.vessel.GetCrewCount() /
                                 LifeSupportManager.GetRecyclerMultiplier(vessel);
            }

            LifeSupportManager.Instance.TrackVessel(v);
        }
Пример #24
0
        private void GenerateWindow()
        {
            GUILayout.BeginVertical();
            scrollPos = GUILayout.BeginScrollView(scrollPos, _scrollStyle, GUILayout.Width(645), GUILayout.Height(350));
            GUILayout.BeginVertical();

            var useHabPenalties = (LifeSupportSetup.Instance.LSConfig.NoHomeEffectVets +
                                   LifeSupportSetup.Instance.LSConfig.NoHomeEffect > 0);

            if (EditorLogic.fetch != null)
            {
                var curCrew       = 0;
                var maxCrew       = 0;
                var supplies      = 0d;
                var extraHabTime  = 0d;
                var habMult       = 1d;
                var batteryAmount = 0d;

                List <ModuleHabitation> habs = new List <ModuleHabitation>();

                foreach (var part in EditorLogic.fetch.ship.parts)
                {
                    maxCrew += part.CrewCapacity;
                }

                CMAssignmentDialog dialog = CMAssignmentDialog.Instance;
                if (dialog != null)
                {
                    VesselCrewManifest manifest = dialog.GetManifest();
                    if (manifest != null)
                    {
                        foreach (PartCrewManifest pcm in manifest)
                        {
                            int partCrewCount = pcm.GetPartCrew().Count(c => c != null);
                            if (partCrewCount > 0)
                            {
                                curCrew += partCrewCount;
                            }
                        }
                    }
                }

                foreach (var part in EditorLogic.fetch.ship.parts)
                {
                    var hab = part.Modules.GetModules <ModuleHabitation>().FirstOrDefault();
                    if (hab != null)
                    {
                        habs.Add(hab);

                        //Certain modules, in addition to crew capacity, have living space.
                        extraHabTime += hab.KerbalMonths;
                        //Some modules act more as 'multipliers', dramatically extending a hab's workable lifespan.
                        habMult += hab.HabMultiplier * Math.Min(1, (hab.CrewCapacity / curCrew));
                    }

                    if (part.Resources.Contains("Supplies"))
                    {
                        supplies += part.Resources["Supplies"].amount;
                    }
                    if (part.Resources.Contains("ElectricCharge"))
                    {
                        batteryAmount += part.Resources["ElectricCharge"].maxAmount;
                    }
                }


                var totalHabSpace = (LifeSupportSetup.Instance.LSConfig.BaseHabTime * maxCrew) + extraHabTime;
                //A Kerbal month is 30 six-hour Kerbin days.
                var totalHabMult = habMult * LifeSupportSetup.Instance.LSConfig.HabMultiplier * 60d * 60d * 6d * 30d;

                var totalBatteryTime = batteryAmount / LifeSupportSetup.Instance.LSConfig.ECAmount;
                var totalSupplyTime  = supplies / LifeSupportSetup.Instance.LSConfig.SupplyAmount;

                if (EditorLogic.fetch.ship.parts.Count > 0)
                {
                    List <ModuleLifeSupportRecycler> recyclers = new List <ModuleLifeSupportRecycler>();
                    foreach (var p in EditorLogic.fetch.ship.parts)
                    {
                        var mod = p.FindModuleImplementing <ModuleLifeSupportRecycler>();
                        if (mod == null)
                        {
                            continue;
                        }

                        recyclers.Add(mod);
                    }
                    var recyclerMultiplier_curCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, curCrew);
                    var recyclerMultiplier_maxCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, maxCrew);

                    var supply_curCrew = LifeSupportUtilities.SecondsToKerbinTime(
                        totalSupplyTime /
                        Math.Max(1, curCrew) /
                        recyclerMultiplier_curCrew
                        );
                    var supply_maxCrew = LifeSupportUtilities.SecondsToKerbinTime(
                        totalSupplyTime /
                        Math.Max(1, maxCrew) /
                        recyclerMultiplier_maxCrew
                        );

                    var hab_curCrew = LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, curCrew) * totalHabMult);
                    var hab_maxCrew = LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, maxCrew) * totalHabMult);

                    // Colors
                    string operColor = "99FF33";
                    string textColor = "FFFFFF";
                    string crewColor = "ADD8E6";
                    string fadeColor = "909090";
                    string partColor = "FFCC00";

                    // SUMMARY
                    {
                        // column widths
                        const int c1 = 90;
                        const int c2 = 160;
                        const int c3 = 160;
                        const int c4 = 160;

                        // LABELS
                        GUILayout.BeginHorizontal();
                        GUILayout.Label("Crew", _labelStyle, GUILayout.Width(c1));
                        GUILayout.Label("Supplies", _labelStyle, GUILayout.Width(c2));
                        GUILayout.Label("Batteries", _labelStyle, GUILayout.Width(c3));
                        GUILayout.Label("Habitation", _labelStyle, GUILayout.Width(c4));
                        GUILayout.EndHorizontal();

                        // CURRENT CREW
                        GUILayout.BeginHorizontal();
                        GUILayout.Label(CTag("Current (", textColor) + CTag(Math.Max(1, curCrew).ToString(), crewColor) + CTag(")", textColor), _labelStyle, GUILayout.Width(c1));
                        GUILayout.Label(CTag(supply_curCrew, textColor), _labelStyle, GUILayout.Width(c2));
                        GUILayout.Label(
                            CTag(LifeSupportUtilities.SecondsToKerbinTime(totalBatteryTime / Math.Max(1, curCrew)), textColor),
                            _labelStyle,
                            GUILayout.Width(c3)
                            );
                        if (useHabPenalties)
                        {
                            GUILayout.Label(CTag(hab_curCrew, textColor), _labelStyle, GUILayout.Width(160));
                        }
                        else
                        {
                            GUILayout.Label(CTag("indefinite", textColor), _labelStyle, GUILayout.Width(c4));
                        }
                        GUILayout.EndHorizontal();

                        // MAX CREW
                        GUILayout.BeginHorizontal();
                        GUILayout.Label(CTag("Max (", textColor) + CTag(Math.Max(1, maxCrew).ToString(), crewColor) + CTag(")", textColor), _labelStyle, GUILayout.Width(c1));
                        GUILayout.Label(CTag(supply_maxCrew, textColor), _labelStyle, GUILayout.Width(c2));
                        GUILayout.Label(
                            CTag(LifeSupportUtilities.SecondsToKerbinTime(totalBatteryTime / Math.Max(1, maxCrew)), textColor),
                            _labelStyle,
                            GUILayout.Width(c3)
                            );
                        if (useHabPenalties)
                        {
                            GUILayout.Label(CTag(hab_maxCrew, textColor), _labelStyle, GUILayout.Width(160));
                        }
                        else
                        {
                            GUILayout.Label(CTag("indefinite", textColor), _labelStyle, GUILayout.Width(160));
                        }
                        GUILayout.EndHorizontal();
                    }

                    GUILayout.Space(20);

                    GUILayout.BeginHorizontal();
                    GUILayout.Label("<b>Details</b>", _labelStyle, GUILayout.Width(150));
                    GUILayout.EndHorizontal();

                    // HABITATION EQUATION
                    if (useHabPenalties)
                    {
                        // column widths
                        const int c1 = 150;
                        const int c2 = 80;
                        const int c3 = 80;
                        const int c4 = 90;
                        const int c5 = 80;
                        const int c6 = 50;
                        const int c7 = 50;

                        // hab = ((LSConfig.BaseHabTime * maxCrew) + ExtraHabTime) * Hab-Multiplier / Crew * LSConfig.HabMultiplier[Kerbin-Months]
                        GUILayout.BeginHorizontal();
                        GUILayout.Label("Habitation", _labelStyle, GUILayout.Width(c1 - 30));
                        GUILayout.Label(CTag("= ( (", operColor), _labelStyle, GUILayout.Width(30));
                        GUILayout.Label("BaseTime " + CTag("*", operColor), _labelStyle, GUILayout.Width(c2));
                        GUILayout.Label("MaxCrew " + CTag(") +", operColor), _labelStyle, GUILayout.Width(c3));
                        GUILayout.Label("ExtraTime " + CTag(") *", operColor), _labelStyle, GUILayout.Width(c4));
                        GUILayout.Label("Multiplier " + CTag("/", operColor), _labelStyle, GUILayout.Width(c5));
                        GUILayout.Label("Crew " + CTag("*", operColor), _labelStyle, GUILayout.Width(c6));
                        GUILayout.Label("Months", _labelStyle, GUILayout.Width(c7));
                        GUILayout.EndHorizontal();

                        GUILayout.BeginHorizontal();
                        GUILayout.Label(CTag(hab_curCrew, textColor), _labelStyle, GUILayout.Width(c1));
                        GUILayout.Label(CTag(LifeSupportSetup.Instance.LSConfig.BaseHabTime.ToString(), fadeColor), _labelStyle, GUILayout.Width(c2));
                        GUILayout.Label(CTag(maxCrew.ToString(), crewColor), _labelStyle, GUILayout.Width(c3));
                        GUILayout.Label(CTag(extraHabTime.ToString(), textColor), _labelStyle, GUILayout.Width(c4));
                        GUILayout.Label(CTag(habMult.ToString(), textColor), _labelStyle, GUILayout.Width(c5));
                        GUILayout.Label(CTag(Math.Max(1, curCrew).ToString(), crewColor), _labelStyle, GUILayout.Width(c6));
                        GUILayout.Label(CTag(LifeSupportSetup.Instance.LSConfig.HabMultiplier.ToString(), fadeColor), _labelStyle, GUILayout.Width(c7));
                        GUILayout.EndHorizontal();

                        GUILayout.BeginHorizontal();
                        GUILayout.Label(CTag(hab_maxCrew, textColor), _labelStyle, GUILayout.Width(c1));
                        GUILayout.Label(CTag(LifeSupportSetup.Instance.LSConfig.BaseHabTime.ToString(), fadeColor), _labelStyle, GUILayout.Width(c2));
                        GUILayout.Label(CTag(maxCrew.ToString(), crewColor), _labelStyle, GUILayout.Width(c3));
                        GUILayout.Label(CTag(extraHabTime.ToString(), textColor), _labelStyle, GUILayout.Width(c4));
                        GUILayout.Label(CTag(habMult.ToString(), textColor), _labelStyle, GUILayout.Width(c5));
                        GUILayout.Label(CTag(Math.Max(1, maxCrew).ToString(), crewColor), _labelStyle, GUILayout.Width(c6));
                        GUILayout.Label(CTag(LifeSupportSetup.Instance.LSConfig.HabMultiplier.ToString(), fadeColor), _labelStyle, GUILayout.Width(c7));
                        GUILayout.EndHorizontal();
                    }

                    GUILayout.Space(20);

                    GUILayout.BeginHorizontal();
                    GUILayout.Label("<b>Parts</b>", _labelStyle, GUILayout.Width(150));
                    GUILayout.EndHorizontal();

                    // RECYCLERS
                    {
                        // column widths
                        const int c1 = 230;
                        const int c2 = 80;
                        const int c3 = 150;

                        GUILayout.BeginHorizontal();
                        GUILayout.Label("Recycler", _labelStyle, GUILayout.Width(c1));
                        GUILayout.Label("Recycle %", _labelStyle, GUILayout.Width(c2));
                        GUILayout.Label("Crew-Capacity", _labelStyle, GUILayout.Width(c3));
                        GUILayout.EndHorizontal();

                        foreach (var recycler in recyclers)
                        {
                            GUILayout.BeginHorizontal();
                            GUILayout.Label(CTag(recycler.part.partInfo.title, partColor), _labelStyle, GUILayout.Width(c1));
                            GUILayout.Label(CTag(((int)(recycler.RecyclePercent * 100)).ToString(), textColor), _labelStyle, GUILayout.Width(c2));
                            GUILayout.Label(CTag(recycler.CrewCapacity.ToString(), textColor), _labelStyle, GUILayout.Width(c3));
                            GUILayout.EndHorizontal();
                        }

                        // HABITATION
                        if (useHabPenalties)
                        {
                            GUILayout.Space(10);

                            GUILayout.BeginHorizontal();
                            GUILayout.Label("Habitation", _labelStyle, GUILayout.Width(c1));
                            GUILayout.Label("ExtraTime", _labelStyle, GUILayout.Width(c2));
                            GUILayout.Label("Multiplier", _labelStyle, GUILayout.Width(c3));
                            GUILayout.EndHorizontal();

                            foreach (var hab in habs)
                            {
                                GUILayout.BeginHorizontal();
                                GUILayout.Label(CTag(hab.part.partInfo.title, partColor), _labelStyle, GUILayout.Width(c1));
                                GUILayout.Label(CTag(hab.KerbalMonths.ToString(), textColor), _labelStyle, GUILayout.Width(c2));
                                GUILayout.Label(CTag(hab.HabMultiplier.ToString(), textColor), _labelStyle, GUILayout.Width(c3));
                                GUILayout.EndHorizontal();
                            }
                        }
                    }
                }
            }
            GUILayout.EndVertical();
            GUILayout.EndScrollView();
            GUILayout.EndVertical();
            GUI.DragWindow();
        }