Update EW Script and refine logic (#555)

This commit is contained in:
Drexyl 2025-08-28 03:20:27 +10:00 committed by GitHub
parent 756602e682
commit d2aa615133
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 245 additions and 136 deletions

View File

@ -13,12 +13,16 @@
* **[Modding]** Add Military Aircraft Mod 1.7.2 (See VSN Discord)
* **[Payload Editor]** Add Sniper POD
* **[Modding]** Update SU-30 mod to v2.8.03 Beta + CWS 3.70
* **[Plugins]** EW Script - DEAD added to applicable flight types.
* **[Plugins]** EW Script - Offensive Jamming restricted to aircraft with ALQ99/249 pods, or "has_built_in_jamming: true" in aircarft yaml (AI and Player)
## Fixes
* **[Flight Plans]** Fixed a bug when a package was created with only escort flights
* **[Flight Plans]** Added AntiShipStrike as a fallback task for OCA/Aircraft to fix a bug where the S-3B could not do OCA/Aircraft
* **[Squadrons]** Fixed a bug where loading an air wing config would not properly load all squadrons
* **[Flight Plans]** Fixed a bug where SEAD flights would fire one ARM and RTB
* **[Plugins]** EW Script - Fix radar detection routine.
# Retribution v1.4.1 (hotfix)

View File

@ -123,6 +123,7 @@ class WeaponType(Enum):
TGP = "TGP"
DECOY = "DECOY"
JAMMER = "JAMMER"
OFFENSIVE_JAMMER = "OFFENSIVE_JAMMER"
UNKNOWN = "unknown"

View File

@ -233,10 +233,14 @@ class AircraftType(UnitType[Type[FlyingType]]):
# when no TGP is mounted on any station.
has_built_in_target_pod: bool
# indicates if the aircraft has a built-in jammer allowing EWJamming to be used
# indicates if the aircraft has a built-in jammer allowing Defensive EWJamming to be used
# without the need for a jamming pod
has_built_in_ecm: bool
# Indicates if the aircraft has a built in jammer allowing Offensive EWJamming to be used
# without the need for a jamming pod
has_built_in_jamming: bool
task_priorities: dict[FlightType, int]
laser_code_configs: list[LaserCodeConfig]
@ -600,6 +604,7 @@ class AircraftType(UnitType[Type[FlyingType]]):
task_priorities=task_priorities,
has_built_in_target_pod=data.get("has_built_in_target_pod", False),
has_built_in_ecm=data.get("has_built_in_ecm", False),
has_built_in_jamming=data.get("has_built_in_jamming", False),
laser_code_configs=[
LaserCodeConfig.from_yaml(d) for d in data.get("laser_codes", [])
],

View File

@ -366,7 +366,9 @@ class AircraftGenerator:
and (
not self.need_ecm
or flight.any_member_has_weapon_of_type(WeaponType.JAMMER)
or flight.any_member_has_weapon_of_type(WeaponType.OFFENSIVE_JAMMER)
or flight.squadron.aircraft.has_built_in_ecm
or flight.squadron.aircraft.has_built_in_jamming
)
):
self.ewrj_package_dict[id(flight.package)].append(group)

View File

