mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Slightly changed versions of Mantis, Sead and Shorad as the Emissions On/Off stuff ED introduced doesn't really work well.
This commit is contained in:
parent
52e2ac7174
commit
c0f4eef896
@ -191,7 +191,7 @@ MANTIS = {
|
|||||||
ShoradLink = false,
|
ShoradLink = false,
|
||||||
ShoradTime = 600,
|
ShoradTime = 600,
|
||||||
ShoradActDistance = 15000,
|
ShoradActDistance = 15000,
|
||||||
UseEmOnOff = true,
|
UseEmOnOff = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
@ -208,7 +208,7 @@ do
|
|||||||
--@param #string coaltion Coalition side of your setup, e.g. "blue", "red" or "neutral"
|
--@param #string coaltion Coalition side of your setup, e.g. "blue", "red" or "neutral"
|
||||||
--@param #boolean dynamic Use constant (true) filtering or just filter once (false, default) (optional)
|
--@param #boolean dynamic Use constant (true) filtering or just filter once (false, default) (optional)
|
||||||
--@param #string awacs Group name of your Awacs (optional)
|
--@param #string awacs Group name of your Awacs (optional)
|
||||||
--@param #boolean EmOnOff Make MANTIS switch Emissions on and off instead of changing the alarm state between RED and GREEN (optional, deault true)
|
--@param #boolean EmOnOff Make MANTIS switch Emissions on and off instead of changing the alarm state between RED and GREEN
|
||||||
--@return #MANTIS self
|
--@return #MANTIS self
|
||||||
--@usage Start up your MANTIS with a basic setting
|
--@usage Start up your MANTIS with a basic setting
|
||||||
--
|
--
|
||||||
@ -267,6 +267,8 @@ do
|
|||||||
if EmOnOff then
|
if EmOnOff then
|
||||||
if EmOnOff == false then
|
if EmOnOff == false then
|
||||||
self.UseEmOnOff = false
|
self.UseEmOnOff = false
|
||||||
|
else
|
||||||
|
self.UseEmOnOff = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
--
|
--
|
||||||
-- ### Authors: **FlightControl**, **applevangelist**
|
-- ### Authors: **FlightControl**, **applevangelist**
|
||||||
--
|
--
|
||||||
-- Last Update: April 2021
|
-- Last Update: Feb 2021
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@ -39,38 +39,21 @@
|
|||||||
--
|
--
|
||||||
-- @field #SEAD
|
-- @field #SEAD
|
||||||
SEAD = {
|
SEAD = {
|
||||||
ClassName = "SEAD",
|
ClassName = "SEAD",
|
||||||
TargetSkill = {
|
TargetSkill = {
|
||||||
Average = { Evade = 30, DelayOn = { 40, 60 } } ,
|
Average = { Evade = 30, DelayOn = { 40, 60 } } ,
|
||||||
Good = { Evade = 20, DelayOn = { 30, 50 } } ,
|
Good = { Evade = 20, DelayOn = { 30, 50 } } ,
|
||||||
High = { Evade = 15, DelayOn = { 20, 40 } } ,
|
High = { Evade = 15, DelayOn = { 20, 40 } } ,
|
||||||
Excellent = { Evade = 10, DelayOn = { 10, 30 } }
|
Excellent = { Evade = 10, DelayOn = { 10, 30 } }
|
||||||
},
|
},
|
||||||
SEADGroupPrefixes = {},
|
SEADGroupPrefixes = {},
|
||||||
SuppressedGroups = {},
|
SuppressedGroups = {},
|
||||||
EngagementRange = 75 -- default 75% engagement range Feature Request #1355
|
EngagementRange = 75 -- default 75% engagement range Feature Request #1355
|
||||||
}
|
}
|
||||||
|
|
||||||
-- TODO Complete list?
|
|
||||||
--- Missile enumerators
|
--- Missile enumerators
|
||||||
-- @field Harms
|
-- @field Harms
|
||||||
SEAD.Harms = {
|
SEAD.Harms = {
|
||||||
--[[
|
|
||||||
["X58"] = "weapons.missiles.X_58", --Kh-58X anti-radiation missiles fired
|
|
||||||
["Kh25"] = "weapons.missiles.Kh25MP_PRGS1VP", --Kh-25MP anti-radiation missiles fired
|
|
||||||
["X25"] = "weapons.missiles.X_25MP", --Kh-25MPU anti-radiation missiles fired
|
|
||||||
["X28"] = "weapons.missiles.X_28", --Kh-28 anti-radiation missiles fired
|
|
||||||
["X31"] = "weapons.missiles.X_31P", --Kh-31P anti-radiation missiles fired
|
|
||||||
["AGM45A"] = "weapons.missiles.AGM_45A", --AGM-45A anti-radiation missiles fired
|
|
||||||
["AGM45"] = "weapons.missiles.AGM_45", --AGM-45B anti-radiation missiles fired
|
|
||||||
["AGM88"] = "weapons.missiles.AGM_88", --AGM-88C anti-radiation missiles fired
|
|
||||||
["AGM122"] = "weapons.missiles.AGM_122", --AGM-122 Sidearm anti-radiation missiles fired
|
|
||||||
["LD10"] = "weapons.missiles.LD-10", --LD-10 anti-radiation missiles fired
|
|
||||||
["ALARM"] = "weapons.missiles.ALARM", --ALARM anti-radiation missiles fired
|
|
||||||
["AGM84E"] = "weapons.missiles.AGM_84E", --AGM84 anti-radiation missiles fired
|
|
||||||
["AGM84A"] = "weapons.missiles.AGM_84A", --AGM84 anti-radiation missiles fired
|
|
||||||
["AGM84H"] = "weapons.missiles.AGM_84H", --AGM84 anti-radiation missiles fired
|
|
||||||
--]]
|
|
||||||
["AGM_88"] = "AGM_88",
|
["AGM_88"] = "AGM_88",
|
||||||
["AGM_45"] = "AGM_45",
|
["AGM_45"] = "AGM_45",
|
||||||
["AGM_122"] = "AGM_122",
|
["AGM_122"] = "AGM_122",
|
||||||
@ -97,20 +80,20 @@ SEAD = {
|
|||||||
-- 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' } )
|
||||||
function SEAD:New( SEADGroupPrefixes )
|
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
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self.SEADGroupPrefixes[SEADGroupPrefixes] = SEADGroupPrefixes
|
self.SEADGroupPrefixes[SEADGroupPrefixes] = SEADGroupPrefixes
|
||||||
end
|
end
|
||||||
|
|
||||||
self:HandleEvent( EVENTS.Shot )
|
self:HandleEvent( EVENTS.Shot, self.HandleEventShot )
|
||||||
self:I("*** SEAD - Started Version 0.2.7")
|
self:I("*** SEAD - Started Version 0.2.8")
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Update the active SEAD Set
|
--- Update the active SEAD Set
|
||||||
@ -164,112 +147,83 @@ end
|
|||||||
-- @see SEAD
|
-- @see SEAD
|
||||||
-- @param #SEAD
|
-- @param #SEAD
|
||||||
-- @param Core.Event#EVENTDATA EventData
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
function SEAD:OnEventShot( EventData )
|
function SEAD:HandleEventShot( EventData )
|
||||||
self:T( { 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
|
||||||
|
|
||||||
self:T( "*** SEAD - Missile Launched = " .. SEADWeaponName)
|
self:T( "*** SEAD - Missile Launched = " .. SEADWeaponName)
|
||||||
self:T({ SEADWeapon })
|
self:T({ SEADWeapon })
|
||||||
|
|
||||||
--[[check for SEAD missiles
|
|
||||||
if SEADWeaponName == "weapons.missiles.X_58" --Kh-58U anti-radiation missiles fired
|
|
||||||
or
|
|
||||||
SEADWeaponName == "weapons.missiles.Kh25MP_PRGS1VP" --Kh-25MP anti-radiation missiles fired
|
|
||||||
or
|
|
||||||
SEADWeaponName == "weapons.missiles.X_25MP" --Kh-25MPU anti-radiation missiles fired
|
|
||||||
or
|
|
||||||
SEADWeaponName == "weapons.missiles.X_28" --Kh-28 anti-radiation missiles fired
|
|
||||||
or
|
|
||||||
SEADWeaponName == "weapons.missiles.X_31P" --Kh-31P anti-radiation missiles fired
|
|
||||||
or
|
|
||||||
SEADWeaponName == "weapons.missiles.AGM_45A" --AGM-45A anti-radiation missiles fired
|
|
||||||
or
|
|
||||||
SEADWeaponName == "weapons.missiles.AGM_45" --AGM-45B anti-radiation missiles fired
|
|
||||||
or
|
|
||||||
SEADWeaponName == "weapons.missiles.AGM_88" --AGM-88C anti-radiation missiles fired
|
|
||||||
or
|
|
||||||
SEADWeaponName == "weapons.missiles.AGM_122" --AGM-122 Sidearm anti-radiation missiles fired
|
|
||||||
or
|
|
||||||
SEADWeaponName == "weapons.missiles.LD-10" --LD-10 anti-radiation missiles fired
|
|
||||||
or
|
|
||||||
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
|
|
||||||
--]]
|
|
||||||
if self:_CheckHarms(SEADWeaponName) then
|
if self:_CheckHarms(SEADWeaponName) then
|
||||||
local _targetskill = "Random"
|
local _targetskill = "Random"
|
||||||
local _targetMimgroupName = "none"
|
local _targetMimgroupName = "none"
|
||||||
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 _targetUnit = UNIT:Find(_targetMim) -- Unit name by DCS Object
|
local _targetUnit = UNIT:Find(_targetMim) -- Unit name by DCS Object
|
||||||
if _targetUnit and _targetUnit:IsAlive() then
|
if _targetUnit and _targetUnit:IsAlive() then
|
||||||
local _targetMimgroup = _targetUnit:GetGroup()
|
local _targetMimgroup = _targetUnit:GetGroup()
|
||||||
local _targetMimgroupName = _targetMimgroup:GetName() -- group name
|
local _targetMimgroupName = _targetMimgroup:GetName() -- group name
|
||||||
--local _targetskill = _DATABASE.Templates.Units[_targetUnit].Template.skill
|
--local _targetskill = _DATABASE.Templates.Units[_targetUnit].Template.skill
|
||||||
self:T( self.SEADGroupPrefixes )
|
self:T( self.SEADGroupPrefixes )
|
||||||
self:T( _targetMimgroupName )
|
self:T( _targetMimgroupName )
|
||||||
end
|
end
|
||||||
-- see if we are shot at
|
-- 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( '*** SEAD - Group Found' )
|
self:T( '*** SEAD - Group Found' )
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if SEADGroupFound == true then -- yes we are being attacked
|
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) ]
|
||||||
end
|
end
|
||||||
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("*** SEAD - Evading, target skill " ..string.format(_targetskill)) )
|
self:T( string.format("*** SEAD - Evading, target skill " ..string.format(_targetskill)) )
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
--tracker ID table to switch groups off and on again
|
--tracker ID table to switch groups off and on again
|
||||||
local id = {
|
local id = {
|
||||||
groupName = _targetMimgroup,
|
groupName = _targetMimgroup,
|
||||||
ctrl = _targetMimcont
|
ctrl = _targetMimcont
|
||||||
}
|
}
|
||||||
|
|
||||||
local function SuppressionEnd(id) --switch group back on
|
local function SuppressionEnd(id) --switch group back on
|
||||||
local range = self.EngagementRange -- Feature Request #1355
|
local range = self.EngagementRange -- Feature Request #1355
|
||||||
self:T(string.format("*** SEAD - Engagement Range is %d", range))
|
self:T(string.format("*** SEAD - Engagement Range is %d", range))
|
||||||
id.ctrl:setOption(AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.RED)
|
id.ctrl:setOption(AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.RED)
|
||||||
--id.groupName:enableEmission(true)
|
--id.groupName:enableEmission(true)
|
||||||
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
|
||||||
self.SuppressedGroups[id.groupName] = nil --delete group id from table when done
|
self.SuppressedGroups[id.groupName] = nil --delete group id from table when done
|
||||||
end
|
end
|
||||||
-- randomize switch-on time
|
-- randomize switch-on time
|
||||||
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
|
local SuppressionEndTime = timer.getTime() + delay
|
||||||
--create entry
|
--create entry
|
||||||
if self.SuppressedGroups[id.groupName] == nil then --no timer entry for this group yet
|
if self.SuppressedGroups[id.groupName] == nil then --no timer entry for this group yet
|
||||||
self.SuppressedGroups[id.groupName] = {
|
self.SuppressedGroups[id.groupName] = {
|
||||||
SuppressionEndTime = delay
|
SuppressionEndTime = delay
|
||||||
}
|
}
|
||||||
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)
|
||||||
--_targetMimgroup:enableEmission(false)
|
--_targetMimgroup:enableEmission(false)
|
||||||
timer.scheduleFunction(SuppressionEnd, id, SuppressionEndTime) --Schedule the SuppressionEnd() function
|
timer.scheduleFunction(SuppressionEnd, id, SuppressionEndTime) --Schedule the SuppressionEnd() function
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -13,12 +13,12 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author : **applevangelist**
|
-- ### Author : **applevangelist **
|
||||||
--
|
--
|
||||||
-- @module Functional.Shorad
|
-- @module Functional.Shorad
|
||||||
-- @image Functional.Shorad.jpg
|
-- @image Functional.Shorad.jpg
|
||||||
--
|
--
|
||||||
-- Date: May 2021
|
-- Date: July 2021
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--- **SHORAD** class, extends Core.Base#BASE
|
--- **SHORAD** class, extends Core.Base#BASE
|
||||||
@ -94,7 +94,7 @@ SHORAD = {
|
|||||||
lid = "",
|
lid = "",
|
||||||
DefendHarms = true,
|
DefendHarms = true,
|
||||||
DefendMavs = true,
|
DefendMavs = true,
|
||||||
DefenseLowProb = 75,
|
DefenseLowProb = 70,
|
||||||
DefenseHighProb = 90,
|
DefenseHighProb = 90,
|
||||||
UseEmOnOff = false,
|
UseEmOnOff = false,
|
||||||
}
|
}
|
||||||
@ -108,22 +108,6 @@ do
|
|||||||
--- Missile enumerators
|
--- Missile enumerators
|
||||||
-- @field Harms
|
-- @field Harms
|
||||||
SHORAD.Harms = {
|
SHORAD.Harms = {
|
||||||
--[[
|
|
||||||
["X58"] = "weapons.missiles.X_58", --Kh-58X anti-radiation missiles fired
|
|
||||||
["Kh25"] = "weapons.missiles.Kh25MP_PRGS1VP", --Kh-25MP anti-radiation missiles fired
|
|
||||||
["X25"] = "weapons.missiles.X_25MP", --Kh-25MPU anti-radiation missiles fired
|
|
||||||
["X28"] = "weapons.missiles.X_28", --Kh-28 anti-radiation missiles fired
|
|
||||||
["X31"] = "weapons.missiles.X_31P", --Kh-31P anti-radiation missiles fired
|
|
||||||
["AGM45A"] = "weapons.missiles.AGM_45A", --AGM-45A anti-radiation missiles fired
|
|
||||||
["AGM45"] = "weapons.missiles.AGM_45", --AGM-45B anti-radiation missiles fired
|
|
||||||
["AGM88"] = "weapons.missiles.AGM_88", --AGM-88C anti-radiation missiles fired
|
|
||||||
["AGM122"] = "weapons.missiles.AGM_122", --AGM-122 Sidearm anti-radiation missiles fired
|
|
||||||
["LD10"] = "weapons.missiles.LD-10", --LD-10 anti-radiation missiles fired
|
|
||||||
["ALARM"] = "weapons.missiles.ALARM", --ALARM anti-radiation missiles fired
|
|
||||||
["AGM84E"] = "weapons.missiles.AGM_84E", --AGM84 anti-radiation missiles fired
|
|
||||||
["AGM84A"] = "weapons.missiles.AGM_84A", --AGM84 anti-radiation missiles fired
|
|
||||||
["AGM84H"] = "weapons.missiles.AGM_84H", --AGM84 anti-radiation missiles fired
|
|
||||||
--]]
|
|
||||||
["AGM_88"] = "AGM_88",
|
["AGM_88"] = "AGM_88",
|
||||||
["AGM_45"] = "AGM_45",
|
["AGM_45"] = "AGM_45",
|
||||||
["AGM_122"] = "AGM_122",
|
["AGM_122"] = "AGM_122",
|
||||||
@ -157,9 +141,11 @@ do
|
|||||||
-- @param #number Radius Defense radius in meters, used to switch on groups
|
-- @param #number Radius Defense radius in meters, used to switch on groups
|
||||||
-- @param #number ActiveTimer Determines how many seconds the systems stay on red alert after wake-up call
|
-- @param #number ActiveTimer Determines how many seconds the systems stay on red alert after wake-up call
|
||||||
-- @param #string Coalition Coalition, i.e. "blue", "red", or "neutral"
|
-- @param #string Coalition Coalition, i.e. "blue", "red", or "neutral"
|
||||||
function SHORAD:New(Name, ShoradPrefix, Samset, Radius, ActiveTimer, Coalition)
|
-- @param #boolean UseEmOnOff Use Emissions On/Off rather than Alarm State Red/Green (default: use Emissions switch)
|
||||||
|
-- @retunr #SHORAD self
|
||||||
|
function SHORAD:New(Name, ShoradPrefix, Samset, Radius, ActiveTimer, Coalition, UseEmOnOff)
|
||||||
local self = BASE:Inherit( self, BASE:New() )
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
self:T({Name, ShoradPrefix, Samset, Radius, ActiveTimer, Coalition})
|
self:I({Name, ShoradPrefix, Samset, Radius, ActiveTimer, Coalition})
|
||||||
|
|
||||||
local GroupSet = SET_GROUP:New():FilterPrefixes(ShoradPrefix):FilterCoalitions(Coalition):FilterCategoryGround():FilterStart()
|
local GroupSet = SET_GROUP:New():FilterPrefixes(ShoradPrefix):FilterCoalitions(Coalition):FilterCategoryGround():FilterStart()
|
||||||
|
|
||||||
@ -171,73 +157,93 @@ do
|
|||||||
self.ActiveTimer = ActiveTimer or 600
|
self.ActiveTimer = ActiveTimer or 600
|
||||||
self.ActiveGroups = {}
|
self.ActiveGroups = {}
|
||||||
self.Groupset = GroupSet
|
self.Groupset = GroupSet
|
||||||
self:HandleEvent( EVENTS.Shot )
|
|
||||||
self.DefendHarms = true
|
self.DefendHarms = true
|
||||||
self.DefendMavs = true
|
self.DefendMavs = true
|
||||||
self.DefenseLowProb = 70 -- probability to detect a missile shot, low margin
|
self.DefenseLowProb = 70 -- probability to detect a missile shot, low margin
|
||||||
self.DefenseHighProb = 90 -- probability to detect a missile shot, high margin
|
self.DefenseHighProb = 90 -- probability to detect a missile shot, high margin
|
||||||
self.UseEmOnOff = true -- Decide if we are using Emission on/off (default) or AlarmState red/green
|
self.UseEmOnOff = UseEmOnOff or false -- Decide if we are using Emission on/off (default) or AlarmState red/green
|
||||||
self:I("*** SHORAD - Started Version 0.2.5")
|
self:I("*** SHORAD - Started Version 0.2.8")
|
||||||
-- Set the string id for output to DCS.log file.
|
-- Set the string id for output to DCS.log file.
|
||||||
self.lid=string.format("SHORAD %s | ", self.name)
|
self.lid=string.format("SHORAD %s | ", self.name)
|
||||||
self:_InitState()
|
self:_InitState()
|
||||||
|
self:HandleEvent(EVENTS.Shot, self.HandleEventShot)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Initially set all groups to alarm state GREEN
|
--- Initially set all groups to alarm state GREEN
|
||||||
-- @param #SHORAD self
|
-- @param #SHORAD self
|
||||||
function SHORAD:_InitState()
|
function SHORAD:_InitState()
|
||||||
|
self:I(self.lid .. " _InitState")
|
||||||
local table = {}
|
local table = {}
|
||||||
local set = self.Groupset
|
local set = self.Groupset
|
||||||
self:T({set = set})
|
self:I({set = set})
|
||||||
local aliveset = set:GetAliveSet() --#table
|
local aliveset = set:GetAliveSet() --#table
|
||||||
for _,_group in pairs (aliveset) do
|
for _,_group in pairs (aliveset) do
|
||||||
if self.UseEmOnOff then
|
if self.UseEmOnOff then
|
||||||
--_group:SetAIOff()
|
--_group:SetAIOff()
|
||||||
_group:EnableEmission(false)
|
_group:EnableEmission(false)
|
||||||
|
_group:OptionAlarmStateRed() --Wrapper.Group#GROUP
|
||||||
else
|
else
|
||||||
_group:OptionAlarmStateGreen() --Wrapper.Group#GROUP
|
_group:OptionAlarmStateGreen() --Wrapper.Group#GROUP
|
||||||
end
|
end
|
||||||
|
_group:OptionDisperseOnAttack(30)
|
||||||
end
|
end
|
||||||
-- gather entropy
|
-- gather entropy
|
||||||
for i=1,10 do
|
for i=1,100 do
|
||||||
math.random()
|
math.random()
|
||||||
end
|
end
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Switch debug state
|
--- Switch debug state on
|
||||||
-- @param #SHORAD self
|
-- @param #SHORAD self
|
||||||
-- @param #boolean debug Switch debug on (true) or off (false)
|
-- @param #boolean debug Switch debug on (true) or off (false)
|
||||||
function SHORAD:SwitchDebug(debug)
|
function SHORAD:SwitchDebug(onoff)
|
||||||
self:T( { debug } )
|
self:I( { onoff } )
|
||||||
local onoff = debug or false
|
if onoff then
|
||||||
if debug then
|
self:SwitchDebugOn()
|
||||||
self.debug = true
|
|
||||||
--tracing
|
|
||||||
BASE:TraceOn()
|
|
||||||
BASE:TraceClass("SHORAD")
|
|
||||||
else
|
else
|
||||||
self.debug = false
|
self.SwitchDebugOff()
|
||||||
BASE:TraceOff()
|
|
||||||
end
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Switch debug state on
|
||||||
|
-- @param #SHORAD self
|
||||||
|
function SHORAD:SwitchDebugOn()
|
||||||
|
self.debug = true
|
||||||
|
--tracing
|
||||||
|
BASE:TraceOn()
|
||||||
|
BASE:TraceClass("SHORAD")
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Switch debug state off
|
||||||
|
-- @param #SHORAD self
|
||||||
|
function SHORAD:SwitchDebugOff()
|
||||||
|
self.debug = false
|
||||||
|
BASE:TraceOff()
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Switch defense for HARMs
|
--- Switch defense for HARMs
|
||||||
-- @param #SHORAD self
|
-- @param #SHORAD self
|
||||||
-- @param #boolean onoff
|
-- @param #boolean onoff
|
||||||
function SHORAD:SwitchHARMDefense(onoff)
|
function SHORAD:SwitchHARMDefense(onoff)
|
||||||
self:T( { onoff } )
|
self:I( { onoff } )
|
||||||
local onoff = onoff or true
|
local onoff = onoff or true
|
||||||
self.DefendHarms = onoff
|
self.DefendHarms = onoff
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Switch defense for AGMs
|
--- Switch defense for AGMs
|
||||||
-- @param #SHORAD self
|
-- @param #SHORAD self
|
||||||
-- @param #boolean onoff
|
-- @param #boolean onoff
|
||||||
function SHORAD:SwitchAGMDefense(onoff)
|
function SHORAD:SwitchAGMDefense(onoff)
|
||||||
self:T( { onoff } )
|
self:I( { onoff } )
|
||||||
local onoff = onoff or true
|
local onoff = onoff or true
|
||||||
self.DefendMavs = onoff
|
self.DefendMavs = onoff
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set defense probability limits
|
--- Set defense probability limits
|
||||||
@ -245,7 +251,7 @@ do
|
|||||||
-- @param #number low Minimum detection limit, integer 1-100
|
-- @param #number low Minimum detection limit, integer 1-100
|
||||||
-- @param #number high Maximum detection limit integer 1-100
|
-- @param #number high Maximum detection limit integer 1-100
|
||||||
function SHORAD:SetDefenseLimits(low,high)
|
function SHORAD:SetDefenseLimits(low,high)
|
||||||
self:T( { low, high } )
|
self:I( { low, high } )
|
||||||
local low = low or 70
|
local low = low or 70
|
||||||
local high = high or 90
|
local high = high or 90
|
||||||
if (low < 0) or (low > 100) or (low > high) then
|
if (low < 0) or (low > 100) or (low > high) then
|
||||||
@ -256,35 +262,42 @@ do
|
|||||||
end
|
end
|
||||||
self.DefenseLowProb = low
|
self.DefenseLowProb = low
|
||||||
self.DefenseHighProb = high
|
self.DefenseHighProb = high
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set the number of seconds a SHORAD site will stay active
|
--- Set the number of seconds a SHORAD site will stay active
|
||||||
-- @param #SHORAD self
|
-- @param #SHORAD self
|
||||||
-- @param #number seconds Number of seconds systems stay active
|
-- @param #number seconds Number of seconds systems stay active
|
||||||
function SHORAD:SetActiveTimer(seconds)
|
function SHORAD:SetActiveTimer(seconds)
|
||||||
|
self:I(self.lid .. " SetActiveTimer")
|
||||||
local timer = seconds or 600
|
local timer = seconds or 600
|
||||||
if timer < 0 then
|
if timer < 0 then
|
||||||
timer = 600
|
timer = 600
|
||||||
end
|
end
|
||||||
self.ActiveTimer = timer
|
self.ActiveTimer = timer
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set the number of meters for the SHORAD defense zone
|
--- Set the number of meters for the SHORAD defense zone
|
||||||
-- @param #SHORAD self
|
-- @param #SHORAD self
|
||||||
-- @param #number meters Radius of the defense search zone in meters. #SHORADs in this range around a targeted group will go active
|
-- @param #number meters Radius of the defense search zone in meters. #SHORADs in this range around a targeted group will go active
|
||||||
function SHORAD:SetDefenseRadius(meters)
|
function SHORAD:SetDefenseRadius(meters)
|
||||||
|
self:I(self.lid .. " SetDefenseRadius")
|
||||||
local radius = meters or 20000
|
local radius = meters or 20000
|
||||||
if radius < 0 then
|
if radius < 0 then
|
||||||
radius = 20000
|
radius = 20000
|
||||||
end
|
end
|
||||||
self.Radius = radius
|
self.Radius = radius
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set using Emission on/off instead of changing alarm state
|
--- Set using Emission on/off instead of changing alarm state
|
||||||
-- @param #SHORAD self
|
-- @param #SHORAD self
|
||||||
-- @param #boolean switch Decide if we are changing alarm state or AI state
|
-- @param #boolean switch Decide if we are changing alarm state or AI state
|
||||||
function SHORAD:SetUsingEmOnOff(switch)
|
function SHORAD:SetUsingEmOnOff(switch)
|
||||||
|
self:I(self.lid .. " SetUsingEmOnOff")
|
||||||
self.UseEmOnOff = switch or false
|
self.UseEmOnOff = switch or false
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Check if a HARM was fired
|
--- Check if a HARM was fired
|
||||||
@ -292,7 +305,8 @@ do
|
|||||||
-- @param #string WeaponName
|
-- @param #string WeaponName
|
||||||
-- @return #boolean Returns true for a match
|
-- @return #boolean Returns true for a match
|
||||||
function SHORAD:_CheckHarms(WeaponName)
|
function SHORAD:_CheckHarms(WeaponName)
|
||||||
self:T( { WeaponName } )
|
self:I(self.lid .. " _CheckHarms")
|
||||||
|
self:I( { WeaponName } )
|
||||||
local hit = false
|
local hit = false
|
||||||
if self.DefendHarms then
|
if self.DefendHarms then
|
||||||
for _,_name in pairs (SHORAD.Harms) do
|
for _,_name in pairs (SHORAD.Harms) do
|
||||||
@ -307,7 +321,8 @@ do
|
|||||||
-- @param #string WeaponName
|
-- @param #string WeaponName
|
||||||
-- @return #boolean Returns true for a match
|
-- @return #boolean Returns true for a match
|
||||||
function SHORAD:_CheckMavs(WeaponName)
|
function SHORAD:_CheckMavs(WeaponName)
|
||||||
self:T( { WeaponName } )
|
self:I(self.lid .. " _CheckMavs")
|
||||||
|
self:I( { WeaponName } )
|
||||||
local hit = false
|
local hit = false
|
||||||
if self.DefendMavs then
|
if self.DefendMavs then
|
||||||
for _,_name in pairs (SHORAD.Mavs) do
|
for _,_name in pairs (SHORAD.Mavs) do
|
||||||
@ -322,6 +337,7 @@ do
|
|||||||
-- @param #string Coalition name
|
-- @param #string Coalition name
|
||||||
-- @return #boolean Returns false for a match
|
-- @return #boolean Returns false for a match
|
||||||
function SHORAD:_CheckCoalition(Coalition)
|
function SHORAD:_CheckCoalition(Coalition)
|
||||||
|
self:I(self.lid .. " _CheckCoalition")
|
||||||
local owncoalition = self.Coalition
|
local owncoalition = self.Coalition
|
||||||
local othercoalition = ""
|
local othercoalition = ""
|
||||||
if Coalition == 0 then
|
if Coalition == 0 then
|
||||||
@ -331,7 +347,7 @@ do
|
|||||||
else
|
else
|
||||||
othercoalition = "blue"
|
othercoalition = "blue"
|
||||||
end
|
end
|
||||||
self:T({owncoalition = owncoalition, othercoalition = othercoalition})
|
self:I({owncoalition = owncoalition, othercoalition = othercoalition})
|
||||||
if owncoalition ~= othercoalition then
|
if owncoalition ~= othercoalition then
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
@ -344,6 +360,7 @@ do
|
|||||||
-- @param #string TargetGroupName Name of the target group
|
-- @param #string TargetGroupName Name of the target group
|
||||||
-- @return #boolean Returns true for a match, else false
|
-- @return #boolean Returns true for a match, else false
|
||||||
function SHORAD:_CheckShotAtShorad(TargetGroupName)
|
function SHORAD:_CheckShotAtShorad(TargetGroupName)
|
||||||
|
self:I(self.lid .. " _CheckShotAtShorad")
|
||||||
local tgtgrp = TargetGroupName
|
local tgtgrp = TargetGroupName
|
||||||
local shorad = self.Groupset
|
local shorad = self.Groupset
|
||||||
local shoradset = shorad:GetAliveSet() --#table
|
local shoradset = shorad:GetAliveSet() --#table
|
||||||
@ -352,7 +369,7 @@ do
|
|||||||
local groupname = _groups:GetName()
|
local groupname = _groups:GetName()
|
||||||
if string.find(groupname, tgtgrp, 1) then
|
if string.find(groupname, tgtgrp, 1) then
|
||||||
returnname = true
|
returnname = true
|
||||||
_groups:RelocateGroundRandomInRadius(7,100,false,false) -- be a bit evasive
|
--_groups:RelocateGroundRandomInRadius(7,100,false,false) -- be a bit evasive
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return returnname
|
return returnname
|
||||||
@ -363,6 +380,7 @@ do
|
|||||||
-- @param #string TargetGroupName Name of the target group
|
-- @param #string TargetGroupName Name of the target group
|
||||||
-- @return #boolean Returns true for a match, else false
|
-- @return #boolean Returns true for a match, else false
|
||||||
function SHORAD:_CheckShotAtSams(TargetGroupName)
|
function SHORAD:_CheckShotAtSams(TargetGroupName)
|
||||||
|
self:I(self.lid .. " _CheckShotAtSams")
|
||||||
local tgtgrp = TargetGroupName
|
local tgtgrp = TargetGroupName
|
||||||
local shorad = self.Samset
|
local shorad = self.Samset
|
||||||
--local shoradset = shorad:GetAliveSet() --#table
|
--local shoradset = shorad:GetAliveSet() --#table
|
||||||
@ -381,6 +399,7 @@ do
|
|||||||
-- @param #SHORAD self
|
-- @param #SHORAD self
|
||||||
-- @return #boolean Returns true for a detection, else false
|
-- @return #boolean Returns true for a detection, else false
|
||||||
function SHORAD:_ShotIsDetected()
|
function SHORAD:_ShotIsDetected()
|
||||||
|
self:I(self.lid .. " _ShotIsDetected")
|
||||||
local IsDetected = false
|
local IsDetected = false
|
||||||
local DetectionProb = math.random(self.DefenseLowProb, self.DefenseHighProb) -- reference value
|
local DetectionProb = math.random(self.DefenseLowProb, self.DefenseHighProb) -- reference value
|
||||||
local ActualDetection = math.random(1,100) -- value for this shot
|
local ActualDetection = math.random(1,100) -- value for this shot
|
||||||
@ -405,7 +424,8 @@ do
|
|||||||
-- mymantis:AddShorad(myshorad,720)
|
-- mymantis:AddShorad(myshorad,720)
|
||||||
-- mymantis:Start()
|
-- mymantis:Start()
|
||||||
function SHORAD:WakeUpShorad(TargetGroup, Radius, ActiveTimer, TargetCat)
|
function SHORAD:WakeUpShorad(TargetGroup, Radius, ActiveTimer, TargetCat)
|
||||||
self:T({TargetGroup, Radius, ActiveTimer, TargetCat})
|
self:I(self.lid .. " WakeUpShorad")
|
||||||
|
self:I({TargetGroup, Radius, ActiveTimer, TargetCat})
|
||||||
local targetcat = TargetCat or Object.Category.UNIT
|
local targetcat = TargetCat or Object.Category.UNIT
|
||||||
local targetgroup = TargetGroup
|
local targetgroup = TargetGroup
|
||||||
local targetvec2 = nil
|
local targetvec2 = nil
|
||||||
@ -432,17 +452,17 @@ do
|
|||||||
group:OptionAlarmStateGreen()
|
group:OptionAlarmStateGreen()
|
||||||
end
|
end
|
||||||
local text = string.format("Sleeping SHORAD %s", group:GetName())
|
local text = string.format("Sleeping SHORAD %s", group:GetName())
|
||||||
self:T(text)
|
self:I(text)
|
||||||
local m = MESSAGE:New(text,10,"SHORAD"):ToAllIf(self.debug)
|
local m = MESSAGE:New(text,10,"SHORAD"):ToAllIf(self.debug)
|
||||||
end
|
end
|
||||||
-- go through set and find the one(s) to activate
|
-- go through set and find the one(s) to activate
|
||||||
for _,_group in pairs (shoradset) do
|
for _,_group in pairs (shoradset) do
|
||||||
if _group:IsAnyInZone(targetzone) then
|
if _group:IsAnyInZone(targetzone) then
|
||||||
local text = string.format("Waking up SHORAD %s", _group:GetName())
|
local text = string.format("Waking up SHORAD %s", _group:GetName())
|
||||||
self:T(text)
|
self:I(text)
|
||||||
local m = MESSAGE:New(text,10,"SHORAD"):ToAllIf(self.debug)
|
local m = MESSAGE:New(text,10,"SHORAD"):ToAllIf(self.debug)
|
||||||
if self.UseEmOnOff then
|
if self.UseEmOnOff then
|
||||||
_group:SetAIOn()
|
--_group:SetAIOn()
|
||||||
_group:EnableEmission(true)
|
_group:EnableEmission(true)
|
||||||
end
|
end
|
||||||
_group:OptionAlarmStateRed()
|
_group:OptionAlarmStateRed()
|
||||||
@ -454,14 +474,15 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Main function - work on the EventData
|
--- Main function - work on the EventData
|
||||||
-- @param #SHORAD self
|
-- @param #SHORAD self
|
||||||
-- @param Core.Event#EVENTDATA EventData The event details table data set
|
-- @param Core.Event#EVENTDATA EventData The event details table data set
|
||||||
function SHORAD:OnEventShot( EventData )
|
function SHORAD:HandleEventShot( EventData )
|
||||||
self:T( { EventData } )
|
self:I( { EventData } )
|
||||||
|
self:I(self.lid .. " HandleEventShot")
|
||||||
--local ShootingUnit = EventData.IniDCSUnit
|
--local ShootingUnit = EventData.IniDCSUnit
|
||||||
--local ShootingUnitName = EventData.IniDCSUnitName
|
--local ShootingUnitName = EventData.IniDCSUnitName
|
||||||
local ShootingWeapon = EventData.Weapon -- Identify the weapon fired
|
local ShootingWeapon = EventData.Weapon -- Identify the weapon fired
|
||||||
@ -477,14 +498,14 @@ do
|
|||||||
DetectedText = "true"
|
DetectedText = "true"
|
||||||
end
|
end
|
||||||
local text = string.format("%s Missile Launched = %s | Detected probability state is %s", self.lid, ShootingWeaponName, DetectedText)
|
local text = string.format("%s Missile Launched = %s | Detected probability state is %s", self.lid, ShootingWeaponName, DetectedText)
|
||||||
self:T( text )
|
self:I( text )
|
||||||
local m = MESSAGE:New(text,10,"Info"):ToAllIf(self.debug)
|
local m = MESSAGE:New(text,10,"Info"):ToAllIf(self.debug)
|
||||||
--
|
--
|
||||||
if (self:_CheckHarms(ShootingWeaponName) or self:_CheckMavs(ShootingWeaponName)) and IsDetected then
|
if (self:_CheckHarms(ShootingWeaponName) or self:_CheckMavs(ShootingWeaponName)) and IsDetected then
|
||||||
-- get target data
|
-- get target data
|
||||||
local targetdata = EventData.Weapon:getTarget() -- Identify target
|
local targetdata = EventData.Weapon:getTarget() -- Identify target
|
||||||
local targetcat = targetdata:getCategory() -- Identify category
|
local targetcat = targetdata:getCategory() -- Identify category
|
||||||
self:T(string.format("Target Category (3=STATIC, 1=UNIT)= %s",tostring(targetcat)))
|
self:I(string.format("Target Category (3=STATIC, 1=UNIT)= %s",tostring(targetcat)))
|
||||||
local targetunit = nil
|
local targetunit = nil
|
||||||
if targetcat == Object.Category.UNIT then -- UNIT
|
if targetcat == Object.Category.UNIT then -- UNIT
|
||||||
targetunit = UNIT:Find(targetdata)
|
targetunit = UNIT:Find(targetdata)
|
||||||
@ -505,7 +526,7 @@ do
|
|||||||
targetgroupname = targetunitname
|
targetgroupname = targetunitname
|
||||||
end
|
end
|
||||||
local text = string.format("%s Missile Target = %s", self.lid, tostring(targetgroupname))
|
local text = string.format("%s Missile Target = %s", self.lid, tostring(targetgroupname))
|
||||||
self:T( text )
|
self:I( text )
|
||||||
local m = MESSAGE:New(text,10,"Info"):ToAllIf(self.debug)
|
local m = MESSAGE:New(text,10,"Info"):ToAllIf(self.debug)
|
||||||
-- check if we or a SAM site are the target
|
-- check if we or a SAM site are the target
|
||||||
--local TargetGroup = EventData.TgtGroup -- Wrapper.Group#GROUP
|
--local TargetGroup = EventData.TgtGroup -- Wrapper.Group#GROUP
|
||||||
@ -513,7 +534,7 @@ do
|
|||||||
local shotatsams = self:_CheckShotAtSams(targetgroupname) --#boolean
|
local shotatsams = self:_CheckShotAtSams(targetgroupname) --#boolean
|
||||||
-- if being shot at, find closest SHORADs to activate
|
-- if being shot at, find closest SHORADs to activate
|
||||||
if shotatsams or shotatus then
|
if shotatsams or shotatus then
|
||||||
self:T({shotatsams=shotatsams,shotatus=shotatus})
|
self:I({shotatsams=shotatsams,shotatus=shotatus})
|
||||||
self:WakeUpShorad(targetgroupname, self.Radius, self.ActiveTimer, targetcat)
|
self:WakeUpShorad(targetgroupname, self.Radius, self.ActiveTimer, targetcat)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user