private Coordinates?GetLandCoordinates( SpawnPointType[] validTypes, Coordinates distanceOrigin1, MinMaxD distanceFrom1, Coordinates?distanceOrigin2 = null, MinMaxD?distanceFrom2 = null, Coalition?coalition = null ) { var validSP = (from DBEntryTheaterSpawnPoint pt in SpawnPoints where validTypes.Contains(pt.PointType) select pt); Coordinates?[] distanceOrigin = new Coordinates?[] { distanceOrigin1, distanceOrigin2 }; MinMaxD?[] distanceFrom = new MinMaxD?[] { distanceFrom1, distanceFrom2 }; for (int i = 0; i < 2; i++) // Remove spawn points too far or too close from distanceOrigin1 and distanceOrigin2 { if (validSP.Count() == 0) { return(null); } if (!distanceFrom[i].HasValue || !distanceOrigin[i].HasValue) { continue; } var searchRange = distanceFrom[i].Value * Toolbox.NM_TO_METERS; // convert distance to meters IEnumerable <DBEntryTheaterSpawnPoint> validSPInRange = (from DBEntryTheaterSpawnPoint s in validSP select s); int iterationsLeft = MAX_RADIUS_SEARCH_ITERATIONS; do { Coordinates origin = distanceOrigin[i].Value; validSPInRange = (from DBEntryTheaterSpawnPoint s in validSP where searchRange.Contains(origin.GetDistanceFrom(s.Coordinates)) && CheckNotInHostileCoords(s.Coordinates, coalition) select s); searchRange = new MinMaxD(searchRange.Min * 0.9, Math.Max(100, searchRange.Max * 1.1)); validSP = (from DBEntryTheaterSpawnPoint s in validSPInRange select s); iterationsLeft--; } while ((validSPInRange.Count() == 0) && (iterationsLeft > 0)); } if (validSP.Count() == 0) { return(null); } DBEntryTheaterSpawnPoint selectedSpawnPoint = Toolbox.RandomFrom(validSP.ToArray()); SpawnPoints.Remove(selectedSpawnPoint); // Remove spawn point so it won't be used again return(selectedSpawnPoint.Coordinates); }
/// <summary> /// Gets a random spawn point around a given point. /// </summary> /// <param name="validTypes">Valid spawn point types</param> /// <param name="distanceOrigin1">Origin point distance must be computed from</param> /// <param name="distanceFrom1">Min/max distance from origin point, in nautical miles</param> /// <param name="distanceOrigin2">Second origin point distance must be computed from</param> /// <param name="distanceFrom2">Min/max distance from second origin point, in nautical miles</param> /// <param name="coalition">Which coalition should the spawn point belong to?</param> /// <returns>A spawn point, or null if none found matching the provided criteria</returns> public DBEntryTheaterSpawnPoint?GetRandomSpawnPoint( TheaterLocationSpawnPointType[] validTypes = null, Coordinates?distanceOrigin1 = null, MinMaxD?distanceFrom1 = null, Coordinates?distanceOrigin2 = null, MinMaxD?distanceFrom2 = null, Coalition?coalition = null) { // Select all spoint points IEnumerable <DBEntryTheaterSpawnPoint> validSP = from DBEntryTheaterSpawnPoint pt in SpawnPoints select pt; if (validTypes != null) // Remove spawn points of invalid types { validSP = (from DBEntryTheaterSpawnPoint pt in validSP where validTypes.Contains(pt.PointType) select pt); } if (coalition.HasValue) // Select spawn points belonging to the proper coalition { IEnumerable <DBEntryTheaterSpawnPoint> coalitionValidSP = coalitionValidSP = (from DBEntryTheaterSpawnPoint sp in validSP where sp.Coalition == coalition.Value select sp); // At least one spawn point found, only use SP for the preferred coalition if (coalitionValidSP.Count() > 0) { validSP = coalitionValidSP; } } Coordinates?[] distanceOrigin = new Coordinates?[] { distanceOrigin1, distanceOrigin2 }; MinMaxD?[] distanceFrom = new MinMaxD?[] { distanceFrom1, distanceFrom2 }; for (int i = 0; i < 2; i++) // Remove spawn points too far or too close from distanceOrigin1 and distanceOrigin2 { if (validSP.Count() == 0) { return(null); } if (!distanceFrom[i].HasValue || !distanceOrigin[i].HasValue) { continue; } MinMaxD searchRange = distanceFrom[i].Value * Toolbox.NM_TO_METERS; // convert distance to meters IEnumerable <DBEntryTheaterSpawnPoint> validSPInRange = (from DBEntryTheaterSpawnPoint s in validSP select s); int iterationsLeft = MAX_RADIUS_SEARCH_ITERATIONS; do { Coordinates origin = distanceOrigin[i].Value; validSPInRange = (from DBEntryTheaterSpawnPoint s in validSP where searchRange.Contains(origin.GetDistanceFrom(s.Coordinates)) select s); searchRange = new MinMaxD(searchRange.Min * 0.9, Math.Max(100, searchRange.Max * 1.1)); iterationsLeft--; } while ((validSPInRange.Count() == 0) && (iterationsLeft > 0)); validSP = (from DBEntryTheaterSpawnPoint s in validSPInRange select s); } if (validSP.Count() == 0) { return(null); } DBEntryTheaterSpawnPoint selectedSpawnPoint = Toolbox.RandomFrom(validSP.ToArray()); SpawnPoints.Remove(selectedSpawnPoint); // Remove spawn point so it won't be used again return(selectedSpawnPoint); }