Add windsocks to FARPs, kneeboard improvements.

Kneeboard improvements:

* Optional (aircraft specific) metric speeds/distances/altitudes.
* Heading to waypoint.

Fuel still needs to be converted to metric, but good enough for now.

Fixes https://github.com/dcs-liberation/dcs_liberation/issues/915
This commit is contained in:
bbirchnz 2022-01-08 11:58:53 +11:00 committed by GitHub
parent eb6c187180
commit 39152eab3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 9 deletions

View File

@ -154,6 +154,9 @@ class AircraftType(UnitType[Type[FlyingType]]):
# main weapon. It'll RTB when it doesn't have gun ammo left. # main weapon. It'll RTB when it doesn't have gun ammo left.
gunfighter: bool gunfighter: bool
# If true, kneeboards will be generated in metric units
metric_kneeboard: bool
max_group_size: int max_group_size: int
patrol_altitude: Optional[Distance] patrol_altitude: Optional[Distance]
patrol_speed: Optional[Speed] patrol_speed: Optional[Speed]
@ -395,4 +398,5 @@ class AircraftType(UnitType[Type[FlyingType]]):
intra_flight_radio=radio_config.intra_flight, intra_flight_radio=radio_config.intra_flight,
channel_allocator=radio_config.channel_allocator, channel_allocator=radio_config.channel_allocator,
channel_namer=radio_config.channel_namer, channel_namer=radio_config.channel_namer,
metric_kneeboard=data.get("metric_kneeboard", False),
) )

View File

