public void HintText(WaypointData wpd)
        {
            // Translate to screen position
            Vector3d localSpacePoint = wpd.celestialBody.GetWorldSurfacePosition(wpd.waypoint.latitude, wpd.waypoint.longitude, wpd.waypoint.altitude);
            Vector3d scaledSpacePoint = ScaledSpace.LocalToScaledSpace(localSpacePoint);
            Vector3 screenPos = MapView.MapCamera.camera.WorldToScreenPoint(new Vector3((float)scaledSpacePoint.x, (float)scaledSpacePoint.y, (float)scaledSpacePoint.z));

            Rect iconRect = new Rect(screenPos.x - 8f, (float)Screen.height - screenPos.y - 39.0f, 16f, 16f);

            // Hint text!
            if (iconRect.Contains(Event.current.mousePosition))
            {
                string label = wpd.waypoint.name + (wpd.waypoint.isClustered ? (" " + StringUtilities.IntegerToGreek(wpd.waypoint.index)) : "");
                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);
            }
        }
Esempio n. 2
0
        public void HintText(WaypointData wpd)
        {
            // Translate to screen position
            Vector3d localSpacePoint  = wpd.celestialBody.GetWorldSurfacePosition(wpd.waypoint.latitude, wpd.waypoint.longitude, wpd.waypoint.altitude);
            Vector3d scaledSpacePoint = ScaledSpace.LocalToScaledSpace(localSpacePoint);
            Vector3  screenPos        = PlanetariumCamera.Camera.WorldToScreenPoint(new Vector3((float)scaledSpacePoint.x, (float)scaledSpacePoint.y, (float)scaledSpacePoint.z));

            Rect iconRect = new Rect(screenPos.x - 8f, (float)Screen.height - screenPos.y - 39.0f, 16f, 16f);

            // Hint text!
            if (iconRect.Contains(Event.current.mousePosition))
            {
                string label   = wpd.waypoint.name + (wpd.waypoint.isClustered ? (" " + StringUtilities.IntegerToGreek(wpd.waypoint.index)) : "");
                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);
            }
        }
        public void HandleClick(WaypointData wpd)
        {
            // Translate to screen position
            Vector3d localSpacePoint = wpd.celestialBody.GetWorldSurfacePosition(wpd.waypoint.latitude, wpd.waypoint.longitude, wpd.waypoint.altitude);
            Vector3d scaledSpacePoint = ScaledSpace.LocalToScaledSpace(localSpacePoint);
            Vector3 screenPos = MapView.MapCamera.camera.WorldToScreenPoint(new Vector3((float)scaledSpacePoint.x, (float)scaledSpacePoint.y, (float)scaledSpacePoint.z));

            Rect markerRect = new Rect(screenPos.x - 15f, (float)Screen.height - screenPos.y - 45.0f, 30f, 45f);

            if (markerRect.Contains(Event.current.mousePosition))
            {
                selectedWaypoint = wpd.waypoint;
                windowPos = new Rect(markerRect.xMin - 97, markerRect.yMax + 12, 224, 60);
                waypointName = wpd.waypoint.name + (wpd.waypoint.isClustered ? (" " + StringUtilities.IntegerToGreek(wpd.waypoint.index)) : "");
                newClick = false;
            }
            else if (newClick)
            {
                selectedWaypoint = null;
            }
        }
        public void HandleClick(WaypointData wpd)
        {
            // Translate to screen position
            Vector3d localSpacePoint  = wpd.celestialBody.GetWorldSurfacePosition(wpd.waypoint.latitude, wpd.waypoint.longitude, wpd.waypoint.altitude);
            Vector3d scaledSpacePoint = ScaledSpace.LocalToScaledSpace(localSpacePoint);
            Vector3  screenPos        = MapView.MapCamera.camera.WorldToScreenPoint(new Vector3((float)scaledSpacePoint.x, (float)scaledSpacePoint.y, (float)scaledSpacePoint.z));

            Rect markerRect = new Rect(screenPos.x - 15f, (float)Screen.height - screenPos.y - 45.0f, 30f, 45f);

            if (markerRect.Contains(Event.current.mousePosition))
            {
                selectedWaypoint = wpd.waypoint;
                windowPos        = new Rect(markerRect.xMin - 97, markerRect.yMax + 12, 224, 60);
                waypointName     = wpd.waypoint.name + (wpd.waypoint.isClustered ? (" " + StringUtilities.IntegerToGreek(wpd.waypoint.index)) : "");
                newClick         = false;
            }
            else if (newClick)
            {
                selectedWaypoint = null;
            }
        }
