コード例 #1
0
        public void Load(ConfigNode node)
        {
            if (node.HasNode(configNodeName))
            {
                ConfigNode settingsNode = node.GetNode(configNodeName);

                IsNewSave = Utilities.GetValue(settingsNode, "IsNewSave", IsNewSave);
                Enabled   = Utilities.GetValue(settingsNode, "Enabled", Enabled);
                HibernateInsteadOfKill = Utilities.GetValue(settingsNode, "HibernateInsteadOfKill", HibernateInsteadOfKill);
                RespawnDelay           = Utilities.GetValue(settingsNode, "RespawnDelay", RespawnDelay);

                knownCrew.Clear();
                var crewNodes = settingsNode.GetNodes(CrewMemberInfo.ConfigNodeName);
                foreach (ConfigNode crewNode in crewNodes)
                {
                    CrewMemberInfo crewMemberInfo = CrewMemberInfo.Load(crewNode);
                    knownCrew[crewMemberInfo.name] = crewMemberInfo;
                }

                knownVessels.Clear();
                var vesselNodes = settingsNode.GetNodes(VesselInfo.ConfigNodeName);
                foreach (ConfigNode vesselNode in vesselNodes)
                {
                    if (vesselNode.HasValue("Guid"))
                    {
                        Guid       id         = new Guid(vesselNode.GetValue("Guid"));
                        VesselInfo vesselInfo = VesselInfo.Load(vesselNode);
                        knownVessels[id] = vesselInfo;
                    }
                }
            }
        }
コード例 #2
0
        void Awake()
        {
            this.Log("Awake");
            //configFilename = IOUtils.GetFilePathFor(this.GetType(), "FuelBalancer.cfg");
            configFilename = DATA_FOLDER + "FuelBalancer.cfg";
            Debug.Log("Awake, configFilename: " + configFilename);
            // No need to check to see if the directory exists, will create it if it doesn't
            System.IO.Directory.CreateDirectory(DATA_FOLDER);
            if (settings == null)
            {
                settings = new Settings();
            }
            if (settings == null)
            {
                Debug.Log("Error, settings is null");
            }
            else
            {
                Debug.Log("Settings inititalized");
            }
#if false
            settingsWindow = new SettingsWindow(settings);
#endif
            helpWindow = new HelpWindow();
            mainWindow = new MainWindow(this, settings, /* settingsWindow, */ helpWindow);
            mainWindow.WindowClosed += OnWindowClosed;
            this.Log("Making Buttons");
            InitButtons( );
            this.Log("Made Buttons");

            vesselInfo = new VesselInfo( );
        }
コード例 #3
0
ファイル: GameSettings.cs プロジェクト: t0chas/TacLifeSupport
        public void Load(ConfigNode node)
        {
            if (node.HasNode(configNodeName))
            {
                ConfigNode settingsNode = node.GetNode(configNodeName);

                settingsNode.TryGetValue("IsNewSave", ref IsNewSave);

                knownCrew.Clear();
                var crewNodes = settingsNode.GetNodes(CrewMemberInfo.ConfigNodeName);
                foreach (ConfigNode crewNode in crewNodes)
                {
                    CrewMemberInfo crewMemberInfo = CrewMemberInfo.Load(crewNode);
                    knownCrew[crewMemberInfo.name] = crewMemberInfo;
                }

                knownVessels.Clear();
                var vesselNodes = settingsNode.GetNodes(VesselInfo.ConfigNodeName);
                foreach (ConfigNode vesselNode in vesselNodes)
                {
                    if (vesselNode.HasValue("Guid"))
                    {
                        Guid       id         = new Guid(vesselNode.GetValue("Guid"));
                        VesselInfo vesselInfo = VesselInfo.Load(vesselNode);
                        knownVessels[id] = vesselInfo;
                    }
                }
            }
        }
コード例 #4
0
        private void ConsumeWater(double currentTime, Vessel vessel, VesselInfo vesselInfo, ProtoCrewMember crewMember, CrewMemberInfo crewMemberInfo, Part part)
        {
            if (vesselInfo.remainingWater >= globalSettings.WaterConsumptionRate)
            {
                double deltaTime     = Math.Min(currentTime - crewMemberInfo.lastWater, globalSettings.MaxDeltaTime);
                double desiredWater  = globalSettings.WaterConsumptionRate * deltaTime;
                double waterObtained = part.TakeResource(globalSettings.WaterId, Math.Min(desiredWater, vesselInfo.remainingWater / vesselInfo.numCrew));

                double wasteWaterProduced = waterObtained * globalSettings.WasteWaterProductionRate / globalSettings.WaterConsumptionRate;
                part.TakeResource(globalSettings.WasteWaterId, -wasteWaterProduced);

                crewMemberInfo.lastWater  += deltaTime - ((desiredWater - waterObtained) / globalSettings.WaterConsumptionRate);
                crewMemberInfo.hibernating = false;
            }
            else
            {
                double timeWithoutWater = currentTime - crewMemberInfo.lastWater;
                if (timeWithoutWater > (globalSettings.MaxTimeWithoutWater + crewMemberInfo.respite))
                {
                    if (!gameSettings.HibernateInsteadOfKill)
                    {
                        KillCrewMember(crewMember, "dehydration", vessel);
                    }
                    else
                    {
                        crewMemberInfo.hibernating = true;
                    }
                }
            }
        }
コード例 #5
0
        private void ConsumeFood(double currentTime, Vessel vessel, VesselInfo vesselInfo, ProtoCrewMember crewMember, CrewMemberInfo crewMemberInfo, Part part)
        {
            if (vesselInfo.remainingFood >= globalSettings.FoodConsumptionRate)
            {
                double deltaTime    = Math.Min(currentTime - crewMemberInfo.lastFood, globalSettings.MaxDeltaTime);
                double desiredFood  = globalSettings.FoodConsumptionRate * deltaTime;
                double foodObtained = part.TakeResource(globalSettings.FoodId, Math.Min(desiredFood, vesselInfo.remainingFood / vesselInfo.numCrew));

                double wasteProduced = foodObtained * globalSettings.WasteProductionRate / globalSettings.FoodConsumptionRate;
                part.TakeResource(globalSettings.WasteId, -wasteProduced);

                crewMemberInfo.lastFood   += deltaTime - ((desiredFood - foodObtained) / globalSettings.FoodConsumptionRate);
                crewMemberInfo.hibernating = false;
            }
            else
            {
                double timeWithoutFood = currentTime - crewMemberInfo.lastFood;
                if (timeWithoutFood > (globalSettings.MaxTimeWithoutFood + crewMemberInfo.respite))
                {
                    if (!gameSettings.HibernateInsteadOfKill)
                    {
                        KillCrewMember(crewMember, "starvation", vessel);
                    }
                    else
                    {
                        crewMemberInfo.hibernating = true;
                    }
                }
            }
        }
コード例 #6
0
        private void ConsumeElectricity(double currentTime, Vessel vessel, VesselInfo vesselInfo)
        {
            double rate = vesselInfo.estimatedElectricityConsumptionRate = CalculateElectricityConsumptionRate(vessel, vesselInfo);

            if (rate > 0.0)
            {
                if (vesselInfo.remainingElectricity >= rate)
                {
                    double deltaTime           = Math.Min(currentTime - vesselInfo.lastElectricity, Math.Max(globalSettings.ElectricityMaxDeltaTime, Time.fixedDeltaTime));
                    double desiredElectricity  = rate * deltaTime;
                    double electricityObtained = vessel.rootPart.TakeResource(globalSettings.ElectricityId, desiredElectricity);

                    vesselInfo.lastElectricity = currentTime - ((desiredElectricity - electricityObtained) / rate);
                }
                else if (NeedElectricity(vessel, vesselInfo))
                {
                    double timeWithoutElectricity = currentTime - vesselInfo.lastElectricity;
                    if (timeWithoutElectricity > globalSettings.MaxTimeWithoutElectricity)
                    {
                        List <ProtoCrewMember> crew = vessel.GetVesselCrew();
                        int crewMemberIndex         = UnityEngine.Random.Range(0, crew.Count - 1);
                        KillCrewMember(crew[crewMemberIndex], "air toxicity", vessel);

                        vesselInfo.lastElectricity += UnityEngine.Random.Range(60, 600);
                    }
                }
            }
            else
            {
                vesselInfo.lastElectricity += currentTime - vesselInfo.lastUpdate;
            }
        }
コード例 #7
0
        private void FillEvaSuit(Part oldPart, Part newPart)
        {
            double desiredFood        = globalSettings.FoodConsumptionRate * globalSettings.EvaDefaultResourceAmount;
            double desiredWater       = globalSettings.WaterConsumptionRate * globalSettings.EvaDefaultResourceAmount;
            double desiredOxygen      = globalSettings.OxygenConsumptionRate * globalSettings.EvaDefaultResourceAmount;
            double desiredElectricity = globalSettings.EvaElectricityConsumptionRate * globalSettings.EvaDefaultResourceAmount;

            Vessel     lastVessel = oldPart.vessel;
            VesselInfo lastVesselInfo;

            if (!gameSettings.knownVessels.TryGetValue(lastVessel.id, out lastVesselInfo))
            {
                lastVesselInfo = new VesselInfo(lastVessel.vesselName, Planetarium.GetUniversalTime());
            }

            UpdateVesselInfo(lastVesselInfo, lastVessel);
            int numCrew = lastVesselInfo.numCrew + 1;

            double foodObtained        = oldPart.TakeResource(globalSettings.FoodId, Math.Min(desiredFood, lastVesselInfo.remainingFood / numCrew));
            double waterObtained       = oldPart.TakeResource(globalSettings.WaterId, Math.Min(desiredWater, lastVesselInfo.remainingWater / numCrew));
            double oxygenObtained      = oldPart.TakeResource(globalSettings.OxygenId, Math.Min(desiredOxygen, lastVesselInfo.remainingOxygen / numCrew));
            double electricityObtained = oldPart.TakeResource(globalSettings.ElectricityId, Math.Min(desiredElectricity, lastVesselInfo.remainingElectricity / numCrew));

            newPart.TakeResource(globalSettings.FoodId, -foodObtained);
            newPart.TakeResource(globalSettings.WaterId, -waterObtained);
            newPart.TakeResource(globalSettings.OxygenId, -oxygenObtained);
            newPart.TakeResource(globalSettings.ElectricityId, -electricityObtained);
        }
コード例 #8
0
        private void ConsumeOxygen(double currentTime, Vessel vessel, VesselInfo vesselInfo, ProtoCrewMember crewMember, CrewMemberInfo crewMemberInfo, Part part)
        {
            if (!vessel.orbit.referenceBody.atmosphereContainsOxygen || FlightGlobals.getStaticPressure() < 0.2)
            {
                if (vesselInfo.remainingOxygen >= settings.OxygenConsumptionRate)
                {
                    double desiredOxygen  = settings.OxygenConsumptionRate * (currentTime - crewMemberInfo.lastUpdate);
                    double oxygenObtained = RequestResource(settings.Oxygen, Min(desiredOxygen, vesselInfo.remainingOxygen / vesselInfo.numCrew, vesselInfo.remainingOxygen * 0.95), part);

                    double co2Production = oxygenObtained * settings.CO2ProductionRate / settings.OxygenConsumptionRate;
                    RequestResource(settings.CO2, -co2Production, part);

                    crewMemberInfo.lastOxygen = currentTime - ((desiredOxygen - oxygenObtained) / settings.OxygenConsumptionRate);
                }
                else
                {
                    double timeWithoutOxygen = currentTime - crewMemberInfo.lastOxygen;
                    if (timeWithoutOxygen > (settings.MaxTimeWithoutOxygen + crewMemberInfo.respite))
                    {
                        KillCrewMember(crewMember, "oxygen deprivation", vessel);
                    }
                }
            }
            else
            {
                crewMemberInfo.lastOxygen = currentTime;
            }
        }
コード例 #9
0
        public static VesselInfo Load(ConfigNode node)
        {
            string vesselName = Utilities.GetValue(node, "vesselName", "Unknown");
            double lastUpdate = Utilities.GetValue(node, "lastUpdate", 0.0);

            VesselInfo info = new VesselInfo(vesselName, lastUpdate);

            info.vesselType       = Utilities.GetValue(node, "vesselType", "Unknown");
            info.numCrew          = Utilities.GetValue(node, "numCrew", 0);
            info.numOccupiedParts = Utilities.GetValue(node, "numOccupiedParts", 0);

            info.lastFood        = Utilities.GetValue(node, "lastFood", lastUpdate);
            info.lastWater       = Utilities.GetValue(node, "lastWater", lastUpdate);
            info.lastOxygen      = Utilities.GetValue(node, "lastOxygen", lastUpdate);
            info.lastElectricity = Utilities.GetValue(node, "lastElectricity", lastUpdate);

            info.remainingFood        = Utilities.GetValue(node, "remainingFood", 0.0);
            info.remainingWater       = Utilities.GetValue(node, "remainingWater", 0.0);
            info.remainingOxygen      = Utilities.GetValue(node, "remainingOxygen", 0.0);
            info.remainingElectricity = Utilities.GetValue(node, "remainingElectricity", 0.0);
            info.remainingCO2         = Utilities.GetValue(node, "remainingCO2", 0.0);
            info.remainingWaste       = Utilities.GetValue(node, "remainingWaste", 0.0);
            info.remainingWasteWater  = Utilities.GetValue(node, "remainingWasteWater", 0.0);

            info.maxFood        = Utilities.GetValue(node, "maxFood", 0.0);
            info.maxWater       = Utilities.GetValue(node, "maxWater", 0.0);
            info.maxOxygen      = Utilities.GetValue(node, "maxOxygen", 0.0);
            info.maxElectricity = Utilities.GetValue(node, "maxElectricity", 0.0);

            info.estimatedElectricityConsumptionRate = Utilities.GetValue(node, "estimatedElectricityConsumptionRate", 0.0);

            info.hibernating = Utilities.GetValue(node, "hibernating", false);

            return(info);
        }
コード例 #10
0
        private int UpdateVesselInfo(VesselInfo vesselInfo, Vessel vessel)
        {
            int crewCapacity = 0;

            vesselInfo.ClearAmounts();

            foreach (Part part in vessel.parts)
            {
                crewCapacity += part.CrewCapacity;
                if (part.protoModuleCrew.Any())
                {
                    vesselInfo.numCrew += part.protoModuleCrew.Count;
                    ++vesselInfo.numOccupiedParts;
                }

                foreach (PartResource resource in part.Resources)
                {
                    if (resource.flowState)
                    {
                        if (resource.info.id == globalSettings.FoodId)
                        {
                            vesselInfo.remainingFood += resource.amount;
                            vesselInfo.maxFood       += resource.maxAmount;
                        }
                        else if (resource.info.id == globalSettings.WaterId)
                        {
                            vesselInfo.remainingWater += resource.amount;
                            vesselInfo.maxWater       += resource.maxAmount;
                        }
                        else if (resource.info.id == globalSettings.OxygenId)
                        {
                            vesselInfo.remainingOxygen += resource.amount;
                            vesselInfo.maxOxygen       += resource.maxAmount;
                        }
                        else if (resource.info.id == globalSettings.ElectricityId)
                        {
                            vesselInfo.remainingElectricity += resource.amount;
                            vesselInfo.maxElectricity       += resource.maxAmount;
                        }
                        else if (resource.info.id == globalSettings.CO2Id)
                        {
                            vesselInfo.remainingCO2 += resource.amount;
                        }
                        else if (resource.info.id == globalSettings.WasteId)
                        {
                            vesselInfo.remainingWaste += resource.amount;
                        }
                        else if (resource.info.id == globalSettings.WasteWaterId)
                        {
                            vesselInfo.remainingWasteWater += resource.amount;
                        }
                    }
                }
            }

            return(crewCapacity);
        }
コード例 #11
0
 private double CalculateElectricityConsumptionRate(Vessel vessel, VesselInfo vesselInfo)
 {
     if (!vessel.isEVA)
     {
         return((globalSettings.ElectricityConsumptionRate * vesselInfo.numCrew) + (globalSettings.BaseElectricityConsumptionRate * vesselInfo.numOccupiedParts));
     }
     else
     {
         return(globalSettings.EvaElectricityConsumptionRate);
     }
 }
コード例 #12
0
 private double CalculateElectricityConsumptionRate(Vessel vessel, VesselInfo vesselInfo)
 {
     if (!vessel.isEVA)
     {
         return (globalSettings.ElectricityConsumptionRate * vesselInfo.numCrew) + (globalSettings.BaseElectricityConsumptionRate * vesselInfo.numOccupiedParts);
     }
     else
     {
         return globalSettings.EvaElectricityConsumptionRate;
     }
 }
コード例 #13
0
 private void DrawVesselInfo(VesselInfo vesselInfo, double currentTime)
 {
     GUILayout.Label(vesselInfo.vesselName + " (" + vesselInfo.numCrew + " crew) [" + vesselInfo.vesselType + "]", headerStyle);
     GUILayout.Label("  Last updated:          " + Utilities.FormatTime(currentTime - vesselInfo.lastUpdate), labelStyle);
     if (vesselInfo.numCrew > 0)
     {
         GUILayout.Label("  Food remaining:        " + Utilities.FormatTime(vesselInfo.estimatedTimeFoodDepleted - currentTime), getStyle(vesselInfo.foodStatus));
         GUILayout.Label("  Water remaining:       " + Utilities.FormatTime(vesselInfo.estimatedTimeWaterDepleted - currentTime), getStyle(vesselInfo.waterStatus));
         GUILayout.Label("  Oxygen remaining:      " + Utilities.FormatTime(vesselInfo.estimatedTimeOxygenDepleted - currentTime), getStyle(vesselInfo.oxygenStatus));
         GUILayout.Label("  Electricity remaining: " + Utilities.FormatTime(vesselInfo.estimatedTimeElectricityDepleted - currentTime), getStyle(vesselInfo.electricityStatus));
     }
 }
コード例 #14
0
 public double CalculateElectricityConsumptionRate(Vessel vessel, VesselInfo vesselInfo)
 {
     if (!vessel.isEVA)
     {
         int numOccupiedParts = vessel.Parts.Count(p => p.protoModuleCrew.Count > 0);
         return (settings.ElectricityConsumptionRate * vesselInfo.numCrew) + (settings.BaseElectricityConsumptionRate * numOccupiedParts);
     }
     else
     {
         return settings.EvaElectricityConsumptionRate;
     }
 }
コード例 #15
0
 public double CalculateElectricityConsumptionRate(Vessel vessel, VesselInfo vesselInfo)
 {
     if (!vessel.isEVA)
     {
         int numOccupiedParts = vessel.Parts.Count(p => p.protoModuleCrew.Count > 0);
         return((settings.ElectricityConsumptionRate * vesselInfo.numCrew) + (settings.BaseElectricityConsumptionRate * numOccupiedParts));
     }
     else
     {
         return(settings.EvaElectricityConsumptionRate);
     }
 }
コード例 #16
0
        private void EmptyEvaSuit(CrewMemberInfo crewMemberInfo, Part part)
        {
            VesselInfo lastVesselInfo = knownVessels[crewMemberInfo.vesselId];

            RequestResource(settings.Food, -lastVesselInfo.remainingFood, part);
            RequestResource(settings.Water, -lastVesselInfo.remainingWater, part);
            RequestResource(settings.Oxygen, -lastVesselInfo.remainingOxygen, part);
            RequestResource(settings.Electricity, -lastVesselInfo.remainingElectricity, part);
            RequestResource(settings.CO2, -lastVesselInfo.remainingCO2, part);
            RequestResource(settings.Waste, -lastVesselInfo.remainingWaste, part);
            RequestResource(settings.WasteWater, -lastVesselInfo.remainingWasteWater, part);
        }
コード例 #17
0
        void FixedUpdate()
        {
            if (!FlightGlobals.ready)
            {
                return;
            }

            double currentTime = Planetarium.GetUniversalTime();
            var    vessels     = FlightGlobals.Vessels.Where(v => v.loaded && v.GetCrewCount() > 0);

            foreach (Vessel vessel in vessels)
            {
                if (!vessel.isEVA)
                {
                    VesselInfo vesselInfo = GetVesselInfo(vessel, currentTime);
                    if (vessel.missionTime < 0.05)
                    {
                        // The vessel has not been launched yet
                        foreach (ProtoCrewMember crewMember in vessel.GetVesselCrew())
                        {
                            knownCrew[crewMember.name] = new CrewMemberInfo(crewMember.name, vessel, currentTime);
                        }
                    }
                    else
                    {
                        ConsumeResources(currentTime, vessel, vesselInfo);
                    }
                }
                else
                {
                    if (vessel.missionTime < 0.05)
                    {
                        // It is a new EVA
                        FillEvaSuit(vessel);
                    }
                    else
                    {
                        VesselInfo vesselInfo = GetVesselInfo(vessel, currentTime);
                        ConsumeResources(currentTime, vessel, vesselInfo);
                    }
                }
            }

            // Clean up the mapping of known vessels, removing ones that are not in the list anymore
            var oldVessels = knownVessels.Keys.Where(key => !vessels.Any(v => v.id.Equals(key))).ToList();

            foreach (Guid id in oldVessels)
            {
                knownVessels.Remove(id);
            }
        }
