Пример #1
0
        private void Start()
        {
            textStyle = GuiUtils.PrepareBigText(Color.grey);
            sim.RefreshSimulationVariables();

            altimeterSliderButtons = (AltimeterSliderButtons)FindObjectOfType(typeof(AltimeterSliderButtons));

            GameEvents.onLaunch.Add(OnLaunch);
            GameEvents.onFlightReady.Add(OnFlightReady);

            if (_status != SimVesselStatus.Waiting)
            {
                if (FlightGlobals.fetch.activeVessel.situation != Vessel.Situations.PRELAUNCH)
                {
                    _status = SimVesselStatus.Launched;
                    Debug.Log($"[QuickIronMan]({name}) This vessel is already launched");
                }
                else
                {
                    _status = SimVesselStatus.Loaded;
                }
            }

            Debug.Log($"[QuickIronMan]({name}) Start, simulation: {sim.IsInSimulation()}");
        }
Пример #2
0
        //Called once when the scene starts
        new public void Start()
        {
            base.Start(); //Call Start() in the parent class
            //Get the MonoBehaviour that controls the buttons at the top of the screen
            AltimeterSliderButtons buttons = (AltimeterSliderButtons)FindObjectOfType(typeof(AltimeterSliderButtons));

            if (buttons != null)
            {
                //back up the original function. We'll call that when we're within range
                originalCallback = buttons.vesselRecoveryButton.onClick;

                //Override the original function with ours, which checks the distance.
                buttons.vesselRecoveryButton.onClick = new Button.ButtonClickedEvent();
                buttons.vesselRecoveryButton.onClick.AddListener(NewRecoveryFunctionFlight);
            }
        }
Пример #3
0
            private void Start()
            // I use Start instead of Awake because whatever setup the editor does to the gizmo won't be done yet
            {
                AltimeterSliderButtons altimeterSliderButtons = null;


                if (gameObject.GetComponentCached(ref altimeterSliderButtons) != null)
                {
                    onAltimeterSliderButtonsSpawned.Fire(altimeterSliderButtons);
                }
                else if (gameObject.GetComponentCached(ref altimeterSliderButtons) != null)
                {
                    onAltimeterSliderButtonsSpawned.Fire(altimeterSliderButtons);
                }
                else
                {
                    Debug.LogError("Didn't find a gizmo on this GameObject -- something has broken");
                }

                // could destroy this MB now, unless you wanted to use OnDestroy to sent an event
            }
