Exemplo n.º 1
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);
                }
            }
        }