Esempio n. 5
0
        void OnGUI()
        {
            // Build the cache of waypoint data
            if (Event.current.type == EventType.Layout)
            {
                WaypointData.CacheWaypointData();
            }

            if (!stylesSetup)
            {
                // Set up the label style
                labelStyle         = new GUIStyle(GUI.skin.label);
                labelStyle.padding = new RectOffset(0, 0, 0, 0);

                // Header buttons
                headerButtonStyle           = new GUIStyle(GUI.skin.button);
                headerButtonStyle.alignment = TextAnchor.MiddleLeft;
                headerButtonStyle.clipping  = TextClipping.Clip;

                // Headings
                headingStyle           = new GUIStyle(GUI.skin.label);
                headingStyle.fontStyle = FontStyle.Bold;

                // Tooltips
                tipStyle                  = new GUIStyle(GUI.skin.box);
                tipStyle.wordWrap         = true;
                tipStyle.stretchHeight    = true;
                tipStyle.normal.textColor = Color.white;

                stylesSetup = true;
            }

            GUI.depth = 0;

            if (showGUI && visible)
            {
                var ainfoV = Attribute.GetCustomAttribute(GetType().Assembly, typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute;
                Config.mainWindowPos = GUILayout.Window(
                    GetType().FullName.GetHashCode(),
                    Config.mainWindowPos,
                    WindowGUI,
                    "Waypoint Manager " + ainfoV.InformationalVersion);

                // Add the close icon
                if (GUI.Button(new Rect(Config.mainWindowPos.xMax - 18, Config.mainWindowPos.yMin + 2, 16, 16), Config.closeIcon, GUI.skin.label))
                {
                    showGUI = false;
                    HideSettings();
                }

                if (showSettings)
                {
                    // Default settings position
                    if (settingsPosition.xMin == settingsPosition.xMax)
                    {
                        settingsPosition = new Rect(Config.mainWindowPos.xMax + SETTINGS_WIDTH + 4 > Screen.width ?
                                                    Config.mainWindowPos.xMin - SETTINGS_WIDTH - 4: Config.mainWindowPos.xMax, Config.mainWindowPos.yMin, SETTINGS_WIDTH + 4, 1);
                    }

                    settingsPosition = GUILayout.Window(
                        GetType().FullName.GetHashCode() + 1,
                        settingsPosition,
                        SettingsGUI,
                        "Waypoint Manager Settings");

                    // Add the close icon
                    if (GUI.Button(new Rect(settingsPosition.xMax - 18, settingsPosition.yMin + 2, 16, 16), Config.closeIcon, GUI.skin.label))
                    {
                        HideSettings();
                    }
                }

                // Reset the position of the settings window
                if (!showSettings)
                {
                    settingsPosition.xMax = settingsPosition.xMin;
                }
            }

            // Display custom waypoint gui windows
            CustomWaypointGUI.OnGUI();

            // Draw any tooltips
            DrawToolTip();
        }
Esempio n. 6
0
        /// <summary>
        /// Caches the waypoint data.
        /// </summary>
        public static void CacheWaypointData()
        {
            if (lastCacheUpdate == UnityEngine.Time.fixedTime)
            {
                return;
            }
            lastCacheUpdate = UnityEngine.Time.fixedTime;

            bool changed = false;

            // Add new waypoints
            foreach (Waypoint w in WaypointManager.AllWaypoints())
            {
                if (w != null && w.isNavigatable)
                {
                    WaypointData wpd;

                    // Update values that are only cached once
                    if (!waypointData.ContainsKey(w))
                    {
                        wpd               = new WaypointData();
                        wpd.waypoint      = w;
                        wpd.celestialBody = Util.GetBody(w.celestialName);

                        // Shouldn't normally happens, but who knows (Util.GetBody will throw a warning)
                        if (wpd.celestialBody == null)
                        {
                            continue;
                        }

                        // Figure out the terrain height
                        wpd.waypoint.height = Util.WaypointHeight(w, wpd.celestialBody);

                        // Add to waypoint data
                        waypointData[w] = wpd;
                        changed         = true;
                    }
                    else
                    {
                        wpd = waypointData[w];
                    }

                    // Update values that change every frame
                    wpd.lastChecked = UnityEngine.Time.fixedTime;
                    if (FlightGlobals.ActiveVessel != null && wpd.celestialBody == FlightGlobals.ActiveVessel.mainBody)
                    {
                        wpd.distanceToActive = Util.GetDistanceToWaypoint(wpd);

                        // Get information about whether the waypoint is occluded
                        Vector3 pos = wpd.celestialBody.GetWorldSurfacePosition(wpd.waypoint.latitude, wpd.waypoint.longitude, wpd.waypoint.height + wpd.waypoint.altitude);
                        wpd.isOccluded = IsOccluded(wpd.celestialBody, FlightCamera.fetch.transform.position, pos, wpd.waypoint.height + wpd.waypoint.altitude);

                        Vector3 vHeading = FlightGlobals.ActiveVessel.transform.up;

                        double vesselLat = FlightGlobals.ActiveVessel.latitude / 180.0 * Math.PI;
                        double vesselLon = FlightGlobals.ActiveVessel.longitude / 180.0 * Math.PI;
                        double wpLat     = wpd.waypoint.latitude / 180.0 * Math.PI;
                        double wpLon     = wpd.waypoint.longitude / 180.0 * Math.PI;

                        double y = Math.Sin(wpLon - vesselLon) * Math.Cos(wpLat);
                        double x = (Math.Cos(vesselLat) * Math.Sin(wpLat)) - (Math.Sin(vesselLat) * Math.Cos(wpLat) * Math.Cos(wpLon - vesselLon));
                        double requiredHeading = Math.Atan2(y, x) * 180.0 / Math.PI;
                        wpd.heading = (requiredHeading + 360.0) % 360.0;
                    }
                }
            }

            // Remove unused waypoints
            foreach (KeyValuePair <Waypoint, WaypointData> p in waypointData.Where(p => p.Value.lastChecked != UnityEngine.Time.fixedTime).ToArray())
            {
                changed = true;
                waypointData.Remove(p.Key);
            }

            if (changed || customWaypoints.waypointByContract.Count != WaypointManager.customWaypoints.Count())
            {
                // Clear the by contract list
                foreach (ContractContainer cc in contractMap.Values)
                {
                    cc.waypointByContract.Clear();
                }
                customWaypoints.waypointByContract.Clear();

                // Rebuild the by contract list
                foreach (WaypointData wpd in waypointData.Values)
                {
                    if (wpd.waypoint.contractReference != null)
                    {
                        if (!contractMap.ContainsKey(wpd.waypoint.contractReference.ContractID))
                        {
                            contractMap[wpd.waypoint.contractReference.ContractID] = new ContractContainer(wpd.waypoint.contractReference);
                        }
                        contractMap[wpd.waypoint.contractReference.ContractID].waypointByContract.Add(wpd);
                    }
                    else
                    {
                        customWaypoints.waypointByContract.Add(wpd);
                    }
                }

                // Remove any unused contracts
                foreach (ContractContainer cc in contractMap.Values.ToList())
                {
                    if (cc.waypointByContract.Count == 0)
                    {
                        contractMap.Remove(cc.contract.ContractID);
                    }
                }


                // Rebuild the by Celestial Body list
                waypointByBody.Clear();
                foreach (WaypointData wpd in waypointData.Values)
                {
                    if (!waypointByBody.ContainsKey(wpd.celestialBody))
                    {
                        waypointByBody[wpd.celestialBody] = new List <WaypointData>();
                    }
                    waypointByBody[wpd.celestialBody].Add(wpd);
                }
            }
        }
        /// <summary>
        /// Caches the waypoint data.
        /// </summary>
        public static void CacheWaypointData()
        {
            if (lastCacheUpdate == UnityEngine.Time.fixedTime || FinePrint.WaypointManager.Instance() == null)
            {
                return;
            }
            lastCacheUpdate = UnityEngine.Time.fixedTime;

            bool changed = false;

            // Add new waypoints
            foreach (Waypoint w in FinePrint.WaypointManager.Instance().Waypoints)
            {
                if (w != null && w.isNavigatable)
                {
                    WaypointData wpd;

                    // Update values that are only cached once
                    if (!waypointData.ContainsKey(w))
                    {
                        wpd = new WaypointData();
                        wpd.waypoint = w;
                        wpd.celestialBody = Util.GetBody(w.celestialName);

                        // Shouldn't normally happens, but who knows (Util.GetBody will throw a warning)
                        if (wpd.celestialBody == null)
                        {
                            continue;
                        }

                        // Figure out the terrain height
                        wpd.waypoint.height = Util.WaypointHeight(w, wpd.celestialBody);

                        // Add to waypoint data
                        waypointData[w] = wpd;
                        changed = true;
                    }
                    else
                    {
                        wpd = waypointData[w];
                    }

                    // Update values that change every frame
                    wpd.lastChecked = UnityEngine.Time.fixedTime;
                    if (FlightGlobals.ActiveVessel != null && wpd.celestialBody == FlightGlobals.ActiveVessel.mainBody)
                    {
                        wpd.distanceToActive = Util.GetDistanceToWaypoint(wpd);

                        // Get information about whether the waypoint is occluded
                        Vector3 pos = wpd.celestialBody.GetWorldSurfacePosition(wpd.waypoint.latitude, wpd.waypoint.longitude, wpd.waypoint.height + wpd.waypoint.altitude);
                        wpd.isOccluded = IsOccluded(wpd.celestialBody, FlightCamera.fetch.transform.position, pos, wpd.waypoint.height + wpd.waypoint.altitude);

                        Vector3 vHeading = FlightGlobals.ActiveVessel.transform.up;

                        double vesselLat = FlightGlobals.ActiveVessel.latitude / 180.0 * Math.PI;
                        double vesselLon = FlightGlobals.ActiveVessel.longitude / 180.0 * Math.PI;
                        double wpLat = wpd.waypoint.latitude / 180.0 * Math.PI;
                        double wpLon = wpd.waypoint.longitude / 180.0 * Math.PI;

                        double y = Math.Sin(wpLon - vesselLon) * Math.Cos(wpLat);
                        double x = (Math.Cos(vesselLat) * Math.Sin(wpLat)) - (Math.Sin(vesselLat) * Math.Cos(wpLat) * Math.Cos(wpLon - vesselLon));
                        double requiredHeading = Math.Atan2(y, x) * 180.0 / Math.PI;
                        wpd.heading = (requiredHeading + 360.0) % 360.0;
                    }
                }
            }

            // Remove unused waypoints
            foreach (KeyValuePair<Waypoint, WaypointData> p in waypointData.Where(p => p.Value.lastChecked != UnityEngine.Time.fixedTime).ToArray())
            {
                changed = true;
                waypointData.Remove(p.Key);
            }

            if (changed || customWaypoints.waypointByContract.Count != FinePrint.WaypointManager.Instance().Waypoints.Count())
            {
                // Clear the by contract list
                foreach (ContractContainer cc in contractMap.Values)
                {
                    cc.waypointByContract.Clear();
                }
                customWaypoints.waypointByContract.Clear();

                // Rebuild the by contract list
                foreach (WaypointData wpd in waypointData.Values)
                {
                    if (wpd.waypoint.contractReference != null)
                    {
                        if (!contractMap.ContainsKey(wpd.waypoint.contractReference.ContractID))
                        {
                            contractMap[wpd.waypoint.contractReference.ContractID] = new ContractContainer(wpd.waypoint.contractReference);
                        }
                        contractMap[wpd.waypoint.contractReference.ContractID].waypointByContract.Add(wpd);
                    }
                    else
                    {
                        customWaypoints.waypointByContract.Add(wpd);
                    }
                }

                // Remove any unused contracts
                foreach (ContractContainer cc in contractMap.Values.ToList())
                {
                    if (cc.waypointByContract.Count == 0)
                    {
                        contractMap.Remove(cc.contract.ContractID);
                    }
                }

                // Rebuild the by Celestial Body list
                waypointByBody.Clear();
                foreach (WaypointData wpd in waypointData.Values)
                {
                    if (!waypointByBody.ContainsKey(wpd.celestialBody))
                    {
                        waypointByBody[wpd.celestialBody] = new List<WaypointData>();
                    }
                    waypointByBody[wpd.celestialBody].Add(wpd);
                }
            }
        }
        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);
                }
            }
        }
