mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
509 lines
20 KiB
Lua
509 lines
20 KiB
Lua
-- This module contains the DETECTION_MANAGER class and derived classes.
|
|
--
|
|
-- ===
|
|
--
|
|
-- 1) @{Tasking.DetectionManager#DETECTION_MANAGER} class, extends @{Core.Base#BASE}
|
|
-- ====================================================================
|
|
-- The @{Tasking.DetectionManager#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:
|
|
-- -----------------------------------
|
|
-- * @{Tasking.DetectionManager#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 @{Tasking.DetectionManager#DETECTION_MANAGER.ReportDetected}(). This method implements polymorphic behaviour.
|
|
--
|
|
-- The time interval in seconds of the reporting can be changed using the methods @{Tasking.DetectionManager#DETECTION_MANAGER.SetReportInterval}().
|
|
-- To control how long a reporting message is displayed, use @{Tasking.DetectionManager#DETECTION_MANAGER.SetReportDisplayTime}().
|
|
-- Derived classes need to implement the method @{Tasking.DetectionManager#DETECTION_MANAGER.GetReportDisplayTime}() to use the correct display time for displayed messages during a report.
|
|
--
|
|
-- Reporting can be started and stopped using the methods @{Tasking.DetectionManager#DETECTION_MANAGER.StartReporting}() and @{Tasking.DetectionManager#DETECTION_MANAGER.StopReporting}() respectively.
|
|
-- If an ad-hoc report is requested, use the method @{Tasking.DetectionManager#DETECTION_MANAGER#ReportNow}().
|
|
--
|
|
-- The default reporting interval is every 60 seconds. The reporting messages are displayed 15 seconds.
|
|
--
|
|
-- ===
|
|
--
|
|
-- 2) @{Tasking.DetectionManager#DETECTION_REPORTING} class, extends @{Tasking.DetectionManager#DETECTION_MANAGER}
|
|
-- =========================================================================================
|
|
-- The @{Tasking.DetectionManager#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 @{Tasking.DetectionManager#DETECTION_REPORTING.New}() method creates a new DETECTION_REPORTING instance.
|
|
--
|
|
-- ===
|
|
--
|
|
-- 3) @{#DETECTION_DISPATCHER} class, extends @{#DETECTION_MANAGER}
|
|
-- ================================================================
|
|
-- The @{#DETECTION_DISPATCHER} class implements the dynamic dispatching of tasks upon groups of detected units determined a @{Set} of FAC (groups).
|
|
-- The FAC will detect units, will group them, and will dispatch @{Task}s to groups. Depending on the type of target detected, different tasks will be dispatched.
|
|
-- Find a summary below describing for which situation a task type is created:
|
|
--
|
|
-- * **CAS Task**: Is created when there are enemy ground units within range of the FAC, while there are friendly units in the FAC perimeter.
|
|
-- * **BAI Task**: Is created when there are enemy ground units within range of the FAC, while there are NO other friendly units within the FAC perimeter.
|
|
-- * **SEAD Task**: Is created when there are enemy ground units wihtin range of the FAC, with air search radars.
|
|
--
|
|
-- Other task types will follow...
|
|
--
|
|
-- 3.1) DETECTION_DISPATCHER constructor:
|
|
-- --------------------------------------
|
|
-- The @{#DETECTION_DISPATCHER.New}() method creates a new DETECTION_DISPATCHER instance.
|
|
--
|
|
-- ===
|
|
--
|
|
-- ### Contributions: Mechanist, Prof_Hilactic, FlightControl - Concept & Testing
|
|
-- ### Author: FlightControl - Framework Design & Programming
|
|
--
|
|
-- @module DetectionManager
|
|
|
|
do -- DETECTION MANAGER
|
|
|
|
--- DETECTION_MANAGER class.
|
|
-- @type DETECTION_MANAGER
|
|
-- @field 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 Base#BASE
|
|
DETECTION_MANAGER = {
|
|
ClassName = "DETECTION_MANAGER",
|
|
SetGroup = nil,
|
|
Detection = nil,
|
|
}
|
|
|
|
--- FAC constructor.
|
|
-- @param #DETECTION_MANAGER self
|
|
-- @param 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, BASE:New() ) -- Functional.Detection#DETECTION_MANAGER
|
|
|
|
self.SetGroup = SetGroup
|
|
self.Detection = Detection
|
|
|
|
self:SetReportInterval( 30 )
|
|
self:SetReportDisplayTime( 25 )
|
|
|
|
return self
|
|
end
|
|
|
|
--- Set the reporting time interval.
|
|
-- @param #DETECTION_MANAGER self
|
|
-- @param #number ReportInterval The interval in seconds when a report needs to be done.
|
|
-- @return #DETECTION_MANAGER self
|
|
function DETECTION_MANAGER:SetReportInterval( ReportInterval )
|
|
self:F2()
|
|
|
|
self._ReportInterval = ReportInterval
|
|
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
|
|
|
|
|
|
|
|
--- Reports the detected items to the @{Set#SET_GROUP}.
|
|
-- @param #DETECTION_MANAGER self
|
|
-- @param Functional.Detection#DETECTION_BASE Detection
|
|
-- @return #DETECTION_MANAGER self
|
|
function DETECTION_MANAGER:ReportDetected( Detection )
|
|
self:F2()
|
|
|
|
end
|
|
|
|
--- Schedule the FAC reporting.
|
|
-- @param #DETECTION_MANAGER self
|
|
-- @param #number DelayTime The delay in seconds to wait the reporting.
|
|
-- @param #number ReportInterval The repeat interval in seconds for the reporting to happen repeatedly.
|
|
-- @return #DETECTION_MANAGER self
|
|
function DETECTION_MANAGER:Schedule( DelayTime, ReportInterval )
|
|
self:F2()
|
|
|
|
self._ScheduleDelayTime = DelayTime
|
|
|
|
self:SetReportInterval( ReportInterval )
|
|
|
|
self.FacScheduler = SCHEDULER:New(self, self._FacScheduler, { self, "DetectionManager" }, self._ScheduleDelayTime, self._ReportInterval )
|
|
return self
|
|
end
|
|
|
|
--- Report the detected @{Wrapper.Unit#UNIT}s detected within the @{Functional.Detection#DETECTION_BASE} object to the @{Set#SET_GROUP}s.
|
|
-- @param #DETECTION_MANAGER self
|
|
function DETECTION_MANAGER:_FacScheduler( SchedulerName )
|
|
self:F2( { SchedulerName } )
|
|
|
|
return self:ProcessDetected( self.Detection )
|
|
|
|
-- self.SetGroup:ForEachGroup(
|
|
-- --- @param Wrapper.Group#GROUP Group
|
|
-- function( Group )
|
|
-- if Group:IsAlive() then
|
|
-- return self:ProcessDetected( self.Detection )
|
|
-- end
|
|
-- end
|
|
-- )
|
|
|
|
-- return true
|
|
end
|
|
|
|
end
|
|
|
|
|
|
do -- DETECTION_REPORTING
|
|
|
|
--- DETECTION_REPORTING class.
|
|
-- @type DETECTION_REPORTING
|
|
-- @field 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 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 @{Detection}.
|
|
-- @param #DETECTION_MANAGER self
|
|
-- @param 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 @{Set#SET_GROUP}.
|
|
-- @param #DETECTION_REPORTING self
|
|
-- @param Wrapper.Group#GROUP Group The @{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 )
|
|
|
|
self:E( 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
|
|
|
|
do -- DETECTION_DISPATCHER
|
|
|
|
--- DETECTION_DISPATCHER class.
|
|
-- @type DETECTION_DISPATCHER
|
|
-- @field 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.Mission#MISSION Mission
|
|
-- @field Wrapper.Group#GROUP CommandCenter
|
|
-- @extends Tasking.DetectionManager#DETECTION_MANAGER
|
|
DETECTION_DISPATCHER = {
|
|
ClassName = "DETECTION_DISPATCHER",
|
|
Mission = nil,
|
|
CommandCenter = nil,
|
|
Detection = nil,
|
|
}
|
|
|
|
|
|
--- DETECTION_DISPATCHER constructor.
|
|
-- @param #DETECTION_DISPATCHER self
|
|
-- @param Set#SET_GROUP SetGroup
|
|
-- @param Functional.Detection#DETECTION_BASE Detection
|
|
-- @return #DETECTION_DISPATCHER self
|
|
function DETECTION_DISPATCHER:New( Mission, CommandCenter, SetGroup, Detection )
|
|
|
|
-- Inherits from DETECTION_MANAGER
|
|
local self = BASE:Inherit( self, DETECTION_MANAGER:New( SetGroup, Detection ) ) -- #DETECTION_DISPATCHER
|
|
|
|
self.Detection = Detection
|
|
self.CommandCenter = CommandCenter
|
|
self.Mission = Mission
|
|
|
|
self:Schedule( 30 )
|
|
return self
|
|
end
|
|
|
|
|
|
--- Creates a SEAD task when there are targets for it.
|
|
-- @param #DETECTION_DISPATCHER self
|
|
-- @param Functional.Detection#DETECTION_AREAS.DetectedArea DetectedArea
|
|
-- @return Set#SET_UNIT TargetSetUnit: The target set of units.
|
|
-- @return #nil If there are no targets to be set.
|
|
function DETECTION_DISPATCHER:EvaluateSEAD( DetectedArea )
|
|
self:F( { DetectedArea.AreaID } )
|
|
|
|
local DetectedSet = DetectedArea.Set
|
|
local DetectedZone = DetectedArea.Zone
|
|
|
|
-- Determine if the set has radar targets. If it does, construct a SEAD task.
|
|
local RadarCount = DetectedSet:HasSEAD()
|
|
|
|
if RadarCount > 0 then
|
|
|
|
-- Here we're doing something advanced... We're copying the DetectedSet, but making a new Set only with SEADable Radar units in it.
|
|
local TargetSetUnit = SET_UNIT:New()
|
|
TargetSetUnit:SetDatabase( DetectedSet )
|
|
TargetSetUnit:FilterHasSEAD()
|
|
TargetSetUnit:FilterOnce() -- Filter but don't do any events!!! Elements are added manually upon each detection.
|
|
|
|
return TargetSetUnit
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
--- Creates a CAS task when there are targets for it.
|
|
-- @param #DETECTION_DISPATCHER self
|
|
-- @param Functional.Detection#DETECTION_AREAS.DetectedArea DetectedArea
|
|
-- @return Tasking.Task#TASK
|
|
function DETECTION_DISPATCHER:EvaluateCAS( DetectedArea )
|
|
self:F( { DetectedArea.AreaID } )
|
|
|
|
local DetectedSet = DetectedArea.Set
|
|
local DetectedZone = DetectedArea.Zone
|
|
|
|
|
|
-- Determine if the set has radar targets. If it does, construct a SEAD task.
|
|
local GroundUnitCount = DetectedSet:HasGroundUnits()
|
|
local FriendliesNearBy = self.Detection:IsFriendliesNearBy( DetectedArea )
|
|
|
|
if GroundUnitCount > 0 and FriendliesNearBy == true then
|
|
|
|
-- Copy the Set
|
|
local TargetSetUnit = SET_UNIT:New()
|
|
TargetSetUnit:SetDatabase( DetectedSet )
|
|
TargetSetUnit:FilterOnce() -- Filter but don't do any events!!! Elements are added manually upon each detection.
|
|
|
|
return TargetSetUnit
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
--- Creates a BAI task when there are targets for it.
|
|
-- @param #DETECTION_DISPATCHER self
|
|
-- @param Functional.Detection#DETECTION_AREAS.DetectedArea DetectedArea
|
|
-- @return Tasking.Task#TASK
|
|
function DETECTION_DISPATCHER:EvaluateBAI( DetectedArea, FriendlyCoalition )
|
|
self:F( { DetectedArea.AreaID } )
|
|
|
|
local DetectedSet = DetectedArea.Set
|
|
local DetectedZone = DetectedArea.Zone
|
|
|
|
|
|
-- Determine if the set has radar targets. If it does, construct a SEAD task.
|
|
local GroundUnitCount = DetectedSet:HasGroundUnits()
|
|
local FriendliesNearBy = self.Detection:IsFriendliesNearBy( DetectedArea )
|
|
|
|
if GroundUnitCount > 0 and FriendliesNearBy == false then
|
|
|
|
-- Copy the Set
|
|
local TargetSetUnit = SET_UNIT:New()
|
|
TargetSetUnit:SetDatabase( DetectedSet )
|
|
TargetSetUnit:FilterOnce() -- Filter but don't do any events!!! Elements are added manually upon each detection.
|
|
|
|
return TargetSetUnit
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
--- Evaluates the removal of the Task from the Mission.
|
|
-- Can only occur when the DetectedArea is Changed AND the state of the Task is "Planned".
|
|
-- @param #DETECTION_DISPATCHER self
|
|
-- @param Tasking.Mission#MISSION Mission
|
|
-- @param Tasking.Task#TASK Task
|
|
-- @param Functional.Detection#DETECTION_AREAS.DetectedArea DetectedArea
|
|
-- @return Tasking.Task#TASK
|
|
function DETECTION_DISPATCHER:EvaluateRemoveTask( Mission, Task, DetectedArea )
|
|
|
|
if Task then
|
|
if Task:IsStatePlanned() and DetectedArea.Changed == true then
|
|
self:E( "Removing Tasking: " .. Task:GetTaskName() )
|
|
Mission:RemoveTaskMenu( Task )
|
|
Task = Mission:RemoveTask( Task )
|
|
end
|
|
end
|
|
|
|
return Task
|
|
end
|
|
|
|
|
|
--- Assigns tasks in relation to the detected items to the @{Set#SET_GROUP}.
|
|
-- @param #DETECTION_DISPATCHER self
|
|
-- @param Functional.Detection#DETECTION_AREAS Detection The detection created by the @{Functional.Detection#DETECTION_AREAS} object.
|
|
-- @return #boolean Return true if you want the task assigning to continue... false will cancel the loop.
|
|
function DETECTION_DISPATCHER:ProcessDetected( Detection )
|
|
self:F2()
|
|
|
|
local AreaMsg = {}
|
|
local TaskMsg = {}
|
|
local ChangeMsg = {}
|
|
|
|
local Mission = self.Mission
|
|
|
|
--- First we need to the detected targets.
|
|
for DetectedAreaID, DetectedAreaData in ipairs( Detection:GetDetectedAreas() ) do
|
|
|
|
local DetectedArea = DetectedAreaData -- Functional.Detection#DETECTION_AREAS.DetectedArea
|
|
local DetectedSet = DetectedArea.Set
|
|
local DetectedZone = DetectedArea.Zone
|
|
self:E( { "Targets in DetectedArea", DetectedArea.AreaID, DetectedSet:Count(), tostring( DetectedArea ) } )
|
|
DetectedSet:Flush()
|
|
|
|
local AreaID = DetectedArea.AreaID
|
|
|
|
-- Evaluate SEAD Tasking
|
|
local SEADTask = Mission:GetTask( "SEAD." .. AreaID )
|
|
SEADTask = self:EvaluateRemoveTask( Mission, SEADTask, DetectedArea )
|
|
if not SEADTask then
|
|
local TargetSetUnit = self:EvaluateSEAD( DetectedArea ) -- Returns a SetUnit if there are targets to be SEADed...
|
|
if TargetSetUnit then
|
|
SEADTask = Mission:AddTask( TASK_SEAD:New( Mission, self.SetGroup, "SEAD." .. AreaID, TargetSetUnit , DetectedZone ) )
|
|
end
|
|
end
|
|
if SEADTask and SEADTask:IsStatePlanned() then
|
|
self:E( "Planned" )
|
|
--SEADTask:SetPlannedMenu()
|
|
TaskMsg[#TaskMsg+1] = " - " .. SEADTask:GetStateString() .. " SEAD " .. AreaID .. " - " .. SEADTask.TargetSetUnit:GetUnitTypesText()
|
|
end
|
|
|
|
-- Evaluate CAS Tasking
|
|
local CASTask = Mission:GetTask( "CAS." .. AreaID )
|
|
CASTask = self:EvaluateRemoveTask( Mission, CASTask, DetectedArea )
|
|
if not CASTask then
|
|
local TargetSetUnit = self:EvaluateCAS( DetectedArea ) -- Returns a SetUnit if there are targets to be SEADed...
|
|
if TargetSetUnit then
|
|
CASTask = Mission:AddTask( TASK_A2G:New( Mission, self.SetGroup, "CAS." .. AreaID, "CAS", TargetSetUnit , DetectedZone, DetectedArea.NearestFAC ) )
|
|
end
|
|
end
|
|
if CASTask and CASTask:IsStatePlanned() then
|
|
--CASTask:SetPlannedMenu()
|
|
TaskMsg[#TaskMsg+1] = " - " .. CASTask:GetStateString() .. " CAS " .. AreaID .. " - " .. CASTask.TargetSetUnit:GetUnitTypesText()
|
|
end
|
|
|
|
-- Evaluate BAI Tasking
|
|
local BAITask = Mission:GetTask( "BAI." .. AreaID )
|
|
BAITask = self:EvaluateRemoveTask( Mission, BAITask, DetectedArea )
|
|
if not BAITask then
|
|
local TargetSetUnit = self:EvaluateBAI( DetectedArea, self.CommandCenter:GetCoalition() ) -- Returns a SetUnit if there are targets to be SEADed...
|
|
if TargetSetUnit then
|
|
BAITask = Mission:AddTask( TASK_A2G:New( Mission, self.SetGroup, "BAI." .. AreaID, "BAI", TargetSetUnit , DetectedZone, DetectedArea.NearestFAC ) )
|
|
end
|
|
end
|
|
if BAITask and BAITask:IsStatePlanned() then
|
|
--BAITask:SetPlannedMenu()
|
|
TaskMsg[#TaskMsg+1] = " - " .. BAITask:GetStateString() .. " BAI " .. AreaID .. " - " .. BAITask.TargetSetUnit:GetUnitTypesText()
|
|
end
|
|
|
|
if #TaskMsg > 0 then
|
|
|
|
local ThreatLevel = Detection:GetTreatLevelA2G( DetectedArea )
|
|
|
|
local DetectedAreaVec3 = DetectedZone:GetVec3()
|
|
local DetectedAreaPointVec3 = POINT_VEC3:New( DetectedAreaVec3.x, DetectedAreaVec3.y, DetectedAreaVec3.z )
|
|
local DetectedAreaPointLL = DetectedAreaPointVec3:ToStringLL( 3, true )
|
|
AreaMsg[#AreaMsg+1] = string.format( " - Area #%d - %s - Threat Level [%s] (%2d)",
|
|
DetectedAreaID,
|
|
DetectedAreaPointLL,
|
|
string.rep( "■", ThreatLevel ),
|
|
ThreatLevel
|
|
)
|
|
|
|
-- Loop through the changes ...
|
|
local ChangeText = Detection:GetChangeText( DetectedArea )
|
|
|
|
if ChangeText ~= "" then
|
|
ChangeMsg[#ChangeMsg+1] = string.gsub( string.gsub( ChangeText, "\n", "%1 - " ), "^.", " - %1" )
|
|
end
|
|
end
|
|
|
|
-- OK, so the tasking has been done, now delete the changes reported for the area.
|
|
Detection:AcceptChanges( DetectedArea )
|
|
|
|
end
|
|
|
|
-- TODO set menus using the HQ coordinator
|
|
Mission:SetMenu()
|
|
|
|
if #AreaMsg > 0 then
|
|
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
|
if not TaskGroup:GetState( TaskGroup, "Assigned" ) then
|
|
self.CommandCenter:MessageToGroup(
|
|
string.format( "HQ Reporting - Target areas for mission '%s':\nAreas:\n%s\n\nTasks:\n%s\n\nChanges:\n%s ",
|
|
self.Mission:GetName(),
|
|
table.concat( AreaMsg, "\n" ),
|
|
table.concat( TaskMsg, "\n" ),
|
|
table.concat( ChangeMsg, "\n" )
|
|
), self:GetReportDisplayTime(), TaskGroup
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
end |