Fix custom waypoints.

Like with deleting waypoints, these will degrade the flight plan to the
2.1 behavior.

Ascend/descend points aren't in use any more, so I removed those.
This commit is contained in:
Dan Albert 2020-11-19 00:29:05 -08:00
parent 4b7b4bf110
commit 94c5ed8bdc
7 changed files with 58 additions and 143 deletions

View File

@ -101,6 +101,10 @@ class TheaterGroundObject(MissionTarget):
"""The name of the unit group.""" """The name of the unit group."""
return f"{self.category}|{self.group_id}" return f"{self.category}|{self.group_id}"
@property
def waypoint_name(self) -> str:
return f"[{self.name}] {self.category}"
def __str__(self) -> str: def __str__(self) -> str:
return NAME_BY_CATEGORY[self.category] return NAME_BY_CATEGORY[self.category]
@ -155,6 +159,10 @@ class BuildingGroundObject(TheaterGroundObject):
"""The name of the unit group.""" """The name of the unit group."""
return f"{self.category}|{self.group_id}|{self.object_id}" 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 NavalGroundObject(TheaterGroundObject): class NavalGroundObject(TheaterGroundObject):
def mission_types(self, for_player: bool) -> Iterator[FlightType]: def mission_types(self, for_player: bool) -> Iterator[FlightType]:

View File

