mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
82 lines
2.6 KiB
Python
82 lines
2.6 KiB
Python
from __future__ import annotations
|
|
|
|
import random
|
|
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.persistency import waypoint_debug_directory
|
|
from game.utils import dcs_to_shapely_point
|
|
from game.utils import nautical_miles
|
|
|
|
if TYPE_CHECKING:
|
|
from game.ato import Package
|
|
from game.coalition import Coalition
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class PackageWaypoints:
|
|
join: Point
|
|
ingress: Point
|
|
initial: 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
|
|
)
|
|
|
|
hdg = package.target.position.heading_between_point(ingress_point)
|
|
# Generate a waypoint randomly between 7 & 9 NM
|
|
dist = nautical_miles(random.random() * 2 + 7).meters
|
|
initial_point = package.target.position.point_from_heading(hdg, dist)
|
|
|
|
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,
|
|
initial_point,
|
|
WaypointBuilder.perturb(join_point),
|
|
refuel_point,
|
|
)
|