MANTIS - Change logic to FSM, added functions

CSAR - advanced options to name injected AI downed pilots
CTLD - added Herc speed check
This commit is contained in:
Applevangelist 2021-07-13 17:50:44 +02:00
parent e33de03522
commit 433d1bbf57
3 changed files with 493 additions and 224 deletions

View File

@ -192,6 +192,16 @@ MANTIS = {
ShoradTime = 600, ShoradTime = 600,
ShoradActDistance = 15000, ShoradActDistance = 15000,
UseEmOnOff = false, UseEmOnOff = false,
TimeStamp = 0,
state2flag = false,
}
--- Advanced state enumerator
-- @type MANTIS.AdvancedState
MANTIS.AdvancedState = {
GREEN = 0,
AMBER = 1,
RED = 2,
} }
----------------------------------------------------------------------- -----------------------------------------------------------------------
@ -263,7 +273,10 @@ do
self.ShoradLink = false self.ShoradLink = false
self.ShoradTime = 600 self.ShoradTime = 600
self.ShoradActDistance = 15000 self.ShoradActDistance = 15000
-- TODO: add emissions on/off when available .... in 2 weeks self.TimeStamp = timer.getAbsTime()
self.relointerval = math.random(1800,3600) -- random between 30 and 60 mins
self.state2flag = false
if EmOnOff then if EmOnOff then
if EmOnOff == false then if EmOnOff == false then
self.UseEmOnOff = false self.UseEmOnOff = false
@ -279,7 +292,7 @@ do
end end
-- Inherit everything from BASE class. -- Inherit everything from BASE class.
local self = BASE:Inherit(self, BASE:New()) -- #MANTIS local self = BASE:Inherit(self, FSM:New()) -- #MANTIS
-- Set the string id for output to DCS.log file. -- Set the string id for output to DCS.log file.
self.lid=string.format("MANTIS %s | ", self.name) self.lid=string.format("MANTIS %s | ", self.name)
@ -310,9 +323,102 @@ do
end end
-- @field #string version -- @field #string version
self.version="0.4.2" self.version="0.5.1"
self:I(string.format("***** Starting MANTIS Version %s *****", self.version)) self:I(string.format("***** Starting MANTIS Version %s *****", self.version))
--- FSM Functions ---
-- Start State.
self:SetStartState("Stopped")
-- Add FSM transitions.
-- From State --> Event --> To State
self:AddTransition("Stopped", "Start", "Running") -- Start FSM.
self:AddTransition("*", "Status", "*") -- MANTIS status update.
self:AddTransition("*", "Relocating", "*") -- MANTIS HQ and EWR are relocating.
self:AddTransition("*", "GreenState", "*") -- MANTIS A SAM switching to GREEN state.
self:AddTransition("*", "RedState", "*") -- MANTIS A SAM switching to RED state.
self:AddTransition("*", "AdvStateChange", "*") -- MANTIS advanced mode state change.
self:AddTransition("*", "ShoradActivated", "*") -- MANTIS woke up a connected SHORAD.
self:AddTransition("*", "Stop", "Stopped") -- Stop FSM.
------------------------
--- Pseudo Functions ---
------------------------
--- Triggers the FSM event "Start". Starts the MANTIS. Initializes parameters and starts event handlers.
-- @function [parent=#MANTIS] Start
-- @param #MANTIS self
--- Triggers the FSM event "Start" after a delay. Starts the MANTIS. Initializes parameters and starts event handlers.
-- @function [parent=#MANTIS] __Start
-- @param #MANTIS self
-- @param #number delay Delay in seconds.
--- Triggers the FSM event "Stop". Stops the MANTIS and all its event handlers.
-- @param #MANTIS self
--- Triggers the FSM event "Stop" after a delay. Stops the MANTIS and all its event handlers.
-- @function [parent=#MANTIS] __Stop
-- @param #MANTIS self
-- @param #number delay Delay in seconds.
--- Triggers the FSM event "Status".
-- @function [parent=#MANTIS] Status
-- @param #MANTIS self
--- Triggers the FSM event "Status" after a delay.
-- @function [parent=#MANTIS] __Status
-- @param #MANTIS self
-- @param #number delay Delay in seconds.
--- On After "Relocating" event. HQ and/or EWR moved.
-- @function [parent=#MANTIS] OnAfterRelocating
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @return #MANTIS self
--- On After "GreenState" event. A SAM group was switched to GREEN alert.
-- @function [parent=#MANTIS] OnAfterGreenState
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param Wrapper.Group#GROUP Group The GROUP object whose state was changed
-- @return #MANTIS self
--- On After "RedState" event. A SAM group was switched to RED alert.
-- @function [parent=#MANTIS] OnAfterRedState
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param Wrapper.Group#GROUP Group The GROUP object whose state was changed
-- @return #MANTIS self
--- On After "AdvStateChange" event. Advanced state changed, influencing detection speed.
-- @function [parent=#MANTIS] OnAfterAdvStateChange
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param #number Oldstate Old state - 0 = green, 1 = amber, 2 = red
-- @param #number Newstate New state - 0 = green, 1 = amber, 2 = red
-- @param #number Interval Calculated detection interval based on state and advanced feature setting
-- @return #MANTIS self
--- On After "ShoradActivated" event. Mantis has activated a SHORAD.
-- @function [parent=#MANTIS] OnAfterShoradActivated
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param #string Name Name of the GROUP which SHORAD shall protect
-- @param #number Radius Radius around the named group to find SHORAD groups
-- @param #number Ontime Seconds the SHORAD will stay active
return self return self
end end
@ -320,17 +426,19 @@ do
-- MANTIS helper functions -- MANTIS helper functions
----------------------------------------------------------------------- -----------------------------------------------------------------------
--- [internal] Function to get the self.SAM_Table --- [Internal] Function to get the self.SAM_Table
-- @param #MANTIS self -- @param #MANTIS self
-- @return #table table -- @return #table table
function MANTIS:_GetSAMTable() function MANTIS:_GetSAMTable()
self:T(self.lid .. "GetSAMTable")
return self.SAM_Table return self.SAM_Table
end end
--- [internal] Function to set the self.SAM_Table --- [Internal] Function to set the self.SAM_Table
-- @param #MANTIS self -- @param #MANTIS self
-- @return #MANTIS self -- @return #MANTIS self
function MANTIS:_SetSAMTable(table) function MANTIS:_SetSAMTable(table)
self:T(self.lid .. "SetSAMTable")
self.SAM_Table = table self.SAM_Table = table
return self return self
end end
@ -339,41 +447,50 @@ do
-- @param #MANTIS self -- @param #MANTIS self
-- @param #number radius Radius upon which detected objects will be grouped -- @param #number radius Radius upon which detected objects will be grouped
function MANTIS:SetEWRGrouping(radius) function MANTIS:SetEWRGrouping(radius)
self:T(self.lid .. "SetEWRGrouping")
local radius = radius or 5000 local radius = radius or 5000
self.grouping = radius self.grouping = radius
return self
end end
--- Function to set the detection radius of the EWR in meters --- Function to set the detection radius of the EWR in meters
-- @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")
local radius = radius or 80000 local radius = radius or 80000
self.acceptrange = radius self.acceptrange = radius
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
-- @param #MANTIS self -- @param #MANTIS self
-- @param #number radius Radius of the firing zone -- @param #number radius Radius of the firing zone
function MANTIS:SetSAMRadius(radius) function MANTIS:SetSAMRadius(radius)
self:T(self.lid .. "SetSAMRadius")
local radius = radius or 25000 local radius = radius or 25000
self.checkradius = radius self.checkradius = radius
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. 75
-- @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")
local range = range or 75 local range = range or 75
if range < 0 or range > 100 then if range < 0 or range > 100 then
range = 75 range = 75
end end
self.engagerange = range self.engagerange = range
return self
end 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
function MANTIS:SetNewSAMRangeWhileRunning(range) function MANTIS:SetNewSAMRangeWhileRunning(range)
self:T(self.lid .. "SetNewSAMRangeWhileRunning")
local range = range or 75 local range = range or 75
if range < 0 or range > 100 then if range < 0 or range > 100 then
range = 75 range = 75
@ -381,20 +498,32 @@ do
self.engagerange = range self.engagerange = range
self:_RefreshSAMTable() self:_RefreshSAMTable()
self.mysead.EngagementRange = range self.mysead.EngagementRange = range
return self
end end
--- Function to set switch-on/off the debug state --- Function to set switch-on/off the debug state
-- @param #MANTIS self -- @param #MANTIS self
-- @param #boolean onoff Set true to switch on -- @param #boolean onoff Set true to switch on
function MANTIS:Debug(onoff) function MANTIS:Debug(onoff)
self:T(self.lid .. "SetDebug")
local onoff = onoff or false local onoff = onoff or false
self.debug = onoff self.debug = onoff
if onoff then
-- Debug trace.
BASE:TraceOn()
BASE:TraceClass("MANTIS")
BASE:TraceLevel(1)
else
BASE:TraceOff()
end
return self
end end
--- Function to get the HQ object for further use --- Function to get the HQ object for further use
-- @param #MANTIS self -- @param #MANTIS self
-- @return Wrapper.GROUP#GROUP The HQ #GROUP object or *nil* if it doesn't exist -- @return Wrapper.GROUP#GROUP The HQ #GROUP object or *nil* if it doesn't exist
function MANTIS:GetCommandCenter() function MANTIS:GetCommandCenter()
self:T(self.lid .. "GetCommandCenter")
if self.HQ_CC then if self.HQ_CC then
return self.HQ_CC return self.HQ_CC
else else
@ -406,26 +535,31 @@ do
-- @param #MANTIS self -- @param #MANTIS self
-- @param #string prefix Name of the AWACS group in the mission editor -- @param #string prefix Name of the AWACS group in the mission editor
function MANTIS:SetAwacs(prefix) function MANTIS:SetAwacs(prefix)
self:T(self.lid .. "SetAwacs")
if prefix ~= nil then if prefix ~= nil then
if type(prefix) == "string" then if type(prefix) == "string" then
self.AWACS_Prefix = prefix self.AWACS_Prefix = prefix
self.advAwacs = true self.advAwacs = true
end end
end end
return self
end end
--- Function to set AWACS detection range. Defaults to 250.000m (250km) - use **before** starting your Mantis! --- Function to set AWACS detection range. Defaults to 250.000m (250km) - use **before** starting your Mantis!
-- @param #MANTIS self -- @param #MANTIS self
-- @param #number range Detection range of the AWACS group -- @param #number range Detection range of the AWACS group
function MANTIS:SetAwacsRange(range) function MANTIS:SetAwacsRange(range)
self:T(self.lid .. "SetAwacsRange")
local range = range or 250000 local range = range or 250000
self.awacsrange = range self.awacsrange = range
return self
end end
--- Function to set the HQ object for further use --- Function to set the HQ object for further use
-- @param #MANTIS self -- @param #MANTIS self
-- @param Wrapper.GROUP#GROUP group The #GROUP object to be set as HQ -- @param Wrapper.GROUP#GROUP group The #GROUP object to be set as HQ
function MANTIS:SetCommandCenter(group) function MANTIS:SetCommandCenter(group)
self:T(self.lid .. "SetCommandCenter")
local group = group or nil local group = group or nil
if group ~= nil then if group ~= nil then
if type(group) == "string" then if type(group) == "string" then
@ -436,14 +570,17 @@ do
self.HQ_Template_CC = group:GetName() self.HQ_Template_CC = group:GetName()
end end
end end
return self
end end
--- Function to set the detection interval --- Function to set the detection interval
-- @param #MANTIS self -- @param #MANTIS self
-- @param #number interval The interval in seconds -- @param #number interval The interval in seconds
function MANTIS:SetDetectInterval(interval) function MANTIS:SetDetectInterval(interval)
self:T(self.lid .. "SetDetectInterval")
local interval = interval or 30 local interval = interval or 30
self.detectinterval = interval self.detectinterval = interval
return self
end end
--- Function to set Advanded Mode --- Function to set Advanded Mode
@ -453,7 +590,8 @@ do
-- @usage Advanced mode will *decrease* reactivity of MANTIS, if HQ and/or EWR network dies. Set SAMs to RED state if both are dead. Requires usage of an **HQ** object and the **dynamic** option. -- @usage Advanced mode will *decrease* reactivity of MANTIS, if HQ and/or EWR network dies. Set SAMs to RED state if both are dead. Requires usage of an **HQ** object and the **dynamic** option.
-- E.g. `mymantis:SetAdvancedMode(true, 90)` -- E.g. `mymantis:SetAdvancedMode(true, 90)`
function MANTIS:SetAdvancedMode(onoff, ratio) function MANTIS:SetAdvancedMode(onoff, ratio)
self:F({onoff, ratio}) self:T(self.lid .. "SetAdvancedMode")
self:T({onoff, ratio})
local onoff = onoff or false local onoff = onoff or false
local ratio = ratio or 100 local ratio = ratio or 100
if (type(self.HQ_Template_CC) == "string") and onoff and self.dynamic then if (type(self.HQ_Template_CC) == "string") and onoff and self.dynamic then
@ -461,53 +599,58 @@ do
self.advanced = true self.advanced = true
self.adv_state = 0 self.adv_state = 0
self.Adv_EWR_Group = SET_GROUP:New():FilterPrefixes(self.EWR_Templates_Prefix):FilterCoalitions(self.Coalition):FilterStart() self.Adv_EWR_Group = SET_GROUP:New():FilterPrefixes(self.EWR_Templates_Prefix):FilterCoalitions(self.Coalition):FilterStart()
env.info(string.format("***** Starting Advanced Mode MANTIS Version %s *****", self.version)) self:I(string.format("***** Starting Advanced Mode MANTIS Version %s *****", self.version))
else else
local text = self.lid.." Advanced Mode requires a HQ and dynamic to be set. Revisit your MANTIS:New() statement to add both." local text = self.lid.." Advanced Mode requires a HQ and dynamic to be set. Revisit your MANTIS:New() statement to add both."
local m= MESSAGE:New(text,10,"MANTIS",true):ToAll() local m= MESSAGE:New(text,10,"MANTIS",true):ToAll()
BASE:E(text) self:E(text)
end end
return self
end end
--- Set using Emissions on/off instead of changing alarm state --- Set using Emissions on/off instead of changing alarm state
-- @param #MANTIS self -- @param #MANTIS self
-- @param #boolean switch Decide if we are changing alarm state or Emission state -- @param #boolean switch Decide if we are changing alarm state or Emission state
function MANTIS:SetUsingEmOnOff(switch) function MANTIS:SetUsingEmOnOff(switch)
self:T(self.lid .. "SetUsingEmOnOff")
self.UseEmOnOff = switch or false self.UseEmOnOff = switch or false
return self
end end
--- [Internal] Function to check if HQ is alive --- [Internal] Function to check if HQ is alive
-- @param #MANTIS self -- @param #MANTIS self
-- @return #boolean True if HQ is alive, else false -- @return #boolean True if HQ is alive, else false
function MANTIS:_CheckHQState() function MANTIS:_CheckHQState()
self:T(self.lid .. "CheckHQState")
local text = self.lid.." Checking HQ State" local text = self.lid.." Checking HQ State"
self:T(text)
local m= MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug) local m= MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
if self.verbose then env.info(text) end if self.verbose then self:I(text) end
-- start check -- start check
if self.advanced then if self.advanced then
local hq = self.HQ_Template_CC local hq = self.HQ_Template_CC
local hqgrp = GROUP:FindByName(hq) local hqgrp = GROUP:FindByName(hq)
if hqgrp then if hqgrp then
if hqgrp:IsAlive() then -- ok we're on, hq exists and as alive if hqgrp:IsAlive() then -- ok we're on, hq exists and as alive
env.info(self.lid.." HQ is alive!") self:T(self.lid.." HQ is alive!")
return true return true
else else
env.info(self.lid.." HQ is dead!") self:T(self.lid.." HQ is dead!")
return false return false
end end
end end
end end
return self
end end
--- [Internal] Function to check if EWR is (at least partially) alive --- [Internal] Function to check if EWR is (at least partially) alive
-- @param #MANTIS self -- @param #MANTIS self
-- @return #boolean True if EWR is alive, else false -- @return #boolean True if EWR is alive, else false
function MANTIS:_CheckEWRState() function MANTIS:_CheckEWRState()
self:T(self.lid .. "CheckEWRState")
local text = self.lid.." Checking EWR State" local text = self.lid.." Checking EWR State"
self:F(text) self:T(text)
local m= MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug) local m= MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
if self.verbose then env.info(text) end if self.verbose then self:I(text) end
-- start check -- start check
if self.advanced then if self.advanced then
local EWR_Group = self.Adv_EWR_Group local EWR_Group = self.Adv_EWR_Group
@ -521,24 +664,26 @@ do
end end
end end
end end
env.info(self.lid..string.format(" No of EWR alive is %d", nalive)) self:T(self.lid..string.format(" No of EWR alive is %d", nalive))
if nalive > 0 then if nalive > 0 then
return true return true
else else
return false return false
end end
end end
return self
end end
--- [Internal] Function to determine state of the advanced mode --- [Internal] Function to determine state of the advanced mode
-- @param #MANTIS self -- @param #MANTIS self
-- @return #number Newly calculated interval -- @return #number Newly calculated interval
-- @return #number Previous state for tracking 0, 1, or 2 -- @return #number Previous state for tracking 0, 1, or 2
function MANTIS:_CheckAdvState() function MANTIS:_CalcAdvState()
local text = self.lid.." Checking Advanced State" self:T(self.lid .. "CalcAdvState")
self:F(text) local text = self.lid.." Calculating Advanced State"
self:T(text)
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug) local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
if self.verbose then env.info(text) end if self.verbose then self:I(text) end
-- start check -- start check
local currstate = self.adv_state -- save curr state for comparison later local currstate = self.adv_state -- save curr state for comparison later
local EWR_State = self:_CheckEWRState() local EWR_State = self:_CheckEWRState()
@ -557,9 +702,9 @@ do
ratio = ratio * self.adv_state -- e.g 0.8*2 = 1.6 ratio = ratio * self.adv_state -- e.g 0.8*2 = 1.6
local newinterval = interval + (interval * ratio) -- e.g. 30+(30*1.6) = 78 local newinterval = interval + (interval * ratio) -- e.g. 30+(30*1.6) = 78
local text = self.lid..string.format(" Calculated OldState/NewState/Interval: %d / %d / %d", currstate, self.adv_state, newinterval) local text = self.lid..string.format(" Calculated OldState/NewState/Interval: %d / %d / %d", currstate, self.adv_state, newinterval)
self:F(text) self:T(text)
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug) local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
if self.verbose then env.info(text) end if self.verbose then self:I(text) end
return newinterval, currstate return newinterval, currstate
end end
@ -568,7 +713,8 @@ do
-- @param #boolean hq If true, will relocate HQ object -- @param #boolean hq If true, will relocate HQ object
-- @param #boolean ewr If true, will relocate EWR objects -- @param #boolean ewr If true, will relocate EWR objects
function MANTIS:SetAutoRelocate(hq, ewr) function MANTIS:SetAutoRelocate(hq, ewr)
self:F({hq, ewr}) self:T(self.lid .. "SetAutoRelocate")
self:T({hq, ewr})
local hqrel = hq or false local hqrel = hq or false
local ewrel = ewr or false local ewrel = ewr or false
if hqrel or ewrel then if hqrel or ewrel then
@ -576,22 +722,24 @@ do
self.autorelocateunits = { HQ = hqrel, EWR = ewrel } self.autorelocateunits = { HQ = hqrel, EWR = ewrel }
self:T({self.autorelocate, self.autorelocateunits}) self:T({self.autorelocate, self.autorelocateunits})
end end
return self
end end
--- [Internal] Function to execute the relocation --- [Internal] Function to execute the relocation
-- @param #MANTIS self -- @param #MANTIS self
function MANTIS:_RelocateGroups() function MANTIS:_RelocateGroups()
self:T(self.lid.." Relocating Groups") self:T(self.lid .. "RelocateGroups")
local text = self.lid.." Relocating Groups" local text = self.lid.." Relocating Groups"
local m= MESSAGE:New(text,10,"MANTIS",true):ToAllIf(self.debug) local m= MESSAGE:New(text,10,"MANTIS",true):ToAllIf(self.debug)
if self.verbose then env.info(text) end if self.verbose then self:I(text) end
if self.autorelocate then if self.autorelocate then
-- relocate HQ -- relocate HQ
if self.autorelocateunits.HQ and self.HQ_CC then --only relocate if HQ exists local HQGroup = self.HQ_CC
if self.autorelocateunits.HQ and self.HQ_CC and HQGroup:IsAlive() then --only relocate if HQ exists
local _hqgrp = self.HQ_CC local _hqgrp = self.HQ_CC
self:T(self.lid.." Relocating HQ") self:T(self.lid.." Relocating HQ")
local text = self.lid.." Relocating HQ" local text = self.lid.." Relocating HQ"
local m= MESSAGE:New(text,10,"MANTIS"):ToAll() --local m= MESSAGE:New(text,10,"MANTIS"):ToAll()
_hqgrp:RelocateGroundRandomInRadius(20,500,true,true) _hqgrp:RelocateGroundRandomInRadius(20,500,true,true)
end end
--relocate EWR --relocate EWR
@ -601,26 +749,27 @@ do
local EWR_GRP = SET_GROUP:New():FilterPrefixes(self.EWR_Templates_Prefix):FilterCoalitions(self.Coalition):FilterOnce() local EWR_GRP = SET_GROUP:New():FilterPrefixes(self.EWR_Templates_Prefix):FilterCoalitions(self.Coalition):FilterOnce()
local EWR_Grps = EWR_GRP.Set --table of objects in SET_GROUP local EWR_Grps = EWR_GRP.Set --table of objects in SET_GROUP
for _,_grp in pairs (EWR_Grps) do for _,_grp in pairs (EWR_Grps) do
if _grp:IsGround() then if _grp:IsAlive() and _grp:IsGround() then
self:T(self.lid.." Relocating EWR ".._grp:GetName()) self:T(self.lid.." Relocating EWR ".._grp:GetName())
local text = self.lid.." Relocating EWR ".._grp:GetName() local text = self.lid.." Relocating EWR ".._grp:GetName()
local m= MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug) local m= MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
if self.verbose then env.info(text) end if self.verbose then self:I(text) end
_grp:RelocateGroundRandomInRadius(20,500,true,true) _grp:RelocateGroundRandomInRadius(20,500,true,true)
end end
end end
end end
end end
return self
end 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 samcoordinate Core.Point#COORDINATE Coordinate object. -- @param Core.Point#COORDINATE samcoordinate Coordinate object.
-- @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)
self:F(self.lid.."CheckObjectInZone Called") 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 radius = self.checkradius
local set = dectset local set = dectset
@ -632,7 +781,7 @@ do
local targetdistance = samcoordinate:DistanceFromPointVec2(coord) local targetdistance = samcoordinate:DistanceFromPointVec2(coord)
local text = string.format("Checking SAM at % s - Distance %d m - Target %s", samstring, targetdistance, dectstring) local text = string.format("Checking SAM at % s - Distance %d m - Target %s", samstring, targetdistance, dectstring)
local m = MESSAGE:New(text,10,"Check"):ToAllIf(self.debug) local m = MESSAGE:New(text,10,"Check"):ToAllIf(self.debug)
if self.verbose then env.info(self.lid..text) end if self.verbose then self:I(self.lid..text) end
-- end output to cross-check -- end output to cross-check
if targetdistance <= radius then if targetdistance <= radius then
return true, targetdistance return true, targetdistance
@ -641,11 +790,11 @@ do
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
-- @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()
self:F(self.lid.."Starting Detection") self:T(self.lid.."Starting Detection")
-- start detection -- start detection
local groupset = self.EWR_Group local groupset = self.EWR_Group
@ -653,14 +802,14 @@ do
local acceptrange = self.acceptrange or 80000 local acceptrange = self.acceptrange or 80000
local interval = self.detectinterval or 60 local interval = self.detectinterval or 60
--@param Functional.Detection #DETECTION_AREAS _MANTISdetection [internal] The MANTIS detection object --@param Functional.Detection #DETECTION_AREAS _MANTISdetection [Internal] The MANTIS detection object
_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)
_MANTISdetection:SetRefreshTimeInterval(interval) MANTISdetection:SetRefreshTimeInterval(interval)
_MANTISdetection:Start() MANTISdetection:Start()
function _MANTISdetection:OnAfterDetectedItem(From,Event,To,DetectedItem) function MANTISdetection:OnAfterDetectedItem(From,Event,To,DetectedItem)
--BASE:I( { From, Event, To, DetectedItem }) --BASE:I( { From, Event, To, DetectedItem })
local debug = false local debug = false
if DetectedItem.IsDetected and debug then if DetectedItem.IsDetected and debug then
@ -669,14 +818,14 @@ do
local m = MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug) local m = MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
end end
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 via AWACS if defined as separate
-- @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()
self:F(self.lid.."Starting Awacs Detection") self:T(self.lid.."Starting Awacs Detection")
-- start detection -- start detection
local group = self.AWACS_Prefix local group = self.AWACS_Prefix
@ -685,14 +834,14 @@ do
--local acceptrange = self.acceptrange or 80000 --local acceptrange = self.acceptrange or 80000
local interval = self.detectinterval or 60 local interval = self.detectinterval or 60
--@param Functional.Detection #DETECTION_AREAS _MANTISdetection [internal] The MANTIS detection object --@param Functional.Detection #DETECTION_AREAS _MANTISdetection [Internal] The MANTIS detection object
_MANTISAwacs = DETECTION_AREAS:New( groupset, grouping ) --[internal] Grouping detected objects to 5000m zones local MANTISAwacs = DETECTION_AREAS:New( groupset, grouping ) --[Internal] Grouping detected objects to 5000m zones
_MANTISAwacs:FilterCategories({ Unit.Category.AIRPLANE, Unit.Category.HELICOPTER }) MANTISAwacs:FilterCategories({ Unit.Category.AIRPLANE, Unit.Category.HELICOPTER })
_MANTISAwacs:SetAcceptRange(self.awacsrange) --250km MANTISAwacs:SetAcceptRange(self.awacsrange) --250km
_MANTISAwacs:SetRefreshTimeInterval(interval) MANTISAwacs:SetRefreshTimeInterval(interval)
_MANTISAwacs:Start() MANTISAwacs:Start()
function _MANTISAwacs:OnAfterDetectedItem(From,Event,To,DetectedItem) function MANTISAwacs:OnAfterDetectedItem(From,Event,To,DetectedItem)
--BASE:I( { From, Event, To, DetectedItem }) --BASE:I( { From, Event, To, DetectedItem })
local debug = false local debug = false
if DetectedItem.IsDetected and debug then if DetectedItem.IsDetected and debug then
@ -701,15 +850,15 @@ do
local m = MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug) local m = MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
end end
end end
return _MANTISAwacs return MANTISAwacs
end 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
self:F(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
@ -742,11 +891,11 @@ do
return self return self
end end
--- (Internal) Function to update SAM table and SEAD state --- [Internal] Function to update SAM table and SEAD state
-- @param #MANTIS self -- @param #MANTIS self
-- @return #MANTIS self -- @return #MANTIS self
function MANTIS:_RefreshSAMTable() function MANTIS:_RefreshSAMTable()
self:F(self.lid.."Setting SAM Start States") self:T(self.lid.."RefreshSAMTable")
-- Requires SEAD 0.2.2 or better -- Requires SEAD 0.2.2 or better
-- get SAM Group -- get SAM Group
local SAM_SET = self.SAM_Group local SAM_SET = self.SAM_Group
@ -779,6 +928,7 @@ do
-- @param Functional.Shorad#SHORAD Shorad The #SHORAD object -- @param Functional.Shorad#SHORAD Shorad The #SHORAD object
-- @param #number Shoradtime Number of seconds #SHORAD stays active post wake-up -- @param #number Shoradtime Number of seconds #SHORAD stays active post wake-up
function MANTIS:AddShorad(Shorad,Shoradtime) function MANTIS:AddShorad(Shorad,Shoradtime)
self:T(self.lid.."AddShorad")
local Shorad = Shorad or nil local Shorad = Shorad or nil
local ShoradTime = Shoradtime or 600 local ShoradTime = Shoradtime or 600
local ShoradLink = true local ShoradLink = true
@ -787,33 +937,30 @@ do
self.Shorad = Shorad --#SHORAD self.Shorad = Shorad --#SHORAD
self.ShoradTime = Shoradtime -- #number self.ShoradTime = Shoradtime -- #number
end end
return self
end end
--- Function to unlink #MANTIS from a #SHORAD installation --- Function to unlink #MANTIS from a #SHORAD installation
-- @param #MANTIS self -- @param #MANTIS self
function MANTIS:RemoveShorad() function MANTIS:RemoveShorad()
self:T(self.lid.."RemoveShorad")
self.ShoradLink = false self.ShoradLink = false
return self
end end
----------------------------------------------------------------------- -----------------------------------------------------------------------
-- MANTIS main functions -- MANTIS main functions
----------------------------------------------------------------------- -----------------------------------------------------------------------
--- Function to set the SAM start state --- [Internal] Check detection function
-- @param #MANTIS self -- @param #MANTIS self
-- @param Functional.Detection#DETECTION_AREAS detection Detection object
-- @return #MANTIS self -- @return #MANTIS self
function MANTIS:Start() function MANTIS:_Check(detection)
self:F(self.lid.."Starting MANTIS") self:T(self.lid .. "Check")
self:SetSAMStartState()
self.Detection = self:StartDetection()
if self.advAwacs then
self.AWACS_Detection = self:StartAwacsDetection()
end
-- detection function
local function check(detection)
--get detected set --get detected set
local detset = detection:GetDetectedItemCoordinates() local detset = detection:GetDetectedItemCoordinates()
self:F("Check:", {detset}) self:T("Check:", {detset})
-- randomly update SAM Table -- randomly update SAM Table
local rand = math.random(1,100) local rand = math.random(1,100)
if rand > 65 then -- 1/3 of cases if rand > 65 then -- 1/3 of cases
@ -835,6 +982,7 @@ do
samgroup:EnableEmission(true) samgroup:EnableEmission(true)
end end
samgroup:OptionAlarmStateRed() samgroup:OptionAlarmStateRed()
self:__RedState(1,samgroup)
-- link in to SHORAD if available -- link in to SHORAD if available
-- DONE: Test integration fully -- DONE: Test integration fully
if self.ShoradLink and Distance < self.ShoradActDistance then -- don't give SHORAD position away too early if self.ShoradLink and Distance < self.ShoradActDistance then -- don't give SHORAD position away too early
@ -842,11 +990,12 @@ do
local radius = self.checkradius local radius = self.checkradius
local ontime = self.ShoradTime local ontime = self.ShoradTime
Shorad:WakeUpShorad(name, radius, ontime) Shorad:WakeUpShorad(name, radius, ontime)
self:__ShoradActivated(1,name, radius, ontime)
end end
-- debug output -- debug output
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 env.info(self.lid..text) end if self.verbose then self:I(self.lid..text) end
end --end alive end --end alive
else else
if samgroup:IsAlive() then if samgroup:IsAlive() then
@ -854,39 +1003,45 @@ do
if self.UseEmOnOff then if self.UseEmOnOff then
-- TODO: add emissions on/off -- TODO: add emissions on/off
samgroup:EnableEmission(false) samgroup:EnableEmission(false)
self:__GreenState(1,samgroup)
--samgroup:SetAIOff() --samgroup:SetAIOff()
else else
samgroup:OptionAlarmStateGreen() samgroup:OptionAlarmStateGreen()
self:__GreenState(1,samgroup)
end end
--samgroup:OptionROEWeaponFree() --samgroup:OptionROEWeaponFree()
--samgroup:SetAIOn() --samgroup:SetAIOn()
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 env.info(self.lid..text) end if self.verbose then self:I(self.lid..text) end
end --end alive end --end alive
end --end check end --end check
end --for for loop end --for for loop
end --end function return self
-- relocation relay function
local function relocate()
self:_RelocateGroups()
end end
-- check advanced state
local function checkadvstate() --- [Internal] Relocation relay function
local interval, oldstate = self:_CheckAdvState() -- @param #MANTIS self
-- @return #MANTIS self
function MANTIS:_Relocate()
self:T(self.lid .. "Relocate")
self:_RelocateGroups()
return self
end
--- [Internal] Check advanced state
-- @param #MANTIS self
-- @return #MANTIS self
function MANTIS:_CheckAdvState()
self:T(self.lid .. "CheckAdvSate")
local interval, oldstate = self:_CalcAdvState()
local newstate = self.adv_state local newstate = self.adv_state
if newstate ~= oldstate then if newstate ~= oldstate then
-- deal with new state -- deal with new state
self:__AdvStateChange(1,oldstate,newstate,interval)
if newstate == 2 then if newstate == 2 then
-- switch alarm state RED -- switch alarm state RED
if self.MantisTimer.isrunning then self.state2flag = true
self.MantisTimer:Stop()
self.MantisTimer.isrunning = false
end -- stop Awacs timer
if self.MantisATimer.isrunning then
self.MantisATimer:Stop()
self.MantisATimer.isrunning = false
end -- stop timer
local samset = self:_GetSAMTable() -- table of i.1=names, i.2=coordinates 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 name = _data[1] local name = _data[1]
@ -902,69 +1057,159 @@ do
end -- end for loop end -- end for loop
elseif newstate <= 1 then elseif newstate <= 1 then
-- change MantisTimer to slow down or speed up -- change MantisTimer to slow down or speed up
if self.MantisTimer.isrunning then self.detectinterval = interval
self.MantisTimer:Stop() self.state2flag = false
self.MantisTimer.isrunning = false
end
if self.MantisATimer.isrunning then
self.MantisATimer:Stop()
self.MantisATimer.isrunning = false
end
self.MantisTimer = TIMER:New(check,self.Detection)
self.MantisTimer:Start(5,interval,nil)
self.MantisTimer.isrunning = true
if self.advAwacs then
self.MantisATimer = TIMER:New(check,self.AWACS_Detection)
self.MantisATimer:Start(15,interval,nil)
self.MantisATimer.isrunning = true
end
end end
end -- end newstate vs oldstate end -- end newstate vs oldstate
return self
end end
-- timers to run the system
local interval = self.detectinterval --- [Internal] Function to set start state
self.MantisTimer = TIMER:New(check,self.Detection) -- @param #MANTIS self
self.MantisTimer:Start(5,interval,nil) -- @param #string From The From State
self.MantisTimer.isrunning = true -- @param #string Event The Event
-- Awacs timer -- @param #string To The To State
-- @return #MANTIS self
function MANTIS:onafterStart(From, Event, To)
self:T({From, Event, To})
self:T(self.lid.."Starting MANTIS")
self:SetSAMStartState()
self.Detection = self:StartDetection()
if self.advAwacs then if self.advAwacs then
self.MantisATimer = TIMER:New(check,self.AWACS_Detection) self.AWACS_Detection = self:StartAwacsDetection()
self.MantisATimer:Start(15,interval,nil)
self.MantisATimer.isrunning = true
end end
-- timer to relocate HQ and EWR self:__Status(self.detectinterval)
return self
end
--- [Internal] Before status function for MANTIS
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @return #MANTIS self
function MANTIS:onbeforeStatus(From, Event, To)
self:T({From, Event, To})
-- check detection
if not self.state2flag then
self:_Check(self.Detection)
end
-- check Awacs
if self.advAwacs and not self.state2flag then
self:_Check(self.AWACS_Detection)
end
-- relocate HQ and EWR
if self.autorelocate then if self.autorelocate then
local relointerval = math.random(1800,3600) -- random between 30 and 60 mins local relointerval = self.relointerval
self.MantisReloTimer = TIMER:New(relocate) local thistime = timer.getAbsTime()
self.MantisReloTimer:Start(relointerval,relointerval,nil) local timepassed = thistime - self.TimeStamp
local halfintv = math.floor(timepassed / relointerval)
--self:T({timepassed=timepassed, halfintv=halfintv})
if halfintv >= 1 then
self.TimeStamp = timer.getAbsTime()
self:_Relocate()
self:__Relocating(1)
end end
end
-- timer for advanced state check -- timer for advanced state check
if self.advanced then if self.advanced then
self.MantisAdvTimer = TIMER:New(checkadvstate) self:_CheckAdvState()
self.MantisAdvTimer:Start(30,interval*5,nil)
end end
return self return self
end end
--- Function to stop MANTIS --- [Internal] Status function for MANTIS
-- @param #MANTIS self -- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @return #MANTIS self -- @return #MANTIS self
function MANTIS:Stop() function MANTIS:onafterStatus(From,Event,To)
if self.MantisTimer.isrunning then self:T({From, Event, To})
self.MantisTimer:Stop() local interval = self.detectinterval * -1
end self:__Status(interval)
if self.MantisATimer.isrunning then
self.MantisATimer:Stop()
end
if self.autorelocate then
self.MantisReloTimer:Stop()
end
if self.advanced then
self.MantisAdvTimer:Stop()
end
return self return self
end end
--- [Internal] Function to stop MANTIS
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @return #MANTIS self
function MANTIS:onafterStop(From, Event, To)
self:T({From, Event, To})
return self
end
--- [Internal] Function triggered by Event Relocating
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @return #MANTIS self
function MANTIS:onafterRelocating(From, Event, To)
self:T({From, Event, To})
return self
end
--- [Internal] Function triggered by Event GreenState
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param Wrapper.Group#GROUP Group The GROUP object whose state was changed
-- @return #MANTIS self
function MANTIS:onafterGreenState(From, Event, To, Group)
self:T({From, Event, To, Group})
return self
end
--- [Internal] Function triggered by Event RedState
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param Wrapper.Group#GROUP Group The GROUP object whose state was changed
-- @return #MANTIS self
function MANTIS:onafterRedState(From, Event, To, Group)
self:T({From, Event, To, Group})
return self
end
--- [Internal] Function triggered by Event AdvStateChange
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param #number Oldstate Old state - 0 = green, 1 = amber, 2 = red
-- @param #number Newstate New state - 0 = green, 1 = amber, 2 = red
-- @param #number Interval Calculated detection interval based on state and advanced feature setting
-- @return #MANTIS self
function MANTIS:onafterAdvStateChange(From, Event, To, Oldstate, Newstate, Interval)
self:T({From, Event, To, Oldstate, Newstate, Interval})
return self
end
--- [Internal] Function triggered by Event ShoradActivated
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param #string Name Name of the GROUP which SHORAD shall protect
-- @param #number Radius Radius around the named group to find SHORAD groups
-- @param #number Ontime Seconds the SHORAD will stay active
function MANTIS:onafterShoradActivated(From, Event, To, Name, Radius, Ontime)
self:T({From, Event, To, Name, Radius, Ontime})
return self
end
end end
----------------------------------------------------------------------- -----------------------------------------------------------------------
-- MANTIS end -- MANTIS end

View File

@ -662,7 +662,9 @@ end
-- @param #string _description (optional) Description. -- @param #string _description (optional) Description.
-- @param #boolean _randomPoint (optional) Random yes or no. -- @param #boolean _randomPoint (optional) Random yes or no.
-- @param #boolean _nomessage (optional) If true, don\'t send a message to SAR. -- @param #boolean _nomessage (optional) If true, don\'t send a message to SAR.
function CSAR:_SpawnCsarAtZone( _zone, _coalition, _description, _randomPoint, _nomessage) -- @param #string unitname (optional) Name of the lost unit.
-- @param #string typename (optional) Type of plane.
function CSAR:_SpawnCsarAtZone( _zone, _coalition, _description, _randomPoint, _nomessage, unitname, typename)
self:T(self.lid .. " _SpawnCsarAtZone") self:T(self.lid .. " _SpawnCsarAtZone")
local freq = self:_GenerateADFFrequency() local freq = self:_GenerateADFFrequency()
local _triggerZone = ZONE:New(_zone) -- trigger to use as reference position local _triggerZone = ZONE:New(_zone) -- trigger to use as reference position
@ -671,7 +673,9 @@ function CSAR:_SpawnCsarAtZone( _zone, _coalition, _description, _randomPoint, _
return return
end end
local _description = _description or "Unknown" local _description = _description or "PoW"
local unitname = unitname or "Old Rusty"
local typename = typename or "Phantom II"
local pos = {} local pos = {}
if _randomPoint then if _randomPoint then
@ -690,7 +694,7 @@ function CSAR:_SpawnCsarAtZone( _zone, _coalition, _description, _randomPoint, _
_country = country.id.UN_PEACEKEEPERS _country = country.id.UN_PEACEKEEPERS
end end
self:_AddCsar(_coalition, _country, pos, "PoW", _description, nil, freq, _nomessage, _description) self:_AddCsar(_coalition, _country, pos, typename, unitname, _description, freq, _nomessage, _description)
return self return self
end end
@ -702,12 +706,14 @@ end
-- @param #string Description (optional) Description. -- @param #string Description (optional) Description.
-- @param #boolean RandomPoint (optional) Random yes or no. -- @param #boolean RandomPoint (optional) Random yes or no.
-- @param #boolean Nomessage (optional) If true, don\'t send a message to SAR. -- @param #boolean Nomessage (optional) If true, don\'t send a message to SAR.
-- @param #string unitname (optional) Name of the lost unit.
-- @param #string typename (optional) Type of plane.
-- @usage If missions designers want to spawn downed pilots into the field, e.g. at mission begin, to give the helicopter guys works, they can do this like so: -- @usage If missions designers want to spawn downed pilots into the field, e.g. at mission begin, to give the helicopter guys works, they can do this like so:
-- --
-- -- Create downed "Pilot Wagner" in #ZONE "CSAR_Start_1" at a random point for the blue coalition -- -- Create downed "Pilot Wagner" in #ZONE "CSAR_Start_1" at a random point for the blue coalition
-- my_csar:SpawnCSARAtZone( "CSAR_Start_1", coalition.side.BLUE, "Pilot Wagner", true ) -- my_csar:SpawnCSARAtZone( "CSAR_Start_1", coalition.side.BLUE, "Wagner", true, false, "Charly-1-1", "F5E" )
function CSAR:SpawnCSARAtZone(Zone, Coalition, Description, RandomPoint, Nomessage) function CSAR:SpawnCSARAtZone(Zone, Coalition, Description, RandomPoint, Nomessage, Unitname, Typename)
self:_SpawnCsarAtZone(Zone, Coalition, Description, RandomPoint, Nomessage) self:_SpawnCsarAtZone(Zone, Coalition, Description, RandomPoint, Nomessage, Unitname, Typename)
return self return self
end end
@ -1199,7 +1205,7 @@ function CSAR:_CheckCloseWoundedGroup(_distance, _heliUnit, _heliName, _woundedG
end end
if _time <= 0 or _distance < self.loadDistance then if _time <= 0 or _distance < self.loadDistance then
if self.pilotmustopendoors and not self:_IsLoadingDoorOpen(_heliName) then if self.pilotmustopendoors and not self:_IsLoadingDoorOpen(_heliName) then
self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me in, bugger!", self.messageTime, true) self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me in!", self.messageTime, true)
return true return true
else else
self.landedStatus[_lookupKeyHeli] = nil self.landedStatus[_lookupKeyHeli] = nil
@ -1211,7 +1217,7 @@ function CSAR:_CheckCloseWoundedGroup(_distance, _heliUnit, _heliName, _woundedG
else else
if (_distance < self.loadDistance) then if (_distance < self.loadDistance) then
if self.pilotmustopendoors and not self:_IsLoadingDoorOpen(_heliName) then if self.pilotmustopendoors and not self:_IsLoadingDoorOpen(_heliName) then
self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me in, honk!", self.messageTime, true) self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me in!", self.messageTime, true)
return true return true
else else
self:_PickupUnit(_heliUnit, _pilotName, _woundedGroup, _woundedGroupName) self:_PickupUnit(_heliUnit, _pilotName, _woundedGroup, _woundedGroupName)
@ -1252,7 +1258,7 @@ function CSAR:_CheckCloseWoundedGroup(_distance, _heliUnit, _heliName, _woundedG
self:_DisplayMessageToSAR(_heliUnit, "Hovering above " .. _pilotName .. ". \n\nHold hover for " .. _time .. " seconds to winch them up. \n\nIf the countdown stops you\'re too far away!", self.messageTime, true) self:_DisplayMessageToSAR(_heliUnit, "Hovering above " .. _pilotName .. ". \n\nHold hover for " .. _time .. " seconds to winch them up. \n\nIf the countdown stops you\'re too far away!", self.messageTime, true)
else else
if self.pilotmustopendoors and not self:_IsLoadingDoorOpen(_heliName) then if self.pilotmustopendoors and not self:_IsLoadingDoorOpen(_heliName) then
self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me in, noob!", self.messageTime, true) self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me in!", self.messageTime, true)
return true return true
else else
self.hoverStatus[_lookupKeyHeli] = nil self.hoverStatus[_lookupKeyHeli] = nil

View File

@ -410,6 +410,7 @@ do
-- my_ctld.enableHercules = true -- my_ctld.enableHercules = true
-- my_ctld.HercMinAngels = 155 -- for troop/cargo drop via chute in meters, ca 470 ft -- my_ctld.HercMinAngels = 155 -- for troop/cargo drop via chute in meters, ca 470 ft
-- my_ctld.HercMaxAngels = 2000 -- for troop/cargo drop via chute in meters, ca 6000 ft -- my_ctld.HercMaxAngels = 2000 -- for troop/cargo drop via chute in meters, ca 6000 ft
-- my_ctld.HercMaxSpeed = 77 -- 77mps or 270 kph or 150 kn
-- --
-- Also, the following options need to be set to `true`: -- Also, the following options need to be set to `true`:
-- --
@ -478,7 +479,7 @@ CTLD = {
-- @field #table vhfbeacon Beacon info as #CTLD.ZoneBeacon -- @field #table vhfbeacon Beacon info as #CTLD.ZoneBeacon
--- Zone Type Info. --- Zone Type Info.
-- @type CTLD. -- @type CTLD.CargoZoneType
CTLD.CargoZoneType = { CTLD.CargoZoneType = {
LOAD = "load", LOAD = "load",
DROP = "drop", DROP = "drop",
@ -651,6 +652,7 @@ function CTLD:New(Coalition, Prefixes, Alias)
self.enableHercules = false self.enableHercules = false
self.HercMinAngels = 165 -- for troop/cargo drop via chute self.HercMinAngels = 165 -- for troop/cargo drop via chute
self.HercMaxAngels = 2000 -- for troop/cargo drop via chute self.HercMaxAngels = 2000 -- for troop/cargo drop via chute
self.HercMaxSpeed = 77 -- 280 kph or 150kn eq 77 mps
-- message suppression -- message suppression
self.suppressmessages = false self.suppressmessages = false
@ -2283,10 +2285,12 @@ end
local aheight = uheight - gheight -- height above ground local aheight = uheight - gheight -- height above ground
local maxh = self.HercMinAngels-- 1500m local maxh = self.HercMinAngels-- 1500m
local minh = self.HercMaxAngels -- 5000m local minh = self.HercMaxAngels -- 5000m
local mspeed = 2 -- 2 m/s local maxspeed = self.HercMaxSpeed -- 77 mps
-- TODO:Add speed test for Herc, should not be above 280kph/150kn -- TODO: TEST - Speed test for Herc, should not be above 280kph/150kn
--self:Tstring.format("%s Unit parameters: at %dm AGL with %dmps",self.lid,aheight,uspeed)) local kmspeed = uspeed * 3.6
if (aheight <= maxh) and (aheight >= minh) then local knspeed = kmspeed / 1.86
self:T(string.format("%s Unit parameters: at %dm AGL with %dmps | %dkph | %dkn",self.lid,aheight,uspeed,kmspeed,knspeed))
if (aheight <= maxh) and (aheight >= minh) and (uspeed <= maxspeed) then
-- yep within parameters -- yep within parameters
outcome = true outcome = true
end end
@ -2302,7 +2306,14 @@ end
local inhover = self:IsCorrectHover(Unit) local inhover = self:IsCorrectHover(Unit)
local htxt = "true" local htxt = "true"
if not inhover then htxt = "false" end if not inhover then htxt = "false" end
local text = string.format("Hover parameters (autoload/drop):\n - Min height %dm \n - Max height %dm \n - Max speed 2mps \n - In parameter: %s", self.minimumHoverHeight, self.maximumHoverHeight, htxt) local text = ""
if _SETTINGS:IsMetric() then
text = string.format("Hover parameters (autoload/drop):\n - Min height %dm \n - Max height %dm \n - Max speed 2mps \n - In parameter: %s", self.minimumHoverHeight, self.maximumHoverHeight, htxt)
else
local minheight = UTILS.MetersToFeet(self.minimumHoverHeight)
local maxheight = UTILS.MetersToFeet(self.maximumHoverHeight)
text = string.format("Hover parameters (autoload/drop):\n - Min height %dm \n - Max height %dm \n - Max speed 6fts \n - In parameter: %s", minheight, maxheight, htxt)
end
self:_SendMessage(text, 10, false, Group) self:_SendMessage(text, 10, false, Group)
--local m = MESSAGE:New(text,10,"CTLD",false):ToGroup(Group) --local m = MESSAGE:New(text,10,"CTLD",false):ToGroup(Group)
return self return self
@ -2316,9 +2327,16 @@ end
local inhover = self:IsCorrectFlightParameters(Unit) local inhover = self:IsCorrectFlightParameters(Unit)
local htxt = "true" local htxt = "true"
if not inhover then htxt = "false" end if not inhover then htxt = "false" end
local text = ""
if _SETTINGS:IsImperial() then
local minheight = UTILS.MetersToFeet(self.HercMinAngels) local minheight = UTILS.MetersToFeet(self.HercMinAngels)
local maxheight = UTILS.MetersToFeet(self.HercMaxAngels) local maxheight = UTILS.MetersToFeet(self.HercMaxAngels)
local text = string.format("Flight parameters (airdrop):\n - Min height %dft \n - Max height %dft \n - In parameter: %s", minheight, maxheight, htxt) text = string.format("Flight parameters (airdrop):\n - Min height %dft \n - Max height %dft \n - In parameter: %s", minheight, maxheight, htxt)
else
local minheight = self.HercMinAngels
local maxheight = self.HercMaxAngels
text = string.format("Flight parameters (airdrop):\n - Min height %dm \n - Max height %dm \n - In parameter: %s", minheight, maxheight, htxt)
end
self:_SendMessage(text, 10, false, Group) self:_SendMessage(text, 10, false, Group)
--local m = MESSAGE:New(text,15,"CTLD",false):ToGroup(Group) --local m = MESSAGE:New(text,15,"CTLD",false):ToGroup(Group)
return self return self