diff --git a/gen/flights/flight.py b/gen/flights/flight.py index 5aba1d83..378f50b8 100644 --- a/gen/flights/flight.py +++ b/gen/flights/flight.py @@ -1,9 +1,11 @@ from enum import Enum -from typing import Dict, Iterable, Optional +from typing import Dict, Iterable, List, Optional + +from dcs.mapping import Point +from dcs.point import MovingPoint, PointAction +from dcs.unittype import UnitType from game import db -from dcs.unittype import UnitType -from dcs.point import MovingPoint, PointAction from theater.controlpoint import ControlPoint, MissionTarget @@ -98,11 +100,15 @@ class FlightWaypoint: self.tot: Optional[int] = None self.departure_time: Optional[int] = 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(point.position.x, point.position.y, - point.alt) + waypoint = FlightWaypoint(FlightWaypointType.NAV, point.position.x, + point.position.y, point.alt) waypoint.alt_type = point.alt_type # Other actions exist... but none of them *should* be the first # waypoint for a flight. @@ -159,14 +165,3 @@ class Flight: if waypoint.waypoint_type in types: return waypoint return None - - -# Test -if __name__ == '__main__': - from dcs.planes import A_10C - from theater import ControlPoint, Point, List - - from_cp = ControlPoint(0, "AA", Point(0, 0), Point(0, 0), [], 0, 0) - f = Flight(A_10C(), 4, from_cp, FlightType.CAS, "Cold") - f.scheduled_in = 50 - print(f) diff --git a/gen/kneeboard.py b/gen/kneeboard.py index 3ef775ef..a0c4c7a5 100644 --- a/gen/kneeboard.py +++ b/gen/kneeboard.py @@ -29,16 +29,19 @@ from pathlib import Path from typing import Dict, List, Optional, Tuple from PIL import Image, ImageDraw, ImageFont +from dcs.mapping import Point from dcs.mission import Mission from dcs.unittype import FlyingType from tabulate import tabulate +from game.utils import meter_to_nm from . import units from .aircraft import AIRCRAFT_DATA, FlightData from .airfields import RunwayData from .airsupportgen import AwacsInfo, TankerInfo from .briefinggen import CommInfo, JtacInfo, MissionInfoGenerator from .flights.flight import FlightWaypoint, FlightWaypointType +from .flights.traveltime import TravelTime from .radios import RadioFrequency @@ -111,6 +114,7 @@ class FlightPlanBuilder: self.start_time = start_time self.rows: List[List[str]] = [] self.target_points: List[NumberedWaypoint] = [] + self.last_waypoint: Optional[FlightWaypoint] = None def add_waypoint(self, waypoint_num: int, waypoint: FlightWaypoint) -> None: if waypoint.waypoint_type == FlightWaypointType.TARGET_POINT: @@ -136,23 +140,59 @@ class FlightPlanBuilder: f"{first_waypoint_num}-{last_waypoint_num}", "Target points", "0", + self._waypoint_distance(self.target_points[0].waypoint), + self._ground_speed(self.target_points[0].waypoint), self._format_time(self.target_points[0].waypoint.tot), + self._format_time(self.target_points[0].waypoint.departure_time), ]) + self.last_waypoint = self.target_points[-1].waypoint def add_waypoint_row(self, waypoint: NumberedWaypoint) -> None: self.rows.append([ str(waypoint.number), waypoint.waypoint.pretty_name, str(int(units.meters_to_feet(waypoint.waypoint.alt))), + self._waypoint_distance(waypoint.waypoint), + self._ground_speed(waypoint.waypoint), self._format_time(waypoint.waypoint.tot), self._format_time(waypoint.waypoint.departure_time), ]) + self.last_waypoint = waypoint.waypoint def _format_time(self, time: Optional[int]) -> str: if time is None: return "" local_time = self.start_time + datetime.timedelta(seconds=time) - return local_time.strftime(f"%H:%M:%S LOCAL") + return local_time.strftime(f"%H:%M:%S") + + def _waypoint_distance(self, waypoint: FlightWaypoint) -> str: + if self.last_waypoint is None: + return "-" + + distance = meter_to_nm(self.last_waypoint.position.distance_to_point( + waypoint.position + )) + return f"{distance} NM" + + def _ground_speed(self, waypoint: FlightWaypoint) -> str: + if self.last_waypoint is None: + return "-" + + if waypoint.tot is None: + return "-" + + if self.last_waypoint.departure_time is not None: + last_time = self.last_waypoint.departure_time + elif self.last_waypoint.tot is not None: + last_time = self.last_waypoint.tot + else: + return "-" + + distance = meter_to_nm(self.last_waypoint.position.distance_to_point( + waypoint.position + )) + duration = (waypoint.tot - last_time) / 3600 + return f"{int(distance / duration)} kt" def build(self) -> List[List[str]]: return self.rows @@ -187,8 +227,9 @@ class BriefingPage(KneeboardPage): flight_plan_builder = FlightPlanBuilder(self.start_time) for num, waypoint in enumerate(self.flight.waypoints): flight_plan_builder.add_waypoint(num, waypoint) - writer.table(flight_plan_builder.build(), - headers=["#", "Action", "Alt", "Time", "Departure"]) + writer.table(flight_plan_builder.build(), headers=[ + "#", "Action", "Alt", "Dist", "GSPD", "Time", "Departure" + ]) writer.heading("Comm Ladder") comms = []