mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Allow squadron switch in flight's edit-dialog
This commit is contained in:
parent
b2315efb6c
commit
31630b4d42
@ -17,6 +17,7 @@
|
||||
* **[ATO]** Allow planning as OPFOR
|
||||
* **[Campaign Design]** Support for Kola map by Orbx
|
||||
* **[UI]** Zoom level retained when switching campaigns
|
||||
* **[UX]** Allow changing squadrons in flight's edit dialog
|
||||
|
||||
## Fixes
|
||||
* **[UI/UX]** A-10A flights can be edited again
|
||||
|
||||
@ -26,6 +26,8 @@ class QEditFlightDialog(QDialog):
|
||||
|
||||
self.game_model = game_model
|
||||
self.flight = flight
|
||||
self.package_model = package_model
|
||||
self.events = GameUpdateEvents()
|
||||
|
||||
self.setWindowTitle("Edit flight")
|
||||
self.setWindowIcon(EVENT_ICONS["strike"])
|
||||
@ -34,11 +36,24 @@ class QEditFlightDialog(QDialog):
|
||||
layout = QVBoxLayout()
|
||||
|
||||
self.flight_planner = QFlightPlanner(package_model, flight, game_model)
|
||||
self.flight_planner.squadron_changed.connect(self.on_squadron_change)
|
||||
layout.addWidget(self.flight_planner)
|
||||
|
||||
self.setLayout(layout)
|
||||
self.finished.connect(self.on_close)
|
||||
|
||||
def on_close(self, _result) -> None:
|
||||
EventStream.put_nowait(GameUpdateEvents().update_flight(self.flight))
|
||||
def on_squadron_change(self, flight: Flight):
|
||||
self.events = GameUpdateEvents().delete_flight(self.flight)
|
||||
self.events = self.events.new_flight(flight)
|
||||
self.game_model.ato_model.client_slots_changed.emit()
|
||||
self.flight = flight
|
||||
self.reject()
|
||||
new_dialog = QEditFlightDialog(
|
||||
self.game_model, self.package_model, flight, self.parent()
|
||||
)
|
||||
new_dialog.show()
|
||||
|
||||
def on_close(self, _result) -> None:
|
||||
self.events = self.events.update_flight(self.flight)
|
||||
EventStream.put_nowait(self.events)
|
||||
self.game_model.ato_model.client_slots_changed.emit()
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
from PySide6.QtCore import Signal
|
||||
from PySide6.QtWidgets import QTabWidget
|
||||
|
||||
from game.ato.flight import Flight
|
||||
@ -10,6 +11,8 @@ from qt_ui.windows.mission.flight.waypoints.QFlightWaypointTab import QFlightWay
|
||||
|
||||
|
||||
class QFlightPlanner(QTabWidget):
|
||||
squadron_changed = Signal(Flight)
|
||||
|
||||
def __init__(self, package_model: PackageModel, flight: Flight, gm: GameModel):
|
||||
super().__init__()
|
||||
|
||||
@ -28,6 +31,7 @@ class QFlightPlanner(QTabWidget):
|
||||
self.general_settings_tab.flight_size_changed.connect(
|
||||
self.payload_tab.resize_for_flight
|
||||
)
|
||||
self.general_settings_tab.squadron_changed.connect(self.squadron_changed)
|
||||
self.addTab(self.general_settings_tab, "General Flight settings")
|
||||
self.addTab(self.payload_tab, "Payload")
|
||||
self.addTab(self.waypoint_tab, "Waypoints")
|
||||
|
||||
@ -11,14 +11,21 @@ from PySide6.QtWidgets import (
|
||||
QHBoxLayout,
|
||||
QCheckBox,
|
||||
QVBoxLayout,
|
||||
QPushButton,
|
||||
QDialog,
|
||||
QWidget,
|
||||
)
|
||||
|
||||
from game import Game
|
||||
from game.ato.closestairfields import ClosestAirfields
|
||||
from game.ato.flight import Flight
|
||||
from game.ato.flightroster import FlightRoster
|
||||
from game.ato.iflightroster import IFlightRoster
|
||||
from game.dcs.aircrafttype import AircraftType
|
||||
from game.squadrons import Squadron
|
||||
from game.squadrons.pilot import Pilot
|
||||
from game.theater import ControlPoint, OffMapSpawn
|
||||
from game.utils import nautical_miles
|
||||
from qt_ui.models import PackageModel
|
||||
|
||||
|
||||
@ -237,8 +244,49 @@ class FlightRosterEditor(QVBoxLayout):
|
||||
controls.replace(squadron, new_roster)
|
||||
|
||||
|
||||
class QSquadronSelector(QDialog):
|
||||
def __init__(self, flight: Flight, parent: Optional[QWidget] = None):
|
||||
super().__init__(parent)
|
||||
self.flight = flight
|
||||
self.parent = parent
|
||||
self.init()
|
||||
|
||||
def init(self):
|
||||
vbox = QVBoxLayout()
|
||||
self.setLayout(vbox)
|
||||
|
||||
self.selector = QComboBox()
|
||||
air_wing = self.flight.coalition.air_wing
|
||||
for squadron in air_wing.best_squadrons_for(
|
||||
self.flight.package.target,
|
||||
self.flight.flight_type,
|
||||
self.flight.roster.max_size,
|
||||
self.flight.is_helo,
|
||||
True,
|
||||
ignore_range=True,
|
||||
):
|
||||
if squadron is self.flight.squadron:
|
||||
continue
|
||||
self.selector.addItem(
|
||||
f"{squadron.name} - {squadron.aircraft.variant_id}", squadron
|
||||
)
|
||||
|
||||
vbox.addWidget(self.selector)
|
||||
|
||||
hbox = QHBoxLayout()
|
||||
accept = QPushButton("Accept")
|
||||
accept.clicked.connect(self.accept)
|
||||
hbox.addWidget(accept)
|
||||
cancel = QPushButton("Cancel")
|
||||
cancel.clicked.connect(self.reject)
|
||||
hbox.addWidget(cancel)
|
||||
|
||||
vbox.addLayout(hbox)
|
||||
|
||||
|
||||
class QFlightSlotEditor(QGroupBox):
|
||||
flight_resized = Signal(int)
|
||||
squadron_changed = Signal(Flight)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@ -250,6 +298,10 @@ class QFlightSlotEditor(QGroupBox):
|
||||
self.package_model = package_model
|
||||
self.flight = flight
|
||||
self.game = game
|
||||
self.closest_airfields = ClosestAirfields(
|
||||
flight.package.target,
|
||||
list(game.theater.control_points_for(self.flight.coalition.player)),
|
||||
)
|
||||
available = self.flight.squadron.untasked_aircraft
|
||||
max_count = self.flight.count + available
|
||||
if max_count > 4:
|
||||
@ -268,7 +320,12 @@ class QFlightSlotEditor(QGroupBox):
|
||||
layout.addWidget(self.aircraft_count_spinner, 0, 1)
|
||||
|
||||
layout.addWidget(QLabel("Squadron:"), 1, 0)
|
||||
layout.addWidget(QLabel(str(self.flight.squadron)), 1, 1)
|
||||
hbox = QHBoxLayout()
|
||||
hbox.addWidget(QLabel(str(self.flight.squadron)))
|
||||
squadron_btn = QPushButton("Change Squadron")
|
||||
squadron_btn.clicked.connect(self._change_squadron)
|
||||
hbox.addWidget(squadron_btn)
|
||||
layout.addLayout(hbox, 1, 1)
|
||||
|
||||
layout.addWidget(QLabel("Assigned pilots:"), 2, 0)
|
||||
self.roster_editor = FlightRosterEditor(flight.squadron, flight.roster)
|
||||
@ -276,6 +333,46 @@ class QFlightSlotEditor(QGroupBox):
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
def _change_squadron(self):
|
||||
dialog = QSquadronSelector(self.flight)
|
||||
if dialog.exec():
|
||||
squadron: Optional[Squadron] = dialog.selector.currentData()
|
||||
if not squadron:
|
||||
return
|
||||
flight = Flight(
|
||||
self.package_model.package,
|
||||
squadron,
|
||||
self.flight.count,
|
||||
self.flight.flight_type,
|
||||
self.flight.start_type,
|
||||
self._find_divert_field(squadron.aircraft, squadron.location),
|
||||
frequency=self.flight.frequency,
|
||||
cargo=self.flight.cargo,
|
||||
channel=self.flight.tacan,
|
||||
callsign_tcn=self.flight.tcn_name,
|
||||
)
|
||||
self.package_model.add_flight(flight)
|
||||
self.package_model.delete_flight(self.flight)
|
||||
self.squadron_changed.emit(flight)
|
||||
|
||||
def _find_divert_field(
|
||||
self, aircraft: AircraftType, arrival: ControlPoint
|
||||
) -> Optional[ControlPoint]:
|
||||
divert_limit = nautical_miles(150)
|
||||
for airfield in self.closest_airfields.operational_airfields_within(
|
||||
divert_limit
|
||||
):
|
||||
if airfield.captured != self.flight.coalition.player:
|
||||
continue
|
||||
if airfield == arrival:
|
||||
continue
|
||||
if not airfield.can_operate(aircraft):
|
||||
continue
|
||||
if isinstance(airfield, OffMapSpawn):
|
||||
continue
|
||||
return airfield
|
||||
return None
|
||||
|
||||
def _changed_aircraft_count(self):
|
||||
old_count = self.flight.count
|
||||
new_count = int(self.aircraft_count_spinner.value())
|
||||
|
||||
@ -21,6 +21,7 @@ from qt_ui.windows.mission.flight.waypoints.QFlightWaypointList import (
|
||||
|
||||
class QGeneralFlightSettingsTab(QFrame):
|
||||
flight_size_changed = Signal()
|
||||
squadron_changed = Signal(Flight)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@ -36,6 +37,7 @@ class QGeneralFlightSettingsTab(QFrame):
|
||||
|
||||
self.flight_slot_editor = QFlightSlotEditor(package_model, flight, game.game)
|
||||
self.flight_slot_editor.flight_resized.connect(self.flight_size_changed)
|
||||
self.flight_slot_editor.squadron_changed.connect(self.squadron_changed)
|
||||
for pc in self.flight_slot_editor.roster_editor.pilot_controls:
|
||||
pc.player_toggled.connect(self.on_player_toggle)
|
||||
pc.player_toggled.connect(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user