@ -44,7 +44,7 @@ from game.dcs.aircrafttype import AircraftType
from game.radio.radios import RadioFrequency from game.radio.radios import RadioFrequency
from game.theater import ConflictTheater, LatLon, TheaterGroundObject from game.theater import ConflictTheater, LatLon, TheaterGroundObject
from game.theater.bullseye import Bullseye from game.theater.bullseye import Bullseye
from game.utils import meters from game.utils import Distance, meters
from game.weather import Weather from game.weather import Weather
from gen.runways import RunwayData from gen.runways import RunwayData
from .aircraft.flightdata import FlightData from .aircraft.flightdata import FlightData
@ -202,11 +202,12 @@ class FlightPlanBuilder:
WAYPOINT_DESC_MAX_LEN = 25 WAYPOINT_DESC_MAX_LEN = 25
def __init__(self, start_time: datetime.datetime) -> None: def __init__(self, start_time: datetime.datetime, is_metric: bool) -> None:
self.start_time = start_time self.start_time = start_time
self.rows: List[List[str]] = [] self.rows: List[List[str]] = []
self.target_points: List[NumberedWaypoint] = [] self.target_points: List[NumberedWaypoint] = []
self.last_waypoint: Optional[FlightWaypoint] = None self.last_waypoint: Optional[FlightWaypoint] = None
self.is_metric = is_metric
def add_waypoint(self, waypoint_num: int, waypoint: FlightWaypoint) -> None: def add_waypoint(self, waypoint_num: int, waypoint: FlightWaypoint) -> None:
if waypoint.waypoint_type == FlightWaypointType.TARGET_POINT: if waypoint.waypoint_type == FlightWaypointType.TARGET_POINT:
@ -251,8 +252,9 @@ class FlightPlanBuilder:
waypoint.waypoint.pretty_name, waypoint.waypoint.pretty_name,
FlightPlanBuilder.WAYPOINT_DESC_MAX_LEN, FlightPlanBuilder.WAYPOINT_DESC_MAX_LEN,
), ),
str(int(waypoint.waypoint.alt.feet)), self._format_alt(waypoint.waypoint.alt),
self._waypoint_distance(waypoint.waypoint), self._waypoint_distance(waypoint.waypoint),
self._waypoint_bearing(waypoint.waypoint),
self._ground_speed(waypoint.waypoint), self._ground_speed(waypoint.waypoint),
self._format_time(waypoint.waypoint.tot), self._format_time(waypoint.waypoint.tot),
self._format_time(waypoint.waypoint.departure_time), self._format_time(waypoint.waypoint.departure_time),
@ -266,14 +268,33 @@ class FlightPlanBuilder:
local_time = self.start_time + time local_time = self.start_time + time
return local_time.strftime(f"%H:%M:%S") return local_time.strftime(f"%H:%M:%S")
def _format_alt(self, alt: Distance) -> str:
if self.is_metric:
return f"{alt.meters:.0f} m"
else:
return f"{alt.feet:.0f} ft"
def _waypoint_distance(self, waypoint: FlightWaypoint) -> str: def _waypoint_distance(self, waypoint: FlightWaypoint) -> str:
if self.last_waypoint is None: if self.last_waypoint is None:
return "-" return "-"
if self.is_metric:
distance = meters( distance = meters(
self.last_waypoint.position.distance_to_point(waypoint.position) self.last_waypoint.position.distance_to_point(waypoint.position)
) )
return f"{distance.nautical_miles:.1f} NM" return f"{(distance.meters / 1000):.1f} km"
else:
distance = meters(
self.last_waypoint.position.distance_to_point(waypoint.position)
)
return f"{distance.nautical_miles:.1f} nm"
def _waypoint_bearing(self, waypoint: FlightWaypoint) -> str:
if self.last_waypoint is None:
return "-"
bearing = self.last_waypoint.position.heading_between_point(waypoint.position)
return f"{(bearing):.0f} T"
def _ground_speed(self, waypoint: FlightWaypoint) -> str: def _ground_speed(self, waypoint: FlightWaypoint) -> str:
if self.last_waypoint is None: if self.last_waypoint is None:
@ -293,6 +314,9 @@ class FlightPlanBuilder:
self.last_waypoint.position.distance_to_point(waypoint.position) self.last_waypoint.position.distance_to_point(waypoint.position)
) )
duration = (waypoint.tot - last_time).total_seconds() / 3600 duration = (waypoint.tot - last_time).total_seconds() / 3600
if self.is_metric:
return f"{int((distance.meters / 1000) / duration)} km/h"
else:
return f"{int(distance.nautical_miles / duration)} kt" return f"{int(distance.nautical_miles / duration)} kt"
@staticmethod @staticmethod
@ -349,7 +373,9 @@ class BriefingPage(KneeboardPage):
) )
writer.heading("Flight Plan") writer.heading("Flight Plan")
flight_plan_builder = FlightPlanBuilder(self.start_time) flight_plan_builder = FlightPlanBuilder(
self.start_time, self.flight.aircraft_type.metric_kneeboard
)
for num, waypoint in enumerate(self.flight.waypoints): for num, waypoint in enumerate(self.flight.waypoints):
flight_plan_builder.add_waypoint(num, waypoint) flight_plan_builder.add_waypoint(num, waypoint)
writer.table( writer.table(
@ -359,6 +385,7 @@ class BriefingPage(KneeboardPage):
"Action", "Action",
"Alt", "Alt",
"Dist", "Dist",
"Brg",
"GSPD", "GSPD",
"Time", "Time",
"Departure", "Departure",

View File

@ -644,6 +644,15 @@ class HelipadGenerator:
).point_from_heading(helipad.heading.degrees + 90, 10), ).point_from_heading(helipad.heading.degrees + 90, 10),
heading=pad.heading, heading=pad.heading,
) )
self.m.static_group(
country=country,
name=(name + "_ws"),
_type=Fortification.Windsock,
position=pad.position.point_from_heading(
helipad.heading.degrees + 45, 35
),
heading=pad.heading,
)
class TgoGenerator: class TgoGenerator:

View File

@ -19,5 +19,6 @@ manufacturer: Mil
origin: USSR/Russia origin: USSR/Russia
price: 14 price: 14
role: Attack/Transport role: Attack/Transport
metric_kneeboard: true
variants: variants:
Mi-24P Hind-F: {} Mi-24P Hind-F: {}