/// <summary> /// Calculate how long we can burn at full throttle until something important runs out. /// </summary> /// <param name="vessel"></param> /// <param name="propellantsConsumed"></param> /// <param name="propellantsAvailable"></param> /// <param name="maxBurnTime"></param> private static double CalculateMaxBurnTime(ShipState vessel, Tally propellantsConsumed) { double maxBurnTime = double.PositiveInfinity; Tally availableResources = vessel.AvailableResources; foreach (string resourceName in propellantsConsumed.Keys) { if (ShouldIgnore(resourceName)) { // ignore this for burn time, it's replenishable continue; } if (!availableResources.Has(resourceName)) { // we're all out! return(0.0); } double availableAmount = availableResources[resourceName]; double rate = propellantsConsumed[resourceName]; double burnTime = availableAmount / rate; if (burnTime < maxBurnTime) { maxBurnTime = burnTime; } } return(maxBurnTime); }
/// <summary> /// Get the vessel's acceleration ability, in m/s2 /// </summary> /// <param name="propellantsConsumed">All the propellants consumed, in tons/second for each one</param> /// <param name="totalThrust">The total thrust produced, in kilonewtons</param> private void GetThrustInfo( Tally propellantsConsumed, out double totalThrust) { // Add up all the thrust for all the active engines on the vessel. // We do this as a vector because the engines might not be parallel to each other. Vector3 totalThrustVector = Vector3.zero; totalThrust = 0.0F; propellantsConsumed.Zero(); Tally availableResources = vessel.AvailableResources; int engineCount = 0; for (int engineIndex = 0; engineIndex < vessel.ActiveEngines.Count; ++engineIndex) { ModuleEngines engine = vessel.ActiveEngines[engineIndex]; if (engine.thrustPercentage > 0) { double engineKilonewtons = engine.ThrustLimit(); if (!CheatOptions.InfinitePropellant) { // Possible future consideraiton: // Get the vacuum Isp from engine.atmosphereCurve.Evaluate(0), rather than ask // for engine.realIsp, because there may be mods that tinker with the atmosphere // curve, which changes the actual Isp that the game uses for vacuum without // updating engine.realIsp. double engineIsp = engine.realIsp; double engineTotalFuelConsumption = engineKilonewtons / (KERBIN_GRAVITY * engineIsp); // tons/sec double ratioSum = 0.0; bool isStarved = false; for (int propellantIndex = 0; propellantIndex < engine.propellants.Count; ++propellantIndex) { Propellant propellant = engine.propellants[propellantIndex]; if (!ShouldIgnore(propellant.name)) { if (!availableResources.Has(propellant.name)) { isStarved = true; break; } ratioSum += propellant.ratio; } } if (isStarved) { continue; } if (ratioSum > 0) { double ratio = 1.0 / ratioSum; for (int propellantIndex = 0; propellantIndex < engine.propellants.Count; ++propellantIndex) { Propellant propellant = engine.propellants[propellantIndex]; if (!ShouldIgnore(propellant.name)) { double consumptionRate = ratio * propellant.ratio * engineTotalFuelConsumption; // tons/sec propellantsConsumed.Add(propellant.name, consumptionRate); } } } } // if we need to worry about fuel ++engineCount; totalThrustVector += engine.Forward() * (float)engineKilonewtons; } // if the engine is operational } // for each engine module on the part totalThrust = totalThrustVector.magnitude; if (engineCount != lastEngineCount) { lastEngineCount = engineCount; Logging.Log(engineCount.ToString("Active engines: ##0")); } }