Possible to plan ships movements on the map (UI only)

This commit is contained in:
Khopa 2020-12-03 01:01:15 +01:00
parent bf275fe564
commit 72ac806cb8
4 changed files with 95 additions and 10 deletions

View File

@ -229,6 +229,8 @@ class ControlPoint(MissionTarget, ABC):
# TODO: Should be Airbase specific.
self.stances: Dict[int, CombatStance] = {}
self.pending_unit_deliveries: Optional[UnitsDeliveryEvent] = None
self.target_position = None
def __repr__(self):
return f"<{__class__}: {self.name}>"
@ -271,6 +273,13 @@ class ControlPoint(MissionTarget, ABC):
"""
return False
@property
def moveable(self) -> bool:
"""
:return: Whether this control point can be moved around
"""
return False
@property
@abstractmethod
def total_aircraft_parking(self):
@ -491,6 +500,7 @@ class Airfield(ControlPoint):
class NavalControlPoint(ControlPoint, ABC):
@property
def is_fleet(self) -> bool:
return True
@ -539,6 +549,10 @@ class NavalControlPoint(ControlPoint, ABC):
def runway_can_be_repaired(self) -> bool:
return False
@property
def moveable(self) -> bool:
return True
class Carrier(NavalControlPoint):
@ -546,8 +560,7 @@ class Carrier(NavalControlPoint):
import game.theater.conflicttheater
super().__init__(cp_id, name, at, at,
game.theater.conflicttheater.SIZE_SMALL, 1,
has_frontline=False,
cptype=ControlPointType.AIRCRAFT_CARRIER_GROUP)
has_frontline=False, cptype=ControlPointType.AIRCRAFT_CARRIER_GROUP)
def capture(self, game: Game, for_player: bool) -> None:
raise RuntimeError("Carriers cannot be captured")

View File

@ -5,7 +5,8 @@ import logging
import math
from typing import Iterable, Iterator, List, Optional, Tuple
from PySide2.QtCore import QPointF, Qt
from PySide2 import QtWidgets, QtCore
from PySide2.QtCore import QPointF, Qt, QLineF
from PySide2.QtGui import (
QBrush,
QColor,
@ -13,21 +14,20 @@ from PySide2.QtGui import (
QPen,
QPixmap,
QPolygonF,
QWheelEvent,
)
QWheelEvent, )
from PySide2.QtWidgets import (
QFrame,
QGraphicsItem,
QGraphicsOpacityEffect,
QGraphicsScene,
QGraphicsView,
QGraphicsView, QGraphicsSceneMouseEvent,
)
from dcs import Point
from dcs.mapping import point_from_heading
import qt_ui.uiconstants as CONST
from game import Game, db
from game.theater import ControlPoint
from game.theater import ControlPoint, Enum
from game.theater.conflicttheater import FrontLine
from game.theater.theatergroundobject import (
EwrGroundObject,
@ -76,6 +76,12 @@ def bezier_curve_range(n: int, points: Iterable[Tuple[float, float]]) -> Iterato
t = i / float(n - 1)
yield bezier(t, points)
class QLiberationMapState(Enum):
NORMAL = 0
MOVING_UNIT = 1
class QLiberationMap(QGraphicsView):
WAYPOINT_SIZE = 4
@ -86,6 +92,7 @@ class QLiberationMap(QGraphicsView):
QLiberationMap.instance = self
self.game_model = game_model
self.game: Optional[Game] = game_model.game
self.state = QLiberationMapState.NORMAL
self.waypoint_info_font = QFont()
self.waypoint_info_font.setPointSize(12)
@ -102,6 +109,11 @@ class QLiberationMap(QGraphicsView):
self.init_scene()
self.setGame(game_model.game)
# Object displayed when unit is selected
self.movement_line = QtWidgets.QGraphicsLineItem(QtCore.QLineF(QPointF(0,0),QPointF(0,0)))
self.movement_line.setPen(QPen(CONST.COLORS["orange"], width=10.0))
self.selected_cp: QMapControlPoint = None
GameUpdateSignal.get_instance().flight_paths_changed.connect(
lambda: self.draw_flight_plans(self.scene())
)
@ -316,6 +328,12 @@ class QLiberationMap(QGraphicsView):
self.draw_ground_objects(scene, cp)
if cp.target_position is not None:
tpos = cp.target_position
scene.addLine(QLineF(QPointF(pos[0], pos[1]), QPointF(tpos[0], tpos[1])),
QPen(CONST.COLORS["green"], width=10, s=Qt.DashDotLine))
for cp in self.game.theater.enemy_points():
if DisplayOptions.lines:
self.scene_create_lines_for_cp(cp, playerColor, enemyColor)
@ -572,6 +590,10 @@ class QLiberationMap(QGraphicsView):
return X > treshold and X or treshold, Y > treshold and Y or treshold
def _scene_to_dcs_coords(self, x, y):
pass
def highlight_color(self, transparent: Optional[bool] = False) -> QColor:
return QColor(255, 255, 0, 20 if transparent else 255)
@ -657,6 +679,32 @@ class QLiberationMap(QGraphicsView):
poly = QPolygonF([QPointF(*self._transform_point(Point(point[0], point[1]))) for point in exclusion_zone])
scene.addPolygon(poly, CONST.COLORS["grey"], CONST.COLORS["dark_dark_grey"])
def setSelectedUnit(self, selected_cp: QMapControlPoint):
self.state = QLiberationMapState.MOVING_UNIT
self.selected_cp = selected_cp
position = self._transform_point(selected_cp.control_point.position)
self.movement_line = QtWidgets.QGraphicsLineItem(QLineF(QPointF(*position), QPointF(*position)))
self.scene().addItem(self.movement_line)
def sceneMouseMovedEvent(self, event: QGraphicsSceneMouseEvent):
if self.state == QLiberationMapState.MOVING_UNIT:
self.setCursor(Qt.PointingHandCursor)
p1 = self.movement_line.line().p1()
self.movement_line.setLine(QLineF(p1, event.scenePos()))
def sceneMousePressEvent(self, event: QGraphicsSceneMouseEvent):
if self.state == QLiberationMapState.MOVING_UNIT:
if event.buttons() == Qt.RightButton:
pass
elif event.buttons() == Qt.LeftButton:
if self.selected_cp is not None:
# Set movement position for the cp
pos = event.scenePos()
point = Point(int(pos.x()), int(pos.y()))
self.selected_cp.control_point.target_position = point.x, point.y # TODO : convert to DCS coords !
GameUpdateSignal.get_instance().updateGame(self.game_model.game)
else:
return
self.state = QLiberationMapState.NORMAL
self.scene().removeItem(self.movement_line)
self.selected_cp = None

View File

@ -1,5 +1,4 @@
from PySide2.QtGui import QFont
from PySide2.QtWidgets import QGraphicsScene
from PySide2.QtWidgets import QGraphicsScene, QGraphicsSceneMouseEvent
import qt_ui.uiconstants as CONST
@ -11,3 +10,9 @@ class QLiberationScene(QGraphicsScene):
item = self.addText("Go to \"File/New Game\" to setup a new campaign or go to \"File/Open\" to load an existing save game.",
CONST.FONT_PRIMARY)
item.setDefaultTextColor(CONST.COLORS["white"])
def mouseMoveEvent(self, event: QGraphicsSceneMouseEvent):
self.parent().sceneMouseMovedEvent(event)
def mousePressEvent(self, event:QGraphicsSceneMouseEvent):
self.parent().sceneMousePressEvent(event)

View File

@ -26,6 +26,12 @@ class QMapControlPoint(QMapObject):
f"CHEAT: Capture {self.control_point.name}")
self.capture_action.triggered.connect(self.cheat_capture)
self.move_action = QAction("Move")
self.move_action.triggered.connect(self.move)
self.cancel_move_action = QAction("Cancel Move")
self.cancel_move_action.triggered.connect(self.cancel_move)
def paint(self, painter, option, widget=None) -> None:
if DisplayOptions.control_points:
painter.save()
@ -70,6 +76,12 @@ class QMapControlPoint(QMapObject):
self.base_details_dialog.show()
def add_context_menu_actions(self, menu: QMenu) -> None:
if self.control_point.moveable and self.control_point.captured:
menu.addAction(self.move_action)
if self.control_point.target_position is not None:
menu.addAction(self.cancel_move_action)
if self.control_point.is_fleet:
return
@ -86,6 +98,13 @@ class QMapControlPoint(QMapObject):
# Reinitialized ground planners and the like.
self.game_model.game.initialize_turn()
GameUpdateSignal.get_instance().updateGame(self.game_model.game)
def move(self):
self.parent.setSelectedUnit(self)
def cancel_move(self):
self.control_point.target_position = None
GameUpdateSignal.get_instance().updateGame(self.game_model.game)
def open_new_package_dialog(self) -> None:
"""Extends the default packagedialog to redirect to base menu for red air base."""