From 30ad71f93b9e77681406055fd2ce4543d2f646e4 Mon Sep 17 00:00:00 2001 From: Raffson Date: Thu, 1 May 2025 17:22:46 +0200 Subject: [PATCH] Refactor & improve EW-jamming setup in mission-generator --- .../aircraft/waypoints/joinpoint.py | 33 +++++------------ .../waypoints/pydcswaypointbuilder.py | 35 +++++++++++++++++++ .../aircraft/waypoints/racetrack.py | 22 +++--------- .../aircraft/waypoints/racetrackend.py | 13 ++----- .../aircraft/waypoints/splitpoint.py | 27 ++++---------- resources/plugins/ewrj/EW script 2.00.lua | 4 +-- 6 files changed, 59 insertions(+), 75 deletions(-) diff --git a/game/missiongenerator/aircraft/waypoints/joinpoint.py b/game/missiongenerator/aircraft/waypoints/joinpoint.py index 9e1d9c43..7dfb8d00 100644 --- a/game/missiongenerator/aircraft/waypoints/joinpoint.py +++ b/game/missiongenerator/aircraft/waypoints/joinpoint.py @@ -9,13 +9,11 @@ from dcs.task import ( OptFormation, Targets, SetUnlimitedFuelCommand, - RunScript, OptReactOnThreat, ) from game.ato import FlightType from game.data.doctrine import Doctrine -from game.data.weapons import WeaponType from game.theater import NavalControlPoint from game.utils import nautical_miles, feet from .pydcswaypointbuilder import PydcsWaypointBuilder @@ -64,7 +62,14 @@ class JoinPointBuilder(PydcsWaypointBuilder): FlightType.SEAD, FlightType.SEAD_ESCORT, ]: - self.start_defensive_jamming(waypoint) + settings = self.flight.coalition.game.settings + 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) + if self.flight.flight_type == FlightType.SEAD_ESCORT: self.handle_sead_escort(doctrine, waypoint) # Let the AI use ECM to preemptively defend themselves. @@ -104,28 +109,6 @@ class JoinPointBuilder(PydcsWaypointBuilder): vertical_spacing=doctrine.sead_escort_spacing.feet, ) - def start_defensive_jamming(self, waypoint: MovingPoint) -> None: - # Start Defensive Jamming - settings = self.flight.coalition.game.settings - ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled") - if settings.plugins.get("ewrj") and ai_jammer: - ecm_required = settings.plugin_option("ewrj.ecm_required") - has_jammer = False - for unit, member in zip(self.group.units, self.flight.iter_members()): - has_jammer = member.loadout.has_weapon_of_type(WeaponType.JAMMER) - if ecm_required and not has_jammer: - continue - if not member.is_player: - script_content = f'startDjamming("{unit.name}")' - start_jamming_script = RunScript(script_content) - waypoint.tasks.append(start_jamming_script) - has_jammer = True - if has_jammer: - passive_defense = OptReactOnThreat( - OptReactOnThreat.Values.PassiveDefense - ) - waypoint.tasks.append(passive_defense) - def configure_escort_tasks( self, waypoint: MovingPoint, diff --git a/game/missiongenerator/aircraft/waypoints/pydcswaypointbuilder.py b/game/missiongenerator/aircraft/waypoints/pydcswaypointbuilder.py index 9ba90ad1..16b2909c 100644 --- a/game/missiongenerator/aircraft/waypoints/pydcswaypointbuilder.py +++ b/game/missiongenerator/aircraft/waypoints/pydcswaypointbuilder.py @@ -13,6 +13,7 @@ from game.ato import Flight, FlightWaypoint from game.ato.flightwaypointtype import FlightWaypointType from game.ato.starttype import StartType from game.ato.traveltime import GroundSpeed +from game.data.weapons import WeaponType from game.missiongenerator.missiondata import MissionData from game.theater import MissionTarget, TheaterUnit, OffMapSpawn @@ -157,3 +158,37 @@ class PydcsWaypointBuilder: self.group.units[0].unit_type in (F_14A_135_GR, F_14B) ): self.group.add_nav_target_point(self.waypoint.position, "IP") + + def defensive_jamming(self, waypoint: MovingPoint, action: str) -> bool: + # 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 + if ecm_required and not (has_jammer or built_in_jammer): + continue + if not member.is_player: + 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: + # 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 + if ecm_required and not (has_jammer or built_in_jammer): + continue + if not member.is_player: + 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 diff --git a/game/missiongenerator/aircraft/waypoints/racetrack.py b/game/missiongenerator/aircraft/waypoints/racetrack.py index f3300fc9..41200b5a 100644 --- a/game/missiongenerator/aircraft/waypoints/racetrack.py +++ b/game/missiongenerator/aircraft/waypoints/racetrack.py @@ -9,8 +9,6 @@ from dcs.task import ( Tanker, Targets, SetUnlimitedFuelCommand, - RunScript, - OptReactOnThreat, ) from game.ato import FlightType @@ -40,21 +38,11 @@ class RaceTrackBuilder(PydcsWaypointBuilder): ) return - if self.flight.flight_type == FlightType.AEWC: - # Start Offensive Jamming for all AWACS flights - settings = self.flight.coalition.game.settings - ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled") - if settings.plugins.get("ewrj") and ai_jammer: - # all units in group are AWACS, no specific checks needed - for unit, member in zip(self.group.units, self.flight.iter_members()): - script_content = f'startEWjamm("{unit.name}")' - start_jamming_script = RunScript(script_content) - waypoint.tasks.append(start_jamming_script) - - passive_defense = OptReactOnThreat( - OptReactOnThreat.Values.PassiveDefense - ) - waypoint.tasks.append(passive_defense) + # Start Defensive Jamming for all flights + settings = self.flight.coalition.game.settings + ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled") + if settings.plugins.get("ewrj") and ai_jammer: + self.defensive_jamming(waypoint, "start") # NB: It's important that the engage task comes before the orbit task. # Though they're on the same waypoint, if the orbit task comes first it diff --git a/game/missiongenerator/aircraft/waypoints/racetrackend.py b/game/missiongenerator/aircraft/waypoints/racetrackend.py index 04841a35..86bd92cc 100644 --- a/game/missiongenerator/aircraft/waypoints/racetrackend.py +++ b/game/missiongenerator/aircraft/waypoints/racetrackend.py @@ -3,8 +3,6 @@ import logging from dcs.point import MovingPoint from dcs.task import ( SetUnlimitedFuelCommand, - RunScript, - OptReactOnThreat, ) from game.ato import FlightType @@ -20,18 +18,11 @@ class RaceTrackEndBuilder(PydcsWaypointBuilder): # Disable Offensive Jamming at Racetrack End if self.flight.flight_type == FlightType.AEWC: - # Stop Offensive Jamming for all AWACS flights + # Stop Defensive Jamming for all AWACS flights settings = self.flight.coalition.game.settings ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled") if settings.plugins.get("ewrj") and ai_jammer: - # all units in group are AWACS, no specific checks needed - for unit, member in zip(self.group.units, self.flight.iter_members()): - script_content = f'stopEWjamming("{unit.name}")' - stop_jamming_script = RunScript(script_content) - waypoint.tasks.append(stop_jamming_script) - - evade_fire = OptReactOnThreat(OptReactOnThreat.Values.EvadeFire) - waypoint.tasks.append(evade_fire) + self.defensive_jamming(waypoint, "stop") def build(self) -> MovingPoint: waypoint = super().build() diff --git a/game/missiongenerator/aircraft/waypoints/splitpoint.py b/game/missiongenerator/aircraft/waypoints/splitpoint.py index 3e29ff35..cfa14059 100644 --- a/game/missiongenerator/aircraft/waypoints/splitpoint.py +++ b/game/missiongenerator/aircraft/waypoints/splitpoint.py @@ -9,7 +9,6 @@ from dcs.task import ( ) from game.ato import FlightType -from game.data.weapons import WeaponType from game.utils import knots from .pydcswaypointbuilder import PydcsWaypointBuilder @@ -55,22 +54,10 @@ class SplitPointBuilder(PydcsWaypointBuilder): if self.flight.flight_type.is_escort_type: index = len(self.group.points) self.group.add_trigger_action(SwitchWaypoint(None, index)) - self.stop_defensive_jamming(waypoint) - - def stop_defensive_jamming(self, waypoint: MovingPoint) -> None: - # Stop Defensive Jamming - settings = self.flight.coalition.game.settings - ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled") - if settings.plugins.get("ewrj") and ai_jammer: - for unit, member in zip(self.group.units, self.flight.iter_members()): - if settings.plugin_option("ewrj.ecm_required"): - ecm = WeaponType.JAMMER - if not member.loadout.has_weapon_of_type(ecm): - continue - if not member.is_player: - script_content = f'stopDjamming("{unit.name}")' - stop_jamming_script = RunScript(script_content) - waypoint.tasks.append(stop_jamming_script) - - evaide_fire = OptReactOnThreat(OptReactOnThreat.Values.EvadeFire) - waypoint.tasks.append(evaide_fire) + settings = self.flight.coalition.game.settings + 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) diff --git a/resources/plugins/ewrj/EW script 2.00.lua b/resources/plugins/ewrj/EW script 2.00.lua index 8c9395b7..19314f39 100644 --- a/resources/plugins/ewrj/EW script 2.00.lua +++ b/resources/plugins/ewrj/EW script 2.00.lua @@ -272,7 +272,7 @@ getRadars() end end -- startEWjamm('Prowler1') - function stopEWjamming(jammer) + function stopEWjamm(jammer) mist.removeFunction(offscriptfunc) trigger.action.outText("OFFENSIVE COUNTER MEASURES POD OFF "..jammer,5) end @@ -300,7 +300,7 @@ local _jammermenuoff = missionCommands.addSubMenuForGroup(_groupID,"Offensive Ja missionCommands.addCommandForGroup(_groupID, "Start Defensive Jamming ",_jammermenudef, function () startDjamming(jammer)end, nil) missionCommands.addCommandForGroup(_groupID, "Stop Defensive Jamming ",_jammermenudef, function () stopDjamming(jammer)end, nil) missionCommands.addCommandForGroup(_groupID, "Start Offensive Jamming ",_jammermenuoff, function () startEWjamm(jammer)end, nil) -missionCommands.addCommandForGroup(_groupID, "Stop Offensive Jamming ",_jammermenuoff, function () stopEWjamming(jammer)end, nil) +missionCommands.addCommandForGroup(_groupID, "Stop Offensive Jamming ",_jammermenuoff, function () stopEWjamm(jammer)end, nil) end end