mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
This is needed to support the upcoming squadron transfers, since squadrons need to bring their aircraft with them. https://github.com/dcs-liberation/dcs_liberation/issues/1145
70 lines
3.1 KiB
Python
70 lines
3.1 KiB
Python
from typing import Optional, Tuple
|
|
|
|
from game.commander.missionproposals import ProposedFlight
|
|
from game.squadrons.airwing import AirWing
|
|
from game.squadrons.squadron import Squadron
|
|
from game.theater import ControlPoint, MissionTarget
|
|
from game.utils import meters
|
|
from gen.flights.ai_flight_planner_db import aircraft_for_task
|
|
from gen.flights.closestairfields import ClosestAirfields
|
|
from gen.flights.flight import FlightType
|
|
|
|
|
|
class AircraftAllocator:
|
|
"""Finds suitable aircraft for proposed missions."""
|
|
|
|
def __init__(
|
|
self, air_wing: AirWing, closest_airfields: ClosestAirfields, is_player: bool
|
|
) -> None:
|
|
self.air_wing = air_wing
|
|
self.closest_airfields = closest_airfields
|
|
self.is_player = is_player
|
|
|
|
def find_squadron_for_flight(
|
|
self, target: MissionTarget, flight: ProposedFlight
|
|
) -> Optional[Tuple[ControlPoint, Squadron]]:
|
|
"""Finds aircraft suitable for the given mission.
|
|
|
|
Searches for aircraft capable of performing the given mission within the
|
|
maximum allowed range. If insufficient aircraft are available for the
|
|
mission, None is returned.
|
|
|
|
Airfields are searched ordered nearest to farthest from the target and
|
|
searched twice. The first search looks for aircraft which prefer the
|
|
mission type, and the second search looks for any aircraft which are
|
|
capable of the mission type. For example, an F-14 from a nearby carrier
|
|
will be preferred for the CAP of an airfield that has only F-16s, but if
|
|
the carrier has only F/A-18s the F-16s will be used for CAP instead.
|
|
|
|
Note that aircraft *will* be removed from the global inventory on
|
|
success. This is to ensure that the same aircraft are not matched twice
|
|
on subsequent calls. If the found aircraft are not used, the caller is
|
|
responsible for returning them to the inventory.
|
|
"""
|
|
return self.find_aircraft_for_task(target, flight, flight.task)
|
|
|
|
def find_aircraft_for_task(
|
|
self, target: MissionTarget, flight: ProposedFlight, task: FlightType
|
|
) -> Optional[Tuple[ControlPoint, Squadron]]:
|
|
types = aircraft_for_task(task)
|
|
for airfield in self.closest_airfields.operational_airfields:
|
|
if not airfield.is_friendly(self.is_player):
|
|
continue
|
|
for aircraft in types:
|
|
if not airfield.can_operate(aircraft):
|
|
continue
|
|
distance_to_target = meters(target.distance_to(airfield))
|
|
if distance_to_target > aircraft.max_mission_range:
|
|
continue
|
|
# Valid location with enough aircraft available. Find a squadron to fit
|
|
# the role.
|
|
squadrons = self.air_wing.auto_assignable_for_task_with_type(
|
|
aircraft, task, airfield
|
|
)
|
|
for squadron in squadrons:
|
|
if squadron.operates_from(airfield) and squadron.can_fulfill_flight(
|
|
flight.num_aircraft
|
|
):
|
|
return airfield, squadron
|
|
return None
|