Merge branch 'master' into develop

This commit is contained in:
Frank 2020-11-30 11:40:34 +01:00
commit edf657c65c
5 changed files with 135 additions and 119 deletions

View File

@ -595,19 +595,24 @@ function AI_AIR:onafterRTB( AIGroup, From, Event, To )
--- Calculate the target route point. --- Calculate the target route point.
local FromCoord = AIGroup:GetCoordinate() local FromCoord = AIGroup:GetCoordinate()
local ToTargetCoord = self.HomeAirbase:GetCoordinate() local ToTargetCoord = self.HomeAirbase:GetCoordinate() -- coordinate is on land height(!)
local ToTargetVec3 = ToTargetCoord:GetVec3()
if not self.RTBMinSpeed and not self.RTBMaxSpeed then ToTargetVec3.y = ToTargetCoord:GetLandHeight()+1000 -- let's set this 1000m/3000 feet above ground
local ToTargetCoord2 = COORDINATE:NewFromVec3( ToTargetVec3 )
if not self.RTBMinSpeed or not self.RTBMaxSpeed then
local RTBSpeedMax = AIGroup:GetSpeedMax() local RTBSpeedMax = AIGroup:GetSpeedMax()
self:SetRTBSpeed( RTBSpeedMax * 0.25, RTBSpeedMax * 0.25 ) self:SetRTBSpeed( RTBSpeedMax * 0.5, RTBSpeedMax * 0.6 )
end end
local RTBSpeed = math.random( self.RTBMinSpeed, self.RTBMaxSpeed ) local RTBSpeed = math.random( self.RTBMinSpeed, self.RTBMaxSpeed )
local ToAirbaseAngle = FromCoord:GetAngleDegrees( FromCoord:GetDirectionVec3( ToTargetCoord ) ) --local ToAirbaseAngle = FromCoord:GetAngleDegrees( FromCoord:GetDirectionVec3( ToTargetCoord2 ) )
local Distance = FromCoord:Get2DDistance( ToTargetCoord ) local Distance = FromCoord:Get2DDistance( ToTargetCoord2 )
local ToAirbaseCoord = FromCoord:Translate( 5000, ToAirbaseAngle ) --local ToAirbaseCoord = FromCoord:Translate( 5000, ToAirbaseAngle )
local ToAirbaseCoord = ToTargetCoord2
if Distance < 5000 then if Distance < 5000 then
self:I( "RTB and near the airbase!" ) self:I( "RTB and near the airbase!" )
self:Home() self:Home()

View File