@ -769,7 +769,6 @@ class FlightPlanBuilder:
builder = WaypointBuilder(self.game.conditions, flight, self.doctrine) builder = WaypointBuilder(self.game.conditions, flight, self.doctrine)
start, end = builder.race_track(start, end, patrol_alt) start, end = builder.race_track(start, end, patrol_alt)
descent, land = builder.rtb(flight.from_cp)
return BarCapFlightPlan( return BarCapFlightPlan(
package=self.package, package=self.package,
@ -778,7 +777,7 @@ class FlightPlanBuilder:
takeoff=builder.takeoff(flight.from_cp), takeoff=builder.takeoff(flight.from_cp),
patrol_start=start, patrol_start=start,
patrol_end=end, patrol_end=end,
land=land land=builder.land(flight.from_cp)
) )
def generate_sweep(self, flight: Flight) -> SweepFlightPlan: def generate_sweep(self, flight: Flight) -> SweepFlightPlan:
@ -794,8 +793,6 @@ class FlightPlanBuilder:
-self.doctrine.sweep_distance) -self.doctrine.sweep_distance)
builder = WaypointBuilder(self.game.conditions, flight, self.doctrine) builder = WaypointBuilder(self.game.conditions, flight, self.doctrine)
descent, land = builder.rtb(flight.from_cp)
start, end = builder.sweep(start, target, start, end = builder.sweep(start, target,
self.doctrine.ingress_altitude) self.doctrine.ingress_altitude)
@ -807,7 +804,7 @@ class FlightPlanBuilder:
hold=builder.hold(self._hold_point(flight)), hold=builder.hold(self._hold_point(flight)),
sweep_start=start, sweep_start=start,
sweep_end=end, sweep_end=end,
land=land land=builder.land(flight.from_cp)
) )
def racetrack_for_objective(self, def racetrack_for_objective(self,
@ -894,7 +891,6 @@ class FlightPlanBuilder:
orbit0p, orbit1p = self.racetrack_for_objective(location) orbit0p, orbit1p = self.racetrack_for_objective(location)
start, end = builder.race_track(orbit0p, orbit1p, patrol_alt) start, end = builder.race_track(orbit0p, orbit1p, patrol_alt)
descent, land = builder.rtb(flight.from_cp)
return TarCapFlightPlan( return TarCapFlightPlan(
package=self.package, package=self.package,
flight=flight, flight=flight,
@ -907,7 +903,7 @@ class FlightPlanBuilder:
takeoff=builder.takeoff(flight.from_cp), takeoff=builder.takeoff(flight.from_cp),
patrol_start=start, patrol_start=start,
patrol_end=end, patrol_end=end,
land=land land=builder.land(flight.from_cp)
) )
def generate_dead(self, flight: Flight, def generate_dead(self, flight: Flight,
@ -965,7 +961,6 @@ class FlightPlanBuilder:
ingress, target, egress = builder.escort( ingress, target, egress = builder.escort(
self.package.waypoints.ingress, self.package.target, self.package.waypoints.ingress, self.package.target,
self.package.waypoints.egress) self.package.waypoints.egress)
descent, land = builder.rtb(flight.from_cp)
return StrikeFlightPlan( return StrikeFlightPlan(
package=self.package, package=self.package,
@ -977,7 +972,7 @@ class FlightPlanBuilder:
targets=[target], targets=[target],
egress=egress, egress=egress,
split=builder.split(self.package.waypoints.split), split=builder.split(self.package.waypoints.split),
land=land land=builder.land(flight.from_cp)
) )
def generate_cas(self, flight: Flight) -> CasFlightPlan: def generate_cas(self, flight: Flight) -> CasFlightPlan:
@ -999,7 +994,6 @@ class FlightPlanBuilder:
egress = ingress.point_from_heading(heading, distance) egress = ingress.point_from_heading(heading, distance)
builder = WaypointBuilder(self.game.conditions, flight, self.doctrine) builder = WaypointBuilder(self.game.conditions, flight, self.doctrine)
descent, land = builder.rtb(flight.from_cp)
return CasFlightPlan( return CasFlightPlan(
package=self.package, package=self.package,
@ -1009,7 +1003,7 @@ class FlightPlanBuilder:
patrol_start=builder.ingress_cas(ingress, location), patrol_start=builder.ingress_cas(ingress, location),
target=builder.cas(center), target=builder.cas(center),
patrol_end=builder.egress(egress, location), patrol_end=builder.egress(egress, location),
land=land land=builder.land(flight.from_cp)
) )
@staticmethod @staticmethod
@ -1081,28 +1075,6 @@ class FlightPlanBuilder:
self.doctrine.hold_distance) self.doctrine.hold_distance)
# TODO: Make a model for the waypoint builder and use that in the UI. # 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, def generate_rtb_waypoint(self, flight: Flight,
arrival: ControlPoint) -> FlightWaypoint: arrival: ControlPoint) -> FlightWaypoint:
"""Generate RTB landing point. """Generate RTB landing point.
@ -1143,7 +1115,6 @@ class FlightPlanBuilder:
target_waypoints.append( target_waypoints.append(
self.target_area_waypoint(flight, location, builder)) self.target_area_waypoint(flight, location, builder))
descent, land = builder.rtb(flight.from_cp)
return StrikeFlightPlan( return StrikeFlightPlan(
package=self.package, package=self.package,
flight=flight, flight=flight,
@ -1154,7 +1125,7 @@ class FlightPlanBuilder:
targets=target_waypoints, targets=target_waypoints,
egress=builder.egress(self.package.waypoints.egress, location), egress=builder.egress(self.package.waypoints.egress, location),
split=builder.split(self.package.waypoints.split), split=builder.split(self.package.waypoints.split),
land=land land=builder.land(flight.from_cp)
) )
def _retreating_rendezvous_point(self, attack_transition: Point) -> Point: def _retreating_rendezvous_point(self, attack_transition: Point) -> Point:

View File

@ -118,8 +118,11 @@ class TotEstimator:
def takeoff_time_for_flight(self, flight: Flight) -> Optional[timedelta]: def takeoff_time_for_flight(self, flight: Flight) -> Optional[timedelta]:
travel_time = self.travel_time_to_rendezvous_or_target(flight) travel_time = self.travel_time_to_rendezvous_or_target(flight)
if travel_time is None: if travel_time is None:
logging.warning("Found no rendezvous or target point. Cannot " from gen.flights.flightplan import CustomFlightPlan
f"estimate takeoff time takeoff time for {flight}") 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 return None
from gen.flights.flightplan import FormationFlightPlan from gen.flights.flightplan import FormationFlightPlan

View File

