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.datalinkbase import DataLinkSettingsWithFlightLead
from dcs.datalinks.link16 import Link16Network, ViperLink16NetworkMemberLink from dcs.datalinks.link16 import Link16Network, ViperLink16NetworkMemberLink
from dcs.mission import Mission from dcs.mission import Mission
from dcs.task import RunScript
from dcs.terrain.terrain import NoParkingSlotError from dcs.terrain.terrain import NoParkingSlotError
from dcs.triggers import TriggerOnce, Event from dcs.triggers import TriggerOnce, Event
from dcs.unit import Skill from dcs.unit import Skill
@ -341,16 +342,49 @@ class AircraftGenerator:
def _track_ewrj_flight(self, flight: Flight, group: FlyingGroup[Any]) -> None: def _track_ewrj_flight(self, flight: Flight, group: FlyingGroup[Any]) -> None:
if not self.ewrj_package_dict.get(id(flight.package)): if not self.ewrj_package_dict.get(id(flight.package)):
self.ewrj_package_dict[id(flight.package)] = [] self.ewrj_package_dict[id(flight.package)] = []
added = False
if ( if (
flight.package.primary_flight not flight.flight_type.is_air_to_air
and flight is flight.package.primary_flight and any(
or flight.client_count [
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 ( and (
not self.need_ecm not self.need_ecm
or flight.any_member_has_weapon_of_type(WeaponType.JAMMER) 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) 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: def _reserve_frequencies_and_tacan(self, ato: AirTaskingOrder) -> None:
for package in ato.packages: for package in ato.packages:

View File

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

View File

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

View File

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

View File

@ -9,6 +9,7 @@ import dcs.lua
from dcs import Mission, Point from dcs import Mission, Point
from dcs.coalition import Coalition from dcs.coalition import Coalition
from dcs.countries import country_dict from dcs.countries import country_dict
from dcs.point import MovingPoint
from dcs.task import OptReactOnThreat from dcs.task import OptReactOnThreat
from dcs.terrain import Airport from dcs.terrain import Airport
from dcs.unit import Static from dcs.unit import Static
@ -131,28 +132,42 @@ class MissionGenerator:
return self.unit_map return self.unit_map
@staticmethod @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(): 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: for group in groups:
tasks = group.points[0].tasks start_point = [
for i in range(len(tasks)): p for p in group.points if p.name in ["JOIN", "RACETRACK START"]
if isinstance(tasks[i], OptReactOnThreat): ]
tasks[i] = OptReactOnThreat( if not start_point:
OptReactOnThreat.Values.PassiveDefense sp = group.points[0]
) else:
break 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: def setup_mission_coalitions(self) -> None:
self.mission.coalition["blue"] = Coalition( self.mission.coalition["blue"] = Coalition(
@ -291,7 +306,7 @@ class MissionGenerator:
flight.aircraft_type.assign_channels_for_flight(flight, self.mission_data) flight.aircraft_type.assign_channels_for_flight(flight, self.mission_data)
if self.game.settings.plugins.get("ewrj"): 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: def generate_destroyed_units(self) -> None:
"""Add destroyed units to the Mission""" """Add destroyed units to the Mission"""