dcs_liberation/qt_ui/windows/basemenu/QRecruitBehaviour.py
Simon Clark 995a89d370 Add initial version of the unit info window.
DCS features a massive range of aircraft and land vehicles, and not all of them make their role(s) clear just from the name alone. What this commit does is add an "information" button (and resultant window) to the recruitment section. This should allow new players to understand what each unit is/does.

Current state - every aircraft has a country of origin and an introduction date for that variant. Some also have a small placeholder description, taken from ED's store page for that aircraft. There is also a placeholder picture (taken from a rejected image from my own personal photography) that will, in time, show a banner image of each unit.

Todo - add appropriate screenshots for each aircraft's banner, replace the placeholder text for each aircraft (this will take a while...) and add more data points for each unit type, such as a unit role (i.e. "air-superiority fighter", "multirole fighter", etc) or perhaps a list of weapons carried. I also haven't made a start on the huge number of ground units yet.
2021-01-18 19:27:54 +00:00

183 lines
6.3 KiB
Python

import logging
from typing import Type
from PySide2.QtCore import Qt
from PySide2.QtWidgets import (
QGroupBox,
QHBoxLayout,
QLabel,
QLayout,
QPushButton,
QSizePolicy,
QSpacerItem,
)
from dcs.unittype import UnitType
from game import db
from game.event import UnitsDeliveryEvent
from game.theater import ControlPoint
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
recruitable_types = []
BUDGET_FORMAT = "Available Budget: <b>${}M</b>"
def __init__(self) -> None:
self.bought_amount_labels = {}
self.existing_units_labels = {}
self.recruitable_types = []
self.update_available_budget()
@property
def pending_deliveries(self) -> UnitsDeliveryEvent:
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: Type[UnitType], layout: QLayout,
row: int, disabled: bool = False) -> 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("<b>" + db.unit_get_expanded_info(self.game_model.game.player_country, unit_type, 'name') + "</b>")
unitName.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
existing_units = QLabel(str(existing_units))
existing_units.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
amount_bought = QLabel("<b>{}</b>".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("<b>$ {:02d}</b> m".format(db.PRICES[unit_type]))
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(disabled)
buy.setMinimumSize(16, 16)
buy.setMaximumSize(16, 16)
buy.clicked.connect(lambda: self.buy(unit_type))
buy.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
sell = QPushButton("-")
sell.setProperty("style", "btn-sell")
sell.setDisabled(disabled)
sell.setMinimumSize(16, 16)
sell.setMaximumSize(16, 16)
sell.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
sell.clicked.connect(lambda: self.sell(unit_type))
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.setDisabled(disabled)
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: Type[UnitType]):
self.bought_amount_labels[unit_type].setText("<b>{}</b>".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("<b>{}</b>".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: Type[UnitType]):
price = db.PRICES[unit_type]
if self.budget >= price:
self.pending_deliveries.order({unit_type: 1})
self.budget -= price
else:
# TODO : display modal warning
logging.info("Not enough money !")
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:
price = db.PRICES[unit_type]
self.budget += price
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 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 set_recruitable_types(self, recruitables_types):
"""
Set the maximum number of units that can be bought
"""
self.recruitables_types = recruitables_types