Convert escort request to a waypoint property.

Another step in reducing the rigidity of FlightPlan and making it
testable.

There is one intentional behavior change here: escort flights no longer
request escorts. That actually has a very minimal effect because these
properties are only used for two things: determining if a package needs
escorts or not, and determining when the TARCAP should show up and
leave. Since escorts won't have been in the package when the first part
happens anyway, that has no effect. The only change is that TARCAP won't
show up earlier or stay later just because of a TOT offset for an escort
flight.
This commit is contained in:
Dan Albert
2023-09-11 21:20:06 -07:00
parent 502d37058c
commit 3862ec1b2e
6 changed files with 111 additions and 28 deletions

View File

@@ -63,12 +63,6 @@ class CasFlightPlan(PatrollingFlightPlan[CasLayout], UiZoneDisplay):
def combat_speed_waypoints(self) -> set[FlightWaypoint]:
return {self.layout.ingress, self.layout.patrol_start, self.layout.patrol_end}
def request_escort_at(self) -> FlightWaypoint | None:
return self.layout.patrol_start
def dismiss_escort_at(self) -> FlightWaypoint | None:
return self.layout.patrol_end
def ui_zone(self) -> UiZone:
midpoint = (
self.layout.patrol_start.position + self.layout.patrol_end.position
@@ -128,6 +122,7 @@ class Builder(IBuilder[CasFlightPlan, CasLayout]):
patrol_start_waypoint.name = "FLOT START"
patrol_start_waypoint.pretty_name = "FLOT start"
patrol_start_waypoint.description = "FLOT boundary"
patrol_start_waypoint.wants_escort = True
patrol_end_waypoint = builder.nav(
patrol_end, patrol_altitude, use_agl_patrol_altitude
@@ -135,6 +130,7 @@ class Builder(IBuilder[CasFlightPlan, CasLayout]):
patrol_end_waypoint.name = "FLOT END"
patrol_end_waypoint.pretty_name = "FLOT end"
patrol_end_waypoint.description = "FLOT boundary"
patrol_end_waypoint.wants_escort = True
ingress = builder.ingress(
FlightWaypointType.INGRESS_CAS, ingress_point, location

View File

@@ -205,24 +205,21 @@ class FlightPlan(ABC, Generic[LayoutT]):
raise NotImplementedError
def request_escort_at(self) -> FlightWaypoint | None:
return None
try:
return next(self.escorted_waypoints())
except StopIteration:
return None
def dismiss_escort_at(self) -> FlightWaypoint | None:
return None
try:
return list(self.escorted_waypoints())[-1]
except IndexError:
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:
for waypoint in self.iter_waypoints():
if waypoint.wants_escort:
yield waypoint
if waypoint == end:
return
def takeoff_time(self) -> datetime:
return self.tot - self._travel_time_to_waypoint(self.tot_waypoint)

View File

@@ -37,12 +37,6 @@ class FormationFlightPlan(LoiterFlightPlan[LayoutT], ABC):
def combat_speed_waypoints(self) -> set[FlightWaypoint]:
return self.package_speed_waypoints
def request_escort_at(self) -> FlightWaypoint | None:
return self.layout.join
def dismiss_escort_at(self) -> FlightWaypoint | None:
return self.layout.split
@cached_property
def best_flight_formation_speed(self) -> Speed:
"""The best speed this flight is capable at all formation waypoints.

View File

@@ -145,7 +145,18 @@ class FormationAttackBuilder(IBuilder[FlightPlanT, LayoutT], ABC):
hold = builder.hold(self._hold_point())
join = builder.join(self.package.waypoints.join)
join.wants_escort = True
ingress = builder.ingress(
ingress_type, self.package.waypoints.ingress, self.package.target
)
ingress.wants_escort = True
for target_waypoint in target_waypoints:
target_waypoint.wants_escort = True
split = builder.split(self.package.waypoints.split)
split.wants_escort = True
refuel = builder.refuel(self.package.waypoints.refuel)
return FormationAttackLayout(
@@ -155,9 +166,7 @@ class FormationAttackBuilder(IBuilder[FlightPlanT, LayoutT], ABC):
hold.position, join.position, self.doctrine.ingress_altitude
),
join=join,
ingress=builder.ingress(
ingress_type, self.package.waypoints.ingress, self.package.target
),
ingress=ingress,
targets=target_waypoints,
split=split,
refuel=refuel,

View File

@@ -41,6 +41,8 @@ class FlightWaypoint:
# The minimum amount of fuel remaining at this waypoint in pounds.
min_fuel: float | None = None
wants_escort: bool = False
actions: list[WaypointAction] = field(default_factory=list)
options: dict[str, WaypointOption] = field(default_factory=dict)