From a3c06ce6e0d81435e4acd41a2a704a8b9867702e Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Fri, 25 Sep 2020 00:25:25 -0700 Subject: [PATCH] Limit task type combo box to valid mission types. --- qt_ui/widgets/combos/QFlightTypeComboBox.py | 107 ++++++++++++++++-- .../windows/mission/flight/QFlightCreator.py | 5 +- theater/theatergroundobject.py | 10 +- 3 files changed, 106 insertions(+), 16 deletions(-) diff --git a/qt_ui/widgets/combos/QFlightTypeComboBox.py b/qt_ui/widgets/combos/QFlightTypeComboBox.py index 9a04df68..8da41217 100644 --- a/qt_ui/widgets/combos/QFlightTypeComboBox.py +++ b/qt_ui/widgets/combos/QFlightTypeComboBox.py @@ -1,22 +1,105 @@ """Combo box for selecting a flight's task type.""" +import logging +from typing import Iterator + from PySide2.QtWidgets import QComboBox from gen.flights.flight import FlightType +from theater import ( + ConflictTheater, + ControlPoint, + FrontLine, + MissionTarget, + TheaterGroundObject, +) class QFlightTypeComboBox(QComboBox): """Combo box for selecting a flight task type.""" - def __init__(self) -> None: + COMMON_ENEMY_MISSIONS = [ + FlightType.TARCAP, + FlightType.SEAD, + FlightType.DEAD, + # TODO: FlightType.ELINT, + # TODO: FlightType.ESCORT, + # TODO: FlightType.EWAR, + # TODO: FlightType.RECON, + ] + + FRIENDLY_AIRBASE_MISSIONS = [ + FlightType.CAP, + # TODO: FlightType.INTERCEPTION + # TODO: FlightType.LOGISTICS + ] + + FRIENDLY_CARRIER_MISSIONS = [ + FlightType.BARCAP, + # TODO: FlightType.INTERCEPTION + # TODO: Buddy tanking for the A-4? + # TODO: Rescue chopper? + # TODO: Inter-ship logistics? + ] + + ENEMY_CARRIER_MISSIONS = [ + FlightType.TARCAP, + # TODO: FlightType.ANTISHIP + # TODO: FlightType.ESCORT, + ] + + ENEMY_AIRBASE_MISSIONS = [ + # TODO: FlightType.STRIKE + ] + COMMON_ENEMY_MISSIONS + + FRIENDLY_GROUND_OBJECT_MISSIONS = [ + FlightType.CAP, + # TODO: FlightType.LOGISTICS + # TODO: FlightType.TROOP_TRANSPORT + ] + + ENEMY_GROUND_OBJECT_MISSIONS = [ + FlightType.STRIKE, + ] + COMMON_ENEMY_MISSIONS + + FRONT_LINE_MISSIONS = [ + FlightType.CAS, + # TODO: FlightType.TROOP_TRANSPORT + # TODO: FlightType.EVAC + ] + COMMON_ENEMY_MISSIONS + + # TODO: Add BAI missions after we have useful BAI targets. + + def __init__(self, theater: ConflictTheater, target: MissionTarget) -> None: super().__init__() - self.addItem("CAP [Combat Air Patrol]", userData=FlightType.CAP) - self.addItem("BARCAP [Barrier Combat Air Patrol]", userData=FlightType.BARCAP) - self.addItem("TARCAP [Target Combat Air Patrol]", userData=FlightType.TARCAP) - self.addItem("INTERCEPT [Interception]", userData=FlightType.INTERCEPTION) - self.addItem("CAS [Close Air Support]", userData=FlightType.CAS) - self.addItem("BAI [Battlefield Interdiction]", userData=FlightType.BAI) - self.addItem("SEAD [Suppression of Enemy Air Defenses]", userData=FlightType.SEAD) - self.addItem("DEAD [Destruction of Enemy Air Defenses]", userData=FlightType.DEAD) - self.addItem("STRIKE [Strike]", userData=FlightType.STRIKE) - self.addItem("ANTISHIP [Antiship Attack]", userData=FlightType.ANTISHIP) - self.model().sort(0) + self.theater = theater + self.target = target + for mission_type in self.mission_types_for_target(): + self.addItem(mission_type.name, userData=mission_type) + + def mission_types_for_target(self) -> Iterator[FlightType]: + if isinstance(self.target, ControlPoint): + friendly = self.target.captured + fleet = self.target.is_fleet + if friendly: + if fleet: + yield from self.FRIENDLY_CARRIER_MISSIONS + else: + yield from self.FRIENDLY_AIRBASE_MISSIONS + else: + if fleet: + yield from self.ENEMY_CARRIER_MISSIONS + else: + yield from self.ENEMY_AIRBASE_MISSIONS + elif isinstance(self.target, TheaterGroundObject): + # TODO: Filter more based on the category. + friendly = self.target.parent_control_point(self.theater).captured + if friendly: + yield from self.FRIENDLY_GROUND_OBJECT_MISSIONS + else: + yield from self.ENEMY_GROUND_OBJECT_MISSIONS + elif isinstance(self.target, FrontLine): + yield from self.FRONT_LINE_MISSIONS + else: + logging.error( + f"Unhandled target type: {self.target.__class__.__name__}" + ) diff --git a/qt_ui/windows/mission/flight/QFlightCreator.py b/qt_ui/windows/mission/flight/QFlightCreator.py index 87693dfc..f1041071 100644 --- a/qt_ui/windows/mission/flight/QFlightCreator.py +++ b/qt_ui/windows/mission/flight/QFlightCreator.py @@ -36,8 +36,9 @@ class QFlightCreator(QDialog): layout = QVBoxLayout() - # TODO: Limit task selection to those valid for the target type. - self.task_selector = QFlightTypeComboBox() + self.task_selector = QFlightTypeComboBox( + self.game.theater, self.package.target + ) self.task_selector.setCurrentIndex(0) layout.addLayout(QLabeledWidget("Task:", self.task_selector)) diff --git a/theater/theatergroundobject.py b/theater/theatergroundobject.py index a01ad85f..3ffa86f2 100644 --- a/theater/theatergroundobject.py +++ b/theater/theatergroundobject.py @@ -1,11 +1,9 @@ -from typing import List import uuid from dcs.mapping import Point from .missiontarget import MissionTarget - NAME_BY_CATEGORY = { "power": "Power plant", "ammo": "Ammo depot", @@ -102,3 +100,11 @@ class TheaterGroundObject(MissionTarget): @property def name(self) -> str: return self.obj_name + + def parent_control_point( + self, theater: "ConflictTheater") -> "ControlPoint": + """Searches the theater for the parent control point.""" + for cp in theater.controlpoints: + if cp.id == self.cp_id: + return cp + raise RuntimeError("Could not find matching control point in theater")