mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Move mission type compatibility to the target.
This was also needed in other parts of the UI and is easier to implement in the target class anyway. Note that DEAD is now properly restricted to air defense targets. Also added error boxes to the UI for when planning fails on an invalid target.
This commit is contained in:
@@ -1,107 +1,16 @@
|
||||
"""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,
|
||||
)
|
||||
from theater import ConflictTheater, MissionTarget
|
||||
|
||||
|
||||
class QFlightTypeComboBox(QComboBox):
|
||||
"""Combo box for selecting a flight task type."""
|
||||
|
||||
COMMON_ENEMY_MISSIONS = [
|
||||
FlightType.TARCAP,
|
||||
FlightType.ESCORT,
|
||||
FlightType.SEAD,
|
||||
FlightType.DEAD,
|
||||
FlightType.SWEEP,
|
||||
# TODO: FlightType.ELINT,
|
||||
# TODO: FlightType.EWAR,
|
||||
# TODO: FlightType.RECON,
|
||||
]
|
||||
|
||||
COMMON_FRIENDLY_MISSIONS = [
|
||||
FlightType.BARCAP,
|
||||
]
|
||||
|
||||
FRIENDLY_AIRBASE_MISSIONS = [
|
||||
# TODO: FlightType.INTERCEPTION
|
||||
# TODO: FlightType.LOGISTICS
|
||||
] + COMMON_FRIENDLY_MISSIONS
|
||||
|
||||
FRIENDLY_CARRIER_MISSIONS = [
|
||||
# TODO: FlightType.INTERCEPTION
|
||||
# TODO: Buddy tanking for the A-4?
|
||||
# TODO: Rescue chopper?
|
||||
# TODO: Inter-ship logistics?
|
||||
] + COMMON_FRIENDLY_MISSIONS
|
||||
|
||||
ENEMY_CARRIER_MISSIONS = [
|
||||
FlightType.ESCORT,
|
||||
FlightType.BARCAP,
|
||||
# TODO: FlightType.ANTISHIP
|
||||
]
|
||||
|
||||
ENEMY_AIRBASE_MISSIONS = [
|
||||
# TODO: FlightType.STRIKE
|
||||
] + COMMON_ENEMY_MISSIONS
|
||||
|
||||
FRIENDLY_GROUND_OBJECT_MISSIONS = [
|
||||
# TODO: FlightType.LOGISTICS
|
||||
# TODO: FlightType.TROOP_TRANSPORT
|
||||
] + COMMON_FRIENDLY_MISSIONS
|
||||
|
||||
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.theater = theater
|
||||
self.target = target
|
||||
for mission_type in self.mission_types_for_target():
|
||||
for mission_type in self.target.mission_types(for_player=True):
|
||||
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.control_point.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__}"
|
||||
)
|
||||
|
||||
@@ -8,6 +8,7 @@ from PySide2.QtWidgets import (
|
||||
QDialog,
|
||||
QHBoxLayout,
|
||||
QLabel,
|
||||
QMessageBox,
|
||||
QPushButton,
|
||||
QTimeEdit,
|
||||
QVBoxLayout,
|
||||
@@ -16,7 +17,7 @@ from PySide2.QtWidgets import (
|
||||
from game.game import Game
|
||||
from gen.ato import Package
|
||||
from gen.flights.flight import Flight
|
||||
from gen.flights.flightplan import FlightPlanBuilder
|
||||
from gen.flights.flightplan import FlightPlanBuilder, PlanningError
|
||||
from gen.flights.traveltime import TotEstimator
|
||||
from qt_ui.models import AtoModel, GameModel, PackageModel
|
||||
from qt_ui.uiconstants import EVENT_ICONS
|
||||
@@ -167,7 +168,15 @@ class QPackageDialog(QDialog):
|
||||
self.package_model.add_flight(flight)
|
||||
planner = FlightPlanBuilder(self.game, self.package_model.package,
|
||||
is_player=True)
|
||||
planner.populate_flight_plan(flight)
|
||||
try:
|
||||
planner.populate_flight_plan(flight)
|
||||
except PlanningError as ex:
|
||||
self.game.aircraft_inventory.return_from_flight(flight)
|
||||
self.package_model.delete_flight(flight)
|
||||
logging.exception("Could not create flight")
|
||||
QMessageBox.critical(
|
||||
self, "Could not create flight", str(ex), QMessageBox.Ok
|
||||
)
|
||||
# noinspection PyUnresolvedReferences
|
||||
self.package_changed.emit()
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import logging
|
||||
from typing import List, Optional
|
||||
|
||||
from PySide2.QtCore import Signal
|
||||
@@ -13,13 +14,15 @@ from PySide2.QtWidgets import (
|
||||
from game import Game
|
||||
from gen.ato import Package
|
||||
from gen.flights.flight import Flight, FlightType
|
||||
from gen.flights.flightplan import FlightPlanBuilder
|
||||
from gen.flights.flightplan import (
|
||||
FlightPlanBuilder,
|
||||
PlanningError,
|
||||
)
|
||||
from qt_ui.windows.mission.flight.waypoints.QFlightWaypointList import \
|
||||
QFlightWaypointList
|
||||
from qt_ui.windows.mission.flight.waypoints\
|
||||
from qt_ui.windows.mission.flight.waypoints \
|
||||
.QPredefinedWaypointSelectionWindow import \
|
||||
QPredefinedWaypointSelectionWindow
|
||||
from theater import FrontLine
|
||||
|
||||
|
||||
class QFlightWaypointTab(QFrame):
|
||||
@@ -55,17 +58,8 @@ class QFlightWaypointTab(QFrame):
|
||||
rlayout.addWidget(QLabel("<strong>Generator :</strong>"))
|
||||
rlayout.addWidget(QLabel("<small>AI compatible</small>"))
|
||||
|
||||
# TODO: Filter by objective type.
|
||||
self.recreate_buttons.clear()
|
||||
recreate_types = [
|
||||
FlightType.CAS,
|
||||
FlightType.CAP,
|
||||
FlightType.DEAD,
|
||||
FlightType.ESCORT,
|
||||
FlightType.SEAD,
|
||||
FlightType.STRIKE
|
||||
]
|
||||
for task in recreate_types:
|
||||
for task in self.package.target.mission_types(for_player=True):
|
||||
def make_closure(arg):
|
||||
def closure():
|
||||
return self.confirm_recreate(arg)
|
||||
@@ -142,19 +136,17 @@ class QFlightWaypointTab(QFrame):
|
||||
QMessageBox.No,
|
||||
QMessageBox.Yes
|
||||
)
|
||||
original_task = self.flight.flight_type
|
||||
if result == QMessageBox.Yes:
|
||||
# TODO: Should be buttons for both BARCAP and TARCAP.
|
||||
# BARCAP and TARCAP behave differently. TARCAP arrives a few minutes
|
||||
# ahead of the rest of the package and stays until the package
|
||||
# departs, whereas BARCAP usually isn't part of a strike package and
|
||||
# has a fixed mission time.
|
||||
if task == FlightType.CAP:
|
||||
if self.package.target.is_friendly(to_player=True):
|
||||
task = FlightType.BARCAP
|
||||
else:
|
||||
task = FlightType.TARCAP
|
||||
self.flight.flight_type = task
|
||||
self.planner.populate_flight_plan(self.flight)
|
||||
try:
|
||||
self.planner.populate_flight_plan(self.flight)
|
||||
except PlanningError as ex:
|
||||
self.flight.flight_type = original_task
|
||||
logging.exception("Could not recreate flight")
|
||||
QMessageBox.critical(
|
||||
self, "Could not recreate flight", str(ex), QMessageBox.Ok
|
||||
)
|
||||
self.flight_waypoint_list.update_list()
|
||||
self.on_change()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user