mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
parent
cc9f61005b
commit
48e0d579cf
@ -13,6 +13,7 @@ from .flightplans.formation import FormationFlightPlan
|
|||||||
from .flighttype import FlightType
|
from .flighttype import FlightType
|
||||||
from .packagewaypoints import PackageWaypoints
|
from .packagewaypoints import PackageWaypoints
|
||||||
from .traveltime import TotEstimator
|
from .traveltime import TotEstimator
|
||||||
|
from ..radio.radios import RadioFrequency
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from game.theater import ControlPoint, MissionTarget
|
from game.theater import ControlPoint, MissionTarget
|
||||||
@ -27,9 +28,11 @@ class Package:
|
|||||||
db: Database[Flight],
|
db: Database[Flight],
|
||||||
auto_asap: bool = False,
|
auto_asap: bool = False,
|
||||||
custom_name: str | None = None,
|
custom_name: str | None = None,
|
||||||
|
frequency: RadioFrequency | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.target = target
|
self.target = target
|
||||||
self._db = db
|
self._db = db
|
||||||
|
self.frequency = frequency
|
||||||
self.custom_name = custom_name
|
self.custom_name = custom_name
|
||||||
|
|
||||||
# True if the package ToT should be reset to ASAP whenever the player makes a
|
# True if the package ToT should be reset to ASAP whenever the player makes a
|
||||||
|
|||||||
@ -48,3 +48,5 @@ class Migrator:
|
|||||||
for p in c.ato.packages:
|
for p in c.ato.packages:
|
||||||
if not hasattr(p, "custom_name"):
|
if not hasattr(p, "custom_name"):
|
||||||
p.custom_name = None
|
p.custom_name = None
|
||||||
|
if not hasattr(p, "frequency"):
|
||||||
|
p.frequency = None
|
||||||
|
|||||||
@ -137,7 +137,11 @@ class FlightGroupConfigurator:
|
|||||||
channel = self.radio_registry.alloc_uhf()
|
channel = self.radio_registry.alloc_uhf()
|
||||||
self.register_air_support(channel)
|
self.register_air_support(channel)
|
||||||
else:
|
else:
|
||||||
channel = self.flight.unit_type.alloc_flight_radio(self.radio_registry)
|
if (channel := self.flight.package.frequency) is None:
|
||||||
|
channel = self.radio_registry.alloc_uhf()
|
||||||
|
self.flight.package.frequency = channel
|
||||||
|
if self.flight.client_count:
|
||||||
|
channel = self.flight.unit_type.alloc_flight_radio(self.radio_registry)
|
||||||
|
|
||||||
self.group.set_frequency(channel.mhz)
|
self.group.set_frequency(channel.mhz)
|
||||||
return channel
|
return channel
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import math
|
|||||||
import textwrap
|
import textwrap
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
from itertools import groupby
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Iterator, List, Optional, TYPE_CHECKING, Tuple
|
from typing import Dict, Iterator, List, Optional, TYPE_CHECKING, Tuple
|
||||||
|
|
||||||
@ -482,6 +483,7 @@ class SupportPage(KneeboardPage):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
flight: FlightData,
|
flight: FlightData,
|
||||||
|
package_flights: List[FlightData],
|
||||||
comms: List[CommInfo],
|
comms: List[CommInfo],
|
||||||
awacs: List[AwacsInfo],
|
awacs: List[AwacsInfo],
|
||||||
tankers: List[TankerInfo],
|
tankers: List[TankerInfo],
|
||||||
@ -490,6 +492,7 @@ class SupportPage(KneeboardPage):
|
|||||||
dark_kneeboard: bool,
|
dark_kneeboard: bool,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.flight = flight
|
self.flight = flight
|
||||||
|
self.package_flights = package_flights
|
||||||
self.comms = list(comms)
|
self.comms = list(comms)
|
||||||
self.awacs = awacs
|
self.awacs = awacs
|
||||||
self.tankers = tankers
|
self.tankers = tankers
|
||||||
@ -506,6 +509,36 @@ class SupportPage(KneeboardPage):
|
|||||||
custom_name_title = ""
|
custom_name_title = ""
|
||||||
writer.title(f"{self.flight.callsign} Support Info{custom_name_title}")
|
writer.title(f"{self.flight.callsign} Support Info{custom_name_title}")
|
||||||
|
|
||||||
|
# Package Section
|
||||||
|
package = self.flight.package
|
||||||
|
custom = f' "{package.custom_name}"' if package.custom_name else ""
|
||||||
|
writer.heading(f"{package.package_description} Package{custom}")
|
||||||
|
freq = self.format_frequency(package.frequency).replace("\n", " - ")
|
||||||
|
writer.text(f" FREQ: {freq}", font=writer.table_font)
|
||||||
|
comm_ladder = []
|
||||||
|
for comm in self.comms:
|
||||||
|
comm_ladder.append(
|
||||||
|
[
|
||||||
|
comm.name,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
str(len(self.flight.units)),
|
||||||
|
self.format_frequency(comm.freq),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
for f in self.package_flights:
|
||||||
|
comm_ladder.append(
|
||||||
|
[
|
||||||
|
f.callsign,
|
||||||
|
str(f.flight_type),
|
||||||
|
str(f.aircraft_type),
|
||||||
|
str(len(f.units)),
|
||||||
|
self.format_frequency(f.intra_flight_channel),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
writer.table(comm_ladder, headers=["Callsign", "Task", "Type", "#A/C", "FREQ"])
|
||||||
|
|
||||||
# AEW&C
|
# AEW&C
|
||||||
writer.heading("AEW&C")
|
writer.heading("AEW&C")
|
||||||
aewc_ladder = []
|
aewc_ladder = []
|
||||||
@ -534,14 +567,8 @@ class SupportPage(KneeboardPage):
|
|||||||
headers=["Callsign", "FREQ", "Depature", "ETD", "ETA"],
|
headers=["Callsign", "FREQ", "Depature", "ETD", "ETA"],
|
||||||
)
|
)
|
||||||
|
|
||||||
# Package Section
|
|
||||||
writer.heading("Comm ladder")
|
|
||||||
comm_ladder = []
|
comm_ladder = []
|
||||||
for comm in self.comms:
|
writer.heading("Tankers:")
|
||||||
comm_ladder.append(
|
|
||||||
[comm.name, "", "", "", self.format_frequency(comm.freq)]
|
|
||||||
)
|
|
||||||
|
|
||||||
for tanker in self.tankers:
|
for tanker in self.tankers:
|
||||||
comm_ladder.append(
|
comm_ladder.append(
|
||||||
[
|
[
|
||||||
@ -573,7 +600,9 @@ class SupportPage(KneeboardPage):
|
|||||||
|
|
||||||
writer.write(path)
|
writer.write(path)
|
||||||
|
|
||||||
def format_frequency(self, frequency: RadioFrequency) -> str:
|
def format_frequency(self, frequency: Optional[RadioFrequency]) -> str:
|
||||||
|
if frequency is None:
|
||||||
|
return ""
|
||||||
channel = self.flight.channel_for(frequency)
|
channel = self.flight.channel_for(frequency)
|
||||||
if channel is None:
|
if channel is None:
|
||||||
return str(frequency)
|
return str(frequency)
|
||||||
@ -733,8 +762,13 @@ class KneeboardGenerator(MissionInfoGenerator):
|
|||||||
for flight in self.flights:
|
for flight in self.flights:
|
||||||
if not flight.client_units:
|
if not flight.client_units:
|
||||||
continue
|
continue
|
||||||
|
package_flights = [
|
||||||
|
f
|
||||||
|
for f in self.flights
|
||||||
|
if f.package is flight.package and f is not flight
|
||||||
|
]
|
||||||
all_flights[flight.aircraft_type].extend(
|
all_flights[flight.aircraft_type].extend(
|
||||||
self.generate_flight_kneeboard(flight)
|
self.generate_flight_kneeboard(flight, package_flights)
|
||||||
)
|
)
|
||||||
return all_flights
|
return all_flights
|
||||||
|
|
||||||
@ -745,7 +779,9 @@ class KneeboardGenerator(MissionInfoGenerator):
|
|||||||
return StrikeTaskPage(flight, self.dark_kneeboard)
|
return StrikeTaskPage(flight, self.dark_kneeboard)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def generate_flight_kneeboard(self, flight: FlightData) -> List[KneeboardPage]:
|
def generate_flight_kneeboard(
|
||||||
|
self, flight: FlightData, package_flights: List[FlightData]
|
||||||
|
) -> List[KneeboardPage]:
|
||||||
"""Returns a list of kneeboard pages for the given flight."""
|
"""Returns a list of kneeboard pages for the given flight."""
|
||||||
|
|
||||||
if flight.aircraft_type.utc_kneeboard:
|
if flight.aircraft_type.utc_kneeboard:
|
||||||
@ -765,6 +801,7 @@ class KneeboardGenerator(MissionInfoGenerator):
|
|||||||
),
|
),
|
||||||
SupportPage(
|
SupportPage(
|
||||||
flight,
|
flight,
|
||||||
|
package_flights,
|
||||||
self.comms,
|
self.comms,
|
||||||
self.awacs,
|
self.awacs,
|
||||||
self.tankers,
|
self.tankers,
|
||||||
|
|||||||
@ -250,13 +250,13 @@ class MissionGenerator:
|
|||||||
self.mission.country(self.game.red.country_name),
|
self.mission.country(self.game.red.country_name),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.mission_data.flights = aircraft_generator.flights
|
||||||
|
|
||||||
for flight in aircraft_generator.flights:
|
for flight in aircraft_generator.flights:
|
||||||
if not flight.client_units:
|
if not flight.client_units:
|
||||||
continue
|
continue
|
||||||
flight.aircraft_type.assign_channels_for_flight(flight, self.mission_data)
|
flight.aircraft_type.assign_channels_for_flight(flight, self.mission_data)
|
||||||
|
|
||||||
self.mission_data.flights = aircraft_generator.flights
|
|
||||||
|
|
||||||
def generate_destroyed_units(self) -> None:
|
def generate_destroyed_units(self) -> None:
|
||||||
"""Add destroyed units to the Mission"""
|
"""Add destroyed units to the Mission"""
|
||||||
if not self.game.settings.perf_destroyed_units:
|
if not self.game.settings.perf_destroyed_units:
|
||||||
|
|||||||
@ -76,6 +76,9 @@ class CommonRadioChannelAllocator(RadioChannelAllocator):
|
|||||||
for jtac in mission_data.jtacs:
|
for jtac in mission_data.jtacs:
|
||||||
flight.assign_channel(radio_id, next(channel_alloc), jtac.freq)
|
flight.assign_channel(radio_id, next(channel_alloc), jtac.freq)
|
||||||
|
|
||||||
|
if (freq := flight.package.frequency) is not None:
|
||||||
|
flight.assign_channel(radio_id, next(channel_alloc), freq)
|
||||||
|
|
||||||
if flight.arrival != flight.departure and flight.arrival.atc is not None:
|
if flight.arrival != flight.departure and flight.arrival.atc is not None:
|
||||||
flight.assign_channel(radio_id, next(channel_alloc), flight.arrival.atc)
|
flight.assign_channel(radio_id, next(channel_alloc), flight.arrival.atc)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user