import logging
from typing import Type, Union
from PySide2.QtWidgets import (
QGroupBox,
QHBoxLayout,
QLabel,
QLayout,
QPushButton,
QSizePolicy,
QSpacerItem,
)
from dcs.unittype import VehicleType
from game.dcs.aircrafttype import AircraftType
from game.theater import ControlPoint
from game.unitdelivery import PendingUnitDeliveries
from qt_ui.models import GameModel
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
from qt_ui.windows.QUnitInfoWindow import QUnitInfoWindow
class QRecruitBehaviour:
game_model: GameModel
cp: ControlPoint
existing_units_labels = None
bought_amount_labels = None
maximum_units = -1
BUDGET_FORMAT = "Available Budget: ${:.2f}M"
def __init__(self) -> None:
self.bought_amount_labels = {}
self.existing_units_labels = {}
self.update_available_budget()
@property
def pending_deliveries(self) -> PendingUnitDeliveries:
return self.cp.pending_unit_deliveries
@property
def budget(self) -> int:
return self.game_model.game.budget
@budget.setter
def budget(self, value: int) -> None:
self.game_model.game.budget = value
def add_purchase_row(
self,
unit_type: Union[AircraftType, Type[VehicleType]],
layout: QLayout,
row: int,
) -> int:
exist = QGroupBox()
exist.setProperty("style", "buy-box")
exist.setMaximumHeight(36)
exist.setMinimumHeight(36)
existLayout = QHBoxLayout()
exist.setLayout(existLayout)
existing_units = self.cp.base.total_units_of_type(unit_type)
scheduled_units = self.pending_deliveries.units.get(unit_type, 0)
unitName = QLabel(f"{self.name_of(unit_type)}")
unitName.setSizePolicy(
QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
)
existing_units = QLabel(str(existing_units))
existing_units.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
amount_bought = QLabel("{}".format(str(scheduled_units)))
amount_bought.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
self.existing_units_labels[unit_type] = existing_units
self.bought_amount_labels[unit_type] = amount_bought
price = QLabel(f"$ {self.price_of(unit_type)} M")
price.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
buysell = QGroupBox()
buysell.setProperty("style", "buy-box")
buysell.setMaximumHeight(36)
buysell.setMinimumHeight(36)
buysellayout = QHBoxLayout()
buysell.setLayout(buysellayout)
buy = QPushButton("+")
buy.setProperty("style", "btn-buy")
buy.setDisabled(not self.enable_purchase(unit_type))
buy.setMinimumSize(16, 16)
buy.setMaximumSize(16, 16)
def on_buy():
self.buy(unit_type)
buy.setDisabled(not self.enable_purchase(unit_type))
sell.setDisabled(not self.enable_sale(unit_type))
buy.clicked.connect(on_buy)
buy.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
sell = QPushButton("-")
sell.setProperty("style", "btn-sell")
sell.setDisabled(not self.enable_sale(unit_type))
sell.setMinimumSize(16, 16)
sell.setMaximumSize(16, 16)
sell.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
def on_sell():
self.sell(unit_type)
sell.setDisabled(not self.enable_sale(unit_type))
buy.setDisabled(not self.enable_purchase(unit_type))
sell.clicked.connect(on_sell)
info = QGroupBox()
info.setProperty("style", "buy-box")
info.setMaximumHeight(36)
info.setMinimumHeight(36)
infolayout = QHBoxLayout()
info.setLayout(infolayout)
unitInfo = QPushButton("i")
unitInfo.setProperty("style", "btn-info")
unitInfo.setMinimumSize(16, 16)
unitInfo.setMaximumSize(16, 16)
unitInfo.clicked.connect(lambda: self.info(unit_type))
unitInfo.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
existLayout.addWidget(unitName)
existLayout.addItem(
QSpacerItem(20, 0, QSizePolicy.Minimum, QSizePolicy.Minimum)
)
existLayout.addWidget(existing_units)
existLayout.addItem(
QSpacerItem(20, 0, QSizePolicy.Minimum, QSizePolicy.Minimum)
)
existLayout.addWidget(price)
buysellayout.addWidget(sell)
buysellayout.addWidget(amount_bought)
buysellayout.addWidget(buy)
infolayout.addWidget(unitInfo)
layout.addWidget(exist, row, 1)
layout.addWidget(buysell, row, 2)
layout.addWidget(info, row, 3)
return row + 1
def _update_count_label(self, unit_type: Union[AircraftType, Type[VehicleType]]):
self.bought_amount_labels[unit_type].setText(
"{}".format(
unit_type in self.pending_deliveries.units
and "{}".format(self.pending_deliveries.units[unit_type])
or "0"
)
)
self.existing_units_labels[unit_type].setText(
"{}".format(self.cp.base.total_units_of_type(unit_type))
)
def update_available_budget(self) -> None:
GameUpdateSignal.get_instance().updateBudget(self.game_model.game)
def buy(self, unit_type: Union[AircraftType, Type[VehicleType]]):
if not self.enable_purchase(unit_type):
logging.error(f"Purchase of {unit_type.id} not allowed at {self.cp.name}")
return
self.pending_deliveries.order({unit_type: 1})
self.budget -= self.price_of(unit_type)
self._update_count_label(unit_type)
self.update_available_budget()
def sell(self, unit_type):
if self.pending_deliveries.available_next_turn(unit_type) > 0:
self.budget += self.price_of(unit_type)
self.pending_deliveries.sell({unit_type: 1})
if self.pending_deliveries.units[unit_type] == 0:
del self.pending_deliveries.units[unit_type]
self._update_count_label(unit_type)
self.update_available_budget()
def enable_purchase(
self, unit_type: Union[AircraftType, Type[VehicleType]]
) -> bool:
return self.budget >= self.price_of(unit_type)
def enable_sale(self, unit_type: Union[AircraftType, Type[VehicleType]]) -> bool:
return True
def info(self, unit_type):
self.info_window = QUnitInfoWindow(self.game_model.game, unit_type)
self.info_window.show()
def set_maximum_units(self, maximum_units):
"""
Set the maximum number of units that can be bought
"""
self.maximum_units = maximum_units
def name_of(self, unit_type: Union[AircraftType, Type[VehicleType]]) -> str:
raise NotImplementedError
def price_of(self, unit_type: Union[AircraftType, Type[VehicleType]]) -> int:
raise NotImplementedError