From 7bae6cd5629d2f510db0b21abee70b2345eae45f Mon Sep 17 00:00:00 2001 From: Raffson Date: Fri, 13 Jan 2023 20:27:13 +0100 Subject: [PATCH] Add package frequency Part of #70 --- .../aircraft/aircraftgenerator.py | 6 +++ .../aircraft/flightgroupconfigurator.py | 23 ++++----- qt_ui/windows/mission/QPackageDialog.py | 46 ++++++++++++++++-- .../mission/package/QPackageFrequency.py | 47 +++++++++++++++++++ resources/stylesheets/style-dcs.css | 10 ++-- 5 files changed, 111 insertions(+), 21 deletions(-) create mode 100644 qt_ui/windows/mission/package/QPackageFrequency.py diff --git a/game/missiongenerator/aircraft/aircraftgenerator.py b/game/missiongenerator/aircraft/aircraftgenerator.py index 231a66b6..300af99b 100644 --- a/game/missiongenerator/aircraft/aircraftgenerator.py +++ b/game/missiongenerator/aircraft/aircraftgenerator.py @@ -104,6 +104,12 @@ class AircraftGenerator: ato: The ATO to spawn aircraft for. dynamic_runways: Runway data for carriers and FARPs. """ + for package in reversed(sorted(ato.packages, key=lambda x: x.time_over_target)): + if package.frequency is None: + continue + if package.frequency not in self.radio_registry.allocated_channels: + self.radio_registry.reserve(package.frequency) + for package in reversed(sorted(ato.packages, key=lambda x: x.time_over_target)): if not package.flights: continue diff --git a/game/missiongenerator/aircraft/flightgroupconfigurator.py b/game/missiongenerator/aircraft/flightgroupconfigurator.py index 2e5acab7..0654973a 100644 --- a/game/missiongenerator/aircraft/flightgroupconfigurator.py +++ b/game/missiongenerator/aircraft/flightgroupconfigurator.py @@ -133,18 +133,19 @@ class FlightGroupConfigurator: laser_codes.append(None) def setup_radios(self) -> RadioFrequency: - if self.flight.flight_type in {FlightType.AEWC, FlightType.REFUELING}: - channel = self.radio_registry.alloc_uhf() - self.register_air_support(channel) - else: - 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) + if (freq := self.flight.package.frequency) is None: + freq = self.radio_registry.alloc_uhf() + self.flight.package.frequency = freq + elif freq not in self.radio_registry.allocated_channels: + self.radio_registry.reserve(freq) - self.group.set_frequency(channel.mhz) - return channel + if self.flight.flight_type in {FlightType.AEWC, FlightType.REFUELING}: + self.register_air_support(freq) + elif self.flight.client_count: + freq = self.flight.unit_type.alloc_flight_radio(self.radio_registry) + + self.group.set_frequency(freq.mhz) + return freq def register_air_support(self, channel: RadioFrequency) -> None: callsign = callsign_for_support_unit(self.group) diff --git a/qt_ui/windows/mission/QPackageDialog.py b/qt_ui/windows/mission/QPackageDialog.py index 306a25d1..de12dafc 100644 --- a/qt_ui/windows/mission/QPackageDialog.py +++ b/qt_ui/windows/mission/QPackageDialog.py @@ -20,6 +20,7 @@ from game.ato.flight import Flight from game.ato.flightplans.planningerror import PlanningError from game.ato.package import Package from game.game import Game +from game.radio.radios import RadioFrequency from game.server import EventStream from game.sim import GameUpdateEvents from game.theater.missiontarget import MissionTarget @@ -27,6 +28,7 @@ from qt_ui.models import AtoModel, GameModel, PackageModel from qt_ui.uiconstants import EVENT_ICONS from qt_ui.widgets.ato import QFlightList from qt_ui.windows.mission.flight.QFlightCreator import QFlightCreator +from qt_ui.windows.mission.package.QPackageFrequency import QPackageFrequency class QPackageDialog(QDialog): @@ -56,17 +58,30 @@ class QPackageDialog(QDialog): self.summary_row = QHBoxLayout() self.layout.addLayout(self.summary_row) - self.package_type_column = QHBoxLayout() + self.package_type_column = QVBoxLayout() self.summary_row.addLayout(self.package_type_column) + package_type_row = QHBoxLayout() self.package_type_label = QLabel("Package Type:") self.package_type_text = QLabel(self.package_model.description) # noinspection PyUnresolvedReferences - self.package_changed.connect( - lambda: self.package_type_text.setText(self.package_model.description) + self.package_changed.connect(self.on_package_changed) + package_type_row.addWidget(self.package_type_label) + package_type_row.addWidget(self.package_type_text) + self.package_type_column.addLayout(package_type_row) + + # TODO: make freq red if used by another package + package_freq_row = QHBoxLayout() + self.package_freq_label = QLabel("Package FREQ:") + freq = ( + self.package_model.package.frequency.mhz + if self.package_model.package.frequency is not None + else "" ) - self.package_type_column.addWidget(self.package_type_label) - self.package_type_column.addWidget(self.package_type_text) + self.package_freq_text = QLabel(f"{freq}") + package_freq_row.addWidget(self.package_freq_label) + package_freq_row.addWidget(self.package_freq_text) + self.package_type_column.addLayout(package_freq_row) self.summary_row.addStretch(1) @@ -130,6 +145,10 @@ class QPackageDialog(QDialog): self.delete_flight_button.setEnabled(model.rowCount() > 0) self.button_layout.addWidget(self.delete_flight_button) + self.open_radio_button = QPushButton("Set Package FREQ") + self.open_radio_button.clicked.connect(self.on_open_radio) + self.button_layout.addWidget(self.open_radio_button) + self.package_model.tot_changed.connect(self.update_tot) self.button_layout.addStretch() @@ -218,6 +237,23 @@ class QPackageDialog(QDialog): def on_change_name(self) -> None: self.package_model.package.custom_name = self.package_name_text.text() + def on_open_radio(self) -> None: + self.package_frequency_dialog = QPackageFrequency( + self.game, self.package_model.package, parent=self.window() + ) + self.package_frequency_dialog.accepted.connect(self.assign_frequency) + self.package_frequency_dialog.show() + + def assign_frequency(self): + hz = round(self.package_frequency_dialog.frequency_input.value() * 10**6) + self.package_model.package.frequency = RadioFrequency(hertz=hz) + self.package_changed.emit() + + def on_package_changed(self): + self.package_type_text.setText(self.package_model.description) + if (freq := self.package_model.package.frequency) is not None: + self.package_freq_text.setText(f"{freq.mhz} MHz") + class QNewPackageDialog(QPackageDialog): """Dialog window for creating a new package. diff --git a/qt_ui/windows/mission/package/QPackageFrequency.py b/qt_ui/windows/mission/package/QPackageFrequency.py new file mode 100644 index 00000000..7a97f319 --- /dev/null +++ b/qt_ui/windows/mission/package/QPackageFrequency.py @@ -0,0 +1,47 @@ +from typing import Optional, Type + +from PySide2.QtCore import Qt +from PySide2.QtWidgets import ( + QDialog, + QPushButton, + QVBoxLayout, + QLabel, + QHBoxLayout, + QDoubleSpinBox, +) + +from game import Game +from game.ato.package import Package +from game.radio.radios import RadioRegistry +from qt_ui.uiconstants import EVENT_ICONS + + +class QPackageFrequency(QDialog): + def __init__(self, game: Game, package: Package, parent=None) -> None: + super().__init__(parent=parent) + self.setMinimumWidth(400) + + self.game = game + self.package = package + + # Make dialog modal to prevent background windows to close unexpectedly. + self.setModal(True) + + self.setWindowTitle("Assign frequency") + self.setWindowIcon(EVENT_ICONS["strike"]) + + layout = QHBoxLayout() + + self.frequency_label = QLabel("FREQ (Mhz):") + self.frequency_input = QDoubleSpinBox() + self.frequency_input.setRange(225, 399.975) + self.frequency_input.setSingleStep(0.025) + self.frequency_input.setDecimals(3) + layout.addWidget(self.frequency_label) + layout.addWidget(self.frequency_input) + + self.create_button = QPushButton("Save") + self.create_button.clicked.connect(self.accept) + layout.addWidget(self.create_button, alignment=Qt.AlignRight) + + self.setLayout(layout) diff --git a/resources/stylesheets/style-dcs.css b/resources/stylesheets/style-dcs.css index b3726b2b..2d0e0ccf 100644 --- a/resources/stylesheets/style-dcs.css +++ b/resources/stylesheets/style-dcs.css @@ -479,7 +479,7 @@ QComboBox QAbstractItemView { /*QSpinBox number input with up down arrows*/ -QSpinBox{ +QSpinBox, QDoubleSpinBox{ border:1px solid #3B4656; color: #fff; padding: 4px 10px; @@ -487,19 +487,19 @@ QSpinBox{ min-width:40px; } -QSpinBox:hover{ +QSpinBox:hover, QDoubleSpinBox:hover{ border-color: #3592C4; } -QSpinBox::up-button , QSpinBox::down-button{ +QSpinBox::up-button , QSpinBox::down-button, QDoubleSpinBox::up-button, QDoubleSpinBox::down-button{ border:none; } -QSpinBox::up-button{ +QSpinBox::up-button, QDoubleSpinBox::up-button{ image: url(resources/stylesheets/chevron-up.png); } -QSpinBox::down-button{ +QSpinBox::down-button, QDoubleSpinBox::down-button{ image: url(resources/stylesheets/chevron-down.png); }