Esempio n. 9
0
        public static double GetStraightDistance(WaypointData wpd)
        {
            Vessel v = FlightGlobals.ActiveVessel;

            Vector3 wpPosition = wpd.celestialBody.GetWorldSurfacePosition(wpd.waypoint.latitude, wpd.waypoint.longitude, wpd.waypoint.height + wpd.waypoint.altitude);
            return Vector3.Distance(wpPosition, v.transform.position);
        }
Esempio n. 10
0
        /// <summary>
        /// Gets the lateral distance in meters from the active vessel to the given waypoint.
        /// </summary>
        /// <param name="wpd">Activated waypoint</param>
        /// <returns>Distance in meters</returns>
        public static double GetLateralDistance(WaypointData wpd)
        {
            Vessel v = FlightGlobals.ActiveVessel;
            CelestialBody celestialBody = v.mainBody;

            // Use the haversine formula to calculate great circle distance.
            double sin1 = Math.Sin(Math.PI / 180.0 * (v.latitude - wpd.waypoint.latitude) / 2);
            double sin2 = Math.Sin(Math.PI / 180.0 * (v.longitude - wpd.waypoint.longitude) / 2);
            double cos1 = Math.Cos(Math.PI / 180.0 * wpd.waypoint.latitude);
            double cos2 = Math.Cos(Math.PI / 180.0 * v.latitude);

            return 2 * (celestialBody.Radius + wpd.waypoint.height + wpd.waypoint.altitude) *
                Math.Asin(Math.Sqrt(sin1 * sin1 + cos1 * cos2 * sin2 * sin2));
        }
