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; } } } }
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( ); }
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; } } } }
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; } } } }
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; } } } }
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; } }
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); }
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; } }
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); }
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); }
private double CalculateElectricityConsumptionRate(Vessel vessel, VesselInfo vesselInfo) { if (!vessel.isEVA) { return((globalSettings.ElectricityConsumptionRate * vesselInfo.numCrew) + (globalSettings.BaseElectricityConsumptionRate * vesselInfo.numOccupiedParts)); } else { return(globalSettings.EvaElectricityConsumptionRate); } }
private double CalculateElectricityConsumptionRate(Vessel vessel, VesselInfo vesselInfo) { if (!vessel.isEVA) { return (globalSettings.ElectricityConsumptionRate * vesselInfo.numCrew) + (globalSettings.BaseElectricityConsumptionRate * vesselInfo.numOccupiedParts); } else { return globalSettings.EvaElectricityConsumptionRate; } }
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)); } }
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; } }
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); } }
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); }
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); } }
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); }
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(); }
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(); } } }
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); }
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); }
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(); } }
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( ); }
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; }
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; } }
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); } } }
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); } } }
/* * 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); }
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); }
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."); } }
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); } } }
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; }
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; }
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; } }
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; } }
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; }
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; }
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; }
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); } } }
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); } } } } }
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; }
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; } }
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; }
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; } }
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(); }
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); } } } } }
/* * 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; }