Ejemplo n.º 1
0
        private void DeactivateDeltaV(Vessel v)
        {
            if (!_settings.DisableStockDeltaV)
            {
                return;
            }

            if (v != FlightGlobals.ActiveVessel)
            {
                return;
            }

            if (v.isEVA)
            {
                return;
            }

            if (v.VesselDeltaV == null)
            {
                return;
            }

            _vesselDeltaV = v.VesselDeltaV;
            _vesselDeltaV.StopAllCoroutines();

            v.VesselDeltaV.enabled = false;

            if (_vesselDeltaVFlag != null)
            {
                _vesselDeltaVFlag.SetValue(_vesselDeltaV, true);
            }
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Calculate the burn time for a given vessel and delta V amount
 /// </summary>
 /// <param name="dvCalc">Stock delta V object from a vessel</param>
 /// <returns>
 /// null if not ready yet;
 /// PositiveInfinity if not enough fuel to do the burn;
 /// NaN if we can't burn at all;
 /// otherwise number of seconds required for the burn
 /// </returns>
 public double?Duration(VesselDeltaV dvCalc)
 {
     if (dvCalc != null && totalDeltaV > 0)
     {
         if (!dvCalc.IsReady)
         {
             return(null);
         }
         else if (totalDeltaV > dvCalc.TotalDeltaVActual)
         {
             return(double.PositiveInfinity);
         }
         else
         {
             double remaining = totalDeltaV;
             double t         = 0;
             for (int i = 0; i < dvCalc.OperatingStageInfo.Count; ++i)
             {
                 DeltaVStageInfo stg    = dvCalc.OperatingStageInfo[i];
                 double          exhVel = stg.ispActual * PhysicsGlobals.GravitationalAcceleration;
                 if (remaining >= stg.deltaVActual)
                 {
                     // We need to expend this whole stage, so just add its complete time
                     remaining -= stg.deltaVActual;
                     t         += stg.stageBurnTime;
                 }
                 else
                 {
                     // We only need part of this stage, so appeal to Tsiolkovsky
                     t += exhVel
                          * stg.startMass
                          * (1.0 - Math.Exp(-remaining / exhVel))
                          / stg.thrustActual;
                     break;
                 }
             }
             return(t);
         }
     }
     else
     {
         // No such burn
         return(double.NaN);
     }
 }
Ejemplo n.º 3
0
        private IEnumerator WaitForEditorShip()
        {
            while (EditorLogic.fetch == null)
            {
                yield return(null);
            }

            while (EditorLogic.fetch.ship == null)
            {
                yield return(null);
            }

            int timer = 0;

            while (EditorLogic.fetch.ship.vesselDeltaV == null)
            {
                timer++;

                if (timer > 120)
                {
                    yield break;
                }

                yield return(null);
            }

            _vesselDeltaV = EditorLogic.fetch.ship.vesselDeltaV;

            if (_vesselDeltaV.enabled)
            {
                _vesselDeltaV.StopAllCoroutines();
                _vesselDeltaV.enabled = false;
            }

            if (_vesselDeltaVFlag != null)
            {
                _vesselDeltaVFlag.SetValue(_vesselDeltaV, true);
            }
        }
Ejemplo n.º 4
0
        private IEnumerable <SmartTankPart> drainedTanks(VesselDeltaV dvCalc, int stageIndex)
        {
            for (int i = 0; i < dvCalc.PartInfo.Count; ++i)
            {
                DeltaVPartInfo pi = dvCalc.PartInfo[i];

                DeltaVPartInfo.PartStageFuelMass psfm = null;

                if (pi.part.Modules.Contains <SmartTankPart>() &&
                    pi.stageFuelMass.TryGetValue(stageIndex, out psfm))
                {
                    // The calculator doesn't give us an end mass of 0 for emptied tanks,
                    // nor end=start for untouched tanks (rounding errors?).
                    // So check whether it's more than half depleted.
                    // Mass of 0 indicates decoupling.
                    if (psfm.endMass < 0.5 * psfm.startMass && psfm.endMass > 0)
                    {
                        yield return(pi.part.Modules.GetModule <SmartTankPart>());
                    }
                }
            }
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Construct a whole-vessel deltaV calculator
 /// </summary>
 /// <param name="shared"></param>
 /// <param name="dv"></param>
 public DeltaVCalc(SharedObjects shared, VesselDeltaV dv)
 {
     this.shared = shared;
     shipDV      = dv;
     RegisterInitializer(InitializeSuffixes);
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Fires when the simulator is updated
        /// Populates the KSPFields for PP tanks so their PartModules can do the scaling
        /// </summary>
        private void OnSimUpdate(VesselDeltaV dvCalc)
        {
            if (dvCalc == null)
            {
                return;
            }
            if (Paused)
            {
                pausedDeltaV = dvCalc;
                return;
            }
            string nodesErr = "";

            getNodeStructureError(ref nodesErr);
            double totalMassChange = 0;

            for (int st = dvCalc.OperatingStageInfo.Count - 1; st >= 0; --st)
            {
                DeltaVStageInfo stage = dvCalc.OperatingStageInfo[st];

                List <SmartTankPart> drained = new List <SmartTankPart>(drainedTanks(dvCalc, stage.stage));
                int numTanks = drained.Count;

                if (stage != null && numTanks > 0)
                {
                    if (stage.thrustVac <= 0)
                    {
                        // No thrust on this stage, so fuel doesn't make sense either.
                        // Note that IdealTotalMass effectively is optional for the parts
                        // to obey; if AutoScale is false, they can ignore it.
                        for (int t = 0; t < numTanks; ++t)
                        {
                            // Reset all the tanks to minimum size with no thrust
                            drained[t].nodesError     = nodesErr;
                            drained[t].IdealTotalMass = 0;
                            if (drained[0].AutoScale)
                            {
                                totalMassChange -= partTotalMass(drained[t].part);
                            }
                        }
                    }
                    else
                    {
                        // This stage has thrust that we can balance against the fuel.

                        // Add up the current procedural tank mass
                        double currentProcTankMass = 0;
                        for (int t = 0; t < numTanks; ++t)
                        {
                            currentProcTankMass += partTotalMass(drained[t].part);
                        }

                        // Determine the mass that the procedural parts can't change
                        double nonProcMass = stage.startMass - currentProcTankMass + totalMassChange;

                        if (nonProcMass < 0)
                        {
                            // Sanity check, this is negative a lot
                            continue;
                        }

                        // Get the thrust this stage is configured to use
                        double thrust = drained[0].Atmospheric
                                                        ? stage.thrustASL
                                                        : stage.thrustVac;

                        // Calculate the mass to distribute among this stage's procedural tanks
                        // This includes their wet AND dry mass!
                        double targetProcTankMass = optimalTankMass(
                            thrust,
                            drained[0].bodyGravAccel,
                            drained[0].targetTWR,
                            nonProcMass
                            );

                        // Assume we'll have our way if auto scaling,
                        // otherwise use the existing mass
                        if (drained[0].AutoScale)
                        {
                            double massChange = targetProcTankMass > 0
                                                                ? targetProcTankMass - currentProcTankMass
                                                                : 0;
                            totalMassChange += massChange;
                        }

                        // Distribute the mass evenly
                        double massPerTank = targetProcTankMass / numTanks;
                        for (int t = 0; t < numTanks; ++t)
                        {
                            drained[t].nodesError     = nodesErr;
                            drained[t].IdealTotalMass = massPerTank;
                        }
                    }
                }
            }
        }