public static double DiuralSMAChange(Vessel vessel) { double RateOfChangeOfSMA = 0; double InitialSMA = VesselData.FetchSMA(vessel); double Albedo = 0.12; // Work on something better for this! Currently using Worn Asphalt as a guide... double MeanMotion = 360.0 / vessel.orbitDriver.orbit.period; double Area = VesselData.FetchArea(vessel); double Mass = VesselData.FetchMass(vessel); double Radius = Math.Sqrt(Area / Math.PI); double Volume = 4.0 / 3.0 * Math.PI * Math.Pow(Radius, 3.0); double Density = Mass / Volume; double c = Math.Pow(8.0 * 10, 8); double Altitude = vessel.orbitDriver.orbit.referenceBody == Sun.Instance.sun ? vessel.orbitDriver.orbit.altitude : vessel.orbitDriver.orbit.referenceBody.orbit.altitude; double SolarEnergy = Math.Pow(3.86 * 10.0, 26.0); double SolarConstant = SolarEnergy / (4.0 * Math.PI * Math.Pow(Altitude, 2.0)); // W/m^2 double BoltzmannConstant = Math.Pow(6.68 * 10.0, -11.0); double SolarTemperature = vessel.externalTemperature; // try this! double Epsilon = UnityEngine.Random.Range(0.75f, 0.9f); double LocalForce = 0; LocalForce = Epsilon * BoltzmannConstant * Math.Pow(SolarTemperature, 4.0) / Albedo; double Iota = 3.0 * LocalForce / (4.0 * Radius * Density * c); Vector3d RotationAxis = vessel.upAxis; float ObliquityOfSpinAxis = 0; double AmplitudeOfRotation = 0; double RotationPhase = 0; if (LoadingCheck.PersistentRotationInstalled) { // Add Persistent Rotation Compatibility here! //1.6.0 } else { if (vessel.isActiveVessel) { Quaternion VesselRotation = vessel.srfRelRotation; Vector3 TemporaryAxis; VesselRotation.ToAngleAxis(out ObliquityOfSpinAxis, out TemporaryAxis); Vector3 AngularSpeed = TemporaryAxis * ObliquityOfSpinAxis; // Rotation Per Second? AmplitudeOfRotation = AngularSpeed.magnitude; RotationPhase = Vector3.Angle(RotationAxis, TemporaryAxis); } else { Quaternion VesselRotation = new Quaternion();//.Inverse(); // Issues here work out a background rotational calculation? Vector3 TemporaryAxis; VesselRotation.ToAngleAxis(out ObliquityOfSpinAxis, out TemporaryAxis); Vector3 AngularSpeed = TemporaryAxis * ObliquityOfSpinAxis; // Rotation Per Second? AmplitudeOfRotation = AngularSpeed.magnitude; RotationPhase = Vector3.Angle(RotationAxis, TemporaryAxis); } } double RotationFrequency = AmplitudeOfRotation; double DiuralThermalParameter = 0; double Gamma = 0; double SpecificHeatCapacity = 670; // Lets not model this too far yet... maybe for 1.6.0 using c of Regolith for now double ThermalConductivity = Math.Pow(100.0, 2.0) / (Density * SpecificHeatCapacity); double PenetrationDepth = 0; double X = 0; DiuralThermalParameter = Math.Sqrt(ThermalConductivity * Density * SpecificHeatCapacity * RotationFrequency) / (Epsilon * BoltzmannConstant * Math.Pow(SolarTemperature, 3.0) * Altitude); PenetrationDepth = Math.Sqrt(ThermalConductivity / (Density * SpecificHeatCapacity * RotationFrequency)); X = Radius * Math.Sqrt(2) / PenetrationDepth; Gamma = DiuralThermalParameter / X; double BigOFunctionOfEccentricity = Math.Pow(vessel.orbitDriver.orbit.eccentricity, 0.0); RateOfChangeOfSMA = -8.0 * Albedo / (9.0 * MeanMotion) * Iota * (AmplitudeOfRotation * Math.Sin(RotationPhase) / 1.0 + Gamma) * Math.Cos(ObliquityOfSpinAxis) + 0; if (double.IsNaN(RateOfChangeOfSMA)) { RateOfChangeOfSMA = 0; } return(RateOfChangeOfSMA); }
public void InformationTab() { GUILayout.BeginHorizontal(); GUI.skin.label.fontSize = 16; GUI.skin.label.alignment = TextAnchor.MiddleCenter; GUILayout.Label("Vessel Information", GUILayout.Width(290)); GUI.skin.label.alignment = TextAnchor.MiddleLeft; GUI.skin.label.fontSize = 12; GUILayout.EndHorizontal(); GUILayout.BeginVertical(); // 1.5.2 Filtering // GUILayout.Space(3); GUILayout.BeginHorizontal(); if (GUILayout.Button(GameDatabase.Instance.GetTexture("Squad/PartList/SimpleIcons/R&D_node_icon_unmannedtech", false))) { if (FilterTypes.Contains(VesselType.Probe)) { FilterTypes.Remove(VesselType.Probe); } else { FilterTypes.Add(VesselType.Probe); } } GUILayout.Space(3); if (GUILayout.Button(GameDatabase.Instance.GetTexture("Squad/PartList/SimpleIcons/R&D_node_icon_advunmanned", false))) { if (FilterTypes.Contains(VesselType.Relay)) { FilterTypes.Remove(VesselType.Relay); } else { FilterTypes.Add(VesselType.Relay); } } GUILayout.Space(3); if (GUILayout.Button(GameDatabase.Instance.GetTexture("Squad/PartList/SimpleIcons/RDicon_commandmodules", false))) { if (FilterTypes.Contains(VesselType.Ship)) { FilterTypes.Remove(VesselType.Ship); } else { FilterTypes.Add(VesselType.Ship); } } GUILayout.Space(3); if (GUILayout.Button(GameDatabase.Instance.GetTexture("Squad/PartList/SimpleIcons/R&D_node_icon_specializedconstruction", false))) { if (FilterTypes.Contains(VesselType.Station)) { FilterTypes.Remove(VesselType.Station); } else { FilterTypes.Add(VesselType.Station); } } GUILayout.Space(3); if (GUILayout.Button(GameDatabase.Instance.GetTexture("Squad/PartList/SimpleIcons/RDicon_telescope", false))) { if (FilterTypes.Contains(VesselType.SpaceObject)) { FilterTypes.Remove(VesselType.SpaceObject); } else { FilterTypes.Add(VesselType.SpaceObject); } if (FilterTypes.Contains(VesselType.Unknown)) { FilterTypes.Remove(VesselType.Unknown); } else { FilterTypes.Add(VesselType.Unknown); } } GUILayout.Space(3); if (GUILayout.Button(GameDatabase.Instance.GetTexture("Squad/PartList/SimpleIcons/R&D_node_icon_composites", false))) { if (FilterTypes.Contains(VesselType.Debris)) { FilterTypes.Remove(VesselType.Debris); } else { FilterTypes.Add(VesselType.Debris); } } GUILayout.Space(3); GUILayout.EndHorizontal(); GUILayout.Space(3); GUILayout.Label("_______________________________________"); GUILayout.EndVertical(); scrollPosition1 = GUILayout.BeginScrollView(scrollPosition1, GUILayout.Width(290), GUILayout.Height(350)); bool Realistic = Settings.ReadRD(); bool ClockType = Settings.Read24Hr(); //151var Resource = Settings.ReadStationKeepingResource(); foreach (Vessel vessel in FlightGlobals.Vessels) { if (FilterTypes.Contains(vessel.vesselType)) { if (vessel.situation == Vessel.Situations.ORBITING) { string StationKeeping = VesselData.FetchStationKeeping(vessel).ToString(); string StationKeepingFuelRemaining = ResourceManager.GetResources(vessel).ToString("F3"); string Resource = ResourceManager.GetResourceNames(vessel); string ButtonText = ""; double HoursInDay = 6.0; double DaysInYear = 0; bool KerbinTime = GameSettings.KERBIN_TIME; if (KerbinTime) { DaysInYear = 9203545 / (60 * 60 * HoursInDay); } else { DaysInYear = 31557600 / (60 * 60 * HoursInDay); } if (StationKeeping == "True") { ButtonText = "Disable Station Keeping"; } else { ButtonText = "Enable Station Keeping"; } if (ClockType) { HoursInDay = 24.0; } else { HoursInDay = 6.0; } GUILayout.BeginVertical(); // GUILayout.Label("Vessels count" + VesselData.VesselInformation.CountNodes.ToString()); GUILayout.Label("Vessel Name: " + vessel.vesselName); // GUILayout.Label("Vessel Area: " + VesselData.FetchArea(vessel).ToString()); // GUILayout.Label("Vessel Mass: " + VesselData.FetchMass(vessel).ToString()); GUILayout.Space(2); GUILayout.Label("Orbiting Body: " + vessel.orbitDriver.orbit.referenceBody.GetName()); GUILayout.Space(2); if (StationKeeping == "True") { GUILayout.Label("Current Total Decay Rate: Vessel is Station Keeping"); GUILayout.Space(2); } else { double TotalDecayRatePerSecond = Math.Abs(DecayManager.DecayRateAtmosphericDrag(vessel)) + Math.Abs(DecayManager.DecayRateRadiationPressure(vessel)) + Math.Abs(DecayManager.DecayRateYarkovskyEffect(vessel)); //+ Math.Abs(DecayManager.DecayRateGravitationalPertubation(vessel)); double ADDR = DecayManager.DecayRateAtmosphericDrag(vessel); double GPDR = DecayManager.DecayRateGravitationalPertubation(vessel); double PRDR = DecayManager.DecayRateRadiationPressure(vessel); double YEDR = DecayManager.DecayRateYarkovskyEffect(vessel); GUILayout.Label("Current Total Decay Rate: " + FormatDecayRateToString(TotalDecayRatePerSecond)); GUILayout.Space(2); if (GUILayout.Button("Toggle Decay Rate Breakdown")) // Display a new window here? { subwindowVessel = vessel; DecayBreakdownVisible = !DecayBreakdownVisible; } // 1.7.0 maybe? if (Settings.ReadNB()) { GUILayout.Space(2); if (GUILayout.Button("Toggle NBody Breakdown")) // New Window for NBody { subwindowVessel = vessel; NBodyVesselAccelTimes.Clear(); NBodyBreakdownVisible = !NBodyBreakdownVisible; } } GUILayout.Space(2); double TimeUntilDecayInUnits = 0.0; string TimeUntilDecayInDays = ""; if (ADDR != 0) { TimeUntilDecayInUnits = DecayManager.DecayTimePredictionExponentialsVariables(vessel); TimeUntilDecayInDays = FormatTimeUntilDecayInDaysToString(TimeUntilDecayInUnits); } else { TimeUntilDecayInUnits = DecayManager.DecayTimePredictionLinearVariables(vessel); TimeUntilDecayInDays = FormatTimeUntilDecayInSecondsToString(TimeUntilDecayInUnits); } GUILayout.Label("Approximate Time Until Decay: " + TimeUntilDecayInDays); GUILayout.Space(2); } GUILayout.Label("Station Keeping: " + StationKeeping); GUILayout.Space(2); GUILayout.Label("Station Keeping Fuel Remaining: " + StationKeepingFuelRemaining); GUILayout.Space(2); GUILayout.Label("Using Fuel Type: " + Resource); //151 GUILayout.Space(2); //151 if (StationKeeping == "True") { double DecayRateSKL = 0; DecayRateSKL = DecayManager.DecayRateAtmosphericDrag(vessel) + DecayManager.DecayRateRadiationPressure(vessel) + DecayManager.DecayRateYarkovskyEffect(vessel); double StationKeepingLifetime = double.Parse(StationKeepingFuelRemaining) / (DecayRateSKL / TimeWarp.CurrentRate * VesselData.FetchEfficiency(vessel) /*ResourceManager.GetEfficiency(Resource)*/ * Settings.ReadResourceRateDifficulty()) / (60 * 60 * HoursInDay); if (StationKeepingLifetime < -5) // SRP Fixes { GUILayout.Label("Station Keeping Fuel Lifetime: > 1000 years."); } else { if (StationKeepingLifetime > 365000 && HoursInDay == 24) { GUILayout.Label("Station Keeping Fuel Lifetime: > 1000 years."); } else if (StationKeepingLifetime > 425000 && HoursInDay == 6) { GUILayout.Label("Station Keeping Fuel Lifetime: > 1000 years."); } else { if (StationKeepingLifetime > 425 && HoursInDay == 6) { GUILayout.Label("Station Keeping Fuel Lifetime: " + (StationKeepingLifetime / 425).ToString("F1") + " years."); } else if (StationKeepingLifetime > 365 && HoursInDay == 24) { GUILayout.Label("Station Keeping Fuel Lifetime: " + (StationKeepingLifetime / 365).ToString("F1") + " years."); } else { GUILayout.Label("Station Keeping Fuel Lifetime: " + StationKeepingLifetime.ToString("F1") + " days."); } } } GUILayout.Space(3); } if (GUILayout.Button(ButtonText)) { if (StationKeeping == "True") { VesselData.UpdateStationKeeping(vessel, false); ScreenMessages.PostScreenMessage("Vessel: " + vessel.vesselName + ": Station Keeping Disabled"); } if (StationKeeping == "False") { if (StationKeepingManager.EngineCheck(vessel)) { if (double.Parse(StationKeepingFuelRemaining) > 0.01) // Good enough... { VesselData.UpdateStationKeeping(vessel, true); ScreenMessages.PostScreenMessage("Vessel: " + vessel.vesselName + ": Station Keeping Enabled"); } else { ScreenMessages.PostScreenMessage("Vessel: " + vessel.vesselName + " has no fuel to Station Keep!"); } } else { ScreenMessages.PostScreenMessage("Vessel: " + vessel.vesselName + " has no Engines or RCS modules on board!"); } } } GUILayout.Space(2); GUILayout.Label("_____________________________________"); GUILayout.Space(3); GUILayout.EndVertical(); } } } GUILayout.EndScrollView(); }
public static List <Vector3d> InfluencingAccelerationsV(Vessel vessel, double time) { List <Vector3d> InfluencingAccelerations = new List <Vector3d>(); // Position at time foreach (CelestialBody Body in InfluencingBodiesV(vessel)) { double VesselMass = VesselData.FetchMass(vessel); #if false if (VesselMass == 0) // Incase vesselData hasnt caught up! { VesselMass = vessel.GetCorrectVesselMass() * 1000; } #endif double PhaseAngle = FindPhaseAngleBetweenObjects(vessel.orbit, Body.orbit); double InfluencingForce = 0; double BodyMass = Body.Mass; Vector3d BodyPosition = new Vector3d(); if (vessel.orbitDriver.orbit.referenceBody == Body || (vessel.orbitDriver.orbit.referenceBody == Body && Body == Sun.Instance.sun)) // Work out sun position later... { BodyPosition = new Vector3d(0, 0, 0); } else { if (Body == Sun.Instance.sun) { BodyPosition = new Vector3d(0, 0, 0); } else { BodyPosition = Body.orbit.getRelativePositionAtUT(time); } } double DistanceToVessel = Vector3d.Distance(Body.bodyTransform.position, vessel.vesselTransform.position); // Maybe but no time aspect //Vector3d.Distance(BodyPosition, vessel.orbitDriver.orbit.getRelativePositionAtUT(time)); // print("Body " + Body.name + " distance to " + vessel.name + " : " + DistanceToVessel); double BodyMNA = 0; try { // BodyMNA = (Body.orbitDriver.orbit.GetMeanAnomaly(Body.orbitDriver.orbit.E, time)); BodyMNA = OrbitalDecayUtilities.GetMeanAnomalyAtTime(Body.orbitDriver.orbit.meanAnomalyAtEpoch, Body.orbitDriver.orbit.epoch, Body.orbitDriver.orbit.period, time); } catch (NullReferenceException) { BodyMNA = 0; } double MNADifference = UtilMath.DegreesToRadians(PhaseAngle); // Fixed the phasing issues 1.6.0 //print("MNA Difference = " + MNADifference); //print("Distance to Vessel: " + vessel.name + " " + DistanceToVessel); InfluencingForce = (GravitationalConstant * BodyMass * VesselMass) / (DistanceToVessel * DistanceToVessel); InfluencingForce = InfluencingForce * Math.Cos(MNADifference); Vector3d InfluencingAccelerationBodyDirectionVector = new Vector3d(); if (vessel.orbitDriver.orbit.referenceBody == Body || (vessel.orbitDriver.orbit.referenceBody == Body && Body == Sun.Instance.sun)) { InfluencingAccelerationBodyDirectionVector = new Vector3d(0, 0, 0); } else { if (Body == Sun.Instance.sun) { InfluencingAccelerationBodyDirectionVector = Body.position; } else { InfluencingAccelerationBodyDirectionVector = Body.orbit.getRelativePositionAtUT(time); } } InfluencingAccelerationBodyDirectionVector = Body.transform.position; // Vector3d VesselRelativePositionVector = vessel.orbitDriver.orbit.getRelativePositionAtUT(time); VesselRelativePositionVector = vessel.transform.position; // Vector3d InfluencingAccelerationVector = (new Vector3d(-InfluencingAccelerationBodyDirectionVector.x + VesselRelativePositionVector.x, -InfluencingAccelerationBodyDirectionVector.y + VesselRelativePositionVector.y, -InfluencingAccelerationBodyDirectionVector.z + VesselRelativePositionVector.z)) * ((InfluencingForce / VesselMass)); // Always positive? InfluencingAccelerationVector = (new Vector3d(InfluencingAccelerationBodyDirectionVector.x - VesselRelativePositionVector.x, InfluencingAccelerationBodyDirectionVector.y - VesselRelativePositionVector.y, InfluencingAccelerationBodyDirectionVector.z - VesselRelativePositionVector.z)) * ((InfluencingForce / VesselMass)); // Better? //print("Accel Vector Magnitude: " + InfluencingAccelerationVector.magnitude); InfluencingAccelerations.Add(InfluencingAccelerationVector); } return(InfluencingAccelerations); }
public void ToggleSK() { VesselData.UpdateStationKeeping(vessel, VesselData.FetchStationKeeping(vessel)); stationKeepData.IsStationKeeping = !stationKeepData.IsStationKeeping; updatedisplayedData(); }
public override void OnUpdate() { if (stationKeepData.IsStationKeeping && vessel == FlightGlobals.ActiveVessel) { foreach (ModuleEngines module in vessel.FindPartModulesImplementing <ModuleEngines>()) { if (!(module.currentThrottle > 0)) { continue; } ScreenMessages.PostScreenMessage("Warning: Vessel is under thrust, station keeping disabled."); VesselData.UpdateStationKeeping(vessel, false); break; } } if (!(Time.time - lastUpdate > UPTInterval)) { return; } lastUpdate = Time.time; FetchEngineData(); List <string> namelist = new List <string>(); if (EngineData.HasNode("ENGINE")) { foreach (ConfigNode engine in EngineData.GetNodes("ENGINE")) { namelist.Add(engine.GetValue("name")); } EngineList = new string[namelist.Count]; EngineList = namelist.ToArray(); } else { EngineList = new string[] { "None Available" }; } updatedisplayedData(); for (int i = 0; i < stationKeepData.resources.Count(); i++) { float ratio1 = 10 * stationKeepData.ratios[i]; for (int j = 0; j < stationKeepData.resources.Count(); j++) { float ratio2 = 10 * stationKeepData.ratios[j]; if (stationKeepData.amounts[i] / ratio1 < stationKeepData.amounts[j] / ratio2) { stationKeepData.amounts[j] = stationKeepData.amounts[i] / ratio1 * ratio2; } /*equalizing fuel amount to comply with consumption ratios * without mutliplying ratios by 10 result is acurate only to 4th position after digital point * or 7th position in total for huge amounts of fuel * 179.999991330234 instead of 180 - tremendous error, i know ;) * tried casting double type to each variable in equasion * bu multiplying ratios seems to be only working solution * its a math issue/limitation encountered in multiple compilers * *************************************************************/ } } StationKeepResources = ""; amounts = ""; ISP = stationKeepData.ISP; StationKeepResources += stationKeepData.resources[0]; amounts += stationKeepData.amounts[0].ToString("F3"); for (int i = 1; i < stationKeepData.resources.Count(); i++) { StationKeepResources += ' ' + stationKeepData.resources[i]; amounts += ' ' + stationKeepData.amounts[i].ToString("F3"); } }
public void FetchEngineData() { double amount = 0; bool engineIsListed; EngineData.RemoveNodes("ENGINE"); foreach (ModuleEngines module in vessel.FindPartModulesImplementing <ModuleEngines>()) { engineIsListed = false; foreach (ConfigNode engineNode in EngineData.GetNodes()) { //ugly names used - can't find way to get editor part names if (engineNode.GetValue("name") != module.part.protoPartSnapshot.partInfo.title) { continue; } engineIsListed = true; break; } if (module.EngineIgnited && !engineIsListed) { ConfigNode engineNode = new ConfigNode("ENGINE"); engineNode.AddValue("name", module.part.protoPartSnapshot.partInfo.title);//ugly names used - can't find way to get editor part names engineNode.AddValue("ISP", module.atmosphereCurve.Evaluate(0).ToString()); foreach (Propellant propellant in module.propellants) { if (propellant.name == "ElectricCharge") { continue; } ConfigNode propellantNode = new ConfigNode("PROPELLANT"); //amount = module.part.Resources.Get(propellant.id).amount; amount = fetchPartResource(module.part, propellant.id, ResourceFlowMode.STAGE_PRIORITY_FLOW); propellantNode.AddValue("name", propellant.name); propellantNode.AddValue("id", propellant.id.ToString()); propellantNode.AddValue("ratio", propellant.ratio.ToString()); propellantNode.AddValue("Available", amount.ToString()); engineNode.AddNode(propellantNode); } EngineData.AddNode(engineNode); if (!stationKeepData.IsStationKeeping || !(module.currentThrottle > 0.0)) { continue; } ScreenMessages.PostScreenMessage("Warning: Vessel is under thrust, station keeping disabled."); VesselData.UpdateStationKeeping(vessel, false); } } foreach (ModuleRCS module in vessel.FindPartModulesImplementing <ModuleRCS>()) { engineIsListed = false; foreach (ConfigNode engineNode in EngineData.GetNodes()) { if (engineNode.GetValue("name") != module.part.protoPartSnapshot.partInfo.title) { continue; } engineIsListed = true; break; } if (!module.rcsEnabled || engineIsListed) { continue; } ConfigNode newEngineNode = new ConfigNode("ENGINE"); newEngineNode.AddValue("name", module.part.protoPartSnapshot.partInfo.title); newEngineNode.AddValue("ISP", module.atmosphereCurve.Evaluate(0).ToString()); foreach (Propellant propellant in module.propellants) { if (propellant.name == "ElectricCharge") { continue; } ConfigNode newPropellantNode = new ConfigNode("PROPELLANT"); //amount = module.part.Resources.Get(propellant.id).amount //amount = amount = fetchPartResource(module.part, propellant.id, ResourceFlowMode.STAGE_PRIORITY_FLOW); newPropellantNode.AddValue("name", propellant.name); newPropellantNode.AddValue("id", propellant.id.ToString()); newPropellantNode.AddValue("ratio", propellant.ratio.ToString()); newPropellantNode.AddValue("Available", amount.ToString()); newEngineNode.AddNode(newPropellantNode); } EngineData.AddNode(newEngineNode); } }
public static void FuelManager(Vessel vessel) { string ResourceName = ""; ResourceName = ResourceManager.GetResourceNames(vessel); double CurrentFuel = 0; CurrentFuel = ResourceManager.GetResources(vessel); double ResourceEfficiency = VesselData.FetchEfficiency(vessel);// effi calculation based on vessel engine ISP stored in stationKeepData.ISP NEED ballance double LostFuel = 0.0; LostFuel = Math.Abs(DecayManager.DecayRateAtmosphericDrag(vessel) + DecayManager.DecayRateRadiationPressure(vessel) + DecayManager.DecayRateYarkovskyEffect(vessel)) * Settings.ReadResourceRateDifficulty() * ResourceEfficiency; // * Fuel Multiplier double FuelNew = CurrentFuel - LostFuel; // Remote tech compatibility - 1.6.0 // bool RemoteTechInstalled = LoadingCheck.RemoteTechInstalled; bool SignalCheck = false; bool ConnectionToVessel = true; if (RemoteTechInstalled) { // Add Part Module Checks Here // Maybe 1.6.0 if (ConnectionToVessel == false) { SignalCheck = false; ScreenMessages.PostScreenMessage("Warning: " + vessel.vesselName + " has no connection to send Station Keeping command!"); VesselData.UpdateStationKeeping(vessel, false); } } else { SignalCheck = true; } if (!SignalCheck) { return; } if (EngineCheck(vessel) == false) // 1.3.0 { ScreenMessages.PostScreenMessage("Warning: " + vessel.vesselName + " has no operational Engines or RCS modules, Station Keeping disabled."); VesselData.UpdateStationKeeping(vessel, false); } else if (EngineCheck(vessel)) { if (FuelNew <= 0) { ScreenMessages.PostScreenMessage("Warning: " + vessel.vesselName + " has run out of " + ResourceName + ", Station Keeping disabled."); VesselData.UpdateStationKeeping(vessel, false); VesselData.UpdateVesselFuel(vessel, 0); } else { VesselData.UpdateVesselFuel(vessel, FuelNew); ResourceManager.RemoveResources(vessel, LostFuel); } } }