@ -1,24 +1,24 @@
--- **Functional** -- Make SAM sites execute evasive and defensive behaviour when being fired upon. --- **Functional** -- Make SAM sites execute evasive and defensive behaviour when being fired upon.
-- --
-- === -- ===
-- --
-- ## Features: -- ## Features:
-- --
-- * When SAM sites are being fired upon, the SAMs will take evasive action will reposition themselves when possible. -- * When SAM sites are being fired upon, the SAMs will take evasive action will reposition themselves when possible.
-- * When SAM sites are being fired upon, the SAMs will take defensive action by shutting down their radars. -- * When SAM sites are being fired upon, the SAMs will take defensive action by shutting down their radars.
-- --
-- === -- ===
-- --
-- ## Missions: -- ## Missions:
-- --
-- [SEV - SEAD Evasion](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/SEV%20-%20SEAD%20Evasion) -- [SEV - SEAD Evasion](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/SEV%20-%20SEAD%20Evasion)
-- --
-- === -- ===
-- --
-- ### Authors: **FlightControl** -- ### Authors: **FlightControl**
-- --
-- === -- ===
-- --
-- @module Functional.Sead -- @module Functional.Sead
-- @image SEAD.JPG -- @image SEAD.JPG
@ -26,25 +26,26 @@
-- @extends Core.Base#BASE -- @extends Core.Base#BASE
--- Make SAM sites execute evasive and defensive behaviour when being fired upon. --- Make SAM sites execute evasive and defensive behaviour when being fired upon.
-- --
-- This class is very easy to use. Just setup a SEAD object by using @{#SEAD.New}() and SAMs will evade and take defensive action when being fired upon. -- This class is very easy to use. Just setup a SEAD object by using @{#SEAD.New}() and SAMs will evade and take defensive action when being fired upon.
-- --
-- # Constructor: -- # Constructor:
-- --
-- Use the @{#SEAD.New}() constructor to create a new SEAD object. -- Use the @{#SEAD.New}() constructor to create a new SEAD object.
-- --
-- SEAD_RU_SAM_Defenses = SEAD:New( { 'RU SA-6 Kub', 'RU SA-6 Defenses', 'RU MI-26 Troops', 'RU Attack Gori' } ) -- SEAD_RU_SAM_Defenses = SEAD:New( { 'RU SA-6 Kub', 'RU SA-6 Defenses', 'RU MI-26 Troops', 'RU Attack Gori' } )
-- --
-- @field #SEAD -- @field #SEAD
SEAD = { SEAD = {
ClassName = "SEAD", ClassName = "SEAD",
TargetSkill = { TargetSkill = {
Average = { Evade = 50, DelayOff = { 10, 25 }, DelayOn = { 10, 30 } } , Average = { Evade = 30, DelayOn = { 40, 60 } } ,
Good = { Evade = 30, DelayOff = { 8, 20 }, DelayOn = { 20, 40 } } , Good = { Evade = 20, DelayOn = { 30, 50 } } ,
High = { Evade = 15, DelayOff = { 5, 17 }, DelayOn = { 30, 50 } } , High = { Evade = 15, DelayOn = { 20, 40 } } ,
Excellent = { Evade = 10, DelayOff = { 3, 10 }, DelayOn = { 30, 60 } } Excellent = { Evade = 10, DelayOn = { 10, 30 } }
}, },
SEADGroupPrefixes = {}, SEADGroupPrefixes = {},
SuppressedGroups = {},
EngagementRange = 75 -- default 75% engagement range Feature Request #1355 EngagementRange = 75 -- default 75% engagement range Feature Request #1355
} }
@ -61,7 +62,7 @@ function SEAD:New( SEADGroupPrefixes )
local self = BASE:Inherit( self, BASE:New() ) local self = BASE:Inherit( self, BASE:New() )
self:F( SEADGroupPrefixes ) self:F( SEADGroupPrefixes )
if type( SEADGroupPrefixes ) == 'table' then if type( SEADGroupPrefixes ) == 'table' then
for SEADGroupPrefixID, SEADGroupPrefix in pairs( SEADGroupPrefixes ) do for SEADGroupPrefixID, SEADGroupPrefix in pairs( SEADGroupPrefixes ) do
self.SEADGroupPrefixes[SEADGroupPrefix] = SEADGroupPrefix self.SEADGroupPrefixes[SEADGroupPrefix] = SEADGroupPrefix
@ -69,15 +70,15 @@ function SEAD:New( SEADGroupPrefixes )
else else
self.SEADGroupNames[SEADGroupPrefixes] = SEADGroupPrefixes self.SEADGroupNames[SEADGroupPrefixes] = SEADGroupPrefixes
end end
self:HandleEvent( EVENTS.Shot ) self:HandleEvent( EVENTS.Shot )
self:I("*** SEAD - Started Version 0.2.0")
return self return self
end end
--- Sets the engagement range of the SAMs. Defaults to 75% to make it more deadly. Feature Request #1355 --- Sets the engagement range of the SAMs. Defaults to 75% to make it more deadly. Feature Request #1355
-- @param #SEAD self -- @param #SEAD self
-- @param #number range Gives the engagement range in percent, e.g. 50 -- @param #number range Set the engagement range in percent, e.g. 50
-- @return self -- @return self
function SEAD:SetEngagementRange(range) function SEAD:SetEngagementRange(range)
self:F( { range } ) self:F( { range } )
@ -86,6 +87,7 @@ function SEAD:SetEngagementRange(range)
range = 75 range = 75
end end
self.EngagementRange = range self.EngagementRange = range
self:T(string.format("*** SEAD - Engagement range set to %s",range))
return self return self
end end
@ -94,18 +96,19 @@ end
-- @param #SEAD -- @param #SEAD
-- @param Core.Event#EVENTDATA EventData -- @param Core.Event#EVENTDATA EventData
function SEAD:OnEventShot( EventData ) function SEAD:OnEventShot( EventData )
self:F( { EventData } ) self:T( { EventData } )
local SEADUnit = EventData.IniDCSUnit local SEADUnit = EventData.IniDCSUnit
local SEADUnitName = EventData.IniDCSUnitName local SEADUnitName = EventData.IniDCSUnitName
local SEADWeapon = EventData.Weapon -- Identify the weapon fired local SEADWeapon = EventData.Weapon -- Identify the weapon fired
local SEADWeaponName = EventData.WeaponName -- return weapon type local SEADWeaponName = EventData.WeaponName -- return weapon type
-- Start of the 2nd loop
self:T( "Missile Launched = " .. SEADWeaponName ) self:T( "*** SEAD - Missile Launched = " .. SEADWeaponName)
self:T({ SEADWeapon })
--if SEADWeaponName == "KH-58" or SEADWeaponName == "KH-25MPU" or SEADWeaponName == "AGM-88" or SEADWeaponName == "KH-31A" or SEADWeaponName == "KH-31P" then -- Check if the missile is a SEAD
--check for SEAD missiles
if SEADWeaponName == "weapons.missiles.X_58" --Kh-58U anti-radiation missiles fired if SEADWeaponName == "weapons.missiles.X_58" --Kh-58U anti-radiation missiles fired
or or
SEADWeaponName == "weapons.missiles.Kh25MP_PRGS1VP" --Kh-25MP anti-radiation missiles fired SEADWeaponName == "weapons.missiles.Kh25MP_PRGS1VP" --Kh-25MP anti-radiation missiles fired
or or
SEADWeaponName == "weapons.missiles.X_25MP" --Kh-25MPU anti-radiation missiles fired SEADWeaponName == "weapons.missiles.X_25MP" --Kh-25MPU anti-radiation missiles fired
@ -122,27 +125,35 @@ function SEAD:OnEventShot( EventData )
or or
SEADWeaponName == "weapons.missiles.AGM_122" --AGM-122 Sidearm anti-radiation missiles fired SEADWeaponName == "weapons.missiles.AGM_122" --AGM-122 Sidearm anti-radiation missiles fired
or or
SEADWeaponName == "weapons.missiles.LD-10" --LD-10 anti-radiation missiles fired
or
SEADWeaponName == "weapons.missiles.ALARM" --ALARM anti-radiation missiles fired SEADWeaponName == "weapons.missiles.ALARM" --ALARM anti-radiation missiles fired
or
SEADWeaponName == "weapons.missiles.AGM_84E" --AGM84 anti-radiation missiles fired
or
SEADWeaponName == "weapons.missiles.AGM_84A" --AGM84 anti-radiation missiles fired
or
SEADWeaponName == "weapons.missiles.AGM_84H" --AGM84 anti-radiation missiles fired
then then
local _evade = math.random (1,100) -- random number for chance of evading action local _evade = math.random (1,100) -- random number for chance of evading action
local _targetMim = EventData.Weapon:getTarget() -- Identify target local _targetMim = EventData.Weapon:getTarget() -- Identify target
local _targetMimname = Unit.getName(_targetMim) local _targetMimname = Unit.getName(_targetMim) -- Unit name
local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon)) local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon)) --targeted grouo
local _targetMimgroupName = _targetMimgroup:getName() local _targetMimgroupName = _targetMimgroup:getName() -- group name
local _targetMimcont= _targetMimgroup:getController()
local _targetskill = _DATABASE.Templates.Units[_targetMimname].Template.skill local _targetskill = _DATABASE.Templates.Units[_targetMimname].Template.skill
self:T( self.SEADGroupPrefixes ) self:T( self.SEADGroupPrefixes )
self:T( _targetMimgroupName ) self:T( _targetMimgroupName )
-- see if we are shot at
local SEADGroupFound = false local SEADGroupFound = false
for SEADGroupPrefixID, SEADGroupPrefix in pairs( self.SEADGroupPrefixes ) do for SEADGroupPrefixID, SEADGroupPrefix in pairs( self.SEADGroupPrefixes ) do
if string.find( _targetMimgroupName, SEADGroupPrefix, 1, true ) then if string.find( _targetMimgroupName, SEADGroupPrefix, 1, true ) then
SEADGroupFound = true SEADGroupFound = true
self:T( 'Group Found' ) self:T( '*** SEAD - Group Found' )
break break
end end
end end
if SEADGroupFound == true then if SEADGroupFound == true then -- yes we are being attacked
if _targetskill == "Random" then -- when skill is random, choose a skill if _targetskill == "Random" then -- when skill is random, choose a skill
local Skills = { "Average", "Good", "High", "Excellent" } local Skills = { "Average", "Good", "High", "Excellent" }
_targetskill = Skills[ math.random(1,4) ] _targetskill = Skills[ math.random(1,4) ]
@ -150,44 +161,36 @@ function SEAD:OnEventShot( EventData )
self:T( _targetskill ) self:T( _targetskill )
if self.TargetSkill[_targetskill] then if self.TargetSkill[_targetskill] then
if (_evade > self.TargetSkill[_targetskill].Evade) then if (_evade > self.TargetSkill[_targetskill].Evade) then
self:T( string.format("Evading, target skill " ..string.format(_targetskill)) ) self:T( string.format("*** SEAD - Evading, target skill " ..string.format(_targetskill)) )
local _targetMim = Weapon.getTarget(SEADWeapon)
local _targetMimname = Unit.getName(_targetMim)
local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon)) local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon))
local _targetMimcont= _targetMimgroup:getController() local _targetMimcont= _targetMimgroup:getController()
routines.groupRandomDistSelf(_targetMimgroup,300,'Diamond',250,20) -- move randomly routines.groupRandomDistSelf(_targetMimgroup,300,'Diamond',250,20) -- move randomly
local SuppressedGroups1 = {} -- unit suppressed radar off for a random time --tracker ID table to switch groups off and on again
local function SuppressionEnd1(id)
id.ctrl:setOption(AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.GREEN)
SuppressedGroups1[id.groupName] = nil
end
local id = { local id = {
groupName = _targetMimgroup, groupName = _targetMimgroup,
ctrl = _targetMimcont ctrl = _targetMimcont
} }
local delay1 = math.random(self.TargetSkill[_targetskill].DelayOff[1], self.TargetSkill[_targetskill].DelayOff[2]) local delay1 = math.random(self.TargetSkill[_targetskill].DelayOff[1], self.TargetSkill[_targetskill].DelayOff[2])
if SuppressedGroups1[id.groupName] == nil then if SuppressedGroups1[id.groupName] == nil then
SuppressedGroups1[id.groupName] = { SuppressedGroups1[id.groupName] = {
SuppressionEndTime1 = timer.getTime() + delay1, SuppressionEndTime1 = timer.getTime() + delay1,
SuppressionEndN1 = SuppressionEndCounter1 --Store instance of SuppressionEnd() scheduled function SuppressionEndN1 = SuppressionEndCounter1 --Store instance of SuppressionEnd() scheduled function
} }
Controller.setOption(_targetMimcont, AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.GREEN) Controller.setOption(_targetMimcont, AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.GREEN)
timer.scheduleFunction(SuppressionEnd1, id, SuppressedGroups1[id.groupName].SuppressionEndTime1) --Schedule the SuppressionEnd() function timer.scheduleFunction(SuppressionEnd1, id, SuppressedGroups1[id.groupName].SuppressionEndTime1) --Schedule the SuppressionEnd() function
--trigger.action.outText( string.format("Radar Off " ..string.format(delay1)), 20) --trigger.action.outText( string.format("Radar Off " ..string.format(delay1)), 20)
end end
local SuppressedGroups = {} local SuppressedGroups = {}
local function SuppressionEnd(id) local function SuppressionEnd(id)
local range = self.EngagementRange -- Feature Request #1355 local range = self.EngagementRange -- Feature Request #1355
--env.info(string.format("*** SEAD - Engagement Range is %d", range)) --env.info(string.format("*** SEAD - Engagement Range is %d", range))
@ -195,22 +198,16 @@ function SEAD:OnEventShot( EventData )
id.ctrl:setOption(AI.Option.Ground.id.AC_ENGAGEMENT_RANGE_RESTRICTION,range) --Feature Request #1355 id.ctrl:setOption(AI.Option.Ground.id.AC_ENGAGEMENT_RANGE_RESTRICTION,range) --Feature Request #1355
SuppressedGroups[id.groupName] = nil SuppressedGroups[id.groupName] = nil
end end
-- randomize switch-on time
local id = {
groupName = _targetMimgroup,
ctrl = _targetMimcont
}
local delay = math.random(self.TargetSkill[_targetskill].DelayOn[1], self.TargetSkill[_targetskill].DelayOn[2]) local delay = math.random(self.TargetSkill[_targetskill].DelayOn[1], self.TargetSkill[_targetskill].DelayOn[2])
local SuppressionEndTime = timer.getTime() + delay
if SuppressedGroups[id.groupName] == nil then --create entry
SuppressedGroups[id.groupName] = { if self.SuppressedGroups[id.groupName] == nil then --no timer entry for this group yet
SuppressionEndTime = timer.getTime() + delay, self.SuppressedGroups[id.groupName] = {
SuppressionEndN = SuppressionEndCounter --Store instance of SuppressionEnd() scheduled function SuppressionEndTime = delay
} }
Controller.setOption(_targetMimcont, AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.GREEN)
timer.scheduleFunction(SuppressionEnd, id, SuppressedGroups[id.groupName].SuppressionEndTime) --Schedule the SuppressionEnd() function timer.scheduleFunction(SuppressionEnd, id, SuppressionEndTime) --Schedule the SuppressionEnd() function
--trigger.action.outText( string.format("Radar On " ..string.format(delay)), 20)
end end
end end
end end