コード例 #18
0
        public static VesselInfo Load(ConfigNode node)
        {
            string vesselName = Utilities.GetValue(node, "vesselName", "Unknown");
            double lastUpdate = Utilities.GetValue(node, "lastUpdate", 0.0);

            Vessel.Situations vesselSituation = Utilities.GetValue(node, "vesselSituation", Vessel.Situations.PRELAUNCH);
            VesselType        vesselType      = Utilities.GetValue(node, "vesselType", VesselType.Unknown);

            VesselInfo info = new VesselInfo(vesselName, vesselSituation, vesselType, lastUpdate);


            info.vesselIsPreLaunch = Utilities.GetValue(node, "vesselIsPreLaunch", true);
            if (info.vesselIsPreLaunch && !(vesselSituation == Vessel.Situations.PRELAUNCH))
            {
                Logging.LogError("VesselInfo.Load",
                                 "Mismatch between VesselSituation and vesselIsPreLaunch, setting to Prelaunch");
                info.vesselIsPreLaunch = true;
                info.vesselSituation   = Vessel.Situations.PRELAUNCH;
            }

            info.numCrew          = Utilities.GetValue(node, "numCrew", 0);
            info.numFrozenCrew    = Utilities.GetValue(node, "numFrozenCrew", 0);
            info.numOccupiedParts = Utilities.GetValue(node, "numOccupiedParts", 0);

            info.lastFood        = Utilities.GetValue(node, "lastFood", lastUpdate);
            info.lastWater       = Utilities.GetValue(node, "lastWater", lastUpdate);
            info.lastOxygen      = Utilities.GetValue(node, "lastOxygen", lastUpdate);
            info.lastElectricity = Utilities.GetValue(node, "lastElectricity", lastUpdate);

            info.remainingFood        = Utilities.GetValue(node, "remainingFood", 0.0);
            info.remainingWater       = Utilities.GetValue(node, "remainingWater", 0.0);
            info.remainingOxygen      = Utilities.GetValue(node, "remainingOxygen", 0.0);
            info.remainingElectricity = Utilities.GetValue(node, "remainingElectricity", 0.0);
            info.remainingCO2         = Utilities.GetValue(node, "remainingCO2", 0.0);
            info.remainingWaste       = Utilities.GetValue(node, "remainingWaste", 0.0);
            info.remainingWasteWater  = Utilities.GetValue(node, "remainingWasteWater", 0.0);

            info.maxFood        = Utilities.GetValue(node, "maxFood", 0.0);
            info.maxWater       = Utilities.GetValue(node, "maxWater", 0.0);
            info.maxOxygen      = Utilities.GetValue(node, "maxOxygen", 0.0);
            info.maxElectricity = Utilities.GetValue(node, "maxElectricity", 0.0);

            info.estimatedElectricityConsumptionRate = Utilities.GetValue(node, "estimatedElectricityConsumptionRate", 0.0);

            info.hibernating    = Utilities.GetValue(node, "hibernating", false);
            info.recoveryvessel = Utilities.GetValue(node, "recoveryvessel", false);
            info.windowOpen     = Utilities.GetValue(node, "windowOpen", false);

            return(info);
        }
コード例 #19
0
        private void ConsumeResources(double currentTime, Vessel vessel, VesselInfo vesselInfo)
        {
            ConsumeElectricity(currentTime, vessel, vesselInfo);
            ConsumeOxygen(currentTime, vessel, vesselInfo);

            vesselInfo.lastFood    = currentTime;
            vesselInfo.lastWater   = currentTime;
            vesselInfo.hibernating = false;

            List <ProtoCrewMember> crew = vessel.GetVesselCrew();
            var knownCrew = gameSettings.knownCrew;

            foreach (ProtoCrewMember crewMember in crew)
            {
                if (knownCrew.ContainsKey(crewMember.name))
                {
                    CrewMemberInfo crewMemberInfo = knownCrew[crewMember.name];
                    Part           part           = (crewMember.KerbalRef != null) ? crewMember.KerbalRef.InPart : vessel.rootPart;

                    ConsumeFood(currentTime, vessel, vesselInfo, crewMember, crewMemberInfo, part);
                    ConsumeWater(currentTime, vessel, vesselInfo, crewMember, crewMemberInfo, part);

                    crewMemberInfo.lastUpdate = currentTime;
                    crewMemberInfo.vesselId   = vessel.id;
                    crewMemberInfo.vesselName = (!vessel.isEVA) ? vessel.vesselName : "EVA";

                    if (vesselInfo.lastFood > crewMemberInfo.lastFood)
                    {
                        vesselInfo.lastFood = crewMemberInfo.lastFood;
                    }
                    if (vesselInfo.lastWater > crewMemberInfo.lastWater)
                    {
                        vesselInfo.lastWater = crewMemberInfo.lastWater;
                    }
                    if (crewMemberInfo.hibernating)
                    {
                        vesselInfo.hibernating = true;
                    }
                }
                else
                {
                    this.LogWarning("Unknown crew member: " + crewMember.name);
                    knownCrew[crewMember.name] = new CrewMemberInfo(crewMember.name, vessel.vesselName, vessel.id, currentTime);
                }
            }

            vesselInfo.lastUpdate = currentTime;
            vesselInfo.vesselName = vessel.vesselName;
            vesselInfo.vesselType = vessel.vesselType.ToString();
        }
コード例 #20
0
 private void DrawVesselInfo(VesselInfo vesselInfo, double currentTime)
 {
     if (DeepFreezeInstalled)
     {
         GUILayout.BeginHorizontal();
         GUILayout.Label(vesselInfo.vesselName + " (" + vesselInfo.numCrew + "/", headerStyle);
         GUILayout.Label(vesselInfo.numFrozenCrew.ToString(), frozenStyle);
         GUILayout.Label(" crew) [" + vesselInfo.vesselType + "]", headerStyle);
         GUILayout.EndHorizontal();
     }
     else
     {
         GUILayout.Label(vesselInfo.vesselName + " (" + vesselInfo.numCrew + " crew) [" + vesselInfo.vesselType + "]", headerStyle);
     }
     if (vesselInfo.vesselIsPreLaunch)
     {
         GUILayout.Label("  Prelaunch Vessel", labelStyle);
     }
     else if (vesselInfo.recoveryvessel)
     {
         GUILayout.Label("  Rescue Vessel", labelStyle);
     }
     else
     {
         GUILayout.BeginHorizontal();
         GUILayout.Label("  Last updated:          ", getStyle(vesselInfo.foodStatus), GUILayout.Width(150));
         GUILayout.Label(Utilities.FormatTime(currentTime - vesselInfo.lastUpdate), labelStyle);
         GUILayout.EndHorizontal();
         if (vesselInfo.numCrew > 0)
         {
             GUILayout.BeginHorizontal();
             GUILayout.Label("  Food remaining:        ", getStyle(vesselInfo.foodStatus), GUILayout.Width(150));
             GUILayout.Label(Utilities.FormatTime(vesselInfo.estimatedTimeFoodDepleted - currentTime), getStyle(vesselInfo.foodStatus));
             GUILayout.EndHorizontal();
             GUILayout.BeginHorizontal();
             GUILayout.Label("  Water remaining:       ", getStyle(vesselInfo.waterStatus), GUILayout.Width(150));
             GUILayout.Label(Utilities.FormatTime(vesselInfo.estimatedTimeWaterDepleted - currentTime), getStyle(vesselInfo.waterStatus));
             GUILayout.EndHorizontal();
             GUILayout.BeginHorizontal();
             GUILayout.Label("  Oxygen remaining:      ", getStyle(vesselInfo.oxygenStatus), GUILayout.Width(150));
             GUILayout.Label(Utilities.FormatTime(vesselInfo.estimatedTimeOxygenDepleted - currentTime), getStyle(vesselInfo.oxygenStatus));
             GUILayout.EndHorizontal();
             GUILayout.BeginHorizontal();
             GUILayout.Label("  Electricity remaining: ", getStyle(vesselInfo.electricityStatus), GUILayout.Width(150));
             GUILayout.Label(Utilities.FormatTime(vesselInfo.estimatedTimeElectricityDepleted - currentTime), getStyle(vesselInfo.electricityStatus));
             GUILayout.EndHorizontal();
         }
     }
 }
コード例 #21
0
        private bool NeedElectricity(Vessel vessel, VesselInfo vesselInfo)
        {
            // Need electricity to survive unless:
            // 1) on Kerbin below a reasonable altitude, so they can open a hatch or window or vent
            if (vessel.mainBody == FlightGlobals.Bodies[1])
            {
                // On or above Kerbin
                if ((vessel.staticPressurekPa / seaLevelPressure) > 0.5)
                {
                    // air pressure is high enough so they can open a window
                    return(false);
                }
            }

            return(true);
        }
コード例 #22
0
        private bool NeedElectricity(Vessel vessel, VesselInfo vesselInfo)
        {
            // Need electricity to survive unless:
            // 1) landed or splashed down on Kerbin below a reasonable altitude, so they can open a hatch
            if (vessel.mainBody == FlightGlobals.Bodies[1])
            {
                // On or above Kerbin
                if (vessel.staticPressure > 0.5 && (vessel.situation == Vessel.Situations.LANDED || vessel.situation == Vessel.Situations.SPLASHED || vessel.situation == Vessel.Situations.PRELAUNCH))
                {
                    // air pressure is high enough & landed/spashed so they can open the hatch
                    return(false);
                }
            }

            return(true);
        }
コード例 #23
0
        public void Load(ConfigNode node)
        {
            if (node.HasNode(configNodeName))
            {
                ConfigNode settingsNode = node.GetNode(configNodeName);
                settingsNode.TryGetValue("Version", ref file_full_version);
                settingsNode.TryGetValue("IsNewSave", ref IsNewSave);
                if (IsNewSave)
                {
                    GetNewFileVersion();
                    compatible = true;
                }
                else
                {
                    CheckFileVersion();
                }

                knownVessels.Clear();
                var vesselNodes = settingsNode.GetNodes(VesselInfo.ConfigNodeName);
                foreach (ConfigNode vesselNode in vesselNodes)
                {
                    if (vesselNode.HasValue("Guid"))
                    {
                        Guid       id         = new Guid(vesselNode.GetValue("Guid"));
                        VesselInfo vesselInfo = VesselInfo.Load(vesselNode);
                        knownVessels[id] = vesselInfo;
                    }
                }

                knownCrew.Clear();
                var crewNodes = settingsNode.GetNodes(CrewMemberInfo.ConfigNodeName);
                foreach (ConfigNode crewNode in crewNodes)
                {
                    CrewMemberInfo crewMemberInfo = CrewMemberInfo.Load(crewNode);
                    knownCrew[crewMemberInfo.name] = crewMemberInfo;
                    if (knownVessels.Contains(crewMemberInfo.vesselId))
                    {
                        knownVessels[crewMemberInfo.vesselId].CrewInVessel.Add(crewMemberInfo);
                    }
                }
            }

            if (!compatible)
            {
                ProcessSaveUpgrade();
            }
        }
コード例 #24
0
        void Awake()
        {
            this.Log("Awake");
            configFilename = IOUtils.GetFilePathFor(this.GetType(), "FuelBalancer.cfg");

            settings = new Settings();

            settingsWindow           = new SettingsWindow(settings);
            helpWindow               = new HelpWindow();
            mainWindow               = new MainWindow(this, settings, settingsWindow, helpWindow);
            mainWindow.WindowClosed += OnWindowClosed;
//			this.Log( "Making Buttons" );
            InitButtons( );
//			this.Log( "Made Buttons" );

            vesselInfo = new VesselInfo( );
        }