@ -189,8 +189,17 @@ class FlightGroupConfigurator:
return
# Check if ecm_required option is enabled
jammer_required = settings.plugin_option("ewrj.ecm_required")
has_jammer = member.loadout.has_weapon_of_type(WeaponType.JAMMER)
if jammer_required and not has_jammer:
offensive_jammer = member.loadout.has_weapon_of_type(
WeaponType.OFFENSIVE_JAMMER
)
offensive_inbuilt = self.flight.squadron.aircraft.has_built_in_jamming
has_jammer = (
member.loadout.has_weapon_of_type(WeaponType.JAMMER) or offensive_jammer
)
built_in_jammer = (
self.flight.squadron.aircraft.has_built_in_ecm or offensive_inbuilt
)
if jammer_required and not (has_jammer or built_in_jammer):
return
# Create the original ewrj_menu_trigger for player flight members
ewrj_menu_trigger = TriggerStart(comment=f"EWRJ-{unit.name}")
@ -199,6 +208,20 @@ class FlightGroupConfigurator:
self.group.points[0].tasks[0] = OptReactOnThreat(
OptReactOnThreat.Values.PassiveDefense
)
# Create LUA Flags for Offensive Jamming in EW Script for Player Flights
if not (offensive_jammer or offensive_inbuilt):
return
ewrj_offensive_trigger = TriggerStart(
comment=f"Offensive Jammer Flag {unit.name}"
)
ewrj_offensive_trigger.add_action(
DoScript(
String(
f'trigger.action.setUserFlag("offensive_jamming_{unit.name}", 1)'
)
)
)
self.mission.triggerrules.triggers.append(ewrj_offensive_trigger)
def setup_radios(self) -> RadioFrequency:
freq = self.flight.frequency

View File

@ -60,6 +60,7 @@ class JoinPointBuilder(PydcsWaypointBuilder):
FlightType.SEAD_SWEEP,
FlightType.SEAD,
FlightType.SEAD_ESCORT,
FlightType.DEAD,
]:
settings = self.flight.coalition.game.settings
ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled")

View File

@ -164,12 +164,17 @@ class PydcsWaypointBuilder:
settings = self.flight.coalition.game.settings
ecm_required = settings.plugin_option("ewrj.ecm_required")
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
has_jammer = member.loadout.has_weapon_of_type(
WeaponType.JAMMER
) or member.loadout.has_weapon_of_type(WeaponType.OFFENSIVE_JAMMER)
built_in_jammer = (
self.flight.squadron.aircraft.has_built_in_ecm
or self.flight.squadron.aircraft.has_built_in_jamming
)
if ecm_required and not (has_jammer or built_in_jammer):
continue
if not member.is_player:
script_content = f'{action}Djamming("{unit.name}")'
script_content = f'{action}IAdefjamming("{unit.name}")'
jamming_script = RunScript(script_content)
waypoint.tasks.append(jamming_script)
@ -178,8 +183,8 @@ class PydcsWaypointBuilder:
settings = self.flight.coalition.game.settings
ecm_required = settings.plugin_option("ewrj.ecm_required")
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
has_jammer = member.loadout.has_weapon_of_type(WeaponType.OFFENSIVE_JAMMER)
built_in_jammer = self.flight.squadron.aircraft.has_built_in_jamming
if ecm_required and not (has_jammer or built_in_jammer):
continue
if not member.is_player:

View File

@ -43,6 +43,7 @@ class RaceTrackBuilder(PydcsWaypointBuilder):
ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled")
if settings.plugins.get("ewrj") and ai_jammer:
self.defensive_jamming(waypoint, "start")
self.offensive_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

View File

@ -23,6 +23,7 @@ class RaceTrackEndBuilder(PydcsWaypointBuilder):
ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled")
if settings.plugins.get("ewrj") and ai_jammer:
self.defensive_jamming(waypoint, "stop")
self.offensive_jamming(waypoint, "stop")
def build(self) -> MovingPoint:
waypoint = super().build()

View File

@ -47,6 +47,7 @@ class SplitPointBuilder(PydcsWaypointBuilder):
FlightType.SEAD_SWEEP,
FlightType.SEAD,
FlightType.SEAD_ESCORT,
FlightType.DEAD,
]:
if self.flight.flight_type == FlightType.SEAD_ESCORT:
# Moved previous escort split tasks

View File

@ -1057,6 +1057,7 @@ class PretenseAircraftGenerator:
and (
not self.need_ecm
or flight.any_member_has_weapon_of_type(WeaponType.JAMMER)
or flight.any_member_has_weapon_of_type(WeaponType.OFFENSIVE_JAMMER)
)
):
self.ewrj_package_dict[id(flight.package)].append(group)

