Merge remote-tracking branch 'khopa/develop' into helipads

# Conflicts:
#	changelog.md
This commit is contained in:
Khopa
2021-09-08 21:56:45 +02:00
132 changed files with 2856 additions and 648 deletions

View File

@@ -70,6 +70,7 @@ class FlightType(Enum):
TRANSPORT = "Transport"
SEAD_ESCORT = "SEAD Escort"
REFUELING = "Refueling"
FERRY = "Ferry"
def __str__(self) -> str:
return self.value
@@ -159,6 +160,7 @@ class FlightWaypoint:
x: float,
y: float,
alt: Distance = meters(0),
control_point: Optional[ControlPoint] = None,
) -> None:
"""Creates a flight waypoint.
@@ -168,11 +170,14 @@ class FlightWaypoint:
y: Y coordinate of the waypoint.
alt: Altitude of the waypoint. By default this is MSL, but it can be
changed to AGL by setting alt_type to "RADIO"
control_point: The control point to associate with this waypoint. Needed for
landing points.
"""
self.waypoint_type = waypoint_type
self.x = x
self.y = y
self.alt = alt
self.control_point = control_point
self.alt_type = "BARO"
self.name = ""
# TODO: Merge with pretty_name.
@@ -282,8 +287,6 @@ class Flight:
count: int,
flight_type: FlightType,
start_type: str,
departure: ControlPoint,
arrival: ControlPoint,
divert: Optional[ControlPoint],
custom_name: Optional[str] = None,
cargo: Optional[TransferOrder] = None,
@@ -297,8 +300,8 @@ class Flight:
self.roster = FlightRoster(self.squadron, initial_size=count)
else:
self.roster = roster
self.departure = departure
self.arrival = arrival
self.departure = self.squadron.location
self.arrival = self.squadron.arrival
self.divert = divert
self.flight_type = flight_type
# TODO: Replace with FlightPlan.

View File

@@ -37,10 +37,8 @@ from game.theater.theatergroundobject import (
NavalGroundObject,
BuildingGroundObject,
)
from game.threatzones import ThreatZones
from game.utils import Distance, Heading, Speed, feet, meters, nautical_miles, knots
from .closestairfields import ObjectiveDistanceCache
from .flight import Flight, FlightType, FlightWaypoint, FlightWaypointType
from .traveltime import GroundSpeed, TravelTime
@@ -836,6 +834,39 @@ class AirliftFlightPlan(FlightPlan):
return self.package.time_over_target
@dataclass(frozen=True)
class FerryFlightPlan(FlightPlan):
takeoff: FlightWaypoint
nav_to_destination: list[FlightWaypoint]
land: FlightWaypoint
divert: Optional[FlightWaypoint]
bullseye: FlightWaypoint
def iter_waypoints(self) -> Iterator[FlightWaypoint]:
yield self.takeoff
yield from self.nav_to_destination
yield self.land
if self.divert is not None:
yield self.divert
yield self.bullseye
@property
def tot_waypoint(self) -> Optional[FlightWaypoint]:
return self.land
def tot_for_waypoint(self, waypoint: FlightWaypoint) -> Optional[timedelta]:
# TOT planning isn't really useful for ferries. They're behind the front
# lines so no need to wait for escorts or for other missions to complete.
return None
def depart_time_for_waypoint(self, waypoint: FlightWaypoint) -> Optional[timedelta]:
return None
@property
def mission_departure_time(self) -> timedelta:
return self.package.time_over_target
@dataclass(frozen=True)
class CustomFlightPlan(FlightPlan):
custom_waypoints: List[FlightWaypoint]
@@ -958,6 +989,8 @@ class FlightPlanBuilder:
return self.generate_transport(flight)
elif task == FlightType.REFUELING:
return self.generate_refueling_racetrack(flight)
elif task == FlightType.FERRY:
return self.generate_ferry(flight)
raise PlanningError(f"{task} flight plan generation not implemented")
def regenerate_package_waypoints(self) -> None:
@@ -1244,6 +1277,42 @@ class FlightPlanBuilder:
bullseye=builder.bullseye(),
)
def generate_ferry(self, flight: Flight) -> FerryFlightPlan:
"""Generate a ferry flight at a given location.
Args:
flight: The flight to generate the flight plan for.
"""
if flight.departure == flight.arrival:
raise PlanningError(
f"Cannot plan ferry flight: departure and arrival are both "
f"{flight.departure}"
)
altitude_is_agl = flight.unit_type.dcs_unit_type.helicopter
altitude = (
feet(1500)
if altitude_is_agl
else flight.unit_type.preferred_patrol_altitude
)
builder = WaypointBuilder(flight, self.coalition)
return FerryFlightPlan(
package=self.package,
flight=flight,
takeoff=builder.takeoff(flight.departure),
nav_to_destination=builder.nav_path(
flight.departure.position,
flight.arrival.position,
altitude,
altitude_is_agl,
),
land=builder.land(flight.arrival),
divert=builder.divert(flight.divert),
bullseye=builder.bullseye(),
)
def cap_racetrack_for_objective(
self, location: MissionTarget, barcap: bool
) -> Tuple[Point, Point]:

View File

@@ -110,7 +110,11 @@ class WaypointBuilder:
waypoint.pretty_name = "Exit theater"
else:
waypoint = FlightWaypoint(
FlightWaypointType.LANDING_POINT, position.x, position.y, meters(0)
FlightWaypointType.LANDING_POINT,
position.x,
position.y,
meters(0),
control_point=arrival,
)
waypoint.name = "LANDING"
waypoint.alt_type = "RADIO"
@@ -139,7 +143,11 @@ class WaypointBuilder:
altitude_type = "RADIO"
waypoint = FlightWaypoint(
FlightWaypointType.DIVERT, position.x, position.y, altitude
FlightWaypointType.DIVERT,
position.x,
position.y,
altitude,
control_point=divert,
)
waypoint.alt_type = altitude_type
waypoint.name = "DIVERT"
@@ -488,6 +496,7 @@ class WaypointBuilder:
control_point.position.x,
control_point.position.y,
meters(0),
control_point=control_point,
)
waypoint.alt_type = "RADIO"
waypoint.name = "DROP OFF"