Пример #4
0
        void Update()
        {
            // We don't want to do anything if we aren't simming
            if (KRASHShelter.persistent.shelterSimulationActive)
            {
#if true
                if (HighLogic.CurrentGame.Parameters.CustomParams<KRASH_Settings>().wireframes)
                {
                    if (!wireFrameAdded)
                    {
                        wireFrameAdded = true;
                        Log.Info("Adding wireframe");
                        cams = Camera.allCameras;

                        for (int i = 0; i < cams.Length; i++)
                        {
                            if (cams[i].name == "Camera 00")
                            {
                                nearCamera = cams[i];
                            }
                            if (cams[i].name == "Camera 01")
                            {
                                //cams [i].renderingPath=RenderingPath.DeferredShading;
                                farCamera = cams[i];
                                //cams [i].enabled=false;

                            }
                            if (cams[i].name == "Camera ScaledSpace")
                            {
                                //cams [i].renderingPath=RenderingPath.DeferredShading;
                                scaledSpaceCamera = cams[i];
                            }
                        }
                        nearCamera.gameObject.AddComponent(typeof(WireFrame));
                        // farCamera.gameObject.AddComponent(typeof(WireFrame));
                        // scaledSpaceCamera.gameObject.AddComponent(typeof(WireFrame));
#if false
                        // Camera.main.gameObject.AddComponent(typeof(Wireframe));
                      
                    var v = FlightGlobals.ActiveVessel;

                    foreach (var p in v.parts)
                    {
                        
                        var mf = p.FindModelComponents<MeshFilter>();
                        var smr = p.FindModelComponents<SkinnedMeshRenderer>();

                        //  if (p.partTransform.GetComponent<MeshFilter>() || p.partTransform.GetComponent<SkinnedMeshRenderer>())
                        if ((mf != null && mf.Count > 0) || (smr != null && smr.Count > 0))
                        {
                            Log.Info("Wireframe added to part: " + p.partInfo.name);
                            // Add a WireFrame object to it.
                           // WireFrame added = p.gameObject.AddComponent<WireFrame>();

                          

                        }

                    }
#endif
                    }
#endif
                }
                // Don't allow any of the recovery buttons to be used
                //	AltimeterSliderButtons _Recovery_button = (AltimeterSliderButtons)GameObject.FindObjectOfType (typeof(AltimeterSliderButtons));
                if (_Recovery_button == null)
                {
                    _Recovery_button = (AltimeterSliderButtons)GameObject.FindObjectOfType(typeof(AltimeterSliderButtons));
                }
                if (_Recovery_button != null && _Recovery_button.slidingTab.enabled)
                {
                    _Recovery_button.hoverArea = new XSelectable();
                    _Recovery_button.slidingTab.enabled = false;
                    _Recovery_button.spaceCenterButton.enabled = false;
                    _Recovery_button.vesselRecoveryButton.enabled = false;
                    Log.Info("Recovery locked");
                }


                if (KRASHShelter.instance.simPauseMenuInstance == null)
                {
                    Log.Info("FlightModule.Update KRASH.simPauseMenuInstance == null");
                    return;
                }
                if (KRASHShelter.instance == null)
                {
                    Log.Info("FlightModule.Update KRASH.instance == null");
                    return;
                }
                //Log.Info ("jbb PauseMenu.isOpen: " + PauseMenu.isOpen.ToString ());
                //Log.Info ("KRASHShelter.instance.simPauseMenuInstance.isOpen: " + KRASHShelter.instance.simPauseMenuInstance.isOpen.ToString ());

                bool b;
                try
                {
                    b = FlightResultsDialog.isDisplaying;
                }
                catch (Exception)
                {
                    Log.Info("FlightResultsDialog.isDisplaying exception");
                    b = false;
                }
                if (b)
                {
                    FlightResultsDialog.showExitControls = false;
                    FlightResultsDialog.allowClosingDialog = true;
                    FlightResultsDialog.Display("Simulation ended!");
                }


                // Hide the vanilla pause menu.
                Log.Info("Checking PauseMenu");
                Log.Info("PauseMenu.isOpen: " + PauseMenu.isOpen.ToString());
                if (PauseMenu.isOpen)
                {
                    PauseMenu.Close();
                    pauseCnt = 1;
                }

                // Check for pause keypress
                //pauseCnt++;
                if (/* GameSettings.PAUSE.GetKeyDown() && */ pauseCnt != 0 && closeCnt == 0)
                {
                    Log.Info("GetKeyDown    menu.isOpen: " + KRASHShelter.instance.simPauseMenuInstance.isOpen);
                    if (GameSettings.PAUSE.GetKeyDown())
                    {
                        pauseCnt = 0;
                        Log.Info("GameSettings.PAUSE.GetKeyDown");
                    }
                    switch (KRASHShelter.instance.simPauseMenuInstance.isOpen)
                    {
                        case false:
                            if (pauseCnt == 1)
                            {
                                KRASHShelter.instance.simPauseMenuInstance.Display();
                                pauseCnt = 2;
                            }
                            break;
                        case true:
                            if (pauseCnt == 0)
                            {
                                Log.Info("menu.Close");
                                KRASHShelter.instance.simPauseMenuInstance.Close();
                                Log.Info("After close simPauseMenuInstance, PauseMenu.isOpen: " + PauseMenu.isOpen.ToString());
                                pauseCnt = 0;
                                closeCnt = 1;
                            }
                            break;
                    }
                }
                else
                {
                    // The wierd issue changed from 1.1.3 to 1.2, now, it pauses for 7-10 tics after unpausing
                    if (closeCnt > 0 && closeCnt++ < 20)
                    {
                        FlightDriver.SetPause(false);
                        PauseMenu.Close();
                        pauseCnt = 0;
                    }
                    else
                        closeCnt = 0;
                    // This is to get around a wierd issue where the game unpauses
                    // for about 7-10 tics after PauseMenu.Close() is called.
                    // if (KRASHShelter.instance.simPauseMenuInstance.isOpen && pauseCnt < 20 /*&& FlightDriver.Pause */)
                    //     FlightDriver.SetPause(true);
                }
            }
        }
 public void OnGameSceneLoadRequested(GameScenes gameScene)
 {
     asb = null;
 }
        protected void DrawWaypoint(WaypointData wpd)
        {
            // Not our planet
            CelestialBody celestialBody = FlightGlobals.currentMainBody;

            if (celestialBody == null || wpd.waypoint.celestialName != celestialBody.name)
            {
                return;
            }

            // Check if the waypoint should be visible
            if (!wpd.waypoint.visible)
            {
                return;
            }

            // Figure out waypoint label
            string label = wpd.waypoint.name + (wpd.waypoint.isClustered ? (" " + StringUtilities.IntegerToGreek(wpd.waypoint.index)) : "");

            // Set the alpha and do a nice fade
            wpd.SetAlpha();

            // Decide whether to actually draw the waypoint
            if (FlightGlobals.ActiveVessel != null)
            {
                // Figure out the distance to the waypoint
                Vessel v = FlightGlobals.ActiveVessel;

                // Only change alpha if the waypoint isn't the nav point
                if (!Util.IsNavPoint(wpd.waypoint))
                {
                    // Get the distance to the waypoint at the current speed
                    double speed      = v.srfSpeed < MIN_SPEED ? MIN_SPEED : v.srfSpeed;
                    double directTime = Util.GetStraightDistance(wpd) / speed;

                    // More than two minutes away
                    if (directTime > MIN_TIME || Config.waypointDisplay != Config.WaypointDisplay.ALL)
                    {
                        return;
                    }
                    else if (directTime >= MIN_TIME - FADE_TIME)
                    {
                        wpd.currentAlpha = (float)((MIN_TIME - directTime) / FADE_TIME) * Config.opacity;
                    }
                }
                // Draw the distance information to the nav point
                else
                {
                    // Draw the distance to waypoint text
                    if (Event.current.type == EventType.Repaint)
                    {
                        if (asb == null)
                        {
                            asb = UnityEngine.Object.FindObjectOfType <AltimeterSliderButtons>();
                        }

                        if (referenceUISize != ScreenSafeUI.VerticalRatio || !referenceSet)
                        {
                            referencePos    = ScreenSafeUI.referenceCam.ViewportToScreenPoint(asb.transform.position).y;
                            referenceUISize = ScreenSafeUI.VerticalRatio;

                            // Need two consistent numbers in a row to set the reference
                            if (lastPos == referencePos)
                            {
                                referenceSet = true;
                            }
                            else
                            {
                                lastPos = referencePos;
                            }
                        }

                        float ybase = (referencePos - ScreenSafeUI.referenceCam.ViewportToScreenPoint(asb.transform.position).y + Screen.height / 11.67f) / ScreenSafeUI.VerticalRatio;

                        string timeToWP = GetTimeToWaypoint(wpd);
                        if (Config.hudDistance)
                        {
                            GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 20f), "Distance to " + label + ":", nameStyle);
                            GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 20f),
                                      v.state != Vessel.State.DEAD ? Util.PrintDistance(wpd) : "N/A", valueStyle);
                            ybase += 18f;
                        }

                        if (timeToWP != null && Config.hudTime)
                        {
                            GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 20f), "ETA to " + label + ":", nameStyle);
                            GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 20f),
                                      v.state != Vessel.State.DEAD ? timeToWP : "N/A", valueStyle);
                            ybase += 18f;
                        }

                        if (Config.hudHeading)
                        {
                            GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 20f), "Heading to " + label + ":", nameStyle);
                            GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 20f),
                                      v.state != Vessel.State.DEAD ? wpd.heading.ToString("N1") : "N/A", valueStyle);
                            ybase += 18f;
                        }

                        if (Config.hudAngle && v.mainBody == wpd.celestialBody)
                        {
                            double distance   = Util.GetLateralDistance(wpd);
                            double heightDist = wpd.waypoint.altitude + wpd.waypoint.height - v.altitude;
                            double angle      = Math.Atan2(heightDist, distance) * 180.0 / Math.PI;

                            GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 20f), "Angle to " + label + ":", nameStyle);
                            GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 20f),
                                      v.state != Vessel.State.DEAD ? angle.ToString("N2") : "N/A", valueStyle);
                            ybase += 18f;

                            if (v.srfSpeed >= 0.1)
                            {
                                double velAngle = 90 - Math.Acos(Vector3d.Dot(v.srf_velocity.normalized, v.upAxis)) * 180.0 / Math.PI;

                                GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 20f), "Velocity pitch angle:", nameStyle);
                                GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 20f),
                                          v.state != Vessel.State.DEAD ? velAngle.ToString("N2") : "N/A", valueStyle);
                                ybase += 18f;
                            }
                        }
                        if (Config.hudCoordinates && v.mainBody == wpd.celestialBody)
                        {
                            ybase += 9;
                            GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 38f), "Coordinates of " + label + ":", nameStyle);
                            GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 38f),
                                      v.state != Vessel.State.DEAD ? string.Format("{0}\r\n{1}", Util.DecimalDegreesToDMS(wpd.waypoint.latitude, true), Util.DecimalDegreesToDMS(wpd.waypoint.longitude, false)) : "N/A", valueStyle);
                            ybase += 18f;
                        }
                    }
                }
            }

            // Don't draw the waypoint
            if (Config.waypointDisplay == Config.WaypointDisplay.NONE)
            {
                return;
            }

            // Translate to scaled space
            Vector3d localSpacePoint  = celestialBody.GetWorldSurfacePosition(wpd.waypoint.latitude, wpd.waypoint.longitude, wpd.waypoint.height + wpd.waypoint.altitude);
            Vector3d scaledSpacePoint = ScaledSpace.LocalToScaledSpace(localSpacePoint);

            // Don't draw if it's behind the camera
            if (Vector3d.Dot(MapView.MapCamera.camera.transform.forward, scaledSpacePoint.normalized) < 0.0)
            {
                return;
            }

            // Translate to screen position
            Vector3 screenPos = MapView.MapCamera.camera.WorldToScreenPoint(new Vector3((float)scaledSpacePoint.x, (float)scaledSpacePoint.y, (float)scaledSpacePoint.z));

            // Draw the marker at half-resolution (30 x 45) - that seems to match the one in the map view
            Rect markerRect = new Rect(screenPos.x - 15f, (float)Screen.height - screenPos.y - 45.0f, 30f, 45f);

            // Set the window position relative to the selected waypoint
            if (selectedWaypoint == wpd.waypoint)
            {
                windowPos = new Rect(markerRect.xMin - 97, markerRect.yMax + 12, 224, 60);
            }

            // Handling clicking on the waypoint
            if (Event.current.type == EventType.MouseUp && Event.current.button == 0)
            {
                if (markerRect.Contains(Event.current.mousePosition))
                {
                    selectedWaypoint = wpd.waypoint;
                    windowPos        = new Rect(markerRect.xMin - 97, markerRect.yMax + 12, 224, 60);
                    waypointName     = label;
                    newClick         = false;
                }
                else if (newClick)
                {
                    selectedWaypoint = null;
                }
            }

            // Only handle on repaint events
            if (Event.current.type == EventType.Repaint)
            {
                // Half-res for the icon too (16 x 16)
                Rect iconRect = new Rect(screenPos.x - 8f, (float)Screen.height - screenPos.y - 39.0f, 16f, 16f);

                // Draw the marker
                Graphics.DrawTexture(markerRect, GameDatabase.Instance.GetTexture("Squad/Contracts/Icons/marker", false), new Rect(0.0f, 0.0f, 1f, 1f), 0, 0, 0, 0, new Color(0.5f, 0.5f, 0.5f, 0.5f * (wpd.currentAlpha - 0.3f) / 0.7f));

                // Draw the icon, but support blinking
                if (!Util.IsNavPoint(wpd.waypoint) || !FinePrint.WaypointManager.navWaypoint.blinking || (int)((Time.fixedTime - (int)Time.fixedTime) * 4) % 2 == 0)
                {
                    Graphics.DrawTexture(iconRect, ContractDefs.textures[wpd.waypoint.id], new Rect(0.0f, 0.0f, 1f, 1f), 0, 0, 0, 0, SystemUtilities.RandomColor(wpd.waypoint.seed, wpd.currentAlpha));
                }

                // Hint text!
                if (iconRect.Contains(Event.current.mousePosition))
                {
                    // Add agency to label
                    if (wpd.waypoint.contractReference != null)
                    {
                        label += "\n" + wpd.waypoint.contractReference.Agent.Name;
                    }
                    float width   = 240f;
                    float height  = hintTextStyle.CalcHeight(new GUIContent(label), width);
                    float yoffset = height + 48.0f;
                    GUI.Box(new Rect(screenPos.x - width / 2.0f, (float)Screen.height - screenPos.y - yoffset, width, height), label, hintTextStyle);
                }
            }
        }
