From 1776452964be979b27d3abc3963aa23eb56a3701 Mon Sep 17 00:00:00 2001 From: Khopa Date: Sat, 6 Jul 2019 13:54:45 +0200 Subject: [PATCH] Show events on map --- qt_ui/main.py | 4 +- qt_ui/uiconstants.py | 19 ++++++++ qt_ui/widgets/map/QLiberationMap.py | 67 ++++++++++++++++++++++++++++- qt_ui/widgets/map/QMapEvent.py | 35 +++++++++++++++ qt_ui/widgets/map/QMapMission.py | 0 qt_ui/windows/QBaseMenu.py | 2 +- 6 files changed, 122 insertions(+), 5 deletions(-) create mode 100644 qt_ui/widgets/map/QMapEvent.py delete mode 100644 qt_ui/widgets/map/QMapMission.py diff --git a/qt_ui/main.py b/qt_ui/main.py index 1de9227f..2acc3b6b 100644 --- a/qt_ui/main.py +++ b/qt_ui/main.py @@ -19,15 +19,15 @@ if __name__ == "__main__": splash = QSplashScreen(pixmap) splash.show() - # Load stuff + # Once splash screen is up : load resources & setup stuff persistency.setup(sys.argv[1]) css = "" with open("./qt_ui/stylesheets/style.css") as stylesheet: css = stylesheet.read() - sleep(0.5) uiconstants.load_icons() + uiconstants.load_event_icons() app.processEvents() GameUpdateSignal() diff --git a/qt_ui/uiconstants.py b/qt_ui/uiconstants.py index 75907f34..041d4f49 100644 --- a/qt_ui/uiconstants.py +++ b/qt_ui/uiconstants.py @@ -3,6 +3,8 @@ from typing import Dict from PySide2.QtGui import QColor, QFont, QPixmap +from game.event import BaseAttackEvent, FrontlinePatrolEvent, FrontlineAttackEvent, InfantryTransportEvent, \ + InsurgentAttackEvent, ConvoyStrikeEvent, InterceptEvent, NavalInterceptEvent, StrikeEvent, UnitsDeliveryEvent from theater.theatergroundobject import CATEGORY_MAP URLS : Dict[str, str] = { @@ -59,3 +61,20 @@ def load_icons(): ICONS["cleared"] = QPixmap("./resources/ui/ground_assets/cleared.png") for category in CATEGORY_MAP.keys(): ICONS[category] = QPixmap("./resources/ui/ground_assets/" + category + ".png") + + +EVENT_ICONS: Dict[str, QPixmap] = {} + + +def load_event_icons(): + for category, image in {BaseAttackEvent: "capture", + FrontlinePatrolEvent: "attack", + FrontlineAttackEvent: "attack", + InfantryTransportEvent: "infantry", + InsurgentAttackEvent: "insurgent_attack", + ConvoyStrikeEvent: "convoy", + InterceptEvent: "air_intercept", + NavalInterceptEvent: "naval_intercept", + StrikeEvent: "strike", + UnitsDeliveryEvent: "delivery"}.items(): + EVENT_ICONS[category] = QPixmap("./resources/ui/events/" + image + ".png") \ No newline at end of file diff --git a/qt_ui/widgets/map/QLiberationMap.py b/qt_ui/widgets/map/QLiberationMap.py index 58697d24..06d18066 100644 --- a/qt_ui/widgets/map/QLiberationMap.py +++ b/qt_ui/widgets/map/QLiberationMap.py @@ -1,11 +1,15 @@ from typing import Dict -from PySide2.QtCore import Qt +import typing +from PySide2.QtCore import Qt, QRect from PySide2.QtGui import QPixmap, QBrush, QColor, QWheelEvent, QPen, QFont from PySide2.QtWidgets import QGraphicsView, QFrame +from game.event import InfantryTransportEvent, StrikeEvent, BaseAttackEvent, UnitsDeliveryEvent, Event, \ + FrontlineAttackEvent, FrontlinePatrolEvent, ConvoyStrikeEvent from gen import Conflict from qt_ui.widgets.map.QMapControlPoint import QMapControlPoint +from qt_ui.widgets.map.QMapEvent import QMapEvent from qt_ui.widgets.map.QMapGroundObject import QMapGroundObject from qt_ui.widgets.map.QLiberationScene import QLiberationScene from dcs import Point @@ -65,6 +69,9 @@ class QLiberationMap(QGraphicsView): scene = self.scene() scene.clear() scene.addPixmap(QPixmap("./resources/" + self.game.theater.overview_image)) + + self.add_game_events() + for cp in self.game.theater.controlpoints: pos = self._transform_point(cp.position) @@ -122,7 +129,6 @@ class QLiberationMap(QGraphicsView): # frontline_pen.setDashPattern([0,1]) scene.addLine(start_coords[0], start_coords[1], end_coords[0], end_coords[1], pen=frontline_pen) - def _frontline_vector(self, from_cp: ControlPoint, to_cp: ControlPoint): # Cache mechanism to avoid performing frontline vector computation on every frame key = str(from_cp.id) + "_" + str(to_cp.id) @@ -133,6 +139,13 @@ class QLiberationMap(QGraphicsView): self.frontline_vector_cache[key] = frontline return frontline + def _frontline_center(self, from_cp: ControlPoint, to_cp: ControlPoint) -> typing.Optional[Point]: + frontline_vector = self._frontline_vector(from_cp, to_cp) + if frontline_vector: + return frontline_vector[0].point_from_heading(frontline_vector[1], frontline_vector[2]/2) + else: + return None + def wheelEvent(self, event: QWheelEvent): if event.angleDelta().y() > 0: @@ -175,6 +188,56 @@ class QLiberationMap(QGraphicsView): return X > treshold and X or treshold, Y > treshold and Y or treshold + def add_game_events(self): + + occupied_rects = [] + + for cp in self.game.theater.controlpoints: + point = self._transform_point(cp.position) + occupied_rects.append(QRect(point[0] - 16, point[1] - 16, 32, 48)) + + def _location_to_rect(location: Point) -> QRect: + nonlocal occupied_rects + point = self._transform_point(location) + rect = QRect(point[0] - 16, point[1] - 16, 32, 32) + + i = 0 + while True: + result = True + for occupied_rect in occupied_rects: + if rect.intersects(occupied_rect): + i += 1 + if i % 2: + rect.setY(rect.y() + occupied_rect.height()) + else: + rect.setX(rect.x() + occupied_rect.width()) + result = False + break + if result: + break + occupied_rects.append(rect) + return rect + + def _events_priority_key(event: Event) -> int: + priority_list = [InfantryTransportEvent, StrikeEvent, BaseAttackEvent, UnitsDeliveryEvent] + if type(event) not in priority_list: + return 0 + else: + return priority_list.index(type(event)) + 1 + + scene = self.scene() + events = self.game.events + events.sort(key=_events_priority_key, reverse=True) + + for event in events: + + location = event.location + if type(event) in [FrontlineAttackEvent, FrontlinePatrolEvent, ConvoyStrikeEvent]: + location = self._frontline_center(event.from_cp, event.to_cp) + + rect = _location_to_rect(location) + scene.addItem(QMapEvent(self, rect.x(), rect.y(), rect.width(), rect.height(), event)) + @staticmethod def set_display_rule(rule: str, value: bool): QLiberationMap.display_rules[rule] = value diff --git a/qt_ui/widgets/map/QMapEvent.py b/qt_ui/widgets/map/QMapEvent.py new file mode 100644 index 00000000..1f444108 --- /dev/null +++ b/qt_ui/widgets/map/QMapEvent.py @@ -0,0 +1,35 @@ +from PySide2.QtGui import QPen +from PySide2.QtWidgets import QGraphicsRectItem + +import qt_ui.uiconstants as CONST +from game.event import Event +from theater import TheaterGroundObject, ControlPoint + + +class QMapEvent(QGraphicsRectItem): + + def __init__(self, parent, x: float, y: float, w: float, h: float, gameEvent: Event): + super(QMapEvent, self).__init__(x, y, w, h) + self.gameEvent = gameEvent + self.parent = parent + self.setAcceptHoverEvents(True) + self.setZValue(2) + self.setToolTip(str(self.gameEvent)) + + + def paint(self, painter, option, widget=None): + + painter.save() + + if self.gameEvent.is_player_attacking: + painter.setPen(QPen(brush=CONST.COLORS["blue"])) + painter.setBrush(CONST.COLORS["blue"]) + else: + painter.setPen(QPen(brush=CONST.COLORS["red"])) + painter.setBrush(CONST.COLORS["red"]) + + painter.drawRect(option.rect) + + painter.drawPixmap(option.rect, CONST.EVENT_ICONS[self.gameEvent.__class__]) + + painter.restore() diff --git a/qt_ui/widgets/map/QMapMission.py b/qt_ui/widgets/map/QMapMission.py deleted file mode 100644 index e69de29b..00000000 diff --git a/qt_ui/windows/QBaseMenu.py b/qt_ui/windows/QBaseMenu.py index 9b15cb18..6501722e 100644 --- a/qt_ui/windows/QBaseMenu.py +++ b/qt_ui/windows/QBaseMenu.py @@ -15,6 +15,7 @@ class QBaseMenu(QDialog): self.game = game self.deliveryEvent = self.game.units_delivery_event(self.cp) self.setWindowFlags(Qt.WindowStaysOnTopHint) + self.setMinimumSize(200,200) self.initUi() def initUi(self): @@ -42,7 +43,6 @@ class QBaseMenu(QDialog): tasks = list(units.keys()) tasks_per_column = 3 - purchaseLayout = QGridLayout() self.bought_amount_labels = {} if self.cp.captured: