Possible to replace SAM, possible to see building recon images on ground site.

This commit is contained in:
Khopa 2020-08-23 18:25:23 +02:00
parent d707a59a71
commit 4b2804427e
11 changed files with 166 additions and 33 deletions

View File

@ -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)

View File

@ -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',

View File

@ -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

View File

@ -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()

View File

@ -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()

View File

@ -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)

View File

@ -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)

View 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)

View File

@ -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]

View File

@ -486,3 +486,7 @@ QWidget[style="baseMenuHeader"]{
font-weight: bold;
color:white;
}*/
QLabel[style="small"]{
font-size: 8px;
}

View File

@ -178,4 +178,8 @@ QLabel[style="SEAD"]{
QWidget[style="baseMenuHeader"]{
font-size: 24px;
font-weight: bold;
}*/
}*/
QLabel[style="small"]{
font-size: 8px;
}