mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Improvements to A2A and A2G Dispatchers
This commit is contained in:
parent
4ea44308bc
commit
ad2ce8df78
@ -125,6 +125,7 @@ function AI_A2A_CAP:New2( AICap, EngageMinSpeed, EngageMaxSpeed, EngageFloorAlti
|
|||||||
self:SetDamageThreshold( 0.4 )
|
self:SetDamageThreshold( 0.4 )
|
||||||
self:SetDisengageRadius( 70000 )
|
self:SetDisengageRadius( 70000 )
|
||||||
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -203,6 +204,7 @@ function AI_A2A_CAP:CreateAttackUnitTasks( AttackSetUnit, DefenderGroup, EngageA
|
|||||||
if AttackUnit:IsAlive() and AttackUnit:IsAir() then
|
if AttackUnit:IsAlive() and AttackUnit:IsAir() then
|
||||||
-- TODO: Add coalition check? Only attack units of if AttackUnit:GetCoalition()~=AICap:GetCoalition()
|
-- TODO: Add coalition check? Only attack units of if AttackUnit:GetCoalition()~=AICap:GetCoalition()
|
||||||
-- Maybe the detected set also contains
|
-- Maybe the detected set also contains
|
||||||
|
self:T( { "Attacking Task:", AttackUnit:GetName(), AttackUnit:IsAlive(), AttackUnit:IsAir() } )
|
||||||
AttackUnitTasks[#AttackUnitTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit )
|
AttackUnitTasks[#AttackUnitTasks+1] = DefenderGroup:TaskAttackUnit( AttackUnit )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -3267,7 +3267,9 @@ do -- AI_A2A_DISPATCHER
|
|||||||
local DefenderName = DefenderGroup:GetCallsign()
|
local DefenderName = DefenderGroup:GetCallsign()
|
||||||
local Dispatcher = self:GetDispatcher() -- #AI_A2A_DISPATCHER
|
local Dispatcher = self:GetDispatcher() -- #AI_A2A_DISPATCHER
|
||||||
local Squadron = Dispatcher:GetSquadronFromDefender( DefenderGroup )
|
local Squadron = Dispatcher:GetSquadronFromDefender( DefenderGroup )
|
||||||
|
if Squadron then
|
||||||
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " returning to base.", DefenderGroup )
|
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " returning to base.", DefenderGroup )
|
||||||
|
end
|
||||||
Dispatcher:ClearDefenderTaskTarget( DefenderGroup )
|
Dispatcher:ClearDefenderTaskTarget( DefenderGroup )
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -3313,7 +3315,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
for DefenderID, Defender in pairs( Defenders ) do
|
for DefenderID, Defender in pairs( Defenders ) do
|
||||||
|
|
||||||
local Fsm = self:GetDefenderTaskFsm( Defender )
|
local Fsm = self:GetDefenderTaskFsm( Defender )
|
||||||
Fsm:__EngageRoute( 1, AttackerDetection.Set ) -- Engage on the TargetSetUnit
|
Fsm:EngageRoute( AttackerDetection.Set ) -- Engage on the TargetSetUnit
|
||||||
|
|
||||||
self:SetDefenderTaskTarget( Defender, AttackerDetection )
|
self:SetDefenderTaskTarget( Defender, AttackerDetection )
|
||||||
|
|
||||||
@ -3630,6 +3632,32 @@ do -- AI_A2A_DISPATCHER
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Assigns A2G AI Tasks in relation to the detected items.
|
||||||
|
-- @param #AI_A2G_DISPATCHER self
|
||||||
|
function AI_A2A_DISPATCHER:Order( DetectedItem )
|
||||||
|
local AttackCoordinate = self.Detection:GetDetectedItemCoordinate( DetectedItem )
|
||||||
|
|
||||||
|
local ShortestDistance = 999999999
|
||||||
|
|
||||||
|
for DefenderSquadronName, DefenderSquadron in pairs( self.DefenderSquadrons ) do
|
||||||
|
|
||||||
|
self:I( { DefenderSquadron = DefenderSquadron.Name } )
|
||||||
|
|
||||||
|
local Airbase = DefenderSquadron.Airbase
|
||||||
|
local AirbaseCoordinate = Airbase:GetCoordinate()
|
||||||
|
|
||||||
|
local EvaluateDistance = AttackCoordinate:Get2DDistance( AirbaseCoordinate )
|
||||||
|
|
||||||
|
if EvaluateDistance <= ShortestDistance then
|
||||||
|
ShortestDistance = EvaluateDistance
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return ShortestDistance
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Shows the tactical display.
|
--- Shows the tactical display.
|
||||||
-- @param #AI_A2A_DISPATCHER self
|
-- @param #AI_A2A_DISPATCHER self
|
||||||
function AI_A2A_DISPATCHER:ShowTacticalDisplay( Detection )
|
function AI_A2A_DISPATCHER:ShowTacticalDisplay( Detection )
|
||||||
@ -3645,7 +3673,8 @@ do -- AI_A2A_DISPATCHER
|
|||||||
local DefenderGroupCount = 0
|
local DefenderGroupCount = 0
|
||||||
|
|
||||||
-- Now that all obsolete tasks are removed, loop through the detected targets.
|
-- Now that all obsolete tasks are removed, loop through the detected targets.
|
||||||
for DetectedItemID, DetectedItem in pairs( Detection:GetDetectedItems() ) do
|
--for DetectedItemID, DetectedItem in pairs( Detection:GetDetectedItems() ) do
|
||||||
|
for DetectedItemID, DetectedItem in UTILS.spairs( Detection:GetDetectedItems(), function( t, a, b ) return self:Order(t[a]) < self:Order(t[b]) end ) do
|
||||||
|
|
||||||
local DetectedItem = DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
|
local DetectedItem = DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
|
||||||
local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT
|
local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT
|
||||||
@ -3761,7 +3790,9 @@ do -- AI_A2A_DISPATCHER
|
|||||||
local DefenderGroupCount = 0
|
local DefenderGroupCount = 0
|
||||||
|
|
||||||
-- Now that all obsolete tasks are removed, loop through the detected targets.
|
-- Now that all obsolete tasks are removed, loop through the detected targets.
|
||||||
for DetectedItemID, DetectedItem in pairs( Detection:GetDetectedItems() ) do
|
-- Closest detected targets to be considered first!
|
||||||
|
--for DetectedItemID, DetectedItem in pairs( Detection:GetDetectedItems() ) do
|
||||||
|
for DetectedItemID, DetectedItem in UTILS.spairs( Detection:GetDetectedItems(), function( t, a, b ) return self:Order(t[a]) < self:Order(t[b]) end ) do
|
||||||
|
|
||||||
local DetectedItem = DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
|
local DetectedItem = DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
|
||||||
local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT
|
local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT
|
||||||
@ -3790,62 +3821,10 @@ do -- AI_A2A_DISPATCHER
|
|||||||
self:GCI( DetectedItem, DefendersMissing, Friendlies )
|
self:GCI( DetectedItem, DefendersMissing, Friendlies )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.TacticalDisplay then
|
|
||||||
-- Show tactical situation
|
|
||||||
Report:Add( string.format( "\n- Target %s (%s): (#%d) %s" , DetectedItem.ItemID, DetectedItem.Index, DetectedItem.Set:Count(), DetectedItem.Set:GetObjectNames() ) )
|
|
||||||
for Defender, DefenderTask in pairs( self:GetDefenderTasks() ) do
|
|
||||||
local Defender = Defender -- Wrapper.Group#GROUP
|
|
||||||
if DefenderTask.Target and DefenderTask.Target.Index == DetectedItem.Index then
|
|
||||||
if Defender and Defender:IsAlive() then
|
|
||||||
DefenderGroupCount = DefenderGroupCount + 1
|
|
||||||
local Fuel = Defender:GetFuelMin() * 100
|
|
||||||
local Damage = Defender:GetLife() / Defender:GetLife0() * 100
|
|
||||||
Report:Add( string.format( " - %s*%d/%d (%s - %s): (#%d) F: %3d, D:%3d - %s",
|
|
||||||
Defender:GetName(),
|
|
||||||
Defender:GetSize(),
|
|
||||||
Defender:GetInitialSize(),
|
|
||||||
DefenderTask.Type,
|
|
||||||
DefenderTask.Fsm:GetState(),
|
|
||||||
Defender:GetSize(),
|
|
||||||
Fuel,
|
|
||||||
Damage,
|
|
||||||
Defender:HasTask() == true and "Executing" or "Idle" ) )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.TacticalDisplay then
|
if self.TacticalDisplay then
|
||||||
Report:Add( "\n- No Targets:")
|
self:ShowTacticalDisplay( Detection )
|
||||||
local TaskCount = 0
|
|
||||||
for Defender, DefenderTask in pairs( self:GetDefenderTasks() ) do
|
|
||||||
TaskCount = TaskCount + 1
|
|
||||||
local Defender = Defender -- Wrapper.Group#GROUP
|
|
||||||
if not DefenderTask.Target then
|
|
||||||
if Defender:IsAlive() then
|
|
||||||
local DefenderHasTask = Defender:HasTask()
|
|
||||||
local Fuel = Defender:GetFuelMin() * 100
|
|
||||||
local Damage = Defender:GetLife() / Defender:GetLife0() * 100
|
|
||||||
DefenderGroupCount = DefenderGroupCount + 1
|
|
||||||
Report:Add( string.format( " - %s*%d/%d (%s - %s): (#%d) F: %3d, D:%3d - %s",
|
|
||||||
Defender:GetName(),
|
|
||||||
Defender:GetSize(),
|
|
||||||
Defender:GetInitialSize(),
|
|
||||||
DefenderTask.Type,
|
|
||||||
DefenderTask.Fsm:GetState(),
|
|
||||||
Defender:GetSize(),
|
|
||||||
Fuel,
|
|
||||||
Damage,
|
|
||||||
Defender:HasTask() == true and "Executing" or "Idle" ) )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Report:Add( string.format( "\n- %d Tasks - %d Defender Groups", TaskCount, DefenderGroupCount ) )
|
|
||||||
|
|
||||||
self:F( Report:Text( "\n" ) )
|
|
||||||
trigger.action.outText( Report:Text( "\n" ), 25 )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|||||||
@ -50,10 +50,6 @@ function AI_A2G_BAI:New2( AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAl
|
|||||||
local AI_Air_Engage = AI_AIR_ENGAGE:New( AI_Air_Patrol, AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, EngageAltType )
|
local AI_Air_Engage = AI_AIR_ENGAGE:New( AI_Air_Patrol, AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, EngageAltType )
|
||||||
local self = BASE:Inherit( self, AI_Air_Engage )
|
local self = BASE:Inherit( self, AI_Air_Engage )
|
||||||
|
|
||||||
local RTBSpeedMax = AIGroup:GetSpeedMax() or 9999
|
|
||||||
|
|
||||||
self:SetRTBSpeed( RTBSpeedMax * 0.50, RTBSpeedMax * 0.75 )
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -50,10 +50,6 @@ function AI_A2G_CAS:New2( AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAl
|
|||||||
local AI_Air_Engage = AI_AIR_ENGAGE:New( AI_Air_Patrol, AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, EngageAltType )
|
local AI_Air_Engage = AI_AIR_ENGAGE:New( AI_Air_Patrol, AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, EngageAltType )
|
||||||
local self = BASE:Inherit( self, AI_Air_Engage )
|
local self = BASE:Inherit( self, AI_Air_Engage )
|
||||||
|
|
||||||
local RTBSpeedMax = AIGroup:GetSpeedMax() or 9999
|
|
||||||
|
|
||||||
self:SetRTBSpeed( RTBSpeedMax * 0.50, RTBSpeedMax * 0.75 )
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -100,10 +100,6 @@ function AI_A2G_SEAD:New2( AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorA
|
|||||||
local AI_Air_Engage = AI_AIR_ENGAGE:New( AI_Air_Patrol, AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, EngageAltType )
|
local AI_Air_Engage = AI_AIR_ENGAGE:New( AI_Air_Patrol, AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAltitude, EngageCeilingAltitude, EngageAltType )
|
||||||
local self = BASE:Inherit( self, AI_Air_Engage )
|
local self = BASE:Inherit( self, AI_Air_Engage )
|
||||||
|
|
||||||
local RTBSpeedMax = AIGroup:GetSpeedMax() or 9999
|
|
||||||
|
|
||||||
self:SetRTBSpeed( RTBSpeedMax * 0.50, RTBSpeedMax * 0.75 )
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -308,7 +308,7 @@ end
|
|||||||
-- @param DCS#Speed RTBMaxSpeed The maximum 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
|
-- @return #AI_AIR self
|
||||||
function AI_AIR:SetRTBSpeed( RTBMinSpeed, RTBMaxSpeed )
|
function AI_AIR:SetRTBSpeed( RTBMinSpeed, RTBMaxSpeed )
|
||||||
self:F2( { RTBMinSpeed, RTBMaxSpeed } )
|
self:F( { RTBMinSpeed, RTBMaxSpeed } )
|
||||||
|
|
||||||
self.RTBMinSpeed = RTBMinSpeed
|
self.RTBMinSpeed = RTBMinSpeed
|
||||||
self.RTBMaxSpeed = RTBMaxSpeed
|
self.RTBMaxSpeed = RTBMaxSpeed
|
||||||
@ -425,7 +425,18 @@ function AI_AIR:onafterStart( Controllable, From, Event, To )
|
|||||||
Controllable:OptionROTVertical()
|
Controllable:OptionROTVertical()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Coordinates the approriate returning action.
|
||||||
|
-- @param #AI_AIR self
|
||||||
|
-- @return #AI_AIR self
|
||||||
|
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable 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_AIR:onafterReturn( Controllable, From, Event, To )
|
||||||
|
|
||||||
|
self:__RTB( self.TaskDelay )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
--- @param #AI_AIR self
|
--- @param #AI_AIR self
|
||||||
function AI_AIR:onbeforeStatus()
|
function AI_AIR:onbeforeStatus()
|
||||||
@ -481,12 +492,15 @@ function AI_AIR:onafterStatus()
|
|||||||
OldAIControllable:SetTask( TimedOrbitTask, 10 )
|
OldAIControllable:SetTask( TimedOrbitTask, 10 )
|
||||||
|
|
||||||
self:Fuel()
|
self:Fuel()
|
||||||
RTB = true
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if self:Is( "Fuel" ) and not self:Is( "Home" ) and not self:is( "Refuelling" ) then
|
||||||
|
RTB = true
|
||||||
|
end
|
||||||
|
|
||||||
-- 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()
|
||||||
@ -581,7 +595,13 @@ function AI_AIR:onafterRTB( AIGroup, From, Event, To )
|
|||||||
|
|
||||||
local FromCoord = AIGroup:GetCoordinate()
|
local FromCoord = AIGroup:GetCoordinate()
|
||||||
local ToTargetCoord = self.HomeAirbase:GetCoordinate()
|
local ToTargetCoord = self.HomeAirbase:GetCoordinate()
|
||||||
local ToTargetSpeed = math.random( self.RTBMinSpeed, self.RTBMaxSpeed )
|
|
||||||
|
if not self.RTBMinSpeed and not self.RTBMaxSpeed then
|
||||||
|
local RTBSpeedMax = AIGroup:GetSpeedMax()
|
||||||
|
self:SetRTBSpeed( RTBSpeedMax * 0.25, RTBSpeedMax * 0.25 )
|
||||||
|
end
|
||||||
|
|
||||||
|
local RTBSpeed = math.random( self.RTBMinSpeed, self.RTBMaxSpeed )
|
||||||
local ToAirbaseAngle = FromCoord:GetAngleDegrees( FromCoord:GetDirectionVec3( ToTargetCoord ) )
|
local ToAirbaseAngle = FromCoord:GetAngleDegrees( FromCoord:GetDirectionVec3( ToTargetCoord ) )
|
||||||
|
|
||||||
local Distance = FromCoord:Get2DDistance( ToTargetCoord )
|
local Distance = FromCoord:Get2DDistance( ToTargetCoord )
|
||||||
@ -593,12 +613,19 @@ function AI_AIR:onafterRTB( AIGroup, From, Event, To )
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not AIGroup:InAir() == true then
|
||||||
|
self:I( "Not anymore in the air, considered Home." )
|
||||||
|
self:Home()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local FromRTBRoutePoint = FromCoord:WaypointAir(
|
local FromRTBRoutePoint = FromCoord:WaypointAir(
|
||||||
self.PatrolAltType,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
ToTargetSpeed,
|
RTBSpeed,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -607,7 +634,7 @@ function AI_AIR:onafterRTB( AIGroup, From, Event, To )
|
|||||||
self.PatrolAltType,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
ToTargetSpeed,
|
RTBSpeed,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -364,7 +364,6 @@ end
|
|||||||
function AI_AIR_ENGAGE:onafterAbort( AIGroup, From, Event, To )
|
function AI_AIR_ENGAGE:onafterAbort( AIGroup, From, Event, To )
|
||||||
AIGroup:ClearTasks()
|
AIGroup:ClearTasks()
|
||||||
self:Return()
|
self:Return()
|
||||||
self:__RTB( self.TaskDelay )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -500,7 +499,6 @@ function AI_AIR_ENGAGE:onafterEngageRoute( DefenderGroup, From, Event, To, Attac
|
|||||||
else
|
else
|
||||||
self:I( DefenderGroupName .. ": No targets found -> Going RTB")
|
self:I( DefenderGroupName .. ": No targets found -> Going RTB")
|
||||||
self:Return()
|
self:Return()
|
||||||
self:__RTB( self.TaskDelay )
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -574,14 +572,14 @@ function AI_AIR_ENGAGE:onafterEngage( DefenderGroup, From, Event, To, AttackSetU
|
|||||||
|
|
||||||
if TargetDistance <= EngageDistance * 3 then
|
if TargetDistance <= EngageDistance * 3 then
|
||||||
|
|
||||||
local AttackUnitTasks = self:CreateAttackUnitTasks( AttackSetUnit, DefenderGroup, EngageAltitude )
|
local AttackUnitTasks = self:CreateAttackUnitTasks( AttackSetUnit, DefenderGroup, EngageAltitude ) -- Polymorphic
|
||||||
|
|
||||||
if #AttackUnitTasks == 0 then
|
if #AttackUnitTasks == 0 then
|
||||||
self:I( DefenderGroupName .. ": No targets found -> Going RTB")
|
self:I( DefenderGroupName .. ": No valid targets found -> Going RTB")
|
||||||
self:Return()
|
self:Return()
|
||||||
self:__RTB( self.TaskDelay )
|
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
|
self:I( DefenderGroupName .. ": Engaging targets " )
|
||||||
DefenderGroup:OptionROEOpenFire()
|
DefenderGroup:OptionROEOpenFire()
|
||||||
DefenderGroup:OptionROTEvadeFire()
|
DefenderGroup:OptionROTEvadeFire()
|
||||||
DefenderGroup:OptionKeepWeaponsOnThreat()
|
DefenderGroup:OptionKeepWeaponsOnThreat()
|
||||||
@ -597,9 +595,8 @@ function AI_AIR_ENGAGE:onafterEngage( DefenderGroup, From, Event, To, AttackSetU
|
|||||||
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:I( DefenderGroupName .. ": No targets found -> Going RTB")
|
self:I( DefenderGroupName .. ": No targets found -> returning.")
|
||||||
self:Return()
|
self:Return()
|
||||||
self:__RTB( self.TaskDelay )
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
289
Moose Development/Moose/AI/AI_Air_Squadron.lua
Normal file
289
Moose Development/Moose/AI/AI_Air_Squadron.lua
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
--- **AI** -- Models squadrons for airplanes and helicopters.
|
||||||
|
--
|
||||||
|
-- This is a class used in the @{AI_Air_Dispatcher} and derived dispatcher classes.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @module AI.AI_Air_Squadron
|
||||||
|
-- @image AI_Air_To_Air_Engage.JPG
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- @type AI_AIR_SQUADRON
|
||||||
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
|
||||||
|
--- Implements the core functions modeling squadrons for airplanes and helicopters.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @field #AI_AIR_SQUADRON
|
||||||
|
AI_AIR_SQUADRON = {
|
||||||
|
ClassName = "AI_AIR_SQUADRON",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Creates a new AI_AIR_SQUADRON object
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @return #AI_AIR_SQUADRON
|
||||||
|
function AI_AIR_SQUADRON:New( SquadronName, AirbaseName, TemplatePrefixes, ResourceCount )
|
||||||
|
|
||||||
|
self:I( { Air_Squadron = { SquadronName, AirbaseName, TemplatePrefixes, ResourceCount } } )
|
||||||
|
|
||||||
|
local AI_Air_Squadron = BASE:New() -- #AI_AIR_SQUADRON
|
||||||
|
|
||||||
|
AI_Air_Squadron.Name = SquadronName
|
||||||
|
AI_Air_Squadron.Airbase = AIRBASE:FindByName( AirbaseName )
|
||||||
|
AI_Air_Squadron.AirbaseName = AI_Air_Squadron.Airbase:GetName()
|
||||||
|
if not AI_Air_Squadron.Airbase then
|
||||||
|
error( "Cannot find airbase with name:" .. AirbaseName )
|
||||||
|
end
|
||||||
|
|
||||||
|
AI_Air_Squadron.Spawn = {}
|
||||||
|
if type( TemplatePrefixes ) == "string" then
|
||||||
|
local SpawnTemplate = TemplatePrefixes
|
||||||
|
self.DefenderSpawns[SpawnTemplate] = self.DefenderSpawns[SpawnTemplate] or SPAWN:New( SpawnTemplate ) -- :InitCleanUp( 180 )
|
||||||
|
AI_Air_Squadron.Spawn[1] = self.DefenderSpawns[SpawnTemplate]
|
||||||
|
else
|
||||||
|
for TemplateID, SpawnTemplate in pairs( TemplatePrefixes ) do
|
||||||
|
self.DefenderSpawns[SpawnTemplate] = self.DefenderSpawns[SpawnTemplate] or SPAWN:New( SpawnTemplate ) -- :InitCleanUp( 180 )
|
||||||
|
AI_Air_Squadron.Spawn[#AI_Air_Squadron.Spawn+1] = self.DefenderSpawns[SpawnTemplate]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
AI_Air_Squadron.ResourceCount = ResourceCount
|
||||||
|
AI_Air_Squadron.TemplatePrefixes = TemplatePrefixes
|
||||||
|
AI_Air_Squadron.Captured = false -- Not captured. This flag will be set to true, when the airbase where the squadron is located, is captured.
|
||||||
|
|
||||||
|
self:SetSquadronLanguage( SquadronName, "EN" ) -- Squadrons speak English by default.
|
||||||
|
|
||||||
|
return AI_Air_Squadron
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the Name of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @param #string Name The Squadron Name.
|
||||||
|
-- @return #AI_AIR_SQUADRON The Squadron.
|
||||||
|
function AI_AIR_SQUADRON:SetName( Name )
|
||||||
|
|
||||||
|
self.Name = Name
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the Name of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @return #string The Squadron Name.
|
||||||
|
function AI_AIR_SQUADRON:GetName()
|
||||||
|
|
||||||
|
return self.Name
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the ResourceCount of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @param #number ResourceCount The Squadron ResourceCount.
|
||||||
|
-- @return #AI_AIR_SQUADRON The Squadron.
|
||||||
|
function AI_AIR_SQUADRON:SetResourceCount( ResourceCount )
|
||||||
|
|
||||||
|
self.ResourceCount = ResourceCount
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the ResourceCount of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @return #number The Squadron ResourceCount.
|
||||||
|
function AI_AIR_SQUADRON:GetResourceCount()
|
||||||
|
|
||||||
|
return self.ResourceCount
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add Resources to the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @param #number Resources The Resources to be added.
|
||||||
|
-- @return #AI_AIR_SQUADRON The Squadron.
|
||||||
|
function AI_AIR_SQUADRON:AddResources( Resources )
|
||||||
|
|
||||||
|
self.ResourceCount = self.ResourceCount + Resources
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove Resources to the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @param #number Resources The Resources to be removed.
|
||||||
|
-- @return #AI_AIR_SQUADRON The Squadron.
|
||||||
|
function AI_AIR_SQUADRON:RemoveResources( Resources )
|
||||||
|
|
||||||
|
self.ResourceCount = self.ResourceCount - Resources
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the Overhead of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @param #number Overhead The Squadron Overhead.
|
||||||
|
-- @return #AI_AIR_SQUADRON The Squadron.
|
||||||
|
function AI_AIR_SQUADRON:SetOverhead( Overhead )
|
||||||
|
|
||||||
|
self.Overhead = Overhead
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the Overhead of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @return #number The Squadron Overhead.
|
||||||
|
function AI_AIR_SQUADRON:GetOverhead()
|
||||||
|
|
||||||
|
return self.Overhead
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the Grouping of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @param #number Grouping The Squadron Grouping.
|
||||||
|
-- @return #AI_AIR_SQUADRON The Squadron.
|
||||||
|
function AI_AIR_SQUADRON:SetGrouping( Grouping )
|
||||||
|
|
||||||
|
self.Grouping = Grouping
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the Grouping of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @return #number The Squadron Grouping.
|
||||||
|
function AI_AIR_SQUADRON:GetGrouping()
|
||||||
|
|
||||||
|
return self.Grouping
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the FuelThreshold of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @param #number FuelThreshold The Squadron FuelThreshold.
|
||||||
|
-- @return #AI_AIR_SQUADRON The Squadron.
|
||||||
|
function AI_AIR_SQUADRON:SetFuelThreshold( FuelThreshold )
|
||||||
|
|
||||||
|
self.FuelThreshold = FuelThreshold
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the FuelThreshold of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @return #number The Squadron FuelThreshold.
|
||||||
|
function AI_AIR_SQUADRON:GetFuelThreshold()
|
||||||
|
|
||||||
|
return self.FuelThreshold
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the EngageProbability of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @param #number EngageProbability The Squadron EngageProbability.
|
||||||
|
-- @return #AI_AIR_SQUADRON The Squadron.
|
||||||
|
function AI_AIR_SQUADRON:SetEngageProbability( EngageProbability )
|
||||||
|
|
||||||
|
self.EngageProbability = EngageProbability
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the EngageProbability of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @return #number The Squadron EngageProbability.
|
||||||
|
function AI_AIR_SQUADRON:GetEngageProbability()
|
||||||
|
|
||||||
|
return self.EngageProbability
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the Takeoff of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @param #number Takeoff The Squadron Takeoff.
|
||||||
|
-- @return #AI_AIR_SQUADRON The Squadron.
|
||||||
|
function AI_AIR_SQUADRON:SetTakeoff( Takeoff )
|
||||||
|
|
||||||
|
self.Takeoff = Takeoff
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the Takeoff of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @return #number The Squadron Takeoff.
|
||||||
|
function AI_AIR_SQUADRON:GetTakeoff()
|
||||||
|
|
||||||
|
return self.Takeoff
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the Landing of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @param #number Landing The Squadron Landing.
|
||||||
|
-- @return #AI_AIR_SQUADRON The Squadron.
|
||||||
|
function AI_AIR_SQUADRON:SetLanding( Landing )
|
||||||
|
|
||||||
|
self.Landing = Landing
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the Landing of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @return #number The Squadron Landing.
|
||||||
|
function AI_AIR_SQUADRON:GetLanding()
|
||||||
|
|
||||||
|
return self.Landing
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the TankerName of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @param #string TankerName The Squadron Tanker Name.
|
||||||
|
-- @return #AI_AIR_SQUADRON The Squadron.
|
||||||
|
function AI_AIR_SQUADRON:SetTankerName( TankerName )
|
||||||
|
|
||||||
|
self.TankerName = TankerName
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the Tanker Name of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @return #string The Squadron Tanker Name.
|
||||||
|
function AI_AIR_SQUADRON:GetTankerName()
|
||||||
|
|
||||||
|
return self.TankerName
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set the Radio of the Squadron.
|
||||||
|
-- @param #AI_AIR_SQUADRON self
|
||||||
|
-- @param #number RadioFrequency The frequency of communication.
|
||||||
|
-- @param #number RadioModulation The modulation of communication.
|
||||||
|
-- @param #number RadioPower The power in Watts of communication.
|
||||||
|
-- @param #string Language The language of the radio speech.
|
||||||
|
-- @return #AI_AIR_SQUADRON The Squadron.
|
||||||
|
function AI_AIR_SQUADRON:SetRadio( RadioFrequency, RadioModulation, RadioPower, Language )
|
||||||
|
|
||||||
|
self.RadioFrequency = RadioFrequency
|
||||||
|
self.RadioModulation = RadioModulation or radio.modulation.AM
|
||||||
|
self.RadioPower = RadioPower or 100
|
||||||
|
|
||||||
|
if self.RadioSpeech then
|
||||||
|
self.RadioSpeech:Stop()
|
||||||
|
end
|
||||||
|
|
||||||
|
self.RadioSpeech = nil
|
||||||
|
|
||||||
|
self.RadioSpeech = RADIOSPEECH:New( RadioFrequency, RadioModulation )
|
||||||
|
self.RadioSpeech.power = RadioPower
|
||||||
|
self.RadioSpeech:Start( 0.5 )
|
||||||
|
|
||||||
|
self.RadioSpeech:SetLanguage( Language )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -214,6 +214,7 @@ function SCHEDULER:New( SchedulerObject, SchedulerFunction, SchedulerArguments,
|
|||||||
local ScheduleID = nil
|
local ScheduleID = nil
|
||||||
|
|
||||||
self.MasterObject = SchedulerObject
|
self.MasterObject = SchedulerObject
|
||||||
|
self.ShowTrace = true
|
||||||
|
|
||||||
if SchedulerFunction then
|
if SchedulerFunction then
|
||||||
ScheduleID = self:Schedule( SchedulerObject, SchedulerFunction, SchedulerArguments, Start, Repeat, RandomizeFactor, Stop, 4 )
|
ScheduleID = self:Schedule( SchedulerObject, SchedulerFunction, SchedulerArguments, Start, Repeat, RandomizeFactor, Stop, 4 )
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user