public string SuicideBurnCountdown()
        {
            if (orbit.PeA > 0)
            {
                return("N/A");
            }

            double angleFromHorizontal = 90 - Vector3d.Angle(-vesselState.velocityVesselSurface, vesselState.up);

            angleFromHorizontal = MuUtils.Clamp(angleFromHorizontal, 0, 90);
            double sine = Math.Sin(angleFromHorizontal * Math.PI / 180);
            double g    = vesselState.localg;
            double T    = vesselState.limitedMaxThrustAccel;

            double effectiveDecel = 0.5 * (-2 * g * sine + Math.Sqrt((2 * g * sine) * (2 * g * sine) + 4 * (T * T - g * g)));
            double decelTime      = vesselState.speedSurface / effectiveDecel;

            Vector3d estimatedLandingSite = vesselState.CoM + 0.5 * decelTime * vesselState.velocityVesselSurface;
            double   terrainRadius        = mainBody.Radius + mainBody.TerrainAltitude(estimatedLandingSite);
            double   impactTime           = 0;

            try
            {
                impactTime = orbit.NextTimeOfRadius(vesselState.time, terrainRadius);
            }
            catch (ArgumentException)
            {
                return(GuiUtils.TimeToDHMS(0));
            }
            return(GuiUtils.TimeToDHMS(impactTime - decelTime / 2 - vesselState.time));
        }
Beispiel #2
0
        public string TimeToImpact()
        {
            if (orbit.PeA > 0)
            {
                return("N/A");
            }

            double impactTime = vesselState.time;

            try
            {
                for (int iter = 0; iter < 10; iter++)
                {
                    Vector3d impactPosition = orbit.SwappedAbsolutePositionAtUT(impactTime);
                    double   terrainRadius  = mainBody.Radius + mainBody.TerrainAltitude(impactPosition);
                    impactTime = orbit.NextTimeOfRadius(vesselState.time, terrainRadius);
                }
            }
            catch (ArgumentException)
            {
                return(GuiUtils.TimeToDHMS(0));
            }


            return(GuiUtils.TimeToDHMS(impactTime - vesselState.time));
        }
Beispiel #3
0
 public string TargetOrbitPeriod()
 {
     if (!core.target.NormalTargetExists)
     {
         return("N/A");
     }
     return(GuiUtils.TimeToDHMS(core.target.TargetOrbit.period));
 }
Beispiel #4
0
 public string TargetEccentricity()
 {
     if (!core.target.NormalTargetExists)
     {
         return("N/A");
     }
     return(GuiUtils.TimeToDHMS(core.target.TargetOrbit.eccentricity));
 }
Beispiel #5
0
 public string TargetOrbitTimeToPe()
 {
     if (!core.target.NormalTargetExists)
     {
         return("N/A");
     }
     return(GuiUtils.TimeToDHMS(core.target.TargetOrbit.timeToPe));
 }
Beispiel #6
0
        public string TimeToManeuverNode()
        {
            if (!vessel.patchedConicsUnlocked() || !vessel.patchedConicSolver.maneuverNodes.Any())
            {
                return("N/A");
            }

            return(GuiUtils.TimeToDHMS(vessel.patchedConicSolver.maneuverNodes[0].UT - vesselState.time));
        }
Beispiel #7
0
        public string TimeToSOITransition()
        {
            if (orbit.patchEndTransition == Orbit.PatchTransitionType.FINAL)
            {
                return("N/A");
            }

            return(GuiUtils.TimeToDHMS(orbit.EndUT - vesselState.time));
        }
Beispiel #8
0
        public string TimeToEquatorialDescendingNode()
        {
            if (!orbit.DescendingNodeEquatorialExists())
            {
                return("N/A");
            }

            return(GuiUtils.TimeToDHMS(orbit.TimeOfDescendingNodeEquatorial(vesselState.time) - vesselState.time));
        }
Beispiel #9
0
 public string SuicideBurnCountdown()
 {
     try
     {
         return(GuiUtils.TimeToDHMS(OrbitExtensions.SuicideBurnCountdown(orbit, vesselState, vessel)));
     }
     catch
     {
         return("N/A");
     }
 }
        public string NextNodeCountdown()
        {
            if (!vessel.patchedConicsUnlocked() || !vessel.patchedConicSolver.maneuverNodes.Any())
            {
                return("-");
            }
            ManeuverNode node = vessel.patchedConicSolver.maneuverNodes.First();
            double       dV   = node.GetBurnVector(orbit).magnitude;

            return(GuiUtils.TimeToDHMS(node.UT - BurnTime(dV) * leadFraction - vesselState.time));
        }
        public string NextNodeBurnTime()
        {
            if (!vessel.patchedConicsUnlocked() || !vessel.patchedConicSolver.maneuverNodes.Any())
            {
                return("-");
            }
            ManeuverNode node = vessel.patchedConicSolver.maneuverNodes.First();
            double       dV   = node.GetBurnVector(orbit).magnitude;

            return(GuiUtils.TimeToDHMS(BurnTime(dV)));
        }
Beispiel #12
0
        public string NextManeuverNodeBurnTime()
        {
            if (!vessel.patchedConicsUnlocked() || !vessel.patchedConicSolver.maneuverNodes.Any())
            {
                return("N/A");
            }

            ManeuverNode node     = vessel.patchedConicSolver.maneuverNodes.First();
            double       burnTime = node.GetBurnVector(node.patch).magnitude / vesselState.limitedMaxThrustAccel;

            return(GuiUtils.TimeToDHMS(burnTime));
        }
 public string TargetTimeToClosestApproach()
 {
     if (!core.target.NormalTargetExists)
     {
         return("N/A");
     }
     if (core.target.Orbit.referenceBody != orbit.referenceBody)
     {
         return("N/A");
     }
     return(GuiUtils.TimeToDHMS(orbit.NextClosestApproachTime(core.target.Orbit, vesselState.time) - vesselState.time));
 }
Beispiel #14
0
 public string SynodicPeriod()
 {
     if (!core.target.NormalTargetExists)
     {
         return("N/A");
     }
     if (core.target.TargetOrbit.referenceBody != orbit.referenceBody)
     {
         return("N/A");
     }
     return(GuiUtils.TimeToDHMS(orbit.SynodicPeriod(core.target.TargetOrbit)));
 }
        public string NextNodeBurnTime()
        {
            if (!vessel.patchedConicsUnlocked() || vessel.patchedConicSolver.maneuverNodes.Count == 0)
            {
                return("-");
            }
            ManeuverNode node = vessel.patchedConicSolver.maneuverNodes[0];
            double       dV   = node.GetBurnVector(orbit).magnitude;
            double       halfBurnTIme;

            return(GuiUtils.TimeToDHMS(BurnTime(dV, out halfBurnTIme)));
        }
Beispiel #16
0
        override public void WindowGUI(int windowID)
        {
            base.preWindowGUI(windowID);
            base.WindowGUI(windowID);

            GUILayout.Label("Warp to: ", GUILayout.ExpandWidth(false));
            warpTarget = (WarpTarget)GuiUtils.ComboBox.Box((int)warpTarget, warpTargetStrings, this);

            if (warpTarget == WarpTarget.Time)
            {
                GUILayout.Label("Warp for: ", GUILayout.ExpandWidth(true));
                timeOffset.text = GUILayout.TextField(timeOffset.text, GUILayout.Width(100));
            }
            else if (warpTarget == WarpTarget.PhaseAngleT)
            {
                // I wonder if I should check for target that don't make sense
                if (!core.target.NormalTargetExists)
                {
                    GUILayout.Label("You need a target");
                }
                else
                {
                    GuiUtils.SimpleTextBox("Phase Angle:", phaseAngle, "º", 60);
                }
            }

            if (!warping)
            {
                GuiUtils.SimpleTextBox("Lead time: ", leadTime, "");
            }

            if (warping)
            {
                if (GUILayout.Button("Abort"))
                {
                    this.onAbord();
                }
            }

            if (warping)
            {
                GUILayout.Label("Warping to " + (leadTime > 0 ? GuiUtils.TimeToDHMS(leadTime) + " before " : "") + warpTargetStrings[(int)warpTarget] + ".");
            }

            if (this.isStarted() && !this.isExecuted() && this.startTime > 0)
            {
                GUILayout.Label(" waiting " + this.spendTime + "s");
            }
            base.postWindowGUI(windowID);
        }
        public string NextNodeCountdown()
        {
            if (!vessel.patchedConicsUnlocked() || !vessel.patchedConicSolver.maneuverNodes.Any())
            {
                return("-");
            }
            ManeuverNode node = vessel.patchedConicSolver.maneuverNodes.First();
            double       dV   = node.GetBurnVector(orbit).magnitude;
            double       halfBurnTIme;
            double       burnTIme = BurnTime(dV, out halfBurnTIme);

            if (double.IsInfinity(halfBurnTIme))
            {
                halfBurnTIme = 0.0;
            }
            return(GuiUtils.TimeToDHMS(node.UT - halfBurnTIme - vesselState.time));
        }
Beispiel #18
0
        public string TimeToDescendingNodeWithTarget()
        {
            if (!core.target.NormalTargetExists)
            {
                return("N/A");
            }
            if (core.target.TargetOrbit.referenceBody != orbit.referenceBody)
            {
                return("N/A");
            }
            if (!orbit.DescendingNodeExists(core.target.TargetOrbit))
            {
                return("N/A");
            }

            return(GuiUtils.TimeToDHMS(orbit.TimeOfDescendingNode(core.target.TargetOrbit, vesselState.time) - vesselState.time));
        }
