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); } }
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; } }
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(); }
/// <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); } } }
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); }
/// <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)); }
/// <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); }
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 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")); }
/// <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; }