MANTIS - latest updates

This commit is contained in:
Applevangelist 2021-11-11 17:45:25 +01:00
parent a6beecf510
commit a38abc2f7f

View File

@ -4,8 +4,8 @@
-- --
-- **MANTIS** - Moose derived Modular, Automatic and Network capable Targeting and Interception System -- **MANTIS** - Moose derived Modular, Automatic and Network capable Targeting and Interception System
-- Controls a network of SAM sites. Use detection to switch on the AA site closest to the enemy -- Controls a network of SAM sites. Use detection to switch on the AA site closest to the enemy
-- Leverage evasiveness from SEAD -- Automatic mode (default since 0.8) can set-up your SAM site network automatically for you
-- Leverage attack range setup added by DCS in 11/20 -- Leverage evasiveness from SEAD, leverage attack range setting
-- --
-- === -- ===
-- --
@ -65,12 +65,49 @@
-- --
-- #MANTIS -- #MANTIS
-- Moose derived Modular, Automatic and Network capable Targeting and Interception System. -- Moose derived Modular, Automatic and Network capable Targeting and Interception System.
-- Controls a network of SAM sites. Use detection to switch on the AA site closest to the enemy. -- * Controls a network of SAM sites. Uses detection to switch on the SAM site closest to the enemy.
-- Leverage evasiveness from @{Functional.Sead#SEAD}. -- * **Automatic mode** (default since 0.8) can set-up your SAM site network automatically for you
-- Leverage attack range setup added by DCS in 11/20. -- * **Classic mode** behaves like before
-- * Leverage evasiveness from SEAD, leverage attack range setting
--
-- # 0. Base considerations and naming conventions
--
-- **Before** you start to set up your SAM sites in the mission editor, please think of naming conventions. This is especially critical to make
-- eveything work as intended, also if you have both a blue and a red installation!
--
-- You need three **non-overlapping** "name spaces" for everything to work properly:
--
-- * SAM sites, e.g. each **group name** begins with "Red SAM"
-- * EWR network and AWACS, e.g. each **group name** begins with "Red EWR" and *not* e.g. "Red SAM EWR" (overlap with "Red SAM"), "Red EWR Awacs" will be found by "Red EWR"
-- * SHORAD, e.g. each **group name** begins with "Red SHORAD" and *not" e.g. just "SHORAD" because you might also have "Blue SHORAD"
--
-- It's important to get this right because of the nature of the filter-system in @{Core.Set#SET_GROUP}. Filters are "greedy", that is they
-- will match *any* string that contains the search string - hence we need to avoid that SAMs, EWR and SHORAD step on each other\'s toes.
--
-- Second, for auto-mode to work, the SAMs need the **SAM Type Name** in their group name, as MANTIS will determine their capabilities from this.
-- This is case-sensitive, so "sa-11" is not equal to "SA-11" is not equal to "Sa-11"!
--
-- Known SAM types at the time of writing are:
--
-- * Avenger
-- * Chaparrel
-- * Hawk
-- * Linebacker
-- * NASAMS
-- * Patriot
-- * Rapier
-- * Roland
-- * SA-2, SA-3, SA-5, SA-6, SA-7, SA-8, SA-9, SA-10, SA-11, SA-13, SA-15, SA-19
--
-- Folowing the example started above, an SA-6 site group name should start with "Red SAM SA-6" then, or a blue Patriot installation with e.g. "Blue SAM Patriot"
--
-- # 0.1 Set-up in the mission editor
--
-- Set up your SAM sites in the mission editor. Name the groups as stated above.
-- Set up your EWR system in the mission editor. Name the groups as stated above. Can be e.g. AWACS or a combination of AWACS and Search Radars like e.g. EWR 1L13 etc.
-- Search Radars usually have "SR" or "STR" in their names.
-- Set up your SHORAD systems. They need to be close to the SAM sites to be effective. Use **one** group per SAM location. SA-15 TOR systems offer a good missile defense.
-- --
-- Set up your SAM sites in the mission editor. Name the groups with common prefix like "Red SAM".
-- Set up your EWR system in the mission editor. Name the groups with common prefix like "Red EWR". Can be e.g. AWACS or a combination of AWACS and Search Radars like e.g. EWR 1L13 etc.
-- [optional] Set up your HQ. Can be any group, e.g. a command vehicle. -- [optional] Set up your HQ. Can be any group, e.g. a command vehicle.
-- --
-- # 1. Basic tactical considerations when setting up your SAM sites -- # 1. Basic tactical considerations when setting up your SAM sites
@ -104,30 +141,47 @@
-- myredmantis = MANTIS:New("myredmantis","Red SAM","Red EWR",nil,"red",false) -- myredmantis = MANTIS:New("myredmantis","Red SAM","Red EWR",nil,"red",false)
-- myredmantis:Start() -- myredmantis:Start()
-- --
-- [optional] Use -- Use
-- --
-- * MANTIS:SetEWRGrouping(radius) -- * MANTIS:SetEWRGrouping(radius) [classic mode]
-- * MANTIS:SetEWRRange(radius) -- * MANTIS:SetSAMRadius(radius) [classic mode]
-- * MANTIS:SetSAMRadius(radius) -- * MANTIS:SetDetectInterval(interval) [classic & auto modes]
-- * MANTIS:SetDetectInterval(interval) -- * MANTIS:SetAutoRelocate(hq, ewr) [classic & auto modes]
-- * MANTIS:SetAutoRelocate(hq, ewr)
-- --
-- before starting #MANTIS to fine-tune your setup. -- before starting #MANTIS to fine-tune your setup.
-- --
-- If you want to use a separate AWACS unit (default detection range: 250km) to support your EWR system, use e.g. the following setup: -- If you want to use a separate AWACS unit to support your EWR system, use e.g. the following setup:
-- --
-- mybluemantis = MANTIS:New("bluemantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs") -- mybluemantis = MANTIS:New("bluemantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
-- mybluemantis:Start() -- mybluemantis:Start()
-- --
-- # 3. Default settings -- # 2.1 Auto mode features
--
-- You can now add Accept- and Reject-Zones to your setup, e.g. to consider borders or de-militarized zones:
--
-- -- paramters are tables of @{Core.Zone#ZONE} objects!
-- mybluemantis:AddZones(AcceptZones,RejectZones)
--
-- Change the number of long-, mid- and short-range systems going live on a detected target:
--
-- -- parameters are numbers. Defaults are 1,2,2,6 respectively
-- mybluemantis:SetMaxActiveSAMs(Short,Mid,Long,Classic)
--
-- Advanced feature
--
-- -- switch off auto mode **before** you start MANTIS
-- mybluemantis.automode = false
-- -- scale of the firing range, i.e. don't fire at the fringes of max range, default 90%
-- mybluemantis.radiusscale = 0.9
--
-- # 3. Default settings [both modes unless stated otherwise]
-- --
-- By default, the following settings are active: -- By default, the following settings are active:
-- --
-- * SAM_Templates_Prefix = "Red SAM" - SAM site group names in the mission editor begin with "Red SAM" -- * SAM_Templates_Prefix = "Red SAM" - SAM site group names in the mission editor begin with "Red SAM"
-- * EWR_Templates_Prefix = "Red EWR" - EWR group names in the mission editor begin with "Red EWR" - can also be combined with an AWACS unit -- * EWR_Templates_Prefix = "Red EWR" - EWR group names in the mission editor begin with "Red EWR" - can also be combined with an AWACS unit
-- * checkradius = 25000 (meters) - SAMs will engage enemy flights, if they are within a 25km around each SAM site - `MANTIS:SetSAMRadius(radius)` -- * [classic mode] checkradius = 25000 (meters) - SAMs will engage enemy flights, if they are within a 25km around each SAM site - `MANTIS:SetSAMRadius(radius)`
-- * grouping = 5000 (meters) - Detection (EWR) will group enemy flights to areas of 5km for tracking - `MANTIS:SetEWRGrouping(radius)` -- * grouping = 5000 (meters) - Detection (EWR) will group enemy flights to areas of 5km for tracking - `MANTIS:SetEWRGrouping(radius)`
-- * acceptrange = 80000 (meters) - Detection (EWR) will on consider flights inside a 80km radius - `MANTIS:SetEWRRange(radius)`
-- * detectinterval = 30 (seconds) - MANTIS will decide every 30 seconds which SAM to activate - `MANTIS:SetDetectInterval(interval)` -- * detectinterval = 30 (seconds) - MANTIS will decide every 30 seconds which SAM to activate - `MANTIS:SetDetectInterval(interval)`
-- * engagerange = 85 (percent) - SAMs will only fire if flights are inside of a 85% radius of their max firerange - `MANTIS:SetSAMRange(range)` -- * engagerange = 85 (percent) - SAMs will only fire if flights are inside of a 85% radius of their max firerange - `MANTIS:SetSAMRange(range)`
-- * dynamic = false - Group filtering is set to once, i.e. newly added groups will not be part of the setup by default - `MANTIS:New(name,samprefix,ewrprefix,hq,coaltion,dynamic)` -- * dynamic = false - Group filtering is set to once, i.e. newly added groups will not be part of the setup by default - `MANTIS:New(name,samprefix,ewrprefix,hq,coaltion,dynamic)`
@ -190,9 +244,12 @@ MANTIS = {
EWR_Templates_Prefix = "", EWR_Templates_Prefix = "",
EWR_Group = nil, EWR_Group = nil,
Adv_EWR_Group = nil, Adv_EWR_Group = nil,
HQ_Template_CC = "", HQ_Template_CC = "",
HQ_CC = nil, HQ_CC = nil,
SAM_Table = {}, SAM_Table = {},
SAM_Table_Long = {},
SAM_Table_Medium = {},
SAM_Table_Short = {},
lid = "", lid = "",
Detection = nil, Detection = nil,
AWACS_Detection = nil, AWACS_Detection = nil,
@ -246,27 +303,28 @@ MANTIS.SamType = {
-- @field #number Blindspot no-firing range (green circle) -- @field #number Blindspot no-firing range (green circle)
-- @field #number Height Max firing height in km -- @field #number Height Max firing height in km
-- @field #string Type #MANTIS.SamType of SAM, i.e. SHORT, MEDIUM or LONG (range) -- @field #string Type #MANTIS.SamType of SAM, i.e. SHORT, MEDIUM or LONG (range)
-- @field #string Radar Radar typename on unit level
MANTIS.SamData = { MANTIS.SamData = {
["Hawk"] = { Range=44, Blindspot=0, Height=9, Type="Medium" }, -- measures in km ["Hawk"] = { Range=44, Blindspot=0, Height=9, Type="Medium", Radar="Hawk" }, -- measures in km
["NASAMS"] = { Range=14, Blindspot=0, Height=3, Type="Short" }, ["NASAMS"] = { Range=14, Blindspot=0, Height=3, Type="Short", Radar="NSAMS" },
["Patriot"] = { Range=99, Blindspot=0, Height=9, Type="Long" }, ["Patriot"] = { Range=99, Blindspot=0, Height=9, Type="Long", Radar="Patriot" },
["Rapier"] = { Range=6, Blindspot=0, Height=3, Type="Short" }, ["Rapier"] = { Range=6, Blindspot=0, Height=3, Type="Short", Radar="rapier" },
["SA-5"] = { Range=250, Blindspot=7, Height=40, Type="Long" }, ["SA-5"] = { Range=250, Blindspot=7, Height=40, Type="Long", Radar="5N62V" },
["SA-6"] = { Range=25, Blindspot=0, Height=8, Type="Medium" }, ["SA-6"] = { Range=25, Blindspot=0, Height=8, Type="Medium", Radar="1S91" },
["SA-3"] = { Range=18, Blindspot=0, Height=18, Type="Short" }, ["SA-3"] = { Range=18, Blindspot=0, Height=18, Type="Short", Radar="s-125" },
["SA-2"] = { Range=40, Blindspot=7, Height=25, Type="Medium" }, ["SA-2"] = { Range=40, Blindspot=7, Height=25, Type="Medium", Radar="SNR_75V" },
["SA-11"] = { Range=35, Blindspot=0, Height=20, Type="Medium" }, ["SA-11"] = { Range=35, Blindspot=0, Height=20, Type="Medium", Radar="SA-11" },
["SA-10"] = { Range=119, Blindspot=0, Height=18, Type="Long" }, ["SA-10"] = { Range=119, Blindspot=0, Height=18, Type="Long" , Radar="S-300PS"},
["Roland"] = { Range=8, Blindspot=0, Height=3, Type="Short" }, ["Roland"] = { Range=8, Blindspot=0, Height=3, Type="Short", Radar="Roland" },
["HQ-7"] = { Range=12, Blindspot=0, Height=3, Type="Short" }, ["HQ-7"] = { Range=12, Blindspot=0, Height=3, Type="Short", Radar="HQ-7" },
["SA-9"] = { Range=4, Blindspot=0, Height=3, Type="Short" }, ["SA-9"] = { Range=4, Blindspot=0, Height=3, Type="Short", Radar="Strela" },
["SA-8"] = { Range=10, Blindspot=0, Height=5, Type="Short" }, ["SA-8"] = { Range=10, Blindspot=0, Height=5, Type="Short", Radar="Osa 9A33" },
["SA-19"] = { Range=8, Blindspot=0, Height=3, Type="Short" }, ["SA-19"] = { Range=8, Blindspot=0, Height=3, Type="Short", Radar="Tunguska" },
["SA-15"] = { Range=11, Blindspot=0, Height=6, Type="Short" }, ["SA-15"] = { Range=11, Blindspot=0, Height=6, Type="Short", Radar="Tor 9A331" },
["SA-13"] = { Range=5, Blindspot=0, Height=3, Type="Short" }, ["SA-13"] = { Range=5, Blindspot=0, Height=3, Type="Short", Radar="Strela" },
["Avenger"] = { Range=4, Blindspot=0, Height=3, Type="Short" }, ["Avenger"] = { Range=4, Blindspot=0, Height=3, Type="Short", Radar="Avenger" },
["Chaparrel"] = { Range=8, Blindspot=0, Height=3, Type="Short" }, ["Chaparrel"] = { Range=8, Blindspot=0, Height=3, Type="Short", Radar="Chaparral" },
["Linebacker"] = { Range=4, Blindspot=0, Height=3, Type="Short" }, ["Linebacker"] = { Range=4, Blindspot=0, Height=3, Type="Short", Radar="Linebacker" },
} }
----------------------------------------------------------------------- -----------------------------------------------------------------------
@ -293,9 +351,6 @@ do
-- --
-- [optional] Use -- [optional] Use
-- --
-- * MANTIS:SetEWRGrouping(radius)
-- * MANTIS:SetEWRRange(radius)
-- * MANTIS:SetSAMRadius(radius)
-- * MANTIS:SetDetectInterval(interval) -- * MANTIS:SetDetectInterval(interval)
-- * MANTIS:SetAutoRelocate(hq, ewr) -- * MANTIS:SetAutoRelocate(hq, ewr)
-- --
@ -313,20 +368,23 @@ do
-- DONE: Set SAMs to auto if EWR dies -- DONE: Set SAMs to auto if EWR dies
-- DONE: Refresh SAM table in dynamic mode -- DONE: Refresh SAM table in dynamic mode
-- DONE: Treat Awacs separately, since they might be >80km off site -- DONE: Treat Awacs separately, since they might be >80km off site
-- TODO: Allow tables of prefixes for the setup -- DONE: Allow tables of prefixes for the setup
-- TODO: Auto-Mode with range setups for various known SAM types. -- DONE: Auto-Mode with range setups for various known SAM types.
self.SAM_Templates_Prefix = samprefix or "Red SAM" self.SAM_Templates_Prefix = samprefix or "Red SAM"
self.EWR_Templates_Prefix = ewrprefix or "Red EWR" self.EWR_Templates_Prefix = ewrprefix or "Red EWR"
self.HQ_Template_CC = hq or nil self.HQ_Template_CC = hq or nil
self.Coalition = coaltion or "red" self.Coalition = coaltion or "red"
self.SAM_Table = {} self.SAM_Table = {}
self.SAM_Table_Long = {}
self.SAM_Table_Medium = {}
self.SAM_Table_Short = {}
self.dynamic = dynamic or false self.dynamic = dynamic or false
self.checkradius = 25000 self.checkradius = 25000
self.grouping = 5000 self.grouping = 5000
self.acceptrange = 80000 self.acceptrange = 80000
self.detectinterval = 30 self.detectinterval = 30
self.engagerange = 75 self.engagerange = 85
self.autorelocate = false self.autorelocate = false
self.autorelocateunits = { HQ = false, EWR = false} self.autorelocateunits = { HQ = false, EWR = false}
self.advanced = false self.advanced = false
@ -347,13 +405,21 @@ do
self.DLink = false self.DLink = false
self.Padding = Padding or 10 self.Padding = Padding or 10
self.SuppressedGroups = {} self.SuppressedGroups = {}
-- 0.8 additions
self.automode = true
self.radiusscale = 0.9
self.SAMCheckRanges = {}
self.usezones = false
self.AcceptZones = {}
self.RejectZones = {}
self.maxlongrange = 1
self.maxmidrange = 2
self.maxshortrange = 2
self.maxclassic = 6
if EmOnOff then self.UseEmOnOff = true
if EmOnOff == false then if EmOnOff == false then
self.UseEmOnOff = false self.UseEmOnOff = false
else
self.UseEmOnOff = true
end
end end
if type(awacs) == "string" then if type(awacs) == "string" then
@ -376,7 +442,7 @@ do
BASE:TraceLevel(1) BASE:TraceLevel(1)
end end
local ewr_templates = {} self.ewr_templates = {}
if type(samprefix) ~= "table" then if type(samprefix) ~= "table" then
self.SAM_Templates_Prefix = {samprefix} self.SAM_Templates_Prefix = {samprefix}
end end
@ -386,23 +452,29 @@ do
end end
for _,_group in pairs (self.SAM_Templates_Prefix) do for _,_group in pairs (self.SAM_Templates_Prefix) do
table.insert(ewr_templates,_group) table.insert(self.ewr_templates,_group)
end end
for _,_group in pairs (self.EWR_Templates_Prefix) do for _,_group in pairs (self.EWR_Templates_Prefix) do
table.insert(ewr_templates,_group) table.insert(self.ewr_templates,_group)
end end
if self.advAwacs then
table.insert(self.ewr_templates,awacs)
end
self:T({self.ewr_templates})
if self.dynamic then if self.dynamic then
-- Set SAM SET_GROUP -- Set SAM SET_GROUP
self.SAM_Group = SET_GROUP:New():FilterPrefixes(self.SAM_Templates_Prefix):FilterCoalitions(self.Coalition):FilterStart() self.SAM_Group = SET_GROUP:New():FilterPrefixes(self.SAM_Templates_Prefix):FilterCoalitions(self.Coalition):FilterStart()
-- Set EWR SET_GROUP -- Set EWR SET_GROUP
self.EWR_Group = SET_GROUP:New():FilterPrefixes(ewr_templates):FilterCoalitions(self.Coalition):FilterStart() self.EWR_Group = SET_GROUP:New():FilterPrefixes(self.ewr_templates):FilterCoalitions(self.Coalition):FilterStart()
else else
-- Set SAM SET_GROUP -- Set SAM SET_GROUP
self.SAM_Group = SET_GROUP:New():FilterPrefixes(self.SAM_Templates_Prefix):FilterCoalitions(self.Coalition):FilterOnce() self.SAM_Group = SET_GROUP:New():FilterPrefixes(self.SAM_Templates_Prefix):FilterCoalitions(self.Coalition):FilterOnce()
-- Set EWR SET_GROUP -- Set EWR SET_GROUP
self.EWR_Group = SET_GROUP:New():FilterPrefixes(ewr_templates):FilterCoalitions(self.Coalition):FilterOnce() self.EWR_Group = SET_GROUP:New():FilterPrefixes(self.ewr_templates):FilterCoalitions(self.Coalition):FilterOnce()
end end
-- set up CC -- set up CC
@ -573,19 +645,34 @@ do
return self return self
end end
--- Function to set the detection radius of the EWR in meters --- Function to set accept and reject zones.
-- @param #MANTIS self
-- @param #table AcceptZones Table of @{Core.Zone#ZONE} objects
-- @param #table RejectZones Table of @{Core.Zone#ZONE} objects
-- @return #MANTIS self
function MANTIS:AddZones(AcceptZones,RejectZones)
self:T(self.lid .. "AddZones")
self.AcceptZones = AcceptZones or {}
self.RejectZones = RejectZones or {}
if #AcceptZones > 0 or #RejectZones > 0 then
self.usezones = true
end
return self
end
--- Function to set the detection radius of the EWR in meters. (Deprecated, SAM range is used)
-- @param #MANTIS self -- @param #MANTIS self
-- @param #number radius Radius of the EWR detection zone -- @param #number radius Radius of the EWR detection zone
function MANTIS:SetEWRRange(radius) function MANTIS:SetEWRRange(radius)
self:T(self.lid .. "SetEWRRange") self:T(self.lid .. "SetEWRRange")
local radius = radius or 80000 --local radius = radius or 80000
self.acceptrange = radius -- self.acceptrange = radius
return self return self
end end
--- Function to set switch-on/off zone for the SAM sites in meters --- Function to set switch-on/off zone for the SAM sites in meters. Overwritten per SAM in automode.
-- @param #MANTIS self -- @param #MANTIS self
-- @param #number radius Radius of the firing zone -- @param #number radius Radius of the firing zone in classic mode
function MANTIS:SetSAMRadius(radius) function MANTIS:SetSAMRadius(radius)
self:T(self.lid .. "SetSAMRadius") self:T(self.lid .. "SetSAMRadius")
local radius = radius or 25000 local radius = radius or 25000
@ -593,19 +680,35 @@ do
return self return self
end end
--- Function to set SAM firing engage range, 0-100 percent, e.g. 75 --- Function to set SAM firing engage range, 0-100 percent, e.g. 85
-- @param #MANTIS self -- @param #MANTIS self
-- @param #number range Percent of the max fire range -- @param #number range Percent of the max fire range
function MANTIS:SetSAMRange(range) function MANTIS:SetSAMRange(range)
self:T(self.lid .. "SetSAMRange") self:T(self.lid .. "SetSAMRange")
local range = range or 75 local range = range or 85
if range < 0 or range > 100 then if range < 0 or range > 100 then
range = 75 range = 85
end end
self.engagerange = range self.engagerange = range
return self return self
end end
--- Function to set number of SAMs going active on a valid, detected thread
-- @param #MANTIS self
-- @param #number Short Number of short-range systems activated, defaults to 1.
-- @param #number Mid Number of mid-range systems activated, defaults to 2.
-- @param #number Long Number of long-range systems activated, defaults to 2.
-- @param #number Classic (non-automode) Number of overall systems activated, defaults to 6.
-- @return #MANTIS self
function MANTIS:SetMaxActiveSAMs(Short,Mid,Long,Classic)
self:T(self.lid .. "SetMaxActiveSAMs")
self.maxclassic = Classic or 6
self.maxlongrange = Long or 1
self.maxmidrange = Mid or 2
self.maxshortrange = Short or 2
return self
end
--- Function to set a new SAM firing engage range, use this method to adjust range while running MANTIS, e.g. for different setups day and night --- Function to set a new SAM firing engage range, use this method to adjust range while running MANTIS, e.g. for different setups day and night
-- @param #MANTIS self -- @param #MANTIS self
-- @param #number range Percent of the max fire range -- @param #number range Percent of the max fire range
@ -737,7 +840,7 @@ do
return self return self
end end
--- Set using an #INTEL_DLINK object instead of #DETECTION --- Set using your own #INTEL_DLINK object instead of #DETECTION
-- @param #MANTIS self -- @param #MANTIS self
-- @param Ops.Intelligence#INTEL_DLINK DLink The data link object to be used. -- @param Ops.Intelligence#INTEL_DLINK DLink The data link object to be used.
function MANTIS:SetUsingDLink(DLink) function MANTIS:SetUsingDLink(DLink)
@ -858,6 +961,7 @@ do
--- [Internal] Function to execute the relocation --- [Internal] Function to execute the relocation
-- @param #MANTIS self -- @param #MANTIS self
-- @return #MANTIS self
function MANTIS:_RelocateGroups() function MANTIS:_RelocateGroups()
self:T(self.lid .. "RelocateGroups") self:T(self.lid .. "RelocateGroups")
local text = self.lid.." Relocating Groups" local text = self.lid.." Relocating Groups"
@ -893,37 +997,112 @@ do
return self return self
end end
--- [Internal] Function to check accept and reject zones
-- @param #MANTIS self
-- @param Core.Point#COORDINATE coord The coordinate to check
-- @return #boolean outcome
function MANTIS:_CheckCoordinateInZones(coord)
-- DEBUG
self:T(self.lid.."_CheckCoordinateInZones")
local inzone = false
-- acceptzones
if #self.AcceptZones > 0 then
for _,_zone in pairs(self.AcceptZones) do
local zone = _zone -- Core.Zone#ZONE
if zone:IsCoordinateInZone(coord) then
inzone = true
self:T(self.lid.."Target coord in Accept Zone!")
break
end
end
end
-- rejectzones
if #self.RejectZones > 0 and inzone then -- maybe in accept zone, but check the overlaps
for _,_zone in pairs(self.RejectZones) do
local zone = _zone -- Core.Zone#ZONE
if zone:IsCoordinateInZone(coord) then
inzone = false
self:T(self.lid.."Target coord in Reject Zone!")
break
end
end
end
return inzone
end
--- [Internal] Function to prefilter height based
-- @param #MANTIS self
-- @param #number height
-- @return #table set
function MANTIS:_PreFilterHeight(height)
self:T(self.lid.."_PreFilterHeight")
local set = {}
local dlink = self.Detection -- Ops.Intelligence#INTEL_DLINK
local detectedgroups = dlink:GetContactTable()
for _,_contact in pairs(detectedgroups) do
local contact = _contact -- Ops.Intelligence#INTEL.Contact
local grp = contact.group -- Wrapper.Group#GROUP
if grp:IsAlive() then
if grp:GetHeight(true) < height then
local coord = grp:GetCoordinate()
table.insert(set,coord)
end
end
end
return set
end
--- [Internal] Function to check if any object is in the given SAM zone --- [Internal] Function to check if any object is in the given SAM zone
-- @param #MANTIS self -- @param #MANTIS self
-- @param #table dectset Table of coordinates of detected items -- @param #table dectset Table of coordinates of detected items
-- @param Core.Point#COORDINATE samcoordinate Coordinate object. -- @param Core.Point#COORDINATE samcoordinate Coordinate object.
-- @param #number radius Radius to check.
-- @param #number height Height to check.
-- @param #boolean dlink Data from DLINK.
-- @return #boolean True if in any zone, else false -- @return #boolean True if in any zone, else false
-- @return #number Distance Target distance in meters or zero when no object is in zone -- @return #number Distance Target distance in meters or zero when no object is in zone
function MANTIS:CheckObjectInZone(dectset, samcoordinate) function MANTIS:_CheckObjectInZone(dectset, samcoordinate, radius, height, dlink)
self:T(self.lid.."CheckObjectInZone") self:T(self.lid.."_CheckObjectInZone")
-- check if non of the coordinate is in the given defense zone -- check if non of the coordinate is in the given defense zone
local radius = self.checkradius local rad = radius or self.checkradius
local set = dectset local set = dectset
if dlink then
-- DEBUG
set = self:_PreFilterHeight(height)
end
for _,_coord in pairs (set) do for _,_coord in pairs (set) do
local coord = _coord -- get current coord to check local coord = _coord -- get current coord to check
-- output for cross-check -- output for cross-check
local targetdistance = samcoordinate:DistanceFromPointVec2(coord) local targetdistance = samcoordinate:DistanceFromPointVec2(coord)
if self.verbose or self.debug then if not targetdistance then
targetdistance = samcoordinate:Get2DDistance(coord)
end
-- check accept/reject zones
local zonecheck = true
if self.usezones then
-- DONE
zonecheck = self:_CheckCoordinateInZones(coord)
end
if self.verbose and self.debug then
local dectstring = coord:ToStringLLDMS() local dectstring = coord:ToStringLLDMS()
local samstring = samcoordinate:ToStringLLDMS() local samstring = samcoordinate:ToStringLLDMS()
local text = string.format("Checking SAM at % s - Distance %d m - Target %s", samstring, targetdistance, dectstring) local inrange = "false"
if targetdistance <= rad then
inrange = "true"
end
local text = string.format("Checking SAM at %s | Targetdist %d | Rad %d | Inrange %s", samstring, targetdistance, rad, inrange)
local m = MESSAGE:New(text,10,"Check"):ToAllIf(self.debug) local m = MESSAGE:New(text,10,"Check"):ToAllIf(self.debug)
self:I(self.lid..text) self:T(self.lid..text)
end end
-- end output to cross-check -- end output to cross-check
if targetdistance <= radius then if targetdistance <= rad and zonecheck then
return true, targetdistance return true, targetdistance
end end
end end
return false, 0 return false, 0
end end
--- [Internal] Function to start the detection via EWR groups --- [Internal] Function to start the detection via EWR groups - if INTEL isn\'t available
-- @param #MANTIS self -- @param #MANTIS self
-- @return Functional.Detection #DETECTION_AREAS The running detection set -- @return Functional.Detection #DETECTION_AREAS The running detection set
function MANTIS:StartDetection() function MANTIS:StartDetection()
@ -932,29 +1111,52 @@ do
-- start detection -- start detection
local groupset = self.EWR_Group local groupset = self.EWR_Group
local grouping = self.grouping or 5000 local grouping = self.grouping or 5000
local acceptrange = self.acceptrange or 80000 --local acceptrange = self.acceptrange or 80000
local interval = self.detectinterval or 60 local interval = self.detectinterval or 20
--@param Functional.Detection #DETECTION_AREAS _MANTISdetection [Internal] The MANTIS detection object
local MANTISdetection = DETECTION_AREAS:New( groupset, grouping ) --[Internal] Grouping detected objects to 5000m zones local MANTISdetection = DETECTION_AREAS:New( groupset, grouping ) --[Internal] Grouping detected objects to 5000m zones
MANTISdetection:FilterCategories({ Unit.Category.AIRPLANE, Unit.Category.HELICOPTER }) MANTISdetection:FilterCategories({ Unit.Category.AIRPLANE, Unit.Category.HELICOPTER })
MANTISdetection:SetAcceptRange(acceptrange) --MANTISdetection:SetAcceptRange(acceptrange) -- deprecated - in range of SAMs is used anyway
MANTISdetection:SetRefreshTimeInterval(interval) MANTISdetection:SetRefreshTimeInterval(interval)
MANTISdetection:Start() MANTISdetection:__Start(2)
function MANTISdetection:OnAfterDetectedItem(From,Event,To,DetectedItem)
--BASE:I( { From, Event, To, DetectedItem })
local debug = false
if DetectedItem.IsDetected and debug then
local Coordinate = DetectedItem.Coordinate -- Core.Point#COORDINATE
local text = "MANTIS: Detection at "..Coordinate:ToStringLLDMS()
local m = MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
end
end
return MANTISdetection return MANTISdetection
end end
--- [Internal] Function to start the detection via AWACS if defined as separate --- [Internal] Function to start the detection with INTEL via EWR groups
-- @param #MANTIS self
-- @return Ops.Intel#INTEL_DLINK The running detection set
function MANTIS:StartIntelDetection()
self:T(self.lid.."Starting Intel Detection")
-- DEBUG
-- start detection
local groupset = self.EWR_Group
local samset = self.SAM_Group
self.intelset = {}
local IntelOne = INTEL:New(groupset,self.Coalition,self.name.." IntelOne")
--IntelOne:SetClusterAnalysis(true,true)
--IntelOne:SetClusterRadius(5000)
IntelOne:Start()
local IntelTwo = INTEL:New(samset,self.Coalition,self.name.." IntelTwo")
--IntelTwo:SetClusterAnalysis(true,true)
--IntelTwo:SetClusterRadius(5000)
IntelTwo:Start()
local IntelDlink = INTEL_DLINK:New({IntelOne,IntelTwo},self.name.." DLINK",22,300)
IntelDlink:__Start(1)
self:SetUsingDLink(IntelDlink)
table.insert(self.intelset, IntelOne)
table.insert(self.intelset, IntelTwo)
return IntelDlink
end
--- [Internal] Function to start the detection via AWACS if defined as separate (classic)
-- @param #MANTIS self -- @param #MANTIS self
-- @return Functional.Detection #DETECTION_AREAS The running detection set -- @return Functional.Detection #DETECTION_AREAS The running detection set
function MANTIS:StartAwacsDetection() function MANTIS:StartAwacsDetection()
@ -974,16 +1176,79 @@ do
MANTISAwacs:SetRefreshTimeInterval(interval) MANTISAwacs:SetRefreshTimeInterval(interval)
MANTISAwacs:Start() MANTISAwacs:Start()
function MANTISAwacs:OnAfterDetectedItem(From,Event,To,DetectedItem) return MANTISAwacs
--BASE:I( { From, Event, To, DetectedItem }) end
local debug = false
if DetectedItem.IsDetected and debug then --- [Internal] Function to get SAM firing data from units types.
local Coordinate = DetectedItem.Coordinate -- Core.Point#COORDINATE -- @param #MANTIS self
local text = "Awacs Detection at "..Coordinate:ToStringLLDMS() -- @param #string grpname Name of the group
local m = MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug) -- @return #number range Max firing range
-- @return #number height Max firing height
-- @return #string type Long, medium or short range
function MANTIS:_GetSAMDataFromUnits(grpname)
self:T(self.lid.."_GetSAMRange")
local found = false
local range = self.checkradius
local height = 3000
local type = MANTIS.SamType.MEDIUM
local group = GROUP:FindByName(grpname) -- Wrapper.Group#GROUP
local units = group:GetUnits()
for _,_unit in pairs(units) do
local unit = _unit -- Wrapper.Unit#UNIT
local type = string.lower(unit:GetTypeName())
--self:I(string.format("Matching typename: %s",type))
for idx,entry in pairs(self.SamData) do
local _entry = entry -- #MANTIS.SamData
local _radar = string.lower(_entry.Radar)
--self:I(string.format("Typing typename: %s",_radar))
if string.find(type,_radar,1,true) then
range = _entry.Range * 1000 * self.radiusscale -- max firing range
height = _entry.Height * 1000 -- max firing height
type = _entry.Type
--self:I(string.format("Match: %s - %s",_radar,type))
found = true
break
end
end
if found then break end
end
if not found then
self:E(self.lid .. string.format("*****Could not match radar data for %s! Will default to midrange values!",grpname))
end
return range, height, type
end
--- [Internal] Function to get SAM firing data
-- @param #MANTIS self
-- @param #string grpname Name of the group
-- @return #number range Max firing range
-- @return #number height Max firing height
-- @return #string type Long, medium or short range
function MANTIS:_GetSAMRange(grpname)
self:T(self.lid.."_GetSAMRange")
local range = self.checkradius
local height = 3000
local type = MANTIS.SamType.MEDIUM
local found = false
if self.automode then
for idx,entry in pairs(self.SamData) do
--self:I("ID = " .. idx)
if string.find(grpname,idx,1,true) then
local _entry = entry -- #MANTIS.SamData
range = _entry.Range * 1000 * self.radiusscale -- max firing range
height = _entry.Height * 1000 -- max firing height
type = _entry.Type
--self:I("Groupname = " .. grpname .. " Range= " .. range)
found = true
break
end
end end
end end
return MANTISAwacs -- secondary filter if not found
if not found and self.automode then
range, height, type = self:_GetSAMDataFromUnits(grpname)
end
return range, height, type
end end
--- [Internal] Function to set the SAM start state --- [Internal] Function to set the SAM start state
@ -991,17 +1256,22 @@ do
-- @return #MANTIS self -- @return #MANTIS self
function MANTIS:SetSAMStartState() function MANTIS:SetSAMStartState()
-- DONE: if using dynamic filtering, update SAM_Table and the (active) SEAD groups, pull req #1405/#1406 -- DONE: if using dynamic filtering, update SAM_Table and the (active) SEAD groups, pull req #1405/#1406
-- DONE: Auto mode
self:T(self.lid.."Setting SAM Start States") self:T(self.lid.."Setting SAM Start States")
-- get SAM Group -- get SAM Group
local SAM_SET = self.SAM_Group local SAM_SET = self.SAM_Group
local SAM_Grps = SAM_SET.Set --table of objects local SAM_Grps = SAM_SET.Set --table of objects
local SAM_Tbl = {} -- table of SAM defense zones local SAM_Tbl = {} -- table of SAM defense zones
local SAM_Tbl_lg = {} -- table of long range SAM defense zones
local SAM_Tbl_md = {} -- table of mid range SAM defense zones
local SAM_Tbl_sh = {} -- table of short range SAM defense zones
local SEAD_Grps = {} -- table of SAM names to make evasive local SEAD_Grps = {} -- table of SAM names to make evasive
local engagerange = self.engagerange -- firing range in % of max local engagerange = self.engagerange -- firing range in % of max
--cycle through groups and set alarm state etc --cycle through groups and set alarm state etc
for _i,_group in pairs (SAM_Grps) do for _i,_group in pairs (SAM_Grps) do
if _group:IsGround() and _group:IsAlive() then
local group = _group -- Wrapper.Group#GROUP local group = _group -- Wrapper.Group#GROUP
-- TODO: add emissions on/off -- DONE: add emissions on/off
if self.UseEmOnOff then if self.UseEmOnOff then
group:OptionAlarmStateRed() group:OptionAlarmStateRed()
group:EnableEmission(false) group:EnableEmission(false)
@ -1009,16 +1279,29 @@ do
else else
group:OptionAlarmStateGreen() -- AI off group:OptionAlarmStateGreen() -- AI off
end end
group:SetOption(AI.Option.Ground.id.AC_ENGAGEMENT_RANGE_RESTRICTION,engagerange) --default engagement will be 75% of firing range group:OptionEngageRange(engagerange) --default engagement will be 85% of firing range
if group:IsGround() and group:IsAlive() then local grpname = group:GetName()
local grpname = group:GetName() local grpcoord = group:GetCoordinate()
local grpcoord = group:GetCoordinate() local grprange,grpheight,type = self:_GetSAMRange(grpname)
table.insert( SAM_Tbl, {grpname, grpcoord}) table.insert( SAM_Tbl, {grpname, grpcoord, grprange, grpheight})
table.insert( SEAD_Grps, grpname ) table.insert( SEAD_Grps, grpname )
self.SamStateTracker[grpname] = "GREEN" if type == MANTIS.SamType.LONG then
table.insert( SAM_Tbl_lg, {grpname, grpcoord, grprange, grpheight})
--self:T("SAM "..grpname.." is type LONG")
elseif type == MANTIS.SamType.MEDIUM then
table.insert( SAM_Tbl_md, {grpname, grpcoord, grprange, grpheight})
--self:T("SAM "..grpname.." is type MEDIUM")
elseif type == MANTIS.SamType.SHORT then
table.insert( SAM_Tbl_sh, {grpname, grpcoord, grprange, grpheight})
--self:T("SAM "..grpname.." is type SHORT")
end
self.SamStateTracker[grpname] = "GREEN"
end end
end end
self.SAM_Table = SAM_Tbl self.SAM_Table = SAM_Tbl
self.SAM_Table_Long = SAM_Tbl_lg
self.SAM_Table_Medium = SAM_Tbl_md
self.SAM_Table_Short = SAM_Tbl_sh
-- make SAMs evasive -- make SAMs evasive
local mysead = SEAD:New( SEAD_Grps, self.Padding ) -- Functional.Sead#SEAD local mysead = SEAD:New( SEAD_Grps, self.Padding ) -- Functional.Sead#SEAD
mysead:SetEngagementRange(engagerange) mysead:SetEngagementRange(engagerange)
@ -1040,20 +1323,37 @@ do
local SAM_SET = self.SAM_Group local SAM_SET = self.SAM_Group
local SAM_Grps = SAM_SET.Set --table of objects local SAM_Grps = SAM_SET.Set --table of objects
local SAM_Tbl = {} -- table of SAM defense zones local SAM_Tbl = {} -- table of SAM defense zones
local SAM_Tbl_lg = {} -- table of long range SAM defense zones
local SAM_Tbl_md = {} -- table of mid range SAM defense zones
local SAM_Tbl_sh = {} -- table of short range SAM defense zon
local SEAD_Grps = {} -- table of SAM names to make evasive local SEAD_Grps = {} -- table of SAM names to make evasive
local engagerange = self.engagerange -- firing range in % of max local engagerange = self.engagerange -- firing range in % of max
--cycle through groups and set alarm state etc --cycle through groups and set alarm state etc
for _i,_group in pairs (SAM_Grps) do for _i,_group in pairs (SAM_Grps) do
local group = _group local group = _group -- Wrapper.Group#GROUP
group:SetOption(AI.Option.Ground.id.AC_ENGAGEMENT_RANGE_RESTRICTION,engagerange) --engagement will be 75% of firing range group:OptionEngageRange(engagerange) --engagement will be 85% of firing range
if group:IsGround() and group:IsAlive() then if group:IsGround() and group:IsAlive() then
local grpname = group:GetName() local grpname = group:GetName()
local grpcoord = group:GetCoordinate() local grpcoord = group:GetCoordinate()
table.insert( SAM_Tbl, {grpname, grpcoord}) -- make the table lighter, as I don't really use the zone here local grprange, grpheight,type = self:_GetSAMRange(grpname)
table.insert( SAM_Tbl, {grpname, grpcoord, grprange, grpheight}) -- make the table lighter, as I don't really use the zone here
table.insert( SEAD_Grps, grpname ) table.insert( SEAD_Grps, grpname )
if type == MANTIS.SamType.LONG then
table.insert( SAM_Tbl_lg, {grpname, grpcoord, grprange, grpheight})
--self:I({grpname,grprange, grpheight})
elseif type == MANTIS.SamType.MEDIUM then
table.insert( SAM_Tbl_md, {grpname, grpcoord, grprange, grpheight})
--self:I({grpname,grprange, grpheight})
elseif type == MANTIS.SamType.SHORT then
table.insert( SAM_Tbl_sh, {grpname, grpcoord, grprange, grpheight})
-- self:I({grpname,grprange, grpheight})
end
end end
end end
self.SAM_Table = SAM_Tbl self.SAM_Table = SAM_Tbl
self.SAM_Table_Long = SAM_Tbl_lg
self.SAM_Table_Medium = SAM_Tbl_md
self.SAM_Table_Short = SAM_Tbl_sh
-- make SAMs evasive -- make SAMs evasive
if self.mysead ~= nil then if self.mysead ~= nil then
local mysead = self.mysead local mysead = self.mysead
@ -1093,37 +1393,37 @@ do
--- [Internal] Check detection function --- [Internal] Check detection function
-- @param #MANTIS self -- @param #MANTIS self
-- @param Functional.Detection#DETECTION_AREAS detection Detection object -- @param #table samset Table of SAM data
-- @param #table detset Table of COORDINATES
-- @param #boolean dlink Using DLINK
-- @param #limit limit of SAM sites to go active on a contact
-- @return #MANTIS self -- @return #MANTIS self
function MANTIS:_Check(detection) function MANTIS:_CheckLoop(samset,detset,dlink,limit)
self:T(self.lid .. "Check") self:T(self.lid .. "CheckLoop " .. #detset .. " Coordinates")
--get detected set local switchedon = 0
local detset = detection:GetDetectedItemCoordinates()
self:T("Check:", {detset})
-- randomly update SAM Table
local rand = math.random(1,100)
if rand > 65 then -- 1/3 of cases
self:_RefreshSAMTable()
end
-- switch SAMs on/off if (n)one of the detected groups is inside their reach
local samset = self:_GetSAMTable() -- table of i.1=names, i.2=coordinates
for _,_data in pairs (samset) do for _,_data in pairs (samset) do
local samcoordinate = _data[2] local samcoordinate = _data[2]
local name = _data[1] local name = _data[1]
local radius = _data[3]
local height = _data[4]
local samgroup = GROUP:FindByName(name) local samgroup = GROUP:FindByName(name)
local IsInZone, Distance = self:CheckObjectInZone(detset, samcoordinate) local IsInZone, Distance = self:_CheckObjectInZone(detset, samcoordinate, radius, height, dlink)
local suppressed = self.SuppressedGroups[name] or false local suppressed = self.SuppressedGroups[name] or false
if IsInZone then --check any target in zone and not curr managed by SEAD if IsInZone and not suppressed then --check any target in zone and not currently managed by SEAD
if samgroup:IsAlive() then if samgroup:IsAlive() then
-- switch on SAM -- switch on SAM
if self.UseEmOnOff and not suppressed then local switch = false
if self.UseEmOnOff and switchedon < limit then
-- DONE: add emissions on/off -- DONE: add emissions on/off
--samgroup:SetAIOn()
samgroup:EnableEmission(true) samgroup:EnableEmission(true)
elseif not self.UseEmOnOff and not suppressed then switchedon = switchedon + 1
switch = true
elseif (not self.UseEmOnOff) and switchedon < limit then
samgroup:OptionAlarmStateRed() samgroup:OptionAlarmStateRed()
switchedon = switchedon + 1
switch = true
end end
if self.SamStateTracker[name] ~= "RED" and not suppressed then if self.SamStateTracker[name] ~= "RED" and switch then
self:__RedState(1,samgroup) self:__RedState(1,samgroup)
self.SamStateTracker[name] = "RED" self.SamStateTracker[name] = "RED"
end end
@ -1137,25 +1437,25 @@ do
self:__ShoradActivated(1,name, radius, ontime) self:__ShoradActivated(1,name, radius, ontime)
end end
-- debug output -- debug output
if self.debug or self.verbose and not suppressed then if (self.debug or self.verbose) and switch then
local text = string.format("SAM %s switched to alarm state RED!", name) local text = string.format("SAM %s switched to alarm state RED!", name)
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug) local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
if self.verbose then self:I(self.lid..text) end if self.verbose then self:I(self.lid..text) end
end end
end --end alive end --end alive
else else
if samgroup:IsAlive() then if samgroup:IsAlive() and not suppressed then
-- switch off SAM -- switch off SAM
if self.UseEmOnOff and not suppressed then if self.UseEmOnOff then
samgroup:EnableEmission(false) samgroup:EnableEmission(false)
elseif not self.UseEmOnOff and not suppressed then else
samgroup:OptionAlarmStateGreen() samgroup:OptionAlarmStateGreen()
end end
if self.SamStateTracker[name] ~= "GREEN" and not suppressed then if self.SamStateTracker[name] ~= "GREEN" then
self:__GreenState(1,samgroup) self:__GreenState(1,samgroup)
self.SamStateTracker[name] = "GREEN" self.SamStateTracker[name] = "GREEN"
end end
if self.debug or self.verbose and not suppressed then if self.debug or self.verbose then
local text = string.format("SAM %s switched to alarm state GREEN!", name) local text = string.format("SAM %s switched to alarm state GREEN!", name)
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug) local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
if self.verbose then self:I(self.lid..text) end if self.verbose then self:I(self.lid..text) end
@ -1166,6 +1466,36 @@ do
return self return self
end end
--- [Internal] Check detection function
-- @param #MANTIS self
-- @param Functional.Detection#DETECTION_AREAS detection Detection object
-- @param #boolean dlink
-- @return #MANTIS self
function MANTIS:_Check(detection,dlink)
self:T(self.lid .. "Check")
--get detected set
local detset = detection:GetDetectedItemCoordinates()
--self:T("Check:", {detset})
-- randomly update SAM Table
local rand = math.random(1,100)
if rand > 65 then -- 1/3 of cases
self:_RefreshSAMTable()
end
-- switch SAMs on/off if (n)one of the detected groups is inside their reach
if self.automode then
local samset = self.SAM_Table_Long -- table of i.1=names, i.2=coordinates, i.3=firing range, i.4=firing height
self:_CheckLoop(samset,detset,dlink,self.maxlongrange)
local samset = self.SAM_Table_Medium -- table of i.1=names, i.2=coordinates, i.3=firing range, i.4=firing height
self:_CheckLoop(samset,detset,dlink,self.maxmidrange)
local samset = self.SAM_Table_Long -- table of i.1=names, i.2=coordinates, i.3=firing range, i.4=firing height
self:_CheckLoop(samset,detset,dlink,self.maxshortrange)
else
local samset = self:_GetSAMTable() -- table of i.1=names, i.2=coordinates, i.3=firing range, i.4=firing height
self:_CheckLoop(samset,detset,dlink,self.maxclassic)
end
return self
end
--- [Internal] Relocation relay function --- [Internal] Relocation relay function
-- @param #MANTIS self -- @param #MANTIS self
-- @return #MANTIS self -- @return #MANTIS self
@ -1194,11 +1524,12 @@ do
local samgroup = GROUP:FindByName(name) local samgroup = GROUP:FindByName(name)
if samgroup:IsAlive() then if samgroup:IsAlive() then
if self.UseEmOnOff then if self.UseEmOnOff then
-- TODO: add emissions on/off -- DONE: add emissions on/off
--samgroup:SetAIOn() --samgroup:SetAIOn()
samgroup:EnableEmission(true) samgroup:EnableEmission(true)
else
samgroup:OptionAlarmStateRed()
end end
samgroup:OptionAlarmStateRed()
end -- end alive end -- end alive
end -- end for loop end -- end for loop
elseif newstate <= 1 then elseif newstate <= 1 then
@ -1234,12 +1565,16 @@ do
self:T({From, Event, To}) self:T({From, Event, To})
self:T(self.lid.."Starting MANTIS") self:T(self.lid.."Starting MANTIS")
self:SetSAMStartState() self:SetSAMStartState()
if not self.DLink then if not INTEL then
self.Detection = self:StartDetection() self.Detection = self:StartDetection()
else
self.Detection = self:StartIntelDetection()
end end
if self.advAwacs then --[[
if self.advAwacs and not self.automode then
self.AWACS_Detection = self:StartAwacsDetection() self.AWACS_Detection = self:StartAwacsDetection()
end end
--]]
self:__Status(-math.random(1,10)) self:__Status(-math.random(1,10))
return self return self
end end
@ -1254,13 +1589,14 @@ do
self:T({From, Event, To}) self:T({From, Event, To})
-- check detection -- check detection
if not self.state2flag then if not self.state2flag then
self:_Check(self.Detection) self:_Check(self.Detection,self.DLink)
end end
-- check Awacs --[[ check Awacs
if self.advAwacs and not self.state2flag then if self.advAwacs and not self.state2flag then
self:_Check(self.AWACS_Detection) self:_Check(self.AWACS_Detection,false)
end end
--]]
-- relocate HQ and EWR -- relocate HQ and EWR
if self.autorelocate then if self.autorelocate then
@ -1301,7 +1637,7 @@ do
function MANTIS:onafterStatus(From,Event,To) function MANTIS:onafterStatus(From,Event,To)
self:T({From, Event, To}) self:T({From, Event, To})
-- Display some states -- Display some states
if self.debug then if self.debug and self.verbose then
self:I(self.lid .. "Status Report") self:I(self.lid .. "Status Report")
for _name,_state in pairs(self.SamStateTracker) do for _name,_state in pairs(self.SamStateTracker) do
self:I(string.format("Site %s\tStatus %s",_name,_state)) self:I(string.format("Site %s\tStatus %s",_name,_state))
@ -1342,7 +1678,7 @@ do
-- @param Wrapper.Group#GROUP Group The GROUP object whose state was changed -- @param Wrapper.Group#GROUP Group The GROUP object whose state was changed
-- @return #MANTIS self -- @return #MANTIS self
function MANTIS:onafterGreenState(From, Event, To, Group) function MANTIS:onafterGreenState(From, Event, To, Group)
self:T({From, Event, To, Group}) self:T({From, Event, To, Group:GetName()})
return self return self
end end
@ -1354,7 +1690,7 @@ do
-- @param Wrapper.Group#GROUP Group The GROUP object whose state was changed -- @param Wrapper.Group#GROUP Group The GROUP object whose state was changed
-- @return #MANTIS self -- @return #MANTIS self
function MANTIS:onafterRedState(From, Event, To, Group) function MANTIS:onafterRedState(From, Event, To, Group)
self:T({From, Event, To, Group}) self:T({From, Event, To, Group:GetName()})
return self return self
end end
@ -1395,6 +1731,13 @@ do
function MANTIS:onafterSeadSuppressionStart(From, Event, To, Group, Name) function MANTIS:onafterSeadSuppressionStart(From, Event, To, Group, Name)
self:T({From, Event, To, Name}) self:T({From, Event, To, Name})
self.SuppressedGroups[Name] = true self.SuppressedGroups[Name] = true
if self.ShoradLink then
local Shorad = self.Shorad
local radius = self.checkradius
local ontime = self.ShoradTime
Shorad:WakeUpShorad(Name, radius, ontime)
self:__ShoradActivated(1,Name, radius, ontime)
end
return self return self
end end