mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Possible to replace SAM, possible to see building recon images on ground site.
This commit is contained in:
parent
d707a59a71
commit
4b2804427e
@ -2,9 +2,12 @@
|
||||
|
||||
## Features/Improvements :
|
||||
* **[Other]** Added an installer option (thanks to contributor parithon)
|
||||
* **[Cheat Menu]** Added possibility to replace destroyed SAM and base defenses units for the player (Click on a SAM site to fix it)
|
||||
* **[Cheat Menu]** Added recon images for buildings on strike targets, click on a Strike target to get detailled informations
|
||||
* **[Units/Factions]** Added F-16C to USA 1990
|
||||
* **[Units/Factions]** Added MQ-9 Reaper as CAS unit for USA 2005
|
||||
* **[Units/Factions]** Added Mig-21, Mig-23, SA-342L to Syria 2011
|
||||
* **[Cheat Menu]** Added buttons to remove money
|
||||
|
||||
## Fixed issues :
|
||||
* **[UI/UX]** Spelling issues (Thanks to Github contributor steveveepee)
|
||||
|
||||
@ -6,7 +6,7 @@ DEFAULT_AVAILABLE_BUILDINGS = ['fuel', 'ammo', 'comms', 'oil', 'ware', 'farp', '
|
||||
WW2_GERMANY_BUILDINGS = ['fuel', 'factory', 'ww2bunker', 'ww2bunker', 'ww2bunker', 'allycamp', 'allycamp', 'aa']
|
||||
WW2_ALLIES_BUILDINGS = ['fuel', 'factory', 'allycamp', 'allycamp', 'allycamp', 'allycamp', 'allycamp', 'aa']
|
||||
|
||||
FORTIFICATION_BUILDINGS = ['Siegfried Line', 'Concertina Wire', 'Czech hedgehogs 1', 'Czech hedgehogs 2',
|
||||
FORTIFICATION_BUILDINGS = ['Siegfried Line', 'Concertina wire', 'Concertina Wire', 'Czech hedgehogs 1', 'Czech hedgehogs 2',
|
||||
'Dragonteeth 1', 'Dragonteeth 2', 'Dragonteeth 3', 'Dragonteeth 4', 'Dragonteeth 5',
|
||||
'Haystack 1', 'Haystack 2', 'Haystack 3', 'Haystack 4', 'Hemmkurvenvenhindernis',
|
||||
'Log posts 1', 'Log posts 2', 'Log posts 3', 'Log ramps 1', 'Log ramps 2', 'Log ramps 3',
|
||||
|
||||
@ -143,7 +143,7 @@ class QLiberationMap(QGraphicsView):
|
||||
go_pos = self._transform_point(ground_object.position)
|
||||
if not ground_object.airbase_group:
|
||||
buildings = self.game.theater.find_ground_objects_by_obj_name(ground_object.obj_name)
|
||||
scene.addItem(QMapGroundObject(self, go_pos[0], go_pos[1], 12, 12, cp, ground_object, self.game, buildings))
|
||||
scene.addItem(QMapGroundObject(self, go_pos[0], go_pos[1], 14, 12, cp, ground_object, self.game, buildings))
|
||||
|
||||
if ground_object.category == "aa" and self.get_display_rule("sam"):
|
||||
max_range = 0
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
from PySide2.QtCore import QPoint, QRect, QPointF, Qt
|
||||
from PySide2.QtGui import QPainter
|
||||
from PySide2.QtGui import QPainter, QBrush
|
||||
from PySide2.QtWidgets import QGraphicsRectItem, QGraphicsItem, QGraphicsSceneHoverEvent, QGraphicsSceneMouseEvent
|
||||
|
||||
import qt_ui.uiconstants as CONST
|
||||
from game import db, Game
|
||||
from game.data.building_data import FORTIFICATION_BUILDINGS
|
||||
from qt_ui.windows.groundobject.QGroundObjectMenu import QGroundObjectMenu
|
||||
from theater import TheaterGroundObject, ControlPoint
|
||||
|
||||
@ -57,14 +58,49 @@ class QMapGroundObject(QGraphicsRectItem):
|
||||
if cat == "aa" and self.model.sea_object:
|
||||
cat = "ship"
|
||||
|
||||
if not self.model.is_dead and not self.cp.captured:
|
||||
painter.drawPixmap(option.rect, CONST.ICONS[cat + enemyIcons])
|
||||
elif not self.model.is_dead:
|
||||
painter.drawPixmap(option.rect, CONST.ICONS[cat + playerIcons])
|
||||
rect = QRect(option.rect.x()+2,option.rect.y(),option.rect.width()-2,option.rect.height())
|
||||
|
||||
is_dead = self.model.is_dead
|
||||
for building in self.buildings:
|
||||
if not building.is_dead:
|
||||
is_dead = False
|
||||
break
|
||||
|
||||
if not is_dead and not self.cp.captured:
|
||||
painter.drawPixmap(rect, CONST.ICONS[cat + enemyIcons])
|
||||
elif not is_dead:
|
||||
painter.drawPixmap(rect, CONST.ICONS[cat + playerIcons])
|
||||
else:
|
||||
painter.drawPixmap(option.rect, CONST.ICONS["destroyed"])
|
||||
painter.drawPixmap(rect, CONST.ICONS["destroyed"])
|
||||
|
||||
self.drawHealthGauge(painter, option)
|
||||
painter.restore()
|
||||
|
||||
def drawHealthGauge(self, painter, option):
|
||||
units_alive = 0
|
||||
units_dead = 0
|
||||
|
||||
if len(self.model.groups) == 0:
|
||||
for building in self.buildings:
|
||||
if building.dcs_identifier in FORTIFICATION_BUILDINGS:
|
||||
continue
|
||||
if building.is_dead:
|
||||
units_dead += 1
|
||||
else:
|
||||
units_alive += 1
|
||||
|
||||
for g in self.model.groups:
|
||||
units_alive += len(g.units)
|
||||
if hasattr(g, "units_losts"):
|
||||
units_dead += len(g.units_losts)
|
||||
|
||||
if units_dead + units_alive > 0:
|
||||
ratio = float(units_alive)/(float(units_dead) + float(units_alive))
|
||||
bar_height = ratio * option.rect.height()
|
||||
painter.fillRect(option.rect.x(), option.rect.y(), 2, option.rect.height(), QBrush(CONST.COLORS["dark_red"]))
|
||||
painter.fillRect(option.rect.x(), option.rect.y(), 2, bar_height, QBrush(CONST.COLORS["green"]))
|
||||
|
||||
|
||||
def hoverEnterEvent(self, event: QGraphicsSceneHoverEvent):
|
||||
self.update()
|
||||
self.setCursor(Qt.PointingHandCursor)
|
||||
@ -77,6 +113,6 @@ class QMapGroundObject(QGraphicsRectItem):
|
||||
self.update()
|
||||
|
||||
def openEditionMenu(self):
|
||||
self.editionMenu = QGroundObjectMenu(self.window(), self.model, self.cp, self.game)
|
||||
self.editionMenu = QGroundObjectMenu(self.window(), self.model, self.buildings, self.cp, self.game)
|
||||
self.editionMenu.show()
|
||||
|
||||
|
||||
@ -1,16 +1,22 @@
|
||||
from PySide2.QtWidgets import QGridLayout, QLabel, QGroupBox
|
||||
from PySide2.QtWidgets import QGridLayout, QLabel, QGroupBox, QPushButton
|
||||
|
||||
from qt_ui.uiconstants import VEHICLES_ICONS
|
||||
from qt_ui.windows.groundobject.QGroundObjectMenu import QGroundObjectMenu
|
||||
from theater import ControlPoint, TheaterGroundObject
|
||||
|
||||
|
||||
class QBaseDefenseGroupInfo(QGroupBox):
|
||||
|
||||
def __init__(self, cp:ControlPoint, ground_object: TheaterGroundObject):
|
||||
def __init__(self, cp:ControlPoint, ground_object: TheaterGroundObject, game):
|
||||
super(QBaseDefenseGroupInfo, self).__init__("Group : " + ground_object.obj_name)
|
||||
self.ground_object = ground_object
|
||||
self.cp = cp
|
||||
self.game = game
|
||||
self.buildings = game.theater.find_ground_objects_by_obj_name(self.ground_object.obj_name)
|
||||
self.init_ui()
|
||||
|
||||
|
||||
|
||||
def init_ui(self):
|
||||
unit_dict = {}
|
||||
layout = QGridLayout()
|
||||
@ -29,8 +35,18 @@ class QBaseDefenseGroupInfo(QGroupBox):
|
||||
# icon.setText("<b>" + k[:6] + "</b>")
|
||||
#icon.setProperty("style", "icon-plane")
|
||||
#layout.addWidget(icon, i, 0)
|
||||
layout.addWidget(QLabel(str(v) + " x " + "<strong>" + k + "</strong>"), i, 1)
|
||||
layout.addWidget(QLabel(str(v) + " x " + "<strong>" + k + "</strong>"), i, 0)
|
||||
i = i + 1
|
||||
|
||||
manage_button = QPushButton("Manage")
|
||||
manage_button.setProperty("style", "btn-success")
|
||||
manage_button.setMaximumWidth(180)
|
||||
manage_button.clicked.connect(self.onManage)
|
||||
layout.addWidget(manage_button, i+1, 0)
|
||||
self.setLayout(layout)
|
||||
|
||||
def onManage(self):
|
||||
self.editionMenu = QGroundObjectMenu(self.window(), self.ground_object, self.buildings, self.cp, self.game)
|
||||
self.editionMenu.show()
|
||||
|
||||
|
||||
|
||||
@ -15,6 +15,6 @@ class QBaseDefensesHQ(QFrame):
|
||||
def init_ui(self):
|
||||
airport = self.game.theater.terrain.airport_by_id(self.cp.id)
|
||||
layout = QGridLayout()
|
||||
layout.addWidget(QBaseInformation(self.cp, airport))
|
||||
layout.addWidget(QBaseInformation(self.cp, airport, self.game))
|
||||
self.setLayout(layout)
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
from PySide2.QtWidgets import QGridLayout, QLabel, QGroupBox, QVBoxLayout, QFrame
|
||||
from PySide2.QtGui import Qt
|
||||
from PySide2.QtWidgets import QGridLayout, QLabel, QGroupBox, QVBoxLayout, QFrame, QWidget, QScrollArea
|
||||
|
||||
from game import db
|
||||
from qt_ui.uiconstants import AIRCRAFT_ICONS, VEHICLES_ICONS
|
||||
@ -8,17 +9,34 @@ from theater import ControlPoint, Airport
|
||||
|
||||
class QBaseInformation(QFrame):
|
||||
|
||||
def __init__(self, cp:ControlPoint, airport:Airport):
|
||||
def __init__(self, cp:ControlPoint, airport:Airport, game):
|
||||
super(QBaseInformation, self).__init__()
|
||||
self.cp = cp
|
||||
self.airport = airport
|
||||
self.game = game
|
||||
self.setMinimumWidth(500)
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
self.layout = QVBoxLayout()
|
||||
self.mainLayout = QVBoxLayout()
|
||||
|
||||
scroll_content = QWidget()
|
||||
task_box_layout = QGridLayout()
|
||||
scroll_content.setLayout(task_box_layout)
|
||||
row = 0
|
||||
|
||||
for g in self.cp.ground_objects:
|
||||
if g.airbase_group:
|
||||
group_info = QBaseDefenseGroupInfo(self.cp, g)
|
||||
self.layout.addWidget(group_info)
|
||||
self.setLayout(self.layout)
|
||||
group_info = QBaseDefenseGroupInfo(self.cp, g, self.game)
|
||||
task_box_layout.addWidget(group_info)
|
||||
|
||||
scroll_content.setLayout(task_box_layout)
|
||||
scroll = QScrollArea()
|
||||
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
|
||||
scroll.setWidgetResizable(True)
|
||||
scroll.setWidget(scroll_content)
|
||||
|
||||
self.mainLayout.addWidget(scroll)
|
||||
|
||||
self.setLayout(self.mainLayout)
|
||||
33
qt_ui/windows/groundobject/QBuildingInfo.py
Normal file
33
qt_ui/windows/groundobject/QBuildingInfo.py
Normal file
@ -0,0 +1,33 @@
|
||||
import os
|
||||
|
||||
from PySide2.QtGui import QPixmap
|
||||
from PySide2.QtWidgets import QGroupBox, QHBoxLayout, QVBoxLayout, QLabel
|
||||
|
||||
|
||||
class QBuildingInfo(QGroupBox):
|
||||
|
||||
def __init__(self, building, ground_object):
|
||||
super(QBuildingInfo, self).__init__()
|
||||
self.building = building
|
||||
self.ground_object = ground_object
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
self.header = QLabel()
|
||||
path = os.path.join("./resources/ui/units/buildings/" + self.building.dcs_identifier + ".png")
|
||||
if self.building.is_dead:
|
||||
pixmap = QPixmap("./resources/ui/units/buildings/dead.png")
|
||||
elif os.path.isfile(path):
|
||||
pixmap = QPixmap(path)
|
||||
else:
|
||||
pixmap = QPixmap("./resources/ui/units/buildings/missing.png")
|
||||
self.header.setPixmap(pixmap)
|
||||
name = "<b>{}</b> {}".format(self.building.dcs_identifier[0:18], "[DEAD]" if self.building.is_dead else "")
|
||||
self.name = QLabel(name)
|
||||
self.name.setProperty("style", "small")
|
||||
layout = QVBoxLayout()
|
||||
layout.addWidget(self.header)
|
||||
layout.addWidget(self.name)
|
||||
footer = QHBoxLayout()
|
||||
self.setLayout(layout)
|
||||
|
||||
@ -5,23 +5,30 @@ from PySide2.QtWidgets import QHBoxLayout, QWidget, QDialog, QGridLayout, QLabel
|
||||
from dcs import Point
|
||||
|
||||
from game import Game
|
||||
from game.data.building_data import FORTIFICATION_BUILDINGS
|
||||
from game.db import PRICES, unit_type_of
|
||||
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 theater import ControlPoint, TheaterGroundObject
|
||||
|
||||
|
||||
class QGroundObjectMenu(QDialog):
|
||||
|
||||
def __init__(self, parent, ground_object: TheaterGroundObject, cp: ControlPoint, game: Game):
|
||||
def __init__(self, parent, ground_object: TheaterGroundObject, buildings:[], cp: ControlPoint, game: Game):
|
||||
super(QGroundObjectMenu, self).__init__(parent)
|
||||
self.setMinimumWidth(350)
|
||||
self.ground_object = ground_object
|
||||
self.buildings = buildings
|
||||
self.cp = cp
|
||||
self.game = game
|
||||
self.setWindowTitle("Location " + self.ground_object.obj_name)
|
||||
self.setWindowIcon(EVENT_ICONS["capture"])
|
||||
self.intelBox = QGroupBox("Units :")
|
||||
self.buildingBox = QGroupBox("Buildings :")
|
||||
self.intelLayout = QGridLayout()
|
||||
self.buildingsLayout = QGridLayout()
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
@ -32,7 +39,10 @@ class QGroundObjectMenu(QDialog):
|
||||
|
||||
self.doLayout()
|
||||
|
||||
self.mainLayout.addWidget(self.intelBox)
|
||||
if len(self.ground_object.groups) > 0:
|
||||
self.mainLayout.addWidget(self.intelBox)
|
||||
else:
|
||||
self.mainLayout.addWidget(self.buildingBox)
|
||||
self.setLayout(self.mainLayout)
|
||||
|
||||
def doLayout(self):
|
||||
@ -55,28 +65,37 @@ class QGroundObjectMenu(QDialog):
|
||||
price = 6
|
||||
|
||||
self.intelLayout.addWidget(QLabel("<b>Unit #" + str(u.id) + " - " + str(u.type) + "</b> [DEAD]"), i, 0)
|
||||
repair = QPushButton("Repair [" + str(price) + "M]")
|
||||
repair.setProperty("style", "btn-primary")
|
||||
repair.clicked.connect(lambda u=u, g=g, p=price: self.repair_unit(g, u, p))
|
||||
self.intelLayout.addWidget(repair, i, 1)
|
||||
if self.cp.captured:
|
||||
repair = QPushButton("Repair [" + str(price) + "M]")
|
||||
repair.setProperty("style", "btn-success")
|
||||
repair.clicked.connect(lambda u=u, g=g, p=price: self.repair_unit(g, u, p))
|
||||
self.intelLayout.addWidget(repair, i, 1)
|
||||
i = i + 1
|
||||
|
||||
self.buildingBox = QGroupBox("Buildings :")
|
||||
self.buildingsLayout = QGridLayout()
|
||||
j = 0
|
||||
for i, building in enumerate(self.buildings):
|
||||
if building.dcs_identifier not in FORTIFICATION_BUILDINGS:
|
||||
self.buildingsLayout.addWidget(QBuildingInfo(building, self.ground_object), j/3, j%3)
|
||||
j = j + 1
|
||||
|
||||
self.buildingBox.setLayout(self.buildingsLayout)
|
||||
self.intelBox.setLayout(self.intelLayout)
|
||||
|
||||
def do_refresh_layout(self):
|
||||
try:
|
||||
for i in range(self.mainLayout.count()):
|
||||
self.mainLayout.removeItem(self.mainLayout.itemAt(i));
|
||||
self.mainLayout.removeItem(self.mainLayout.itemAt(i))
|
||||
self.doLayout()
|
||||
self.mainLayout.addWidget(self.intelBox)
|
||||
if len(self.ground_object.groups) > 0:
|
||||
self.mainLayout.addWidget(self.intelBox)
|
||||
else:
|
||||
self.mainLayout.addWidget(self.buildingBox)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def repair_unit(self, group, unit, price):
|
||||
|
||||
print(group)
|
||||
print(unit.type)
|
||||
[print(u.id) for u in group.units]
|
||||
|
||||
if self.game.budget > price:
|
||||
self.game.budget -= price
|
||||
group.units_losts = [u for u in group.units_losts if u.id != unit.id]
|
||||
|
||||
@ -486,3 +486,7 @@ QWidget[style="baseMenuHeader"]{
|
||||
font-weight: bold;
|
||||
color:white;
|
||||
}*/
|
||||
|
||||
QLabel[style="small"]{
|
||||
font-size: 8px;
|
||||
}
|
||||
@ -178,4 +178,8 @@ QLabel[style="SEAD"]{
|
||||
QWidget[style="baseMenuHeader"]{
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
}*/
|
||||
}*/
|
||||
|
||||
QLabel[style="small"]{
|
||||
font-size: 8px;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user