View File

@ -1,4 +1,7 @@
--EW Script 1.01
-- EW Script 2.02
-- Original script by ESA_Matador
-- Adapted for Retribution with fixes by Drexyl
--
-- DEFENSIVE JAMMING
-- We all know that DCS lacks an Electronic War (EW) enviroment… The ECM, are available only for individual aircraft. But in modern conflicts, since Vietnam, the Jammers, with aircrafts like, F4 Phantom, A6 Intruder, F18 Hornet, or AWACS... have been used to avoid enemy SAMs to shot down aircrafts.
-- What I did in this Script is to Emulate this EW (not simulate!!!). We need to use a little bit our imagination and to imagine, that some aircraft has Jamming Pods... with chaffs, ECMs or whatever. So i recommend that if you or any of your friends is flying as if he is carrying ECM pods... just put One or Two Mk82-84 to simulate that they are carrying this pod. And AVOID them to use them as weapons... (I would love if someone can model an AN/ANQ pod...
@ -57,132 +60,146 @@ end
---------------------------- LOOP TO SEE IF A SAM SHOULD BE SHUT OFF DEPENDING ON THE TARGET DETECTED, THE JAMMER AND THE SAM
function check(jammer, samunit)
-- trigger.action.outText(samunit.."Checking",1)
-- trigger.action.outText(samunit.."Checking",1)
--- New logic to replace unreliable getRadar() ---
local UnitObject = Unit.getByName(samunit)
if UnitObject ~= nil then
local status, target = UnitObject:getRadar()
local status, target = false, nil
local controller = UnitObject:getController()
local detectedTargets = controller:getDetectedTargets()
for _, tgt in pairs(detectedTargets) do
if tgt.object and tgt.object:isExist() then
status = true
target = tgt.object
break
end
end
--- Start of original script ---
-- trigger.action.outText(Unitobject,20)
-- if status == true then -- to see if the Radar is working
if target ~= nil then -- to see if it is engaging
local targetname = target:getName()
-- trigger.action.outText(samunit.." Detecting "..targetname,2)
-- trigger.action.outText(mist.utils.tableShow(jammerplanes),20)
-- trigger.action.outText("Target= "..target, "Jammer= "..jammer,10)
jammerobject = Unit.getByName(jammer)
if jammerobject ~= nil then
-- trigger.action.outText(jammer.." "..samunit,20)
if isLOS(samunit, jammer)==true then
-- trigger.action.outText(jammer..'is LOS with '..samunit,20)
if isLOS(samunit, jammer)==true then
-- trigger.action.outText(jammer..'is LOS with '..samunit,20)
local distSamJammer = get3DDist(Unit.getPoint(Unit.getByName(samunit)), Unit.getPoint(Unit.getByName(jammer)))
local distSamTarget = get3DDist(Unit.getPoint(Unit.getByName(samunit)), Unit.getPoint(Unit.getByName(targetname)))
local dice = math.random(0,100)
local conditiondist = 100 * distSamTarget / distSamJammer
-------------------------------------------- HEIGHT OF JAMMER
local distSamJammer = get3DDist(Unit.getPoint(Unit.getByName(samunit)), Unit.getPoint(Unit.getByName(jammer)))
local distSamTarget = get3DDist(Unit.getByName(samunit):getPoint(), Unit.getByName(targetname):getPoint())
local dice = math.random(0,100)
local conditiondist = 100 * distSamTarget / distSamJammer
local Position_vec3 = Unit.getByName(jammer):getPoint()
local _elevation = land.getHeight({x = Position_vec3.x, y = Position_vec3.z})
local _height = Position_vec3.y - _elevation
local tPosition_vec3 = Unit.getByName(targetname):getPoint()
local t_elevation = land.getHeight({x = tPosition_vec3.x, y = tPosition_vec3.z})
local t_height = tPosition_vec3.y - t_elevation
local prob = dice + _height/1000 + (_height - t_height)/1000
-- trigger.action.outText("dice "..dice.."prob "..prob.."altjammer".._height.."alttarget"..t_height,20)
-- HEIGHT OF JAMMER
-------------------------------------------- LOBE parameter
local SamPos = mist.utils.makeVec2(Unit.getByName(samunit):getPosition().p)-- tenemos un vector x e y
-- trigger.action.outText(mist.utils.tableShow(SamPos),20)
local JammerPos = mist.utils.makeVec2(Unit.getByName(jammer):getPosition().p)
-- trigger.action.outText(mist.utils.tableShow(JammerPos),20)
local TargetPos = mist.utils.makeVec2(Unit.getByName(targetname):getPosition().p)
-- trigger.action.outText(mist.utils.tableShow(TargetPos),20)
local AngleSamJammer = mist.utils.toDegree(mist.utils.getDir(mist.vec.sub(mist.utils.makeVec3GL(JammerPos),mist.utils.makeVec3GL(SamPos))))
-- trigger.action.outText(AngleSamJammer,20)
local AngleSamTarget = mist.utils.toDegree(mist.utils.getDir(mist.vec.sub(mist.utils.makeVec3GL(TargetPos),mist.utils.makeVec3GL(SamPos))))
-- trigger.action.outText(AngleSamTarget,20)
local offsetJamTar = smallestAngleDiff(AngleSamJammer, AngleSamTarget )
-- trigger.action.outText(offsetJamTar,20)
local offsetJamSam = smallestAngleDiff(AngleSamJammer, 180 )
-- trigger.action.outText("Jamm "..AngleSamJammer.."-Target ".. AngleSamTarget.."-Offjam ".. offsetJamSam.." -Offtar "..offsetJamTar,20)
local TargetandOffsetJamSam = smallestAngleDiff(AngleSamTarget, offsetJamSam )*2
if TargetandOffsetJamSam < 0 then
TargetandOffsetJamSam = -TargetandOffsetJamSam
end
-- trigger.action.outText(conditiondist.." relacion ".. prob.." probabilidad",20)
local anglecondition = 2/3 * distSamJammer/1000
-- trigger.action.outText(anglecondition.." target difference "..TargetandOffsetJamSam,20)
local Position_vec3 = Unit.getByName(jammer):getPoint()
local _elevation = land.getHeight({x = Position_vec3.x, y = Position_vec3.z})
local _height = Position_vec3.y - _elevation
--------------------------------------------------- PITCH and BANK
local tPosition_vec3 = Unit.getByName(targetname):getPoint()
local t_elevation = land.getHeight({x = tPosition_vec3.x, y = tPosition_vec3.z})
local t_height = tPosition_vec3.y - t_elevation
local prob = dice + _height/1000 + (_height - t_height)/1000
-- trigger.action.outText("dice "..dice.."prob "..prob.."altjammer".._height.."alttarget"..t_height,20)
local bankr = mist.utils.toDegree(mist.getRoll(Unit.getByName(jammer)))
if bankr < 0 then
bankr = -bankr
end
bank = bankr - 30
-- LOBE parameter
local SamPos = mist.utils.makeVec2(Unit.getByName(samunit):getPosition().p)-- tenemos un vector x e y
-- trigger.action.outText(mist.utils.tableShow(SamPos),20)
local JammerPos = mist.utils.makeVec2(Unit.getByName(jammer):getPosition().p)
-- trigger.action.outText(mist.utils.tableShow(JammerPos),20)
local TargetPos = mist.utils.makeVec2(Unit.getByName(targetname):getPosition().p)
-- trigger.action.outText(mist.utils.tableShow(TargetPos),20)
local AngleSamJammer = mist.utils.toDegree(mist.utils.getDir(mist.vec.sub(mist.utils.makeVec3GL(JammerPos),mist.utils.makeVec3GL(SamPos))))
-- trigger.action.outText(AngleSamJammer,20)
local AngleSamTarget = mist.utils.toDegree(mist.utils.getDir(mist.vec.sub(mist.utils.makeVec3GL(TargetPos),mist.utils.makeVec3GL(SamPos))))
-- trigger.action.outText(AngleSamTarget,20)
local offsetJamTar = smallestAngleDiff(AngleSamJammer, AngleSamTarget )
-- trigger.action.outText(offsetJamTar,20)
local offsetJamSam = smallestAngleDiff(AngleSamJammer, 180 )
-- trigger.action.outText("Jamm "..AngleSamJammer.."-Target ".. AngleSamTarget.."-Offjam ".. offsetJamSam.." -Offtar "..offsetJamTar,20)
local TargetandOffsetJamSam = smallestAngleDiff(AngleSamTarget, offsetJamSam )*2
if TargetandOffsetJamSam < 0 then
TargetandOffsetJamSam = -TargetandOffsetJamSam
-- trigger.action.outText("real"..bankr.."tocado"..bank,20)
local pitchr = mist.utils.toDegree(mist.getPitch(Unit.getByName(jammer)))
if pitchr < 0 then
pitchr = -pitch
end
pitch = pitchr - 30
-- trigger.action.outText("real"..bankr.."tocado"..bank,20)
end
-- trigger.action.outText(conditiondist.." relacion ".. prob.." probabilidad",20)
local anglecondition = 2/3 * distSamJammer/1000
-- trigger.action.outText(anglecondition.." target difference "..TargetandOffsetJamSam,20)
local sPosition_vec3 = Unit.getByName(samunit):getPoint()
-- trigger.action.outText(mist.utils.tableShow(sPosition_vec3),20)
local s_elevation = land.getHeight({x = sPosition_vec3.x, y = sPosition_vec3.z})
local s_height = sPosition_vec3.y - s_elevation
-- PITCH and BANK
local bankr = mist.utils.toDegree(mist.getRoll(Unit.getByName(jammer)))
if bankr < 0 then
bankr = -bankr
end
bank = bankr - 30
-- trigger.action.outText("real"..bankr.."tocado"..bank,20)
local pitchr = mist.utils.toDegree(mist.getPitch(Unit.getByName(jammer)))
if pitchr < 0 then
pitchr = -pitchr
end
pitch = pitchr - 30
-- trigger.action.outText("real"..pitchr.."tocado"..pitch,20)
local cateto = _height - s_height
-- trigger.action.outText("altura sam "..cateto,20)
local samunitposition = Unit.getByName(samunit):getPosition().p
local jammerposition = Unit.getByName(jammer):getPosition().p
local _2DDistSamJammer = mist.utils.get2DDist(samunitposition, jammerposition)
local anglesamjam = mist.utils.toDegree(math.asin(cateto/_2DDistSamJammer))
-- trigger.action.outText("angulo is "..anglesamjam,20)
------------------------------------------------------------------------
local probsector1 = ((5/2)*conditiondist)+10
local probsector2 = (conditiondist+30)
local probsector3 = ((conditiondist/3)+57)
if (conditiondist > 40.5)
and (prob <= probsector3)
and (anglecondition < TargetandOffsetJamSam)
and anglesamjam >= bank
and anglesamjam > pitch
then
-- trigger.action.outText(samunit.." "..conditiondist.." "..probsector3.." "..dice,20)
mist.scheduleFunction(samOFF, {samunit}, timer.getTime())
elseif ((conditiondist < 40.5) and (conditiondist > 13.33))
and (prob <= probsector2)
and (anglecondition < TargetandOffsetJamSam)
and anglesamjam >= bank
and anglesamjam > pitch
then
-- trigger.action.outText(samunit.." "..conditiondist.." "..probsector2.." "..dice,20)
mist.scheduleFunction(samOFF, {samunit}, timer.getTime())
elseif (conditiondist < 13.33)
and (prob <= probsector1 )
and (anglecondition < TargetandOffsetJamSam)
and anglesamjam >= bank
and anglesamjam > pitch
then
mist.scheduleFunction(samOFF, {samunit}, timer.getTime())
-- trigger.action.outText(samunit.." "..conditiondist.." "..probsector1.." "..dice,20)
else
mist.scheduleFunction(samON, {samunit}, timer.getTime()+ math.random(15,25))
-- trigger.action.outText("fuera de cobertura",20)
end
local sPosition_vec3 = Unit.getByName(samunit):getPoint()
-- trigger.action.outText(mist.utils.tableShow(sPosition_vec3),20)
local s_elevation = land.getHeight({x = sPosition_vec3.x, y = sPosition_vec3.z})
local s_height = sPosition_vec3.y - s_elevation
local cateto = _height - s_height
-- trigger.action.outText("altura sam "..cateto,20)
local samunitposition = Unit.getByName(samunit):getPosition().p
local jammerposition = Unit.getByName(jammer):getPosition().p
local _2DDistSamJammer = mist.utils.get2DDist(samunitposition, jammerposition)
local anglesamjam = mist.utils.toDegree(math.asin(cateto/_2DDistSamJammer))
-- trigger.action.outText("angulo is "..anglesamjam,20)
------------------------------------------------------------------------
local probsector1 = ((5/2)*conditiondist)+10
local probsector2 = (conditiondist+30)
local probsector3 = ((conditiondist/3)+57)
if (conditiondist > 40.5)
and (prob <= probsector3)
and (anglecondition < TargetandOffsetJamSam)
and anglesamjam >= bank
and anglesamjam > pitch
then
-- trigger.action.outText(samunit.." "..conditiondist.." "..probsector3.." "..dice,20)
mist.scheduleFunction(samOFF, {samunit}, timer.getTime())
elseif ((conditiondist < 40.5) and (conditiondist > 13.33))
and (prob <= probsector2)
and (anglecondition < TargetandOffsetJamSam)
and anglesamjam >= bank
and anglesamjam > pitch
then
-- trigger.action.outText(samunit.." "..conditiondist.." "..probsector2.." "..dice,20)
mist.scheduleFunction(samOFF, {samunit}, timer.getTime())
elseif (conditiondist < 13.33)
and (prob <= probsector1 )
and (anglecondition < TargetandOffsetJamSam)
and anglesamjam >= bank
and anglesamjam > pitch
then
mist.scheduleFunction(samOFF, {samunit}, timer.getTime())
-- trigger.action.outText(samunit.." "..conditiondist.." "..probsector1.." "..dice,20)
else
mist.scheduleFunction(samON, {samunit}, timer.getTime()+ math.random(15,25))
-- trigger.action.outText("fuera de cobertura",20)
end
else
-- trigger.action.outText(jammer..'NOT LOS with '..samunit,20)
mist.scheduleFunction(samON, {samunit}, timer.getTime()+ math.random(15,25))
@ -288,20 +305,53 @@ end
--------------------- MENU CRATION FOR START/STOP JAMMING
--function createmenu(jammer)
--if Unit.getByName(jammer) ~= nil then
--local _groupID = Unit.getByName(jammer):getGroup():getID()
--
--local _jammermenu = missionCommands.addSubMenuForGroup(_groupID,"Jammer menu", nil)
--local _jammermenudef = missionCommands.addSubMenuForGroup(_groupID,"Defensive Jamming", _jammermenu)
--local _jammermenuoff = missionCommands.addSubMenuForGroup(_groupID,"Offensive Jamming", _jammermenu)
--
--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 () stopEWjamm(jammer)end, nil)
--end
--end
-------------------- Retribution Specific Menu Creation
function createmenu(jammer)
if Unit.getByName(jammer) ~= nil then
local _groupID = Unit.getByName(jammer):getGroup():getID()
if Unit.getByName(jammer) ~= nil then
local _groupID = Unit.getByName(jammer):getGroup():getID()
local ecmFlag = trigger.misc.getUserFlag("offensive_jamming_" .. jammer)
local _jammermenu = missionCommands.addSubMenuForGroup(_groupID,"Jammer menu", nil)
local _jammermenudef = missionCommands.addSubMenuForGroup(_groupID,"Defensive Jamming", _jammermenu)
local _jammermenuoff = missionCommands.addSubMenuForGroup(_groupID,"Offensive Jamming", _jammermenu)
local _jammermenu = missionCommands.addSubMenuForGroup(_groupID, "Jammer menu", nil)
local _jammermenudef = missionCommands.addSubMenuForGroup(_groupID, "Defensive Jamming", _jammermenu)
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 () stopEWjamm(jammer)end, nil)
end
missionCommands.addCommandForGroup(_groupID, "Start Defensive Jamming", _jammermenudef, function ()
startDjamming(jammer)
end, nil)
missionCommands.addCommandForGroup(_groupID, "Stop Defensive Jamming", _jammermenudef, function ()
stopDjamming(jammer)
end, nil)
-- Only create Offensive Jamming menu if ECM flag is set
if ecmFlag == 1 then
local _jammermenuoff = missionCommands.addSubMenuForGroup(_groupID, "Offensive Jamming", _jammermenu)
missionCommands.addCommandForGroup(_groupID, "Start Offensive Jamming", _jammermenuoff, function ()
startEWjamm(jammer)
end, nil)
missionCommands.addCommandForGroup(_groupID, "Stop Offensive Jamming", _jammermenuoff, function ()
stopEWjamm(jammer)
end, nil)
end
end
end
-------------------- SWITCH TO ON AND OFF THE DEFENSIVE JAMMING
@ -311,7 +361,7 @@ EWJD(jammer)
end
function startDjamming(jammer)
switch[#switch+1]=jammer
trigger.action.outText("DEFENSIVE COUNTER MEASURES POD ON"..jammer,5)
trigger.action.outText("DEFENSIVE COUNTER MEASURES POD ON "..jammer,5)
end
function stopDjamming(jammer)
@ -320,25 +370,29 @@ if switch[i]==jammer then
switch[i] = nil
end
end
trigger.action.outText("DEFENSIVE COUNTER MEASURES POD OFF"..jammer,5)
trigger.action.outText("DEFENSIVE COUNTER MEASURES POD OFF "..jammer,5)
end
-------------------------------------- FUNCTION THAT EVALUATES THE DISTANCE OF THE MISSILE TO THE TARGET... YOU CAN EVEN DEFEND CLOSER AIRCRAFTS. BASED ON TRAINING MISSILES FROM GRIMES
function EWJD(jammer)
trigger.action.outText("EWJD Script ON"..jammer,5)
-- trigger.action.outText("EWJD Script ON "..jammer,5)
------------------------------------------------------------ DISTANCES AND PROBABILITIES OF JAMM THE MISSILE FOR DEFENSIVE JAMMING REMOVALDIST1 CORRESPOND TO PKILL1, REMOVALDIST2 CORRESPOND TO PKILL2, ETC...
local removalDist1 = 500
local removalDist2 = 1500
local removalDist3 = 3000
local removalDist4 = 5000
local removalDist5 = 7000
-- local pkill_1 =100 -------- PROBAILITY OF SUCCESFULL JAMMING REMOVALDIST1 CORRESPOND TO PKILL1, REMOVALDIST2 CORRESPOND TO PKILL2, ETC...
-- local pkill_2 =100
-- local pkill_3 =100
-- local pkill_4 =100
-- local pkill_5 =100
local pkill_1 =95 -------- PROBAILITY OF SUCCESFULL JAMMING REMOVALDIST1 CORRESPOND TO PKILL1, REMOVALDIST2 CORRESPOND TO PKILL2, ETC...
local pkill_2 =65
local pkill_3 =50
local pkill_4 =30
local pkill_5 =15
local remove_missile_method = 0
-- 0 will create an explosion
-- 1 will use Object.destroy() which simply makes the missile disappear.
@ -375,6 +429,7 @@ local pkill_5 =15
end
if remove_missile_method == 0 then
trigger.action.explosion(Object.getPosition(aiMissiles[id].missile).p, 5)
-- trigger.action.outText("MISSILE GO BOOM!!! "..jammer,10)
else
Object.destroy(aiMissiles[id].missile)
end
@ -403,19 +458,19 @@ local pkill_5 =15
-- trigger.action.outText(prob..jammer, 20)
if dist < removalDist5 and prob < pkill_5 then -- if its close and still guiding
removeMis(mis.uid)
-- trigger.action.outText('5', 20)
-- trigger.action.outText('5', 20)
elseif dist < removalDist4 and prob < pkill_4 then -- if its close and still guiding
removeMis(mis.uid)
-- trigger.action.outText('4', 20)
-- trigger.action.outText('4', 20)
elseif dist < removalDist3 and prob < pkill_3 then -- if its close and still guiding
removeMis(mis.uid)
-- trigger.action.outText('3', 20)
-- trigger.action.outText('3', 20)
elseif dist < removalDist2 and prob < pkill_2 then -- if its close and still guiding
removeMis(mis.uid)
-- trigger.action.outText('2', 20)
-- trigger.action.outText('2', 20)
elseif dist < removalDist1 and prob < pkill_1 then -- if its close and still guiding
removeMis(mis.uid)
-- trigger.action.outText('1', 20)
-- trigger.action.outText('1', 20)
else
tot = math.min(10, dist/getMag(mist.vec.sub(misVel, targVel)))
timer.scheduleFunction(checkMis, mis, timer.getTime() + tot)

Binary file not shown.

View File

@ -15,7 +15,7 @@
],
"scriptsWorkOrders": [
{
"file": "EW script 2.00.lua",
"file": "EW script 2.02.lua",
"mnemonic": "ewrj"
}
],

View File

@ -8,4 +8,4 @@ variants:
E-7A Wedgetail: {}
tasks:
AEW&C: 30
has_built_in_ecm: true
has_built_in_jamming: true

View File

@ -68,3 +68,5 @@ tasks:
SEAD Escort: 450
Strike: 600
TARCAP: 450
has_built_in_ecm: true

View File

@ -76,3 +76,5 @@ weapon_injections: # AGM-154B only works for AI
8:
- "{AGM-154B}"
- "{BRU57_2*AGM-154B}"
has_built_in_ecm: true

View File

@ -60,3 +60,4 @@ tasks:
Refueling: 0
Recovery: 0
has_built_in_ecm: true

View File

@ -76,3 +76,5 @@ weapon_injections: # AGM-154B only works for AI
8:
- "{AGM-154B}"
- "{BRU57_2*AGM-154B}"
has_built_in_ecm: true

View File

@ -59,3 +59,5 @@ utc_kneeboard: true
tasks:
Refueling: 0
Recovery: 0
has_built_in_ecm: true

View File

@ -1,5 +1,5 @@
name: ALQ-249 Mid Band Next Generation Jammer
type: JAMMER
type: OFFENSIVE_JAMMER
# https://www.deagel.com/Components/ALQ-249%20Next%20Generation%20Jammer/a002543#001
year: 2025
fallback:

View File

@ -1,5 +1,5 @@
name: AN/ALQ-99 ECM
type: JAMMER
type: OFFENSIVE_JAMMER
# https://www.deagel.com/Components/ANALQ-99/a000899#001
year: 1973
fallback: