mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Plan multiple CAP rounds per turn.
On station time for CAP is only 30 minutes, so plan three cycles to give ~90 minutes of CAP coverage. Default starting budget has increased significantly to account for the greatly increased aircraft needs on turn 1. Fixes https://github.com/Khopa/dcs_liberation/issues/673
This commit is contained in:
@@ -118,6 +118,15 @@ class Package:
|
||||
return max(times)
|
||||
return None
|
||||
|
||||
@property
|
||||
def mission_departure_time(self) -> Optional[timedelta]:
|
||||
times = []
|
||||
for flight in self.flights:
|
||||
times.append(flight.flight_plan.mission_departure_time)
|
||||
if times:
|
||||
return max(times)
|
||||
return None
|
||||
|
||||
def add_flight(self, flight: Flight) -> None:
|
||||
"""Adds a flight to the package."""
|
||||
self.flights.append(flight)
|
||||
|
||||
@@ -481,6 +481,14 @@ class CoalitionMissionPlanner:
|
||||
"""
|
||||
# Find friendly CPs within 100 nmi from an enemy airfield, plan CAP.
|
||||
for cp in self.objective_finder.vulnerable_control_points():
|
||||
# Plan three rounds of CAP to give ~90 minutes coverage. Spacing
|
||||
# these out appropriately is done in stagger_missions.
|
||||
yield ProposedMission(cp, [
|
||||
ProposedFlight(FlightType.BARCAP, 2, self.MAX_CAP_RANGE),
|
||||
])
|
||||
yield ProposedMission(cp, [
|
||||
ProposedFlight(FlightType.BARCAP, 2, self.MAX_CAP_RANGE),
|
||||
])
|
||||
yield ProposedMission(cp, [
|
||||
ProposedFlight(FlightType.BARCAP, 2, self.MAX_CAP_RANGE),
|
||||
])
|
||||
@@ -698,10 +706,12 @@ class CoalitionMissionPlanner:
|
||||
|
||||
dca_types = {
|
||||
FlightType.BARCAP,
|
||||
FlightType.INTERCEPTION,
|
||||
FlightType.TARCAP,
|
||||
}
|
||||
|
||||
previous_cap_end_time: Dict[MissionTarget, timedelta] = defaultdict(
|
||||
timedelta
|
||||
)
|
||||
non_dca_packages = [p for p in self.ato.packages if
|
||||
p.primary_task not in dca_types]
|
||||
|
||||
@@ -714,8 +724,22 @@ class CoalitionMissionPlanner:
|
||||
for package in self.ato.packages:
|
||||
tot = TotEstimator(package).earliest_tot()
|
||||
if package.primary_task in dca_types:
|
||||
# All CAP missions should be on station ASAP.
|
||||
package.time_over_target = tot
|
||||
previous_end_time = previous_cap_end_time[package.target]
|
||||
if tot > previous_end_time:
|
||||
# Can't get there exactly on time, so get there ASAP. This
|
||||
# will typically only happen for the first CAP at each
|
||||
# target.
|
||||
package.time_over_target = tot
|
||||
else:
|
||||
package.time_over_target = previous_end_time
|
||||
|
||||
departure_time = package.mission_departure_time
|
||||
# Should be impossible for CAPs
|
||||
if departure_time is None:
|
||||
logging.error(
|
||||
f"Could not determine mission end time for {package}")
|
||||
continue
|
||||
previous_cap_end_time[package.target] = departure_time
|
||||
else:
|
||||
# But other packages should be spread out a bit. Note that take
|
||||
# times are delayed, but all aircraft will become active at
|
||||
|
||||
@@ -243,6 +243,11 @@ class FlightPlan:
|
||||
else:
|
||||
return timedelta(minutes=5)
|
||||
|
||||
@property
|
||||
def mission_departure_time(self) -> timedelta:
|
||||
"""The time that the mission is complete and the flight RTBs."""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class LoiterFlightPlan(FlightPlan):
|
||||
@@ -356,6 +361,10 @@ class FormationFlightPlan(LoiterFlightPlan):
|
||||
GroundSpeed.for_flight(self.flight, self.hold.alt)
|
||||
)
|
||||
|
||||
@property
|
||||
def mission_departure_time(self) -> timedelta:
|
||||
return self.split_time
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class PatrollingFlightPlan(FlightPlan):
|
||||
@@ -406,6 +415,10 @@ class PatrollingFlightPlan(FlightPlan):
|
||||
def tot_waypoint(self) -> Optional[FlightWaypoint]:
|
||||
return self.patrol_start
|
||||
|
||||
@property
|
||||
def mission_departure_time(self) -> timedelta:
|
||||
return self.patrol_end_time
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class BarCapFlightPlan(PatrollingFlightPlan):
|
||||
@@ -678,6 +691,9 @@ class SweepFlightPlan(LoiterFlightPlan):
|
||||
GroundSpeed.for_flight(self.flight, self.hold.alt)
|
||||
)
|
||||
|
||||
def mission_departure_time(self) -> timedelta:
|
||||
return self.sweep_end_time
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class CustomFlightPlan(FlightPlan):
|
||||
@@ -708,6 +724,10 @@ class CustomFlightPlan(FlightPlan):
|
||||
self, waypoint: FlightWaypoint) -> Optional[timedelta]:
|
||||
return None
|
||||
|
||||
@property
|
||||
def mission_departure_time(self) -> timedelta:
|
||||
return self.package.time_over_target
|
||||
|
||||
|
||||
class FlightPlanBuilder:
|
||||
"""Generates flight plans for flights."""
|
||||
|
||||
Reference in New Issue
Block a user