diff --git a/gen/flights/flightplan.py b/gen/flights/flightplan.py
index 7919ae9f..430a8c11 100644
--- a/gen/flights/flightplan.py
+++ b/gen/flights/flightplan.py
@@ -659,7 +659,6 @@ class FlightPlanBuilder:
builder = WaypointBuilder(self.game.conditions, flight, self.doctrine)
start, end = builder.race_track(start, end, patrol_alt)
- descent, land = builder.rtb(flight.from_cp)
return BarCapFlightPlan(
package=self.package,
@@ -668,7 +667,7 @@ class FlightPlanBuilder:
takeoff=builder.takeoff(flight.from_cp),
patrol_start=start,
patrol_end=end,
- land=land
+ land=builder.land(flight.from_cp)
)
def generate_frontline_cap(self, flight: Flight) -> FrontLineCapFlightPlan:
@@ -707,9 +706,8 @@ class FlightPlanBuilder:
# Create points
builder = WaypointBuilder(self.game.conditions, flight, self.doctrine)
-
start, end = builder.race_track(orbit0p, orbit1p, patrol_alt)
- descent, land = builder.rtb(flight.from_cp)
+
return FrontLineCapFlightPlan(
package=self.package,
flight=flight,
@@ -721,7 +719,7 @@ class FlightPlanBuilder:
takeoff=builder.takeoff(flight.from_cp),
patrol_start=start,
patrol_end=end,
- land=land
+ land=builder.land(flight.from_cp)
)
def generate_dead(self, flight: Flight,
@@ -780,7 +778,6 @@ class FlightPlanBuilder:
ingress, target, egress = builder.escort(
self.package.waypoints.ingress, self.package.target,
self.package.waypoints.egress)
- descent, land = builder.rtb(flight.from_cp)
return StrikeFlightPlan(
package=self.package,
@@ -792,7 +789,7 @@ class FlightPlanBuilder:
targets=[target],
egress=egress,
split=builder.split(self.package.waypoints.split),
- land=land
+ land=builder.land(flight.from_cp)
)
def generate_cas(self, flight: Flight) -> CasFlightPlan:
@@ -814,7 +811,6 @@ class FlightPlanBuilder:
egress = ingress.point_from_heading(heading, distance)
builder = WaypointBuilder(self.game.conditions, flight, self.doctrine)
- descent, land = builder.rtb(flight.from_cp)
return CasFlightPlan(
package=self.package,
@@ -824,7 +820,7 @@ class FlightPlanBuilder:
patrol_start=builder.ingress_cas(ingress, location),
target=builder.cas(center),
patrol_end=builder.egress(egress, location),
- land=land
+ land=builder.land(flight.from_cp)
)
@staticmethod
@@ -894,28 +890,6 @@ class FlightPlanBuilder:
self.doctrine.hold_distance)
# TODO: Make a model for the waypoint builder and use that in the UI.
- def generate_ascend_point(self, flight: Flight,
- departure: ControlPoint) -> FlightWaypoint:
- """Generate ascend point.
-
- Args:
- flight: The flight to generate the descend point for.
- departure: Departure airfield or carrier.
- """
- builder = WaypointBuilder(self.game.conditions, flight, self.doctrine)
- return builder.ascent(departure)
-
- def generate_descend_point(self, flight: Flight,
- arrival: ControlPoint) -> FlightWaypoint:
- """Generate approach/descend point.
-
- Args:
- flight: The flight to generate the descend point for.
- arrival: Arrival airfield or carrier.
- """
- builder = WaypointBuilder(self.game.conditions, flight, self.doctrine)
- return builder.descent(arrival)
-
def generate_rtb_waypoint(self, flight: Flight,
arrival: ControlPoint) -> FlightWaypoint:
"""Generate RTB landing point.
@@ -954,7 +928,6 @@ class FlightPlanBuilder:
target_waypoints.append(
self.target_area_waypoint(flight, location, builder))
- descent, land = builder.rtb(flight.from_cp)
return StrikeFlightPlan(
package=self.package,
flight=flight,
@@ -965,7 +938,7 @@ class FlightPlanBuilder:
targets=target_waypoints,
egress=builder.egress(self.package.waypoints.egress, location),
split=builder.split(self.package.waypoints.split),
- land=land
+ land=builder.land(flight.from_cp)
)
def _retreating_rendezvous_point(self, attack_transition: Point) -> Point:
diff --git a/gen/flights/traveltime.py b/gen/flights/traveltime.py
index 17f8ec36..0bddfcaf 100644
--- a/gen/flights/traveltime.py
+++ b/gen/flights/traveltime.py
@@ -118,8 +118,11 @@ class TotEstimator:
def takeoff_time_for_flight(self, flight: Flight) -> Optional[timedelta]:
travel_time = self.travel_time_to_rendezvous_or_target(flight)
if travel_time is None:
- logging.warning("Found no rendezvous or target point. Cannot "
- f"estimate takeoff time takeoff time for {flight}")
+ from gen.flights.flightplan import CustomFlightPlan
+ if not isinstance(flight.flight_plan, CustomFlightPlan):
+ logging.warning(
+ "Found no rendezvous or target point. Cannot estimate "
+ f"takeoff time takeoff time for {flight}.")
return None
from gen.flights.flightplan import FormationFlightPlan
diff --git a/gen/flights/waypointbuilder.py b/gen/flights/waypointbuilder.py
index ddc76b5f..3b67e8e0 100644
--- a/gen/flights/waypointbuilder.py
+++ b/gen/flights/waypointbuilder.py
@@ -7,11 +7,9 @@ from dcs.mapping import Point
from dcs.unit import Unit
from game.data.doctrine import Doctrine
-from game.utils import nm_to_meter
from game.weather import Conditions
from theater import ControlPoint, MissionTarget, TheaterGroundObject
from .flight import Flight, FlightWaypoint, FlightWaypointType
-from ..runways import RunwayAssigner
@dataclass(frozen=True)
@@ -57,52 +55,6 @@ class WaypointBuilder:
waypoint.pretty_name = "Takeoff"
return waypoint
- def ascent(self, departure: ControlPoint) -> FlightWaypoint:
- """Create ascent waypoint for the given departure airfield or carrier.
-
- Args:
- departure: Departure airfield or carrier.
- """
- heading = RunwayAssigner(self.conditions).takeoff_heading(departure)
- position = departure.position.point_from_heading(
- heading, nm_to_meter(5)
- )
- waypoint = FlightWaypoint(
- FlightWaypointType.ASCEND_POINT,
- position.x,
- position.y,
- 500 if self.is_helo else self.doctrine.pattern_altitude
- )
- waypoint.name = "ASCEND"
- waypoint.alt_type = "RADIO"
- waypoint.description = "Ascend"
- waypoint.pretty_name = "Ascend"
- return waypoint
-
- def descent(self, arrival: ControlPoint) -> FlightWaypoint:
- """Create descent waypoint for the given arrival airfield or carrier.
-
- Args:
- arrival: Arrival airfield or carrier.
- """
- landing_heading = RunwayAssigner(self.conditions).landing_heading(
- arrival)
- heading = (landing_heading + 180) % 360
- position = arrival.position.point_from_heading(
- heading, nm_to_meter(5)
- )
- waypoint = FlightWaypoint(
- FlightWaypointType.DESCENT_POINT,
- position.x,
- position.y,
- 300 if self.is_helo else self.doctrine.pattern_altitude
- )
- waypoint.name = "DESCEND"
- waypoint.alt_type = "RADIO"
- waypoint.description = "Descend to pattern altitude"
- waypoint.pretty_name = "Descend"
- return waypoint
-
@staticmethod
def land(arrival: ControlPoint) -> FlightWaypoint:
"""Create descent waypoint for the given arrival airfield or carrier.
@@ -326,15 +278,6 @@ class WaypointBuilder:
return (self.race_track_start(start, altitude),
self.race_track_end(end, altitude))
- def rtb(self,
- arrival: ControlPoint) -> Tuple[FlightWaypoint, FlightWaypoint]:
- """Creates descent ant landing waypoints for the given control point.
-
- Args:
- arrival: Arrival airfield or carrier.
- """
- return self.descent(arrival), self.land(arrival)
-
def escort(self, ingress: Point, target: MissionTarget, egress: Point) -> \
Tuple[FlightWaypoint, FlightWaypoint, FlightWaypoint]:
"""Creates the waypoints needed to escort the package.
diff --git a/qt_ui/widgets/combos/QPredefinedWaypointSelectionComboBox.py b/qt_ui/widgets/combos/QPredefinedWaypointSelectionComboBox.py
index 72ece41e..2a9f8bc9 100644
--- a/qt_ui/widgets/combos/QPredefinedWaypointSelectionComboBox.py
+++ b/qt_ui/widgets/combos/QPredefinedWaypointSelectionComboBox.py
@@ -44,7 +44,6 @@ class QPredefinedWaypointSelectionComboBox(QFilteredComboBox):
i = 0
def add_model_item(i, model, name, wpt):
- print(name)
item = QStandardItem(name)
model.setItem(i, 0, item)
self.wpts.append(wpt)
@@ -79,7 +78,7 @@ class QPredefinedWaypointSelectionComboBox(QFilteredComboBox):
0
)
wpt.alt_type = "RADIO"
- wpt.name = wpt.name = "[" + str(ground_object.obj_name) + "] : " + ground_object.category + " #" + str(ground_object.object_id)
+ wpt.name = ground_object.waypoint_name
wpt.pretty_name = wpt.name
wpt.obj_name = ground_object.obj_name
wpt.targets.append(ground_object)
diff --git a/qt_ui/windows/mission/flight/waypoints/QFlightWaypointTab.py b/qt_ui/windows/mission/flight/waypoints/QFlightWaypointTab.py
index 4352ac47..c480da2a 100644
--- a/qt_ui/windows/mission/flight/waypoints/QFlightWaypointTab.py
+++ b/qt_ui/windows/mission/flight/waypoints/QFlightWaypointTab.py
@@ -1,4 +1,4 @@
-from typing import List, Optional
+from typing import Iterable, List, Optional
from PySide2.QtCore import Signal
from PySide2.QtWidgets import (
@@ -20,7 +20,7 @@ from gen.flights.flightplan import (
)
from qt_ui.windows.mission.flight.waypoints.QFlightWaypointList import \
QFlightWaypointList
-from qt_ui.windows.mission.flight.waypoints\
+from qt_ui.windows.mission.flight.waypoints \
.QPredefinedWaypointSelectionWindow import \
QPredefinedWaypointSelectionWindow
from theater import FrontLine
@@ -38,8 +38,6 @@ class QFlightWaypointTab(QFrame):
self.planner = FlightPlanBuilder(self.game, package, is_player=True)
self.flight_waypoint_list: Optional[QFlightWaypointList] = None
- self.ascend_waypoint: Optional[QPushButton] = None
- self.descend_waypoint: Optional[QPushButton] = None
self.rtb_waypoint: Optional[QPushButton] = None
self.delete_selected: Optional[QPushButton] = None
self.open_fast_waypoint_button: Optional[QPushButton] = None
@@ -82,14 +80,6 @@ class QFlightWaypointTab(QFrame):
rlayout.addWidget(QLabel("Advanced : "))
rlayout.addWidget(QLabel("Do not use for AI flights"))
- self.ascend_waypoint = QPushButton("Add Ascend Waypoint")
- self.ascend_waypoint.clicked.connect(self.on_ascend_waypoint)
- rlayout.addWidget(self.ascend_waypoint)
-
- self.descend_waypoint = QPushButton("Add Descend Waypoint")
- self.descend_waypoint.clicked.connect(self.on_descend_waypoint)
- rlayout.addWidget(self.descend_waypoint)
-
self.rtb_waypoint = QPushButton("Add RTB Waypoint")
self.rtb_waypoint.clicked.connect(self.on_rtb_waypoint)
rlayout.addWidget(self.rtb_waypoint)
@@ -115,47 +105,43 @@ class QFlightWaypointTab(QFrame):
# Need to degrade to a custom flight plan and remove the waypoint.
# If the waypoint is a target waypoint and is not the last target
# waypoint, we don't need to degrade.
- flight_plan = self.flight.flight_plan
- if isinstance(flight_plan, StrikeFlightPlan):
- if waypoint in flight_plan.targets and len(flight_plan.targets) > 1:
- flight_plan.targets.remove(waypoint)
+ if isinstance(self.flight.flight_plan, StrikeFlightPlan):
+ is_target = waypoint in self.flight.flight_plan.targets
+ if is_target and len(self.flight.flight_plan.targets) > 1:
+ self.flight.flight_plan.targets.remove(waypoint)
return
- if not isinstance(flight_plan, CustomFlightPlan):
- flight_plan = CustomFlightPlan(
- package=self.flight.package,
- flight=self.flight,
- custom_waypoints=flight_plan.waypoints
- )
-
- flight_plan.waypoints.remove(waypoint)
- self.flight.flight_plan = flight_plan
+ self.degrade_to_custom_flight_plan()
+ self.flight.flight_plan.waypoints.remove(waypoint)
def on_fast_waypoint(self):
self.subwindow = QPredefinedWaypointSelectionWindow(self.game, self.flight, self.flight_waypoint_list)
- self.subwindow.finished.connect(self.on_change)
+ self.subwindow.waypoints_added.connect(self.on_waypoints_added)
self.subwindow.show()
- def on_ascend_waypoint(self):
- ascend = self.planner.generate_ascend_point(self.flight,
- self.flight.from_cp)
- self.flight.points.append(ascend)
+ def on_waypoints_added(self, waypoints: Iterable[FlightWaypoint]) -> None:
+ if not waypoints:
+ return
+ self.degrade_to_custom_flight_plan()
+ self.flight.flight_plan.waypoints.extend(waypoints)
self.flight_waypoint_list.update_list()
self.on_change()
def on_rtb_waypoint(self):
rtb = self.planner.generate_rtb_waypoint(self.flight,
self.flight.from_cp)
- self.flight.points.append(rtb)
+ self.degrade_to_custom_flight_plan()
+ self.flight.flight_plan.waypoints.append(rtb)
self.flight_waypoint_list.update_list()
self.on_change()
- def on_descend_waypoint(self):
- descend = self.planner.generate_descend_point(self.flight,
- self.flight.from_cp)
- self.flight.points.append(descend)
- self.flight_waypoint_list.update_list()
- self.on_change()
+ def degrade_to_custom_flight_plan(self) -> None:
+ if not isinstance(self.flight.flight_plan, CustomFlightPlan):
+ self.flight.flight_plan = CustomFlightPlan(
+ package=self.flight.package,
+ flight=self.flight,
+ custom_waypoints=self.flight.flight_plan.waypoints
+ )
def confirm_recreate(self, task: FlightType) -> None:
result = QMessageBox.question(
diff --git a/qt_ui/windows/mission/flight/waypoints/QPredefinedWaypointSelectionWindow.py b/qt_ui/windows/mission/flight/waypoints/QPredefinedWaypointSelectionWindow.py
index e7e2a90c..ccec5034 100644
--- a/qt_ui/windows/mission/flight/waypoints/QPredefinedWaypointSelectionWindow.py
+++ b/qt_ui/windows/mission/flight/waypoints/QPredefinedWaypointSelectionWindow.py
@@ -1,11 +1,20 @@
-from PySide2.QtCore import Qt
-from PySide2.QtWidgets import QDialog, QLabel, QHBoxLayout, QVBoxLayout, QPushButton, QCheckBox
+from PySide2.QtCore import Qt, Signal
+from PySide2.QtWidgets import (
+ QCheckBox,
+ QDialog,
+ QHBoxLayout,
+ QLabel,
+ QPushButton,
+ QVBoxLayout,
+)
from game import Game
from gen.flights.flight import Flight
from qt_ui.uiconstants import EVENT_ICONS
-from qt_ui.widgets.combos.QPredefinedWaypointSelectionComboBox import QPredefinedWaypointSelectionComboBox
-from qt_ui.windows.mission.flight.waypoints.QFlightWaypointInfoBox import QFlightWaypointInfoBox
+from qt_ui.widgets.combos.QPredefinedWaypointSelectionComboBox import \
+ QPredefinedWaypointSelectionComboBox
+from qt_ui.windows.mission.flight.waypoints.QFlightWaypointInfoBox import \
+ QFlightWaypointInfoBox
PREDEFINED_WAYPOINT_CATEGORIES = [
"Frontline (CAS AREA)",
@@ -17,6 +26,8 @@ PREDEFINED_WAYPOINT_CATEGORIES = [
class QPredefinedWaypointSelectionWindow(QDialog):
+ # List of FlightWaypoint
+ waypoints_added = Signal(list)
def __init__(self, game: Game, flight: Flight, flight_waypoint_list):
super(QPredefinedWaypointSelectionWindow, self).__init__()
@@ -44,7 +55,6 @@ class QPredefinedWaypointSelectionWindow(QDialog):
self.init_ui()
self.on_select_wpt_changed()
- print("DONE")
def init_ui(self):
@@ -77,12 +87,5 @@ class QPredefinedWaypointSelectionWindow(QDialog):
self.add_button.setDisabled(False)
def add_waypoint(self):
-
- for wpt in self.selected_waypoints:
- self.flight.points.append(wpt)
-
- self.flight_waypoint_list.update_list()
+ self.waypoints_added.emit(self.selected_waypoints)
self.close()
-
-
-
diff --git a/theater/theatergroundobject.py b/theater/theatergroundobject.py
index 0e8b3c87..a0694974 100644
--- a/theater/theatergroundobject.py
+++ b/theater/theatergroundobject.py
@@ -99,6 +99,10 @@ class TheaterGroundObject(MissionTarget):
"""The name of the unit group."""
return f"{self.category}|{self.group_id}"
+ @property
+ def waypoint_name(self) -> str:
+ return f"[{self.name}] {self.category}"
+
def __str__(self) -> str:
return NAME_BY_CATEGORY[self.category]
@@ -136,6 +140,10 @@ class BuildingGroundObject(TheaterGroundObject):
"""The name of the unit group."""
return f"{self.category}|{self.group_id}|{self.object_id}"
+ @property
+ def waypoint_name(self) -> str:
+ return f"{super().waypoint_name} #{self.object_id}"
+
class GenericCarrierGroundObject(TheaterGroundObject):
pass