mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
refactor to enum typing and many other fixes fix tests attempt to fix some typescript more typescript fixes more typescript test fixes revert all API changes update to pydcs mypy fixes Use properties to check if player is blue/red/neutral update requirements.txt black -_- bump pydcs and fix mypy add opponent property bump pydcs
113 lines
3.3 KiB
Python
113 lines
3.3 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 game.callsigns import create_group_callsign_from_unit
|
|
from game.squadrons import Squadron
|
|
|
|
if TYPE_CHECKING:
|
|
from game.ato import FlightType, FlightWaypoint, Package
|
|
from game.dcs.aircrafttype import AircraftType
|
|
from game.radio.radios import RadioFrequency
|
|
from game.runways import RunwayData
|
|
from game.theater.player import Player
|
|
|
|
|
|
@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
|
|
|
|
squadron: Squadron
|
|
|
|
#: 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: Player
|
|
|
|
#: 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
|
|
)
|