diff --git a/Moose Development/Moose/AI/AI_A2A_Cap.lua b/Moose Development/Moose/AI/AI_A2A_Cap.lua index a804ecaa3..2509721b9 100644 --- a/Moose Development/Moose/AI/AI_A2A_Cap.lua +++ b/Moose Development/Moose/AI/AI_A2A_Cap.lua @@ -391,9 +391,9 @@ function AI_A2A_CAP:onafterEngage( AIGroup, From, Event, To, AttackSetUnit ) self.AttackSetUnit = AttackSetUnit or self.AttackSetUnit -- Core.Set#SET_UNIT - local FirstAttackUnit = self.AttackSetUnit:GetFirst() + local FirstAttackUnit = self.AttackSetUnit:GetFirst() -- Wrapper.Unit#UNIT - if FirstAttackUnit then + if FirstAttackUnit and FirstAttackUnit:IsAlive() then -- If there is no attacker anymore, stop the engagement. if AIGroup:IsAlive() then diff --git a/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua b/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua index ccfbfa352..649d2223e 100644 --- a/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua +++ b/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua @@ -1369,14 +1369,14 @@ do -- AI_A2A_DISPATCHER --- -- @param #AI_A2A_DISPATCHER self -- @param Wrapper.Group#GROUP AIGroup - function AI_A2A_DISPATCHER:SetDefenderTaskTarget( Defender, Target ) + function AI_A2A_DISPATCHER:SetDefenderTaskTarget( Defender, AttackerDetection ) local Message = "(" .. self.DefenderTasks[Defender].Type .. ") " Message = Message .. Defender:GetName() - Message = Message .. ( Target and ( " target " .. Target.Index .. " [" .. Target.Set:Count() .. "]" ) ) or "" - self:F( { Target = Message } ) - if Target then - self.DefenderTasks[Defender].Target = Target + Message = Message .. ( AttackerDetection and ( " target " .. AttackerDetection.Index .. " [" .. AttackerDetection.Set:Count() .. "]" ) ) or "" + self:F( { AttackerDetection = Message } ) + if AttackerDetection then + self.DefenderTasks[Defender].Target = AttackerDetection end return self end @@ -2510,20 +2510,20 @@ do -- AI_A2A_DISPATCHER --- -- @param #AI_A2A_DISPATCHER self - function AI_A2A_DISPATCHER:CountDefendersEngaged( Target ) + function AI_A2A_DISPATCHER:CountDefendersEngaged( AttackerDetection ) -- First, count the active AIGroups Units, targetting the DetectedSet local AIUnitCount = 0 self:E( "Counting Defenders Engaged for Attacker:" ) - local DetectedSet = Target.Set + local DetectedSet = AttackerDetection.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 + if DefenderTask and DefenderTask.Index == AttackerDetection.Index then AIUnitCount = AIUnitCount + AIGroup:GetSize() self:E( "Defender Group Name: " .. AIGroup:GetName() .. ", Size: " .. AIGroup:GetSize() ) end @@ -2534,18 +2534,18 @@ do -- AI_A2A_DISPATCHER --- -- @param #AI_A2A_DISPATCHER self - function AI_A2A_DISPATCHER:CountDefendersToBeEngaged( DetectedItem, DefenderCount ) + function AI_A2A_DISPATCHER:CountDefendersToBeEngaged( AttackerDetection, DefenderCount ) local Friendlies = nil - local DetectedSet = DetectedItem.Set - local DetectedCount = DetectedSet:Count() + local AttackerSet = AttackerDetection.Set + local AttackerCount = AttackerSet:Count() - local AIFriendlies = self:GetAIFriendliesNearBy( DetectedItem ) + local DefenderFriendlies = self:GetAIFriendliesNearBy( AttackerDetection ) - for FriendlyDistance, AIFriendly in UTILS.spairs( AIFriendlies or {} ) do + for FriendlyDistance, AIFriendly in UTILS.spairs( DefenderFriendlies or {} ) do -- We only allow to ENGAGE targets as long as the Units on both sides are balanced. - if DetectedCount > DefenderCount then + if AttackerCount > DefenderCount then local Friendly = AIFriendly:GetGroup() -- Wrapper.Group#GROUP if Friendly and Friendly:IsAlive() then -- Ok, so we have a friendly near the potential target. @@ -2554,7 +2554,7 @@ do -- AI_A2A_DISPATCHER if DefenderTask then -- The Task should be CAP or GCI if DefenderTask.Type == "CAP" or DefenderTask.Type == "GCI" then - -- If there is no target, then add the AIGroup to the ResultAIGroups for Engagement to the TargetSet + -- If there is no target, then add the AIGroup to the ResultAIGroups for Engagement to the AttackerSet if DefenderTask.Target == nil then if DefenderTask.Fsm:Is( "Returning" ) or DefenderTask.Fsm:Is( "Patrolling" ) then @@ -2650,16 +2650,16 @@ do -- AI_A2A_DISPATCHER --- -- @param #AI_A2A_DISPATCHER self - function AI_A2A_DISPATCHER:onafterENGAGE( From, Event, To, Target, Defenders ) + function AI_A2A_DISPATCHER:onafterENGAGE( From, Event, To, AttackerDetection, Defenders ) if Defenders then for DefenderID, Defender in pairs( Defenders ) do local Fsm = self:GetDefenderTaskFsm( Defender ) - Fsm:__Engage( 1, Target.Set ) -- Engage on the TargetSetUnit + Fsm:__Engage( 1, AttackerDetection.Set ) -- Engage on the TargetSetUnit - self:SetDefenderTaskTarget( Defender, Target ) + self:SetDefenderTaskTarget( Defender, AttackerDetection ) end end @@ -2667,164 +2667,169 @@ do -- AI_A2A_DISPATCHER --- -- @param #AI_A2A_DISPATCHER self - function AI_A2A_DISPATCHER:onafterGCI( From, Event, To, DetectedItem, DefendersMissing, Friendlies ) + function AI_A2A_DISPATCHER:onafterGCI( From, Event, To, AttackerDetection, DefendersMissing, DefenderFriendlies ) - self:F( { From, Event, To, DetectedItem.Index, DefendersMissing, Friendlies } ) + self:F( { From, Event, To, AttackerDetection.Index, DefendersMissing, DefenderFriendlies } ) - local AttackerSet = DetectedItem.Set - local AttackerCount = AttackerSet:Count() - local DefendersCount = 0 - - for DefenderID, AIGroup in pairs( Friendlies or {} ) do - - local Fsm = self:GetDefenderTaskFsm( AIGroup ) - Fsm:__Engage( 1, AttackerSet ) -- Engage on the TargetSetUnit + local AttackerSet = AttackerDetection.Set + local AttackerUnit = AttackerSet:GetFirst() + + if AttackerUnit and AttackerUnit:IsAlive() then + local AttackerCount = AttackerSet:Count() + local DefenderCount = 0 + + for DefenderID, DefenderGroup in pairs( DefenderFriendlies or {} ) do + + local Fsm = self:GetDefenderTaskFsm( DefenderGroup ) + Fsm:__Engage( 1, AttackerSet ) -- Engage on the TargetSetUnit + + self:SetDefenderTaskTarget( DefenderGroup, AttackerDetection ) + + DefenderCount = DefenderCount + DefenderGroup:GetSize() + end + + DefenderCount = DefendersMissing + + local ClosestDistance = 0 + local ClosestDefenderSquadronName = nil - self:SetDefenderTaskTarget( AIGroup, DetectedItem ) - - DefendersCount = DefendersCount + AIGroup:GetSize() - end - - DefendersCount = DefendersMissing - - local ClosestDistance = 0 - local ClosestDefenderSquadronName = nil - - 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:F( { DefenderSquadron } ) - local SpawnCoord = DefenderSquadron.Airbase:GetCoordinate() -- Core.Point#COORDINATE - --local TargetCoord = AttackerSet:GetFirst():GetCoordinate() - 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 + local BreakLoop = false + + while( DefenderCount > 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:F( { DefenderSquadron } ) + local SpawnCoord = DefenderSquadron.Airbase:GetCoordinate() -- Core.Point#COORDINATE + local AttackerCoord = AttackerUnit:GetCoordinate() + local InterceptCoord = AttackerDetection.InterceptCoord + self:F({InterceptCoord = InterceptCoord}) + if InterceptCoord then + local InterceptDistance = SpawnCoord:Get2DDistance( InterceptCoord ) + local AirbaseDistance = SpawnCoord:Get2DDistance( AttackerCoord ) + self:F( { InterceptDistance = InterceptDistance, AirbaseDistance = AirbaseDistance, InterceptCoord = InterceptCoord } ) - -- Only intercept if the distance to target is smaller or equal to the GciRadius limit. - if Distance <= self.GciRadius then - ClosestDistance = Distance - ClosestDefenderSquadronName = SquadronName + if ClosestDistance == 0 or InterceptDistance < ClosestDistance then + + -- Only intercept if the distance to target is smaller or equal to the GciRadius limit. + if AirbaseDistance <= self.GciRadius then + ClosestDistance = InterceptDistance + ClosestDefenderSquadronName = SquadronName + end end end end end - end - - if ClosestDefenderSquadronName then - - local DefenderSquadron = self:CanGCI( ClosestDefenderSquadronName ) - if DefenderSquadron then - - local Gci = self.DefenderSquadrons[ClosestDefenderSquadronName].Gci - - if Gci then + if ClosestDefenderSquadronName then - local DefenderOverhead = DefenderSquadron.Overhead or self.DefenderDefault.Overhead - local DefenderGrouping = DefenderSquadron.Grouping or self.DefenderDefault.Grouping - local DefendersNeeded = math.ceil( DefendersCount * DefenderOverhead ) - - self:F( { DefaultOverhead = self.DefenderDefault.Overhead, Overhead = DefenderOverhead } ) - self:F( { DefaultGrouping = self.DefenderDefault.Grouping, Grouping = DefenderGrouping } ) - self:F( { DefendersCount = DefendersCount, DefendersNeeded = DefendersNeeded } ) - - while ( DefendersNeeded > 0 ) do + local DefenderSquadron = self:CanGCI( ClosestDefenderSquadronName ) - local Spawn = DefenderSquadron.Spawn[ math.random( 1, #DefenderSquadron.Spawn ) ] -- Functional.Spawn#SPAWN - local DefenderGrouping = ( DefenderGrouping < DefendersNeeded ) and DefenderGrouping or DefendersNeeded - if DefenderGrouping then - Spawn:InitGrouping( DefenderGrouping ) - else - Spawn:InitGrouping() - end + if DefenderSquadron then + + local Gci = self.DefenderSquadrons[ClosestDefenderSquadronName].Gci + + if Gci then + + local DefenderOverhead = DefenderSquadron.Overhead or self.DefenderDefault.Overhead + local DefenderGrouping = DefenderSquadron.Grouping or self.DefenderDefault.Grouping + local DefendersNeeded = math.ceil( DefenderCount * DefenderOverhead ) - local TakeoffMethod = self:GetSquadronTakeoff( ClosestDefenderSquadronName ) - local DefenderGCI = Spawn:SpawnAtAirbase( DefenderSquadron.Airbase, TakeoffMethod, DefenderSquadron.TakeoffAltitude or self.DefenderDefault.TakeoffAltitude ) -- Wrapper.Group#GROUP - self:F( { GCIDefender = DefenderGCI:GetName() } ) - - DefendersNeeded = DefendersNeeded - DefenderGrouping - - self:AddDefenderToSquadron( DefenderSquadron, DefenderGCI, DefenderGrouping ) + self:F( { DefaultOverhead = self.DefenderDefault.Overhead, Overhead = DefenderOverhead } ) + self:F( { DefaultGrouping = self.DefenderDefault.Grouping, Grouping = DefenderGrouping } ) + self:F( { DefendersCount = DefenderCount, DefendersNeeded = DefendersNeeded } ) + + while ( DefendersNeeded > 0 ) do + + local Spawn = DefenderSquadron.Spawn[ math.random( 1, #DefenderSquadron.Spawn ) ] -- Functional.Spawn#SPAWN + local DefenderGrouping = ( DefenderGrouping < DefendersNeeded ) and DefenderGrouping or DefendersNeeded + if DefenderGrouping then + Spawn:InitGrouping( DefenderGrouping ) + else + Spawn:InitGrouping() + end + + local TakeoffMethod = self:GetSquadronTakeoff( ClosestDefenderSquadronName ) + local DefenderGCI = Spawn:SpawnAtAirbase( DefenderSquadron.Airbase, TakeoffMethod, DefenderSquadron.TakeoffAltitude or self.DefenderDefault.TakeoffAltitude ) -- Wrapper.Group#GROUP + self:F( { GCIDefender = DefenderGCI:GetName() } ) + + DefendersNeeded = DefendersNeeded - DefenderGrouping - if DefenderGCI then - - DefendersCount = DefendersCount - DefenderGrouping - - local Fsm = AI_A2A_GCI:New( DefenderGCI, Gci.EngageMinSpeed, Gci.EngageMaxSpeed ) - Fsm:SetDispatcher( self ) - Fsm:SetHomeAirbase( DefenderSquadron.Airbase ) - Fsm:SetFuelThreshold( DefenderSquadron.FuelThreshold or self.DefenderDefault.FuelThreshold, 60 ) - Fsm:SetDamageThreshold( self.DefenderDefault.DamageThreshold ) - Fsm:SetDisengageRadius( self.DisengageRadius ) - Fsm:Start() - Fsm:__Engage( 2, DetectedItem.Set ) -- Engage on the TargetSetUnit - + self:AddDefenderToSquadron( DefenderSquadron, DefenderGCI, DefenderGrouping ) + + if DefenderGCI then - self:SetDefenderTask( ClosestDefenderSquadronName, DefenderGCI, "GCI", Fsm, DetectedItem ) - - - function Fsm:onafterRTB( Defender, From, Event, To ) - self:F({"GCI RTB", Defender:GetName()}) - self:GetParent(self).onafterRTB( self, Defender, From, Event, To ) + DefenderCount = DefenderCount - DefenderGrouping - local Dispatcher = self:GetDispatcher() -- #AI_A2A_DISPATCHER - Dispatcher:ClearDefenderTaskTarget( Defender ) - end - - --- @param #AI_A2A_DISPATCHER self - function Fsm:onafterLostControl( Defender, From, Event, To ) - self:F({"GCI LostControl", Defender:GetName()}) - self:GetParent(self).onafterHome( self, Defender, From, Event, To ) + local Fsm = AI_A2A_GCI:New( DefenderGCI, Gci.EngageMinSpeed, Gci.EngageMaxSpeed ) + Fsm:SetDispatcher( self ) + Fsm:SetHomeAirbase( DefenderSquadron.Airbase ) + Fsm:SetFuelThreshold( DefenderSquadron.FuelThreshold or self.DefenderDefault.FuelThreshold, 60 ) + Fsm:SetDamageThreshold( self.DefenderDefault.DamageThreshold ) + Fsm:SetDisengageRadius( self.DisengageRadius ) + Fsm:Start() + Fsm:__Engage( 2, AttackerDetection.Set ) -- Engage on the TargetSetUnit + + + self:SetDefenderTask( ClosestDefenderSquadronName, DefenderGCI, "GCI", Fsm, AttackerDetection ) - local Dispatcher = Fsm:GetDispatcher() -- #AI_A2A_DISPATCHER - local Squadron = Dispatcher:GetSquadronFromDefender( Defender ) - if Defender:IsAboveRunway() then - Dispatcher:RemoveDefenderFromSquadron( Squadron, Defender ) - Defender:Destroy() - end - end - - --- @param #AI_A2A_DISPATCHER self - function Fsm:onafterHome( Defender, From, Event, To, Action ) - self:F({"GCI 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() + function Fsm:onafterRTB( Defender, From, Event, To ) + self:F({"GCI RTB", Defender:GetName()}) + self:GetParent(self).onafterRTB( self, Defender, From, Event, To ) + + local Dispatcher = self:GetDispatcher() -- #AI_A2A_DISPATCHER + Dispatcher:ClearDefenderTaskTarget( Defender ) end - - if Dispatcher:GetSquadronLanding( Squadron.Name ) == AI_A2A_DISPATCHER.Landing.NearAirbase then - Dispatcher:RemoveDefenderFromSquadron( Squadron, Defender ) - Defender:Destroy() + + --- @param #AI_A2A_DISPATCHER self + function Fsm:onafterLostControl( Defender, From, Event, To ) + self:F({"GCI LostControl", Defender:GetName()}) + self:GetParent(self).onafterHome( self, Defender, From, Event, To ) + + local Dispatcher = Fsm:GetDispatcher() -- #AI_A2A_DISPATCHER + local Squadron = Dispatcher:GetSquadronFromDefender( Defender ) + if Defender:IsAboveRunway() then + Dispatcher:RemoveDefenderFromSquadron( Squadron, Defender ) + Defender:Destroy() + end end - end - end -- if DefenderGCI then - end -- while ( DefendersNeeded > 0 ) do + + --- @param #AI_A2A_DISPATCHER self + function Fsm:onafterHome( Defender, From, Event, To, Action ) + self:F({"GCI 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 -- if DefenderGCI then + end -- while ( DefendersNeeded > 0 ) do + end + else + -- No more resources, try something else. + -- Subject for a later enhancement to try to depart from another squadron and disable this one. + BreakLoop = true + break end else - -- No more resources, try something else. - -- Subject for a later enhancement to try to depart from another squadron and disable this one. - BreakLoop = true + -- There isn't any closest airbase anymore, break the loop. break end - else - -- There isn't any closest airbase anymore, break the loop. - break - end - end -- if DefenderSquadron then + end -- if DefenderSquadron then + end -- if AttackerUnit end diff --git a/Moose Development/Moose/AI/AI_A2A_Gci.lua b/Moose Development/Moose/AI/AI_A2A_Gci.lua index 3bdc0ebbb..5d0c415c7 100644 --- a/Moose Development/Moose/AI/AI_A2A_Gci.lua +++ b/Moose Development/Moose/AI/AI_A2A_Gci.lua @@ -360,14 +360,13 @@ function AI_A2A_GCI:onafterEngage( AIGroup, From, Event, To, AttackSetUnit ) local FirstAttackUnit = self.AttackSetUnit:GetFirst() - if FirstAttackUnit then + if FirstAttackUnit and FirstAttackUnit:IsAlive() then if AIGroup:IsAlive() then local EngageRoute = {} local CurrentCoord = AIGroup:GetCoordinate() - --- Calculate the target route point. diff --git a/Moose Development/Moose/Functional/Designate.lua b/Moose Development/Moose/Functional/Designate.lua index 78758e763..a70f12f7e 100644 --- a/Moose Development/Moose/Functional/Designate.lua +++ b/Moose Development/Moose/Functional/Designate.lua @@ -990,6 +990,8 @@ do -- DESIGNATE function DESIGNATE:onafterLaseOn( From, Event, To, Index, Duration, LaserCode ) self.Designating[Index] = "Laser" + self.LaseStart = timer.getTime() + self.LaseDuration = Duration self:__Lasing( -1, Index, Duration, LaserCode ) end @@ -1038,59 +1040,84 @@ do -- DESIGNATE end end + if self.AutoLase or ( not self.AutoLase and ( self.LaseStart + Duration >= timer.getTime() ) ) then - TargetSetUnit:ForEachUnitPerThreatLevel( 10, 0, - --- @param Wrapper.Unit#UNIT SmokeUnit - function( TargetUnit ) - - self:F( { TargetUnit = TargetUnit:GetName() } ) - - if MarkingCount < self.MaximumMarkings then - - if TargetUnit:IsAlive() then + TargetSetUnit:ForEachUnitPerThreatLevel( 10, 0, + --- @param Wrapper.Unit#UNIT SmokeUnit + function( TargetUnit ) + + self:F( { TargetUnit = TargetUnit:GetName() } ) - local Recce = self.Recces[TargetUnit] + if MarkingCount < self.MaximumMarkings then - if not Recce then - - self:E( "Lasing..." ) - self.RecceSet:Flush() - - for RecceGroupID, RecceGroup in pairs( self.RecceSet:GetSet() ) do - for UnitID, UnitData in pairs( RecceGroup:GetUnits() or {} ) do - - local RecceUnit = UnitData -- Wrapper.Unit#UNIT - local RecceUnitDesc = RecceUnit:GetDesc() - --self:F( { RecceUnit = RecceUnit:GetName(), RecceDescription = RecceUnitDesc } ) - - if RecceUnit:IsLasing() == false then - --self:F( { IsDetected = RecceUnit:IsDetected( TargetUnit ), IsLOS = RecceUnit:IsLOS( TargetUnit ) } ) - - if RecceUnit:IsDetected( TargetUnit ) and RecceUnit:IsLOS( TargetUnit ) then - - local LaserCodeIndex = math.random( 1, #self.LaserCodes ) - 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 - local Spot = RecceUnit:LaseUnit( TargetUnit, LaserCode, Duration ) - local AttackSet = self.AttackSet - - function Spot:OnAfterDestroyed( From, Event, To ) - self:E( "Destroyed Message" ) - self.Recce:ToSetGroup( "Target " .. TargetUnit:GetTypeName() .. " destroyed. " .. TargetSetUnit:Count() .. " targets left.", 5, AttackSet, self.DesignateName ) + if TargetUnit:IsAlive() then + + local Recce = self.Recces[TargetUnit] + + if not Recce then + + self:E( "Lasing..." ) + self.RecceSet:Flush() + + for RecceGroupID, RecceGroup in pairs( self.RecceSet:GetSet() ) do + for UnitID, UnitData in pairs( RecceGroup:GetUnits() or {} ) do + + local RecceUnit = UnitData -- Wrapper.Unit#UNIT + local RecceUnitDesc = RecceUnit:GetDesc() + --self:F( { RecceUnit = RecceUnit:GetName(), RecceDescription = RecceUnitDesc } ) + + if RecceUnit:IsLasing() == false then + --self:F( { IsDetected = RecceUnit:IsDetected( TargetUnit ), IsLOS = RecceUnit:IsLOS( TargetUnit ) } ) + + if RecceUnit:IsDetected( TargetUnit ) and RecceUnit:IsLOS( TargetUnit ) then + + local LaserCodeIndex = math.random( 1, #self.LaserCodes ) + local LaserCode = self.LaserCodes[LaserCodeIndex] + --self:F( { LaserCode = LaserCode, LaserCodeUsed = self.LaserCodesUsed[LaserCode] } ) + + if LaserCodeRequested and LaserCodeRequested ~= LaserCode then + LaserCode = LaserCodeRequested + LaserCodeRequested = nil end - - 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. + + if not self.LaserCodesUsed[LaserCode] then + + self.LaserCodesUsed[LaserCode] = LaserCodeIndex + local Spot = RecceUnit:LaseUnit( TargetUnit, LaserCode, Duration ) + local AttackSet = self.AttackSet + + function Spot:OnAfterDestroyed( From, Event, To ) + self:E( "Destroyed Message" ) + self.Recce:ToSetGroup( "Target " .. TargetUnit:GetTypeName() .. " destroyed. " .. TargetSetUnit:Count() .. " targets left.", 5, AttackSet, self.DesignateName ) + end + + 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. + MarkingCount = MarkingCount + 1 + local TargetUnitType = TargetUnit:GetTypeName() + if not MarkedTypes[TargetUnitType] then + MarkedTypes[TargetUnitType] = true + ReportTypes:Add(TargetUnitType) + end + ReportLaserCodes:Add(RecceUnit.LaserCode) + return + end + else + --RecceUnit:MessageToSetGroup( "Can't mark " .. TargetUnit:GetTypeName(), 5, self.AttackSet ) + end + else + -- The Recce is lasing, but the Target is not detected or within LOS. So stop lasing and send a report. + + if not RecceUnit:IsDetected( TargetUnit ) or not RecceUnit:IsLOS( TargetUnit ) then + + local Recce = self.Recces[TargetUnit] -- Wrapper.Unit#UNIT + + if Recce then + Recce:LaseOff() + Recce:MessageToSetGroup( "Target " .. TargetUnit:GetTypeName() "out of LOS. Cancelling lase!", 5, self.AttackSet, self.DesignateName ) + end + else MarkingCount = MarkingCount + 1 local TargetUnitType = TargetUnit:GetTypeName() if not MarkedTypes[TargetUnitType] then @@ -1098,59 +1125,39 @@ do -- DESIGNATE ReportTypes:Add(TargetUnitType) end ReportLaserCodes:Add(RecceUnit.LaserCode) - return - end - else - --RecceUnit:MessageToSetGroup( "Can't mark " .. TargetUnit:GetTypeName(), 5, self.AttackSet ) + end end - else - -- The Recce is lasing, but the Target is not detected or within LOS. So stop lasing and send a report. - - if not RecceUnit:IsDetected( TargetUnit ) or not RecceUnit:IsLOS( TargetUnit ) then - - local Recce = self.Recces[TargetUnit] -- Wrapper.Unit#UNIT - - if Recce then - Recce:LaseOff() - Recce:MessageToSetGroup( "Target " .. TargetUnit:GetTypeName() "out of LOS. Cancelling lase!", 5, self.AttackSet, self.DesignateName ) - end - else - MarkingCount = MarkingCount + 1 - local TargetUnitType = TargetUnit:GetTypeName() - if not MarkedTypes[TargetUnitType] then - MarkedTypes[TargetUnitType] = true - ReportTypes:Add(TargetUnitType) - end - ReportLaserCodes:Add(RecceUnit.LaserCode) - end end end + else + MarkingCount = MarkingCount + 1 + local TargetUnitType = TargetUnit:GetTypeName() + if not MarkedTypes[TargetUnitType] then + MarkedTypes[TargetUnitType] = true + ReportTypes:Add(TargetUnitType) + end + ReportLaserCodes:Add(Recce.LaserCode) + --Recce:MessageToSetGroup( self.DesignateName .. ": Marking " .. TargetUnit:GetTypeName() .. " with laser " .. Recce.LaserCode .. ".", 5, self.AttackSet ) end - else - MarkingCount = MarkingCount + 1 - local TargetUnitType = TargetUnit:GetTypeName() - if not MarkedTypes[TargetUnitType] then - MarkedTypes[TargetUnitType] = true - ReportTypes:Add(TargetUnitType) - end - ReportLaserCodes:Add(Recce.LaserCode) - --Recce:MessageToSetGroup( self.DesignateName .. ": Marking " .. TargetUnit:GetTypeName() .. " with laser " .. Recce.LaserCode .. ".", 5, self.AttackSet ) end end end + ) + + local MarkedTypesText = ReportTypes:Text(', ') + local MarkedLaserCodesText = ReportLaserCodes:Text(', ') + for MarkedType, MarketCount in pairs( MarkedTypes ) do + self.CC:GetPositionable():MessageToSetGroup( "Marking " .. MarkingCount .. " x " .. MarkedTypesText .. " with lasers " .. MarkedLaserCodesText .. ".", 5, self.AttackSet, self.DesignateName ) end - ) + + self:__Lasing( -30, Index, Duration, LaserCodeRequested ) + + self:SetDesignateMenu() - local MarkedTypesText = ReportTypes:Text(', ') - local MarkedLaserCodesText = ReportLaserCodes:Text(', ') - for MarkedType, MarketCount in pairs( MarkedTypes ) do - self.CC:GetPositionable():MessageToSetGroup( "Marking " .. MarkingCount .. " x " .. MarkedTypesText .. " with lasers " .. MarkedLaserCodesText .. ".", 5, self.AttackSet, self.DesignateName ) + else + self:__LaseOff( 1 ) end - self:__Lasing( -30, Index, Duration ) - - self:SetDesignateMenu() - end ---