mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
This feature allows you to cancel the sales of aircraft or ground vehicles if needed. Upon clicking the minus button, a count of sold units will be appended to the unit count. This count responds to both further presses of the minus button, and also to presses of the plus button. No further units will be requested for the next turn until all sold units have been re-bought. I've tested a bunch of different scenarios with this: - Selling and rebuying a unit - the budget increases and decreases as expected. - Selling one unit, buying a unit worth the new player budget, and then trying to rebuy the old unit - the old unit cannot be rebought until the budget has been freed up for it. - Closing the base window and re-opening it - the sold unit count is retained. - Ending the turn - the sold unit count is reset back to 0 as expected. Contributes to Khopa/dcs_liberation#365
187 lines
6.6 KiB
Python
187 lines
6.6 KiB
Python
import logging
|
|
from typing import Type
|
|
|
|
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
|
|
|
|
|
|
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_type_name_2(unit_type) + "</b>")
|
|
unitName.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
|
|
|
|
sold_count = self.cp.base.sold_units.get(unit_type)
|
|
if sold_count is None:
|
|
sold_count = 0
|
|
if sold_count > 0:
|
|
existing_units = QLabel("<b>{} (-{})</b>".format(existing_units, sold_count))
|
|
else:
|
|
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))
|
|
|
|
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)
|
|
|
|
layout.addWidget(exist, row, 1)
|
|
layout.addWidget(buysell, row, 2)
|
|
|
|
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"
|
|
))
|
|
|
|
sold_count = self.cp.base.sold_units.get(unit_type)
|
|
if sold_count is None:
|
|
sold_count = 0
|
|
if sold_count > 0:
|
|
self.existing_units_labels[unit_type].setText("<b>{} (-{})</b>".format(
|
|
self.cp.base.total_units_of_type(unit_type), self.cp.base.sold_units[unit_type]
|
|
))
|
|
else:
|
|
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:
|
|
sold_count = self.cp.base.sold_units.get(unit_type)
|
|
if sold_count is None:
|
|
sold_count = 0
|
|
if sold_count > 0:
|
|
self.cp.base.sold_units[unit_type] -= 1
|
|
self.cp.base.commision_units({unit_type: 1})
|
|
self.budget -= price
|
|
else:
|
|
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.units.get(unit_type, 0) > 0:
|
|
price = db.PRICES[unit_type]
|
|
self.budget += price
|
|
self.pending_deliveries.units[unit_type] = self.pending_deliveries.units[unit_type] - 1
|
|
if self.pending_deliveries.units[unit_type] == 0:
|
|
del self.pending_deliveries.units[unit_type]
|
|
elif self.cp.base.total_units_of_type(unit_type) > 0:
|
|
price = db.PRICES[unit_type]
|
|
self.budget += price
|
|
self.cp.base.commit_losses({unit_type: 1})
|
|
self.cp.base.sold_units[unit_type] += 1
|
|
|
|
self._update_count_label(unit_type)
|
|
self.update_available_budget()
|
|
|
|
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
|