Beispiel #19
0
        void DrawGUIPrediction()
        {
            ReentrySimulation.Result result = predictor.Result;
            if (result != null)
            {
                switch (result.outcome)
                {
                case ReentrySimulation.Outcome.LANDED:
                    GUILayout.Label("Landing Predictions:");
                    GUILayout.Label(Coordinates.ToStringDMS(result.endPosition.latitude, result.endPosition.longitude) + "\nASL:" + MuUtils.ToSI(result.endASL, -1, 4) + "m");
                    GUILayout.Label(result.body.GetExperimentBiomeSafe(result.endPosition.latitude, result.endPosition.longitude));
                    double error = Vector3d.Distance(mainBody.GetWorldSurfacePosition(result.endPosition.latitude, result.endPosition.longitude, 0) - mainBody.position,
                                                     mainBody.GetWorldSurfacePosition(core.target.targetLatitude, core.target.targetLongitude, 0) - mainBody.position);
                    GUILayout.Label("Target difference = " + MuUtils.ToSI(error, 0) + "m"
                                    + "\nMax drag: " + result.maxDragGees.ToString("F1") + "g"
                                    + "\nDelta-v needed: " + result.deltaVExpended.ToString("F1") + "m/s"
                                    + "\nTime to land: " + (vessel.Landed ? "0.0s" : GuiUtils.TimeToDHMS(result.endUT - Planetarium.GetUniversalTime(), 1)));
                    break;

                case ReentrySimulation.Outcome.AEROBRAKED:
                    GUILayout.Label("Predicted orbit after aerobraking:");
                    Orbit o = result.AeroBrakeOrbit();
                    if (o.eccentricity > 1)
                    {
                        GUILayout.Label("Hyperbolic, eccentricity = " + o.eccentricity.ToString("F2"));
                    }
                    else
                    {
                        GUILayout.Label(MuUtils.ToSI(o.PeA, 3) + "m x " + MuUtils.ToSI(o.ApA, 3) + "m");
                    }
                    GUILayout.Label("Max drag: " + result.maxDragGees.ToString("F1") + "g"
                                    + "\nExit atmosphere in: " + GuiUtils.TimeToDHMS(result.aeroBrakeUT - Planetarium.GetUniversalTime(), 1));
                    break;

                case ReentrySimulation.Outcome.NO_REENTRY:
                    GUILayout.Label("Orbit does not reenter:\n"
                                    + MuUtils.ToSI(orbit.PeA, 3) + "m Pe > " + MuUtils.ToSI(mainBody.RealMaxAtmosphereAltitude(), 3) + (mainBody.atmosphere ? "m atmosphere height" : "m ground"));
                    break;

                case ReentrySimulation.Outcome.TIMED_OUT:
                    GUILayout.Label("Reentry simulation timed out.");
                    break;
                }
            }
        }
Beispiel #20
0
        protected override void WindowGUI(int windowID)
        {
            GUILayout.BeginVertical();

            GUILayout.BeginHorizontal();
            GUILayout.Label("Warp to: ", GUILayout.ExpandWidth(false));
            warpTarget = (WarpTarget)GuiUtils.ArrowSelector((int)warpTarget, numWarpTargets, warpTargetStrings[(int)warpTarget]);
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();

            GuiUtils.SimpleTextBox("Lead time: ", leadTime, "");

            if (warping)
            {
                if (GUILayout.Button("Abort"))
                {
                    warping = false;
                    core.warp.MinimumWarp(true);
                }
            }
            else
            {
                if (GUILayout.Button("Warp"))
                {
                    warping = true;
                }
            }

            GUILayout.EndHorizontal();

            if (warping)
            {
                GUILayout.Label("Warping to " + (leadTime > 0 ? GuiUtils.TimeToDHMS(leadTime) + " before " : "") + warpTargetStrings[(int)warpTarget] + ".");
            }

            GUILayout.EndVertical();

            GUI.DragWindow();
        }
Beispiel #21
0
 public string TargetTimeToClosestApproach()
 {
     if (core.target.Target != null && vesselState.altitudeTrue < 1000.0)
     {
         return(GuiUtils.TimeToDHMS(GuiUtils.FromToETA(vessel.CoM, core.target.Transform.position)));
     }
     if (!core.target.NormalTargetExists)
     {
         return("N/A");
     }
     if (vesselState.altitudeTrue < 1000.0)
     {
         double a   = (vessel.mainBody.transform.position - vessel.transform.position).magnitude;
         double b   = (vessel.mainBody.transform.position - core.target.Transform.position).magnitude;
         double c   = Vector3d.Distance(vessel.transform.position, core.target.Position);
         double ang = Math.Acos(((a * a + b * b) - c * c) / (double)(2f * a * b));
         return(GuiUtils.TimeToDHMS(ang * vessel.mainBody.Radius / vesselState.speedSurfaceHorizontal));
     }
     if (!core.target.NormalTargetExists)
     {
         return("N/A");
     }
     if (vesselState.altitudeTrue < 1000.0)
     {
         double a   = (vessel.mainBody.transform.position - vessel.transform.position).magnitude;
         double b   = (vessel.mainBody.transform.position - core.target.Transform.position).magnitude;
         double c   = Vector3d.Distance(vessel.transform.position, core.target.Position);
         double ang = Math.Acos(((a * a + b * b) - c * c) / (double)(2f * a * b));
         return(GuiUtils.TimeToDHMS(ang * vessel.mainBody.Radius / vesselState.speedSurfaceHorizontal));
     }
     if (core.target.TargetOrbit.referenceBody != orbit.referenceBody)
     {
         return("N/A");
     }
     return(GuiUtils.TimeToDHMS(orbit.NextClosestApproachTime(core.target.TargetOrbit, vesselState.time) - vesselState.time));
 }
        string GetStringValue(object value)
        {
            if (value == null)
            {
                return("null");
            }

            if (value is string)
            {
                return((string)value + " " + units);
            }

            if (value is int)
            {
                return(((int)value).ToString() + " " + units);
            }

            double doubleValue = -999;

            if (value is double)
            {
                doubleValue = (double)value;
            }
            else if (value is float)
            {
                doubleValue = (float)value;
            }
            else if (value is MovingAverage)
            {
                doubleValue = (MovingAverage)value;
            }
            else if (value is Vector3d)
            {
                doubleValue = ((Vector3d)value).magnitude;
            }
            else if (value is Vector3)
            {
                doubleValue = ((Vector3)value).magnitude;
            }
            else if (value is EditableDouble)
            {
                doubleValue = (EditableDouble)value;
            }

            if (format == TIME)
            {
                return(GuiUtils.TimeToDHMS(doubleValue, timeDecimalPlaces));
            }
            else if (format == ANGLE)
            {
                return(Coordinates.AngleToDMS(doubleValue));
            }
            else if (format == ANGLE_NS)
            {
                return(Coordinates.AngleToDMS(doubleValue) + " " + (doubleValue > 0 ? "N" : "S"));
            }
            else if (format == ANGLE_EW)
            {
                return(Coordinates.AngleToDMS(doubleValue) + " " + (doubleValue > 0 ? "E" : "W"));
            }
            else if (format == SI)
            {
                return(MuUtils.ToSI(doubleValue, siMaxPrecision, siSigFigs) + units);
            }
            else
            {
                return(doubleValue.ToString(format) + " " + units);
            }
        }
