mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
These changes will blast the hell out of A2G... this is going to be great.
This commit is contained in:
parent
d4510af249
commit
6f13aa2c5b
@ -144,7 +144,7 @@ function AI_A2G_BAI:onafterEngage( DefenderGroup, From, Event, To, AttackSetUnit
|
||||
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 )
|
||||
AttackUnitTasks[#AttackUnitTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit, true, false, nil, nil, EngageAltitude )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -141,7 +141,7 @@ function AI_A2G_CAS:onafterEngage( DefenderGroup, From, Event, To, AttackSetUnit
|
||||
if AttackUnit then
|
||||
if AttackUnit:IsAlive() and AttackUnit:IsGround() then
|
||||
self:T( { "CAS Unit:", AttackUnit:GetName() } )
|
||||
AttackUnitTasks[#AttackUnitTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit, false, false, nil, nil, EngageAltitude )
|
||||
AttackUnitTasks[#AttackUnitTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit, true, false, nil, nil, EngageAltitude )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -3169,14 +3169,13 @@ do -- AI_A2G_DISPATCHER
|
||||
|
||||
---
|
||||
-- @param #AI_A2G_DISPATCHER self
|
||||
function AI_A2G_DISPATCHER:CountDefendersEngaged( AttackerDetection )
|
||||
function AI_A2G_DISPATCHER:CountDefendersEngaged( AttackerDetection, AttackerCount )
|
||||
|
||||
-- First, count the active AIGroups Units, targetting the DetectedSet
|
||||
local DefendersEngaged = 0
|
||||
local DefendersTotal = 0
|
||||
|
||||
local AttackerSet = AttackerDetection.Set
|
||||
local AttackerCount = AttackerSet:Count()
|
||||
local DefendersMissing = AttackerCount
|
||||
--DetectedSet:Flush()
|
||||
|
||||
@ -3628,13 +3627,64 @@ do -- AI_A2G_DISPATCHER
|
||||
|
||||
---
|
||||
-- @param #AI_A2G_DISPATCHER self
|
||||
function AI_A2G_DISPATCHER:onafterDefend( From, Event, To, AttackerDetection, DefendersTotal, DefendersEngaged, DefendersMissing, DefenderFriendlies, DefenseTaskType )
|
||||
function AI_A2G_DISPATCHER:HasDefenseLine( DefenseCoordinate, DetectedItem )
|
||||
|
||||
self:F( { From, Event, To, AttackerDetection.Index, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing, DefenderFriendlies = DefenderFriendlies } )
|
||||
local AttackCoordinate = self.Detection:GetDetectedItemCoordinate( DetectedItem )
|
||||
local EvaluateDistance = AttackCoordinate:Get2DDistance( DefenseCoordinate )
|
||||
|
||||
AttackerDetection.Type = DefenseTaskType -- This is set to report the task type in the status panel.
|
||||
-- Now check if this coordinate is not in a danger zone, meaning, that the attack line is not crossing other coordinates.
|
||||
-- (y1 – y2)x + (x2 – x1)y + (x1y2 – x2y1) = 0
|
||||
|
||||
local c1 = DefenseCoordinate
|
||||
local c2 = AttackCoordinate
|
||||
|
||||
local a = c1.z - c2.z -- Calculate a
|
||||
local b = c2.x - c1.x -- Calculate b
|
||||
local c = c1.x * c2.z - c2.x * c1.z -- calculate c
|
||||
|
||||
local ok = true
|
||||
|
||||
-- Now we check if each coordinate radius of about 30km of each attack is crossing a defense line. If yes, then this is not a good attack!
|
||||
for AttackItemID, CheckAttackItem in pairs( self.Detection:GetDetectedItems() ) do
|
||||
|
||||
-- Only compare other detected coordinates.
|
||||
if AttackItemID ~= DetectedItem.ID then
|
||||
|
||||
local CheckAttackCoordinate = self.Detection:GetDetectedItemCoordinate( CheckAttackItem )
|
||||
|
||||
local x = CheckAttackCoordinate.x
|
||||
local y = CheckAttackCoordinate.z
|
||||
local r = 8000
|
||||
|
||||
-- now we check if the coordinate is intersecting with the defense line.
|
||||
|
||||
local IntersectDistance = ( math.abs( a * x + b * y + c ) ) / math.sqrt( a * a + b * b )
|
||||
self:F( { IntersectDistance = IntersectDistance, x = x, y = y } )
|
||||
|
||||
local IntersectAttackDistance = CheckAttackCoordinate:Get2DDistance( DefenseCoordinate )
|
||||
|
||||
self:F( { IntersectAttackDistance=IntersectAttackDistance, EvaluateDistance=EvaluateDistance } )
|
||||
|
||||
-- If the distance of the attack coordinate is larger than the test radius; then the line intersects, and this is not a good coordinate.
|
||||
if IntersectDistance < r and IntersectAttackDistance < EvaluateDistance then
|
||||
ok = false
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return ok
|
||||
end
|
||||
|
||||
local AttackerSet = AttackerDetection.Set
|
||||
---
|
||||
-- @param #AI_A2G_DISPATCHER self
|
||||
function AI_A2G_DISPATCHER:onafterDefend( From, Event, To, DetectedItem, DefendersTotal, DefendersEngaged, DefendersMissing, DefenderFriendlies, DefenseTaskType )
|
||||
|
||||
self:F( { From, Event, To, DetectedItem.Index, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing, DefenderFriendlies = DefenderFriendlies } )
|
||||
|
||||
DetectedItem.Type = DefenseTaskType -- This is set to report the task type in the status panel.
|
||||
|
||||
local AttackerSet = DetectedItem.Set
|
||||
local AttackerUnit = AttackerSet:GetFirst()
|
||||
|
||||
if AttackerUnit and AttackerUnit:IsAlive() then
|
||||
@ -3642,18 +3692,25 @@ do -- AI_A2G_DISPATCHER
|
||||
local DefenderCount = 0
|
||||
|
||||
for DefenderID, DefenderGroup in pairs( DefenderFriendlies or {} ) do
|
||||
|
||||
local SquadronName = self:GetDefenderTask( DefenderGroup ).SquadronName
|
||||
local SquadronOverhead = self:GetSquadronOverhead( SquadronName )
|
||||
|
||||
local Fsm = self:GetDefenderTaskFsm( DefenderGroup )
|
||||
Fsm:Engage( AttackerSet ) -- Engage on the TargetSetUnit
|
||||
|
||||
self:SetDefenderTaskTarget( DefenderGroup, AttackerDetection )
|
||||
-- Here we check if the defenders have a defense line to the attackers.
|
||||
-- If the attackers are behind enemy lines or too close to an other defense line; then don´t engage.
|
||||
local DefenseCoordinate = DefenderGroup:GetCoordinate()
|
||||
local HasDefenseLine = self:HasDefenseLine( DefenseCoordinate, DetectedItem )
|
||||
|
||||
local DefenderGroupSize = DefenderGroup:GetSize()
|
||||
DefendersMissing = DefendersMissing - DefenderGroupSize / SquadronOverhead
|
||||
DefendersTotal = DefendersTotal + DefenderGroupSize / SquadronOverhead
|
||||
if HasDefenseLine == true then
|
||||
local SquadronName = self:GetDefenderTask( DefenderGroup ).SquadronName
|
||||
local SquadronOverhead = self:GetSquadronOverhead( SquadronName )
|
||||
|
||||
local Fsm = self:GetDefenderTaskFsm( DefenderGroup )
|
||||
Fsm:Engage( AttackerSet ) -- Engage on the TargetSetUnit
|
||||
|
||||
self:SetDefenderTaskTarget( DefenderGroup, DetectedItem )
|
||||
|
||||
local DefenderGroupSize = DefenderGroup:GetSize()
|
||||
DefendersMissing = DefendersMissing - DefenderGroupSize / SquadronOverhead
|
||||
DefendersTotal = DefendersTotal + DefenderGroupSize / SquadronOverhead
|
||||
end
|
||||
|
||||
if DefendersMissing <= 0 then
|
||||
break
|
||||
@ -3676,21 +3733,26 @@ do -- AI_A2G_DISPATCHER
|
||||
|
||||
if DefenderSquadron[DefenseTaskType] then
|
||||
|
||||
local SpawnCoord = DefenderSquadron.Airbase:GetCoordinate() -- Core.Point#COORDINATE
|
||||
local AirbaseCoordinate = DefenderSquadron.Airbase:GetCoordinate() -- Core.Point#COORDINATE
|
||||
local AttackerCoord = AttackerUnit:GetCoordinate()
|
||||
local InterceptCoord = AttackerDetection.InterceptCoord
|
||||
local InterceptCoord = DetectedItem.InterceptCoord
|
||||
self:F( { InterceptCoord = InterceptCoord } )
|
||||
if InterceptCoord then
|
||||
local InterceptDistance = SpawnCoord:Get2DDistance( InterceptCoord )
|
||||
local AirbaseDistance = SpawnCoord:Get2DDistance( AttackerCoord )
|
||||
local InterceptDistance = AirbaseCoordinate:Get2DDistance( InterceptCoord )
|
||||
local AirbaseDistance = AirbaseCoordinate:Get2DDistance( AttackerCoord )
|
||||
self:F( { InterceptDistance = InterceptDistance, AirbaseDistance = AirbaseDistance, InterceptCoord = InterceptCoord } )
|
||||
|
||||
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.DefenseRadius then
|
||||
ClosestDistance = InterceptDistance
|
||||
ClosestDefenderSquadronName = SquadronName
|
||||
|
||||
-- Check if there is a defense line...
|
||||
local HasDefenseLine = self:HasDefenseLine( AirbaseCoordinate, DetectedItem )
|
||||
if HasDefenseLine == true then
|
||||
ClosestDistance = InterceptDistance
|
||||
ClosestDefenderSquadronName = SquadronName
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -3735,7 +3797,7 @@ do -- AI_A2G_DISPATCHER
|
||||
end
|
||||
|
||||
while ( DefendersNeeded > 0 ) do
|
||||
self:ResourceQueue( false, DefenderSquadron, DefendersNeeded, Defense, DefenseTaskType, AttackerDetection, ClosestDefenderSquadronName )
|
||||
self:ResourceQueue( false, DefenderSquadron, DefendersNeeded, Defense, DefenseTaskType, DetectedItem, ClosestDefenderSquadronName )
|
||||
DefendersNeeded = DefendersNeeded - DefenderGrouping
|
||||
DefenderCount = DefenderCount - DefenderGrouping / DefenderOverhead
|
||||
end -- while ( DefendersNeeded > 0 ) do
|
||||
@ -3764,13 +3826,12 @@ do -- AI_A2G_DISPATCHER
|
||||
self:F( { DetectedItem.ItemID } )
|
||||
|
||||
local AttackerSet = DetectedItem.Set -- Core.Set#SET_UNIT
|
||||
local AttackerCount = AttackerSet:Count()
|
||||
local IsSEAD = AttackerSet:HasSEAD() -- Is the AttackerSet a SEAD group?
|
||||
local AttackerCount = AttackerSet:HasSEAD() -- Is the AttackerSet a SEAD group, then the amount of radar emitters will be returned; that need to be attacked.
|
||||
|
||||
if ( IsSEAD > 0 ) then
|
||||
if ( AttackerCount > 0 ) then
|
||||
|
||||
-- First, count the active defenders, engaging the DetectedItem.
|
||||
local DefendersTotal, DefendersEngaged, DefendersMissing = self:CountDefendersEngaged( DetectedItem )
|
||||
local DefendersTotal, DefendersEngaged, DefendersMissing = self:CountDefendersEngaged( DetectedItem, AttackerCount )
|
||||
|
||||
self:F( { AttackerCount = AttackerCount, DefendersTotal = DefendersTotal, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing } )
|
||||
|
||||
@ -3805,7 +3866,7 @@ do -- AI_A2G_DISPATCHER
|
||||
if IsCas == true then
|
||||
|
||||
-- First, count the active defenders, engaging the DetectedItem.
|
||||
local DefendersTotal, DefendersEngaged, DefendersMissing = self:CountDefendersEngaged( DetectedItem )
|
||||
local DefendersTotal, DefendersEngaged, DefendersMissing = self:CountDefendersEngaged( DetectedItem, AttackerCount )
|
||||
|
||||
self:F( { AttackerCount = AttackerCount, DefendersTotal = DefendersTotal, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing } )
|
||||
|
||||
@ -3838,7 +3899,7 @@ do -- AI_A2G_DISPATCHER
|
||||
if IsBai == true then
|
||||
|
||||
-- First, count the active defenders, engaging the DetectedItem.
|
||||
local DefendersTotal, DefendersEngaged, DefendersMissing = self:CountDefendersEngaged( DetectedItem )
|
||||
local DefendersTotal, DefendersEngaged, DefendersMissing = self:CountDefendersEngaged( DetectedItem, AttackerCount )
|
||||
|
||||
self:F( { AttackerCount = AttackerCount, DefendersTotal = DefendersTotal, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing } )
|
||||
|
||||
@ -3854,6 +3915,8 @@ do -- AI_A2G_DISPATCHER
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--- Assigns A2G AI Tasks in relation to the detected items.
|
||||
-- @param #AI_A2G_DISPATCHER self
|
||||
-- @param Functional.Detection#DETECTION_BASE Detection The detection created by the @{Functional.Detection#DETECTION_BASE} derived object.
|
||||
@ -3900,7 +3963,6 @@ do -- AI_A2G_DISPATCHER
|
||||
local Report = REPORT:New( "\nTactical Overview" )
|
||||
|
||||
local DefenderGroupCount = 0
|
||||
local Delay = 0 -- We need to implement a delay for each action because the spawning on airbases get confused if done too quick.
|
||||
|
||||
local DefendersTotal = 0
|
||||
|
||||
@ -3940,52 +4002,8 @@ do -- AI_A2G_DISPATCHER
|
||||
self:F( { DistanceProbability = DistanceProbability, DefenseProbability = DefenseProbability } )
|
||||
|
||||
if DefenseProbability <= DistanceProbability / ( 300 / 30 ) then
|
||||
|
||||
-- Now check if this coordinate is not in a danger zone, meaning, that the attack line is not crossing other coordinates.
|
||||
-- (y1 – y2)x + (x2 – x1)y + (x1y2 – x2y1) = 0
|
||||
|
||||
local c1 = DefenseCoordinate
|
||||
local c2 = AttackCoordinate
|
||||
|
||||
local a = c1.z - c2.z -- Calculate a
|
||||
local b = c2.x - c1.x -- Calculate b
|
||||
local c = c1.x * c2.z - c2.x * c1.z -- calculate c
|
||||
|
||||
local ok = true
|
||||
|
||||
-- Now we check if each coordinate radius of about 30km of each attack is crossing a defense line. If yes, then this is not a good attack!
|
||||
for AttackItemID, CheckAttackItem in pairs( Detection:GetDetectedItems() ) do
|
||||
|
||||
-- Only compare other detected coordinates.
|
||||
if AttackItemID ~= DetectedItemID then
|
||||
|
||||
local CheckAttackCoordinate = self.Detection:GetDetectedItemCoordinate( CheckAttackItem )
|
||||
|
||||
local x = CheckAttackCoordinate.x
|
||||
local y = CheckAttackCoordinate.z
|
||||
local r = 8000
|
||||
|
||||
-- now we check if the coordinate is intersecting with the defense line.
|
||||
|
||||
local IntersectDistance = ( math.abs( a * x + b * y + c ) ) / math.sqrt( a * a + b * b )
|
||||
self:F( { IntersectDistance = IntersectDistance, x = x, y = y } )
|
||||
|
||||
local IntersectAttackDistance = CheckAttackCoordinate:Get2DDistance( DefenseCoordinate )
|
||||
|
||||
self:F( { IntersectAttackDistance=IntersectAttackDistance, EvaluateDistance=EvaluateDistance } )
|
||||
|
||||
-- If the distance of the attack coordinate is larger than the test radius; then the line intersects, and this is not a good coordinate.
|
||||
if IntersectDistance < r and IntersectAttackDistance < EvaluateDistance then
|
||||
ok = false
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if ok == true then
|
||||
EngageCoordinate = DefenseCoordinate
|
||||
break
|
||||
end
|
||||
EngageCoordinate = DefenseCoordinate
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -3996,7 +4014,6 @@ do -- AI_A2G_DISPATCHER
|
||||
if DefendersMissing and DefendersMissing > 0 then
|
||||
self:F( { DefendersTotal = DefendersTotal, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing } )
|
||||
self:Defend( DetectedItem, DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies, "SEAD", EngageCoordinate )
|
||||
Delay = Delay + 1
|
||||
end
|
||||
end
|
||||
|
||||
@ -4005,7 +4022,6 @@ do -- AI_A2G_DISPATCHER
|
||||
if DefendersMissing and DefendersMissing > 0 then
|
||||
self:F( { DefendersTotal = DefendersTotal, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing } )
|
||||
self:Defend( DetectedItem, DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies, "CAS", EngageCoordinate )
|
||||
Delay = Delay + 1
|
||||
end
|
||||
end
|
||||
|
||||
@ -4014,7 +4030,6 @@ do -- AI_A2G_DISPATCHER
|
||||
if DefendersMissing and DefendersMissing > 0 then
|
||||
self:F( { DefendersTotal = DefendersTotal, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing } )
|
||||
self:Defend( DetectedItem, DefendersTotal, DefendersEngaged, DefendersMissing, Friendlies, "BAI", EngageCoordinate )
|
||||
Delay = Delay + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -4030,7 +4045,7 @@ do -- AI_A2G_DISPATCHER
|
||||
if self.TacticalDisplay then
|
||||
-- Show tactical situation
|
||||
local ThreatLevel = DetectedItem.Set:CalculateThreatLevelA2G()
|
||||
Report:Add( string.format( " - %s ( %s ): ( #%d - %4s ) %s" , DetectedItem.ItemID, DetectedItem.Index, DetectedItem.Set:Count(), DetectedItem.Type or " --- ", string.rep( "■", ThreatLevel ) ) )
|
||||
Report:Add( string.format( " - %1s%s ( %4s ): ( #%d - %4s ) %s" , ( DetectedItem.IsDetected == true ) and "!" or " ", DetectedItem.ItemID, DetectedItem.Index, DetectedItem.Set:Count(), DetectedItem.Type or " --- ", string.rep( "■", ThreatLevel ) ) )
|
||||
for Defender, DefenderTask in pairs( self:GetDefenderTasks() ) do
|
||||
local Defender = Defender -- Wrapper.Group#GROUP
|
||||
if DefenderTask.Target and DefenderTask.Target.Index == DetectedItem.Index then
|
||||
|
||||
@ -189,7 +189,7 @@ function AI_A2G_SEAD:onafterEngage( DefenderGroup, From, Event, To, AttackSetUni
|
||||
local HasRadar = AttackUnit:HasSEAD()
|
||||
if HasRadar then
|
||||
self:F( { "SEAD Unit:", AttackUnit:GetName() } )
|
||||
AttackUnitTasks[#AttackUnitTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit, false, false, nil, nil, EngageAltitude )
|
||||
AttackUnitTasks[#AttackUnitTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit, true, false, nil, nil, EngageAltitude )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user