Esempio n. 1
0
        /// <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);
        }
Esempio n. 2
0
        /// <summary>
        /// Picks a starting airbase for the player(s)
        /// </summary>
        /// <param name="mission">Mission for which the starting airbase must be set</param>
        /// <param name="template">Mission template to use</param>
        /// <param name="theaterDB">Theater database entry</param>
        /// <param name="lastCoordinates">Last location for referance</param>
        /// <param name="distance">Base Distance Range</param>
        /// <param name="first">is first objective</param>
        /// <returns>Information about the starting airbase</returns>
        public DBEntryTheaterAirbase SelectObjectiveAirbase(DCSMission mission, MissionTemplate template, DBEntryTheater theaterDB, Coordinates lastCoordinates, MinMaxD distance, bool first = false)
        {
            List <DBEntryTheaterAirbase> airbasesList = new List <DBEntryTheaterAirbase>();

            // Select all airbases with enough parking spots, trying to match the preferred coalition for enemy unit location, if any
            if ((template.OptionsTheaterCountriesCoalitions == CountryCoalition.AllBlue) || (template.OptionsTheaterCountriesCoalitions == CountryCoalition.AllRed) ||
                (template.OptionsEnemyUnitsLocation == SpawnPointPreferredCoalition.Any))
            {
                airbasesList.AddRange((from DBEntryTheaterAirbase ab in theaterDB.Airbases where ab.ParkingSpots.Length >= Toolbox.MAXIMUM_FLIGHT_GROUP_SIZE select ab).ToArray());
            }
            else
            {
                Coalition preferredCoalition;

                if (template.OptionsEnemyUnitsLocation == SpawnPointPreferredCoalition.Blue)
                {
                    preferredCoalition = (template.OptionsTheaterCountriesCoalitions == CountryCoalition.Inverted) ? Coalition.Red : Coalition.Blue;
                }
                else
                {
                    preferredCoalition = (template.OptionsTheaterCountriesCoalitions == CountryCoalition.Inverted) ? Coalition.Blue : Coalition.Red;
                }

                airbasesList.AddRange(
                    (from DBEntryTheaterAirbase ab in theaterDB.Airbases where ab.ParkingSpots.Length >= Toolbox.MAXIMUM_FLIGHT_GROUP_SIZE && ab.Coalition == preferredCoalition select ab).ToArray());

                if (airbasesList.Count == 0)
                {
                    airbasesList.AddRange((from DBEntryTheaterAirbase ab in theaterDB.Airbases where ab.ParkingSpots.Length >= Toolbox.MAXIMUM_FLIGHT_GROUP_SIZE select ab).ToArray());
                }
            }

            // Remove players' home airbase and airbases already used by other objectives from the list of available airbases
            List <int> airbasesInUse = (from DCSMissionObjective objective in mission.Objectives select objective.AirbaseID).ToList();

            airbasesInUse.Add(mission.InitialAirbaseID);
            airbasesList = (from DBEntryTheaterAirbase ab in airbasesList where !airbasesInUse.Contains(ab.DCSID) select ab).ToList();

            if (airbasesList.Count == 0)
            {
                throw new Exception($"No airbase found with at least {Toolbox.MAXIMUM_FLIGHT_GROUP_SIZE} parking spots to use as an objective.");
            }

            int distanceMultiplier = 1;

            do
            {
                MinMaxD searchDistance = new MinMaxD(first ? distance.Min : 0, distance.Max * distanceMultiplier);
                List <DBEntryTheaterAirbase> airbasesInRange = airbasesList.FindAll(x => searchDistance.Contains(x.Coordinates.GetDistanceFrom(lastCoordinates) * Toolbox.METERS_TO_NM));
                if (airbasesInRange.Count > 0)
                {
                    DBEntryTheaterAirbase selectedAirbase = Toolbox.RandomFrom(airbasesInRange);
                    mission.AirbasesCoalition[selectedAirbase.DCSID] = mission.CoalitionEnemy;
                    return(selectedAirbase);
                }

                distanceMultiplier++;

                if (distanceMultiplier > 128)
                {
                    throw new Exception($"No target airbase found within range, try a larger objective range.");
                }
            } while (true);
        }
        public DefinitionTheaterSpawnPoint?GetRandomSpawnPoint(
            TheaterLocationSpawnPointType[] validTypes = null, DCSCountry[] validCountries = null,
            MinMaxD?distanceFrom  = null, Coordinates?distanceOrigin  = null,
            MinMaxD?distanceFrom2 = null, Coordinates?distanceOrigin2 = null)
        {
            IEnumerable <DefinitionTheaterSpawnPoint> validSP = (from DefinitionTheaterSpawnPoint s in SpawnPoints where !UsedSpawnPointsID.Contains(s.UniqueID) select s);

            if (validTypes != null)
            {
                validSP = (from DefinitionTheaterSpawnPoint s in validSP where validTypes.Contains(s.PointType) select s);
            }

            if (validCountries != null)
            {
                validSP = (from DefinitionTheaterSpawnPoint s in validSP where validCountries.Contains(s.Country) select s);
            }

            if (distanceFrom.HasValue && distanceOrigin.HasValue)
            {
                if (validSP.Count() == 0)
                {
                    return(null);
                }

                MinMaxD searchRange = distanceFrom.Value;

                IEnumerable <DefinitionTheaterSpawnPoint> validSPInRange = (from DefinitionTheaterSpawnPoint s in validSP select s);

                do
                {
                    validSPInRange = (from DefinitionTheaterSpawnPoint s in validSP where searchRange.Contains(distanceOrigin.Value.GetDistanceFrom(s.Coordinates)) select s);
                    searchRange    = new MinMaxD(searchRange.Min * 0.9, Math.Max(100, searchRange.Max * 1.1));
                } while (validSPInRange.Count() == 0);

                validSP = (from DefinitionTheaterSpawnPoint s in validSPInRange select s);
            }

            if (distanceFrom2.HasValue && distanceOrigin2.HasValue)
            {
                if (validSP.Count() == 0)
                {
                    return(null);
                }

                MinMaxD searchRange = distanceFrom2.Value;

                IEnumerable <DefinitionTheaterSpawnPoint> validSPInRange = (from DefinitionTheaterSpawnPoint s in validSP select s);

                do
                {
                    validSPInRange = (from DefinitionTheaterSpawnPoint s in validSP where searchRange.Contains(distanceOrigin2.Value.GetDistanceFrom(s.Coordinates)) select s);
                    searchRange    = new MinMaxD(searchRange.Min * 0.9, Math.Max(100, searchRange.Max * 1.1));
                } while (validSPInRange.Count() == 0);

                validSP = (from DefinitionTheaterSpawnPoint s in validSPInRange select s);
            }

            if (validSP.Count() == 0)
            {
                return(null);
            }

            DefinitionTheaterSpawnPoint selectedSpawnPoint = HQTools.RandomFrom(validSP.ToArray());

            UsedSpawnPointsID.Add(selectedSpawnPoint.UniqueID);
            return(selectedSpawnPoint);
        }