View File

@ -253,7 +253,12 @@ do -- TASK_A2A_DISPATCHER
return self return self
end end
--- Set flashing player messages on or off
-- @param #TASK_A2A_DISPATCHER self
-- @param #boolean onoff Set messages on (true) or off (false)
function TASK_A2A_DISPATCHER:SetSendMessages( onoff )
self.FlashNewTask = onoff
end
--- Creates an INTERCEPT task when there are targets for it. --- Creates an INTERCEPT task when there are targets for it.
-- @param #TASK_A2A_DISPATCHER self -- @param #TASK_A2A_DISPATCHER self
@ -610,7 +615,7 @@ do -- TASK_A2A_DISPATCHER
local TaskText = TaskReport:Text(", ") local TaskText = TaskReport:Text(", ")
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
if ( not Mission:IsGroupAssigned(TaskGroup) ) and TaskText ~= "" and ( not not self.FlashNewTask) then if ( not Mission:IsGroupAssigned(TaskGroup) ) and TaskText ~= "" and (self.FlashNewTask) then
Mission:GetCommandCenter():MessageToGroup( string.format( "%s has tasks %s. Subscribe to a task using the radio menu.", Mission:GetShortText(), TaskText ), TaskGroup ) Mission:GetCommandCenter():MessageToGroup( string.format( "%s has tasks %s. Subscribe to a task using the radio menu.", Mission:GetShortText(), TaskText ), TaskGroup )
end end
end end

