Merge branch 'master' into funkyfranky

This commit is contained in:
funkyfranky
2017-08-30 08:51:53 +02:00
38 changed files with 1944 additions and 827 deletions

View File

@@ -440,7 +440,7 @@ function AI_A2A:onafterStatus()
end
end
if self:Is( "Damaged" ) or self:Is( "LostControl" ) then
if self:Is( "Fuel" ) or self:Is( "Damaged" ) or self:Is( "LostControl" ) then
if DistanceFromHomeBase < 5000 then
self:E( self.Controllable:GetName() .. " is too far from home base, RTB!" )
self:Home( "Destroy" )
@@ -448,25 +448,27 @@ function AI_A2A:onafterStatus()
end
local Fuel = self.Controllable:GetFuel()
self:F({Fuel=Fuel})
if Fuel < self.PatrolFuelThresholdPercentage then
if self.TankerName then
self:E( self.Controllable:GetName() .. " is out of fuel: " .. Fuel .. " ... Refuelling at Tanker!" )
self:Refuel()
if not self:Is( "Fuel" ) and not self:Is( "Home" ) then
local Fuel = self.Controllable:GetFuel()
self:F({Fuel=Fuel})
if Fuel < self.PatrolFuelThresholdPercentage then
if self.TankerName then
self:E( self.Controllable:GetName() .. " is out of fuel: " .. Fuel .. " ... Refuelling at Tanker!" )
self:Refuel()
else
self:E( self.Controllable:GetName() .. " is out of fuel: " .. Fuel .. " ... RTB!" )
local OldAIControllable = self.Controllable
local AIControllableTemplate = self.Controllable:GetTemplate()
local OrbitTask = OldAIControllable:TaskOrbitCircle( math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude ), self.PatrolMinSpeed )
local TimedOrbitTask = OldAIControllable:TaskControlled( OrbitTask, OldAIControllable:TaskCondition(nil,nil,nil,nil,self.PatrolOutOfFuelOrbitTime,nil ) )
OldAIControllable:SetTask( TimedOrbitTask, 10 )
self:Fuel()
RTB = true
end
else
self:E( self.Controllable:GetName() .. " is out of fuel: " .. Fuel .. " ... RTB!" )
local OldAIControllable = self.Controllable
local AIControllableTemplate = self.Controllable:GetTemplate()
local OrbitTask = OldAIControllable:TaskOrbitCircle( math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude ), self.PatrolMinSpeed )
local TimedOrbitTask = OldAIControllable:TaskControlled( OrbitTask, OldAIControllable:TaskCondition(nil,nil,nil,nil,self.PatrolOutOfFuelOrbitTime,nil ) )
OldAIControllable:SetTask( TimedOrbitTask, 10 )
self:Fuel()
RTB = true
end
else
end
-- TODO: Check GROUP damage function.
@@ -477,6 +479,7 @@ function AI_A2A:onafterStatus()
self:E( self.Controllable:GetName() .. " is damaged: " .. Damage .. " ... RTB!" )
self:Damaged()
RTB = true
self:SetStatusOff()
end
-- Check if planes went RTB and are out of control.

View File

@@ -1000,7 +1000,7 @@ do -- AI_A2A_DISPATCHER
--- @param #AI_A2A_DISPATCHER self
-- @param Core.Event#EVENTDATA EventData
function AI_A2A_DISPATCHER:OnEventLand( EventData )
self:F( "Landed" )
self:E( "Landed" )
local DefenderUnit = EventData.IniUnit
local Defender = EventData.IniGroup
local Squadron = self:GetSquadronFromDefender( Defender )
@@ -1019,7 +1019,11 @@ do -- AI_A2A_DISPATCHER
-- Damaged units cannot be repaired anymore.
DefenderUnit:Destroy()
return
end
end
if DefenderUnit:GetFuel() <= self.DefenderDefault.FuelThreshold then
DefenderUnit:Destroy()
return
end
end
end
@@ -1348,11 +1352,12 @@ do -- AI_A2A_DISPATCHER
---
-- @param #AI_A2A_DISPATCHER self
function AI_A2A_DISPATCHER:SetDefenderTask( Defender, Type, Fsm, Target )
function AI_A2A_DISPATCHER:SetDefenderTask( SquadronName, Defender, Type, Fsm, Target )
self.DefenderTasks[Defender] = self.DefenderTasks[Defender] or {}
self.DefenderTasks[Defender].Type = Type
self.DefenderTasks[Defender].Fsm = Fsm
self.DefenderTasks[Defender].SquadronName = SquadronName
if Target then
self:SetDefenderTaskTarget( Defender, Target )
@@ -1449,7 +1454,6 @@ do -- AI_A2A_DISPATCHER
-- @return #AI_A2A_DISPATCHER
function AI_A2A_DISPATCHER:SetSquadron( SquadronName, AirbaseName, SpawnTemplates, Resources )
self:E( { SquadronName = SquadronName, AirbaseName = AirbaseName, SpawnTemplates = SpawnTemplates, Resources = Resources } )
self.DefenderSquadrons[SquadronName] = self.DefenderSquadrons[SquadronName] or {}
@@ -1473,6 +1477,8 @@ do -- AI_A2A_DISPATCHER
end
end
DefenderSquadron.Resources = Resources
self:E( { Squadron = {SquadronName, AirbaseName, SpawnTemplates, Resources } } )
return self
end
@@ -1537,6 +1543,8 @@ do -- AI_A2A_DISPATCHER
Cap.AltType = AltType
self:SetSquadronCapInterval( SquadronName, self.DefenderDefault.CapLimit, self.DefenderDefault.CapMinSeconds, self.DefenderDefault.CapMaxSeconds, 1 )
self:E( { CAP = { SquadronName, Zone, FloorAltitude, CeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, EngageMinSpeed, EngageMaxSpeed, AltType } } )
return self
end
@@ -1577,14 +1585,15 @@ do -- AI_A2A_DISPATCHER
local Scheduler = Cap.Scheduler -- Core.Scheduler#SCHEDULER
local ScheduleID = Cap.ScheduleID
local Variance = ( Cap.HighInterval - Cap.LowInterval ) / 2
local Median = Cap.LowInterval + Variance
local Randomization = Variance / Median
local Repeat = Cap.LowInterval + Variance
local Randomization = Variance / Repeat
local Start = math.random( 1, Cap.HighInterval )
if ScheduleID then
Scheduler:Stop( ScheduleID )
end
Cap.ScheduleID = Scheduler:Schedule( self, self.SchedulerCAP, { SquadronName }, Median, Median, Randomization )
Cap.ScheduleID = Scheduler:Schedule( self, self.SchedulerCAP, { SquadronName }, Start, Repeat, Randomization )
else
error( "This squadron does not exist:" .. SquadronName )
end
@@ -1627,6 +1636,7 @@ do -- AI_A2A_DISPATCHER
local Cap = DefenderSquadron.Cap
if Cap then
local CapCount = self:CountCapAirborne( SquadronName )
self:E( { CapCount = CapCount } )
if CapCount < Cap.CapLimit then
local Probability = math.random()
if Probability <= Cap.Probability then
@@ -1683,6 +1693,8 @@ do -- AI_A2A_DISPATCHER
Intercept.Name = SquadronName
Intercept.EngageMinSpeed = EngageMinSpeed
Intercept.EngageMaxSpeed = EngageMaxSpeed
self:E( { GCI = { SquadronName, EngageMinSpeed, EngageMaxSpeed } } )
end
--- Defines the default amount of extra planes that will take-off as part of the defense system.
@@ -2465,12 +2477,14 @@ do -- AI_A2A_DISPATCHER
local DefenderSquadron = self.DefenderSquadrons[SquadronName]
if DefenderSquadron then
for AIGroup, DefenderTask in pairs( self:GetDefenderTasks() ) do
if DefenderTask.Type == "CAP" then
if AIGroup:IsAlive() then
-- Check if the CAP is patrolling or engaging. If not, this is not a valid CAP, even if it is alive!
-- The CAP could be damaged, lost control, or out of fuel!
if DefenderTask.Fsm:Is( "Patrolling" ) or DefenderTask.Fsm:Is( "Engaging" ) or DefenderTask.Fsm:Is( "Refuelling" )then
CapCount = CapCount + 1
if DefenderTask.SquadronName == SquadronName then
if DefenderTask.Type == "CAP" then
if AIGroup:IsAlive() then
-- Check if the CAP is patrolling or engaging. If not, this is not a valid CAP, even if it is alive!
-- The CAP could be damaged, lost control, or out of fuel!
if DefenderTask.Fsm:Is( "Patrolling" ) or DefenderTask.Fsm:Is( "Engaging" ) or DefenderTask.Fsm:Is( "Refuelling" )then
CapCount = CapCount + 1
end
end
end
end
@@ -2488,12 +2502,17 @@ do -- AI_A2A_DISPATCHER
-- First, count the active AIGroups Units, targetting the DetectedSet
local AIUnitCount = 0
self:E( "Counting Defenders Engaged for Attacker:" )
local DetectedSet = Target.Set
DetectedSet:Flush()
local DefenderTasks = self:GetDefenderTasks()
for AIGroup, DefenderTask in pairs( DefenderTasks ) do
local AIGroup = AIGroup -- Wrapper.Group#GROUP
local DefenderTask = self:GetDefenderTaskTarget( AIGroup )
if DefenderTask and DefenderTask.Index == Target.Index then
AIUnitCount = AIUnitCount + AIGroup:GetSize()
self:E( "Defender Group Name: " .. AIGroup:GetName() .. ", Size: " .. AIGroup:GetSize() )
end
end
@@ -2581,7 +2600,34 @@ do -- AI_A2A_DISPATCHER
Fsm:Start()
Fsm:__Patrol( 2 )
self:SetDefenderTask( DefenderCAP, "CAP", Fsm )
self:SetDefenderTask( SquadronName, DefenderCAP, "CAP", Fsm )
function Fsm:onafterRTB( Defender, From, Event, To )
self:F({"CAP RTB", Defender:GetName()})
self:GetParent(self).onafterRTB( self, Defender, From, Event, To )
local Dispatcher = self:GetDispatcher() -- #AI_A2A_DISPATCHER
Dispatcher:ClearDefenderTaskTarget( Defender )
end
--- @param #AI_A2A_DISPATCHER self
function Fsm:onafterHome( Defender, From, Event, To, Action )
self:E({"CAP Home", Defender:GetName()})
self:GetParent(self).onafterHome( self, Defender, From, Event, To )
local Dispatcher = self:GetDispatcher() -- #AI_A2A_DISPATCHER
local Squadron = Dispatcher:GetSquadronFromDefender( Defender )
if Action and Action == "Destroy" then
Dispatcher:RemoveDefenderFromSquadron( Squadron, Defender )
Defender:Destroy()
end
if Dispatcher:GetSquadronLanding( Squadron.Name ) == AI_A2A_DISPATCHER.Landing.NearAirbase then
Dispatcher:RemoveDefenderFromSquadron( Squadron, Defender )
Defender:Destroy()
end
end
end
end
end
@@ -2602,32 +2648,6 @@ do -- AI_A2A_DISPATCHER
self:SetDefenderTaskTarget( Defender, Target )
function Fsm:onafterRTB( Defender, From, Event, To )
self:F({"CAP RTB", Defender:GetName()})
self:GetParent(self).onafterRTB( self, Defender, From, Event, To )
local Dispatcher = self:GetDispatcher() -- #AI_A2A_DISPATCHER
Dispatcher:ClearDefenderTaskTarget( Defender )
end
--- @param #AI_A2A_DISPATCHER self
function Fsm:onafterHome( Defender, From, Event, To, Action )
self:F({"CAP Home", Defender:GetName()})
self:GetParent(self).onafterHome( self, Defender, From, Event, To )
local Dispatcher = self:GetDispatcher() -- #AI_A2A_DISPATCHER
local Squadron = Dispatcher:GetSquadronFromDefender( Defender )
if Action and Action == "Destroy" then
Dispatcher:RemoveDefenderFromSquadron( Squadron, Defender )
Defender:Destroy()
end
if Dispatcher:GetSquadronLanding( Squadron.Name ) == AI_A2A_DISPATCHER.Landing.NearAirbase then
Dispatcher:RemoveDefenderFromSquadron( Squadron, Defender )
Defender:Destroy()
end
end
end
end
end
@@ -2636,6 +2656,8 @@ do -- AI_A2A_DISPATCHER
-- @param #AI_A2A_DISPATCHER self
function AI_A2A_DISPATCHER:onafterGCI( From, Event, To, DetectedItem, DefendersMissing, Friendlies )
self:F( { From, Event, To, DetectedItem.Index, DefendersMissing, Friendlies } )
local AttackerSet = DetectedItem.Set
local AttackerCount = AttackerSet:Count()
local DefendersCount = 0
@@ -2658,17 +2680,19 @@ do -- AI_A2A_DISPATCHER
local BreakLoop = false
while( DefendersCount > 0 and not BreakLoop ) do
self:F( { DefenderSquadrons = self.DefenderSquadrons } )
for SquadronName, DefenderSquadron in pairs( self.DefenderSquadrons or {} ) do
self:F( { GCI = DefenderSquadron.Gci } )
for InterceptID, Intercept in pairs( DefenderSquadron.Gci or {} ) do
--self:E( { DefenderSquadron } )
self:F( { DefenderSquadron } )
local SpawnCoord = DefenderSquadron.Airbase:GetCoordinate() -- Core.Point#COORDINATE
--local TargetCoord = AttackerSet:GetFirst():GetCoordinate()
local TargetCoord = DetectedItem.InterceptCoord
if TargetCoord then
local Distance = SpawnCoord:Get2DDistance( TargetCoord )
self:F( { Distance = Distance, TargetCoord = TargetCoord } )
local InterceptCoord = DetectedItem.InterceptCoord
self:F({InterceptCoord = InterceptCoord})
if InterceptCoord then
local Distance = SpawnCoord:Get2DDistance( InterceptCoord )
self:F( { Distance = Distance, InterceptCoord = InterceptCoord } )
if ClosestDistance == 0 or Distance < ClosestDistance then
@@ -2732,7 +2756,7 @@ do -- AI_A2A_DISPATCHER
Fsm:__Engage( 2, DetectedItem.Set ) -- Engage on the TargetSetUnit
self:SetDefenderTask( DefenderGCI, "GCI", Fsm, DetectedItem )
self:SetDefenderTask( ClosestDefenderSquadronName, DefenderGCI, "GCI", Fsm, DetectedItem )
function Fsm:onafterRTB( Defender, From, Event, To )
@@ -2865,14 +2889,14 @@ do -- AI_A2A_DISPATCHER
self:ClearDefenderTask( AIGroup )
else
if DefenderTask.Target then
local Target = Detection:GetDetectedItem( DefenderTask.Target.Index )
if not Target then
local AttackerItem = Detection:GetDetectedItem( DefenderTask.Target.Index )
if not AttackerItem then
self:F( { "Removing obsolete Target:", DefenderTask.Target.Index } )
self:ClearDefenderTaskTarget( AIGroup )
else
if DefenderTask.Target.Set then
if DefenderTask.Target.Set:Count() == 0 then
local AttackerCount = DefenderTask.Target.Set:Count()
if AttackerCount == 0 then
self:F( { "All Targets destroyed in Target, removing:", DefenderTask.Target.Index } )
self:ClearDefenderTaskTarget( AIGroup )
end
@@ -2958,7 +2982,7 @@ do -- AI_A2A_DISPATCHER
end
Report:Add( string.format( "\n - %d Tasks", TaskCount ) )
self:T( Report:Text( "\n" ) )
self:E( Report:Text( "\n" ) )
trigger.action.outText( Report:Text( "\n" ), 25 )
end
@@ -3454,6 +3478,7 @@ do
-- Setup squadrons
self:F( { Airbases = AirbaseNames } )
self.Templates:Flush()
for AirbaseID, AirbaseName in pairs( AirbaseNames ) do
local Airbase = _DATABASE:FindAirbase( AirbaseName ) -- Wrapper.Airbase#AIRBASE

