예제 #1
0
        /// <summary>
        /// Whether this vessel meets the parameter condition.
        /// </summary>
        /// <param name="vessel">The vessel to check</param>
        /// <returns>Whether the vessel meets the condition</returns>
        protected override bool VesselMeetsCondition(Vessel vessel)
        {
            LoggingUtil.LogVerbose(this, "Checking VesselMeetsCondition: " + vessel.id);

            // Not even close
            if (vessel.mainBody.name != waypoint.celestialName)
            {
                return(false);
            }

            // Default distance
            if (distance == 0.0)
            {
                if (waypoint.isOnSurface)
                {
                    distance = 500.0;
                }
                else
                {
                    distance = Math.Max(1000.0, waypoint.altitude / 5.0);
                }
            }

            // Calculate the distance
            double actualDistance = WaypointUtil.GetDistanceToWaypoint(vessel, waypoint, ref height);

            LoggingUtil.LogVerbose(this, "Distance to waypoint '" + waypoint.name + "': " + actualDistance);
            return(actualDistance <= distance);
        }
        public void Initialize()
        {
            if (!initialized)
            {
                LoggingUtil.LogVerbose(this, "Initializing waypoint generator.");
                foreach (WaypointData wpData in waypoints)
                {
                    CelestialBody body = FlightGlobals.Bodies.Where <CelestialBody>(b => b.name == wpData.waypoint.celestialName).FirstOrDefault();
                    if (body == null)
                    {
                        continue;
                    }

                    // Do type-specific waypoint handling
                    if (wpData.type == "RANDOM_WAYPOINT")
                    {
                        LoggingUtil.LogVerbose(this, "   Generating a random waypoint...");

                        while (true)
                        {
                            // Generate the position
                            WaypointManager.ChooseRandomPosition(out wpData.waypoint.latitude, out wpData.waypoint.longitude,
                                                                 wpData.waypoint.celestialName, wpData.waterAllowed, wpData.forceEquatorial, random);

                            // Force a water waypoint
                            if (wpData.underwater)
                            {
                                Vector3d radialVector = QuaternionD.AngleAxis(wpData.waypoint.longitude, Vector3d.down) *
                                                        QuaternionD.AngleAxis(wpData.waypoint.latitude, Vector3d.forward) * Vector3d.right;
                                if (body.pqsController.GetSurfaceHeight(radialVector) - body.pqsController.radius >= 0.0)
                                {
                                    continue;
                                }
                            }
                            break;
                        }
                    }
                    else if (wpData.type == "RANDOM_WAYPOINT_NEAR")
                    {
                        Waypoint nearWaypoint = waypoints[wpData.nearIndex].waypoint;

                        LoggingUtil.LogVerbose(this, "   Generating a random waypoint near waypoint " + nearWaypoint.name + "...");

                        // TODO - this is really bad, we need to implement this method ourselves...
                        do
                        {
                            WaypointManager.ChooseRandomPositionNear(out wpData.waypoint.latitude, out wpData.waypoint.longitude,
                                                                     nearWaypoint.latitude, nearWaypoint.longitude, wpData.waypoint.celestialName,
                                                                     wpData.maxDistance, wpData.waterAllowed, random);

                            // Force a water waypoint
                            if (wpData.underwater)
                            {
                                Vector3d radialVector = QuaternionD.AngleAxis(wpData.waypoint.longitude, Vector3d.down) *
                                                        QuaternionD.AngleAxis(wpData.waypoint.latitude, Vector3d.forward) * Vector3d.right;
                                if (body.pqsController.GetSurfaceHeight(radialVector) - body.pqsController.radius >= 0.0)
                                {
                                    continue;
                                }
                            }
                        } while (WaypointUtil.GetDistance(wpData.waypoint.latitude, wpData.waypoint.longitude, nearWaypoint.latitude, nearWaypoint.longitude,
                                                          body.Radius) < wpData.minDistance);
                    }
                    else if (wpData.type == "PQS_CITY")
                    {
                        GeneratePQSCityCoordinates(wpData, body);
                    }

                    // Set altitude
                    SetAltitude(wpData, body);

                    LoggingUtil.LogVerbose(this, "   Generated waypoint " + wpData.waypoint.name + " at " +
                                           wpData.waypoint.latitude + ", " + wpData.waypoint.longitude + ".");
                }

                initialized = true;
                LoggingUtil.LogVerbose(this, "Waypoint generator initialized.");
            }
        }