View File

@ -451,6 +451,7 @@ do -- TASK_A2G_DISPATCHER
self.Detection = Detection self.Detection = Detection
self.Mission = Mission self.Mission = Mission
self.FlashNewTask = true --set to false to suppress flash messages
self.Detection:FilterCategories( { Unit.Category.GROUND_UNIT } ) self.Detection:FilterCategories( { Unit.Category.GROUND_UNIT } )
@ -471,6 +472,12 @@ do -- TASK_A2G_DISPATCHER
return self return self
end end
--- Set flashing player messages on or off
-- @param #TASK_A2G_DISPATCHER self
-- @param #boolean onoff Set messages on (true) or off (false)
function TASK_A2G_DISPATCHER:SetSendMessages( onoff )
self.FlashNewTask = onoff
end
--- Creates a SEAD task when there are targets for it. --- Creates a SEAD task when there are targets for it.
-- @param #TASK_A2G_DISPATCHER self -- @param #TASK_A2G_DISPATCHER self
@ -616,7 +623,9 @@ do -- TASK_A2G_DISPATCHER
if not DetectedItem then if not DetectedItem then
local TaskText = Task:GetName() local TaskText = Task:GetName()
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
Mission:GetCommandCenter():MessageToGroup( string.format( "Obsolete A2G task %s for %s removed.", TaskText, Mission:GetShortText() ), TaskGroup ) if self.FlashNewTask then
Mission:GetCommandCenter():MessageToGroup( string.format( "Obsolete A2G task %s for %s removed.", TaskText, Mission:GetShortText() ), TaskGroup )
end
end end
Task = self:RemoveTask( TaskIndex ) Task = self:RemoveTask( TaskIndex )
end end
@ -686,7 +695,7 @@ do -- TASK_A2G_DISPATCHER
-- Now we send to each group the changes, if any. -- Now we send to each group the changes, if any.
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
local TargetsText = TargetsReport:Text(", ") local TargetsText = TargetsReport:Text(", ")
if ( Mission:IsGroupAssigned(TaskGroup) ) and TargetsText ~= "" then if ( Mission:IsGroupAssigned(TaskGroup) ) and TargetsText ~= "" and self.FlashNewTask then
Mission:GetCommandCenter():MessageToGroup( string.format( "Task %s has change of targets:\n %s", Task:GetName(), TargetsText ), TaskGroup ) Mission:GetCommandCenter():MessageToGroup( string.format( "Task %s has change of targets:\n %s", Task:GetName(), TargetsText ), TaskGroup )
end end
end end
@ -805,7 +814,7 @@ do -- TASK_A2G_DISPATCHER
local TaskText = TaskReport:Text(", ") local TaskText = TaskReport:Text(", ")
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
if ( not Mission:IsGroupAssigned(TaskGroup) ) and TaskText ~= "" then if ( not Mission:IsGroupAssigned(TaskGroup) ) and TaskText ~= "" and self.FlashNewTask then
Mission:GetCommandCenter():MessageToGroup( string.format( "%s has tasks %s. Subscribe to a task using the radio menu.", Mission:GetShortText(), TaskText ), TaskGroup ) Mission:GetCommandCenter():MessageToGroup( string.format( "%s has tasks %s. Subscribe to a task using the radio menu.", Mission:GetShortText(), TaskText ), TaskGroup )
end end
end end
@ -815,4 +824,4 @@ do -- TASK_A2G_DISPATCHER
return true return true
end end
end end