コード例 #25
0
        private void ConsumeResources(double currentTime, Vessel vessel, VesselInfo vesselInfo)
        {
            // Electricity
            ConsumeElectricity(currentTime, vessel, vesselInfo);

            List <ProtoCrewMember> crew = vessel.GetVesselCrew();

            foreach (ProtoCrewMember crewMember in crew)
            {
                if (knownCrew.ContainsKey(crewMember.name))
                {
                    CrewMemberInfo crewMemberInfo = knownCrew[crewMember.name];
                    var            part           = (crewMember.KerbalRef != null) ? crewMember.KerbalRef.InPart : vessel.rootPart;

                    if (crewMemberInfo.vesselId != vessel.id && crewMemberInfo.isEVA)
                    {
                        // The crewmember came back inside after EVA, return the remaining resources out of the suit
                        EmptyEvaSuit(crewMemberInfo, part);
                    }

                    // Oxygen
                    ConsumeOxygen(currentTime, vessel, vesselInfo, crewMember, crewMemberInfo, part);

                    // Water
                    ConsumeWater(currentTime, vessel, vesselInfo, crewMember, crewMemberInfo, part);

                    // Food
                    ConsumeFood(currentTime, vessel, vesselInfo, crewMember, crewMemberInfo, part);

                    crewMemberInfo.lastUpdate = currentTime;
                    crewMemberInfo.vesselId   = vessel.id;
                    crewMemberInfo.isEVA      = vessel.isEVA;
                }
                else
                {
                    Debug.Log("TAC Life Support (LifeSupportController) [" + this.GetInstanceID().ToString("X") + "][" + Time.time + "]: Unknown crew member: " + crewMember.name);
                    knownCrew[crewMember.name] = new CrewMemberInfo(crewMember.name, vessel, currentTime);
                }
            }

            vesselInfo.lastUpdate = currentTime;
        }
コード例 #26
0
        private void ConsumeOxygen(double currentTime, Vessel vessel, VesselInfo vesselInfo)
        {
            if (NeedOxygen(vessel, vesselInfo))
            {
                if (vesselInfo.remainingOxygen >= globalSettings.OxygenConsumptionRate)
                {
                    double deltaTime = Math.Min(currentTime - vesselInfo.lastOxygen, globalSettings.MaxDeltaTime);
                    if (vesselInfo.numCrew > 0)
                    {
                        double rate           = globalSettings.OxygenConsumptionRate * vesselInfo.numCrew;
                        double desiredOxygen  = rate * deltaTime;
                        double oxygenObtained = vessel.rootPart.TakeResource(globalSettings.OxygenId, desiredOxygen);

                        double co2Production = oxygenObtained * globalSettings.CO2ProductionRate / globalSettings.OxygenConsumptionRate;
                        vessel.rootPart.TakeResource(globalSettings.CO2Id, -co2Production);

                        vesselInfo.lastOxygen += deltaTime - ((desiredOxygen - oxygenObtained) / rate);
                    }
                    else
                    {
                        vesselInfo.lastOxygen += currentTime - vesselInfo.lastUpdate;
                    }
                }
                else
                {
                    double timeWithoutOxygen = currentTime - vesselInfo.lastOxygen;
                    if (timeWithoutOxygen > globalSettings.MaxTimeWithoutOxygen)
                    {
                        List <ProtoCrewMember> crew = vessel.GetVesselCrew();
                        int crewMemberIndex         = UnityEngine.Random.Range(0, crew.Count - 1);
                        KillCrewMember(crew[crewMemberIndex], "oxygen deprivation", vessel);

                        vesselInfo.lastOxygen += UnityEngine.Random.Range(60, 600);
                    }
                }
            }
            else
            {
                vesselInfo.lastOxygen = currentTime;
            }
        }
コード例 #27
0
        private void ConsumeWater(double currentTime, Vessel vessel, VesselInfo vesselInfo, ProtoCrewMember crewMember, CrewMemberInfo crewMemberInfo, Part part)
        {
            if (vesselInfo.remainingWater >= settings.WaterConsumptionRate)
            {
                double desiredWater  = settings.WaterConsumptionRate * (currentTime - crewMemberInfo.lastUpdate);
                double waterObtained = RequestResource(settings.Water, Min(desiredWater, vesselInfo.remainingWater / vesselInfo.numCrew, vesselInfo.remainingWater * 0.95), part);

                double wasteWaterProduced = waterObtained * settings.WasteWaterProductionRate / settings.WaterConsumptionRate;
                RequestResource(settings.WasteWater, -wasteWaterProduced, part);

                crewMemberInfo.lastWater = currentTime - ((desiredWater - waterObtained) / settings.WaterConsumptionRate);
            }
            else
            {
                double timeWithoutWater = currentTime - crewMemberInfo.lastWater;
                if (timeWithoutWater > (settings.MaxTimeWithoutWater + crewMemberInfo.respite))
                {
                    KillCrewMember(crewMember, "dehydration", vessel);
                }
            }
        }
コード例 #28
0
        private void ConsumeFood(double currentTime, Vessel vessel, VesselInfo vesselInfo, ProtoCrewMember crewMember, CrewMemberInfo crewMemberInfo, Part part)
        {
            if (vesselInfo.remainingFood >= settings.FoodConsumptionRate)
            {
                double desiredFood  = settings.FoodConsumptionRate * (currentTime - crewMemberInfo.lastUpdate);
                double foodObtained = RequestResource(settings.Food, Min(desiredFood, vesselInfo.remainingFood / vesselInfo.numCrew, vesselInfo.remainingFood * 0.95), part);

                double wasteProduced = foodObtained * settings.WasteProductionRate / settings.FoodConsumptionRate;
                RequestResource(settings.Waste, -wasteProduced, part);

                crewMemberInfo.lastFood = currentTime - ((desiredFood - foodObtained) / settings.FoodConsumptionRate);
            }
            else
            {
                double timeWithoutFood = currentTime - crewMemberInfo.lastFood;
                if (timeWithoutFood > (settings.MaxTimeWithoutFood + crewMemberInfo.respite))
                {
                    KillCrewMember(crewMember, "starvation", vessel);
                }
            }
        }
コード例 #29
0
        /*
         * Notes:
         *  Mt Everest is at 8,848 meters (29,029 ft). The air pressure is ~0.33 atm.
         *  Everest Base Camp is at ~5,000 m (16,000 ft), with an air pressure of ~0.5 atm.
         *  0.2 atm is around 12,500 m (41,010.5 ft), close to the maximum altitude most airliners fly.
         * References:
         *  http://en.wikipedia.org/wiki/Mount_Everest
         *  http://en.wikipedia.org/wiki/Effects_of_high_altitude_on_humans
         *  http://www.altitude.org/air_pressure.php
         */
        private bool NeedOxygen(Vessel vessel, VesselInfo vesselInfo)
        {
            // Need oxygen unless:
            // 1) on Kerbin below a reasonable altitude, so they can open a hatch or window or vent
            // 2) flying on Kerbin with electricity for the vents, below a reasonable altitude
            if (vessel.mainBody == FlightGlobals.Bodies[1])
            {
                // On or above Kerbin
                if ((vessel.staticPressurekPa / seaLevelPressure) > 0.5)
                {
                    // air pressure is high enough so they can open a window
                    return(false);
                }
                else if ((vessel.staticPressurekPa / seaLevelPressure) > 0.2 && vesselInfo.remainingElectricity > vesselInfo.estimatedElectricityConsumptionRate)
                {
                    // air pressure is high enough & have electricity to run vents
                    return(false);
                }
            }

            return(true);
        }
コード例 #30
0
        private bool NeedOxygen(Vessel vessel, VesselInfo vesselInfo)
        {
            // Need oxygen unless:
            // 1) landed or splashed down on Kerbin below a reasonable altitude, so they can open a hatch
            // 2) flying on Kerbin with electricity for the vents, below a reasonable altitude
            if (vessel.mainBody == FlightGlobals.Bodies[1])
            {
                // On or above Kerbin
                if (vessel.staticPressure > 0.2 && vesselInfo.remainingElectricity > vesselInfo.estimatedElectricityConsumptionRate)
                {
                    // air pressure is high enough & have electricity to run vents
                    return(false);
                }
                else if (vessel.staticPressure > 0.5 && (vessel.situation == Vessel.Situations.LANDED || vessel.situation == Vessel.Situations.SPLASHED || vessel.situation == Vessel.Situations.PRELAUNCH))
                {
                    // air pressure is high enough & landed/spashed so they can open the hatch
                    return(false);
                }
            }

            return(true);
        }
コード例 #31
0
        private void FillEvaSuit(Vessel evaVessel)
        {
            ProtoCrewMember crewMember     = evaVessel.GetVesselCrew()[0];
            CrewMemberInfo  crewMemberInfo = knownCrew[crewMember.name];

            if (crewMemberInfo.vesselId != evaVessel.id)
            {
                Debug.Log("TAC Life Support (LifeSupportController) [" + this.GetInstanceID().ToString("X") + "][" + Time.time + "]: Filling EVA suit for " + crewMember.name);

                Vessel     lastVessel     = FlightGlobals.Vessels.Find(v => v.id.Equals(crewMemberInfo.vesselId));
                VesselInfo lastVesselInfo = knownVessels[crewMemberInfo.vesselId];

                double desiredFood        = settings.FoodConsumptionRate * settings.EvaDefaultResourceAmount;
                double desiredWater       = settings.WaterConsumptionRate * settings.EvaDefaultResourceAmount;
                double desiredOxygen      = settings.OxygenConsumptionRate * settings.EvaDefaultResourceAmount;
                double desiredElectricity = settings.EvaElectricityConsumptionRate * settings.EvaDefaultResourceAmount;

                Part oldPart = lastVessel.rootPart;
                int  numCrew = lastVessel.GetCrewCount() + 1;

                double foodObtained        = RequestResource(settings.Food, Min(desiredFood, lastVesselInfo.remainingFood / numCrew, lastVesselInfo.remainingFood * 0.95), oldPart);
                double waterObtained       = RequestResource(settings.Water, Min(desiredWater, lastVesselInfo.remainingWater / numCrew, lastVesselInfo.remainingWater * 0.95), oldPart);
                double oxygenObtained      = RequestResource(settings.Oxygen, Min(desiredOxygen, lastVesselInfo.remainingOxygen / numCrew, lastVesselInfo.remainingOxygen * 0.95), oldPart);
                double electricityObtained = RequestResource(settings.Electricity, Min(desiredElectricity, lastVesselInfo.remainingElectricity / numCrew, lastVesselInfo.remainingElectricity * 0.95), oldPart);

                Part newPart = evaVessel.rootPart;
                RequestResource(settings.Food, -foodObtained, newPart);
                RequestResource(settings.Water, -waterObtained, newPart);
                RequestResource(settings.Oxygen, -oxygenObtained, newPart);
                RequestResource(settings.Electricity, -electricityObtained, newPart);

                crewMemberInfo.vesselId = evaVessel.id;
                crewMemberInfo.isEVA    = true;
            }
            else
            {
                Debug.Log("TAC Life Support (LifeSupportController) [" + this.GetInstanceID().ToString("X") + "][" + Time.time + "]: EVA suit for " + crewMember.name + " has already been filled.");
            }
        }
