mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
MANTIS - latest updates
This commit is contained in:
parent
a6beecf510
commit
a38abc2f7f
@ -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)`
|
||||||
@ -193,6 +247,9 @@ MANTIS = {
|
|||||||
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,34 +1176,102 @@ do
|
|||||||
MANTISAwacs:SetRefreshTimeInterval(interval)
|
MANTISAwacs:SetRefreshTimeInterval(interval)
|
||||||
MANTISAwacs:Start()
|
MANTISAwacs:Start()
|
||||||
|
|
||||||
function MANTISAwacs: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 = "Awacs Detection at "..Coordinate:ToStringLLDMS()
|
|
||||||
local m = MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return MANTISAwacs
|
return MANTISAwacs
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- [Internal] Function to get SAM firing data from units types.
|
||||||
|
-- @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:_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
|
||||||
|
-- secondary filter if not found
|
||||||
|
if not found and self.automode then
|
||||||
|
range, height, type = self:_GetSAMDataFromUnits(grpname)
|
||||||
|
end
|
||||||
|
return range, height, type
|
||||||
|
end
|
||||||
|
|
||||||
--- [Internal] Function to set the SAM start state
|
--- [Internal] Function to set the SAM start state
|
||||||
-- @param #MANTIS self
|
-- @param #MANTIS self
|
||||||
-- @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()
|
||||||
table.insert( SAM_Tbl, {grpname, grpcoord})
|
local grprange,grpheight,type = self:_GetSAMRange(grpname)
|
||||||
|
table.insert( SAM_Tbl, {grpname, grpcoord, grprange, grpheight})
|
||||||
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: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"
|
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)
|
||||||
end
|
else
|
||||||
samgroup:OptionAlarmStateRed()
|
samgroup:OptionAlarmStateRed()
|
||||||
|
end
|
||||||
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
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user