Passive defense for non-air-to-air flights in package with jammer

This commit is contained in:
Raffson 2025-05-01 19:52:52 +02:00
parent 01832b6594
commit 09617adc56
No known key found for this signature in database
GPG Key ID: B0402B2C9B764D99
5 changed files with 77 additions and 40 deletions

View File

@ -13,6 +13,7 @@ from dcs.datalinks.datalink import DataLinkType
from dcs.datalinks.datalinkbase import DataLinkSettingsWithFlightLead
from dcs.datalinks.link16 import Link16Network, ViperLink16NetworkMemberLink
from dcs.mission import Mission
from dcs.task import RunScript
from dcs.terrain.terrain import NoParkingSlotError
from dcs.triggers import TriggerOnce, Event
from dcs.unit import Skill
@ -341,16 +342,49 @@ class AircraftGenerator:
def _track_ewrj_flight(self, flight: Flight, group: FlyingGroup[Any]) -> None:
if not self.ewrj_package_dict.get(id(flight.package)):
self.ewrj_package_dict[id(flight.package)] = []
added = False
if (
flight.package.primary_flight
and flight is flight.package.primary_flight
or flight.client_count
not flight.flight_type.is_air_to_air
and any(
[
wpt
for wpt in group.points
if wpt.name in ["JOIN", "SPLIT", "RACETRACK START", "RACETRACK END"]
and any(
[
t
for t in wpt.tasks
if isinstance(t, RunScript)
and (
"Djamming" in t.params["action"]["params"]["command"]
or "EWjamm" in t.params["action"]["params"]["command"]
)
]
)
]
)
and (
not self.need_ecm
or flight.any_member_has_weapon_of_type(WeaponType.JAMMER)
or flight.squadron.aircraft.has_built_in_ecm
)
):
self.ewrj_package_dict[id(flight.package)].append(group)
added = True
if (
added
or not flight.flight_type.is_air_to_air
and self.ewrj_package_dict[id(flight.package)]
):
for f in flight.package.flights:
if f is flight or f.group_id == 0 or f.flight_type.is_air_to_air:
continue
g = self.mission.find_group_by_id(f.group_id)
if (
isinstance(g, FlyingGroup)
and g not in self.ewrj_package_dict[id(flight.package)]
):
self.ewrj_package_dict[id(flight.package)].append(g)
def _reserve_frequencies_and_tacan(self, ato: AirTaskingOrder) -> None:
for package in ato.packages:

View File

@ -9,7 +9,6 @@ from dcs.task import (
OptFormation,
Targets,
SetUnlimitedFuelCommand,
OptReactOnThreat,
)
from game.ato import FlightType
@ -66,9 +65,7 @@ class JoinPointBuilder(PydcsWaypointBuilder):
ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled")
if settings.plugins.get("ewrj") and ai_jammer:
self.offensive_jamming(waypoint, "start")
if self.defensive_jamming(waypoint, "start"):
reaction = OptReactOnThreat(OptReactOnThreat.Values.PassiveDefense)
waypoint.tasks.append(reaction)
self.defensive_jamming(waypoint, "start")
if self.flight.flight_type == FlightType.SEAD_ESCORT:
self.handle_sead_escort(doctrine, waypoint)

View File

@ -159,11 +159,10 @@ class PydcsWaypointBuilder:
):
self.group.add_nav_target_point(self.waypoint.position, "IP")
def defensive_jamming(self, waypoint: MovingPoint, action: str) -> bool:
def defensive_jamming(self, waypoint: MovingPoint, action: str) -> None:
# Explodes incoming missiles within the jamming bubble through the EW-Jamming script
settings = self.flight.coalition.game.settings
ecm_required = settings.plugin_option("ewrj.ecm_required")
has_jammers = False
for unit, member in zip(self.group.units, self.flight.iter_members()):
has_jammer = member.loadout.has_weapon_of_type(WeaponType.JAMMER)
built_in_jammer = self.flight.squadron.aircraft.has_built_in_ecm
@ -173,14 +172,11 @@ class PydcsWaypointBuilder:
script_content = f'{action}Djamming("{unit.name}")'
jamming_script = RunScript(script_content)
waypoint.tasks.append(jamming_script)
has_jammers = True
return has_jammers
def offensive_jamming(self, waypoint: MovingPoint, action: str) -> bool:
def offensive_jamming(self, waypoint: MovingPoint, action: str) -> None:
# Silences enemy radars through the EW-Jamming script
settings = self.flight.coalition.game.settings
ecm_required = settings.plugin_option("ewrj.ecm_required")
has_jammers = False
for unit, member in zip(self.group.units, self.flight.iter_members()):
has_jammer = member.loadout.has_weapon_of_type(WeaponType.JAMMER)
built_in_jammer = self.flight.squadron.aircraft.has_built_in_ecm
@ -190,5 +186,3 @@ class PydcsWaypointBuilder:
script_content = f'{action}EWjamm("{unit.name}")'
stop_jamming_script = RunScript(script_content)
waypoint.tasks.append(stop_jamming_script)
has_jammers = True
return has_jammers