Beispiel #23
0
        protected override void WindowGUI(int windowID)
        {
            if (!core.target.NormalTargetExists)
            {
                GUILayout.Label("Select a target to rendezvous with.");
                base.WindowGUI(windowID);
                return;
            }

            if (core.target.Orbit.referenceBody != orbit.referenceBody)
            {
                GUILayout.Label("Rendezvous target must be in the same sphere of influence.");
                base.WindowGUI(windowID);
                return;
            }

            GUILayout.BeginVertical();

            //Information readouts:

            GuiUtils.SimpleLabel("Rendezvous target", core.target.Name);

            double leadTime = 30;

            GuiUtils.SimpleLabel("Target orbit", MuUtils.ToSI(core.target.Orbit.PeA, 3) + "m x " + MuUtils.ToSI(core.target.Orbit.ApA, 3) + "m");
            GuiUtils.SimpleLabel("Current orbit", MuUtils.ToSI(orbit.PeA, 3) + "m x " + MuUtils.ToSI(orbit.ApA, 3) + "m");
            GuiUtils.SimpleLabel("Relative inclination", orbit.RelativeInclination(core.target.Orbit).ToString("F2") + "º");

            double closestApproachTime = orbit.NextClosestApproachTime(core.target.Orbit, vesselState.time);

            GuiUtils.SimpleLabel("Time until closest approach", GuiUtils.TimeToDHMS(closestApproachTime - vesselState.time));
            GuiUtils.SimpleLabel("Separation at closest approach", MuUtils.ToSI(orbit.Separation(core.target.Orbit, closestApproachTime), 0) + "m");


            //Maneuver planning buttons:

            if (GUILayout.Button("Align Planes"))
            {
                double   UT;
                Vector3d dV;
                if (orbit.AscendingNodeExists(core.target.Orbit))
                {
                    dV = OrbitalManeuverCalculator.DeltaVAndTimeToMatchPlanesAscending(orbit, core.target.Orbit, vesselState.time, out UT);
                }
                else
                {
                    dV = OrbitalManeuverCalculator.DeltaVAndTimeToMatchPlanesDescending(orbit, core.target.Orbit, vesselState.time, out UT);
                }
                vessel.RemoveAllManeuverNodes();
                vessel.PlaceManeuverNode(orbit, dV, UT);
            }


            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Establish new orbit at"))
            {
                double phasingOrbitRadius = phasingOrbitAltitude + mainBody.Radius;

                vessel.RemoveAllManeuverNodes();
                if (orbit.ApR < phasingOrbitRadius)
                {
                    double   UT1 = vesselState.time + leadTime;
                    Vector3d dV1 = OrbitalManeuverCalculator.DeltaVToChangeApoapsis(orbit, UT1, phasingOrbitRadius);
                    vessel.PlaceManeuverNode(orbit, dV1, UT1);
                    Orbit    transferOrbit = vessel.patchedConicSolver.maneuverNodes[0].nextPatch;
                    double   UT2           = transferOrbit.NextApoapsisTime(UT1);
                    Vector3d dV2           = OrbitalManeuverCalculator.DeltaVToCircularize(transferOrbit, UT2);
                    vessel.PlaceManeuverNode(transferOrbit, dV2, UT2);
                }
                else if (orbit.PeR > phasingOrbitRadius)
                {
                    double   UT1 = vesselState.time + leadTime;
                    Vector3d dV1 = OrbitalManeuverCalculator.DeltaVToChangePeriapsis(orbit, UT1, phasingOrbitRadius);
                    vessel.PlaceManeuverNode(orbit, dV1, UT1);
                    Orbit    transferOrbit = vessel.patchedConicSolver.maneuverNodes[0].nextPatch;
                    double   UT2           = transferOrbit.NextPeriapsisTime(UT1);
                    Vector3d dV2           = OrbitalManeuverCalculator.DeltaVToCircularize(transferOrbit, UT2);
                    vessel.PlaceManeuverNode(transferOrbit, dV2, UT2);
                }
                else
                {
                    double   UT = orbit.NextTimeOfRadius(vesselState.time, phasingOrbitRadius);
                    Vector3d dV = OrbitalManeuverCalculator.DeltaVToCircularize(orbit, UT);
                    vessel.PlaceManeuverNode(orbit, dV, UT);
                }
            }
            phasingOrbitAltitude.text = GUILayout.TextField(phasingOrbitAltitude.text, GUILayout.Width(70));
            GUILayout.Label("km", GUILayout.ExpandWidth(false));
            GUILayout.EndHorizontal();

            if (GUILayout.Button("Intercept with Hohmann transfer"))
            {
                double   UT;
                Vector3d dV = OrbitalManeuverCalculator.DeltaVAndTimeForHohmannTransfer(orbit, core.target.Orbit, vesselState.time, out UT);
                vessel.RemoveAllManeuverNodes();
                vessel.PlaceManeuverNode(orbit, dV, UT);
            }

            if (GUILayout.Button("Match velocities at closest approach"))
            {
                double   UT = closestApproachTime;
                Vector3d dV = OrbitalManeuverCalculator.DeltaVToMatchVelocities(orbit, UT, core.target.Orbit);
                vessel.RemoveAllManeuverNodes();
                vessel.PlaceManeuverNode(orbit, dV, UT);
            }

            if (GUILayout.Button("Get closer"))
            {
                double   UT          = vesselState.time;
                double   interceptUT = UT + 100;
                Vector3d dV          = OrbitalManeuverCalculator.DeltaVToInterceptAtTime(orbit, UT, core.target.Orbit, interceptUT, 10);
                vessel.RemoveAllManeuverNodes();
                vessel.PlaceManeuverNode(orbit, dV, UT);
            }

            GUILayout.EndVertical();

            base.WindowGUI(windowID);
        }
        protected override void WindowGUI(int windowID)
        {
            if (btNormal == null)
            {
                btNormal = new GUIStyle(GUI.skin.button);
                btNormal.normal.textColor   = btNormal.focused.textColor = Color.white;
                btNormal.hover.textColor    = btNormal.active.textColor = Color.yellow;
                btNormal.onNormal.textColor = btNormal.onFocused.textColor = btNormal.onHover.textColor = btNormal.onActive.textColor = Color.green;
                btNormal.padding            = new RectOffset(8, 8, 8, 8);

                btActive           = new GUIStyle(btNormal);
                btActive.active    = btActive.onActive;
                btActive.normal    = btActive.onNormal;
                btActive.onFocused = btActive.focused;
                btActive.hover     = btActive.onHover;
            }

            GUILayout.BeginVertical();

            if (autopilot != null)
            {
                if (autopilot.enabled)
                {
                    if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button1")))//Disengage autopilot
                    {
                        autopilot.users.Remove(this);
                    }
                }
                else
                {
                    if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button2")))//Engage autopilot
                    {
                        autopilot.users.Add(this);
                    }
                }
                if (ascentPathIdx == ascentType.PVG)
                {
                    if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button3")))//Reset Guidance (DO NOT PRESS)
                    {
                        core.guidance.Reset();
                    }


                    GUILayout.BeginHorizontal();                                                                                                                   // EditorStyles.toolbar);

                    if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button4"), autopilot.showTargeting ? btActive : btNormal, GUILayout.ExpandWidth(true))) //"TARG"
                    {
                        autopilot.showTargeting = !autopilot.showTargeting;
                    }
                    if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button5"), autopilot.showGuidanceSettings ? btActive : btNormal, GUILayout.ExpandWidth(true)))  //GUID
                    {
                        autopilot.showGuidanceSettings = !autopilot.showGuidanceSettings;
                    }
                    if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button6"), autopilot.showSettings ? btActive : btNormal, GUILayout.ExpandWidth(true)))  //OPTS
                    {
                        autopilot.showSettings = !autopilot.showSettings;
                    }
                    if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button7"), autopilot.showStatus ? btActive : btNormal, GUILayout.ExpandWidth(true)))  //STATUS
                    {
                        autopilot.showStatus = !autopilot.showStatus;
                    }
                    GUILayout.EndHorizontal();
                }
                else if (ascentPathIdx == ascentType.GRAVITYTURN)
                {
                    GUILayout.BeginHorizontal();                                                                                                                   // EditorStyles.toolbar);
                    if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button8"), autopilot.showTargeting ? btActive : btNormal, GUILayout.ExpandWidth(true))) //TARG
                    {
                        autopilot.showTargeting = !autopilot.showTargeting;
                    }
                    if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button9"), autopilot.showGuidanceSettings ? btActive : btNormal, GUILayout.ExpandWidth(true)))  //GUID
                    {
                        autopilot.showGuidanceSettings = !autopilot.showGuidanceSettings;
                    }
                    if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button10"), autopilot.showSettings ? btActive : btNormal, GUILayout.ExpandWidth(true)))  //OPTS
                    {
                        autopilot.showSettings = !autopilot.showSettings;
                    }
                    GUILayout.EndHorizontal();
                }
                else if (ascentPathIdx == ascentType.BREATHING_GT)
                {
                    GUILayout.BeginHorizontal();                                                                                                                   // EditorStyles.toolbar);
                    if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button8"), autopilot.showTargeting ? btActive : btNormal, GUILayout.ExpandWidth(true))) //TARG
                    {
                        autopilot.showTargeting = !autopilot.showTargeting;
                    }
                    if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button9"), autopilot.showGuidanceSettings ? btActive : btNormal, GUILayout.ExpandWidth(true)))//GUID
                    {
                        autopilot.showGuidanceSettings = !autopilot.showGuidanceSettings;
                    }
                    if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button10"), autopilot.showSettings ? btActive : btNormal, GUILayout.ExpandWidth(true)))//OPTS
                    {
                        autopilot.showSettings = !autopilot.showSettings;
                    }
                    GUILayout.EndHorizontal();
                }
                else if (ascentPathIdx == ascentType.CLASSIC)
                {
                    GUILayout.BeginHorizontal();                                                                                                                    // EditorStyles.toolbar);
                    if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button11"), autopilot.showTargeting ? btActive : btNormal, GUILayout.ExpandWidth(true))) //TARG
                    {
                        autopilot.showTargeting = !autopilot.showTargeting;
                    }
                    if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button12"), autopilot.showSettings ? btActive : btNormal, GUILayout.ExpandWidth(true)))  //OPTS
                    {
                        autopilot.showSettings = !autopilot.showSettings;
                    }
                    GUILayout.EndHorizontal();
                }

                if (autopilot.showTargeting)
                {
                    if (ascentPathIdx == ascentType.PVG)
                    {
                        GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label1"), autopilot.desiredOrbitAltitude, "km"); //Target Periapsis
                        GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label2"), pvgascent.desiredApoapsis, "km");      //Target Apoapsis:
                        if (pvgascent.desiredApoapsis >= 0 && pvgascent.desiredApoapsis < autopilot.desiredOrbitAltitude)
                        {
                            GUIStyle s = new GUIStyle(GUI.skin.label);
                            s.normal.textColor = Color.yellow;
                            GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label3"), s);//Ap < Pe: circularizing orbit
                        }
                        if (pvgascent.desiredApoapsis < 0)
                        {
                            GUIStyle s = new GUIStyle(GUI.skin.label);
                            s.normal.textColor = XKCDColors.Orange;
                            GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label4"), s);//Hyperbolic target orbit (neg Ap)
                        }
                    }
                    else
                    {
                        GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label5"), autopilot.desiredOrbitAltitude, "km");//Orbit altitude
                    }

                    GUIStyle si = new GUIStyle(GUI.skin.label);
                    if (Math.Abs(desiredInclination) < Math.Abs(vesselState.latitude) - 2.001)
                    {
                        si.onHover.textColor = si.onNormal.textColor = si.normal.textColor = XKCDColors.Orange;
                    }
                    GUILayout.BeginHorizontal();
                    GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label6"), si, GUILayout.ExpandWidth(true));//Orbit inc.
                    desiredInclination.text = GUILayout.TextField(desiredInclination.text, GUILayout.ExpandWidth(true), GUILayout.Width(100));
                    GUILayout.Label("º", GUILayout.ExpandWidth(false));
                    if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button13")))//Current
                    {
                        desiredInclination.val = vesselState.latitude;
                    }
                    GUILayout.EndHorizontal();
                    GUILayout.BeginHorizontal();
                    if (Math.Abs(desiredInclination) < Math.Abs(vesselState.latitude) - 2.001)
                    {
                        GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label7", Math.Abs(vesselState.latitude) - Math.Abs(desiredInclination)), si);//inc {0:F1}º below current latitude
                    }
                    GUILayout.EndHorizontal();
                    autopilot.desiredInclination = desiredInclination;
                }

                if (autopilot.showGuidanceSettings)
                {
                    if (ascentPathIdx == ascentType.GRAVITYTURN)
                    {
                        GUILayout.BeginVertical();

                        GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label8"), gtascent.turnStartAltitude, "km");     //Turn start altitude:
                        GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label9"), gtascent.turnStartVelocity, "m/s");    //Turn start velocity:
                        GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label10"), gtascent.turnStartPitch, "deg");      //Turn start pitch:
                        GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label11"), gtascent.intermediateAltitude, "km"); //Intermediate altitude:
                        GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label12"), gtascent.holdAPTime, "s");            //Hold AP Time:

                        GUILayout.EndVertical();
                    }
                    else if (ascentPathIdx == ascentType.BREATHING_GT)
                    {
                        GUILayout.BeginVertical();

                        //GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label8"), bgtascent.turnStartAltitude, "km");//Turn start altitude:
                        GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label9"), bgtascent.turnStartVelocity, "m/s");      //Turn start velocity:
                        GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label10"), bgtascent.turnStartPitch, "deg");        //Turn start pitch:
                        GuiUtils.SimpleTextBox(Localizer.Format("speed for breathing mode:"), bgtascent.startBreathingSpeed, "m/s"); //speed for breathing mode:
                        GuiUtils.SimpleTextBox(Localizer.Format("TWR to throttle other:"), bgtascent.minTWRthrottle, "s");           //TWR to throttle other:

                        GUILayout.EndVertical();
                    }
                    else if (ascentPathIdx == ascentType.PVG)
                    {
                        GUILayout.BeginVertical();
                        GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label13"), pvgascent.pitchStartVelocity, "m/s"); //Booster Pitch start:
                        GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label14"), pvgascent.pitchRate, "°/s");          //Booster Pitch rate:
                        GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label15"), core.guidance.pvgInterval, "s");      //Guidance Interval:
                        if (core.guidance.pvgInterval < 1 || core.guidance.pvgInterval > 30)
                        {
                            GUIStyle s = new GUIStyle(GUI.skin.label);
                            s.normal.textColor = Color.yellow;
                            GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label16"), s);                              //Guidance intervals are limited to between 1s and 30s
                        }
                        GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label17"), autopilot.limitQa, "Pa-rad"); //Qα limit
                        if (autopilot.limitQa < 100 || autopilot.limitQa > 4000)
                        {
                            GUIStyle s = new GUIStyle(GUI.skin.label);
                            s.normal.textColor = Color.yellow;

                            if (autopilot.limitQa < 100)
                            {
                                GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label18"), s);//Qα limit cannot be set to lower than 100 Pa-rad
                            }
                            else if (autopilot.limitQa > 10000)
                            {
                                GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label19"), s);//Qα limit cannot be set to higher than 10000 Pa-rad
                            }
                            else
                            {
                                GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label20"), s);//Qα limit is recommended to be 1000 to 4000 Pa-rad
                            }
                        }
                        pvgascent.omitCoast = GUILayout.Toggle(pvgascent.omitCoast, Localizer.Format("#MechJeb_Ascent_checkbox1"));//Omit Coast
                        GUILayout.EndVertical();
                    }
                }

                autopilot.limitQaEnabled = (ascentPathIdx == ascentType.PVG);    // this is mandatory for PVG

                if (autopilot.showSettings)
                {
                    ToggleAscentNavballGuidanceInfoItem();
                    if (ascentPathIdx != ascentType.PVG)
                    {
                        core.thrust.LimitToPreventOverheatsInfoItem();
                        //core.thrust.LimitToTerminalVelocityInfoItem();
                        core.thrust.LimitToMaxDynamicPressureInfoItem();
                        core.thrust.LimitAccelerationInfoItem();
                        core.thrust.LimitThrottleInfoItem();
                        core.thrust.LimiterMinThrottleInfoItem();
                        core.thrust.LimitElectricInfoItem();
                    }
                    else
                    {
                        core.thrust.LimitToPreventOverheatsInfoItem();
                        //core.thrust.LimitToTerminalVelocityInfoItem();
                        core.thrust.LimitToMaxDynamicPressureInfoItem();
                        //core.thrust.LimitAccelerationInfoItem();
                        //core.thrust.LimitThrottleInfoItem();
                        core.thrust.LimiterMinThrottleInfoItem();
                        //core.thrust.LimitElectricInfoItem();

                        GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label21")); //FIXME: g-limiter is down for maintenance
                        core.thrust.limitAcceleration       = false;
                        core.thrust.limitThrottle           = false;
                        core.thrust.limitToTerminalVelocity = false;
                        core.thrust.electricThrottle        = false;
                    }

                    GUILayout.BeginHorizontal();
                    autopilot.forceRoll = GUILayout.Toggle(autopilot.forceRoll, Localizer.Format("#MechJeb_Ascent_checkbox2"));//Force Roll
                    if (autopilot.forceRoll)
                    {
                        GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label22"), autopilot.verticalRoll, "º", 30f); //climb
                        GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label23"), autopilot.turnRoll, "º", 30f);     //turn
                    }
                    GUILayout.EndHorizontal();

                    if (ascentPathIdx != ascentType.PVG)
                    {
                        GUILayout.BeginHorizontal();
                        GUIStyle s = new GUIStyle(GUI.skin.toggle);
                        if (autopilot.limitingAoA)
                        {
                            s.onHover.textColor = s.onNormal.textColor = Color.green;
                        }
                        autopilot.limitAoA    = GUILayout.Toggle(autopilot.limitAoA, Localizer.Format("#MechJeb_Ascent_checkbox3"), s, GUILayout.ExpandWidth(true));//Limit AoA to
                        autopilot.maxAoA.text = GUILayout.TextField(autopilot.maxAoA.text, GUILayout.Width(30));
                        GUILayout.Label("º (" + autopilot.currentMaxAoA.ToString("F1") + "°)", GUILayout.ExpandWidth(true));
                        GUILayout.EndHorizontal();

                        GUILayout.BeginHorizontal();
                        GUILayout.Space(25);
                        if (autopilot.limitAoA)
                        {
                            GUIStyle sl = new GUIStyle(GUI.skin.label);
                            if (autopilot.limitingAoA && vesselState.dynamicPressure < autopilot.aoALimitFadeoutPressure)
                            {
                                sl.normal.textColor = sl.hover.textColor = Color.green;
                            }
                            GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Ascent_label24"), autopilot.aoALimitFadeoutPressure, "Pa", 50, sl);//Dynamic Pressure Fadeout
                        }
                        GUILayout.EndHorizontal();
                        autopilot.limitQaEnabled = false; // this is only for PVG
                    }

                    if (ascentPathIdx == ascentType.CLASSIC)
                    {
                        // corrective steering only applies to Classic
                        GUILayout.BeginHorizontal();
                        autopilot.correctiveSteering = GUILayout.Toggle(autopilot.correctiveSteering, Localizer.Format("#MechJeb_Ascent_checkbox4"), GUILayout.ExpandWidth(false));//Corrective steering
                        if (autopilot.correctiveSteering)
                        {
                            GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label25"), GUILayout.ExpandWidth(false));//Gain
                            autopilot.correctiveSteeringGain.text = GUILayout.TextField(autopilot.correctiveSteeringGain.text, GUILayout.Width(40));
                        }
                        GUILayout.EndHorizontal();
                    }

                    autopilot.autostage = GUILayout.Toggle(autopilot.autostage, Localizer.Format("#MechJeb_Ascent_checkbox5"));//Autostage
                    if (autopilot.autostage)
                    {
                        core.staging.AutostageSettingsInfoItem();
                    }

                    autopilot.autodeploySolarPanels = GUILayout.Toggle(autopilot.autodeploySolarPanels,
                                                                       Localizer.Format("#MechJeb_Ascent_checkbox6"));//Auto-deploy solar panels

                    autopilot.autoDeployAntennas = GUILayout.Toggle(autopilot.autoDeployAntennas,
                                                                    Localizer.Format("#MechJeb_Ascent_checkbox7"));//Auto-deploy antennas

                    GUILayout.BeginHorizontal();
                    core.node.autowarp = GUILayout.Toggle(core.node.autowarp, Localizer.Format("#MechJeb_Ascent_checkbox8"));//Auto-warp
                    if (ascentPathIdx != ascentType.PVG)
                    {
                        autopilot.skipCircularization = GUILayout.Toggle(autopilot.skipCircularization, Localizer.Format("#MechJeb_Ascent_checkbox9"));//Skip Circularization
                    }
                    else
                    {
                        // skipCircularization is always true for Optimizer
                        autopilot.skipCircularization = true;
                    }
                    GUILayout.EndHorizontal();
                }

                if (autopilot.showStatus)
                {
                    if (ascentPathIdx == ascentType.PVG)
                    {
                        if (core.guidance.solution != null)
                        {
                            for (int i = core.guidance.solution.num_segments; i > 0; i--)
                            {
                                GUILayout.Label(String.Format("{0}: {1}", i, core.guidance.solution.ArcString(vesselState.time, i - 1)));
                            }
                        }

                        GUILayout.BeginHorizontal();
                        GUILayout.Label(String.Format("vgo: {0:F1}", core.guidance.vgo), GUILayout.Width(100));
                        GUILayout.Label(String.Format("heading: {0:F1}", core.guidance.heading), GUILayout.Width(100));
                        GUILayout.EndHorizontal();
                        GUILayout.BeginHorizontal();
                        GUILayout.Label(String.Format("tgo: {0:F3}", core.guidance.tgo), GUILayout.Width(100));
                        GUILayout.Label(String.Format("pitch: {0:F1}", core.guidance.pitch), GUILayout.Width(100));
                        GUILayout.EndHorizontal();
                        GUILayout.BeginHorizontal();
                        GUIStyle si = new GUIStyle(GUI.skin.label);
                        if (core.guidance.isStable())
                        {
                            si.onHover.textColor = si.onNormal.textColor = si.normal.textColor = XKCDColors.Green;
                        }
                        else if (core.guidance.isInitializing() || core.guidance.status == PVGStatus.FINISHED)
                        {
                            si.onHover.textColor = si.onNormal.textColor = si.normal.textColor = XKCDColors.Orange;
                        }
                        else
                        {
                            si.onHover.textColor = si.onNormal.textColor = si.normal.textColor = XKCDColors.Red;
                        }
                        GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label26") + core.guidance.status, si);//Guidance Status:
                        GUILayout.EndHorizontal();
                        GUILayout.BeginHorizontal();
                        GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label27") + core.guidance.successful_converges, GUILayout.Width(100)); //converges:
                        GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label28") + core.guidance.last_lm_status, GUILayout.Width(100));       //status:
                        GUILayout.EndHorizontal();
                        GUILayout.BeginHorizontal();
                        GUILayout.Label("n: " + core.guidance.last_lm_iteration_count + "(" + core.guidance.max_lm_iteration_count + ")", GUILayout.Width(100));
                        GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label29") + GuiUtils.TimeToDHMS(core.guidance.staleness));//staleness:
                        GUILayout.EndHorizontal();
                        GUILayout.BeginHorizontal();
                        GUILayout.Label(String.Format("znorm: {0:G5}", core.guidance.last_znorm));
                        GUILayout.EndHorizontal();
                        if (core.guidance.last_failure_cause != null)
                        {
                            GUIStyle s = new GUIStyle(GUI.skin.label);
                            s.normal.textColor = Color.red;
                            GUILayout.BeginHorizontal();
                            GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label30") + core.guidance.last_failure_cause, s);//LAST FAILURE:
                            GUILayout.EndHorizontal();
                        }

                        if (vessel.situation != Vessel.Situations.LANDED && vessel.situation != Vessel.Situations.PRELAUNCH && vessel.situation != Vessel.Situations.SPLASHED)
                        {
                            double m0     = atmoStats[vessel.currentStage].startMass;
                            double thrust = atmoStats[vessel.currentStage].startThrust;

                            if (Math.Abs(vesselState.mass - m0) / m0 > 0.01)
                            {
                                GUIStyle s = new GUIStyle(GUI.skin.label);
                                s.normal.textColor = Color.yellow;
                                GUILayout.BeginHorizontal();
                                GUILayout.Label(String.Format(Localizer.Format("#MechJeb_Ascent_label31") + "{0:F1}%", (vesselState.mass - m0) / m0 * 100.0), s);//MASS IS OFF BY
                                GUILayout.EndHorizontal();
                            }

                            if (Math.Abs(vesselState.thrustCurrent - thrust) / thrust > 0.01)
                            {
                                GUIStyle s = new GUIStyle(GUI.skin.label);
                                s.normal.textColor = Color.yellow;
                                GUILayout.BeginHorizontal();
                                GUILayout.Label(String.Format(Localizer.Format("#MechJeb_Ascent_label32") + "{0:F1}%", (vesselState.thrustCurrent - thrust) / thrust * 100.0), s);//THRUST IS OFF BY
                                GUILayout.EndHorizontal();
                            }
                        }
                    }
                }

                if (vessel.LandedOrSplashed)
                {
                    if (core.target.NormalTargetExists)
                    {
                        if (core.node.autowarp)
                        {
                            GUILayout.BeginHorizontal();
                            GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label33"), GUILayout.ExpandWidth(true));    //Launch countdown:
                            autopilot.warpCountDown.text = GUILayout.TextField(autopilot.warpCountDown.text,
                                                                               GUILayout.Width(60));
                            GUILayout.Label("s", GUILayout.ExpandWidth(false));
                            GUILayout.EndHorizontal();
                        }
                        if (!launchingToPlane && !launchingToRendezvous && !launchingToInterplanetary)
                        {
                            // disable plane/rendezvous/interplanetary for now
                            if (ascentPathIdx != ascentType.PVG)
                            {
                                GUILayout.BeginHorizontal();
                                if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button14"), GUILayout.ExpandWidth(false)))    //Launch to rendezvous:
                                {
                                    launchingToRendezvous = true;
                                    autopilot.StartCountdown(vesselState.time +
                                                             LaunchTiming.TimeToPhaseAngle(autopilot.launchPhaseAngle,
                                                                                           mainBody, vesselState.longitude, core.target.TargetOrbit));
                                }
                                autopilot.launchPhaseAngle.text = GUILayout.TextField(autopilot.launchPhaseAngle.text,
                                                                                      GUILayout.Width(60));
                                GUILayout.Label("º", GUILayout.ExpandWidth(false));
                                GUILayout.EndHorizontal();
                            }

                            GUILayout.BeginHorizontal();
                            if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button15"), GUILayout.ExpandWidth(false)))    //Launch into plane of target
                            {
                                launchingToPlane = true;

                                autopilot.StartCountdown(vesselState.time +
                                                         LaunchTiming.TimeToPlane(autopilot.launchLANDifference,
                                                                                  mainBody, vesselState.latitude, vesselState.longitude,
                                                                                  core.target.TargetOrbit));
                            }
                            autopilot.launchLANDifference.text = GUILayout.TextField(
                                autopilot.launchLANDifference.text, GUILayout.Width(60));
                            GUILayout.Label("º", GUILayout.ExpandWidth(false));
                            GUILayout.EndHorizontal();

                            if (core.target.TargetOrbit.referenceBody == orbit.referenceBody.referenceBody)
                            {
                                if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button16")))    //Launch at interplanetary window
                                {
                                    launchingToInterplanetary = true;
                                    //compute the desired launch date
                                    OrbitalManeuverCalculator.DeltaVAndTimeForHohmannTransfer(mainBody.orbit,
                                                                                              core.target.TargetOrbit, vesselState.time, out interplanetaryWindowUT);
                                    double desiredOrbitPeriod = 2 * Math.PI *
                                                                Math.Sqrt(
                                        Math.Pow(mainBody.Radius + autopilot.desiredOrbitAltitude, 3)
                                        / mainBody.gravParameter);
                                    //launch just before the window, but don't try to launch in the past
                                    interplanetaryWindowUT -= 3 * desiredOrbitPeriod;
                                    interplanetaryWindowUT  = Math.Max(vesselState.time + autopilot.warpCountDown,
                                                                       interplanetaryWindowUT);
                                    autopilot.StartCountdown(interplanetaryWindowUT);
                                }
                            }
                        }
                    }
                    else
                    {
                        launchingToInterplanetary = launchingToPlane = launchingToRendezvous = false;
                        GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label34"));    //Select a target for a timed launch.
                    }

                    if (launchingToInterplanetary || launchingToPlane || launchingToRendezvous)
                    {
                        string message = "";
                        if (launchingToInterplanetary)
                        {
                            message = Localizer.Format("#MechJeb_Ascent_msg1");    //Launching at interplanetary window
                        }
                        else if (launchingToPlane)
                        {
                            desiredInclination  = MuUtils.Clamp(core.target.TargetOrbit.inclination, Math.Abs(vesselState.latitude), 180 - Math.Abs(vesselState.latitude));
                            desiredInclination *=
                                Math.Sign(Vector3d.Dot(core.target.TargetOrbit.SwappedOrbitNormal(),
                                                       Vector3d.Cross(vesselState.CoM - mainBody.position, mainBody.transform.up)));
                            message = Localizer.Format("#MechJeb_Ascent_msg2");    //Launching to target plane
                        }
                        else if (launchingToRendezvous)
                        {
                            message = "#MechJeb_Ascent_msg3";    //Launching to rendezvous
                        }

                        if (autopilot.tMinus > 3 * vesselState.deltaT)
                        {
                            message += ": T-" + GuiUtils.TimeToDHMS(autopilot.tMinus, 1);
                        }

                        GUILayout.Label(message);

                        if (GUILayout.Button(Localizer.Format("#MechJeb_Ascent_button17")))//Abort
                        {
                            launchingToInterplanetary =
                                launchingToPlane      = launchingToRendezvous = autopilot.timedLaunch = false;
                        }
                    }
                }

                if (autopilot.enabled)
                {
                    GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label35") + autopilot.status);//Autopilot status:
                }
                if (core.DeactivateControl)
                {
                    GUIStyle s = new GUIStyle(GUI.skin.label);
                    s.normal.textColor = Color.red;
                    GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label36"), s);//CONTROL DISABLED (AVIONICS)
                }
            }

            if (!vessel.patchedConicsUnlocked() && ascentPathIdx != ascentType.PVG)
            {
                GUILayout.Label(Localizer.Format("#MechJeb_Ascent_label37"));//"Warning: MechJeb is unable to circularize without an upgraded Tracking Station."
            }

            GUILayout.BeginHorizontal();
            autopilot.ascentPathIdxPublic = (ascentType)GuiUtils.ComboBox.Box((int)autopilot.ascentPathIdxPublic, autopilot.ascentPathList, this);
            GUILayout.EndHorizontal();

            if (autopilot.ascentMenu != null)
            {
                autopilot.ascentMenu.enabled = GUILayout.Toggle(autopilot.ascentMenu.enabled, Localizer.Format("#MechJeb_Ascent_checkbox10"));                              //Edit ascent path
            }
            GUILayout.EndVertical();

            base.WindowGUI(windowID);
        }
        protected override void WindowGUI(int windowID)
        {
            GUILayout.BeginVertical();

            bool showingGuidance = (core.target.Target != null && core.target.Name == TARGET_NAME);

            if (showingGuidance)
            {
                GUILayout.Label("The purple circle on the navball points along the ascent path.");
                if (GUILayout.Button("Stop showing navball guidance"))
                {
                    core.target.Unset();
                }
            }
            else if (GUILayout.Button("Show navball ascent path guidance"))
            {
                core.target.SetDirectionTarget(TARGET_NAME);
            }

            if (autopilot != null)
            {
                if (autopilot.enabled)
                {
                    if (GUILayout.Button("Disengage autopilot"))
                    {
                        autopilot.users.Remove(this);
                    }
                }
                else
                {
                    if (GUILayout.Button("Engage autopilot"))
                    {
                        autopilot.users.Add(this);
                    }
                }

                ascentPath = autopilot.ascentPath;

                GuiUtils.SimpleTextBox("Orbit altitude", autopilot.desiredOrbitAltitude, "km");
                autopilot.desiredInclination = desiredInclination;
            }

            GuiUtils.SimpleTextBox("Orbit inclination", desiredInclination, "º");

            core.thrust.LimitToPreventOverheatsInfoItem();
            core.thrust.LimitToTerminalVelocityInfoItem();
            core.thrust.LimitAccelerationInfoItem();
            core.thrust.LimitThrottleInfoItem();
            GUILayout.BeginHorizontal();
            autopilot.forceRoll = GUILayout.Toggle(autopilot.forceRoll, "Force Roll");
            if (autopilot.forceRoll)
            {
                GuiUtils.SimpleTextBox("climb", autopilot.verticalRoll, "º", 30f);
                GuiUtils.SimpleTextBox("turn", autopilot.turnRoll, "º", 30f);
            }
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUIStyle s = new GUIStyle(GUI.skin.toggle);

            if (autopilot.limitingAoA)
            {
                s.onHover.textColor = s.onNormal.textColor = Color.green;
            }
            autopilot.limitAoA    = GUILayout.Toggle(autopilot.limitAoA, "Limit AoA to", s, GUILayout.ExpandWidth(true));
            autopilot.maxAoA.text = GUILayout.TextField(autopilot.maxAoA.text, GUILayout.Width(30));
            GUILayout.Label("º (" + autopilot.currentMaxAoA.ToString("F1") + "°)", GUILayout.ExpandWidth(true));
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Space(25);
            if (autopilot.limitAoA)
            {
                GUIStyle sl = new GUIStyle(GUI.skin.label);
                if (autopilot.limitingAoA && vesselState.dynamicPressure < autopilot.aoALimitFadeoutPressure)
                {
                    sl.normal.textColor = sl.hover.textColor = Color.green;
                }
                GuiUtils.SimpleTextBox("Dynamic Pressure Fadeout", autopilot.aoALimitFadeoutPressure, "pa", 50, sl);
            }
            GUILayout.EndHorizontal();

            autopilot.correctiveSteering = GUILayout.Toggle(autopilot.correctiveSteering, "Corrective steering");

            autopilot.autostage = GUILayout.Toggle(autopilot.autostage, "Autostage");
            if (autopilot.autostage)
            {
                core.staging.AutostageSettingsInfoItem();
            }

            autopilot.autodeploySolarPanels = GUILayout.Toggle(autopilot.autodeploySolarPanels, "Auto-deploy solar panels");

            core.node.autowarp = GUILayout.Toggle(core.node.autowarp, "Auto-warp");

            if (autopilot != null && vessel.LandedOrSplashed)
            {
                if (core.target.NormalTargetExists)
                {
                    if (core.node.autowarp)
                    {
                        GUILayout.BeginHorizontal();
                        GUILayout.Label("Launch countdown:", GUILayout.ExpandWidth(true));
                        autopilot.warpCountDown.text = GUILayout.TextField(autopilot.warpCountDown.text, GUILayout.Width(60));
                        GUILayout.Label("s", GUILayout.ExpandWidth(false));
                        GUILayout.EndHorizontal();
                    }
                    if (!launchingToPlane && !launchingToRendezvous && !launchingToInterplanetary)
                    {
                        GUILayout.BeginHorizontal();
                        if (GUILayout.Button("Launch to rendezvous:", GUILayout.ExpandWidth(false)))
                        {
                            launchingToRendezvous = true;
                            autopilot.StartCountdown(vesselState.time + LaunchTiming.TimeToPhaseAngle(autopilot.launchPhaseAngle, mainBody, vesselState.longitude, core.target.TargetOrbit));
                        }
                        autopilot.launchPhaseAngle.text = GUILayout.TextField(autopilot.launchPhaseAngle.text, GUILayout.Width(60));
                        GUILayout.Label("º", GUILayout.ExpandWidth(false));
                        GUILayout.EndHorizontal();

                        if (GUILayout.Button("Launch into plane of target"))
                        {
                            launchingToPlane = true;
                            autopilot.StartCountdown(vesselState.time +
                                                     LaunchTiming.TimeToPlane(mainBody, vesselState.latitude, vesselState.longitude, core.target.TargetOrbit));
                        }
                        if (core.target.TargetOrbit.referenceBody == orbit.referenceBody.referenceBody)
                        {
                            if (GUILayout.Button("Launch at interplanetary window"))
                            {
                                launchingToInterplanetary = true;
                                //compute the desired launch date
                                OrbitalManeuverCalculator.DeltaVAndTimeForHohmannTransfer(mainBody.orbit, core.target.TargetOrbit, vesselState.time, out interplanetaryWindowUT);
                                double desiredOrbitPeriod = 2 * Math.PI * Math.Sqrt(Math.Pow(mainBody.Radius + autopilot.desiredOrbitAltitude, 3) / mainBody.gravParameter);
                                //launch just before the window, but don't try to launch in the past
                                interplanetaryWindowUT -= 3 * desiredOrbitPeriod;
                                interplanetaryWindowUT  = Math.Max(vesselState.time + autopilot.warpCountDown, interplanetaryWindowUT);
                                autopilot.StartCountdown(interplanetaryWindowUT);
                            }
                        }
                    }
                }
                else
                {
                    launchingToInterplanetary = launchingToPlane = launchingToRendezvous = false;
                    GUILayout.Label("Select a target for a timed launch.");
                }

                if (launchingToInterplanetary || launchingToPlane || launchingToRendezvous)
                {
                    string message = "";
                    if (launchingToInterplanetary)
                    {
                        message = "Launching at interplanetary window";
                    }
                    else if (launchingToPlane)
                    {
                        desiredInclination  = core.target.TargetOrbit.inclination;
                        desiredInclination *= Math.Sign(Vector3d.Dot(core.target.TargetOrbit.SwappedOrbitNormal(), Vector3d.Cross(vesselState.CoM - mainBody.position, mainBody.transform.up)));
                        message             = "Launching to target plane";
                    }
                    else if (launchingToRendezvous)
                    {
                        message = "Launching to rendezvous";
                    }

                    if (autopilot.tMinus > 3 * vesselState.deltaT)
                    {
                        message += ": T-" + GuiUtils.TimeToDHMS(autopilot.tMinus, 1);
                    }

                    GUILayout.Label(message);

                    if (GUILayout.Button("Abort"))
                    {
                        launchingToInterplanetary = launchingToPlane = launchingToRendezvous = autopilot.timedLaunch = false;
                    }
                }
            }

            if (autopilot != null && autopilot.enabled)
            {
                GUILayout.Label("Autopilot status: " + autopilot.status);
            }

            if (!vessel.patchedConicsUnlocked())
            {
                GUILayout.Label("Warning: MechJeb is unable to circularize without an upgraded Tracking Station.");
            }

            MechJebModuleAscentPathEditor editor = core.GetComputerModule <MechJebModuleAscentPathEditor>();

            if (editor != null)
            {
                editor.enabled = GUILayout.Toggle(editor.enabled, "Edit ascent path");
            }

            GUILayout.EndVertical();

            base.WindowGUI(windowID);
        }
Beispiel #26
0
 public EditableTime(double seconds)
     : base(seconds)
 {
     _text = GuiUtils.TimeToDHMS(seconds);
 }
        protected override void WindowGUI(int windowID)
        {
            if (!core.target.NormalTargetExists)
            {
                GUILayout.Label("Select a target to rendezvous with.");
                base.WindowGUI(windowID);
                return;
            }

            if (core.target.Orbit.referenceBody != orbit.referenceBody)
            {
                GUILayout.Label("Rendezvous target must be in the same sphere of influence.");
                base.WindowGUI(windowID);
                return;
            }

            GUILayout.BeginVertical();

            step = (Step)GuiUtils.ArrowSelector((int)step, numSteps, stepStrings[(int)step]);

            double leadTime = 30;

            switch (step)
            {
            case Step.AlignPlanes:

                GUILayout.Label("First, bring your relative inclination to zero by aligning your orbital plane with the target's orbital plane:");
                GUILayout.Label("Relative inclination: " + orbit.RelativeInclination(core.target.Orbit).ToString("F2") + "º");

                if (GUILayout.Button("Align Planes"))
                {
                    double   UT;
                    Vector3d dV;
                    if (orbit.AscendingNodeExists(core.target.Orbit))
                    {
                        dV = OrbitalManeuverCalculator.DeltaVAndTimeToMatchPlanesAscending(orbit, core.target.Orbit, vesselState.time, out UT);
                    }
                    else
                    {
                        dV = OrbitalManeuverCalculator.DeltaVAndTimeToMatchPlanesDescending(orbit, core.target.Orbit, vesselState.time, out UT);
                    }
                    vessel.PlaceManeuverNode(orbit, dV, UT);
                }
                break;

            case Step.PhasingOrbit:

                double phasingOrbitRadius = 0.9 * core.target.Orbit.PeR;
                if (phasingOrbitRadius < orbit.referenceBody.Radius + orbit.referenceBody.RealMaxAtmosphereAltitude())
                {
                    phasingOrbitRadius = 1.1 * core.target.Orbit.ApR;
                }
                double phasingOrbitAltitude = phasingOrbitRadius - mainBody.Radius;
                GUILayout.Label("Next, establish a circular phasing orbit close to the target orbit.");
                GUILayout.Label("Target orbit: " + MuUtils.ToSI(core.target.Orbit.PeA, 3) + "m x " + MuUtils.ToSI(core.target.Orbit.ApA, 3) + "m");
                GUILayout.Label("Suggested phasing orbit: " + MuUtils.ToSI(phasingOrbitAltitude, 3) + "m x " + MuUtils.ToSI(phasingOrbitAltitude, 3) + "m");
                GUILayout.Label("Current orbit: " + MuUtils.ToSI(orbit.PeA, 3) + "m x " + MuUtils.ToSI(orbit.ApA, 3) + "m");

                if (GUILayout.Button("Establish Phasing Orbit"))
                {
                    if (orbit.ApR < phasingOrbitRadius)
                    {
                        double   UT1 = vesselState.time + leadTime;
                        Vector3d dV1 = OrbitalManeuverCalculator.DeltaVToChangeApoapsis(orbit, UT1, phasingOrbitRadius);
                        vessel.PlaceManeuverNode(orbit, dV1, UT1);
                        Orbit    transferOrbit = vessel.patchedConicSolver.maneuverNodes[0].nextPatch;
                        double   UT2           = transferOrbit.NextApoapsisTime(UT1);
                        Vector3d dV2           = OrbitalManeuverCalculator.DeltaVToCircularize(transferOrbit, UT2);
                        vessel.PlaceManeuverNode(transferOrbit, dV2, UT2);
                    }
                    else if (orbit.PeR > phasingOrbitRadius)
                    {
                        double   UT1 = vesselState.time + leadTime;
                        Vector3d dV1 = OrbitalManeuverCalculator.DeltaVToChangePeriapsis(orbit, UT1, phasingOrbitRadius);
                        vessel.PlaceManeuverNode(orbit, dV1, UT1);
                        Orbit    transferOrbit = vessel.patchedConicSolver.maneuverNodes[0].nextPatch;
                        double   UT2           = transferOrbit.NextPeriapsisTime(UT1);
                        Vector3d dV2           = OrbitalManeuverCalculator.DeltaVToCircularize(transferOrbit, UT2);
                        vessel.PlaceManeuverNode(transferOrbit, dV2, UT2);
                    }
                    else
                    {
                        double   UT = orbit.NextTimeOfRadius(vesselState.time, phasingOrbitRadius);
                        Vector3d dV = OrbitalManeuverCalculator.DeltaVToCircularize(orbit, UT);
                        vessel.PlaceManeuverNode(orbit, dV, UT);
                    }
                }

                break;

            case Step.Transfer:

                GUILayout.Label("Once in the phasing orbit, transfer to the target orbit at just the right time to intercept the target:");

                if (GUILayout.Button("Intercept with Hohmann transfer"))
                {
                    double   UT;
                    Vector3d dV = OrbitalManeuverCalculator.DeltaVAndTimeForHohmannTransfer(orbit, core.target.Orbit, vesselState.time, out UT);
                    vessel.PlaceManeuverNode(orbit, dV, UT);
                }

                double closestApproachTime = orbit.NextClosestApproachTime(core.target.Orbit, vesselState.time);

                GUILayout.Label("Once on a transfer trajectory, match velocities at closest approach:");
                GUILayout.Label("Time until closest approach: " + GuiUtils.TimeToDHMS(closestApproachTime - vesselState.time));
                GUILayout.Label("Separation at closest approach: " + MuUtils.ToSI(orbit.Separation(core.target.Orbit, closestApproachTime), 0) + "m");

                if (GUILayout.Button("Match velocities at closest approach"))
                {
                    double   UT = closestApproachTime;
                    Vector3d dV = OrbitalManeuverCalculator.DeltaVToMatchVelocities(orbit, UT, core.target.Orbit);
                    vessel.PlaceManeuverNode(orbit, dV, UT);
                }

                break;

            case Step.GetCloser:
                GUILayout.Label("If you aren't close enough after matching velocities, thrust gently toward the target:");

                if (GUILayout.Button("Get closer"))
                {
                    double   UT          = vesselState.time;
                    double   interceptUT = UT + 100;
                    Vector3d dV          = OrbitalManeuverCalculator.DeltaVToInterceptAtTime(orbit, UT, core.target.Orbit, interceptUT, 10);
                    vessel.PlaceManeuverNode(orbit, dV, UT);
                }

                GUILayout.Label("Then match velocities again at closest approach");

                break;
            }

            GUILayout.EndVertical();

            MechJebModuleRendezvousAutopilot autopilot = core.GetComputerModule <MechJebModuleRendezvousAutopilot>();

            if (autopilot != null)
            {
                bool active = GUILayout.Toggle(autopilot.enabled, "Autopilot enable");
                if (autopilot.enabled != active)
                {
                    if (active)
                    {
                        autopilot.users.Add(this);
                    }
                    else
                    {
                        autopilot.users.Remove(this);
                    }
                }
                if (autopilot.enabled)
                {
                    GUILayout.Label("Status: " + autopilot.status);
                }
            }

            base.WindowGUI(windowID);
        }
        protected override void WindowGUI(int windowID)
        {
            if (!core.target.NormalTargetExists)
            {
                GUILayout.Label(Localizer.Format("#MechJeb_RZplan_label1"));//"Select a target to rendezvous with."
                base.WindowGUI(windowID);
                return;
            }

            if (core.target.TargetOrbit.referenceBody != orbit.referenceBody)
            {
                GUILayout.Label(Localizer.Format("#MechJeb_RZplan_label2"));//"Rendezvous target must be in the same sphere of influence."
                base.WindowGUI(windowID);
                return;
            }

            GUILayout.BeginVertical();

            //Information readouts:

            GuiUtils.SimpleLabel(Localizer.Format("#MechJeb_RZplan_label3"), core.target.Name);//"Rendezvous target"

            const double leadTime = 30;

            GuiUtils.SimpleLabel(Localizer.Format("#MechJeb_RZplan_label4"), MuUtils.ToSI(core.target.TargetOrbit.PeA, 3) + "m x " + MuUtils.ToSI(core.target.TargetOrbit.ApA, 3) + "m"); //"Target orbit"
            GuiUtils.SimpleLabel(Localizer.Format("#MechJeb_RZplan_label5"), MuUtils.ToSI(orbit.PeA, 3) + "m x " + MuUtils.ToSI(orbit.ApA, 3) + "m");                                     //"Current orbit"
            GuiUtils.SimpleLabel(Localizer.Format("#MechJeb_RZplan_label6"), orbit.RelativeInclination(core.target.TargetOrbit).ToString("F2") + "º");                                    //"Relative inclination"

            double closestApproachTime = orbit.NextClosestApproachTime(core.target.TargetOrbit, vesselState.time);

            GuiUtils.SimpleLabel(Localizer.Format("#MechJeb_RZplan_label7"), GuiUtils.TimeToDHMS(closestApproachTime - vesselState.time));                           //"Time until closest approach"
            GuiUtils.SimpleLabel(Localizer.Format("#MechJeb_RZplan_label8"), MuUtils.ToSI(orbit.Separation(core.target.TargetOrbit, closestApproachTime), 0) + "m"); //"Separation at closest approach"


            //Maneuver planning buttons:

            if (GUILayout.Button(Localizer.Format("#MechJeb_RZplan_button1")))//"Align Planes"
            {
                double   UT;
                Vector3d dV;
                if (orbit.AscendingNodeExists(core.target.TargetOrbit))
                {
                    dV = OrbitalManeuverCalculator.DeltaVAndTimeToMatchPlanesAscending(orbit, core.target.TargetOrbit, vesselState.time, out UT);
                }
                else
                {
                    dV = OrbitalManeuverCalculator.DeltaVAndTimeToMatchPlanesDescending(orbit, core.target.TargetOrbit, vesselState.time, out UT);
                }
                vessel.RemoveAllManeuverNodes();
                vessel.PlaceManeuverNode(orbit, dV, UT);
            }


            GUILayout.BeginHorizontal();
            if (GUILayout.Button(Localizer.Format("#MechJeb_RZplan_button2")))//"Establish new orbit at"
            {
                double phasingOrbitRadius = phasingOrbitAltitude + mainBody.Radius;

                vessel.RemoveAllManeuverNodes();
                if (orbit.ApR < phasingOrbitRadius)
                {
                    double   UT1 = vesselState.time + leadTime;
                    Vector3d dV1 = OrbitalManeuverCalculator.DeltaVToChangeApoapsis(orbit, UT1, phasingOrbitRadius);
                    vessel.PlaceManeuverNode(orbit, dV1, UT1);
                    Orbit    transferOrbit = vessel.patchedConicSolver.maneuverNodes[0].nextPatch;
                    double   UT2           = transferOrbit.NextApoapsisTime(UT1);
                    Vector3d dV2           = OrbitalManeuverCalculator.DeltaVToCircularize(transferOrbit, UT2);
                    vessel.PlaceManeuverNode(transferOrbit, dV2, UT2);
                }
                else if (orbit.PeR > phasingOrbitRadius)
                {
                    double   UT1 = vesselState.time + leadTime;
                    Vector3d dV1 = OrbitalManeuverCalculator.DeltaVToChangePeriapsis(orbit, UT1, phasingOrbitRadius);
                    vessel.PlaceManeuverNode(orbit, dV1, UT1);
                    Orbit    transferOrbit = vessel.patchedConicSolver.maneuverNodes[0].nextPatch;
                    double   UT2           = transferOrbit.NextPeriapsisTime(UT1);
                    Vector3d dV2           = OrbitalManeuverCalculator.DeltaVToCircularize(transferOrbit, UT2);
                    vessel.PlaceManeuverNode(transferOrbit, dV2, UT2);
                }
                else
                {
                    double   UT = orbit.NextTimeOfRadius(vesselState.time, phasingOrbitRadius);
                    Vector3d dV = OrbitalManeuverCalculator.DeltaVToCircularize(orbit, UT);
                    vessel.PlaceManeuverNode(orbit, dV, UT);
                }
            }
            phasingOrbitAltitude.text = GUILayout.TextField(phasingOrbitAltitude.text, GUILayout.Width(70));
            GUILayout.Label("km", GUILayout.ExpandWidth(false));
            GUILayout.EndHorizontal();

            if (GUILayout.Button(Localizer.Format("#MechJeb_RZplan_button3")))//"Intercept with Hohmann transfer"
            {
                double   UT;
                Vector3d dV = OrbitalManeuverCalculator.DeltaVAndTimeForHohmannTransfer(orbit, core.target.TargetOrbit, vesselState.time, out UT);
                vessel.RemoveAllManeuverNodes();
                vessel.PlaceManeuverNode(orbit, dV, UT);
            }

            if (GUILayout.Button(Localizer.Format("#MechJeb_RZplan_button4")))//"Match velocities at closest approach"
            {
                double   UT = closestApproachTime;
                Vector3d dV = OrbitalManeuverCalculator.DeltaVToMatchVelocities(orbit, UT, core.target.TargetOrbit);
                vessel.RemoveAllManeuverNodes();
                vessel.PlaceManeuverNode(orbit, dV, UT);
            }

            if (GUILayout.Button(Localizer.Format("#MechJeb_RZplan_button5")))//"Get closer"
            {
                double   UT = vesselState.time;
                Vector3d dV = OrbitalManeuverCalculator.DeltaVToInterceptAtTime(orbit, UT, core.target.TargetOrbit, 100, 10);
                vessel.RemoveAllManeuverNodes();
                vessel.PlaceManeuverNode(orbit, dV, UT);
            }

            if (core.node != null)
            {
                if (vessel.patchedConicSolver.maneuverNodes.Any() && !core.node.enabled)
                {
                    if (GUILayout.Button(Localizer.Format("#MechJeb_RZplan_button6")))//"Execute next node"
                    {
                        core.node.ExecuteOneNode(this);
                    }

                    if (vessel.patchedConicSolver.maneuverNodes.Count > 1)
                    {
                        if (GUILayout.Button(Localizer.Format("#MechJeb_RZplan_button7")))//"Execute all nodes"
                        {
                            core.node.ExecuteAllNodes(this);
                        }
                    }
                }
                else if (core.node.enabled)
                {
                    if (GUILayout.Button(Localizer.Format("#MechJeb_RZplan_button8")))//"Abort node execution"
                    {
                        core.node.Abort();
                    }
                }

                GUILayout.BeginHorizontal();
                core.node.autowarp = GUILayout.Toggle(core.node.autowarp, Localizer.Format("#MechJeb_RZplan_checkbox"), GUILayout.ExpandWidth(true)); //"Auto-warp"
                GUILayout.Label(Localizer.Format("#MechJeb_RZplan_label9"), GUILayout.ExpandWidth(false));                                            //"Tolerance:"
                core.node.tolerance.text = GUILayout.TextField(core.node.tolerance.text, GUILayout.Width(35), GUILayout.ExpandWidth(false));
                if (GUILayout.Button("+", GUILayout.ExpandWidth(false)))
                {
                    core.node.tolerance.val += 0.1;
                }
                if (GUILayout.Button("-", GUILayout.ExpandWidth(false)))
                {
                    core.node.tolerance.val -= core.node.tolerance.val > 0.1 ? 0.1 : 0.0;
                }
                if (GUILayout.Button("R", GUILayout.ExpandWidth(false)))
                {
                    core.node.tolerance.val = 0.1;
                }
                GUILayout.Label("m/s", GUILayout.ExpandWidth(false));
                GUILayout.EndHorizontal();
            }

            GUILayout.EndVertical();

            base.WindowGUI(windowID);
        }
		private void DoPorkchopGui(Orbit o, double universalTime, MechJebModuleTargetController target)
		{
            // That mess is why you should not compute anything inside a GUI call
            // TODO : rewrite all that...
			if (worker == null)
			{
			    if (Event.current.type == EventType.Layout)
			        layoutSkipped = true;
			    return;
			}
            if (Event.current.type == EventType.Layout)
                layoutSkipped = false;
            if (layoutSkipped)
                return;

            string dv = " - ";
			string departure = " - ";
			string duration = " - ";
			if (worker.Finished && worker.computed.GetLength(1) == porkchop_Height)
			{
				if (plot == null && Event.current.type == EventType.Layout)
				{

                    int width = worker.computed.GetLength(0);
                    int height = worker.computed.GetLength(1);

                    if (texture != null && (texture.width != width || texture.height != height))
                    {
                        Object.Destroy(texture);
                        texture = null;
                    }

                    if (texture == null)
                        texture = new Texture2D(width, height, TextureFormat.RGB24, false);

                    Porkchop.RefreshTexture(worker.computed, texture);

                    plot = new PlotArea(
						worker.minDepartureTime,
						worker.maxDepartureTime,
						worker.minTransferTime,
						worker.maxTransferTime,
						texture,
						(xmin, xmax, ymin, ymax) => {
							minDepartureTime = Math.Max(xmin, universalTime);
							maxDepartureTime = xmax;
							minTransferTime = Math.Max(ymin, 3600);
							maxTransferTime = ymax;
							GUI.changed = true;
						});
					plot.selectedPoint = new int[]{worker.bestDate, worker.bestDuration};
				}
			}
			if (plot != null)
			{
				var point = plot.selectedPoint;
				if (plot.hoveredPoint != null)
					point = plot.hoveredPoint;

				var p = worker.computed[point[0], point[1]];
				if (p != null)
				{
					dv = MuUtils.ToSI(p.dV.magnitude) + "m/s";
					if (worker.DateFromIndex(point[0]) < Planetarium.GetUniversalTime())
						departure = "any time now";
					else
						departure = GuiUtils.TimeToDHMS(worker.DateFromIndex(point[0]) - Planetarium.GetUniversalTime());
					duration = GuiUtils.TimeToDHMS(worker.DurationFromIndex(point[1]));
				}
				plot.DoGUI();
				if (!plot.draggable) _draggable = false;
			}
			else
			{
				GUIStyle progressStyle = new GUIStyle
				{
					font = GuiUtils.skin.font,
					fontSize = GuiUtils.skin.label.fontSize,
					fontStyle = GuiUtils.skin.label.fontStyle,
					normal = {textColor = GuiUtils.skin.label.normal.textColor}
				};

				GUILayout.Box("Computing: " + worker.Progress + "%", progressStyle, new GUILayoutOption[] {
					GUILayout.Width(windowWidth),
					GUILayout.Height(porkchop_Height)});
			}
			GUILayout.BeginHorizontal();
			GUILayout.Label("ΔV: " + dv);
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("Reset", GuiUtils.yellowOnHover))
				ComputeTimes(o, target.TargetOrbit, universalTime);
			GUILayout.EndHorizontal();

			GUILayout.BeginHorizontal();
			GUILayout.Label("Select: ");
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("Lowest ΔV"))
			{
				plot.selectedPoint = new int[]{ worker.bestDate, worker.bestDuration };
				GUI.changed = false;
			}

			if (GUILayout.Button("ASAP"))
			{
				int bestDuration = 0;
				for (int i = 1; i < worker.computed.GetLength(1); i++)
				{
					if (worker.computed[0, bestDuration].dV.sqrMagnitude > worker.computed[0, i].dV.sqrMagnitude)
						bestDuration = i;
				}
				plot.selectedPoint = new int[]{ 0, bestDuration };
				GUI.changed = false;
			}
			GUILayout.EndHorizontal();

			GUILayout.Label("Departure in " + departure);
			GUILayout.Label("Transit duration " + duration);
		}
