From a2abdcf5d302f0c43ba3c6ca320e7f4f39ee4cfd Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Fri, 28 May 2021 16:26:21 -0700 Subject: [PATCH] Ensure that a transit path exists for recruitment. Networks can be disconnected even by airlift because FOBs are not airports. Fixes https://github.com/dcs-liberation/dcs_liberation/issues/1147 --- game/theater/transitnetwork.py | 22 ++++++++++++++++++++-- game/unitdelivery.py | 4 +++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/game/theater/transitnetwork.py b/game/theater/transitnetwork.py index 63d0d0e1..571d447b 100644 --- a/game/theater/transitnetwork.py +++ b/game/theater/transitnetwork.py @@ -88,9 +88,27 @@ class TransitNetwork: TransitConnection.Airlift: a.position.distance_to_point(b.position), }[self.link_type(a, b)] + def has_path_between( + self, + origin: ControlPoint, + destination: ControlPoint, + seen: Optional[set[ControlPoint]] = None, + ) -> bool: + if seen is None: + seen = set() + seen.add(origin) + for connection in self.connections_from(origin): + if connection in seen: + continue + if connection == destination: + return True + if self.has_path_between(connection, destination, seen): + return True + return False + def shortest_path_between( self, origin: ControlPoint, destination: ControlPoint - ) -> List[ControlPoint]: + ) -> list[ControlPoint]: return self.shortest_path_with_cost(origin, destination)[0] def shortest_path_with_cost( @@ -127,7 +145,7 @@ class TransitNetwork: path: List[ControlPoint] = [] while current != origin: path.append(current) - previous = came_from[current] + previous = came_from.get(current) if previous is None: raise NoPathError(origin, destination) current = previous diff --git a/game/unitdelivery.py b/game/unitdelivery.py index d6bfa826..752d4719 100644 --- a/game/unitdelivery.py +++ b/game/unitdelivery.py @@ -139,7 +139,9 @@ class PendingUnitDeliveries: ) -> Optional[ControlPoint]: sources = [] for control_point in game.theater.control_points_for(self.destination.captured): - if control_point.can_recruit_ground_units(game): + if control_point.can_recruit_ground_units( + game + ) and network.has_path_between(self.destination, control_point): sources.append(control_point) if not sources: