From 2d4287df2a5dde0347fb54aea14a40c01437c35d Mon Sep 17 00:00:00 2001 From: Khopa Date: Wed, 10 Jun 2020 22:34:31 +0200 Subject: [PATCH] Polished mission generator, fixed sam bug on map view. --- __init__.py | 64 ---------------- changelog.md | 34 +++++++-- game/data/aaa_db.py | 21 ++++++ game/data/radar_db.py | 54 +++++++++++++ gen/flights/ai_flight_planner.py | 5 +- .../combos/QSEADTargetSelectionComboBox.py | 19 ++--- .../combos/QStrikeTargetSelectionComboBox.py | 7 +- qt_ui/widgets/map/QLiberationMap.py | 6 +- qt_ui/widgets/views/QSeadTargetInfoView.py | 42 +++++++++++ qt_ui/widgets/views/QStrikeTargetInfoView.py | 75 +++++++++++++++++++ .../flight/generator/QCASMissionGenerator.py | 8 +- .../flight/generator/QSEADMissionGenerator.py | 25 +++++-- .../generator/QSTRIKEMissionGenerator.py | 19 +++-- .../mission/flight/payload/QLoadoutEditor.py | 7 +- .../flight/waypoints/QFlightWaypointList.py | 8 +- 15 files changed, 286 insertions(+), 108 deletions(-) delete mode 100755 __init__.py create mode 100644 game/data/aaa_db.py create mode 100644 game/data/radar_db.py create mode 100644 qt_ui/widgets/views/QSeadTargetInfoView.py create mode 100644 qt_ui/widgets/views/QStrikeTargetInfoView.py diff --git a/__init__.py b/__init__.py deleted file mode 100755 index 62d099e6..00000000 --- a/__init__.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python3 -import logging -import os -import re -import sys - -import dcs - -import ui.corruptedsavemenu -import ui.mainmenu -import ui.newgamemenu -import ui.window -from game.game import Game -from userdata import persistency, logging as logging_module - -assert len(sys.argv) >= 3, "__init__.py should be started with two mandatory arguments: %UserProfile% location and application version" - -persistency.setup(sys.argv[1]) -dcs.planes.FlyingType.payload_dirs = [os.path.join(os.path.dirname(os.path.realpath(__file__)), "resources\\payloads")] - -VERSION_STRING = sys.argv[2] -logging_module.setup_version_string(VERSION_STRING) -logging.info("Using {} as userdata folder".format(persistency.base_path())) - - -def proceed_to_main_menu(game: Game): - m = ui.mainmenu.MainMenu(w, None, game) - m.display() - - -def is_version_compatible(save_version): - current_version_components = re.split(r"[\._]", VERSION_STRING) - save_version_components = re.split(r"[\._]", save_version) - - if "--ignore-save" in sys.argv: - return False - - if current_version_components == save_version_components: - return True - - if save_version in ["1.4_rc1", "1.4_rc2", "1.4_rc3", "1.4_rc4", "1.4_rc5", "1.4_rc6"]: - return False - - if current_version_components[:2] == save_version_components[:2]: - return True - - return False - - -w = ui.window.Window() - -try: - game = persistency.restore_game() - if not game or not is_version_compatible(game.settings.version): - ui.newgamemenu.NewGameMenu(w, w.start_new_game).display() - else: - game.settings.version = VERSION_STRING - proceed_to_main_menu(game) -except Exception as e: - logging.exception(e) - ui.corruptedsavemenu.CorruptedSaveMenu(w).display() - -w.run() - diff --git a/changelog.md b/changelog.md index d40d8eaf..77181bf8 100644 --- a/changelog.md +++ b/changelog.md @@ -1,8 +1,10 @@ #2.0 RC 7 ##Features/Improvements : + * **[Units/Factions]** Added P-47D-30 for factions allies_1944 -* **[Units/Factions]** Replaced S3-B Tanker by KC130 for most factions +* **[Campaign/Map]** Added support for The Channel map [TODO] + * **[Mission Generator]** AI Flight generator has been reworked * **[Mission Generator]** Add PP points for JF-17 on STRIKE missions * **[Mission Generator]** Add ST point for F-14B on STRIKE missions @@ -10,26 +12,42 @@ * **[Mission Generator]** AI units can start from parking (With a new setting in Settings Window to disable it) * **[Mission Generator]** Tacan for carrier will only be in Mode X from now * **[Mission Generator]** RTB waypoints for autogenerated flights + +* **[Flight Planner]** Added CAS mission generator +* **[Flight Planner]** Added CAP mission generator +* **[Flight Planner]** Added SEAD mission generator +* **[Flight Planner]** Added STRIKE mission generator +* **[Flight Planner]** Added buttons to add autogenerated waypoints (ASCEND, DESCEND, RTB) +* **[Flight Planner]** Improved waypoint list [TODO] + * **[Settings]** Added settings to disallow external views * **[Settings]** Added settings to choose F10 Map mode (All, Allies only, Player only, Fog of War, Map Only) * **[Settings]** Added settings to choose whether to auto-generate objective marks on the map + * **[Info Panel]** Added information about destroyed buildings in info panel * **[Info Panel]** Added information about destroyed units at SAM site in info panel -* **[Info Panel]** Added information about units destroyed outside the frontline in the debriefing window -* **[Info Panel]** Added information about buildings destroyed in the debriefing window + +* **[Debriefing]** Added information about units destroyed outside the frontline in the debriefing window +* **[Debriefing]** Added information about buildings destroyed in the debriefing window + * **[Map]** Tooltip now contains the list of building for Strike targets on the map * **[Map]** Added "Oil derrick" building -* **[Misc]** Made it possible to setup DCS Saved Games directory and DCS installation directory manually +* **[Misc]** Made it possible to setup DCS Saved Games directory and DCS installation directory manually at first start ##Fixed issues : + +* **[Units/Factions]** Replaced S3-B Tanker by KC130 for most factions (More fuel) * **[Mission Generator]** When playing as RED the activation trigger would not be properly generated +* **[Mission Generator]** FW-190A8 is now properly considered as a flyable aircraft * **[Mission Generator]** Changed "strike" payload for Su-24M that was innefective * **[Mission Generator]** Changed "strike" payload for JF-17 to use LS-6 bombs instead of GBU -* **[Mission Generator]** FW-190A8 is now properly considered as a flyable -* **[Maps/Campaign]** Now using Vasiani airport instead of Soganlung in North Caucasus campaign (More parking slots) +* **[Mission Generator]** Change power station template. (Buildings could end up superposed). +* **[Maps/Campaign]** Now using Vasiani airbase instead of Soganlung airport in North Caucasus campaign (More parking slots) * **[Info Panel]** Message displayed on base capture event stated that the ennemy captured an airbase, while it was the player who captured it. -* **[Map]** Graphical glitch on map when one building of an objective was destroyed, but not the others -* **[Map]** Change power station template. (Buildings could end up superposed). +* **[Map View]** Graphical glitch on map when one building of an objective was destroyed, but not the others +* **[Map View]** + + #2.0 RC 6 diff --git a/game/data/aaa_db.py b/game/data/aaa_db.py new file mode 100644 index 00000000..1aa7d597 --- /dev/null +++ b/game/data/aaa_db.py @@ -0,0 +1,21 @@ +from dcs.vehicles import AirDefence + +AAA_UNITS = [ + AirDefence.SPAAA_Gepard, + AirDefence.SPAAA_ZSU_23_4_Shilka, + AirDefence.AAA_Vulcan_M163, + AirDefence.AAA_ZU_23_Closed, + AirDefence.AAA_ZU_23_Emplacement, + AirDefence.AAA_ZU_23_on_Ural_375, + AirDefence.AAA_ZU_23_Insurgent_Closed, + AirDefence.AAA_ZU_23_Insurgent_on_Ural_375, + AirDefence.AAA_ZU_23_Insurgent, + AirDefence.AAA_8_8cm_Flak_18, + AirDefence.AAA_Flak_38, + AirDefence.AAA_8_8cm_Flak_36, + AirDefence.AAA_8_8cm_Flak_37, + AirDefence.AAA_Flak_Vierling_38, + AirDefence.AAA_Kdo_G_40, + AirDefence.AAA_8_8cm_Flak_41, + AirDefence.AAA_Bofors_40mm +] \ No newline at end of file diff --git a/game/data/radar_db.py b/game/data/radar_db.py new file mode 100644 index 00000000..0c6e0709 --- /dev/null +++ b/game/data/radar_db.py @@ -0,0 +1,54 @@ +from dcs.vehicles import AirDefence +from dcs.ships import * + +UNITS_WITH_RADAR = [ + + # Radars + AirDefence.SAM_SA_15_Tor_9A331, + AirDefence.SAM_SA_11_Buk_CC_9S470M1, + AirDefence.SAM_Patriot_AMG_AN_MRC_137, + AirDefence.SAM_Patriot_ECS_AN_MSQ_104, + AirDefence.SPAAA_Gepard, + AirDefence.AAA_Vulcan_M163, + AirDefence.SPAAA_ZSU_23_4_Shilka, + AirDefence.EWR_1L13, + AirDefence.SAM_SA_6_Kub_STR_9S91, + AirDefence.SAM_SA_10_S_300PS_TR_30N6, + AirDefence.SAM_SA_10_S_300PS_SR_5N66M, + AirDefence.EWR_55G6, + AirDefence.SAM_SA_10_S_300PS_SR_64H6E, + AirDefence.SAM_SA_11_Buk_SR_9S18M1, + AirDefence.CP_9S80M1_Sborka, + AirDefence.SAM_Hawk_TR_AN_MPQ_46, + AirDefence.SAM_Hawk_SR_AN_MPQ_50, + AirDefence.SAM_Patriot_STR_AN_MPQ_53, + AirDefence.SAM_Hawk_CWAR_AN_MPQ_55, + AirDefence.SAM_SR_P_19, + AirDefence.SAM_Roland_EWR, + AirDefence.SAM_SA_3_S_125_TR_SNR, + AirDefence.SAM_SA_2_TR_SNR_75_Fan_Song, + AirDefence.HQ_7_Self_Propelled_STR, + + # Ships + CVN_70_Carl_Vinson, + Oliver_Hazzard_Perry_class, + Ticonderoga_class, + FFL_1124_4_Grisha, + CV_1143_5_Admiral_Kuznetsov, + FSG_1241_1MP_Molniya, + CG_1164_Moskva, + FFG_11540_Neustrashimy, + CGN_1144_2_Pyotr_Velikiy, + FF_1135M_Rezky, + CV_1143_5_Admiral_Kuznetsov_2017, + CVN_74_John_C__Stennis, + CVN_71_Theodore_Roosevelt, + CVN_72_Abraham_Lincoln, + CVN_73_George_Washington, + USS_Arleigh_Burke_IIa, + LHA_1_Tarawa, + Type_052B_Destroyer, + Type_054A_Frigate, + Type_052C_Destroyer, + Type_093, +] \ No newline at end of file diff --git a/gen/flights/ai_flight_planner.py b/gen/flights/ai_flight_planner.py index 68ac16b6..05557af9 100644 --- a/gen/flights/ai_flight_planner.py +++ b/gen/flights/ai_flight_planner.py @@ -1,6 +1,5 @@ import math import operator -import typing import random from game import db @@ -414,8 +413,8 @@ class FlightPlanner: continue point = FlightWaypoint(building.position.x, building.position.y, 0) - point.description = "STRIKE on " + building.obj_name + " " + str(building.category) - point.pretty_name = "STRIKE on " + building.obj_name + " " + str(building.category) + point.description = "STRIKE on " + building.obj_name + " " + building.category + " [" + str(building.dcs_identifier) + " ]" + point.pretty_name = "STRIKE on " + building.obj_name + " " + building.category + " [" + str(building.dcs_identifier) + " ]" point.name = building.obj_name point.only_for_player = True ingress_point.targets.append(building) diff --git a/qt_ui/widgets/combos/QSEADTargetSelectionComboBox.py b/qt_ui/widgets/combos/QSEADTargetSelectionComboBox.py index 07cda611..a037d1b4 100644 --- a/qt_ui/widgets/combos/QSEADTargetSelectionComboBox.py +++ b/qt_ui/widgets/combos/QSEADTargetSelectionComboBox.py @@ -1,11 +1,9 @@ -from PySide2.QtCore import QSortFilterProxyModel, Qt, QModelIndex from PySide2.QtGui import QStandardItem, QStandardItemModel -from PySide2.QtWidgets import QComboBox, QCompleter + from game import Game -from gen import Conflict, FlightWaypointType, db -from gen.flights.flight import FlightWaypoint, PredefinedWaypointCategory +from game.data.radar_db import UNITS_WITH_RADAR +from gen import db from qt_ui.widgets.combos.QFilteredComboBox import QFilteredComboBox -from theater import ControlPointType class SEADTargetInfo: @@ -24,7 +22,7 @@ class QSEADTargetSelectionComboBox(QFilteredComboBox): self.game = game self.find_possible_sead_targets() - def get_selected_target(self): + def get_selected_target(self) -> SEADTargetInfo: n = self.currentText() for target in self.targets: if target.name == n: @@ -53,10 +51,13 @@ class QSEADTargetSelectionComboBox(QFilteredComboBox): for group in g.groups: for u in group.units: utype = db.unit_type_from_name(u.type) - if hasattr(utype, "detection_range") and utype.detection_range > 1000: - if utype.detection_range > detection_range: - detection_range = utype.detection_range + + if utype in UNITS_WITH_RADAR: + if hasattr(utype, "detection_range") and utype.detection_range > 1000: + if utype.detection_range > detection_range: + detection_range = utype.detection_range radars.append(u) + if hasattr(utype, "threat_range"): if utype.threat_range > threat_range: threat_range = utype.threat_range diff --git a/qt_ui/widgets/combos/QStrikeTargetSelectionComboBox.py b/qt_ui/widgets/combos/QStrikeTargetSelectionComboBox.py index c1027cb6..b5fcc57d 100644 --- a/qt_ui/widgets/combos/QStrikeTargetSelectionComboBox.py +++ b/qt_ui/widgets/combos/QStrikeTargetSelectionComboBox.py @@ -20,7 +20,12 @@ class QStrikeTargetSelectionComboBox(QFilteredComboBox): self.game = game self.find_possible_strike_targets() - def get_selected_target(self): + + for t in self.targets: + print(t.name + " - " + str(len(t.units)) + " " + str(len(t.buildings))) + + + def get_selected_target(self) -> StrikeTargetInfo: n = self.currentText() for target in self.targets: if target.name == n: diff --git a/qt_ui/widgets/map/QLiberationMap.py b/qt_ui/widgets/map/QLiberationMap.py index 2acdfe88..59d74bbb 100644 --- a/qt_ui/widgets/map/QLiberationMap.py +++ b/qt_ui/widgets/map/QLiberationMap.py @@ -9,6 +9,7 @@ from dcs.mapping import point_from_heading import qt_ui.uiconstants as CONST from game import Game, db +from game.data.radar_db import UNITS_WITH_RADAR from game.event import UnitsDeliveryEvent, Event, ControlPointType from gen import Conflict from qt_ui.widgets.map.QLiberationScene import QLiberationScene @@ -96,13 +97,16 @@ class QLiberationMap(QGraphicsView): if ground_object.category == "aa" and self.get_display_rule("sam"): max_range = 0 + has_radar = False if ground_object.groups: for g in ground_object.groups: for u in g.units: unit = db.unit_type_from_name(u.type) + if unit in UNITS_WITH_RADAR: + has_radar = True if unit.threat_range > max_range: max_range = unit.threat_range - if max_range >= 6000: + if has_radar: scene.addEllipse(go_pos[0] - max_range/300.0 + 8, go_pos[1] - max_range/300.0 + 8, max_range/150.0, max_range/150.0, pen, brush) added_objects.append(ground_object.obj_name) diff --git a/qt_ui/widgets/views/QSeadTargetInfoView.py b/qt_ui/widgets/views/QSeadTargetInfoView.py new file mode 100644 index 00000000..06dcdfc3 --- /dev/null +++ b/qt_ui/widgets/views/QSeadTargetInfoView.py @@ -0,0 +1,42 @@ +from PySide2.QtGui import QStandardItemModel, QStandardItem +from PySide2.QtWidgets import QGroupBox, QVBoxLayout, QListView, QAbstractItemView + +from qt_ui.widgets.combos.QSEADTargetSelectionComboBox import SEADTargetInfo + + +class QSeadTargetInfoView(QGroupBox): + """ + UI Component to display info about a sead target + """ + + def __init__(self, sead_target_infos: SEADTargetInfo): + if sead_target_infos is None: + sead_target_infos = SEADTargetInfo() + super(QSeadTargetInfoView, self).__init__("Target : " + sead_target_infos.name) + self.sead_target_infos = sead_target_infos + self.radar_list = QListView() + self.init_ui() + + def init_ui(self): + layout = QVBoxLayout(self) + layout.setSpacing(0) + layout.addWidget(self.radar_list) + self.setLayout(layout) + + def setTarget(self, target: SEADTargetInfo): + self.setTitle(target.name) + self.sead_target_infos = target + radar_list_model = QStandardItemModel() + self.radar_list.setSelectionMode(QAbstractItemView.NoSelection) + for r in self.sead_target_infos.radars: + radar_list_model.appendRow(QStandardItem(r.type)) + self.radar_list.setModel(radar_list_model) + + + + + + + + + diff --git a/qt_ui/widgets/views/QStrikeTargetInfoView.py b/qt_ui/widgets/views/QStrikeTargetInfoView.py new file mode 100644 index 00000000..efa707f9 --- /dev/null +++ b/qt_ui/widgets/views/QStrikeTargetInfoView.py @@ -0,0 +1,75 @@ +import random + +from PySide2.QtGui import QStandardItemModel, QStandardItem +from PySide2.QtWidgets import QGroupBox, QLabel, QWidget, QVBoxLayout, QListView, QAbstractItemView + +from qt_ui.widgets.combos.QStrikeTargetSelectionComboBox import StrikeTargetInfo + + +class QStrikeTargetInfoView(QGroupBox): + """ + UI Component to display info about a strike target + """ + + def __init__(self, strike_target_infos: StrikeTargetInfo): + + if strike_target_infos is None: + strike_target_infos = StrikeTargetInfo() + + super(QStrikeTargetInfoView, self).__init__("Target : " + strike_target_infos.name) + + self.strike_target_infos = strike_target_infos + + self.listView = QListView() + + self.init_ui() + + + def init_ui(self): + layout = QVBoxLayout(self) + layout.setSpacing(0) + layout.addWidget(self.listView) + self.setLayout(layout) + + + def setTarget(self, target): + + self.setTitle(target.name) + self.strike_target_infos = target + model = QStandardItemModel() + self.listView.setSelectionMode(QAbstractItemView.NoSelection) + + if len(self.strike_target_infos.units) > 0: + dic = {} + for u in self.strike_target_infos.units: + if u.type in dic.keys(): + dic[u.type] = dic[u.type] + 1 + else: + dic[u.type] = 1 + for k,v in dic.items(): + model.appendRow(QStandardItem(k + " x " + str(v))) + print(k + " x " + str(v)) + else: + dic = {} + for b in self.strike_target_infos.buildings: + id = b.dcs_identifier + if b.is_dead: + id = id + "[Destroyed]" + if id in dic.keys(): + dic[id] = dic[id] + 1 + else: + dic[id] = 1 + for k, v in dic.items(): + model.appendRow(QStandardItem(k + " x " + str(v))) + print(k + " x " + str(v)) + + self.listView.setModel(model) + + + + + + + + + diff --git a/qt_ui/windows/mission/flight/generator/QCASMissionGenerator.py b/qt_ui/windows/mission/flight/generator/QCASMissionGenerator.py index 92305af7..f655c693 100644 --- a/qt_ui/windows/mission/flight/generator/QCASMissionGenerator.py +++ b/qt_ui/windows/mission/flight/generator/QCASMissionGenerator.py @@ -1,5 +1,5 @@ from PySide2.QtGui import Qt -from PySide2.QtWidgets import QLabel, QHBoxLayout, QVBoxLayout +from PySide2.QtWidgets import QLabel, QHBoxLayout, QVBoxLayout, QGroupBox from dcs import Point from game import Game @@ -31,8 +31,6 @@ class QCASMissionGenerator(QAbstractMissionGenerator): else: self.distanceToTargetLabel.setText("??? nm") - - def init_ui(self): layout = QVBoxLayout() @@ -41,14 +39,16 @@ class QCASMissionGenerator(QAbstractMissionGenerator): wpt_layout.addWidget(self.wpt_selection_box) wpt_layout.addStretch() + distToTargetBox = QGroupBox("Infos :") distToTarget = QHBoxLayout() distToTarget.addWidget(QLabel("Distance to target : ")) distToTarget.addStretch() distToTarget.addWidget(self.distanceToTargetLabel, alignment=Qt.AlignRight) + distToTargetBox.setLayout(distToTarget) layout.addLayout(wpt_layout) layout.addWidget(self.wpt_info) - layout.addLayout(distToTarget) + layout.addWidget(distToTargetBox) layout.addStretch() layout.addWidget(self.ok_button) diff --git a/qt_ui/windows/mission/flight/generator/QSEADMissionGenerator.py b/qt_ui/windows/mission/flight/generator/QSEADMissionGenerator.py index b61435da..e243a5f5 100644 --- a/qt_ui/windows/mission/flight/generator/QSEADMissionGenerator.py +++ b/qt_ui/windows/mission/flight/generator/QSEADMissionGenerator.py @@ -1,10 +1,11 @@ from PySide2.QtGui import Qt -from PySide2.QtWidgets import QLabel, QHBoxLayout, QVBoxLayout +from PySide2.QtWidgets import QLabel, QHBoxLayout, QVBoxLayout, QGroupBox from game import Game from gen.flights.ai_flight_planner import meter_to_nm from gen.flights.flight import Flight from qt_ui.widgets.combos.QSEADTargetSelectionComboBox import QSEADTargetSelectionComboBox +from qt_ui.widgets.views.QSeadTargetInfoView import QSeadTargetInfoView from qt_ui.windows.mission.flight.generator.QAbstractMissionGenerator import QAbstractMissionGenerator @@ -20,14 +21,17 @@ class QSEADMissionGenerator(QAbstractMissionGenerator): self.distanceToTargetLabel = QLabel("0 nm") self.threatRangeLabel = QLabel("0 nm") self.detectionRangeLabel = QLabel("0 nm") + self.seadTargetInfoView = QSeadTargetInfoView(None) self.init_ui() self.on_selected_target_changed() def on_selected_target_changed(self): target = self.tgt_selection_box.get_selected_target() - self.distanceToTargetLabel.setText("~" + str(meter_to_nm(self.flight.from_cp.position.distance_to_point(target.location.position))) + " nm") - self.threatRangeLabel.setText(str(meter_to_nm(target.threat_range)) + " nm") - self.detectionRangeLabel.setText(str(meter_to_nm(target.detection_range)) + " nm") + if target is not None: + self.distanceToTargetLabel.setText("~" + str(meter_to_nm(self.flight.from_cp.position.distance_to_point(target.location.position))) + " nm") + self.threatRangeLabel.setText(str(meter_to_nm(target.threat_range)) + " nm") + self.detectionRangeLabel.setText(str(meter_to_nm(target.detection_range)) + " nm") + self.seadTargetInfoView.setTarget(target) def init_ui(self): layout = QVBoxLayout() @@ -37,6 +41,9 @@ class QSEADMissionGenerator(QAbstractMissionGenerator): wpt_layout.addStretch() wpt_layout.addWidget(self.tgt_selection_box, alignment=Qt.AlignRight) + distThreatBox = QGroupBox("Infos :") + threatLayout = QVBoxLayout() + distToTarget = QHBoxLayout() distToTarget.addWidget(QLabel("Distance to site : ")) distToTarget.addStretch() @@ -52,10 +59,14 @@ class QSEADMissionGenerator(QAbstractMissionGenerator): detectionRangeLayout.addStretch() detectionRangeLayout.addWidget(self.detectionRangeLabel, alignment=Qt.AlignRight) + threatLayout.addLayout(distToTarget) + threatLayout.addLayout(threatRangeLayout) + threatLayout.addLayout(detectionRangeLayout) + distThreatBox.setLayout(threatLayout) + layout.addLayout(wpt_layout) - layout.addLayout(distToTarget) - layout.addLayout(threatRangeLayout) - layout.addLayout(detectionRangeLayout) + layout.addWidget(self.seadTargetInfoView) + layout.addWidget(distThreatBox) layout.addStretch() layout.addWidget(self.ok_button) diff --git a/qt_ui/windows/mission/flight/generator/QSTRIKEMissionGenerator.py b/qt_ui/windows/mission/flight/generator/QSTRIKEMissionGenerator.py index 7d7477d3..ea948814 100644 --- a/qt_ui/windows/mission/flight/generator/QSTRIKEMissionGenerator.py +++ b/qt_ui/windows/mission/flight/generator/QSTRIKEMissionGenerator.py @@ -1,10 +1,11 @@ from PySide2.QtGui import Qt -from PySide2.QtWidgets import QLabel, QHBoxLayout, QVBoxLayout +from PySide2.QtWidgets import QLabel, QHBoxLayout, QVBoxLayout, QGroupBox from game import Game from gen.flights.ai_flight_planner import meter_to_nm from gen.flights.flight import Flight from qt_ui.widgets.combos.QStrikeTargetSelectionComboBox import QStrikeTargetSelectionComboBox +from qt_ui.widgets.views.QStrikeTargetInfoView import QStrikeTargetInfoView from qt_ui.windows.mission.flight.generator.QAbstractMissionGenerator import QAbstractMissionGenerator @@ -17,13 +18,16 @@ class QSTRIKEMissionGenerator(QAbstractMissionGenerator): self.tgt_selection_box.setMinimumWidth(200) self.tgt_selection_box.currentTextChanged.connect(self.on_selected_target_changed) + self.distanceToTargetLabel = QLabel("0 nm") + self.strike_infos = QStrikeTargetInfoView(None) self.init_ui() self.on_selected_target_changed() def on_selected_target_changed(self): target = self.tgt_selection_box.get_selected_target() self.distanceToTargetLabel.setText("~" + str(meter_to_nm(self.flight.from_cp.position.distance_to_point(target.location.position))) + " nm") + self.strike_infos.setTarget(target) def init_ui(self): layout = QVBoxLayout() @@ -33,13 +37,16 @@ class QSTRIKEMissionGenerator(QAbstractMissionGenerator): wpt_layout.addStretch() wpt_layout.addWidget(self.tgt_selection_box, alignment=Qt.AlignRight) + distToTargetBox = QGroupBox("Infos :") distToTarget = QHBoxLayout() distToTarget.addWidget(QLabel("Distance to target : ")) distToTarget.addStretch() distToTarget.addWidget(self.distanceToTargetLabel, alignment=Qt.AlignRight) + distToTargetBox.setLayout(distToTarget) layout.addLayout(wpt_layout) - layout.addLayout(distToTarget) + layout.addWidget(self.strike_infos) + layout.addWidget(distToTargetBox) layout.addStretch() layout.addWidget(self.ok_button) @@ -47,10 +54,10 @@ class QSTRIKEMissionGenerator(QAbstractMissionGenerator): def apply(self): self.flight.points = [] - # target = self.tgt_selection_box.get_selected_target() - # self.planner.generate_sead(self.flight, target.location, target.radars) - # self.flight_waypoint_list.update_list() - # self.close() + target = self.tgt_selection_box.get_selected_target() + self.planner.generate_strike(self.flight, target.location) + self.flight_waypoint_list.update_list() + self.close() diff --git a/qt_ui/windows/mission/flight/payload/QLoadoutEditor.py b/qt_ui/windows/mission/flight/payload/QLoadoutEditor.py index 80eee78b..4dac3bed 100644 --- a/qt_ui/windows/mission/flight/payload/QLoadoutEditor.py +++ b/qt_ui/windows/mission/flight/payload/QLoadoutEditor.py @@ -16,7 +16,8 @@ class QLoadoutEditor(QGroupBox): self.toggled.connect(self.on_toggle) - layout = QGridLayout() + hboxLayout = QVBoxLayout(self) + layout = QGridLayout(self) pylons = [v for v in self.flight.unit_type.__dict__.values() if inspect.isclass(v) and v.__name__.startswith("Pylon")] for i, pylon in enumerate(pylons): @@ -25,7 +26,9 @@ class QLoadoutEditor(QGroupBox): layout.addWidget(label, i, 0) layout.addWidget(QPylonEditor(flight, pylon, i+1), i, 1) - self.setLayout(layout) + hboxLayout.addLayout(layout) + hboxLayout.addStretch() + self.setLayout(hboxLayout) def on_toggle(self): self.flight.use_custom_loadout = self.isChecked() diff --git a/qt_ui/windows/mission/flight/waypoints/QFlightWaypointList.py b/qt_ui/windows/mission/flight/waypoints/QFlightWaypointList.py index c3521f33..6efdfe79 100644 --- a/qt_ui/windows/mission/flight/waypoints/QFlightWaypointList.py +++ b/qt_ui/windows/mission/flight/waypoints/QFlightWaypointList.py @@ -1,17 +1,19 @@ -from PySide2.QtCore import QItemSelectionModel, QPoint +from PySide2.QtCore import QItemSelectionModel, QPoint, Qt from PySide2.QtGui import QStandardItemModel -from PySide2.QtWidgets import QListView +from PySide2.QtWidgets import QListView, QTableView, QHeaderView from gen.flights.flight import Flight, FlightWaypoint from qt_ui.windows.mission.flight.waypoints.QFlightWaypointItem import QWaypointItem -class QFlightWaypointList(QListView): +class QFlightWaypointList(QTableView): def __init__(self, flight: Flight): super(QFlightWaypointList, self).__init__() self.model = QStandardItemModel(self) self.setModel(self.model) + self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) + self.model.setHorizontalHeaderLabels(["Name"]) self.flight = flight if len(self.flight.points) > 0: