Exemple #1
0
 def on_add_flight(self) -> None:
     """Opens the new flight dialog."""
     self.add_flight_dialog = QFlightCreator(self.game,
                                             self.package_model.package,
                                             parent=self.window())
     self.add_flight_dialog.created.connect(self.add_flight)
     self.add_flight_dialog.show()
    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()
Exemple #3
0
class QPackageDialog(QDialog):
    """Base package management dialog.

    The dialogs for creating a new package and editing an existing dialog are
    very similar, and this implements the shared behavior.
    """

    #: Emitted when a change is made to the package.
    package_changed = Signal()

    def __init__(self,
                 game_model: GameModel,
                 model: PackageModel,
                 parent=None) -> None:
        super().__init__(parent)
        self.game_model = game_model
        self.package_model = model
        self.add_flight_dialog: Optional[QFlightCreator] = None

        self.setMinimumSize(1000, 440)
        self.setWindowTitle(
            f"Mission Package: {self.package_model.mission_target.name}")
        self.setWindowIcon(EVENT_ICONS["strike"])

        self.layout = QVBoxLayout()

        self.summary_row = QHBoxLayout()
        self.layout.addLayout(self.summary_row)

        self.package_type_column = QHBoxLayout()
        self.summary_row.addLayout(self.package_type_column)

        self.package_type_label = QLabel("Package Type:")
        self.package_type_text = QLabel(self.package_model.description)
        # noinspection PyUnresolvedReferences
        self.package_changed.connect(lambda: self.package_type_text.setText(
            self.package_model.description))
        self.package_type_column.addWidget(self.package_type_label)
        self.package_type_column.addWidget(self.package_type_text)

        self.summary_row.addStretch(1)

        self.tot_column = QHBoxLayout()
        self.summary_row.addLayout(self.tot_column)

        self.tot_label = QLabel("Time Over Target:")
        self.tot_column.addWidget(self.tot_label)

        self.tot_spinner = QTimeEdit(self.tot_qtime())
        self.tot_spinner.setMinimumTime(QTime(0, 0))
        self.tot_spinner.setDisplayFormat("T+hh:mm:ss")
        self.tot_spinner.timeChanged.connect(self.save_tot)
        self.tot_spinner.setToolTip("Package TOT relative to mission TOT")
        self.tot_spinner.setEnabled(not self.package_model.package.auto_asap)
        self.tot_column.addWidget(self.tot_spinner)

        self.auto_asap = QCheckBox("ASAP")
        self.auto_asap.setToolTip(
            "Sets the package TOT to the earliest time that all flights can "
            "arrive at the target.")
        self.auto_asap.setChecked(self.package_model.package.auto_asap)
        self.auto_asap.toggled.connect(self.set_asap)
        self.tot_column.addWidget(self.auto_asap)

        self.tot_help_label = QLabel(
            "<a href=\"https://github.com/Khopa/dcs_liberation/wiki/Mission-planning\"><span style=\"color:#FFFFFF;\">Help</span></a>"
        )
        self.tot_help_label.setAlignment(Qt.AlignCenter)
        self.tot_help_label.setOpenExternalLinks(True)
        self.tot_column.addWidget(self.tot_help_label)

        self.package_view = QFlightList(self.game_model, self.package_model)
        self.package_view.selectionModel().selectionChanged.connect(
            self.on_selection_changed)
        self.layout.addWidget(self.package_view)

        self.button_layout = QHBoxLayout()
        self.layout.addLayout(self.button_layout)

        self.add_flight_button = QPushButton("Add Flight")
        self.add_flight_button.clicked.connect(self.on_add_flight)
        self.button_layout.addWidget(self.add_flight_button)

        self.delete_flight_button = QPushButton("Delete Selected")
        self.delete_flight_button.setProperty("style", "btn-danger")
        self.delete_flight_button.clicked.connect(self.on_delete_flight)
        self.delete_flight_button.setEnabled(model.rowCount() > 0)
        self.button_layout.addWidget(self.delete_flight_button)

        self.package_model.tot_changed.connect(self.update_tot)

        self.button_layout.addStretch()

        self.setLayout(self.layout)

        self.accepted.connect(self.on_save)
        self.finished.connect(self.on_close)
        self.rejected.connect(self.on_cancel)

    @property
    def game(self) -> Game:
        return self.game_model.game

    def tot_qtime(self) -> QTime:
        delay = int(
            self.package_model.package.time_over_target.total_seconds())
        hours = delay // 3600
        minutes = delay // 60 % 60
        seconds = delay % 60
        return QTime(hours, minutes, seconds)

    def on_cancel(self) -> None:
        pass

    @staticmethod
    def on_close(_result) -> None:
        GameUpdateSignal.get_instance().redraw_flight_paths()

    def on_save(self) -> None:
        self.save_tot()

    def save_tot(self) -> None:
        time = self.tot_spinner.time()
        seconds = time.hour() * 3600 + time.minute() * 60 + time.second()
        self.package_model.set_tot(timedelta(seconds=seconds))

    def set_asap(self, checked: bool) -> None:
        self.package_model.set_asap(checked)
        self.tot_spinner.setEnabled(not self.package_model.package.auto_asap)
        self.update_tot()

    def update_tot(self) -> None:
        self.tot_spinner.setTime(self.tot_qtime())

    def on_selection_changed(self, selected: QItemSelection,
                             _deselected: QItemSelection) -> None:
        """Updates the state of the delete button."""
        self.delete_flight_button.setEnabled(not selected.empty())

    def on_add_flight(self) -> None:
        """Opens the new flight dialog."""
        self.add_flight_dialog = QFlightCreator(self.game,
                                                self.package_model.package,
                                                parent=self.window())
        self.add_flight_dialog.created.connect(self.add_flight)
        self.add_flight_dialog.show()

    def add_flight(self, flight: Flight) -> None:
        """Adds the new flight to the package."""
        self.game.aircraft_inventory.claim_for_flight(flight)
        self.package_model.add_flight(flight)
        planner = FlightPlanBuilder(self.game,
                                    self.package_model.package,
                                    is_player=True)
        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)
        self.package_model.update_tot()
        # noinspection PyUnresolvedReferences
        self.package_changed.emit()

    def on_delete_flight(self) -> None:
        """Removes the selected flight from the package."""
        flight = self.package_view.selected_item
        if flight is None:
            logging.error(f"Cannot delete flight when no flight is selected.")
            return
        self.game.aircraft_inventory.return_from_flight(flight)
        self.package_model.delete_flight(flight)
        # noinspection PyUnresolvedReferences
        self.package_changed.emit()
