Dan Albert 88b4039e47 Clean up AircraftGenerator.
This class does far too many things and the file is huge. Split it up
into a few more classes.
2021-10-23 20:18:40 -07:00

109 lines
3.2 KiB
Python

from __future__ import annotations
from dataclasses import dataclass, field
from datetime import timedelta
from typing import Optional, TYPE_CHECKING
from dcs.flyingunit import FlyingUnit
from gen.callsigns import create_group_callsign_from_unit
if TYPE_CHECKING:
from game.ato import FlightType, FlightWaypoint, Package
from game.dcs.aircrafttype import AircraftType
from game.radio.radios import RadioFrequency
from gen.runways import RunwayData
@dataclass(frozen=True)
class ChannelAssignment:
radio_id: int
channel: int
@dataclass
class FlightData:
"""Details of a planned flight."""
#: The package that the flight belongs to.
package: Package
flight_type: FlightType
aircraft_type: AircraftType
#: All units in the flight.
units: list[FlyingUnit]
#: Total number of aircraft in the flight.
size: int
#: True if this flight belongs to the player's coalition.
friendly: bool
#: Number of seconds after mission start the flight is set to depart.
departure_delay: timedelta
#: Arrival airport.
arrival: RunwayData
#: Departure airport.
departure: RunwayData
#: Diver airport.
divert: Optional[RunwayData]
#: Waypoints of the flight plan.
waypoints: list[FlightWaypoint]
#: Radio frequency for intra-flight communications.
intra_flight_channel: RadioFrequency
#: Bingo fuel value in lbs.
bingo_fuel: Optional[int]
joker_fuel: Optional[int]
laser_codes: list[Optional[int]]
custom_name: Optional[str]
callsign: str = field(init=False)
#: Map of radio frequencies to their assigned radio and channel, if any.
frequency_to_channel_map: dict[RadioFrequency, ChannelAssignment] = field(
init=False, default_factory=dict
)
def __post_init__(self) -> None:
self.callsign = create_group_callsign_from_unit(self.units[0])
@property
def client_units(self) -> list[FlyingUnit]:
"""List of playable units in the flight."""
return [u for u in self.units if u.is_human()]
def num_radio_channels(self, radio_id: int) -> int:
"""Returns the number of preset channels for the given radio."""
# Note: pydcs only initializes the radio presets for client slots.
return self.client_units[0].num_radio_channels(radio_id)
def channel_for(self, frequency: RadioFrequency) -> Optional[ChannelAssignment]:
"""Returns the radio and channel number for the given frequency."""
return self.frequency_to_channel_map.get(frequency, None)
def assign_channel(
self, radio_id: int, channel_id: int, frequency: RadioFrequency
) -> None:
"""Assigns a preset radio channel to the given frequency."""
for unit in self.client_units:
unit.set_radio_channel_preset(radio_id, channel_id, frequency.mhz)
# One frequency could be bound to multiple channels. Prefer the first,
# since with the current implementation it will be the lowest numbered
# channel.
if frequency not in self.frequency_to_channel_map:
self.frequency_to_channel_map[frequency] = ChannelAssignment(
radio_id, channel_id
)