mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Putting the ingress point directly on one end of the FLOT means that AI flights won't start searching and engaging targets until they reach that point. If the front line has advanced toward the flight's departure airfield, it might overfly targets on its way to the IP. Instead, place an IP for CAS the same way we place any other IP. The AI will fly to that and start searching from there. This also: * Removes the midpoint waypoint, since it didn't serve any real purpose * Names the FLOT boundary waypoints for what they actually are Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2231.
73 lines
2.3 KiB
Python
73 lines
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import TYPE_CHECKING
|
|
|
|
from dcs import Point
|
|
|
|
from game.ato.flightplans.waypointbuilder import WaypointBuilder
|
|
from game.flightplan import JoinZoneGeometry
|
|
from game.flightplan.ipsolver import IpSolver
|
|
from game.flightplan.refuelzonegeometry import RefuelZoneGeometry
|
|
from game.persistence.paths import waypoint_debug_directory
|
|
from game.utils import dcs_to_shapely_point
|
|
|
|
if TYPE_CHECKING:
|
|
from game.ato import Package
|
|
from game.coalition import Coalition
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class PackageWaypoints:
|
|
join: Point
|
|
ingress: Point
|
|
split: Point
|
|
refuel: Point
|
|
|
|
@staticmethod
|
|
def create(
|
|
package: Package, coalition: Coalition, dump_debug_info: bool
|
|
) -> PackageWaypoints:
|
|
origin = package.departure_closest_to_target()
|
|
|
|
# Start by picking the best IP for the attack.
|
|
ip_solver = IpSolver(
|
|
dcs_to_shapely_point(origin.position),
|
|
dcs_to_shapely_point(package.target.position),
|
|
coalition.doctrine,
|
|
coalition.opponent.threat_zone.all,
|
|
)
|
|
ip_solver.set_debug_properties(
|
|
waypoint_debug_directory() / "IP", coalition.game.theater.terrain
|
|
)
|
|
ingress_point_shapely = ip_solver.solve()
|
|
if dump_debug_info:
|
|
ip_solver.dump_debug_info()
|
|
|
|
ingress_point = origin.position.new_in_same_map(
|
|
ingress_point_shapely.x, ingress_point_shapely.y
|
|
)
|
|
|
|
join_point = JoinZoneGeometry(
|
|
package.target.position,
|
|
origin.position,
|
|
ingress_point,
|
|
coalition,
|
|
).find_best_join_point()
|
|
|
|
refuel_point = RefuelZoneGeometry(
|
|
origin.position,
|
|
join_point,
|
|
coalition,
|
|
).find_best_refuel_point()
|
|
|
|
# And the split point based on the best route from the IP. Since that's no
|
|
# different than the best route *to* the IP, this is the same as the join point.
|
|
# TODO: Estimate attack completion point based on the IP and split from there?
|
|
return PackageWaypoints(
|
|
WaypointBuilder.perturb(join_point),
|
|
ingress_point,
|
|
WaypointBuilder.perturb(join_point),
|
|
refuel_point,
|
|
)
|