mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge branch 'develop' into FF/Develop
This commit is contained in:
commit
e082ee17e4
@ -489,7 +489,7 @@ function AI_A2A:onafterStatus()
|
|||||||
not self:Is( "Fuel" ) and
|
not self:Is( "Fuel" ) and
|
||||||
not self:Is( "Damaged" ) and
|
not self:Is( "Damaged" ) and
|
||||||
not self:Is( "Home" ) then
|
not self:Is( "Home" ) then
|
||||||
if self.IdleCount >= 2 then
|
if self.IdleCount >= 3 then
|
||||||
if Damage ~= InitialLife then
|
if Damage ~= InitialLife then
|
||||||
self:Damaged()
|
self:Damaged()
|
||||||
else
|
else
|
||||||
|
|||||||
@ -61,7 +61,7 @@ function AI_A2G:New( AIGroup )
|
|||||||
local self = BASE:Inherit( self, AI_AIR:New( AIGroup ) ) -- #AI_A2G
|
local self = BASE:Inherit( self, AI_AIR:New( AIGroup ) ) -- #AI_A2G
|
||||||
|
|
||||||
self:SetFuelThreshold( .2, 60 )
|
self:SetFuelThreshold( .2, 60 )
|
||||||
self:SetDamageThreshold( 0.4 )
|
self:SetDamageThreshold( 0.95 )
|
||||||
self:SetDisengageRadius( 70000 )
|
self:SetDisengageRadius( 70000 )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|||||||
149
Moose Development/Moose/AI/AI_A2G_BAI.lua
Normal file
149
Moose Development/Moose/AI/AI_A2G_BAI.lua
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
--- **AI** -- Models the process of air to ground BAI engagement for airplanes and helicopters.
|
||||||
|
--
|
||||||
|
-- This is a class used in the @{AI_A2G_Dispatcher}.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @module AI.AI_A2G_BAI
|
||||||
|
-- @image AI_Air_To_Ground_Engage.JPG
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- @type AI_A2G_BAI
|
||||||
|
-- @extends AI.AI_A2A_Engage#AI_A2A_Engage
|
||||||
|
|
||||||
|
|
||||||
|
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @field #AI_A2G_BAI
|
||||||
|
AI_A2G_BAI = {
|
||||||
|
ClassName = "AI_A2G_BAI",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Creates a new AI_A2G_BAI object
|
||||||
|
-- @param #AI_A2G_BAI self
|
||||||
|
-- @param Wrapper.Group#GROUP AIGroup
|
||||||
|
-- @param DCS#Speed EngageMinSpeed The minimum speed of the @{Wrapper.Group} in km/h when engaging a target.
|
||||||
|
-- @param DCS#Speed EngageMaxSpeed The maximum speed of the @{Wrapper.Group} in km/h when engaging a target.
|
||||||
|
-- @param DCS#Altitude EngageFloorAltitude The lowest altitude in meters where to execute the engagement.
|
||||||
|
-- @param DCS#Altitude EngageCeilingAltitude The highest altitude in meters where to execute the engagement.
|
||||||
|
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
|
||||||
|
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
|
||||||
|
-- @param DCS#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
|
||||||
|
-- @param DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Group} in km/h.
|
||||||
|
-- @param DCS#Speed PatrolMaxSpeed The maximum speed of the @{Wrapper.Group} in km/h.
|
||||||
|
-- @param DCS#AltitudeType PatrolAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to RADIO
|
||||||
|
-- @return #AI_A2G_BAI
|
||||||
|
function AI_A2G_BAI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
|
||||||
|
|
||||||
|
-- Inherits from BASE
|
||||||
|
local self = BASE:Inherit( self, AI_A2G_PATROL:New( AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType ) ) -- #AI_A2G_BAI
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- @param #AI_A2G_BAI self
|
||||||
|
-- @param Wrapper.Group#GROUP DefenderGroup The GroupGroup managed by the FSM.
|
||||||
|
-- @param #string From The From State string.
|
||||||
|
-- @param #string Event The Event string.
|
||||||
|
-- @param #string To The To State string.
|
||||||
|
function AI_A2G_BAI:onafterEngage( DefenderGroup, From, Event, To, AttackSetUnit )
|
||||||
|
|
||||||
|
self:F( { DefenderGroup, From, Event, To, AttackSetUnit} )
|
||||||
|
|
||||||
|
local DefenderGroupName = DefenderGroup:GetName()
|
||||||
|
|
||||||
|
self.AttackSetUnit = AttackSetUnit or self.AttackSetUnit -- Core.Set#SET_UNIT
|
||||||
|
|
||||||
|
local AttackCount = self.AttackSetUnit:Count()
|
||||||
|
|
||||||
|
if AttackCount > 0 then
|
||||||
|
|
||||||
|
if DefenderGroup:IsAlive() then
|
||||||
|
|
||||||
|
-- Determine the distance to the target.
|
||||||
|
-- If it is less than 10km, then attack without a route.
|
||||||
|
-- Otherwise perform a route attack.
|
||||||
|
|
||||||
|
local DefenderCoord = DefenderGroup:GetPointVec3()
|
||||||
|
DefenderCoord:SetY( math.random( self.EngageFloorAltitude, self.EngageCeilingAltitude ) ) -- Ground targets don't have an altitude.
|
||||||
|
|
||||||
|
local TargetCoord = self.AttackSetUnit:GetFirst():GetPointVec3()
|
||||||
|
TargetCoord:SetY( math.random( self.EngageFloorAltitude, self.EngageCeilingAltitude ) ) -- Ground targets don't have an altitude.
|
||||||
|
|
||||||
|
local TargetDistance = DefenderCoord:Get2DDistance( TargetCoord )
|
||||||
|
|
||||||
|
local EngageRoute = {}
|
||||||
|
|
||||||
|
local ToTargetSpeed = math.random( self.EngageMinSpeed, self.EngageMaxSpeed )
|
||||||
|
|
||||||
|
--- Calculate the target route point.
|
||||||
|
|
||||||
|
local FromWP = DefenderCoord:WaypointAir(
|
||||||
|
self.PatrolAltType or "RADIO",
|
||||||
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
|
ToTargetSpeed,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
EngageRoute[#EngageRoute+1] = FromWP
|
||||||
|
|
||||||
|
local ToCoord = self.AttackSetUnit:GetFirst():GetCoordinate()
|
||||||
|
self:SetTargetDistance( ToCoord ) -- For RTB status check
|
||||||
|
|
||||||
|
local FromEngageAngle = ToCoord:GetAngleDegrees( ToCoord:GetDirectionVec3( DefenderCoord ) )
|
||||||
|
|
||||||
|
--- Create a route point of type air.
|
||||||
|
local ToWP = ToCoord:Translate( 10000, FromEngageAngle ):WaypointAir(
|
||||||
|
self.PatrolAltType or "RADIO",
|
||||||
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
|
ToTargetSpeed,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
self:F( { Angle = FromEngageAngle, ToTargetSpeed = ToTargetSpeed } )
|
||||||
|
self:F( { self.EngageMinSpeed, self.EngageMaxSpeed, ToTargetSpeed } )
|
||||||
|
|
||||||
|
EngageRoute[#EngageRoute+1] = ToWP
|
||||||
|
|
||||||
|
local AttackTasks = {}
|
||||||
|
|
||||||
|
for AttackUnitID, AttackUnit in pairs( self.AttackSetUnit:GetSet() ) do
|
||||||
|
if AttackUnit:IsAlive() and AttackUnit:IsGround() then
|
||||||
|
self:T( { "Engage Unit evaluation:", AttackUnit:GetName(), AttackUnit:IsAlive(), AttackUnit:IsGround() } )
|
||||||
|
self:T( { "Eliminating Unit:", AttackUnit:GetName() } )
|
||||||
|
AttackTasks[#AttackTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if #AttackTasks == 0 then
|
||||||
|
self:E( DefenderGroupName .. ": No targets found -> Going RTB")
|
||||||
|
self:Return()
|
||||||
|
self:__RTB( 0.5 )
|
||||||
|
else
|
||||||
|
DefenderGroup:OptionROEOpenFire()
|
||||||
|
DefenderGroup:OptionROTEvadeFire()
|
||||||
|
|
||||||
|
AttackTasks[#AttackTasks+1] = DefenderGroup:TaskFunction( "AI_A2G_ENGAGE.EngageRoute", self )
|
||||||
|
EngageRoute[#EngageRoute].task = DefenderGroup:TaskCombo( AttackTasks )
|
||||||
|
end
|
||||||
|
|
||||||
|
DefenderGroup:Route( EngageRoute, 0.5 )
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:E( DefenderGroupName .. ": No targets found -> Going RTB")
|
||||||
|
self:Return()
|
||||||
|
self:__RTB( 0.5 )
|
||||||
|
end
|
||||||
|
end
|
||||||
154
Moose Development/Moose/AI/AI_A2G_CAS.lua
Normal file
154
Moose Development/Moose/AI/AI_A2G_CAS.lua
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
--- **AI** -- Models the process of air to ground engagement for airplanes and helicopters.
|
||||||
|
--
|
||||||
|
-- This is a class used in the @{AI_A2G_Dispatcher}.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @module AI.AI_A2G_CAS
|
||||||
|
-- @image AI_Air_To_Ground_Engage.JPG
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- @type AI_A2G_CAS
|
||||||
|
-- @extends AI.AI_A2G_Patrol#AI_A2G_PATROL
|
||||||
|
|
||||||
|
|
||||||
|
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @field #AI_A2G_CAS
|
||||||
|
AI_A2G_CAS = {
|
||||||
|
ClassName = "AI_A2G_CAS",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Creates a new AI_A2G_CAS object
|
||||||
|
-- @param #AI_A2G_CAS self
|
||||||
|
-- @param Wrapper.Group#GROUP AIGroup
|
||||||
|
-- @param DCS#Speed EngageMinSpeed The minimum speed of the @{Wrapper.Group} in km/h when engaging a target.
|
||||||
|
-- @param DCS#Speed EngageMaxSpeed The maximum speed of the @{Wrapper.Group} in km/h when engaging a target.
|
||||||
|
-- @param DCS#Altitude EngageFloorAltitude The lowest altitude in meters where to execute the engagement.
|
||||||
|
-- @param DCS#Altitude EngageCeilingAltitude The highest altitude in meters where to execute the engagement.
|
||||||
|
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
|
||||||
|
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
|
||||||
|
-- @param DCS#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
|
||||||
|
-- @param DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Group} in km/h.
|
||||||
|
-- @param DCS#Speed PatrolMaxSpeed The maximum speed of the @{Wrapper.Group} in km/h.
|
||||||
|
-- @param DCS#AltitudeType PatrolAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to RADIO
|
||||||
|
-- @return #AI_A2G_CAS
|
||||||
|
function AI_A2G_CAS:New( AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
|
||||||
|
|
||||||
|
-- Inherits from BASE
|
||||||
|
local self = BASE:Inherit( self, AI_A2G_PATROL:New( AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType ) ) -- #AI_A2G_CAS
|
||||||
|
|
||||||
|
local RTBSpeedMax = AIGroup:GetSpeedMax()
|
||||||
|
|
||||||
|
self:SetRTBSpeed( RTBSpeedMax * 0.50, RTBSpeedMax * 0.75 )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- @param #AI_A2G_CAS self
|
||||||
|
-- @param Wrapper.Group#GROUP DefenderGroup The GroupGroup managed by the FSM.
|
||||||
|
-- @param #string From The From State string.
|
||||||
|
-- @param #string Event The Event string.
|
||||||
|
-- @param #string To The To State string.
|
||||||
|
function AI_A2G_CAS:onafterEngage( DefenderGroup, From, Event, To, AttackSetUnit )
|
||||||
|
|
||||||
|
self:F( { DefenderGroup, From, Event, To, AttackSetUnit} )
|
||||||
|
|
||||||
|
local DefenderGroupName = DefenderGroup:GetName()
|
||||||
|
|
||||||
|
self.AttackSetUnit = AttackSetUnit or self.AttackSetUnit -- Core.Set#SET_UNIT
|
||||||
|
|
||||||
|
local AttackCount = self.AttackSetUnit:Count()
|
||||||
|
|
||||||
|
if AttackCount > 0 then
|
||||||
|
|
||||||
|
if DefenderGroup:IsAlive() then
|
||||||
|
|
||||||
|
-- Determine the distance to the target.
|
||||||
|
-- If it is less than 10km, then attack without a route.
|
||||||
|
-- Otherwise perform a route attack.
|
||||||
|
|
||||||
|
local DefenderCoord = DefenderGroup:GetPointVec3()
|
||||||
|
DefenderCoord:SetY( math.random( self.EngageFloorAltitude, self.EngageCeilingAltitude ) ) -- Ground targets don't have an altitude.
|
||||||
|
|
||||||
|
local TargetCoord = self.AttackSetUnit:GetFirst():GetPointVec3()
|
||||||
|
TargetCoord:SetY( math.random( self.EngageFloorAltitude, self.EngageCeilingAltitude ) ) -- Ground targets don't have an altitude.
|
||||||
|
|
||||||
|
local TargetDistance = DefenderCoord:Get2DDistance( TargetCoord )
|
||||||
|
|
||||||
|
local EngageRoute = {}
|
||||||
|
|
||||||
|
local ToTargetSpeed = math.random( self.EngageMinSpeed, self.EngageMaxSpeed )
|
||||||
|
|
||||||
|
--- Calculate the target route point.
|
||||||
|
|
||||||
|
local FromWP = DefenderCoord:WaypointAir(
|
||||||
|
self.PatrolAltType or "RADIO",
|
||||||
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
|
ToTargetSpeed,
|
||||||
|
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 ):WaypointAir(
|
||||||
|
self.PatrolAltType or "RADIO",
|
||||||
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
|
ToTargetSpeed,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
self:F( { Angle = FromEngageAngle, ToTargetSpeed = ToTargetSpeed } )
|
||||||
|
self:F( { self.EngageMinSpeed, self.EngageMaxSpeed, ToTargetSpeed } )
|
||||||
|
|
||||||
|
EngageRoute[#EngageRoute+1] = ToWP
|
||||||
|
|
||||||
|
local AttackTasks = {}
|
||||||
|
|
||||||
|
for AttackUnitID, AttackUnit in pairs( self.AttackSetUnit:GetSet() ) do
|
||||||
|
if AttackUnit:IsAlive() and AttackUnit:IsGround() then
|
||||||
|
self:T( { "Eliminating Unit:", AttackUnit:GetName() } )
|
||||||
|
AttackTasks[#AttackTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if #AttackTasks == 0 then
|
||||||
|
self:E( DefenderGroupName .. ": No targets found -> Going RTB")
|
||||||
|
self:Return()
|
||||||
|
self:__RTB( 0.5 )
|
||||||
|
else
|
||||||
|
DefenderGroup:OptionROEOpenFire()
|
||||||
|
DefenderGroup:OptionROTEvadeFire()
|
||||||
|
|
||||||
|
AttackTasks[#AttackTasks+1] = DefenderGroup:TaskFunction( "AI_A2G_ENGAGE.EngageRoute", self )
|
||||||
|
EngageRoute[#EngageRoute].task = DefenderGroup:TaskCombo( AttackTasks )
|
||||||
|
end
|
||||||
|
|
||||||
|
DefenderGroup:Route( EngageRoute, 0.5 )
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:E( DefenderGroupName .. ": No targets found -> Going RTB")
|
||||||
|
self:Return()
|
||||||
|
self:__RTB( 0.5 )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@ -810,6 +810,7 @@ do -- AI_A2G_DISPATCHER
|
|||||||
if Squadron then
|
if Squadron then
|
||||||
self:F( { SquadronName = Squadron.Name } )
|
self:F( { SquadronName = Squadron.Name } )
|
||||||
local LandingMethod = self:GetSquadronLanding( Squadron.Name )
|
local LandingMethod = self:GetSquadronLanding( Squadron.Name )
|
||||||
|
|
||||||
if LandingMethod == AI_A2G_DISPATCHER.Landing.AtRunway then
|
if LandingMethod == AI_A2G_DISPATCHER.Landing.AtRunway then
|
||||||
local DefenderSize = Defender:GetSize()
|
local DefenderSize = Defender:GetSize()
|
||||||
if DefenderSize == 1 then
|
if DefenderSize == 1 then
|
||||||
@ -1395,6 +1396,8 @@ do -- AI_A2G_DISPATCHER
|
|||||||
local DefenderSquadron = self:GetSquadron( SquadronName )
|
local DefenderSquadron = self:GetSquadron( SquadronName )
|
||||||
|
|
||||||
DefenderSquadron.Uncontrolled = true
|
DefenderSquadron.Uncontrolled = true
|
||||||
|
self:SetSquadronTakeoffFromParkingCold( SquadronName )
|
||||||
|
self:SetSquadronLandingAtEngineShutdown( SquadronName )
|
||||||
|
|
||||||
for SpawnTemplate, DefenderSpawn in pairs( self.DefenderSpawns ) do
|
for SpawnTemplate, DefenderSpawn in pairs( self.DefenderSpawns ) do
|
||||||
DefenderSpawn:InitUnControlled()
|
DefenderSpawn:InitUnControlled()
|
||||||
@ -1653,8 +1656,10 @@ do -- AI_A2G_DISPATCHER
|
|||||||
---
|
---
|
||||||
-- @param #AI_A2G_DISPATCHER self
|
-- @param #AI_A2G_DISPATCHER self
|
||||||
-- @param #string SquadronName The squadron name.
|
-- @param #string SquadronName The squadron name.
|
||||||
-- @param #number EngageMinSpeed The minimum speed at which the SEAD task can be executed.
|
-- @param #number EngageMinSpeed (optional, default = 50% of max speed) The minimum speed at which the SEAD task can be executed.
|
||||||
-- @param #number EngageMaxSpeed The maximum speed at which the SEAD task can be executed.
|
-- @param #number EngageMaxSpeed (optional, default = 75% of max speed) The maximum speed at which the SEAD task can be executed.
|
||||||
|
-- @param DCS#Altitude EngageFloorAltitude (optional, default = 1000m ) The lowest altitude in meters where to execute the engagement.
|
||||||
|
-- @param DCS#Altitude EngageCeilingAltitude (optional, default = 1500m ) The highest altitude in meters where to execute the engagement.
|
||||||
-- @usage
|
-- @usage
|
||||||
--
|
--
|
||||||
-- -- SEAD Squadron execution.
|
-- -- SEAD Squadron execution.
|
||||||
@ -1663,7 +1668,7 @@ do -- AI_A2G_DISPATCHER
|
|||||||
-- A2GDispatcher:SetSquadronSead( "Maykop", 900, 1200 )
|
-- A2GDispatcher:SetSquadronSead( "Maykop", 900, 1200 )
|
||||||
--
|
--
|
||||||
-- @return #AI_A2G_DISPATCHER
|
-- @return #AI_A2G_DISPATCHER
|
||||||
function AI_A2G_DISPATCHER:SetSquadronSead( SquadronName, EngageMinSpeed, EngageMaxSpeed )
|
function AI_A2G_DISPATCHER:SetSquadronSead( SquadronName, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude )
|
||||||
|
|
||||||
local DefenderSquadron = self:GetSquadron( SquadronName )
|
local DefenderSquadron = self:GetSquadron( SquadronName )
|
||||||
|
|
||||||
@ -1673,6 +1678,8 @@ do -- AI_A2G_DISPATCHER
|
|||||||
Sead.Name = SquadronName
|
Sead.Name = SquadronName
|
||||||
Sead.EngageMinSpeed = EngageMinSpeed
|
Sead.EngageMinSpeed = EngageMinSpeed
|
||||||
Sead.EngageMaxSpeed = EngageMaxSpeed
|
Sead.EngageMaxSpeed = EngageMaxSpeed
|
||||||
|
Sead.EngageFloorAltitude = EngageFloorAltitude
|
||||||
|
Sead.EngageCeilingAltitude = EngageCeilingAltitude
|
||||||
Sead.Defend = true
|
Sead.Defend = true
|
||||||
|
|
||||||
self:F( { Sead = Sead } )
|
self:F( { Sead = Sead } )
|
||||||
@ -1703,12 +1710,12 @@ do -- AI_A2G_DISPATCHER
|
|||||||
-- @param #AI_A2G_DISPATCHER self
|
-- @param #AI_A2G_DISPATCHER self
|
||||||
-- @param #string SquadronName The squadron name.
|
-- @param #string SquadronName The squadron name.
|
||||||
-- @param Core.Zone#ZONE_BASE Zone The @{Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
|
-- @param Core.Zone#ZONE_BASE Zone The @{Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
|
||||||
-- @param #number FloorAltitude The minimum altitude at which the cap can be executed.
|
-- @param #number FloorAltitude (optional, default = 1000m ) The minimum altitude at which the cap can be executed.
|
||||||
-- @param #number CeilingAltitude the maximum altitude at which the cap can be executed.
|
-- @param #number CeilingAltitude (optional, default = 1500m ) The maximum altitude at which the cap can be executed.
|
||||||
-- @param #number PatrolMinSpeed The minimum speed at which the cap can be executed.
|
-- @param #number PatrolMinSpeed (optional, default = 50% of max speed) The minimum speed at which the cap can be executed.
|
||||||
-- @param #number PatrolMaxSpeed The maximum speed at which the cap can be executed.
|
-- @param #number PatrolMaxSpeed (optional, default = 75% of max speed) The maximum speed at which the cap can be executed.
|
||||||
-- @param #number EngageMinSpeed The minimum speed at which the engage can be executed.
|
-- @param #number EngageMinSpeed (optional, default = 50% of max speed) The minimum speed at which the engage can be executed.
|
||||||
-- @param #number EngageMaxSpeed The maximum speed at which the engage can be executed.
|
-- @param #number EngageMaxSpeed (optional, default = 75% of max speed) The maximum speed at which the engage can be executed.
|
||||||
-- @param #number AltType The altitude type, which is a string "BARO" defining Barometric or "RADIO" defining radio controlled altitude.
|
-- @param #number AltType The altitude type, which is a string "BARO" defining Barometric or "RADIO" defining radio controlled altitude.
|
||||||
-- @return #AI_A2G_DISPATCHER
|
-- @return #AI_A2G_DISPATCHER
|
||||||
-- @usage
|
-- @usage
|
||||||
@ -1726,8 +1733,10 @@ do -- AI_A2G_DISPATCHER
|
|||||||
local SeadPatrol = DefenderSquadron.SEAD
|
local SeadPatrol = DefenderSquadron.SEAD
|
||||||
SeadPatrol.Name = SquadronName
|
SeadPatrol.Name = SquadronName
|
||||||
SeadPatrol.Zone = Zone
|
SeadPatrol.Zone = Zone
|
||||||
SeadPatrol.FloorAltitude = FloorAltitude
|
SeadPatrol.PatrolFloorAltitude = FloorAltitude
|
||||||
SeadPatrol.CeilingAltitude = CeilingAltitude
|
SeadPatrol.PatrolCeilingAltitude = CeilingAltitude
|
||||||
|
SeadPatrol.EngageFloorAltitude = FloorAltitude
|
||||||
|
SeadPatrol.EngageCeilingAltitude = CeilingAltitude
|
||||||
SeadPatrol.PatrolMinSpeed = PatrolMinSpeed
|
SeadPatrol.PatrolMinSpeed = PatrolMinSpeed
|
||||||
SeadPatrol.PatrolMaxSpeed = PatrolMaxSpeed
|
SeadPatrol.PatrolMaxSpeed = PatrolMaxSpeed
|
||||||
SeadPatrol.EngageMinSpeed = EngageMinSpeed
|
SeadPatrol.EngageMinSpeed = EngageMinSpeed
|
||||||
@ -1744,8 +1753,10 @@ do -- AI_A2G_DISPATCHER
|
|||||||
---
|
---
|
||||||
-- @param #AI_A2G_DISPATCHER self
|
-- @param #AI_A2G_DISPATCHER self
|
||||||
-- @param #string SquadronName The squadron name.
|
-- @param #string SquadronName The squadron name.
|
||||||
-- @param #number EngageMinSpeed The minimum speed at which the CAS task can be executed.
|
-- @param #number EngageMinSpeed (optional, default = 50% of max speed) The minimum speed at which the CAS task can be executed.
|
||||||
-- @param #number EngageMaxSpeed The maximum speed at which the CAS task can be executed.
|
-- @param #number EngageMaxSpeed (optional, default = 75% of max speed) The maximum speed at which the CAS task can be executed.
|
||||||
|
-- @param DCS#Altitude EngageFloorAltitude (optional, default = 1000m ) The lowest altitude in meters where to execute the engagement.
|
||||||
|
-- @param DCS#Altitude EngageCeilingAltitude (optional, default = 1500m ) The highest altitude in meters where to execute the engagement.
|
||||||
-- @usage
|
-- @usage
|
||||||
--
|
--
|
||||||
-- -- CAS Squadron execution.
|
-- -- CAS Squadron execution.
|
||||||
@ -1754,7 +1765,7 @@ do -- AI_A2G_DISPATCHER
|
|||||||
-- A2GDispatcher:SetSquadronCas( "Maykop", 900, 1200 )
|
-- A2GDispatcher:SetSquadronCas( "Maykop", 900, 1200 )
|
||||||
--
|
--
|
||||||
-- @return #AI_A2G_DISPATCHER
|
-- @return #AI_A2G_DISPATCHER
|
||||||
function AI_A2G_DISPATCHER:SetSquadronCas( SquadronName, EngageMinSpeed, EngageMaxSpeed )
|
function AI_A2G_DISPATCHER:SetSquadronCas( SquadronName, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude )
|
||||||
|
|
||||||
local DefenderSquadron = self:GetSquadron( SquadronName )
|
local DefenderSquadron = self:GetSquadron( SquadronName )
|
||||||
|
|
||||||
@ -1764,6 +1775,8 @@ do -- AI_A2G_DISPATCHER
|
|||||||
Cas.Name = SquadronName
|
Cas.Name = SquadronName
|
||||||
Cas.EngageMinSpeed = EngageMinSpeed
|
Cas.EngageMinSpeed = EngageMinSpeed
|
||||||
Cas.EngageMaxSpeed = EngageMaxSpeed
|
Cas.EngageMaxSpeed = EngageMaxSpeed
|
||||||
|
Cas.EngageFloorAltitude = EngageFloorAltitude
|
||||||
|
Cas.EngageCeilingAltitude = EngageCeilingAltitude
|
||||||
Cas.Defend = true
|
Cas.Defend = true
|
||||||
|
|
||||||
self:F( { Cas = Cas } )
|
self:F( { Cas = Cas } )
|
||||||
@ -1795,12 +1808,12 @@ do -- AI_A2G_DISPATCHER
|
|||||||
-- @param #AI_A2G_DISPATCHER self
|
-- @param #AI_A2G_DISPATCHER self
|
||||||
-- @param #string SquadronName The squadron name.
|
-- @param #string SquadronName The squadron name.
|
||||||
-- @param Core.Zone#ZONE_BASE Zone The @{Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
|
-- @param Core.Zone#ZONE_BASE Zone The @{Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
|
||||||
-- @param #number FloorAltitude The minimum altitude at which the cap can be executed.
|
-- @param #number FloorAltitude (optional, default = 1000m ) The minimum altitude at which the cap can be executed.
|
||||||
-- @param #number CeilingAltitude the maximum altitude at which the cap can be executed.
|
-- @param #number CeilingAltitude (optional, default = 1500m ) The maximum altitude at which the cap can be executed.
|
||||||
-- @param #number PatrolMinSpeed The minimum speed at which the cap can be executed.
|
-- @param #number PatrolMinSpeed (optional, default = 50% of max speed) The minimum speed at which the cap can be executed.
|
||||||
-- @param #number PatrolMaxSpeed The maximum speed at which the cap can be executed.
|
-- @param #number PatrolMaxSpeed (optional, default = 75% of max speed) The maximum speed at which the cap can be executed.
|
||||||
-- @param #number EngageMinSpeed The minimum speed at which the engage can be executed.
|
-- @param #number EngageMinSpeed (optional, default = 50% of max speed) The minimum speed at which the engage can be executed.
|
||||||
-- @param #number EngageMaxSpeed The maximum speed at which the engage can be executed.
|
-- @param #number EngageMaxSpeed (optional, default = 75% of max speed) The maximum speed at which the engage can be executed.
|
||||||
-- @param #number AltType The altitude type, which is a string "BARO" defining Barometric or "RADIO" defining radio controlled altitude.
|
-- @param #number AltType The altitude type, which is a string "BARO" defining Barometric or "RADIO" defining radio controlled altitude.
|
||||||
-- @return #AI_A2G_DISPATCHER
|
-- @return #AI_A2G_DISPATCHER
|
||||||
-- @usage
|
-- @usage
|
||||||
@ -1818,8 +1831,10 @@ do -- AI_A2G_DISPATCHER
|
|||||||
local CasPatrol = DefenderSquadron.CAS
|
local CasPatrol = DefenderSquadron.CAS
|
||||||
CasPatrol.Name = SquadronName
|
CasPatrol.Name = SquadronName
|
||||||
CasPatrol.Zone = Zone
|
CasPatrol.Zone = Zone
|
||||||
CasPatrol.FloorAltitude = FloorAltitude
|
CasPatrol.PatrolFloorAltitude = FloorAltitude
|
||||||
CasPatrol.CeilingAltitude = CeilingAltitude
|
CasPatrol.PatrolCeilingAltitude = CeilingAltitude
|
||||||
|
CasPatrol.EngageFloorAltitude = FloorAltitude
|
||||||
|
CasPatrol.EngageCeilingAltitude = CeilingAltitude
|
||||||
CasPatrol.PatrolMinSpeed = PatrolMinSpeed
|
CasPatrol.PatrolMinSpeed = PatrolMinSpeed
|
||||||
CasPatrol.PatrolMaxSpeed = PatrolMaxSpeed
|
CasPatrol.PatrolMaxSpeed = PatrolMaxSpeed
|
||||||
CasPatrol.EngageMinSpeed = EngageMinSpeed
|
CasPatrol.EngageMinSpeed = EngageMinSpeed
|
||||||
@ -1836,8 +1851,10 @@ do -- AI_A2G_DISPATCHER
|
|||||||
---
|
---
|
||||||
-- @param #AI_A2G_DISPATCHER self
|
-- @param #AI_A2G_DISPATCHER self
|
||||||
-- @param #string SquadronName The squadron name.
|
-- @param #string SquadronName The squadron name.
|
||||||
-- @param #number EngageMinSpeed The minimum speed at which the BAI task can be executed.
|
-- @param #number EngageMinSpeed (optional, default = 50% of max speed) The minimum speed at which the BAI task can be executed.
|
||||||
-- @param #number EngageMaxSpeed The maximum speed at which the BAI task can be executed.
|
-- @param #number EngageMaxSpeed (optional, default = 75% of max speed) The maximum speed at which the BAI task can be executed.
|
||||||
|
-- @param DCS#Altitude EngageFloorAltitude (optional, default = 1000m ) The lowest altitude in meters where to execute the engagement.
|
||||||
|
-- @param DCS#Altitude EngageCeilingAltitude (optional, default = 1500m ) The highest altitude in meters where to execute the engagement.
|
||||||
-- @usage
|
-- @usage
|
||||||
--
|
--
|
||||||
-- -- BAI Squadron execution.
|
-- -- BAI Squadron execution.
|
||||||
@ -1846,7 +1863,7 @@ do -- AI_A2G_DISPATCHER
|
|||||||
-- A2GDispatcher:SetSquadronBai( "Maykop", 900, 1200 )
|
-- A2GDispatcher:SetSquadronBai( "Maykop", 900, 1200 )
|
||||||
--
|
--
|
||||||
-- @return #AI_A2G_DISPATCHER
|
-- @return #AI_A2G_DISPATCHER
|
||||||
function AI_A2G_DISPATCHER:SetSquadronBai( SquadronName, EngageMinSpeed, EngageMaxSpeed )
|
function AI_A2G_DISPATCHER:SetSquadronBai( SquadronName, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude )
|
||||||
|
|
||||||
local DefenderSquadron = self:GetSquadron( SquadronName )
|
local DefenderSquadron = self:GetSquadron( SquadronName )
|
||||||
|
|
||||||
@ -1856,6 +1873,8 @@ do -- AI_A2G_DISPATCHER
|
|||||||
Bai.Name = SquadronName
|
Bai.Name = SquadronName
|
||||||
Bai.EngageMinSpeed = EngageMinSpeed
|
Bai.EngageMinSpeed = EngageMinSpeed
|
||||||
Bai.EngageMaxSpeed = EngageMaxSpeed
|
Bai.EngageMaxSpeed = EngageMaxSpeed
|
||||||
|
Bai.EngageFloorAltitude = EngageFloorAltitude
|
||||||
|
Bai.EngageCeilingAltitude = EngageCeilingAltitude
|
||||||
Bai.Defend = true
|
Bai.Defend = true
|
||||||
|
|
||||||
self:F( { Bai = Bai } )
|
self:F( { Bai = Bai } )
|
||||||
@ -1885,12 +1904,12 @@ do -- AI_A2G_DISPATCHER
|
|||||||
-- @param #AI_A2G_DISPATCHER self
|
-- @param #AI_A2G_DISPATCHER self
|
||||||
-- @param #string SquadronName The squadron name.
|
-- @param #string SquadronName The squadron name.
|
||||||
-- @param Core.Zone#ZONE_BASE Zone The @{Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
|
-- @param Core.Zone#ZONE_BASE Zone The @{Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
|
||||||
-- @param #number FloorAltitude The minimum altitude at which the cap can be executed.
|
-- @param #number FloorAltitude (optional, default = 1000m ) The minimum altitude at which the cap can be executed.
|
||||||
-- @param #number CeilingAltitude the maximum altitude at which the cap can be executed.
|
-- @param #number CeilingAltitude (optional, default = 1500m ) The maximum altitude at which the cap can be executed.
|
||||||
-- @param #number PatrolMinSpeed The minimum speed at which the cap can be executed.
|
-- @param #number PatrolMinSpeed (optional, default = 50% of max speed) The minimum speed at which the cap can be executed.
|
||||||
-- @param #number PatrolMaxSpeed The maximum speed at which the cap can be executed.
|
-- @param #number PatrolMaxSpeed (optional, default = 75% of max speed) The maximum speed at which the cap can be executed.
|
||||||
-- @param #number EngageMinSpeed The minimum speed at which the engage can be executed.
|
-- @param #number EngageMinSpeed (optional, default = 50% of max speed) The minimum speed at which the engage can be executed.
|
||||||
-- @param #number EngageMaxSpeed The maximum speed at which the engage can be executed.
|
-- @param #number EngageMaxSpeed (optional, default = 75% of max speed) The maximum speed at which the engage can be executed.
|
||||||
-- @param #number AltType The altitude type, which is a string "BARO" defining Barometric or "RADIO" defining radio controlled altitude.
|
-- @param #number AltType The altitude type, which is a string "BARO" defining Barometric or "RADIO" defining radio controlled altitude.
|
||||||
-- @return #AI_A2G_DISPATCHER
|
-- @return #AI_A2G_DISPATCHER
|
||||||
-- @usage
|
-- @usage
|
||||||
@ -1908,8 +1927,10 @@ do -- AI_A2G_DISPATCHER
|
|||||||
local BaiPatrol = DefenderSquadron.BAI
|
local BaiPatrol = DefenderSquadron.BAI
|
||||||
BaiPatrol.Name = SquadronName
|
BaiPatrol.Name = SquadronName
|
||||||
BaiPatrol.Zone = Zone
|
BaiPatrol.Zone = Zone
|
||||||
BaiPatrol.FloorAltitude = FloorAltitude
|
BaiPatrol.PatrolFloorAltitude = FloorAltitude
|
||||||
BaiPatrol.CeilingAltitude = CeilingAltitude
|
BaiPatrol.PatrolCeilingAltitude = CeilingAltitude
|
||||||
|
BaiPatrol.EngageFloorAltitude = FloorAltitude
|
||||||
|
BaiPatrol.EngageCeilingAltitude = CeilingAltitude
|
||||||
BaiPatrol.PatrolMinSpeed = PatrolMinSpeed
|
BaiPatrol.PatrolMinSpeed = PatrolMinSpeed
|
||||||
BaiPatrol.PatrolMaxSpeed = PatrolMaxSpeed
|
BaiPatrol.PatrolMaxSpeed = PatrolMaxSpeed
|
||||||
BaiPatrol.EngageMinSpeed = EngageMinSpeed
|
BaiPatrol.EngageMinSpeed = EngageMinSpeed
|
||||||
@ -2856,13 +2877,16 @@ do -- AI_A2G_DISPATCHER
|
|||||||
if DefenderUnitIndex == 1 then
|
if DefenderUnitIndex == 1 then
|
||||||
DefenderPatrolTemplate = UTILS.DeepCopy( DefenderTemplate )
|
DefenderPatrolTemplate = UTILS.DeepCopy( DefenderTemplate )
|
||||||
self.DefenderPatrolIndex = self.DefenderPatrolIndex + 1
|
self.DefenderPatrolIndex = self.DefenderPatrolIndex + 1
|
||||||
DefenderPatrolTemplate.name = SquadronName .. "#" .. self.DefenderPatrolIndex .. "#" .. GroupName
|
--DefenderPatrolTemplate.name = SquadronName .. "#" .. self.DefenderPatrolIndex .. "#" .. GroupName
|
||||||
|
DefenderPatrolTemplate.name = GroupName
|
||||||
DefenderName = DefenderPatrolTemplate.name
|
DefenderName = DefenderPatrolTemplate.name
|
||||||
else
|
else
|
||||||
-- Add the unit in the template to the DefenderPatrolTemplate.
|
-- Add the unit in the template to the DefenderPatrolTemplate.
|
||||||
local DefenderUnitTemplate = DefenderTemplate.units[1]
|
local DefenderUnitTemplate = DefenderTemplate.units[1]
|
||||||
DefenderPatrolTemplate.units[DefenderUnitIndex] = DefenderUnitTemplate
|
DefenderPatrolTemplate.units[DefenderUnitIndex] = DefenderUnitTemplate
|
||||||
end
|
end
|
||||||
|
DefenderPatrolTemplate.units[DefenderUnitIndex].name = string.format( DefenderPatrolTemplate.name .. '-%02d', DefenderUnitIndex )
|
||||||
|
DefenderPatrolTemplate.units[DefenderUnitIndex].unitId = nil
|
||||||
DefenderUnitIndex = DefenderUnitIndex + 1
|
DefenderUnitIndex = DefenderUnitIndex + 1
|
||||||
DefenderSquadron.Resources[TemplateID][GroupName] = nil
|
DefenderSquadron.Resources[TemplateID][GroupName] = nil
|
||||||
if DefenderUnitIndex > DefenderGrouping then
|
if DefenderUnitIndex > DefenderGrouping then
|
||||||
@ -2880,8 +2904,8 @@ do -- AI_A2G_DISPATCHER
|
|||||||
DefenderPatrolTemplate.route.points[1].type = GROUPTEMPLATE.Takeoff[Takeoff][1] -- type
|
DefenderPatrolTemplate.route.points[1].type = GROUPTEMPLATE.Takeoff[Takeoff][1] -- type
|
||||||
DefenderPatrolTemplate.route.points[1].action = GROUPTEMPLATE.Takeoff[Takeoff][2] -- action
|
DefenderPatrolTemplate.route.points[1].action = GROUPTEMPLATE.Takeoff[Takeoff][2] -- action
|
||||||
local Defender = _DATABASE:Spawn( DefenderPatrolTemplate )
|
local Defender = _DATABASE:Spawn( DefenderPatrolTemplate )
|
||||||
|
|
||||||
self:AddDefenderToSquadron( DefenderSquadron, Defender, DefenderGrouping )
|
self:AddDefenderToSquadron( DefenderSquadron, Defender, DefenderGrouping )
|
||||||
|
Defender:Activate()
|
||||||
return Defender, DefenderGrouping
|
return Defender, DefenderGrouping
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -2915,7 +2939,9 @@ do -- AI_A2G_DISPATCHER
|
|||||||
|
|
||||||
if DefenderPatrol then
|
if DefenderPatrol then
|
||||||
|
|
||||||
local Fsm = AI_A2G_PATROL:New( DefenderPatrol, Patrol.Zone, Patrol.FloorAltitude, Patrol.CeilingAltitude, Patrol.PatrolMinSpeed, Patrol.PatrolMaxSpeed, Patrol.EngageMinSpeed, Patrol.EngageMaxSpeed, Patrol.AltType )
|
local AI_A2G_PATROL = { SEAD = AI_A2G_SEAD, BAI = AI_A2G_BAI, CAS = AI_A2G_CAS }
|
||||||
|
|
||||||
|
local Fsm = AI_A2G_PATROL[DefenseTaskType]:New( DefenderPatrol, Patrol.EngageMinSpeed, Patrol.EngageMaxSpeed, Patrol.EngageFloorAltitude, Patrol.EngageCeilingAltitude, Patrol.Zone, Patrol.PatrolFloorAltitude, Patrol.PatrolCeilingAltitude, Patrol.PatrolMinSpeed, Patrol.PatrolMaxSpeed, Patrol.AltType )
|
||||||
Fsm:SetDispatcher( self )
|
Fsm:SetDispatcher( self )
|
||||||
Fsm:SetHomeAirbase( DefenderSquadron.Airbase )
|
Fsm:SetHomeAirbase( DefenderSquadron.Airbase )
|
||||||
Fsm:SetFuelThreshold( DefenderSquadron.FuelThreshold or self.DefenderDefault.FuelThreshold, 60 )
|
Fsm:SetFuelThreshold( DefenderSquadron.FuelThreshold or self.DefenderDefault.FuelThreshold, 60 )
|
||||||
@ -2924,7 +2950,7 @@ do -- AI_A2G_DISPATCHER
|
|||||||
Fsm:SetTanker( DefenderSquadron.TankerName or self.DefenderDefault.TankerName )
|
Fsm:SetTanker( DefenderSquadron.TankerName or self.DefenderDefault.TankerName )
|
||||||
Fsm:Start()
|
Fsm:Start()
|
||||||
|
|
||||||
self:SetDefenderTask( SquadronName, DefenderPatrol, DefenseTaskType, Fsm )
|
self:SetDefenderTask( SquadronName, DefenderPatrol, DefenseTaskType, Fsm, nil, DefenderGrouping )
|
||||||
|
|
||||||
function Fsm:onafterTakeoff( Defender, From, Event, To )
|
function Fsm:onafterTakeoff( Defender, From, Event, To )
|
||||||
self:F({"Patrol Birth", Defender:GetName()})
|
self:F({"Patrol Birth", Defender:GetName()})
|
||||||
@ -2961,7 +2987,7 @@ do -- AI_A2G_DISPATCHER
|
|||||||
if Dispatcher:GetSquadronLanding( Squadron.Name ) == AI_A2G_DISPATCHER.Landing.NearAirbase then
|
if Dispatcher:GetSquadronLanding( Squadron.Name ) == AI_A2G_DISPATCHER.Landing.NearAirbase then
|
||||||
Dispatcher:RemoveDefenderFromSquadron( Squadron, Defender )
|
Dispatcher:RemoveDefenderFromSquadron( Squadron, Defender )
|
||||||
Defender:Destroy()
|
Defender:Destroy()
|
||||||
self:ParkDefender( Squadron, Defender )
|
Dispatcher:ParkDefender( Squadron, Defender )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -2993,6 +3019,8 @@ do -- AI_A2G_DISPATCHER
|
|||||||
|
|
||||||
self:F( { From, Event, To, AttackerDetection.Index, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing, DefenderFriendlies = DefenderFriendlies } )
|
self:F( { From, Event, To, AttackerDetection.Index, DefendersEngaged = DefendersEngaged, DefendersMissing = DefendersMissing, DefenderFriendlies = DefenderFriendlies } )
|
||||||
|
|
||||||
|
AttackerDetection.Type = DefenseTaskType -- This is set to report the task type in the status panel.
|
||||||
|
|
||||||
local AttackerSet = AttackerDetection.Set
|
local AttackerSet = AttackerDetection.Set
|
||||||
local AttackerUnit = AttackerSet:GetFirst()
|
local AttackerUnit = AttackerSet:GetFirst()
|
||||||
|
|
||||||
@ -3103,7 +3131,9 @@ do -- AI_A2G_DISPATCHER
|
|||||||
|
|
||||||
DefenderCount = DefenderCount - DefenderGrouping / DefenderOverhead
|
DefenderCount = DefenderCount - DefenderGrouping / DefenderOverhead
|
||||||
|
|
||||||
local Fsm = AI_A2G_ENGAGE:New( DefenderGroup, Defense.EngageMinSpeed, Defense.EngageMaxSpeed )
|
local AI_A2G_ENGAGE = { SEAD = AI_A2G_SEAD, BAI = AI_A2G_BAI, CAS = AI_A2G_CAS }
|
||||||
|
|
||||||
|
local Fsm = AI_A2G_ENGAGE[DefenseTaskType]:New( DefenderGroup, Defense.EngageMinSpeed, Defense.EngageMaxSpeed, Defense.EngageFloorAltitude, Defense.EngageCeilingAltitude ) -- AI.AI_A2G_ENGAGE
|
||||||
Fsm:SetDispatcher( self )
|
Fsm:SetDispatcher( self )
|
||||||
Fsm:SetHomeAirbase( DefenderSquadron.Airbase )
|
Fsm:SetHomeAirbase( DefenderSquadron.Airbase )
|
||||||
Fsm:SetFuelThreshold( DefenderSquadron.FuelThreshold or self.DefenderDefault.FuelThreshold, 60 )
|
Fsm:SetFuelThreshold( DefenderSquadron.FuelThreshold or self.DefenderDefault.FuelThreshold, 60 )
|
||||||
@ -3121,6 +3151,8 @@ do -- AI_A2G_DISPATCHER
|
|||||||
local Squadron = Dispatcher:GetSquadronFromDefender( Defender )
|
local Squadron = Dispatcher:GetSquadronFromDefender( Defender )
|
||||||
local DefenderTarget = Dispatcher:GetDefenderTaskTarget( Defender )
|
local DefenderTarget = Dispatcher:GetDefenderTaskTarget( Defender )
|
||||||
|
|
||||||
|
self:F( { DefenderTarget = DefenderTarget } )
|
||||||
|
|
||||||
if DefenderTarget then
|
if DefenderTarget then
|
||||||
Fsm:__Engage( 2, DefenderTarget.Set ) -- Engage on the TargetSetUnit
|
Fsm:__Engage( 2, DefenderTarget.Set ) -- Engage on the TargetSetUnit
|
||||||
end
|
end
|
||||||
@ -3141,10 +3173,10 @@ do -- AI_A2G_DISPATCHER
|
|||||||
|
|
||||||
local Dispatcher = Fsm:GetDispatcher() -- #AI_A2G_DISPATCHER
|
local Dispatcher = Fsm:GetDispatcher() -- #AI_A2G_DISPATCHER
|
||||||
local Squadron = Dispatcher:GetSquadronFromDefender( Defender )
|
local Squadron = Dispatcher:GetSquadronFromDefender( Defender )
|
||||||
if Defender:IsAboveRunway() then
|
--if Defender:IsAboveRunway() then
|
||||||
Dispatcher:RemoveDefenderFromSquadron( Squadron, Defender )
|
--Dispatcher:RemoveDefenderFromSquadron( Squadron, Defender )
|
||||||
Defender:Destroy()
|
--Defender:Destroy()
|
||||||
end
|
--end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_A2G_DISPATCHER self
|
--- @param #AI_A2G_DISPATCHER self
|
||||||
@ -3163,7 +3195,7 @@ do -- AI_A2G_DISPATCHER
|
|||||||
if Dispatcher:GetSquadronLanding( Squadron.Name ) == AI_A2G_DISPATCHER.Landing.NearAirbase then
|
if Dispatcher:GetSquadronLanding( Squadron.Name ) == AI_A2G_DISPATCHER.Landing.NearAirbase then
|
||||||
Dispatcher:RemoveDefenderFromSquadron( Squadron, Defender )
|
Dispatcher:RemoveDefenderFromSquadron( Squadron, Defender )
|
||||||
Defender:Destroy()
|
Defender:Destroy()
|
||||||
self:ParkDefender( Squadron, Defender )
|
Dispatcher:ParkDefender( Squadron, Defender )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end -- if DefenderGCI then
|
end -- if DefenderGCI then
|
||||||
@ -3298,8 +3330,11 @@ do -- AI_A2G_DISPATCHER
|
|||||||
|
|
||||||
for DefenderGroup, DefenderTask in pairs( self:GetDefenderTasks() ) do
|
for DefenderGroup, DefenderTask in pairs( self:GetDefenderTasks() ) do
|
||||||
local DefenderGroup = DefenderGroup -- Wrapper.Group#GROUP
|
local DefenderGroup = DefenderGroup -- Wrapper.Group#GROUP
|
||||||
|
local DefenderTaskFsm = self:GetDefenderTaskFsm( DefenderGroup )
|
||||||
|
if DefenderTaskFsm:Is( "LostControl" ) then
|
||||||
|
self:ClearDefenderTask( DefenderGroup )
|
||||||
|
end
|
||||||
if not DefenderGroup:IsAlive() then
|
if not DefenderGroup:IsAlive() then
|
||||||
local DefenderTaskFsm = self:GetDefenderTaskFsm( DefenderGroup )
|
|
||||||
self:F( { Defender = DefenderGroup:GetName(), DefenderState = DefenderTaskFsm:GetState() } )
|
self:F( { Defender = DefenderGroup:GetName(), DefenderState = DefenderTaskFsm:GetState() } )
|
||||||
if not DefenderTaskFsm:Is( "Started" ) then
|
if not DefenderTaskFsm:Is( "Started" ) then
|
||||||
self:ClearDefenderTask( DefenderGroup )
|
self:ClearDefenderTask( DefenderGroup )
|
||||||
@ -3312,10 +3347,10 @@ do -- AI_A2G_DISPATCHER
|
|||||||
self:ClearDefenderTaskTarget( DefenderGroup )
|
self:ClearDefenderTaskTarget( DefenderGroup )
|
||||||
else
|
else
|
||||||
if DefenderTask.Target.Set then
|
if DefenderTask.Target.Set then
|
||||||
local AttackerCount = DefenderTask.Target.Set:Count()
|
local TargetCount = DefenderTask.Target.Set:Count()
|
||||||
if AttackerCount == 0 then
|
if TargetCount == 0 then
|
||||||
self:F( { "All Targets destroyed in Target, removing:", DefenderTask.Target.Index } )
|
self:F( { "All Targets destroyed in Target, removing:", DefenderTask.Target.Index } )
|
||||||
self:ClearDefenderTaskTarget( DefenderGroup )
|
self:ClearDefenderTask( DefenderGroup )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -3410,7 +3445,7 @@ do -- AI_A2G_DISPATCHER
|
|||||||
|
|
||||||
if self.TacticalDisplay then
|
if self.TacticalDisplay then
|
||||||
-- Show tactical situation
|
-- Show tactical situation
|
||||||
Report:Add( string.format( "\n - Target %s ( %s ): ( #%d ) %s" , DetectedItem.ItemID, DetectedItem.Index, DetectedItem.Set:Count(), DetectedItem.Set:GetObjectNames() ) )
|
Report:Add( string.format( "\n - %4s %s ( %s ): ( #%d ) %s" , DetectedItem.Type or " --- ", DetectedItem.ItemID, DetectedItem.Index, DetectedItem.Set:Count(), DetectedItem.Set:GetObjectNames() ) )
|
||||||
for Defender, DefenderTask in pairs( self:GetDefenderTasks() ) do
|
for Defender, DefenderTask in pairs( self:GetDefenderTasks() ) do
|
||||||
local Defender = Defender -- Wrapper.Group#GROUP
|
local Defender = Defender -- Wrapper.Group#GROUP
|
||||||
if DefenderTask.Target and DefenderTask.Target.Index == DetectedItem.Index then
|
if DefenderTask.Target and DefenderTask.Target.Index == DetectedItem.Index then
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
|
|
||||||
--- @type AI_A2G_ENGAGE
|
--- @type AI_A2G_ENGAGE
|
||||||
-- @extends AI.AI_A2A#AI_A2A
|
-- @extends AI.AI_A2G#AI_A2G
|
||||||
|
|
||||||
|
|
||||||
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
|
||||||
@ -81,8 +81,12 @@ AI_A2G_ENGAGE = {
|
|||||||
--- Creates a new AI_A2G_ENGAGE object
|
--- Creates a new AI_A2G_ENGAGE object
|
||||||
-- @param #AI_A2G_ENGAGE self
|
-- @param #AI_A2G_ENGAGE self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup
|
-- @param Wrapper.Group#GROUP AIGroup
|
||||||
|
-- @param DCS#Speed EngageMinSpeed (optional, default = 50% of max speed) The minimum speed of the @{Wrapper.Group} in km/h when engaging a target.
|
||||||
|
-- @param DCS#Speed EngageMaxSpeed (optional, default = 75% of max speed) The maximum speed of the @{Wrapper.Group} in km/h when engaging a target.
|
||||||
|
-- @param DCS#Altitude EngageFloorAltitude (optional, default = 1000m ) The lowest altitude in meters where to execute the engagement.
|
||||||
|
-- @param DCS#Altitude EngageCeilingAltitude (optional, default = 1500m ) The highest altitude in meters where to execute the engagement.
|
||||||
-- @return #AI_A2G_ENGAGE
|
-- @return #AI_A2G_ENGAGE
|
||||||
function AI_A2G_ENGAGE:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
|
function AI_A2G_ENGAGE:New( AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude )
|
||||||
|
|
||||||
-- Inherits from BASE
|
-- Inherits from BASE
|
||||||
local self = BASE:Inherit( self, AI_A2G:New( AIGroup ) ) -- #AI_A2G_ENGAGE
|
local self = BASE:Inherit( self, AI_A2G:New( AIGroup ) ) -- #AI_A2G_ENGAGE
|
||||||
@ -90,14 +94,14 @@ function AI_A2G_ENGAGE:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
|
|||||||
self.Accomplished = false
|
self.Accomplished = false
|
||||||
self.Engaging = false
|
self.Engaging = false
|
||||||
|
|
||||||
self.EngageMinSpeed = EngageMinSpeed
|
local SpeedMax = AIGroup:GetSpeedMax()
|
||||||
self.EngageMaxSpeed = EngageMaxSpeed
|
|
||||||
self.PatrolMinSpeed = EngageMinSpeed
|
|
||||||
self.PatrolMaxSpeed = EngageMaxSpeed
|
|
||||||
|
|
||||||
self.PatrolAltType = "RADIO"
|
self.EngageMinSpeed = EngageMinSpeed or SpeedMax * 0.5
|
||||||
|
self.EngageMaxSpeed = EngageMaxSpeed or SpeedMax * 0.75
|
||||||
|
self.EngageFloorAltitude = EngageFloorAltitude or 1000
|
||||||
|
self.EngageCeilingAltitude = EngageCeilingAltitude or 1500
|
||||||
|
|
||||||
self:AddTransition( { "Started", "Engaging", "Returning", "Airborne" }, "Engage", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_A2G_ENGAGE.
|
self:AddTransition( { "Started", "Engaging", "Returning", "Airborne", "Patrolling" }, "Engage", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_A2G_ENGAGE.
|
||||||
|
|
||||||
--- OnBefore Transition Handler for Event Engage.
|
--- OnBefore Transition Handler for Event Engage.
|
||||||
-- @function [parent=#AI_A2G_ENGAGE] OnBeforeEngage
|
-- @function [parent=#AI_A2G_ENGAGE] OnBeforeEngage
|
||||||
@ -266,7 +270,8 @@ end
|
|||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2G_ENGAGE:onafterStart( AIGroup, From, Event, To )
|
function AI_A2G_ENGAGE:onafterStart( AIGroup, From, Event, To )
|
||||||
|
|
||||||
self:GetParent( self ).onafterStart( self, AIGroup, From, Event, To )
|
self:GetParent( self, AI_A2G_ENGAGE ).onafterStart( self, AIGroup, From, Event, To )
|
||||||
|
|
||||||
AIGroup:HandleEvent( EVENTS.Takeoff, nil, self )
|
AIGroup:HandleEvent( EVENTS.Takeoff, nil, self )
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -327,81 +332,14 @@ end
|
|||||||
|
|
||||||
|
|
||||||
--- @param #AI_A2G_ENGAGE self
|
--- @param #AI_A2G_ENGAGE self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The GroupGroup managed by the FSM.
|
-- @param Wrapper.Group#GROUP DefenderGroup The GroupGroup managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2G_ENGAGE:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
|
function AI_A2G_ENGAGE:onafterEngage( DefenderGroup, From, Event, To, AttackSetUnit )
|
||||||
|
|
||||||
self:F( { AIGroup, From, Event, To, AttackSetUnit} )
|
self:F( { DefenderGroup, From, Event, To, AttackSetUnit} )
|
||||||
|
|
||||||
self.AttackSetUnit = AttackSetUnit or self.AttackSetUnit -- Core.Set#SET_UNIT
|
|
||||||
|
|
||||||
local FirstAttackUnit = self.AttackSetUnit:GetFirst()
|
|
||||||
|
|
||||||
if FirstAttackUnit and FirstAttackUnit:IsAlive() then
|
|
||||||
|
|
||||||
if AIGroup:IsAlive() then
|
|
||||||
|
|
||||||
local EngageRoute = {}
|
|
||||||
|
|
||||||
local CurrentCoord = AIGroup:GetCoordinate()
|
|
||||||
|
|
||||||
--- Calculate the target route point.
|
|
||||||
|
|
||||||
local CurrentCoord = AIGroup:GetCoordinate()
|
|
||||||
|
|
||||||
local ToTargetCoord = self.AttackSetUnit:GetFirst():GetCoordinate()
|
|
||||||
self:SetTargetDistance( ToTargetCoord ) -- For RTB status check
|
|
||||||
|
|
||||||
local ToTargetSpeed = math.random( self.EngageMinSpeed, self.EngageMaxSpeed )
|
|
||||||
local ToEngageAngle = CurrentCoord:GetAngleDegrees( CurrentCoord:GetDirectionVec3( ToTargetCoord ) )
|
|
||||||
|
|
||||||
--- Create a route point of type air.
|
|
||||||
local ToPatrolRoutePoint = CurrentCoord:Translate( 15000, ToEngageAngle ):WaypointAir(
|
|
||||||
self.PatrolAltType,
|
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
|
||||||
ToTargetSpeed,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
|
|
||||||
self:F( { Angle = ToEngageAngle, ToTargetSpeed = ToTargetSpeed } )
|
|
||||||
self:F( { self.EngageMinSpeed, self.EngageMaxSpeed, ToTargetSpeed } )
|
|
||||||
|
|
||||||
EngageRoute[#EngageRoute+1] = ToPatrolRoutePoint
|
|
||||||
EngageRoute[#EngageRoute+1] = ToPatrolRoutePoint
|
|
||||||
|
|
||||||
local AttackTasks = {}
|
|
||||||
|
|
||||||
for AttackUnitID, AttackUnit in pairs( self.AttackSetUnit:GetSet() ) do
|
|
||||||
local AttackUnit = AttackUnit -- Wrapper.Unit#UNIT
|
|
||||||
if AttackUnit:IsAlive() and AttackUnit:IsGround() then
|
|
||||||
self:T( { "Eliminating Unit:", AttackUnit:GetName(), AttackUnit:IsAlive(), AttackUnit:IsGround() } )
|
|
||||||
AttackTasks[#AttackTasks+1] = AIGroup:TaskAttackUnit( AttackUnit )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if #AttackTasks == 0 then
|
|
||||||
self:E("No targets found -> Going RTB")
|
|
||||||
self:Return()
|
|
||||||
self:__RTB( 0.5 )
|
|
||||||
else
|
|
||||||
AIGroup:OptionROEOpenFire()
|
|
||||||
AIGroup:OptionROTEvadeFire()
|
|
||||||
|
|
||||||
AttackTasks[#AttackTasks+1] = AIGroup:TaskFunction( "AI_A2G_ENGAGE.EngageRoute", self )
|
|
||||||
EngageRoute[#EngageRoute].task = AIGroup:TaskCombo( AttackTasks )
|
|
||||||
end
|
|
||||||
|
|
||||||
AIGroup:Route( EngageRoute, 0.5 )
|
|
||||||
|
|
||||||
end
|
|
||||||
else
|
|
||||||
self:E("No targets found -> Going RTB")
|
|
||||||
self:Return()
|
|
||||||
self:__RTB( 0.5 )
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_A2G_ENGAGE self
|
--- @param #AI_A2G_ENGAGE self
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
-- @image AI_Air_To_Ground_Patrol.JPG
|
-- @image AI_Air_To_Ground_Patrol.JPG
|
||||||
|
|
||||||
--- @type AI_A2G_PATROL
|
--- @type AI_A2G_PATROL
|
||||||
-- @extends AI.AI_A2A_Patrol#AI_A2A_PATROL
|
-- @extends AI.AI_A2G_Engage#AI_A2G_ENGAGE
|
||||||
|
|
||||||
|
|
||||||
--- The AI_A2G_PATROL class implements the core functions to patrol a @{Zone} by an AI @{Wrapper.Group} or @{Wrapper.Group}
|
--- The AI_A2G_PATROL class implements the core functions to patrol a @{Zone} by an AI @{Wrapper.Group} or @{Wrapper.Group}
|
||||||
@ -99,31 +99,39 @@ AI_A2G_PATROL = {
|
|||||||
|
|
||||||
--- Creates a new AI_A2G_PATROL object
|
--- Creates a new AI_A2G_PATROL object
|
||||||
-- @param #AI_A2G_PATROL self
|
-- @param #AI_A2G_PATROL self
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol
|
-- @param Wrapper.Group#GROUP AIGroup
|
||||||
|
-- @param DCS#Speed EngageMinSpeed (optional, default = 50% of max speed) The minimum speed of the @{Wrapper.Group} in km/h when engaging a target.
|
||||||
|
-- @param DCS#Speed EngageMaxSpeed (optional, default = 75% of max speed) The maximum speed of the @{Wrapper.Group} in km/h when engaging a target.
|
||||||
|
-- @param DCS#Altitude EngageFloorAltitude (optional, default = 1000m ) The lowest altitude in meters where to execute the engagement.
|
||||||
|
-- @param DCS#Altitude EngageCeilingAltitude (optional, default = 1500m ) The highest altitude in meters where to execute the engagement.
|
||||||
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
|
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
|
||||||
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
|
-- @param DCS#Altitude PatrolFloorAltitude (optional, default = 1000m ) The lowest altitude in meters where to execute the patrol.
|
||||||
-- @param DCS#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
|
-- @param DCS#Altitude PatrolCeilingAltitude (optional, default = 1500m ) The highest altitude in meters where to execute the patrol.
|
||||||
-- @param DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Group} in km/h.
|
-- @param DCS#Speed PatrolMinSpeed (optional, default = 50% of max speed) The minimum speed of the @{Wrapper.Group} in km/h.
|
||||||
-- @param DCS#Speed PatrolMaxSpeed The maximum speed of the @{Wrapper.Group} in km/h.
|
-- @param DCS#Speed PatrolMaxSpeed (optional, default = 75% of max speed) The maximum speed of the @{Wrapper.Group} in km/h.
|
||||||
-- @param DCS#Speed EngageMinSpeed The minimum speed of the @{Wrapper.Group} in km/h when engaging a target.
|
-- @param DCS#AltitudeType PatrolAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to RADIO.
|
||||||
-- @param DCS#Speed EngageMaxSpeed The maximum speed of the @{Wrapper.Group} in km/h when engaging a target.
|
|
||||||
-- @param DCS#AltitudeType PatrolAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to RADIO
|
|
||||||
-- @return #AI_A2G_PATROL
|
-- @return #AI_A2G_PATROL
|
||||||
function AI_A2G_PATROL:New( AIPatrol, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, EngageMinSpeed, EngageMaxSpeed, PatrolAltType )
|
function AI_A2G_PATROL:New( AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
|
||||||
|
|
||||||
-- Inherits from BASE
|
-- Inherits from BASE
|
||||||
local self = BASE:Inherit( self, AI_A2A_PATROL:New( AIPatrol, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType ) ) -- #AI_A2G_PATROL
|
local self = BASE:Inherit( self, AI_A2G_ENGAGE:New( AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude ) ) -- #AI_A2G_PATROL
|
||||||
|
|
||||||
self.Accomplished = false
|
local SpeedMax = AIGroup:GetSpeedMax()
|
||||||
self.Engaging = false
|
|
||||||
|
|
||||||
self.EngageMinSpeed = EngageMinSpeed
|
self.PatrolZone = PatrolZone
|
||||||
self.EngageMaxSpeed = EngageMaxSpeed
|
|
||||||
|
|
||||||
self:AddTransition( { "Patrolling", "Engaging", "Returning", "Airborne" }, "Engage", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_A2G_PATROL.
|
self.PatrolFloorAltitude = PatrolFloorAltitude or 1000
|
||||||
|
self.PatrolCeilingAltitude = PatrolCeilingAltitude or 1500
|
||||||
|
self.PatrolMinSpeed = PatrolMinSpeed or SpeedMax * 0.5
|
||||||
|
self.PatrolMaxSpeed = PatrolMaxSpeed or SpeedMax * 0.75
|
||||||
|
|
||||||
|
-- defafult PatrolAltType to "RADIO" if not specified
|
||||||
|
self.PatrolAltType = PatrolAltType or "RADIO"
|
||||||
|
|
||||||
|
self:AddTransition( { "Started", "Airborne", "Refuelling" }, "Patrol", "Patrolling" )
|
||||||
|
|
||||||
--- OnBefore Transition Handler for Event Engage.
|
--- OnBefore Transition Handler for Event Patrol.
|
||||||
-- @function [parent=#AI_A2G_PATROL] OnBeforeEngage
|
-- @function [parent=#AI_A2G_PATROL] OnBeforePatrol
|
||||||
-- @param #AI_A2G_PATROL self
|
-- @param #AI_A2G_PATROL self
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
@ -131,44 +139,25 @@ function AI_A2G_PATROL:New( AIPatrol, PatrolZone, PatrolFloorAltitude, PatrolCei
|
|||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
-- @return #boolean Return false to cancel Transition.
|
-- @return #boolean Return false to cancel Transition.
|
||||||
|
|
||||||
--- OnAfter Transition Handler for Event Engage.
|
--- OnAfter Transition Handler for Event Patrol.
|
||||||
-- @function [parent=#AI_A2G_PATROL] OnAfterEngage
|
-- @function [parent=#AI_A2G_PATROL] OnAfterPatrol
|
||||||
-- @param #AI_A2G_PATROL self
|
-- @param #AI_A2G_PATROL self
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
|
|
||||||
--- Synchronous Event Trigger for Event Engage.
|
--- Synchronous Event Trigger for Event Patrol.
|
||||||
-- @function [parent=#AI_A2G_PATROL] Engage
|
-- @function [parent=#AI_A2G_PATROL] Patrol
|
||||||
-- @param #AI_A2G_PATROL self
|
-- @param #AI_A2G_PATROL self
|
||||||
|
|
||||||
--- Asynchronous Event Trigger for Event Engage.
|
--- Asynchronous Event Trigger for Event Patrol.
|
||||||
-- @function [parent=#AI_A2G_PATROL] __Engage
|
-- @function [parent=#AI_A2G_PATROL] __Patrol
|
||||||
-- @param #AI_A2G_PATROL self
|
-- @param #AI_A2G_PATROL self
|
||||||
-- @param #number Delay The delay in seconds.
|
-- @param #number Delay The delay in seconds.
|
||||||
|
|
||||||
--- OnLeave Transition Handler for State Engaging.
|
|
||||||
-- @function [parent=#AI_A2G_PATROL] OnLeaveEngaging
|
|
||||||
-- @param #AI_A2G_PATROL self
|
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
|
||||||
-- @param #string From The From State string.
|
|
||||||
-- @param #string Event The Event string.
|
|
||||||
-- @param #string To The To State string.
|
|
||||||
-- @return #boolean Return false to cancel Transition.
|
|
||||||
|
|
||||||
--- OnEnter Transition Handler for State Engaging.
|
|
||||||
-- @function [parent=#AI_A2G_PATROL] OnEnterEngaging
|
|
||||||
-- @param #AI_A2G_PATROL self
|
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
|
||||||
-- @param #string From The From State string.
|
|
||||||
-- @param #string Event The Event string.
|
|
||||||
-- @param #string To The To State string.
|
|
||||||
|
|
||||||
self:AddTransition( "Engaging", "Fired", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_A2G_PATROL.
|
|
||||||
|
|
||||||
--- OnBefore Transition Handler for Event Fired.
|
--- OnLeave Transition Handler for State Patrolling.
|
||||||
-- @function [parent=#AI_A2G_PATROL] OnBeforeFired
|
-- @function [parent=#AI_A2G_PATROL] OnLeavePatrolling
|
||||||
-- @param #AI_A2G_PATROL self
|
-- @param #AI_A2G_PATROL self
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
@ -176,27 +165,18 @@ function AI_A2G_PATROL:New( AIPatrol, PatrolZone, PatrolFloorAltitude, PatrolCei
|
|||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
-- @return #boolean Return false to cancel Transition.
|
-- @return #boolean Return false to cancel Transition.
|
||||||
|
|
||||||
--- OnAfter Transition Handler for Event Fired.
|
--- OnEnter Transition Handler for State Patrolling.
|
||||||
-- @function [parent=#AI_A2G_PATROL] OnAfterFired
|
-- @function [parent=#AI_A2G_PATROL] OnEnterPatrolling
|
||||||
-- @param #AI_A2G_PATROL self
|
-- @param #AI_A2G_PATROL self
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
|
|
||||||
--- Synchronous Event Trigger for Event Fired.
|
|
||||||
-- @function [parent=#AI_A2G_PATROL] Fired
|
|
||||||
-- @param #AI_A2G_PATROL self
|
|
||||||
|
|
||||||
--- Asynchronous Event Trigger for Event Fired.
|
self:AddTransition( "Patrolling", "Route", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_A2G_PATROL.
|
||||||
-- @function [parent=#AI_A2G_PATROL] __Fired
|
|
||||||
-- @param #AI_A2G_PATROL self
|
--- OnBefore Transition Handler for Event Route.
|
||||||
-- @param #number Delay The delay in seconds.
|
-- @function [parent=#AI_A2G_PATROL] OnBeforeRoute
|
||||||
|
|
||||||
self:AddTransition( "*", "Destroy", "*" ) -- FSM_CONTROLLABLE Transition for type #AI_A2G_PATROL.
|
|
||||||
|
|
||||||
--- OnBefore Transition Handler for Event Destroy.
|
|
||||||
-- @function [parent=#AI_A2G_PATROL] OnBeforeDestroy
|
|
||||||
-- @param #AI_A2G_PATROL self
|
-- @param #AI_A2G_PATROL self
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
@ -204,111 +184,30 @@ function AI_A2G_PATROL:New( AIPatrol, PatrolZone, PatrolFloorAltitude, PatrolCei
|
|||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
-- @return #boolean Return false to cancel Transition.
|
-- @return #boolean Return false to cancel Transition.
|
||||||
|
|
||||||
--- OnAfter Transition Handler for Event Destroy.
|
--- OnAfter Transition Handler for Event Route.
|
||||||
-- @function [parent=#AI_A2G_PATROL] OnAfterDestroy
|
-- @function [parent=#AI_A2G_PATROL] OnAfterRoute
|
||||||
-- @param #AI_A2G_PATROL self
|
-- @param #AI_A2G_PATROL self
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
|
|
||||||
--- Synchronous Event Trigger for Event Destroy.
|
--- Synchronous Event Trigger for Event Route.
|
||||||
-- @function [parent=#AI_A2G_PATROL] Destroy
|
-- @function [parent=#AI_A2G_PATROL] Route
|
||||||
-- @param #AI_A2G_PATROL self
|
-- @param #AI_A2G_PATROL self
|
||||||
|
|
||||||
--- Asynchronous Event Trigger for Event Destroy.
|
--- Asynchronous Event Trigger for Event Route.
|
||||||
-- @function [parent=#AI_A2G_PATROL] __Destroy
|
-- @function [parent=#AI_A2G_PATROL] __Route
|
||||||
-- @param #AI_A2G_PATROL self
|
-- @param #AI_A2G_PATROL self
|
||||||
-- @param #number Delay The delay in seconds.
|
-- @param #number Delay The delay in seconds.
|
||||||
|
|
||||||
|
|
||||||
self:AddTransition( "Engaging", "Abort", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_A2G_PATROL.
|
self:AddTransition( "*", "Reset", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_A2G_PATROL.
|
||||||
|
|
||||||
--- OnBefore Transition Handler for Event Abort.
|
|
||||||
-- @function [parent=#AI_A2G_PATROL] OnBeforeAbort
|
|
||||||
-- @param #AI_A2G_PATROL self
|
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
|
||||||
-- @param #string From The From State string.
|
|
||||||
-- @param #string Event The Event string.
|
|
||||||
-- @param #string To The To State string.
|
|
||||||
-- @return #boolean Return false to cancel Transition.
|
|
||||||
|
|
||||||
--- OnAfter Transition Handler for Event Abort.
|
|
||||||
-- @function [parent=#AI_A2G_PATROL] OnAfterAbort
|
|
||||||
-- @param #AI_A2G_PATROL self
|
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
|
||||||
-- @param #string From The From State string.
|
|
||||||
-- @param #string Event The Event string.
|
|
||||||
-- @param #string To The To State string.
|
|
||||||
|
|
||||||
--- Synchronous Event Trigger for Event Abort.
|
|
||||||
-- @function [parent=#AI_A2G_PATROL] Abort
|
|
||||||
-- @param #AI_A2G_PATROL self
|
|
||||||
|
|
||||||
--- Asynchronous Event Trigger for Event Abort.
|
|
||||||
-- @function [parent=#AI_A2G_PATROL] __Abort
|
|
||||||
-- @param #AI_A2G_PATROL self
|
|
||||||
-- @param #number Delay The delay in seconds.
|
|
||||||
|
|
||||||
self:AddTransition( "Engaging", "Accomplish", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_A2G_PATROL.
|
|
||||||
|
|
||||||
--- OnBefore Transition Handler for Event Accomplish.
|
|
||||||
-- @function [parent=#AI_A2G_PATROL] OnBeforeAccomplish
|
|
||||||
-- @param #AI_A2G_PATROL self
|
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
|
||||||
-- @param #string From The From State string.
|
|
||||||
-- @param #string Event The Event string.
|
|
||||||
-- @param #string To The To State string.
|
|
||||||
-- @return #boolean Return false to cancel Transition.
|
|
||||||
|
|
||||||
--- OnAfter Transition Handler for Event Accomplish.
|
|
||||||
-- @function [parent=#AI_A2G_PATROL] OnAfterAccomplish
|
|
||||||
-- @param #AI_A2G_PATROL self
|
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
|
||||||
-- @param #string From The From State string.
|
|
||||||
-- @param #string Event The Event string.
|
|
||||||
-- @param #string To The To State string.
|
|
||||||
|
|
||||||
--- Synchronous Event Trigger for Event Accomplish.
|
|
||||||
-- @function [parent=#AI_A2G_PATROL] Accomplish
|
|
||||||
-- @param #AI_A2G_PATROL self
|
|
||||||
|
|
||||||
--- Asynchronous Event Trigger for Event Accomplish.
|
|
||||||
-- @function [parent=#AI_A2G_PATROL] __Accomplish
|
|
||||||
-- @param #AI_A2G_PATROL self
|
|
||||||
-- @param #number Delay The delay in seconds.
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- onafter State Transition for Event Patrol.
|
|
||||||
-- @param #AI_A2G_PATROL self
|
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The AI Group managed by the FSM.
|
|
||||||
-- @param #string From The From State string.
|
|
||||||
-- @param #string Event The Event string.
|
|
||||||
-- @param #string To The To State string.
|
|
||||||
function AI_A2G_PATROL:onafterStart( AIPatrol, From, Event, To )
|
|
||||||
|
|
||||||
self:GetParent( self ).onafterStart( self, AIPatrol, From, Event, To )
|
|
||||||
AIPatrol:HandleEvent( EVENTS.Takeoff, nil, self )
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the Engage Zone which defines where the AI will engage bogies.
|
|
||||||
-- @param #AI_A2G_PATROL self
|
|
||||||
-- @param Core.Zone#ZONE EngageZone The zone where the AI is performing CAP.
|
|
||||||
-- @return #AI_A2G_PATROL self
|
|
||||||
function AI_A2G_PATROL:SetEngageZone( EngageZone )
|
|
||||||
self:F2()
|
|
||||||
|
|
||||||
if EngageZone then
|
|
||||||
self.EngageZone = EngageZone
|
|
||||||
else
|
|
||||||
self.EngageZone = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Set the Engage Range when the AI will engage with airborne enemies.
|
--- Set the Engage Range when the AI will engage with airborne enemies.
|
||||||
-- @param #AI_A2G_PATROL self
|
-- @param #AI_A2G_PATROL self
|
||||||
-- @param #number EngageRange The Engage Range.
|
-- @param #number EngageRange The Engage Range.
|
||||||
@ -323,157 +222,93 @@ function AI_A2G_PATROL:SetEngageRange( EngageRange )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- onafter State Transition for Event Patrol.
|
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
|
||||||
-- @param #AI_A2G_PATROL self
|
-- @param #AI_A2G_PATROL self
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The AI Group managed by the FSM.
|
-- @return #AI_A2G_PATROL self
|
||||||
|
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2G_PATROL:onafterPatrol( AIPatrol, From, Event, To )
|
function AI_A2G_PATROL:onafterPatrol( AIPatrol, From, Event, To )
|
||||||
|
self:F2()
|
||||||
|
|
||||||
-- Call the parent Start event handler
|
self:ClearTargetDistance()
|
||||||
self:GetParent(self).onafterPatrol( self, AIPatrol, From, Event, To )
|
|
||||||
self:HandleEvent( EVENTS.Dead )
|
|
||||||
|
|
||||||
|
self:__Route( 1 )
|
||||||
|
|
||||||
|
AIPatrol:OnReSpawn(
|
||||||
|
function( PatrolGroup )
|
||||||
|
self:__Reset( 1 )
|
||||||
|
self:__Route( 5 )
|
||||||
|
end
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- todo: need to fix this global function
|
|
||||||
|
|
||||||
--- @param Wrapper.Group#GROUP AIPatrol
|
--- @param Wrapper.Group#GROUP AIPatrol
|
||||||
function AI_A2G_PATROL.AttackRoute( AIPatrol, Fsm )
|
-- This statis method is called from the route path within the last task at the last waaypoint of the AIPatrol.
|
||||||
|
-- Note that this method is required, as triggers the next route when patrolling for the AIPatrol.
|
||||||
|
function AI_A2G_PATROL.PatrolRoute( AIPatrol, Fsm )
|
||||||
|
|
||||||
AIPatrol:F( { "AI_A2G_PATROL.AttackRoute:", AIPatrol:GetName() } )
|
AIPatrol:F( { "AI_A2G_PATROL.PatrolRoute:", AIPatrol:GetName() } )
|
||||||
|
|
||||||
if AIPatrol:IsAlive() then
|
if AIPatrol:IsAlive() then
|
||||||
Fsm:__Engage( 0.5 )
|
Fsm:Route()
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_A2G_PATROL self
|
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
-- @param #AI_A2G_PATROL self
|
||||||
|
-- @param Wrapper.Group#GROUP AIPatrol The Group managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2G_PATROL:onbeforeEngage( AIPatrol, From, Event, To )
|
function AI_A2G_PATROL:onafterRoute( AIPatrol, From, Event, To )
|
||||||
|
|
||||||
if self.Accomplished == true then
|
self:F2()
|
||||||
return false
|
|
||||||
|
-- When RTB, don't allow anymore the routing.
|
||||||
|
if From == "RTB" then
|
||||||
|
return
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
--- @param #AI_A2G_PATROL self
|
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The AI Group managed by the FSM.
|
|
||||||
-- @param #string From The From State string.
|
|
||||||
-- @param #string Event The Event string.
|
|
||||||
-- @param #string To The To State string.
|
|
||||||
function AI_A2G_PATROL:onafterAbort( AIPatrol, From, Event, To )
|
|
||||||
AIPatrol:ClearTasks()
|
|
||||||
self:__Route( 0.5 )
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- @param #AI_A2G_PATROL self
|
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The AIPatrol Object managed by the FSM.
|
|
||||||
-- @param #string From The From State string.
|
|
||||||
-- @param #string Event The Event string.
|
|
||||||
-- @param #string To The To State string.
|
|
||||||
function AI_A2G_PATROL:onafterEngage( AIPatrol, From, Event, To, AttackSetUnit )
|
|
||||||
|
|
||||||
self:F( { AIPatrol, From, Event, To, AttackSetUnit} )
|
|
||||||
|
|
||||||
self.AttackSetUnit = AttackSetUnit or self.AttackSetUnit -- Core.Set#SET_UNIT
|
|
||||||
|
|
||||||
local FirstAttackUnit = self.AttackSetUnit:GetFirst() -- Wrapper.Unit#UNIT
|
if AIPatrol:IsAlive() then
|
||||||
|
|
||||||
if FirstAttackUnit and FirstAttackUnit:IsAlive() then -- If there is no attacker anymore, stop the engagement.
|
local PatrolRoute = {}
|
||||||
|
|
||||||
if AIPatrol:IsAlive() then
|
|
||||||
|
|
||||||
local EngageRoute = {}
|
--- Calculate the target route point.
|
||||||
|
|
||||||
|
local CurrentCoord = AIPatrol:GetCoordinate()
|
||||||
|
|
||||||
|
local ToTargetCoord = self.PatrolZone:GetRandomPointVec2()
|
||||||
|
ToTargetCoord:SetAlt( math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude ) )
|
||||||
|
self:SetTargetDistance( ToTargetCoord ) -- For RTB status check
|
||||||
|
|
||||||
|
local ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
|
||||||
|
|
||||||
|
--- Create a route point of type air.
|
||||||
|
local ToPatrolRoutePoint = ToTargetCoord:WaypointAir(
|
||||||
|
self.PatrolAltType,
|
||||||
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
|
ToTargetSpeed,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
--- Calculate the target route point.
|
PatrolRoute[#PatrolRoute+1] = ToPatrolRoutePoint
|
||||||
local CurrentCoord = AIPatrol:GetCoordinate()
|
PatrolRoute[#PatrolRoute+1] = ToPatrolRoutePoint
|
||||||
local ToTargetCoord = self.AttackSetUnit:GetFirst():GetCoordinate()
|
|
||||||
local ToTargetSpeed = math.random( self.EngageMinSpeed, self.EngageMaxSpeed )
|
local Tasks = {}
|
||||||
local ToInterceptAngle = CurrentCoord:GetAngleDegrees( CurrentCoord:GetDirectionVec3( ToTargetCoord ) )
|
Tasks[#Tasks+1] = AIPatrol:TaskFunction( "AI_A2G_PATROL.PatrolRoute", self )
|
||||||
|
PatrolRoute[#PatrolRoute].task = AIPatrol:TaskCombo( Tasks )
|
||||||
--- Create a route point of type air.
|
|
||||||
local ToPatrolRoutePoint = CurrentCoord:Translate( 5000, ToInterceptAngle ):WaypointAir(
|
AIPatrol:OptionROEReturnFire()
|
||||||
self.PatrolAltType,
|
AIPatrol:OptionROTEvadeFire()
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
|
||||||
ToTargetSpeed,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
|
|
||||||
self:F( { Angle = ToInterceptAngle, ToTargetSpeed = ToTargetSpeed } )
|
|
||||||
self:T2( { self.MinSpeed, self.MaxSpeed, ToTargetSpeed } )
|
|
||||||
|
|
||||||
EngageRoute[#EngageRoute+1] = ToPatrolRoutePoint
|
|
||||||
EngageRoute[#EngageRoute+1] = ToPatrolRoutePoint
|
|
||||||
|
|
||||||
local AttackTasks = {}
|
AIPatrol:Route( PatrolRoute, 0.5 )
|
||||||
|
|
||||||
for AttackUnitID, AttackUnit in pairs( self.AttackSetUnit:GetSet() ) do
|
|
||||||
local AttackUnit = AttackUnit -- Wrapper.Unit#UNIT
|
|
||||||
self:T( { "Attacking Unit:", AttackUnit:GetName(), AttackUnit:IsAlive(), AttackUnit:IsAir() } )
|
|
||||||
if AttackUnit:IsAlive() and AttackUnit:IsGround() then
|
|
||||||
AttackTasks[#AttackTasks+1] = AIPatrol:TaskAttackUnit( AttackUnit )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if #AttackTasks == 0 then
|
|
||||||
self:E("No targets found -> Going back to Patrolling")
|
|
||||||
self:__Abort( 0.5 )
|
|
||||||
else
|
|
||||||
AIPatrol:OptionROEOpenFire()
|
|
||||||
AIPatrol:OptionROTEvadeFire()
|
|
||||||
|
|
||||||
AttackTasks[#AttackTasks+1] = AIPatrol:TaskFunction( "AI_A2G_PATROL.AttackRoute", self )
|
|
||||||
EngageRoute[#EngageRoute].task = AIPatrol:TaskCombo( AttackTasks )
|
|
||||||
end
|
|
||||||
|
|
||||||
AIPatrol:Route( EngageRoute, 0.5 )
|
|
||||||
end
|
|
||||||
else
|
|
||||||
self:E("No targets found -> Going back to Patrolling")
|
|
||||||
self:__Abort( 0.5 )
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
--- @param #AI_A2G_PATROL self
|
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
|
||||||
-- @param #string From The From State string.
|
|
||||||
-- @param #string Event The Event string.
|
|
||||||
-- @param #string To The To State string.
|
|
||||||
function AI_A2G_PATROL:onafterAccomplish( AIPatrol, From, Event, To )
|
|
||||||
self.Accomplished = true
|
|
||||||
self:SetDetectionOff()
|
|
||||||
end
|
|
||||||
|
|
||||||
--- @param #AI_A2G_PATROL self
|
|
||||||
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
|
||||||
-- @param #string From The From State string.
|
|
||||||
-- @param #string Event The Event string.
|
|
||||||
-- @param #string To The To State string.
|
|
||||||
-- @param Core.Event#EVENTDATA EventData
|
|
||||||
function AI_A2G_PATROL:onafterDestroy( AIPatrol, From, Event, To, EventData )
|
|
||||||
|
|
||||||
if EventData.IniUnit then
|
|
||||||
self.AttackUnits[EventData.IniUnit] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- @param #AI_A2G_PATROL self
|
|
||||||
-- @param Core.Event#EVENTDATA EventData
|
|
||||||
function AI_A2G_PATROL:OnEventDead( EventData )
|
|
||||||
self:F( { "EventDead", EventData } )
|
|
||||||
|
|
||||||
if EventData.IniDCSUnit then
|
|
||||||
if self.AttackUnits and self.AttackUnits[EventData.IniUnit] then
|
|
||||||
self:__Destroy( 1, EventData )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param Wrapper.Group#GROUP AIPatrol
|
--- @param Wrapper.Group#GROUP AIPatrol
|
||||||
|
|||||||
231
Moose Development/Moose/AI/AI_A2G_SEAD.lua
Normal file
231
Moose Development/Moose/AI/AI_A2G_SEAD.lua
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
--- **AI** -- Models the process of air to ground SEAD engagement for airplanes and helicopters.
|
||||||
|
--
|
||||||
|
-- This is a class used in the @{AI_A2G_Dispatcher}.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @module AI.AI_A2G_SEAD
|
||||||
|
-- @image AI_Air_To_Ground_Engage.JPG
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- @type AI_A2G_SEAD
|
||||||
|
-- @extends AI.AI_A2G_Patrol#AI_A2G_PATROL
|
||||||
|
|
||||||
|
|
||||||
|
--- Implements the core functions to SEAD intruders. Use the Engage trigger to intercept intruders.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- The AI_A2G_SEAD is assigned a @{Wrapper.Group} and this must be done before the AI_A2G_SEAD process can be started using the **Start** event.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
||||||
|
-- Upon arrival at the 3D point, a new random 3D point will be selected within the patrol zone using the given limits.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- This cycle will continue.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- During the patrol, the AI will detect enemy targets, which are reported through the **Detected** event.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- When enemies are detected, the AI will automatically engage the enemy.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- Until a fuel or damage treshold has been reached by the AI, or when the AI is commanded to RTB.
|
||||||
|
-- When the fuel treshold has been reached, the airplane will fly towards the nearest friendly airbase and will land.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- ## 1. AI_A2G_SEAD constructor
|
||||||
|
--
|
||||||
|
-- * @{#AI_A2G_SEAD.New}(): Creates a new AI_A2G_SEAD object.
|
||||||
|
--
|
||||||
|
-- ## 3. Set the Range of Engagement
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- An optional range can be set in meters,
|
||||||
|
-- that will define when the AI will engage with the detected airborne enemy targets.
|
||||||
|
-- The range can be beyond or smaller than the range of the Patrol Zone.
|
||||||
|
-- The range is applied at the position of the AI.
|
||||||
|
-- Use the method @{AI.AI_GCI#AI_A2G_SEAD.SetEngageRange}() to define that range.
|
||||||
|
--
|
||||||
|
-- ## 4. Set the Zone of Engagement
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- An optional @{Zone} can be set,
|
||||||
|
-- that will define when the AI will engage with the detected airborne enemy targets.
|
||||||
|
-- Use the method @{AI.AI_Cap#AI_A2G_SEAD.SetEngageZone}() to define that Zone.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @field #AI_A2G_SEAD
|
||||||
|
AI_A2G_SEAD = {
|
||||||
|
ClassName = "AI_A2G_SEAD",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Creates a new AI_A2G_SEAD object
|
||||||
|
-- @param #AI_A2G_SEAD self
|
||||||
|
-- @param Wrapper.Group#GROUP AIGroup
|
||||||
|
-- @param DCS#Speed EngageMinSpeed The minimum speed of the @{Wrapper.Group} in km/h when engaging a target.
|
||||||
|
-- @param DCS#Speed EngageMaxSpeed The maximum speed of the @{Wrapper.Group} in km/h when engaging a target.
|
||||||
|
-- @param DCS#Altitude EngageFloorAltitude The lowest altitude in meters where to execute the engagement.
|
||||||
|
-- @param DCS#Altitude EngageCeilingAltitude The highest altitude in meters where to execute the engagement.
|
||||||
|
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
|
||||||
|
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
|
||||||
|
-- @param DCS#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
|
||||||
|
-- @param DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Group} in km/h.
|
||||||
|
-- @param DCS#Speed PatrolMaxSpeed The maximum speed of the @{Wrapper.Group} in km/h.
|
||||||
|
-- @param DCS#AltitudeType PatrolAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to RADIO
|
||||||
|
-- @return #AI_A2G_SEAD
|
||||||
|
function AI_A2G_SEAD:New( AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
|
||||||
|
|
||||||
|
-- Inherits from BASE
|
||||||
|
local self = BASE:Inherit( self, AI_A2G_PATROL:New( AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType ) ) -- #AI_A2G_SEAD
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- @param #AI_A2G_SEAD self
|
||||||
|
-- @param Wrapper.Group#GROUP DefenderGroup The GroupGroup managed by the FSM.
|
||||||
|
-- @param #string From The From State string.
|
||||||
|
-- @param #string Event The Event string.
|
||||||
|
-- @param #string To The To State string.
|
||||||
|
function AI_A2G_SEAD:onafterEngage( DefenderGroup, From, Event, To, AttackSetUnit )
|
||||||
|
|
||||||
|
self:F( { DefenderGroup, From, Event, To, AttackSetUnit} )
|
||||||
|
|
||||||
|
local DefenderGroupName = DefenderGroup:GetName()
|
||||||
|
|
||||||
|
self.AttackSetUnit = AttackSetUnit or self.AttackSetUnit -- Core.Set#SET_UNIT
|
||||||
|
|
||||||
|
local AttackCount = self.AttackSetUnit:Count()
|
||||||
|
|
||||||
|
if AttackCount > 0 then
|
||||||
|
|
||||||
|
if DefenderGroup:IsAlive() then
|
||||||
|
|
||||||
|
-- Determine the distance to the target.
|
||||||
|
-- If it is less than 50km, then attack without a route.
|
||||||
|
-- Otherwise perform a route attack.
|
||||||
|
|
||||||
|
local DefenderCoord = DefenderGroup:GetPointVec3()
|
||||||
|
DefenderCoord:SetY( math.random( self.EngageFloorAltitude, self.EngageCeilingAltitude ) ) -- Ground targets don't have an altitude.
|
||||||
|
|
||||||
|
local TargetCoord = self.AttackSetUnit:GetFirst():GetPointVec3()
|
||||||
|
TargetCoord:SetY( math.random( self.EngageFloorAltitude, self.EngageCeilingAltitude ) ) -- Ground targets don't have an altitude.
|
||||||
|
|
||||||
|
local TargetDistance = DefenderCoord:Get2DDistance( TargetCoord )
|
||||||
|
|
||||||
|
-- if TargetDistance >= 50000 then
|
||||||
|
|
||||||
|
local EngageRoute = {}
|
||||||
|
|
||||||
|
local ToTargetSpeed = math.random( self.EngageMinSpeed, self.EngageMaxSpeed )
|
||||||
|
|
||||||
|
--- Calculate the target route point.
|
||||||
|
|
||||||
|
local FromWP = DefenderCoord:WaypointAir(
|
||||||
|
self.PatrolAltType or "RADIO",
|
||||||
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
|
ToTargetSpeed,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
EngageRoute[#EngageRoute+1] = FromWP
|
||||||
|
|
||||||
|
local ToCoord = self.AttackSetUnit:GetFirst():GetCoordinate()
|
||||||
|
self:SetTargetDistance( ToCoord ) -- For RTB status check
|
||||||
|
|
||||||
|
local FromEngageAngle = ToCoord:GetAngleDegrees( ToCoord:GetDirectionVec3( DefenderCoord ) )
|
||||||
|
|
||||||
|
--- Create a route point of type air, 50km from the center of the attack point.
|
||||||
|
local ToWP = ToCoord:Translate( 50000, FromEngageAngle ):WaypointAir(
|
||||||
|
self.PatrolAltType or "RADIO",
|
||||||
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
|
ToTargetSpeed,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
self:F( { Angle = FromEngageAngle, ToTargetSpeed = ToTargetSpeed } )
|
||||||
|
self:F( { self.EngageMinSpeed, self.EngageMaxSpeed, ToTargetSpeed } )
|
||||||
|
|
||||||
|
EngageRoute[#EngageRoute+1] = ToWP
|
||||||
|
|
||||||
|
local AttackTasks = {}
|
||||||
|
|
||||||
|
for AttackUnitID, AttackUnit in pairs( self.AttackSetUnit:GetSet() ) do
|
||||||
|
if AttackUnit:IsAlive() and AttackUnit:IsGround() then
|
||||||
|
self:T( { "Engage Unit evaluation:", AttackUnit:GetName(), AttackUnit:IsAlive(), AttackUnit:IsGround() } )
|
||||||
|
local HasRadar = AttackUnit:HasSEAD()
|
||||||
|
if HasRadar then
|
||||||
|
self:T( { "Eliminating Unit:", AttackUnit:GetName() } )
|
||||||
|
AttackTasks[#AttackTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if #AttackTasks == 0 then
|
||||||
|
self:E( DefenderGroupName .. ": No targets found -> Going RTB")
|
||||||
|
self:Return()
|
||||||
|
self:__RTB( 0.5 )
|
||||||
|
else
|
||||||
|
DefenderGroup:OptionROEOpenFire()
|
||||||
|
DefenderGroup:OptionROTVertical()
|
||||||
|
DefenderGroup:OptionKeepWeaponsOnThreat()
|
||||||
|
--DefenderGroup:OptionRTBAmmo( Weapon.flag.AnyASM )
|
||||||
|
|
||||||
|
AttackTasks[#AttackTasks+1] = DefenderGroup:TaskFunction( "AI_A2G_ENGAGE.EngageRoute", self )
|
||||||
|
EngageRoute[#EngageRoute].task = DefenderGroup:TaskCombo( AttackTasks )
|
||||||
|
end
|
||||||
|
|
||||||
|
DefenderGroup:Route( EngageRoute, 2 )
|
||||||
|
|
||||||
|
-- else
|
||||||
|
-- local AttackTasks = {}
|
||||||
|
-- --local AttackUnit = self.AttackSetUnit:GetRandom() -- Wrapper.Unit#UNIT
|
||||||
|
-- for AttackUnitID, AttackUnit in pairs( self.AttackSetUnit:GetSet() ) do
|
||||||
|
-- if AttackUnit:IsAlive() and AttackUnit:IsGround() then
|
||||||
|
-- local HasRadar = AttackUnit:HasSEAD()
|
||||||
|
-- if HasRadar then
|
||||||
|
-- self:T( { "Eliminating Unit:", AttackUnit:GetName(), AttackUnit:IsAlive(), AttackUnit:IsGround() } )
|
||||||
|
-- AttackTasks[#AttackTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit )
|
||||||
|
-- AttackTasks[#AttackTasks+1] = DefenderGroup:TaskFunction( "AI_A2G_ENGAGE.EngageRoute", self )
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- local DefenderTask = DefenderGroup:TaskCombo( AttackTasks )
|
||||||
|
--
|
||||||
|
-- DefenderGroup:OptionROEOpenFire()
|
||||||
|
-- DefenderGroup:OptionROTVertical()
|
||||||
|
-- DefenderGroup:OptionKeepWeaponsOnThreat()
|
||||||
|
-- DefenderGroup:OptionRTBAmmo( Weapon.flag.AnyASM )
|
||||||
|
--
|
||||||
|
-- DefenderGroup:SetTask( DefenderTask, 0 )
|
||||||
|
-- end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:E( DefenderGroupName .. ": No targets found -> Going RTB")
|
||||||
|
self:Return()
|
||||||
|
self:__RTB( 0.5 )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@ -298,6 +298,19 @@ function AI_AIR:SetSpeed( PatrolMinSpeed, PatrolMaxSpeed )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Sets (modifies) the minimum and maximum RTB speed of the patrol.
|
||||||
|
-- @param #AI_AIR self
|
||||||
|
-- @param DCS#Speed RTBMinSpeed The minimum speed of the @{Wrapper.Controllable} in km/h.
|
||||||
|
-- @param DCS#Speed RTBMaxSpeed The maximum speed of the @{Wrapper.Controllable} in km/h.
|
||||||
|
-- @return #AI_AIR self
|
||||||
|
function AI_AIR:SetRTBSpeed( RTBMinSpeed, RTBMaxSpeed )
|
||||||
|
self:F2( { RTBMinSpeed, RTBMaxSpeed } )
|
||||||
|
|
||||||
|
self.RTBMinSpeed = RTBMinSpeed
|
||||||
|
self.RTBMaxSpeed = RTBMaxSpeed
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Sets the floor and ceiling altitude of the patrol.
|
--- Sets the floor and ceiling altitude of the patrol.
|
||||||
-- @param #AI_AIR self
|
-- @param #AI_AIR self
|
||||||
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
|
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
|
||||||
@ -425,7 +438,6 @@ function AI_AIR:onafterStatus()
|
|||||||
|
|
||||||
if not self:Is( "Holding" ) and not self:Is( "Returning" ) then
|
if not self:Is( "Holding" ) and not self:Is( "Returning" ) then
|
||||||
local DistanceFromHomeBase = self.HomeAirbase:GetCoordinate():Get2DDistance( self.Controllable:GetCoordinate() )
|
local DistanceFromHomeBase = self.HomeAirbase:GetCoordinate():Get2DDistance( self.Controllable:GetCoordinate() )
|
||||||
self:F({DistanceFromHomeBase=DistanceFromHomeBase})
|
|
||||||
|
|
||||||
if DistanceFromHomeBase > self.DisengageRadius then
|
if DistanceFromHomeBase > self.DisengageRadius then
|
||||||
self:E( self.Controllable:GetName() .. " is too far from home base, RTB!" )
|
self:E( self.Controllable:GetName() .. " is too far from home base, RTB!" )
|
||||||
@ -444,9 +456,13 @@ function AI_AIR:onafterStatus()
|
|||||||
|
|
||||||
|
|
||||||
if not self:Is( "Fuel" ) and not self:Is( "Home" ) then
|
if not self:Is( "Fuel" ) and not self:Is( "Home" ) then
|
||||||
|
|
||||||
local Fuel = self.Controllable:GetFuelMin()
|
local Fuel = self.Controllable:GetFuelMin()
|
||||||
self:F({Fuel=Fuel, FuelThresholdPercentage=self.FuelThresholdPercentage})
|
|
||||||
|
-- If the fuel in the controllable is below the treshold percentage,
|
||||||
|
-- then send for refuel in case of a tanker, otherwise RTB.
|
||||||
if Fuel < self.FuelThresholdPercentage then
|
if Fuel < self.FuelThresholdPercentage then
|
||||||
|
|
||||||
if self.TankerName then
|
if self.TankerName then
|
||||||
self:E( self.Controllable:GetName() .. " is out of fuel: " .. Fuel .. " ... Refuelling at Tanker!" )
|
self:E( self.Controllable:GetName() .. " is out of fuel: " .. Fuel .. " ... Refuelling at Tanker!" )
|
||||||
self:Refuel()
|
self:Refuel()
|
||||||
@ -468,14 +484,17 @@ function AI_AIR:onafterStatus()
|
|||||||
-- TODO: Check GROUP damage function.
|
-- TODO: Check GROUP damage function.
|
||||||
local Damage = self.Controllable:GetLife()
|
local Damage = self.Controllable:GetLife()
|
||||||
local InitialLife = self.Controllable:GetLife0()
|
local InitialLife = self.Controllable:GetLife0()
|
||||||
self:F( { Damage = Damage, InitialLife = InitialLife, DamageThreshold = self.PatrolDamageThreshold } )
|
|
||||||
|
-- If the group is damaged, then RTB.
|
||||||
|
-- Note that a group can consist of more units, so if one unit is damaged of a group, the mission may continue.
|
||||||
|
-- The damaged unit will RTB due to DCS logic, and the others will continue to engage.
|
||||||
if ( Damage / InitialLife ) < self.PatrolDamageThreshold then
|
if ( Damage / InitialLife ) < self.PatrolDamageThreshold then
|
||||||
self:E( self.Controllable:GetName() .. " is damaged: " .. Damage .. " ... RTB!" )
|
self:E( self.Controllable:GetName() .. " is damaged: " .. Damage .. " ... RTB!" )
|
||||||
self:Damaged()
|
self:Damaged()
|
||||||
RTB = true
|
RTB = true
|
||||||
self:SetStatusOff()
|
self:SetStatusOff()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check if planes went RTB and are out of control.
|
-- Check if planes went RTB and are out of control.
|
||||||
-- We only check if planes are out of control, when they are in duty.
|
-- We only check if planes are out of control, when they are in duty.
|
||||||
if self.Controllable:HasTask() == false then
|
if self.Controllable:HasTask() == false then
|
||||||
@ -484,11 +503,12 @@ function AI_AIR:onafterStatus()
|
|||||||
not self:Is( "Fuel" ) and
|
not self:Is( "Fuel" ) and
|
||||||
not self:Is( "Damaged" ) and
|
not self:Is( "Damaged" ) and
|
||||||
not self:Is( "Home" ) then
|
not self:Is( "Home" ) then
|
||||||
if self.IdleCount >= 2 then
|
if self.IdleCount >= 10 then
|
||||||
if Damage ~= InitialLife then
|
if Damage ~= InitialLife then
|
||||||
self:Damaged()
|
self:Damaged()
|
||||||
else
|
else
|
||||||
self:E( self.Controllable:GetName() .. " control lost! " )
|
self:E( self.Controllable:GetName() .. " control lost! " )
|
||||||
|
|
||||||
self:LostControl()
|
self:LostControl()
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -547,7 +567,7 @@ function AI_AIR:onafterRTB( AIGroup, From, Event, To )
|
|||||||
self:E( "Group " .. AIGroup:GetName() .. " ... RTB! ( " .. self:GetState() .. " )" )
|
self:E( "Group " .. AIGroup:GetName() .. " ... RTB! ( " .. self:GetState() .. " )" )
|
||||||
|
|
||||||
self:ClearTargetDistance()
|
self:ClearTargetDistance()
|
||||||
AIGroup:ClearTasks()
|
--AIGroup:ClearTasks()
|
||||||
|
|
||||||
local EngageRoute = {}
|
local EngageRoute = {}
|
||||||
|
|
||||||
@ -555,7 +575,7 @@ function AI_AIR:onafterRTB( AIGroup, From, Event, To )
|
|||||||
|
|
||||||
local CurrentCoord = AIGroup:GetCoordinate()
|
local CurrentCoord = AIGroup:GetCoordinate()
|
||||||
local ToTargetCoord = self.HomeAirbase:GetCoordinate()
|
local ToTargetCoord = self.HomeAirbase:GetCoordinate()
|
||||||
local ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
|
local ToTargetSpeed = math.random( self.RTBMinSpeed, self.RTBMaxSpeed )
|
||||||
local ToAirbaseAngle = CurrentCoord:GetAngleDegrees( CurrentCoord:GetDirectionVec3( ToTargetCoord ) )
|
local ToAirbaseAngle = CurrentCoord:GetAngleDegrees( CurrentCoord:GetDirectionVec3( ToTargetCoord ) )
|
||||||
|
|
||||||
local Distance = CurrentCoord:Get2DDistance( ToTargetCoord )
|
local Distance = CurrentCoord:Get2DDistance( ToTargetCoord )
|
||||||
@ -575,9 +595,6 @@ function AI_AIR:onafterRTB( AIGroup, From, Event, To )
|
|||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|
||||||
self:F( { Angle = ToAirbaseAngle, ToTargetSpeed = ToTargetSpeed } )
|
|
||||||
self:T2( { self.MinSpeed, self.MaxSpeed, ToTargetSpeed } )
|
|
||||||
|
|
||||||
EngageRoute[#EngageRoute+1] = ToRTBRoutePoint
|
EngageRoute[#EngageRoute+1] = ToRTBRoutePoint
|
||||||
EngageRoute[#EngageRoute+1] = ToRTBRoutePoint
|
EngageRoute[#EngageRoute+1] = ToRTBRoutePoint
|
||||||
|
|
||||||
|
|||||||
@ -430,6 +430,8 @@ do -- Types
|
|||||||
|
|
||||||
end --
|
end --
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
do -- Object
|
do -- Object
|
||||||
|
|
||||||
--- [DCS Class Object](https://wiki.hoggitworld.com/view/DCS_Class_Object)
|
--- [DCS Class Object](https://wiki.hoggitworld.com/view/DCS_Class_Object)
|
||||||
@ -527,6 +529,126 @@ do -- CoalitionObject
|
|||||||
end -- CoalitionObject
|
end -- CoalitionObject
|
||||||
|
|
||||||
|
|
||||||
|
do -- Weapon
|
||||||
|
|
||||||
|
--- [DCS Class Weapon](https://wiki.hoggitworld.com/view/DCS_Class_Weapon)
|
||||||
|
-- @type Weapon
|
||||||
|
-- @extends #CoalitionObject
|
||||||
|
-- @field #Weapon.flag flag enum stores weapon flags. Some of them are combination of another flags.
|
||||||
|
-- @field #Weapon.Category Category enum that stores weapon categories.
|
||||||
|
-- @field #Weapon.GuidanceType GuidanceType enum that stores guidance methods. Available only for guided weapon (Weapon.Category.MISSILE and some Weapon.Category.BOMB).
|
||||||
|
-- @field #Weapon.MissileCategory MissileCategory enum that stores missile category. Available only for missiles (Weapon.Category.MISSILE).
|
||||||
|
-- @field #Weapon.WarheadType WarheadType enum that stores warhead types.
|
||||||
|
-- @field #Weapon.Desc Desc The descriptor of a weapon.
|
||||||
|
|
||||||
|
--- enum stores weapon flags. Some of them are combination of another flags.
|
||||||
|
-- @type Weapon.flag
|
||||||
|
-- @field LGB
|
||||||
|
-- @field TvGB
|
||||||
|
-- @field SNSGB
|
||||||
|
-- @field HEBomb
|
||||||
|
-- @field Penetrator
|
||||||
|
-- @field NapalmBomb
|
||||||
|
-- @field FAEBomb
|
||||||
|
-- @field ClusterBomb
|
||||||
|
-- @field Dispencer
|
||||||
|
-- @field CandleBomb
|
||||||
|
-- @field ParachuteBomb
|
||||||
|
-- @field GuidedBomb = LGB + TvGB + SNSGB
|
||||||
|
-- @field AnyUnguidedBomb = HEBomb + Penetrator + NapalmBomb + FAEBomb + ClusterBomb + Dispencer + CandleBomb + ParachuteBomb
|
||||||
|
-- @field AnyBomb = GuidedBomb + AnyUnguidedBomb
|
||||||
|
-- @field LightRocket
|
||||||
|
-- @field MarkerRocket
|
||||||
|
-- @field CandleRocket
|
||||||
|
-- @field HeavyRocket
|
||||||
|
-- @field AnyRocket = LightRocket + HeavyRocket + MarkerRocket + CandleRocket
|
||||||
|
-- @field AntiRadarMissile
|
||||||
|
-- @field AntiShipMissile
|
||||||
|
-- @field AntiTankMissile
|
||||||
|
-- @field FireAndForgetASM
|
||||||
|
-- @field LaserASM
|
||||||
|
-- @field TeleASM
|
||||||
|
-- @field CruiseMissile
|
||||||
|
-- @field GuidedASM = LaserASM + TeleASM
|
||||||
|
-- @field TacticASM = GuidedASM + FireAndForgetASM
|
||||||
|
-- @field AnyASM = AntiRadarMissile + AntiShipMissile + AntiTankMissile + FireAndForgetASM + GuidedASM + CruiseMissile
|
||||||
|
-- @field SRAAM
|
||||||
|
-- @field MRAAM
|
||||||
|
-- @field LRAAM
|
||||||
|
-- @field IR_AAM
|
||||||
|
-- @field SAR_AAM
|
||||||
|
-- @field AR_AAM
|
||||||
|
-- @field AnyAAM = IR_AAM + SAR_AAM + AR_AAM + SRAAM + MRAAM + LRAAM
|
||||||
|
-- @field AnyMissile = AnyASM + AnyAAM
|
||||||
|
-- @field AnyAutonomousMissile = IR_AAM + AntiRadarMissile + AntiShipMissile + FireAndForgetASM + CruiseMissile
|
||||||
|
-- @field GUN_POD
|
||||||
|
-- @field BuiltInCannon
|
||||||
|
-- @field Cannons = GUN_POD + BuiltInCannon
|
||||||
|
-- @field AnyAGWeapon = BuiltInCannon + GUN_POD + AnyBomb + AnyRocket + AnyASM
|
||||||
|
-- @field AnyAAWeapon = BuiltInCannon + GUN_POD + AnyAAM
|
||||||
|
-- @field UnguidedWeapon = Cannons + BuiltInCannon + GUN_POD + AnyUnguidedBomb + AnyRocket
|
||||||
|
-- @field GuidedWeapon = GuidedBomb + AnyASM + AnyAAM
|
||||||
|
-- @field AnyWeapon = AnyBomb + AnyRocket + AnyMissile + Cannons
|
||||||
|
-- @field MarkerWeapon = MarkerRocket + CandleRocket + CandleBomb
|
||||||
|
-- @field ArmWeapon = AnyWeapon - MarkerWeapon
|
||||||
|
|
||||||
|
--- Weapon.Category enum that stores weapon categories.
|
||||||
|
-- @type Weapon.Category
|
||||||
|
-- @field SHELL
|
||||||
|
-- @field MISSILE
|
||||||
|
-- @field ROCKET
|
||||||
|
-- @field BOMB
|
||||||
|
|
||||||
|
|
||||||
|
--- Weapon.GuidanceType enum that stores guidance methods. Available only for guided weapon (Weapon.Category.MISSILE and some Weapon.Category.BOMB).
|
||||||
|
-- @type Weapon.GuidanceType
|
||||||
|
-- @field INS
|
||||||
|
-- @field IR
|
||||||
|
-- @field RADAR_ACTIVE
|
||||||
|
-- @field RADAR_SEMI_ACTIVE
|
||||||
|
-- @field RADAR_PASSIVE
|
||||||
|
-- @field TV
|
||||||
|
-- @field LASER
|
||||||
|
-- @field TELE
|
||||||
|
|
||||||
|
|
||||||
|
--- Weapon.MissileCategory enum that stores missile category. Available only for missiles (Weapon.Category.MISSILE).
|
||||||
|
-- @type Weapon.MissileCategory
|
||||||
|
-- @field AAM
|
||||||
|
-- @field SAM
|
||||||
|
-- @field BM
|
||||||
|
-- @field ANTI_SHIP
|
||||||
|
-- @field CRUISE
|
||||||
|
-- @field OTHER
|
||||||
|
|
||||||
|
--- Weapon.WarheadType enum that stores warhead types.
|
||||||
|
-- @type Weapon.WarheadType
|
||||||
|
-- @field AP
|
||||||
|
-- @field HE
|
||||||
|
-- @field SHAPED_EXPLOSIVE
|
||||||
|
|
||||||
|
--- Returns the unit that launched the weapon.
|
||||||
|
-- @function [parent=#Weapon] getLauncher
|
||||||
|
-- @param #Weapon self
|
||||||
|
-- @return #Unit
|
||||||
|
|
||||||
|
--- returns target of the guided weapon. Unguided weapons and guided weapon that is targeted at the point on the ground will return nil.
|
||||||
|
-- @function [parent=#Weapon] getTarget
|
||||||
|
-- @param #Weapon self
|
||||||
|
-- @return #Object
|
||||||
|
|
||||||
|
--- returns weapon descriptor. Descriptor type depends on weapon category.
|
||||||
|
-- @function [parent=#Weapon] getDesc
|
||||||
|
-- @param #Weapon self
|
||||||
|
-- @return #Weapon.Desc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Weapon = {} --#Weapon
|
||||||
|
|
||||||
|
end -- Weapon
|
||||||
|
|
||||||
|
|
||||||
do -- Airbase
|
do -- Airbase
|
||||||
|
|
||||||
--- [DCS Class Airbase](https://wiki.hoggitworld.com/view/DCS_Class_Airbase)
|
--- [DCS Class Airbase](https://wiki.hoggitworld.com/view/DCS_Class_Airbase)
|
||||||
|
|||||||
115
Moose Development/Moose/Modules.lua
Normal file
115
Moose Development/Moose/Modules.lua
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
__Moose.Include( 'Scripts/Moose/Utilities/Routines.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Utilities/Utils.lua' )
|
||||||
|
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/Base.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/UserFlag.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/UserSound.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/Report.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/Scheduler.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/ScheduleDispatcher.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/Event.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/Settings.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/Menu.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/Zone.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/Database.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/Set.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/Point.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/Velocity.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/Message.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/Fsm.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/Radio.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/Spawn.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/SpawnStatic.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/Goal.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Core/Spot.lua' )
|
||||||
|
|
||||||
|
__Moose.Include( 'Scripts/Moose/Wrapper/Object.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Wrapper/Identifiable.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Wrapper/Positionable.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Wrapper/Controllable.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Wrapper/Group.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Wrapper/Unit.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Wrapper/Client.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Wrapper/Static.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Wrapper/Airbase.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Wrapper/Scenery.lua' )
|
||||||
|
|
||||||
|
__Moose.Include( 'Scripts/Moose/Cargo/Cargo.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Cargo/CargoUnit.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Cargo/CargoSlingload.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Cargo/CargoCrate.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Cargo/CargoGroup.lua' )
|
||||||
|
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/Scoring.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/CleanUp.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/Movement.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/Sead.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/Escort.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/MissileTrainer.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/ATC_Ground.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/Detection.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/Designate.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/RAT.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/Range.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/ZoneGoal.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/ZoneGoalCoalition.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/ZoneCaptureCoalition.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/Artillery.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/Suppression.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/PseudoATC.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Functional/Warehouse.lua' )
|
||||||
|
|
||||||
|
__Moose.Include( 'Scripts/Moose/Ops/Airboss.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Ops/RecoveryTanker.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Ops/RescueHelo.lua' )
|
||||||
|
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_Balancer.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_Air.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_A2A.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_A2A_Patrol.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_A2A_Cap.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_A2A_Gci.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_A2A_Dispatcher.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_A2G.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_A2G_Engage.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_A2G_BAI.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_A2G_CAS.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_A2G_SEAD.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_A2G_Patrol.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_A2G_Dispatcher.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_Patrol.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_Cap.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_Cas.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_Bai.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_Formation.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_APC.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Helicopter.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Airplane.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Dispatcher.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Dispatcher_APC.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Dispatcher_Helicopter.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Dispatcher_Airplane.lua' )
|
||||||
|
|
||||||
|
__Moose.Include( 'Scripts/Moose/Actions/Act_Assign.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Actions/Act_Route.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Actions/Act_Account.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Actions/Act_Assist.lua' )
|
||||||
|
|
||||||
|
__Moose.Include( 'Scripts/Moose/Tasking/CommandCenter.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Tasking/Mission.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Tasking/Task.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Tasking/TaskInfo.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Tasking/Task_Manager.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Tasking/DetectionManager.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Tasking/Task_A2G_Dispatcher.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Tasking/Task_A2G.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Tasking/Task_A2A_Dispatcher.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Tasking/Task_A2A.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Tasking/Task_Cargo.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Tasking/Task_Cargo_Transport.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Tasking/Task_Cargo_CSAR.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Tasking/Task_Cargo_Dispatcher.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/Tasking/TaskZoneCapture.lua' )
|
||||||
|
|
||||||
|
__Moose.Include( 'Scripts/Moose/Globals.lua' )
|
||||||
@ -168,6 +168,11 @@
|
|||||||
-- * @{#CONTROLLABLE.OptionAlarmStateGreen}
|
-- * @{#CONTROLLABLE.OptionAlarmStateGreen}
|
||||||
-- * @{#CONTROLLABLE.OptionAlarmStateRed}
|
-- * @{#CONTROLLABLE.OptionAlarmStateRed}
|
||||||
--
|
--
|
||||||
|
-- ## 5.4) Jettison weapons:
|
||||||
|
--
|
||||||
|
-- * @{#CONTROLLABLE.OptionAllowJettisonWeaponsOnThreat}
|
||||||
|
-- * @{#CONTROLLABLE.OptionKeepWeaponsOnThreat}
|
||||||
|
--
|
||||||
-- @field #CONTROLLABLE
|
-- @field #CONTROLLABLE
|
||||||
CONTROLLABLE = {
|
CONTROLLABLE = {
|
||||||
ClassName = "CONTROLLABLE",
|
ClassName = "CONTROLLABLE",
|
||||||
@ -302,7 +307,7 @@ end
|
|||||||
-- @param #CONTROLLABLE self
|
-- @param #CONTROLLABLE self
|
||||||
-- @return #CONTROLLABLE
|
-- @return #CONTROLLABLE
|
||||||
function CONTROLLABLE:ClearTasks()
|
function CONTROLLABLE:ClearTasks()
|
||||||
self:F2()
|
self:E( "ClearTasks" )
|
||||||
|
|
||||||
local DCSControllable = self:GetDCSObject()
|
local DCSControllable = self:GetDCSObject()
|
||||||
|
|
||||||
@ -376,13 +381,15 @@ end
|
|||||||
-- @param #number WaitTime Time in seconds, before the task is set.
|
-- @param #number WaitTime Time in seconds, before the task is set.
|
||||||
-- @return Wrapper.Controllable#CONTROLLABLE self
|
-- @return Wrapper.Controllable#CONTROLLABLE self
|
||||||
function CONTROLLABLE:SetTask( DCSTask, WaitTime )
|
function CONTROLLABLE:SetTask( DCSTask, WaitTime )
|
||||||
self:F2( { DCSTask = DCSTask } )
|
self:E( { "SetTask", WaitTime, DCSTask = DCSTask } )
|
||||||
|
|
||||||
local DCSControllable = self:GetDCSObject()
|
local DCSControllable = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSControllable then
|
if DCSControllable then
|
||||||
|
|
||||||
local DCSControllableName = self:GetName()
|
local DCSControllableName = self:GetName()
|
||||||
|
|
||||||
|
self:E( "Controllable Name = " .. DCSControllableName )
|
||||||
|
|
||||||
-- When a controllable SPAWNs, it takes about a second to get the controllable in the simulator. Setting tasks to unspawned controllables provides unexpected results.
|
-- When a controllable SPAWNs, it takes about a second to get the controllable in the simulator. Setting tasks to unspawned controllables provides unexpected results.
|
||||||
-- Therefore we schedule the functions to set the mission and options for the Controllable.
|
-- Therefore we schedule the functions to set the mission and options for the Controllable.
|
||||||
@ -1810,6 +1817,7 @@ function CONTROLLABLE:TaskFunction( FunctionString, ... )
|
|||||||
|
|
||||||
local DCSScript = {}
|
local DCSScript = {}
|
||||||
DCSScript[#DCSScript+1] = "local MissionControllable = GROUP:Find( ... ) "
|
DCSScript[#DCSScript+1] = "local MissionControllable = GROUP:Find( ... ) "
|
||||||
|
DCSScript[#DCSScript+1] = "env.info( 'TaskFunction: ' .. ( MissionControllable and MissionControllable:GetName() ) or 'No Group' )"
|
||||||
|
|
||||||
if arg and arg.n > 0 then
|
if arg and arg.n > 0 then
|
||||||
local ArgumentKey = '_' .. tostring( arg ):match("table: (.*)")
|
local ArgumentKey = '_' .. tostring( arg ):match("table: (.*)")
|
||||||
@ -3073,7 +3081,7 @@ function CONTROLLABLE:OptionRTBAmmo( WeaponsFlag )
|
|||||||
local Controller = self:_GetController()
|
local Controller = self:_GetController()
|
||||||
|
|
||||||
if self:IsAir() then
|
if self:IsAir() then
|
||||||
Controller:setOption( AI.Option.GROUND.id.RTB_ON_OUT_OF_AMMO, WeaponsFlag )
|
Controller:setOption( AI.Option.Air.id.RTB_ON_OUT_OF_AMMO, WeaponsFlag )
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@ -3083,6 +3091,47 @@ function CONTROLLABLE:OptionRTBAmmo( WeaponsFlag )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Allow to Jettison of weapons upon threat.
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:OptionAllowJettisonWeaponsOnThreat()
|
||||||
|
self:F2( { self.ControllableName } )
|
||||||
|
|
||||||
|
local DCSControllable = self:GetDCSObject()
|
||||||
|
if DCSControllable then
|
||||||
|
local Controller = self:_GetController()
|
||||||
|
|
||||||
|
if self:IsAir() then
|
||||||
|
Controller:setOption( AI.Option.Air.id.PROHIBIT_JETT, false )
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Keep weapons upon threat.
|
||||||
|
-- @param #CONTROLLABLE self
|
||||||
|
-- @return #CONTROLLABLE self
|
||||||
|
function CONTROLLABLE:OptionKeepWeaponsOnThreat()
|
||||||
|
self:F2( { self.ControllableName } )
|
||||||
|
|
||||||
|
local DCSControllable = self:GetDCSObject()
|
||||||
|
if DCSControllable then
|
||||||
|
local Controller = self:_GetController()
|
||||||
|
|
||||||
|
if self:IsAir() then
|
||||||
|
Controller:setOption( AI.Option.Air.id.PROHIBIT_JETT, true )
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -934,7 +934,7 @@ end
|
|||||||
-- @return #number The fuel state of the unit with the least amount of fuel
|
-- @return #number The fuel state of the unit with the least amount of fuel
|
||||||
-- @return #Unit reference to #Unit object for further processing
|
-- @return #Unit reference to #Unit object for further processing
|
||||||
function GROUP:GetFuelMin()
|
function GROUP:GetFuelMin()
|
||||||
self:F(self.ControllableName)
|
self:F3(self.ControllableName)
|
||||||
|
|
||||||
if not self:GetDCSObject() then
|
if not self:GetDCSObject() then
|
||||||
BASE:E( { "Cannot GetFuel", Group = self, Alive = self:IsAlive() } )
|
BASE:E( { "Cannot GetFuel", Group = self, Alive = self:IsAlive() } )
|
||||||
|
|||||||
@ -555,7 +555,7 @@ end
|
|||||||
-- @return #number The relative amount of fuel (from 0.0 to 1.0).
|
-- @return #number The relative amount of fuel (from 0.0 to 1.0).
|
||||||
-- @return #nil The DCS Unit is not existing or alive.
|
-- @return #nil The DCS Unit is not existing or alive.
|
||||||
function UNIT:GetFuel()
|
function UNIT:GetFuel()
|
||||||
self:F( self.UnitName )
|
self:F3( self.UnitName )
|
||||||
|
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
@ -571,7 +571,7 @@ end
|
|||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #list<Wrapper.Unit#UNIT> A list of one @{Wrapper.Unit}.
|
-- @return #list<Wrapper.Unit#UNIT> A list of one @{Wrapper.Unit}.
|
||||||
function UNIT:GetUnits()
|
function UNIT:GetUnits()
|
||||||
self:F2( { self.UnitName } )
|
self:F3( { self.UnitName } )
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
|
|
||||||
local Units = {}
|
local Units = {}
|
||||||
|
|||||||
6
Moose Setup/Eclipse/Moose Loader Dynamic.launch
Normal file
6
Moose Setup/Eclipse/Moose Loader Dynamic.launch
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
|
||||||
|
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="C:\ProgramData\chocolatey\lib\lua51\tools\lua5.1.exe"/>
|
||||||
|
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value=""Moose Setup\Moose_Create.lua" "D" "LOCAL" "${resource_loc:/MOOSE/Moose Development/Moose}" "${resource_loc:/MOOSE/Moose Setup}" ${resource_loc:/MOOSE_INCLUDE/Moose_Include_Dynamic}"/>
|
||||||
|
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/MOOSE}"/>
|
||||||
|
</launchConfiguration>
|
||||||
6
Moose Setup/Eclipse/Moose Loader Static.launch
Normal file
6
Moose Setup/Eclipse/Moose Loader Static.launch
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
|
||||||
|
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="C:\ProgramData\chocolatey\lib\lua51\tools\lua5.1.exe"/>
|
||||||
|
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value=""Moose Setup\Moose_Create.lua" "S" "LOCAL" "${resource_loc:/MOOSE/Moose Development/Moose}" "${resource_loc:/MOOSE/Moose Setup}" ${resource_loc:/MOOSE_INCLUDE/Moose_Include_Static}"/>
|
||||||
|
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/MOOSE}"/>
|
||||||
|
</launchConfiguration>
|
||||||
@ -18,3 +18,5 @@ __Moose.Include = function( IncludeFile )
|
|||||||
end
|
end
|
||||||
|
|
||||||
__Moose.Includes = {}
|
__Moose.Includes = {}
|
||||||
|
|
||||||
|
__Moose.Include( 'Scripts/Moose/Modules.lua' )
|
||||||
|
|||||||
@ -72,6 +72,9 @@ AI/AI_A2A_Gci.lua
|
|||||||
AI/AI_A2A_Dispatcher.lua
|
AI/AI_A2A_Dispatcher.lua
|
||||||
AI/AI_A2G.lua
|
AI/AI_A2G.lua
|
||||||
AI/AI_A2G_Engage.lua
|
AI/AI_A2G_Engage.lua
|
||||||
|
AI/AI_A2G_BAI.lua
|
||||||
|
AI/AI_A2G_CAS.lua
|
||||||
|
AI/AI_A2G_SEAD.lua
|
||||||
AI/AI_A2G_Patrol.lua
|
AI/AI_A2G_Patrol.lua
|
||||||
AI/AI_A2G_Dispatcher.lua
|
AI/AI_A2G_Dispatcher.lua
|
||||||
AI/AI_Patrol.lua
|
AI/AI_Patrol.lua
|
||||||
@ -109,4 +112,4 @@ Tasking/Task_Cargo_CSAR.lua
|
|||||||
Tasking/Task_Cargo_Dispatcher.lua
|
Tasking/Task_Cargo_Dispatcher.lua
|
||||||
Tasking/TaskZoneCapture.lua
|
Tasking/TaskZoneCapture.lua
|
||||||
|
|
||||||
Moose.lua
|
Globals.lua
|
||||||
|
|||||||
@ -12,15 +12,15 @@ print( "Moose development path : " .. MooseDevelopmentPath )
|
|||||||
print( "Moose setup path : " .. MooseSetupPath )
|
print( "Moose setup path : " .. MooseSetupPath )
|
||||||
print( "Moose target path : " .. MooseTargetPath )
|
print( "Moose target path : " .. MooseTargetPath )
|
||||||
|
|
||||||
local MooseSourcesFilePath = MooseSetupPath .. "/Moose.files"
|
local MooseModulesFilePath = MooseDevelopmentPath .. "/Modules.lua"
|
||||||
local MooseFilePath = MooseTargetPath.."/Moose.lua"
|
local LoaderFilePath = MooseTargetPath .. "/Moose.lua"
|
||||||
|
|
||||||
print( "Reading Moose source list : " .. MooseSourcesFilePath )
|
print( "Reading Moose source list : " .. MooseModulesFilePath )
|
||||||
|
|
||||||
local MooseFile = io.open( MooseFilePath, "w" )
|
local LoaderFile = io.open( LoaderFilePath, "w" )
|
||||||
|
|
||||||
if MooseDynamicStatic == "S" then
|
if MooseDynamicStatic == "S" then
|
||||||
MooseFile:write( "env.info( '*** MOOSE GITHUB Commit Hash ID: " .. MooseCommitHash .. " ***' )\n" )
|
LoaderFile:write( "env.info( '*** MOOSE GITHUB Commit Hash ID: " .. MooseCommitHash .. " ***' )\n" )
|
||||||
end
|
end
|
||||||
|
|
||||||
local MooseLoaderPath
|
local MooseLoaderPath
|
||||||
@ -35,27 +35,26 @@ local MooseLoader = io.open( MooseLoaderPath, "r" )
|
|||||||
local MooseLoaderText = MooseLoader:read( "*a" )
|
local MooseLoaderText = MooseLoader:read( "*a" )
|
||||||
MooseLoader:close()
|
MooseLoader:close()
|
||||||
|
|
||||||
MooseFile:write( MooseLoaderText )
|
LoaderFile:write( MooseLoaderText )
|
||||||
|
|
||||||
|
local MooseSourcesFile = io.open( MooseModulesFilePath, "r" )
|
||||||
local MooseSourcesFile = io.open( MooseSourcesFilePath, "r" )
|
|
||||||
local MooseSource = MooseSourcesFile:read("*l")
|
local MooseSource = MooseSourcesFile:read("*l")
|
||||||
|
|
||||||
while( MooseSource ) do
|
while( MooseSource ) do
|
||||||
|
|
||||||
if MooseSource ~= "" then
|
if MooseSource ~= "" then
|
||||||
|
MooseSource = string.match( MooseSource, "Scripts/Moose/(.+)'" )
|
||||||
local MooseFilePath = MooseDevelopmentPath .. "/" .. MooseSource
|
local MooseFilePath = MooseDevelopmentPath .. "/" .. MooseSource
|
||||||
if MooseDynamicStatic == "D" then
|
if MooseDynamicStatic == "D" then
|
||||||
print( "Load dynamic: " .. MooseSource )
|
print( "Load dynamic: " .. MooseFilePath )
|
||||||
MooseFile:write( "__Moose.Include( 'Scripts/Moose/" .. MooseSource .. "' )\n" )
|
|
||||||
end
|
end
|
||||||
if MooseDynamicStatic == "S" then
|
if MooseDynamicStatic == "S" then
|
||||||
print( "Load static: " .. MooseSource )
|
print( "Load static: " .. MooseFilePath )
|
||||||
local MooseSourceFile = io.open( MooseFilePath, "r" )
|
local MooseSourceFile = io.open( MooseFilePath, "r" )
|
||||||
local MooseSourceFileText = MooseSourceFile:read( "*a" )
|
local MooseSourceFileText = MooseSourceFile:read( "*a" )
|
||||||
MooseSourceFile:close()
|
MooseSourceFile:close()
|
||||||
|
|
||||||
MooseFile:write( MooseSourceFileText )
|
LoaderFile:write( MooseSourceFileText )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -63,13 +62,13 @@ while( MooseSource ) do
|
|||||||
end
|
end
|
||||||
|
|
||||||
if MooseDynamicStatic == "D" then
|
if MooseDynamicStatic == "D" then
|
||||||
MooseFile:write( "BASE:TraceOnOff( true )\n" )
|
LoaderFile:write( "BASE:TraceOnOff( true )\n" )
|
||||||
end
|
end
|
||||||
if MooseDynamicStatic == "S" then
|
if MooseDynamicStatic == "S" then
|
||||||
MooseFile:write( "BASE:TraceOnOff( false )\n" )
|
LoaderFile:write( "BASE:TraceOnOff( false )\n" )
|
||||||
end
|
end
|
||||||
|
|
||||||
MooseFile:write( "env.info( '*** MOOSE INCLUDE END *** ' )\n" )
|
LoaderFile:write( "env.info( '*** MOOSE INCLUDE END *** ' )\n" )
|
||||||
|
|
||||||
MooseSourcesFile:close()
|
MooseSourcesFile:close()
|
||||||
MooseFile:close()
|
LoaderFile:close()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user