From 8bc77bbf18c61cbb9745ff152ec74aae7f0b8439 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sun, 6 Sep 2020 22:39:59 -0700 Subject: [PATCH] Make waypoint types less error prone. Make the type of the waypoint a non-optional part of the constructor. Every waypoint needs a type, and there's no good default (the previous default, `TAKEOFF`, is actually unused). All of the target waypoints were mistakenly being set as `TAKEOFF`, so I've fixed that in the process. Also, fix the bug where only the last custom target of a SEAD objective was being added to the waypoint list because the append was scoped incorrectly. --- gen/flights/ai_flight_planner.py | 154 +++++++++++++----- gen/flights/flight.py | 7 +- .../QPredefinedWaypointSelectionComboBox.py | 31 +++- 3 files changed, 143 insertions(+), 49 deletions(-) diff --git a/gen/flights/ai_flight_planner.py b/gen/flights/ai_flight_planner.py index 90a91500..42787bfc 100644 --- a/gen/flights/ai_flight_planner.py +++ b/gen/flights/ai_flight_planner.py @@ -372,17 +372,26 @@ class FlightPlanner: egress_heading = heading - 180 - 25 ingress_pos = location.position.point_from_heading(ingress_heading, self.doctrine["INGRESS_EGRESS_DISTANCE"]) - ingress_point = FlightWaypoint(ingress_pos.x, ingress_pos.y, self.doctrine["INGRESS_ALT"]) + ingress_point = FlightWaypoint( + FlightWaypointType.INGRESS_STRIKE, + ingress_pos.x, + ingress_pos.y, + self.doctrine["INGRESS_ALT"] + ) ingress_point.pretty_name = "INGRESS on " + location.obj_name ingress_point.description = "INGRESS on " + location.obj_name ingress_point.name = "INGRESS" - ingress_point.waypoint_type = FlightWaypointType.INGRESS_STRIKE flight.points.append(ingress_point) if len(location.groups) > 0 and location.dcs_identifier == "AA": for g in location.groups: for j, u in enumerate(g.units): - point = FlightWaypoint(u.position.x, u.position.y, 0) + point = FlightWaypoint( + FlightWaypointType.TARGET_POINT, + u.position.x, + u.position.y, + 0 + ) point.description = "STRIKE " + "[" + str(location.obj_name) + "] : " + u.type + " #" + str(j) point.pretty_name = "STRIKE " + "[" + str(location.obj_name) + "] : " + u.type + " #" + str(j) point.name = location.obj_name + "#" + str(j) @@ -398,7 +407,12 @@ class FlightPlanner: if building.is_dead: continue - point = FlightWaypoint(building.position.x, building.position.y, 0) + point = FlightWaypoint( + FlightWaypointType.TARGET_POINT, + building.position.x, + building.position.y, + 0 + ) point.description = "STRIKE on " + building.obj_name + " " + building.category + " [" + str(building.dcs_identifier) + " ]" point.pretty_name = "STRIKE on " + building.obj_name + " " + building.category + " [" + str(building.dcs_identifier) + " ]" point.name = building.obj_name @@ -406,7 +420,12 @@ class FlightPlanner: ingress_point.targets.append(building) flight.points.append(point) else: - point = FlightWaypoint(location.position.x, location.position.y, 0) + point = FlightWaypoint( + FlightWaypointType.TARGET_GROUP_LOC, + location.position.x, + location.position.y, + 0 + ) point.description = "STRIKE on " + location.obj_name point.pretty_name = "STRIKE on " + location.obj_name point.name = location.obj_name @@ -415,11 +434,15 @@ class FlightPlanner: flight.points.append(point) egress_pos = location.position.point_from_heading(egress_heading, self.doctrine["INGRESS_EGRESS_DISTANCE"]) - egress_point = FlightWaypoint(egress_pos.x, egress_pos.y, self.doctrine["EGRESS_ALT"]) + egress_point = FlightWaypoint( + FlightWaypointType.EGRESS, + egress_pos.x, + egress_pos.y, + self.doctrine["EGRESS_ALT"] + ) egress_point.name = "EGRESS" egress_point.pretty_name = "EGRESS from " + location.obj_name egress_point.description = "EGRESS from " + location.obj_name - egress_point.waypoint_type = FlightWaypointType.EGRESS flight.points.append(egress_point) descend = self.generate_descend_point(flight.from_cp) @@ -454,18 +477,26 @@ class FlightPlanner: ascend = self.generate_ascend_point(flight.from_cp) flight.points.append(ascend) - orbit0 = FlightWaypoint(orbit0p.x, orbit0p.y, patrol_alt) + orbit0 = FlightWaypoint( + FlightWaypointType.PATROL_TRACK, + orbit0p.x, + orbit0p.y, + patrol_alt + ) orbit0.name = "ORBIT 0" orbit0.description = "Standby between this point and the next one" orbit0.pretty_name = "Race-track start" - orbit0.waypoint_type = FlightWaypointType.PATROL_TRACK flight.points.append(orbit0) - orbit1 = FlightWaypoint(orbit1p.x, orbit1p.y, patrol_alt) + orbit1 = FlightWaypoint( + FlightWaypointType.PATROL, + orbit1p.x, + orbit1p.y, + patrol_alt + ) orbit1.name = "ORBIT 1" orbit1.description = "Standby between this point and the previous one" orbit1.pretty_name = "Race-track end" - orbit1.waypoint_type = FlightWaypointType.PATROL flight.points.append(orbit1) orbit0.targets.append(for_cp) @@ -512,18 +543,26 @@ class FlightPlanner: ascend = self.generate_ascend_point(flight.from_cp) flight.points.append(ascend) - orbit0 = FlightWaypoint(orbit0p.x, orbit0p.y, patrol_alt) + orbit0 = FlightWaypoint( + FlightWaypointType.PATROL_TRACK, + orbit0p.x, + orbit0p.y, + patrol_alt + ) orbit0.name = "ORBIT 0" orbit0.description = "Standby between this point and the next one" orbit0.pretty_name = "Race-track start" - orbit0.waypoint_type = FlightWaypointType.PATROL_TRACK flight.points.append(orbit0) - orbit1 = FlightWaypoint(orbit1p.x, orbit1p.y, patrol_alt) + orbit1 = FlightWaypoint( + FlightWaypointType.PATROL, + orbit1p.x, + orbit1p.y, + patrol_alt + ) orbit1.name = "ORBIT 1" orbit1.description = "Standby between this point and the previous one" orbit1.pretty_name = "Race-track end" - orbit1.waypoint_type = FlightWaypointType.PATROL flight.points.append(orbit1) # Note : Targets of a PATROL TRACK waypoints are the points to be defended @@ -555,16 +594,25 @@ class FlightPlanner: egress_heading = heading - 180 - 25 ingress_pos = location.position.point_from_heading(ingress_heading, self.doctrine["INGRESS_EGRESS_DISTANCE"]) - ingress_point = FlightWaypoint(ingress_pos.x, ingress_pos.y, self.doctrine["INGRESS_ALT"]) + ingress_point = FlightWaypoint( + FlightWaypointType.INGRESS_SEAD, + ingress_pos.x, + ingress_pos.y, + self.doctrine["INGRESS_ALT"] + ) ingress_point.name = "INGRESS" ingress_point.pretty_name = "INGRESS on " + location.obj_name ingress_point.description = "INGRESS on " + location.obj_name - ingress_point.waypoint_type = FlightWaypointType.INGRESS_SEAD flight.points.append(ingress_point) if len(custom_targets) > 0: for target in custom_targets: - point = FlightWaypoint(target.position.x, target.position.y, 0) + point = FlightWaypoint( + FlightWaypointType.TARGET_POINT, + target.position.x, + target.position.y, + 0 + ) point.alt_type = "RADIO" if flight.flight_type == FlightType.DEAD: point.description = "SEAD on " + target.type @@ -574,11 +622,16 @@ class FlightPlanner: point.description = "DEAD on " + location.obj_name point.pretty_name = "DEAD on " + location.obj_name point.only_for_player = True + flight.points.append(point) ingress_point.targets.append(location) ingress_point.targetGroup = location - flight.points.append(point) else: - point = FlightWaypoint(location.position.x, location.position.y, 0) + point = FlightWaypoint( + FlightWaypointType.TARGET_GROUP_LOC, + location.position.x, + location.position.y, + 0 + ) point.alt_type = "RADIO" if flight.flight_type == FlightType.DEAD: point.description = "SEAD on " + location.obj_name @@ -593,11 +646,15 @@ class FlightPlanner: flight.points.append(point) egress_pos = location.position.point_from_heading(egress_heading, self.doctrine["INGRESS_EGRESS_DISTANCE"]) - egress_point = FlightWaypoint(egress_pos.x, egress_pos.y, self.doctrine["EGRESS_ALT"]) + egress_point = FlightWaypoint( + FlightWaypointType.EGRESS, + egress_pos.x, + egress_pos.y, + self.doctrine["EGRESS_ALT"] + ) egress_point.name = "EGRESS" egress_point.pretty_name = "EGRESS from " + location.obj_name egress_point.description = "EGRESS from " + location.obj_name - egress_point.waypoint_type = FlightWaypointType.EGRESS flight.points.append(egress_point) descend = self.generate_descend_point(flight.from_cp) @@ -628,28 +685,40 @@ class FlightPlanner: ascend.alt = 500 flight.points.append(ascend) - ingress_point = FlightWaypoint(ingress.x, ingress.y, cap_alt) + ingress_point = FlightWaypoint( + FlightWaypointType.INGRESS_CAS, + ingress.x, + ingress.y, + cap_alt + ) ingress_point.alt_type = "RADIO" ingress_point.name = "INGRESS" ingress_point.pretty_name = "INGRESS" ingress_point.description = "Ingress into CAS area" - ingress_point.waypoint_type = FlightWaypointType.INGRESS_CAS flight.points.append(ingress_point) - center_point = FlightWaypoint(center.x, center.y, cap_alt) + center_point = FlightWaypoint( + FlightWaypointType.CAS, + center.x, + center.y, + cap_alt + ) center_point.alt_type = "RADIO" center_point.description = "Provide CAS" center_point.name = "CAS" center_point.pretty_name = "CAS" - center_point.waypoint_type = FlightWaypointType.CAS flight.points.append(center_point) - egress_point = FlightWaypoint(egress.x, egress.y, cap_alt) + egress_point = FlightWaypoint( + FlightWaypointType.EGRESS, + egress.x, + egress.y, + cap_alt + ) egress_point.alt_type = "RADIO" egress_point.description = "Egress from CAS area" egress_point.name = "EGRESS" egress_point.pretty_name = "EGRESS" - egress_point.waypoint_type = FlightWaypointType.EGRESS flight.points.append(egress_point) descend = self.generate_descend_point(flight.from_cp) @@ -660,7 +729,6 @@ class FlightPlanner: rtb = self.generate_rtb_waypoint(flight.from_cp) flight.points.append(rtb) - def generate_ascend_point(self, from_cp): """ Generate ascend point @@ -669,15 +737,18 @@ class FlightPlanner: """ ascend_heading = from_cp.heading pos_ascend = from_cp.position.point_from_heading(ascend_heading, 10000) - ascend = FlightWaypoint(pos_ascend.x, pos_ascend.y, self.doctrine["PATTERN_ALTITUDE"]) + ascend = FlightWaypoint( + FlightWaypointType.ASCEND_POINT, + pos_ascend.x, + pos_ascend.y, + self.doctrine["PATTERN_ALTITUDE"] + ) ascend.name = "ASCEND" ascend.alt_type = "RADIO" ascend.description = "Ascend" ascend.pretty_name = "Ascend" - ascend.waypoint_type = FlightWaypointType.ASCEND_POINT return ascend - def generate_descend_point(self, from_cp): """ Generate approach/descend point @@ -686,15 +757,18 @@ class FlightPlanner: """ ascend_heading = from_cp.heading descend = from_cp.position.point_from_heading(ascend_heading - 180, 10000) - descend = FlightWaypoint(descend.x, descend.y, self.doctrine["PATTERN_ALTITUDE"]) + descend = FlightWaypoint( + FlightWaypointType.DESCENT_POINT, + descend.x, + descend.y, + self.doctrine["PATTERN_ALTITUDE"] + ) descend.name = "DESCEND" descend.alt_type = "RADIO" descend.description = "Descend to pattern alt" descend.pretty_name = "Descend to pattern alt" - descend.waypoint_type = FlightWaypointType.DESCENT_POINT return descend - def generate_rtb_waypoint(self, from_cp): """ Generate RTB landing point @@ -702,10 +776,14 @@ class FlightPlanner: :return: """ rtb = from_cp.position - rtb = FlightWaypoint(rtb.x, rtb.y, 0) + rtb = FlightWaypoint( + FlightWaypointType.LANDING_POINT, + rtb.x, + rtb.y, + 0 + ) rtb.name = "LANDING" rtb.alt_type = "RADIO" rtb.description = "RTB" rtb.pretty_name = "RTB" - rtb.waypoint_type = FlightWaypointType.LANDING_POINT - return rtb \ No newline at end of file + return rtb diff --git a/gen/flights/flight.py b/gen/flights/flight.py index 6e2522f5..b736247f 100644 --- a/gen/flights/flight.py +++ b/gen/flights/flight.py @@ -60,7 +60,9 @@ class PredefinedWaypointCategory(Enum): class FlightWaypoint: - def __init__(self, x: float, y: float, alt=0): + def __init__(self, waypoint_type: FlightWaypointType, x: float, y: float, + alt: int = 0) -> None: + self.waypoint_type = waypoint_type self.x = x self.y = y self.alt = alt @@ -71,8 +73,7 @@ class FlightWaypoint: self.targetGroup = None self.obj_name = "" self.pretty_name = "" - self.waypoint_type = FlightWaypointType.TAKEOFF # type: FlightWaypointType - self.category = PredefinedWaypointCategory.NOT_PREDEFINED# type: PredefinedWaypointCategory + self.category: PredefinedWaypointCategory = PredefinedWaypointCategory.NOT_PREDEFINED self.only_for_player = False self.data = None diff --git a/qt_ui/widgets/combos/QPredefinedWaypointSelectionComboBox.py b/qt_ui/widgets/combos/QPredefinedWaypointSelectionComboBox.py index c8721a17..079aab99 100644 --- a/qt_ui/widgets/combos/QPredefinedWaypointSelectionComboBox.py +++ b/qt_ui/widgets/combos/QPredefinedWaypointSelectionComboBox.py @@ -57,13 +57,16 @@ class QPredefinedWaypointSelectionComboBox(QFilteredComboBox): enemy_cp = [ecp for ecp in cp.connected_points if ecp.captured != cp.captured] for ecp in enemy_cp: pos = Conflict.frontline_position(self.game.theater, cp, ecp)[0] - wpt = FlightWaypoint(pos.x, pos.y, 800) + wpt = FlightWaypoint( + FlightWaypointType.CUSTOM, + pos.x, + pos.y, + 800) wpt.name = "Frontline " + cp.name + "/" + ecp.name + " [CAS]" wpt.alt_type = "RADIO" wpt.pretty_name = wpt.name wpt.description = "Frontline" wpt.data = [cp, ecp] - wpt.waypoint_type = FlightWaypointType.CUSTOM wpt.category = PredefinedWaypointCategory.FRONTLINE i = add_model_item(i, model, wpt.pretty_name, wpt) @@ -72,14 +75,18 @@ class QPredefinedWaypointSelectionComboBox(QFilteredComboBox): if (self.include_enemy and not cp.captured) or (self.include_friendly and cp.captured): for ground_object in cp.ground_objects: if not ground_object.is_dead and not ground_object.dcs_identifier == "AA": - wpt = FlightWaypoint(ground_object.position.x,ground_object.position.y, 0) + wpt = FlightWaypoint( + FlightWaypointType.CUSTOM, + ground_object.position.x, + ground_object.position.y, + 0 + ) wpt.alt_type = "RADIO" wpt.name = wpt.name = "[" + str(ground_object.obj_name) + "] : " + ground_object.category + " #" + str(ground_object.object_id) wpt.pretty_name = wpt.name wpt.obj_name = ground_object.obj_name wpt.targets.append(ground_object) wpt.data = ground_object - wpt.waypoint_type = FlightWaypointType.CUSTOM if cp.captured: wpt.description = "Friendly Building" wpt.category = PredefinedWaypointCategory.ALLY_BUILDING @@ -95,7 +102,12 @@ class QPredefinedWaypointSelectionComboBox(QFilteredComboBox): if not ground_object.is_dead and ground_object.dcs_identifier == "AA": for g in ground_object.groups: for j, u in enumerate(g.units): - wpt = FlightWaypoint(u.position.x, u.position.y, 0) + wpt = FlightWaypoint( + FlightWaypointType.CUSTOM, + u.position.x, + u.position.y, + 0 + ) wpt.alt_type = "RADIO" wpt.name = wpt.name = "[" + str(ground_object.obj_name) + "] : " + u.type + " #" + str(j) wpt.pretty_name = wpt.name @@ -114,11 +126,15 @@ class QPredefinedWaypointSelectionComboBox(QFilteredComboBox): if self.include_airbases: for cp in self.game.theater.controlpoints: if (self.include_enemy and not cp.captured) or (self.include_friendly and cp.captured): - wpt = FlightWaypoint(cp.position.x, cp.position.y, 0) + wpt = FlightWaypoint( + FlightWaypointType.CUSTOM, + cp.position.x, + cp.position.y, + 0 + ) wpt.alt_type = "RADIO" wpt.name = cp.name wpt.data = cp - wpt.waypoint_type = FlightWaypointType.CUSTOM if cp.captured: wpt.description = "Position of " + cp.name + " [Friendly Airbase]" wpt.category = PredefinedWaypointCategory.ALLY_CP @@ -133,7 +149,6 @@ class QPredefinedWaypointSelectionComboBox(QFilteredComboBox): else: wpt.pretty_name = cp.name + " (Airbase)" - i = add_model_item(i, model, wpt.pretty_name, wpt) self.setModel(model)