Exemple #4
0
class QMissionPlanning(QDialog):
    def __init__(self, game: Game):
        super(QMissionPlanning, self).__init__()
        self.game = game
        self.setWindowFlags(Qt.WindowStaysOnTopHint)
        self.setMinimumSize(1000, 440)
        self.setWindowTitle("Mission Preparation")
        self.setWindowIcon(EVENT_ICONS["strike"])
        self.init_ui()
        print("DONE")

    def init_ui(self):

        self.captured_cp = [
            cp for cp in self.game.theater.controlpoints if cp.captured
        ]

        self.layout = QGridLayout()
        self.left_bar_layout = QVBoxLayout()

        self.select_airbase = QChooseAirbase(self.game)
        self.select_airbase.selected_airbase_changed.connect(
            self.on_departure_cp_changed)
        self.planned_flight_view = QPlannedFlightsView(None)
        self.available_aircraft_at_selected_location = {}
        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.available_aircraft_at_selected_location = self.planner.get_available_aircraft(
            )

        self.planned_flight_view.selectionModel().setCurrentIndex(
            self.planned_flight_view.indexAt(QPoint(1, 1)),
            QItemSelectionModel.Rows)
        self.planned_flight_view.selectionModel().selectionChanged.connect(
            self.on_flight_selection_change)

        if len(self.planned_flight_view.flight_planner.flights) > 0:
            self.flight_planner = QFlightPlanner(
                self.planned_flight_view.flight_planner.flights[0], self.game,
                self.planned_flight_view.flight_planner, 0)
            self.flight_planner.on_planned_flight_changed.connect(
                self.update_planned_flight_view)
        else:
            self.flight_planner = QFlightPlanner(
                None, self.game, self.planned_flight_view.flight_planner, 0)
            self.flight_planner.on_planned_flight_changed.connect(
                self.update_planned_flight_view)

        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.setProperty("style", "btn-danger")
        self.delete_flight_button.clicked.connect(self.on_delete_flight)

        self.button_layout = QHBoxLayout()
        self.button_layout.addStretch()
        self.button_layout.addWidget(self.delete_flight_button)
        self.button_layout.addWidget(self.add_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)
        self.layout.addWidget(self.mission_start_button,
                              1,
                              1,
                              alignment=Qt.AlignRight)

        self.setLayout(self.layout)

    @Slot(str)
    def on_departure_cp_changed(self, cp_name):
        cps = [
            cp for cp in self.game.theater.controlpoints if cp.name == cp_name
        ]

        print(cps)

        if len(cps) == 1:
            self.selected_cp = cps[0]
            self.planner = self.game.planners[cps[0].id]
            self.available_aircraft_at_selected_location = self.planner.get_available_aircraft(
            )
            self.planned_flight_view.set_flight_planner(self.planner)
        else:
            self.available_aircraft_at_selected_location = {}
            self.planned_flight_view.set_flight_planner(None)

    def on_flight_selection_change(self):

        print("On flight selection change")

        index = self.planned_flight_view.selectionModel().currentIndex().row()
        self.planned_flight_view.repaint()

        if self.flight_planner is not None:
            self.flight_planner.on_planned_flight_changed.disconnect()
            self.flight_planner.clearTabs()

        try:
            flight = self.planner.flights[index]
        except IndexError:
            flight = None
        self.flight_planner = QFlightPlanner(
            flight, self.game, self.planner,
            self.flight_planner.currentIndex())
        self.flight_planner.on_planned_flight_changed.connect(
            self.update_planned_flight_view)
        self.layout.addWidget(self.flight_planner, 0, 1)

    def update_planned_flight_view(self):
        self.planned_flight_view.update_content()

    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, index)

    def on_start(self):

        # TODO : refactor this nonsense
        self.gameEvent = None
        for event in self.game.events:
            if isinstance(event,
                          FrontlineAttackEvent) and event.is_player_attacking:
                self.gameEvent = event
        if self.gameEvent is None:
            self.gameEvent = FrontlineAttackEvent(
                self.game, self.game.theater.controlpoints[0],
                self.game.theater.controlpoints[0],
                self.game.theater.controlpoints[0].position,
                self.game.player_name, self.game.enemy_name)
        #if self.awacs_checkbox.isChecked() == 1:
        #    self.gameEvent.is_awacs_enabled = True
        #    self.game.awacs_expense_commit()
        #else:
        #    self.gameEvent.is_awacs_enabled = False
        self.gameEvent.is_awacs_enabled = True
        self.gameEvent.ca_slots = 1
        self.gameEvent.departure_cp = self.game.theater.controlpoints[0]
        self.gameEvent.player_attacking({CAS: {}, CAP: {}})
        self.gameEvent.depart_from = self.game.theater.controlpoints[0]

        self.game.initiate_event(self.gameEvent)
        waiting = QWaitingForMissionResultWindow(self.gameEvent, self.game)
        waiting.show()
        self.close()