Implemented the linking of TASK_CAPTURE_DISPATCHER and AI_A2G_DISPATCHER.

This commit is contained in:
FlightControl 2019-03-18 19:53:12 +01:00
parent 02a486e457
commit 70e7857b62
3 changed files with 193 additions and 87 deletions

View File

@ -1126,7 +1126,7 @@ do -- AI_A2G_DISPATCHER
self.TakeoffScheduleID = self:ScheduleRepeat( 10, 10, 0, nil, self.ResourceTakeoff, self ) self.TakeoffScheduleID = self:ScheduleRepeat( 10, 10, 0, nil, self.ResourceTakeoff, self )
self:__Start( 5 ) self:__Start( 1 )
return self return self
end end
@ -1150,9 +1150,30 @@ do -- AI_A2G_DISPATCHER
--- Locks the DefenseItem from being defended. --- Locks the DefenseItem from being defended.
-- @param #AI_A2G_DISPATCHER self -- @param #AI_A2G_DISPATCHER self
-- @param #string DefenseItemKey The key of the defense item. -- @param #string DetectedItemIndex The index of the detected item.
function AI_A2G_DISPATCHER:Lock( DetectedItemIndex )
self:F( { DetectedItemIndex = DetectedItemIndex } )
local DetectedItem = self.Detection:GetDetectedItemByIndex( DetectedItemIndex )
if DetectedItem then
self:F( { Locked = DetectedItem } )
self.Detection:LockDetectedItem( DetectedItem )
end
end
--- Unlocks the DefenseItem from being defended.
-- @param #AI_A2G_DISPATCHER self
-- @param #string DetectedItemIndex The index of the detected item.
function AI_A2G_DISPATCHER:Unlock( DetectedItemIndex )
self:F( { DetectedItemIndex = DetectedItemIndex } )
self:F( { Index = self.Detection.DetectedItemsByIndex } )
local DetectedItem = self.Detection:GetDetectedItemByIndex( DetectedItemIndex )
if DetectedItem then
self:F( { Unlocked = DetectedItem } )
self.Detection:UnlockDetectedItem( DetectedItem )
end
end
--- @param #AI_A2G_DISPATCHER self --- @param #AI_A2G_DISPATCHER self
@ -4032,100 +4053,102 @@ do -- AI_A2G_DISPATCHER
-- Now that all obsolete tasks are removed, loop through the detected targets. -- Now that all obsolete tasks are removed, loop through the detected targets.
for DetectedItemID, DetectedItem in pairs( Detection:GetDetectedItems() ) do for DetectedItemID, DetectedItem in pairs( Detection:GetDetectedItems() ) do
local DetectedItem = DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem if not self.Detection:IsDetectedItemLocked( DetectedItem ) == true then
local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT local DetectedItem = DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
local DetectedCount = DetectedSet:Count() local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT
local DetectedZone = DetectedItem.Zone local DetectedCount = DetectedSet:Count()
local DetectedZone = DetectedItem.Zone
self:F( { "Target ID", DetectedItem.ItemID } )
DetectedSet:Flush( self ) self:F( { "Target ID", DetectedItem.ItemID } )
DetectedSet:Flush( self )
local DetectedID = DetectedItem.ID
local DetectionIndex = DetectedItem.Index local DetectedID = DetectedItem.ID
local DetectedItemChanged = DetectedItem.Changed local DetectionIndex = DetectedItem.Index
local DetectedItemChanged = DetectedItem.Changed
local AttackCoordinate = self.Detection:GetDetectedItemCoordinate( DetectedItem )
-- Calculate if for this DetectedItem if a defense needs to be initiated.
-- This calculation is based on the distance between the defense point and the attackers, and the defensiveness parameter.
-- The attackers closest to the defense coordinates will be handled first, or course!
local EngageCoordinate = nil
for DefenseCoordinateName, DefenseCoordinate in pairs( self.DefenseCoordinates ) do
local DefenseCoordinate = DefenseCoordinate -- Core.Point#COORDINATE
local EvaluateDistance = AttackCoordinate:Get2DDistance( DefenseCoordinate )
if EvaluateDistance <= self.DefenseRadius then local AttackCoordinate = self.Detection:GetDetectedItemCoordinate( DetectedItem )
local DistanceProbability = ( self.DefenseRadius / EvaluateDistance * self.DefenseReactivity ) -- Calculate if for this DetectedItem if a defense needs to be initiated.
local DefenseProbability = math.random() -- This calculation is based on the distance between the defense point and the attackers, and the defensiveness parameter.
-- The attackers closest to the defense coordinates will be handled first, or course!
local EngageCoordinate = nil
for DefenseCoordinateName, DefenseCoordinate in pairs( self.DefenseCoordinates ) do
local DefenseCoordinate = DefenseCoordinate -- Core.Point#COORDINATE
local EvaluateDistance = AttackCoordinate:Get2DDistance( DefenseCoordinate )
self:F( { DistanceProbability = DistanceProbability, DefenseProbability = DefenseProbability } ) if EvaluateDistance <= self.DefenseRadius then
if DefenseProbability <= DistanceProbability / ( 300 / 30 ) then local DistanceProbability = ( self.DefenseRadius / EvaluateDistance * self.DefenseReactivity )
EngageCoordinate = DefenseCoordinate local DefenseProbability = math.random()
break
self:F( { DistanceProbability = DistanceProbability, DefenseProbability = DefenseProbability } )
if DefenseProbability <= DistanceProbability / ( 300 / 30 ) then
EngageCoordinate = DefenseCoordinate
break
end
end end
end end
end
if EngageCoordinate then
if EngageCoordinate then do
do local DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies = self:Evaluate_SEAD( DetectedItem ) -- Returns a SET_UNIT with the SEAD targets to be engaged...
local DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies = self:Evaluate_SEAD( DetectedItem ) -- Returns a SET_UNIT with the SEAD targets to be engaged... if DefendersMissing and DefendersMissing > 0 then
if DefendersMissing and DefendersMissing > 0 then self:F( { DefendersTotal = DefendersTotal, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing } )
self:F( { DefendersTotal = DefendersTotal, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing } ) self:Defend( DetectedItem, DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies, "SEAD", EngageCoordinate )
self:Defend( DetectedItem, DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies, "SEAD", EngageCoordinate ) end
end
do
local DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies = self:Evaluate_CAS( DetectedItem ) -- Returns a SET_UNIT with the CAS targets to be engaged...
if DefendersMissing and DefendersMissing > 0 then
self:F( { DefendersTotal = DefendersTotal, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing } )
self:Defend( DetectedItem, DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies, "CAS", EngageCoordinate )
end
end
do
local DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies = self:Evaluate_BAI( DetectedItem ) -- Returns a SET_UNIT with the CAS targets to be engaged...
if DefendersMissing and DefendersMissing > 0 then
self:F( { DefendersTotal = DefendersTotal, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing } )
self:Defend( DetectedItem, DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies, "BAI", EngageCoordinate )
end
end end
end end
do -- do
local DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies = self:Evaluate_CAS( DetectedItem ) -- Returns a SET_UNIT with the CAS targets to be engaged... -- local DefendersMissing, Friendlies = self:Evaluate_CAS( DetectedItem )
if DefendersMissing and DefendersMissing > 0 then -- if DefendersMissing and DefendersMissing > 0 then
self:F( { DefendersTotal = DefendersTotal, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing } ) -- self:F( { DefendersMissing = DefendersMissing } )
self:Defend( DetectedItem, DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies, "CAS", EngageCoordinate ) -- self:CAS( DetectedItem, DefendersMissing, Friendlies )
end -- end
end -- end
do if self.TacticalDisplay then
local DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies = self:Evaluate_BAI( DetectedItem ) -- Returns a SET_UNIT with the CAS targets to be engaged... -- Show tactical situation
if DefendersMissing and DefendersMissing > 0 then local ThreatLevel = DetectedItem.Set:CalculateThreatLevelA2G()
self:F( { DefendersTotal = DefendersTotal, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing } ) Report:Add( string.format( " - %1s%s ( %4s ): ( #%d - %4s ) %s" , ( DetectedItem.IsDetected == true ) and "!" or " ", DetectedItem.ItemID, DetectedItem.Index, DetectedItem.Set:Count(), DetectedItem.Type or " --- ", string.rep( "", ThreatLevel ) ) )
self:Defend( DetectedItem, DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies, "BAI", EngageCoordinate ) for Defender, DefenderTask in pairs( self:GetDefenderTasks() ) do
end local Defender = Defender -- Wrapper.Group#GROUP
end if DefenderTask.Target and DefenderTask.Target.Index == DetectedItem.Index then
end if Defender:IsAlive() then
DefenderGroupCount = DefenderGroupCount + 1
-- do local Fuel = Defender:GetFuelMin() * 100
-- local DefendersMissing, Friendlies = self:Evaluate_CAS( DetectedItem ) local Damage = Defender:GetLife() / Defender:GetLife0() * 100
-- if DefendersMissing and DefendersMissing > 0 then Report:Add( string.format( " - %s ( %s - %s ): ( #%d ) F: %3d, D:%3d - %s",
-- self:F( { DefendersMissing = DefendersMissing } ) Defender:GetName(),
-- self:CAS( DetectedItem, DefendersMissing, Friendlies ) DefenderTask.Type,
-- end DefenderTask.Fsm:GetState(),
-- end Defender:GetSize(),
Fuel,
if self.TacticalDisplay then Damage,
-- Show tactical situation Defender:HasTask() == true and "Executing" or "Idle" ) )
local ThreatLevel = DetectedItem.Set:CalculateThreatLevelA2G() end
Report:Add( string.format( " - %1s%s ( %4s ): ( #%d - %4s ) %s" , ( DetectedItem.IsDetected == true ) and "!" or " ", DetectedItem.ItemID, DetectedItem.Index, DetectedItem.Set:Count(), DetectedItem.Type or " --- ", string.rep( "", ThreatLevel ) ) )
for Defender, DefenderTask in pairs( self:GetDefenderTasks() ) do
local Defender = Defender -- Wrapper.Group#GROUP
if DefenderTask.Target and DefenderTask.Target.Index == DetectedItem.Index then
if Defender:IsAlive() then
DefenderGroupCount = DefenderGroupCount + 1
local Fuel = Defender:GetFuelMin() * 100
local Damage = Defender:GetLife() / Defender:GetLife0() * 100
Report:Add( string.format( " - %s ( %s - %s ): ( #%d ) F: %3d, D:%3d - %s",
Defender:GetName(),
DefenderTask.Type,
DefenderTask.Fsm:GetState(),
Defender:GetSize(),
Fuel,
Damage,
Defender:HasTask() == true and "Executing" or "Idle" ) )
end end
end end
end end
end end
end end

