mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Fix several cases of wrongly using broken runways.
The usual symptom here was the game breaking when a carrier is destroyed. The carrier would no longer be operational but missions would be assigned there that could not generate flight plans.
This commit is contained in:
@@ -162,7 +162,7 @@ class AircraftAllocator:
|
||||
self, flight: ProposedFlight, task: FlightType
|
||||
) -> Optional[Tuple[ControlPoint, Squadron]]:
|
||||
types = aircraft_for_task(task)
|
||||
airfields_in_range = self.closest_airfields.airfields_within(
|
||||
airfields_in_range = self.closest_airfields.operational_airfields_within(
|
||||
flight.max_distance
|
||||
)
|
||||
|
||||
@@ -258,7 +258,9 @@ class PackageBuilder:
|
||||
self, aircraft: Type[FlyingType], arrival: ControlPoint
|
||||
) -> Optional[ControlPoint]:
|
||||
divert_limit = nautical_miles(150)
|
||||
for airfield in self.closest_airfields.airfields_within(divert_limit):
|
||||
for airfield in self.closest_airfields.operational_airfields_within(
|
||||
divert_limit
|
||||
):
|
||||
if airfield.captured != self.is_player:
|
||||
continue
|
||||
if airfield == arrival:
|
||||
@@ -467,8 +469,10 @@ class ObjectiveFinder:
|
||||
# Off-map spawn locations don't need protection.
|
||||
continue
|
||||
airfields_in_proximity = self.closest_airfields_to(cp)
|
||||
airfields_in_threat_range = airfields_in_proximity.airfields_within(
|
||||
self.AIRFIELD_THREAT_RANGE
|
||||
airfields_in_threat_range = (
|
||||
airfields_in_proximity.operational_airfields_within(
|
||||
self.AIRFIELD_THREAT_RANGE
|
||||
)
|
||||
)
|
||||
for airfield in airfields_in_threat_range:
|
||||
if not airfield.is_friendly(self.is_player):
|
||||
|
||||
@@ -27,17 +27,35 @@ class ClosestAirfields:
|
||||
def operational_airfields(self) -> Iterator[ControlPoint]:
|
||||
return (c for c in self.closest_airfields if c.runway_is_operational())
|
||||
|
||||
def airfields_within(self, distance: Distance) -> Iterator[ControlPoint]:
|
||||
def _airfields_within(
|
||||
self, distance: Distance, operational: bool
|
||||
) -> Iterator[ControlPoint]:
|
||||
airfields = (
|
||||
self.operational_airfields if operational else self.closest_airfields
|
||||
)
|
||||
for cp in airfields:
|
||||
if cp.distance_to(self.target) < distance.meters:
|
||||
yield cp
|
||||
else:
|
||||
break
|
||||
|
||||
def operational_airfields_within(
|
||||
self, distance: Distance
|
||||
) -> Iterator[ControlPoint]:
|
||||
"""Iterates over all airfields within the given range of the target.
|
||||
|
||||
Note that this iterates over *all* airfields, not just friendly
|
||||
airfields.
|
||||
"""
|
||||
for cp in self.closest_airfields:
|
||||
if cp.distance_to(self.target) < distance.meters:
|
||||
yield cp
|
||||
else:
|
||||
break
|
||||
return self._airfields_within(distance, operational=True)
|
||||
|
||||
def all_airfields_within(self, distance: Distance) -> Iterator[ControlPoint]:
|
||||
"""Iterates over all airfields within the given range of the target.
|
||||
|
||||
Note that this iterates over *all* airfields, not just friendly
|
||||
airfields.
|
||||
"""
|
||||
return self._airfields_within(distance, operational=False)
|
||||
|
||||
|
||||
class ObjectiveDistanceCache:
|
||||
|
||||
@@ -1807,7 +1807,7 @@ class FlightPlanBuilder:
|
||||
# We'll always have a package, but if this is being planned via the UI
|
||||
# it could be the first flight in the package.
|
||||
if not self.package.flights:
|
||||
raise RuntimeError(
|
||||
raise PlanningError(
|
||||
"Cannot determine source airfield for package with no flights"
|
||||
)
|
||||
|
||||
@@ -1819,4 +1819,4 @@ class FlightPlanBuilder:
|
||||
for flight in self.package.flights:
|
||||
if flight.departure == airfield:
|
||||
return airfield
|
||||
raise RuntimeError("Could not find any airfield assigned to this package")
|
||||
raise PlanningError("Could not find any airfield assigned to this package")
|
||||
|
||||
Reference in New Issue
Block a user