Ignore non-escorted regions when planning escorts.

We shouldn't consider the non-escorted parts of the flight path when
checking for threats to determine if escorts should be used or not,
since escorts can't help in those areas anyway. This was causing escorts
to be overly requested since the bullseye is now a part of the
"flight plan", but could have also triggered for divert waypoints, or
for aircraft taking off in a retreat from a threatened location.
This commit is contained in:
Dan Albert 2021-05-23 12:58:16 -07:00
parent ddd6e7d18f
commit eedb5c26a9
3 changed files with 36 additions and 8 deletions

View File

@ -1,7 +1,7 @@
from __future__ import annotations
from functools import singledispatchmethod
from typing import Optional, TYPE_CHECKING, Union
from typing import Optional, TYPE_CHECKING, Union, Iterable
from dcs.mapping import Point as DcsPoint
from shapely.geometry import (
@ -16,7 +16,7 @@ from shapely.ops import nearest_points, unary_union
from game.theater import ControlPoint
from game.utils import Distance, meters, nautical_miles
from gen.flights.closestairfields import ObjectiveDistanceCache
from gen.flights.flight import Flight
from gen.flights.flight import Flight, FlightWaypoint
if TYPE_CHECKING:
from game import Game
@ -71,6 +71,13 @@ class ThreatZones:
LineString((self.dcs_to_shapely_point(p.position) for p in flight.points))
)
def waypoints_threatened_by_aircraft(
self, waypoints: Iterable[FlightWaypoint]
) -> bool:
return self.threatened_by_aircraft(
LineString((self.dcs_to_shapely_point(p.position) for p in waypoints))
)
@singledispatchmethod
def threatened_by_air_defense(self, target) -> bool:
raise NotImplementedError
@ -99,6 +106,13 @@ class ThreatZones:
LineString((self.dcs_to_shapely_point(p.position) for p in flight.points))
)
def waypoints_threatened_by_radar_sam(
self, waypoints: Iterable[FlightWaypoint]
) -> bool:
return self.threatened_by_radar_sam(
LineString((self.dcs_to_shapely_point(p.position) for p in waypoints))
)
@classmethod
def closest_enemy_airbase(
cls, location: ControlPoint, max_distance: Distance

View File

@ -831,9 +831,13 @@ class CoalitionMissionPlanner:
def check_needed_escorts(self, builder: PackageBuilder) -> Dict[EscortType, bool]:
threats = defaultdict(bool)
for flight in builder.package.flights:
if self.threat_zones.threatened_by_aircraft(flight):
if self.threat_zones.waypoints_threatened_by_aircraft(
flight.flight_plan.escorted_waypoints()
):
threats[EscortType.AirToAir] = True
if self.threat_zones.threatened_by_radar_sam(flight):
if self.threat_zones.waypoints_threatened_by_radar_sam(
list(flight.flight_plan.escorted_waypoints())
):
threats[EscortType.Sead] = True
return threats

View File

@ -198,6 +198,20 @@ class FlightPlan:
def dismiss_escort_at(self) -> Optional[FlightWaypoint]:
return None
def escorted_waypoints(self) -> Iterator[FlightWaypoint]:
begin = self.request_escort_at()
end = self.dismiss_escort_at()
if begin is None or end is None:
return
escorting = False
for waypoint in self.waypoints:
if waypoint == begin:
escorting = True
if escorting:
yield waypoint
if waypoint == end:
return
def takeoff_time(self) -> Optional[timedelta]:
tot_waypoint = self.tot_waypoint
if tot_waypoint is None:
@ -600,10 +614,6 @@ class StrikeFlightPlan(FormationFlightPlan):
)
return total
@property
def mission_speed(self) -> Speed:
return GroundSpeed.for_flight(self.flight, self.ingress.alt)
@property
def join_time(self) -> timedelta:
travel_time = self.travel_time_between_waypoints(self.join, self.ingress)