View File

@@ -871,9 +871,9 @@ function EVENT:onEvent( Event )
-- Okay, we got the event from DCS. Now loop the SORTED self.EventSorted[] table for the received Event.id, and for each EventData registered, check if a function needs to be called.
for EventClass, EventData in pairs( self.Events[Event.id][EventPriority] ) do
if Event.IniObjectCategory ~= Object.Category.STATIC then
self:E( { "Evaluating: ", EventClass:GetClassNameAndID() } )
end
--if Event.IniObjectCategory ~= Object.Category.STATIC then
-- self:E( { "Evaluating: ", EventClass:GetClassNameAndID() } )
--end
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName )

View File

@@ -838,8 +838,12 @@ do -- COORDINATE
if ModeA2A then
if Settings:IsA2A_BRAA() then
local Coordinate = Controllable:GetCoordinate()
return self:ToStringBRA( Coordinate, Settings )
if Controllable then
local Coordinate = Controllable:GetCoordinate()
return self:ToStringBRA( Coordinate, Settings )
else
return self:ToStringMGRS( Settings )
end
end
if Settings:IsA2A_BULLS() then
local Coalition = Controllable:GetCoalition()
@@ -856,8 +860,13 @@ do -- COORDINATE
end
else
if Settings:IsA2G_BR() then
local Coordinate = Controllable:GetCoordinate()
return Controllable and self:ToStringBR( Coordinate, Settings ) or self:ToStringMGRS( Settings )
-- If no Controllable is given to calculate the BR from, then MGRS will be used!!!
if Controllable then
local Coordinate = Controllable:GetCoordinate()
return Controllable and self:ToStringBR( Coordinate, Settings ) or self:ToStringMGRS( Settings )
else
return self:ToStringMGRS( Settings )
end
end
if Settings:IsA2G_LL_DMS() then
return self:ToStringLLDMS( Settings )

View File

@@ -1784,6 +1784,7 @@ end
--- Calculate the maxium A2G threat level of the SET_UNIT.
-- @param #SET_UNIT self
-- @return #number The maximum threatlevel
function SET_UNIT:CalculateThreatLevelA2G()
local MaxThreatLevelA2G = 0

View File

@@ -834,6 +834,20 @@ function ZONE_GROUP:GetRandomVec2()
return Point
end
--- Returns a @{Point#POINT_VEC2} object reflecting a random 2D location within the zone.
-- @param #ZONE_GROUP self
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
-- @return Core.Point#POINT_VEC2 The @{Point#POINT_VEC2} object reflecting the random 3D location within the zone.
function ZONE_GROUP:GetRandomPointVec2( inner, outer )
self:F( self.ZoneName, inner, outer )
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2() )
self:T3( { PointVec2 } )
return PointVec2
end
--- @type ZONE_POLYGON_BASE

View File

