mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
- setting for on-station time - always include CVN carriers as targets - autoplanner adjustment for continuous coverage
95 lines
3.4 KiB
Python
95 lines
3.4 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import timedelta
|
|
from typing import Type
|
|
|
|
from game.ato.flightplans.ibuilder import IBuilder
|
|
from game.ato.flightplans.patrolling import PatrollingFlightPlan, PatrollingLayout
|
|
from game.ato.flightplans.waypointbuilder import WaypointBuilder
|
|
from game.utils import Distance, Heading, Speed, knots, meters, nautical_miles
|
|
|
|
|
|
class AewcFlightPlan(PatrollingFlightPlan[PatrollingLayout]):
|
|
@property
|
|
def patrol_duration(self) -> timedelta:
|
|
return self.flight.coalition.game.settings.desired_awacs_mission_duration
|
|
|
|
@property
|
|
def patrol_speed(self) -> Speed:
|
|
altitude = self.layout.patrol_start.alt
|
|
if self.flight.unit_type.preferred_patrol_speed(altitude) is not None:
|
|
return self.flight.unit_type.preferred_patrol_speed(altitude)
|
|
return knots(390)
|
|
|
|
@property
|
|
def engagement_distance(self) -> Distance:
|
|
# TODO: Factor out a common base of the combat and non-combat race-tracks.
|
|
# No harm in setting this, but we ought to clean up a bit.
|
|
return meters(0)
|
|
|
|
@staticmethod
|
|
def builder_type() -> Type[Builder]:
|
|
return Builder
|
|
|
|
|
|
class Builder(IBuilder[AewcFlightPlan, PatrollingLayout]):
|
|
def layout(self) -> PatrollingLayout:
|
|
racetrack_half_distance = nautical_miles(30).meters
|
|
|
|
location = self.package.target
|
|
|
|
closest_boundary = self.threat_zones.closest_boundary(location.position)
|
|
heading_to_threat_boundary = Heading.from_degrees(
|
|
location.position.heading_between_point(closest_boundary)
|
|
)
|
|
distance_to_threat = meters(
|
|
location.position.distance_to_point(closest_boundary)
|
|
)
|
|
orbit_heading = heading_to_threat_boundary
|
|
|
|
# Station 80nm outside the threat zone.
|
|
threat_buffer = nautical_miles(
|
|
self.coalition.game.settings.aewc_threat_buffer_min_distance
|
|
)
|
|
if self.threat_zones.threatened(location.position):
|
|
orbit_distance = distance_to_threat + threat_buffer
|
|
else:
|
|
orbit_distance = distance_to_threat - threat_buffer
|
|
|
|
racetrack_center = location.position.point_from_heading(
|
|
orbit_heading.degrees, orbit_distance.meters
|
|
)
|
|
|
|
racetrack_start = racetrack_center.point_from_heading(
|
|
orbit_heading.right.degrees, racetrack_half_distance
|
|
)
|
|
|
|
racetrack_end = racetrack_center.point_from_heading(
|
|
orbit_heading.left.degrees, racetrack_half_distance
|
|
)
|
|
|
|
builder = WaypointBuilder(self.flight)
|
|
|
|
altitude = builder.get_patrol_altitude
|
|
|
|
racetrack = builder.race_track(racetrack_start, racetrack_end, altitude)
|
|
|
|
return PatrollingLayout(
|
|
departure=builder.takeoff(self.flight.departure),
|
|
nav_to=builder.nav_path(
|
|
self.flight.departure.position, racetrack_start, altitude
|
|
),
|
|
nav_from=builder.nav_path(
|
|
racetrack_end, self.flight.arrival.position, altitude
|
|
),
|
|
patrol_start=racetrack[0],
|
|
patrol_end=racetrack[1],
|
|
arrival=builder.land(self.flight.arrival),
|
|
divert=builder.divert(self.flight.divert),
|
|
bullseye=builder.bullseye(),
|
|
custom_waypoints=list(),
|
|
)
|
|
|
|
def build(self, dump_debug_info: bool = False) -> AewcFlightPlan:
|
|
return AewcFlightPlan(self.flight, self.layout())
|