Esempio n. 11
0
        /// <summary>
        /// Gets the distance in meters from the active vessel to the given waypoint.
        /// </summary>
        /// <param name="wpd">Activated waypoint</param>
        /// <returns>Distance in meters</returns>
        public static double GetDistanceToWaypoint(WaypointData wpd)
        {
            Vessel v = FlightGlobals.ActiveVessel;
            CelestialBody celestialBody = v.mainBody;

            // Simple distance
            if (Config.distanceCalcMethod == Config.DistanceCalcMethod.STRAIGHT_LINE || celestialBody != wpd.celestialBody)
            {
                return GetStraightDistance(wpd);
            }

            // Use the haversine formula to calculate great circle distance.
            double sin1 = Math.Sin(Math.PI / 180.0 * (v.latitude - wpd.waypoint.latitude) / 2);
            double sin2 = Math.Sin(Math.PI / 180.0 * (v.longitude - wpd.waypoint.longitude) / 2);
            double cos1 = Math.Cos(Math.PI / 180.0 * wpd.waypoint.latitude);
            double cos2 = Math.Cos(Math.PI / 180.0 * v.latitude);

            double lateralDist = 2 * (celestialBody.Radius + wpd.waypoint.height + wpd.waypoint.altitude) *
                Math.Asin(Math.Sqrt(sin1 * sin1 + cos1 * cos2 * sin2 * sin2));
            double heightDist = Math.Abs(wpd.waypoint.altitude + wpd.waypoint.height - v.altitude);

            if (Config.distanceCalcMethod == Config.DistanceCalcMethod.LATERAL || heightDist <= lateralDist / 2.0)
            {
                return lateralDist;
            }
            else
            {
                // Get the ratio to use in our formula
                double x = (heightDist - lateralDist / 2.0) / lateralDist;

                // x / (x + 1) starts at 0 when x = 0, and increases to 1
                return (x / (x + 1)) * heightDist + lateralDist;
            }
        }
 protected GUIContent ContractIcon(WaypointData wpd)
 {
     Texture2D texture = Util.GetContractIcon(wpd.waypoint.id, wpd.waypoint.seed);
     return new GUIContent(texture, wpd.waypoint.contractReference != null ? wpd.waypoint.contractReference.Title : "No contract");
 }
        protected void WaypointLineGUI(WaypointData wpd)
        {
            if (!wpd.waypoint.visible)
            {
                return;
            }

            GUILayout.BeginHorizontal(GUILayout.Height(32));

            // Contract icon
            GUILayout.Label(ContractIcon(wpd), GUILayout.ExpandWidth(false), GUILayout.Height(38), GUILayout.Width(38));
            GUILayout.Space(2);

            // Celestial body icon
            GUILayout.Label(CelestialBodyIcon(wpd.celestialBody.name), GUILayout.ExpandWidth(false));
            GUILayout.Space(2);

            GUILayout.BeginVertical();

            // Waypoint name, distance
            GUILayout.BeginHorizontal();
            string name = wpd.waypoint.name;
            if (wpd.waypoint.isClustered)
            {
                name += " " + StringUtilities.IntegerToGreek(wpd.waypoint.index);
            }
            GUILayout.Label(name, labelStyle, GUILayout.Height(16), GUILayout.Width(GUI_WIDTH - 240), GUILayout.ExpandWidth(false));
            if (FlightGlobals.currentMainBody == wpd.celestialBody)
            {
                GUILayout.Label("Dist: " + Util.PrintDistance(wpd), labelStyle, GUILayout.Height(16), GUILayout.ExpandWidth(false));
            }
            GUILayout.EndHorizontal();

            // Waypoint location
            GUILayout.BeginHorizontal();
            GUILayout.Label("Lat: " + Util.FormatCoordinate(wpd.waypoint.latitude, true), labelStyle, GUILayout.Height(16), GUILayout.Width(GUI_WIDTH / 2.0f - 72.0f), GUILayout.ExpandWidth(false));
            GUILayout.Label("Lon: " + Util.FormatCoordinate(wpd.waypoint.longitude, false), labelStyle, GUILayout.Height(16), GUILayout.ExpandWidth(false));
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();
            GUILayout.FlexibleSpace();

            if (CustomWaypoints.Instance.IsCustom(wpd.waypoint))
            {
                GUILayout.BeginVertical();
                GUILayout.Space(8);
                GUILayout.BeginHorizontal();

                if (GUILayout.Button(new GUIContent(Config.editWaypointIcon, "Edit Waypoint"), GUI.skin.label))
                {
                    CustomWaypointGUI.EditWaypoint(wpd.waypoint);
                }
                if (GUILayout.Button(new GUIContent(Config.deleteWaypointIcon, "Delete Waypoint"), GUI.skin.label))
                {
                    CustomWaypointGUI.DeleteWaypoint(wpd.waypoint);
                }

                GUILayout.EndHorizontal();
                GUILayout.EndVertical();
            }

            // Active waypoint toggle
            GUILayout.BeginVertical();
            GUILayout.Space(8);
            bool isNavPoint = Util.IsNavPoint(wpd.waypoint);
            if (GUILayout.Toggle(isNavPoint, (string)null) != isNavPoint)
            {
                if (isNavPoint)
                {
                    NavWaypoint.fetch.Clear();
                    NavWaypoint.fetch.Deactivate();
                }
                else
                {
                    NavWaypoint.fetch.Setup(wpd.waypoint);
                    NavWaypoint.fetch.Activate();
                }
            }
            GUILayout.EndVertical();

            GUILayout.EndHorizontal();

            GUILayout.Space(6);
        }
        protected void WaypointLineGUI(WaypointData wpd)
        {
            GUILayout.BeginHorizontal(GUILayout.Height(32));

            // Contract icon
            GUILayout.Label(ContractIcon(wpd), GUILayout.ExpandWidth(false), GUILayout.Height(38));
            GUILayout.Space(2);

            // Celestial body icon
            GUILayout.Label(CelestialBodyIcon(wpd.celestialBody.name), GUILayout.ExpandWidth(false));
            GUILayout.Space(2);

            GUILayout.BeginVertical();

            // Waypoint name
            string name = wpd.waypoint.name;
            if (wpd.waypoint.isClustered)
            {
                name += " " + StringUtilities.IntegerToGreek(wpd.waypoint.index);
            }
            GUILayout.Label(name, labelStyle, GUILayout.Height(16), GUILayout.ExpandWidth(false));

            // Waypoint distance
            GUILayout.Label("Distance: " + Util.PrintDistance(wpd), labelStyle, GUILayout.Height(16), GUILayout.ExpandWidth(false));

            GUILayout.EndVertical();
            GUILayout.FlexibleSpace();

            if (CustomWaypoints.Instance.IsCustom(wpd.waypoint))
            {
                GUILayout.BeginVertical();
                GUILayout.Space(8);
                GUILayout.BeginHorizontal();

                if (GUILayout.Button(new GUIContent(Config.editWaypointIcon, "Edit Waypoint"), GUI.skin.label))
                {
                    CustomWaypointGUI.EditWaypoint(wpd.waypoint);
                }
                if (GUILayout.Button(new GUIContent(Config.deleteWaypointIcon, "Delete Waypoint"), GUI.skin.label))
                {
                    CustomWaypointGUI.DeleteWaypoint(wpd.waypoint);
                }

                GUILayout.EndHorizontal();
                GUILayout.EndVertical();
            }

            // Active waypoint toggle
            GUILayout.BeginVertical();
            GUILayout.Space(8);
            bool isNavPoint = Util.IsNavPoint(wpd.waypoint);
            if (GUILayout.Toggle(isNavPoint, (string)null) != isNavPoint)
            {
                if (isNavPoint)
                {
                    FinePrint.WaypointManager.clearNavPoint();
                }
                else
                {
                    FinePrint.WaypointManager.setupNavPoint(wpd.waypoint);
                    FinePrint.WaypointManager.activateNavPoint();
                }
            }
            GUILayout.EndVertical();

            GUILayout.EndHorizontal();

            GUILayout.Space(6);
        }
        protected void WaypointLineGUI(WaypointData wpd)
        {
            GUILayout.BeginHorizontal(GUILayout.Height(32));

            // Contract icon
            GUILayout.Label(ContractIcon(wpd), GUILayout.ExpandWidth(false), GUILayout.Height(38));
            GUILayout.Space(2);

            // Celestial body icon
            GUILayout.Label(CelestialBodyIcon(wpd.celestialBody.name), GUILayout.ExpandWidth(false));
            GUILayout.Space(2);

            GUILayout.BeginVertical();

            // Waypoint name
            string name = wpd.waypoint.name;

            if (wpd.waypoint.isClustered)
            {
                name += " " + StringUtilities.IntegerToGreek(wpd.waypoint.index);
            }
            GUILayout.Label(name, labelStyle, GUILayout.Height(16), GUILayout.ExpandWidth(false));

            // Waypoint distance
            GUILayout.Label("Distance: " + Util.PrintDistance(wpd), labelStyle, GUILayout.Height(16), GUILayout.ExpandWidth(false));

            GUILayout.EndVertical();
            GUILayout.FlexibleSpace();

            if (CustomWaypoints.Instance.IsCustom(wpd.waypoint))
            {
                GUILayout.BeginVertical();
                GUILayout.Space(8);
                GUILayout.BeginHorizontal();

                if (GUILayout.Button(new GUIContent(Config.editWaypointIcon, "Edit Waypoint"), GUI.skin.label))
                {
                    CustomWaypointGUI.EditWaypoint(wpd.waypoint);
                }
                if (GUILayout.Button(new GUIContent(Config.deleteWaypointIcon, "Delete Waypoint"), GUI.skin.label))
                {
                    CustomWaypointGUI.DeleteWaypoint(wpd.waypoint);
                }

                GUILayout.EndHorizontal();
                GUILayout.EndVertical();
            }

            // Active waypoint toggle
            GUILayout.BeginVertical();
            GUILayout.Space(8);
            bool isNavPoint = Util.IsNavPoint(wpd.waypoint);

            if (GUILayout.Toggle(isNavPoint, (string)null) != isNavPoint)
            {
                if (isNavPoint)
                {
                    FinePrint.WaypointManager.clearNavPoint();
                }
                else
                {
                    FinePrint.WaypointManager.setupNavPoint(wpd.waypoint);
                    FinePrint.WaypointManager.activateNavPoint();
                }
            }
            GUILayout.EndVertical();

            GUILayout.EndHorizontal();

            GUILayout.Space(6);
        }