コード例 #32
0
        private void ConsumeElectricity(double currentTime, Vessel vessel, VesselInfo vesselInfo)
        {
            double rate = CalculateElectricityConsumptionRate(vessel, vesselInfo);

            if (vesselInfo.remainingElectricity >= rate)
            {
                double desiredElectricity  = rate * TimeWarp.fixedDeltaTime;
                double electricityObtained = RequestResource(settings.Electricity, Min(desiredElectricity, vesselInfo.remainingElectricity * 0.95), vessel.rootPart);

                vesselInfo.lastElectricity = currentTime - ((desiredElectricity - electricityObtained) / rate);
            }
            else
            {
                double timeWithoutElectricity = currentTime - vesselInfo.lastElectricity;
                if (timeWithoutElectricity > settings.MaxTimeWithoutElectricity)
                {
                    List <ProtoCrewMember> crew = vessel.GetVesselCrew();
                    int crewMemberIndex         = UnityEngine.Random.Range(0, crew.Count - 1);
                    KillCrewMember(crew[crewMemberIndex], "heat/cold/air stagnation", vessel);

                    vesselInfo.lastElectricity += UnityEngine.Random.Range(60, 180);
                }
            }
        }
コード例 #33
0
ファイル: VesselInfo.cs プロジェクト: VenVen/TacLifeSupport
        public static VesselInfo Load(ConfigNode node)
        {
            string vesselName = Utilities.GetValue(node, "vesselName", "Unknown");
            double lastUpdate = Utilities.GetValue(node, "lastUpdate", 0.0);

            VesselInfo info = new VesselInfo(vesselName, lastUpdate);
            info.vesselType = Utilities.GetValue(node, "vesselType", VesselType.Unknown);
            info.numCrew = Utilities.GetValue(node, "numCrew", 0);
            info.numOccupiedParts = Utilities.GetValue(node, "numOccupiedParts", 0);

            info.lastFood = Utilities.GetValue(node, "lastFood", lastUpdate);
            info.lastWater = Utilities.GetValue(node, "lastWater", lastUpdate);
            info.lastOxygen = Utilities.GetValue(node, "lastOxygen", lastUpdate);
            info.lastElectricity = Utilities.GetValue(node, "lastElectricity", lastUpdate);

            info.remainingFood = Utilities.GetValue(node, "remainingFood", 0.0);
            info.remainingWater = Utilities.GetValue(node, "remainingWater", 0.0);
            info.remainingOxygen = Utilities.GetValue(node, "remainingOxygen", 0.0);
            info.remainingElectricity = Utilities.GetValue(node, "remainingElectricity", 0.0);
            info.remainingCO2 = Utilities.GetValue(node, "remainingCO2", 0.0);
            info.remainingWaste = Utilities.GetValue(node, "remainingWaste", 0.0);
            info.remainingWasteWater = Utilities.GetValue(node, "remainingWasteWater", 0.0);

            info.maxFood = Utilities.GetValue(node, "maxFood", 0.0);
            info.maxWater = Utilities.GetValue(node, "maxWater", 0.0);
            info.maxOxygen = Utilities.GetValue(node, "maxOxygen", 0.0);
            info.maxElectricity = Utilities.GetValue(node, "maxElectricity", 0.0);

            info.estimatedElectricityConsumptionRate = Utilities.GetValue(node, "estimatedElectricityConsumptionRate", 0.0);

            info.hibernating = Utilities.GetValue(node, "hibernating", false);

            return info;
        }
コード例 #34
0
        private VesselInfo GetVesselInfo(Vessel vessel, double currentTime)
        {
            VesselInfo vesselInfo;
            if (knownVessels.ContainsKey(vessel.id))
            {
                vesselInfo = knownVessels[vessel.id];
            }
            else
            {
                vesselInfo = new VesselInfo(currentTime);
                knownVessels[vessel.id] = vesselInfo;
            }

            vesselInfo.numCrew = vessel.GetCrewCount();
            vesselInfo.ClearResourceAmounts();

            foreach (Part part in vessel.parts)
            {
                foreach (PartResource resource in part.Resources)
                {
                    if (resource.info.id == settings.FoodId)
                    {
                        vesselInfo.remainingFood += resource.amount;
                        vesselInfo.maxFood += resource.maxAmount;
                    }
                    else if (resource.info.id == settings.WaterId)
                    {
                        vesselInfo.remainingWater += resource.amount;
                        vesselInfo.maxWater += resource.maxAmount;
                    }
                    else if (resource.info.id == settings.OxygenId)
                    {
                        vesselInfo.remainingOxygen += resource.amount;
                        vesselInfo.maxOxygen += resource.maxAmount;
                    }
                    else if (resource.info.id == settings.ElectricityId)
                    {
                        vesselInfo.remainingElectricity += resource.amount;
                        vesselInfo.maxElectricity += resource.maxAmount;
                    }
                    else if (resource.info.id == settings.CO2Id)
                    {
                        vesselInfo.remainingCO2 += resource.amount;
                    }
                    else if (resource.info.id == settings.WasteId)
                    {
                        vesselInfo.remainingWaste += resource.amount;
                    }
                    else if (resource.info.id == settings.WasteWaterId)
                    {
                        vesselInfo.remainingWasteWater += resource.amount;
                    }
                }
            }

            ShowWarnings(vessel, vesselInfo.remainingFood, vesselInfo.maxFood, settings.FoodConsumptionRate / vesselInfo.numCrew, "Food", ref vesselInfo.foodStatus);
            ShowWarnings(vessel, vesselInfo.remainingWater, vesselInfo.maxWater, settings.WaterConsumptionRate / vesselInfo.numCrew, "Water", ref vesselInfo.waterStatus);
            ShowWarnings(vessel, vesselInfo.remainingOxygen, vesselInfo.maxOxygen, settings.OxygenConsumptionRate / vesselInfo.numCrew, "Oxygen", ref vesselInfo.oxygenStatus);
            ShowWarnings(vessel, vesselInfo.remainingElectricity, vesselInfo.maxElectricity, CalculateElectricityConsumptionRate(vessel, vesselInfo), "Electric Charge", ref vesselInfo.electricityStatus);

            return vesselInfo;
        }
コード例 #35
0
        private void ConsumeElectricity(double currentTime, Vessel vessel, VesselInfo vesselInfo)
        {
            double rate = vesselInfo.estimatedElectricityConsumptionRate = CalculateElectricityConsumptionRate(vessel, vesselInfo);
            if (rate > 0.0)
            {
                if (vesselInfo.remainingElectricity >= rate)
                {
                    double deltaTime = Math.Min(currentTime - vesselInfo.lastElectricity, Math.Max(globalSettings.ElectricityMaxDeltaTime, Time.fixedDeltaTime));
                    double desiredElectricity = rate * deltaTime;
                    double electricityObtained = vessel.rootPart.TakeResource(globalSettings.ElectricityId, desiredElectricity);

                    vesselInfo.lastElectricity = currentTime - ((desiredElectricity - electricityObtained) / rate);
                }
                else if (NeedElectricity(vessel, vesselInfo))
                {
                    double timeWithoutElectricity = currentTime - vesselInfo.lastElectricity;
                    if (timeWithoutElectricity > globalSettings.MaxTimeWithoutElectricity)
                    {
                        List<ProtoCrewMember> crew = vessel.GetVesselCrew();
                        int crewMemberIndex = UnityEngine.Random.Range(0, crew.Count - 1);
                        KillCrewMember(crew[crewMemberIndex], "air toxicity", vessel);

                        vesselInfo.lastElectricity += UnityEngine.Random.Range(60, 600);
                    }
                }
            }
            else
            {
                vesselInfo.lastElectricity += currentTime - vesselInfo.lastUpdate;
            }
        }
コード例 #36
0
        private void ShowWarnings(Vessel vessel, double resourceRemaining, double max, double rate, string resourceName, ref VesselInfo.Status status)
        {
            double criticalLevel = rate; // 1 second of resources
            double warningLevel = max * 0.10; // 10% full

            if (resourceRemaining < criticalLevel)
            {
                if (status != VesselInfo.Status.CRITICAL)
                {
                    ScreenMessages.PostScreenMessage(vessel.vesselName + " - " + resourceName + " depleted!", 10.0f, ScreenMessageStyle.UPPER_CENTER);
                    this.Log(vessel.vesselName + " - " + resourceName + " depleted!");
                    status = VesselInfo.Status.CRITICAL;
                    TimeWarp.SetRate(0, false);
                }
            }
            else if (resourceRemaining < warningLevel)
            {
                if (status == VesselInfo.Status.CRITICAL)
                {
                    status = VesselInfo.Status.LOW;
                }
                else if (status != VesselInfo.Status.LOW)
                {
                    ScreenMessages.PostScreenMessage(vessel.vesselName + " - " + resourceName + " is running out!", 10.0f, ScreenMessageStyle.UPPER_CENTER);
                    this.Log(vessel.vesselName + " - " + resourceName + " is running out!");
                    status = VesselInfo.Status.LOW;
                    TimeWarp.SetRate(0, false);
                }
            }
            else
            {
                status = VesselInfo.Status.GOOD;
            }
        }
コード例 #37
0
        private int UpdateVesselInfo(VesselInfo vesselInfo, Vessel vessel)
        {
            int crewCapacity = 0;
            vesselInfo.ClearAmounts();

            foreach (Part part in vessel.parts)
            {
                crewCapacity += part.CrewCapacity;
                if (part.protoModuleCrew.Any())
                {
                    vesselInfo.numCrew += part.protoModuleCrew.Count;
                    ++vesselInfo.numOccupiedParts;
                }

                foreach (PartResource resource in part.Resources)
                {
                    if (resource.flowState)
                    {
                        if (resource.info.id == globalSettings.FoodId)
                        {
                            vesselInfo.remainingFood += resource.amount;
                            vesselInfo.maxFood += resource.maxAmount;
                        }
                        else if (resource.info.id == globalSettings.WaterId)
                        {
                            vesselInfo.remainingWater += resource.amount;
                            vesselInfo.maxWater += resource.maxAmount;
                        }
                        else if (resource.info.id == globalSettings.OxygenId)
                        {
                            vesselInfo.remainingOxygen += resource.amount;
                            vesselInfo.maxOxygen += resource.maxAmount;
                        }
                        else if (resource.info.id == globalSettings.ElectricityId)
                        {
                            vesselInfo.remainingElectricity += resource.amount;
                            vesselInfo.maxElectricity += resource.maxAmount;
                        }
                        else if (resource.info.id == globalSettings.CO2Id)
                        {
                            vesselInfo.remainingCO2 += resource.amount;
                        }
                        else if (resource.info.id == globalSettings.WasteId)
                        {
                            vesselInfo.remainingWaste += resource.amount;
                        }
                        else if (resource.info.id == globalSettings.WasteWaterId)
                        {
                            vesselInfo.remainingWasteWater += resource.amount;
                        }
                    }
                }
            }

            return crewCapacity;
        }
