diff --git a/qt_ui/uiconstants.py b/qt_ui/uiconstants.py index 98026f3a..1a15c811 100644 --- a/qt_ui/uiconstants.py +++ b/qt_ui/uiconstants.py @@ -82,6 +82,7 @@ def load_icons(): ICONS["New"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/new.png") ICONS["Open"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/open.png") ICONS["Save"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/save.png") + ICONS["Hangar"] = QPixmap("./resources/ui/misc/hangar.png") ICONS["Terrain_Caucasus"] = QPixmap("./resources/ui/terrain_caucasus.gif") ICONS["Terrain_Persian_Gulf"] = QPixmap("./resources/ui/terrain_pg.gif") diff --git a/qt_ui/windows/basemenu/QRecruitBehaviour.py b/qt_ui/windows/basemenu/QRecruitBehaviour.py index a42b00d5..f180dd58 100644 --- a/qt_ui/windows/basemenu/QRecruitBehaviour.py +++ b/qt_ui/windows/basemenu/QRecruitBehaviour.py @@ -1,3 +1,5 @@ +import logging + from PySide2.QtWidgets import QLabel, QPushButton, \ QSizePolicy, QSpacerItem, QGroupBox, QHBoxLayout from dcs.unittype import UnitType @@ -11,11 +13,14 @@ class QRecruitBehaviour: deliveryEvent = None existing_units_labels = None bought_amount_labels = None + maximum_units = -1 + recruitable_types = [] BUDGET_FORMAT = "Available Budget: ${}M" def __init__(self): self.bought_amount_labels = {} self.existing_units_labels = {} + self.recruitable_types = [] self.update_available_budget() def add_purchase_row(self, unit_type, layout, row): @@ -66,7 +71,6 @@ class QRecruitBehaviour: sell.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) sell.clicked.connect(lambda: self.sell(unit_type)) - existLayout.addWidget(unitName) existLayout.addItem(QSpacerItem(20, 0, QSizePolicy.Minimum, QSizePolicy.Minimum)) existLayout.addWidget(existing_units) @@ -102,10 +106,19 @@ class QRecruitBehaviour: def buy(self, unit_type): + if self.maximum_units > 0: + if self.total_units + 1 > self.maximum_units: + logging.info("Not enough space left !") + # TODO : display modal warning + return + price = db.PRICES[unit_type] if self.game.budget >= price: self.deliveryEvent.deliver({unit_type: 1}) self.game.budget -= price + else: + # TODO : display modal warning + logging.info("Not enough money !") self._update_count_label(unit_type) self.update_available_budget() @@ -123,3 +136,34 @@ class QRecruitBehaviour: self._update_count_label(unit_type) self.update_available_budget() + + @property + def total_units(self): + + total = 0 + for unit_type in self.recruitables_types: + total += self.cp.base.total_units(unit_type) + print(unit_type, total, self.cp.base.total_units(unit_type)) + print("--------------------------------") + + if self.deliveryEvent: + for unit_bought in self.deliveryEvent.units: + if db.unit_task(unit_bought) in self.recruitables_types: + total += self.deliveryEvent.units[unit_bought] + print(unit_bought, total, self.deliveryEvent.units[unit_bought]) + + print("=============================") + + return total + + def set_maximum_units(self, maximum_units): + """ + Set the maximum number of units that can be bought + """ + self.maximum_units = maximum_units + + def set_recruitable_types(self, recruitables_types): + """ + Set the maximum number of units that can be bought + """ + self.recruitables_types = recruitables_types \ No newline at end of file diff --git a/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py b/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py index 2d4621d6..a4abf404 100644 --- a/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py +++ b/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py @@ -1,28 +1,35 @@ from PySide2.QtCore import Qt -from PySide2.QtWidgets import QVBoxLayout, QGridLayout, QGroupBox, QScrollArea, QFrame, QWidget +from PySide2.QtWidgets import QVBoxLayout, QGridLayout, QGroupBox, QScrollArea, QFrame, QWidget, QHBoxLayout, QLabel from game.event import UnitsDeliveryEvent +from qt_ui.uiconstants import ICONS from qt_ui.windows.basemenu.QRecruitBehaviour import QRecruitBehaviour -from theater import ControlPoint, CAP, CAS, db +from theater import ControlPoint, CAP, CAS, db, ControlPointType from game import Game class QAircraftRecruitmentMenu(QFrame, QRecruitBehaviour): - def __init__(self, cp:ControlPoint, game:Game): + def __init__(self, cp: ControlPoint, game: Game): QFrame.__init__(self) self.cp = cp self.game = game - self.bought_amount_labels = {} - self.existing_units_labels = {} - for event in self.game.events: if event.__class__ == UnitsDeliveryEvent and event.from_cp == self.cp: self.deliveryEvent = event if not self.deliveryEvent: self.deliveryEvent = self.game.units_delivery_event(self.cp) + # Determine maximum number of aircrafts that can be bought + self.set_maximum_units(self.cp.available_aircraft_slots) + self.set_recruitable_types([CAP, CAS]) + + self.bought_amount_labels = {} + self.existing_units_labels = {} + + self.hangar_status = QHangarStatus(self.total_units, self.cp.available_aircraft_slots) + self.init_ui() def init_ui(self): @@ -57,5 +64,32 @@ class QAircraftRecruitmentMenu(QFrame, QRecruitBehaviour): scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) scroll.setWidgetResizable(True) scroll.setWidget(scroll_content) + main_layout.addLayout(self.hangar_status) main_layout.addWidget(scroll) self.setLayout(main_layout) + + def buy(self, unit_type): + super().buy(unit_type) + self.hangar_status.update_label(self.total_units, self.cp.available_aircraft_slots) + + def sell(self, unit_type): + super().sell(unit_type) + self.hangar_status.update_label(self.total_units, self.cp.available_aircraft_slots) + + +class QHangarStatus(QHBoxLayout): + + def __init__(self, current_amount: int, max_amount: int): + super(QHangarStatus, self).__init__() + self.icon = QLabel() + self.icon.setPixmap(ICONS["Hangar"]) + self.text = QLabel("") + + self.update_label(current_amount, max_amount) + self.addWidget(self.icon, Qt.AlignLeft) + self.addWidget(self.text, Qt.AlignLeft) + self.addStretch(50) + self.setAlignment(Qt.AlignLeft) + + def update_label(self, current_amount: int, max_amount: int): + self.text.setText("{}/{}".format(current_amount, max_amount)) diff --git a/resources/ui/misc/hangar.png b/resources/ui/misc/hangar.png new file mode 100644 index 00000000..dc98f559 Binary files /dev/null and b/resources/ui/misc/hangar.png differ diff --git a/theater/controlpoint.py b/theater/controlpoint.py index d7a726e7..2aba30ca 100644 --- a/theater/controlpoint.py +++ b/theater/controlpoint.py @@ -102,14 +102,23 @@ class ControlPoint: @property def is_carrier(self): + """ + :return: Whether this control point is an aircraft carrier + """ return self.cptype in [ControlPointType.AIRCRAFT_CARRIER_GROUP, ControlPointType.LHA_GROUP] @property def is_fleet(self): + """ + :return: Whether this control point is a boat (mobile) + """ return self.cptype in [ControlPointType.AIRCRAFT_CARRIER_GROUP, ControlPointType.LHA_GROUP] @property def is_lha(self): + """ + :return: Whether this control point is an LHA + """ return self.cptype in [ControlPointType.LHA_GROUP] @property @@ -122,6 +131,20 @@ class ControlPoint: result.append(r) return result + @property + def available_aircraft_slots(self): + """ + :return: The maximum number of aircraft that can be stored in this control point + """ + if self.cptype == ControlPointType.AIRBASE: + return len(self.airport.parking_slots) + elif self.is_lha: + return 20 + elif self.is_carrier: + return 90 + else: + return 0 + def connect(self, to): self.connected_points.append(to) self.stances[to.id] = CombatStance.DEFENSIVE