View File

@ -175,7 +175,7 @@
-- --
-- ## 5.5) Air-2-Air missile attack range: -- ## 5.5) Air-2-Air missile attack range:
-- * @{#CONTROLLABLE.OptionAAAttackRange}(): Defines the usage of A2A missiles against possible targets . -- * @{#CONTROLLABLE.OptionAAAttackRange}(): Defines the usage of A2A missiles against possible targets .
-- --
-- @field #CONTROLLABLE -- @field #CONTROLLABLE
CONTROLLABLE = { CONTROLLABLE = {
ClassName = "CONTROLLABLE", ClassName = "CONTROLLABLE",
@ -503,7 +503,7 @@ function CONTROLLABLE:TaskCombo( DCSTasks )
tasks = DCSTasks tasks = DCSTasks
} }
} }
return DCSTaskCombo return DCSTaskCombo
end end
@ -801,12 +801,12 @@ end
-- @return #CONTROLLABLE self -- @return #CONTROLLABLE self
function CONTROLLABLE:CommandSetFrequency(Frequency, Modulation, Delay) function CONTROLLABLE:CommandSetFrequency(Frequency, Modulation, Delay)
local CommandSetFrequency = { local CommandSetFrequency = {
id = 'SetFrequency', id = 'SetFrequency',
params = { params = {
frequency = Frequency*1000000, frequency = Frequency*1000000,
modulation = Modulation or radio.modulation.AM, modulation = Modulation or radio.modulation.AM,
} }
} }
if Delay and Delay>0 then if Delay and Delay>0 then
@ -880,7 +880,7 @@ function CONTROLLABLE:TaskAttackGroup( AttackGroup, WeaponType, WeaponExpend, At
groupId = AttackGroup:GetID(), groupId = AttackGroup:GetID(),
weaponType = WeaponType or 1073741822, weaponType = WeaponType or 1073741822,
expend = WeaponExpend or "Auto", expend = WeaponExpend or "Auto",
attackQtyLimit = AttackQty and true or false, attackQtyLimit = AttackQty and true or false,
attackQty = AttackQty or 1, attackQty = AttackQty or 1,
directionEnabled = Direction and true or false, directionEnabled = Direction and true or false,
direction = Direction and math.rad(Direction) or 0, direction = Direction and math.rad(Direction) or 0,
@ -920,7 +920,7 @@ function CONTROLLABLE:TaskAttackUnit(AttackUnit, GroupAttack, WeaponExpend, Atta
weaponType = WeaponType or 1073741822, weaponType = WeaponType or 1073741822,
} }
} }
return DCSTask return DCSTask
end end
@ -1084,7 +1084,7 @@ function CONTROLLABLE:TaskEmbarking(Coordinate, GroupSetForEmbarking, Duration,
-- Distribution -- Distribution
--local distribution={} --local distribution={}
--distribution[id]=gids --distribution[id]=gids
local groupID=self and self:GetID() local groupID=self and self:GetID()
local DCSTask = { local DCSTask = {
@ -1313,7 +1313,7 @@ function CONTROLLABLE:TaskLandAtVec2(Vec2, Duration)
duration = Duration, duration = Duration,
}, },
} }
return DCSTask return DCSTask
end end
@ -1795,7 +1795,7 @@ function CONTROLLABLE:TaskFunction( FunctionString, ... )
-- DCS task. -- DCS task.
local DCSTask = self:TaskWrappedAction(self:CommandDoScript(table.concat( DCSScript ))) local DCSTask = self:TaskWrappedAction(self:CommandDoScript(table.concat( DCSScript )))
return DCSTask return DCSTask
end end
@ -1972,7 +1972,7 @@ function CONTROLLABLE:TaskRoute( Points )
id = 'Mission', id = 'Mission',
params = { params = {
airborne = self:IsAir(), airborne = self:IsAir(),
route = {points = Points}, route = {points = Points},
}, },
} }
@ -2898,9 +2898,9 @@ end
function CONTROLLABLE:OptionROE(ROEvalue) function CONTROLLABLE:OptionROE(ROEvalue)
local DCSControllable = self:GetDCSObject() local DCSControllable = self:GetDCSObject()
if DCSControllable then if DCSControllable then
local Controller = self:_GetController() local Controller = self:_GetController()
if self:IsAir() then if self:IsAir() then
@ -3464,13 +3464,13 @@ end
-- @return #CONTROLLABLE self -- @return #CONTROLLABLE self
function CONTROLLABLE:OptionProhibitAfterburner(Prohibit) function CONTROLLABLE:OptionProhibitAfterburner(Prohibit)
self:F2( { self.ControllableName } ) self:F2( { self.ControllableName } )
if Prohibit==nil then if Prohibit==nil then
Prohibit=true Prohibit=true
end end
if self:IsAir() then if self:IsAir() then
self:SetOption(AI.Option.Air.id.PROHIBIT_AB, Prohibit) self:SetOption(AI.Option.Air.id.PROHIBIT_AB, Prohibit)
end end
return self return self
@ -3481,9 +3481,9 @@ end
-- @return #CONTROLLABLE self -- @return #CONTROLLABLE self
function CONTROLLABLE:OptionECM_Never() function CONTROLLABLE:OptionECM_Never()
self:F2( { self.ControllableName } ) self:F2( { self.ControllableName } )
if self:IsAir() then if self:IsAir() then
self:SetOption(AI.Option.Air.id.ECM_USING, 0) self:SetOption(AI.Option.Air.id.ECM_USING, 0)
end end
return self return self
@ -3494,9 +3494,9 @@ end
-- @return #CONTROLLABLE self -- @return #CONTROLLABLE self
function CONTROLLABLE:OptionECM_OnlyLockByRadar() function CONTROLLABLE:OptionECM_OnlyLockByRadar()
self:F2( { self.ControllableName } ) self:F2( { self.ControllableName } )
if self:IsAir() then if self:IsAir() then
self:SetOption(AI.Option.Air.id.ECM_USING, 1) self:SetOption(AI.Option.Air.id.ECM_USING, 1)
end end
return self return self
@ -3508,9 +3508,9 @@ end
-- @return #CONTROLLABLE self -- @return #CONTROLLABLE self
function CONTROLLABLE:OptionECM_DetectedLockByRadar() function CONTROLLABLE:OptionECM_DetectedLockByRadar()
self:F2( { self.ControllableName } ) self:F2( { self.ControllableName } )
if self:IsAir() then if self:IsAir() then
self:SetOption(AI.Option.Air.id.ECM_USING, 2) self:SetOption(AI.Option.Air.id.ECM_USING, 2)
end end
return self return self
@ -3521,9 +3521,9 @@ end
-- @return #CONTROLLABLE self -- @return #CONTROLLABLE self
function CONTROLLABLE:OptionECM_AlwaysOn() function CONTROLLABLE:OptionECM_AlwaysOn()
self:F2( { self.ControllableName } ) self:F2( { self.ControllableName } )
if self:IsAir() then if self:IsAir() then
self:SetOption(AI.Option.Air.id.ECM_USING, 3) self:SetOption(AI.Option.Air.id.ECM_USING, 3)
end end
return self return self
@ -3667,18 +3667,18 @@ end
-- @param #CONTROLLABLE self -- @param #CONTROLLABLE self
-- @param #number Defines the range: MAX_RANGE = 0, NEZ_RANGE = 1, HALF_WAY_RMAX_NEZ = 2, TARGET_THREAT_EST = 3, RANDOM_RANGE = 4. Defaults to 3. See: https://wiki.hoggitworld.com/view/DCS_option_missileAttack -- @param #number Defines the range: MAX_RANGE = 0, NEZ_RANGE = 1, HALF_WAY_RMAX_NEZ = 2, TARGET_THREAT_EST = 3, RANDOM_RANGE = 4. Defaults to 3. See: https://wiki.hoggitworld.com/view/DCS_option_missileAttack
function CONTROLLABLE:OptionAAAttackRange(range) function CONTROLLABLE:OptionAAAttackRange(range)
self:F2( { self.ControllableName } ) self:F2( { self.ControllableName } )
-- defaults to 3 -- defaults to 3
local range = range or 3 local range = range or 3
if range < 0 or range > 4 then if range < 0 or range > 4 then
range = 3 range = 3
end end
local DCSControllable = self:GetDCSObject() local DCSControllable = self:GetDCSObject()
if DCSControllable then if DCSControllable then
local Controller = self:_GetController() local Controller = self:_GetController()
if Controller then if Controller then
if self:IsAir() then if self:IsAir() then
self:SetOption(AI.Option.Air.val.MISSILE_ATTACK, range) self:SetOption(AI.Option.Air.val.MISSILE_ATTACK, range)
end end
end end
return self return self