コード例 #38
0
        private bool NeedElectricity(Vessel vessel, VesselInfo vesselInfo)
        {
            // Need electricity to survive unless:
            // 1) landed or splashed down on Kerbin below a reasonable altitude, so they can open a hatch
            if (vessel.mainBody == FlightGlobals.Bodies[1])
            {
                // On or above Kerbin
                if (vessel.staticPressure > 0.5 && (vessel.situation == Vessel.Situations.LANDED || vessel.situation == Vessel.Situations.SPLASHED || vessel.situation == Vessel.Situations.PRELAUNCH))
                {
                    // air pressure is high enough & landed/spashed so they can open the hatch
                    return false;
                }
            }

            return true;
        }
コード例 #39
0
        private bool NeedOxygen(Vessel vessel, VesselInfo vesselInfo)
        {
            // Need oxygen unless:
            // 1) landed or splashed down on Kerbin below a reasonable altitude, so they can open a hatch
            // 2) flying on Kerbin with electricity for the vents, below a reasonable altitude
            if (vessel.mainBody == FlightGlobals.Bodies[1])
            {
                // On or above Kerbin
                if (vessel.staticPressure > 0.2 && vesselInfo.remainingElectricity > vesselInfo.estimatedElectricityConsumptionRate)
                {
                    // air pressure is high enough & have electricity to run vents
                    return false;
                }
                else if (vessel.staticPressure > 0.5 && (vessel.situation == Vessel.Situations.LANDED || vessel.situation == Vessel.Situations.SPLASHED || vessel.situation == Vessel.Situations.PRELAUNCH))
                {
                    // air pressure is high enough & landed/spashed so they can open the hatch
                    return false;
                }
            }

            return true;
        }
コード例 #40
0
        private void ConsumeElectricity(double currentTime, Vessel vessel, VesselInfo vesselInfo)
        {
            double rate = CalculateElectricityConsumptionRate(vessel, vesselInfo);
            if (vesselInfo.remainingElectricity >= rate)
            {
                double desiredElectricity = rate * TimeWarp.fixedDeltaTime;
                double electricityObtained = RequestResource(settings.Electricity, Min(desiredElectricity, vesselInfo.remainingElectricity * 0.95), vessel.rootPart);

                vesselInfo.lastElectricity = currentTime - ((desiredElectricity - electricityObtained) / rate);
            }
            else
            {
                double timeWithoutElectricity = currentTime - vesselInfo.lastElectricity;
                if (timeWithoutElectricity > settings.MaxTimeWithoutElectricity)
                {
                    List<ProtoCrewMember> crew = vessel.GetVesselCrew();
                    int crewMemberIndex = UnityEngine.Random.Range(0, crew.Count - 1);
                    KillCrewMember(crew[crewMemberIndex], "heat/cold/air stagnation", vessel);

                    vesselInfo.lastElectricity += UnityEngine.Random.Range(60, 180);
                }
            }
        }
コード例 #41
0
        void FixedUpdate()
        {
            if (Time.timeSinceLevelLoad < 1.0f || !FlightGlobals.ready || loadingNewScene)
            {
                return;
            }

            double currentTime = Planetarium.GetUniversalTime();
            var allVessels = FlightGlobals.Vessels;
            var knownVessels = gameSettings.knownVessels;

            var vesselsToDelete = new List<Guid>();
            foreach (var entry in knownVessels)
            {
                Guid vesselId = entry.Key;
                VesselInfo vesselInfo = entry.Value;
                Vessel vessel = allVessels.Find(v => v.id == vesselId);

                if (vessel == null)
                {
                    this.Log("Deleting vessel " + vesselInfo.vesselName + " - vessel does not exist anymore");
                    vesselsToDelete.Add(vesselId);
                    var crewToDelete = gameSettings.knownCrew.Where(e => e.Value.vesselId == vesselId).Select(e => e.Key).ToList();
                    foreach (String name in crewToDelete)
                    {
                        this.Log("Deleting crew member: " + name);
                        gameSettings.knownCrew.Remove(name);
                    }
                    continue;
                }

                if (vessel.loaded)
                {
                    int crewCapacity = UpdateVesselInfo(vesselInfo, vessel);

                    if (crewCapacity == 0)
                    {
                        this.Log("Deleting vessel " + vesselInfo.vesselName + " - no crew parts anymore");
                        vesselsToDelete.Add(vesselId);
                        continue;
                    }
                }

                if (vesselInfo.numCrew > 0)
                {
                    double foodRate = globalSettings.FoodConsumptionRate * vesselInfo.numCrew;
                    vesselInfo.estimatedTimeFoodDepleted = vesselInfo.lastFood + (vesselInfo.remainingFood / foodRate);
                    double estimatedFood = vesselInfo.remainingFood - ((currentTime - vesselInfo.lastFood) * foodRate);
                    ShowWarnings(vessel, estimatedFood, vesselInfo.maxFood, foodRate, globalSettings.Food, ref vesselInfo.foodStatus);

                    double waterRate = globalSettings.WaterConsumptionRate * vesselInfo.numCrew;
                    vesselInfo.estimatedTimeWaterDepleted = vesselInfo.lastWater + (vesselInfo.remainingWater / waterRate);
                    double estimatedWater = vesselInfo.remainingWater - ((currentTime - vesselInfo.lastWater) * waterRate);
                    ShowWarnings(vessel, estimatedWater, vesselInfo.maxWater, waterRate, globalSettings.Water, ref vesselInfo.waterStatus);

                    double oxygenRate = globalSettings.OxygenConsumptionRate * vesselInfo.numCrew;
                    vesselInfo.estimatedTimeOxygenDepleted = vesselInfo.lastOxygen + (vesselInfo.remainingOxygen / oxygenRate);
                    double estimatedOxygen = vesselInfo.remainingOxygen - ((currentTime - vesselInfo.lastOxygen) * oxygenRate);
                    ShowWarnings(vessel, estimatedOxygen, vesselInfo.maxOxygen, oxygenRate, globalSettings.Oxygen, ref vesselInfo.oxygenStatus);

                    vesselInfo.estimatedTimeElectricityDepleted = vesselInfo.lastElectricity + (vesselInfo.remainingElectricity / vesselInfo.estimatedElectricityConsumptionRate);
                    if (vessel.loaded)
                    {
                        ShowWarnings(vessel, vesselInfo.remainingElectricity, vesselInfo.maxElectricity, vesselInfo.estimatedElectricityConsumptionRate, globalSettings.Electricity, ref vesselInfo.electricityStatus);
                    }
                }

                if (vessel.loaded)
                {
                    ConsumeResources(currentTime, vessel, vesselInfo);
                }
            }

            vesselsToDelete.ForEach(id => knownVessels.Remove(id));

            foreach (Vessel vessel in allVessels.Where(v => v.loaded))
            {
                if (!knownVessels.ContainsKey(vessel.id) && vessel.parts.Any(p => p.protoModuleCrew.Any()) && IsLaunched(vessel))
                {
                    this.Log("New vessel: " + vessel.vesselName + " (" + vessel.id + ")");
                    VesselInfo vesselInfo = new VesselInfo(vessel.vesselName, currentTime);
                    knownVessels[vessel.id] = vesselInfo;
                    UpdateVesselInfo(vesselInfo, vessel);

                    var knownCrew = gameSettings.knownCrew;
                    foreach (ProtoCrewMember crewMember in vessel.GetVesselCrew())
                    {
                        if (knownCrew.ContainsKey(crewMember.name))
                        {
                            CrewMemberInfo crewMemberInfo = knownCrew[crewMember.name];
                            crewMemberInfo.vesselId = vessel.id;
                            crewMemberInfo.vesselName = vessel.vesselName;
                        }
                        else
                        {
                            this.Log("New crew member: " + crewMember.name);
                            knownCrew[crewMember.name] = new CrewMemberInfo(crewMember.name, vessel.vesselName, vessel.id, currentTime);
                        }
                    }
                }
            }
        }
コード例 #42
0
        private bool NeedElectricity(Vessel vessel, VesselInfo vesselInfo)
        {
            // Need electricity to survive unless:
            // 1) on Kerbin below a reasonable altitude, so they can open a hatch or window or vent
            if (vessel.mainBody == FlightGlobals.Bodies[1])
            {
                // On or above Kerbin
                if (vessel.staticPressure > 0.5)
                {
                    // air pressure is high enough so they can open a window
                    return false;
                }
            }

            return true;
        }
コード例 #43
0
        private void ConsumeFood(double currentTime, Vessel vessel, VesselInfo vesselInfo, ProtoCrewMember crewMember, CrewMemberInfo crewMemberInfo, Part part)
        {
            if (vesselInfo.remainingFood >= settings.FoodConsumptionRate)
            {
                double desiredFood = settings.FoodConsumptionRate * (currentTime - crewMemberInfo.lastUpdate);
                double foodObtained = RequestResource(settings.Food, Min(desiredFood, vesselInfo.remainingFood / vesselInfo.numCrew, vesselInfo.remainingFood * 0.95), part);

                double wasteProduced = foodObtained * settings.WasteProductionRate / settings.FoodConsumptionRate;
                RequestResource(settings.Waste, -wasteProduced, part);

                crewMemberInfo.lastFood = currentTime - ((desiredFood - foodObtained) / settings.FoodConsumptionRate);
            }
            else
            {
                double timeWithoutFood = currentTime - crewMemberInfo.lastFood;
                if (timeWithoutFood > (settings.MaxTimeWithoutFood + crewMemberInfo.respite))
                {
                    KillCrewMember(crewMember, "starvation", vessel);
                }
            }
        }
コード例 #44
0
        private void ConsumeOxygen(double currentTime, Vessel vessel, VesselInfo vesselInfo)
        {
            if (NeedOxygen(vessel, vesselInfo))
            {
                if (vesselInfo.remainingOxygen >= globalSettings.OxygenConsumptionRate)
                {
                    double deltaTime = Math.Min(currentTime - vesselInfo.lastOxygen, globalSettings.MaxDeltaTime);
                    if (vesselInfo.numCrew > 0)
                    {
                        double rate = globalSettings.OxygenConsumptionRate * vesselInfo.numCrew;
                        double desiredOxygen = rate * deltaTime;
                        double oxygenObtained = vessel.rootPart.TakeResource(globalSettings.OxygenId, desiredOxygen);

                        double co2Production = oxygenObtained * globalSettings.CO2ProductionRate / globalSettings.OxygenConsumptionRate;
                        vessel.rootPart.TakeResource(globalSettings.CO2Id, -co2Production);

                        vesselInfo.lastOxygen += deltaTime - ((desiredOxygen - oxygenObtained) / rate);
                    }
                    else
                    {
                        vesselInfo.lastOxygen += currentTime - vesselInfo.lastUpdate;
                    }
                }
                else
                {
                    double timeWithoutOxygen = currentTime - vesselInfo.lastOxygen;
                    if (timeWithoutOxygen > globalSettings.MaxTimeWithoutOxygen)
                    {
                        List<ProtoCrewMember> crew = vessel.GetVesselCrew();
                        int crewMemberIndex = UnityEngine.Random.Range(0, crew.Count - 1);
                        KillCrewMember(crew[crewMemberIndex], "oxygen deprivation", vessel);

                        vesselInfo.lastOxygen += UnityEngine.Random.Range(60, 600);
                    }
                }
            }
            else
            {
                vesselInfo.lastOxygen = currentTime;
            }
        }
コード例 #45
0
        private void ConsumeResources(double currentTime, Vessel vessel, VesselInfo vesselInfo)
        {
            // Electricity
            ConsumeElectricity(currentTime, vessel, vesselInfo);

            List<ProtoCrewMember> crew = vessel.GetVesselCrew();
            foreach (ProtoCrewMember crewMember in crew)
            {
                if (knownCrew.ContainsKey(crewMember.name))
                {
                    CrewMemberInfo crewMemberInfo = knownCrew[crewMember.name];
                    var part = (crewMember.KerbalRef != null) ? crewMember.KerbalRef.InPart : vessel.rootPart;

                    if (crewMemberInfo.vesselId != vessel.id && crewMemberInfo.isEVA)
                    {
                        // The crewmember came back inside after EVA, return the remaining resources out of the suit
                        EmptyEvaSuit(crewMemberInfo, part);
                    }

                    // Oxygen
                    ConsumeOxygen(currentTime, vessel, vesselInfo, crewMember, crewMemberInfo, part);

                    // Water
                    ConsumeWater(currentTime, vessel, vesselInfo, crewMember, crewMemberInfo, part);

                    // Food
                    ConsumeFood(currentTime, vessel, vesselInfo, crewMember, crewMemberInfo, part);

                    crewMemberInfo.lastUpdate = currentTime;
                    crewMemberInfo.vesselId = vessel.id;
                    crewMemberInfo.isEVA = vessel.isEVA;
                }
                else
                {
                    Debug.Log("TAC Life Support (LifeSupportController) [" + this.GetInstanceID().ToString("X") + "][" + Time.time + "]: Unknown crew member: " + crewMember.name);
                    knownCrew[crewMember.name] = new CrewMemberInfo(crewMember.name, vessel, currentTime);
                }
            }

            vesselInfo.lastUpdate = currentTime;
        }
コード例 #46
0
        private void ShowWarnings(Vessel vessel, double resourceRemaining, double max, double consumptionRate, string resourceName, ref VesselInfo.Status status)
        {
            const double multiplier = 1.1;
            const double warningLevel = 0.10;

            int currentWarpRateIndex = TimeWarp.CurrentRateIndex;
            float currentWarpRate = TimeWarp.fetch.warpRates[currentWarpRateIndex];

            if ((resourceRemaining / consumptionRate) < (currentWarpRate * multiplier))
            {
                if (status != VesselInfo.Status.CRITICAL)
                {
                    if (currentWarpRateIndex > 0)
                    {
                        Debug.Log("TAC Life Support (LifeSupportController) [" + this.GetInstanceID().ToString("X") + "][" + Time.time + "]: @CRITICAL, warp rate: " + currentWarpRate);
                        TimeWarp.SetRate(currentWarpRateIndex - 1, false);
                    }
                    else
                    {
                        ScreenMessages.PostScreenMessage(vessel.vesselName + " - " + resourceName + " depleted!", 15.0f, ScreenMessageStyle.UPPER_CENTER);
                        Debug.Log("TAC Life Support (LifeSupportController) [" + this.GetInstanceID().ToString("X") + "][" + Time.time + "]: " + vessel.vesselName + " - " + resourceName + " depleted!");
                        status = VesselInfo.Status.CRITICAL;
                    }
                }
            }
            else if (resourceRemaining < (max * warningLevel))
            {
                if (status != VesselInfo.Status.LOW)
                {
                    if (currentWarpRateIndex > 0)
                    {
                        Debug.Log("TAC Life Support (LifeSupportController) [" + this.GetInstanceID().ToString("X") + "][" + Time.time + "]: @LOW, warp rate: " + currentWarpRate);
                        TimeWarp.SetRate(currentWarpRateIndex - 1, false);
                    }
                    else
                    {
                        ScreenMessages.PostScreenMessage(vessel.vesselName + " - " + resourceName + " is running out!", 15.0f, ScreenMessageStyle.UPPER_CENTER);
                        Debug.Log("TAC Life Support (LifeSupportController) [" + this.GetInstanceID().ToString("X") + "][" + Time.time + "]: " + vessel.vesselName + " - " + resourceName + " is running out!");
                        status = VesselInfo.Status.LOW;
                    }
                }
            }
            else
            {
                status = VesselInfo.Status.GOOD;
            }
        }
コード例 #47
0
        private void ConsumeResources(double currentTime, Vessel vessel, VesselInfo vesselInfo)
        {
            ConsumeElectricity(currentTime, vessel, vesselInfo);
            ConsumeOxygen(currentTime, vessel, vesselInfo);

            vesselInfo.lastFood = currentTime;
            vesselInfo.lastWater = currentTime;
            vesselInfo.hibernating = false;

            List<ProtoCrewMember> crew = vessel.GetVesselCrew();
            var knownCrew = gameSettings.knownCrew;
            foreach (ProtoCrewMember crewMember in crew)
            {
                if (knownCrew.ContainsKey(crewMember.name))
                {
                    CrewMemberInfo crewMemberInfo = knownCrew[crewMember.name];
                    Part part = (crewMember.KerbalRef != null) ? crewMember.KerbalRef.InPart : vessel.rootPart;

                    ConsumeFood(currentTime, vessel, vesselInfo, crewMember, crewMemberInfo, part);
                    ConsumeWater(currentTime, vessel, vesselInfo, crewMember, crewMemberInfo, part);

                    crewMemberInfo.lastUpdate = currentTime;
                    crewMemberInfo.vesselId = vessel.id;
                    crewMemberInfo.vesselName = (!vessel.isEVA) ? vessel.vesselName : "EVA";

                    if (vesselInfo.lastFood > crewMemberInfo.lastFood)
                    {
                        vesselInfo.lastFood = crewMemberInfo.lastFood;
                    }
                    if (vesselInfo.lastWater > crewMemberInfo.lastWater)
                    {
                        vesselInfo.lastWater = crewMemberInfo.lastWater;
                    }
                    if (crewMemberInfo.hibernating)
                    {
                        vesselInfo.hibernating = true;
                    }
                }
                else
                {
                    this.LogWarning("Unknown crew member: " + crewMember.name);
                    knownCrew[crewMember.name] = new CrewMemberInfo(crewMember.name, vessel.vesselName, vessel.id, currentTime);
                }
            }

            vesselInfo.lastUpdate = currentTime;
            vesselInfo.vesselName = vessel.vesselName;
            vesselInfo.vesselType = vessel.vesselType.ToString();
        }
コード例 #48
0
        void FixedUpdate()
        {
            if (Time.timeSinceLevelLoad < 1.0f || loadingNewScene)
            {
                return;
            }

            // If DeepFreeze is installed do DeepFreeze processing to remove frozen kerbals from our list.
            if (IsDFInstalled)
            {
                if (!DFWrapper.InstanceExists)  // Check if DFWrapper has been initialized or not. If not try to initialize.
                {
                    DFWrapper.InitDFWrapper();
                }
                if (DFWrapper.APIReady)
                {
                    Dictionary<string, DFWrapper.KerbalInfo> DFFrozenKerbals = new Dictionary<string, DFWrapper.KerbalInfo>();
                    //Get the DeepFreeze Dictionary of all Frozen Kerbals in the current Game.
                    DFFrozenKerbals = DFWrapper.DeepFreezeAPI.FrozenKerbals;
                    //Remove any Frozen Kerbals from TAC LS tracking.
                    RemoveFrozenKerbals(DFFrozenKerbals);
                }
            }

            double currentTime = Planetarium.GetUniversalTime();
            var allVessels = FlightGlobals.Vessels;
            var knownVessels = gameSettings.knownVessels;

            var vesselsToDelete = new List<Guid>();
            foreach (var entry in knownVessels)
            {
                Guid vesselId = entry.Key;
                VesselInfo vesselInfo = entry.Value;
                Vessel vessel = allVessels.Find(v => v.id == vesselId);

                if (vessel == null)
                {
                    this.Log("Deleting vessel " + vesselInfo.vesselName + " - vessel does not exist anymore");
                    vesselsToDelete.Add(vesselId);
                    var crewToDelete = gameSettings.knownCrew.Where(e => e.Value.vesselId == vesselId).Select(e => e.Key).ToList();
                    foreach (String name in crewToDelete)
                    {
                        this.Log("Deleting crew member: " + name);
                        gameSettings.knownCrew.Remove(name);
                    }
                    continue;
                }

                if (vessel.loaded)
                {
                    int crewCapacity = UpdateVesselInfo(vesselInfo, vessel);

                    if (crewCapacity == 0)
                    {
                        this.Log("Deleting vessel " + vesselInfo.vesselName + " - no crew parts anymore");
                        vesselsToDelete.Add(vesselId);
                        continue;
                    }

                    ConsumeResources(currentTime, vessel, vesselInfo);

                    if (vesselInfo.numCrew > 0)
                    {
                        ShowWarnings(vessel.vesselName, vesselInfo.remainingElectricity, vesselInfo.maxElectricity, vesselInfo.estimatedElectricityConsumptionRate, globalSettings.Electricity, ref vesselInfo.electricityStatus);
                    }
                }

                if (vesselInfo.numCrew > 0)
                {
                    double foodRate = globalSettings.FoodConsumptionRate * vesselInfo.numCrew;
                    vesselInfo.estimatedTimeFoodDepleted = vesselInfo.lastFood + (vesselInfo.remainingFood / foodRate);
                    double estimatedFood = vesselInfo.remainingFood - ((currentTime - vesselInfo.lastFood) * foodRate);
                    ShowWarnings(vesselInfo.vesselName, estimatedFood, vesselInfo.maxFood, foodRate, globalSettings.Food, ref vesselInfo.foodStatus);

                    double waterRate = globalSettings.WaterConsumptionRate * vesselInfo.numCrew;
                    vesselInfo.estimatedTimeWaterDepleted = vesselInfo.lastWater + (vesselInfo.remainingWater / waterRate);
                    double estimatedWater = vesselInfo.remainingWater - ((currentTime - vesselInfo.lastWater) * waterRate);
                    ShowWarnings(vesselInfo.vesselName, estimatedWater, vesselInfo.maxWater, waterRate, globalSettings.Water, ref vesselInfo.waterStatus);

                    double oxygenRate = globalSettings.OxygenConsumptionRate * vesselInfo.numCrew;
                    vesselInfo.estimatedTimeOxygenDepleted = vesselInfo.lastOxygen + (vesselInfo.remainingOxygen / oxygenRate);
                    double estimatedOxygen = vesselInfo.remainingOxygen - ((currentTime - vesselInfo.lastOxygen) * oxygenRate);
                    ShowWarnings(vesselInfo.vesselName, estimatedOxygen, vesselInfo.maxOxygen, oxygenRate, globalSettings.Oxygen, ref vesselInfo.oxygenStatus);

                    vesselInfo.estimatedTimeElectricityDepleted = vesselInfo.lastElectricity + (vesselInfo.remainingElectricity / vesselInfo.estimatedElectricityConsumptionRate);
                }

            }

            vesselsToDelete.ForEach(id => knownVessels.Remove(id));

            foreach (Vessel vessel in allVessels.Where(v => v.loaded))
            {
                if (!knownVessels.ContainsKey(vessel.id) && vessel.parts.Any(p => p.protoModuleCrew.Count > 0) && IsLaunched(vessel))
                {
                    this.Log("New vessel: " + vessel.vesselName + " (" + vessel.id + ")");
                    var knownCrew = gameSettings.knownCrew;

                    if (vessel.isEVA)
                    {
                        ProtoCrewMember crewMember = vessel.GetVesselCrew().FirstOrDefault();
                        if (crewMember != null && !knownCrew.ContainsKey(crewMember.name))
                        {
                            FillRescueEvaSuit(vessel);
                        }
                    }

                    VesselInfo vesselInfo = new VesselInfo(vessel.vesselName, currentTime);
                    knownVessels[vessel.id] = vesselInfo;
                    UpdateVesselInfo(vesselInfo, vessel);

                    foreach (ProtoCrewMember crewMember in vessel.GetVesselCrew())
                    {
                        if (knownCrew.ContainsKey(crewMember.name))
                        {
                            CrewMemberInfo crewMemberInfo = knownCrew[crewMember.name];
                            crewMemberInfo.vesselId = vessel.id;
                            crewMemberInfo.vesselName = vessel.vesselName;
                        }
                        else
                        {
                            this.Log("New crew member: " + crewMember.name);
                            knownCrew[crewMember.name] = new CrewMemberInfo(crewMember.name, vessel.vesselName, vessel.id, currentTime);
                        }
                    }
                }
            }
        }