@@ -133,7 +133,7 @@ do -- DESIGNATE
--
-- ## 4. Laser codes
--
-- ### 4.1 Set possible laser codes
-- ### 4.1. Set possible laser codes
--
-- An array of laser codes can be provided, that will be used by the DESIGNATE when lasing.
-- The laser code is communicated by the Recce when it is lasing a larget.
@@ -151,10 +151,19 @@ do -- DESIGNATE
--
-- The above sets a collection of possible laser codes that can be assigned. **Note the { } notation!**
--
-- ### 4.2 Auto generate laser codes
-- ### 4.2. Auto generate laser codes
--
-- Use the method @{#DESIGNATE.GenerateLaserCodes}() to generate all possible laser codes. Logic implemented and advised by Ciribob!
--
-- ### 4.3. Add specific lase codes to the lase menu
--
-- Certain plane types can only drop laser guided ordonnance when targets are lased with specific laser codes.
-- The SU-25T needs targets to be lased using laser code 1113.
-- The A-10A needs targets to be lased using laser code 1680.
--
-- The method @{#DESIGNATE.AddMenuLaserCode}() to allow a player to lase a target using a specific laser code.
-- Remove such a lase menu option using @{#DESIGNATE.RemoveMenuLaserCode}().
--
-- ## 5. Autolase to automatically lase detected targets.
--
-- DetectionItems can be auto lased once detected by Recces. As such, there is almost no action required from the Players using the Designate Menu.
@@ -396,6 +405,8 @@ do -- DESIGNATE
self.LaserCodesUsed = {}
self.MenuLaserCodes = {} -- This map contains the laser codes that will be shown in the designate menu to lase with specific laser codes.
self.Detection:__Start( 2 )
self:__Detect( -15 )
@@ -491,6 +502,43 @@ do -- DESIGNATE
end
--- Add a specific lase code to the designate lase menu to lase targets with a specific laser code.
-- The MenuText will appear in the lase menu.
-- @param #DESIGNATE self
-- @param #number LaserCode The specific laser code to be added to the lase menu.
-- @param #string MenuText The text to be shown to the player. If you specify a %d in the MenuText, the %d will be replaced with the LaserCode specified.
-- @return #DESIGNATE
-- @usage
-- RecceDesignation:AddMenuLaserCode( 1113, "Lase with %d for Su-25T" )
-- RecceDesignation:AddMenuLaserCode( 1680, "Lase with %d for A-10A" )
--
function DESIGNATE:AddMenuLaserCode( LaserCode, MenuText )
self.MenuLaserCodes[LaserCode] = MenuText
self:SetDesignateMenu()
return self
end
--- Removes a specific lase code from the designate lase menu.
-- @param #DESIGNATE self
-- @param #number LaserCode The specific laser code that was set to be added to the lase menu.
-- @return #DESIGNATE
-- @usage
-- RecceDesignation:RemoveMenuLaserCode( 1113 )
--
function DESIGNATE:RemoveMenuLaserCode( LaserCode )
self.MenuLaserCodes[LaserCode] = nil
self:SetDesignateMenu()
return self
end
--- Set the name of the designation. The name will appear in the menu.
-- This method can be used to control different designations for different plane types.
-- @param #DESIGNATE self
@@ -797,11 +845,9 @@ do -- DESIGNATE
MENU_GROUP_COMMAND:New( AttackGroup, "Flash Status Report On", StatusMenu, self.MenuFlashStatus, self, AttackGroup, true ):SetTime( MenuTime ):SetTag( self.DesignateName )
end
local DetectedItems = self.Detection:GetDetectedItems()
for DesignateIndex, Designating in pairs( self.Designating ) do
local DetectedItem = DetectedItems[DesignateIndex]
local DetectedItem = self.Detection:GetDetectedItem( DesignateIndex )
if DetectedItem then
@@ -813,8 +859,10 @@ do -- DESIGNATE
MenuText = "(-) " .. MenuText
local DetectedMenu = MENU_GROUP:New( AttackGroup, MenuText, MenuDesignate ):SetTime( MenuTime ):SetTag( self.DesignateName )
MENU_GROUP_COMMAND:New( AttackGroup, "Search other target", DetectedMenu, self.MenuForget, self, DesignateIndex ):SetTime( MenuTime ):SetTag( self.DesignateName )
MENU_GROUP_COMMAND:New( AttackGroup, "Lase target 60 secs", DetectedMenu, self.MenuLaseOn, self, DesignateIndex, 60 ):SetTime( MenuTime ):SetTag( self.DesignateName )
MENU_GROUP_COMMAND:New( AttackGroup, "Lase target 120 secs", DetectedMenu, self.MenuLaseOn, self, DesignateIndex, 120 ):SetTime( MenuTime ):SetTag( self.DesignateName )
for LaserCode, MenuText in pairs( self.MenuLaserCodes ) do
MENU_GROUP_COMMAND:New( AttackGroup, string.format( MenuText, LaserCode ), DetectedMenu, self.MenuLaseCode, self, DesignateIndex, 60, LaserCode ):SetTime( MenuTime ):SetTag( self.DesignateName )
end
MENU_GROUP_COMMAND:New( AttackGroup, "Lase targets", DetectedMenu, self.MenuLaseOn, self, DesignateIndex, 60 ):SetTime( MenuTime ):SetTag( self.DesignateName )
MENU_GROUP_COMMAND:New( AttackGroup, "Smoke red", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.Red ):SetTime( MenuTime ):SetTag( self.DesignateName )
MENU_GROUP_COMMAND:New( AttackGroup, "Smoke blue", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.Blue ):SetTime( MenuTime ):SetTag( self.DesignateName )
MENU_GROUP_COMMAND:New( AttackGroup, "Smoke green", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.Green ):SetTime( MenuTime ):SetTag( self.DesignateName )
@@ -914,6 +962,18 @@ do -- DESIGNATE
self:SetDesignateMenu()
end
---
-- @param #DESIGNATE self
function DESIGNATE:MenuLaseCode( Index, Duration, LaserCode )
self:E( "Designate through Lase using " .. LaserCode )
self:__LaseOn( 1, Index, Duration, LaserCode )
self:SetDesignateMenu()
end
---
-- @param #DESIGNATE self
function DESIGNATE:MenuLaseOff( Index, Duration )
@@ -927,21 +987,22 @@ do -- DESIGNATE
---
-- @param #DESIGNATE self
function DESIGNATE:onafterLaseOn( From, Event, To, Index, Duration )
function DESIGNATE:onafterLaseOn( From, Event, To, Index, Duration, LaserCode )
self.Designating[Index] = "Laser"
self:__Lasing( -1, Index, Duration )
self:__Lasing( -1, Index, Duration, LaserCode )
end
---
-- @param #DESIGNATE self
-- @return #DESIGNATE
function DESIGNATE:onafterLasing( From, Event, To, Index, Duration )
function DESIGNATE:onafterLasing( From, Event, To, Index, Duration, LaserCodeRequested )
local TargetSetUnit = self.Detection:GetDetectedSet( Index )
local MarkedCount = 0
local MarkingCount = 0
local MarkedTypes = {}
local ReportTypes = REPORT:New()
local ReportLaserCodes = REPORT:New()
@@ -953,12 +1014,30 @@ do -- DESIGNATE
local Recce = RecceData -- Wrapper.Unit#UNIT
self:F( { TargetUnit = TargetUnit, Recce = Recce:GetName() } )
if not Recce:IsLasing() then
local LaserCode = Recce:GetLaserCode() --(Not deleted when stopping with lasing).
local LaserCode = Recce:GetLaserCode() -- (Not deleted when stopping with lasing).
self:F( { ClearingLaserCode = LaserCode } )
self.LaserCodesUsed[LaserCode] = nil
self.Recces[TargetUnit] = nil
end
end
-- If a specific lasercode is requested, we disable one active lase!
if LaserCodeRequested then
for TargetUnit, RecceData in pairs( self.Recces ) do -- We break after the first has been processed.
local Recce = RecceData -- Wrapper.Unit#UNIT
self:F( { TargetUnit = TargetUnit, Recce = Recce:GetName() } )
if Recce:IsLasing() then
-- When a Recce is lasing, we switch the lasing off, and clear the references to the lasing in the DESIGNATE class.
Recce:LaseOff() -- Switch off the lasing.
local LaserCode = Recce:GetLaserCode() -- (Not deleted when stopping with lasing).
self:F( { ClearingLaserCode = LaserCode } )
self.LaserCodesUsed[LaserCode] = nil
self.Recces[TargetUnit] = nil
break
end
end
end
TargetSetUnit:ForEachUnitPerThreatLevel( 10, 0,
--- @param Wrapper.Unit#UNIT SmokeUnit
@@ -966,7 +1045,7 @@ do -- DESIGNATE
self:F( { TargetUnit = TargetUnit:GetName() } )
if MarkedCount < self.MaximumMarkings then
if MarkingCount < self.MaximumMarkings then
if TargetUnit:IsAlive() then
@@ -993,6 +1072,11 @@ do -- DESIGNATE
local LaserCode = self.LaserCodes[LaserCodeIndex]
--self:F( { LaserCode = LaserCode, LaserCodeUsed = self.LaserCodesUsed[LaserCode] } )
if LaserCodeRequested and LaserCodeRequested ~= LaserCode then
LaserCode = LaserCodeRequested
LaserCodeRequested = nil
end
if not self.LaserCodesUsed[LaserCode] then
self.LaserCodesUsed[LaserCode] = LaserCodeIndex
@@ -1007,7 +1091,7 @@ do -- DESIGNATE
self.Recces[TargetUnit] = RecceUnit
RecceUnit:MessageToSetGroup( "Marking " .. TargetUnit:GetTypeName() .. " with laser " .. RecceUnit:GetSpot().LaserCode .. " for " .. Duration .. "s.", 5, self.AttackSet, self.DesignateName )
-- OK. We have assigned for the Recce a TargetUnit. We can exit the function.
MarkedCount = MarkedCount + 1
MarkingCount = MarkingCount + 1
local TargetUnitType = TargetUnit:GetTypeName()
if not MarkedTypes[TargetUnitType] then
MarkedTypes[TargetUnitType] = true
@@ -1031,7 +1115,7 @@ do -- DESIGNATE
Recce:MessageToSetGroup( "Target " .. TargetUnit:GetTypeName() "out of LOS. Cancelling lase!", 5, self.AttackSet, self.DesignateName )
end
else
MarkedCount = MarkedCount + 1
MarkingCount = MarkingCount + 1
local TargetUnitType = TargetUnit:GetTypeName()
if not MarkedTypes[TargetUnitType] then
MarkedTypes[TargetUnitType] = true
@@ -1043,7 +1127,7 @@ do -- DESIGNATE
end
end
else
MarkedCount = MarkedCount + 1
MarkingCount = MarkingCount + 1
local TargetUnitType = TargetUnit:GetTypeName()
if not MarkedTypes[TargetUnitType] then
MarkedTypes[TargetUnitType] = true
@@ -1060,7 +1144,7 @@ do -- DESIGNATE
local MarkedTypesText = ReportTypes:Text(', ')
local MarkedLaserCodesText = ReportLaserCodes:Text(', ')
for MarkedType, MarketCount in pairs( MarkedTypes ) do
self.CC:GetPositionable():MessageToSetGroup( "Marking " .. MarkedCount .. " x " .. MarkedTypesText .. " with lasers " .. MarkedLaserCodesText .. ".", 5, self.AttackSet, self.DesignateName )
self.CC:GetPositionable():MessageToSetGroup( "Marking " .. MarkingCount .. " x " .. MarkedTypesText .. " with lasers " .. MarkedLaserCodesText .. ".", 5, self.AttackSet, self.DesignateName )
end
self:__Lasing( -30, Index, Duration )

View File

@@ -305,7 +305,7 @@ do -- DETECTION_BASE
-- @field #number ID -- The identifier of the detected area.
-- @field #boolean FriendliesNearBy Indicates if there are friendlies within the detected area.
-- @field Wrapper.Unit#UNIT NearestFAC The nearest FAC near the Area.
-- @field Core.Point#COORDINATE Coordinate The last known coordinate of the DetectedItem.
--- DETECTION constructor.
-- @param #DETECTION_BASE self
@@ -604,6 +604,14 @@ do -- DETECTION_BASE
DetectionAccepted = self._.FilterCategories[DetectedUnitCategory] ~= nil and DetectionAccepted or false
-- if Distance > 15000 then
-- if DetectedUnitCategory == Unit.Category.GROUND_UNIT or DetectedUnitCategory == Unit.Category.SHIP then
-- if DetectedObject:hasSensors( Unit.SensorType.RADAR, Unit.RadarType.AS ) == false then
-- DetectionAccepted = false
-- end
-- end
-- end
if self.AcceptRange and Distance > self.AcceptRange then
DetectionAccepted = false
end
@@ -1101,8 +1109,8 @@ do -- DETECTION_BASE
DetectedItem.Changes[ChangeCode].ID = ID
DetectedItem.Changes[ChangeCode].ItemUnitType = ItemUnitType
self:T( { "Change on Detection Item:", DetectedItem.ID, ChangeCode, ItemUnitType } )
self:E( { "Change on Detection Item:", DetectedItem.ID, ChangeCode, ItemUnitType } )
return self
end
@@ -1124,7 +1132,7 @@ do -- DETECTION_BASE
DetectedItem.Changes[ChangeCode][ChangeUnitType] = DetectedItem.Changes[ChangeCode][ChangeUnitType] + 1
DetectedItem.Changes[ChangeCode].ID = ID
self:T( { "Change on Detection Item:", DetectedItem.ID, ChangeCode, ChangeUnitType } )
self:E( { "Change on Detection Item:", DetectedItem.ID, ChangeCode, ChangeUnitType } )
return self
end
@@ -1353,6 +1361,32 @@ do -- DETECTION_BASE
return nil
end
--- Gets a detected unit type name, taking into account the detection results.
-- @param #DETECTION_BASE self
-- @param Wrapper.Unit#UNIT DetectedUnit
-- @return #string The type name
function DETECTION_BASE:GetDetectedUnitTypeName( DetectedUnit )
--self:F2( ObjectName )
if DetectedUnit and DetectedUnit:IsAlive() then
local DetectedUnitName = DetectedUnit:GetName()
local DetectedObject = self.DetectedObjects[DetectedUnitName]
if DetectedObject then
if DetectedObject.KnowType then
return DetectedUnit:GetTypeName()
else
return "Unknown"
end
end
else
return "Dead:" .. DetectedUnit:GetName()
end
return "Undetected:" .. DetectedUnit:GetName()
end
--- Adds a new DetectedItem to the DetectedItems list.
-- The DetectedItem is a table and contains a SET_UNIT in the field Set.
@@ -1538,15 +1572,78 @@ do -- DETECTION_BASE
end
--- Set the detected item coordinate.
-- @param #DETECTION_BASE self
-- @param #DETECTION_BASE.DetectedItem The DetectedItem to set the coordinate at.
-- @param Core.Point#COORDINATE Coordinate The coordinate to set the last know detected position at.
-- @param Wrapper.Unit#UNIT DetectedItemUnit The unit to set the heading and altitude from.
-- @return #DETECTION_BASE
function DETECTION_BASE:SetDetectedItemCoordinate( DetectedItem, Coordinate, DetectedItemUnit )
self:F( { Coordinate = Coordinate } )
if DetectedItem then
if DetectedItemUnit then
DetectedItem.Coordinate = Coordinate
DetectedItem.Coordinate:SetHeading( DetectedItemUnit:GetHeading() )
DetectedItem.Coordinate.y = DetectedItemUnit:GetAltitude()
DetectedItem.Coordinate.Speed = DetectedItemUnit:GetVelocityMPS()
end
end
end
--- Get the detected item coordinate.
-- @param #DETECTION_BASE self
-- @param Index
-- @param #number Index
-- @return Core.Point#COORDINATE
function DETECTION_BASE:GetDetectedItemCoordinate( Index )
self:F( { Index = Index } )
local DetectedItem = self:GetDetectedItem( Index )
if DetectedItem then
return DetectedItem.Coordinate
end
return nil
end
--- Set the detected item threatlevel.
-- @param #DETECTION_BASE self
-- @param #DETECTION_BASE.DetectedItem The DetectedItem to calculate the threatlevel for.
-- @return #DETECTION_BASE
function DETECTION_BASE:SetDetectedItemThreatLevel( DetectedItem )
local DetectedSet = DetectedItem.Set
if DetectedItem then
DetectedItem.ThreatLevel = DetectedSet:CalculateThreatLevelA2G()
end
end
--- Get the detected item coordinate.
-- @param #DETECTION_BASE self
-- @param #number Index
-- @return #number ThreatLevel
function DETECTION_BASE:GetDetectedItemThreatLevel( Index )
self:F( { Index = Index } )
local DetectedItem = self:GetDetectedItem( Index )
if DetectedItem then
return DetectedItem.ThreatLevel or 0
end
return nil
end
--- Menu of a detected item using a given numeric index.
-- @param #DETECTION_BASE self
@@ -1639,27 +1736,6 @@ do -- DETECTION_UNITS
return self
end
--- Get the detected item coordinate.
-- @param #DETECTION_UNITS self
-- @param Index
-- @return Core.Point#COORDINATE
function DETECTION_UNITS:GetDetectedItemCoordinate( Index )
self:F( { Index = Index } )
local DetectedItem = self:GetDetectedItem( Index )
local DetectedSet = self:GetDetectedSet( Index )
if DetectedSet then
local DetectedItemUnit = DetectedSet:GetFirst() -- Wrapper.Unit#UNIT
if DetectedItemUnit and DetectedItemUnit:IsAlive() then
local DetectedItemCoordinate = DetectedItemUnit:GetCoordinate()
DetectedItemCoordinate:SetHeading( DetectedItemUnit:GetHeading() )
return DetectedItemCoordinate
end
end
end
--- Make text documenting the changes of the detected zone.
-- @param #DETECTION_UNITS self
-- @param #DETECTION_UNITS.DetectedItem DetectedItem
@@ -1727,6 +1803,7 @@ do -- DETECTION_UNITS
-- Update the detection with the new data provided.
DetectedItem.TypeName = DetectedUnit:GetTypeName()
DetectedItem.CategoryName = DetectedUnit:GetCategoryName()
DetectedItem.Name = DetectedObject.Name
DetectedItem.IsVisible = DetectedObject.IsVisible
DetectedItem.LastTime = DetectedObject.LastTime
@@ -1781,8 +1858,14 @@ do -- DETECTION_UNITS
local DetectedItem = DetectedItemData -- #DETECTION_BASE.DetectedItem
local DetectedSet = DetectedItem.Set
-- Set the last known coordinate.
local DetectedFirstUnit = DetectedSet:GetFirst()
local DetectedFirstUnitCoord = DetectedFirstUnit:GetCoordinate()
self:SetDetectedItemCoordinate( DetectedItem, DetectedFirstUnitCoord, DetectedFirstUnit )
self:ReportFriendliesNearBy( { DetectedItem = DetectedItem, ReportSetGroup = self.DetectionSetGroup } ) -- Fill the Friendlies table
--self:NearestFAC( DetectedItem )
end
end
@@ -1804,21 +1887,14 @@ do -- DETECTION_UNITS
local UnitDistanceText = ""
local UnitCategoryText = ""
local DetectedItemUnit = DetectedSet:GetFirst() -- Wrapper.Unit#UNIT
if DetectedItemUnit and DetectedItemUnit:IsAlive() then
self:T(DetectedItemUnit)
local DetectedItemCoordinate = DetectedItemUnit:GetCoordinate()
local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup )
ReportSummary = string.format(
"%s - %s",
DetectedItemID,
DetectedItemCoordText
)
end
local DetectedItemCoordinate = self:GetDetectedItemCoordinate( Index )
local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup )
ReportSummary = string.format(
"%s - %s",
DetectedItemID,
DetectedItemCoordText
)
self:T( ReportSummary )
return ReportSummary
@@ -1835,54 +1911,46 @@ do -- DETECTION_UNITS
self:F( { Index, self.DetectedItems } )
local DetectedItem = self:GetDetectedItem( Index )
local DetectedSet = self:GetDetectedSet( Index )
local DetectedItemID = self:GetDetectedItemID( Index )
self:T( DetectedSet )
if DetectedSet then
if DetectedItem then
local ReportSummary = ""
local UnitDistanceText = ""
local UnitCategoryText = ""
local DetectedItemUnit = DetectedSet:GetFirst() -- Wrapper.Unit#UNIT
if DetectedItemUnit and DetectedItemUnit:IsAlive() then
self:T(DetectedItemUnit)
if DetectedItem.KnowType then
local UnitCategoryName = DetectedItemUnit:GetCategoryName()
if UnitCategoryName then
UnitCategoryText = UnitCategoryName
end
if DetectedItem.TypeName then
UnitCategoryText = UnitCategoryText .. " (" .. DetectedItem.TypeName .. ")"
end
else
UnitCategoryText = "Unknown"
if DetectedItem.KnowType then
local UnitCategoryName = DetectedItem.CategoryName
if UnitCategoryName then
UnitCategoryText = UnitCategoryName
end
if DetectedItem.KnowDistance then
if DetectedItem.IsVisible then
UnitDistanceText = " at " .. string.format( "%.2f", DetectedItem.Distance ) .. " km"
end
else
if DetectedItem.IsVisible then
UnitDistanceText = " at +/- " .. string.format( "%.0f", DetectedItem.Distance ) .. " km"
end
if DetectedItem.TypeName then
UnitCategoryText = UnitCategoryText .. " (" .. DetectedItem.TypeName .. ")"
end
local DetectedItemCoordinate = DetectedItemUnit:GetCoordinate()
local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup, Settings )
local ThreatLevelA2G = DetectedItemUnit:GetThreatLevel( DetectedItem )
local Report = REPORT:New()
Report:Add(DetectedItemID .. ", " .. DetectedItemCoordText)
Report:Add( string.format( "Threat: [%s]", string.rep( "", ThreatLevelA2G ) ) )
Report:Add( string.format("Type: %s%s", UnitCategoryText, UnitDistanceText ) )
return Report
else
UnitCategoryText = "Unknown"
end
if DetectedItem.KnowDistance then
if DetectedItem.IsVisible then
UnitDistanceText = " at " .. string.format( "%.2f", DetectedItem.Distance ) .. " km"
end
else
if DetectedItem.IsVisible then
UnitDistanceText = " at +/- " .. string.format( "%.0f", DetectedItem.Distance ) .. " km"
end
end
--TODO: solve Index reference
local DetectedItemCoordinate = self:GetDetectedItemCoordinate( Index )
local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup, Settings )
local ThreatLevelA2G = self:GetDetectedItemThreatLevel( Index )
local Report = REPORT:New()
Report:Add(DetectedItemID .. ", " .. DetectedItemCoordText)
Report:Add( string.format( "Threat: [%s]", string.rep( "", ThreatLevelA2G ) ) )
Report:Add( string.format("Type: %s%s", UnitCategoryText, UnitDistanceText ) )
return Report
end
return nil
end
@@ -1900,7 +1968,7 @@ do -- DETECTION_UNITS
local DetectedItem = DetectedItem -- #DETECTION_BASE.DetectedItem
local ReportSummary = self:DetectedItemReportSummary( DetectedItemID, AttackGroup )
Report:SetTitle( "Detected units:" )
Report:Add( ReportSummary )
Report:Add( ReportSummary:Text() )
end
local ReportText = Report:Text()
@@ -1944,25 +2012,6 @@ do -- DETECTION_TYPES
return self
end
--- Get the detected item coordinate.
-- @param #DETECTION_TYPES self
-- @param DetectedTypeName
-- @return #Core.Point#COORDINATE
function DETECTION_TYPES:GetDetectedItemCoordinate( DetectedTypeName )
self:F( { DetectedTypeName = DetectedTypeName } )
local DetectedItem = self:GetDetectedItem( DetectedTypeName )
local DetectedSet = self:GetDetectedSet( DetectedTypeName )
if DetectedItem then
local DetectedItemUnit = DetectedSet:GetFirst()
local DetectedItemCoordinate = DetectedItemUnit:GetCoordinate()
DetectedItemCoordinate:SetHeading( DetectedItemUnit:GetHeading() )
return DetectedItemCoordinate
end
end
--- Make text documenting the changes of the detected zone.
-- @param #DETECTION_TYPES self
-- @param #DETECTION_TYPES.DetectedItem DetectedItem
@@ -2067,10 +2116,16 @@ do -- DETECTION_TYPES
local DetectedItem = DetectedItemData -- #DETECTION_BASE.DetectedItem
local DetectedSet = DetectedItem.Set
-- Set the last known coordinate.
local DetectedFirstUnit = DetectedSet:GetFirst()
local DetectedUnitCoord = DetectedFirstUnit:GetCoordinate()
self:SetDetectedItemCoordinate( DetectedItem, DetectedUnitCoord, DetectedFirstUnit )
self:ReportFriendliesNearBy( { DetectedItem = DetectedItem, ReportSetGroup = self.DetectionSetGroup } ) -- Fill the Friendlies table
--self:NearestFAC( DetectedItem )
end
end
@@ -2082,20 +2137,13 @@ do -- DETECTION_TYPES
self:F( DetectedTypeName )
local DetectedItem = self:GetDetectedItem( DetectedTypeName )
local DetectedSet = self:GetDetectedSet( DetectedTypeName )
local DetectedItemID = self:GetDetectedItemID( DetectedTypeName )
self:T( DetectedItem )
if DetectedItem then
local DetectedItemUnit = DetectedSet:GetFirst()
local DetectedItemCoordinate = DetectedItemUnit:GetCoordinate()
local DetectedItemCoordinate = self:GetDetectedItemCoordinate( DetectedTypeName )
local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup )
--self:E( { DetectedItemID,
-- DetectedItemCoordText } )
local ReportSummary = string.format(
"%s - %s",
DetectedItemID,
@@ -2123,13 +2171,11 @@ do -- DETECTION_TYPES
self:T( DetectedItem )
if DetectedItem then
local ThreatLevelA2G = DetectedSet:CalculateThreatLevelA2G()
local ThreatLevelA2G = self:GetDetectedItemThreatLevel( DetectedTypeName )
local DetectedItemsCount = DetectedSet:Count()
local DetectedItemType = DetectedItem.TypeName
local DetectedItemUnit = DetectedSet:GetFirst()
local DetectedItemCoordinate = DetectedItemUnit:GetCoordinate()
local DetectedItemCoordinate = self:GetDetectedItemCoordinate( DetectedTypeName )
local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup, Settings )
local Report = REPORT:New()
@@ -2152,7 +2198,7 @@ do -- DETECTION_TYPES
local DetectedItem = DetectedItem -- #DETECTION_BASE.DetectedItem
local ReportSummary = self:DetectedItemReportSummary( DetectedItemTypeName, AttackGroup )
Report:SetTitle( "Detected types:" )
Report:Add( ReportSummary )
Report:Add( ReportSummary:Text() )
end
local ReportText = Report:Text()
@@ -2228,32 +2274,6 @@ do -- DETECTION_AREAS
return self
end
--- Get the detected item coordinate.
-- In this case, the coordinate is the center of the zone of the area, not the center unit!
-- So if units move, the retrieved coordinate can be different from the units positions.
-- @param #DETECTION_AREAS self
-- @param Index
-- @return Core.Point#COORDINATE The coordinate.
function DETECTION_AREAS:GetDetectedItemCoordinate( Index )
self:F( { Index = Index } )
local DetectedItem = self:GetDetectedItem( Index )
local DetectedItemSet = self:GetDetectedSet( Index )
local FirstUnit = DetectedItemSet:GetFirst()
if DetectedItem then
local DetectedZone = self:GetDetectedItemZone( Index )
-- TODO: Rework to COORDINATE. Problem with SetAlt.
local DetectedItemCoordinate = DetectedZone:GetPointVec2()
-- These need to be done to understand the heading and altitude of the first unit in the zone.
DetectedItemCoordinate:SetHeading( FirstUnit:GetHeading() )
DetectedItemCoordinate:SetAlt( FirstUnit:GetAltitude() )
return DetectedItemCoordinate
end
return nil
end
--- Menu of a detected item using a given numeric index.
-- @param #DETECTION_AREAS self
@@ -2305,7 +2325,7 @@ do -- DETECTION_AREAS
local DetectedItemCoordinate = DetectedZone:GetCoordinate()
local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup, Settings )
local ThreatLevelA2G = self:GetTreatLevelA2G( DetectedItem )
local ThreatLevelA2G = self:GetDetectedItemThreatLevel( Index )
local DetectedItemsCount = DetectedSet:Count()
local DetectedItemsTypes = DetectedSet:GetTypeNames()
@@ -2332,7 +2352,7 @@ do -- DETECTION_AREAS
local DetectedItem = DetectedItem -- #DETECTION_BASE.DetectedItem
local ReportSummary = self:DetectedItemReportSummary( DetectedItemIndex, AttackGroup )
Report:SetTitle( "Detected areas:" )
Report:Add( ReportSummary )
Report:Add( ReportSummary:Text() )
end
local ReportText = Report:Text()
@@ -2341,48 +2361,26 @@ do -- DETECTION_AREAS
end
--- Calculate the maxium A2G threat level of the DetectedItem.
-- @param #DETECTION_AREAS self
-- @param #DETECTION_BASE.DetectedItem DetectedItem
function DETECTION_AREAS:CalculateThreatLevelA2G( DetectedItem )
local MaxThreatLevelA2G = 0
for UnitName, UnitData in pairs( DetectedItem.Set:GetSet() ) do
local ThreatUnit = UnitData -- Wrapper.Unit#UNIT
local ThreatLevelA2G = ThreatUnit:GetThreatLevel()
if ThreatLevelA2G > MaxThreatLevelA2G then
MaxThreatLevelA2G = ThreatLevelA2G
end
end
self:T3( MaxThreatLevelA2G )
DetectedItem.MaxThreatLevelA2G = MaxThreatLevelA2G
end
--- Calculate the optimal intercept point of the DetectedItem.
-- @param #DETECTION_AREAS self
-- @param #DETECTION_BASE.DetectedItem DetectedItem
function DETECTION_AREAS:CalculateIntercept( DetectedItem )
local DetectedSpeed = DetectedItem.Coordinate.Speed
local DetectedHeading = DetectedItem.Coordinate.Heading
local DetectedCoord = DetectedItem.Coordinate
if self.Intercept then
local DetectedSet = DetectedItem.Set
local DetectedUnit = DetectedSet:GetFirst() -- Wrapper.Unit#UNIT
if DetectedUnit then
local UnitSpeed = DetectedUnit:GetVelocityMPS()
local UnitHeading = DetectedUnit:GetHeading()
local UnitCoord = DetectedUnit:GetCoordinate()
local TranslateDistance = UnitSpeed * self.InterceptDelay
local InterceptCoord = UnitCoord:Translate( TranslateDistance, UnitHeading )
DetectedItem.InterceptCoord = InterceptCoord
else
DetectedItem.InterceptCoord = nil
end
-- todo: speed
local TranslateDistance = DetectedSpeed * self.InterceptDelay
local InterceptCoord = DetectedCoord:Translate( TranslateDistance, DetectedHeading )
DetectedItem.InterceptCoord = InterceptCoord
else
DetectedItem.InterceptCoord = nil
DetectedItem.InterceptCoord = DetectedCoord
end
end
@@ -2415,18 +2413,6 @@ do -- DETECTION_AREAS
end
--- Returns the A2G threat level of the units in the DetectedItem
-- @param #DETECTION_AREAS self
-- @param #DETECTION_BASE.DetectedItem DetectedItem
-- @return #number a scale from 0 to 10.
function DETECTION_AREAS:GetTreatLevelA2G( DetectedItem )
self:T3( DetectedItem.MaxThreatLevelA2G )
return DetectedItem.MaxThreatLevelA2G
end
--- Smoke the detected units
-- @param #DETECTION_AREAS self
-- @return #DETECTION_AREAS self
@@ -2571,13 +2557,14 @@ do -- DETECTION_AREAS
-- First remove the center unit from the set.
DetectedSet:RemoveUnitsByName( DetectedItem.Zone.ZoneUNIT.UnitName )
self:AddChangeItem( DetectedItem, 'RAU', "Dummy" )
self:AddChangeItem( DetectedItem, 'RAU', self:GetDetectedUnitTypeName( DetectedItem.Zone.ZoneUNIT ) )
-- Then search for a new center area unit within the set. Note that the new area unit candidate must be within the area range.
for DetectedUnitName, DetectedUnitData in pairs( DetectedSet:GetSet() ) do
local DetectedUnit = DetectedUnitData -- Wrapper.Unit#UNIT
local DetectedObject = self:GetDetectedObject( DetectedUnit.UnitName )
local DetectedUnitTypeName = self:GetDetectedUnitTypeName( DetectedUnit )
-- The DetectedObject can be nil when the DetectedUnit is not alive anymore or it is not in the DetectedObjects map.
-- If the DetectedUnit was already identified, DetectedObject will be nil.
@@ -2590,13 +2577,13 @@ do -- DETECTION_AREAS
-- Assign the Unit as the new center unit of the detected area.
DetectedItem.Zone = ZONE_UNIT:New( DetectedUnit:GetName(), DetectedUnit, self.DetectionZoneRange )
self:AddChangeItem( DetectedItem, "AAU", DetectedItem.Zone.ZoneUNIT:GetTypeName() )
self:AddChangeItem( DetectedItem, "AAU", DetectedUnitTypeName )
-- We don't need to add the DetectedObject to the area set, because it is already there ...
break
else
DetectedSet:Remove( DetectedUnitName )
self:AddChangeUnit( DetectedItem, "RU", DetectedUnit:GetTypeName() )
self:AddChangeUnit( DetectedItem, "RU", DetectedUnitTypeName )
end
end
end
@@ -2612,13 +2599,15 @@ do -- DETECTION_AREAS
for DetectedUnitName, DetectedUnitData in pairs( DetectedSet:GetSet() ) do
local DetectedUnit = DetectedUnitData -- Wrapper.Unit#UNIT
local DetectedUnitTypeName = self:GetDetectedUnitTypeName( DetectedUnit )
local DetectedObject = nil
if DetectedUnit:IsAlive() then
--self:E(DetectedUnit:GetName())
DetectedObject = self:GetDetectedObject( DetectedUnit:GetName() )
end
if DetectedObject then
-- Check if the DetectedUnit is within the DetectedItem.Zone
if DetectedUnit:IsInZone( DetectedItem.Zone ) then
@@ -2628,7 +2617,7 @@ do -- DETECTION_AREAS
else
-- No, the DetectedUnit is not within the DetectedItem.Zone, remove DetectedUnit from the Set.
DetectedSet:Remove( DetectedUnitName )
self:AddChangeUnit( DetectedItem, "RU", DetectedUnit:GetTypeName() )
self:AddChangeUnit( DetectedItem, "RU", DetectedUnitTypeName )
end
else
@@ -2665,6 +2654,7 @@ do -- DETECTION_AREAS
-- We found an unidentified unit outside of any existing detection area.
local DetectedUnit = UNIT:FindByName( DetectedUnitName ) -- Wrapper.Unit#UNIT
local DetectedUnitTypeName = self:GetDetectedUnitTypeName( DetectedUnit )
local AddedToDetectionArea = false
@@ -2678,7 +2668,7 @@ do -- DETECTION_AREAS
self:IdentifyDetectedObject( DetectedObject )
DetectedSet:AddUnit( DetectedUnit )
AddedToDetectionArea = true
self:AddChangeUnit( DetectedItem, "AU", DetectedUnit:GetTypeName() )
self:AddChangeUnit( DetectedItem, "AU", DetectedUnitTypeName )
end
end
end
@@ -2692,7 +2682,7 @@ do -- DETECTION_AREAS
)
--self:E( DetectedItem.Zone.ZoneUNIT.UnitName )
DetectedItem.Set:AddUnit( DetectedUnit )
self:AddChangeItem( DetectedItem, "AA", DetectedUnit:GetTypeName() )
self:AddChangeItem( DetectedItem, "AA", DetectedUnitTypeName )
end
end
end
@@ -2704,13 +2694,19 @@ do -- DETECTION_AREAS
local DetectedItem = DetectedItemData -- #DETECTION_BASE.DetectedItem
local DetectedSet = DetectedItem.Set
local DetectedFirstUnit = DetectedSet:GetFirst()
local DetectedZone = DetectedItem.Zone
-- Set the last known coordinate to the detection item.
local DetectedZoneCoord = DetectedZone:GetCoordinate()
self:SetDetectedItemCoordinate( DetectedItem, DetectedZoneCoord, DetectedFirstUnit )
self:CalculateIntercept( DetectedItem )
self:ReportFriendliesNearBy( { DetectedItem = DetectedItem, ReportSetGroup = self.DetectionSetGroup } ) -- Fill the Friendlies table
self:CalculateThreatLevelA2G( DetectedItem ) -- Calculate A2G threat level
self:SetDetectedItemThreatLevel( DetectedItem ) -- Calculate A2G threat level
self:NearestFAC( DetectedItem )
if DETECTION_AREAS._SmokeDetectedUnits or self._SmokeDetectedUnits then
DetectedZone.ZoneUNIT:SmokeRed()