@ -58,52 +58,6 @@ class WaypointBuilder:
waypoint.pretty_name = "Takeoff" waypoint.pretty_name = "Takeoff"
return waypoint 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 @staticmethod
def land(arrival: ControlPoint) -> FlightWaypoint: def land(arrival: ControlPoint) -> FlightWaypoint:
"""Create descent waypoint for the given arrival airfield or carrier. """Create descent waypoint for the given arrival airfield or carrier.
@ -385,15 +339,6 @@ class WaypointBuilder:
return (self.sweep_start(start, altitude), return (self.sweep_start(start, altitude),
self.sweep_end(end, altitude)) self.sweep_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) -> \ def escort(self, ingress: Point, target: MissionTarget, egress: Point) -> \
Tuple[FlightWaypoint, FlightWaypoint, FlightWaypoint]: Tuple[FlightWaypoint, FlightWaypoint, FlightWaypoint]:
"""Creates the waypoints needed to escort the package. """Creates the waypoints needed to escort the package.

View File

@ -44,7 +44,6 @@ class QPredefinedWaypointSelectionComboBox(QFilteredComboBox):
i = 0 i = 0
def add_model_item(i, model, name, wpt): def add_model_item(i, model, name, wpt):
print(name)
item = QStandardItem(name) item = QStandardItem(name)
model.setItem(i, 0, item) model.setItem(i, 0, item)
self.wpts.append(wpt) self.wpts.append(wpt)
@ -79,7 +78,7 @@ class QPredefinedWaypointSelectionComboBox(QFilteredComboBox):
0 0
) )
wpt.alt_type = "RADIO" 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.pretty_name = wpt.name
wpt.obj_name = ground_object.obj_name wpt.obj_name = ground_object.obj_name
wpt.targets.append(ground_object) wpt.targets.append(ground_object)

View File

