dcs_liberation/qt_ui/widgets/map/SupplyRouteSegment.py
Dan Albert 3f16c0378a Add BAI planning against supply routes.
This currently is only supported for player flights. I have no idea how
to create an AI flight plan that won't just get them killed. AI-only BAI
missions against supply routes will warn the player on mission creation.
2021-04-19 23:09:39 -07:00

114 lines
3.4 KiB
Python

from functools import cached_property
from typing import List, Optional
from PySide2.QtCore import Qt
from PySide2.QtGui import QColor, QPen
from PySide2.QtWidgets import (
QAction,
QGraphicsItem,
QGraphicsLineItem,
QGraphicsSceneContextMenuEvent,
QGraphicsSceneHoverEvent,
QMenu,
)
from game.theater import ControlPoint
from game.theater.supplyroutes import SupplyRouteLink
from game.transfers import RoadTransferOrder
from qt_ui.dialogs import Dialog
from qt_ui.uiconstants import COLORS
class SupplyRouteSegment(QGraphicsLineItem):
def __init__(
self,
x0: float,
y0: float,
x1: float,
y1: float,
control_point_a: ControlPoint,
control_point_b: ControlPoint,
convoys: List[RoadTransferOrder],
parent: Optional[QGraphicsItem] = None,
) -> None:
super().__init__(x0, y0, x1, y1, parent)
self.control_point_a = control_point_a
self.control_point_b = control_point_b
self.convoys = convoys
self.setPen(self.make_pen())
self.setToolTip(self.make_tooltip())
self.setAcceptHoverEvents(True)
@cached_property
def convoy_size(self) -> int:
return sum(sum(c.units.values()) for c in self.convoys)
def make_tooltip(self) -> str:
if not self.convoys:
return "No convoys present on this supply route."
units = "units" if self.convoy_size > 1 else "unit"
return (
f"{self.convoy_size} {units} transferring between {self.control_point_a} "
f"and {self.control_point_b}."
)
@property
def line_color(self) -> QColor:
if self.control_point_a.front_is_active(self.control_point_b):
return COLORS["red"]
elif self.control_point_a.captured:
return COLORS["dark_blue"]
else:
return COLORS["dark_red"]
@property
def line_style(self) -> Qt.PenStyle:
if (
self.control_point_a.front_is_active(self.control_point_b)
or self.has_convoys
):
return Qt.PenStyle.SolidLine
return Qt.PenStyle.DotLine
def make_pen(self) -> QPen:
pen = QPen(brush=self.line_color)
pen.setColor(self.line_color)
pen.setStyle(self.line_style)
pen.setWidth(6)
return pen
@property
def has_convoys(self) -> bool:
return bool(self.convoys)
@property
def targetable(self) -> bool:
return self.convoys and not self.control_point_a.captured
def contextMenuEvent(self, event: QGraphicsSceneContextMenuEvent) -> None:
# Can only plan missions against enemy supply routes that have convoys.
if not self.targetable:
super().contextMenuEvent(event)
return
menu = QMenu("Menu")
new_package_action = QAction(f"New package")
new_package_action.triggered.connect(self.open_new_package_dialog)
menu.addAction(new_package_action)
menu.exec_(event.screenPos())
def open_new_package_dialog(self) -> None:
"""Opens the dialog for planning a new mission package."""
Dialog.open_new_package_dialog(
SupplyRouteLink(self.control_point_a, self.control_point_b)
)
def hoverEnterEvent(self, event: QGraphicsSceneHoverEvent):
if self.targetable:
self.setCursor(Qt.PointingHandCursor)
else:
super().hoverEnterEvent(event)