View File

@ -5,7 +5,6 @@ from dcs.task import (
SetUnlimitedFuelCommand,
SwitchWaypoint,
RunScript,
OptReactOnThreat,
)
from game.ato import FlightType
@ -58,6 +57,4 @@ class SplitPointBuilder(PydcsWaypointBuilder):
ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled")
if settings.plugins.get("ewrj") and ai_jammer:
self.offensive_jamming(waypoint, "stop")
if self.defensive_jamming(waypoint, "stop"):
reaction = OptReactOnThreat(OptReactOnThreat.Values.EvadeFire)
waypoint.tasks.append(reaction)
self.defensive_jamming(waypoint, "stop")

View File

@ -9,6 +9,7 @@ import dcs.lua
from dcs import Mission, Point
from dcs.coalition import Coalition
from dcs.countries import country_dict
from dcs.point import MovingPoint
from dcs.task import OptReactOnThreat
from dcs.terrain import Airport
from dcs.unit import Static
@ -131,28 +132,42 @@ class MissionGenerator:
return self.unit_map
@staticmethod
def _configure_ewrj(gen: AircraftGenerator) -> None:
def _configure_react_to_threat_for_ew_jamming_packages(
gen: AircraftGenerator,
) -> None:
for groups in gen.ewrj_package_dict.values():
optrot = [
task
for task in groups[0].points[0].tasks
if isinstance(task, OptReactOnThreat)
][0]
assert isinstance(optrot, OptReactOnThreat)
if (
len(groups) == 1
and optrot.value != OptReactOnThreat.Values.PassiveDefense
):
# primary flight with no EWR-Jamming capability
continue
for group in groups:
tasks = group.points[0].tasks
for i in range(len(tasks)):
if isinstance(tasks[i], OptReactOnThreat):
tasks[i] = OptReactOnThreat(
OptReactOnThreat.Values.PassiveDefense
)
break
start_point = [
p for p in group.points if p.name in ["JOIN", "RACETRACK START"]
]
if not start_point:
sp = group.points[0]
else:
sp = start_point[0]
MissionGenerator.set_react_to_threat(
OptReactOnThreat.Values.PassiveDefense, sp
)
stop_point = [
p for p in group.points if p.name in ["SPLIT", "RACETRACK END"]
]
if not stop_point:
sp = group.points[0]
else:
sp = stop_point[0]
MissionGenerator.set_react_to_threat(
OptReactOnThreat.Values.EvadeFire, sp
)
@staticmethod
def set_react_to_threat(
optrot: OptReactOnThreat.Values, start_point: MovingPoint
) -> None:
tasks = start_point.tasks
for i in range(len(tasks)):
if isinstance(tasks[i], OptReactOnThreat):
tasks[i] = OptReactOnThreat(optrot)
return
tasks.append(OptReactOnThreat(optrot))
def setup_mission_coalitions(self) -> None:
self.mission.coalition["blue"] = Coalition(
@ -291,7 +306,7 @@ class MissionGenerator:
flight.aircraft_type.assign_channels_for_flight(flight, self.mission_data)
if self.game.settings.plugins.get("ewrj"):
self._configure_ewrj(aircraft_generator)
self._configure_react_to_threat_for_ew_jamming_packages(aircraft_generator)
def generate_destroyed_units(self) -> None:
"""Add destroyed units to the Mission"""