Пример #7
0
        void Update()
        {
            // We don't want to do anything if we aren't simming
            if (KRASHShelter.persistent.shelterSimulationActive)
            {
                // Don't allow any of the recovery buttons to be used
                //	AltimeterSliderButtons _Recovery_button = (AltimeterSliderButtons)GameObject.FindObjectOfType (typeof(AltimeterSliderButtons));
                if (_Recovery_button == null)
                {
                    _Recovery_button = (AltimeterSliderButtons)GameObject.FindObjectOfType(typeof(AltimeterSliderButtons));
                }
                if (_Recovery_button != null && _Recovery_button.slidingTab.enabled)
                {
                    _Recovery_button.hoverArea                    = new XSelectable();
                    _Recovery_button.slidingTab.enabled           = false;
                    _Recovery_button.spaceCenterButton.enabled    = false;
                    _Recovery_button.vesselRecoveryButton.enabled = false;
                    Log.Info("Recovery locked");
                }


                if (KRASHShelter.instance.simPauseMenuInstance == null)
                {
                    Log.Info("FlightModule.Update KRASH.simPauseMenuInstance == null");
                    return;
                }
                if (KRASHShelter.instance == null)
                {
                    Log.Info("FlightModule.Update KRASH.instance == null");
                    return;
                }
                //Log.Info ("jbb PauseMenu.isOpen: " + PauseMenu.isOpen.ToString ());
                //Log.Info ("KRASHShelter.instance.simPauseMenuInstance.isOpen: " + KRASHShelter.instance.simPauseMenuInstance.isOpen.ToString ());

                bool b;
                try
                {
                    b = FlightResultsDialog.isDisplaying;
                }
                catch (Exception)
                {
                    Log.Info("FlightResultsDialog.isDisplaying exception");
                    b = false;
                }
                if (b)
                {
                    FlightResultsDialog.showExitControls   = false;
                    FlightResultsDialog.allowClosingDialog = true;
                    FlightResultsDialog.Display("Simulation ended!");
                }


                // Hide the vanilla pause menu.
                Log.Info("Checking PauseMenu");
                Log.Info("PauseMenu.isOpen: " + PauseMenu.isOpen.ToString());
                if (PauseMenu.isOpen)
                {
                    PauseMenu.Close();
                    pauseCnt = 1;
                }

                // Check for pause keypress
                //pauseCnt++;
                if (/* GameSettings.PAUSE.GetKeyDown() && */ pauseCnt != 0 && closeCnt == 0)
                {
                    Log.Info("GetKeyDown    menu.isOpen: " + KRASHShelter.instance.simPauseMenuInstance.isOpen);
                    if (GameSettings.PAUSE.GetKeyDown())
                    {
                        pauseCnt = 0;
                        Log.Info("GameSettings.PAUSE.GetKeyDown");
                    }
                    switch (KRASHShelter.instance.simPauseMenuInstance.isOpen)
                    {
                    case false:
                        if (pauseCnt == 1)
                        {
                            KRASHShelter.instance.simPauseMenuInstance.Display();
                            pauseCnt = 2;
                        }
                        break;

                    case true:
                        if (pauseCnt == 0)
                        {
                            Log.Info("menu.Close");
                            KRASHShelter.instance.simPauseMenuInstance.Close();
                            Log.Info("After close simPauseMenuInstance, PauseMenu.isOpen: " + PauseMenu.isOpen.ToString());
                            pauseCnt = 0;
                            closeCnt = 1;
                        }
                        break;
                    }
                }
                else
                {
                    // The wierd issue changed from 1.1.3 to 1.2, now, it pauses for 7-10 tics after unpausing
                    if (closeCnt > 0 && closeCnt++ < 20)
                    {
                        FlightDriver.SetPause(false);
                        PauseMenu.Close();
                        pauseCnt = 0;
                    }
                    else
                    {
                        closeCnt = 0;
                    }
                    // This is to get around a wierd issue where the game unpauses
                    // for about 7-10 tics after PauseMenu.Close() is called.
                    // if (KRASHShelter.instance.simPauseMenuInstance.isOpen && pauseCnt < 20 /*&& FlightDriver.Pause */)
                    //     FlightDriver.SetPause(true);
                }
            }
        }
 public void OnGameSceneLoadRequested(GameScenes gameScene)
 {
     asb = null;
 }
        protected void DrawWaypoint(WaypointData wpd)
        {
            // Not our planet
            CelestialBody celestialBody = FlightGlobals.currentMainBody;
            if (celestialBody == null || wpd.waypoint.celestialName != celestialBody.name)
            {
                return;
            }

            // Check if the waypoint should be visible
            if (!wpd.waypoint.visible)
            {
                return;
            }

            // Figure out waypoint label
            string label = wpd.waypoint.name + (wpd.waypoint.isClustered ? (" " + StringUtilities.IntegerToGreek(wpd.waypoint.index)) : "");

            // Set the alpha and do a nice fade
            wpd.SetAlpha();

            // Decide whether to actually draw the waypoint
            if (FlightGlobals.ActiveVessel != null)
            {
                // Figure out the distance to the waypoint
                Vessel v = FlightGlobals.ActiveVessel;

                // Only change alpha if the waypoint isn't the nav point
                if (!Util.IsNavPoint(wpd.waypoint))
                {
                    // Get the distance to the waypoint at the current speed
                    double speed = v.srfSpeed < MIN_SPEED ? MIN_SPEED : v.srfSpeed;
                    double directTime = Util.GetStraightDistance(wpd) / speed;

                    // More than two minutes away
                    if (directTime > MIN_TIME || Config.waypointDisplay != Config.WaypointDisplay.ALL)
                    {
                        return;
                    }
                    else if (directTime >= MIN_TIME - FADE_TIME)
                    {
                        wpd.currentAlpha = (float)((MIN_TIME - directTime) / FADE_TIME) * Config.opacity;
                    }
                }
                // Draw the distance information to the nav point
                else
                {
                    // Draw the distance to waypoint text
                    if (Event.current.type == EventType.Repaint)
                    {
                        if (asb == null)
                        {
                            asb = UnityEngine.Object.FindObjectOfType<AltimeterSliderButtons>();
                        }

                        if (referenceUISize != ScreenSafeUI.VerticalRatio || !referenceSet)
                        {
                            referencePos = ScreenSafeUI.referenceCam.ViewportToScreenPoint(asb.transform.position).y;
                            referenceUISize = ScreenSafeUI.VerticalRatio;

                            // Need two consistent numbers in a row to set the reference
                            if (lastPos == referencePos)
                            {
                                referenceSet = true;
                            }
                            else
                            {
                                lastPos = referencePos;
                            }
                        }

                        float ybase = (referencePos - ScreenSafeUI.referenceCam.ViewportToScreenPoint(asb.transform.position).y + Screen.height / 11.67f) / ScreenSafeUI.VerticalRatio;

                        string timeToWP = GetTimeToWaypoint(wpd);
                        if (Config.hudDistance)
                        {
                            GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 20f), "Distance to " + label + ":", nameStyle);
                            GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 20f),
                                v.state != Vessel.State.DEAD ? Util.PrintDistance(wpd) : "N/A", valueStyle);
                            ybase += 18f;
                        }

                        if (timeToWP != null && Config.hudTime)
                        {
                            GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 20f), "ETA to " + label + ":", nameStyle);
                            GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 20f),
                                v.state != Vessel.State.DEAD ? timeToWP : "N/A", valueStyle);
                            ybase += 18f;
                        }

                        if (Config.hudHeading)
                        {
                            GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 20f), "Heading to " + label + ":", nameStyle);
                            GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 20f),
                                v.state != Vessel.State.DEAD ? wpd.heading.ToString("N1") : "N/A", valueStyle);
                            ybase += 18f;
                        }

                        if (Config.hudAngle && v.mainBody == wpd.celestialBody)
                        {
                            double distance = Util.GetLateralDistance(wpd);
                            double heightDist = wpd.waypoint.altitude + wpd.waypoint.height - v.altitude;
                            double angle = Math.Atan2(heightDist, distance) * 180.0 / Math.PI;

                            GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 20f), "Angle to " + label + ":", nameStyle);
                            GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 20f),
                                v.state != Vessel.State.DEAD ? angle.ToString("N2") : "N/A", valueStyle);
                            ybase += 18f;

                            if (v.srfSpeed >= 0.1)
                            {
                                double velAngle = 90 - Math.Acos(Vector3d.Dot(v.srf_velocity.normalized, v.upAxis)) * 180.0 / Math.PI;

                                GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 20f), "Velocity pitch angle:", nameStyle);
                                GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 20f),
                                    v.state != Vessel.State.DEAD ? velAngle.ToString("N2") : "N/A", valueStyle);
                                ybase += 18f;
                            }
                        }
                        if(Config.hudCoordinates&&v.mainBody==wpd.celestialBody)
                        {
                            ybase += 9;
                            GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 38f), "Coordinates of " + label + ":", nameStyle);
                            GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 38f),
                                v.state != Vessel.State.DEAD ? string.Format("{0}\r\n{1}", Util.DecimalDegreesToDMS(wpd.waypoint.latitude,true), Util.DecimalDegreesToDMS(wpd.waypoint.longitude,false)) : "N/A", valueStyle);
                            ybase += 18f;
                        }
                    }
                }
            }

            // Don't draw the waypoint
            if (Config.waypointDisplay == Config.WaypointDisplay.NONE)
            {
                return;
            }

            // Translate to scaled space
            Vector3d localSpacePoint = celestialBody.GetWorldSurfacePosition(wpd.waypoint.latitude, wpd.waypoint.longitude, wpd.waypoint.height + wpd.waypoint.altitude);
            Vector3d scaledSpacePoint = ScaledSpace.LocalToScaledSpace(localSpacePoint);

            // Don't draw if it's behind the camera
            if (Vector3d.Dot(MapView.MapCamera.camera.transform.forward, scaledSpacePoint.normalized) < 0.0)
            {
                return;
            }

            // Translate to screen position
            Vector3 screenPos = MapView.MapCamera.camera.WorldToScreenPoint(new Vector3((float)scaledSpacePoint.x, (float)scaledSpacePoint.y, (float)scaledSpacePoint.z));

            // Draw the marker at half-resolution (30 x 45) - that seems to match the one in the map view
            Rect markerRect = new Rect(screenPos.x - 15f, (float)Screen.height - screenPos.y - 45.0f, 30f, 45f);

            // Set the window position relative to the selected waypoint
            if (selectedWaypoint == wpd.waypoint)
            {
                windowPos = new Rect(markerRect.xMin - 97, markerRect.yMax + 12, 224, 60);
            }

            // Handling clicking on the waypoint
            if (Event.current.type == EventType.MouseUp && Event.current.button == 0)
            {
                if (markerRect.Contains(Event.current.mousePosition))
                {
                    selectedWaypoint = wpd.waypoint;
                    windowPos = new Rect(markerRect.xMin - 97, markerRect.yMax + 12, 224, 60);
                    waypointName = label;
                    newClick = false;
                }
                else if (newClick)
                {
                    selectedWaypoint = null;
                }
            }

            // Only handle on repaint events
            if (Event.current.type == EventType.Repaint)
            {
                // Half-res for the icon too (16 x 16)
                Rect iconRect = new Rect(screenPos.x - 8f, (float)Screen.height - screenPos.y - 39.0f, 16f, 16f);

                // Draw the marker
                Graphics.DrawTexture(markerRect, GameDatabase.Instance.GetTexture("Squad/Contracts/Icons/marker", false), new Rect(0.0f, 0.0f, 1f, 1f), 0, 0, 0, 0, new Color(0.5f, 0.5f, 0.5f, 0.5f * (wpd.currentAlpha - 0.3f) / 0.7f));

                // Draw the icon, but support blinking
                if (!Util.IsNavPoint(wpd.waypoint) || !FinePrint.WaypointManager.navWaypoint.blinking || (int)((Time.fixedTime - (int)Time.fixedTime) * 4) % 2 == 0)
                {
                    Graphics.DrawTexture(iconRect, ContractDefs.textures[wpd.waypoint.id], new Rect(0.0f, 0.0f, 1f, 1f), 0, 0, 0, 0, SystemUtilities.RandomColor(wpd.waypoint.seed, wpd.currentAlpha));
                }

                // Hint text!
                if (iconRect.Contains(Event.current.mousePosition))
                {
                    // Add agency to label
                    if (wpd.waypoint.contractReference != null)
                    {
                        label += "\n" + wpd.waypoint.contractReference.Agent.Name;
                    }
                    float width = 240f;
                    float height = hintTextStyle.CalcHeight(new GUIContent(label), width);
                    float yoffset = height + 48.0f;
                    GUI.Box(new Rect(screenPos.x - width/2.0f, (float)Screen.height - screenPos.y - yoffset, width, height), label, hintTextStyle);
                }
            }
        }