@ -1,5 +1,5 @@
import logging import logging
from typing import List, Optional from typing import Iterable, List, Optional
from PySide2.QtCore import Signal from PySide2.QtCore import Signal
from PySide2.QtWidgets import ( from PySide2.QtWidgets import (
@ -39,8 +39,6 @@ class QFlightWaypointTab(QFrame):
self.planner = FlightPlanBuilder(self.game, package, is_player=True) self.planner = FlightPlanBuilder(self.game, package, is_player=True)
self.flight_waypoint_list: Optional[QFlightWaypointList] = None 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.rtb_waypoint: Optional[QPushButton] = None
self.delete_selected: Optional[QPushButton] = None self.delete_selected: Optional[QPushButton] = None
self.open_fast_waypoint_button: Optional[QPushButton] = None self.open_fast_waypoint_button: Optional[QPushButton] = None
@ -74,14 +72,6 @@ class QFlightWaypointTab(QFrame):
rlayout.addWidget(QLabel("<strong>Advanced : </strong>")) rlayout.addWidget(QLabel("<strong>Advanced : </strong>"))
rlayout.addWidget(QLabel("<small>Do not use for AI flights</small>")) rlayout.addWidget(QLabel("<small>Do not use for AI flights</small>"))
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 = QPushButton("Add RTB Waypoint")
self.rtb_waypoint.clicked.connect(self.on_rtb_waypoint) self.rtb_waypoint.clicked.connect(self.on_rtb_waypoint)
rlayout.addWidget(self.rtb_waypoint) rlayout.addWidget(self.rtb_waypoint)
@ -107,47 +97,43 @@ class QFlightWaypointTab(QFrame):
# Need to degrade to a custom flight plan and remove the waypoint. # 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 # If the waypoint is a target waypoint and is not the last target
# waypoint, we don't need to degrade. # waypoint, we don't need to degrade.
flight_plan = self.flight.flight_plan if isinstance(self.flight.flight_plan, StrikeFlightPlan):
if isinstance(flight_plan, StrikeFlightPlan): is_target = waypoint in self.flight.flight_plan.targets
if waypoint in flight_plan.targets and len(flight_plan.targets) > 1: if is_target and len(self.flight.flight_plan.targets) > 1:
flight_plan.targets.remove(waypoint) self.flight.flight_plan.targets.remove(waypoint)
return return
if not isinstance(flight_plan, CustomFlightPlan): self.degrade_to_custom_flight_plan()
flight_plan = CustomFlightPlan( self.flight.flight_plan.waypoints.remove(waypoint)
package=self.flight.package,
flight=self.flight,
custom_waypoints=flight_plan.waypoints
)
flight_plan.waypoints.remove(waypoint)
self.flight.flight_plan = flight_plan
def on_fast_waypoint(self): def on_fast_waypoint(self):
self.subwindow = QPredefinedWaypointSelectionWindow(self.game, self.flight, self.flight_waypoint_list) 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() self.subwindow.show()
def on_ascend_waypoint(self): def on_waypoints_added(self, waypoints: Iterable[FlightWaypoint]) -> None:
ascend = self.planner.generate_ascend_point(self.flight, if not waypoints:
self.flight.from_cp) return
self.flight.points.append(ascend) self.degrade_to_custom_flight_plan()
self.flight.flight_plan.waypoints.extend(waypoints)
self.flight_waypoint_list.update_list() self.flight_waypoint_list.update_list()
self.on_change() self.on_change()
def on_rtb_waypoint(self): def on_rtb_waypoint(self):
rtb = self.planner.generate_rtb_waypoint(self.flight, rtb = self.planner.generate_rtb_waypoint(self.flight,
self.flight.from_cp) 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.flight_waypoint_list.update_list()
self.on_change() self.on_change()
def on_descend_waypoint(self): def degrade_to_custom_flight_plan(self) -> None:
descend = self.planner.generate_descend_point(self.flight, if not isinstance(self.flight.flight_plan, CustomFlightPlan):
self.flight.from_cp) self.flight.flight_plan = CustomFlightPlan(
self.flight.points.append(descend) package=self.flight.package,
self.flight_waypoint_list.update_list() flight=self.flight,
self.on_change() custom_waypoints=self.flight.flight_plan.waypoints
)
def confirm_recreate(self, task: FlightType) -> None: def confirm_recreate(self, task: FlightType) -> None:
result = QMessageBox.question( result = QMessageBox.question(

View File

@ -1,11 +1,20 @@
from PySide2.QtCore import Qt from PySide2.QtCore import Qt, Signal
from PySide2.QtWidgets import QDialog, QLabel, QHBoxLayout, QVBoxLayout, QPushButton, QCheckBox from PySide2.QtWidgets import (
QCheckBox,
QDialog,
QHBoxLayout,
QLabel,
QPushButton,
QVBoxLayout,
)
from game import Game from game import Game
from gen.flights.flight import Flight from gen.flights.flight import Flight
from qt_ui.uiconstants import EVENT_ICONS from qt_ui.uiconstants import EVENT_ICONS
from qt_ui.widgets.combos.QPredefinedWaypointSelectionComboBox import QPredefinedWaypointSelectionComboBox from qt_ui.widgets.combos.QPredefinedWaypointSelectionComboBox import \
from qt_ui.windows.mission.flight.waypoints.QFlightWaypointInfoBox import QFlightWaypointInfoBox QPredefinedWaypointSelectionComboBox
from qt_ui.windows.mission.flight.waypoints.QFlightWaypointInfoBox import \
QFlightWaypointInfoBox
PREDEFINED_WAYPOINT_CATEGORIES = [ PREDEFINED_WAYPOINT_CATEGORIES = [
"Frontline (CAS AREA)", "Frontline (CAS AREA)",
@ -17,6 +26,8 @@ PREDEFINED_WAYPOINT_CATEGORIES = [
class QPredefinedWaypointSelectionWindow(QDialog): class QPredefinedWaypointSelectionWindow(QDialog):
# List of FlightWaypoint
waypoints_added = Signal(list)
def __init__(self, game: Game, flight: Flight, flight_waypoint_list): def __init__(self, game: Game, flight: Flight, flight_waypoint_list):
super(QPredefinedWaypointSelectionWindow, self).__init__() super(QPredefinedWaypointSelectionWindow, self).__init__()
@ -44,7 +55,6 @@ class QPredefinedWaypointSelectionWindow(QDialog):
self.init_ui() self.init_ui()
self.on_select_wpt_changed() self.on_select_wpt_changed()
print("DONE")
def init_ui(self): def init_ui(self):
@ -77,12 +87,5 @@ class QPredefinedWaypointSelectionWindow(QDialog):
self.add_button.setDisabled(False) self.add_button.setDisabled(False)
def add_waypoint(self): def add_waypoint(self):
self.waypoints_added.emit(self.selected_waypoints)
for wpt in self.selected_waypoints:
self.flight.points.append(wpt)
self.flight_waypoint_list.update_list()
self.close() self.close()