diff --git a/gen/aircraft.py b/gen/aircraft.py index fdd0de34..9fe2f584 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -330,6 +330,18 @@ class AircraftConflictGenerator: self.setup_group_as_sead_flight(group, flight) self._setup_custom_payload(flight, group) + for flight in flight_planner.custom_flights: + group = self.generate_planned_flight(cp, country, flight) + if flight.flight_type == FlightType.INTERCEPTION: + self.setup_group_as_intercept_flight(group, flight) + elif flight.flight_type == FlightType.CAP: + self.setup_group_as_cap_flight(group, flight) + elif flight.flight_type == FlightType.CAS: + self.setup_group_as_cas_flight(group, flight) + elif flight.flight_type == FlightType.SEAD or flight.flight_type == FlightType.DEAD: + self.setup_group_as_sead_flight(group, flight) + self._setup_custom_payload(flight, group) + def generate_planned_flight(self, cp, country, flight:Flight): try: if flight.start_type == "In Flight" or flight.client_count == 0: diff --git a/gen/flights/ai_flight_planner.py b/gen/flights/ai_flight_planner.py index 86889fe8..c4e0eada 100644 --- a/gen/flights/ai_flight_planner.py +++ b/gen/flights/ai_flight_planner.py @@ -29,6 +29,7 @@ class FlightPlanner: cas_flights = [] strike_flights = [] sead_flights = [] + custom_flights = [] flights = [] potential_sead_targets = [] @@ -75,6 +76,20 @@ class FlightPlanner: # TODO : commision STRIKE / ANTISHIP + def remove_flight(self, index): + try: + flight = self.flights[index] + if flight in self.interceptor_flights: self.interceptor_flights.remove(flight) + if flight in self.cap_flights: self.cap_flights.remove(flight) + if flight in self.cas_flights: self.cas_flights.remove(flight) + if flight in self.strike_flights: self.strike_flights.remove(flight) + if flight in self.sead_flights: self.sead_flights.remove(flight) + if flight in self.custom_flights: self.custom_flights.remove(flight) + self.flights.remove(flight) + except IndexError: + return + + def commision_interceptors(self): """ Pick some aircraft to assign them to interception roles diff --git a/qt_ui/windows/mission/QMissionPlanning.py b/qt_ui/windows/mission/QMissionPlanning.py index 15926a84..81dc6240 100644 --- a/qt_ui/windows/mission/QMissionPlanning.py +++ b/qt_ui/windows/mission/QMissionPlanning.py @@ -1,11 +1,12 @@ from PySide2.QtCore import Qt, Slot, QItemSelectionModel, QPoint -from PySide2.QtWidgets import QDialog, QGridLayout, QScrollArea, QVBoxLayout, QPushButton +from PySide2.QtWidgets import QDialog, QGridLayout, QScrollArea, QVBoxLayout, QPushButton, QHBoxLayout, QMessageBox from game import Game from game.event import CAP, CAS, FrontlineAttackEvent from qt_ui.uiconstants import EVENT_ICONS from qt_ui.windows.QWaitingForMissionResultWindow import QWaitingForMissionResultWindow from qt_ui.windows.mission.QPlannedFlightsView import QPlannedFlightsView from qt_ui.windows.mission.QChooseAirbase import QChooseAirbase +from qt_ui.windows.mission.flight.QFlightCreator import QFlightCreator from qt_ui.windows.mission.flight.QFlightPlanner import QFlightPlanner @@ -35,6 +36,7 @@ class QMissionPlanning(QDialog): if self.captured_cp[0].id in self.game.planners.keys(): self.planner = self.game.planners[self.captured_cp[0].id] self.planned_flight_view.set_flight_planner(self.planner) + self.selected_cp = self.captured_cp[0] self.planned_flight_view.selectionModel().setCurrentIndex(self.planned_flight_view.indexAt(QPoint(1, 1)), QItemSelectionModel.Select) self.planned_flight_view.selectionModel().selectionChanged.connect(self.on_flight_selection_change) @@ -44,12 +46,23 @@ class QMissionPlanning(QDialog): else: self.flight_planner = QFlightPlanner(None, self.game) + self.add_flight_button = QPushButton("Add Flight") + self.add_flight_button.clicked.connect(self.on_add_flight) + self.delete_flight_button = QPushButton("Delete Selected") + self.delete_flight_button.clicked.connect(self.on_delete_flight) + + self.button_layout = QHBoxLayout() + self.button_layout.addStretch() + self.button_layout.addWidget(self.add_flight_button) + self.button_layout.addWidget(self.delete_flight_button) + self.mission_start_button = QPushButton("Take Off") self.mission_start_button.setProperty("style", "start-button") self.mission_start_button.clicked.connect(self.on_start) self.left_bar_layout.addWidget(self.select_airbase) self.left_bar_layout.addWidget(self.planned_flight_view) + self.left_bar_layout.addLayout(self.button_layout) self.layout.addLayout(self.left_bar_layout, 0, 0) self.layout.addWidget(self.flight_planner, 0, 1) @@ -61,6 +74,7 @@ class QMissionPlanning(QDialog): def on_departure_cp_changed(self, cp_name): cps = [cp for cp in self.game.theater.controlpoints if cp.name == cp_name] if len(cps) == 1: + self.selected_cp = cps[0] self.planner = self.game.planners[cps[0].id] self.planned_flight_view.set_flight_planner(self.planner) else: @@ -71,7 +85,27 @@ class QMissionPlanning(QDialog): flight = self.planner.flights[index] self.flight_planner = QFlightPlanner(flight, self.game) - self.layout.addWidget(self.flight_planner,0 ,1) + self.layout.addWidget(self.flight_planner, 0, 1) + + def on_add_flight(self): + possible_aircraft_type = list(self.selected_cp.base.aircraft.keys()) + + if len(possible_aircraft_type) == 0: + msg = QMessageBox() + msg.setIcon(QMessageBox.Information) + msg.setText("No more aircraft are available on " + self.selected_cp.name + " airbase.") + msg.setWindowTitle("No more aircraft") + msg.setStandardButtons(QMessageBox.Ok) + msg.setWindowFlags(Qt.WindowStaysOnTopHint) + msg.exec_() + else: + self.subwindow = QFlightCreator(self.game, self.selected_cp, possible_aircraft_type, self.planned_flight_view) + self.subwindow.show() + + def on_delete_flight(self): + index = self.planned_flight_view.selectionModel().currentIndex().row() + self.planner.remove_flight(index) + self.planned_flight_view.set_flight_planner(self.planner) def on_start(self): @@ -96,3 +130,6 @@ class QMissionPlanning(QDialog): self.close() + + + diff --git a/qt_ui/windows/mission/flight/QFlightCreator.py b/qt_ui/windows/mission/flight/QFlightCreator.py new file mode 100644 index 00000000..7e729e67 --- /dev/null +++ b/qt_ui/windows/mission/flight/QFlightCreator.py @@ -0,0 +1,103 @@ +from typing import List + +from PySide2.QtCore import Qt +from PySide2.QtWidgets import QDialog, QGridLayout, QLabel, QComboBox, QHBoxLayout, QVBoxLayout, QPushButton, QSpinBox +from dcs import Point +from dcs.unittype import UnitType + +from game import Game +from gen.flights.ai_flight_planner import FlightPlanner +from gen.flights.flight import Flight, FlightWaypoint, FlightType +from qt_ui.uiconstants import EVENT_ICONS +from qt_ui.windows.mission.flight.waypoints.QFlightWaypointInfoBox import QFlightWaypointInfoBox +from theater import ControlPoint + +PREDEFINED_WAYPOINT_CATEGORIES = [ + "Frontline (CAS AREA)", + "Building", + "Units", + "Airbase" +] + + +class QFlightCreator(QDialog): + + def __init__(self, game: Game, from_cp:ControlPoint, possible_aircraft_type:List[UnitType], flight_view=None): + super(QFlightCreator, self).__init__() + self.game = game + self.from_cp = from_cp + self.flight_view = flight_view + self.planner = self.game.planners[from_cp.id] + + self.setWindowFlags(Qt.WindowStaysOnTopHint) + self.setModal(True) + self.setWindowTitle("Create flight") + self.setWindowIcon(EVENT_ICONS["strike"]) + + self.select_type_aircraft = QComboBox() + for aircraft_type in possible_aircraft_type: + print(aircraft_type) + print(aircraft_type.name) + self.select_type_aircraft.addItem(aircraft_type.id, userData=aircraft_type) + self.select_type_aircraft.setCurrentIndex(0) + + self.select_flight_type = QComboBox() + self.select_flight_type.addItem("CAP", userData=FlightType.CAP) + self.select_flight_type.addItem("BARCAP", userData=FlightType.BARCAP) + self.select_flight_type.addItem("TARCAP", userData=FlightType.TARCAP) + self.select_flight_type.addItem("INTERCEPT", userData=FlightType.INTERCEPTION) + self.select_flight_type.addItem("CAS", userData=FlightType.CAS) + self.select_flight_type.addItem("SEAD", userData=FlightType.SEAD) + self.select_flight_type.addItem("DEAD", userData=FlightType.DEAD) + self.select_flight_type.addItem("STRIKE", userData=FlightType.STRIKE) + self.select_flight_type.setCurrentIndex(0) + + self.select_count_of_aircraft = QSpinBox() + self.select_count_of_aircraft.setMinimum(1) + self.select_count_of_aircraft.setMaximum(4) + self.select_count_of_aircraft.setValue(2) + + self.add_button = QPushButton("Add") + self.add_button.clicked.connect(self.create) + + self.init_ui() + + + def init_ui(self): + layout = QVBoxLayout() + + type_layout = QHBoxLayout() + type_layout.addWidget(QLabel("Type of Aircraft : ")) + type_layout.addStretch() + type_layout.addWidget(self.select_type_aircraft, alignment=Qt.AlignRight) + + + count_layout = QHBoxLayout() + count_layout.addWidget(QLabel("Count : ")) + count_layout.addStretch() + count_layout.addWidget(self.select_count_of_aircraft, alignment=Qt.AlignRight) + + + flight_type_layout = QHBoxLayout() + flight_type_layout.addWidget(QLabel("Task : ")) + flight_type_layout.addStretch() + flight_type_layout.addWidget(self.select_flight_type, alignment=Qt.AlignRight) + + layout.addLayout(type_layout) + layout.addLayout(count_layout) + layout.addLayout(flight_type_layout) + layout.addStretch() + layout.addWidget(self.add_button, alignment=Qt.AlignRight) + + self.setLayout(layout) + + def create(self): + aircraft_type = self.select_type_aircraft.currentData() + count = self.select_count_of_aircraft.value() + flight = Flight(aircraft_type, count, self.from_cp, self.select_flight_type.currentData()) + self.planner.flights.append(flight) + self.planner.custom_flights.append(flight) + if self.flight_view is not None: + self.flight_view.set_flight_planner(self.planner) + self.close() + diff --git a/qt_ui/windows/mission/flight/waypoints/QFlightWaypointTab.py b/qt_ui/windows/mission/flight/waypoints/QFlightWaypointTab.py index 06fc85a6..1b5f31b0 100644 --- a/qt_ui/windows/mission/flight/waypoints/QFlightWaypointTab.py +++ b/qt_ui/windows/mission/flight/waypoints/QFlightWaypointTab.py @@ -2,7 +2,7 @@ from PySide2.QtWidgets import QFrame, QGridLayout, QLabel, QPushButton, QVBoxLay from gen.flights.flight import Flight from qt_ui.windows.mission.flight.waypoints.QFlightWaypointList import QFlightWaypointList -from qt_ui.windows.mission.flight.waypoints.QWaypointSelectionWindow import QWaypointSelectionWindow +from qt_ui.windows.mission.flight.waypoints.QPredefinedWaypointSelectionWindow import QPredefinedWaypointSelectionWindow from game import Game class QFlightWaypointTab(QFrame): @@ -22,7 +22,6 @@ class QFlightWaypointTab(QFrame): self.delete_selected = QPushButton("Delete Selected") self.delete_selected.clicked.connect(self.on_delete_waypoint) - layout.addWidget(self.flight_waypoint_list,0,0) rlayout.addWidget(self.open_fast_waypoint_button) rlayout.addWidget(self.delete_selected) @@ -37,5 +36,5 @@ class QFlightWaypointTab(QFrame): self.flight_waypoint_list.update_list() def on_fast_waypoint(self): - self.subwindow = QWaypointSelectionWindow(self.game, self.flight, self.flight_waypoint_list) + self.subwindow = QPredefinedWaypointSelectionWindow(self.game, self.flight, self.flight_waypoint_list) self.subwindow.show() \ No newline at end of file diff --git a/qt_ui/windows/mission/flight/waypoints/QWaypointSelectionWindow.py b/qt_ui/windows/mission/flight/waypoints/QPredefinedWaypointSelectionWindow.py similarity index 98% rename from qt_ui/windows/mission/flight/waypoints/QWaypointSelectionWindow.py rename to qt_ui/windows/mission/flight/waypoints/QPredefinedWaypointSelectionWindow.py index c6ab2ab6..9ab97faa 100644 --- a/qt_ui/windows/mission/flight/waypoints/QWaypointSelectionWindow.py +++ b/qt_ui/windows/mission/flight/waypoints/QPredefinedWaypointSelectionWindow.py @@ -15,11 +15,11 @@ PREDEFINED_WAYPOINT_CATEGORIES = [ ] -class QWaypointSelectionWindow(QDialog): +class QPredefinedWaypointSelectionWindow(QDialog): def __init__(self, game: Game, flight: Flight, flight_waypoint_list): - super(QWaypointSelectionWindow, self).__init__() + super(QPredefinedWaypointSelectionWindow, self).__init__() self.game = game self.flight = flight self.setWindowFlags(Qt.WindowStaysOnTopHint)