mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
- Factored out the current generators to use a better approach with Templates build from the dcs mission editor. - This information is extended with a template-mapping in a json file which allows to logically group together multiple dcs groups and even statics to one template - The combination of mapping and miz will be serialized to a template.json which is only used for loading. - Factions now load templates during initialization and hold all the templates they can really use. This is based around the faction file. - Implemented a template randomizer which allows to add some randomization to templates - Each Template Group can have 1 randomizer which randomizes unit_type and size based on the mapping definition. Larger groups need to be devided in more fine detailed groups as we can now handle them better due to the change from dcs group types to our own classes. - Rewritten the ArmorGroup, Naval and EWR template handling Rework GroundObjectBuyMenu to support templates
227 lines
8.0 KiB
Python
227 lines
8.0 KiB
Python
import logging
|
|
|
|
from PySide2.QtWidgets import (
|
|
QDialog,
|
|
QGridLayout,
|
|
QGroupBox,
|
|
QHBoxLayout,
|
|
QLabel,
|
|
QPushButton,
|
|
QVBoxLayout,
|
|
)
|
|
from dcs import Point, vehicles
|
|
|
|
from game import Game
|
|
from game.config import REWARDS
|
|
from game.data.building_data import FORTIFICATION_BUILDINGS
|
|
from game.data.groundunitclass import GroundUnitClass
|
|
from game.dcs.groundunittype import GroundUnitType
|
|
from game.theater import ControlPoint, TheaterGroundObject
|
|
from game.theater.theatergroundobject import (
|
|
BuildingGroundObject,
|
|
EwrGroundObject,
|
|
SamGroundObject,
|
|
VehicleGroupGroundObject,
|
|
)
|
|
from qt_ui.uiconstants import EVENT_ICONS
|
|
from qt_ui.widgets.QBudgetBox import QBudgetBox
|
|
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
|
|
from qt_ui.windows.groundobject.QBuildingInfo import QBuildingInfo
|
|
from qt_ui.windows.groundobject.QGroundObjectBuyMenu import QGroundObjectBuyMenu
|
|
|
|
|
|
class QGroundObjectMenu(QDialog):
|
|
def __init__(
|
|
self,
|
|
parent,
|
|
ground_object: TheaterGroundObject,
|
|
cp: ControlPoint,
|
|
game: Game,
|
|
):
|
|
super().__init__(parent)
|
|
self.setMinimumWidth(350)
|
|
self.ground_object = ground_object
|
|
self.cp = cp
|
|
self.game = game
|
|
self.setWindowTitle(
|
|
f"Location - {self.ground_object.obj_name} ({self.cp.name})"
|
|
)
|
|
self.setWindowIcon(EVENT_ICONS["capture"])
|
|
self.intelBox = QGroupBox("Units :")
|
|
self.buildingBox = QGroupBox("Buildings :")
|
|
self.intelLayout = QGridLayout()
|
|
self.buildingsLayout = QGridLayout()
|
|
self.sell_all_button = None
|
|
self.total_value = 0
|
|
self.init_ui()
|
|
|
|
def init_ui(self):
|
|
|
|
self.mainLayout = QVBoxLayout()
|
|
self.budget = QBudgetBox(self.game)
|
|
self.budget.setGame(self.game)
|
|
|
|
self.doLayout()
|
|
|
|
if isinstance(self.ground_object, BuildingGroundObject):
|
|
self.mainLayout.addWidget(self.buildingBox)
|
|
if self.cp.captured:
|
|
self.mainLayout.addWidget(self.financesBox)
|
|
else:
|
|
self.mainLayout.addWidget(self.intelBox)
|
|
|
|
self.actionLayout = QHBoxLayout()
|
|
|
|
self.sell_all_button = QPushButton("Disband (+" + str(self.total_value) + "M)")
|
|
self.sell_all_button.clicked.connect(self.sell_all)
|
|
self.sell_all_button.setProperty("style", "btn-danger")
|
|
|
|
self.buy_replace = QPushButton("Buy/Replace")
|
|
self.buy_replace.clicked.connect(self.buy_group)
|
|
self.buy_replace.setProperty("style", "btn-success")
|
|
|
|
if self.ground_object.purchasable:
|
|
if self.total_value > 0:
|
|
self.actionLayout.addWidget(self.sell_all_button)
|
|
self.actionLayout.addWidget(self.buy_replace)
|
|
|
|
if self.cp.captured and self.ground_object.purchasable:
|
|
self.mainLayout.addLayout(self.actionLayout)
|
|
self.setLayout(self.mainLayout)
|
|
|
|
def doLayout(self):
|
|
|
|
self.update_total_value()
|
|
self.intelBox = QGroupBox("Units :")
|
|
self.intelLayout = QGridLayout()
|
|
i = 0
|
|
for g in self.ground_object.groups:
|
|
for unit in g.units:
|
|
self.intelLayout.addWidget(
|
|
QLabel(f"<b>Unit {str(unit.display_name)}</b>"), i, 0
|
|
)
|
|
|
|
if not unit.alive and self.cp.captured:
|
|
price = unit.unit_type.price if unit.unit_type else 0
|
|
repair = QPushButton(f"Repair [{price}M]")
|
|
repair.setProperty("style", "btn-success")
|
|
repair.clicked.connect(
|
|
lambda u=unit, p=price: self.repair_unit(u, p)
|
|
)
|
|
self.intelLayout.addWidget(repair, i, 1)
|
|
i += 1
|
|
|
|
stretch = QVBoxLayout()
|
|
stretch.addStretch()
|
|
self.intelLayout.addLayout(stretch, i, 0)
|
|
|
|
self.buildingBox = QGroupBox("Buildings :")
|
|
self.buildingsLayout = QGridLayout()
|
|
|
|
j = 0
|
|
total_income = 0
|
|
received_income = 0
|
|
for static in self.ground_object.statics:
|
|
if static not in FORTIFICATION_BUILDINGS:
|
|
self.buildingsLayout.addWidget(
|
|
QBuildingInfo(static, self.ground_object), j / 3, j % 3
|
|
)
|
|
j = j + 1
|
|
|
|
if self.ground_object.category in REWARDS.keys():
|
|
total_income += REWARDS[self.ground_object.category]
|
|
if static.alive:
|
|
received_income += REWARDS[self.ground_object.category]
|
|
else:
|
|
logging.warning(self.ground_object.category + " not in REWARDS")
|
|
|
|
self.financesBox = QGroupBox("Finances: ")
|
|
self.financesBoxLayout = QGridLayout()
|
|
self.financesBoxLayout.addWidget(
|
|
QLabel("Available: " + str(total_income) + "M"), 2, 1
|
|
)
|
|
self.financesBoxLayout.addWidget(
|
|
QLabel("Receiving: " + str(received_income) + "M"), 2, 2
|
|
)
|
|
|
|
self.financesBox.setLayout(self.financesBoxLayout)
|
|
self.buildingBox.setLayout(self.buildingsLayout)
|
|
self.intelBox.setLayout(self.intelLayout)
|
|
|
|
def do_refresh_layout(self):
|
|
try:
|
|
for i in range(self.mainLayout.count()):
|
|
item = self.mainLayout.itemAt(i)
|
|
if item is not None and item.widget() is not None:
|
|
item.widget().setParent(None)
|
|
self.sell_all_button.setParent(None)
|
|
self.buy_replace.setParent(None)
|
|
self.actionLayout.setParent(None)
|
|
|
|
self.doLayout()
|
|
if isinstance(self.ground_object, BuildingGroundObject):
|
|
self.mainLayout.addWidget(self.buildingBox)
|
|
else:
|
|
self.mainLayout.addWidget(self.intelBox)
|
|
|
|
self.actionLayout = QHBoxLayout()
|
|
if self.total_value > 0:
|
|
self.actionLayout.addWidget(self.sell_all_button)
|
|
self.actionLayout.addWidget(self.buy_replace)
|
|
|
|
if self.cp.captured and self.ground_object.purchasable:
|
|
self.mainLayout.addLayout(self.actionLayout)
|
|
except Exception as e:
|
|
logging.exception(e)
|
|
self.update_total_value()
|
|
|
|
def update_total_value(self):
|
|
total_value = 0
|
|
if not self.ground_object.purchasable:
|
|
return
|
|
for u in self.ground_object.units:
|
|
# Hack: Unknown variant.
|
|
unit_type = next(GroundUnitType.for_dcs_type(vehicles.vehicle_map[u.type]))
|
|
total_value += unit_type.price
|
|
if self.sell_all_button is not None:
|
|
self.sell_all_button.setText("Disband (+$" + str(self.total_value) + "M)")
|
|
self.total_value = total_value
|
|
|
|
def repair_unit(self, unit, price):
|
|
if self.game.blue.budget > price:
|
|
self.game.blue.budget -= price
|
|
unit.alive = True
|
|
GameUpdateSignal.get_instance().updateGame(self.game)
|
|
|
|
# Remove destroyed units in the vicinity
|
|
destroyed_units = self.game.get_destroyed_units()
|
|
for d in destroyed_units:
|
|
p = Point(d["x"], d["z"])
|
|
if p.distance_to_point(unit.position) < 15:
|
|
destroyed_units.remove(d)
|
|
logging.info("Removed destroyed units " + str(d))
|
|
logging.info("Repaired unit : " + str(unit.id) + " " + str(unit.type))
|
|
|
|
self.do_refresh_layout()
|
|
|
|
def sell_all(self):
|
|
self.update_total_value()
|
|
self.game.blue.budget = self.game.blue.budget + self.total_value
|
|
self.ground_object.groups = []
|
|
|
|
# Replan if the tgo was a target of the redfor
|
|
if any(
|
|
package.target == self.ground_object
|
|
for package in self.game.ato_for(player=False).packages
|
|
):
|
|
self.game.initialize_turn(for_red=True, for_blue=False)
|
|
|
|
self.do_refresh_layout()
|
|
GameUpdateSignal.get_instance().updateGame(self.game)
|
|
|
|
def buy_group(self):
|
|
self.subwindow = QGroundObjectBuyMenu(
|
|
self, self.ground_object, self.game, self.total_value
|
|
)
|
|
self.subwindow.show()
|