mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
New detection method based on zones and scanning.
This commit is contained in:
parent
044b5cba7c
commit
3b520ab0c4
@ -1688,7 +1688,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
|
|
||||||
-- Add the CAP to the EWR network.
|
-- Add the CAP to the EWR network.
|
||||||
|
|
||||||
local RecceSet = self.Detection:GetDetectionSetGroup()
|
local RecceSet = self.Detection:GetDetectionSet()
|
||||||
RecceSet:FilterPrefixes( DefenderSquadron.TemplatePrefixes )
|
RecceSet:FilterPrefixes( DefenderSquadron.TemplatePrefixes )
|
||||||
RecceSet:FilterStart()
|
RecceSet:FilterStart()
|
||||||
|
|
||||||
|
|||||||
@ -148,7 +148,7 @@ do -- SET_BASE
|
|||||||
function SET_BASE:GetSet()
|
function SET_BASE:GetSet()
|
||||||
self:F2()
|
self:F2()
|
||||||
|
|
||||||
return self.Set
|
return self.Set or {}
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Gets a list of the Names of the Objects in the Set.
|
--- Gets a list of the Names of the Objects in the Set.
|
||||||
|
|||||||
@ -469,7 +469,7 @@ do -- DESIGNATE
|
|||||||
self.CC = CC
|
self.CC = CC
|
||||||
self.Detection = Detection
|
self.Detection = Detection
|
||||||
self.AttackSet = AttackSet
|
self.AttackSet = AttackSet
|
||||||
self.RecceSet = Detection:GetDetectionSetGroup()
|
self.RecceSet = Detection:GetDetectionSet()
|
||||||
self.Recces = {}
|
self.Recces = {}
|
||||||
self.Designating = {}
|
self.Designating = {}
|
||||||
self:SetDesignateName()
|
self:SetDesignateName()
|
||||||
@ -1182,7 +1182,7 @@ do -- DESIGNATE
|
|||||||
|
|
||||||
|
|
||||||
local DetectedItem = self.Detection:GetDetectedItemByIndex( Index )
|
local DetectedItem = self.Detection:GetDetectedItemByIndex( Index )
|
||||||
local TargetSetUnit = self.Detection:GetDetectedSet( DetectedItem )
|
local TargetSetUnit = self.Detection:GetDetectedItemSet( DetectedItem )
|
||||||
|
|
||||||
local MarkingCount = 0
|
local MarkingCount = 0
|
||||||
local MarkedTypes = {}
|
local MarkedTypes = {}
|
||||||
@ -1352,7 +1352,7 @@ do -- DESIGNATE
|
|||||||
end
|
end
|
||||||
|
|
||||||
local DetectedItem = self.Detection:GetDetectedItemByIndex( Index )
|
local DetectedItem = self.Detection:GetDetectedItemByIndex( Index )
|
||||||
local TargetSetUnit = self.Detection:GetDetectedSet( DetectedItem )
|
local TargetSetUnit = self.Detection:GetDetectedItemSet( DetectedItem )
|
||||||
|
|
||||||
local Recces = self.Recces
|
local Recces = self.Recces
|
||||||
|
|
||||||
@ -1377,7 +1377,7 @@ do -- DESIGNATE
|
|||||||
function DESIGNATE:onafterSmoke( From, Event, To, Index, Color )
|
function DESIGNATE:onafterSmoke( From, Event, To, Index, Color )
|
||||||
|
|
||||||
local DetectedItem = self.Detection:GetDetectedItemByIndex( Index )
|
local DetectedItem = self.Detection:GetDetectedItemByIndex( Index )
|
||||||
local TargetSetUnit = self.Detection:GetDetectedSet( DetectedItem )
|
local TargetSetUnit = self.Detection:GetDetectedItemSet( DetectedItem )
|
||||||
local TargetSetUnitCount = TargetSetUnit:Count()
|
local TargetSetUnitCount = TargetSetUnit:Count()
|
||||||
|
|
||||||
local MarkedCount = 0
|
local MarkedCount = 0
|
||||||
@ -1422,7 +1422,7 @@ do -- DESIGNATE
|
|||||||
function DESIGNATE:onafterIlluminate( From, Event, To, Index )
|
function DESIGNATE:onafterIlluminate( From, Event, To, Index )
|
||||||
|
|
||||||
local DetectedItem = self.Detection:GetDetectedItemByIndex( Index )
|
local DetectedItem = self.Detection:GetDetectedItemByIndex( Index )
|
||||||
local TargetSetUnit = self.Detection:GetDetectedSet( DetectedItem )
|
local TargetSetUnit = self.Detection:GetDetectedItemSet( DetectedItem )
|
||||||
local TargetUnit = TargetSetUnit:GetFirst()
|
local TargetUnit = TargetSetUnit:GetFirst()
|
||||||
|
|
||||||
if TargetUnit then
|
if TargetUnit then
|
||||||
|
|||||||
@ -541,11 +541,11 @@ do -- DETECTION_BASE
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.DetectionCount = self.DetectionSet:Count()
|
||||||
for DetectionID, DetectionData in pairs( self.DetectionSet:GetSet() ) do
|
for DetectionID, DetectionData in pairs( self.DetectionSet:GetSet() ) do
|
||||||
--self:F( { DetectionGroupData } )
|
--self:F( { DetectionGroupData } )
|
||||||
self:F( { DetectionGroup = DetectionData:GetName() } )
|
self:F( { DetectionGroup = DetectionData:GetName() } )
|
||||||
self:__Detection( DetectDelay, DetectionData, DetectionTimeStamp ) -- Process each detection asynchronously.
|
self:__Detection( DetectDelay, DetectionData, DetectionTimeStamp ) -- Process each detection asynchronously.
|
||||||
self.DetectionCount = self.DetectionCount + 1
|
|
||||||
DetectDelay = DetectDelay + 1
|
DetectDelay = DetectDelay + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -839,7 +839,7 @@ do -- DETECTION_BASE
|
|||||||
local DetectedItems = self:GetDetectedItems()
|
local DetectedItems = self:GetDetectedItems()
|
||||||
|
|
||||||
for DetectedItemIndex, DetectedItem in pairs( DetectedItems ) do
|
for DetectedItemIndex, DetectedItem in pairs( DetectedItems ) do
|
||||||
local DetectedSet = self:GetDetectedSet( DetectedItem )
|
local DetectedSet = self:GetDetectedItemSet( DetectedItem )
|
||||||
if DetectedSet then
|
if DetectedSet then
|
||||||
DetectedSet:RemoveUnitsByName( UnitName )
|
DetectedSet:RemoveUnitsByName( UnitName )
|
||||||
end
|
end
|
||||||
@ -1552,6 +1552,8 @@ do -- DETECTION_BASE
|
|||||||
-- @return #DETECTION_BASE.DetectedItem
|
-- @return #DETECTION_BASE.DetectedItem
|
||||||
function DETECTION_BASE:AddDetectedItemZone( ItemPrefix, DetectedItemKey, Set, Zone )
|
function DETECTION_BASE:AddDetectedItemZone( ItemPrefix, DetectedItemKey, Set, Zone )
|
||||||
|
|
||||||
|
self:F( { ItemPrefix, DetectedItemKey, Set, Zone } )
|
||||||
|
|
||||||
local DetectedItem = self:AddDetectedItem( ItemPrefix, DetectedItemKey, Set )
|
local DetectedItem = self:AddDetectedItem( ItemPrefix, DetectedItemKey, Set )
|
||||||
|
|
||||||
DetectedItem.Zone = Zone
|
DetectedItem.Zone = Zone
|
||||||
@ -1662,7 +1664,7 @@ do -- DETECTION_BASE
|
|||||||
-- @param #DETECTION_BASE self
|
-- @param #DETECTION_BASE self
|
||||||
-- @param #DETECTION_BASE.DetectedItem DetectedItem
|
-- @param #DETECTION_BASE.DetectedItem DetectedItem
|
||||||
-- @return Core.Set#SET_UNIT DetectedSet
|
-- @return Core.Set#SET_UNIT DetectedSet
|
||||||
function DETECTION_BASE:GetDetectedSet( DetectedItem )
|
function DETECTION_BASE:GetDetectedItemSet( DetectedItem )
|
||||||
|
|
||||||
local DetectedSetUnit = DetectedItem and DetectedItem.Set
|
local DetectedSetUnit = DetectedItem and DetectedItem.Set
|
||||||
if DetectedSetUnit then
|
if DetectedSetUnit then
|
||||||
@ -1811,13 +1813,13 @@ do -- DETECTION_BASE
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get the detection Groups.
|
--- Get the Detection Set.
|
||||||
-- @param #DETECTION_BASE self
|
-- @param #DETECTION_BASE self
|
||||||
-- @return Core.Set#SET_GROUP
|
-- @return Core.Set#SET_BASE
|
||||||
function DETECTION_BASE:GetDetectionSetGroup()
|
function DETECTION_BASE:GetDetectionSet()
|
||||||
|
|
||||||
local DetectionSetGroup = self.DetectionSetGroup
|
local DetectionSet = self.DetectionSet
|
||||||
return DetectionSetGroup
|
return DetectionSet
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Find the nearest Recce of the DetectedItem.
|
--- Find the nearest Recce of the DetectedItem.
|
||||||
@ -1829,7 +1831,7 @@ do -- DETECTION_BASE
|
|||||||
local NearestRecce = nil
|
local NearestRecce = nil
|
||||||
local DistanceRecce = 1000000000 -- Units are not further than 1000000 km away from an area :-)
|
local DistanceRecce = 1000000000 -- Units are not further than 1000000 km away from an area :-)
|
||||||
|
|
||||||
for RecceGroupName, RecceGroup in pairs( self.DetectionSetGroup:GetSet() ) do
|
for RecceGroupName, RecceGroup in pairs( self.DetectionSet:GetSet() ) do
|
||||||
if RecceGroup and RecceGroup:IsAlive() then
|
if RecceGroup and RecceGroup:IsAlive() then
|
||||||
for RecceUnit, RecceUnit in pairs( RecceGroup:GetUnits() ) do
|
for RecceUnit, RecceUnit in pairs( RecceGroup:GetUnits() ) do
|
||||||
if RecceUnit:IsActive() then
|
if RecceUnit:IsActive() then
|
||||||
@ -2034,7 +2036,7 @@ do -- DETECTION_UNITS
|
|||||||
local DetectedFirstUnitCoord = DetectedFirstUnit:GetCoordinate()
|
local DetectedFirstUnitCoord = DetectedFirstUnit:GetCoordinate()
|
||||||
self:SetDetectedItemCoordinate( DetectedItem, DetectedFirstUnitCoord, DetectedFirstUnit )
|
self:SetDetectedItemCoordinate( DetectedItem, DetectedFirstUnitCoord, DetectedFirstUnit )
|
||||||
|
|
||||||
self:ReportFriendliesNearBy( { DetectedItem = DetectedItem, ReportSetGroup = self.DetectionSetGroup } ) -- Fill the Friendlies table
|
self:ReportFriendliesNearBy( { DetectedItem = DetectedItem, ReportSetGroup = self.DetectionSet } ) -- Fill the Friendlies table
|
||||||
self:SetDetectedItemThreatLevel( DetectedItem )
|
self:SetDetectedItemThreatLevel( DetectedItem )
|
||||||
self:NearestRecce( DetectedItem )
|
self:NearestRecce( DetectedItem )
|
||||||
|
|
||||||
@ -2269,7 +2271,7 @@ do -- DETECTION_TYPES
|
|||||||
local DetectedUnitCoord = DetectedFirstUnit:GetCoordinate()
|
local DetectedUnitCoord = DetectedFirstUnit:GetCoordinate()
|
||||||
self:SetDetectedItemCoordinate( DetectedItem, DetectedUnitCoord, DetectedFirstUnit )
|
self:SetDetectedItemCoordinate( DetectedItem, DetectedUnitCoord, DetectedFirstUnit )
|
||||||
|
|
||||||
self:ReportFriendliesNearBy( { DetectedItem = DetectedItem, ReportSetGroup = self.DetectionSetGroup } ) -- Fill the Friendlies table
|
self:ReportFriendliesNearBy( { DetectedItem = DetectedItem, ReportSetGroup = self.DetectionSet } ) -- Fill the Friendlies table
|
||||||
self:SetDetectedItemThreatLevel( DetectedItem )
|
self:SetDetectedItemThreatLevel( DetectedItem )
|
||||||
self:NearestRecce( DetectedItem )
|
self:NearestRecce( DetectedItem )
|
||||||
end
|
end
|
||||||
@ -2287,7 +2289,7 @@ do -- DETECTION_TYPES
|
|||||||
function DETECTION_TYPES:DetectedItemReportSummary( DetectedItem, AttackGroup, Settings )
|
function DETECTION_TYPES:DetectedItemReportSummary( DetectedItem, AttackGroup, Settings )
|
||||||
self:F( { DetectedItem = DetectedItem } )
|
self:F( { DetectedItem = DetectedItem } )
|
||||||
|
|
||||||
local DetectedSet = self:GetDetectedSet( DetectedItem )
|
local DetectedSet = self:GetDetectedItemSet( DetectedItem )
|
||||||
local DetectedItemID = self:GetDetectedItemID( DetectedItem )
|
local DetectedItemID = self:GetDetectedItemID( DetectedItem )
|
||||||
|
|
||||||
self:T( DetectedItem )
|
self:T( DetectedItem )
|
||||||
@ -2409,7 +2411,7 @@ do -- DETECTION_AREAS
|
|||||||
local DetectedItemID = self:GetDetectedItemID( DetectedItem )
|
local DetectedItemID = self:GetDetectedItemID( DetectedItem )
|
||||||
|
|
||||||
if DetectedItem then
|
if DetectedItem then
|
||||||
local DetectedSet = self:GetDetectedSet( DetectedItem )
|
local DetectedSet = self:GetDetectedItemSet( DetectedItem )
|
||||||
local ReportSummaryItem
|
local ReportSummaryItem
|
||||||
|
|
||||||
local DetectedZone = self:GetDetectedItemZone( DetectedItem )
|
local DetectedZone = self:GetDetectedItemZone( DetectedItem )
|
||||||
@ -2774,7 +2776,7 @@ do -- DETECTION_AREAS
|
|||||||
-- If there were friendlies nearby, and now there aren't any friendlies nearby, we flag the area as "changed".
|
-- If there were friendlies nearby, and now there aren't any friendlies nearby, we flag the area as "changed".
|
||||||
-- This is for the A2G dispatcher to detect if there is a change in the tactical situation.
|
-- This is for the A2G dispatcher to detect if there is a change in the tactical situation.
|
||||||
local OldFriendliesNearbyGround = self:IsFriendliesNearBy( DetectedItem, Unit.Category.GROUND_UNIT )
|
local OldFriendliesNearbyGround = self:IsFriendliesNearBy( DetectedItem, Unit.Category.GROUND_UNIT )
|
||||||
self:ReportFriendliesNearBy( { DetectedItem = DetectedItem, ReportSetGroup = self.DetectionSetGroup } ) -- Fill the Friendlies table
|
self:ReportFriendliesNearBy( { DetectedItem = DetectedItem, ReportSetGroup = self.DetectionSet } ) -- Fill the Friendlies table
|
||||||
local NewFriendliesNearbyGround = self:IsFriendliesNearBy( DetectedItem, Unit.Category.GROUND_UNIT )
|
local NewFriendliesNearbyGround = self:IsFriendliesNearBy( DetectedItem, Unit.Category.GROUND_UNIT )
|
||||||
if OldFriendliesNearbyGround ~= NewFriendliesNearbyGround then
|
if OldFriendliesNearbyGround ~= NewFriendliesNearbyGround then
|
||||||
DetectedItem.Changed = true
|
DetectedItem.Changed = true
|
||||||
@ -2821,390 +2823,4 @@ do -- DETECTION_AREAS
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
do -- DETECTION_ZONES
|
|
||||||
|
|
||||||
--- @type DETECTION_ZONES
|
|
||||||
-- @field DCS#Distance DetectionZoneRange The range till which targets are grouped upon the first detected target.
|
|
||||||
-- @field #DETECTION_BASE.DetectedItems DetectedItems A list of areas containing the set of @{Wrapper.Unit}s, @{Zone}s, the center @{Wrapper.Unit} within the zone, and ID of each area that was detected within a DetectionZoneRange.
|
|
||||||
-- @extends Functional.Detection#DETECTION_BASE
|
|
||||||
|
|
||||||
--- Detect units within the battle zone for a list of @{Wrapper.Group}s detecting targets following (a) detection method(s),
|
|
||||||
-- and will build a list (table) of @{Core.Set#SET_UNIT}s containing the @{Wrapper.Unit#UNIT}s detected.
|
|
||||||
-- The class is group the detected units within zones given a DetectedZoneRange parameter.
|
|
||||||
-- A set with multiple detected zones will be created as there are groups of units detected.
|
|
||||||
--
|
|
||||||
-- ## 4.1) Retrieve the Detected Unit Sets and Detected Zones
|
|
||||||
--
|
|
||||||
-- The methods to manage the DetectedItems[].Set(s) are implemented in @{Functional.Detection#DECTECTION_BASE} and
|
|
||||||
-- the methods to manage the DetectedItems[].Zone(s) is implemented in @{Functional.Detection#DETECTION_ZONES}.
|
|
||||||
--
|
|
||||||
-- Retrieve the DetectedItems[].Set with the method @{Functional.Detection#DETECTION_BASE.GetDetectedSet}(). A @{Core.Set#SET_UNIT} object will be returned.
|
|
||||||
--
|
|
||||||
-- Retrieve the formed @{Zone@ZONE_UNIT}s as a result of the grouping the detected units within the DetectionZoneRange, use the method @{Functional.Detection#DETECTION_BASE.GetDetectionZones}().
|
|
||||||
-- To understand the amount of zones created, use the method @{Functional.Detection#DETECTION_BASE.GetDetectionZoneCount}().
|
|
||||||
-- If you want to obtain a specific zone from the DetectedZones, use the method @{Functional.Detection#DETECTION_BASE.GetDetectionZone}() with a given index.
|
|
||||||
--
|
|
||||||
-- ## 4.4) Flare or Smoke detected units
|
|
||||||
--
|
|
||||||
-- Use the methods @{Functional.Detection#DETECTION_ZONES.FlareDetectedUnits}() or @{Functional.Detection#DETECTION_ZONES.SmokeDetectedUnits}() to flare or smoke the detected units when a new detection has taken place.
|
|
||||||
--
|
|
||||||
-- ## 4.5) Flare or Smoke or Bound detected zones
|
|
||||||
--
|
|
||||||
-- Use the methods:
|
|
||||||
--
|
|
||||||
-- * @{Functional.Detection#DETECTION_ZONES.FlareDetectedZones}() to flare in a color
|
|
||||||
-- * @{Functional.Detection#DETECTION_ZONES.SmokeDetectedZones}() to smoke in a color
|
|
||||||
-- * @{Functional.Detection#DETECTION_ZONES.SmokeDetectedZones}() to bound with a tire with a white flag
|
|
||||||
--
|
|
||||||
-- the detected zones when a new detection has taken place.
|
|
||||||
--
|
|
||||||
-- @field #DETECTION_ZONES
|
|
||||||
DETECTION_ZONES = {
|
|
||||||
ClassName = "DETECTION_ZONES",
|
|
||||||
DetectionZoneRange = nil,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
--- DETECTION_ZONES constructor.
|
|
||||||
-- @param #DETECTION_ZONES self
|
|
||||||
-- @param Core.Set#SET_ZONE_RADIUS DetectionSetZone The @{Set} of ZONE_RADIUS.
|
|
||||||
-- @param DCS#Coalition.side DetectionCoalition The coalition of the detection.
|
|
||||||
-- @return #DETECTION_ZONES
|
|
||||||
function DETECTION_ZONES:New( DetectionSetZone, DetectionCoalition )
|
|
||||||
|
|
||||||
-- Inherits from DETECTION_BASE
|
|
||||||
local self = BASE:Inherit( self, DETECTION_BASE:New() )
|
|
||||||
|
|
||||||
self.DetectionSetZone = DetectionSetZone
|
|
||||||
self.DetectionCoalition = DetectionCoalition
|
|
||||||
|
|
||||||
self._SmokeDetectedUnits = false
|
|
||||||
self._FlareDetectedUnits = false
|
|
||||||
self._SmokeDetectedZones = false
|
|
||||||
self._FlareDetectedZones = false
|
|
||||||
self._BoundDetectedZones = false
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Report summary of a detected item using a given numeric index.
|
|
||||||
-- @param #DETECTION_ZONES self
|
|
||||||
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
|
|
||||||
-- @param Wrapper.Group#GROUP AttackGroup The group to get the settings for.
|
|
||||||
-- @param Core.Settings#SETTINGS Settings (Optional) Message formatting settings to use.
|
|
||||||
-- @return Core.Report#REPORT The report of the detection items.
|
|
||||||
function DETECTION_ZONES:DetectedItemReportSummary( DetectedItem, AttackGroup, Settings )
|
|
||||||
self:F( { DetectedItem = DetectedItem } )
|
|
||||||
|
|
||||||
local DetectedItemID = self:GetDetectedItemID( DetectedItem )
|
|
||||||
|
|
||||||
if DetectedItem then
|
|
||||||
local DetectedSet = self:GetDetectedSet( DetectedItem )
|
|
||||||
local ReportSummaryItem
|
|
||||||
|
|
||||||
local DetectedZone = self:GetDetectedItemZone( DetectedItem )
|
|
||||||
local DetectedItemCoordinate = DetectedZone:GetCoordinate()
|
|
||||||
local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup, Settings )
|
|
||||||
|
|
||||||
local ThreatLevelA2G = self:GetDetectedItemThreatLevel( DetectedItem )
|
|
||||||
local DetectedItemsCount = DetectedSet:Count()
|
|
||||||
local DetectedItemsTypes = DetectedSet:GetTypeNames()
|
|
||||||
|
|
||||||
local Report = REPORT:New()
|
|
||||||
Report:Add(DetectedItemID .. ", " .. DetectedItemCoordText)
|
|
||||||
Report:Add( string.format( "Threat: [%s]", string.rep( "■", ThreatLevelA2G ), string.rep( "□", 10-ThreatLevelA2G ) ) )
|
|
||||||
Report:Add( string.format("Type: %2d of %s", DetectedItemsCount, DetectedItemsTypes ) )
|
|
||||||
Report:Add( string.format("Detected: %s", DetectedItem.IsDetected and "yes" or "no" ) )
|
|
||||||
|
|
||||||
return Report
|
|
||||||
end
|
|
||||||
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Report detailed of a detection result.
|
|
||||||
-- @param #DETECTION_ZONES self
|
|
||||||
-- @param Wrapper.Group#GROUP AttackGroup The group to generate the report for.
|
|
||||||
-- @return #string
|
|
||||||
function DETECTION_ZONES:DetectedReportDetailed( AttackGroup ) --R2.1 Fixed missing report
|
|
||||||
self:F()
|
|
||||||
|
|
||||||
local Report = REPORT:New()
|
|
||||||
for DetectedItemIndex, DetectedItem in pairs( self.DetectedItems ) do
|
|
||||||
local DetectedItem = DetectedItem -- #DETECTION_BASE.DetectedItem
|
|
||||||
local ReportSummary = self:DetectedItemReportSummary( DetectedItem, AttackGroup )
|
|
||||||
Report:SetTitle( "Detected areas:" )
|
|
||||||
Report:Add( ReportSummary:Text() )
|
|
||||||
end
|
|
||||||
|
|
||||||
local ReportText = Report:Text()
|
|
||||||
|
|
||||||
return ReportText
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Calculate the optimal intercept point of the DetectedItem.
|
|
||||||
-- @param #DETECTION_ZONES self
|
|
||||||
-- @param #DETECTION_BASE.DetectedItem DetectedItem
|
|
||||||
function DETECTION_ZONES:CalculateIntercept( DetectedItem )
|
|
||||||
|
|
||||||
local DetectedCoord = DetectedItem.Coordinate
|
|
||||||
local DetectedSpeed = DetectedCoord:GetVelocity()
|
|
||||||
local DetectedHeading = DetectedCoord:GetHeading()
|
|
||||||
|
|
||||||
if self.Intercept then
|
|
||||||
local DetectedSet = DetectedItem.Set
|
|
||||||
-- todo: speed
|
|
||||||
|
|
||||||
local TranslateDistance = DetectedSpeed * self.InterceptDelay
|
|
||||||
|
|
||||||
local InterceptCoord = DetectedCoord:Translate( TranslateDistance, DetectedHeading )
|
|
||||||
|
|
||||||
DetectedItem.InterceptCoord = InterceptCoord
|
|
||||||
else
|
|
||||||
DetectedItem.InterceptCoord = DetectedCoord
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Smoke the detected units
|
|
||||||
-- @param #DETECTION_ZONES self
|
|
||||||
-- @return #DETECTION_ZONES self
|
|
||||||
function DETECTION_ZONES:SmokeDetectedUnits()
|
|
||||||
self:F2()
|
|
||||||
|
|
||||||
self._SmokeDetectedUnits = true
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Flare the detected units
|
|
||||||
-- @param #DETECTION_ZONES self
|
|
||||||
-- @return #DETECTION_ZONES self
|
|
||||||
function DETECTION_ZONES:FlareDetectedUnits()
|
|
||||||
self:F2()
|
|
||||||
|
|
||||||
self._FlareDetectedUnits = true
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Smoke the detected zones
|
|
||||||
-- @param #DETECTION_ZONES self
|
|
||||||
-- @return #DETECTION_ZONES self
|
|
||||||
function DETECTION_ZONES:SmokeDetectedZones()
|
|
||||||
self:F2()
|
|
||||||
|
|
||||||
self._SmokeDetectedZones = true
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Flare the detected zones
|
|
||||||
-- @param #DETECTION_ZONES self
|
|
||||||
-- @return #DETECTION_ZONES self
|
|
||||||
function DETECTION_ZONES:FlareDetectedZones()
|
|
||||||
self:F2()
|
|
||||||
|
|
||||||
self._FlareDetectedZones = true
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Bound the detected zones
|
|
||||||
-- @param #DETECTION_ZONES self
|
|
||||||
-- @return #DETECTION_ZONES self
|
|
||||||
function DETECTION_ZONES:BoundDetectedZones()
|
|
||||||
self:F2()
|
|
||||||
|
|
||||||
self._BoundDetectedZones = true
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Make text documenting the changes of the detected zone.
|
|
||||||
-- @param #DETECTION_ZONES self
|
|
||||||
-- @param #DETECTION_BASE.DetectedItem DetectedItem
|
|
||||||
-- @return #string The Changes text
|
|
||||||
function DETECTION_ZONES:GetChangeText( DetectedItem )
|
|
||||||
self:F( DetectedItem )
|
|
||||||
|
|
||||||
local MT = {}
|
|
||||||
|
|
||||||
for ChangeCode, ChangeData in pairs( DetectedItem.Changes ) do
|
|
||||||
|
|
||||||
if ChangeCode == "AA" then
|
|
||||||
MT[#MT+1] = "Detected new area " .. ChangeData.ID .. ". The center target is a " .. ChangeData.ItemUnitType .. "."
|
|
||||||
end
|
|
||||||
|
|
||||||
if ChangeCode == "RAU" then
|
|
||||||
MT[#MT+1] = "Changed area " .. ChangeData.ID .. ". Removed the center target."
|
|
||||||
end
|
|
||||||
|
|
||||||
if ChangeCode == "AAU" then
|
|
||||||
MT[#MT+1] = "Changed area " .. ChangeData.ID .. ". The new center target is a " .. ChangeData.ItemUnitType .. "."
|
|
||||||
end
|
|
||||||
|
|
||||||
if ChangeCode == "RA" then
|
|
||||||
MT[#MT+1] = "Removed old area " .. ChangeData.ID .. ". No more targets in this area."
|
|
||||||
end
|
|
||||||
|
|
||||||
if ChangeCode == "AU" then
|
|
||||||
local MTUT = {}
|
|
||||||
for ChangeUnitType, ChangeUnitCount in pairs( ChangeData ) do
|
|
||||||
if ChangeUnitType ~= "ID" then
|
|
||||||
MTUT[#MTUT+1] = ChangeUnitCount .. " of " .. ChangeUnitType
|
|
||||||
end
|
|
||||||
end
|
|
||||||
MT[#MT+1] = "Detected for area " .. ChangeData.ID .. " new target(s) " .. table.concat( MTUT, ", " ) .. "."
|
|
||||||
end
|
|
||||||
|
|
||||||
if ChangeCode == "RU" then
|
|
||||||
local MTUT = {}
|
|
||||||
for ChangeUnitType, ChangeUnitCount in pairs( ChangeData ) do
|
|
||||||
if ChangeUnitType ~= "ID" then
|
|
||||||
MTUT[#MTUT+1] = ChangeUnitCount .. " of " .. ChangeUnitType
|
|
||||||
end
|
|
||||||
end
|
|
||||||
MT[#MT+1] = "Removed for area " .. ChangeData.ID .. " invisible or destroyed target(s) " .. table.concat( MTUT, ", " ) .. "."
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
return table.concat( MT, "\n" )
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Make a DetectionSet table. This function will be overridden in the derived clsses.
|
|
||||||
-- @param #DETECTION_ZONES self
|
|
||||||
-- @return #DETECTION_ZONES self
|
|
||||||
function DETECTION_ZONES:CreateDetectionItems()
|
|
||||||
|
|
||||||
|
|
||||||
self:F( "Checking Detected Items for new Detected Units ..." )
|
|
||||||
|
|
||||||
local DetectedUnits = SET_UNIT:New()
|
|
||||||
|
|
||||||
-- First go through all detected sets, and check if there are new detected units, match all existing detected units and identify undetected units.
|
|
||||||
-- Regroup when needed, split groups when needed.
|
|
||||||
for ZoneName, DetectionZone in pairs( self.DetectionSetZones:GetSet() ) do
|
|
||||||
|
|
||||||
local DetectedItem = self:GetDetectedItemByKey( ZoneName )
|
|
||||||
|
|
||||||
if DetectedItem == nil then
|
|
||||||
DetectedItem = self:AddDetectedItemZone( "ZONE", ZoneName, nil, DetectionZone )
|
|
||||||
end
|
|
||||||
|
|
||||||
local DetectedItemSetUnit = self
|
|
||||||
|
|
||||||
-- Scan the zone
|
|
||||||
DetectionZone:Scan( { Object.Category.UNIT }, { Unit.Category.GROUND_UNIT } )
|
|
||||||
|
|
||||||
local ZoneUnits = DetectionZone:GetScannedUnits()
|
|
||||||
for DCSUnitID, DCSUnit in pairs( ZoneUnits ) do
|
|
||||||
local UnitName = DCSUnit:getName()
|
|
||||||
local ZoneUnit = UNIT:FindByName( UnitName )
|
|
||||||
local ZoneUnitCoalition = ZoneUnit:GetCoalition()
|
|
||||||
if ZoneUnitCoalition == self.DetectionCoalition then
|
|
||||||
if DetectedUnits:FindUnit( UnitName ) ~= nil then
|
|
||||||
DetectedItemSetUnit:AddUnit( ZoneUnit )
|
|
||||||
DetectedUnits:AddUnit( ZoneUnit )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Now all the tests should have been build, now make some smoke and flares...
|
|
||||||
-- We also report here the friendlies within the detected areas.
|
|
||||||
|
|
||||||
for DetectedItemID, DetectedItemData in pairs( self.DetectedItems ) do
|
|
||||||
|
|
||||||
local DetectedItem = DetectedItemData -- #DETECTION_BASE.DetectedItem
|
|
||||||
local DetectedSet = DetectedItem.Set
|
|
||||||
local DetectedFirstUnit = DetectedSet:GetFirst()
|
|
||||||
local DetectedZone = DetectedItem.Zone
|
|
||||||
|
|
||||||
-- Set the last known coordinate to the detection item.
|
|
||||||
local DetectedZoneCoord = DetectedZone:GetCoordinate()
|
|
||||||
self:SetDetectedItemCoordinate( DetectedItem, DetectedZoneCoord, DetectedFirstUnit )
|
|
||||||
|
|
||||||
self:CalculateIntercept( DetectedItem )
|
|
||||||
|
|
||||||
-- We search for friendlies nearby.
|
|
||||||
-- If there weren't any friendlies nearby, and now there are friendlies nearby, we flag the area as "changed".
|
|
||||||
-- If there were friendlies nearby, and now there aren't any friendlies nearby, we flag the area as "changed".
|
|
||||||
-- This is for the A2G dispatcher to detect if there is a change in the tactical situation.
|
|
||||||
local OldFriendliesNearbyGround = self:IsFriendliesNearBy( DetectedItem, Unit.Category.GROUND_UNIT )
|
|
||||||
self:ReportFriendliesNearBy( { DetectedItem = DetectedItem, ReportSetGroup = self.DetectionSetGroup } ) -- Fill the Friendlies table
|
|
||||||
local NewFriendliesNearbyGround = self:IsFriendliesNearBy( DetectedItem, Unit.Category.GROUND_UNIT )
|
|
||||||
if OldFriendliesNearbyGround ~= NewFriendliesNearbyGround then
|
|
||||||
DetectedItem.Changed = true
|
|
||||||
end
|
|
||||||
|
|
||||||
self:SetDetectedItemThreatLevel( DetectedItem ) -- Calculate A2G threat level
|
|
||||||
self:NearestRecce( DetectedItem )
|
|
||||||
|
|
||||||
|
|
||||||
if DETECTION_ZONES._SmokeDetectedUnits or self._SmokeDetectedUnits then
|
|
||||||
DetectedZone.ZoneUNIT:SmokeRed()
|
|
||||||
end
|
|
||||||
|
|
||||||
--DetectedSet:Flush( self )
|
|
||||||
|
|
||||||
DetectedSet:ForEachUnit(
|
|
||||||
--- @param Wrapper.Unit#UNIT DetectedUnit
|
|
||||||
function( DetectedUnit )
|
|
||||||
if DetectedUnit:IsAlive() then
|
|
||||||
--self:T( "Detected Set #" .. DetectedItem.ID .. ":" .. DetectedUnit:GetName() )
|
|
||||||
if DETECTION_ZONES._FlareDetectedUnits or self._FlareDetectedUnits then
|
|
||||||
DetectedUnit:FlareGreen()
|
|
||||||
end
|
|
||||||
if DETECTION_ZONES._SmokeDetectedUnits or self._SmokeDetectedUnits then
|
|
||||||
DetectedUnit:SmokeGreen()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
)
|
|
||||||
if DETECTION_ZONES._FlareDetectedZones or self._FlareDetectedZones then
|
|
||||||
DetectedZone:FlareZone( SMOKECOLOR.White, 30, math.random( 0,90 ) )
|
|
||||||
end
|
|
||||||
if DETECTION_ZONES._SmokeDetectedZones or self._SmokeDetectedZones then
|
|
||||||
DetectedZone:SmokeZone( SMOKECOLOR.White, 30 )
|
|
||||||
end
|
|
||||||
|
|
||||||
if DETECTION_ZONES._BoundDetectedZones or self._BoundDetectedZones then
|
|
||||||
self.CountryID = DetectedSet:GetFirst():GetCountry()
|
|
||||||
DetectedZone:BoundZone( 12, self.CountryID )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
--- @param #DETECTION_ZONES self
|
|
||||||
-- @param #string From The From State string.
|
|
||||||
-- @param #string Event The Event string.
|
|
||||||
-- @param #string To The To State string.
|
|
||||||
-- @param Detection The element on which the detection is based.
|
|
||||||
-- @param #number DetectionTimeStamp Time stamp of detection event.
|
|
||||||
function DETECTION_ZONES:onafterDetection( From, Event, To, Detection, DetectionTimeStamp )
|
|
||||||
|
|
||||||
self:CreateDetectionItems() -- Polymorphic call to Create/Update the DetectionItems list for the DETECTION_ class grouping method.
|
|
||||||
|
|
||||||
for DetectedItemID, DetectedItem in pairs( self.DetectedItems ) do
|
|
||||||
self:UpdateDetectedItemDetection( DetectedItem )
|
|
||||||
self:CleanDetectionItem( DetectedItem, DetectedItemID ) -- Any DetectionItem that has a Set with zero elements in it, must be removed from the DetectionItems list.
|
|
||||||
if DetectedItem then
|
|
||||||
self:__DetectedItem( 0.1, DetectedItem )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
self:__Detect( self.RefreshTimeInterval )
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|||||||
403
Moose Development/Moose/Functional/DetectionZones.lua
Normal file
403
Moose Development/Moose/Functional/DetectionZones.lua
Normal file
@ -0,0 +1,403 @@
|
|||||||
|
do -- DETECTION_ZONES
|
||||||
|
|
||||||
|
--- @type DETECTION_ZONES
|
||||||
|
-- @field DCS#Distance DetectionZoneRange The range till which targets are grouped upon the first detected target.
|
||||||
|
-- @field #DETECTION_BASE.DetectedItems DetectedItems A list of areas containing the set of @{Wrapper.Unit}s, @{Zone}s, the center @{Wrapper.Unit} within the zone, and ID of each area that was detected within a DetectionZoneRange.
|
||||||
|
-- @extends Functional.Detection#DETECTION_BASE
|
||||||
|
|
||||||
|
--- (old, to be revised ) Detect units within the battle zone for a list of @{Core.Zone}s detecting targets following (a) detection method(s),
|
||||||
|
-- and will build a list (table) of @{Core.Set#SET_UNIT}s containing the @{Wrapper.Unit#UNIT}s detected.
|
||||||
|
-- The class is group the detected units within zones given a DetectedZoneRange parameter.
|
||||||
|
-- A set with multiple detected zones will be created as there are groups of units detected.
|
||||||
|
--
|
||||||
|
-- ## 4.1) Retrieve the Detected Unit Sets and Detected Zones
|
||||||
|
--
|
||||||
|
-- The methods to manage the DetectedItems[].Set(s) are implemented in @{Functional.Detection#DECTECTION_BASE} and
|
||||||
|
-- the methods to manage the DetectedItems[].Zone(s) is implemented in @{Functional.Detection#DETECTION_ZONES}.
|
||||||
|
--
|
||||||
|
-- Retrieve the DetectedItems[].Set with the method @{Functional.Detection#DETECTION_BASE.GetDetectedSet}(). A @{Core.Set#SET_UNIT} object will be returned.
|
||||||
|
--
|
||||||
|
-- Retrieve the formed @{Zone@ZONE_UNIT}s as a result of the grouping the detected units within the DetectionZoneRange, use the method @{Functional.Detection#DETECTION_BASE.GetDetectionZones}().
|
||||||
|
-- To understand the amount of zones created, use the method @{Functional.Detection#DETECTION_BASE.GetDetectionZoneCount}().
|
||||||
|
-- If you want to obtain a specific zone from the DetectedZones, use the method @{Functional.Detection#DETECTION_BASE.GetDetectionZone}() with a given index.
|
||||||
|
--
|
||||||
|
-- ## 4.4) Flare or Smoke detected units
|
||||||
|
--
|
||||||
|
-- Use the methods @{Functional.Detection#DETECTION_ZONES.FlareDetectedUnits}() or @{Functional.Detection#DETECTION_ZONES.SmokeDetectedUnits}() to flare or smoke the detected units when a new detection has taken place.
|
||||||
|
--
|
||||||
|
-- ## 4.5) Flare or Smoke or Bound detected zones
|
||||||
|
--
|
||||||
|
-- Use the methods:
|
||||||
|
--
|
||||||
|
-- * @{Functional.Detection#DETECTION_ZONES.FlareDetectedZones}() to flare in a color
|
||||||
|
-- * @{Functional.Detection#DETECTION_ZONES.SmokeDetectedZones}() to smoke in a color
|
||||||
|
-- * @{Functional.Detection#DETECTION_ZONES.SmokeDetectedZones}() to bound with a tire with a white flag
|
||||||
|
--
|
||||||
|
-- the detected zones when a new detection has taken place.
|
||||||
|
--
|
||||||
|
-- @field #DETECTION_ZONES
|
||||||
|
DETECTION_ZONES = {
|
||||||
|
ClassName = "DETECTION_ZONES",
|
||||||
|
DetectionZoneRange = nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--- DETECTION_ZONES constructor.
|
||||||
|
-- @param #DETECTION_ZONES self
|
||||||
|
-- @param Core.Set#SET_ZONE_RADIUS DetectionSetZone The @{Set} of ZONE_RADIUS.
|
||||||
|
-- @param DCS#Coalition.side DetectionCoalition The coalition of the detection.
|
||||||
|
-- @return #DETECTION_ZONES
|
||||||
|
function DETECTION_ZONES:New( DetectionSetZone, DetectionCoalition )
|
||||||
|
|
||||||
|
-- Inherits from DETECTION_BASE
|
||||||
|
local self = BASE:Inherit( self, DETECTION_BASE:New( DetectionSetZone ) )
|
||||||
|
|
||||||
|
self.DetectionSetZone = DetectionSetZone
|
||||||
|
self.DetectionCoalition = DetectionCoalition
|
||||||
|
|
||||||
|
self._SmokeDetectedUnits = false
|
||||||
|
self._FlareDetectedUnits = false
|
||||||
|
self._SmokeDetectedZones = false
|
||||||
|
self._FlareDetectedZones = false
|
||||||
|
self._BoundDetectedZones = false
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Report summary of a detected item using a given numeric index.
|
||||||
|
-- @param #DETECTION_ZONES self
|
||||||
|
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
|
||||||
|
-- @param Wrapper.Group#GROUP AttackGroup The group to get the settings for.
|
||||||
|
-- @param Core.Settings#SETTINGS Settings (Optional) Message formatting settings to use.
|
||||||
|
-- @return Core.Report#REPORT The report of the detection items.
|
||||||
|
function DETECTION_ZONES:DetectedItemReportSummary( DetectedItem, AttackGroup, Settings )
|
||||||
|
self:F( { DetectedItem = DetectedItem } )
|
||||||
|
|
||||||
|
local DetectedItemID = self:GetDetectedItemID( DetectedItem )
|
||||||
|
|
||||||
|
if DetectedItem then
|
||||||
|
local DetectedSet = self:GetDetectedItemSet( DetectedItem )
|
||||||
|
local ReportSummaryItem
|
||||||
|
|
||||||
|
local DetectedZone = self:GetDetectedItemZone( DetectedItem )
|
||||||
|
local DetectedItemCoordinate = DetectedZone:GetCoordinate()
|
||||||
|
local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup, Settings )
|
||||||
|
|
||||||
|
local ThreatLevelA2G = self:GetDetectedItemThreatLevel( DetectedItem )
|
||||||
|
local DetectedItemsCount = DetectedSet:Count()
|
||||||
|
local DetectedItemsTypes = DetectedSet:GetTypeNames()
|
||||||
|
|
||||||
|
local Report = REPORT:New()
|
||||||
|
Report:Add(DetectedItemID .. ", " .. DetectedItemCoordText)
|
||||||
|
Report:Add( string.format( "Threat: [%s]", string.rep( "■", ThreatLevelA2G ), string.rep( "□", 10-ThreatLevelA2G ) ) )
|
||||||
|
Report:Add( string.format("Type: %2d of %s", DetectedItemsCount, DetectedItemsTypes ) )
|
||||||
|
Report:Add( string.format("Detected: %s", DetectedItem.IsDetected and "yes" or "no" ) )
|
||||||
|
|
||||||
|
return Report
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Report detailed of a detection result.
|
||||||
|
-- @param #DETECTION_ZONES self
|
||||||
|
-- @param Wrapper.Group#GROUP AttackGroup The group to generate the report for.
|
||||||
|
-- @return #string
|
||||||
|
function DETECTION_ZONES:DetectedReportDetailed( AttackGroup ) --R2.1 Fixed missing report
|
||||||
|
self:F()
|
||||||
|
|
||||||
|
local Report = REPORT:New()
|
||||||
|
for DetectedItemIndex, DetectedItem in pairs( self.DetectedItems ) do
|
||||||
|
local DetectedItem = DetectedItem -- #DETECTION_BASE.DetectedItem
|
||||||
|
local ReportSummary = self:DetectedItemReportSummary( DetectedItem, AttackGroup )
|
||||||
|
Report:SetTitle( "Detected areas:" )
|
||||||
|
Report:Add( ReportSummary:Text() )
|
||||||
|
end
|
||||||
|
|
||||||
|
local ReportText = Report:Text()
|
||||||
|
|
||||||
|
return ReportText
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Calculate the optimal intercept point of the DetectedItem.
|
||||||
|
-- @param #DETECTION_ZONES self
|
||||||
|
-- @param #DETECTION_BASE.DetectedItem DetectedItem
|
||||||
|
function DETECTION_ZONES:CalculateIntercept( DetectedItem )
|
||||||
|
|
||||||
|
local DetectedCoord = DetectedItem.Coordinate
|
||||||
|
local DetectedSpeed = DetectedCoord:GetVelocity()
|
||||||
|
local DetectedHeading = DetectedCoord:GetHeading()
|
||||||
|
|
||||||
|
if self.Intercept then
|
||||||
|
local DetectedSet = DetectedItem.Set
|
||||||
|
-- todo: speed
|
||||||
|
|
||||||
|
local TranslateDistance = DetectedSpeed * self.InterceptDelay
|
||||||
|
|
||||||
|
local InterceptCoord = DetectedCoord:Translate( TranslateDistance, DetectedHeading )
|
||||||
|
|
||||||
|
DetectedItem.InterceptCoord = InterceptCoord
|
||||||
|
else
|
||||||
|
DetectedItem.InterceptCoord = DetectedCoord
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Smoke the detected units
|
||||||
|
-- @param #DETECTION_ZONES self
|
||||||
|
-- @return #DETECTION_ZONES self
|
||||||
|
function DETECTION_ZONES:SmokeDetectedUnits()
|
||||||
|
self:F2()
|
||||||
|
|
||||||
|
self._SmokeDetectedUnits = true
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Flare the detected units
|
||||||
|
-- @param #DETECTION_ZONES self
|
||||||
|
-- @return #DETECTION_ZONES self
|
||||||
|
function DETECTION_ZONES:FlareDetectedUnits()
|
||||||
|
self:F2()
|
||||||
|
|
||||||
|
self._FlareDetectedUnits = true
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Smoke the detected zones
|
||||||
|
-- @param #DETECTION_ZONES self
|
||||||
|
-- @return #DETECTION_ZONES self
|
||||||
|
function DETECTION_ZONES:SmokeDetectedZones()
|
||||||
|
self:F2()
|
||||||
|
|
||||||
|
self._SmokeDetectedZones = true
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Flare the detected zones
|
||||||
|
-- @param #DETECTION_ZONES self
|
||||||
|
-- @return #DETECTION_ZONES self
|
||||||
|
function DETECTION_ZONES:FlareDetectedZones()
|
||||||
|
self:F2()
|
||||||
|
|
||||||
|
self._FlareDetectedZones = true
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Bound the detected zones
|
||||||
|
-- @param #DETECTION_ZONES self
|
||||||
|
-- @return #DETECTION_ZONES self
|
||||||
|
function DETECTION_ZONES:BoundDetectedZones()
|
||||||
|
self:F2()
|
||||||
|
|
||||||
|
self._BoundDetectedZones = true
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Make text documenting the changes of the detected zone.
|
||||||
|
-- @param #DETECTION_ZONES self
|
||||||
|
-- @param #DETECTION_BASE.DetectedItem DetectedItem
|
||||||
|
-- @return #string The Changes text
|
||||||
|
function DETECTION_ZONES:GetChangeText( DetectedItem )
|
||||||
|
self:F( DetectedItem )
|
||||||
|
|
||||||
|
local MT = {}
|
||||||
|
|
||||||
|
for ChangeCode, ChangeData in pairs( DetectedItem.Changes ) do
|
||||||
|
|
||||||
|
if ChangeCode == "AA" then
|
||||||
|
MT[#MT+1] = "Detected new area " .. ChangeData.ID .. ". The center target is a " .. ChangeData.ItemUnitType .. "."
|
||||||
|
end
|
||||||
|
|
||||||
|
if ChangeCode == "RAU" then
|
||||||
|
MT[#MT+1] = "Changed area " .. ChangeData.ID .. ". Removed the center target."
|
||||||
|
end
|
||||||
|
|
||||||
|
if ChangeCode == "AAU" then
|
||||||
|
MT[#MT+1] = "Changed area " .. ChangeData.ID .. ". The new center target is a " .. ChangeData.ItemUnitType .. "."
|
||||||
|
end
|
||||||
|
|
||||||
|
if ChangeCode == "RA" then
|
||||||
|
MT[#MT+1] = "Removed old area " .. ChangeData.ID .. ". No more targets in this area."
|
||||||
|
end
|
||||||
|
|
||||||
|
if ChangeCode == "AU" then
|
||||||
|
local MTUT = {}
|
||||||
|
for ChangeUnitType, ChangeUnitCount in pairs( ChangeData ) do
|
||||||
|
if ChangeUnitType ~= "ID" then
|
||||||
|
MTUT[#MTUT+1] = ChangeUnitCount .. " of " .. ChangeUnitType
|
||||||
|
end
|
||||||
|
end
|
||||||
|
MT[#MT+1] = "Detected for area " .. ChangeData.ID .. " new target(s) " .. table.concat( MTUT, ", " ) .. "."
|
||||||
|
end
|
||||||
|
|
||||||
|
if ChangeCode == "RU" then
|
||||||
|
local MTUT = {}
|
||||||
|
for ChangeUnitType, ChangeUnitCount in pairs( ChangeData ) do
|
||||||
|
if ChangeUnitType ~= "ID" then
|
||||||
|
MTUT[#MTUT+1] = ChangeUnitCount .. " of " .. ChangeUnitType
|
||||||
|
end
|
||||||
|
end
|
||||||
|
MT[#MT+1] = "Removed for area " .. ChangeData.ID .. " invisible or destroyed target(s) " .. table.concat( MTUT, ", " ) .. "."
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return table.concat( MT, "\n" )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Make a DetectionSet table. This function will be overridden in the derived clsses.
|
||||||
|
-- @param #DETECTION_ZONES self
|
||||||
|
-- @return #DETECTION_ZONES self
|
||||||
|
function DETECTION_ZONES:CreateDetectionItems()
|
||||||
|
|
||||||
|
|
||||||
|
self:F( "Checking Detected Items for new Detected Units ..." )
|
||||||
|
|
||||||
|
local DetectedUnits = SET_UNIT:New()
|
||||||
|
|
||||||
|
-- First go through all detected sets, and check if there are new detected units, match all existing detected units and identify undetected units.
|
||||||
|
-- Regroup when needed, split groups when needed.
|
||||||
|
for ZoneName, DetectionZone in pairs( self.DetectionSetZone:GetSet() ) do
|
||||||
|
|
||||||
|
local DetectedItem = self:GetDetectedItemByKey( ZoneName )
|
||||||
|
|
||||||
|
if DetectedItem == nil then
|
||||||
|
DetectedItem = self:AddDetectedItemZone( "ZONE", ZoneName, nil, DetectionZone )
|
||||||
|
end
|
||||||
|
|
||||||
|
local DetectedItemSetUnit = self:GetDetectedItemSet( DetectedItem )
|
||||||
|
|
||||||
|
-- Scan the zone
|
||||||
|
DetectionZone:Scan( { Object.Category.UNIT }, { Unit.Category.GROUND_UNIT } )
|
||||||
|
|
||||||
|
local ZoneUnits = DetectionZone:GetScannedUnits()
|
||||||
|
for DCSUnitID, DCSUnit in pairs( ZoneUnits ) do
|
||||||
|
local UnitName = DCSUnit:getName()
|
||||||
|
local ZoneUnit = UNIT:FindByName( UnitName )
|
||||||
|
local ZoneUnitCoalition = ZoneUnit:GetCoalition()
|
||||||
|
if ZoneUnitCoalition == self.DetectionCoalition then
|
||||||
|
if DetectedItemSetUnit:FindUnit( UnitName ) == nil and DetectedUnits:FindUnit( UnitName ) == nil then
|
||||||
|
self:F( "Adding " .. UnitName )
|
||||||
|
DetectedItemSetUnit:AddUnit( ZoneUnit )
|
||||||
|
DetectedUnits:AddUnit( ZoneUnit )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- Now all the tests should have been build, now make some smoke and flares...
|
||||||
|
-- We also report here the friendlies within the detected areas.
|
||||||
|
|
||||||
|
for DetectedItemID, DetectedItemData in pairs( self.DetectedItems ) do
|
||||||
|
|
||||||
|
local DetectedItem = DetectedItemData -- #DETECTION_BASE.DetectedItem
|
||||||
|
local DetectedSet = self:GetDetectedItemSet( DetectedItem )
|
||||||
|
local DetectedFirstUnit = DetectedSet:GetFirst()
|
||||||
|
local DetectedZone = self:GetDetectedItemZone( DetectedItem )
|
||||||
|
|
||||||
|
-- Set the last known coordinate to the detection item.
|
||||||
|
local DetectedZoneCoord = DetectedZone:GetCoordinate()
|
||||||
|
self:SetDetectedItemCoordinate( DetectedItem, DetectedZoneCoord, DetectedFirstUnit )
|
||||||
|
|
||||||
|
self:CalculateIntercept( DetectedItem )
|
||||||
|
|
||||||
|
-- We search for friendlies nearby.
|
||||||
|
-- If there weren't any friendlies nearby, and now there are friendlies nearby, we flag the area as "changed".
|
||||||
|
-- If there were friendlies nearby, and now there aren't any friendlies nearby, we flag the area as "changed".
|
||||||
|
-- This is for the A2G dispatcher to detect if there is a change in the tactical situation.
|
||||||
|
local OldFriendliesNearbyGround = self:IsFriendliesNearBy( DetectedItem, Unit.Category.GROUND_UNIT )
|
||||||
|
self:ReportFriendliesNearBy( { DetectedItem = DetectedItem, ReportSetGroup = self.DetectionSetGroup } ) -- Fill the Friendlies table
|
||||||
|
local NewFriendliesNearbyGround = self:IsFriendliesNearBy( DetectedItem, Unit.Category.GROUND_UNIT )
|
||||||
|
if OldFriendliesNearbyGround ~= NewFriendliesNearbyGround then
|
||||||
|
DetectedItem.Changed = true
|
||||||
|
end
|
||||||
|
|
||||||
|
self:SetDetectedItemThreatLevel( DetectedItem ) -- Calculate A2G threat level
|
||||||
|
--self:NearestRecce( DetectedItem )
|
||||||
|
|
||||||
|
|
||||||
|
if DETECTION_ZONES._SmokeDetectedUnits or self._SmokeDetectedUnits then
|
||||||
|
DetectedZone:SmokeZone( SMOKECOLOR.Red, 30 )
|
||||||
|
end
|
||||||
|
|
||||||
|
--DetectedSet:Flush( self )
|
||||||
|
|
||||||
|
DetectedSet:ForEachUnit(
|
||||||
|
--- @param Wrapper.Unit#UNIT DetectedUnit
|
||||||
|
function( DetectedUnit )
|
||||||
|
if DetectedUnit:IsAlive() then
|
||||||
|
--self:T( "Detected Set #" .. DetectedItem.ID .. ":" .. DetectedUnit:GetName() )
|
||||||
|
if DETECTION_ZONES._FlareDetectedUnits or self._FlareDetectedUnits then
|
||||||
|
DetectedUnit:FlareGreen()
|
||||||
|
end
|
||||||
|
if DETECTION_ZONES._SmokeDetectedUnits or self._SmokeDetectedUnits then
|
||||||
|
DetectedUnit:SmokeGreen()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
)
|
||||||
|
if DETECTION_ZONES._FlareDetectedZones or self._FlareDetectedZones then
|
||||||
|
DetectedZone:FlareZone( SMOKECOLOR.White, 30, math.random( 0,90 ) )
|
||||||
|
end
|
||||||
|
if DETECTION_ZONES._SmokeDetectedZones or self._SmokeDetectedZones then
|
||||||
|
DetectedZone:SmokeZone( SMOKECOLOR.White, 30 )
|
||||||
|
end
|
||||||
|
|
||||||
|
if DETECTION_ZONES._BoundDetectedZones or self._BoundDetectedZones then
|
||||||
|
self.CountryID = DetectedSet:GetFirst():GetCountry()
|
||||||
|
DetectedZone:BoundZone( 12, self.CountryID )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param #DETECTION_ZONES self
|
||||||
|
-- @param #string From The From State string.
|
||||||
|
-- @param #string Event The Event string.
|
||||||
|
-- @param #string To The To State string.
|
||||||
|
-- @param Detection The element on which the detection is based.
|
||||||
|
-- @param #number DetectionTimeStamp Time stamp of detection event.
|
||||||
|
function DETECTION_ZONES:onafterDetection( From, Event, To, Detection, DetectionTimeStamp )
|
||||||
|
|
||||||
|
self.DetectionRun = self.DetectionRun + 1
|
||||||
|
if self.DetectionCount > 0 and self.DetectionRun == self.DetectionCount then
|
||||||
|
self:CreateDetectionItems() -- Polymorphic call to Create/Update the DetectionItems list for the DETECTION_ class grouping method.
|
||||||
|
|
||||||
|
for DetectedItemID, DetectedItem in pairs( self.DetectedItems ) do
|
||||||
|
self:UpdateDetectedItemDetection( DetectedItem )
|
||||||
|
self:CleanDetectionItem( DetectedItem, DetectedItemID ) -- Any DetectionItem that has a Set with zero elements in it, must be removed from the DetectionItems list.
|
||||||
|
if DetectedItem then
|
||||||
|
self:__DetectedItem( 0.1, DetectedItem )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self:__Detect( self.RefreshTimeInterval )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set IsDetected flag for the DetectedItem, which can have more units.
|
||||||
|
-- @param #DETECTION_ZONES self
|
||||||
|
-- @return #DETECTION_ZONES.DetectedItem DetectedItem
|
||||||
|
-- @return #boolean true if at least one UNIT is detected from the DetectedSet, false if no UNIT was detected from the DetectedSet.
|
||||||
|
function DETECTION_ZONES:UpdateDetectedItemDetection( DetectedItem )
|
||||||
|
|
||||||
|
local IsDetected = true
|
||||||
|
|
||||||
|
DetectedItem.IsDetected = true
|
||||||
|
|
||||||
|
return IsDetected
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
@ -872,7 +872,7 @@ function ESCORT:_AttackTarget( DetectedItem )
|
|||||||
EscortGroup:OptionROTPassiveDefense()
|
EscortGroup:OptionROTPassiveDefense()
|
||||||
EscortGroup:SetState( EscortGroup, "Escort", self )
|
EscortGroup:SetState( EscortGroup, "Escort", self )
|
||||||
|
|
||||||
local DetectedSet = self.Detection:GetDetectedSet( DetectedItem )
|
local DetectedSet = self.Detection:GetDetectedItemSet( DetectedItem )
|
||||||
|
|
||||||
local Tasks = {}
|
local Tasks = {}
|
||||||
|
|
||||||
@ -895,7 +895,7 @@ function ESCORT:_AttackTarget( DetectedItem )
|
|||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
local DetectedSet = self.Detection:GetDetectedSet( DetectedItem )
|
local DetectedSet = self.Detection:GetDetectedItemSet( DetectedItem )
|
||||||
|
|
||||||
local Tasks = {}
|
local Tasks = {}
|
||||||
|
|
||||||
@ -934,7 +934,7 @@ function ESCORT:_AssistTarget( EscortGroupAttack, DetectedItem )
|
|||||||
EscortGroupAttack:OptionROEOpenFire()
|
EscortGroupAttack:OptionROEOpenFire()
|
||||||
EscortGroupAttack:OptionROTVertical()
|
EscortGroupAttack:OptionROTVertical()
|
||||||
|
|
||||||
local DetectedSet = self.Detection:GetDetectedSet( DetectedItem )
|
local DetectedSet = self.Detection:GetDetectedItemSet( DetectedItem )
|
||||||
|
|
||||||
local Tasks = {}
|
local Tasks = {}
|
||||||
|
|
||||||
@ -956,7 +956,7 @@ function ESCORT:_AssistTarget( EscortGroupAttack, DetectedItem )
|
|||||||
)
|
)
|
||||||
|
|
||||||
else
|
else
|
||||||
local DetectedSet = self.Detection:GetDetectedSet( DetectedItem )
|
local DetectedSet = self.Detection:GetDetectedItemSet( DetectedItem )
|
||||||
|
|
||||||
local Tasks = {}
|
local Tasks = {}
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,7 @@ __Moose.Include( 'Scripts/Moose/Functional/Escort.lua' )
|
|||||||
__Moose.Include( 'Scripts/Moose/Functional/MissileTrainer.lua' )
|
__Moose.Include( 'Scripts/Moose/Functional/MissileTrainer.lua' )
|
||||||
__Moose.Include( 'Scripts/Moose/Functional/ATC_Ground.lua' )
|
__Moose.Include( 'Scripts/Moose/Functional/ATC_Ground.lua' )
|
||||||
__Moose.Include( 'Scripts/Moose/Functional/Detection.lua' )
|
__Moose.Include( 'Scripts/Moose/Functional/Detection.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/DetectionZones.lua' )
|
||||||
__Moose.Include( 'Scripts/Moose/Functional/Designate.lua' )
|
__Moose.Include( 'Scripts/Moose/Functional/Designate.lua' )
|
||||||
__Moose.Include( 'Scripts/Moose/Functional/RAT.lua' )
|
__Moose.Include( 'Scripts/Moose/Functional/RAT.lua' )
|
||||||
__Moose.Include( 'Scripts/Moose/Functional/Range.lua' )
|
__Moose.Include( 'Scripts/Moose/Functional/Range.lua' )
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user