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:
parent
f6909d2f98
commit
355e6e1d15
@ -46,6 +46,7 @@ Saves from 2.5 are not compatible with 3.0.
|
||||
* **[Campaign]** Fixed bug where offshore strike locations were being used to spawn ship objectives.
|
||||
* **[Flight Planner]** AI strike flight plans now include the correct target actions for building groups.
|
||||
* **[Flight Planner]** AI BAI/DEAD/SEAD flights now have tasks to attack all groups at the target location, not just the primary group (for multi-group SAM sites).
|
||||
* **[Flight Planner]** Fixed some contexts where damaged runways would be used. Destroying a carrier will no longer break the game.
|
||||
|
||||
# 2.5.1
|
||||
|
||||
|
||||
@ -258,11 +258,9 @@ class ProcurementAi:
|
||||
) -> Iterator[ControlPoint]:
|
||||
distance_cache = ObjectiveDistanceCache.get_closest_airfields(request.near)
|
||||
threatened = []
|
||||
for cp in distance_cache.airfields_within(request.range):
|
||||
for cp in distance_cache.operational_airfields_within(request.range):
|
||||
if not cp.is_friendly(self.is_player):
|
||||
continue
|
||||
if not cp.runway_is_operational():
|
||||
continue
|
||||
if cp.unclaimed_parking(self.game) < request.number:
|
||||
continue
|
||||
if self.threat_zones.threatened(cp.position):
|
||||
|
||||
@ -517,7 +517,7 @@ class ControlPoint(MissionTarget, ABC):
|
||||
max_retreat_distance = nautical_miles(200)
|
||||
# Skip the first airbase because that's the airbase we're retreating
|
||||
# from.
|
||||
airfields = list(closest.airfields_within(max_retreat_distance))[1:]
|
||||
airfields = list(closest.operational_airfields_within(max_retreat_distance))[1:]
|
||||
for airbase in airfields:
|
||||
if not airbase.can_operate(airframe):
|
||||
continue
|
||||
|
||||
@ -124,7 +124,7 @@ class ThreatZones:
|
||||
cls, location: ControlPoint, max_distance: Distance
|
||||
) -> Optional[ControlPoint]:
|
||||
airfields = ObjectiveDistanceCache.get_closest_airfields(location)
|
||||
for airfield in airfields.airfields_within(max_distance):
|
||||
for airfield in airfields.all_airfields_within(max_distance):
|
||||
if airfield.captured != location.captured:
|
||||
return airfield
|
||||
return None
|
||||
|
||||
@ -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")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user