From 6fe86678855a17314e6ad314fc38cf97752fccf7 Mon Sep 17 00:00:00 2001 From: FlightControl Date: Mon, 4 Mar 2019 20:27:40 +0100 Subject: [PATCH] Some important fixes that improves the routing of the engagements of aircraft. when ground forces move, the aircraft engaging will approach correctly. also added the squaddrons with resources in the tactical information panel. and for patrols, now the amount of resources are correctly calculated. --- Moose Development/Moose/AI/AI_A2G_BAI.lua | 83 +++++++---------- Moose Development/Moose/AI/AI_A2G_CAS.lua | 90 +++++++------------ .../Moose/AI/AI_A2G_Dispatcher.lua | 21 ++++- Moose Development/Moose/AI/AI_A2G_Engage.lua | 4 +- Moose Development/Moose/AI/AI_A2G_SEAD.lua | 84 ++++++++--------- 5 files changed, 123 insertions(+), 159 deletions(-) diff --git a/Moose Development/Moose/AI/AI_A2G_BAI.lua b/Moose Development/Moose/AI/AI_A2G_BAI.lua index 027474c2c..055994d6b 100644 --- a/Moose Development/Moose/AI/AI_A2G_BAI.lua +++ b/Moose Development/Moose/AI/AI_A2G_BAI.lua @@ -66,9 +66,7 @@ function AI_A2G_BAI:onafterEngage( DefenderGroup, From, Event, To, AttackSetUnit local DefenderGroupName = DefenderGroup:GetName() - self.AttackSetUnit = AttackSetUnit or self.AttackSetUnit -- Core.Set#SET_UNIT - - local AttackCount = self.AttackSetUnit:Count() + local AttackCount = AttackSetUnit:Count() if AttackCount > 0 then @@ -84,12 +82,14 @@ function AI_A2G_BAI:onafterEngage( DefenderGroup, From, Event, To, AttackSetUnit local DefenderCoord = DefenderGroup:GetPointVec3() DefenderCoord:SetY( EngageAltitude ) -- Ground targets don't have an altitude. - local TargetCoord = self.AttackSetUnit:GetFirst():GetPointVec3() + local TargetCoord = AttackSetUnit:GetFirst():GetPointVec3() TargetCoord:SetY( EngageAltitude ) -- Ground targets don't have an altitude. local TargetDistance = DefenderCoord:Get2DDistance( TargetCoord ) + local EngageDistance = ( DefenderGroup:IsHelicopter() and 5000 ) or ( DefenderGroup:IsAirPlane() and 10000 ) local EngageRoute = {} + local AttackTasks = {} --- Calculate the target route point. @@ -105,64 +105,47 @@ function AI_A2G_BAI:onafterEngage( DefenderGroup, From, Event, To, AttackSetUnit self:SetTargetDistance( TargetCoord ) -- For RTB status check - local FromEngageAngle = TargetCoord:GetAngleDegrees( TargetCoord:GetDirectionVec3( DefenderCoord ) ) - local EngageDistance = ( DefenderGroup:IsHelicopter() and 5000 ) or ( DefenderGroup:IsAirPlane() and 10000 ) - - --- Create a route point of type air. - local ToWP = TargetCoord:Translate( EngageDistance, FromEngageAngle ):WaypointAir( + local FromEngageAngle = DefenderCoord:GetAngleDegrees( DefenderCoord:GetDirectionVec3( TargetCoord ) ) + local ToWP = DefenderCoord:Translate( EngageDistance, FromEngageAngle, true ):WaypointAir( self.PatrolAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, EngageSpeed, true ) - - EngageRoute[#EngageRoute+1] = ToWP - - local AttackTasks = {} - - self.AttackSetUnit.AttackIndex = self.AttackSetUnit.AttackIndex and self.AttackSetUnit.AttackIndex + 1 or 1 - - local AttackSetUnitPerThreatLevel = self.AttackSetUnit:GetSetPerThreatLevel( 10, 0 ) - - local AttackUnit = AttackSetUnitPerThreatLevel[self.AttackSetUnit.AttackIndex] - - local AttackUnitTasks = {} --- if not AttackUnit then --- self.AttackSetUnit.AttackIndex = 1 --- AttackUnit = AttackSetUnitPerThreatLevel[self.AttackSetUnit.AttackIndex] --- end --- if AttackUnit then --- if AttackUnit:IsAlive() and AttackUnit:IsGround() then --- self:T( { "BAI Unit:", AttackUnit:GetName() } ) --- AttackUnitTasks[#AttackUnitTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit, false, false, nil, nil, EngageAltitude ) --- end --- end - - for AttackUnitIndex, AttackUnit in ipairs( AttackSetUnitPerThreatLevel or {} ) do - if AttackUnit then - if AttackUnit:IsAlive() and AttackUnit:IsGround() then - self:T( { "BAI Unit:", AttackUnit:GetName() } ) - AttackUnitTasks[#AttackUnitTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit, true, false, nil, nil, EngageAltitude ) + EngageRoute[#EngageRoute+1] = ToWP + + if TargetDistance <= EngageDistance * 3 then + + local AttackUnitTasks = {} + + local AttackSetUnitPerThreatLevel = AttackSetUnit:GetSetPerThreatLevel( 10, 0 ) + for AttackUnitIndex, AttackUnit in ipairs( AttackSetUnitPerThreatLevel or {} ) do + if AttackUnit then + if AttackUnit:IsAlive() and AttackUnit:IsGround() then + self:T( { "BAI Unit:", AttackUnit:GetName() } ) + AttackUnitTasks[#AttackUnitTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit, true, false, nil, nil, EngageAltitude ) + end end end - end - - if #AttackUnitTasks == 0 then - self:E( DefenderGroupName .. ": No targets found -> Going RTB") - self:Return() - self:__RTB( self.TaskDelay ) - else - DefenderGroup:OptionROEOpenFire() - DefenderGroup:OptionROTEvadeFire() - DefenderGroup:OptionKeepWeaponsOnThreat() + if #AttackUnitTasks == 0 then + self:E( DefenderGroupName .. ": No targets found -> Going RTB") + self:Return() + self:__RTB( self.TaskDelay ) + else + DefenderGroup:OptionROEOpenFire() + DefenderGroup:OptionROTEvadeFire() + DefenderGroup:OptionKeepWeaponsOnThreat() + + AttackTasks[#AttackTasks+1] = DefenderGroup:TaskCombo( AttackUnitTasks ) + end - AttackTasks[#AttackTasks+1] = DefenderGroup:TaskCombo( AttackUnitTasks ) - AttackTasks[#AttackTasks+1] = DefenderGroup:TaskFunction( "AI_A2G_ENGAGE.EngageRoute", self ) - EngageRoute[#EngageRoute].task = DefenderGroup:TaskCombo( AttackTasks ) end + + AttackTasks[#AttackTasks+1] = DefenderGroup:TaskFunction( "AI_A2G_ENGAGE.EngageRoute", self, AttackSetUnit ) + EngageRoute[#EngageRoute].task = DefenderGroup:TaskCombo( AttackTasks ) DefenderGroup:Route( EngageRoute, self.TaskDelay ) end diff --git a/Moose Development/Moose/AI/AI_A2G_CAS.lua b/Moose Development/Moose/AI/AI_A2G_CAS.lua index 221341608..1978803d0 100644 --- a/Moose Development/Moose/AI/AI_A2G_CAS.lua +++ b/Moose Development/Moose/AI/AI_A2G_CAS.lua @@ -66,9 +66,7 @@ function AI_A2G_CAS:onafterEngage( DefenderGroup, From, Event, To, AttackSetUnit local DefenderGroupName = DefenderGroup:GetName() - self.AttackSetUnit = AttackSetUnit or self.AttackSetUnit -- Core.Set#SET_UNIT - - local AttackCount = self.AttackSetUnit:Count() + local AttackCount = AttackSetUnit:Count() if AttackCount > 0 then @@ -80,14 +78,14 @@ function AI_A2G_CAS:onafterEngage( DefenderGroup, From, Event, To, AttackSetUnit local DefenderCoord = DefenderGroup:GetPointVec3() DefenderCoord:SetY( EngageAltitude ) -- Ground targets don't have an altitude. - local TargetCoord = self.AttackSetUnit:GetFirst():GetPointVec3() + local TargetCoord = AttackSetUnit:GetFirst():GetPointVec3() TargetCoord:SetY( EngageAltitude ) -- Ground targets don't have an altitude. local TargetDistance = DefenderCoord:Get2DDistance( TargetCoord ) + local EngageDistance = ( DefenderGroup:IsHelicopter() and 5000 ) or ( DefenderGroup:IsAirPlane() and 10000 ) local EngageRoute = {} - - --- Calculate the target route point. + local AttackTasks = {} local FromWP = DefenderCoord:WaypointAir( self.PatrolAltType or "RADIO", @@ -96,70 +94,50 @@ function AI_A2G_CAS:onafterEngage( DefenderGroup, From, Event, To, AttackSetUnit EngageSpeed, true ) - EngageRoute[#EngageRoute+1] = FromWP self:SetTargetDistance( TargetCoord ) -- For RTB status check - - local FromEngageAngle = TargetCoord:GetAngleDegrees( TargetCoord:GetDirectionVec3( DefenderCoord ) ) - local EngageDistance = ( DefenderGroup:IsHelicopter() and 5000 ) or ( DefenderGroup:IsAirPlane() and 10000 ) - - --- Create a route point of type air. - local ToWP = TargetCoord:Translate( EngageDistance, FromEngageAngle, true ):WaypointAir( + + local FromEngageAngle = DefenderCoord:GetAngleDegrees( DefenderCoord:GetDirectionVec3( TargetCoord ) ) + local ToWP = DefenderCoord:Translate( EngageDistance, FromEngageAngle, true ):WaypointAir( self.PatrolAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, EngageSpeed, true ) - EngageRoute[#EngageRoute+1] = ToWP - - local AttackTasks = {} - - self.AttackSetUnit.AttackIndex = self.AttackSetUnit.AttackIndex and self.AttackSetUnit.AttackIndex + 1 or 1 - - local AttackSetUnitPerThreatLevel = self.AttackSetUnit:GetSetPerThreatLevel( 10, 0 ) - - --local AttackUnit = AttackSetUnitPerThreatLevel[self.AttackSetUnit.AttackIndex] - - local AttackUnitTasks = {} - --- if not AttackUnit then --- self.AttackSetUnit.AttackIndex = 1 --- AttackUnit = AttackSetUnitPerThreatLevel[self.AttackSetUnit.AttackIndex] --- end --- --- if AttackUnit then --- if AttackUnit:IsAlive() and AttackUnit:IsGround() then --- self:F( { "CAS Unit:", AttackUnit:GetName() } ) --- AttackTasks[#AttackTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit, false, false, nil, nil, EngageAltitude ) --- end --- end - for AttackUnitIndex, AttackUnit in ipairs( AttackSetUnitPerThreatLevel or {} ) do - if AttackUnit then - if AttackUnit:IsAlive() and AttackUnit:IsGround() then - self:T( { "CAS Unit:", AttackUnit:GetName() } ) - AttackUnitTasks[#AttackUnitTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit, true, false, nil, nil, EngageAltitude ) + if TargetDistance <= EngageDistance * 3 then + + local AttackUnitTasks = {} + + local AttackSetUnitPerThreatLevel = AttackSetUnit:GetSetPerThreatLevel( 10, 0 ) + for AttackUnitIndex, AttackUnit in ipairs( AttackSetUnitPerThreatLevel or {} ) do + if AttackUnit then + if AttackUnit:IsAlive() and AttackUnit:IsGround() then + self:T( { "CAS Unit:", AttackUnit:GetName() } ) + AttackUnitTasks[#AttackUnitTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit, true, false, nil, nil, EngageAltitude ) + end end end + + + if #AttackUnitTasks == 0 then + self:E( DefenderGroupName .. ": No targets found -> Going RTB") + self:Return() + self:__RTB( self.TaskDelay ) + else + DefenderGroup:OptionROEOpenFire() + DefenderGroup:OptionROTEvadeFire() + DefenderGroup:OptionKeepWeaponsOnThreat() + + AttackTasks[#AttackTasks+1] = DefenderGroup:TaskCombo( AttackUnitTasks ) + end end - - - if #AttackUnitTasks == 0 then - self:E( DefenderGroupName .. ": No targets found -> Going RTB") - self:Return() - self:__RTB( self.TaskDelay ) - else - DefenderGroup:OptionROEOpenFire() - DefenderGroup:OptionROTEvadeFire() - DefenderGroup:OptionKeepWeaponsOnThreat() - - AttackTasks[#AttackTasks+1] = DefenderGroup:TaskCombo( AttackUnitTasks ) - AttackTasks[#AttackTasks+1] = DefenderGroup:TaskFunction( "AI_A2G_ENGAGE.EngageRoute", self ) - EngageRoute[#EngageRoute].task = DefenderGroup:TaskCombo( AttackTasks ) - end + + AttackTasks[#AttackTasks+1] = DefenderGroup:TaskFunction( "AI_A2G_ENGAGE.EngageRoute", self, AttackSetUnit ) + EngageRoute[#EngageRoute].task = DefenderGroup:TaskCombo( AttackTasks ) DefenderGroup:Route( EngageRoute, self.TaskDelay ) end diff --git a/Moose Development/Moose/AI/AI_A2G_Dispatcher.lua b/Moose Development/Moose/AI/AI_A2G_Dispatcher.lua index abbfd61ff..5d32f9354 100644 --- a/Moose Development/Moose/AI/AI_A2G_Dispatcher.lua +++ b/Moose Development/Moose/AI/AI_A2G_Dispatcher.lua @@ -3351,8 +3351,20 @@ do -- AI_A2G_DISPATCHER local DefenderSquadron, Patrol = self:CanPatrol( SquadronName, DefenseTaskType ) + -- Determine if there are sufficient resources to form a complete group for patrol. + local DefendersNeeded + if DefenderSquadron.ResourceCount == nil then + DefendersNeeded = DefenderSquadron.Grouping + else + if DefenderSquadron.ResourceCount >= DefenderSquadron.Grouping then + DefendersNeeded = DefenderSquadron.Grouping + else + DefendersNeeded = DefenderSquadron.ResourceCount + end + end + if Patrol then - self:ResourceQueue( true, DefenderSquadron, nil, Patrol, DefenseTaskType, nil, SquadronName ) + self:ResourceQueue( true, DefenderSquadron, DefendersNeeded, Patrol, DefenseTaskType, nil, SquadronName ) end end @@ -3654,7 +3666,7 @@ do -- AI_A2G_DISPATCHER local x = CheckAttackCoordinate.x local y = CheckAttackCoordinate.z - local r = 8000 + local r = 5000 -- now we check if the coordinate is intersecting with the defense line. @@ -4098,6 +4110,11 @@ do -- AI_A2G_DISPATCHER Report:Add( string.format( " - %s - %s", DefenseQueueItem.SquadronName, DefenseQueueItem.DefenderSquadron.TakeoffTime, DefenseQueueItem.DefenderSquadron.TakeoffInterval) ) end + + Report:Add( string.format( "\n - Squadron Resources: ", #self.DefenseQueue ) ) + for DefenderSquadronName, DefenderSquadron in pairs( self.DefenderSquadrons ) do + Report:Add( string.format( " - %s - %d", DefenderSquadronName, DefenderSquadron.ResourceCount and DefenderSquadron.ResourceCount or "n/a" ) ) + end self:F( Report:Text( "\n" ) ) trigger.action.outText( Report:Text( "\n" ), 25 ) diff --git a/Moose Development/Moose/AI/AI_A2G_Engage.lua b/Moose Development/Moose/AI/AI_A2G_Engage.lua index b71da1dce..0035ed3ef 100644 --- a/Moose Development/Moose/AI/AI_A2G_Engage.lua +++ b/Moose Development/Moose/AI/AI_A2G_Engage.lua @@ -293,12 +293,12 @@ end -- todo: need to fix this global function --- @param Wrapper.Group#GROUP AIControllable -function AI_A2G_ENGAGE.EngageRoute( AIGroup, Fsm ) +function AI_A2G_ENGAGE.EngageRoute( AIGroup, Fsm, AttackSetUnit ) AIGroup:I( { "AI_A2G_ENGAGE.EngageRoute:", AIGroup:GetName() } ) if AIGroup:IsAlive() then - Fsm:__Engage( Fsm.TaskDelay ) + Fsm:__Engage( Fsm.TaskDelay, AttackSetUnit ) --local Task = AIGroup:TaskOrbitCircle( 4000, 400 ) --AIGroup:SetTask( Task ) diff --git a/Moose Development/Moose/AI/AI_A2G_SEAD.lua b/Moose Development/Moose/AI/AI_A2G_SEAD.lua index 77a69ca10..f5d73a217 100644 --- a/Moose Development/Moose/AI/AI_A2G_SEAD.lua +++ b/Moose Development/Moose/AI/AI_A2G_SEAD.lua @@ -117,9 +117,7 @@ function AI_A2G_SEAD:onafterEngage( DefenderGroup, From, Event, To, AttackSetUni local DefenderGroupName = DefenderGroup:GetName() - self.AttackSetUnit = AttackSetUnit or self.AttackSetUnit -- Core.Set#SET_UNIT - - local AttackCount = self.AttackSetUnit:Count() + local AttackCount = AttackSetUnit:Count() if AttackCount > 0 then @@ -135,15 +133,14 @@ function AI_A2G_SEAD:onafterEngage( DefenderGroup, From, Event, To, AttackSetUni local DefenderCoord = DefenderGroup:GetPointVec3() DefenderCoord:SetY( EngageAltitude ) -- Ground targets don't have an altitude. - local TargetCoord = self.AttackSetUnit:GetFirst():GetPointVec3() + local TargetCoord = AttackSetUnit:GetFirst():GetPointVec3() TargetCoord:SetY( EngageAltitude ) -- Ground targets don't have an altitude. local TargetDistance = DefenderCoord:Get2DDistance( TargetCoord ) - - local EngageRoute = {} + local EngageDistance = ( DefenderGroup:IsHelicopter() and 5000 ) or ( DefenderGroup:IsAirPlane() and 25000 ) - - --- Calculate the target route point. + local EngageRoute = {} + local AttackTasks = {} local FromWP = DefenderCoord:WaypointAir( self.PatrolAltType or "RADIO", @@ -152,66 +149,55 @@ function AI_A2G_SEAD:onafterEngage( DefenderGroup, From, Event, To, AttackSetUni EngageSpeed, false ) - EngageRoute[#EngageRoute+1] = FromWP self:SetTargetDistance( TargetCoord ) -- For RTB status check - - local FromEngageAngle = TargetCoord:GetAngleDegrees( TargetCoord:GetDirectionVec3( DefenderCoord ) ) - local EngageDistance = ( DefenderGroup:IsHelicopter() and 5000 ) or ( DefenderGroup:IsAirPlane() and 25000 ) - --- Create a route point of type air, 50km from the center of the attack point. - - local ToWP = TargetCoord:Translate( EngageDistance, FromEngageAngle, true ):WaypointAir( + local FromEngageAngle = DefenderCoord:GetAngleDegrees( DefenderCoord:GetDirectionVec3( TargetCoord ) ) + local ToWP = DefenderCoord:Translate( EngageDistance, FromEngageAngle, true ):WaypointAir( self.PatrolAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, EngageSpeed, true ) - EngageRoute[#EngageRoute+1] = ToWP - - local AttackTasks = {} --- self.AttackSetUnit.AttackIndex = self.AttackSetUnit.AttackIndex and self.AttackSetUnit.AttackIndex + 1 or 1 --- if self.AttackSetUnit.AttackIndex > self.AttackSetUnit:Count() then --- self.AttackSetUnit.AttackIndex = 1 --- end --- - local AttackSetUnitPerThreatLevel = self.AttackSetUnit:GetSetPerThreatLevel( 10, 0 ) - - local AttackUnitTasks = {} - - for AttackUnitID, AttackUnit in ipairs( AttackSetUnitPerThreatLevel ) do - if AttackUnit then - if AttackUnit:IsAlive() and AttackUnit:IsGround() then - local HasRadar = AttackUnit:HasSEAD() - if HasRadar then - self:F( { "SEAD Unit:", AttackUnit:GetName() } ) - AttackUnitTasks[#AttackUnitTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit, true, false, nil, nil, EngageAltitude ) + if TargetDistance <= EngageDistance * 3 then + + local AttackUnitTasks = {} + + local AttackSetUnitPerThreatLevel = AttackSetUnit:GetSetPerThreatLevel( 10, 0 ) + for AttackUnitID, AttackUnit in ipairs( AttackSetUnitPerThreatLevel ) do + if AttackUnit then + if AttackUnit:IsAlive() and AttackUnit:IsGround() then + local HasRadar = AttackUnit:HasSEAD() + if HasRadar then + self:F( { "SEAD Unit:", AttackUnit:GetName() } ) + AttackUnitTasks[#AttackUnitTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit, true, false, nil, nil, EngageAltitude ) + end end end end + + if #AttackUnitTasks == 0 then + self:E( DefenderGroupName .. ": No targets found -> Going RTB") + self:Return() + self:__RTB( self.TaskDelay ) + else + DefenderGroup:OptionROEOpenFire() + DefenderGroup:OptionROTVertical() + DefenderGroup:OptionKeepWeaponsOnThreat() + --DefenderGroup:OptionRTBAmmo( Weapon.flag.AnyASM ) + + AttackTasks[#AttackTasks+1] = DefenderGroup:TaskCombo( AttackUnitTasks ) + end end - - if #AttackUnitTasks == 0 then - self:E( DefenderGroupName .. ": No targets found -> Going RTB") - self:Return() - self:__RTB( self.TaskDelay ) - else - DefenderGroup:OptionROEOpenFire() - DefenderGroup:OptionROTVertical() - DefenderGroup:OptionKeepWeaponsOnThreat() - --DefenderGroup:OptionRTBAmmo( Weapon.flag.AnyASM ) - AttackTasks[#AttackTasks+1] = DefenderGroup:TaskCombo( AttackUnitTasks ) - AttackTasks[#AttackTasks+1] = DefenderGroup:TaskFunction( "AI_A2G_ENGAGE.EngageRoute", self ) - EngageRoute[#EngageRoute].task = DefenderGroup:TaskCombo( AttackTasks ) - end + AttackTasks[#AttackTasks+1] = DefenderGroup:TaskFunction( "AI_A2G_ENGAGE.EngageRoute", self, AttackSetUnit ) + EngageRoute[#EngageRoute].task = DefenderGroup:TaskCombo( AttackTasks ) DefenderGroup:Route( EngageRoute, self.TaskDelay ) - end else self:E( DefenderGroupName .. ": No targets found -> Going RTB")