MOOSE/Moose Development/Moose/Tasking/DetectionManager.lua
Thomas 946a1de931
Merge docu changes (#1818)
* Documentation fixes. (#1810)

Fix documentation references.
Correct spelling errors.
Remove empty whitespaces.
Correct a single mis-spelled ZONE_BASE variable, see 'Core/Zone.lua' (variable "Sureface" -> "Surface", no references to mis-spelled "Sureface" throughout the codebase).
Correct mis-spelling of "coaltion" in 'Functional/Mantis.lua', corrected to "coalition".

* Documentation fixes. (#1811)

Update documentation text and links.
Fix spelling errors.
Other minor adjustments where appropriate, such as remove whitespaces and format code.

* Documentation fixes. (#1815)

Minor documentation and code formatting fixes.
This is mostly intended to have something re-trigger the documentation generation to see if the filename capitalization is resolved.

* Code formatting preparation. (#1817)

Use EmmyLuaCodeStyle that comes with "Lua" VS Code extension (https://marketplace.visualstudio.com/items?itemName=sumneko.lua). More features and configurability than LuaFormatter, and no need for additional extension (beyond "Lua").
Formatting file set up from default template with some tweaks to correspond to most common coding style observed in the code base. Further tweaks are likely required.

* Documentation fixes. (#1816)

Co-authored-by: TommyC81 <tommyc81@gmail.com>
2022-10-29 10:49:18 +02:00

398 lines
14 KiB
Lua

--- **Tasking** - This module contains the DETECTION_MANAGER class and derived classes.
--
-- ===
--
-- The @{#DETECTION_MANAGER} class defines the core functions to report detected objects to groups.
-- Reportings can be done in several manners, and it is up to the derived classes if DETECTION_MANAGER to model the reporting behaviour.
--
-- 1.1) DETECTION_MANAGER constructor:
-- -----------------------------------
-- * @{#DETECTION_MANAGER.New}(): Create a new DETECTION_MANAGER instance.
--
-- 1.2) DETECTION_MANAGER reporting:
-- ---------------------------------
-- Derived DETECTION_MANAGER classes will reports detected units using the method @{#DETECTION_MANAGER.ReportDetected}(). This method implements polymorphic behaviour.
--
-- The time interval in seconds of the reporting can be changed using the methods @{#DETECTION_MANAGER.SetRefreshTimeInterval}().
-- To control how long a reporting message is displayed, use @{#DETECTION_MANAGER.SetReportDisplayTime}().
-- Derived classes need to implement the method @{#DETECTION_MANAGER.GetReportDisplayTime}() to use the correct display time for displayed messages during a report.
--
-- Reporting can be started and stopped using the methods @{#DETECTION_MANAGER.StartReporting}() and @{#DETECTION_MANAGER.StopReporting}() respectively.
-- If an ad-hoc report is requested, use the method @{#DETECTION_MANAGER#ReportNow}().
--
-- The default reporting interval is every 60 seconds. The reporting messages are displayed 15 seconds.
--
-- ===
--
-- 2) @{#DETECTION_REPORTING} class, extends @{#DETECTION_MANAGER}
-- ===
-- The @{#DETECTION_REPORTING} class implements detected units reporting. Reporting can be controlled using the reporting methods available in the @{Tasking.DetectionManager#DETECTION_MANAGER} class.
--
-- 2.1) DETECTION_REPORTING constructor:
-- -------------------------------
-- The @{#DETECTION_REPORTING.New}() method creates a new DETECTION_REPORTING instance.
--
--
-- ===
--
-- ### Contributions: Mechanist, Prof_Hilactic, FlightControl - Concept & Testing
-- ### Author: FlightControl - Framework Design & Programming
--
-- @module Tasking.DetectionManager
-- @image Task_Detection_Manager.JPG
do -- DETECTION MANAGER
--- @type DETECTION_MANAGER
-- @field Core.Set#SET_GROUP SetGroup The groups to which the FAC will report to.
-- @field Functional.Detection#DETECTION_BASE Detection The DETECTION_BASE object that is used to report the detected objects.
-- @field Tasking.CommandCenter#COMMANDCENTER CC The command center that is used to communicate with the players.
-- @extends Core.Fsm#FSM
--- DETECTION_MANAGER class.
-- @field #DETECTION_MANAGER
DETECTION_MANAGER = {
ClassName = "DETECTION_MANAGER",
SetGroup = nil,
Detection = nil,
}
--- @field Tasking.CommandCenter#COMMANDCENTER
DETECTION_MANAGER.CC = nil
--- FAC constructor.
-- @param #DETECTION_MANAGER self
-- @param Core.Set#SET_GROUP SetGroup
-- @param Functional.Detection#DETECTION_BASE Detection
-- @return #DETECTION_MANAGER self
function DETECTION_MANAGER:New( SetGroup, Detection )
-- Inherits from BASE
local self = BASE:Inherit( self, FSM:New() ) -- #DETECTION_MANAGER
self.SetGroup = SetGroup
self.Detection = Detection
self:SetStartState( "Stopped" )
self:AddTransition( "Stopped", "Start", "Started" )
--- Start Handler OnBefore for DETECTION_MANAGER
-- @function [parent=#DETECTION_MANAGER] OnBeforeStart
-- @param #DETECTION_MANAGER self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #boolean
--- Start Handler OnAfter for DETECTION_MANAGER
-- @function [parent=#DETECTION_MANAGER] OnAfterStart
-- @param #DETECTION_MANAGER self
-- @param #string From
-- @param #string Event
-- @param #string To
--- Start Trigger for DETECTION_MANAGER
-- @function [parent=#DETECTION_MANAGER] Start
-- @param #DETECTION_MANAGER self
--- Start Asynchronous Trigger for DETECTION_MANAGER
-- @function [parent=#DETECTION_MANAGER] __Start
-- @param #DETECTION_MANAGER self
-- @param #number Delay
self:AddTransition( "Started", "Stop", "Stopped" )
--- Stop Handler OnBefore for DETECTION_MANAGER
-- @function [parent=#DETECTION_MANAGER] OnBeforeStop
-- @param #DETECTION_MANAGER self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #boolean
--- Stop Handler OnAfter for DETECTION_MANAGER
-- @function [parent=#DETECTION_MANAGER] OnAfterStop
-- @param #DETECTION_MANAGER self
-- @param #string From
-- @param #string Event
-- @param #string To
--- Stop Trigger for DETECTION_MANAGER
-- @function [parent=#DETECTION_MANAGER] Stop
-- @param #DETECTION_MANAGER self
--- Stop Asynchronous Trigger for DETECTION_MANAGER
-- @function [parent=#DETECTION_MANAGER] __Stop
-- @param #DETECTION_MANAGER self
-- @param #number Delay
self:AddTransition( "Started", "Success", "Started" )
--- Success Handler OnAfter for DETECTION_MANAGER
-- @function [parent=#DETECTION_MANAGER] OnAfterSuccess
-- @param #DETECTION_MANAGER self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @param Tasking.Task#TASK Task
self:AddTransition( "Started", "Failed", "Started" )
--- Failed Handler OnAfter for DETECTION_MANAGER
-- @function [parent=#DETECTION_MANAGER] OnAfterFailed
-- @param #DETECTION_MANAGER self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @param Tasking.Task#TASK Task
self:AddTransition( "Started", "Aborted", "Started" )
--- Aborted Handler OnAfter for DETECTION_MANAGER
-- @function [parent=#DETECTION_MANAGER] OnAfterAborted
-- @param #DETECTION_MANAGER self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @param Tasking.Task#TASK Task
self:AddTransition( "Started", "Cancelled", "Started" )
--- Cancelled Handler OnAfter for DETECTION_MANAGER
-- @function [parent=#DETECTION_MANAGER] OnAfterCancelled
-- @param #DETECTION_MANAGER self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @param Tasking.Task#TASK Task
self:AddTransition( "Started", "Report", "Started" )
self:SetRefreshTimeInterval( 30 )
self:SetReportDisplayTime( 25 )
Detection:__Start( 3 )
return self
end
function DETECTION_MANAGER:onafterStart( From, Event, To )
self:Report()
end
function DETECTION_MANAGER:onafterReport( From, Event, To )
self:__Report( -self._RefreshTimeInterval )
self:ProcessDetected( self.Detection )
end
--- Set the reporting time interval.
-- @param #DETECTION_MANAGER self
-- @param #number RefreshTimeInterval The interval in seconds when a report needs to be done.
-- @return #DETECTION_MANAGER self
function DETECTION_MANAGER:SetRefreshTimeInterval( RefreshTimeInterval )
self:F2()
self._RefreshTimeInterval = RefreshTimeInterval
end
--- Set the reporting message display time.
-- @param #DETECTION_MANAGER self
-- @param #number ReportDisplayTime The display time in seconds when a report needs to be done.
-- @return #DETECTION_MANAGER self
function DETECTION_MANAGER:SetReportDisplayTime( ReportDisplayTime )
self:F2()
self._ReportDisplayTime = ReportDisplayTime
end
--- Get the reporting message display time.
-- @param #DETECTION_MANAGER self
-- @return #number ReportDisplayTime The display time in seconds when a report needs to be done.
function DETECTION_MANAGER:GetReportDisplayTime()
self:F2()
return self._ReportDisplayTime
end
--- Set a command center to communicate actions to the players reporting to the command center.
-- @param #DETECTION_MANAGER self
-- @return #DETECTION_MANGER self
function DETECTION_MANAGER:SetTacticalMenu( DispatcherMainMenuText, DispatcherMenuText )
local DispatcherMainMenu = MENU_MISSION:New( DispatcherMainMenuText, nil )
local DispatcherMenu = MENU_MISSION_COMMAND:New( DispatcherMenuText, DispatcherMainMenu,
function()
self:ShowTacticalDisplay( self.Detection )
end
)
return self
end
--- Set a command center to communicate actions to the players reporting to the command center.
-- @param #DETECTION_MANAGER self
-- @param Tasking.CommandCenter#COMMANDCENTER CommandCenter The command center.
-- @return #DETECTION_MANGER self
function DETECTION_MANAGER:SetCommandCenter( CommandCenter )
self.CC = CommandCenter
return self
end
--- Get the command center to communicate actions to the players.
-- @param #DETECTION_MANAGER self
-- @return Tasking.CommandCenter#COMMANDCENTER The command center.
function DETECTION_MANAGER:GetCommandCenter()
return self.CC
end
--- Send an information message to the players reporting to the command center.
-- @param #DETECTION_MANAGER self
-- @param #table Squadron The squadron table.
-- @param #string Message The message to be sent.
-- @param #string SoundFile The name of the sound file .wav or .ogg.
-- @param #number SoundDuration The duration of the sound.
-- @param #string SoundPath The path pointing to the folder in the mission file.
-- @param Wrapper.Group#GROUP DefenderGroup The defender group sending the message.
-- @return #DETECTION_MANGER self
function DETECTION_MANAGER:MessageToPlayers( Squadron, Message, DefenderGroup )
self:F( { Message = Message } )
-- if not self.PreviousMessage or self.PreviousMessage ~= Message then
-- self.PreviousMessage = Message
-- if self.CC then
-- self.CC:MessageToCoalition( Message )
-- end
-- end
if self.CC then
self.CC:MessageToCoalition( Message )
end
Message = Message:gsub( "°", " degrees " )
Message = Message:gsub( "(%d)%.(%d)", "%1 dot %2" )
-- Here we handle the transmission of the voice over.
-- If for a certain reason the Defender does not exist, we use the coordinate of the airbase to send the message from.
local RadioQueue = Squadron.RadioQueue -- Core.RadioSpeech#RADIOSPEECH
if RadioQueue then
local DefenderUnit = DefenderGroup:GetUnit(1)
if DefenderUnit and DefenderUnit:IsAlive() then
RadioQueue:SetSenderUnitName( DefenderUnit:GetName() )
end
RadioQueue:Speak( Message, Squadron.Language )
end
return self
end
--- Reports the detected items to the @{Core.Set#SET_GROUP}.
-- @param #DETECTION_MANAGER self
-- @param Functional.Detection#DETECTION_BASE Detection
-- @return #DETECTION_MANAGER self
function DETECTION_MANAGER:ProcessDetected( Detection )
end
end
do -- DETECTION_REPORTING
--- DETECTION_REPORTING class.
-- @type DETECTION_REPORTING
-- @field Core.Set#SET_GROUP SetGroup The groups to which the FAC will report to.
-- @field Functional.Detection#DETECTION_BASE Detection The DETECTION_BASE object that is used to report the detected objects.
-- @extends #DETECTION_MANAGER
DETECTION_REPORTING = {
ClassName = "DETECTION_REPORTING",
}
--- DETECTION_REPORTING constructor.
-- @param #DETECTION_REPORTING self
-- @param Core.Set#SET_GROUP SetGroup
-- @param Functional.Detection#DETECTION_AREAS Detection
-- @return #DETECTION_REPORTING self
function DETECTION_REPORTING:New( SetGroup, Detection )
-- Inherits from DETECTION_MANAGER
local self = BASE:Inherit( self, DETECTION_MANAGER:New( SetGroup, Detection ) ) -- #DETECTION_REPORTING
self:Schedule( 1, 30 )
return self
end
--- Creates a string of the detected items in a @{Functional.Detection} object.
-- @param #DETECTION_MANAGER self
-- @param Core.Set#SET_UNIT DetectedSet The detected Set created by the @{Functional.Detection#DETECTION_BASE} object.
-- @return #DETECTION_MANAGER self
function DETECTION_REPORTING:GetDetectedItemsText( DetectedSet )
self:F2()
local MT = {} -- Message Text
local UnitTypes = {}
for DetectedUnitID, DetectedUnitData in pairs( DetectedSet:GetSet() ) do
local DetectedUnit = DetectedUnitData -- Wrapper.Unit#UNIT
if DetectedUnit:IsAlive() then
local UnitType = DetectedUnit:GetTypeName()
if not UnitTypes[UnitType] then
UnitTypes[UnitType] = 1
else
UnitTypes[UnitType] = UnitTypes[UnitType] + 1
end
end
end
for UnitTypeID, UnitType in pairs( UnitTypes ) do
MT[#MT+1] = UnitType .. " of " .. UnitTypeID
end
return table.concat( MT, ", " )
end
--- Reports the detected items to the @{Core.Set#SET_GROUP}.
-- @param #DETECTION_REPORTING self
-- @param Wrapper.Group#GROUP Group The @{Wrapper.Group} object to where the report needs to go.
-- @param Functional.Detection#DETECTION_AREAS Detection The detection created by the @{Functional.Detection#DETECTION_BASE} object.
-- @return #boolean Return true if you want the reporting to continue... false will cancel the reporting loop.
function DETECTION_REPORTING:ProcessDetected( Group, Detection )
self:F2( Group )
local DetectedMsg = {}
for DetectedAreaID, DetectedAreaData in pairs( Detection:GetDetectedAreas() ) do
local DetectedArea = DetectedAreaData -- Functional.Detection#DETECTION_AREAS.DetectedArea
DetectedMsg[#DetectedMsg+1] = " - Group #" .. DetectedAreaID .. ": " .. self:GetDetectedItemsText( DetectedArea.Set )
end
local FACGroup = Detection:GetDetectionGroups()
FACGroup:MessageToGroup( "Reporting detected target groups:\n" .. table.concat( DetectedMsg, "\n" ), self:GetReportDisplayTime(), Group )
return true
end
end