mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Carrier and Tarawa are now fully moveable
This commit is contained in:
parent
44ed895277
commit
1258f3e17c
@ -438,6 +438,10 @@ class ConflictTheater:
|
|||||||
if self.is_on_land(point):
|
if self.is_on_land(point):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
for exclusion_zone in self.landmap[1]:
|
||||||
|
if poly_contains(point.x, point.y, exclusion_zone):
|
||||||
|
return False
|
||||||
|
|
||||||
for sea in self.landmap[2]:
|
for sea in self.landmap[2]:
|
||||||
if poly_contains(point.x, point.y, sea):
|
if poly_contains(point.x, point.y, sea):
|
||||||
return True
|
return True
|
||||||
|
|||||||
@ -29,7 +29,7 @@ from .theatergroundobject import (
|
|||||||
EwrGroundObject,
|
EwrGroundObject,
|
||||||
SamGroundObject,
|
SamGroundObject,
|
||||||
TheaterGroundObject,
|
TheaterGroundObject,
|
||||||
VehicleGroupGroundObject,
|
VehicleGroupGroundObject, GenericCarrierGroundObject,
|
||||||
)
|
)
|
||||||
from ..weather import Conditions
|
from ..weather import Conditions
|
||||||
|
|
||||||
@ -443,6 +443,20 @@ class ControlPoint(MissionTarget, ABC):
|
|||||||
if runway_status is not None:
|
if runway_status is not None:
|
||||||
runway_status.process_turn()
|
runway_status.process_turn()
|
||||||
|
|
||||||
|
# Process movements for ships control points group
|
||||||
|
if self.target_position is not None:
|
||||||
|
delta = self.target_position - self.position
|
||||||
|
self.position = self.target_position
|
||||||
|
self.target_position = None
|
||||||
|
|
||||||
|
# Move the linked unit groups
|
||||||
|
for ground_object in self.ground_objects:
|
||||||
|
if isinstance(ground_object, GenericCarrierGroundObject):
|
||||||
|
for group in ground_object.groups:
|
||||||
|
for u in group.units:
|
||||||
|
u.position.x = u.position.x + delta.x
|
||||||
|
u.position.y = u.position.y + delta.y
|
||||||
|
|
||||||
|
|
||||||
class Airfield(ControlPoint):
|
class Airfield(ControlPoint):
|
||||||
|
|
||||||
|
|||||||
@ -204,7 +204,10 @@ class GenericCarrierGenerator(GenericGroundObjectGenerator):
|
|||||||
tacan_callsign = self.tacan_callsign()
|
tacan_callsign = self.tacan_callsign()
|
||||||
icls = next(self.icls_alloc)
|
icls = next(self.icls_alloc)
|
||||||
|
|
||||||
brc = self.steam_into_wind(ship_group)
|
if self.control_point.target_position is not None:
|
||||||
|
brc = self.steam_to_target_position(ship_group)
|
||||||
|
else:
|
||||||
|
brc = self.steam_into_wind(ship_group)
|
||||||
self.activate_beacons(ship_group, tacan, tacan_callsign, icls)
|
self.activate_beacons(ship_group, tacan, tacan_callsign, icls)
|
||||||
self.add_runway_data(brc or 0, atc, tacan, tacan_callsign, icls)
|
self.add_runway_data(brc or 0, atc, tacan, tacan_callsign, icls)
|
||||||
self._register_unit_group(group, ship_group)
|
self._register_unit_group(group, ship_group)
|
||||||
@ -248,6 +251,10 @@ class GenericCarrierGenerator(GenericGroundObjectGenerator):
|
|||||||
return brc
|
return brc
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def steam_to_target_position(self, group: ShipGroup) -> Optional[int]:
|
||||||
|
group.add_waypoint(self.control_point.target_position)
|
||||||
|
return group.position.heading_between_point(self.control_point.target_position)
|
||||||
|
|
||||||
def tacan_callsign(self) -> str:
|
def tacan_callsign(self) -> str:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,7 @@ from game.theater.conflicttheater import FrontLine
|
|||||||
from game.theater.theatergroundobject import (
|
from game.theater.theatergroundobject import (
|
||||||
TheaterGroundObject,
|
TheaterGroundObject,
|
||||||
)
|
)
|
||||||
from game.utils import meter_to_feet
|
from game.utils import meter_to_feet, nm_to_meter, meter_to_nm
|
||||||
from game.weather import TimeOfDay
|
from game.weather import TimeOfDay
|
||||||
from gen import Conflict
|
from gen import Conflict
|
||||||
from gen.flights.flight import Flight, FlightWaypoint, FlightWaypointType
|
from gen.flights.flight import Flight, FlightWaypoint, FlightWaypointType
|
||||||
@ -45,6 +45,7 @@ from qt_ui.widgets.map.QMapControlPoint import QMapControlPoint
|
|||||||
from qt_ui.widgets.map.QMapGroundObject import QMapGroundObject
|
from qt_ui.widgets.map.QMapGroundObject import QMapGroundObject
|
||||||
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
|
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
|
||||||
|
|
||||||
|
MAX_SHIP_DISTANCE = 80
|
||||||
|
|
||||||
def binomial(i: int, n: int) -> float:
|
def binomial(i: int, n: int) -> float:
|
||||||
"""Binomial coefficient"""
|
"""Binomial coefficient"""
|
||||||
@ -153,6 +154,9 @@ class QLiberationMap(QGraphicsView):
|
|||||||
update_flight_selection
|
update_flight_selection
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.nm_to_pixel_ratio: int = 0
|
||||||
|
|
||||||
|
|
||||||
def init_scene(self):
|
def init_scene(self):
|
||||||
scene = QLiberationScene(self)
|
scene = QLiberationScene(self)
|
||||||
self.setScene(scene)
|
self.setScene(scene)
|
||||||
@ -166,6 +170,7 @@ class QLiberationMap(QGraphicsView):
|
|||||||
self.game = game
|
self.game = game
|
||||||
if self.game is not None:
|
if self.game is not None:
|
||||||
logging.debug("Reloading Map Canvas")
|
logging.debug("Reloading Map Canvas")
|
||||||
|
self.nm_to_pixel_ratio = self.km_to_pixel(float(nm_to_meter(1)) / 1000.0)
|
||||||
self.reload_scene()
|
self.reload_scene()
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -320,12 +325,10 @@ class QLiberationMap(QGraphicsView):
|
|||||||
self.draw_ground_objects(scene, cp)
|
self.draw_ground_objects(scene, cp)
|
||||||
|
|
||||||
if cp.target_position is not None:
|
if cp.target_position is not None:
|
||||||
tpos = cp.target_position
|
proj = self._transform_point(cp.target_position)
|
||||||
proj = self._transform_point(Point(tpos[0], tpos[1]))
|
|
||||||
scene.addLine(QLineF(QPointF(pos[0], pos[1]), QPointF(proj[0], proj[1])),
|
scene.addLine(QLineF(QPointF(pos[0], pos[1]), QPointF(proj[0], proj[1])),
|
||||||
QPen(CONST.COLORS["green"], width=10, s=Qt.DashDotLine))
|
QPen(CONST.COLORS["green"], width=10, s=Qt.DashDotLine))
|
||||||
|
|
||||||
|
|
||||||
for cp in self.game.theater.enemy_points():
|
for cp in self.game.theater.enemy_points():
|
||||||
if DisplayOptions.lines:
|
if DisplayOptions.lines:
|
||||||
self.scene_create_lines_for_cp(cp, playerColor, enemyColor)
|
self.scene_create_lines_for_cp(cp, playerColor, enemyColor)
|
||||||
@ -533,6 +536,37 @@ class QLiberationMap(QGraphicsView):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def draw_scale(self, scale_distance_nm=20, number_of_points=4):
|
||||||
|
|
||||||
|
PADDING = 14
|
||||||
|
POS_X = 0
|
||||||
|
POS_Y = 10
|
||||||
|
BIG_LINE = 5
|
||||||
|
SMALL_LINE = 2
|
||||||
|
|
||||||
|
dist = self.km_to_pixel(nm_to_meter(scale_distance_nm)/1000.0)
|
||||||
|
self.scene().addRect(POS_X, POS_Y-PADDING, PADDING*2 + dist, BIG_LINE*2+3*PADDING, pen=CONST.COLORS["black"], brush=CONST.COLORS["black"])
|
||||||
|
l = self.scene().addLine(POS_X + PADDING, POS_Y + BIG_LINE*2, POS_X + PADDING + dist, POS_Y + BIG_LINE*2)
|
||||||
|
|
||||||
|
text = self.scene().addText("0nm", font=QFont("Trebuchet MS", 6, weight=5, italic=False))
|
||||||
|
text.setPos(POS_X, POS_Y + BIG_LINE*2)
|
||||||
|
text.setDefaultTextColor(Qt.white)
|
||||||
|
|
||||||
|
text2 = self.scene().addText(str(scale_distance_nm) + "nm", font=QFont("Trebuchet MS", 6, weight=5, italic=False))
|
||||||
|
text2.setPos(POS_X + dist, POS_Y + BIG_LINE * 2)
|
||||||
|
text2.setDefaultTextColor(Qt.white)
|
||||||
|
|
||||||
|
l.setPen(CONST.COLORS["white"])
|
||||||
|
for i in range(number_of_points+1):
|
||||||
|
d = float(i)/float(number_of_points)
|
||||||
|
if i == 0 or i == number_of_points:
|
||||||
|
h = BIG_LINE
|
||||||
|
else:
|
||||||
|
h = SMALL_LINE
|
||||||
|
|
||||||
|
l = self.scene().addLine(POS_X + PADDING + d * dist, POS_Y + BIG_LINE*2, POS_X + PADDING + d * dist, POS_Y + BIG_LINE - h)
|
||||||
|
l.setPen(CONST.COLORS["white"])
|
||||||
|
|
||||||
def wheelEvent(self, event: QWheelEvent):
|
def wheelEvent(self, event: QWheelEvent):
|
||||||
if event.angleDelta().y() > 0:
|
if event.angleDelta().y() > 0:
|
||||||
factor = 1.25
|
factor = 1.25
|
||||||
@ -597,6 +631,12 @@ class QLiberationMap(QGraphicsView):
|
|||||||
|
|
||||||
return Y, X
|
return Y, X
|
||||||
|
|
||||||
|
def km_to_pixel(self, km):
|
||||||
|
p1 = Point(0, 0)
|
||||||
|
p2 = Point(0, 1000*km)
|
||||||
|
p1a = Point(*self._transform_point(p1))
|
||||||
|
p2a = Point(*self._transform_point(p2))
|
||||||
|
return p1a.distance_to_point(p2a)
|
||||||
|
|
||||||
def highlight_color(self, transparent: Optional[bool] = False) -> QColor:
|
def highlight_color(self, transparent: Optional[bool] = False) -> QColor:
|
||||||
return QColor(255, 255, 0, 20 if transparent else 255)
|
return QColor(255, 255, 0, 20 if transparent else 255)
|
||||||
@ -644,7 +684,6 @@ class QLiberationMap(QGraphicsView):
|
|||||||
def addBackground(self):
|
def addBackground(self):
|
||||||
scene = self.scene()
|
scene = self.scene()
|
||||||
|
|
||||||
|
|
||||||
if not DisplayOptions.map_poly:
|
if not DisplayOptions.map_poly:
|
||||||
bg = QPixmap("./resources/" + self.game.theater.overview_image)
|
bg = QPixmap("./resources/" + self.game.theater.overview_image)
|
||||||
scene.addPixmap(bg)
|
scene.addPixmap(bg)
|
||||||
@ -686,9 +725,7 @@ class QLiberationMap(QGraphicsView):
|
|||||||
|
|
||||||
# Uncomment to display plan projection test
|
# Uncomment to display plan projection test
|
||||||
#self.projection_test(scene)
|
#self.projection_test(scene)
|
||||||
|
self.draw_scale()
|
||||||
zero = self._transform_point(Point(0,0))
|
|
||||||
self.scene().addRect(QRectF(zero[0] + 1, zero[1] + 1, 50, 50), CONST.COLORS["red"], QBrush(CONST.COLORS["red"]))
|
|
||||||
|
|
||||||
def projection_test(self, scene):
|
def projection_test(self, scene):
|
||||||
for i in range(100):
|
for i in range(100):
|
||||||
@ -722,8 +759,19 @@ class QLiberationMap(QGraphicsView):
|
|||||||
def sceneMouseMovedEvent(self, event: QGraphicsSceneMouseEvent):
|
def sceneMouseMovedEvent(self, event: QGraphicsSceneMouseEvent):
|
||||||
if self.state == QLiberationMapState.MOVING_UNIT:
|
if self.state == QLiberationMapState.MOVING_UNIT:
|
||||||
self.setCursor(Qt.PointingHandCursor)
|
self.setCursor(Qt.PointingHandCursor)
|
||||||
|
pos = event.scenePos()
|
||||||
p1 = self.movement_line.line().p1()
|
p1 = self.movement_line.line().p1()
|
||||||
self.movement_line.setLine(QLineF(p1, event.scenePos()))
|
|
||||||
|
distance = Point(p1.x(), p1.y()).distance_to_point(Point(pos.x(), pos.y()))
|
||||||
|
|
||||||
|
self.movement_line.setLine(QLineF(p1, pos))
|
||||||
|
|
||||||
|
if distance / self.nm_to_pixel_ratio < MAX_SHIP_DISTANCE:
|
||||||
|
self.movement_line.setPen(CONST.COLORS["green"])
|
||||||
|
else:
|
||||||
|
self.movement_line.setPen(CONST.COLORS["red"])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def sceneMousePressEvent(self, event: QGraphicsSceneMouseEvent):
|
def sceneMousePressEvent(self, event: QGraphicsSceneMouseEvent):
|
||||||
if self.state == QLiberationMapState.MOVING_UNIT:
|
if self.state == QLiberationMapState.MOVING_UNIT:
|
||||||
@ -734,9 +782,17 @@ class QLiberationMap(QGraphicsView):
|
|||||||
# Set movement position for the cp
|
# Set movement position for the cp
|
||||||
pos = event.scenePos()
|
pos = event.scenePos()
|
||||||
point = Point(int(pos.x()), int(pos.y()))
|
point = Point(int(pos.x()), int(pos.y()))
|
||||||
proj = self._scene_to_dcs_coords(point)
|
proj = Point(*self._scene_to_dcs_coords(point))
|
||||||
self.selected_cp.control_point.target_position = proj # TODO : convert to DCS coords !
|
|
||||||
print(proj)
|
# Check distance (max = 80 nm)
|
||||||
|
distance = meter_to_nm(proj.distance_to_point(self.selected_cp.control_point.position))
|
||||||
|
|
||||||
|
# Check if point is in sea
|
||||||
|
if self.game.theater.is_in_sea(proj) and distance < MAX_SHIP_DISTANCE:
|
||||||
|
self.selected_cp.control_point.target_position = proj
|
||||||
|
else:
|
||||||
|
self.selected_cp.control_point.target_position = None
|
||||||
|
|
||||||
GameUpdateSignal.get_instance().updateGame(self.game_model.game)
|
GameUpdateSignal.get_instance().updateGame(self.game_model.game)
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user