Selectable aircraft type in AutoCreateDialog

Resolves #165
This commit is contained in:
Raffson 2024-02-25 00:38:17 +01:00
parent b737f4e00c
commit e36e213b76
No known key found for this signature in database
GPG Key ID: B0402B2C9B764D99
5 changed files with 103 additions and 27 deletions

View File

@ -3,6 +3,7 @@ from enum import Enum, auto
from typing import Optional from typing import Optional
from game.ato.flighttype import FlightType from game.ato.flighttype import FlightType
from game.dcs.aircrafttype import AircraftType
from game.theater import MissionTarget from game.theater import MissionTarget
@ -33,6 +34,8 @@ class ProposedFlight:
#: field is None. #: field is None.
escort_type: Optional[EscortType] = field(default=None) escort_type: Optional[EscortType] = field(default=None)
preferred_type: Optional[AircraftType] = field(default=None)
def __str__(self) -> str: def __str__(self) -> str:
return f"{self.task} {self.num_aircraft} ship" return f"{self.task} {self.num_aircraft} ship"

View File

@ -49,7 +49,12 @@ class PackageBuilder:
pf = self.package.primary_flight pf = self.package.primary_flight
heli = pf.is_helo if pf else False heli = pf.is_helo if pf else False
squadron = self.air_wing.best_squadron_for( squadron = self.air_wing.best_squadron_for(
self.package.target, plan.task, plan.num_aircraft, heli, this_turn=True self.package.target,
plan.task,
plan.num_aircraft,
heli,
this_turn=True,
preferred_type=plan.preferred_type,
) )
if squadron is None: if squadron is None:
return False return False

View File

@ -51,6 +51,7 @@ class AirWing:
size: int, size: int,
heli: bool, heli: bool,
this_turn: bool, this_turn: bool,
preferred_type: Optional[AircraftType] = None,
) -> list[Squadron]: ) -> list[Squadron]:
airfield_cache = ObjectiveDistanceCache.get_closest_airfields(location) airfield_cache = ObjectiveDistanceCache.get_closest_airfields(location)
best_aircraft = AircraftType.priority_list_for_task(task) best_aircraft = AircraftType.priority_list_for_task(task)
@ -59,7 +60,13 @@ class AirWing:
if control_point.captured != self.player: if control_point.captured != self.player:
continue continue
capable_at_base = [] capable_at_base = []
for squadron in control_point.squadrons: squadrons = [
s
for s in control_point.squadrons
if not preferred_type
or s.aircraft.variant_id == preferred_type.variant_id
]
for squadron in squadrons:
if squadron.can_auto_assign_mission( if squadron.can_auto_assign_mission(
location, task, size, heli, this_turn location, task, size, heli, this_turn
): ):
@ -92,8 +99,11 @@ class AirWing:
size: int, size: int,
heli: bool, heli: bool,
this_turn: bool, this_turn: bool,
preferred_type: Optional[AircraftType] = None,
) -> Optional[Squadron]: ) -> Optional[Squadron]:
for squadron in self.best_squadrons_for(location, task, size, heli, this_turn): for squadron in self.best_squadrons_for(
location, task, size, heli, this_turn, preferred_type
):
return squadron return squadron
return None return None

View File

