Prevent decoy flights from overflying the target.

Force decoy flights to the next waypoints 120 seconds after the IP.
The duration is just an approximation, but it seems to work.

See discussion in https://github.com/dcs-liberation/dcs_liberation/pull/2810
for more details.

Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2781.
This commit is contained in:
zhexu14 2023-04-27 12:30:34 +10:00 committed by GitHub
parent 7266de42f5
commit f86709ebd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 4 deletions

View File

@ -31,6 +31,7 @@ class PydcsWaypointBuilder:
now: datetime, now: datetime,
mission_data: MissionData, mission_data: MissionData,
unit_map: UnitMap, unit_map: UnitMap,
generated_waypoint_idx: int,
) -> None: ) -> None:
self.waypoint = waypoint self.waypoint = waypoint
self.group = group self.group = group
@ -40,6 +41,7 @@ class PydcsWaypointBuilder:
self.now = now self.now = now
self.mission_data = mission_data self.mission_data = mission_data
self.unit_map = unit_map self.unit_map = unit_map
self.generated_waypoint_idx = generated_waypoint_idx
def build(self) -> MovingPoint: def build(self) -> MovingPoint:
waypoint = self.group.add_waypoint( waypoint = self.group.add_waypoint(

View File

@ -3,11 +3,14 @@ import logging
from dcs.point import MovingPoint from dcs.point import MovingPoint
from dcs.task import ( from dcs.task import (
AttackGroup, AttackGroup,
ControlledTask,
EngageGroup, EngageGroup,
Expend, Expend,
OptECMUsing, OptECMUsing,
SwitchWaypoint,
WeaponType as DcsWeaponType, WeaponType as DcsWeaponType,
) )
from game.ato.flightstate import InFlight
from game.data.weapons import WeaponType from game.data.weapons import WeaponType
from game.theater import TheaterGroundObject from game.theater import TheaterGroundObject
from .pydcswaypointbuilder import PydcsWaypointBuilder from .pydcswaypointbuilder import PydcsWaypointBuilder
@ -49,13 +52,21 @@ class SeadIngressBuilder(PydcsWaypointBuilder):
# - Specify that DECOY weapon type is used in AttackGroup task so that # - Specify that DECOY weapon type is used in AttackGroup task so that
# the flight actually launches the decoy. See link below for details # the flight actually launches the decoy. See link below for details
# https://github.com/dcs-liberation/dcs_liberation/issues/2780 # https://github.com/dcs-liberation/dcs_liberation/issues/2780
# - Set a stop condition of 120 seconds so that the flight does not continue
# press the engagement as a DCS limitation means the RTB on winchester
# does not work well with decoys. See link below for details.
# https://github.com/dcs-liberation/dcs_liberation/issues/2781
# This stop condition will allow the SwitchWaypoint task defined below
# to kick in.
attack_task = AttackGroup( attack_task = AttackGroup(
miz_group.id, miz_group.id,
weapon_type=DcsWeaponType.Decoy, weapon_type=DcsWeaponType.Decoy,
group_attack=True, group_attack=True,
expend=Expend.All, expend=Expend.All,
) )
waypoint.tasks.append(attack_task) attack_task_control = ControlledTask(attack_task)
attack_task_control.stop_after_duration(120)
waypoint.tasks.append(attack_task_control)
else: else:
# All non ARM and non DECOY types will use the normal AttackGroup Task # All non ARM and non DECOY types will use the normal AttackGroup Task
attack_task = AttackGroup( attack_task = AttackGroup(
@ -69,3 +80,14 @@ class SeadIngressBuilder(PydcsWaypointBuilder):
# Preemptively use ECM to better avoid getting swatted. # Preemptively use ECM to better avoid getting swatted.
ecm_option = OptECMUsing(value=OptECMUsing.Values.UseIfDetectedLockByRadar) ecm_option = OptECMUsing(value=OptECMUsing.Values.UseIfDetectedLockByRadar)
waypoint.tasks.append(ecm_option) waypoint.tasks.append(ecm_option)
# For DECOY type flights, setup a waypoint task to skip the target waypoint after
# the attack task is complete. This is achieved using a switch waypoint task from the
# INGRESS point to the SPLIT point. This tasking prevents the flights continuing to
# overfly the target. See link below for the details of this issue
# https://github.com/dcs-liberation/dcs_liberation/issues/2781
if self.flight.loadout.has_weapon_of_type(WeaponType.DECOY):
switch_waypoint_task = SwitchWaypoint(
self.generated_waypoint_idx, self.generated_waypoint_idx + 2
)
waypoint.tasks.append(switch_waypoint_task)

View File

@ -80,7 +80,7 @@ class WaypointGenerator:
# us, but we do need to configure the tasks for it so that mid- # us, but we do need to configure the tasks for it so that mid-
# mission aircraft starting at a waypoint with tasks behave # mission aircraft starting at a waypoint with tasks behave
# correctly. # correctly.
self.builder_for_waypoint(point).add_tasks(self.group.points[0]) self.builder_for_waypoint(point, 1).add_tasks(self.group.points[0])
if not self.flight.state.has_passed_waypoint(point): if not self.flight.state.has_passed_waypoint(point):
filtered_points.append(point) filtered_points.append(point)
else: else:
@ -110,7 +110,10 @@ class WaypointGenerator:
] ]
for idx, point in enumerate(filtered_points): for idx, point in enumerate(filtered_points):
self.builder_for_waypoint(point).build() # We add 2 to idx to get the generated waypoint index as
# 1) pydcs seems to decrement the index by 1 and
# 2) DCS starts the first waypoint at index 1 as 0 is the starting position
self.builder_for_waypoint(point, idx + 2).build()
# Set here rather than when the FlightData is created so they waypoints # Set here rather than when the FlightData is created so they waypoints
# have their TOTs and fuel minimums set. Once we're more confident in our fuel # have their TOTs and fuel minimums set. Once we're more confident in our fuel
@ -120,7 +123,9 @@ class WaypointGenerator:
self._estimate_min_fuel_for(waypoints) self._estimate_min_fuel_for(waypoints)
return mission_start_time, waypoints return mission_start_time, waypoints
def builder_for_waypoint(self, waypoint: FlightWaypoint) -> PydcsWaypointBuilder: def builder_for_waypoint(
self, waypoint: FlightWaypoint, generated_waypoint_index: int
) -> PydcsWaypointBuilder:
builders = { builders = {
FlightWaypointType.INGRESS_BAI: BaiIngressBuilder, FlightWaypointType.INGRESS_BAI: BaiIngressBuilder,
FlightWaypointType.INGRESS_CAS: CasIngressBuilder, FlightWaypointType.INGRESS_CAS: CasIngressBuilder,
@ -151,6 +156,7 @@ class WaypointGenerator:
self.time, self.time,
self.mission_data, self.mission_data,
self.unit_map, self.unit_map,
generated_waypoint_index,
) )
def _estimate_min_fuel_for(self, waypoints: list[FlightWaypoint]) -> None: def _estimate_min_fuel_for(self, waypoints: list[FlightWaypoint]) -> None: