Allow selection of auto-assigned mission types.

Fixes https://github.com/dcs-liberation/dcs_liberation/issues/1176
This commit is contained in:
Dan Albert 2021-06-04 17:50:21 -07:00
parent 8bb1b1da7c
commit a0833e8943
6 changed files with 64 additions and 10 deletions

View File

@ -193,7 +193,7 @@ class ProcurementAi:
continue
for squadron in self.air_wing.squadrons_for(unit):
if task in squadron.mission_types:
if task in squadron.auto_assignable_mission_types:
break
else:
continue

View File

@ -10,7 +10,6 @@ from pathlib import Path
from typing import (
Type,
Tuple,
List,
TYPE_CHECKING,
Optional,
Iterator,
@ -82,9 +81,12 @@ class Squadron:
role: str
aircraft: Type[FlyingType]
livery: Optional[str]
mission_types: Tuple[FlightType, ...]
pilots: List[Pilot]
available_pilots: List[Pilot] = field(init=False, hash=False, compare=False)
mission_types: tuple[FlightType, ...]
pilots: list[Pilot]
available_pilots: list[Pilot] = field(init=False, hash=False, compare=False)
auto_assignable_mission_types: set[FlightType] = field(
init=False, hash=False, compare=False
)
# We need a reference to the Game so that we can access the Faker without needing to
# persist it to the save game, or having to reconstruct it (it's not cheap) each
@ -94,6 +96,7 @@ class Squadron:
def __post_init__(self) -> None:
self.available_pilots = list(self.active_pilots)
self.auto_assignable_mission_types = set(self.mission_types)
def __str__(self) -> str:
return f'{self.name} "{self.nickname}"'
@ -223,6 +226,12 @@ class Squadron:
player=player,
)
def __setstate__(self, state) -> None:
# TODO: Remove save compat.
if "auto_assignable_mission_types" not in state:
state["auto_assignable_mission_types"] = set(state["mission_types"])
self.__dict__.update(state)
class SquadronLoader:
def __init__(self, game: Game, player: bool) -> None:

View File

@ -238,7 +238,7 @@ class AirliftPlanner:
for s in self.game.air_wing_for(self.for_player).squadrons_for(
unit_type
)
if FlightType.TRANSPORT in s.mission_types
if FlightType.TRANSPORT in s.auto_assignable_mission_types
]
if not squadrons:
continue

View File

@ -180,7 +180,7 @@ class AircraftAllocator:
# Valid location with enough aircraft available. Find a squadron to fit
# the role.
for squadron in self.air_wing.squadrons_for(aircraft):
if task not in squadron.mission_types:
if task not in squadron.auto_assignable_mission_types:
continue
if len(squadron.available_pilots) >= flight.num_aircraft:
inventory.remove_aircraft(aircraft, flight.num_aircraft)
@ -604,7 +604,7 @@ class CoalitionMissionPlanner:
for squadron in self.game.air_wing_for(self.is_player).iter_squadrons():
if (
squadron.aircraft in all_compatible
and mission_type in squadron.mission_types
and mission_type in squadron.auto_assignable_mission_types
):
return True
return False

View File

@ -18,7 +18,7 @@ from game.squadrons import Squadron, Pilot
from game.theater.missiontarget import MissionTarget
from game.transfers import TransferOrder
from gen.ato import AirTaskingOrder, Package
from gen.flights.flight import Flight
from gen.flights.flight import Flight, FlightType
from gen.flights.traveltime import TotEstimator
from qt_ui.uiconstants import AIRCRAFT_ICONS
@ -467,6 +467,15 @@ class SquadronModel(QAbstractListModel):
pilot.send_on_leave()
self.endResetModel()
def is_auto_assignable(self, task: FlightType) -> bool:
return task in self.squadron.auto_assignable_mission_types
def set_auto_assignable(self, task: FlightType, auto_assignable: bool) -> None:
if auto_assignable:
self.squadron.auto_assignable_mission_types.add(task)
else:
self.squadron.auto_assignable_mission_types.remove(task)
class GameModel:
"""A model for the Game object.

View File

@ -1,4 +1,5 @@
import logging
from typing import Callable
from PySide2.QtCore import (
QItemSelectionModel,
@ -13,9 +14,13 @@ from PySide2.QtWidgets import (
QVBoxLayout,
QPushButton,
QHBoxLayout,
QGridLayout,
QLabel,
QCheckBox,
)
from game.squadrons import Pilot
from gen.flights.flight import FlightType
from qt_ui.delegates import TwoColumnRowDelegate
from qt_ui.models import SquadronModel
@ -61,6 +66,31 @@ class PilotList(QListView):
self.setSelectionBehavior(QAbstractItemView.SelectItems)
class AutoAssignedTaskControls(QVBoxLayout):
def __init__(self, squadron_model: SquadronModel) -> None:
super().__init__()
self.squadron_model = squadron_model
self.addWidget(QLabel("Auto-assignable mission types"))
def make_callback(toggled_task: FlightType) -> Callable[[bool], None]:
def callback(checked: bool) -> None:
self.on_toggled(toggled_task, checked)
return callback
for task in squadron_model.squadron.mission_types:
checkbox = QCheckBox(text=task.value)
checkbox.setChecked(squadron_model.is_auto_assignable(task))
checkbox.toggled.connect(make_callback(task))
self.addWidget(checkbox)
self.addStretch()
def on_toggled(self, task: FlightType, checked: bool) -> None:
self.squadron_model.set_auto_assignable(task, checked)
class SquadronDialog(QDialog):
"""Dialog window showing a squadron."""
@ -75,11 +105,17 @@ class SquadronDialog(QDialog):
layout = QVBoxLayout()
self.setLayout(layout)
columns = QHBoxLayout()
layout.addLayout(columns)
auto_assigned_tasks = AutoAssignedTaskControls(squadron_model)
columns.addLayout(auto_assigned_tasks)
self.pilot_list = PilotList(squadron_model)
self.pilot_list.selectionModel().selectionChanged.connect(
self.on_selection_changed
)
layout.addWidget(self.pilot_list)
columns.addWidget(self.pilot_list)
button_panel = QHBoxLayout()
button_panel.addStretch()