mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Add arrival/divert airfield selection.
Breaks save compat because it adds new fields to `Flight` that have no constant default. Removing all of our other save compat at the same time. Note that player flights with a divert point will have a nav point for their actual landing point. This is because we place the divert point last, and DCS won't let us have a land point anywhere but the final waypoint. It would allow a LandingReFuAr point, but they're only generated for player flights anyway so it doesn't really matter. Fixes https://github.com/Khopa/dcs_liberation/issues/342
This commit is contained in:
@@ -68,6 +68,10 @@ class FlightPlan:
|
||||
@property
|
||||
def waypoints(self) -> List[FlightWaypoint]:
|
||||
"""A list of all waypoints in the flight plan, in order."""
|
||||
return list(self.iter_waypoints())
|
||||
|
||||
def iter_waypoints(self) -> Iterator[FlightWaypoint]:
|
||||
"""Iterates over all waypoints in the flight plan, in order."""
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
@@ -166,8 +170,7 @@ class FlightPlan:
|
||||
class LoiterFlightPlan(FlightPlan):
|
||||
hold: FlightWaypoint
|
||||
|
||||
@property
|
||||
def waypoints(self) -> List[FlightWaypoint]:
|
||||
def iter_waypoints(self) -> Iterator[FlightWaypoint]:
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
@@ -193,8 +196,7 @@ class FormationFlightPlan(LoiterFlightPlan):
|
||||
join: FlightWaypoint
|
||||
split: FlightWaypoint
|
||||
|
||||
@property
|
||||
def waypoints(self) -> List[FlightWaypoint]:
|
||||
def iter_waypoints(self) -> Iterator[FlightWaypoint]:
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
@@ -295,8 +297,7 @@ class PatrollingFlightPlan(FlightPlan):
|
||||
return self.patrol_end_time
|
||||
return None
|
||||
|
||||
@property
|
||||
def waypoints(self) -> List[FlightWaypoint]:
|
||||
def iter_waypoints(self) -> Iterator[FlightWaypoint]:
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
@@ -312,15 +313,17 @@ class PatrollingFlightPlan(FlightPlan):
|
||||
class BarCapFlightPlan(PatrollingFlightPlan):
|
||||
takeoff: FlightWaypoint
|
||||
land: FlightWaypoint
|
||||
divert: Optional[FlightWaypoint]
|
||||
|
||||
@property
|
||||
def waypoints(self) -> List[FlightWaypoint]:
|
||||
return [
|
||||
def iter_waypoints(self) -> Iterator[FlightWaypoint]:
|
||||
yield from [
|
||||
self.takeoff,
|
||||
self.patrol_start,
|
||||
self.patrol_end,
|
||||
self.land,
|
||||
]
|
||||
if self.divert is not None:
|
||||
yield self.divert
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -328,16 +331,18 @@ class CasFlightPlan(PatrollingFlightPlan):
|
||||
takeoff: FlightWaypoint
|
||||
target: FlightWaypoint
|
||||
land: FlightWaypoint
|
||||
divert: Optional[FlightWaypoint]
|
||||
|
||||
@property
|
||||
def waypoints(self) -> List[FlightWaypoint]:
|
||||
return [
|
||||
def iter_waypoints(self) -> Iterator[FlightWaypoint]:
|
||||
yield from [
|
||||
self.takeoff,
|
||||
self.patrol_start,
|
||||
self.target,
|
||||
self.patrol_end,
|
||||
self.land,
|
||||
]
|
||||
if self.divert is not None:
|
||||
yield self.divert
|
||||
|
||||
def request_escort_at(self) -> Optional[FlightWaypoint]:
|
||||
return self.patrol_start
|
||||
@@ -350,16 +355,18 @@ class CasFlightPlan(PatrollingFlightPlan):
|
||||
class TarCapFlightPlan(PatrollingFlightPlan):
|
||||
takeoff: FlightWaypoint
|
||||
land: FlightWaypoint
|
||||
divert: Optional[FlightWaypoint]
|
||||
lead_time: timedelta
|
||||
|
||||
@property
|
||||
def waypoints(self) -> List[FlightWaypoint]:
|
||||
return [
|
||||
def iter_waypoints(self) -> Iterator[FlightWaypoint]:
|
||||
yield from [
|
||||
self.takeoff,
|
||||
self.patrol_start,
|
||||
self.patrol_end,
|
||||
self.land,
|
||||
]
|
||||
if self.divert is not None:
|
||||
yield self.divert
|
||||
|
||||
@property
|
||||
def tot_offset(self) -> timedelta:
|
||||
@@ -400,19 +407,23 @@ class StrikeFlightPlan(FormationFlightPlan):
|
||||
egress: FlightWaypoint
|
||||
split: FlightWaypoint
|
||||
land: FlightWaypoint
|
||||
divert: Optional[FlightWaypoint]
|
||||
|
||||
@property
|
||||
def waypoints(self) -> List[FlightWaypoint]:
|
||||
return [
|
||||
def iter_waypoints(self) -> Iterator[FlightWaypoint]:
|
||||
yield from [
|
||||
self.takeoff,
|
||||
self.hold,
|
||||
self.join,
|
||||
self.ingress
|
||||
] + self.targets + [
|
||||
]
|
||||
yield from self.targets
|
||||
yield from[
|
||||
self.egress,
|
||||
self.split,
|
||||
self.land,
|
||||
]
|
||||
if self.divert is not None:
|
||||
yield self.divert
|
||||
|
||||
@property
|
||||
def package_speed_waypoints(self) -> Set[FlightWaypoint]:
|
||||
@@ -511,17 +522,19 @@ class SweepFlightPlan(LoiterFlightPlan):
|
||||
sweep_start: FlightWaypoint
|
||||
sweep_end: FlightWaypoint
|
||||
land: FlightWaypoint
|
||||
divert: Optional[FlightWaypoint]
|
||||
lead_time: timedelta
|
||||
|
||||
@property
|
||||
def waypoints(self) -> List[FlightWaypoint]:
|
||||
return [
|
||||
def iter_waypoints(self) -> Iterator[FlightWaypoint]:
|
||||
yield from [
|
||||
self.takeoff,
|
||||
self.hold,
|
||||
self.sweep_start,
|
||||
self.sweep_end,
|
||||
self.land,
|
||||
]
|
||||
if self.divert is not None:
|
||||
yield self.divert
|
||||
|
||||
@property
|
||||
def tot_waypoint(self) -> Optional[FlightWaypoint]:
|
||||
@@ -567,9 +580,8 @@ class SweepFlightPlan(LoiterFlightPlan):
|
||||
class CustomFlightPlan(FlightPlan):
|
||||
custom_waypoints: List[FlightWaypoint]
|
||||
|
||||
@property
|
||||
def waypoints(self) -> List[FlightWaypoint]:
|
||||
return self.custom_waypoints
|
||||
def iter_waypoints(self) -> Iterator[FlightWaypoint]:
|
||||
yield from self.custom_waypoints
|
||||
|
||||
@property
|
||||
def tot_waypoint(self) -> Optional[FlightWaypoint]:
|
||||
@@ -774,10 +786,11 @@ class FlightPlanBuilder:
|
||||
package=self.package,
|
||||
flight=flight,
|
||||
patrol_duration=self.doctrine.cap_duration,
|
||||
takeoff=builder.takeoff(flight.from_cp),
|
||||
takeoff=builder.takeoff(flight.departure),
|
||||
patrol_start=start,
|
||||
patrol_end=end,
|
||||
land=builder.land(flight.from_cp)
|
||||
land=builder.land(flight.arrival),
|
||||
divert=builder.divert(flight.divert)
|
||||
)
|
||||
|
||||
def generate_sweep(self, flight: Flight) -> SweepFlightPlan:
|
||||
@@ -800,11 +813,12 @@ class FlightPlanBuilder:
|
||||
package=self.package,
|
||||
flight=flight,
|
||||
lead_time=timedelta(minutes=5),
|
||||
takeoff=builder.takeoff(flight.from_cp),
|
||||
takeoff=builder.takeoff(flight.departure),
|
||||
hold=builder.hold(self._hold_point(flight)),
|
||||
sweep_start=start,
|
||||
sweep_end=end,
|
||||
land=builder.land(flight.from_cp)
|
||||
land=builder.land(flight.arrival),
|
||||
divert=builder.divert(flight.divert)
|
||||
)
|
||||
|
||||
def racetrack_for_objective(self,
|
||||
@@ -900,10 +914,11 @@ class FlightPlanBuilder:
|
||||
# requests an escort the CAP flight will remain on station for the
|
||||
# duration of the escorted mission, or until it is winchester/bingo.
|
||||
patrol_duration=self.doctrine.cap_duration,
|
||||
takeoff=builder.takeoff(flight.from_cp),
|
||||
takeoff=builder.takeoff(flight.departure),
|
||||
patrol_start=start,
|
||||
patrol_end=end,
|
||||
land=builder.land(flight.from_cp)
|
||||
land=builder.land(flight.arrival),
|
||||
divert=builder.divert(flight.divert)
|
||||
)
|
||||
|
||||
def generate_dead(self, flight: Flight,
|
||||
@@ -965,14 +980,15 @@ class FlightPlanBuilder:
|
||||
return StrikeFlightPlan(
|
||||
package=self.package,
|
||||
flight=flight,
|
||||
takeoff=builder.takeoff(flight.from_cp),
|
||||
takeoff=builder.takeoff(flight.departure),
|
||||
hold=builder.hold(self._hold_point(flight)),
|
||||
join=builder.join(self.package.waypoints.join),
|
||||
ingress=ingress,
|
||||
targets=[target],
|
||||
egress=egress,
|
||||
split=builder.split(self.package.waypoints.split),
|
||||
land=builder.land(flight.from_cp)
|
||||
land=builder.land(flight.arrival),
|
||||
divert=builder.divert(flight.divert)
|
||||
)
|
||||
|
||||
def generate_cas(self, flight: Flight) -> CasFlightPlan:
|
||||
@@ -999,11 +1015,12 @@ class FlightPlanBuilder:
|
||||
package=self.package,
|
||||
flight=flight,
|
||||
patrol_duration=self.doctrine.cas_duration,
|
||||
takeoff=builder.takeoff(flight.from_cp),
|
||||
takeoff=builder.takeoff(flight.departure),
|
||||
patrol_start=builder.ingress_cas(ingress, location),
|
||||
target=builder.cas(center),
|
||||
patrol_end=builder.egress(egress, location),
|
||||
land=builder.land(flight.from_cp)
|
||||
land=builder.land(flight.arrival),
|
||||
divert=builder.divert(flight.divert)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
@@ -1030,7 +1047,7 @@ class FlightPlanBuilder:
|
||||
|
||||
def _hold_point(self, flight: Flight) -> Point:
|
||||
assert self.package.waypoints is not None
|
||||
origin = flight.from_cp.position
|
||||
origin = flight.departure.position
|
||||
target = self.package.target.position
|
||||
join = self.package.waypoints.join
|
||||
origin_to_target = origin.distance_to_point(target)
|
||||
@@ -1118,14 +1135,15 @@ class FlightPlanBuilder:
|
||||
return StrikeFlightPlan(
|
||||
package=self.package,
|
||||
flight=flight,
|
||||
takeoff=builder.takeoff(flight.from_cp),
|
||||
takeoff=builder.takeoff(flight.departure),
|
||||
hold=builder.hold(self._hold_point(flight)),
|
||||
join=builder.join(self.package.waypoints.join),
|
||||
ingress=ingress,
|
||||
targets=target_waypoints,
|
||||
egress=builder.egress(self.package.waypoints.egress, location),
|
||||
split=builder.split(self.package.waypoints.split),
|
||||
land=builder.land(flight.from_cp)
|
||||
land=builder.land(flight.arrival),
|
||||
divert=builder.divert(flight.divert)
|
||||
)
|
||||
|
||||
def _retreating_rendezvous_point(self, attack_transition: Point) -> Point:
|
||||
@@ -1201,7 +1219,7 @@ class FlightPlanBuilder:
|
||||
)
|
||||
for airfield in cache.closest_airfields:
|
||||
for flight in self.package.flights:
|
||||
if flight.from_cp == airfield:
|
||||
if flight.departure == airfield:
|
||||
return airfield
|
||||
raise RuntimeError(
|
||||
"Could not find any airfield assigned to this package"
|
||||
|
||||
Reference in New Issue
Block a user