dcs-retribution/game/ato/flightwaypoint.py

93 lines
3.5 KiB
Python

from datetime import timedelta
from typing import Optional, Sequence, Union
from dcs import Point
from dcs.point import MovingPoint, PointAction
from dcs.unit import Unit
from game.theater import ControlPoint, MissionTarget
from game.utils import Distance, meters
from game.ato.flightwaypointtype import FlightWaypointType
class FlightWaypoint:
def __init__(
self,
waypoint_type: FlightWaypointType,
x: float,
y: float,
alt: Distance = meters(0),
control_point: Optional[ControlPoint] = None,
) -> None:
"""Creates a flight waypoint.
Args:
waypoint_type: The waypoint type.
x: X coordinate of the waypoint.
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.
# Only used in the waypoint list in the flight edit page. No sense
# having three names. A short and long form is enough.
self.description = ""
self.targets: Sequence[Union[MissionTarget, Unit]] = []
self.obj_name = ""
self.pretty_name = ""
self.only_for_player = False
self.flyover = False
# The minimum amount of fuel remaining at this waypoint in pounds.
self.min_fuel: Optional[float] = None
# These are set very late by the air conflict generator (part of mission
# generation). We do it late so that we don't need to propagate changes
# to waypoint times whenever the player alters the package TOT or the
# flight's offset in the UI.
self.tot: Optional[timedelta] = None
self.departure_time: Optional[timedelta] = None
@property
def position(self) -> Point:
return Point(self.x, self.y)
@classmethod
def from_pydcs(cls, point: MovingPoint, from_cp: ControlPoint) -> "FlightWaypoint":
waypoint = FlightWaypoint(
FlightWaypointType.NAV,
point.position.x,
point.position.y,
meters(point.alt),
)
waypoint.alt_type = point.alt_type
# Other actions exist... but none of them *should* be the first
# waypoint for a flight.
waypoint.waypoint_type = {
PointAction.TurningPoint: FlightWaypointType.NAV,
PointAction.FlyOverPoint: FlightWaypointType.NAV,
PointAction.FromParkingArea: FlightWaypointType.TAKEOFF,
PointAction.FromParkingAreaHot: FlightWaypointType.TAKEOFF,
PointAction.FromRunway: FlightWaypointType.TAKEOFF,
PointAction.FromGroundArea: FlightWaypointType.TAKEOFF,
PointAction.FromGroundAreaHot: FlightWaypointType.TAKEOFF,
}[point.action]
if waypoint.waypoint_type == FlightWaypointType.NAV:
waypoint.name = "NAV"
waypoint.pretty_name = "Nav"
waypoint.description = "Nav"
else:
waypoint.name = "TAKEOFF"
waypoint.pretty_name = "Takeoff"
waypoint.description = "Takeoff"
waypoint.description = f"Takeoff from {from_cp.name}"
return waypoint