mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Use all modeled radio-bands in freq-selector
This commit is contained in:
parent
d581af3b8a
commit
3b7077e593
@ -18,6 +18,7 @@
|
|||||||
* **[Waypoints]** Allow user to add navigation waypoints where possible without degrading to a custom flight-plan
|
* **[Waypoints]** Allow user to add navigation waypoints where possible without degrading to a custom flight-plan
|
||||||
* **[Campaign Management]** Improve squadron retreat logic to account for parking-slot sizes
|
* **[Campaign Management]** Improve squadron retreat logic to account for parking-slot sizes
|
||||||
* **[Autoplanner]** Support for auto-planning Air Assaults
|
* **[Autoplanner]** Support for auto-planning Air Assaults
|
||||||
|
* **[UI]** Improved frequency selector to support all modeled bands for every aircraft's intra-flight radio
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
* **[Mission Generation]** Anti-ship strikes should use "group attack" in their attack-task
|
* **[Mission Generation]** Anti-ship strikes should use "group attack" in their attack-task
|
||||||
|
|||||||
@ -190,8 +190,8 @@ RADIOS: List[Radio] = [
|
|||||||
Radio(
|
Radio(
|
||||||
"AN/ARC-222",
|
"AN/ARC-222",
|
||||||
(
|
(
|
||||||
RadioRange(MHz(30), MHz(88), kHz(25), Modulation.FM),
|
|
||||||
RadioRange(MHz(116), MHz(152), kHz(25), Modulation.AM),
|
RadioRange(MHz(116), MHz(152), kHz(25), Modulation.AM),
|
||||||
|
RadioRange(MHz(30), MHz(88), kHz(25), Modulation.FM),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Radio("SCR-522", (RadioRange(MHz(100), MHz(156), kHz(25), Modulation.AM),)),
|
Radio("SCR-522", (RadioRange(MHz(100), MHz(156), kHz(25), Modulation.AM),)),
|
||||||
@ -200,8 +200,8 @@ RADIOS: List[Radio] = [
|
|||||||
Radio(
|
Radio(
|
||||||
"TRT ERA 7000 V/UHF",
|
"TRT ERA 7000 V/UHF",
|
||||||
(
|
(
|
||||||
RadioRange(MHz(118), MHz(150), kHz(25), Modulation.AM),
|
|
||||||
RadioRange(MHz(225), MHz(400), kHz(25), Modulation.AM),
|
RadioRange(MHz(225), MHz(400), kHz(25), Modulation.AM),
|
||||||
|
RadioRange(MHz(118), MHz(150), kHz(25), Modulation.AM),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Radio(
|
Radio(
|
||||||
@ -247,10 +247,10 @@ RADIOS: List[Radio] = [
|
|||||||
Radio(
|
Radio(
|
||||||
"R-863",
|
"R-863",
|
||||||
(
|
(
|
||||||
RadioRange(MHz(100), MHz(150), kHz(25), Modulation.AM),
|
|
||||||
RadioRange(MHz(220), MHz(400), kHz(25), Modulation.AM),
|
RadioRange(MHz(220), MHz(400), kHz(25), Modulation.AM),
|
||||||
RadioRange(MHz(100), MHz(150), kHz(25), Modulation.FM),
|
RadioRange(MHz(100), MHz(150), kHz(25), Modulation.AM),
|
||||||
RadioRange(MHz(220), MHz(400), kHz(25), Modulation.FM),
|
RadioRange(MHz(220), MHz(400), kHz(25), Modulation.FM),
|
||||||
|
RadioRange(MHz(100), MHz(150), kHz(25), Modulation.FM),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
# UH-1H
|
# UH-1H
|
||||||
@ -263,8 +263,8 @@ RADIOS: List[Radio] = [
|
|||||||
Radio(
|
Radio(
|
||||||
"V/UHF TRAP 136",
|
"V/UHF TRAP 136",
|
||||||
(
|
(
|
||||||
RadioRange(MHz(118), MHz(144), kHz(25), Modulation.AM),
|
|
||||||
RadioRange(MHz(225), MHz(400), kHz(25), Modulation.AM),
|
RadioRange(MHz(225), MHz(400), kHz(25), Modulation.AM),
|
||||||
|
RadioRange(MHz(118), MHz(144), kHz(25), Modulation.AM),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Radio("UHF TRAP 137B", (RadioRange(MHz(225), MHz(400), kHz(25), Modulation.AM),)),
|
Radio("UHF TRAP 137B", (RadioRange(MHz(225), MHz(400), kHz(25), Modulation.AM),)),
|
||||||
@ -272,9 +272,9 @@ RADIOS: List[Radio] = [
|
|||||||
Radio(
|
Radio(
|
||||||
"R-800",
|
"R-800",
|
||||||
(
|
(
|
||||||
RadioRange(MHz(30), MHz(88), kHz(25), Modulation.AM),
|
|
||||||
RadioRange(MHz(108), MHz(174), kHz(25), Modulation.AM),
|
|
||||||
RadioRange(MHz(225), MHz(400), kHz(25), Modulation.AM),
|
RadioRange(MHz(225), MHz(400), kHz(25), Modulation.AM),
|
||||||
|
RadioRange(MHz(108), MHz(174), kHz(25), Modulation.AM),
|
||||||
|
RadioRange(MHz(30), MHz(88), kHz(25), Modulation.AM),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
# MB-339A
|
# MB-339A
|
||||||
@ -294,18 +294,11 @@ RADIOS: List[Radio] = [
|
|||||||
"SRT-651/N",
|
"SRT-651/N",
|
||||||
(
|
(
|
||||||
RadioRange(
|
RadioRange(
|
||||||
MHz(30),
|
MHz(225),
|
||||||
MHz(88),
|
MHz(400),
|
||||||
kHz(25),
|
kHz(25),
|
||||||
Modulation.FM,
|
Modulation.AM, # Actually AM/FM, but we can't represent that.
|
||||||
frozenset((MHz(40, 500),)),
|
frozenset((MHz(243),)),
|
||||||
),
|
|
||||||
RadioRange(
|
|
||||||
MHz(108),
|
|
||||||
MHz(156),
|
|
||||||
kHz(25),
|
|
||||||
Modulation.AM,
|
|
||||||
frozenset((MHz(121, 500),)),
|
|
||||||
),
|
),
|
||||||
RadioRange(
|
RadioRange(
|
||||||
MHz(156),
|
MHz(156),
|
||||||
@ -315,11 +308,18 @@ RADIOS: List[Radio] = [
|
|||||||
frozenset((MHz(156, 800),)),
|
frozenset((MHz(156, 800),)),
|
||||||
),
|
),
|
||||||
RadioRange(
|
RadioRange(
|
||||||
MHz(225),
|
MHz(108),
|
||||||
MHz(400),
|
MHz(156),
|
||||||
kHz(25),
|
kHz(25),
|
||||||
Modulation.AM, # Actually AM/FM, but we can't represent that.
|
Modulation.AM,
|
||||||
frozenset((MHz(243),)),
|
frozenset((MHz(121, 500),)),
|
||||||
|
),
|
||||||
|
RadioRange(
|
||||||
|
MHz(30),
|
||||||
|
MHz(88),
|
||||||
|
kHz(25),
|
||||||
|
Modulation.FM,
|
||||||
|
frozenset((MHz(40, 500),)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -49,22 +49,18 @@ class QFrequencyWidget(QWidget):
|
|||||||
return f"<b>FREQ: {freq}</b>"
|
return f"<b>FREQ: {freq}</b>"
|
||||||
|
|
||||||
def open_freq_dialog(self) -> None:
|
def open_freq_dialog(self) -> None:
|
||||||
range = RadioRange(MHz(100), MHz(400), kHz(25))
|
ranges = [RadioRange(MHz(30), MHz(400), kHz(25))]
|
||||||
if isinstance(self.ct, Flight):
|
if isinstance(self.ct, Flight):
|
||||||
if self.ct.unit_type.intra_flight_radio is not None:
|
if self.ct.unit_type.intra_flight_radio is not None:
|
||||||
range = self.ct.unit_type.intra_flight_radio.ranges[0]
|
ranges = self.ct.unit_type.intra_flight_radio.ranges
|
||||||
self.frequency_dialog = QRadioFrequencyDialog(self, self.ct, range)
|
self.frequency_dialog = QRadioFrequencyDialog(self, self.ct, ranges)
|
||||||
self.frequency_dialog.accepted.connect(self.assign_frequency)
|
self.frequency_dialog.accepted.connect(self.assign_frequency)
|
||||||
self.frequency_dialog.show()
|
self.frequency_dialog.show()
|
||||||
|
|
||||||
def assign_frequency(self) -> None:
|
def assign_frequency(self) -> None:
|
||||||
hz = round(self.frequency_dialog.frequency_input.value() * 10**6)
|
hz = round(self.frequency_dialog.frequency_input.value() * 10**6)
|
||||||
self._try_remove()
|
self._try_remove()
|
||||||
mod = RadioFrequency.modulation
|
mod = self.frequency_dialog.frequency_modulation.currentData()
|
||||||
if isinstance(self.ct, Flight):
|
|
||||||
if self.ct.unit_type.intra_flight_radio is not None:
|
|
||||||
range = self.ct.unit_type.intra_flight_radio.ranges[0]
|
|
||||||
mod = range.modulation
|
|
||||||
self.ct.frequency = RadioFrequency(hertz=hz, modulation=mod)
|
self.ct.frequency = RadioFrequency(hertz=hz, modulation=mod)
|
||||||
self.gm.allocated_freqs.append(self.ct.frequency)
|
self.gm.allocated_freqs.append(self.ct.frequency)
|
||||||
self.freq.setText(self._get_label_text())
|
self.freq.setText(self._get_label_text())
|
||||||
|
|||||||
@ -46,8 +46,8 @@ class QLink4Widget(QWidget):
|
|||||||
return f"<b>LINK4: {freq}</b>"
|
return f"<b>LINK4: {freq}</b>"
|
||||||
|
|
||||||
def open_freq_dialog(self) -> None:
|
def open_freq_dialog(self) -> None:
|
||||||
range = RadioRange(MHz(225), MHz(400), kHz(25))
|
ranges = [RadioRange(MHz(225), MHz(400), kHz(25))]
|
||||||
self.frequency_dialog = QRadioFrequencyDialog(self, self.cp, range, link4=True)
|
self.frequency_dialog = QRadioFrequencyDialog(self, self.cp, ranges, link4=True)
|
||||||
self.frequency_dialog.accepted.connect(self.assign_frequency)
|
self.frequency_dialog.accepted.connect(self.assign_frequency)
|
||||||
self.frequency_dialog.show()
|
self.frequency_dialog.show()
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
from typing import Optional
|
from typing import Optional, Iterable
|
||||||
|
|
||||||
from PySide2.QtCore import Qt, QLocale
|
from PySide2.QtCore import Qt, QLocale
|
||||||
|
from PySide2.QtGui import QIcon
|
||||||
from PySide2.QtWidgets import (
|
from PySide2.QtWidgets import (
|
||||||
QDialog,
|
QDialog,
|
||||||
QPushButton,
|
QPushButton,
|
||||||
QLabel,
|
QLabel,
|
||||||
QHBoxLayout,
|
QHBoxLayout,
|
||||||
QDoubleSpinBox,
|
QDoubleSpinBox,
|
||||||
|
QComboBox,
|
||||||
)
|
)
|
||||||
|
|
||||||
from game.radio.Link4Container import Link4Container
|
from game.radio.Link4Container import Link4Container
|
||||||
@ -15,12 +17,80 @@ from game.radio.radios import RadioRange, kHz, MHz
|
|||||||
from qt_ui.uiconstants import EVENT_ICONS
|
from qt_ui.uiconstants import EVENT_ICONS
|
||||||
|
|
||||||
|
|
||||||
|
class QFrequencySpinbox(QDoubleSpinBox):
|
||||||
|
def __init__(self, ranges: Iterable[RadioRange]) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.setLocale(QLocale(QLocale.Language.English))
|
||||||
|
self.setDecimals(3)
|
||||||
|
self.ranges = list(ranges)
|
||||||
|
first = True
|
||||||
|
for r in ranges:
|
||||||
|
if r.minimum.mhz < self.minimum():
|
||||||
|
self.setMinimum(r.minimum.mhz)
|
||||||
|
if self.maximum() < r.maximum.mhz:
|
||||||
|
self.setMaximum(r.maximum.mhz)
|
||||||
|
if first:
|
||||||
|
self.setSingleStep(r.step.mhz)
|
||||||
|
self.setValue(r.minimum.mhz)
|
||||||
|
first = False
|
||||||
|
|
||||||
|
def correct_value(self, value: float) -> None:
|
||||||
|
for r in self.ranges:
|
||||||
|
if r.maximum.mhz == value:
|
||||||
|
self.setValue(value - r.step.mhz)
|
||||||
|
return
|
||||||
|
|
||||||
|
def stepBy(self, steps: int) -> None:
|
||||||
|
new_value = self.check_value(self.value() + (steps * self.singleStep()))
|
||||||
|
self.setValue(new_value)
|
||||||
|
|
||||||
|
def check_value(self, value: float) -> float:
|
||||||
|
for r in self.ranges:
|
||||||
|
if r.minimum.mhz <= value < r.maximum.mhz:
|
||||||
|
self.setSingleStep(r.step.mhz)
|
||||||
|
return value
|
||||||
|
minimums = [m for m in set(r.minimum.mhz for r in self.ranges) if m > value]
|
||||||
|
maximums = [m for m in set(r.maximum.mhz for r in self.ranges) if m <= value]
|
||||||
|
if not minimums or not maximums:
|
||||||
|
return self.value()
|
||||||
|
smallest_min = min(minimums)
|
||||||
|
largest_max = max(maximums)
|
||||||
|
if largest_max <= value < smallest_min:
|
||||||
|
if value < self.value():
|
||||||
|
rs = [r for r in self.ranges if r.maximum.mhz == largest_max]
|
||||||
|
value = largest_max - rs[0].step.mhz
|
||||||
|
else:
|
||||||
|
rs = [r for r in self.ranges if r.minimum.mhz == smallest_min]
|
||||||
|
value = smallest_min
|
||||||
|
r = rs[0]
|
||||||
|
self.setSingleStep(r.step.mhz)
|
||||||
|
return value
|
||||||
|
raise RuntimeError()
|
||||||
|
|
||||||
|
|
||||||
|
class QFrequencyModulationBox(QComboBox):
|
||||||
|
def __init__(self, ranges: Iterable[RadioRange], freq: float) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.setMaximumWidth(60)
|
||||||
|
self.ranges = list(ranges)
|
||||||
|
self.update_modulations(freq)
|
||||||
|
|
||||||
|
def update_modulations(self, freq: float) -> None:
|
||||||
|
self.modulations = set(
|
||||||
|
r.modulation for r in self.ranges if r.minimum.mhz <= freq < r.maximum.mhz
|
||||||
|
)
|
||||||
|
self.setEnabled(len(self.modulations) > 1)
|
||||||
|
self.clear()
|
||||||
|
for i, m in enumerate(sorted(self.modulations, key=lambda x: x.name)):
|
||||||
|
self.addItem(QIcon(), m.name, m)
|
||||||
|
|
||||||
|
|
||||||
class QRadioFrequencyDialog(QDialog):
|
class QRadioFrequencyDialog(QDialog):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
parent=None,
|
parent=None,
|
||||||
container: Optional[RadioFrequencyContainer] = None,
|
container: Optional[RadioFrequencyContainer] = None,
|
||||||
range: RadioRange = RadioRange(MHz(225), MHz(400), kHz(25)),
|
ranges: Iterable[RadioRange] = tuple([RadioRange(MHz(225), MHz(400), kHz(25))]),
|
||||||
link4: bool = False,
|
link4: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(parent=parent)
|
super().__init__(parent=parent)
|
||||||
@ -36,20 +106,18 @@ class QRadioFrequencyDialog(QDialog):
|
|||||||
layout = QHBoxLayout()
|
layout = QHBoxLayout()
|
||||||
|
|
||||||
self.frequency_label = QLabel("FREQ (MHz):")
|
self.frequency_label = QLabel("FREQ (MHz):")
|
||||||
self.frequency_input = QDoubleSpinBox()
|
self.frequency_input = QFrequencySpinbox(ranges)
|
||||||
self.frequency_input.setRange(
|
self.frequency_modulation = QFrequencyModulationBox(
|
||||||
range.minimum.mhz, range.maximum.mhz - range.step.mhz
|
ranges, self.frequency_input.value()
|
||||||
)
|
)
|
||||||
self.frequency_input.setSingleStep(range.step.mhz)
|
self.frequency_input.valueChanged.connect(
|
||||||
self.frequency_input.setDecimals(3)
|
self.frequency_modulation.update_modulations
|
||||||
self.frequency_input.setLocale(QLocale(QLocale.Language.English))
|
)
|
||||||
if range.minimum.mhz <= 225.0 < range.maximum.mhz:
|
self.frequency_input.valueChanged.connect(self.frequency_input.correct_value)
|
||||||
self.frequency_input.setValue(225.0)
|
|
||||||
else:
|
|
||||||
mid = range.minimum.mhz + (range.maximum.mhz - range.minimum.mhz) / 2
|
|
||||||
self.frequency_input.setValue(mid)
|
|
||||||
layout.addWidget(self.frequency_label)
|
layout.addWidget(self.frequency_label)
|
||||||
layout.addWidget(self.frequency_input)
|
layout.addWidget(self.frequency_input)
|
||||||
|
layout.addWidget(self.frequency_modulation)
|
||||||
|
|
||||||
self.create_button = QPushButton("Save")
|
self.create_button = QPushButton("Save")
|
||||||
self.create_button.clicked.connect(self.accept)
|
self.create_button.clicked.connect(self.accept)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user