Beispiel #30
0
        protected override void WindowGUI(int windowID)
        {
            GUILayout.BeginVertical();

            GUILayout.BeginHorizontal();
            GUILayout.Label(Localizer.Format("#MechJeb_WarpHelper_label1"), GUILayout.ExpandWidth(false));//"Warp to: "
            warpTarget = (WarpTarget)GuiUtils.ComboBox.Box((int)warpTarget, warpTargetStrings, this);
            GUILayout.EndHorizontal();

            if (warpTarget == WarpTarget.Time)
            {
                GUILayout.BeginHorizontal();
                GUILayout.Label(Localizer.Format("#MechJeb_WarpHelper_label2"), GUILayout.ExpandWidth(true));//"Warp for: "
                timeOffset.text = GUILayout.TextField(timeOffset.text, GUILayout.Width(100));
                GUILayout.EndHorizontal();
            }
            else if (warpTarget == WarpTarget.PhaseAngleT)
            {
                // I wonder if I should check for target that don't make sense
                if (!core.target.NormalTargetExists)
                {
                    GUILayout.Label(Localizer.Format("#MechJeb_WarpHelper_label3"));//"You need a target"
                }
                else
                {
                    GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_WarpHelper_label4"), phaseAngle, "º", 60);//"Phase Angle:"
                }
            }

            GUILayout.BeginHorizontal();

            GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_WarpHelper_label5"), leadTime, "");//"Lead time: "

            if (warping)
            {
                if (GUILayout.Button(Localizer.Format("#MechJeb_WarpHelper_button1")))//"Abort"
                {
                    warping = false;
                    core.warp.MinimumWarp(true);
                }
            }
            else
            {
                if (GUILayout.Button(Localizer.Format("#MechJeb_WarpHelper_button2")))//"Warp"
                {
                    warping = true;

                    switch (warpTarget)
                    {
                    case WarpTarget.Periapsis:
                        targetUT = orbit.NextPeriapsisTime(vesselState.time);
                        break;

                    case WarpTarget.Apoapsis:
                        if (orbit.eccentricity < 1)
                        {
                            targetUT = orbit.NextApoapsisTime(vesselState.time);
                        }
                        break;

                    case WarpTarget.SoI:
                        if (orbit.patchEndTransition != Orbit.PatchTransitionType.FINAL)
                        {
                            targetUT = orbit.EndUT;
                        }
                        break;

                    case WarpTarget.Node:
                        if (vessel.patchedConicsUnlocked() && vessel.patchedConicSolver.maneuverNodes.Any())
                        {
                            targetUT = vessel.patchedConicSolver.maneuverNodes[0].UT;
                        }
                        break;

                    case WarpTarget.Time:
                        targetUT = vesselState.time + timeOffset;
                        break;

                    case WarpTarget.PhaseAngleT:
                        if (core.target.NormalTargetExists)
                        {
                            Orbit reference;
                            if (core.target.TargetOrbit.referenceBody == orbit.referenceBody)
                            {
                                reference = orbit;     // we orbit arround the same body
                            }
                            else
                            {
                                reference = orbit.referenceBody.orbit;
                            }
                            // From Kerbal Alarm Clock
                            double angleChangePerSec = (360 / core.target.TargetOrbit.period) - (360 / reference.period);
                            double currentAngle      = reference.PhaseAngle(core.target.TargetOrbit, vesselState.time);
                            double angleDigff        = currentAngle - phaseAngle;
                            if (angleDigff > 0 && angleChangePerSec > 0)
                            {
                                angleDigff -= 360;
                            }
                            if (angleDigff < 0 && angleChangePerSec < 0)
                            {
                                angleDigff += 360;
                            }
                            double TimeToTarget = Math.Floor(Math.Abs(angleDigff / angleChangePerSec));
                            targetUT = vesselState.time + TimeToTarget;
                        }
                        break;

                    case WarpTarget.AtmosphericEntry:
                        try
                        {
                            targetUT = OrbitExtensions.NextTimeOfRadius(vessel.orbit, vesselState.time, vesselState.mainBody.Radius + vesselState.mainBody.RealMaxAtmosphereAltitude());
                        }
                        catch
                        {
                            warping = false;
                        }
                        break;

                    case WarpTarget.SuicideBurn:
                        try
                        {
                            targetUT = OrbitExtensions.SuicideBurnCountdown(orbit, vesselState, vessel) + vesselState.time;
                        }
                        catch
                        {
                            warping = false;
                        }
                        break;

                    default:
                        targetUT = vesselState.time;
                        break;
                    }
                }
            }

            GUILayout.EndHorizontal();

            core.warp.useQuickWarpInfoItem();

            if (warping)
            {
                GUILayout.Label(Localizer.Format("#MechJeb_WarpHelper_label6") + (leadTime > 0 ? GuiUtils.TimeToDHMS(leadTime) + " before " : "") + warpTargetStrings[(int)warpTarget] + ".");         //"Warping to "
            }
            core.warp.ControlWarpButton();

            GUILayout.EndVertical();

            base.WindowGUI(windowID);
        }