コード例 #49
0
        private void ConsumeWater(double currentTime, Vessel vessel, VesselInfo vesselInfo, ProtoCrewMember crewMember, CrewMemberInfo crewMemberInfo, Part part)
        {
            if (vesselInfo.remainingWater >= settings.WaterConsumptionRate)
            {
                double desiredWater = settings.WaterConsumptionRate * (currentTime - crewMemberInfo.lastUpdate);
                double waterObtained = RequestResource(settings.Water, Min(desiredWater, vesselInfo.remainingWater / vesselInfo.numCrew, vesselInfo.remainingWater * 0.95), part);

                double wasteWaterProduced = waterObtained * settings.WasteWaterProductionRate / settings.WaterConsumptionRate;
                RequestResource(settings.WasteWater, -wasteWaterProduced, part);

                crewMemberInfo.lastWater = currentTime - ((desiredWater - waterObtained) / settings.WaterConsumptionRate);
            }
            else
            {
                double timeWithoutWater = currentTime - crewMemberInfo.lastWater;
                if (timeWithoutWater > (settings.MaxTimeWithoutWater + crewMemberInfo.respite))
                {
                    KillCrewMember(crewMember, "dehydration", vessel);
                }
            }
        }
コード例 #50
0
        private void ConsumeWater(double currentTime, Vessel vessel, VesselInfo vesselInfo, ProtoCrewMember crewMember, CrewMemberInfo crewMemberInfo, Part part)
        {
            if (vesselInfo.remainingWater >= globalSettings.WaterConsumptionRate)
            {
                double deltaTime = Math.Min(currentTime - crewMemberInfo.lastWater, globalSettings.MaxDeltaTime);
                double desiredWater = globalSettings.WaterConsumptionRate * deltaTime;
                double waterObtained = part.TakeResource(globalSettings.WaterId, Math.Min(desiredWater, vesselInfo.remainingWater / vesselInfo.numCrew));

                double wasteWaterProduced = waterObtained * globalSettings.WasteWaterProductionRate / globalSettings.WaterConsumptionRate;
                part.TakeResource(globalSettings.WasteWaterId, -wasteWaterProduced);

                crewMemberInfo.lastWater += deltaTime - ((desiredWater - waterObtained) / globalSettings.WaterConsumptionRate);
                crewMemberInfo.hibernating = false;
            }
            else
            {
                double timeWithoutWater = currentTime - crewMemberInfo.lastWater;
                if (timeWithoutWater > (globalSettings.MaxTimeWithoutWater + crewMemberInfo.respite))
                {
                    if (!gameSettings.HibernateInsteadOfKill)
                    {
                        KillCrewMember(crewMember, "dehydration", vessel);
                    }
                    else
                    {
                        crewMemberInfo.hibernating = true;
                    }
                }
            }
        }
コード例 #51
0
        private void FillEvaSuit(Part oldPart, Part newPart)
        {
            double desiredFood = globalSettings.FoodConsumptionRate * globalSettings.EvaDefaultResourceAmount;
            double desiredWater = globalSettings.WaterConsumptionRate * globalSettings.EvaDefaultResourceAmount;
            double desiredOxygen = globalSettings.OxygenConsumptionRate * globalSettings.EvaDefaultResourceAmount;
            double desiredElectricity = globalSettings.EvaElectricityConsumptionRate * globalSettings.EvaDefaultResourceAmount;

            Vessel lastVessel = oldPart.vessel;
            VesselInfo lastVesselInfo;
            if (!gameSettings.knownVessels.TryGetValue(lastVessel.id, out lastVesselInfo))
            {
                lastVesselInfo = new VesselInfo(lastVessel.vesselName, Planetarium.GetUniversalTime());
            }

            UpdateVesselInfo(lastVesselInfo, lastVessel);
            int numCrew = lastVesselInfo.numCrew + 1;

            double foodObtained = oldPart.TakeResource(globalSettings.FoodId, Math.Min(desiredFood, lastVesselInfo.remainingFood / numCrew));
            double waterObtained = oldPart.TakeResource(globalSettings.WaterId, Math.Min(desiredWater, lastVesselInfo.remainingWater / numCrew));
            double oxygenObtained = oldPart.TakeResource(globalSettings.OxygenId, Math.Min(desiredOxygen, lastVesselInfo.remainingOxygen / numCrew));
            double electricityObtained = oldPart.TakeResource(globalSettings.ElectricityId, Math.Min(desiredElectricity, lastVesselInfo.remainingElectricity / numCrew));

            newPart.TakeResource(globalSettings.FoodId, -foodObtained);
            newPart.TakeResource(globalSettings.WaterId, -waterObtained);
            newPart.TakeResource(globalSettings.OxygenId, -oxygenObtained);
            newPart.TakeResource(globalSettings.ElectricityId, -electricityObtained);
        }
コード例 #52
0
        /*
         * Notes:
         *  Mt Everest is at 8,848 meters (29,029 ft). The air pressure is ~0.33 atm.
         *  Everest Base Camp is at ~5,000 m (16,000 ft), with an air pressure of ~0.5 atm.
         *  0.2 atm is around 12,500 m (41,010.5 ft), close to the maximum altitude most airliners fly.
         * References:
         *  http://en.wikipedia.org/wiki/Mount_Everest
         *  http://en.wikipedia.org/wiki/Effects_of_high_altitude_on_humans
         *  http://www.altitude.org/air_pressure.php
         */
        private bool NeedOxygen(Vessel vessel, VesselInfo vesselInfo)
        {
            // Need oxygen unless:
            // 1) on Kerbin below a reasonable altitude, so they can open a hatch or window or vent
            // 2) flying on Kerbin with electricity for the vents, below a reasonable altitude
            if (vessel.mainBody == FlightGlobals.Bodies[1])
            {
                // On or above Kerbin
                if (vessel.staticPressure > 0.5)
                {
                    // air pressure is high enough so they can open a window
                    return false;
                }
                else if (vessel.staticPressure > 0.2 && vesselInfo.remainingElectricity > vesselInfo.estimatedElectricityConsumptionRate)
                {
                    // air pressure is high enough & have electricity to run vents
                    return false;
                }
            }

            return true;
        }
コード例 #53
0
        private void ConsumeFood(double currentTime, Vessel vessel, VesselInfo vesselInfo, ProtoCrewMember crewMember, CrewMemberInfo crewMemberInfo, Part part)
        {
            if (vesselInfo.remainingFood >= globalSettings.FoodConsumptionRate)
            {
                double deltaTime = Math.Min(currentTime - crewMemberInfo.lastFood, globalSettings.MaxDeltaTime);
                double desiredFood = globalSettings.FoodConsumptionRate * deltaTime;
                double foodObtained = part.TakeResource(globalSettings.FoodId, Math.Min(desiredFood, vesselInfo.remainingFood / vesselInfo.numCrew));

                double wasteProduced = foodObtained * globalSettings.WasteProductionRate / globalSettings.FoodConsumptionRate;
                part.TakeResource(globalSettings.WasteId, -wasteProduced);

                crewMemberInfo.lastFood += deltaTime - ((desiredFood - foodObtained) / globalSettings.FoodConsumptionRate);
                crewMemberInfo.hibernating = false;
            }
            else
            {
                double timeWithoutFood = currentTime - crewMemberInfo.lastFood;
                if (timeWithoutFood > (globalSettings.MaxTimeWithoutFood + crewMemberInfo.respite))
                {
                    if (!gameSettings.HibernateInsteadOfKill)
                    {
                        KillCrewMember(crewMember, "starvation", vessel);
                    }
                    else
                    {
                        crewMemberInfo.hibernating = true;
                    }
                }
            }
        }
コード例 #54
0
        private void ConsumeOxygen(double currentTime, Vessel vessel, VesselInfo vesselInfo, ProtoCrewMember crewMember, CrewMemberInfo crewMemberInfo, Part part)
        {
            if (!vessel.orbit.referenceBody.atmosphereContainsOxygen || FlightGlobals.getStaticPressure() < 0.2)
            {
                if (vesselInfo.remainingOxygen >= settings.OxygenConsumptionRate)
                {
                    double desiredOxygen = settings.OxygenConsumptionRate * (currentTime - crewMemberInfo.lastUpdate);
                    double oxygenObtained = RequestResource(settings.Oxygen, Min(desiredOxygen, vesselInfo.remainingOxygen / vesselInfo.numCrew, vesselInfo.remainingOxygen * 0.95), part);

                    double co2Production = oxygenObtained * settings.CO2ProductionRate / settings.OxygenConsumptionRate;
                    RequestResource(settings.CO2, -co2Production, part);

                    crewMemberInfo.lastOxygen = currentTime - ((desiredOxygen - oxygenObtained) / settings.OxygenConsumptionRate);
                }
                else
                {
                    double timeWithoutOxygen = currentTime - crewMemberInfo.lastOxygen;
                    if (timeWithoutOxygen > (settings.MaxTimeWithoutOxygen + crewMemberInfo.respite))
                    {
                        KillCrewMember(crewMember, "oxygen deprivation", vessel);
                    }
                }
            }
            else
            {
                crewMemberInfo.lastOxygen = currentTime;
            }
        }