New mission briefing menu, work in progress.
41
game/db.py
@ -30,9 +30,11 @@ from game.factions.russia_1965 import Russia_1965
|
||||
from game.factions.russia_1990 import Russia_1990
|
||||
from game.factions.russia_2010 import Russia_2010
|
||||
from game.factions.spain_1990 import Spain_1990
|
||||
from game.factions.sweden_1990 import Sweden_1990
|
||||
from game.factions.turkey_2005 import Turkey_2005
|
||||
from game.factions.uae_2005 import UAE_2005
|
||||
from game.factions.uk_1990 import UnitedKingdom_1990
|
||||
from game.factions.ukraine_2010 import Ukraine_2010
|
||||
from game.factions.usa_1944 import USA_1944
|
||||
from game.factions.usa_1955 import USA_1955
|
||||
from game.factions.usa_1960 import USA_1960
|
||||
@ -162,23 +164,26 @@ PRICES = {
|
||||
Armor.IFV_BMD_1: 8,
|
||||
Armor.IFV_BMP_1: 14,
|
||||
Armor.IFV_BMP_2: 16,
|
||||
Armor.IFV_BMP_3: 20,
|
||||
Armor.IFV_BMP_3: 18,
|
||||
Armor.ZBD_04A: 12,
|
||||
|
||||
Armor.APC_Cobra: 4,
|
||||
Armor.APC_M113: 6,
|
||||
Armor.APC_M1043_HMMWV_Armament: 2,
|
||||
Armor.ATGM_M1045_HMMWV_TOW: 8,
|
||||
Armor.IFV_M2A2_Bradley: 12,
|
||||
Armor.APC_M1126_Stryker_ICV: 16,
|
||||
Armor.ATGM_M1134_Stryker: 18,
|
||||
Armor.APC_M1126_Stryker_ICV: 10,
|
||||
Armor.ATGM_M1134_Stryker: 12,
|
||||
Armor.MBT_M60A3_Patton: 18,
|
||||
Armor.MBT_M1A2_Abrams: 35,
|
||||
Armor.MBT_Leclerc: 35,
|
||||
Armor.MBT_Leopard_1A3: 24,
|
||||
Armor.MBT_Leopard_2: 35,
|
||||
Armor.MBT_Merkava_Mk__4: 35,
|
||||
Armor.TPz_Fuchs: 8,
|
||||
Armor.TPz_Fuchs: 5,
|
||||
Armor.MBT_Challenger_II: 30,
|
||||
Armor.IFV_Marder: 10,
|
||||
Armor.IFV_MCV_80: 10,
|
||||
|
||||
Unarmed.Transport_UAZ_469: 3,
|
||||
Unarmed.Transport_Ural_375: 3,
|
||||
@ -336,9 +341,24 @@ UNIT_BY_TASK = {
|
||||
Armor.ARV_BRDM_2,
|
||||
Armor.ARV_BRDM_2,
|
||||
Armor.ARV_BTR_RD,
|
||||
Armor.ARV_BTR_RD,
|
||||
Armor.ARV_BTR_RD,
|
||||
Armor.ARV_BTR_RD,
|
||||
Armor.APC_BTR_80,
|
||||
Armor.APC_BTR_80,
|
||||
Armor.APC_BTR_80,
|
||||
Armor.APC_BTR_80,
|
||||
Armor.APC_BTR_80,
|
||||
Armor.IFV_BMP_1,
|
||||
Armor.IFV_BMP_1,
|
||||
Armor.IFV_BMP_1,
|
||||
Armor.IFV_BMP_2,
|
||||
Armor.IFV_BMP_2,
|
||||
Armor.IFV_BMP_3,
|
||||
Armor.IFV_BMP_3,
|
||||
Armor.ZBD_04A,
|
||||
Armor.ZBD_04A,
|
||||
Armor.ZBD_04A,
|
||||
Armor.MBT_T_55,
|
||||
Armor.MBT_T_55,
|
||||
Armor.MBT_T_55,
|
||||
@ -368,6 +388,16 @@ UNIT_BY_TASK = {
|
||||
Armor.IFV_M2A2_Bradley,
|
||||
Armor.ATGM_M1134_Stryker,
|
||||
Armor.ATGM_M1134_Stryker,
|
||||
Armor.APC_M1126_Stryker_ICV,
|
||||
Armor.APC_M1126_Stryker_ICV,
|
||||
Armor.APC_M1126_Stryker_ICV,
|
||||
Armor.IFV_MCV_80,
|
||||
Armor.IFV_MCV_80,
|
||||
Armor.IFV_MCV_80,
|
||||
Armor.IFV_Marder,
|
||||
Armor.IFV_Marder,
|
||||
Armor.IFV_Marder,
|
||||
Armor.IFV_Marder,
|
||||
Armor.MBT_M60A3_Patton,
|
||||
Armor.MBT_M60A3_Patton,
|
||||
Armor.MBT_M60A3_Patton,
|
||||
@ -531,6 +561,8 @@ FACTIONS = {
|
||||
"United Kingdown 1990": UnitedKingdom_1990,
|
||||
"Spain 1990": Spain_1990,
|
||||
"Italy 1990": Italy_1990,
|
||||
"Sweden 1990": Sweden_1990,
|
||||
"Ukrain 2010": Ukraine_2010,
|
||||
"India 2010": India_2010,
|
||||
"Israel 2000": Israel_2000,
|
||||
"Turkey 2005": Turkey_2005,
|
||||
@ -899,7 +931,6 @@ class DefaultLiveries:
|
||||
class Default(Enum):
|
||||
af_standard = ""
|
||||
|
||||
# TODO : refactor/remove
|
||||
OH_58D.Liveries = DefaultLiveries
|
||||
F_16C_50.Liveries = DefaultLiveries
|
||||
P_51D_30_NA.Liveries = DefaultLiveries
|
||||
@ -23,6 +23,7 @@ Germany_1990 = {
|
||||
Armor.TPz_Fuchs,
|
||||
Armor.MBT_Leopard_1A3,
|
||||
Armor.MBT_Leopard_2,
|
||||
Armor.IFV_Marder,
|
||||
|
||||
Unarmed.Transport_M818,
|
||||
Infantry.Infantry_M4,
|
||||
|
||||
@ -20,7 +20,7 @@ Israel_2000 = {
|
||||
AH_64D,
|
||||
|
||||
Armor.MBT_Merkava_Mk__4,
|
||||
Armor.APC_M113, # Standing as VAB
|
||||
Armor.APC_M113,
|
||||
|
||||
Unarmed.Transport_M818,
|
||||
Infantry.Infantry_M4,
|
||||
|
||||
31
game/factions/sweden_1990.py
Normal file
@ -0,0 +1,31 @@
|
||||
from dcs.vehicles import *
|
||||
from dcs.ships import *
|
||||
from dcs.planes import *
|
||||
from dcs.helicopters import *
|
||||
|
||||
Sweden_1990 = {
|
||||
"country": "Sweden",
|
||||
"side": "blue",
|
||||
"units": [
|
||||
AJS37,
|
||||
|
||||
UH_1H,
|
||||
|
||||
AirDefence.SAM_Hawk_LN_M192,
|
||||
|
||||
Armor.IFV_MCV_80, # Standing as Strf 90
|
||||
Armor.MBT_Leopard_2,
|
||||
Armor.APC_M1126_Stryker_ICV, # Closest thing available
|
||||
|
||||
Unarmed.Transport_Ural_375,
|
||||
Unarmed.Transport_UAZ_469,
|
||||
Infantry.Soldier_AK,
|
||||
CV_1143_5_Admiral_Kuznetsov,
|
||||
Bulk_cargo_ship_Yakushev,
|
||||
Dry_cargo_ship_Ivanov,
|
||||
Tanker_Elnya_160,
|
||||
],
|
||||
"shorad":[
|
||||
AirDefence.SAM_Avenger_M1097
|
||||
]
|
||||
}
|
||||
@ -20,7 +20,7 @@ UnitedKingdom_1990 = {
|
||||
AH_64A,
|
||||
|
||||
Armor.MBT_Challenger_II,
|
||||
Armor.IFV_M2A2_Bradley, # Standing as Warrior IFV
|
||||
Armor.IFV_MCV_80,
|
||||
|
||||
Unarmed.Transport_M818,
|
||||
Infantry.Infantry_M4,
|
||||
|
||||
51
game/factions/ukraine_2010.py
Normal file
@ -0,0 +1,51 @@
|
||||
from dcs.vehicles import *
|
||||
from dcs.ships import *
|
||||
from dcs.planes import *
|
||||
from dcs.helicopters import *
|
||||
|
||||
Ukraine_2010 = {
|
||||
"country": "Ukraine",
|
||||
"side": "blue",
|
||||
"units": [
|
||||
Su_25,
|
||||
Su_25T,
|
||||
Su_24M,
|
||||
Su_27,
|
||||
MiG_29S,
|
||||
L_39ZA,
|
||||
|
||||
IL_76MD,
|
||||
IL_78M,
|
||||
An_26B,
|
||||
An_30M,
|
||||
Yak_40,
|
||||
A_50,
|
||||
|
||||
Mi_8MT,
|
||||
Mi_24V,
|
||||
|
||||
AirDefence.SAM_SA_3_S_125_LN_5P73,
|
||||
AirDefence.SAM_SA_11_Buk_LN_9A310M1,
|
||||
AirDefence.SAM_SA_10_S_300PS_LN_5P85C,
|
||||
|
||||
Armor.APC_M1043_HMMWV_Armament,
|
||||
Armor.IFV_BMP_3,
|
||||
Armor.IFV_BMP_2,
|
||||
Armor.APC_BTR_80,
|
||||
Armor.MBT_T_80U,
|
||||
Armor.MBT_T_72B,
|
||||
|
||||
Unarmed.Transport_Ural_375,
|
||||
Unarmed.Transport_UAZ_469,
|
||||
Infantry.Soldier_AK,
|
||||
CV_1143_5_Admiral_Kuznetsov,
|
||||
Bulk_cargo_ship_Yakushev,
|
||||
Dry_cargo_ship_Ivanov,
|
||||
Tanker_Elnya_160,
|
||||
],
|
||||
"shorad":[
|
||||
AirDefence.SAM_SA_19_Tunguska_2S6,
|
||||
AirDefence.SAM_SA_13_Strela_10M3_9A35M3,
|
||||
AirDefence.AAA_ZU_23_on_Ural_375
|
||||
]
|
||||
}
|
||||
@ -29,6 +29,8 @@ if __name__ == "__main__":
|
||||
app = QApplication(sys.argv)
|
||||
uiconstants.load_icons()
|
||||
uiconstants.load_event_icons()
|
||||
uiconstants.load_aircraft_icons()
|
||||
uiconstants.load_vehicle_icons()
|
||||
|
||||
# Splash screen setup
|
||||
pixmap = QPixmap("./resources/ui/splash_screen.png")
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
# URL for UI links
|
||||
import os
|
||||
from typing import Dict
|
||||
|
||||
from PySide2.QtGui import QColor, QFont, QPixmap
|
||||
@ -38,7 +39,8 @@ CP_SIZE = 25
|
||||
FONT = QFont("Arial", 12, weight=5, italic=True)
|
||||
|
||||
|
||||
|
||||
AIRCRAFT_ICONS: Dict[str, QPixmap] = {}
|
||||
VEHICLES_ICONS: Dict[str, QPixmap] = {}
|
||||
ICONS: Dict[str, QPixmap] = {}
|
||||
|
||||
def load_icons():
|
||||
@ -93,4 +95,22 @@ def load_event_icons():
|
||||
NavalInterceptEvent: "naval_intercept",
|
||||
StrikeEvent: "strike",
|
||||
UnitsDeliveryEvent: "delivery"}.items():
|
||||
EVENT_ICONS[category] = QPixmap("./resources/ui/events/" + image + ".png")
|
||||
EVENT_ICONS[category] = QPixmap("./resources/ui/events/" + image + ".png")
|
||||
|
||||
|
||||
def load_aircraft_icons():
|
||||
for aircraft in os.listdir("./resources/ui/units/aircrafts/"):
|
||||
print(aircraft)
|
||||
if aircraft.endswith(".jpg"):
|
||||
print(aircraft[:-7] + " : " + os.path.join("./resources/ui/units/aircrafts/", aircraft) + " ")
|
||||
AIRCRAFT_ICONS[aircraft[:-7]] = QPixmap(os.path.join("./resources/ui/units/aircrafts/", aircraft))
|
||||
AIRCRAFT_ICONS["F-16C_50"] = AIRCRAFT_ICONS["F-16C"]
|
||||
AIRCRAFT_ICONS["FA-18C_hornet"] = AIRCRAFT_ICONS["FA-18C"]
|
||||
|
||||
|
||||
def load_vehicle_icons():
|
||||
for vehicle in os.listdir("./resources/ui/units/vehicles/"):
|
||||
print(vehicle)
|
||||
if vehicle.endswith(".jpg"):
|
||||
print(vehicle[:-7] + " : " + os.path.join("./resources/ui/units/vehicles/", vehicle) + " ")
|
||||
VEHICLES_ICONS[vehicle[:-7]] = QPixmap(os.path.join("./resources/ui/units/vehicles/", vehicle))
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from PySide2.QtWidgets import QFrame, QHBoxLayout, QPushButton, QVBoxLayout, QMessageBox
|
||||
from PySide2.QtWidgets import QFrame, QHBoxLayout, QPushButton, QVBoxLayout, QMessageBox, QGridLayout
|
||||
|
||||
from game import Game
|
||||
from qt_ui.widgets.QBudgetBox import QBudgetBox
|
||||
@ -7,6 +7,7 @@ from qt_ui.widgets.QTurnCounter import QTurnCounter
|
||||
|
||||
import qt_ui.uiconstants as CONST
|
||||
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
|
||||
from qt_ui.windows.mission.QMissionPlanning import QMissionPlanning
|
||||
from qt_ui.windows.settings.QSettingsWindow import QSettingsWindow
|
||||
|
||||
|
||||
@ -23,11 +24,17 @@ class QTopPanel(QFrame):
|
||||
self.turnCounter = QTurnCounter()
|
||||
self.budgetBox = QBudgetBox()
|
||||
|
||||
|
||||
self.passTurnButton = QPushButton("Pass Turn")
|
||||
self.passTurnButton.setIcon(CONST.ICONS["PassTurn"])
|
||||
self.passTurnButton.setProperty("style", "btn-primary")
|
||||
self.passTurnButton.clicked.connect(self.passTurn)
|
||||
|
||||
self.proceedButton = QPushButton("Proceed")
|
||||
self.proceedButton.setIcon(CONST.ICONS["PassTurn"])
|
||||
self.proceedButton.setProperty("style", "btn-primary")
|
||||
self.proceedButton.clicked.connect(self.proceed)
|
||||
|
||||
self.submenus = QVBoxLayout()
|
||||
self.settings = QPushButton("Settings")
|
||||
self.settings.setIcon(CONST.ICONS["Settings"])
|
||||
@ -48,6 +55,7 @@ class QTopPanel(QFrame):
|
||||
self.layout.addWidget(self.turnCounter)
|
||||
self.layout.addWidget(self.budgetBox)
|
||||
self.layout.addWidget(self.passTurnButton)
|
||||
self.layout.addWidget(self.proceedButton)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
def setGame(self, game:Game):
|
||||
@ -66,4 +74,8 @@ class QTopPanel(QFrame):
|
||||
|
||||
def passTurn(self):
|
||||
self.game.pass_turn()
|
||||
GameUpdateSignal.get_instance().updateGame(self.game)
|
||||
GameUpdateSignal.get_instance().updateGame(self.game)
|
||||
|
||||
def proceed(self):
|
||||
self.subwindow = QMissionPlanning(self.game)
|
||||
self.subwindow.show()
|
||||
@ -1,5 +1,7 @@
|
||||
from PySide2.QtWidgets import QGridLayout, QLabel, QGroupBox, QVBoxLayout
|
||||
|
||||
from game import db
|
||||
from qt_ui.uiconstants import AIRCRAFT_ICONS, VEHICLES_ICONS
|
||||
from theater import ControlPoint, Airport
|
||||
|
||||
|
||||
@ -26,7 +28,14 @@ class QBaseInformation(QGroupBox):
|
||||
|
||||
i = 0
|
||||
for k,v in unit_dict.items():
|
||||
self.layout.addWidget(QLabel(str(v) + " x " + k), i, 0)
|
||||
icon = QLabel()
|
||||
if k in VEHICLES_ICONS.keys():
|
||||
icon.setPixmap(VEHICLES_ICONS[k])
|
||||
else:
|
||||
icon.setText("<b>"+k[:6]+"</b>")
|
||||
icon.setProperty("style", "icon-plane")
|
||||
self.layout.addWidget(icon, i, 0)
|
||||
self.layout.addWidget(QLabel(str(v) + " x " + k), i, 1)
|
||||
i = i + 1
|
||||
|
||||
stretch = QVBoxLayout()
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
from PySide2.QtWidgets import QGridLayout, QLabel, QGroupBox, QVBoxLayout, QHBoxLayout
|
||||
|
||||
from game import db
|
||||
from gen.flights.ai_flight_planner import FlightPlanner
|
||||
|
||||
|
||||
class QPlannedFlightView(QGroupBox):
|
||||
|
||||
def __init__(self, flight_planner:FlightPlanner):
|
||||
super(QPlannedFlightView, self).__init__("Planned flights")
|
||||
self.flight_planner = flight_planner
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
self.layout = QGridLayout()
|
||||
|
||||
for i,f in enumerate(self.flight_planner.flights):
|
||||
ftype = QLabel("<b>" + f.flight_type.name + "</b>")
|
||||
count = QLabel(str(f.count) + " x " + db.unit_type_name(f.unit_type))
|
||||
sched = QLabel(" in " + str(f.scheduled_in) + " minutes")
|
||||
|
||||
self.layout.addWidget(ftype, i, 0)
|
||||
self.layout.addWidget(count, i, 1)
|
||||
self.layout.addWidget(sched, i, 2)
|
||||
|
||||
stretch = QVBoxLayout()
|
||||
stretch.addStretch()
|
||||
self.layout.addLayout(stretch, len(self.flight_planner.flights)+1, 0)
|
||||
self.setLayout(self.layout)
|
||||
@ -83,13 +83,28 @@ class QLiberationMap(QGraphicsView):
|
||||
text.setPos(pos[0] + CONST.CP_SIZE + 1, pos[1] - CONST.CP_SIZE / 2 + 1)
|
||||
|
||||
|
||||
if cp.captured:
|
||||
pen = QPen(brush=CONST.COLORS["blue"])
|
||||
brush = CONST.COLORS["blue_transparent"]
|
||||
|
||||
flight_path_pen = QPen(brush=CONST.COLORS["blue"])
|
||||
flight_path_pen.setColor(CONST.COLORS["blue"])
|
||||
flight_path_pen.setWidth(1)
|
||||
flight_path_pen.setStyle(Qt.DashDotLine)
|
||||
else:
|
||||
pen = QPen(brush=CONST.COLORS["red"])
|
||||
brush = CONST.COLORS["red_transparent"]
|
||||
|
||||
flight_path_pen = QPen(brush=CONST.COLORS["bright_red"])
|
||||
flight_path_pen.setColor(CONST.COLORS["bright_red"])
|
||||
flight_path_pen.setWidth(1)
|
||||
flight_path_pen.setStyle(Qt.DashDotLine)
|
||||
|
||||
for ground_object in cp.ground_objects:
|
||||
|
||||
if ground_object.airbase_group:
|
||||
continue
|
||||
|
||||
go_pos = self._transform_point(ground_object.position)
|
||||
scene.addItem(QMapGroundObject(self, go_pos[0], go_pos[1], 16, 16, cp, ground_object))
|
||||
if not ground_object.airbase_group:
|
||||
scene.addItem(QMapGroundObject(self, go_pos[0], go_pos[1], 16, 16, cp, ground_object))
|
||||
|
||||
if ground_object.category == "aa" and self.get_display_rule("sam"):
|
||||
max_range = 0
|
||||
@ -99,17 +114,24 @@ class QLiberationMap(QGraphicsView):
|
||||
unit = db.unit_type_from_name(u.type)
|
||||
if unit.threat_range > max_range:
|
||||
max_range = unit.threat_range
|
||||
if cp.captured:
|
||||
pen = QPen(brush=CONST.COLORS["blue"])
|
||||
brush = CONST.COLORS["blue_transparent"]
|
||||
else:
|
||||
pen = QPen(brush=CONST.COLORS["red"])
|
||||
brush = CONST.COLORS["red_transparent"]
|
||||
|
||||
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)
|
||||
|
||||
if self.get_display_rule("lines"):
|
||||
self.scene_create_lines_for_cp(cp)
|
||||
|
||||
if cp.id in self.game.planners.keys():
|
||||
planner = self.game.planners[cp.id]
|
||||
for flight in planner.flights:
|
||||
scene.addEllipse(pos[0], pos[1], 4, 4)
|
||||
prev_pos = list(pos)
|
||||
for points in flight.points:
|
||||
new_pos = self._transform_point(Point(points[0], points[1]))
|
||||
scene.addLine(prev_pos[0]+2, prev_pos[1]+2, new_pos[0]+2, new_pos[1]+2, flight_path_pen)
|
||||
scene.addEllipse(new_pos[0], new_pos[1], 4, 4, pen, brush)
|
||||
prev_pos = list(new_pos)
|
||||
scene.addLine(prev_pos[0] + 2, prev_pos[1] + 2, pos[0] + 2, pos[1] + 2, flight_path_pen)
|
||||
|
||||
def scene_create_lines_for_cp(self, cp: ControlPoint):
|
||||
scene = self.scene()
|
||||
pos = self._transform_point(cp.position)
|
||||
|
||||
@ -7,9 +7,10 @@ from PySide2.QtWidgets import QHBoxLayout, QLabel, QWidget, QDialog, QVBoxLayout
|
||||
from dcs.unittype import UnitType
|
||||
|
||||
from game.event import UnitsDeliveryEvent
|
||||
from qt_ui.widgets.QBudgetBox import QBudgetBox
|
||||
from qt_ui.widgets.base.QAirportInformation import QAirportInformation
|
||||
from qt_ui.widgets.base.QBaseInformation import QBaseInformation
|
||||
from qt_ui.widgets.base.QPlannedFlightView import QPlannedFlightView
|
||||
from qt_ui.windows.mission.QPlannedFlightsView import QPlannedFlightsView
|
||||
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
|
||||
from theater import ControlPoint, CAP, Embarking, CAS, PinpointStrike, db
|
||||
from game import Game
|
||||
@ -90,6 +91,9 @@ class QBaseMenu(QDialog):
|
||||
|
||||
self.recruitment = QGroupBox("Recruitment")
|
||||
self.recruitmentLayout = QVBoxLayout()
|
||||
self.budget = QBudgetBox()
|
||||
self.budget.setBudget(self.game.budget, self.game.budget_reward_amount)
|
||||
self.recruitmentLayout.addWidget(self.budget)
|
||||
|
||||
for task_type in units.keys():
|
||||
|
||||
@ -147,7 +151,7 @@ class QBaseMenu(QDialog):
|
||||
|
||||
self.rightLayout = QVBoxLayout()
|
||||
try:
|
||||
self.rightLayout.addWidget(QPlannedFlightView(self.game.planners[self.cp.id]))
|
||||
self.rightLayout.addWidget(QPlannedFlightsView(self.game.planners[self.cp.id]))
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
self.rightLayout.addWidget(QAirportInformation(self.cp, self.airport))
|
||||
@ -212,7 +216,7 @@ class QBaseMenu(QDialog):
|
||||
if self.game.budget >= price:
|
||||
self.deliveryEvent.deliver({unit_type: 1})
|
||||
self.game.budget -= price
|
||||
|
||||
self.budget.setBudget(self.game.budget, self.game.budget_reward_amount)
|
||||
self._update_count_label(unit_type)
|
||||
|
||||
def sell(self, unit_type):
|
||||
|
||||
34
qt_ui/windows/mission/QChooseAirbase.py
Normal file
@ -0,0 +1,34 @@
|
||||
from PySide2.QtCore import Signal
|
||||
from PySide2.QtWidgets import QGroupBox, QHBoxLayout, QComboBox, QLabel
|
||||
|
||||
from game import Game
|
||||
|
||||
|
||||
class QChooseAirbase(QGroupBox):
|
||||
|
||||
selected_airbase_changed = Signal(str)
|
||||
|
||||
def __init__(self, game:Game, title=""):
|
||||
super(QChooseAirbase, self).__init__(title)
|
||||
self.game = game
|
||||
|
||||
self.layout = QHBoxLayout()
|
||||
self.depart_from_label = QLabel("Airbase : ")
|
||||
self.depart_from = QComboBox()
|
||||
|
||||
for i, cp in enumerate([b for b in self.game.theater.controlpoints if b.captured]):
|
||||
self.depart_from.addItem(str(cp.name), cp)
|
||||
self.depart_from.setCurrentIndex(0)
|
||||
self.depart_from.currentTextChanged.connect(self._on_airbase_selected)
|
||||
self.layout.addWidget(self.depart_from_label)
|
||||
self.layout.addWidget(self.depart_from)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
def _on_airbase_selected(self):
|
||||
selected = self.depart_from.currentText()
|
||||
print("Airbase changed to : " + selected)
|
||||
self.selected_airbase_changed.emit(selected)
|
||||
print("Airbase changed to : " + selected)
|
||||
|
||||
|
||||
|
||||
20
qt_ui/windows/mission/QFlightItem.py
Normal file
@ -0,0 +1,20 @@
|
||||
from PySide2.QtGui import QStandardItem, QIcon
|
||||
|
||||
from game import db
|
||||
from gen.flights.flight import Flight
|
||||
from qt_ui.uiconstants import AIRCRAFT_ICONS
|
||||
|
||||
|
||||
class QFlightItem(QStandardItem):
|
||||
|
||||
def __init__(self, flight:Flight):
|
||||
super(QFlightItem, self).__init__()
|
||||
self.flight = flight
|
||||
|
||||
if db.unit_type_name(self.flight.unit_type).replace("/", " ") in AIRCRAFT_ICONS.keys():
|
||||
icon = QIcon((AIRCRAFT_ICONS[db.unit_type_name(self.flight.unit_type)]))
|
||||
self.setIcon(icon)
|
||||
self.setEditable(False)
|
||||
self.setText("["+str(self.flight.flight_type.name[:6])+"] "
|
||||
+ str(self.flight.count) + " x " + db.unit_type_name(self.flight.unit_type)
|
||||
+ " in " + str(self.flight.scheduled_in) + " minutes")
|
||||
63
qt_ui/windows/mission/QMissionPlanning.py
Normal file
@ -0,0 +1,63 @@
|
||||
from PySide2.QtCore import Qt, Slot, QItemSelectionModel, QPoint
|
||||
from PySide2.QtWidgets import QDialog, QGridLayout, QScrollArea, QVBoxLayout
|
||||
from game import Game
|
||||
from qt_ui.windows.mission.QPlannedFlightsView import QPlannedFlightsView
|
||||
from qt_ui.windows.mission.QChooseAirbase import QChooseAirbase
|
||||
from qt_ui.windows.mission.flight.QFlightPlanner import QFlightPlanner
|
||||
|
||||
|
||||
class QMissionPlanning(QDialog):
|
||||
|
||||
def __init__(self, game: Game):
|
||||
super(QMissionPlanning, self).__init__()
|
||||
self.game = game
|
||||
self.setWindowFlags(Qt.WindowStaysOnTopHint)
|
||||
self.setMinimumSize(750, 350)
|
||||
self.setModal(True)
|
||||
self.setWindowTitle("Mission Preparation")
|
||||
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)
|
||||
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.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)
|
||||
|
||||
self.flight_planner = QFlightPlanner(self.planned_flight_view.flight_planner.flights[0], self.game)
|
||||
|
||||
|
||||
self.left_bar_layout.addWidget(self.select_airbase)
|
||||
self.left_bar_layout.addWidget(self.planned_flight_view)
|
||||
|
||||
self.layout.addLayout(self.left_bar_layout, 0, 0)
|
||||
self.layout.addWidget(self.flight_planner, 0, 1)
|
||||
|
||||
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]
|
||||
if len(cps) == 1:
|
||||
self.planner = self.game.planners[cps[0].id]
|
||||
self.planned_flight_view.set_flight_planner(self.planner)
|
||||
else:
|
||||
self.planned_flight_view.set_flight_planner(None)
|
||||
|
||||
def on_flight_selection_change(self):
|
||||
index = self.planned_flight_view.selectionModel().currentIndex().row()
|
||||
flight = self.planner.flights[index]
|
||||
|
||||
self.flight_planner = QFlightPlanner(flight, self.game)
|
||||
self.layout.addWidget(self.flight_planner,0 ,1)
|
||||
30
qt_ui/windows/mission/QPlannedFlightsView.py
Normal file
@ -0,0 +1,30 @@
|
||||
from PySide2.QtCore import QSize
|
||||
from PySide2.QtGui import QStandardItemModel
|
||||
from PySide2.QtWidgets import QListView
|
||||
|
||||
from gen.flights.ai_flight_planner import FlightPlanner
|
||||
from qt_ui.windows.mission.QFlightItem import QFlightItem
|
||||
|
||||
|
||||
class QPlannedFlightsView(QListView):
|
||||
|
||||
def __init__(self, flight_planner: FlightPlanner):
|
||||
super(QPlannedFlightsView, self).__init__()
|
||||
self.model = QStandardItemModel(self)
|
||||
self.setModel(self.model)
|
||||
self.setIconSize(QSize(91, 24))
|
||||
if flight_planner:
|
||||
self.set_flight_planner(flight_planner)
|
||||
|
||||
def update_content(self):
|
||||
for i, f in enumerate(self.flight_planner.flights):
|
||||
self.model.appendRow(QFlightItem(f))
|
||||
|
||||
def clear_layout(self):
|
||||
self.model.removeRows(0, self.model.rowCount())
|
||||
|
||||
def set_flight_planner(self, flight_planner: FlightPlanner):
|
||||
self.clear_layout()
|
||||
self.flight_planner = flight_planner
|
||||
if self.flight_planner:
|
||||
self.update_content()
|
||||
19
qt_ui/windows/mission/flight/QFlightPlanner.py
Normal file
@ -0,0 +1,19 @@
|
||||
from PySide2.QtWidgets import QTabWidget
|
||||
|
||||
from gen.flights.flight import Flight
|
||||
from game import Game
|
||||
from qt_ui.windows.mission.flight.payload.QFlightPayloadTab import QFlightPayloadTab
|
||||
from qt_ui.windows.mission.flight.settings.QGeneralFlightSettingsTab import QGeneralFlightSettingsTab
|
||||
from qt_ui.windows.mission.flight.waypoints.QFlightWaypointTab import QFlightWaypointTab
|
||||
|
||||
|
||||
class QFlightPlanner(QTabWidget):
|
||||
|
||||
def __init__(self, flight: Flight, game: Game):
|
||||
super(QFlightPlanner, self).__init__()
|
||||
self.general_settings_tab = QGeneralFlightSettingsTab(flight, game)
|
||||
self.payload_tab = QFlightPayloadTab(flight)
|
||||
self.waypoint_tab = QFlightWaypointTab(flight)
|
||||
self.addTab(self.general_settings_tab, "General Flight settings")
|
||||
self.addTab(self.payload_tab, "Payload")
|
||||
self.addTab(self.waypoint_tab, "Waypoints")
|
||||
16
qt_ui/windows/mission/flight/payload/QFlightPayloadTab.py
Normal file
@ -0,0 +1,16 @@
|
||||
from PySide2.QtWidgets import QFrame, QGridLayout, QLabel
|
||||
|
||||
from gen.flights.flight import Flight
|
||||
|
||||
|
||||
class QFlightPayloadTab(QFrame):
|
||||
|
||||
def __init__(self, flight: Flight):
|
||||
super(QFlightPayloadTab, self).__init__()
|
||||
self.flight = flight
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
layout = QGridLayout()
|
||||
layout.addWidget(QLabel("Coming in two weeks"))
|
||||
self.setLayout(layout)
|
||||
@ -0,0 +1,28 @@
|
||||
from PySide2.QtWidgets import QLabel, QHBoxLayout, QGroupBox, QSpinBox
|
||||
|
||||
|
||||
class QFlightDepartureEditor(QGroupBox):
|
||||
|
||||
def __init__(self, flight):
|
||||
super(QFlightDepartureEditor, self).__init__("Departure")
|
||||
self.flight = flight
|
||||
|
||||
layout = QHBoxLayout()
|
||||
self.depart_from = QLabel("Departing from <b>" + self.flight.from_cp.name + "</b>")
|
||||
self.depart_at_t = QLabel("At T +")
|
||||
self.minutes = QLabel(" minutes")
|
||||
|
||||
self.departure_delta = QSpinBox(self)
|
||||
self.departure_delta.setMinimum(0)
|
||||
self.departure_delta.setMaximum(120)
|
||||
self.departure_delta.setValue(self.flight.scheduled_in)
|
||||
self.departure_delta.valueChanged.connect(self.change_scheduled)
|
||||
|
||||
layout.addWidget(self.depart_from)
|
||||
layout.addWidget(self.depart_at_t)
|
||||
layout.addWidget(self.departure_delta)
|
||||
layout.addWidget(self.minutes)
|
||||
self.setLayout(layout)
|
||||
|
||||
def change_scheduled(self):
|
||||
self.flight.scheduled_in = int(self.departure_delta.value())
|
||||
50
qt_ui/windows/mission/flight/settings/QFlightSlotEditor.py
Normal file
@ -0,0 +1,50 @@
|
||||
from PySide2.QtWidgets import QLabel, QHBoxLayout, QGroupBox, QSpinBox, QGridLayout
|
||||
|
||||
|
||||
class QFlightSlotEditor(QGroupBox):
|
||||
|
||||
def __init__(self, flight, game):
|
||||
super(QFlightSlotEditor, self).__init__("Slots")
|
||||
self.flight = flight
|
||||
self.game = game
|
||||
|
||||
layout = QGridLayout()
|
||||
|
||||
self.aircraft_count = QLabel("Aircraft count :")
|
||||
self.aircraft_count_spinner = QSpinBox()
|
||||
self.aircraft_count_spinner.setMinimum(1)
|
||||
self.aircraft_count_spinner.setMaximum(4)
|
||||
self.aircraft_count_spinner.setValue(flight.count)
|
||||
self.aircraft_count_spinner.valueChanged.connect(self._changed_aircraft_count)
|
||||
|
||||
self.client_count = QLabel("Client slots count :")
|
||||
self.client_count_spinner = QSpinBox()
|
||||
self.client_count_spinner.setMinimum(0)
|
||||
self.client_count_spinner.setMaximum(4)
|
||||
self.client_count_spinner.setValue(flight.client_count)
|
||||
self.client_count_spinner.valueChanged.connect(self._changed_client_count)
|
||||
|
||||
if not self.flight.unit_type.flyable:
|
||||
self.client_count_spinner.setValue(0)
|
||||
self.client_count_spinner.setEnabled(False)
|
||||
|
||||
layout.addWidget(self.aircraft_count, 0, 0)
|
||||
layout.addWidget(self.aircraft_count_spinner, 0, 1)
|
||||
|
||||
layout.addWidget(self.client_count, 1, 0)
|
||||
layout.addWidget(self.client_count_spinner, 1, 1)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
def _changed_aircraft_count(self):
|
||||
self.flight.count = int(self.aircraft_count_spinner.value())
|
||||
# TODO check if enough aircraft are available
|
||||
|
||||
def _changed_client_count(self):
|
||||
self.flight.client_count = int(self.client_count_spinner.value())
|
||||
self._cap_client_count()
|
||||
|
||||
def _cap_client_count(self):
|
||||
if self.flight.client_count > self.flight.count:
|
||||
self.flight.client_count = self.flight.count
|
||||
self.client_count_spinner.setValue(self.flight.client_count)
|
||||
28
qt_ui/windows/mission/flight/settings/QFlightTypeTaskInfo.py
Normal file
@ -0,0 +1,28 @@
|
||||
from PySide2.QtWidgets import QLabel, QHBoxLayout, QGroupBox, QSpinBox, QGridLayout
|
||||
|
||||
from game import db
|
||||
from qt_ui.uiconstants import AIRCRAFT_ICONS
|
||||
|
||||
|
||||
class QFlightTypeTaskInfo(QGroupBox):
|
||||
|
||||
def __init__(self, flight):
|
||||
super(QFlightTypeTaskInfo, self).__init__("Flight")
|
||||
self.flight = flight
|
||||
|
||||
layout = QGridLayout()
|
||||
|
||||
self.aircraft_icon = QLabel()
|
||||
if db.unit_type_name(self.flight.unit_type) in AIRCRAFT_ICONS:
|
||||
self.aircraft_icon.setPixmap(AIRCRAFT_ICONS[db.unit_type_name(self.flight.unit_type)])
|
||||
|
||||
self.task = QLabel("Task :")
|
||||
self.task_type = QLabel(flight.flight_type.name)
|
||||
self.task_type.setProperty("style", flight.flight_type.name)
|
||||
|
||||
layout.addWidget(self.aircraft_icon, 0, 0)
|
||||
|
||||
layout.addWidget(self.task, 1, 0)
|
||||
layout.addWidget(self.task_type, 1, 1)
|
||||
|
||||
self.setLayout(layout)
|
||||
@ -0,0 +1,29 @@
|
||||
from PySide2.QtWidgets import QFrame, QGridLayout, QVBoxLayout
|
||||
|
||||
from gen.flights.flight import Flight
|
||||
from game import Game
|
||||
from qt_ui.windows.mission.flight.settings.QFlightDepartureEditor import QFlightDepartureEditor
|
||||
from qt_ui.windows.mission.flight.settings.QFlightSlotEditor import QFlightSlotEditor
|
||||
from qt_ui.windows.mission.flight.settings.QFlightTypeTaskInfo import QFlightTypeTaskInfo
|
||||
|
||||
|
||||
class QGeneralFlightSettingsTab(QFrame):
|
||||
|
||||
def __init__(self, flight: Flight, game: Game):
|
||||
super(QGeneralFlightSettingsTab, self).__init__()
|
||||
self.flight = flight
|
||||
self.game = game
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
layout = QGridLayout()
|
||||
self.flight_info = QFlightTypeTaskInfo(self.flight)
|
||||
self.flight_departure = QFlightDepartureEditor(self.flight)
|
||||
self.flight_slots = QFlightSlotEditor(self.flight, self.game)
|
||||
layout.addWidget(self.flight_info, 0, 0)
|
||||
layout.addWidget(self.flight_departure, 1, 0)
|
||||
layout.addWidget(self.flight_slots, 2, 0)
|
||||
vstretch = QVBoxLayout()
|
||||
vstretch.addStretch()
|
||||
layout.addLayout(vstretch, 3, 0)
|
||||
self.setLayout(layout)
|
||||
16
qt_ui/windows/mission/flight/waypoints/QFlightWaypointTab.py
Normal file
@ -0,0 +1,16 @@
|
||||
from PySide2.QtWidgets import QFrame, QGridLayout, QLabel
|
||||
|
||||
from gen.flights.flight import Flight
|
||||
|
||||
|
||||
class QFlightWaypointTab(QFrame):
|
||||
|
||||
def __init__(self, flight: Flight):
|
||||
super(QFlightWaypointTab, self).__init__()
|
||||
self.flight = flight
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
layout = QGridLayout()
|
||||
layout.addWidget(QLabel("Coming in two weeks"))
|
||||
self.setLayout(layout)
|
||||
@ -59,6 +59,48 @@ QLabel[style="base-title"]{
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
QLabel[style="icon-plane"]{
|
||||
background-color:#48719D;
|
||||
min-height:24px;
|
||||
border: 1px solid black;
|
||||
text-align:center;
|
||||
color:white;
|
||||
}
|
||||
|
||||
QLabel[style="bordered"]{
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
QLabel[style="BARCAP"]{
|
||||
border: 1px solid black;
|
||||
background-color: #445299;
|
||||
color:white;
|
||||
}
|
||||
|
||||
QLabel[style="INTERCEPTION"]{
|
||||
border: 1px solid black;
|
||||
background-color: #7752bc;
|
||||
color:white;
|
||||
}
|
||||
|
||||
QLabel[style="CAS"]{
|
||||
border: 1px solid black;
|
||||
background-color: #ab2244;
|
||||
color:white;
|
||||
}
|
||||
|
||||
QLabel[style="DEAD"]{
|
||||
border: 1px solid black;
|
||||
background-color: #cc8844;
|
||||
color:white;
|
||||
}
|
||||
|
||||
QLabel[style="SEAD"]{
|
||||
border: 1px solid black;
|
||||
background-color: #aa7744;
|
||||
color:white;
|
||||
}
|
||||
|
||||
/*QBaseMenu{
|
||||
background-color:#699245;
|
||||
color:white;
|
||||
|
||||
BIN
resources/ui/units/aircrafts/A-10A_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/A-10C_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/A-50_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/AH-1W_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/AH-64A_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/AH-64D_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/AJS37 Viggen_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/AV8BNA_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/An-26B_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/An-30M_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/B-17G_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/B-1B_24.jpg
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
resources/ui/units/aircrafts/B-52H_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/Bf 109 K-4_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/C-101EB CC_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/C-130_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/CH-47D_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/CH-53E_24.jpg
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
resources/ui/units/aircrafts/Christen Eagle II_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/E-2D_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/E-3C_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/F-117A_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/F-14A_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/F-14B_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/F-15C_24.jpg
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
resources/ui/units/aircrafts/F-15E_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/F-16C_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/F-4E_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/F-5E_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/F-86F_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/FA-18C_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/Fw 190 A-8_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/Fw 190 D-9_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/Hawk T.1A_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/I-16_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/IL-76MD_24.jpg
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
resources/ui/units/aircrafts/IL-78M_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/J-11A_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/KC-135_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/KJ-2000_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/Ka-27_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/Ka-50_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/L-39C_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/L-39ZA_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/M-2000C_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/MB-339A PAN_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/MQ RQ-1_24.jpg
Normal file
|
After Width: | Height: | Size: 1017 B |
BIN
resources/ui/units/aircrafts/Mi-24_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/Mi-26_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/Mi-28_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/Mi-8MT_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/MiG-15bis_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/MiG-19P_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/MiG-21Bis_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/MiG-23MLD_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/MiG-25PD_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/MiG-25RBT_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/MiG-27K_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/MiG-29A_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/MiG-29S_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/MiG-31_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/Mirage 2000-5_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/OH-58D_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/P-51D_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/S-3B_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/SA342L_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/SA342M_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/SA342Minigun_24.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/units/aircrafts/SA342Mistral_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/SH-60B_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/Spitfire LF Mk. IX_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/ui/units/aircrafts/Su-17M4_24.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |