mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Merge branch 'FF/Develop' of https://github.com/FlightControl-Master/MOOSE into FF/Develop
This commit is contained in:
commit
e4935d8717
@ -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()
|
||||||
|
|
||||||
|
|||||||
@ -919,7 +919,7 @@ do -- AI_A2G_DISPATCHER
|
|||||||
AI_A2G_DISPATCHER.Takeoff = GROUP.Takeoff
|
AI_A2G_DISPATCHER.Takeoff = GROUP.Takeoff
|
||||||
|
|
||||||
--- Defnes Landing location.
|
--- Defnes Landing location.
|
||||||
-- @field Landing
|
-- @field #AI_A2G_DISPATCHER.Landing
|
||||||
AI_A2G_DISPATCHER.Landing = {
|
AI_A2G_DISPATCHER.Landing = {
|
||||||
NearAirbase = 1,
|
NearAirbase = 1,
|
||||||
AtRunway = 2,
|
AtRunway = 2,
|
||||||
@ -950,7 +950,12 @@ do -- AI_A2G_DISPATCHER
|
|||||||
AI_A2G_DISPATCHER.DefenseQueue = {}
|
AI_A2G_DISPATCHER.DefenseQueue = {}
|
||||||
|
|
||||||
|
|
||||||
|
--- Defense approach types
|
||||||
|
-- @type #AI_A2G_DISPATCHER.DefenseApproach
|
||||||
|
AI_A2G_DISPATCHER.DefenseApproach = {
|
||||||
|
Random = 1,
|
||||||
|
Distance = 2,
|
||||||
|
}
|
||||||
|
|
||||||
--- AI_A2G_DISPATCHER constructor.
|
--- AI_A2G_DISPATCHER constructor.
|
||||||
-- This is defining the A2G DISPATCHER for one coaliton.
|
-- This is defining the A2G DISPATCHER for one coaliton.
|
||||||
@ -996,6 +1001,8 @@ do -- AI_A2G_DISPATCHER
|
|||||||
-- self.Detection:SetRefreshTimeInterval( 30 )
|
-- self.Detection:SetRefreshTimeInterval( 30 )
|
||||||
|
|
||||||
self:SetDefenseRadius()
|
self:SetDefenseRadius()
|
||||||
|
self:SetDefenseLimit( nil )
|
||||||
|
self:SetDefenseApproach( AI_A2G_DISPATCHER.DefenseApproach.Random )
|
||||||
self:SetIntercept( 300 ) -- A default intercept delay time of 300 seconds.
|
self:SetIntercept( 300 ) -- A default intercept delay time of 300 seconds.
|
||||||
self:SetDisengageRadius( 300000 ) -- The default Disengage Radius is 300 km.
|
self:SetDisengageRadius( 300000 ) -- The default Disengage Radius is 300 km.
|
||||||
|
|
||||||
@ -1126,7 +1133,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
|
||||||
@ -1148,6 +1155,53 @@ do -- AI_A2G_DISPATCHER
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Locks the DefenseItem from being defended.
|
||||||
|
-- @param #AI_A2G_DISPATCHER self
|
||||||
|
-- @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
|
||||||
|
|
||||||
|
|
||||||
|
--- Sets maximum zones to be engaged at one time by defenders.
|
||||||
|
-- @param #AI_A2G_DISPATCHER self
|
||||||
|
-- @param #number DefenseLimit The maximum amount of detected items to be engaged at the same time.
|
||||||
|
function AI_A2G_DISPATCHER:SetDefenseLimit( DefenseLimit )
|
||||||
|
self:F( { DefenseLimit = DefenseLimit } )
|
||||||
|
|
||||||
|
self.DefenseLimit = DefenseLimit
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Sets the method of the tactical approach of the defenses.
|
||||||
|
-- @param #AI_A2G_DISPATCHER self
|
||||||
|
-- @param #number DefenseApproach Use the structure AI_A2G_DISPATCHER.DefenseApproach to set the defense approach.
|
||||||
|
-- The default defense approach is AI_A2G_DISPATCHER.DefenseApproach.Random.
|
||||||
|
function AI_A2G_DISPATCHER:SetDefenseApproach( DefenseApproach )
|
||||||
|
self:F( { DefenseApproach = DefenseApproach } )
|
||||||
|
|
||||||
|
self._DefenseApproach = DefenseApproach
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- @param #AI_A2G_DISPATCHER self
|
--- @param #AI_A2G_DISPATCHER self
|
||||||
function AI_A2G_DISPATCHER:ResourcePark( DefenderSquadron )
|
function AI_A2G_DISPATCHER:ResourcePark( DefenderSquadron )
|
||||||
@ -3467,6 +3521,20 @@ do -- AI_A2G_DISPATCHER
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Fsm:onafterPatrolRoute( Defender, From, Event, To, AttackSetUnit )
|
||||||
|
self:F({"Defender PatrolRoute", Defender:GetName()})
|
||||||
|
self:GetParent(self).onafterPatrolRoute( self, Defender, From, Event, To, AttackSetUnit )
|
||||||
|
|
||||||
|
local DefenderName = Defender:GetName()
|
||||||
|
local Dispatcher = self:GetDispatcher() -- #AI_A2G_DISPATCHER
|
||||||
|
local Squadron = Dispatcher:GetSquadronFromDefender( Defender )
|
||||||
|
if Squadron then
|
||||||
|
Dispatcher:MessageToPlayers( "Squadron " .. Squadron.Name .. ", " .. DefenderName .. " returning." )
|
||||||
|
end
|
||||||
|
|
||||||
|
Dispatcher:ClearDefenderTaskTarget( Defender )
|
||||||
|
end
|
||||||
|
|
||||||
function Fsm:onafterRTB( Defender, From, Event, To )
|
function Fsm:onafterRTB( Defender, From, Event, To )
|
||||||
self:F({"Defender RTB", Defender:GetName()})
|
self:F({"Defender RTB", Defender:GetName()})
|
||||||
self:GetParent(self).onafterRTB( self, Defender, From, Event, To )
|
self:GetParent(self).onafterRTB( self, Defender, From, Event, To )
|
||||||
@ -3564,15 +3632,15 @@ do -- AI_A2G_DISPATCHER
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Fsm:OnAfterEngageRoute( Defender, From, Event, To, AttackSetUnit )
|
function Fsm:onafterEngageRoute( Defender, From, Event, To, AttackSetUnit )
|
||||||
self:F({"Engage Route", Defender:GetName()})
|
self:F({"Engage Route", Defender:GetName()})
|
||||||
--self:GetParent(self).onafterBirth( self, Defender, From, Event, To )
|
self:GetParent(self).onafterEngageRoute( self, Defender, From, Event, To, AttackSetUnit )
|
||||||
|
|
||||||
local DefenderName = Defender:GetName()
|
local DefenderName = Defender:GetName()
|
||||||
local Dispatcher = Fsm:GetDispatcher() -- #AI_A2G_DISPATCHER
|
local Dispatcher = Fsm:GetDispatcher() -- #AI_A2G_DISPATCHER
|
||||||
local Squadron = Dispatcher:GetSquadronFromDefender( Defender )
|
local Squadron = Dispatcher:GetSquadronFromDefender( Defender )
|
||||||
|
|
||||||
if FirstUnit then
|
if Squadron then
|
||||||
local FirstUnit = AttackSetUnit:GetFirst()
|
local FirstUnit = AttackSetUnit:GetFirst()
|
||||||
local Coordinate = FirstUnit:GetCoordinate() -- Core.Point#COORDINATE
|
local Coordinate = FirstUnit:GetCoordinate() -- Core.Point#COORDINATE
|
||||||
|
|
||||||
@ -3886,7 +3954,7 @@ do -- AI_A2G_DISPATCHER
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return nil, nil, nil
|
return 0, 0, 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -3919,7 +3987,7 @@ do -- AI_A2G_DISPATCHER
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return nil, nil, nil
|
return 0, 0, 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -3952,11 +4020,29 @@ do -- AI_A2G_DISPATCHER
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return nil, nil, nil
|
return 0, 0, 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Assigns A2G AI Tasks in relation to the detected items.
|
||||||
|
-- @param #AI_A2G_DISPATCHER self
|
||||||
|
function AI_A2G_DISPATCHER:Order( DetectedItem )
|
||||||
|
local AttackCoordinate = self.Detection:GetDetectedItemCoordinate( DetectedItem )
|
||||||
|
|
||||||
|
local ShortestDistance = 999999999
|
||||||
|
|
||||||
|
for DefenseCoordinateName, DefenseCoordinate in pairs( self.DefenseCoordinates ) do
|
||||||
|
local DefenseCoordinate = DefenseCoordinate -- Core.Point#COORDINATE
|
||||||
|
|
||||||
|
local EvaluateDistance = AttackCoordinate:Get2DDistance( DefenseCoordinate )
|
||||||
|
|
||||||
|
if EvaluateDistance <= ShortestDistance then
|
||||||
|
ShortestDistance = EvaluateDistance
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return ShortestDistance
|
||||||
|
end
|
||||||
|
|
||||||
--- Assigns A2G AI Tasks in relation to the detected items.
|
--- Assigns A2G AI Tasks in relation to the detected items.
|
||||||
-- @param #AI_A2G_DISPATCHER self
|
-- @param #AI_A2G_DISPATCHER self
|
||||||
@ -3983,7 +4069,9 @@ do -- AI_A2G_DISPATCHER
|
|||||||
self:ClearDefenderTask( DefenderGroup )
|
self:ClearDefenderTask( DefenderGroup )
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
-- TODO: prio 1, what is this index stuff again, simplify it.
|
||||||
if DefenderTask.Target then
|
if DefenderTask.Target then
|
||||||
|
self:F( { TargetIndex = DefenderTask.Target.Index } )
|
||||||
local AttackerItem = Detection:GetDetectedItemByIndex( DefenderTask.Target.Index )
|
local AttackerItem = Detection:GetDetectedItemByIndex( DefenderTask.Target.Index )
|
||||||
if not AttackerItem then
|
if not AttackerItem then
|
||||||
self:F( { "Removing obsolete Target:", DefenderTask.Target.Index } )
|
self:F( { "Removing obsolete Target:", DefenderTask.Target.Index } )
|
||||||
@ -4006,104 +4094,123 @@ do -- AI_A2G_DISPATCHER
|
|||||||
local DefenderGroupCount = 0
|
local DefenderGroupCount = 0
|
||||||
|
|
||||||
local DefendersTotal = 0
|
local DefendersTotal = 0
|
||||||
|
local DefenseTotal = 0
|
||||||
|
|
||||||
-- 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
|
||||||
|
for DetectedItemID, DetectedItem in UTILS.spairs( Detection:GetDetectedItems(), function( t, a, b ) return self:Order(t[a]) < self:Order(t[b]) end ) 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 } )
|
self:F( { "Target ID", DetectedItem.ItemID } )
|
||||||
DetectedSet:Flush( self )
|
|
||||||
|
|
||||||
local DetectedID = DetectedItem.ID
|
self:F( { DefenseLimit = self.DefenseLimitmit, DefenseTotal = DefenseTotal } )
|
||||||
local DetectionIndex = DetectedItem.Index
|
DetectedSet:Flush( self )
|
||||||
local DetectedItemChanged = DetectedItem.Changed
|
|
||||||
|
|
||||||
local AttackCoordinate = self.Detection:GetDetectedItemCoordinate( DetectedItem )
|
local DetectedID = DetectedItem.ID
|
||||||
|
local DetectionIndex = DetectedItem.Index
|
||||||
|
local DetectedItemChanged = DetectedItem.Changed
|
||||||
|
|
||||||
-- Calculate if for this DetectedItem if a defense needs to be initiated.
|
local AttackCoordinate = self.Detection:GetDetectedItemCoordinate( DetectedItem )
|
||||||
-- 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
|
-- 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!
|
||||||
|
|
||||||
for DefenseCoordinateName, DefenseCoordinate in pairs( self.DefenseCoordinates ) do
|
local EngageCoordinate = nil
|
||||||
local DefenseCoordinate = DefenseCoordinate -- Core.Point#COORDINATE
|
|
||||||
|
|
||||||
local EvaluateDistance = AttackCoordinate:Get2DDistance( DefenseCoordinate )
|
for DefenseCoordinateName, DefenseCoordinate in pairs( self.DefenseCoordinates ) do
|
||||||
|
local DefenseCoordinate = DefenseCoordinate -- Core.Point#COORDINATE
|
||||||
|
|
||||||
if EvaluateDistance <= self.DefenseRadius then
|
local EvaluateDistance = AttackCoordinate:Get2DDistance( DefenseCoordinate )
|
||||||
|
|
||||||
local DistanceProbability = ( self.DefenseRadius / EvaluateDistance * self.DefenseReactivity )
|
if EvaluateDistance <= self.DefenseRadius then
|
||||||
local DefenseProbability = math.random()
|
|
||||||
|
|
||||||
self:F( { DistanceProbability = DistanceProbability, DefenseProbability = DefenseProbability } )
|
local DistanceProbability = ( self.DefenseRadius / EvaluateDistance * self.DefenseReactivity )
|
||||||
|
local DefenseProbability = math.random()
|
||||||
|
|
||||||
if DefenseProbability <= DistanceProbability / ( 300 / 30 ) then
|
self:F( { DistanceProbability = DistanceProbability, DefenseProbability = DefenseProbability } )
|
||||||
EngageCoordinate = DefenseCoordinate
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if EngageCoordinate then
|
if self._DefenseApproach == AI_A2G_DISPATCHER.DefenseApproach.Random then
|
||||||
do
|
|
||||||
local DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies = self:Evaluate_SEAD( DetectedItem ) -- Returns a SET_UNIT with the SEAD targets to be engaged...
|
if DefenseProbability <= DistanceProbability / ( 300 / 30 ) then
|
||||||
if DefendersMissing and DefendersMissing > 0 then
|
EngageCoordinate = DefenseCoordinate
|
||||||
self:F( { DefendersTotal = DefendersTotal, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing } )
|
break
|
||||||
self:Defend( DetectedItem, DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies, "SEAD", EngageCoordinate )
|
end
|
||||||
|
end
|
||||||
|
if self._DefenseApproach == AI_A2G_DISPATCHER.DefenseApproach.Distance then
|
||||||
|
EngageCoordinate = DefenseCoordinate
|
||||||
|
break
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
do
|
if EngageCoordinate and DefenseTotal < self.DefenseLimit then
|
||||||
local DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies = self:Evaluate_CAS( DetectedItem ) -- Returns a SET_UNIT with the CAS targets to be engaged...
|
do
|
||||||
if DefendersMissing and DefendersMissing > 0 then
|
local DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies = self:Evaluate_SEAD( DetectedItem ) -- Returns a SET_UNIT with the SEAD targets to be engaged...
|
||||||
self:F( { DefendersTotal = DefendersTotal, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing } )
|
if DefendersMissing > 0 then
|
||||||
self:Defend( DetectedItem, DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies, "CAS", EngageCoordinate )
|
self:F( { DefendersTotal = DefendersTotal, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing } )
|
||||||
|
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 > 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 > 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
|
|
||||||
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
|
|
||||||
|
|
||||||
-- do
|
|
||||||
-- local DefendersMissing, Friendlies = self:Evaluate_CAS( DetectedItem )
|
|
||||||
-- if DefendersMissing and DefendersMissing > 0 then
|
|
||||||
-- self:F( { DefendersMissing = DefendersMissing } )
|
|
||||||
-- self:CAS( DetectedItem, DefendersMissing, Friendlies )
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
|
|
||||||
if self.TacticalDisplay then
|
|
||||||
-- Show tactical situation
|
|
||||||
local ThreatLevel = DetectedItem.Set:CalculateThreatLevelA2G()
|
|
||||||
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
|
for Defender, DefenderTask in pairs( self:GetDefenderTasks() ) do
|
||||||
local Defender = Defender -- Wrapper.Group#GROUP
|
local Defender = Defender -- Wrapper.Group#GROUP
|
||||||
if DefenderTask.Target and DefenderTask.Target.Index == DetectedItem.Index then
|
if DefenderTask.Target and DefenderTask.Target.Index == DetectedItem.Index then
|
||||||
if Defender:IsAlive() then
|
DefenseTotal = DefenseTotal + 1
|
||||||
DefenderGroupCount = DefenderGroupCount + 1
|
end
|
||||||
local Fuel = Defender:GetFuelMin() * 100
|
end
|
||||||
local Damage = Defender:GetLife() / Defender:GetLife0() * 100
|
|
||||||
Report:Add( string.format( " - %s ( %s - %s ): ( #%d ) F: %3d, D:%3d - %s",
|
for DefenseQueueID, DefenseQueueItem in pairs( self.DefenseQueue ) do
|
||||||
Defender:GetName(),
|
local DefenseQueueItem = DefenseQueueItem -- #AI_A2G_DISPATCHER.DefenseQueueItem
|
||||||
DefenderTask.Type,
|
if DefenseQueueItem.AttackerDetection.Index == DetectedItem.Index then
|
||||||
DefenderTask.Fsm:GetState(),
|
DefenseTotal = DefenseTotal + 1
|
||||||
Defender:GetSize(),
|
end
|
||||||
Fuel,
|
end
|
||||||
Damage,
|
|
||||||
Defender:HasTask() == true and "Executing" or "Idle" ) )
|
if self.TacticalDisplay then
|
||||||
|
-- Show tactical situation
|
||||||
|
local ThreatLevel = DetectedItem.Set:CalculateThreatLevelA2G()
|
||||||
|
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
|
end
|
||||||
|
|||||||
@ -142,6 +142,7 @@ do -- Goal
|
|||||||
-- @param #GOAL self
|
-- @param #GOAL self
|
||||||
-- @param #string PlayerName The name of the player.
|
-- @param #string PlayerName The name of the player.
|
||||||
function GOAL:AddPlayerContribution( PlayerName )
|
function GOAL:AddPlayerContribution( PlayerName )
|
||||||
|
self:F({PlayerName})
|
||||||
self.Players[PlayerName] = self.Players[PlayerName] or 0
|
self.Players[PlayerName] = self.Players[PlayerName] or 0
|
||||||
self.Players[PlayerName] = self.Players[PlayerName] + 1
|
self.Players[PlayerName] = self.Players[PlayerName] + 1
|
||||||
self.TotalContributions = self.TotalContributions + 1
|
self.TotalContributions = self.TotalContributions + 1
|
||||||
|
|||||||
@ -131,6 +131,20 @@ do -- SET_BASE
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Clear the Objects in the Set.
|
||||||
|
-- @param #SET_BASE self
|
||||||
|
-- @return #SET_BASE self
|
||||||
|
function SET_BASE:Clear()
|
||||||
|
|
||||||
|
for Name, Object in pairs( self.Set ) do
|
||||||
|
self:Remove( Name )
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Finds an @{Core.Base#BASE} object based on the object Name.
|
--- Finds an @{Core.Base#BASE} object based on the object Name.
|
||||||
-- @param #SET_BASE self
|
-- @param #SET_BASE self
|
||||||
-- @param #string ObjectName
|
-- @param #string ObjectName
|
||||||
@ -148,7 +162,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.
|
||||||
|
|||||||
@ -631,8 +631,8 @@ end
|
|||||||
-- * @{ZONE_RADIUS.IsNoneInZone}(): Scan if the zone is empty.
|
-- * @{ZONE_RADIUS.IsNoneInZone}(): Scan if the zone is empty.
|
||||||
-- @{#ZONE_RADIUS.
|
-- @{#ZONE_RADIUS.
|
||||||
-- @param #ZONE_RADIUS self
|
-- @param #ZONE_RADIUS self
|
||||||
-- @param ObjectCategories
|
-- @param ObjectCategories An array of categories of the objects to find in the zone.
|
||||||
-- @param UnitCategories
|
-- @param UnitCategories An array of unit categories of the objects to find in the zone.
|
||||||
-- @usage
|
-- @usage
|
||||||
-- self.Zone:Scan()
|
-- self.Zone:Scan()
|
||||||
-- local IsAttacked = self.Zone:IsSomeInZoneOfCoalition( self.Coalition )
|
-- local IsAttacked = self.Zone:IsSomeInZoneOfCoalition( self.Coalition )
|
||||||
@ -704,6 +704,31 @@ function ZONE_RADIUS:GetScannedUnits()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_RADIUS:GetScannedSetUnit()
|
||||||
|
|
||||||
|
local SetUnit = SET_UNIT:New()
|
||||||
|
|
||||||
|
if self.ScanData then
|
||||||
|
for ObjectID, UnitObject in pairs( self.ScanData.Units ) do
|
||||||
|
local UnitObject = UnitObject -- DCS#Unit
|
||||||
|
if UnitObject:isExist() then
|
||||||
|
local FoundUnit = UNIT:FindByName( UnitObject:getName() )
|
||||||
|
if FoundUnit then
|
||||||
|
SetUnit:AddUnit( FoundUnit )
|
||||||
|
else
|
||||||
|
local FoundStatic = STATIC:FindByName( UnitObject:getName() )
|
||||||
|
if FoundStatic then
|
||||||
|
SetUnit:AddUnit( FoundStatic )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return SetUnit
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function ZONE_RADIUS:CountScannedCoalitions()
|
function ZONE_RADIUS:CountScannedCoalitions()
|
||||||
|
|
||||||
local Count = 0
|
local Count = 0
|
||||||
|
|||||||
@ -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
|
||||||
@ -1393,7 +1393,7 @@ do -- DESIGNATE
|
|||||||
self:F( "Smoking ..." )
|
self:F( "Smoking ..." )
|
||||||
|
|
||||||
local RecceGroup = self.RecceSet:FindNearestGroupFromPointVec2(SmokeUnit:GetPointVec2())
|
local RecceGroup = self.RecceSet:FindNearestGroupFromPointVec2(SmokeUnit:GetPointVec2())
|
||||||
local RecceUnit = RecceGroup:GetUnit( 1 )
|
local RecceUnit = RecceGroup:GetUnit( 1 ) -- Wrapper.Unit#UNIT
|
||||||
|
|
||||||
if RecceUnit then
|
if RecceUnit then
|
||||||
|
|
||||||
@ -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
|
||||||
|
|||||||
@ -305,9 +305,9 @@ do -- DETECTION_BASE
|
|||||||
|
|
||||||
--- DETECTION constructor.
|
--- DETECTION constructor.
|
||||||
-- @param #DETECTION_BASE self
|
-- @param #DETECTION_BASE self
|
||||||
-- @param Core.Set#SET_GROUP DetectionSetGroup The @{Set} of GROUPs in the Forward Air Controller role.
|
-- @param Core.Set#SET_BASE DetectionSet The @{Set} that is used to detect the units.
|
||||||
-- @return #DETECTION_BASE self
|
-- @return #DETECTION_BASE self
|
||||||
function DETECTION_BASE:New( DetectionSetGroup )
|
function DETECTION_BASE:New( DetectionSet )
|
||||||
|
|
||||||
-- Inherits from BASE
|
-- Inherits from BASE
|
||||||
local self = BASE:Inherit( self, FSM:New() ) -- #DETECTION_BASE
|
local self = BASE:Inherit( self, FSM:New() ) -- #DETECTION_BASE
|
||||||
@ -316,7 +316,7 @@ do -- DETECTION_BASE
|
|||||||
self.DetectedItemMax = 0
|
self.DetectedItemMax = 0
|
||||||
self.DetectedItems = {}
|
self.DetectedItems = {}
|
||||||
|
|
||||||
self.DetectionSetGroup = DetectionSetGroup
|
self.DetectionSet = DetectionSet
|
||||||
|
|
||||||
self.RefreshTimeInterval = 30
|
self.RefreshTimeInterval = 30
|
||||||
|
|
||||||
@ -398,7 +398,7 @@ do -- DETECTION_BASE
|
|||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
|
|
||||||
self:AddTransition( "Detecting", "Detect", "Detecting" )
|
self:AddTransition( "Detecting", "Detect", "Detecting" )
|
||||||
self:AddTransition( "Detecting", "DetectionGroup", "Detecting" )
|
self:AddTransition( "Detecting", "Detection", "Detecting" )
|
||||||
|
|
||||||
--- OnBefore Transition Handler for Event Detect.
|
--- OnBefore Transition Handler for Event Detect.
|
||||||
-- @function [parent=#DETECTION_BASE] OnBeforeDetect
|
-- @function [parent=#DETECTION_BASE] OnBeforeDetect
|
||||||
@ -540,11 +540,12 @@ do -- DETECTION_BASE
|
|||||||
self.DetectedObjects[DetectionObjectName].Distance = 10000000
|
self.DetectedObjects[DetectionObjectName].Distance = 10000000
|
||||||
|
|
||||||
end
|
end
|
||||||
for DetectionGroupID, DetectionGroupData in pairs( self.DetectionSetGroup:GetSet() ) do
|
|
||||||
|
self.DetectionCount = self.DetectionSet:Count()
|
||||||
|
for DetectionID, DetectionData in pairs( self.DetectionSet:GetSet() ) do
|
||||||
--self:F( { DetectionGroupData } )
|
--self:F( { DetectionGroupData } )
|
||||||
self:F( { DetectionGroup = DetectionGroupData:GetName() } )
|
self:F( { DetectionGroup = DetectionData:GetName() } )
|
||||||
self:__DetectionGroup( DetectDelay, DetectionGroupData, 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
|
||||||
@ -555,7 +556,7 @@ do -- DETECTION_BASE
|
|||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
-- @param Wrapper.Group#GROUP DetectionGroup The Group detecting.
|
-- @param Wrapper.Group#GROUP DetectionGroup The Group detecting.
|
||||||
-- @param #number DetectionTimeStamp Time stamp of detection event.
|
-- @param #number DetectionTimeStamp Time stamp of detection event.
|
||||||
function DETECTION_BASE:onafterDetectionGroup( From, Event, To, DetectionGroup, DetectionTimeStamp )
|
function DETECTION_BASE:onafterDetection( From, Event, To, Detection, DetectionTimeStamp )
|
||||||
|
|
||||||
--self:F( { DetectedObjects = self.DetectedObjects } )
|
--self:F( { DetectedObjects = self.DetectedObjects } )
|
||||||
|
|
||||||
@ -563,16 +564,16 @@ do -- DETECTION_BASE
|
|||||||
|
|
||||||
local HasDetectedObjects = false
|
local HasDetectedObjects = false
|
||||||
|
|
||||||
if DetectionGroup:IsAlive() then
|
if Detection:IsAlive() then
|
||||||
|
|
||||||
--self:T( { "DetectionGroup is Alive", DetectionGroup:GetName() } )
|
--self:T( { "DetectionGroup is Alive", DetectionGroup:GetName() } )
|
||||||
|
|
||||||
local DetectionGroupName = DetectionGroup:GetName()
|
local DetectionGroupName = Detection:GetName()
|
||||||
local DetectionUnit = DetectionGroup:GetUnit(1)
|
local DetectionUnit = Detection:GetUnit(1)
|
||||||
|
|
||||||
local DetectedUnits = {}
|
local DetectedUnits = {}
|
||||||
|
|
||||||
local DetectedTargets = DetectionGroup:GetDetectedTargets(
|
local DetectedTargets = Detection:GetDetectedTargets(
|
||||||
self.DetectVisual,
|
self.DetectVisual,
|
||||||
self.DetectOptical,
|
self.DetectOptical,
|
||||||
self.DetectRadar,
|
self.DetectRadar,
|
||||||
@ -624,7 +625,7 @@ do -- DETECTION_BASE
|
|||||||
|
|
||||||
local DetectedObjectVec3 = DetectedObject:getPoint()
|
local DetectedObjectVec3 = DetectedObject:getPoint()
|
||||||
local DetectedObjectVec2 = { x = DetectedObjectVec3.x, y = DetectedObjectVec3.z }
|
local DetectedObjectVec2 = { x = DetectedObjectVec3.x, y = DetectedObjectVec3.z }
|
||||||
local DetectionGroupVec3 = DetectionGroup:GetVec3()
|
local DetectionGroupVec3 = Detection:GetVec3()
|
||||||
local DetectionGroupVec2 = { x = DetectionGroupVec3.x, y = DetectionGroupVec3.z }
|
local DetectionGroupVec2 = { x = DetectionGroupVec3.x, y = DetectionGroupVec3.z }
|
||||||
|
|
||||||
local Distance = ( ( DetectedObjectVec3.x - DetectionGroupVec3.x )^2 +
|
local Distance = ( ( DetectedObjectVec3.x - DetectionGroupVec3.x )^2 +
|
||||||
@ -838,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
|
||||||
@ -1524,21 +1525,21 @@ do -- DETECTION_BASE
|
|||||||
self.DetectedItemCount = self.DetectedItemCount + 1
|
self.DetectedItemCount = self.DetectedItemCount + 1
|
||||||
self.DetectedItemMax = self.DetectedItemMax + 1
|
self.DetectedItemMax = self.DetectedItemMax + 1
|
||||||
|
|
||||||
if DetectedItemKey then
|
|
||||||
self.DetectedItems[DetectedItemKey] = DetectedItem
|
|
||||||
else
|
|
||||||
self.DetectedItems[self.DetectedItemMax] = DetectedItem
|
|
||||||
end
|
|
||||||
|
|
||||||
self.DetectedItemsByIndex[self.DetectedItemMax] = DetectedItem
|
|
||||||
|
|
||||||
|
DetectedItemKey = DetectedItemKey or self.DetectedItemMax
|
||||||
|
self.DetectedItems[DetectedItemKey] = DetectedItem
|
||||||
|
self.DetectedItemsByIndex[DetectedItemKey] = DetectedItem
|
||||||
|
DetectedItem.Index = DetectedItemKey
|
||||||
|
|
||||||
DetectedItem.Set = Set or SET_UNIT:New():FilterDeads():FilterCrashes()
|
DetectedItem.Set = Set or SET_UNIT:New():FilterDeads():FilterCrashes()
|
||||||
DetectedItem.Index = DetectedItemKey or self.DetectedItemMax
|
|
||||||
DetectedItem.ItemID = ItemPrefix .. "." .. self.DetectedItemMax
|
DetectedItem.ItemID = ItemPrefix .. "." .. self.DetectedItemMax
|
||||||
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
|
||||||
|
|
||||||
@ -1549,9 +1550,11 @@ do -- DETECTION_BASE
|
|||||||
-- @param Core.Set#SET_UNIT Set (optional) The Set of Units to be added.
|
-- @param Core.Set#SET_UNIT Set (optional) The Set of Units to be added.
|
||||||
-- @param Core.Zone#ZONE_UNIT Zone (optional) The Zone to be added where the Units are located.
|
-- @param Core.Zone#ZONE_UNIT Zone (optional) The Zone to be added where the Units are located.
|
||||||
-- @return #DETECTION_BASE.DetectedItem
|
-- @return #DETECTION_BASE.DetectedItem
|
||||||
function DETECTION_BASE:AddDetectedItemZone( DetectedItemKey, Set, Zone )
|
function DETECTION_BASE:AddDetectedItemZone( ItemPrefix, DetectedItemKey, Set, Zone )
|
||||||
|
|
||||||
local DetectedItem = self:AddDetectedItem( "AREA", DetectedItemKey, Set )
|
self:F( { ItemPrefix, DetectedItemKey, Set, Zone } )
|
||||||
|
|
||||||
|
local DetectedItem = self:AddDetectedItem( ItemPrefix, DetectedItemKey, Set )
|
||||||
|
|
||||||
DetectedItem.Zone = Zone
|
DetectedItem.Zone = Zone
|
||||||
|
|
||||||
@ -1624,7 +1627,9 @@ do -- DETECTION_BASE
|
|||||||
-- @return #DETECTION_BASE.DetectedItem
|
-- @return #DETECTION_BASE.DetectedItem
|
||||||
function DETECTION_BASE:GetDetectedItemByIndex( Index )
|
function DETECTION_BASE:GetDetectedItemByIndex( Index )
|
||||||
|
|
||||||
self:F( { DetectedItemsByIndex = self.DetectedItemsByIndex } )
|
self:I( { DetectedItemsByIndex = self.DetectedItemsByIndex } )
|
||||||
|
|
||||||
|
self:I( { self.DetectedItemsByIndex } )
|
||||||
|
|
||||||
local DetectedItem = self.DetectedItemsByIndex[Index]
|
local DetectedItem = self.DetectedItemsByIndex[Index]
|
||||||
if DetectedItem then
|
if DetectedItem then
|
||||||
@ -1661,7 +1666,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
|
||||||
@ -1724,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
|
||||||
@ -1810,13 +1877,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.
|
||||||
@ -1828,7 +1895,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
|
||||||
@ -2033,7 +2100,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 )
|
||||||
|
|
||||||
@ -2268,7 +2335,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
|
||||||
@ -2286,7 +2353,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 )
|
||||||
@ -2408,7 +2475,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 )
|
||||||
@ -2741,7 +2808,7 @@ do -- DETECTION_AREAS
|
|||||||
if AddedToDetectionArea == false then
|
if AddedToDetectionArea == false then
|
||||||
|
|
||||||
-- New detection area
|
-- New detection area
|
||||||
local DetectedItem = self:AddDetectedItemZone( nil,
|
local DetectedItem = self:AddDetectedItemZone( "AREA", nil,
|
||||||
SET_UNIT:New():FilterDeads():FilterCrashes(),
|
SET_UNIT:New():FilterDeads():FilterCrashes(),
|
||||||
ZONE_UNIT:New( DetectedUnitName, DetectedUnit, self.DetectionZoneRange )
|
ZONE_UNIT:New( DetectedUnitName, DetectedUnit, self.DetectionZoneRange )
|
||||||
)
|
)
|
||||||
@ -2773,7 +2840,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
|
||||||
@ -2819,3 +2886,5 @@ do -- DETECTION_AREAS
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
402
Moose Development/Moose/Functional/DetectionZones.lua
Normal file
402
Moose Development/Moose/Functional/DetectionZones.lua
Normal file
@ -0,0 +1,402 @@
|
|||||||
|
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
|
||||||
|
DetectedItem.InterceptCoord = DetectedCoord
|
||||||
|
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 zones, and check if there are new Zones.
|
||||||
|
-- New Zones become a new DetectedItem.
|
||||||
|
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 } )
|
||||||
|
|
||||||
|
-- For all the units in the zone,
|
||||||
|
-- check if they are of the same coalition to be included.
|
||||||
|
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 = {}
|
||||||
|
|
||||||
|
|||||||
@ -356,11 +356,11 @@ do -- ZONE_CAPTURE_COALITION
|
|||||||
-- ZoneCaptureCoalition = ZONE_CAPTURE_COALITION:New( AttackZone, coalition.side.RED ) -- Create a new ZONE_CAPTURE_COALITION object of zone AttackZone with ownership RED coalition.
|
-- ZoneCaptureCoalition = ZONE_CAPTURE_COALITION:New( AttackZone, coalition.side.RED ) -- Create a new ZONE_CAPTURE_COALITION object of zone AttackZone with ownership RED coalition.
|
||||||
-- ZoneCaptureCoalition:__Guard( 1 ) -- Start the Guarding of the AttackZone.
|
-- ZoneCaptureCoalition:__Guard( 1 ) -- Start the Guarding of the AttackZone.
|
||||||
--
|
--
|
||||||
function ZONE_CAPTURE_COALITION:New( Zone, Coalition )
|
function ZONE_CAPTURE_COALITION:New( Zone, Coalition, UnitCategories )
|
||||||
|
|
||||||
local self = BASE:Inherit( self, ZONE_GOAL_COALITION:New( Zone, Coalition ) ) -- #ZONE_CAPTURE_COALITION
|
local self = BASE:Inherit( self, ZONE_GOAL_COALITION:New( Zone, Coalition, UnitCategories ) ) -- #ZONE_CAPTURE_COALITION
|
||||||
|
|
||||||
self:F( { Zone = Zone, Coalition = Coalition } )
|
self:F( { Zone = Zone, Coalition = Coalition, UnitCategories = UnitCategories } )
|
||||||
|
|
||||||
do
|
do
|
||||||
|
|
||||||
|
|||||||
@ -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' )
|
||||||
|
|||||||
@ -73,8 +73,9 @@
|
|||||||
-- * [[MOOSE] Airboss - Groove Test A-4E Community Mod](https://www.youtube.com/watch?v=ZbjD7FHiaHo)
|
-- * [[MOOSE] Airboss - Groove Test A-4E Community Mod](https://www.youtube.com/watch?v=ZbjD7FHiaHo)
|
||||||
-- * [[MOOSE] Airboss - Groove Test: On-the-fly LSO Grading](https://www.youtube.com/watch?v=Xgs1hwDcPyM)
|
-- * [[MOOSE] Airboss - Groove Test: On-the-fly LSO Grading](https://www.youtube.com/watch?v=Xgs1hwDcPyM)
|
||||||
-- * [[MOOSE] Airboss - Carrier Auto Steam Into Wind](https://www.youtube.com/watch?v=IsU8dYgsp90)
|
-- * [[MOOSE] Airboss - Carrier Auto Steam Into Wind](https://www.youtube.com/watch?v=IsU8dYgsp90)
|
||||||
-- * [[MOOSE] Airboss - CASE I Walkthrough by TG](https://www.youtube.com/watch?v=o1UrP4Q6PMM)
|
-- * [[MOOSE] Airboss - CASE I Walkthrough in the F/A-18C by TG](https://www.youtube.com/watch?v=o1UrP4Q6PMM)
|
||||||
-- * [[MOOSE] Airboss - New LSO/Marshal Voice Overs by Raynor](https://www.youtube.com/watch?v=_Suo68bRu8k)
|
-- * [[MOOSE] Airboss - New LSO/Marshal Voice Overs by Raynor](https://www.youtube.com/watch?v=_Suo68bRu8k)
|
||||||
|
-- * [[MOOSE] Airboss - CASE I, "Until We Go Down" featuring the F-14B by Pikes](https://www.youtube.com/watch?v=ojgHDSw3Doc)
|
||||||
--
|
--
|
||||||
-- ### Lex explaining Boat Ops:
|
-- ### Lex explaining Boat Ops:
|
||||||
--
|
--
|
||||||
@ -1663,7 +1664,7 @@ AIRBOSS.MenuF10Root=nil
|
|||||||
|
|
||||||
--- Airboss class version.
|
--- Airboss class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
AIRBOSS.version="0.9.9.6w"
|
AIRBOSS.version="0.9.9.6"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@ -4205,6 +4206,9 @@ function AIRBOSS:SetVoiceOversLSOByFF(mizfolder)
|
|||||||
self.soundfolderLSO=self.soundfolder
|
self.soundfolderLSO=self.soundfolder
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Report for duty.
|
||||||
|
self:I(self.lid..string.format("LSO FF reporting for duty! Soundfolder=%s", tostring(self.soundfolderLSO)))
|
||||||
|
|
||||||
self.LSOCall.BOLTER.duration=0.75
|
self.LSOCall.BOLTER.duration=0.75
|
||||||
self.LSOCall.CALLTHEBALL.duration=0.60
|
self.LSOCall.CALLTHEBALL.duration=0.60
|
||||||
self.LSOCall.CHECK.duration=0.45
|
self.LSOCall.CHECK.duration=0.45
|
||||||
|
|||||||
@ -212,7 +212,7 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
|||||||
if EventGroup and self:HasGroup( EventGroup ) then
|
if EventGroup and self:HasGroup( EventGroup ) then
|
||||||
local CommandCenterMenu = MENU_GROUP:New( EventGroup, self:GetText() )
|
local CommandCenterMenu = MENU_GROUP:New( EventGroup, self:GetText() )
|
||||||
local MenuReporting = MENU_GROUP:New( EventGroup, "Missions Reports", CommandCenterMenu )
|
local MenuReporting = MENU_GROUP:New( EventGroup, "Missions Reports", CommandCenterMenu )
|
||||||
local MenuMissionsSummary = MENU_GROUP_COMMAND:New( EventGroup, "Missions Status Report", MenuReporting, self.ReportMissionsStatus, self, EventGroup )
|
local MenuMissionsSummary = MENU_GROUP_COMMAND:New( EventGroup, "Missions Status Report", MenuReporting, self.ReportSummary, self, EventGroup )
|
||||||
local MenuMissionsDetails = MENU_GROUP_COMMAND:New( EventGroup, "Missions Players Report", MenuReporting, self.ReportMissionsPlayers, self, EventGroup )
|
local MenuMissionsDetails = MENU_GROUP_COMMAND:New( EventGroup, "Missions Players Report", MenuReporting, self.ReportMissionsPlayers, self, EventGroup )
|
||||||
self:ReportSummary( EventGroup )
|
self:ReportSummary( EventGroup )
|
||||||
local PlayerUnit = EventData.IniUnit
|
local PlayerUnit = EventData.IniUnit
|
||||||
@ -508,14 +508,18 @@ function COMMANDCENTER:AssignTask( TaskGroup )
|
|||||||
|
|
||||||
local Task = Tasks[ math.random( 1, #Tasks ) ] -- Tasking.Task#TASK
|
local Task = Tasks[ math.random( 1, #Tasks ) ] -- Tasking.Task#TASK
|
||||||
|
|
||||||
self:I( "Assigning task " .. Task:GetName() .. " using auto assign method " .. self.AutoAssignMethod .. " to " .. TaskGroup:GetName() .. " with task priority " .. AssignPriority )
|
if Task then
|
||||||
|
|
||||||
|
self:I( "Assigning task " .. Task:GetName() .. " using auto assign method " .. self.AutoAssignMethod .. " to " .. TaskGroup:GetName() .. " with task priority " .. AssignPriority )
|
||||||
|
|
||||||
|
if not self.AutoAcceptTasks == true then
|
||||||
|
Task:SetAutoAssignMethod( ACT_ASSIGN_MENU_ACCEPT:New( Task.TaskBriefing ) )
|
||||||
|
end
|
||||||
|
|
||||||
|
Task:AssignToGroup( TaskGroup )
|
||||||
|
|
||||||
if not self.AutoAcceptTasks == true then
|
|
||||||
Task:SetAutoAssignMethod( ACT_ASSIGN_MENU_ACCEPT:New( Task.TaskBriefing ) )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Task:AssignToGroup( TaskGroup )
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -240,6 +240,8 @@ do -- DETECTION MANAGER
|
|||||||
-- @return #DETECTION_MANGER self
|
-- @return #DETECTION_MANGER self
|
||||||
function DETECTION_MANAGER:MessageToPlayers( Message )
|
function DETECTION_MANAGER:MessageToPlayers( Message )
|
||||||
|
|
||||||
|
self:F( { Message = Message } )
|
||||||
|
|
||||||
if self.CC then
|
if self.CC then
|
||||||
self.CC:MessageToCoalition( Message )
|
self.CC:MessageToCoalition( Message )
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1808,7 +1808,7 @@ function TASK:GetPlayerNames() --R2.1 Get a map of the players.
|
|||||||
if PlayerGroup:IsAlive() == true then
|
if PlayerGroup:IsAlive() == true then
|
||||||
if self:IsGroupAssigned( PlayerGroup ) then
|
if self:IsGroupAssigned( PlayerGroup ) then
|
||||||
local PlayerNames = PlayerGroup:GetPlayerNames()
|
local PlayerNames = PlayerGroup:GetPlayerNames()
|
||||||
for PlayerNameID, PlayerName in pairs( PlayerNames ) do
|
for PlayerNameID, PlayerName in pairs( PlayerNames or {} ) do
|
||||||
PlayerNameMap[PlayerName] = PlayerGroup
|
PlayerNameMap[PlayerName] = PlayerGroup
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -162,7 +162,7 @@ end
|
|||||||
-- @param #boolean Keep (optional) If true, this would indicate that the planned taskinfo would be persistent when the task is completed, so that the original planned task info is used at the completed reports.
|
-- @param #boolean Keep (optional) If true, this would indicate that the planned taskinfo would be persistent when the task is completed, so that the original planned task info is used at the completed reports.
|
||||||
-- @return #TASKINFO self
|
-- @return #TASKINFO self
|
||||||
function TASKINFO:AddThreat( ThreatText, ThreatLevel, Order, Detail, Keep )
|
function TASKINFO:AddThreat( ThreatText, ThreatLevel, Order, Detail, Keep )
|
||||||
self:AddInfo( "Threat", ThreatText .. " [" .. string.rep( "■", ThreatLevel ) .. string.rep( "□", 10 - ThreatLevel ) .. "]", Order, Detail, Keep )
|
self:AddInfo( "Threat", " [" .. string.rep( "■", ThreatLevel ) .. string.rep( "□", 10 - ThreatLevel ) .. "]:" .. ThreatText, Order, Detail, Keep )
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -306,65 +306,51 @@ function TASKINFO:Report( Report, Detail, ReportGroup, Task )
|
|||||||
|
|
||||||
for Key, Data in UTILS.spairs( self.Info.Set, function( t, a, b ) return t[a].Order < t[b].Order end ) do
|
for Key, Data in UTILS.spairs( self.Info.Set, function( t, a, b ) return t[a].Order < t[b].Order end ) do
|
||||||
|
|
||||||
self:F( { Key = Key, Detail = Detail, Data = Data } )
|
|
||||||
|
|
||||||
if Data.Detail:find( Detail ) then
|
if Data.Detail:find( Detail ) then
|
||||||
local Text = ""
|
local Text = ""
|
||||||
if Key == "TaskName" then
|
if Key == "TaskName" then
|
||||||
Key = nil
|
Key = nil
|
||||||
Text = Data.Data
|
Text = Data.Data
|
||||||
end
|
elseif Key == "Coordinate" then
|
||||||
if Key == "Coordinate" then
|
|
||||||
local Coordinate = Data.Data -- Core.Point#COORDINATE
|
local Coordinate = Data.Data -- Core.Point#COORDINATE
|
||||||
Text = Coordinate:ToString( ReportGroup:GetUnit(1), nil, Task )
|
Text = Coordinate:ToString( ReportGroup:GetUnit(1), nil, Task )
|
||||||
end
|
elseif Key == "Threat" then
|
||||||
if Key == "Threat" then
|
|
||||||
local DataText = Data.Data -- #string
|
local DataText = Data.Data -- #string
|
||||||
Text = DataText
|
Text = DataText
|
||||||
end
|
elseif Key == "Counting" then
|
||||||
if Key == "Counting" then
|
|
||||||
local DataText = Data.Data -- #string
|
local DataText = Data.Data -- #string
|
||||||
Text = DataText
|
Text = DataText
|
||||||
end
|
elseif Key == "Targets" then
|
||||||
if Key == "Targets" then
|
|
||||||
local DataText = Data.Data -- #string
|
local DataText = Data.Data -- #string
|
||||||
Text = DataText
|
Text = DataText
|
||||||
end
|
elseif Key == "QFE" then
|
||||||
if Key == "QFE" then
|
|
||||||
local Coordinate = Data.Data -- Core.Point#COORDINATE
|
local Coordinate = Data.Data -- Core.Point#COORDINATE
|
||||||
Text = Coordinate:ToStringPressure( ReportGroup:GetUnit(1), nil, Task )
|
Text = Coordinate:ToStringPressure( ReportGroup:GetUnit(1), nil, Task )
|
||||||
end
|
elseif Key == "Temperature" then
|
||||||
if Key == "Temperature" then
|
|
||||||
local Coordinate = Data.Data -- Core.Point#COORDINATE
|
local Coordinate = Data.Data -- Core.Point#COORDINATE
|
||||||
Text = Coordinate:ToStringTemperature( ReportGroup:GetUnit(1), nil, Task )
|
Text = Coordinate:ToStringTemperature( ReportGroup:GetUnit(1), nil, Task )
|
||||||
end
|
elseif Key == "Wind" then
|
||||||
if Key == "Wind" then
|
|
||||||
local Coordinate = Data.Data -- Core.Point#COORDINATE
|
local Coordinate = Data.Data -- Core.Point#COORDINATE
|
||||||
Text = Coordinate:ToStringWind( ReportGroup:GetUnit(1), nil, Task )
|
Text = Coordinate:ToStringWind( ReportGroup:GetUnit(1), nil, Task )
|
||||||
end
|
elseif Key == "Cargo" then
|
||||||
if Key == "Cargo" then
|
local DataText = Data.Data -- #string
|
||||||
|
Text = DataText
|
||||||
|
elseif Key == "Friendlies" then
|
||||||
|
local DataText = Data.Data -- #string
|
||||||
|
Text = DataText
|
||||||
|
elseif Key == "Players" then
|
||||||
|
local DataText = Data.Data -- #string
|
||||||
|
Text = DataText
|
||||||
|
else
|
||||||
local DataText = Data.Data -- #string
|
local DataText = Data.Data -- #string
|
||||||
Text = DataText
|
Text = DataText
|
||||||
end
|
end
|
||||||
if Key == "Friendlies" then
|
|
||||||
local DataText = Data.Data -- #string
|
|
||||||
Text = DataText
|
|
||||||
end
|
|
||||||
if Key == "Players" then
|
|
||||||
local DataText = Data.Data -- #string
|
|
||||||
Text = DataText
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
if Line < math.floor( Data.Order / 10 ) then
|
if Line < math.floor( Data.Order / 10 ) then
|
||||||
if Line == 0 then
|
if Line == 0 then
|
||||||
if Text ~= "" then
|
Report:AddIndent( LineReport:Text( ", " ), "-" )
|
||||||
Report:AddIndent( LineReport:Text( ", " ), "-" )
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
if Text ~= "" then
|
Report:AddIndent( LineReport:Text( ", " ) )
|
||||||
Report:AddIndent( LineReport:Text( ", " ) )
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
LineReport = REPORT:New()
|
LineReport = REPORT:New()
|
||||||
Line = math.floor( Data.Order / 10 )
|
Line = math.floor( Data.Order / 10 )
|
||||||
@ -373,8 +359,9 @@ function TASKINFO:Report( Report, Detail, ReportGroup, Task )
|
|||||||
if Text ~= "" then
|
if Text ~= "" then
|
||||||
LineReport:Add( ( Key and ( Key .. ":" ) or "" ) .. Text )
|
LineReport:Add( ( Key and ( Key .. ":" ) or "" ) .. Text )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Report:AddIndent( LineReport:Text( ", " ) )
|
|
||||||
|
|
||||||
|
Report:AddIndent( LineReport:Text( ", " ) )
|
||||||
end
|
end
|
||||||
|
|||||||
@ -362,7 +362,7 @@ do -- TASK_A2A
|
|||||||
return math.random( 1, 9 )
|
return math.random( 1, 9 )
|
||||||
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Distance then
|
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Distance then
|
||||||
local Coordinate = self.TaskInfo:GetData( "Coordinate" )
|
local Coordinate = self.TaskInfo:GetData( "Coordinate" )
|
||||||
local Distance = TaskGroup:GetCoordinate():Get2DDistance( CommandCenter:GetPositionable():GetCoordinate() )
|
local Distance = Coordinate:Get2DDistance( CommandCenter:GetPositionable():GetCoordinate() )
|
||||||
return math.floor( Distance )
|
return math.floor( Distance )
|
||||||
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Priority then
|
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Priority then
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@ -367,7 +367,8 @@ do -- TASK_A2G
|
|||||||
return math.random( 1, 9 )
|
return math.random( 1, 9 )
|
||||||
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Distance then
|
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Distance then
|
||||||
local Coordinate = self.TaskInfo:GetData( "Coordinate" )
|
local Coordinate = self.TaskInfo:GetData( "Coordinate" )
|
||||||
local Distance = TaskGroup:GetCoordinate():Get2DDistance( CommandCenter:GetPositionable():GetCoordinate() )
|
local Distance = Coordinate:Get2DDistance( CommandCenter:GetPositionable():GetCoordinate() )
|
||||||
|
self:F({Distance=Distance})
|
||||||
return math.floor( Distance )
|
return math.floor( Distance )
|
||||||
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Priority then
|
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Priority then
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@ -633,7 +633,7 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
--DetectedSet:Flush( self )
|
--DetectedSet:Flush( self )
|
||||||
|
|
||||||
local DetectedItemID = DetectedItem.ID
|
local DetectedItemID = DetectedItem.ID
|
||||||
local TaskIndex = DetectedItem.ID
|
local TaskIndex = DetectedItem.Index
|
||||||
local DetectedItemChanged = DetectedItem.Changed
|
local DetectedItemChanged = DetectedItem.Changed
|
||||||
|
|
||||||
self:F( { DetectedItemChanged = DetectedItemChanged, DetectedItemID = DetectedItemID, TaskIndex = TaskIndex } )
|
self:F( { DetectedItemChanged = DetectedItemChanged, DetectedItemID = DetectedItemID, TaskIndex = TaskIndex } )
|
||||||
@ -649,6 +649,7 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
if TargetSetUnit then
|
if TargetSetUnit then
|
||||||
if Task:IsInstanceOf( TASK_A2G_SEAD ) then
|
if Task:IsInstanceOf( TASK_A2G_SEAD ) then
|
||||||
Task:SetTargetSetUnit( TargetSetUnit )
|
Task:SetTargetSetUnit( TargetSetUnit )
|
||||||
|
Task:SetDetection( Detection, DetectedItem )
|
||||||
Task:UpdateTaskInfo( DetectedItem )
|
Task:UpdateTaskInfo( DetectedItem )
|
||||||
TargetsReport:Add( Detection:GetChangeText( DetectedItem ) )
|
TargetsReport:Add( Detection:GetChangeText( DetectedItem ) )
|
||||||
else
|
else
|
||||||
@ -659,7 +660,7 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
if TargetSetUnit then
|
if TargetSetUnit then
|
||||||
if Task:IsInstanceOf( TASK_A2G_CAS ) then
|
if Task:IsInstanceOf( TASK_A2G_CAS ) then
|
||||||
Task:SetTargetSetUnit( TargetSetUnit )
|
Task:SetTargetSetUnit( TargetSetUnit )
|
||||||
Task:SetDetection( Detection, TaskIndex )
|
Task:SetDetection( Detection, DetectedItem )
|
||||||
Task:UpdateTaskInfo( DetectedItem )
|
Task:UpdateTaskInfo( DetectedItem )
|
||||||
TargetsReport:Add( Detection:GetChangeText( DetectedItem ) )
|
TargetsReport:Add( Detection:GetChangeText( DetectedItem ) )
|
||||||
else
|
else
|
||||||
@ -671,7 +672,7 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
if TargetSetUnit then
|
if TargetSetUnit then
|
||||||
if Task:IsInstanceOf( TASK_A2G_BAI ) then
|
if Task:IsInstanceOf( TASK_A2G_BAI ) then
|
||||||
Task:SetTargetSetUnit( TargetSetUnit )
|
Task:SetTargetSetUnit( TargetSetUnit )
|
||||||
Task:SetDetection( Detection, TaskIndex )
|
Task:SetDetection( Detection, DetectedItem )
|
||||||
Task:UpdateTaskInfo( DetectedItem )
|
Task:UpdateTaskInfo( DetectedItem )
|
||||||
TargetsReport:Add( Detection:GetChangeText( DetectedItem ) )
|
TargetsReport:Add( Detection:GetChangeText( DetectedItem ) )
|
||||||
else
|
else
|
||||||
|
|||||||
@ -170,6 +170,9 @@ do -- TASK_CAPTURE_DISPATCHER
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TASK_CAPTURE_DISPATCHER.AI_A2G_Dispatcher = nil -- AI.AI_A2G_Dispatcher#AI_A2G_DISPATCHER
|
||||||
|
|
||||||
--- TASK_CAPTURE_DISPATCHER constructor.
|
--- TASK_CAPTURE_DISPATCHER constructor.
|
||||||
-- @param #TASK_CAPTURE_DISPATCHER self
|
-- @param #TASK_CAPTURE_DISPATCHER self
|
||||||
-- @param Tasking.Mission#MISSION Mission The mission for which the task dispatching is done.
|
-- @param Tasking.Mission#MISSION Mission The mission for which the task dispatching is done.
|
||||||
@ -223,6 +226,19 @@ do -- TASK_CAPTURE_DISPATCHER
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Link an AI_A2G_DISPATCHER to the TASK_CAPTURE_DISPATCHER.
|
||||||
|
-- @param #TASK_CAPTURE_DISPATCHER self
|
||||||
|
-- @param AI.AI_A2G_Dispatcher#AI_A2G_DISPATCHER AI_A2G_Dispatcher The AI Dispatcher to be linked to the tasking.
|
||||||
|
-- @return Tasking.Task_Capture_Zone#TASK_CAPTURE_ZONE
|
||||||
|
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
|
||||||
|
AI_A2G_Dispatcher.Detection:LockDetectedItems()
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Assigns tasks to the @{Core.Set#SET_GROUP}.
|
--- Assigns tasks to the @{Core.Set#SET_GROUP}.
|
||||||
-- @param #TASK_CAPTURE_DISPATCHER self
|
-- @param #TASK_CAPTURE_DISPATCHER self
|
||||||
-- @return #boolean Return true if you want the task assigning to continue... false will cancel the loop.
|
-- @return #boolean Return true if you want the task assigning to continue... false will cancel the loop.
|
||||||
@ -246,6 +262,7 @@ do -- TASK_CAPTURE_DISPATCHER
|
|||||||
-- Here we need to check if the pilot is still existing.
|
-- Here we need to check if the pilot is still existing.
|
||||||
-- Task = self:RemoveTask( TaskIndex )
|
-- Task = self:RemoveTask( TaskIndex )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Now that all obsolete tasks are removed, loop through the Zone tasks.
|
-- Now that all obsolete tasks are removed, loop through the Zone tasks.
|
||||||
@ -257,25 +274,54 @@ do -- TASK_CAPTURE_DISPATCHER
|
|||||||
CaptureZone.Task.TaskPrefix = CaptureZone.TaskPrefix -- We keep the TaskPrefix for further reference!
|
CaptureZone.Task.TaskPrefix = CaptureZone.TaskPrefix -- We keep the TaskPrefix for further reference!
|
||||||
Mission:AddTask( CaptureZone.Task )
|
Mission:AddTask( CaptureZone.Task )
|
||||||
TaskReport:Add( TaskName )
|
TaskReport:Add( TaskName )
|
||||||
|
CaptureZone.Task:UpdateTaskInfo()
|
||||||
|
|
||||||
|
function CaptureZone.Task.OnEnterAssigned( Task, From, Event, To )
|
||||||
|
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()
|
||||||
|
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()
|
||||||
end
|
end
|
||||||
|
|
||||||
function CaptureZone.Task.OnEnterCancelled( Task, From, Event, To )
|
function CaptureZone.Task.OnEnterCancelled( Task, From, Event, To )
|
||||||
self:Cancelled( Task )
|
self:Cancelled( 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()
|
||||||
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()
|
||||||
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()
|
||||||
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()
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -47,7 +47,7 @@ do -- TASK_ZONE_GOAL
|
|||||||
-- @param Tasking.Mission#MISSION Mission
|
-- @param Tasking.Mission#MISSION Mission
|
||||||
-- @param Core.Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned.
|
-- @param Core.Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned.
|
||||||
-- @param #string TaskName The name of the Task.
|
-- @param #string TaskName The name of the Task.
|
||||||
-- @param Core.ZoneGoal#ZONE_GOAL ZoneGoal
|
-- @param Core.ZoneGoalCoalition#ZONE_GOAL_COALITION ZoneGoal
|
||||||
-- @return #TASK_ZONE_GOAL self
|
-- @return #TASK_ZONE_GOAL self
|
||||||
function TASK_ZONE_GOAL:New( Mission, SetGroup, TaskName, ZoneGoal, TaskType, TaskBriefing )
|
function TASK_ZONE_GOAL:New( Mission, SetGroup, TaskName, ZoneGoal, TaskType, TaskBriefing )
|
||||||
local self = BASE:Inherit( self, TASK:New( Mission, SetGroup, TaskName, TaskType, TaskBriefing ) ) -- #TASK_ZONE_GOAL
|
local self = BASE:Inherit( self, TASK:New( Mission, SetGroup, TaskName, TaskType, TaskBriefing ) ) -- #TASK_ZONE_GOAL
|
||||||
@ -211,7 +211,9 @@ do -- TASK_CAPTURE_ZONE
|
|||||||
"Capture Zone " .. self.TaskZoneName
|
"Capture Zone " .. self.TaskZoneName
|
||||||
)
|
)
|
||||||
|
|
||||||
self:UpdateTaskInfo()
|
self:UpdateTaskInfo( true )
|
||||||
|
|
||||||
|
self:SetGoalTotal( 1 )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -219,12 +221,18 @@ do -- TASK_CAPTURE_ZONE
|
|||||||
|
|
||||||
--- Instantiates a new TASK_CAPTURE_ZONE.
|
--- Instantiates a new TASK_CAPTURE_ZONE.
|
||||||
-- @param #TASK_CAPTURE_ZONE self
|
-- @param #TASK_CAPTURE_ZONE self
|
||||||
function TASK_CAPTURE_ZONE:UpdateTaskInfo()
|
function TASK_CAPTURE_ZONE:UpdateTaskInfo( Persist )
|
||||||
|
|
||||||
|
Persist = Persist or false
|
||||||
|
|
||||||
local ZoneCoordinate = self.ZoneGoal:GetZone():GetCoordinate()
|
local ZoneCoordinate = self.ZoneGoal:GetZone():GetCoordinate()
|
||||||
self.TaskInfo:AddCoordinate( ZoneCoordinate, 0, "SOD" )
|
self.TaskInfo:AddTaskName( 0, "MSOD", Persist )
|
||||||
self.TaskInfo:AddText( "Zone Name", self.ZoneGoal:GetZoneName(), 10, "MOD" )
|
self.TaskInfo:AddCoordinate( ZoneCoordinate, 1, "SOD", Persist )
|
||||||
self.TaskInfo:AddText( "Zone Coalition", self.ZoneGoal:GetCoalitionName(), 11, "MOD" )
|
self.TaskInfo:AddText( "Zone Name", self.ZoneGoal:GetZoneName(), 10, "MOD", Persist )
|
||||||
|
self.TaskInfo:AddText( "Zone Coalition", self.ZoneGoal:GetCoalitionName(), 11, "MOD", Persist )
|
||||||
|
local SetUnit = self.ZoneGoal.Zone:GetScannedSetUnit()
|
||||||
|
local ThreatLevel, ThreatText = SetUnit:CalculateThreatLevelA2G()
|
||||||
|
self.TaskInfo:AddThreat( ThreatText, ThreatLevel, 20, "MSOD", Persist )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -245,7 +253,6 @@ do -- TASK_CAPTURE_ZONE
|
|||||||
|
|
||||||
if self.ZoneGoal then
|
if self.ZoneGoal then
|
||||||
if self.ZoneGoal.Goal:IsAchieved() then
|
if self.ZoneGoal.Goal:IsAchieved() then
|
||||||
self:Success()
|
|
||||||
local TotalContributions = self.ZoneGoal.Goal:GetTotalContributions()
|
local TotalContributions = self.ZoneGoal.Goal:GetTotalContributions()
|
||||||
local PlayerContributions = self.ZoneGoal.Goal:GetPlayerContributions()
|
local PlayerContributions = self.ZoneGoal.Goal:GetPlayerContributions()
|
||||||
self:F( { TotalContributions = TotalContributions, PlayerContributions = PlayerContributions } )
|
self:F( { TotalContributions = TotalContributions, PlayerContributions = PlayerContributions } )
|
||||||
@ -255,6 +262,7 @@ do -- TASK_CAPTURE_ZONE
|
|||||||
Scoring:_AddMissionGoalScore( self.Mission, PlayerName, "Zone " .. self.ZoneGoal:GetZoneName() .." captured", PlayerContribution * 200 / TotalContributions )
|
Scoring:_AddMissionGoalScore( self.Mission, PlayerName, "Zone " .. self.ZoneGoal:GetZoneName() .." captured", PlayerContribution * 200 / TotalContributions )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
self:Success()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -272,7 +280,7 @@ do -- TASK_CAPTURE_ZONE
|
|||||||
return math.random( 1, 9 )
|
return math.random( 1, 9 )
|
||||||
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Distance then
|
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Distance then
|
||||||
local Coordinate = self.TaskInfo:GetCoordinate()
|
local Coordinate = self.TaskInfo:GetCoordinate()
|
||||||
local Distance = TaskGroup:GetCoordinate():Get2DDistance( CommandCenter:GetPositionable():GetCoordinate() )
|
local Distance = Coordinate:Get2DDistance( CommandCenter:GetPositionable():GetCoordinate() )
|
||||||
return math.floor( Distance )
|
return math.floor( Distance )
|
||||||
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Priority then
|
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Priority then
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@ -1101,7 +1101,7 @@ function POSITIONABLE:MessageToSetGroup( Message, Duration, MessageSetGroup, Nam
|
|||||||
local DCSObject = self:GetDCSObject()
|
local DCSObject = self:GetDCSObject()
|
||||||
if DCSObject then
|
if DCSObject then
|
||||||
if DCSObject:isExist() then
|
if DCSObject:isExist() then
|
||||||
MessageSetGroup:ForEachGroup(
|
MessageSetGroup:ForEachGroupAlive(
|
||||||
function( MessageGroup )
|
function( MessageGroup )
|
||||||
self:GetMessage( Message, Duration, Name ):ToGroup( MessageGroup )
|
self:GetMessage( Message, Duration, Name ):ToGroup( MessageGroup )
|
||||||
end
|
end
|
||||||
@ -1479,3 +1479,33 @@ function POSITIONABLE:SmokeBlue()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Returns true if the unit is within a @{Zone}.
|
||||||
|
-- @param #STPOSITIONABLEATIC self
|
||||||
|
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
||||||
|
-- @return #boolean Returns true if the unit is within the @{Core.Zone#ZONE_BASE}
|
||||||
|
function POSITIONABLE:IsInZone( Zone )
|
||||||
|
self:F2( { self.PositionableName, Zone } )
|
||||||
|
|
||||||
|
if self:IsAlive() then
|
||||||
|
local IsInZone = Zone:IsVec3InZone( self:GetVec3() )
|
||||||
|
|
||||||
|
return IsInZone
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns true if the unit is not within a @{Zone}.
|
||||||
|
-- @param #POSITIONABLE self
|
||||||
|
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
||||||
|
-- @return #boolean Returns true if the unit is not within the @{Core.Zone#ZONE_BASE}
|
||||||
|
function POSITIONABLE:IsNotInZone( Zone )
|
||||||
|
self:F2( { self.PositionableName, Zone } )
|
||||||
|
|
||||||
|
if self:IsAlive() then
|
||||||
|
local IsNotInZone = not Zone:IsVec3InZone( self:GetVec3() )
|
||||||
|
|
||||||
|
return IsNotInZone
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -214,35 +214,3 @@ function STATIC:ReSpawnAt( Coordinate, Heading )
|
|||||||
SpawnStatic:ReSpawnAt( Coordinate, Heading )
|
SpawnStatic:ReSpawnAt( Coordinate, Heading )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Returns true if the unit is within a @{Zone}.
|
|
||||||
-- @param #STATIC self
|
|
||||||
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
|
||||||
-- @return #boolean Returns true if the unit is within the @{Core.Zone#ZONE_BASE}
|
|
||||||
function STATIC:IsInZone( Zone )
|
|
||||||
self:F2( { self.StaticName, Zone } )
|
|
||||||
|
|
||||||
if self:IsAlive() then
|
|
||||||
local IsInZone = Zone:IsVec3InZone( self:GetVec3() )
|
|
||||||
|
|
||||||
return IsInZone
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Returns true if the unit is not within a @{Zone}.
|
|
||||||
-- @param #STATIC self
|
|
||||||
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
|
||||||
-- @return #boolean Returns true if the unit is not within the @{Core.Zone#ZONE_BASE}
|
|
||||||
function STATIC:IsNotInZone( Zone )
|
|
||||||
self:F2( { self.StaticName, Zone } )
|
|
||||||
|
|
||||||
if self:IsAlive() then
|
|
||||||
local IsInZone = not Zone:IsVec3InZone( self:GetVec3() )
|
|
||||||
|
|
||||||
self:T( { IsInZone } )
|
|
||||||
return IsInZone
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|||||||
@ -348,7 +348,7 @@ end
|
|||||||
-- @return #string Player Name
|
-- @return #string Player Name
|
||||||
-- @return #nil The DCS Unit is not existing or alive.
|
-- @return #nil The DCS Unit is not existing or alive.
|
||||||
function UNIT:GetPlayerName()
|
function UNIT:GetPlayerName()
|
||||||
self:F2( self.UnitName )
|
self:F( self.UnitName )
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject() -- DCS#Unit
|
local DCSUnit = self:GetDCSObject() -- DCS#Unit
|
||||||
|
|
||||||
@ -831,37 +831,6 @@ end
|
|||||||
|
|
||||||
-- Is functions
|
-- Is functions
|
||||||
|
|
||||||
--- Returns true if the unit is within a @{Zone}.
|
|
||||||
-- @param #UNIT self
|
|
||||||
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
|
||||||
-- @return #boolean Returns true if the unit is within the @{Core.Zone#ZONE_BASE}
|
|
||||||
function UNIT:IsInZone( Zone )
|
|
||||||
self:F2( { self.UnitName, Zone } )
|
|
||||||
|
|
||||||
if self:IsAlive() then
|
|
||||||
local IsInZone = Zone:IsVec3InZone( self:GetVec3() )
|
|
||||||
|
|
||||||
return IsInZone
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Returns true if the unit is not within a @{Zone}.
|
|
||||||
-- @param #UNIT self
|
|
||||||
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
|
||||||
-- @return #boolean Returns true if the unit is not within the @{Core.Zone#ZONE_BASE}
|
|
||||||
function UNIT:IsNotInZone( Zone )
|
|
||||||
self:F2( { self.UnitName, Zone } )
|
|
||||||
|
|
||||||
if self:IsAlive() then
|
|
||||||
local IsInZone = not Zone:IsVec3InZone( self:GetVec3() )
|
|
||||||
|
|
||||||
self:T( { IsInZone } )
|
|
||||||
return IsInZone
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Returns true if there is an **other** DCS Unit within a radius of the current 2D point of the DCS Unit.
|
--- Returns true if there is an **other** DCS Unit within a radius of the current 2D point of the DCS Unit.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user