예제 #3
0
        /// <summary>
        /// Whether this vessel meets the parameter condition.
        /// </summary>
        /// <param name="vessel">The vessel to check</param>
        /// <returns>Whether the vessel meets the condition</returns>
        protected override bool VesselMeetsCondition(Vessel vessel)
        {
            LoggingUtil.LogVerbose(this, "Checking VesselMeetsCondition: " + vessel.id);

            // Make sure we have a waypoint
            if (waypoint == null && Root != null)
            {
                waypoint = FetchWaypoint(Root, true);
            }
            if (waypoint == null)
            {
                return(false);
            }

            // Not even close
            if (vessel.mainBody.name != waypoint.celestialName)
            {
                return(false);
            }

            // Default distance
            if (distance == 0.0 && horizontalDistance == 0.0)
            {
                // Close to the surface
                if (waypoint.altitude < 25.0)
                {
                    distance = 500.0;
                }
                else
                {
                    distance = Math.Max(1000.0, waypoint.altitude / 5.0);
                }
            }

            // Calculate the distance
            bool check = false;

            if (distance != 0.0)
            {
                double actualDistance = WaypointUtil.GetDistanceToWaypoint(vessel, waypoint, ref height);
                LoggingUtil.LogVerbose(this, "Distance to waypoint '" + waypoint.name + "': " + actualDistance);
                check = actualDistance <= distance;
            }
            else
            {
                double actualDistance = WaypointUtil.GetDistance(vessel.latitude, vessel.longitude, waypoint.latitude, waypoint.longitude, vessel.altitude);
                LoggingUtil.LogVerbose(this, "Horizontal distance to waypoint '" + waypoint.name + "': " + actualDistance);
                check = actualDistance <= horizontalDistance;
            }

            // Output the message for entering/leaving the waypoint area.
            if (showMessages)
            {
                if (check ^ nearWaypoint)
                {
                    nearWaypoint = check;
                    string waypointName = waypoint.name + (waypoint.isClustered ? " " + StringUtilities.IntegerToGreek(waypoint.index) : "");
                    string msg          = "You are " + (nearWaypoint ? "entering " : "leaving ") + waypointName + ".";
                    ScreenMessages.PostScreenMessage(msg, 5.0f, ScreenMessageStyle.UPPER_CENTER);
                }

                NavWaypoint navWaypoint = NavWaypoint.fetch;
                if (navWaypoint != null && navWaypoint.Latitude == waypoint.latitude && navWaypoint.Longitude == waypoint.longitude)
                {
                    navWaypoint.IsBlinking = nearWaypoint;
                }
            }

            return(check);
        }
예제 #4
0
        protected override void OnOffered()
        {
            System.Random random = new System.Random(contract.MissionSeed);

            int index = 0;

            foreach (WaypointData wpData in waypoints)
            {
                // Do type-specific waypoint handling
                if (wpData.type == "RANDOM_WAYPOINT")
                {
                    // Generate the position
                    WaypointManager.ChooseRandomPosition(out wpData.waypoint.latitude, out wpData.waypoint.longitude,
                                                         wpData.waypoint.celestialName, wpData.waterAllowed, wpData.forceEquatorial, random);
                }
                else if (wpData.type == "RANDOM_WAYPOINT_NEAR")
                {
                    CelestialBody body         = FlightGlobals.Bodies.Where(b => b.name == wpData.waypoint.celestialName).First();
                    Waypoint      nearWaypoint = waypoints[wpData.nearIndex].waypoint;
                    // TODO - this is really bad, we need to implement this method ourselves...
                    do
                    {
                        WaypointManager.ChooseRandomPositionNear(out wpData.waypoint.latitude, out wpData.waypoint.longitude,
                                                                 nearWaypoint.latitude, nearWaypoint.longitude, wpData.waypoint.celestialName,
                                                                 wpData.maxDistance, wpData.waterAllowed, random);
                    } while (WaypointUtil.GetDistance(wpData.waypoint.latitude, wpData.waypoint.longitude, nearWaypoint.latitude, nearWaypoint.longitude,
                                                      body.Radius) < wpData.minDistance);
                }
                else if (wpData.type == "PQS_CITY")
                {
                    CelestialBody body     = FlightGlobals.Bodies.Where(b => b.name == wpData.waypoint.celestialName).First();
                    Vector3d      position = wpData.pqsCity.transform.position;

                    // Translate by the PQS offset (inverse transform of coordinate system)
                    Vector3d v         = wpData.pqsOffset;
                    Vector3d i         = wpData.pqsCity.transform.right;
                    Vector3d j         = wpData.pqsCity.transform.forward;
                    Vector3d k         = wpData.pqsCity.transform.up;
                    Vector3d offsetPos = new Vector3d(
                        (j.y * k.z - j.z * k.y) * v.x + (i.z * k.y - i.y * k.z) * v.y + (i.y * j.z - i.z * j.y) * v.z,
                        (j.z * k.x - j.x * k.z) * v.x + (i.x * k.z - i.z * k.x) * v.y + (i.z * j.x - i.x * j.z) * v.z,
                        (j.x * k.y - j.y * k.x) * v.x + (i.y * k.x - i.x * k.y) * v.y + (i.x * j.y - i.y * j.x) * v.z
                        );
                    offsetPos *= (i.x * j.y * k.z) + (i.y * j.z * k.x) + (i.z * j.x * k.y) - (i.z * j.y * k.x) - (i.y * j.x * k.z) - (i.x * j.z * k.y);
                    wpData.waypoint.latitude  = body.GetLatitude(position + offsetPos);
                    wpData.waypoint.longitude = body.GetLongitude(position + offsetPos);
                }

                // Set altitude
                if (wpData.randomAltitude)
                {
                    CelestialBody body = FlightGlobals.Bodies.Where <CelestialBody>(b => b.name == wpData.waypoint.celestialName).First();
                    if (body.atmosphere)
                    {
                        wpData.waypoint.altitude = random.NextDouble() * (body.atmosphereDepth);
                    }
                    else
                    {
                        wpData.waypoint.altitude = 0.0;
                    }
                }

                // Set name
                if (string.IsNullOrEmpty(wpData.waypoint.name))
                {
                    CelestialBody body = FlightGlobals.Bodies.Where <CelestialBody>(b => b.name == wpData.waypoint.celestialName).First();
                    wpData.waypoint.name = StringUtilities.GenerateSiteName(contract.MissionSeed + index++, body, !wpData.waterAllowed);
                }

                if (!wpData.hidden && (string.IsNullOrEmpty(wpData.parameter) || contract.AllParameters.
                                       Where(p => p.ID == wpData.parameter && p.State == ParameterState.Complete).Any()))
                {
                    AddWayPoint(wpData.waypoint);
                }
            }
        }