This commit is contained in:
Dan Albert
2021-02-12 19:58:30 -08:00
parent 053663bd76
commit a47bef1f13
222 changed files with 8434 additions and 4461 deletions

View File

@@ -70,10 +70,10 @@ from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
MAX_SHIP_DISTANCE = nautical_miles(80)
def binomial(i: int, n: int) -> float:
"""Binomial coefficient"""
return math.factorial(n) / float(
math.factorial(i) * math.factorial(n - i))
return math.factorial(n) / float(math.factorial(i) * math.factorial(n - i))
def bernstein(t: float, i: int, n: int) -> float:
@@ -92,7 +92,9 @@ def bezier(t: float, points: Iterable[Tuple[float, float]]) -> Tuple[float, floa
return x, y
def bezier_curve_range(n: int, points: Iterable[Tuple[float, float]]) -> Iterator[Tuple[float, float]]:
def bezier_curve_range(
n: int, points: Iterable[Tuple[float, float]]
) -> Iterator[Tuple[float, float]]:
"""Range of points in a curve bezier"""
for i in range(n):
t = i / float(n - 1)
@@ -133,7 +135,9 @@ class QLiberationMap(QGraphicsView):
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 = 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
@@ -162,8 +166,7 @@ class QLiberationMap(QGraphicsView):
# update_flight_selection will be called in when the last
# package is removed. If no flight is selected, it's not a
# problem to also have no package selected.
logging.error(
"Flight was selected with no package selected")
logging.error("Flight was selected with no package selected")
return
# Optional[int] isn't a valid type for a Qt signal. None will be
@@ -183,7 +186,6 @@ class QLiberationMap(QGraphicsView):
self.navmesh_highlight: Optional[QPolygonF] = None
self.shortest_path_segments: List[QLineF] = []
def init_scene(self):
scene = QLiberationScene(self)
self.setScene(scene)
@@ -203,6 +205,7 @@ class QLiberationMap(QGraphicsView):
"""
Uncomment to set up theather reference points"""
def keyPressEvent(self, event):
modifiers = QtWidgets.QApplication.keyboardModifiers()
if not self.reference_point_setup_mode:
@@ -225,40 +228,39 @@ class QLiberationMap(QGraphicsView):
if event.key() == QtCore.Qt.Key_Down:
self.update_reference_point(
self.game.theater.reference_points[0],
Point(0, distance))
self.game.theater.reference_points[0], Point(0, distance)
)
if event.key() == QtCore.Qt.Key_Up:
self.update_reference_point(
self.game.theater.reference_points[0],
Point(0, -distance))
self.game.theater.reference_points[0], Point(0, -distance)
)
if event.key() == QtCore.Qt.Key_Left:
self.update_reference_point(
self.game.theater.reference_points[0],
Point(-distance, 0))
self.game.theater.reference_points[0], Point(-distance, 0)
)
if event.key() == QtCore.Qt.Key_Right:
self.update_reference_point(
self.game.theater.reference_points[0],
Point(distance, 0))
self.game.theater.reference_points[0], Point(distance, 0)
)
if event.key() == QtCore.Qt.Key_S:
self.update_reference_point(
self.game.theater.reference_points[1],
Point(0, distance))
self.game.theater.reference_points[1], Point(0, distance)
)
if event.key() == QtCore.Qt.Key_W:
self.update_reference_point(
self.game.theater.reference_points[1],
Point(0, -distance))
self.game.theater.reference_points[1], Point(0, -distance)
)
if event.key() == QtCore.Qt.Key_A:
self.update_reference_point(
self.game.theater.reference_points[1],
Point(-distance, 0))
self.game.theater.reference_points[1], Point(-distance, 0)
)
if event.key() == QtCore.Qt.Key_D:
self.update_reference_point(
self.game.theater.reference_points[1],
Point(distance, 0))
self.game.theater.reference_points[1], Point(distance, 0)
)
logging.debug(
f"Reference points: {self.game.theater.reference_points}")
logging.debug(f"Reference points: {self.game.theater.reference_points}")
self.reload_scene()
@staticmethod
@@ -275,16 +277,33 @@ class QLiberationMap(QGraphicsView):
distance_point = self._transform_point(culling_distance_point)
transformed = self._transform_point(point)
radius = distance_point[0] - transformed[0]
scene.addEllipse(transformed[0]-radius, transformed[1]-radius, 2*radius, 2*radius, CONST.COLORS["transparent"], CONST.COLORS["light_green_transparent"])
scene.addEllipse(
transformed[0] - radius,
transformed[1] - radius,
2 * radius,
2 * radius,
CONST.COLORS["transparent"],
CONST.COLORS["light_green_transparent"],
)
for zone in culling_zones:
culling_distance_zone = Point(zone.x + culling_distance*1000, zone.y + culling_distance*1000)
culling_distance_zone = Point(
zone.x + culling_distance * 1000, zone.y + culling_distance * 1000
)
distance_zone = self._transform_point(culling_distance_zone)
transformed = self._transform_point(zone)
radius = distance_zone[0] - transformed[0]
scene.addEllipse(transformed[0]-radius, transformed[1]-radius, 2*radius, 2*radius, CONST.COLORS["transparent"], CONST.COLORS["light_green_transparent"])
scene.addEllipse(
transformed[0] - radius,
transformed[1] - radius,
2 * radius,
2 * radius,
CONST.COLORS["transparent"],
CONST.COLORS["light_green_transparent"],
)
def draw_shapely_poly(self, scene: QGraphicsScene, poly: Polygon, pen: QPen,
brush: QBrush) -> Optional[QPolygonF]:
def draw_shapely_poly(
self, scene: QGraphicsScene, poly: Polygon, pen: QPen, brush: QBrush
) -> Optional[QPolygonF]:
if poly.is_empty:
return None
points = []
@@ -293,16 +312,18 @@ class QLiberationMap(QGraphicsView):
points.append(QPointF(x, y))
return scene.addPolygon(QPolygonF(points), pen, brush)
def draw_threat_zone(self, scene: QGraphicsScene, poly: Polygon,
player: bool) -> None:
def draw_threat_zone(
self, scene: QGraphicsScene, poly: Polygon, player: bool
) -> None:
if player:
brush = QColor(0, 132, 255, 100)
else:
brush = QColor(227, 32, 0, 100)
self.draw_shapely_poly(scene, poly, CONST.COLORS["transparent"], brush)
def display_threat_zones(self, scene: QGraphicsScene,
options: ThreatZoneOptions, player: bool) -> None:
def display_threat_zones(
self, scene: QGraphicsScene, options: ThreatZoneOptions, player: bool
) -> None:
"""Draws the threat zones on the map."""
threat_zones = self.game.threat_zone_for(player)
if options.all:
@@ -321,33 +342,44 @@ class QLiberationMap(QGraphicsView):
for poly in polys:
self.draw_threat_zone(scene, poly, player)
def draw_navmesh_neighbor_line(self, scene: QGraphicsScene, poly: Polygon,
begin: ShapelyPoint) -> None:
def draw_navmesh_neighbor_line(
self, scene: QGraphicsScene, poly: Polygon, begin: ShapelyPoint
) -> None:
vertex = Point(begin.x, begin.y)
centroid = poly.centroid
direction = Point(centroid.x, centroid.y)
end = vertex.point_from_heading(vertex.heading_between_point(direction),
nautical_miles(2).meters)
end = vertex.point_from_heading(
vertex.heading_between_point(direction), nautical_miles(2).meters
)
scene.addLine(QLineF(QPointF(*self._transform_point(vertex)),
QPointF(*self._transform_point(end))),
CONST.COLORS["yellow"])
scene.addLine(
QLineF(
QPointF(*self._transform_point(vertex)),
QPointF(*self._transform_point(end)),
),
CONST.COLORS["yellow"],
)
@singledispatchmethod
def draw_navmesh_border(self, intersection, scene: QGraphicsScene,
poly: Polygon) -> None:
raise NotImplementedError("draw_navmesh_border not implemented for %s",
intersection.__class__.__name__)
def draw_navmesh_border(
self, intersection, scene: QGraphicsScene, poly: Polygon
) -> None:
raise NotImplementedError(
"draw_navmesh_border not implemented for %s",
intersection.__class__.__name__,
)
@draw_navmesh_border.register
def draw_navmesh_point_border(self, intersection: ShapelyPoint,
scene: QGraphicsScene, poly: Polygon) -> None:
def draw_navmesh_point_border(
self, intersection: ShapelyPoint, scene: QGraphicsScene, poly: Polygon
) -> None:
# Draw a line from the vertex toward the center of the polygon.
self.draw_navmesh_neighbor_line(scene, poly, intersection)
@draw_navmesh_border.register
def draw_navmesh_edge_border(self, intersection: LineString,
scene: QGraphicsScene, poly: Polygon) -> None:
def draw_navmesh_edge_border(
self, intersection: LineString, scene: QGraphicsScene, poly: Polygon
) -> None:
# Draw a line from the center of the edge toward the center of the
# polygon.
edge_center = intersection.interpolate(0.5, normalized=True)
@@ -355,13 +387,16 @@ class QLiberationMap(QGraphicsView):
def display_navmesh(self, scene: QGraphicsScene, player: bool) -> None:
for navpoly in self.game.navmesh_for(player).polys:
self.draw_shapely_poly(scene, navpoly.poly, CONST.COLORS["black"],
CONST.COLORS["transparent"])
self.draw_shapely_poly(
scene, navpoly.poly, CONST.COLORS["black"], CONST.COLORS["transparent"]
)
position = self._transform_point(
Point(navpoly.poly.centroid.x, navpoly.poly.centroid.y))
text = scene.addSimpleText(f"Navmesh {navpoly.ident}",
self.waypoint_info_font)
Point(navpoly.poly.centroid.x, navpoly.poly.centroid.y)
)
text = scene.addSimpleText(
f"Navmesh {navpoly.ident}", self.waypoint_info_font
)
text.setBrush(QColor(255, 255, 255))
text.setPen(QColor(255, 255, 255))
text.moveBy(position[0] + 8, position[1])
@@ -370,8 +405,9 @@ class QLiberationMap(QGraphicsView):
for border in navpoly.neighbors.values():
self.draw_navmesh_border(border, scene, navpoly.poly)
def highlight_mouse_navmesh(self, scene: QGraphicsScene, navmesh: NavMesh,
mouse_position: Point) -> None:
def highlight_mouse_navmesh(
self, scene: QGraphicsScene, navmesh: NavMesh, mouse_position: Point
) -> None:
if self.navmesh_highlight is not None:
try:
scene.removeItem(self.navmesh_highlight)
@@ -381,11 +417,15 @@ class QLiberationMap(QGraphicsView):
if navpoly is None:
return
self.navmesh_highlight = self.draw_shapely_poly(
scene, navpoly.poly, CONST.COLORS["transparent"],
CONST.COLORS["light_green_transparent"])
scene,
navpoly.poly,
CONST.COLORS["transparent"],
CONST.COLORS["light_green_transparent"],
)
def draw_shortest_path(self, scene: QGraphicsScene, navmesh: NavMesh,
destination: Point, player: bool) -> None:
def draw_shortest_path(
self, scene: QGraphicsScene, navmesh: NavMesh, destination: Point, player: bool
) -> None:
for line in self.shortest_path_segments:
try:
scene.removeItem(line)
@@ -407,21 +447,36 @@ class QLiberationMap(QGraphicsView):
flight_path_pen = self.flight_path_pen(player, selected=True)
# Draw the line to the *middle* of the waypoint.
offset = self.WAYPOINT_SIZE // 2
self.shortest_path_segments.append(scene.addLine(
prev_pos[0] + offset, prev_pos[1] + offset,
new_pos[0] + offset, new_pos[1] + offset,
flight_path_pen
))
self.shortest_path_segments.append(
scene.addLine(
prev_pos[0] + offset,
prev_pos[1] + offset,
new_pos[0] + offset,
new_pos[1] + offset,
flight_path_pen,
)
)
self.shortest_path_segments.append(scene.addEllipse(
new_pos[0], new_pos[1], self.WAYPOINT_SIZE,
self.WAYPOINT_SIZE, flight_path_pen, flight_path_pen
))
self.shortest_path_segments.append(
scene.addEllipse(
new_pos[0],
new_pos[1],
self.WAYPOINT_SIZE,
self.WAYPOINT_SIZE,
flight_path_pen,
flight_path_pen,
)
)
prev_pos = new_pos
def draw_test_flight_plan(self, scene: QGraphicsScene, task: FlightType,
point_near_target: Point, player: bool) -> None:
def draw_test_flight_plan(
self,
scene: QGraphicsScene,
task: FlightType,
point_near_target: Point,
player: bool,
) -> None:
for line in self.shortest_path_segments:
try:
scene.removeItem(line)
@@ -438,8 +493,16 @@ class QLiberationMap(QGraphicsView):
origin = self.game.theater.enemy_points()[0]
package = Package(target)
flight = Flight(package, F_16C_50, 2, task, start_type="Warm",
departure=origin, arrival=origin, divert=None)
flight = Flight(
package,
F_16C_50,
2,
task,
start_type="Warm",
departure=origin,
arrival=origin,
divert=None,
)
package.add_flight(flight)
planner = FlightPlanBuilder(self.game, package, is_player=player)
try:
@@ -452,31 +515,49 @@ class QLiberationMap(QGraphicsView):
@staticmethod
def should_display_ground_objects_at(cp: ControlPoint) -> bool:
return ((DisplayOptions.sam_ranges and cp.captured) or
(DisplayOptions.enemy_sam_ranges and not cp.captured))
return (DisplayOptions.sam_ranges and cp.captured) or (
DisplayOptions.enemy_sam_ranges and not cp.captured
)
def draw_threat_range(self, scene: QGraphicsScene, group: Group, ground_object: TheaterGroundObject, cp: ControlPoint) -> None:
def draw_threat_range(
self,
scene: QGraphicsScene,
group: Group,
ground_object: TheaterGroundObject,
cp: ControlPoint,
) -> None:
go_pos = self._transform_point(ground_object.position)
detection_range = ground_object.detection_range(group)
threat_range = ground_object.threat_range(group)
if threat_range:
threat_pos = self._transform_point(
ground_object.position + Point(threat_range.meters,
threat_range.meters))
ground_object.position + Point(threat_range.meters, threat_range.meters)
)
threat_radius = Point(*go_pos).distance_to_point(Point(*threat_pos))
# Add threat range circle
scene.addEllipse(go_pos[0] - threat_radius / 2 + 7, go_pos[1] - threat_radius / 2 + 6,
threat_radius, threat_radius, self.threat_pen(cp.captured))
scene.addEllipse(
go_pos[0] - threat_radius / 2 + 7,
go_pos[1] - threat_radius / 2 + 6,
threat_radius,
threat_radius,
self.threat_pen(cp.captured),
)
if detection_range and DisplayOptions.detection_range:
# Add detection range circle
detection_pos = self._transform_point(
ground_object.position + Point(detection_range.meters,
detection_range.meters))
ground_object.position
+ Point(detection_range.meters, detection_range.meters)
)
detection_radius = Point(*go_pos).distance_to_point(Point(*detection_pos))
scene.addEllipse(go_pos[0] - detection_radius/2 + 7, go_pos[1] - detection_radius/2 + 6,
detection_radius, detection_radius, self.detection_pen(cp.captured))
scene.addEllipse(
go_pos[0] - detection_radius / 2 + 7,
go_pos[1] - detection_radius / 2 + 6,
detection_radius,
detection_radius,
self.detection_pen(cp.captured),
)
def draw_ground_objects(self, scene: QGraphicsScene, cp: ControlPoint) -> None:
added_objects = []
@@ -486,8 +567,22 @@ 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], 14, 12, cp, ground_object, self.game, buildings))
buildings = self.game.theater.find_ground_objects_by_obj_name(
ground_object.obj_name
)
scene.addItem(
QMapGroundObject(
self,
go_pos[0],
go_pos[1],
14,
12,
cp,
ground_object,
self.game,
buildings,
)
)
should_display = self.should_display_ground_objects_at(cp)
if ground_object.might_have_aa and should_display:
@@ -508,10 +603,8 @@ class QLiberationMap(QGraphicsView):
if DisplayOptions.culling and self.game.settings.perf_culling:
self.display_culling(scene)
self.display_threat_zones(scene, DisplayOptions.blue_threat_zones,
player=True)
self.display_threat_zones(scene, DisplayOptions.red_threat_zones,
player=False)
self.display_threat_zones(scene, DisplayOptions.blue_threat_zones, player=True)
self.display_threat_zones(scene, DisplayOptions.red_threat_zones, player=False)
if DisplayOptions.navmeshes.blue_navmesh:
self.display_navmesh(scene, player=True)
@@ -522,24 +615,33 @@ class QLiberationMap(QGraphicsView):
pos = self._transform_point(cp.position)
scene.addItem(QMapControlPoint(self, pos[0] - CONST.CP_SIZE / 2,
pos[1] - CONST.CP_SIZE / 2,
CONST.CP_SIZE,
CONST.CP_SIZE, cp, self.game_model))
scene.addItem(
QMapControlPoint(
self,
pos[0] - CONST.CP_SIZE / 2,
pos[1] - CONST.CP_SIZE / 2,
CONST.CP_SIZE,
CONST.CP_SIZE,
cp,
self.game_model,
)
)
if cp.captured:
pen = QPen(brush=CONST.COLORS[playerColor])
brush = CONST.COLORS[playerColor+"_transparent"]
brush = CONST.COLORS[playerColor + "_transparent"]
else:
pen = QPen(brush=CONST.COLORS[enemyColor])
brush = CONST.COLORS[enemyColor+"_transparent"]
brush = CONST.COLORS[enemyColor + "_transparent"]
self.draw_ground_objects(scene, cp)
if cp.target_position is not None:
proj = self._transform_point(cp.target_position)
scene.addLine(QLineF(QPointF(pos[0], pos[1]), QPointF(proj[0], proj[1])),
QPen(CONST.COLORS["green"], width=10, s=Qt.DashDotLine))
scene.addLine(
QLineF(QPointF(pos[0], pos[1]), QPointF(proj[0], proj[1])),
QPen(CONST.COLORS["green"], width=10, s=Qt.DashDotLine),
)
for cp in self.game.theater.enemy_points():
if DisplayOptions.lines:
@@ -585,8 +687,9 @@ class QLiberationMap(QGraphicsView):
continue
self.draw_flight_plan(scene, flight, selected)
def draw_flight_plan(self, scene: QGraphicsScene, flight: Flight,
selected: bool) -> None:
def draw_flight_plan(
self, scene: QGraphicsScene, flight: Flight, selected: bool
) -> None:
is_player = flight.from_cp.captured
pos = self._transform_point(flight.from_cp.position)
@@ -604,8 +707,7 @@ class QLiberationMap(QGraphicsView):
continue
new_pos = self._transform_point(Point(point.x, point.y))
self.draw_flight_path(scene, prev_pos, new_pos, is_player,
selected)
self.draw_flight_path(scene, prev_pos, new_pos, is_player, selected)
self.draw_waypoint(scene, new_pos, is_player, selected)
if selected and DisplayOptions.waypoint_info:
if point.waypoint_type in target_types:
@@ -613,44 +715,63 @@ class QLiberationMap(QGraphicsView):
# Don't draw dozens of targets over each other.
continue
drew_target = True
self.draw_waypoint_info(scene, idx + 1, point, new_pos,
flight.flight_plan)
self.draw_waypoint_info(
scene, idx + 1, point, new_pos, flight.flight_plan
)
prev_pos = tuple(new_pos)
if selected and DisplayOptions.barcap_commit_range:
self.draw_barcap_commit_range(scene, flight)
def draw_barcap_commit_range(self, scene: QGraphicsScene,
flight: Flight) -> None:
def draw_barcap_commit_range(self, scene: QGraphicsScene, flight: Flight) -> None:
if flight.flight_type is not FlightType.BARCAP:
return
if not isinstance(flight.flight_plan, BarCapFlightPlan):
return
start = flight.flight_plan.patrol_start
end = flight.flight_plan.patrol_end
line = LineString([
ShapelyPoint(start.x, start.y),
ShapelyPoint(end.x, end.y),
])
line = LineString(
[
ShapelyPoint(start.x, start.y),
ShapelyPoint(end.x, end.y),
]
)
doctrine = self.game.faction_for(flight.departure.captured).doctrine
bubble = line.buffer(doctrine.cap_engagement_range.meters)
self.flight_path_items.append(self.draw_shapely_poly(
scene, bubble, CONST.COLORS["yellow"], CONST.COLORS["transparent"]
))
self.flight_path_items.append(
self.draw_shapely_poly(
scene, bubble, CONST.COLORS["yellow"], CONST.COLORS["transparent"]
)
)
def draw_waypoint(self, scene: QGraphicsScene,
position: Tuple[float, float], player: bool,
selected: bool) -> None:
def draw_waypoint(
self,
scene: QGraphicsScene,
position: Tuple[float, float],
player: bool,
selected: bool,
) -> None:
waypoint_pen = self.waypoint_pen(player, selected)
waypoint_brush = self.waypoint_brush(player, selected)
self.flight_path_items.append(scene.addEllipse(
position[0], position[1], self.WAYPOINT_SIZE,
self.WAYPOINT_SIZE, waypoint_pen, waypoint_brush
))
self.flight_path_items.append(
scene.addEllipse(
position[0],
position[1],
self.WAYPOINT_SIZE,
self.WAYPOINT_SIZE,
waypoint_pen,
waypoint_brush,
)
)
def draw_waypoint_info(self, scene: QGraphicsScene, number: int,
waypoint: FlightWaypoint, position: Tuple[int, int],
flight_plan: FlightPlan) -> None:
def draw_waypoint_info(
self,
scene: QGraphicsScene,
number: int,
waypoint: FlightWaypoint,
position: Tuple[int, int],
flight_plan: FlightPlan,
) -> None:
altitude = int(waypoint.alt.feet)
altitude_type = "AGL" if waypoint.alt_type == "RADIO" else "MSL"
@@ -669,11 +790,13 @@ class QLiberationMap(QGraphicsView):
pen = QPen(QColor("black"), 0.3)
brush = QColor("white")
text = "\n".join([
f"{number} {waypoint.name}",
f"{altitude} ft {altitude_type}",
tot,
])
text = "\n".join(
[
f"{number} {waypoint.name}",
f"{altitude} ft {altitude_type}",
tot,
]
)
item = scene.addSimpleText(text, self.waypoint_info_font)
item.setFlag(QGraphicsItem.ItemIgnoresTransformations)
@@ -683,19 +806,30 @@ class QLiberationMap(QGraphicsView):
item.setZValue(2)
self.flight_path_items.append(item)
def draw_flight_path(self, scene: QGraphicsScene, pos0: Tuple[float, float],
pos1: Tuple[float, float], player: bool,
selected: bool) -> None:
def draw_flight_path(
self,
scene: QGraphicsScene,
pos0: Tuple[float, float],
pos1: Tuple[float, float],
player: bool,
selected: bool,
) -> None:
flight_path_pen = self.flight_path_pen(player, selected)
# Draw the line to the *middle* of the waypoint.
offset = self.WAYPOINT_SIZE // 2
self.flight_path_items.append(scene.addLine(
pos0[0] + offset, pos0[1] + offset,
pos1[0] + offset, pos1[1] + offset,
flight_path_pen
))
self.flight_path_items.append(
scene.addLine(
pos0[0] + offset,
pos0[1] + offset,
pos1[0] + offset,
pos1[1] + offset,
flight_path_pen,
)
)
def draw_bezier_frontline(self, scene: QGraphicsScene, pen:QPen, frontline: FrontLine) -> None:
def draw_bezier_frontline(
self, scene: QGraphicsScene, pen: QPen, frontline: FrontLine
) -> None:
"""
Thanks to Alquimista for sharing a python implementation of the bezier algorithm this is adapted from.
https://gist.github.com/Alquimista/1274149#file-bezdraw-py
@@ -706,7 +840,9 @@ class QLiberationMap(QGraphicsView):
bezier_fixed_points.append(self._transform_point(segment.point_b))
old_point = bezier_fixed_points[0]
for point in bezier_curve_range(int(len(bezier_fixed_points) * 2), bezier_fixed_points):
for point in bezier_curve_range(
int(len(bezier_fixed_points) * 2), bezier_fixed_points
):
scene.addLine(old_point[0], old_point[1], point[0], point[1], pen=pen)
old_point = point
@@ -715,14 +851,18 @@ class QLiberationMap(QGraphicsView):
for connected_cp in cp.connected_points:
pos2 = self._transform_point(connected_cp.position)
if not cp.captured:
color = CONST.COLORS["dark_"+enemyColor]
color = CONST.COLORS["dark_" + enemyColor]
else:
color = CONST.COLORS["dark_"+playerColor]
color = CONST.COLORS["dark_" + playerColor]
pen = QPen(brush=color)
pen.setColor(color)
pen.setWidth(6)
frontline = FrontLine(cp, connected_cp, self.game.theater)
if cp.captured and not connected_cp.captured and Conflict.has_frontline_between(cp, connected_cp):
if (
cp.captured
and not connected_cp.captured
and Conflict.has_frontline_between(cp, connected_cp)
):
if DisplayOptions.actual_frontline_pos:
self.draw_actual_frontline(frontline, scene, pen)
else:
@@ -730,35 +870,30 @@ class QLiberationMap(QGraphicsView):
else:
self.draw_bezier_frontline(scene, pen, frontline)
def draw_frontline_approximation(self, frontline: FrontLine, scene: QGraphicsScene, pen: QPen) -> None:
def draw_frontline_approximation(
self, frontline: FrontLine, scene: QGraphicsScene, pen: QPen
) -> None:
posx = frontline.position
h = frontline.attack_heading
pos2 = self._transform_point(posx)
self.draw_bezier_frontline(scene, pen, frontline)
p1 = point_from_heading(pos2[0], pos2[1], h+180, 25)
p1 = point_from_heading(pos2[0], pos2[1], h + 180, 25)
p2 = point_from_heading(pos2[0], pos2[1], h, 25)
scene.addItem(
QFrontLine(
p1[0],
p1[1],
p2[0],
p2[1],
frontline,
self.game_model
)
QFrontLine(p1[0], p1[1], p2[0], p2[1], frontline, self.game_model)
)
def draw_actual_frontline(self, frontline: FrontLine, scene: QGraphicsScene, pen: QPen) -> None:
def draw_actual_frontline(
self, frontline: FrontLine, scene: QGraphicsScene, pen: QPen
) -> None:
self.draw_bezier_frontline(scene, pen, frontline)
vector = Conflict.frontline_vector(
frontline.control_point_a,
frontline.control_point_b,
self.game.theater
frontline.control_point_a, frontline.control_point_b, self.game.theater
)
left_pos = self._transform_point(vector[0])
right_pos = self._transform_point(
vector[0].point_from_heading(vector[1], vector[2])
)
vector[0].point_from_heading(vector[1], vector[2])
)
scene.addItem(
QFrontLine(
left_pos[0],
@@ -766,7 +901,7 @@ class QLiberationMap(QGraphicsView):
right_pos[0],
right_pos[1],
frontline,
self.game_model
self.game_model,
)
)
@@ -779,26 +914,48 @@ class QLiberationMap(QGraphicsView):
SMALL_LINE = 2
dist = self.distance_to_pixels(nautical_miles(scale_distance_nm))
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)
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 = 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 = 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)
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 = 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):
@@ -828,7 +985,8 @@ class QLiberationMap(QGraphicsView):
point_b = self.game.theater.reference_points[1]
world_distance = self._transpose_point(
point_b.world_coordinates - point_a.world_coordinates)
point_b.world_coordinates - point_a.world_coordinates
)
image_distance = point_b.image_coordinates - point_a.image_coordinates
x_scale = image_distance.x / world_distance.x
@@ -870,8 +1028,7 @@ class QLiberationMap(QGraphicsView):
scale = self._scaling_factor()
offset = point_a.image_coordinates - scene_point
scaled = self._transpose_point(
Point(offset.x / scale.x, offset.y / scale.y))
scaled = self._transpose_point(Point(offset.x / scale.x, offset.y / scale.y))
return point_a.world_coordinates - scaled
def distance_to_pixels(self, distance: Distance) -> int:
@@ -955,7 +1112,12 @@ class QLiberationMap(QGraphicsView):
for sea_zone in self.game.theater.landmap.sea_zones:
print(sea_zone)
poly = QPolygonF([QPointF(*self._transform_point(Point(point[0], point[1]))) for point in sea_zone.exterior.coords])
poly = QPolygonF(
[
QPointF(*self._transform_point(Point(point[0], point[1])))
for point in sea_zone.exterior.coords
]
)
if self.reference_point_setup_mode:
color = "sea_blue_transparent"
else:
@@ -963,18 +1125,40 @@ class QLiberationMap(QGraphicsView):
scene.addPolygon(poly, CONST.COLORS[color], CONST.COLORS[color])
for inclusion_zone in self.game.theater.landmap.inclusion_zones:
poly = QPolygonF([QPointF(*self._transform_point(Point(point[0], point[1]))) for point in inclusion_zone.exterior.coords])
poly = QPolygonF(
[
QPointF(*self._transform_point(Point(point[0], point[1])))
for point in inclusion_zone.exterior.coords
]
)
if self.reference_point_setup_mode:
scene.addPolygon(poly, CONST.COLORS["grey_transparent"], CONST.COLORS["dark_grey_transparent"])
scene.addPolygon(
poly,
CONST.COLORS["grey_transparent"],
CONST.COLORS["dark_grey_transparent"],
)
else:
scene.addPolygon(poly, CONST.COLORS["grey"], CONST.COLORS["dark_grey"])
scene.addPolygon(
poly, CONST.COLORS["grey"], CONST.COLORS["dark_grey"]
)
for exclusion_zone in self.game.theater.landmap.exclusion_zones:
poly = QPolygonF([QPointF(*self._transform_point(Point(point[0], point[1]))) for point in exclusion_zone.exterior.coords])
poly = QPolygonF(
[
QPointF(*self._transform_point(Point(point[0], point[1])))
for point in exclusion_zone.exterior.coords
]
)
if self.reference_point_setup_mode:
scene.addPolygon(poly, CONST.COLORS["grey_transparent"], CONST.COLORS["dark_dark_grey_transparent"])
scene.addPolygon(
poly,
CONST.COLORS["grey_transparent"],
CONST.COLORS["dark_dark_grey_transparent"],
)
else:
scene.addPolygon(poly, CONST.COLORS["grey"], CONST.COLORS["dark_dark_grey"])
scene.addPolygon(
poly, CONST.COLORS["grey"], CONST.COLORS["dark_dark_grey"]
)
# Uncomment to display plan projection test
# self.projection_test()
@@ -983,15 +1167,18 @@ class QLiberationMap(QGraphicsView):
if self.reference_point_setup_mode:
for i, point in enumerate(self.game.theater.reference_points):
self.scene().addRect(
QRectF(point.image_coordinates.x, point.image_coordinates.y,
25, 25), pen=CONST.COLORS["red"],
brush=CONST.COLORS["red"])
QRectF(
point.image_coordinates.x, point.image_coordinates.y, 25, 25
),
pen=CONST.COLORS["red"],
brush=CONST.COLORS["red"],
)
text = self.scene().addText(
f"P{i} = {point.image_coordinates}",
font=QFont("Trebuchet MS", 14, weight=8, italic=False))
font=QFont("Trebuchet MS", 14, weight=8, italic=False),
)
text.setDefaultTextColor(CONST.COLORS["red"])
text.setPos(point.image_coordinates.x + 26,
point.image_coordinates.y)
text.setPos(point.image_coordinates.x + 26, point.image_coordinates.y)
# Set to True to visually debug _transform_point.
draw_transformed = False
@@ -1000,10 +1187,12 @@ class QLiberationMap(QGraphicsView):
self.scene().addRect(
QRectF(x, y, 25, 25),
pen=CONST.COLORS["red"],
brush=CONST.COLORS["red"])
brush=CONST.COLORS["red"],
)
text = self.scene().addText(
f"P{i}' = {x}, {y}",
font=QFont("Trebuchet MS", 14, weight=8, italic=False))
font=QFont("Trebuchet MS", 14, weight=8, italic=False),
)
text.setDefaultTextColor(CONST.COLORS["red"])
text.setPos(x + 26, y)
@@ -1023,7 +1212,9 @@ class QLiberationMap(QGraphicsView):
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.movement_line = QtWidgets.QGraphicsLineItem(
QLineF(QPointF(*position), QPointF(*position))
)
self.scene().addItem(self.movement_line)
def is_valid_ship_pos(self, scene_position: Point) -> bool:
@@ -1043,7 +1234,8 @@ class QLiberationMap(QGraphicsView):
if self.state == QLiberationMapState.MOVING_UNIT:
self.setCursor(Qt.PointingHandCursor)
self.movement_line.setLine(
QLineF(self.movement_line.line().p1(), event.scenePos()))
QLineF(self.movement_line.line().p1(), event.scenePos())
)
if self.is_valid_ship_pos(mouse_position):
self.movement_line.setPen(CONST.COLORS["green"])
@@ -1053,21 +1245,28 @@ class QLiberationMap(QGraphicsView):
mouse_world_pos = self._scene_to_dcs_coords(mouse_position)
if DisplayOptions.navmeshes.blue_navmesh:
self.highlight_mouse_navmesh(
self.scene(), self.game.blue_navmesh,
self._scene_to_dcs_coords(mouse_position))
self.scene(),
self.game.blue_navmesh,
self._scene_to_dcs_coords(mouse_position),
)
if DisplayOptions.path_debug.shortest_path:
self.draw_shortest_path(self.scene(), self.game.blue_navmesh,
mouse_world_pos, player=True)
self.draw_shortest_path(
self.scene(), self.game.blue_navmesh, mouse_world_pos, player=True
)
if DisplayOptions.navmeshes.red_navmesh:
self.highlight_mouse_navmesh(
self.scene(), self.game.red_navmesh, mouse_world_pos)
self.scene(), self.game.red_navmesh, mouse_world_pos
)
debug_blue = DisplayOptions.path_debug_faction.blue
if DisplayOptions.path_debug.shortest_path:
self.draw_shortest_path(
self.scene(), self.game.navmesh_for(player=debug_blue),
mouse_world_pos, player=False)
self.scene(),
self.game.navmesh_for(player=debug_blue),
mouse_world_pos,
player=False,
)
elif not DisplayOptions.path_debug.hide:
if DisplayOptions.path_debug.barcap:
task = FlightType.BARCAP
@@ -1080,10 +1279,10 @@ class QLiberationMap(QGraphicsView):
elif DisplayOptions.path_debug.tarcap:
task = FlightType.TARCAP
else:
raise ValueError(
"Unexpected value for DisplayOptions.path_debug")
self.draw_test_flight_plan(self.scene(), task, mouse_world_pos,
player=debug_blue)
raise ValueError("Unexpected value for DisplayOptions.path_debug")
self.draw_test_flight_plan(
self.scene(), task, mouse_world_pos, player=debug_blue
)
def sceneMousePressEvent(self, event: QGraphicsSceneMouseEvent):
if self.state == QLiberationMapState.MOVING_UNIT:
@@ -1109,4 +1308,4 @@ class QLiberationMap(QGraphicsView):
self.scene().removeItem(self.movement_line)
except:
pass
self.selected_cp = None
self.selected_cp = None