From 24844571833b70bb577fe8519c28b1349c00952b Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Mon, 23 Nov 2020 00:12:42 -0800 Subject: [PATCH] Spawn unused aircraft at airports. The aircraft that have not been fragged will now be spawned in parking to provide more targets for OCA strikes. We do this only at airports, not carriers. The AI has enough trouble taxiing around uncrowded carrier decks that we probably shouldn't make it harder for them, plus most of the aircraft will be stored below the flight deck (we allow 90 aircraft to be stored at the carrier, which certainly will not fit on the flight deck). The aircraft are spawned in an uncontrolled state and nothing will activate them, so aside from the cost of rendering them they shouldn't affect performance. Fixes https://github.com/Khopa/dcs_liberation/issues/148 --- game/operation/operation.py | 3 +++ game/unitmap.py | 4 +-- gen/aircraft.py | 52 ++++++++++++++++++++++++++++++++++--- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/game/operation/operation.py b/game/operation/operation.py index 5f015b10..671d060b 100644 --- a/game/operation/operation.py +++ b/game/operation/operation.py @@ -360,6 +360,9 @@ class Operation: cls.game.red_ato, cls.groundobjectgen.runways ) + cls.airgen.spawn_unused_aircraft( + cls.current_mission.country(cls.game.player_country), + cls.current_mission.country(cls.game.enemy_country)) def _generate_ground_conflicts(self) -> None: """For each frontline in the Operation, generate the ground conflicts and JTACs""" diff --git a/game/unitmap.py b/game/unitmap.py index f08fbad6..0ca34fe5 100644 --- a/game/unitmap.py +++ b/game/unitmap.py @@ -19,5 +19,5 @@ class UnitMap: raise RuntimeError(f"Duplicate unit name: {name}") self.aircraft[name] = flight - def flight(self, group_name: str) -> Optional[Flight]: - return self.aircraft.get(group_name, None) + def flight(self, unit_name: str) -> Optional[Flight]: + return self.aircraft.get(unit_name, None) diff --git a/gen/aircraft.py b/gen/aircraft.py index edf9dcb8..ec5aaa2d 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -61,7 +61,7 @@ from dcs.task import ( Task, WeaponType, ) -from dcs.terrain.terrain import Airport +from dcs.terrain.terrain import Airport, NoParkingSlotError from dcs.translation import String from dcs.triggers import Event, TriggerOnce, TriggerRule from dcs.unitgroup import FlyingGroup, ShipGroup, StaticGroup @@ -795,7 +795,8 @@ class AircraftConflictGenerator: unit.fuel = Su_33.fuel_max * 0.8 def _generate_at_airport(self, name: str, side: Country, - unit_type: FlyingType, count: int, start_type: str, + unit_type: Type[FlyingType], count: int, + start_type: str, airport: Optional[Airport] = None) -> FlyingGroup: assert count > 0 @@ -844,7 +845,8 @@ class AircraftConflictGenerator: return group def _generate_at_group(self, name: str, side: Country, - unit_type: FlyingType, count: int, start_type: str, + unit_type: Type[FlyingType], count: int, + start_type: str, at: Union[ShipGroup, StaticGroup]) -> FlyingGroup: assert count > 0 @@ -890,7 +892,6 @@ class AircraftConflictGenerator: else: assert False - def _setup_custom_payload(self, flight, group:FlyingGroup): if flight.use_custom_loadout: @@ -933,6 +934,49 @@ class AircraftConflictGenerator: self.setup_flight_group(group, package, flight, dynamic_runways) self.create_waypoints(group, package, flight) + def spawn_unused_aircraft(self, player_country: Country, + enemy_country: Country) -> None: + inventories = self.game.aircraft_inventory.inventories + for control_point, inventory in inventories.items(): + if isinstance(control_point, OffMapSpawn): + continue + if control_point.is_fleet: + # Don't crowd the deck since the AI will struggle. + continue + + if control_point.captured: + country = player_country + else: + country = enemy_country + + for aircraft, available in inventory.all_aircraft: + try: + self._spawn_unused_at(control_point, country, aircraft, + available) + except NoParkingSlotError: + # If we run out of parking, stop spawning aircraft. + return + + def _spawn_unused_at(self, control_point: ControlPoint, country: Country, + aircraft: Type[FlyingType], number: int) -> None: + for _ in range(number): + # Creating a flight even those this isn't a fragged mission lets us + # reuse the existing debriefing code. + # TODO: Special flight type? + flight = Flight(Package(control_point), aircraft, 1, FlightType.CAP, + "Cold", departure=control_point, + arrival=control_point, divert=None) + group = self._generate_at_airport( + name=namegen.next_unit_name(country, control_point.id, + aircraft), + side=country, + unit_type=aircraft, + count=1, + start_type="Cold", + airport=control_point.airport) + group.uncontrolled = True + self.unit_map.add_aircraft(group, flight) + def set_activation_time(self, flight: Flight, group: FlyingGroup, delay: timedelta) -> None: # Note: Late activation causes the waypoint TOTs to look *weird* in the