@ -47,76 +47,100 @@ class QAutoCreateDialog(QDialog):
hbox = QHBoxLayout() hbox = QHBoxLayout()
self.primary_combobox = QComboBox() self.primary_combobox = QComboBox()
self.primary_combobox.setFixedWidth(100)
self.primary_count = _spinbox_template() self.primary_count = _spinbox_template()
self.primary_type = QComboBox()
nr_targets = len(self.package.target.strike_targets) nr_targets = len(self.package.target.strike_targets)
count = max(1, min(4, nr_targets // 2) + nr_targets % 1) if nr_targets else 4 count = max(1, min(4, nr_targets // 2) + nr_targets % 1) if nr_targets else 4
self.primary_count.setValue(count) self.primary_count.setValue(count)
hbox.addWidget(self.primary_combobox) hbox.addWidget(self.primary_combobox)
hbox.addWidget(self.primary_count) hbox.addWidget(self.primary_count)
hbox.addWidget(self.primary_type)
self.layout.addLayout(hbox) self.layout.addLayout(hbox)
self.checkboxes = {} self.checkboxes = {}
hbox = QHBoxLayout() hbox = QHBoxLayout()
self.tarcap = QCheckBox() self.tarcap = self._create_checkbox("TARCAP")
self.tarcap.setText("TARCAP")
self.tarcap_count = _spinbox_template() self.tarcap_count = _spinbox_template()
hbox.addWidget(self.tarcap) hbox.addWidget(self.tarcap)
hbox.addWidget(self.tarcap_count) hbox.addWidget(self.tarcap_count)
self.tarcap_type = self._create_type_selector(FlightType.TARCAP)
hbox.addWidget(self.tarcap_type)
self.layout.addLayout(hbox) self.layout.addLayout(hbox)
self.checkboxes[self.tarcap] = (FlightType.TARCAP, self.tarcap_count) self.checkboxes[self.tarcap] = (
FlightType.TARCAP,
self.tarcap_count,
self.tarcap_type,
)
hbox = QHBoxLayout() hbox = QHBoxLayout()
self.escort = QCheckBox() self.escort = self._create_checkbox("Escort")
self.escort.setText("Escort")
self.escort_count = _spinbox_template() self.escort_count = _spinbox_template()
hbox.addWidget(self.escort) hbox.addWidget(self.escort)
hbox.addWidget(self.escort_count) hbox.addWidget(self.escort_count)
self.escort_type = self._create_type_selector(FlightType.ESCORT)
hbox.addWidget(self.escort_type)
self.layout.addLayout(hbox) self.layout.addLayout(hbox)
self.checkboxes[self.escort] = (FlightType.ESCORT, self.escort_count) self.checkboxes[self.escort] = (
FlightType.ESCORT,
self.escort_count,
self.escort_type,
)
hbox = QHBoxLayout() hbox = QHBoxLayout()
self.sead_escort = QCheckBox() self.sead_escort = self._create_checkbox("SEAD Escort")
self.sead_escort.setText("SEAD Escort")
self.sead_escort_count = _spinbox_template() self.sead_escort_count = _spinbox_template()
hbox.addWidget(self.sead_escort) hbox.addWidget(self.sead_escort)
hbox.addWidget(self.sead_escort_count) hbox.addWidget(self.sead_escort_count)
self.sead_escort_type = self._create_type_selector(FlightType.SEAD_ESCORT)
hbox.addWidget(self.sead_escort_type)
self.layout.addLayout(hbox) self.layout.addLayout(hbox)
self.checkboxes[self.sead_escort] = ( self.checkboxes[self.sead_escort] = (
FlightType.SEAD_ESCORT, FlightType.SEAD_ESCORT,
self.sead_escort_count, self.sead_escort_count,
self.sead_escort_type,
) )
hbox = QHBoxLayout() hbox = QHBoxLayout()
self.sead = QCheckBox() self.sead = self._create_checkbox("SEAD")
self.sead.setText("SEAD")
self.sead_count = _spinbox_template() self.sead_count = _spinbox_template()
hbox.addWidget(self.sead) hbox.addWidget(self.sead)
hbox.addWidget(self.sead_count) hbox.addWidget(self.sead_count)
self.sead_type = self._create_type_selector(FlightType.SEAD)
hbox.addWidget(self.sead_type)
self.layout.addLayout(hbox) self.layout.addLayout(hbox)
self.checkboxes[self.sead] = (FlightType.SEAD, self.sead_count) self.checkboxes[self.sead] = (FlightType.SEAD, self.sead_count, self.sead_type)
hbox = QHBoxLayout() hbox = QHBoxLayout()
self.sead_sweep = QCheckBox() self.sead_sweep = self._create_checkbox("SEAD Sweep")
self.sead_sweep.setText("SEAD Sweep")
self.sead_sweep_count = _spinbox_template() self.sead_sweep_count = _spinbox_template()
hbox.addWidget(self.sead_sweep) hbox.addWidget(self.sead_sweep)
hbox.addWidget(self.sead_sweep_count) hbox.addWidget(self.sead_sweep_count)
self.sead_sweep_type = self._create_type_selector(FlightType.SEAD_SWEEP)
hbox.addWidget(self.sead_sweep_type)
self.layout.addLayout(hbox) self.layout.addLayout(hbox)
self.checkboxes[self.sead_sweep] = ( self.checkboxes[self.sead_sweep] = (
FlightType.SEAD_SWEEP, FlightType.SEAD_SWEEP,
self.sead_sweep_count, self.sead_sweep_count,
self.sead_sweep_type,
) )
hbox = QHBoxLayout() hbox = QHBoxLayout()
self.refueling = QCheckBox() self.refueling = self._create_checkbox("Refueling")
self.refueling.setText("Refueling")
self.refueling_count = _spinbox_template() self.refueling_count = _spinbox_template()
self.refueling_count.setValue(1) self.refueling_count.setValue(1)
hbox.addWidget(self.refueling) hbox.addWidget(self.refueling)
hbox.addWidget(self.refueling_count) hbox.addWidget(self.refueling_count)
self.refueling_type = self._create_type_selector(FlightType.REFUELING)
hbox.addWidget(self.refueling_type, 1)
self.layout.addLayout(hbox) self.layout.addLayout(hbox)
self.checkboxes[self.refueling] = (FlightType.REFUELING, self.refueling_count) self.checkboxes[self.refueling] = (
FlightType.REFUELING,
self.refueling_count,
self.refueling_type,
)
self.create_button = QPushButton("Create") self.create_button = QPushButton("Create")
self.create_button.setProperty("style", "start-button") self.create_button.setProperty("style", "start-button")
@ -139,6 +163,28 @@ class QAutoCreateDialog(QDialog):
if mt in primary_tasks: if mt in primary_tasks:
self.primary_combobox.addItem(mt.value, mt) self.primary_combobox.addItem(mt.value, mt)
self.primary_combobox.setCurrentIndex(0) self.primary_combobox.setCurrentIndex(0)
self._load_aircraft_types()
@staticmethod
def _create_checkbox(label: str) -> QCheckBox:
cb = QCheckBox(label)
cb.setFixedWidth(100)
return cb
def _create_type_selector(self, flight_type: FlightType) -> QComboBox:
airwing = self.game.blue.air_wing
cb = QComboBox()
for ac in airwing.best_available_aircrafts_for(flight_type):
cb.addItem(ac.variant_id, ac)
return cb
def _load_aircraft_types(self):
self.primary_type.clear()
for ac in self.game.blue.air_wing.best_available_aircrafts_for(
self.primary_combobox.currentData()
):
self.primary_type.addItem(ac.variant_id, ac)
self.primary_type.setCurrentIndex(0)
def on_primary_task_changed(self) -> None: def on_primary_task_changed(self) -> None:
disable = self.primary_combobox.currentData() == FlightType.CAS disable = self.primary_combobox.currentData() == FlightType.CAS
@ -147,15 +193,26 @@ class QAutoCreateDialog(QDialog):
if disable: if disable:
cb.setChecked(False) cb.setChecked(False)
cb.setDisabled(disable) cb.setDisabled(disable)
self._load_aircraft_types()
def on_create_clicked(self) -> None: def on_create_clicked(self) -> None:
pf: List[ProposedFlight] = [] pf: List[ProposedFlight] = []
count = self.primary_count.value() count = self.primary_count.value()
pf.append(ProposedFlight(self.primary_combobox.currentData(), count)) pf.append(
ProposedFlight(
self.primary_combobox.currentData(),
count,
preferred_type=self.primary_type.currentData(),
)
)
for cb in self.checkboxes: for cb in self.checkboxes:
if cb.isChecked(): if cb.isChecked():
type, spinner = self.checkboxes[cb] type, spinner, ac_box = self.checkboxes[cb]
pf.append(ProposedFlight(type, spinner.value())) pf.append(
ProposedFlight(
type, spinner.value(), preferred_type=ac_box.currentData()
)
)
with MultiEventTracer() as tracer: with MultiEventTracer() as tracer:
with tracer.trace(f"Auto-plan package"): with tracer.trace(f"Auto-plan package"):
pm = ProposedMission(self.package.target, pf, asap=True) pm = ProposedMission(self.package.target, pf, asap=True)

View File

@ -237,11 +237,12 @@ class QPackageDialog(QDialog):
auto_create_dialog = QAutoCreateDialog( auto_create_dialog = QAutoCreateDialog(
self.game, self.package_model, parent=self.window() self.game, self.package_model, parent=self.window()
) )
auto_create_dialog.exec_() if auto_create_dialog.exec_() == QDialog.DialogCode.Accepted:
for f in self.package_model.package.flights: for f in self.package_model.package.flights:
EventStream.put_nowait(GameUpdateEvents().new_flight(f)) EventStream.put_nowait(GameUpdateEvents().new_flight(f))
self.package_model.update_tot() self.package_model.update_tot()
self.package_changed.emit() self.package_changed.emit()
self.auto_create_button.setDisabled(True)
def on_change_name(self) -> None: def on_change_name(self) -> None:
self.package_model.package.custom_name = self.package_name_text.text() self.package_model.package.custom_name = self.package_name_text.text()