Fix AI landing behavior.

The landing waypoints need the airdrome_id field set to actually
associate with the airfield. Without this ferry flights will take off
and immediately land at their departure airfield.
This commit is contained in:
Dan Albert 2021-08-31 23:03:46 -07:00
parent 1a4be911c0
commit 90a8bb63dc
5 changed files with 28 additions and 2 deletions

View File

@ -27,6 +27,7 @@ Saves from 4.x are not compatible with 5.0.
* **[Campaign]** Naval control points will no longer claim ground objectives during campaign generation and prevent them from spawning.
* **[Mission Generation]** Mission results and other files will now be opened with enforced utf-8 encoding to prevent an issue where destroyed ground units were untracked because of special characters in their names.
* **[Mission Generation]** Fixed generation of landing waypoints so that the AI obeys them.
* **[UI]** Selling of Units is now visible again in the UI dialog and shows the correct amount of sold units
* **[UI]** Fixed bug where an incompatible campaign could be generated if no action is taken on the campaign selection screen.

View File

@ -687,6 +687,10 @@ class ControlPoint(MissionTarget, ABC):
) -> RunwayData:
...
@property
def airdrome_id_for_landing(self) -> Optional[int]:
return None
@property
def parking_slots(self) -> Iterator[ParkingSlot]:
yield from []
@ -904,6 +908,10 @@ class Airfield(ControlPoint):
assigner = RunwayAssigner(conditions)
return assigner.get_preferred_runway(self.airport)
@property
def airdrome_id_for_landing(self) -> Optional[int]:
return self.airport.id
@property
def parking_slots(self) -> Iterator[ParkingSlot]:
yield from self.airport.parking_slots

View File

@ -1736,6 +1736,8 @@ class LandingPointBuilder(PydcsWaypointBuilder):
waypoint = super().build()
waypoint.type = "Land"
waypoint.action = PointAction.Landing
if (control_point := self.waypoint.control_point) is not None:
waypoint.airdrome_id = control_point.airdrome_id_for_landing
return waypoint
@ -1745,6 +1747,8 @@ class CargoStopBuilder(PydcsWaypointBuilder):
waypoint.type = "LandingReFuAr"
waypoint.action = PointAction.LandingReFuAr
waypoint.landing_refuel_rearm_time = 2 # Minutes.
if (control_point := self.waypoint.control_point) is not None:
waypoint.airdrome_id = control_point.airdrome_id_for_landing
return waypoint

View File

@ -160,6 +160,7 @@ class FlightWaypoint:
x: float,
y: float,
alt: Distance = meters(0),
control_point: Optional[ControlPoint] = None,
) -> None:
"""Creates a flight waypoint.
@ -169,11 +170,14 @@ class FlightWaypoint:
y: Y coordinate of the waypoint.
alt: Altitude of the waypoint. By default this is MSL, but it can be
changed to AGL by setting alt_type to "RADIO"
control_point: The control point to associate with this waypoint. Needed for
landing points.
"""
self.waypoint_type = waypoint_type
self.x = x
self.y = y
self.alt = alt
self.control_point = control_point
self.alt_type = "BARO"
self.name = ""
# TODO: Merge with pretty_name.

View File

@ -110,7 +110,11 @@ class WaypointBuilder:
waypoint.pretty_name = "Exit theater"
else:
waypoint = FlightWaypoint(
FlightWaypointType.LANDING_POINT, position.x, position.y, meters(0)
FlightWaypointType.LANDING_POINT,
position.x,
position.y,
meters(0),
control_point=arrival,
)
waypoint.name = "LANDING"
waypoint.alt_type = "RADIO"
@ -139,7 +143,11 @@ class WaypointBuilder:
altitude_type = "RADIO"
waypoint = FlightWaypoint(
FlightWaypointType.DIVERT, position.x, position.y, altitude
FlightWaypointType.DIVERT,
position.x,
position.y,
altitude,
control_point=divert,
)
waypoint.alt_type = altitude_type
waypoint.name = "DIVERT"
@ -488,6 +496,7 @@ class WaypointBuilder:
control_point.position.x,
control_point.position.y,
meters(0),
control_point=control_point,
)
waypoint.alt_type = "RADIO"
waypoint.name = "DROP OFF"