internal List <DBEntryAirbaseParkingSpot> GetFreeParkingSpots(int airbaseID, int unitCount, UnitFamily unitFamily, bool requiresOpenAirParking = false) { if (!AirbaseParkingSpots.ContainsKey(airbaseID)) { throw new BriefingRoomException($"Airbase {airbaseID} not found in parking map"); } var airbaseDB = SituationDB.GetAirbases(InvertCoalition).First(x => x.DCSID == airbaseID); var parkingSpots = new List <DBEntryAirbaseParkingSpot>(); DBEntryAirbaseParkingSpot?lastSpot = null; for (int i = 0; i < unitCount; i++) { var viableSpots = FilterAndSortSuitableSpots(AirbaseParkingSpots[airbaseID].ToArray(), unitFamily, requiresOpenAirParking); if (viableSpots.Count == 0) { throw new BriefingRoomException("Airbase didn't have enough suitable parking spots."); } var parkingSpot = viableSpots.First(); if (lastSpot.HasValue) //find nearest spot distance wise in attempt to cluster { parkingSpot = viableSpots .Aggregate((acc, x) => acc.Coordinates.GetDistanceFrom(lastSpot.Value.Coordinates) > x.Coordinates.GetDistanceFrom(lastSpot.Value.Coordinates) ? x : acc); } lastSpot = parkingSpot; AirbaseParkingSpots[airbaseID].Remove(parkingSpot); parkingSpots.Add(parkingSpot); } return(parkingSpots); }
internal DBEntryAirbase SelectStartingAirbase(DCSMission mission, string selectedAirbaseID, int requiredParkingSpots = 0, int requiredRunway = 0) { // Get total number of required parking spots for flight groups if (requiredParkingSpots == 0) { requiredParkingSpots = _template.PlayerFlightGroups.Sum(x => x.Count); } // Select all airbases for this theater DBEntryAirbase[] airbases = _situationDB.GetAirbases(_template.OptionsMission.Contains("InvertCountriesCoalitions")); // If a particular airbase name has been specified and an airbase with this name exists, pick it if (!string.IsNullOrEmpty(selectedAirbaseID)) { var airbase = airbases.FirstOrDefault(x => x.ID == selectedAirbaseID); if (airbase is null) { throw new BriefingRoomException($"No airbase found with ID \"{selectedAirbaseID}\", cannot spawn player aircraft."); } return(airbase); } var opts = airbases.Where(x => x.ParkingSpots.Length >= requiredParkingSpots && x.Coalition == _template.ContextPlayerCoalition && x.RunwayLengthFt > requiredRunway && (MissionPrefersShoreAirbase() ? x.Flags.HasFlag(AirbaseFlag.NearWater) : true) ).ToList(); if (opts.Count == 0) { throw new BriefingRoomException($"No airbase found, cannot spawn player aircraft."); } return(Toolbox.RandomFrom(opts)); }
private Coordinates PlaceInAirbase(MissionTemplateRecord template, DBEntrySituation situationDB, DBEntryAirbase playerAirbase, List <KeyValuePair <string, object> > extraSettings, DBEntryObjectiveTarget targetDB, DBEntryObjectiveTargetBehavior targetBehaviorDB, ref string luaUnit, Coordinates objectiveCoordinates, int unitCount, UnitFamily objectiveTargetUnitFamily) { int airbaseID = 0; var parkingSpotIDsList = new List <int>(); var parkingSpotCoordinatesList = new List <Coordinates>(); var targetAirbaseOptions = (from DBEntryAirbase airbaseDB in situationDB.GetAirbases(template.OptionsMission.Contains("InvertCountriesCoalitions")) where airbaseDB.DCSID != playerAirbase.DCSID select airbaseDB).OrderBy(x => x.Coordinates.GetDistanceFrom(objectiveCoordinates)); DBEntryAirbase targetAirbase = targetAirbaseOptions.FirstOrDefault(x => template.OptionsMission.Contains("SpawnAnywhere") ? true : x.Coalition == template.ContextPlayerCoalition.GetEnemy()); airbaseID = targetAirbase.DCSID; var parkingSpots = UnitMaker.SpawnPointSelector.GetFreeParkingSpots( targetAirbase.DCSID, unitCount, objectiveTargetUnitFamily, targetBehaviorDB.Location == DBEntryObjectiveTargetBehaviorLocation.SpawnOnAirbaseParkingNoHardenedShelter); parkingSpotIDsList = parkingSpots.Select(x => x.DCSID).ToList(); parkingSpotCoordinatesList = parkingSpots.Select(x => x.Coordinates).ToList(); luaUnit += "Parked"; extraSettings.Add("GroupAirbaseID".ToKeyValuePair(airbaseID)); extraSettings.Add("ParkingID".ToKeyValuePair(parkingSpotIDsList.ToArray())); extraSettings.Add("UnitX".ToKeyValuePair((from Coordinates coordinates in parkingSpotCoordinatesList select coordinates.X).ToArray())); extraSettings.Add("UnitY".ToKeyValuePair((from Coordinates coordinates in parkingSpotCoordinatesList select coordinates.Y).ToArray())); return(targetAirbase.Coordinates); }
internal UnitMakerSpawnPointSelector(DBEntryTheater theaterDB, DBEntrySituation situationDB, bool invertCoalition) { TheaterDB = theaterDB; SituationDB = situationDB; AirbaseParkingSpots = new Dictionary <int, List <DBEntryAirbaseParkingSpot> >(); SpawnPoints = new List <DBEntryTheaterSpawnPoint>(); InvertCoalition = invertCoalition; if (TheaterDB.SpawnPoints is not null) { SpawnPoints.AddRange(TheaterDB.SpawnPoints.Where(x => CheckNotInNoSpawnCoords(x.Coordinates)).ToList()); } foreach (DBEntryAirbase airbase in SituationDB.GetAirbases(InvertCoalition)) { if (airbase.ParkingSpots.Length < 1) { continue; } if (AirbaseParkingSpots.ContainsKey(airbase.DCSID)) { continue; } AirbaseParkingSpots.Add(airbase.DCSID, airbase.ParkingSpots.ToList()); } }