View File

@@ -1163,7 +1163,7 @@ function ESCORT:_ReportTargetsScheduler()
local ClientEscortTargets = EscortGroupData.Detection
--local EscortUnit = EscortGroupData:GetUnit( 1 )
for DetectedItemID, DetectedItem in ipairs( DetectedItems ) do
for DetectedItemID, DetectedItem in pairs( DetectedItems ) do
self:E( { DetectedItemID, DetectedItem } )
-- Remove the sub menus of the Attack menu of the Escort for the EscortGroup.
@@ -1171,10 +1171,13 @@ function ESCORT:_ReportTargetsScheduler()
if ClientEscortGroupName == EscortGroupName then
DetectedMsgs[#DetectedMsgs+1] = DetectedItemReportSummary:Text("\n")
local DetectedMsg = DetectedItemReportSummary:Text("\n")
DetectedMsgs[#DetectedMsgs+1] = DetectedMsg
self:T( DetectedMsg )
MENU_CLIENT_COMMAND:New( self.EscortClient,
DetectedItemReportSummary,
DetectedMsg,
self.EscortMenuAttackNearbyTargets,
ESCORT._AttackTarget,
self,
@@ -1183,10 +1186,12 @@ function ESCORT:_ReportTargetsScheduler()
else
if self.EscortMenuTargetAssistance then
self:T( DetectedItemReportSummary )
local DetectedMsg = DetectedItemReportSummary:Text("\n")
self:T( DetectedMsg )
local MenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, EscortGroupData.EscortName, self.EscortMenuTargetAssistance )
MENU_CLIENT_COMMAND:New( self.EscortClient,
DetectedItemReportSummary,
DetectedMsg,
MenuTargetAssistance,
ESCORT._AssistTarget,
self,

View File

@@ -860,8 +860,9 @@ end
--- Create a summary report of the Mission (one line).
-- @param #MISSION self
-- @param Wrapper.Group#GROUP ReportGroup
-- @return #string
function MISSION:ReportSummary()
function MISSION:ReportSummary( ReportGroup )
local Report = REPORT:New()
@@ -874,9 +875,9 @@ function MISSION:ReportSummary()
Report:Add( string.format( '%s - %s - Task Overview Report', Name, Status ) )
-- Determine how many tasks are remaining.
for TaskID, Task in pairs( self:GetTasks() ) do
for TaskID, Task in UTILS.spairs( self:GetTasks(), function( t, a, b ) return t[a]:ReportOrder( ReportGroup ) < t[b]:ReportOrder( ReportGroup ) end ) do
local Task = Task -- Tasking.Task#TASK
Report:Add( "- " .. Task:ReportSummary() )
Report:Add( "- " .. Task:ReportSummary( ReportGroup ) )
end
return Report:Text()
@@ -898,13 +899,17 @@ function MISSION:ReportOverview( ReportGroup, TaskStatus )
Report:Add( string.format( '%s - %s - %s Tasks Report', Name, Status, TaskStatus ) )
-- Determine how many tasks are remaining.
local TasksRemaining = 0
local Tasks = 0
for TaskID, Task in UTILS.spairs( self:GetTasks(), function( t, a, b ) return t[a]:ReportOrder( ReportGroup ) < t[b]:ReportOrder( ReportGroup ) end ) do
local Task = Task -- Tasking.Task#TASK
if Task:Is( TaskStatus ) then
Report:Add( string.rep( "-", 140 ) )
Report:Add( " - " .. Task:ReportOverview( ReportGroup ) )
end
Tasks = Tasks + 1
if Tasks >= 8 then
break
end
end
return Report:Text()
@@ -963,7 +968,7 @@ end
-- @param Wrapper.Group#GROUP ReportGroup
function MISSION:MenuReportTasksSummary( ReportGroup )
local Report = self:ReportSummary()
local Report = self:ReportSummary( ReportGroup )
self:GetCommandCenter():MessageToGroup( Report, ReportGroup )
end

View File

@@ -1343,7 +1343,7 @@ function TASK:onbeforeTimeOut( From, Event, To )
return false
end
do -- Dispatcher
do -- Links
--- Set dispatcher of a task
-- @param #TASK self
@@ -1353,6 +1353,19 @@ do -- Dispatcher
self.Dispatcher = Dispatcher
end
--- Set detection of a task
-- @param #TASK self
-- @param Function.Detection#DETECTION_BASE Detection
-- @param #number DetectedItemIndex
-- @return #TASK
function TASK:SetDetection( Detection, DetectedItemIndex )
self:E({DetectedItemIndex,Detection})
self.Detection = Detection
self.DetectedItemIndex = DetectedItemIndex
end
end
do -- Reporting
@@ -1360,36 +1373,38 @@ do -- Reporting
--- Create a summary report of the Task.
-- List the Task Name and Status
-- @param #TASK self
-- @param Wrapper.Group#GROUP ReportGroup
-- @return #string
function TASK:ReportSummary() --R2.1 fixed report. Now nicely formatted and contains the info required.
function TASK:ReportSummary( ReportGroup )
local Report = REPORT:New()
-- List the name of the Task.
local Name = self:GetName()
Report:Add( self:GetName() )
-- Determine the status of the Task.
local Status = "<" .. self:GetState() .. ">"
Report:Add( "State: <" .. self:GetState() .. ">" )
Report:Add( 'Task ' .. Name .. ' - State ' .. Status )
return Report:Text()
if self.TaskInfo["Coordinates"] then
local TaskInfoIDText = string.format( "%s: ", "Coordinate" )
local TaskCoord = self.TaskInfo["Coordinates"].TaskInfoText -- Core.Point#COORDINATE
Report:Add( TaskInfoIDText .. TaskCoord:ToString( ReportGroup, nil, self ) )
end
return Report:Text( ', ' )
end
--- Create an overiew report of the Task.
-- List the Task Name and Status
-- @param #TASK self
-- @return #string
function TASK:ReportOverview( ReportGroup ) --R2.1 fixed report. Now nicely formatted and contains the info required.
function TASK:ReportOverview( ReportGroup )
self:UpdateTaskInfo()
-- List the name of the Task.
local TaskName = self:GetName()
local Report = REPORT:New()
-- Determine the status of the Task.
local Status = "<" .. self:GetState() .. ">"
local Line = 0
local LineReport = REPORT:New()
@@ -1402,7 +1417,7 @@ function TASK:ReportOverview( ReportGroup ) --R2.1 fixed report. Now nicely form
if Line ~= 0 then
Report:AddIndent( LineReport:Text( ", " ) )
else
Report:Add( TaskName .. " - " .. LineReport:Text( ", " ) )
Report:Add( TaskName .. ", " .. LineReport:Text( ", " ) )
end
LineReport = REPORT:New()
Line = math.floor( TaskInfo.TaskInfoOrder / 10 )
@@ -1414,7 +1429,6 @@ function TASK:ReportOverview( ReportGroup ) --R2.1 fixed report. Now nicely form
LineReport:Add( TaskInfoIDText .. TaskInfo.TaskInfoText )
elseif type(TaskInfo) == "table" then
if TaskInfoID == "Coordinates" then
local FromCoordinate = ReportGroup:GetUnit(1):GetCoordinate()
local ToCoordinate = TaskInfo.TaskInfoText -- Core.Point#COORDINATE
--Report:Add( TaskInfoIDText )
LineReport:Add( TaskInfoIDText .. ToCoordinate:ToString( ReportGroup, nil, self ) )
@@ -1422,8 +1436,6 @@ function TASK:ReportOverview( ReportGroup ) --R2.1 fixed report. Now nicely form
else
end
end
end
Report:AddIndent( LineReport:Text( ", " ) )

View File

@@ -328,17 +328,39 @@ do -- TASK_A2A_INTERCEPT
"Intercept incoming intruders.\n"
)
local TargetCoordinate = TargetSetUnit:GetFirst():GetCoordinate()
self:SetInfo( "Coordinates", TargetCoordinate, 10 )
self:SetInfo( "Threat", "[" .. string.rep( "", TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
local DetectedItemsCount = TargetSetUnit:Count()
local DetectedItemsTypes = TargetSetUnit:GetTypeNames()
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 0 )
self:UpdateTaskInfo()
return self
end
function TASK_A2A_INTERCEPT:UpdateTaskInfo()
local TargetCoordinate = self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) or self.TargetSetUnit:GetFirst():GetCoordinate()
self:SetInfo( "Coordinates", TargetCoordinate, 0 )
self:SetInfo( "Threat", "[" .. string.rep( "", self.Detection and self.Detection:GetDetectedItemThreatLevel( self.DetectedItemIndex ) or self.TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
if self.Detection then
local DetectedItemsCount = self.TargetSetUnit:Count()
local ReportTypes = REPORT:New()
local TargetTypes = {}
for TargetUnitName, TargetUnit in pairs( self.TargetSetUnit:GetSet() ) do
local TargetType = self.Detection:GetDetectedUnitTypeName( TargetUnit )
if not TargetTypes[TargetType] then
TargetTypes[TargetType] = TargetType
ReportTypes:Add( TargetType )
end
end
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, ReportTypes:Text( ", " ) ), 10 )
else
local DetectedItemsCount = self.TargetSetUnit:Count()
local DetectedItemsTypes = self.TargetSetUnit:GetTypeNames()
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 10 )
end
end
--- @param #TASK_A2A_INTERCEPT self
-- @param Wrapper.Group#GROUP ReportGroup
function TASK_A2A_INTERCEPT:ReportOrder( ReportGroup )
@@ -461,17 +483,40 @@ do -- TASK_A2A_SWEEP
"Perform a fighter sweep. Incoming intruders were detected and could be hiding at the location.\n"
)
local TargetCoordinate = TargetSetUnit:GetFirst():GetCoordinate()
self:SetInfo( "Coordinates", TargetCoordinate, 10 )
self:SetInfo( "Assumed Threat", "[" .. string.rep( "", TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
local DetectedItemsCount = TargetSetUnit:Count()
local DetectedItemsTypes = TargetSetUnit:GetTypeNames()
self:SetInfo( "Lost Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 0 )
self:UpdateTaskInfo()
return self
end
function TASK_A2A_SWEEP:UpdateTaskInfo()
local TargetCoordinate = self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) or self.TargetSetUnit:GetFirst():GetCoordinate()
self:SetInfo( "Coordinates", TargetCoordinate, 0 )
self:SetInfo( "Assumed Threat", "[" .. string.rep( "", self.Detection and self.Detection:GetDetectedItemThreatLevel( self.DetectedItemIndex ) or self.TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
if self.Detection then
local DetectedItemsCount = self.TargetSetUnit:Count()
local ReportTypes = REPORT:New()
local TargetTypes = {}
for TargetUnitName, TargetUnit in pairs( self.TargetSetUnit:GetSet() ) do
local TargetType = self.Detection:GetDetectedUnitTypeName( TargetUnit )
if not TargetTypes[TargetType] then
TargetTypes[TargetType] = TargetType
ReportTypes:Add( TargetType )
end
end
self:SetInfo( "Lost Targets", string.format( "%d of %s", DetectedItemsCount, ReportTypes:Text( ", " ) ), 10 )
else
local DetectedItemsCount = self.TargetSetUnit:Count()
local DetectedItemsTypes = self.TargetSetUnit:GetTypeNames()
self:SetInfo( "Lost Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 10 )
end
end
function TASK_A2A_SWEEP:ReportOrder( ReportGroup )
local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate )
@@ -587,17 +632,39 @@ do -- TASK_A2A_ENGAGE
"Bogeys are nearby! Players close by are ordered to ENGAGE the intruders!\n"
)
local TargetCoordinate = TargetSetUnit:GetFirst():GetCoordinate()
self:SetInfo( "Coordinates", TargetCoordinate, 10 )
self:SetInfo( "Threat", "[" .. string.rep( "", TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
local DetectedItemsCount = TargetSetUnit:Count()
local DetectedItemsTypes = TargetSetUnit:GetTypeNames()
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 0 )
self:UpdateTaskInfo()
return self
end
function TASK_A2A_ENGAGE:UpdateTaskInfo()
local TargetCoordinate = self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) or self.TargetSetUnit:GetFirst():GetCoordinate()
self:SetInfo( "Coordinates", TargetCoordinate, 0 )
self:SetInfo( "Threat", "[" .. string.rep( "", self.Detection and self.Detection:GetDetectedItemThreatLevel( self.DetectedItemIndex ) or self.TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
if self.Detection then
local DetectedItemsCount = self.TargetSetUnit:Count()
local ReportTypes = REPORT:New()
local TargetTypes = {}
for TargetUnitName, TargetUnit in pairs( self.TargetSetUnit:GetSet() ) do
local TargetType = self.Detection:GetDetectedUnitTypeName( TargetUnit )
if not TargetTypes[TargetType] then
TargetTypes[TargetType] = TargetType
ReportTypes:Add( TargetType )
end
end
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, ReportTypes:Text( ", " ) ), 10 )
else
local DetectedItemsCount = self.TargetSetUnit:Count()
local DetectedItemsTypes = self.TargetSetUnit:GetTypeNames()
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 10 )
end
end
function TASK_A2A_ENGAGE:ReportOrder( ReportGroup )
local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate )

View File

@@ -382,9 +382,7 @@ do -- TASK_A2A_DISPATCHER
end
if DetectedItemChanged == true or Remove then
--self:E( "Removing Tasking: " .. Task:GetTaskName() )
Mission:RemoveTask( Task )
self.Tasks[DetectedItemIndex] = nil
Task = self:RemoveTask( DetectedItemIndex )
end
end
end
@@ -482,6 +480,11 @@ do -- TASK_A2A_DISPATCHER
return PlayersCount, PlayerTypesReport
end
function TASK_A2A_DISPATCHER:RemoveTask( TaskIndex )
self.Mission:RemoveTask( self.Tasks[TaskIndex] )
self.Tasks[TaskIndex] = nil
end
--- Assigns tasks in relation to the detected items to the @{Set#SET_GROUP}.
-- @param #TASK_A2A_DISPATCHER self
@@ -510,8 +513,7 @@ do -- TASK_A2A_DISPATCHER
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
Mission:GetCommandCenter():MessageToGroup( string.format( "Obsolete A2A task %s for %s removed.", TaskText, Mission:GetName() ), TaskGroup )
end
Mission:RemoveTask( Task )
self.Tasks[TaskIndex] = nil
Task = self:RemoveTask( TaskIndex )
end
end
end
@@ -538,21 +540,24 @@ do -- TASK_A2A_DISPATCHER
local TargetSetUnit = self:EvaluateENGAGE( DetectedItem ) -- Returns a SetUnit if there are targets to be INTERCEPTed...
if TargetSetUnit then
Task = TASK_A2A_ENGAGE:New( Mission, self.SetGroup, string.format( "ENGAGE.%03d", DetectedID ), TargetSetUnit )
Task:SetDetection( Detection, TaskIndex )
else
local TargetSetUnit = self:EvaluateINTERCEPT( DetectedItem ) -- Returns a SetUnit if there are targets to be INTERCEPTed...
if TargetSetUnit then
Task = TASK_A2A_INTERCEPT:New( Mission, self.SetGroup, string.format( "INTERCEPT.%03d", DetectedID ), TargetSetUnit )
Task:SetDetection( Detection, TaskIndex )
else
local TargetSetUnit = self:EvaluateSWEEP( DetectedItem ) -- Returns a SetUnit
if TargetSetUnit then
Task = TASK_A2A_SWEEP:New( Mission, self.SetGroup, string.format( "SWEEP.%03d", DetectedID ), TargetSetUnit )
Task:SetDetection( Detection, TaskIndex )
end
end
end
if Task then
self.Tasks[TaskIndex] = Task
Task:SetTargetZone( DetectedZone, DetectedSet:GetFirst():GetAltitude(), DetectedSet:GetFirst():GetHeading() )
Task:SetTargetZone( DetectedZone, DetectedItem.Coordinate.y, DetectedItem.Coordinate.Heading )
Task:SetDispatcher( self )
Mission:AddTask( Task )

View File

@@ -317,7 +317,7 @@ do -- TASK_A2G_SEAD
-- @param Core.Set#SET_UNIT TargetSetUnit
-- @param #string TaskBriefing The briefing of the task.
-- @return #TASK_A2G_SEAD self
function TASK_A2G_SEAD:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskBriefing )
function TASK_A2G_SEAD:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskBriefing)
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "SEAD", TaskBriefing ) ) -- #TASK_A2G_SEAD
self:F()
@@ -335,13 +335,29 @@ do -- TASK_A2G_SEAD
function TASK_A2G_SEAD:UpdateTaskInfo()
local TargetCoordinate = self.TargetSetUnit:GetFirst():GetCoordinate()
local TargetCoordinate = self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) or self.TargetSetUnit:GetFirst():GetCoordinate()
self:SetInfo( "Coordinates", TargetCoordinate, 0 )
self:SetInfo( "Threat", "[" .. string.rep( "", self.TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
local DetectedItemsCount = self.TargetSetUnit:Count()
local DetectedItemsTypes = self.TargetSetUnit:GetTypeNames()
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 10 )
self:SetInfo( "Threat", "[" .. string.rep( "", self.Detection and self.Detection:GetDetectedItemThreatLevel( self.DetectedItemIndex ) or self.TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
if self.Detection then
local DetectedItemsCount = self.TargetSetUnit:Count()
local ReportTypes = REPORT:New()
local TargetTypes = {}
for TargetUnitName, TargetUnit in pairs( self.TargetSetUnit:GetSet() ) do
local TargetType = self.Detection:GetDetectedUnitTypeName( TargetUnit )
if not TargetTypes[TargetType] then
TargetTypes[TargetType] = TargetType
ReportTypes:Add( TargetType )
end
end
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, ReportTypes:Text( ", " ) ), 10 )
else
local DetectedItemsCount = self.TargetSetUnit:Count()
local DetectedItemsTypes = self.TargetSetUnit:GetTypeNames()
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 10 )
end
end
@@ -462,13 +478,30 @@ do -- TASK_A2G_BAI
function TASK_A2G_BAI:UpdateTaskInfo()
local TargetCoordinate = self.TargetSetUnit:GetFirst():GetCoordinate()
self:E({self.Detection, self.DetectedItemIndex})
local TargetCoordinate = self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) or self.TargetSetUnit:GetFirst():GetCoordinate()
self:SetInfo( "Coordinates", TargetCoordinate, 0 )
self:SetInfo( "Threat", "[" .. string.rep( "", self.TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
local DetectedItemsCount = self.TargetSetUnit:Count()
local DetectedItemsTypes = self.TargetSetUnit:GetTypeNames()
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 10 )
self:SetInfo( "Threat", "[" .. string.rep( "", self.Detection and self.Detection:GetDetectedItemThreatLevel( self.DetectedItemIndex ) or self.TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
if self.Detection then
local DetectedItemsCount = self.TargetSetUnit:Count()
local ReportTypes = REPORT:New()
local TargetTypes = {}
for TargetUnitName, TargetUnit in pairs( self.TargetSetUnit:GetSet() ) do
local TargetType = self.Detection:GetDetectedUnitTypeName( TargetUnit )
if not TargetTypes[TargetType] then
TargetTypes[TargetType] = TargetType
ReportTypes:Add( TargetType )
end
end
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, ReportTypes:Text( ", " ) ), 10 )
else
local DetectedItemsCount = self.TargetSetUnit:Count()
local DetectedItemsTypes = self.TargetSetUnit:GetTypeNames()
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 10 )
end
end
@@ -590,13 +623,28 @@ do -- TASK_A2G_CAS
function TASK_A2G_CAS:UpdateTaskInfo()
local TargetCoordinate = self.TargetSetUnit:GetFirst():GetCoordinate()
local TargetCoordinate = self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) or self.TargetSetUnit:GetFirst():GetCoordinate()
self:SetInfo( "Coordinates", TargetCoordinate, 0 )
self:SetInfo( "Threat", "[" .. string.rep( "", self.TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
local DetectedItemsCount = self.TargetSetUnit:Count()
local DetectedItemsTypes = self.TargetSetUnit:GetTypeNames()
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 10 )
self:SetInfo( "Threat", "[" .. string.rep( "", self.Detection and self.Detection:GetDetectedItemThreatLevel( self.DetectedItemIndex ) or self.TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
if self.Detection then
local DetectedItemsCount = self.TargetSetUnit:Count()
local ReportTypes = REPORT:New()
local TargetTypes = {}
for TargetUnitName, TargetUnit in pairs( self.TargetSetUnit:GetSet() ) do
local TargetType = self.Detection:GetDetectedUnitTypeName( TargetUnit )
if not TargetTypes[TargetType] then
TargetTypes[TargetType] = TargetType
ReportTypes:Add( TargetType )
end
end
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, ReportTypes:Text( ", " ) ), 10 )
else
local DetectedItemsCount = self.TargetSetUnit:Count()
local DetectedItemsTypes = self.TargetSetUnit:GetTypeNames()
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 10 )
end
end