Esempio n. 16
0
        protected void WaypointLineGUI(WaypointData wpd)
        {
            if (!wpd.waypoint.visible)
            {
                return;
            }

            GUILayout.BeginHorizontal(GUILayout.Height(32));

            // Contract icon
            GUILayout.Label(ContractIcon(wpd), GUILayout.ExpandWidth(false), GUILayout.Height(38), GUILayout.Width(38));
            GUILayout.Space(2);

            // Celestial body icon
            GUILayout.Label(CelestialBodyIcon(wpd.celestialBody.name), GUILayout.ExpandWidth(false));
            GUILayout.Space(2);

            GUILayout.BeginVertical();

            // Waypoint name, distance
            GUILayout.BeginHorizontal();
            string name = wpd.waypoint.name;

            if (wpd.waypoint.isClustered)
            {
                name += " " + StringUtilities.IntegerToGreek(wpd.waypoint.index);
            }
            GUILayout.Label(name, labelStyle, GUILayout.Height(16), GUILayout.Width(GUI_WIDTH - 240), GUILayout.ExpandWidth(false));
            if (FlightGlobals.currentMainBody == wpd.celestialBody)
            {
                GUILayout.Label("Dist: " + Util.PrintDistance(wpd), labelStyle, GUILayout.Height(16), GUILayout.ExpandWidth(false));
            }
            GUILayout.EndHorizontal();

            // Waypoint location
            GUILayout.BeginHorizontal();
            GUILayout.Label("Lat: " + Util.FormatCoordinate(wpd.waypoint.latitude, true), labelStyle, GUILayout.Height(16), GUILayout.Width(GUI_WIDTH / 2.0f - 72.0f), GUILayout.ExpandWidth(false));
            GUILayout.Label("Lon: " + Util.FormatCoordinate(wpd.waypoint.longitude, false), labelStyle, GUILayout.Height(16), GUILayout.ExpandWidth(false));
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();
            GUILayout.FlexibleSpace();

            if (CustomWaypoints.Instance.IsCustom(wpd.waypoint))
            {
                GUILayout.BeginVertical();
                GUILayout.Space(8);
                GUILayout.BeginHorizontal();

                if (GUILayout.Button(new GUIContent(Config.editWaypointIcon, "Edit Waypoint"), GUI.skin.label))
                {
                    CustomWaypointGUI.EditWaypoint(wpd.waypoint);
                }
                if (GUILayout.Button(new GUIContent(Config.deleteWaypointIcon, "Delete Waypoint"), GUI.skin.label))
                {
                    CustomWaypointGUI.DeleteWaypoint(wpd.waypoint);
                }

                GUILayout.EndHorizontal();
                GUILayout.EndVertical();
            }

            // Active waypoint toggle
            GUILayout.BeginVertical();
            GUILayout.Space(8);
            bool isNavPoint = Util.IsNavPoint(wpd.waypoint);

            if (GUILayout.Toggle(isNavPoint, (string)null) != isNavPoint)
            {
                if (isNavPoint)
                {
                    NavWaypoint.fetch.Clear();
                    NavWaypoint.fetch.Deactivate();
                }
                else
                {
                    NavWaypoint.fetch.Setup(wpd.waypoint);
                    NavWaypoint.fetch.Activate();
                }
            }
            GUILayout.EndVertical();

            GUILayout.EndHorizontal();

            GUILayout.Space(6);
        }
