diff --git a/game/ato/flight.py b/game/ato/flight.py index 048738c8..278283f5 100644 --- a/game/ato/flight.py +++ b/game/ato/flight.py @@ -272,5 +272,5 @@ class Flight(SidcDescribable): if pilot is not None: results.kill_pilot(self, pilot) - def recreate_flight_plan(self) -> None: - self._flight_plan_builder.regenerate() + def recreate_flight_plan(self, dump_debug_info: bool = False) -> None: + self._flight_plan_builder.regenerate(dump_debug_info) diff --git a/game/ato/flightplans/ibuilder.py b/game/ato/flightplans/ibuilder.py index a1b6c905..b85589e4 100644 --- a/game/ato/flightplans/ibuilder.py +++ b/game/ato/flightplans/ibuilder.py @@ -32,9 +32,9 @@ class IBuilder(ABC, Generic[FlightPlanT, LayoutT]): assert self._flight_plan is not None return self._flight_plan - def regenerate(self) -> None: + def regenerate(self, dump_debug_info: bool = False) -> None: try: - self._generate_package_waypoints_if_needed() + self._generate_package_waypoints_if_needed(dump_debug_info) self._flight_plan = self.build() except NavMeshError as ex: color = "blue" if self.flight.squadron.player else "red" @@ -43,14 +43,15 @@ class IBuilder(ABC, Generic[FlightPlanT, LayoutT]): f"{self.flight.departure} to {self.package.target}" ) from ex - def _generate_package_waypoints_if_needed(self) -> None: + def _generate_package_waypoints_if_needed(self, dump_debug_info: bool) -> None: # Package waypoints are only valid for offensive missions. Skip this if the # target is friendly. - if self.package.waypoints is None and not self.package.target.is_friendly( - self.is_player - ): + if self.package.target.is_friendly(self.is_player): + return + + if self.package.waypoints is None or dump_debug_info: self.package.waypoints = PackageWaypoints.create( - self.package, self.coalition + self.package, self.coalition, dump_debug_info ) @property diff --git a/game/ato/packagewaypoints.py b/game/ato/packagewaypoints.py index e0092ad0..d53bc558 100644 --- a/game/ato/packagewaypoints.py +++ b/game/ato/packagewaypoints.py @@ -9,6 +9,7 @@ from game.ato.flightplans.waypointbuilder import WaypointBuilder from game.flightplan import JoinZoneGeometry from game.flightplan.ipsolver import IpSolver from game.flightplan.refuelzonegeometry import RefuelZoneGeometry +from game.persistence.paths import liberation_user_dir from game.utils import dcs_to_shapely_point if TYPE_CHECKING: @@ -24,16 +25,27 @@ class PackageWaypoints: refuel: Point @staticmethod - def create(package: Package, coalition: Coalition) -> PackageWaypoints: + def create( + package: Package, coalition: Coalition, dump_debug_info: bool + ) -> PackageWaypoints: origin = package.departure_closest_to_target() + waypoint_debug_directory = liberation_user_dir() / "Debug/Waypoints" + # Start by picking the best IP for the attack. - ingress_point_shapely = IpSolver( + ip_solver = IpSolver( dcs_to_shapely_point(origin.position), dcs_to_shapely_point(package.target.position), coalition.doctrine, coalition.opponent.threat_zone.all, - ).solve() + ) + ip_solver.set_debug_properties( + waypoint_debug_directory / "IP", coalition.game.theater.terrain + ) + ingress_point_shapely = ip_solver.solve() + if dump_debug_info: + ip_solver.dump_debug_info() + ingress_point = origin.position.new_in_same_map( ingress_point_shapely.x, ingress_point_shapely.y ) diff --git a/qt_ui/windows/mission/flight/waypoints/QFlightWaypointTab.py b/qt_ui/windows/mission/flight/waypoints/QFlightWaypointTab.py index 416e5d23..29c5e545 100644 --- a/qt_ui/windows/mission/flight/waypoints/QFlightWaypointTab.py +++ b/qt_ui/windows/mission/flight/waypoints/QFlightWaypointTab.py @@ -167,7 +167,7 @@ class QFlightWaypointTab(QFrame): if result == QMessageBox.Yes: self.flight.set_flight_type(task) try: - self.flight.recreate_flight_plan() + self.flight.recreate_flight_plan(dump_debug_info=True) except PlanningError as ex: self.flight.set_flight_type(original_task) logging.exception("Could not recreate flight")