mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
* Added a separate Doctrine page in settings with the following new options: - Minimum number of aircraft for autoplanner to plan OCA packages against - Airbase threat range (nmi) - TARCAP threat buffer distance (nmi) - AEW&C threat buffer distance (nmi) - Theater tanker threat buffer distance (nmi) Implemented handling for the OPFOR autoplanner aggressiveness in objectivefinder.py vulnerable_control_points(). * * Added three new options in Settings: - Autoplanner plans refueling flights for Strike packages - Autoplanner plans refueling flights for OCA packages - Autoplanner plans refueling flights for DEAD packages Fixed a bug in faction.py where F-16Ds were not correctly removed from the faction when the F-16I/F-16D mod was not selected. * Renamed Maximum frontline length -> Maximum frontline width.
86 lines
3.0 KiB
Python
86 lines
3.0 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import timedelta
|
|
from typing import Type
|
|
|
|
from game.utils import Heading, feet, meters, nautical_miles
|
|
from .ibuilder import IBuilder
|
|
from .patrolling import PatrollingLayout
|
|
from .refuelingflightplan import RefuelingFlightPlan
|
|
from .waypointbuilder import WaypointBuilder
|
|
|
|
|
|
class TheaterRefuelingFlightPlan(RefuelingFlightPlan):
|
|
@staticmethod
|
|
def builder_type() -> Type[Builder]:
|
|
return Builder
|
|
|
|
@property
|
|
def patrol_duration(self) -> timedelta:
|
|
return self.flight.coalition.game.settings.desired_tanker_on_station_time
|
|
|
|
|
|
class Builder(IBuilder[TheaterRefuelingFlightPlan, PatrollingLayout]):
|
|
def layout(self) -> PatrollingLayout:
|
|
racetrack_half_distance = nautical_miles(20).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 70nm outside the threat zone.
|
|
threat_buffer = nautical_miles(
|
|
self.flight.coalition.game.settings.tanker_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, self.coalition)
|
|
|
|
tanker_type = self.flight.unit_type
|
|
if tanker_type.patrol_altitude is not None:
|
|
altitude = tanker_type.patrol_altitude
|
|
else:
|
|
altitude = feet(21000)
|
|
|
|
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(),
|
|
)
|
|
|
|
def build(self) -> TheaterRefuelingFlightPlan:
|
|
return TheaterRefuelingFlightPlan(self.flight, self.layout())
|