mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Initial attempt at fixing escorts
This commit is contained in:
parent
f2f818acb3
commit
395969a371
@ -63,6 +63,7 @@ class Flight(SidcDescribable):
|
|||||||
self.start_type = start_type
|
self.start_type = start_type
|
||||||
self.use_custom_loadout = False
|
self.use_custom_loadout = False
|
||||||
self.custom_name = custom_name
|
self.custom_name = custom_name
|
||||||
|
self.group_id: int = 0
|
||||||
|
|
||||||
# Only used by transport missions.
|
# Only used by transport missions.
|
||||||
self.cargo = cargo
|
self.cargo = cargo
|
||||||
|
|||||||
@ -129,6 +129,16 @@ class Package:
|
|||||||
if not self.flights:
|
if not self.flights:
|
||||||
self.waypoints = None
|
self.waypoints = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def primary_flight(self) -> Optional[Flight]:
|
||||||
|
task = self.primary_task
|
||||||
|
if not task:
|
||||||
|
return None
|
||||||
|
primaries = [x for x in self.flights if x.flight_type == task]
|
||||||
|
if len(primaries) > 0:
|
||||||
|
return primaries[0]
|
||||||
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def primary_task(self) -> Optional[FlightType]:
|
def primary_task(self) -> Optional[FlightType]:
|
||||||
if not self.flights:
|
if not self.flights:
|
||||||
|
|||||||
@ -8,6 +8,7 @@ from dcs.task import (
|
|||||||
CAP,
|
CAP,
|
||||||
CAS,
|
CAS,
|
||||||
EPLRS,
|
EPLRS,
|
||||||
|
Escort,
|
||||||
FighterSweep,
|
FighterSweep,
|
||||||
GroundAttack,
|
GroundAttack,
|
||||||
Nothing,
|
Nothing,
|
||||||
@ -18,7 +19,7 @@ from dcs.task import (
|
|||||||
OptRestrictJettison,
|
OptRestrictJettison,
|
||||||
Refueling,
|
Refueling,
|
||||||
RunwayAttack,
|
RunwayAttack,
|
||||||
Transport,
|
Transport, SEAD,
|
||||||
)
|
)
|
||||||
from dcs.unitgroup import FlyingGroup
|
from dcs.unitgroup import FlyingGroup
|
||||||
|
|
||||||
@ -265,7 +266,7 @@ class AircraftBehavior:
|
|||||||
# Escort groups are actually given the CAP task so they can perform the
|
# Escort groups are actually given the CAP task so they can perform the
|
||||||
# Search Then Engage task, which we have to use instead of the Escort
|
# Search Then Engage task, which we have to use instead of the Escort
|
||||||
# task for the reasons explained in JoinPointBuilder.
|
# task for the reasons explained in JoinPointBuilder.
|
||||||
group.task = CAP.name
|
group.task = Escort.name
|
||||||
self.configure_behavior(
|
self.configure_behavior(
|
||||||
flight, group, roe=OptROE.Values.OpenFire, restrict_jettison=True
|
flight, group, roe=OptROE.Values.OpenFire, restrict_jettison=True
|
||||||
)
|
)
|
||||||
@ -274,7 +275,7 @@ class AircraftBehavior:
|
|||||||
# CAS is able to perform all the same tasks as SEAD using a superset of the
|
# CAS is able to perform all the same tasks as SEAD using a superset of the
|
||||||
# available aircraft, and F-14s are not able to be SEAD despite having TALDs.
|
# available aircraft, and F-14s are not able to be SEAD despite having TALDs.
|
||||||
# https://forums.eagle.ru/topic/272112-cannot-assign-f-14-to-sead/
|
# https://forums.eagle.ru/topic/272112-cannot-assign-f-14-to-sead/
|
||||||
group.task = CAS.name
|
group.task = SEAD.name
|
||||||
self.configure_behavior(
|
self.configure_behavior(
|
||||||
flight,
|
flight,
|
||||||
group,
|
group,
|
||||||
|
|||||||
@ -74,8 +74,14 @@ class FlightGroupSpawner:
|
|||||||
self.flight.state.is_waiting_for_start
|
self.flight.state.is_waiting_for_start
|
||||||
or self.flight.state.spawn_type is not StartType.IN_FLIGHT
|
or self.flight.state.spawn_type is not StartType.IN_FLIGHT
|
||||||
):
|
):
|
||||||
return self.generate_flight_at_departure()
|
grp = self.generate_flight_at_departure()
|
||||||
return self.generate_mid_mission()
|
# grp.id = id(self.flight)
|
||||||
|
self.flight.group_id = grp.id
|
||||||
|
return grp
|
||||||
|
grp = self.generate_mid_mission()
|
||||||
|
# grp.id = id(self.flight)
|
||||||
|
self.flight.group_id = grp.id
|
||||||
|
return grp
|
||||||
|
|
||||||
def create_idle_aircraft(self) -> FlyingGroup[Any]:
|
def create_idle_aircraft(self) -> FlyingGroup[Any]:
|
||||||
airport = self.flight.squadron.location.dcs_airport
|
airport = self.flight.squadron.location.dcs_airport
|
||||||
|
|||||||
@ -1,13 +1,15 @@
|
|||||||
from typing import List, Type
|
import random
|
||||||
|
from typing import List, Type, Optional
|
||||||
|
|
||||||
from dcs.point import MovingPoint
|
from dcs.point import MovingPoint
|
||||||
from dcs.task import (
|
from dcs.task import (
|
||||||
ControlledTask,
|
ControlledTask,
|
||||||
EngageTargets,
|
EngageTargets,
|
||||||
|
EscortTaskAction,
|
||||||
OptECMUsing,
|
OptECMUsing,
|
||||||
OptFormation,
|
OptFormation,
|
||||||
TargetType,
|
TargetType,
|
||||||
Targets,
|
Targets, GoToWaypoint, SwitchWaypoint,
|
||||||
)
|
)
|
||||||
|
|
||||||
from game.ato import FlightType
|
from game.ato import FlightType
|
||||||
@ -19,42 +21,69 @@ from .pydcswaypointbuilder import PydcsWaypointBuilder
|
|||||||
class JoinPointBuilder(PydcsWaypointBuilder):
|
class JoinPointBuilder(PydcsWaypointBuilder):
|
||||||
def add_tasks(self, waypoint: MovingPoint) -> None:
|
def add_tasks(self, waypoint: MovingPoint) -> None:
|
||||||
if self.flight.flight_type == FlightType.ESCORT:
|
if self.flight.flight_type == FlightType.ESCORT:
|
||||||
self.configure_escort_tasks(
|
# self.configure_escort_tasks(
|
||||||
waypoint,
|
# waypoint,
|
||||||
[
|
# [
|
||||||
Targets.All.Air.Planes.Fighters,
|
# Targets.All.Air.Planes.Fighters,
|
||||||
Targets.All.Air.Planes.MultiroleFighters,
|
# Targets.All.Air.Planes.MultiroleFighters,
|
||||||
],
|
# ],
|
||||||
|
# )
|
||||||
|
|
||||||
|
waypoint.tasks.append(OptFormation.finger_four_open())
|
||||||
|
waypoint.tasks.append(SwitchWaypoint(3, 7))
|
||||||
|
|
||||||
|
rx = (random.random() + 0.1) * 500 * random.choice([-1, 1])
|
||||||
|
ry = (random.random() + 0.1) * 500 * random.choice([-1, 1])
|
||||||
|
rz = (random.random() + 0.1) * 500 * random.choice([-1, 1])
|
||||||
|
pos = {"x": rx, "y": ry, "z": rz}
|
||||||
|
targets = [
|
||||||
|
Targets.All.Air.Planes.Fighters.id,
|
||||||
|
Targets.All.Air.Planes.MultiroleFighters.id,
|
||||||
|
]
|
||||||
|
waypoint.tasks.append(
|
||||||
|
EscortTaskAction(
|
||||||
|
group_id=self.package.primary_flight.group_id,
|
||||||
|
engagement_max_dist=int(nautical_miles(40).meters),
|
||||||
|
lastwpt=6,
|
||||||
|
targets=targets,
|
||||||
|
position=pos)
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.flight.count < 4:
|
|
||||||
waypoint.tasks.append(OptFormation.line_abreast_open())
|
|
||||||
else:
|
|
||||||
waypoint.tasks.append(OptFormation.spread_four_open())
|
|
||||||
|
|
||||||
elif self.flight.flight_type == FlightType.SEAD_ESCORT:
|
elif self.flight.flight_type == FlightType.SEAD_ESCORT:
|
||||||
if isinstance(self.flight.package.target, NavalControlPoint):
|
# if isinstance(self.flight.package.target, NavalControlPoint):
|
||||||
self.configure_escort_tasks(
|
# self.configure_escort_tasks(
|
||||||
waypoint,
|
# waypoint,
|
||||||
[
|
# [
|
||||||
Targets.All.Naval,
|
# Targets.All.Naval,
|
||||||
Targets.All.GroundUnits.AirDefence.AAA.SAMRelated,
|
# Targets.All.GroundUnits.AirDefence.AAA.SAMRelated,
|
||||||
],
|
# ],
|
||||||
)
|
# )
|
||||||
else:
|
# else:
|
||||||
self.configure_escort_tasks(
|
# self.configure_escort_tasks(
|
||||||
waypoint, [Targets.All.GroundUnits.AirDefence.AAA.SAMRelated]
|
# waypoint, [Targets.All.GroundUnits.AirDefence.AAA.SAMRelated]
|
||||||
)
|
# )
|
||||||
|
|
||||||
# Let the AI use ECM to preemptively defend themselves.
|
# Let the AI use ECM to preemptively defend themselves.
|
||||||
ecm_option = OptECMUsing(value=OptECMUsing.Values.UseIfDetectedLockByRadar)
|
ecm_option = OptECMUsing(value=OptECMUsing.Values.UseIfDetectedLockByRadar)
|
||||||
waypoint.tasks.append(ecm_option)
|
waypoint.tasks.append(ecm_option)
|
||||||
|
|
||||||
if self.flight.count < 4:
|
waypoint.tasks.append(OptFormation.finger_four_open())
|
||||||
waypoint.tasks.append(OptFormation.line_abreast_open())
|
waypoint.tasks.append(SwitchWaypoint(3, 7))
|
||||||
else:
|
|
||||||
waypoint.tasks.append(OptFormation.spread_four_open())
|
|
||||||
|
|
||||||
|
rx = (random.random() + 0.1) * 500 * random.choice([-1, 1])
|
||||||
|
ry = (random.random() + 0.1) * 500 * random.choice([-1, 1])
|
||||||
|
rz = (random.random() + 0.1) * 500 * random.choice([-1, 1])
|
||||||
|
pos = {"x": rx, "y": ry, "z": rz}
|
||||||
|
targets = [Targets.All.GroundUnits.AirDefence.AAA.SAMRelated.id]
|
||||||
|
if isinstance(self.flight.package.target, NavalControlPoint):
|
||||||
|
targets.append(Targets.All.Naval.id)
|
||||||
|
waypoint.tasks.append(
|
||||||
|
EscortTaskAction(
|
||||||
|
group_id=self.package.primary_flight.group_id,
|
||||||
|
engagement_max_dist=int(nautical_miles(40).meters),
|
||||||
|
lastwpt=6,
|
||||||
|
targets=targets,
|
||||||
|
position=pos)
|
||||||
|
)
|
||||||
elif not self.flight.flight_type.is_air_to_air:
|
elif not self.flight.flight_type.is_air_to_air:
|
||||||
# Capture any non A/A type to avoid issues with SPJs that use the primary radar such as the F/A-18C.
|
# Capture any non A/A type to avoid issues with SPJs that use the primary radar such as the F/A-18C.
|
||||||
# You can bully them with STT to not be able to fire radar guided missiles at you,
|
# You can bully them with STT to not be able to fire radar guided missiles at you,
|
||||||
@ -68,7 +97,9 @@ class JoinPointBuilder(PydcsWaypointBuilder):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def configure_escort_tasks(
|
def configure_escort_tasks(
|
||||||
waypoint: MovingPoint, target_types: List[Type[TargetType]]
|
waypoint: MovingPoint,
|
||||||
|
target_types: List[Type[TargetType]],
|
||||||
|
max_dist: Optional[float] = 30.0
|
||||||
) -> None:
|
) -> None:
|
||||||
# Ideally we would use the escort mission type and escort task to have
|
# Ideally we would use the escort mission type and escort task to have
|
||||||
# the AI automatically but the AI only escorts AI flights while they are
|
# the AI automatically but the AI only escorts AI flights while they are
|
||||||
@ -100,7 +131,7 @@ class JoinPointBuilder(PydcsWaypointBuilder):
|
|||||||
ControlledTask(
|
ControlledTask(
|
||||||
EngageTargets(
|
EngageTargets(
|
||||||
# TODO: From doctrine.
|
# TODO: From doctrine.
|
||||||
max_distance=int(nautical_miles(30).meters),
|
max_distance=int(nautical_miles(max_dist).meters),
|
||||||
targets=target_types,
|
targets=target_types,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user