diff --git a/game/threatzones.py b/game/threatzones.py index 6118d4d5..4d29c6c3 100644 --- a/game/threatzones.py +++ b/game/threatzones.py @@ -40,6 +40,10 @@ class ThreatZones: ) return DcsPoint(boundary.x, boundary.y) + def distance_to_threat(self, point: DcsPoint) -> Distance: + boundary = self.closest_boundary(point) + return meters(boundary.distance_to_point(point)) + @singledispatchmethod def threatened(self, position) -> bool: raise NotImplementedError diff --git a/gen/flights/ai_flight_planner.py b/gen/flights/ai_flight_planner.py index fa7e9d3c..a6903ea7 100644 --- a/gen/flights/ai_flight_planner.py +++ b/gen/flights/ai_flight_planner.py @@ -506,31 +506,21 @@ class ObjectiveFinder: c for c in self.game.theater.controlpoints if c.is_friendly(self.is_player) ) - def farthest_friendly_control_point(self) -> Optional[ControlPoint]: - """ - Iterates over all friendly control points and find the one farthest away from the frontline - BUT! prefer Cvs. Everybody likes CVs! - """ - from_frontline = 0 - cp = None - first_friendly_cp = None + def farthest_friendly_control_point(self) -> ControlPoint: + """Finds the friendly control point that is farthest from any threats.""" + threat_zones = self.game.threat_zone_for(not self.is_player) - for c in self.game.theater.controlpoints: - if c.is_friendly(self.is_player): - if first_friendly_cp is None: - first_friendly_cp = c - if c.is_carrier: - return c - if c.has_active_frontline: - if c.distance_to(self.front_lines().__next__()) > from_frontline: - from_frontline = c.distance_to(self.front_lines().__next__()) - cp = c + farthest = None + max_distance = meters(0) + for cp in self.friendly_control_points(): + distance = threat_zones.distance_to_threat(cp.position) + if distance > max_distance: + farthest = cp + max_distance = distance - # If no frontlines on the map, return the first friendly cp - if cp is None: - return first_friendly_cp - else: - return cp + if farthest is None: + raise RuntimeError("Found no friendly control points. You probably lost.") + return farthest def enemy_control_points(self) -> Iterator[ControlPoint]: """Iterates over all enemy control points.""" @@ -628,15 +618,13 @@ class CoalitionMissionPlanner: eliminated this turn. """ - # Find farthest, friendly CP for AEWC - cp = self.objective_finder.farthest_friendly_control_point() - if cp is not None: - yield ProposedMission( - cp, - [ProposedFlight(FlightType.AEWC, 1, self.MAX_AWEC_RANGE)], - # Supports all the early CAP flights, so should be in the air ASAP. - asap=True, - ) + # Find farthest, friendly CP for AEWC. + yield ProposedMission( + self.objective_finder.farthest_friendly_control_point(), + [ProposedFlight(FlightType.AEWC, 1, self.MAX_AWEC_RANGE)], + # Supports all the early CAP flights, so should be in the air ASAP. + asap=True, + ) # Find friendly CPs within 100 nmi from an enemy airfield, plan CAP. for cp in self.objective_finder.vulnerable_control_points():