Esempio n. 17
0
        protected GUIContent ContractIcon(WaypointData wpd)
        {
            Texture2D texture = Util.GetContractIcon(wpd.waypoint.id, wpd.waypoint.seed);

            return(new GUIContent(texture, wpd.waypoint.contractReference != null ? wpd.waypoint.contractReference.Title : "No contract"));
        }
Esempio n. 18
0
        /// <summary>
        /// Gets the printable distance to the waypoint.
        /// </summary>
        /// <param name="wpd">WaypointData object</param>
        /// <returns>The distance and unit for screen output</returns>
        public static string PrintDistance(WaypointData wpd)
        {
            int unit = 0;
            double distance = wpd.distanceToActive;
            while (unit < 4 && distance >= 10000.0)
            {
                distance /= 1000.0;
                unit++;
            }

            return distance.ToString("N1") + " " + UNITS[unit];
        }
        /// <summary>
        /// Calculates the time to the distance based on the vessels srfSpeed and transform it to a readable string.
        /// </summary>
        /// <param name="waypoint">The waypoint</param>
        /// <param name="distance">Distance in meters</param>
        /// <returns></returns>
        protected string GetTimeToWaypoint(WaypointData wpd)
        {
            Vessel v = FlightGlobals.ActiveVessel;

            if (v.srfSpeed < 0.1)
            {
                return(null);
            }

            double time = (wpd.distanceToActive / v.horizontalSrfSpeed);

            // Earthtime
            uint SecondsPerYear   = 31536000; // = 365d
            uint SecondsPerDay    = 86400;    // = 24h
            uint SecondsPerHour   = 3600;     // = 60m
            uint SecondsPerMinute = 60;       // = 60s

            if (GameSettings.KERBIN_TIME == true)
            {
                SecondsPerYear   = 9201600; // = 426d
                SecondsPerDay    = 21600;   // = 6h
                SecondsPerHour   = 3600;    // = 60m
                SecondsPerMinute = 60;      // = 60s
            }

            int years = (int)(time / SecondsPerYear);

            time -= years * SecondsPerYear;

            int days = (int)(time / SecondsPerDay);

            time -= days * SecondsPerDay;

            int hours = (int)(time / SecondsPerHour);

            time -= hours * SecondsPerHour;

            int minutes = (int)(time / SecondsPerMinute);

            time -= minutes * SecondsPerMinute;

            int seconds = (int)(time);

            string output = "";

            if (years != 0)
            {
                output += years + "y";
            }
            if (days != 0)
            {
                if (output.Length != 0)
                {
                    output += ", ";
                }
                output += days + "d";
            }
            if (hours != 0 || minutes != 0 || seconds != 0 || output.Length == 0)
            {
                if (output.Length != 0)
                {
                    output += ", ";
                }
                output += hours.ToString("D2") + ":" + minutes.ToString("D2") + ":" + seconds.ToString("D2");
            }

            return(output);
        }
        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);
                }
            }
        }
        public void OnGUI()
        {
            if (visible)
            {
                if (Event.current.type == EventType.MouseUp && Event.current.button == 0)
                {
                    newClick = true;
                }

                if (HighLogic.LoadedSceneIsFlight || HighLogic.LoadedScene == GameScenes.TRACKSTATION)
                {
                    // Draw the marker for custom waypoints that are currently being created
                    CustomWaypointGUI.DrawMarker();

                    // Draw waypoints if not in career mode
                    if (ContractSystem.Instance == null && MapView.MapIsEnabled)
                    {
                        foreach (WaypointData wpd in WaypointData.Waypoints)
                        {
                            if (wpd.celestialBody != null && wpd.waypoint.celestialName == wpd.celestialBody.name)
                            {
                                if (Event.current.type == EventType.Repaint)
                                {
                                    wpd.SetAlpha();
                                    Util.DrawWaypoint(wpd.celestialBody, wpd.waypoint.latitude, wpd.waypoint.longitude,
                                                      wpd.waypoint.altitude, wpd.waypoint.id, wpd.waypoint.seed, wpd.currentAlpha);
                                }

                                // Handling clicking on the waypoint
                                if (Event.current.type == EventType.MouseUp && Event.current.button == 0)
                                {
                                    HandleClick(wpd);
                                }

                                // Draw hint text
                                if (Event.current.type == EventType.Repaint)
                                {
                                    HintText(wpd);
                                }
                            }
                        }
                    }
                }

                if (HighLogic.LoadedSceneIsFlight && !MapView.MapIsEnabled)
                {
                    SetupStyles();

                    WaypointData.CacheWaypointData();

                    foreach (WaypointData wpd in WaypointData.Waypoints)
                    {
                        DrawWaypoint(wpd);
                    }
                }

                if (HighLogic.LoadedSceneIsFlight && (!MapView.MapIsEnabled || ContractSystem.Instance == null))
                {
                    ShowNavigationWindow();
                }
            }
        }
        /// <summary>
        /// Calculates the time to the distance based on the vessels srfSpeed and transform it to a readable string.
        /// </summary>
        /// <param name="waypoint">The waypoint</param>
        /// <param name="distance">Distance in meters</param>
        /// <returns></returns>
        protected string GetTimeToWaypoint(WaypointData wpd)
        {
            Vessel v = FlightGlobals.ActiveVessel;
            if (v.srfSpeed < 0.1)
            {
                return null;
            }

            double time = (wpd.distanceToActive / v.horizontalSrfSpeed);

            // Earthtime
            uint SecondsPerYear = 31536000; // = 365d
            uint SecondsPerDay = 86400;     // = 24h
            uint SecondsPerHour = 3600;     // = 60m
            uint SecondsPerMinute = 60;     // = 60s

            if (GameSettings.KERBIN_TIME == true)
            {
                SecondsPerYear = 9201600;  // = 426d
                SecondsPerDay = 21600;     // = 6h
                SecondsPerHour = 3600;     // = 60m
                SecondsPerMinute = 60;     // = 60s
            }

            int years = (int)(time / SecondsPerYear);
            time -= years * SecondsPerYear;

            int days = (int)(time / SecondsPerDay);
            time -= days * SecondsPerDay;

            int hours = (int)(time / SecondsPerHour);
            time -= hours * SecondsPerHour;

            int minutes = (int)(time / SecondsPerMinute);
            time -= minutes * SecondsPerMinute;

            int seconds = (int)(time);

            string output = "";
            if (years != 0)
            {
                output += years + "y";
            }
            if (days != 0)
            {
                if (output.Length != 0) output += ", ";
                output += days + "d";
            }
            if (hours != 0 || minutes != 0 || seconds != 0 || output.Length == 0)
            {
                if (output.Length != 0) output += ", ";
                output += hours.ToString("D2") + ":" + minutes.ToString("D2") + ":" + seconds.ToString("D2");
            }

            return output;
        }