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