View File

@@ -121,8 +121,9 @@ do -- TASK_A2G_DISPATCHER
-- Determine if the set has radar targets. If it does, construct a SEAD task.
local GroundUnitCount = DetectedSet:HasGroundUnits()
local FriendliesNearBy = self.Detection:IsFriendliesNearBy( DetectedItem )
local RadarCount = DetectedSet:HasSEAD()
if GroundUnitCount > 0 and FriendliesNearBy == true then
if RadarCount == 0 and GroundUnitCount > 0 and FriendliesNearBy == true then
-- Copy the Set
local TargetSetUnit = SET_UNIT:New()
@@ -150,8 +151,9 @@ do -- TASK_A2G_DISPATCHER
-- Determine if the set has radar targets. If it does, construct a SEAD task.
local GroundUnitCount = DetectedSet:HasGroundUnits()
local FriendliesNearBy = self.Detection:IsFriendliesNearBy( DetectedItem )
local RadarCount = DetectedSet:HasSEAD()
if GroundUnitCount > 0 and FriendliesNearBy == false then
if RadarCount == 0 and GroundUnitCount > 0 and FriendliesNearBy == false then
-- Copy the Set
local TargetSetUnit = SET_UNIT:New()
@@ -164,6 +166,12 @@ do -- TASK_A2G_DISPATCHER
return nil
end
function TASK_A2G_DISPATCHER:RemoveTask( TaskIndex )
self.Mission:RemoveTask( self.Tasks[TaskIndex] )
self.Tasks[TaskIndex] = nil
end
--- Evaluates the removal of the Task from the Mission.
-- Can only occur when the DetectedItem is Changed AND the state of the Task is "Planned".
-- @param #TASK_A2G_DISPATCHER self
@@ -177,8 +185,7 @@ do -- TASK_A2G_DISPATCHER
if Task then
if ( Task:IsStatePlanned() and DetectedItemChanged == true ) or Task:IsStateCancelled() then
--self:E( "Removing Tasking: " .. Task:GetTaskName() )
Mission:RemoveTask( Task )
self.Tasks[TaskIndex] = nil
self:RemoveTask( TaskIndex )
end
end
@@ -213,6 +220,7 @@ do -- TASK_A2G_DISPATCHER
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
Mission:GetCommandCenter():MessageToGroup( string.format( "Obsolete A2G task %s for %s removed.", TaskText, Mission:GetName() ), TaskGroup )
end
Task = self:RemoveTask( TaskIndex )
Mission:RemoveTask( Task )
self.Tasks[TaskIndex] = nil
end
@@ -232,10 +240,11 @@ do -- TASK_A2G_DISPATCHER
local TaskIndex = DetectedItem.Index
local DetectedItemChanged = DetectedItem.Changed
self:E( { DetectedItemChanged = DetectedItemChanged, DetectedItemID = DetectedItemID, TaskIndex = TaskIndex } )
local Task = self.Tasks[TaskIndex] -- Tasking.Task_A2G#TASK_A2G
if Task then
-- If there is a Task and the task was assigned, then we check if the task was changed ... If it was, we need to reevaluate the targets.
if Task:IsStateAssigned() then
if DetectedItemChanged == true then -- The detection has changed, thus a new TargetSet is to be evaluated and set
@@ -254,24 +263,24 @@ do -- TASK_A2G_DISPATCHER
if TargetSetUnit then
if Task:IsInstanceOf( TASK_A2G_CAS ) then
Task:SetTargetSetUnit( TargetSetUnit )
Task:SetDetection( Detection, TaskIndex )
Task:UpdateTaskInfo()
TargetsReport:Add( Detection:GetChangeText( DetectedItem ) )
else
Task:Cancel()
Task = nil
self.Tasks[TaskIndex] = nil
Task = self:RemoveTask( TaskIndex )
end
else
local TargetSetUnit = self:EvaluateBAI( DetectedItem ) -- Returns a SetUnit if there are targets to be BAIed...
if TargetSetUnit then
if Task:IsInstanceOf( TASK_A2G_BAI ) then
Task:SetTargetSetUnit( TargetSetUnit )
Task:SetDetection( Detection, TaskIndex )
Task:UpdateTaskInfo()
TargetsReport:Add( Detection:GetChangeText( DetectedItem ) )
else
Task:Cancel()
Task = nil
self.Tasks[TaskIndex] = nil
Task = self:RemoveTask( TaskIndex )
end
end
end
@@ -288,14 +297,56 @@ do -- TASK_A2G_DISPATCHER
end
end
Task = self:EvaluateRemoveTask( Mission, Task, TaskIndex, DetectedItemChanged ) -- Task will be removed if it is planned and changed.
if Task then
if Task:IsStatePlanned() then
if DetectedItemChanged == true then -- The detection has changed, thus a new TargetSet is to be evaluated and set
if Task:IsInstanceOf( TASK_A2G_SEAD ) then
local TargetSetUnit = self:EvaluateSEAD( DetectedItem ) -- Returns a SetUnit if there are targets to be SEADed...
if TargetSetUnit then
Task:SetTargetSetUnit( TargetSetUnit )
Task:UpdateTaskInfo()
else
Task:Cancel()
Task = self:RemoveTask( TaskIndex )
end
else
if Task:IsInstanceOf( TASK_A2G_CAS ) then
local TargetSetUnit = self:EvaluateCAS( DetectedItem ) -- Returns a SetUnit if there are targets to be CASed...
if TargetSetUnit then
Task:SetTargetSetUnit( TargetSetUnit )
Task:SetDetection( Detection, TaskIndex )
Task:UpdateTaskInfo()
else
Task:Cancel()
Task = self:RemoveTask( TaskIndex )
end
else
if Task:IsInstanceOf( TASK_A2G_BAI ) then
local TargetSetUnit = self:EvaluateBAI( DetectedItem ) -- Returns a SetUnit if there are targets to be BAIed...
if TargetSetUnit then
Task:SetTargetSetUnit( TargetSetUnit )
Task:SetDetection( Detection, TaskIndex )
Task:UpdateTaskInfo()
else
Task:Cancel()
Task = self:RemoveTask( TaskIndex )
end
else
Task:Cancel()
Task = self:RemoveTask( TaskIndex )
end
end
end
end
end
end
-- Evaluate SEAD
if not Task then
local TargetSetUnit = self:EvaluateSEAD( DetectedItem ) -- Returns a SetUnit if there are targets to be SEADed...
if TargetSetUnit then
Task = TASK_A2G_SEAD:New( Mission, self.SetGroup, string.format( "SEAD.%03d", DetectedItemID ), TargetSetUnit )
Task:SetDetection( Detection, TaskIndex )
end
-- Evaluate CAS
@@ -303,6 +354,7 @@ do -- TASK_A2G_DISPATCHER
local TargetSetUnit = self:EvaluateCAS( DetectedItem ) -- Returns a SetUnit if there are targets to be CASed...
if TargetSetUnit then
Task = TASK_A2G_CAS:New( Mission, self.SetGroup, string.format( "CAS.%03d", DetectedItemID ), TargetSetUnit )
Task:SetDetection( Detection, TaskIndex )
end
-- Evaluate BAI
@@ -310,6 +362,7 @@ do -- TASK_A2G_DISPATCHER
local TargetSetUnit = self:EvaluateBAI( DetectedItem, self.Mission:GetCommandCenter():GetPositionable():GetCoalition() ) -- Returns a SetUnit if there are targets to be BAIed...
if TargetSetUnit then
Task = TASK_A2G_BAI:New( Mission, self.SetGroup, string.format( "BAI.%03d", DetectedItemID ), TargetSetUnit )
Task:SetDetection( Detection, TaskIndex )
end
end
end

View File

@@ -379,7 +379,7 @@ function CONTROLLABLE:SetTask( DCSTask, WaitTime )
end
if not WaitTime or WaitTime == 0 then
self:SetTask( DCSTask )
SetTask( DCSTask )
else
self.TaskScheduler:Schedule( self, SetTask, { DCSTask }, WaitTime )
end

View File

@@ -83,15 +83,8 @@ end
function IDENTIFIABLE:GetName()
self:F2( self.IdentifiableName )
local DCSIdentifiable = self:GetDCSObject()
if DCSIdentifiable then
local IdentifiableName = self.IdentifiableName
return IdentifiableName
end
self:E( self.ClassName .. " " .. self.IdentifiableName .. " not found!" )
return nil
local IdentifiableName = self.IdentifiableName
return IdentifiableName
end