Add escort tasks for the AI.

This commit is contained in:
Dan Albert
2020-10-18 15:05:26 -07:00
parent 95f486870d
commit fd969020af
6 changed files with 133 additions and 41 deletions

View File

@@ -52,6 +52,7 @@ class FlightWaypointType(Enum):
JOIN = 16
SPLIT = 17
LOITER = 18
INGRESS_ESCORT = 19
class PredefinedWaypointCategory(Enum):

View File

@@ -132,7 +132,7 @@ class FlightPlanBuilder:
if not isinstance(location, TheaterGroundObject):
raise InvalidObjectiveLocation(flight.flight_type, location)
builder = WaypointBuilder(self.doctrine)
builder = WaypointBuilder(flight, self.doctrine)
builder.ascent(flight.from_cp)
builder.hold(self._hold_point(flight))
builder.join(self.package.waypoints.join)
@@ -222,7 +222,7 @@ class FlightPlanBuilder:
)
start = end.point_from_heading(heading - 180, diameter)
builder = WaypointBuilder(self.doctrine)
builder = WaypointBuilder(flight, self.doctrine)
builder.ascent(flight.from_cp)
builder.race_track(start, end, patrol_alt)
builder.rtb(flight.from_cp)
@@ -264,7 +264,7 @@ class FlightPlanBuilder:
orbit1p = orbit_center.point_from_heading(heading + 180, radius)
# Create points
builder = WaypointBuilder(self.doctrine)
builder = WaypointBuilder(flight, self.doctrine)
builder.ascent(flight.from_cp)
builder.hold(self._hold_point(flight))
builder.join(self.package.waypoints.join)
@@ -290,7 +290,7 @@ class FlightPlanBuilder:
if custom_targets is None:
custom_targets = []
builder = WaypointBuilder(self.doctrine)
builder = WaypointBuilder(flight, self.doctrine)
builder.ascent(flight.from_cp)
builder.hold(self._hold_point(flight))
builder.join(self.package.waypoints.join)
@@ -328,17 +328,12 @@ class FlightPlanBuilder:
def generate_escort(self, flight: Flight) -> None:
assert self.package.waypoints is not None
patrol_alt = random.randint(
self.doctrine.min_patrol_altitude,
self.doctrine.max_patrol_altitude
)
builder = WaypointBuilder(self.doctrine)
builder = WaypointBuilder(flight, self.doctrine)
builder.ascent(flight.from_cp)
builder.hold(self._hold_point(flight))
builder.join(self.package.waypoints.join)
builder.race_track(self.package.waypoints.ingress,
self.package.waypoints.egress, patrol_alt)
builder.escort(self.package.waypoints.ingress,
self.package.target, self.package.waypoints.egress)
builder.split(self.package.waypoints.split)
builder.rtb(flight.from_cp)
@@ -366,7 +361,7 @@ class FlightPlanBuilder:
center = ingress.point_from_heading(heading, distance / 2)
egress = ingress.point_from_heading(heading, distance)
builder = WaypointBuilder(self.doctrine)
builder = WaypointBuilder(flight, self.doctrine)
builder.ascent(flight.from_cp, is_helo)
builder.hold(self._hold_point(flight))
builder.join(self.package.waypoints.join)
@@ -379,33 +374,39 @@ class FlightPlanBuilder:
flight.points = builder.build()
# TODO: Make a model for the waypoint builder and use that in the UI.
def generate_ascend_point(self, departure: ControlPoint) -> FlightWaypoint:
def generate_ascend_point(self, flight: Flight,
departure: ControlPoint) -> FlightWaypoint:
"""Generate ascend point.
Args:
flight: The flight to generate the descend point for.
departure: Departure airfield or carrier.
"""
builder = WaypointBuilder(self.doctrine)
builder = WaypointBuilder(flight, self.doctrine)
builder.ascent(departure)
return builder.build()[0]
def generate_descend_point(self, arrival: ControlPoint) -> FlightWaypoint:
def generate_descend_point(self, flight: Flight,
arrival: ControlPoint) -> FlightWaypoint:
"""Generate approach/descend point.
Args:
flight: The flight to generate the descend point for.
arrival: Arrival airfield or carrier.
"""
builder = WaypointBuilder(self.doctrine)
builder = WaypointBuilder(flight, self.doctrine)
builder.descent(arrival)
return builder.build()[0]
def generate_rtb_waypoint(self, arrival: ControlPoint) -> FlightWaypoint:
def generate_rtb_waypoint(self, flight: Flight,
arrival: ControlPoint) -> FlightWaypoint:
"""Generate RTB landing point.
Args:
flight: The flight to generate the landing waypoint for.
arrival: Arrival airfield or carrier.
"""
builder = WaypointBuilder(self.doctrine)
builder = WaypointBuilder(flight, self.doctrine)
builder.land(arrival)
return builder.build()[0]

View File

@@ -22,12 +22,14 @@ CAP_DURATION = 30 # Minutes
INGRESS_TYPES = {
FlightWaypointType.INGRESS_CAS,
FlightWaypointType.INGRESS_ESCORT,
FlightWaypointType.INGRESS_SEAD,
FlightWaypointType.INGRESS_STRIKE,
}
IP_TYPES = {
FlightWaypointType.INGRESS_CAS,
FlightWaypointType.INGRESS_ESCORT,
FlightWaypointType.INGRESS_SEAD,
FlightWaypointType.INGRESS_STRIKE,
FlightWaypointType.PATROL_TRACK,

View File

@@ -8,11 +8,12 @@ from dcs.unit import Unit
from game.data.doctrine import Doctrine
from game.utils import nm_to_meter
from theater import ControlPoint, MissionTarget, TheaterGroundObject
from .flight import FlightWaypoint, FlightWaypointType
from .flight import Flight, FlightWaypoint, FlightWaypointType
class WaypointBuilder:
def __init__(self, doctrine: Doctrine) -> None:
def __init__(self, flight: Flight, doctrine: Doctrine) -> None:
self.flight = flight
self.doctrine = doctrine
self.waypoints: List[FlightWaypoint] = []
self.ingress_point: Optional[FlightWaypoint] = None
@@ -127,6 +128,9 @@ class WaypointBuilder:
def ingress_cas(self, position: Point, objective: MissionTarget) -> None:
self._ingress(FlightWaypointType.INGRESS_CAS, position, objective)
def ingress_escort(self, position: Point, objective: MissionTarget) -> None:
self._ingress(FlightWaypointType.INGRESS_ESCORT, position, objective)
def ingress_sead(self, position: Point, objective: MissionTarget) -> None:
self._ingress(FlightWaypointType.INGRESS_SEAD, position, objective)
@@ -199,6 +203,9 @@ class WaypointBuilder:
waypoint.description = description
waypoint.pretty_name = description
waypoint.name = name
# The target waypoints are only for the player's benefit. AI tasks for
# the target are set on the ingress point so they begin their attack
# *before* reaching the target.
waypoint.only_for_player = True
self.waypoints.append(waypoint)
# TODO: This seems wrong, but it's what was there before.
@@ -231,6 +238,9 @@ class WaypointBuilder:
waypoint.description = name
waypoint.pretty_name = name
waypoint.name = name
# The target waypoints are only for the player's benefit. AI tasks for
# the target are set on the ingress point so they begin their attack
# *before* reaching the target.
waypoint.only_for_player = True
self.waypoints.append(waypoint)
# TODO: This seems wrong, but it's what was there before.
@@ -305,3 +315,33 @@ class WaypointBuilder:
"""
self.descent(arrival, is_helo)
self.land(arrival)
def escort(self, ingress: Point, target: MissionTarget,
egress: Point) -> None:
"""Creates the waypoints needed to escort the package.
Args:
ingress: The package ingress point.
target: The mission target.
egress: The package egress point.
"""
# This would preferably be no points at all, and instead the Escort task
# would begin on the join point and end on the split point, however the
# escort task does not appear to work properly (see the longer
# description in gen.aircraft.JoinPointBuilder), so instead we give
# the escort flights a flight plan including the ingress point, target
# area, and egress point.
self._ingress(FlightWaypointType.INGRESS_ESCORT, ingress, target)
waypoint = FlightWaypoint(
FlightWaypointType.TARGET_GROUP_LOC,
target.position.x,
target.position.y,
self.doctrine.ingress_altitude
)
waypoint.name = "TARGET"
waypoint.description = "Escort the package"
waypoint.pretty_name = "Target area"
self.waypoints.append(waypoint)
self.egress(egress, target)