View File

@ -1536,6 +1536,10 @@ do -- DETECTION_BASE
DetectedItem.ID = self.DetectedItemMax DetectedItem.ID = self.DetectedItemMax
DetectedItem.Removed = false DetectedItem.Removed = false
if self.Locking then
self:LockDetectedItem( DetectedItem )
end
return DetectedItem return DetectedItem
end end
@ -1725,6 +1729,68 @@ do -- DETECTION_BASE
end end
--- Lock the detected items when created and lock all existing detected items.
-- @param #DETECTION_BASE self
-- @return #DETECTION_BASE
function DETECTION_BASE:LockDetectedItems()
for DetectedItemID, DetectedItem in pairs( self.DetectedItems ) do
self:LockDetectedItem( DetectedItem )
end
self.Locking = true
return self
end
--- Unlock the detected items when created and unlock all existing detected items.
-- @param #DETECTION_BASE self
-- @return #DETECTION_BASE
function DETECTION_BASE:UnlockDetectedItems()
for DetectedItemID, DetectedItem in pairs( self.DetectedItems ) do
self:UnlockDetectedItem( DetectedItem )
end
self.Locking = nil
return self
end
--- Validate if the detected item is locked.
-- @param #DETECTION_BASE self
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
-- @return #boolean
function DETECTION_BASE:IsDetectedItemLocked( DetectedItem )
return self.Locking and DetectedItem.Locked == true
end
--- Lock a detected item.
-- @param #DETECTION_BASE self
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
-- @return #DETECTION_BASE
function DETECTION_BASE:LockDetectedItem( DetectedItem )
DetectedItem.Locked = true
return self
end
--- Unlock a detected item.
-- @param #DETECTION_BASE self
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
-- @return #DETECTION_BASE
function DETECTION_BASE:UnlockDetectedItem( DetectedItem )
DetectedItem.Locked = nil
return self
end
--- Set the detected item coordinate. --- Set the detected item coordinate.
-- @param #DETECTION_BASE self -- @param #DETECTION_BASE self

View File

@ -233,6 +233,7 @@ do -- TASK_CAPTURE_DISPATCHER
function TASK_CAPTURE_DISPATCHER:Link_AI_A2G_Dispatcher( AI_A2G_Dispatcher ) function TASK_CAPTURE_DISPATCHER:Link_AI_A2G_Dispatcher( AI_A2G_Dispatcher )
self.AI_A2G_Dispatcher = AI_A2G_Dispatcher -- AI.AI_A2G_Dispatcher#AI_A2G_DISPATCHER self.AI_A2G_Dispatcher = AI_A2G_Dispatcher -- AI.AI_A2G_Dispatcher#AI_A2G_DISPATCHER
AI_A2G_Dispatcher.Detection:LockDetectedItems()
return self return self
end end
@ -276,34 +277,50 @@ do -- TASK_CAPTURE_DISPATCHER
CaptureZone.Task:UpdateTaskInfo() CaptureZone.Task:UpdateTaskInfo()
function CaptureZone.Task.OnEnterAssigned( Task, From, Event, To ) function CaptureZone.Task.OnEnterAssigned( Task, From, Event, To )
self.AI_A2G_Dispatcher:Unlock( Task.TaskZoneName ) -- This will unlock the zone to be defended by AI. if self.AI_A2G_Dispatcher then
self.AI_A2G_Dispatcher:Unlock( Task.TaskZoneName ) -- This will unlock the zone to be defended by AI.
end
CaptureZone.Task:UpdateTaskInfo() CaptureZone.Task:UpdateTaskInfo()
end end
function CaptureZone.Task.OnEnterSuccess( Task, From, Event, To ) function CaptureZone.Task.OnEnterSuccess( Task, From, Event, To )
self:Success( Task ) self:Success( Task )
if self.AI_A2G_Dispatcher then
self.AI_A2G_Dispatcher:Lock( Task.TaskZoneName ) -- This will lock the zone from being defended by AI.
end
CaptureZone.Task:UpdateTaskInfo() CaptureZone.Task:UpdateTaskInfo()
end end
function CaptureZone.Task.OnEnterCancelled( Task, From, Event, To ) function CaptureZone.Task.OnEnterCancelled( Task, From, Event, To )
self:Cancelled( Task ) self:Cancelled( Task )
self.AI_A2G_Dispatcher:Unlock( Task.TaskZoneName ) -- This will lock the zone from being defended by AI. if self.AI_A2G_Dispatcher then
self.AI_A2G_Dispatcher:Lock( Task.TaskZoneName ) -- This will lock the zone from being defended by AI.
end
CaptureZone.Task:UpdateTaskInfo() CaptureZone.Task:UpdateTaskInfo()
end end
function CaptureZone.Task.OnEnterFailed( Task, From, Event, To ) function CaptureZone.Task.OnEnterFailed( Task, From, Event, To )
self:Failed( Task ) self:Failed( Task )
if self.AI_A2G_Dispatcher then
self.AI_A2G_Dispatcher:Lock( Task.TaskZoneName ) -- This will lock the zone from being defended by AI.
end
CaptureZone.Task:UpdateTaskInfo() CaptureZone.Task:UpdateTaskInfo()
end end
function CaptureZone.Task.OnEnterAborted( Task, From, Event, To ) function CaptureZone.Task.OnEnterAborted( Task, From, Event, To )
self:Aborted( Task ) self:Aborted( Task )
if self.AI_A2G_Dispatcher then
self.AI_A2G_Dispatcher:Lock( Task.TaskZoneName ) -- This will lock the zone from being defended by AI.
end
CaptureZone.Task:UpdateTaskInfo() CaptureZone.Task:UpdateTaskInfo()
end end
-- Now broadcast the onafterCargoPickedUp event to the Task Cargo Dispatcher. -- Now broadcast the onafterCargoPickedUp event to the Task Cargo Dispatcher.
function CaptureZone.Task.OnAfterCaptured( Task, From, Event, To, TaskUnit ) function CaptureZone.Task.OnAfterCaptured( Task, From, Event, To, TaskUnit )
self:Captured( Task, Task.TaskPrefix, TaskUnit ) self:Captured( Task, Task.TaskPrefix, TaskUnit )
if self.AI_A2G_Dispatcher then
self.AI_A2G_Dispatcher:Lock( Task.TaskZoneName ) -- This will lock the zone from being defended by AI.
end
CaptureZone.Task:UpdateTaskInfo() CaptureZone.Task:UpdateTaskInfo()
end end