diff --git a/Moose Development/Moose/AI/AI_A2A.lua b/Moose Development/Moose/AI/AI_A2A.lua index 0cd259add..fac8b4eaa 100644 --- a/Moose Development/Moose/AI/AI_A2A.lua +++ b/Moose Development/Moose/AI/AI_A2A.lua @@ -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. diff --git a/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua b/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua index 843d9ad5d..74c3b5746 100644 --- a/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua +++ b/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua @@ -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 diff --git a/Moose Development/Moose/Core/Event.lua b/Moose Development/Moose/Core/Event.lua index 46fdeebb1..28a4ecf26 100644 --- a/Moose Development/Moose/Core/Event.lua +++ b/Moose Development/Moose/Core/Event.lua @@ -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 ) diff --git a/Moose Development/Moose/Core/Point.lua b/Moose Development/Moose/Core/Point.lua index d9e55dc04..7f9b04620 100644 --- a/Moose Development/Moose/Core/Point.lua +++ b/Moose Development/Moose/Core/Point.lua @@ -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 ) diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index 65a9354f6..f89224259 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -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 diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index 5d183f58d..aa061a94f 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -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 diff --git a/Moose Development/Moose/Functional/Designate.lua b/Moose Development/Moose/Functional/Designate.lua index 44b26a0b7..78758e763 100644 --- a/Moose Development/Moose/Functional/Designate.lua +++ b/Moose Development/Moose/Functional/Designate.lua @@ -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 ) diff --git a/Moose Development/Moose/Functional/Detection.lua b/Moose Development/Moose/Functional/Detection.lua index 034361595..b2ce1538b 100644 --- a/Moose Development/Moose/Functional/Detection.lua +++ b/Moose Development/Moose/Functional/Detection.lua @@ -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() diff --git a/Moose Development/Moose/Functional/Escort.lua b/Moose Development/Moose/Functional/Escort.lua index 697a00e00..66496f973 100644 --- a/Moose Development/Moose/Functional/Escort.lua +++ b/Moose Development/Moose/Functional/Escort.lua @@ -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, diff --git a/Moose Development/Moose/Tasking/Mission.lua b/Moose Development/Moose/Tasking/Mission.lua index 5d1bcfc38..8565078f2 100644 --- a/Moose Development/Moose/Tasking/Mission.lua +++ b/Moose Development/Moose/Tasking/Mission.lua @@ -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 diff --git a/Moose Development/Moose/Tasking/Task.lua b/Moose Development/Moose/Tasking/Task.lua index b1da137fa..89c0e0bcd 100644 --- a/Moose Development/Moose/Tasking/Task.lua +++ b/Moose Development/Moose/Tasking/Task.lua @@ -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( ", " ) ) diff --git a/Moose Development/Moose/Tasking/Task_A2A.lua b/Moose Development/Moose/Tasking/Task_A2A.lua index cbef9d502..a40424276 100644 --- a/Moose Development/Moose/Tasking/Task_A2A.lua +++ b/Moose Development/Moose/Tasking/Task_A2A.lua @@ -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 ) diff --git a/Moose Development/Moose/Tasking/Task_A2A_Dispatcher.lua b/Moose Development/Moose/Tasking/Task_A2A_Dispatcher.lua index 018ba2910..f21928fdf 100644 --- a/Moose Development/Moose/Tasking/Task_A2A_Dispatcher.lua +++ b/Moose Development/Moose/Tasking/Task_A2A_Dispatcher.lua @@ -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 ) diff --git a/Moose Development/Moose/Tasking/Task_A2G.lua b/Moose Development/Moose/Tasking/Task_A2G.lua index 7cdb72da3..9760326c4 100644 --- a/Moose Development/Moose/Tasking/Task_A2G.lua +++ b/Moose Development/Moose/Tasking/Task_A2G.lua @@ -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 diff --git a/Moose Development/Moose/Tasking/Task_A2G_Dispatcher.lua b/Moose Development/Moose/Tasking/Task_A2G_Dispatcher.lua index 2234ef950..9de721ff4 100644 --- a/Moose Development/Moose/Tasking/Task_A2G_Dispatcher.lua +++ b/Moose Development/Moose/Tasking/Task_A2G_Dispatcher.lua @@ -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 diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index aca0a5936..8d3a037a1 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -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 diff --git a/Moose Development/Moose/Wrapper/Identifiable.lua b/Moose Development/Moose/Wrapper/Identifiable.lua index f863e9bd4..cd7243f4b 100644 --- a/Moose Development/Moose/Wrapper/Identifiable.lua +++ b/Moose Development/Moose/Wrapper/Identifiable.lua @@ -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 diff --git a/docs/Documentation/AI_A2A_Dispatcher.html b/docs/Documentation/AI_A2A_Dispatcher.html index 14b161be1..a44b0d577 100644 --- a/docs/Documentation/AI_A2A_Dispatcher.html +++ b/docs/Documentation/AI_A2A_Dispatcher.html @@ -713,7 +713,7 @@ Per one, two, three, four?
SquadronName :
Defender :
This table contains the targets detected during patrol.
-DESIGNATE| DESIGNATE:AddMenuLaserCode(LaserCode, MenuText) | +
+ Add a specific lase code to the designate lase menu to lase targets with a specific laser code. + |
+ |||
| DESIGNATE.AttackSet | @@ -185,6 +191,12 @@ each detected set of potential targets can be lased or smoked... | DESIGNATE:CoordinateLase() |
Coordinates the Auto Lase. + |
+ |
| DESIGNATE.DesignateName | ++ | |||
| DESIGNATE.LaserCodesUsed | + | +|||
| DESIGNATE.MarkScheduler | ++ | |||
| DESIGNATE.MaximumDesignations | + | +|||
| DESIGNATE.MaximumDistanceAirDesignation | ++ + | +|||
| DESIGNATE.MaximumDistanceDesignations | ++ + | +|||
| DESIGNATE.MaximumDistanceGroundDesignation | ++ + | +|||
| DESIGNATE.MaximumMarkings | ++ | |||
| DESIGNATE:MenuIlluminate(Index) | + | +|||
| DESIGNATE:MenuLaseCode(Index, Duration, LaserCode) | ++ | |||
| DESIGNATE:MenuLaseOn(Index, Duration) | + | +|||
| DESIGNATE.MenuLaserCodes | ++ | |||
| DESIGNATE.Recces | + | +|||
| DESIGNATE:RemoveMenuLaserCode(LaserCode) | +
+ Removes a specific lase code from the designate lase menu. |
|||
| DESIGNATE:SetAutoLase(AutoLase) | +DESIGNATE:SetAutoLase(AutoLase, Message) |
Set auto lase. |
@@ -431,6 +491,12 @@ each detected set of potential targets can be lased or smoked...
DESIGNATE:SetDesignateMenu() |
Sets the Designate Menu. + |
+
| DESIGNATE:SetDesignateName(DesignateName) | +
+ Set the name of the designation. |
|||
| DESIGNATE:SetMaximumDesignations(MaximumDesignations) |
Set the maximum amount of designations. + |
+ |||
| DESIGNATE:SetMaximumDistanceAirDesignation(MaximumDistanceAirDesignation) | +
+ Set the maximum air designation distance. + |
+ |||
| DESIGNATE:SetMaximumDistanceDesignations(MaximumDistanceDesignations) | +
+ Set the overall maximum distance when designations can be accepted. + |
+ |||
| DESIGNATE:SetMaximumDistanceGroundDesignation(MaximumDistanceGroundDesignation) | +
+ Set the maximum ground designation distance. + |
+ |||
| DESIGNATE:SetMaximumMarkings(MaximumMarkings) | +
+ Set the maximum amount of markings FACs will do, per designated target group. |
|||
| DESIGNATE:onafterLaseOn(From, Event, To, Index, Duration) | +DESIGNATE:onafterLaseOn(From, Event, To, Index, Duration, LaserCode) | |||
| DESIGNATE:onafterLasing(From, Event, To, Index, Duration) | +DESIGNATE:onafterLasing(From, Event, To, Index, Duration, LaserCodeRequested) | @@ -685,7 +775,7 @@ Using the menu system, the player can "forget" a designation, so that gradually | DETECTION_AREAS:CalculateIntercept(DetectedItem) |
Calculate the optimal intercept point of the DetectedItem. - |
-
| DETECTION_AREAS:CalculateThreatLevelA2G(DetectedItem) | -
- Calculate the maxium A2G threat level of the DetectedItem. |
|||
| DETECTION_AREAS:GetChangeText(DetectedItem) |
Make text documenting the changes of the detected zone. - |
- |||
| DETECTION_AREAS:GetDetectedItemCoordinate(Index) | -
- Get the detected item coordinate. - |
- |||
| DETECTION_AREAS:GetTreatLevelA2G(DetectedItem) | -
- Returns the A2G threat level of the units in the DetectedItem |
|||
| DETECTION_BASE:GetDetectedItemID(Index) |
Get a detected ItemID using a given numeric index. + |
+ |||
| DETECTION_BASE:GetDetectedItemThreatLevel(Index) | +
+ Get the detected item coordinate. |
|||
| DETECTION_BASE:GetDetectedSet(Index) |
Get the Set#SET_UNIT of a detecttion area using a given numeric index. + |
+ |||
| DETECTION_BASE:GetDetectedUnitTypeName(DetectedUnit) | +
+ Gets a detected unit type name, taking into account the detection results. |
|||
| DETECTION_BASE:GetPlayersNearBy(DetectedItem) |
Returns friendly units nearby the FAC units ... - |
- |||
| DETECTION_BASE:HasDetectedItemLOS(Index) | -
- Has the detected item LOS (Line Of Sight) with one of the Recce? |
|||
| DETECTION_BASE:SetAlphaAngleProbability(AlphaAngleProbability) |
Upon a visual detection, the higher the unit is during the detecting process, the more likely the detected unit is to be detected properly. + |
+ |||
| DETECTION_BASE:SetDetectedItemCoordinate(The, Coordinate, DetectedItemUnit, DetectedItem) | +
+ Set the detected item coordinate. + |
+ |||
| DETECTION_BASE:SetDetectedItemThreatLevel(The, DetectedItem) | +
+ Set the detected item threatlevel. |
|||
| DETECTION_BASE.DetectedItem.Changes |
A list of the changes reported on the detected area. (It is up to the user of the detected area to consume those changes). + |
+ |||
| DETECTION_BASE.DetectedItem.Coordinate | +
+ The last known coordinate of the DetectedItem. + |
+ |||
| DETECTION_BASE.DetectedItem.DistanceRecce | ++ | |||
| DETECTION_BASE.DetectedItem.InterceptCoord | - | -|||
| DETECTION_BASE.DetectedItem.MaxThreatLevelA2G | -- | |||
| DETECTION_BASE.DetectedItem.Set |
-- The Set of Units in the detected area. + |
+ |||
| DETECTION_BASE.DetectedItem.ThreatLevel | ++ | |||
| DETECTION_TYPES:GetChangeText(DetectedItem) |
Make text documenting the changes of the detected zone. - |
- |||
| DETECTION_TYPES:GetDetectedItemCoordinate(DetectedTypeName) | -
- Get the detected item coordinate. |
|||
| DETECTION_UNITS:GetChangeText(DetectedItem) |
Make text documenting the changes of the detected zone. - |
- |||
| DETECTION_UNITS:GetDetectedItemCoordinate(Index) | -
- Get the detected item coordinate. |
|||
| MENU_COMMAND_BASE.New(#, self, MenuText, ParentMenu, CommandMenuFunction, CommandMenuArguments) |
Constructor + |
+ |||
| MENU_COMMAND_BASE.SetCommandMenuArguments(#, self, CommandMenuArguments) | +
+ This sets the new command arguments of a menu, +so that if a menu is regenerated, or if command arguments change, +that the arguments set for the menu are loosely coupled with the menu itself!!! +If the arguments change, no new menu needs to be generated if the menu text is the same!!! + |
+ |||
| MENU_COMMAND_BASE.SetCommandMenuFunction(#, self, CommandMenuFunction) | +
+ This sets the new command function of a menu, +so that if a menu is regenerated, or if command function changes, +that the function set for the menu is loosely coupled with the menu itself!!! +If the function changes, no new menu needs to be generated if the menu text is the same!!! |
The MENUCOMMANDBASE class defines the main MENU class where other MENU COMMAND_ classes are derived from, in order to set commands.
+This sets the new command arguments of a menu, +so that if a menu is regenerated, or if command arguments change, +that the arguments set for the menu are loosely coupled with the menu itself!!! +If the arguments change, no new menu needs to be generated if the menu text is the same!!!
+ + # :
+ENUCOMMANDBASE
self :
CommandMenuArguments :
This sets the new command function of a menu, +so that if a menu is regenerated, or if command function changes, +that the function set for the menu is loosely coupled with the menu itself!!! +If the function changes, no new menu needs to be generated if the menu text is the same!!!
+ + # :
+ENUCOMMANDBASE
self :
CommandMenuFunction :
Create a summary report of the Mission (one line).
Create a summary report of the Mission (one line).
+Wrapper.Group#GROUP ReportGroup :
#string:
diff --git a/docs/Documentation/Point.html b/docs/Documentation/Point.html index 90f96d0c2..22a8976b5 100644 --- a/docs/Documentation/Point.html +++ b/docs/Documentation/Point.html @@ -416,9 +416,15 @@Provides a Lat Lon string
+Provides a Lat Lon string in Degree Decimal Minute format.
+Provides a Lat Lon string in Degree Minute Second format.
Provides a Lat Lon string
+Provides a Lat Lon string in Degree Decimal Minute format.
#string: -The LL Text
+The LL DDM Text + +Provides a Lat Lon string in Degree Minute Second format.
+ +Core.Settings#SETTINGS Settings :
+(optional) Settings
#string: +The LL DMS Text
Smoke the POSITIONABLE.
SmokeColor :
Utilities.Utils#SMOKECOLOR SmokeColor :
+The color to smoke to positionable.
Range :
#number Range :
+The range in meters to randomize the smoking around the positionable.
#number AddHeight :
+The height in meters to add to the altitude of the positionable.
Clears all pending schedules.
+Clears all pending schedules.
+ + +Calculate the maxium A2G threat level of the SET_UNIT.
+#number: +The maximum threatlevel
+Gets the SETTINGS LL accuracy.
-Gets the SETTINGS LL DMS.
Is LL
+Is LL DDM
+Is LL DMS
Is LL
+Is LL DDM
+Is LL DMS
Sets A2A LL
+Sets A2A LL DDM
+Sets A2A LL DMS
Sets A2G LL
+Sets A2G LL DDM
+Sets A2G LL DMS
Sets the SETTINGS LL accuracy.
-Sets the SETTINGS LL DMS.
#number:
-Gets the SETTINGS LL DMS.
- -#number:
- -Is LL
+Is LL DDM
#boolean: -true if LL
+true if LL DDM + +Is LL DMS
+ +#boolean: +true if LL DMS
Is LL
+Is LL DDM
#boolean: -true if LL
+true if LL DDM + +Is LL DMS
+ +#boolean: +true if LL DMS
PlayerUnit :
PlayerGroup :
PlayerName :
LL_DMS :
MenuGroup :
RootMenu :
LL_DMS :
Sets A2A LL
+Sets A2A LL DDM
+ +Sets A2A LL DMS
Sets A2G LL
+Sets A2G LL DDM
+ +Sets A2G LL DMS
Sets the SETTINGS LL DMS.
- -#number LL_DMS :
Don't repeat the group from Take-Off till Landing and back Take-Off by ReSpawning.
-By default, no InitLimit
-A PlayerUnit crashed in a Task.
+Create a summary report of the Task.
Sets a Task briefing.
+Set detection of a task
List the Task Name and Status
+Wrapper.Group#GROUP ReportGroup :
#string:
@@ -2429,6 +2483,37 @@ self#TASK: self
+Set detection of a task
+ +Function.Detection#DETECTION_BASE Detection :
#number DetectedItemIndex :
Assigns tasks in relation to the detected items to the Set#SET_GROUP.
+ TaskIndex :
Assigns tasks in relation to the detected items to the Set#SET_GROUP.
+#boolean: Return true if you want the task assigning to continue... false will cancel the loop.
+ + + TaskIndex :
ZONE_GROUP| ZONE_GROUP:GetRandomPointVec2(inner, outer) | +
+ Returns a Point#POINT_VEC2 object reflecting a random 2D location within the zone. + |
+
| ZONE_GROUP:GetRandomVec2() |
Returns a random location within the zone of the Group. @@ -1425,6 +1431,39 @@ The smoke color.
|