mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Progress
This commit is contained in:
parent
531f8a9106
commit
17838d7099
@ -168,26 +168,27 @@ do -- AI_A2A_DISPATCHER
|
|||||||
|
|
||||||
function AI_A2A_DISPATCHER:onafterCAP( SquadronName, Repeat )
|
function AI_A2A_DISPATCHER:onafterCAP( SquadronName, Repeat )
|
||||||
|
|
||||||
local A2AType = "CAP"
|
self.DefenderSquadrons[SquadronName] = self.DefenderSquadrons[SquadronName] or {}
|
||||||
|
self.DefenderSquadrons[SquadronName].Cap = self.DefenderSquadrons[SquadronName].Cap or {}
|
||||||
self.DefenderSquadrons["CAP"] = self.DefenderSquadrons["CAP"] or {}
|
|
||||||
self.DefenderSquadrons["CAP"][SquadronName] = self.DefenderSquadrons["CAP"][SquadronName] or {}
|
|
||||||
|
|
||||||
local CAP = self.DefenderSquadrons["CAP"][SquadronName]
|
local DefenderSquadron = self.DefenderSquadrons[SquadronName]
|
||||||
if CAP then
|
local Cap = DefenderSquadron.Cap
|
||||||
|
|
||||||
|
if Cap then
|
||||||
|
|
||||||
if self:CanCAP( SquadronName ) then
|
if self:CanCAP( SquadronName ) then
|
||||||
local AIGroup = CAP.Spawn:Spawn()
|
local Spawn = DefenderSquadron.Spawn[ math.random( 1, #DefenderSquadron.Spawn ) ]
|
||||||
|
local AIGroup = Spawn:SpawnAtAirbase( DefenderSquadron.Airbase )
|
||||||
self:F( { AIGroup = AIGroup:GetName() } )
|
self:F( { AIGroup = AIGroup:GetName() } )
|
||||||
|
|
||||||
if AIGroup then
|
if AIGroup then
|
||||||
|
|
||||||
local Fsm = AI_A2A_CAP:New( AIGroup, CAP.Zone, CAP.FloorAltitude, CAP.CeilingAltitude, CAP.MinSpeed, CAP.MaxSpeed, CAP.AltType )
|
local Fsm = AI_A2A_CAP:New( AIGroup, Cap.Zone, Cap.FloorAltitude, Cap.CeilingAltitude, Cap.MinSpeed, Cap.MaxSpeed, Cap.AltType )
|
||||||
Fsm:__Patrol( 1 )
|
Fsm:__Patrol( 1 )
|
||||||
|
|
||||||
self.DefenderTasks = self.DefenderTasks or {}
|
self.DefenderTasks = self.DefenderTasks or {}
|
||||||
self.DefenderTasks[AIGroup] = self.DefenderTasks[AIGroup] or {}
|
self.DefenderTasks[AIGroup] = self.DefenderTasks[AIGroup] or {}
|
||||||
self.DefenderTasks[AIGroup].Type = A2AType
|
self.DefenderTasks[AIGroup].Type = "CAP"
|
||||||
self.DefenderTasks[AIGroup].Fsm = Fsm
|
self.DefenderTasks[AIGroup].Fsm = Fsm
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -202,8 +203,6 @@ do -- AI_A2A_DISPATCHER
|
|||||||
|
|
||||||
function AI_A2A_DISPATCHER:onafterENGAGE( From, Event, To, TargetSetUnit, TargetReference, AIGroups )
|
function AI_A2A_DISPATCHER:onafterENGAGE( From, Event, To, TargetSetUnit, TargetReference, AIGroups )
|
||||||
|
|
||||||
local A2AType = "CAP"
|
|
||||||
|
|
||||||
self:F( { AIGroups = AIGroups } )
|
self:F( { AIGroups = AIGroups } )
|
||||||
|
|
||||||
if AIGroups then
|
if AIGroups then
|
||||||
@ -229,33 +228,35 @@ do -- AI_A2A_DISPATCHER
|
|||||||
|
|
||||||
function AI_A2A_DISPATCHER:onafterINTERCEPT( From, Event, To, TargetSetUnit, TargetReference, DefendersMissing )
|
function AI_A2A_DISPATCHER:onafterINTERCEPT( From, Event, To, TargetSetUnit, TargetReference, DefendersMissing )
|
||||||
|
|
||||||
local A2AType = "INTERCEPT"
|
|
||||||
|
|
||||||
local ClosestDistance = 0
|
local ClosestDistance = 0
|
||||||
local ClosestINTERCEPTName = nil
|
local ClosestDefenderSquadronName = nil
|
||||||
|
|
||||||
local AttackerCount = TargetSetUnit:Count()
|
local AttackerCount = TargetSetUnit:Count()
|
||||||
local DefendersCount = 0
|
local DefendersCount = 0
|
||||||
|
|
||||||
while( DefendersCount < DefendersMissing ) do
|
while( DefendersCount < DefendersMissing ) do
|
||||||
|
|
||||||
for INTERCEPTName, INTERCEPT in pairs( self.DefenderSquadrons[A2AType] or {} ) do
|
for SquadronName, DefenderSquadron in pairs( self.DefenderSquadrons or {} ) do
|
||||||
|
for InterceptID, Intercept in pairs( DefenderSquadron.Intercept or {} ) do
|
||||||
local SpawnCoord = INTERCEPT.Spawn:GetCoordinate() -- Core.Point#COORDINATE
|
|
||||||
local TargetCoord = TargetSetUnit:GetFirst():GetCoordinate()
|
local SpawnCoord = DefenderSquadron.Airbase:GetCoordinate() -- Core.Point#COORDINATE
|
||||||
local Distance = SpawnCoord:Get2DDistance( TargetCoord )
|
local TargetCoord = TargetSetUnit:GetFirst():GetCoordinate()
|
||||||
|
local Distance = SpawnCoord:Get2DDistance( TargetCoord )
|
||||||
if ClosestDistance == 0 or Distance < ClosestDistance then
|
|
||||||
ClosestDistance = Distance
|
if ClosestDistance == 0 or Distance < ClosestDistance then
|
||||||
ClosestINTERCEPTName = INTERCEPTName
|
ClosestDistance = Distance
|
||||||
|
ClosestDefenderSquadronName = SquadronName
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if ClosestINTERCEPTName then
|
if ClosestDefenderSquadronName then
|
||||||
|
|
||||||
local INTERCEPT = self.DefenderSquadrons[A2AType][ClosestINTERCEPTName]
|
local DefenderSquadron = self.DefenderSquadrons[ClosestDefenderSquadronName]
|
||||||
|
local Intercept = self.DefenderSquadrons[ClosestDefenderSquadronName].Intercept
|
||||||
|
|
||||||
local AIGroup = INTERCEPT.Spawn:Spawn()
|
local Spawn = DefenderSquadron.Spawn[ math.random( 1, #DefenderSquadron.Spawn ) ]
|
||||||
|
local AIGroup = Spawn:SpawnAtAirbase( DefenderSquadron.Airbase )
|
||||||
self:F( { AIGroup = AIGroup:GetName() } )
|
self:F( { AIGroup = AIGroup:GetName() } )
|
||||||
|
|
||||||
if AIGroup then
|
if AIGroup then
|
||||||
@ -267,7 +268,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
|
|
||||||
self.DefenderTasks = self.DefenderTasks or {}
|
self.DefenderTasks = self.DefenderTasks or {}
|
||||||
self.DefenderTasks[AIGroup] = self.DefenderTasks[AIGroup] or {}
|
self.DefenderTasks[AIGroup] = self.DefenderTasks[AIGroup] or {}
|
||||||
self.DefenderTasks[AIGroup].Type = A2AType
|
self.DefenderTasks[AIGroup].Type = "INTERCEPT"
|
||||||
self.DefenderTasks[AIGroup].Fsm = Fsm
|
self.DefenderTasks[AIGroup].Fsm = Fsm
|
||||||
self.DefenderTasks[AIGroup].Target = TargetReference
|
self.DefenderTasks[AIGroup].Target = TargetReference
|
||||||
|
|
||||||
@ -284,53 +285,80 @@ do -- AI_A2A_DISPATCHER
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function AI_A2A_DISPATCHER:SetSquadron( SquadronName, AirbaseName, SpawnTemplates, Resources )
|
||||||
|
|
||||||
function AI_A2A_DISPATCHER:SetCAP( SquadronName, Spawn, Zone, FloorAltitude, CeilingAltitude, MinSpeed, MaxSpeed, AltType )
|
self.DefenderSquadrons[SquadronName] = self.DefenderSquadrons[SquadronName] or {}
|
||||||
|
|
||||||
self.DefenderSquadrons["CAP"] = self.DefenderSquadrons["CAP"] or {}
|
|
||||||
self.DefenderSquadrons["CAP"][SquadronName] = self.DefenderSquadrons["CAP"][SquadronName] or {}
|
|
||||||
|
|
||||||
local CAP = self.DefenderSquadrons["CAP"][SquadronName]
|
|
||||||
CAP.Name = SquadronName
|
|
||||||
CAP.Spawn = Spawn -- Funtional.Spawn#SPAWN
|
|
||||||
CAP.Zone = Zone
|
|
||||||
CAP.FloorAltitude = FloorAltitude
|
|
||||||
CAP.CeilingAltitude = CeilingAltitude
|
|
||||||
CAP.MinSpeed = MinSpeed
|
|
||||||
CAP.MaxSpeed = MaxSpeed
|
|
||||||
CAP.AltType = AltType
|
|
||||||
|
|
||||||
self:SetCAPInterval( SquadronName, 60, 300, 1 )
|
local DefenderSquadron = self.DefenderSquadrons[SquadronName]
|
||||||
|
|
||||||
|
self:E( { AirbaseName = AirbaseName } )
|
||||||
|
DefenderSquadron.Airbase = AIRBASE:FindByName( AirbaseName )
|
||||||
|
self:E( { Airbase = DefenderSquadron.Airbase } )
|
||||||
|
self:E( { AirbaseObject = DefenderSquadron.Airbase:GetDCSObject() } )
|
||||||
|
|
||||||
|
DefenderSquadron.Spawn = {}
|
||||||
|
if type( SpawnTemplates ) == "string" then
|
||||||
|
local SpawnTemplate = SpawnTemplates
|
||||||
|
DefenderSquadron.Spawn[1] = SPAWN:New( SpawnTemplate )
|
||||||
|
else
|
||||||
|
for TemplateID, SpawnTemplate in pairs( SpawnTemplates ) do
|
||||||
|
DefenderSquadron.Spawn[#DefenderSquadron.Spawn+1] = SPAWN:New( SpawnTemplate )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
DefenderSquadron.Resources = Resources
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function AI_A2A_DISPATCHER:SetCAP( SquadronName, Zone, FloorAltitude, CeilingAltitude, MinSpeed, MaxSpeed, AltType )
|
||||||
|
|
||||||
|
self.DefenderSquadrons[SquadronName] = self.DefenderSquadrons[SquadronName] or {}
|
||||||
|
self.DefenderSquadrons[SquadronName].Cap = self.DefenderSquadrons[SquadronName].Cap or {}
|
||||||
|
|
||||||
|
local DefenderSquadron = self.DefenderSquadrons[SquadronName]
|
||||||
|
|
||||||
|
local Cap = self.DefenderSquadrons[SquadronName].Cap
|
||||||
|
Cap.Name = SquadronName
|
||||||
|
Cap.Zone = Zone
|
||||||
|
Cap.FloorAltitude = FloorAltitude
|
||||||
|
Cap.CeilingAltitude = CeilingAltitude
|
||||||
|
Cap.MinSpeed = MinSpeed
|
||||||
|
Cap.MaxSpeed = MaxSpeed
|
||||||
|
Cap.AltType = AltType
|
||||||
|
|
||||||
|
self:SetCAPInterval( SquadronName, 2, 180, 600, 1 )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function AI_A2A_DISPATCHER:SetCAPInterval( SquadronName, LowInterval, HighInterval, Probability )
|
function AI_A2A_DISPATCHER:SetCAPInterval( SquadronName, Limit, LowInterval, HighInterval, Probability )
|
||||||
|
|
||||||
self.DefenderSquadrons["CAP"] = self.DefenderSquadrons["CAP"] or {}
|
self.DefenderSquadrons[SquadronName] = self.DefenderSquadrons[SquadronName] or {}
|
||||||
self.DefenderSquadrons["CAP"][SquadronName] = self.DefenderSquadrons["CAP"][SquadronName] or {}
|
self.DefenderSquadrons[SquadronName].Cap = self.DefenderSquadrons[SquadronName].Cap or {}
|
||||||
|
|
||||||
local CAP = self.DefenderSquadrons["CAP"][SquadronName]
|
local DefenderSquadron = self.DefenderSquadrons[SquadronName]
|
||||||
|
|
||||||
if CAP then
|
local Cap = self.DefenderSquadrons[SquadronName].Cap
|
||||||
CAP.LowInterval = LowInterval
|
if Cap then
|
||||||
CAP.HighInterval = HighInterval
|
Cap.LowInterval = LowInterval
|
||||||
CAP.Probability = Probability
|
Cap.HighInterval = HighInterval
|
||||||
|
Cap.Probability = Probability
|
||||||
|
Cap.Limit = Limit
|
||||||
else
|
else
|
||||||
error( "This squadron does not exist:" .. SquadronName )
|
error( "This squadron does not exist:" .. SquadronName )
|
||||||
end
|
end
|
||||||
|
|
||||||
self:__CAP( self:GetCAPDelay( SquadronName ), SquadronName, true )
|
self:__CAP( -self:GetCAPDelay( SquadronName ), SquadronName, true )
|
||||||
end
|
end
|
||||||
|
|
||||||
function AI_A2A_DISPATCHER:GetCAPDelay( SquadronName )
|
function AI_A2A_DISPATCHER:GetCAPDelay( SquadronName )
|
||||||
|
|
||||||
self.DefenderSquadrons["CAP"] = self.DefenderSquadrons["CAP"] or {}
|
self.DefenderSquadrons[SquadronName] = self.DefenderSquadrons[SquadronName] or {}
|
||||||
self.DefenderSquadrons["CAP"][SquadronName] = self.DefenderSquadrons["CAP"][SquadronName] or {}
|
self.DefenderSquadrons[SquadronName].Cap = self.DefenderSquadrons[SquadronName].Cap or {}
|
||||||
|
|
||||||
local CAP = self.DefenderSquadrons["CAP"][SquadronName]
|
local DefenderSquadron = self.DefenderSquadrons[SquadronName]
|
||||||
|
|
||||||
if CAP then
|
local Cap = self.DefenderSquadrons[SquadronName].Cap
|
||||||
return math.random( CAP.LowInterval, CAP.HighInterval )
|
if Cap then
|
||||||
|
return math.random( Cap.LowInterval, Cap.HighInterval )
|
||||||
else
|
else
|
||||||
error( "This squadron does not exist:" .. SquadronName )
|
error( "This squadron does not exist:" .. SquadronName )
|
||||||
end
|
end
|
||||||
@ -338,33 +366,34 @@ do -- AI_A2A_DISPATCHER
|
|||||||
|
|
||||||
function AI_A2A_DISPATCHER:CanCAP( SquadronName )
|
function AI_A2A_DISPATCHER:CanCAP( SquadronName )
|
||||||
|
|
||||||
self.DefenderSquadrons["CAP"] = self.DefenderSquadrons["CAP"] or {}
|
self.DefenderSquadrons[SquadronName] = self.DefenderSquadrons[SquadronName] or {}
|
||||||
self.DefenderSquadrons["CAP"][SquadronName] = self.DefenderSquadrons["CAP"][SquadronName] or {}
|
self.DefenderSquadrons[SquadronName].Cap = self.DefenderSquadrons[SquadronName].Cap or {}
|
||||||
|
|
||||||
local CAP = self.DefenderSquadrons["CAP"][SquadronName]
|
local DefenderSquadron = self.DefenderSquadrons[SquadronName]
|
||||||
|
|
||||||
if CAP then
|
local Cap = self.DefenderSquadrons[SquadronName].Cap
|
||||||
local Probability = math.random()
|
if Cap then
|
||||||
if Probability < CAP.Probability then
|
local CapCount = self:CountCapAirborne( SquadronName )
|
||||||
return true
|
if CapCount < Cap.Limit then
|
||||||
else
|
local Probability = math.random()
|
||||||
return false
|
if Probability <= Cap.Probability then
|
||||||
|
return true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
return false
|
||||||
else
|
else
|
||||||
error( "This squadron does not exist:" .. SquadronName )
|
error( "This squadron does not exist:" .. SquadronName )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function AI_A2A_DISPATCHER:SetINTERCEPT( Name, Spawn, MinSpeed, MaxSpeed )
|
function AI_A2A_DISPATCHER:SetINTERCEPT( SquadronName, MinSpeed, MaxSpeed )
|
||||||
|
|
||||||
self.DefenderSquadrons["INTERCEPT"] = self.DefenderSquadrons["INTERCEPT"] or {}
|
self.DefenderSquadrons[SquadronName] = self.DefenderSquadrons[SquadronName] or {}
|
||||||
self.DefenderSquadrons["INTERCEPT"][Name] = self.DefenderSquadrons["INTERCEPT"][Name] or {}
|
self.DefenderSquadrons[SquadronName].Intercept = self.DefenderSquadrons[SquadronName].Intercept or {}
|
||||||
|
|
||||||
local INTERCEPT = self.DefenderSquadrons["INTERCEPT"][Name]
|
local Intercept = self.DefenderSquadrons[SquadronName].Intercept
|
||||||
INTERCEPT.Name = Name
|
Intercept.Name = SquadronName
|
||||||
INTERCEPT.Spawn = Spawn
|
Intercept.MaxSpeed = MaxSpeed
|
||||||
INTERCEPT.MinSpeed = MinSpeed
|
|
||||||
INTERCEPT.MaxSpeed = MaxSpeed
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -393,6 +422,22 @@ do -- AI_A2A_DISPATCHER
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function AI_A2A_DISPATCHER:CountCapAirborne( SquadronName )
|
||||||
|
|
||||||
|
-- First, count the active AIGroups Units, targetting the DetectedSet
|
||||||
|
local CapCount = 0
|
||||||
|
|
||||||
|
local DefenderSquadron = self.DefenderSquadrons[SquadronName]
|
||||||
|
if DefenderSquadron then
|
||||||
|
for InterceptID, Intercept in pairs( DefenderSquadron.Intercept or {} ) do
|
||||||
|
CapCount = CapCount + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return CapCount
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function AI_A2A_DISPATCHER:CountDefendersEngaged( DetectedItem )
|
function AI_A2A_DISPATCHER:CountDefendersEngaged( DetectedItem )
|
||||||
|
|
||||||
@ -613,27 +658,27 @@ do -- AI_A2A_DISPATCHER
|
|||||||
-- @param #boolean DetectedItemID
|
-- @param #boolean DetectedItemID
|
||||||
-- @param #boolean DetectedItemChange
|
-- @param #boolean DetectedItemChange
|
||||||
-- @return Tasking.Task#TASK
|
-- @return Tasking.Task#TASK
|
||||||
function AI_A2A_DISPATCHER:EvaluateRemoveTask( DetectedItem, A2A_Index )
|
function AI_A2A_DISPATCHER:EvaluateRemoveTask( DetectedItem, TargetIndex )
|
||||||
|
|
||||||
local A2A_Target = self.DefenderTargets[A2A_Index]
|
local DefenderTarget = self.DefenderTargets[TargetIndex]
|
||||||
|
|
||||||
if A2A_Target then
|
if DefenderTarget then
|
||||||
|
|
||||||
for AIGroupName, AIGroup in pairs( A2A_Target.Groups ) do
|
for AIGroupName, AIGroup in pairs( DefenderTarget.Groups ) do
|
||||||
local AIGroup = AIGroup -- Wrapper.Group#GROUP
|
local AIGroup = AIGroup -- Wrapper.Group#GROUP
|
||||||
if not AIGroup:IsAlive() then
|
if not AIGroup:IsAlive() then
|
||||||
self.DefenderTasks[AIGroup] = nil
|
self.DefenderTasks[AIGroup] = nil
|
||||||
self.DefenderTargets[A2A_Index].Groups[AIGroupName] = nil
|
self.DefenderTargets[TargetIndex].Groups[AIGroupName] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT
|
local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT
|
||||||
if DetectedSet:Count() == 0 then
|
if DetectedSet:Count() == 0 then
|
||||||
self.DefenderTargets[A2A_Index] = nil
|
self.DefenderTargets[TargetIndex] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return self.DefenderTargets[A2A_Index]
|
return self.DefenderTargets[TargetIndex]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,9 @@
|
|||||||
-- @module AI_A2A_Intercept
|
-- @module AI_A2A_Intercept
|
||||||
|
|
||||||
|
|
||||||
|
BASE:TraceClass("AI_A2A_INTERCEPT")
|
||||||
|
|
||||||
|
|
||||||
--- @type AI_A2A_INTERCEPT
|
--- @type AI_A2A_INTERCEPT
|
||||||
-- @extends AI.AI_A2A#AI_A2A
|
-- @extends AI.AI_A2A#AI_A2A
|
||||||
|
|
||||||
@ -352,32 +355,40 @@ function AI_A2A_INTERCEPT:onafterEngage( AIGroup, From, Event, To, AttackSetUnit
|
|||||||
local EngageRoute = {}
|
local EngageRoute = {}
|
||||||
|
|
||||||
--- Calculate the current route point.
|
--- Calculate the current route point.
|
||||||
local CurrentVec2 = AIGroup:GetVec2()
|
|
||||||
|
|
||||||
--TODO: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
local CurrentCoord = AIGroup:GetCoordinate()
|
||||||
local CurrentAltitude = AIGroup:GetUnit(1):GetAltitude()
|
local ToTargetSpeed = math.random( self.MinSpeed, self.MaxSpeed )
|
||||||
local CurrentSpeed = AIGroup:GetUnit(1):GetVelocityKMH()
|
|
||||||
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
if not AIGroup:GetUnit(1):IsAboveRunway() then
|
||||||
local ToEngageZoneSpeed = self.PatrolMaxSpeed
|
|
||||||
local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
|
--TODO: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
||||||
self.PatrolAltType,
|
local CurrentSpeed = AIGroup:GetUnit(1):GetVelocityKMH()
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
local ToEngageZoneSpeed = self.PatrolMaxSpeed
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
local CurrentRoutePoint = CurrentCoord:RoutePointAir(
|
||||||
CurrentSpeed,
|
self.PatrolAltType,
|
||||||
true
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
)
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
|
ToTargetSpeed,
|
||||||
EngageRoute[#EngageRoute+1] = CurrentRoutePoint
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
EngageRoute[#EngageRoute+1] = CurrentRoutePoint
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Find the target point.
|
--- Find the target point.
|
||||||
|
|
||||||
|
|
||||||
local ToTargetCoord = self.AttackSetUnit:GetFirst():GetCoordinate()
|
local ToTargetCoord = self.AttackSetUnit:GetFirst():GetCoordinate()
|
||||||
|
|
||||||
local ToTargetSpeed = math.random( self.MinSpeed, self.MaxSpeed )
|
local ToInterceptAngle = CurrentCoord:GetAngleDegrees( CurrentCoord:GetDirectionVec3( ToTargetCoord ) )
|
||||||
|
local ToInterceptCoord = CurrentCoord:Translate( 5000, ToInterceptAngle )
|
||||||
|
|
||||||
self:T2( { self.MinSpeed, self.MaxSpeed, ToTargetSpeed } )
|
self:T2( { self.MinSpeed, self.MaxSpeed, ToTargetSpeed } )
|
||||||
|
|
||||||
|
|
||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local ToPatrolRoutePoint = ToTargetCoord:RoutePointAir(
|
local ToPatrolRoutePoint = ToInterceptCoord:RoutePointAir(
|
||||||
self.PatrolAltType,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
@ -386,6 +397,8 @@ function AI_A2A_INTERCEPT:onafterEngage( AIGroup, From, Event, To, AttackSetUnit
|
|||||||
)
|
)
|
||||||
|
|
||||||
EngageRoute[#EngageRoute+1] = ToPatrolRoutePoint
|
EngageRoute[#EngageRoute+1] = ToPatrolRoutePoint
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AIGroup:OptionROEOpenFire()
|
AIGroup:OptionROEOpenFire()
|
||||||
AIGroup:OptionROTPassiveDefense()
|
AIGroup:OptionROTPassiveDefense()
|
||||||
@ -394,7 +407,7 @@ function AI_A2A_INTERCEPT:onafterEngage( AIGroup, From, Event, To, AttackSetUnit
|
|||||||
|
|
||||||
for AttackUnitID, AttackUnit in pairs( self.AttackSetUnit:GetSet() ) do
|
for AttackUnitID, AttackUnit in pairs( self.AttackSetUnit:GetSet() ) do
|
||||||
local AttackUnit = AttackUnit -- Wrapper.Unit#UNIT
|
local AttackUnit = AttackUnit -- Wrapper.Unit#UNIT
|
||||||
self:T( { AttackUnit, AttackUnit:IsAlive(), AttackUnit:IsAir() } )
|
self:T( { "Intercepting Unit:", AttackUnit:GetName(), AttackUnit:IsAlive(), AttackUnit:IsAir() } )
|
||||||
if AttackUnit:IsAlive() and AttackUnit:IsAir() then
|
if AttackUnit:IsAlive() and AttackUnit:IsAir() then
|
||||||
AttackTasks[#AttackTasks+1] = AIGroup:TaskAttackUnit( AttackUnit )
|
AttackTasks[#AttackTasks+1] = AIGroup:TaskAttackUnit( AttackUnit )
|
||||||
end
|
end
|
||||||
|
|||||||
@ -138,12 +138,13 @@ do -- COORDINATE
|
|||||||
ClassName = "COORDINATE",
|
ClassName = "COORDINATE",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
--- COORDINATE constructor.
|
--- COORDINATE constructor.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param Dcs.DCSTypes#Distance x The x coordinate of the Vec3 point, pointing to the North.
|
-- @param Dcs.DCSTypes#Distance x The x coordinate of the Vec3 point, pointing to the North.
|
||||||
-- @param Dcs.DCSTypes#Distance y The y coordinate of the Vec3 point, pointing to the Right.
|
-- @param Dcs.DCSTypes#Distance y The y coordinate of the Vec3 point, pointing to the Right.
|
||||||
-- @param Dcs.DCSTypes#Distance z The z coordinate of the Vec3 point, pointing to the Right.
|
-- @param Dcs.DCSTypes#Distance z The z coordinate of the Vec3 point, pointing to the Right.
|
||||||
-- @return Core.Point#COORDINATE
|
-- @return #COORDINATE
|
||||||
function COORDINATE:New( x, y, z )
|
function COORDINATE:New( x, y, z )
|
||||||
|
|
||||||
local self = BASE:Inherit( self, BASE:New() ) -- #COORDINATE
|
local self = BASE:Inherit( self, BASE:New() ) -- #COORDINATE
|
||||||
@ -177,7 +178,7 @@ do -- COORDINATE
|
|||||||
--- Create a new COORDINATE object from Vec3 coordinates.
|
--- Create a new COORDINATE object from Vec3 coordinates.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param Dcs.DCSTypes#Vec3 Vec3 The Vec3 point.
|
-- @param Dcs.DCSTypes#Vec3 Vec3 The Vec3 point.
|
||||||
-- @return Core.Point#COORDINATE
|
-- @return #COORDINATE
|
||||||
function COORDINATE:NewFromVec3( Vec3 )
|
function COORDINATE:NewFromVec3( Vec3 )
|
||||||
|
|
||||||
local self = self:New( Vec3.x, Vec3.y, Vec3.z ) -- #COORDINATE
|
local self = self:New( Vec3.x, Vec3.y, Vec3.z ) -- #COORDINATE
|
||||||
|
|||||||
@ -957,6 +957,68 @@ function SPAWN:OnSpawnGroup( SpawnCallBackFunction, ... )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Will spawn a group at an airbase.
|
||||||
|
-- This method is mostly advisable to be used if you want to simulate spawning units at an airbase.
|
||||||
|
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
|
||||||
|
-- You can use the returned group to further define the route to be followed.
|
||||||
|
-- @param #SPAWN self
|
||||||
|
-- @param Wrapper.Airbase#AIRBASE Airbase The @{Airbase} where to spawn the group.
|
||||||
|
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
|
||||||
|
-- @return Wrapper.Group#GROUP that was spawned.
|
||||||
|
-- @return #nil Nothing was spawned.
|
||||||
|
function SPAWN:SpawnAtAirbase( Airbase, SpawnIndex )
|
||||||
|
self:F( { self.SpawnTemplatePrefix, Airbase, SpawnIndex } )
|
||||||
|
|
||||||
|
local PointVec3 = Airbase:GetPointVec3()
|
||||||
|
self:T2(PointVec3)
|
||||||
|
|
||||||
|
if SpawnIndex then
|
||||||
|
else
|
||||||
|
SpawnIndex = self.SpawnIndex + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:_GetSpawnIndex( SpawnIndex ) then
|
||||||
|
|
||||||
|
local SpawnTemplate = self.SpawnGroups[self.SpawnIndex].SpawnTemplate
|
||||||
|
|
||||||
|
if SpawnTemplate then
|
||||||
|
|
||||||
|
self:T( { "Current point of ", self.SpawnTemplatePrefix, Airbase } )
|
||||||
|
|
||||||
|
-- Translate the position of the Group Template to the Vec3.
|
||||||
|
for UnitID = 1, #SpawnTemplate.units do
|
||||||
|
self:T( 'Before Translation SpawnTemplate.units['..UnitID..'].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. SpawnTemplate.units[UnitID].y )
|
||||||
|
local UnitTemplate = SpawnTemplate.units[UnitID]
|
||||||
|
local SX = UnitTemplate.x
|
||||||
|
local SY = UnitTemplate.y
|
||||||
|
local BX = SpawnTemplate.route.points[1].x
|
||||||
|
local BY = SpawnTemplate.route.points[1].y
|
||||||
|
local TX = PointVec3.x + ( SX - BX )
|
||||||
|
local TY = PointVec3.z + ( SY - BY )
|
||||||
|
SpawnTemplate.units[UnitID].x = TX
|
||||||
|
SpawnTemplate.units[UnitID].y = TY
|
||||||
|
SpawnTemplate.units[UnitID].alt = PointVec3.y
|
||||||
|
self:T( 'After Translation SpawnTemplate.units['..UnitID..'].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. SpawnTemplate.units[UnitID].y )
|
||||||
|
end
|
||||||
|
|
||||||
|
SpawnTemplate.route.points[1].x = PointVec3.x
|
||||||
|
SpawnTemplate.route.points[1].y = PointVec3.z
|
||||||
|
SpawnTemplate.route.points[1].alt = Airbase.y
|
||||||
|
SpawnTemplate.route.points[1].action = "From Parking Area Hot"
|
||||||
|
SpawnTemplate.route.points[1].type = "TakeOffParkingHot"
|
||||||
|
SpawnTemplate.route.points[1].airdromeId = Airbase:GetID()
|
||||||
|
|
||||||
|
SpawnTemplate.x = PointVec3.x
|
||||||
|
SpawnTemplate.y = PointVec3.z
|
||||||
|
|
||||||
|
return self:SpawnWithIndex( self.SpawnIndex )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Will spawn a group from a Vec3 in 3D space.
|
--- Will spawn a group from a Vec3 in 3D space.
|
||||||
-- This method is mostly advisable to be used if you want to simulate spawning units in the air, like helicopters or airplanes.
|
-- This method is mostly advisable to be used if you want to simulate spawning units in the air, like helicopters or airplanes.
|
||||||
|
|||||||
@ -47,7 +47,7 @@
|
|||||||
-- the first letter of the method is also capitalized. So, by example, the DCS Airbase method @{DCSWrapper.Airbase#Airbase.getName}()
|
-- the first letter of the method is also capitalized. So, by example, the DCS Airbase method @{DCSWrapper.Airbase#Airbase.getName}()
|
||||||
-- is implemented in the AIRBASE class as @{#AIRBASE.GetName}().
|
-- is implemented in the AIRBASE class as @{#AIRBASE.GetName}().
|
||||||
--
|
--
|
||||||
-- @field #AIRBASE
|
-- @field #AIRBASE AIRBASE
|
||||||
AIRBASE = {
|
AIRBASE = {
|
||||||
ClassName="AIRBASE",
|
ClassName="AIRBASE",
|
||||||
CategoryName = {
|
CategoryName = {
|
||||||
@ -57,6 +57,31 @@ AIRBASE = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- @field Caucasus
|
||||||
|
AIRBASE.Caucasus = {
|
||||||
|
["Gelendzhik"] = "Gelendzhik",
|
||||||
|
["Krasnodar_Pashkovsky"] = "Krasnodar-Pashkovsky",
|
||||||
|
["Sukhumi_Babushara"] = "Sukhumi-Babushara",
|
||||||
|
["Gudauta"] = "Gudauta",
|
||||||
|
["Batumi"] = "Batumi",
|
||||||
|
["Senaki_Kolkhi"] = "Senaki-Kolkhi",
|
||||||
|
["Kobuleti"] = "Kobuleti",
|
||||||
|
["Kutaisi"] = "Kutaisi",
|
||||||
|
["Tbilisi_Lochini"] = "Tbilisi-Lochini",
|
||||||
|
["Soganlug"] = "Soganlug",
|
||||||
|
["Vaziani"] = "Vaziani",
|
||||||
|
["Anapa_Vityazevo"] = "Anapa-Vityazevo",
|
||||||
|
["Krasnodar_Center"] = "Krasnodar-Center",
|
||||||
|
["Novorossiysk"] = "Novorossiysk",
|
||||||
|
["Krymsk"] = "Krymsk",
|
||||||
|
["Maykop_Khanskaya"] = "Maykop-Khanskaya",
|
||||||
|
["Sochi_Adler"] = "Sochi-Adler",
|
||||||
|
["Mineralnye_Vody"] = "Mineralnye Vody",
|
||||||
|
["Nalchik"] = "Nalchik",
|
||||||
|
["Mozdok"] = "Mozdok",
|
||||||
|
["Beslan"] = "Beslan",
|
||||||
|
}
|
||||||
|
|
||||||
-- Registration.
|
-- Registration.
|
||||||
|
|
||||||
--- Create a new AIRBASE from DCSAirbase.
|
--- Create a new AIRBASE from DCSAirbase.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user