mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge branch 'master' into funkyfranky
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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( ", " ) )
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 )
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user