mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Set preferred mission types for aircraft.
This commit is contained in:
parent
93db1254ec
commit
023925d741
@ -3,9 +3,9 @@ from __future__ import annotations
|
|||||||
import logging
|
import logging
|
||||||
import operator
|
import operator
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Iterator, List, Optional, Set, TYPE_CHECKING, Tuple
|
from typing import Iterator, List, Optional, Set, TYPE_CHECKING, Tuple, Type
|
||||||
|
|
||||||
from dcs.unittype import UnitType
|
from dcs.unittype import FlyingType, UnitType
|
||||||
|
|
||||||
from game import db
|
from game import db
|
||||||
from game.data.radar_db import UNITS_WITH_RADAR
|
from game.data.radar_db import UNITS_WITH_RADAR
|
||||||
@ -15,9 +15,13 @@ from gen import Conflict
|
|||||||
from gen.ato import Package
|
from gen.ato import Package
|
||||||
from gen.flights.ai_flight_planner_db import (
|
from gen.flights.ai_flight_planner_db import (
|
||||||
CAP_CAPABLE,
|
CAP_CAPABLE,
|
||||||
|
CAP_PREFERRED,
|
||||||
CAS_CAPABLE,
|
CAS_CAPABLE,
|
||||||
|
CAS_PREFERRED,
|
||||||
SEAD_CAPABLE,
|
SEAD_CAPABLE,
|
||||||
|
SEAD_PREFERRED,
|
||||||
STRIKE_CAPABLE,
|
STRIKE_CAPABLE,
|
||||||
|
STRIKE_PREFERRED,
|
||||||
)
|
)
|
||||||
from gen.flights.closestairfields import (
|
from gen.flights.closestairfields import (
|
||||||
ClosestAirfields,
|
ClosestAirfields,
|
||||||
@ -102,30 +106,63 @@ class AircraftAllocator:
|
|||||||
maximum allowed range. If insufficient aircraft are available for the
|
maximum allowed range. If insufficient aircraft are available for the
|
||||||
mission, None is returned.
|
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
|
Note that aircraft *will* be removed from the global inventory on
|
||||||
success. This is to ensure that the same aircraft are not matched twice
|
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
|
on subsequent calls. If the found aircraft are not used, the caller is
|
||||||
responsible for returning them to the inventory.
|
responsible for returning them to the inventory.
|
||||||
"""
|
"""
|
||||||
cap_missions = (FlightType.BARCAP, FlightType.CAP, FlightType.TARCAP)
|
result = self.find_aircraft_of_type(
|
||||||
if flight.task in cap_missions:
|
flight, self.preferred_aircraft_for_task(flight.task)
|
||||||
types = CAP_CAPABLE
|
)
|
||||||
elif flight.task == FlightType.CAS:
|
if result is not None:
|
||||||
types = CAS_CAPABLE
|
return result
|
||||||
elif flight.task in (FlightType.DEAD, FlightType.SEAD):
|
return self.find_aircraft_of_type(
|
||||||
types = SEAD_CAPABLE
|
flight, self.capable_aircraft_for_task(flight.task)
|
||||||
elif flight.task == FlightType.STRIKE:
|
)
|
||||||
types = STRIKE_CAPABLE
|
|
||||||
elif flight.task == FlightType.ESCORT:
|
|
||||||
types = CAP_CAPABLE
|
|
||||||
else:
|
|
||||||
logging.error(f"Unplannable flight type: {flight.task}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
# TODO: Implement mission type weighting for aircraft.
|
@staticmethod
|
||||||
# We should avoid assigning F/A-18s to CAP missions when there are F-15s
|
def preferred_aircraft_for_task(task: FlightType) -> List[Type[FlyingType]]:
|
||||||
# available, since the F/A-18 is capable of performing other tasks that
|
cap_missions = (FlightType.BARCAP, FlightType.CAP, FlightType.TARCAP)
|
||||||
# the F-15 is not capable of.
|
if task in cap_missions:
|
||||||
|
return CAP_PREFERRED
|
||||||
|
elif task == FlightType.CAS:
|
||||||
|
return CAS_PREFERRED
|
||||||
|
elif task in (FlightType.DEAD, FlightType.SEAD):
|
||||||
|
return SEAD_PREFERRED
|
||||||
|
elif task == FlightType.STRIKE:
|
||||||
|
return STRIKE_PREFERRED
|
||||||
|
elif task == FlightType.ESCORT:
|
||||||
|
return CAP_PREFERRED
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def capable_aircraft_for_task(task: FlightType) -> List[Type[FlyingType]]:
|
||||||
|
cap_missions = (FlightType.BARCAP, FlightType.CAP, FlightType.TARCAP)
|
||||||
|
if task in cap_missions:
|
||||||
|
return CAP_CAPABLE
|
||||||
|
elif task == FlightType.CAS:
|
||||||
|
return CAS_CAPABLE
|
||||||
|
elif task in (FlightType.DEAD, FlightType.SEAD):
|
||||||
|
return SEAD_CAPABLE
|
||||||
|
elif task == FlightType.STRIKE:
|
||||||
|
return STRIKE_CAPABLE
|
||||||
|
elif task == FlightType.ESCORT:
|
||||||
|
return CAP_CAPABLE
|
||||||
|
else:
|
||||||
|
logging.error(f"Unplannable flight type: {task}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
def find_aircraft_of_type(
|
||||||
|
self, flight: ProposedFlight, types: List[Type[FlyingType]],
|
||||||
|
) -> Optional[Tuple[ControlPoint, UnitType]]:
|
||||||
airfields_in_range = self.closest_airfields.airfields_within(
|
airfields_in_range = self.closest_airfields.airfields_within(
|
||||||
flight.max_distance
|
flight.max_distance
|
||||||
)
|
)
|
||||||
@ -312,7 +349,8 @@ class ObjectiveFinder:
|
|||||||
yield from cp.ground_objects
|
yield from cp.ground_objects
|
||||||
yield from self.front_lines()
|
yield from self.front_lines()
|
||||||
|
|
||||||
def closest_airfields_to(self, location: MissionTarget) -> ClosestAirfields:
|
@staticmethod
|
||||||
|
def closest_airfields_to(location: MissionTarget) -> ClosestAirfields:
|
||||||
"""Returns the closest airfields to the given location."""
|
"""Returns the closest airfields to the given location."""
|
||||||
return ObjectiveDistanceCache.get_closest_airfields(location)
|
return ObjectiveDistanceCache.get_closest_airfields(location)
|
||||||
|
|
||||||
|
|||||||
@ -80,6 +80,10 @@ from pydcs_extensions.a4ec.a4ec import A_4E_C
|
|||||||
from pydcs_extensions.mb339.mb339 import MB_339PAN
|
from pydcs_extensions.mb339.mb339 import MB_339PAN
|
||||||
from pydcs_extensions.rafale.rafale import Rafale_A_S, Rafale_M
|
from pydcs_extensions.rafale.rafale import Rafale_A_S, Rafale_M
|
||||||
|
|
||||||
|
# TODO: These lists really ought to be era (faction) dependent.
|
||||||
|
# Factions which have F-5s, F-86s, and A-4s will should prefer F-5s for CAP, but
|
||||||
|
# factions that also have F-4s should not.
|
||||||
|
|
||||||
INTERCEPT_CAPABLE = [
|
INTERCEPT_CAPABLE = [
|
||||||
MiG_21Bis,
|
MiG_21Bis,
|
||||||
MiG_25PD,
|
MiG_25PD,
|
||||||
@ -150,6 +154,42 @@ CAP_CAPABLE = [
|
|||||||
Rafale_M,
|
Rafale_M,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
CAP_PREFERRED = [
|
||||||
|
MiG_15bis,
|
||||||
|
MiG_19P,
|
||||||
|
MiG_21Bis,
|
||||||
|
MiG_23MLD,
|
||||||
|
MiG_25PD,
|
||||||
|
MiG_29A,
|
||||||
|
MiG_29G,
|
||||||
|
MiG_29S,
|
||||||
|
MiG_31,
|
||||||
|
|
||||||
|
Su_27,
|
||||||
|
J_11A,
|
||||||
|
Su_30,
|
||||||
|
Su_33,
|
||||||
|
|
||||||
|
M_2000C,
|
||||||
|
Mirage_2000_5,
|
||||||
|
|
||||||
|
F_86F_Sabre,
|
||||||
|
F_14B,
|
||||||
|
F_15C,
|
||||||
|
|
||||||
|
P_51D_30_NA,
|
||||||
|
P_51D,
|
||||||
|
|
||||||
|
SpitfireLFMkIXCW,
|
||||||
|
SpitfireLFMkIX,
|
||||||
|
|
||||||
|
Bf_109K_4,
|
||||||
|
FW_190D9,
|
||||||
|
FW_190A8,
|
||||||
|
|
||||||
|
Rafale_M,
|
||||||
|
]
|
||||||
|
|
||||||
# Used for CAS (Close air support) and BAI (Battlefield Interdiction)
|
# Used for CAS (Close air support) and BAI (Battlefield Interdiction)
|
||||||
CAS_CAPABLE = [
|
CAS_CAPABLE = [
|
||||||
|
|
||||||
@ -228,6 +268,59 @@ CAS_CAPABLE = [
|
|||||||
RQ_1A_Predator
|
RQ_1A_Predator
|
||||||
]
|
]
|
||||||
|
|
||||||
|
CAS_PREFERRED = [
|
||||||
|
Su_17M4,
|
||||||
|
Su_24M,
|
||||||
|
Su_24MR,
|
||||||
|
Su_25,
|
||||||
|
Su_25T,
|
||||||
|
Su_25TM,
|
||||||
|
Su_34,
|
||||||
|
|
||||||
|
JF_17,
|
||||||
|
|
||||||
|
A_10A,
|
||||||
|
A_10C,
|
||||||
|
A_10C_2,
|
||||||
|
AV8BNA,
|
||||||
|
|
||||||
|
F_15E,
|
||||||
|
|
||||||
|
Tornado_GR4,
|
||||||
|
|
||||||
|
C_101CC,
|
||||||
|
MB_339PAN,
|
||||||
|
L_39ZA,
|
||||||
|
AJS37,
|
||||||
|
|
||||||
|
SA342M,
|
||||||
|
SA342L,
|
||||||
|
OH_58D,
|
||||||
|
|
||||||
|
AH_64A,
|
||||||
|
AH_64D,
|
||||||
|
AH_1W,
|
||||||
|
|
||||||
|
UH_1H,
|
||||||
|
|
||||||
|
Mi_8MT,
|
||||||
|
Mi_28N,
|
||||||
|
Mi_24V,
|
||||||
|
Ka_50,
|
||||||
|
|
||||||
|
P_47D_30,
|
||||||
|
P_47D_30bl1,
|
||||||
|
P_47D_40,
|
||||||
|
A_20G,
|
||||||
|
|
||||||
|
A_4E_C,
|
||||||
|
Rafale_A_S,
|
||||||
|
|
||||||
|
WingLoong_I,
|
||||||
|
MQ_9_Reaper,
|
||||||
|
RQ_1A_Predator
|
||||||
|
]
|
||||||
|
|
||||||
# Aircraft used for SEAD / DEAD tasks
|
# Aircraft used for SEAD / DEAD tasks
|
||||||
SEAD_CAPABLE = [
|
SEAD_CAPABLE = [
|
||||||
F_4E,
|
F_4E,
|
||||||
@ -252,6 +345,12 @@ SEAD_CAPABLE = [
|
|||||||
Rafale_A_S
|
Rafale_A_S
|
||||||
]
|
]
|
||||||
|
|
||||||
|
SEAD_PREFERRED = [
|
||||||
|
F_4E,
|
||||||
|
Su_25T,
|
||||||
|
Tornado_IDS,
|
||||||
|
]
|
||||||
|
|
||||||
# Aircraft used for Strike mission
|
# Aircraft used for Strike mission
|
||||||
STRIKE_CAPABLE = [
|
STRIKE_CAPABLE = [
|
||||||
MiG_15bis,
|
MiG_15bis,
|
||||||
@ -309,6 +408,15 @@ STRIKE_CAPABLE = [
|
|||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
STRIKE_PREFERRED = [
|
||||||
|
AJS37,
|
||||||
|
F_15E,
|
||||||
|
Tornado_GR4,
|
||||||
|
|
||||||
|
A_20G,
|
||||||
|
B_17G,
|
||||||
|
]
|
||||||
|
|
||||||
ANTISHIP_CAPABLE = [
|
ANTISHIP_CAPABLE = [
|
||||||
Su_24M,
|
Su_24M,
|
||||||
Su_17M4,
|
Su_17M4,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user