mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge pull request #1244 from FlightControl-Master/FF/Develop
A2A Dispatcher and other fixes/improvements
This commit is contained in:
commit
a193d342d7
@ -3045,8 +3045,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
if DefenderTask.Type == "CAP" or DefenderTask.Type == "GCI" then
|
if DefenderTask.Type == "CAP" or DefenderTask.Type == "GCI" then
|
||||||
-- If there is no target, then add the AIGroup to the ResultAIGroups for Engagement to the AttackerSet
|
-- If there is no target, then add the AIGroup to the ResultAIGroups for Engagement to the AttackerSet
|
||||||
if DefenderTask.Target == nil then
|
if DefenderTask.Target == nil then
|
||||||
if DefenderTask.Fsm:Is( "Returning" )
|
if DefenderTask.Fsm:Is( "Returning" ) or DefenderTask.Fsm:Is( "Patrolling" ) then
|
||||||
or DefenderTask.Fsm:Is( "Patrolling" ) then
|
|
||||||
Friendlies = Friendlies or {}
|
Friendlies = Friendlies or {}
|
||||||
Friendlies[Friendly] = Friendly
|
Friendlies[Friendly] = Friendly
|
||||||
DefenderCount = DefenderCount + Friendly:GetSize()
|
DefenderCount = DefenderCount + Friendly:GetSize()
|
||||||
@ -3315,19 +3314,20 @@ do -- AI_A2A_DISPATCHER
|
|||||||
-- @param Functional.Detection#DETECTION_BASE.DetectedItem AttackerDetection Detected item.
|
-- @param Functional.Detection#DETECTION_BASE.DetectedItem AttackerDetection Detected item.
|
||||||
-- @param #table Defenders Defenders table.
|
-- @param #table Defenders Defenders table.
|
||||||
function AI_A2A_DISPATCHER:onafterENGAGE( From, Event, To, AttackerDetection, Defenders )
|
function AI_A2A_DISPATCHER:onafterENGAGE( From, Event, To, AttackerDetection, Defenders )
|
||||||
|
self:F("ENGAGING Detection ID="..tostring(AttackerDetection.ID))
|
||||||
self:F("ENGAGING "..tostring(AttackerDetection.Name))
|
|
||||||
|
|
||||||
if Defenders then
|
if Defenders then
|
||||||
|
|
||||||
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( AttackerDetection.Set ) -- Engage on the TargetSetUnit
|
Fsm:EngageRoute( AttackerDetection.Set ) -- Engage on the TargetSetUnit
|
||||||
|
|
||||||
self:SetDefenderTaskTarget( Defender, AttackerDetection )
|
self:SetDefenderTaskTarget( Defender, AttackerDetection )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -3341,7 +3341,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
-- @param #table DefenderFriendlies Friendly defenders.
|
-- @param #table DefenderFriendlies Friendly defenders.
|
||||||
function AI_A2A_DISPATCHER:onafterGCI( From, Event, To, AttackerDetection, DefendersMissing, DefenderFriendlies )
|
function AI_A2A_DISPATCHER:onafterGCI( From, Event, To, AttackerDetection, DefendersMissing, DefenderFriendlies )
|
||||||
|
|
||||||
self:F("GCI "..tostring(AttackerDetection.Name))
|
self:F("GCI Detection ID="..tostring(AttackerDetection.ID))
|
||||||
|
|
||||||
self:F( { From, Event, To, AttackerDetection.Index, DefendersMissing, DefenderFriendlies } )
|
self:F( { From, Event, To, AttackerDetection.Index, DefendersMissing, DefenderFriendlies } )
|
||||||
|
|
||||||
@ -3606,8 +3606,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
-- 2. There is sufficient fuel
|
-- 2. There is sufficient fuel
|
||||||
-- 3. There is sufficient ammo
|
-- 3. There is sufficient ammo
|
||||||
-- 4. The plane is not damaged
|
-- 4. The plane is not damaged
|
||||||
if DefenderGroups and DetectedItem.IsDetected == true then
|
if DefenderGroups and DetectedItem.IsDetected == true then
|
||||||
|
|
||||||
return DefenderGroups
|
return DefenderGroups
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -3686,13 +3685,13 @@ do -- AI_A2A_DISPATCHER
|
|||||||
|
|
||||||
local TaskReport = REPORT:New()
|
local TaskReport = REPORT:New()
|
||||||
|
|
||||||
local Report = REPORT:New( "Tactical Overviews" )
|
local Report = REPORT:New( "Tactical Overview:" )
|
||||||
|
|
||||||
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
|
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
|
||||||
|
|||||||
@ -334,9 +334,8 @@ end
|
|||||||
-- @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_AIR_ENGAGE:onafterEngage( AIGroup, From, Event, To )
|
function AI_AIR_ENGAGE:onafterEngage( AIGroup, From, Event, To )
|
||||||
|
-- TODO: This function is overwritten below!
|
||||||
self:HandleEvent( EVENTS.Dead )
|
self:HandleEvent( EVENTS.Dead )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- todo: need to fix this global function
|
-- todo: need to fix this global function
|
||||||
@ -349,10 +348,10 @@ end
|
|||||||
-- @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_AIR_ENGAGE:onbeforeEngage( AIGroup, From, Event, To )
|
function AI_AIR_ENGAGE:onbeforeEngage( AIGroup, From, Event, To )
|
||||||
|
|
||||||
if self.Accomplished == true then
|
if self.Accomplished == true then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
--- onafter event handler for Abort event.
|
--- onafter event handler for Abort event.
|
||||||
@ -405,14 +404,10 @@ end
|
|||||||
|
|
||||||
--- @param Wrapper.Group#GROUP AIControllable
|
--- @param Wrapper.Group#GROUP AIControllable
|
||||||
function AI_AIR_ENGAGE.___EngageRoute( AIGroup, Fsm, AttackSetUnit )
|
function AI_AIR_ENGAGE.___EngageRoute( AIGroup, Fsm, AttackSetUnit )
|
||||||
|
Fsm:I(string.format("AI_AIR_ENGAGE.___EngageRoute: %s", tostring(AIGroup:GetName())))
|
||||||
Fsm:I( { "AI_AIR_ENGAGE.___EngageRoute:", AIGroup:GetName() } )
|
|
||||||
|
|
||||||
if AIGroup:IsAlive() then
|
if AIGroup and AIGroup:IsAlive() then
|
||||||
Fsm:__EngageRoute( Fsm.TaskDelay, AttackSetUnit )
|
Fsm:__EngageRoute( Fsm.TaskDelay or 0.1, AttackSetUnit )
|
||||||
|
|
||||||
--local Task = AIGroup:TaskOrbitCircle( 4000, 400 )
|
|
||||||
--AIGroup:SetTask( Task )
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -423,7 +418,6 @@ end
|
|||||||
-- @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_AIR_ENGAGE:onafterEngageRoute( DefenderGroup, From, Event, To, AttackSetUnit )
|
function AI_AIR_ENGAGE:onafterEngageRoute( DefenderGroup, From, Event, To, AttackSetUnit )
|
||||||
|
|
||||||
self:I( { DefenderGroup, From, Event, To, AttackSetUnit } )
|
self:I( { DefenderGroup, From, Event, To, AttackSetUnit } )
|
||||||
|
|
||||||
local DefenderGroupName = DefenderGroup:GetName()
|
local DefenderGroupName = DefenderGroup:GetName()
|
||||||
@ -450,39 +444,33 @@ function AI_AIR_ENGAGE:onafterEngageRoute( DefenderGroup, From, Event, To, Attac
|
|||||||
TargetCoord:SetY( EngageAltitude ) -- Ground targets don't have an altitude.
|
TargetCoord:SetY( EngageAltitude ) -- Ground targets don't have an altitude.
|
||||||
|
|
||||||
local TargetDistance = DefenderCoord:Get2DDistance( TargetCoord )
|
local TargetDistance = DefenderCoord:Get2DDistance( TargetCoord )
|
||||||
local EngageDistance = ( DefenderGroup:IsHelicopter() and 5000 ) or ( DefenderGroup:IsAirPlane() and 10000 )
|
local EngageDistance = ( DefenderGroup:IsHelicopter() and 5000 ) or ( DefenderGroup:IsAirPlane() and 10000 )
|
||||||
|
|
||||||
if TargetDistance <= EngageDistance * 3 then
|
-- TODO: A factor of * 3 is way too close. This causes the AI not to engange until merged sometimes!
|
||||||
|
if TargetDistance <= EngageDistance * 9 then
|
||||||
|
|
||||||
|
self:I(string.format("AI_AIR_ENGAGE onafterEngageRoute ==> __Engage - target distance = %.1f km", TargetDistance/1000))
|
||||||
self:__Engage( 0.1, AttackSetUnit )
|
self:__Engage( 0.1, AttackSetUnit )
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
|
self:I(string.format("FF AI_AIR_ENGAGE onafterEngageRoute ==> Routing - target distance = %.1f km", TargetDistance/1000))
|
||||||
|
|
||||||
local EngageRoute = {}
|
local EngageRoute = {}
|
||||||
local AttackTasks = {}
|
local AttackTasks = {}
|
||||||
|
|
||||||
--- Calculate the target route point.
|
--- Calculate the target route point.
|
||||||
|
|
||||||
local FromWP = DefenderCoord:WaypointAir(
|
local FromWP = DefenderCoord:WaypointAir(self.PatrolAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, EngageSpeed, true)
|
||||||
self.PatrolAltType or "RADIO",
|
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
|
||||||
EngageSpeed,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
|
|
||||||
EngageRoute[#EngageRoute+1] = FromWP
|
EngageRoute[#EngageRoute+1] = FromWP
|
||||||
|
|
||||||
self:SetTargetDistance( TargetCoord ) -- For RTB status check
|
self:SetTargetDistance( TargetCoord ) -- For RTB status check
|
||||||
|
|
||||||
local FromEngageAngle = DefenderCoord:GetAngleDegrees( DefenderCoord:GetDirectionVec3( TargetCoord ) )
|
local FromEngageAngle = DefenderCoord:GetAngleDegrees( DefenderCoord:GetDirectionVec3( TargetCoord ) )
|
||||||
local ToWP = DefenderCoord:Translate( EngageDistance, FromEngageAngle, true ):WaypointAir(
|
local ToCoord=DefenderCoord:Translate( EngageDistance, FromEngageAngle, true )
|
||||||
self.PatrolAltType or "RADIO",
|
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
local ToWP = ToCoord:WaypointAir(self.PatrolAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, EngageSpeed, true)
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
|
||||||
EngageSpeed,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
|
|
||||||
EngageRoute[#EngageRoute+1] = ToWP
|
EngageRoute[#EngageRoute+1] = ToWP
|
||||||
|
|
||||||
@ -492,11 +480,12 @@ function AI_AIR_ENGAGE:onafterEngageRoute( DefenderGroup, From, Event, To, Attac
|
|||||||
DefenderGroup:OptionROEReturnFire()
|
DefenderGroup:OptionROEReturnFire()
|
||||||
DefenderGroup:OptionROTEvadeFire()
|
DefenderGroup:OptionROTEvadeFire()
|
||||||
|
|
||||||
DefenderGroup:Route( EngageRoute, self.TaskDelay )
|
DefenderGroup:Route( EngageRoute, self.TaskDelay or 0.1 )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
-- TODO: This will make an A2A Dispatcher CAP flight to return rather than going back to patrolling!
|
||||||
self:I( DefenderGroupName .. ": No targets found -> Going RTB")
|
self:I( DefenderGroupName .. ": No targets found -> Going RTB")
|
||||||
self:Return()
|
self:Return()
|
||||||
end
|
end
|
||||||
@ -506,10 +495,11 @@ end
|
|||||||
--- @param Wrapper.Group#GROUP AIControllable
|
--- @param Wrapper.Group#GROUP AIControllable
|
||||||
function AI_AIR_ENGAGE.___Engage( AIGroup, Fsm, AttackSetUnit )
|
function AI_AIR_ENGAGE.___Engage( AIGroup, Fsm, AttackSetUnit )
|
||||||
|
|
||||||
Fsm:I( { "AI_AIR_ENGAGE.___Engage:", AIGroup:GetName() } )
|
Fsm:I(string.format("AI_AIR_ENGAGE.___Engage: %s", tostring(AIGroup:GetName())))
|
||||||
|
|
||||||
if AIGroup:IsAlive() then
|
if AIGroup and AIGroup:IsAlive() then
|
||||||
Fsm:__Engage( Fsm.TaskDelay, AttackSetUnit )
|
local delay=Fsm.TaskDelay or 0.1
|
||||||
|
Fsm:__Engage(delay, AttackSetUnit)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -520,7 +510,6 @@ end
|
|||||||
-- @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_AIR_ENGAGE:onafterEngage( DefenderGroup, From, Event, To, AttackSetUnit )
|
function AI_AIR_ENGAGE:onafterEngage( DefenderGroup, From, Event, To, AttackSetUnit )
|
||||||
|
|
||||||
self:F( { DefenderGroup, From, Event, To, AttackSetUnit} )
|
self:F( { DefenderGroup, From, Event, To, AttackSetUnit} )
|
||||||
|
|
||||||
local DefenderGroupName = DefenderGroup:GetName()
|
local DefenderGroupName = DefenderGroup:GetName()
|
||||||
@ -532,7 +521,7 @@ function AI_AIR_ENGAGE:onafterEngage( DefenderGroup, From, Event, To, AttackSetU
|
|||||||
|
|
||||||
if AttackCount > 0 then
|
if AttackCount > 0 then
|
||||||
|
|
||||||
if DefenderGroup:IsAlive() then
|
if DefenderGroup and DefenderGroup:IsAlive() then
|
||||||
|
|
||||||
local EngageAltitude = math.random( self.EngageFloorAltitude or 500, self.EngageCeilingAltitude or 1000 )
|
local EngageAltitude = math.random( self.EngageFloorAltitude or 500, self.EngageCeilingAltitude or 1000 )
|
||||||
local EngageSpeed = math.random( self.EngageMinSpeed, self.EngageMaxSpeed )
|
local EngageSpeed = math.random( self.EngageMinSpeed, self.EngageMaxSpeed )
|
||||||
@ -544,33 +533,25 @@ function AI_AIR_ENGAGE:onafterEngage( DefenderGroup, From, Event, To, AttackSetU
|
|||||||
TargetCoord:SetY( EngageAltitude ) -- Ground targets don't have an altitude.
|
TargetCoord:SetY( EngageAltitude ) -- Ground targets don't have an altitude.
|
||||||
|
|
||||||
local TargetDistance = DefenderCoord:Get2DDistance( TargetCoord )
|
local TargetDistance = DefenderCoord:Get2DDistance( TargetCoord )
|
||||||
|
|
||||||
local EngageDistance = ( DefenderGroup:IsHelicopter() and 5000 ) or ( DefenderGroup:IsAirPlane() and 10000 )
|
local EngageDistance = ( DefenderGroup:IsHelicopter() and 5000 ) or ( DefenderGroup:IsAirPlane() and 10000 )
|
||||||
|
|
||||||
local EngageRoute = {}
|
local EngageRoute = {}
|
||||||
local AttackTasks = {}
|
local AttackTasks = {}
|
||||||
|
|
||||||
local FromWP = DefenderCoord:WaypointAir(
|
local FromWP = DefenderCoord:WaypointAir(self.EngageAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, EngageSpeed, true)
|
||||||
self.EngageAltType or "RADIO",
|
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
|
||||||
EngageSpeed,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
EngageRoute[#EngageRoute+1] = FromWP
|
EngageRoute[#EngageRoute+1] = FromWP
|
||||||
|
|
||||||
self:SetTargetDistance( TargetCoord ) -- For RTB status check
|
self:SetTargetDistance( TargetCoord ) -- For RTB status check
|
||||||
|
|
||||||
local FromEngageAngle = DefenderCoord:GetAngleDegrees( DefenderCoord:GetDirectionVec3( TargetCoord ) )
|
local FromEngageAngle = DefenderCoord:GetAngleDegrees( DefenderCoord:GetDirectionVec3( TargetCoord ) )
|
||||||
local ToWP = DefenderCoord:Translate( EngageDistance, FromEngageAngle, true ):WaypointAir(
|
local ToCoord=DefenderCoord:Translate( EngageDistance, FromEngageAngle, true )
|
||||||
self.EngageAltType or "RADIO",
|
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
local ToWP = ToCoord:WaypointAir(self.EngageAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, EngageSpeed, true)
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
|
||||||
EngageSpeed,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
EngageRoute[#EngageRoute+1] = ToWP
|
EngageRoute[#EngageRoute+1] = ToWP
|
||||||
|
|
||||||
if TargetDistance <= EngageDistance * 3 then
|
-- TODO: A factor of * 3 this way too low. This causes the AI NOT to engage until very close or even merged sometimes. Some A2A missiles have a much longer range! Needs more frequent updates of the task!
|
||||||
|
if TargetDistance <= EngageDistance * 9 then
|
||||||
|
|
||||||
local AttackUnitTasks = self:CreateAttackUnitTasks( AttackSetUnit, DefenderGroup, EngageAltitude ) -- Polymorphic
|
local AttackUnitTasks = self:CreateAttackUnitTasks( AttackSetUnit, DefenderGroup, EngageAltitude ) -- Polymorphic
|
||||||
|
|
||||||
@ -579,7 +560,8 @@ function AI_AIR_ENGAGE:onafterEngage( DefenderGroup, From, Event, To, AttackSetU
|
|||||||
self:Return()
|
self:Return()
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
self:I( DefenderGroupName .. ": Engaging targets " )
|
local text=string.format("%s: Engaging targets at distance %.2f NM", DefenderGroupName, UTILS.MetersToNM(TargetDistance))
|
||||||
|
self:I(text)
|
||||||
DefenderGroup:OptionROEOpenFire()
|
DefenderGroup:OptionROEOpenFire()
|
||||||
DefenderGroup:OptionROTEvadeFire()
|
DefenderGroup:OptionROTEvadeFire()
|
||||||
DefenderGroup:OptionKeepWeaponsOnThreat()
|
DefenderGroup:OptionKeepWeaponsOnThreat()
|
||||||
@ -591,10 +573,11 @@ function AI_AIR_ENGAGE:onafterEngage( DefenderGroup, From, Event, To, AttackSetU
|
|||||||
AttackTasks[#AttackTasks+1] = DefenderGroup:TaskFunction( "AI_AIR_ENGAGE.___Engage", self, AttackSetUnit )
|
AttackTasks[#AttackTasks+1] = DefenderGroup:TaskFunction( "AI_AIR_ENGAGE.___Engage", self, AttackSetUnit )
|
||||||
EngageRoute[#EngageRoute].task = DefenderGroup:TaskCombo( AttackTasks )
|
EngageRoute[#EngageRoute].task = DefenderGroup:TaskCombo( AttackTasks )
|
||||||
|
|
||||||
DefenderGroup:Route( EngageRoute, self.TaskDelay )
|
DefenderGroup:Route( EngageRoute, self.TaskDelay or 0.1 )
|
||||||
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
-- TODO: This will make an A2A Dispatcher CAP flight to return rather than going back to patrolling!
|
||||||
self:I( DefenderGroupName .. ": No targets found -> returning.")
|
self:I( DefenderGroupName .. ": No targets found -> returning.")
|
||||||
self:Return()
|
self:Return()
|
||||||
return
|
return
|
||||||
@ -605,9 +588,9 @@ end
|
|||||||
function AI_AIR_ENGAGE.Resume( AIEngage, Fsm )
|
function AI_AIR_ENGAGE.Resume( AIEngage, Fsm )
|
||||||
|
|
||||||
AIEngage:F( { "Resume:", AIEngage:GetName() } )
|
AIEngage:F( { "Resume:", AIEngage:GetName() } )
|
||||||
if AIEngage:IsAlive() then
|
if AIEngage and AIEngage:IsAlive() then
|
||||||
Fsm:__Reset( Fsm.TaskDelay )
|
Fsm:__Reset( Fsm.TaskDelay or 0.1 )
|
||||||
Fsm:__EngageRoute( Fsm.TaskDelay, Fsm.AttackSetUnit )
|
Fsm:__EngageRoute( Fsm.TaskDelay or 0.2, Fsm.AttackSetUnit )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -421,7 +421,7 @@ end
|
|||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
|
function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
|
||||||
|
|
||||||
if Controllable:IsAlive() then
|
if Controllable and Controllable:IsAlive() then
|
||||||
|
|
||||||
local EngageRoute = {}
|
local EngageRoute = {}
|
||||||
|
|
||||||
|
|||||||
@ -198,7 +198,7 @@ FOX.MenuF10Root=nil
|
|||||||
|
|
||||||
--- FOX class version.
|
--- FOX class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
FOX.version="0.6.0"
|
FOX.version="0.6.1"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- ToDo list
|
-- ToDo list
|
||||||
@ -243,6 +243,7 @@ function FOX:New()
|
|||||||
self:AddTransition("*", "MissileDestroyed", "*") -- Missile was destroyed before impact.
|
self:AddTransition("*", "MissileDestroyed", "*") -- Missile was destroyed before impact.
|
||||||
self:AddTransition("*", "EnterSafeZone", "*") -- Player enters a safe zone.
|
self:AddTransition("*", "EnterSafeZone", "*") -- Player enters a safe zone.
|
||||||
self:AddTransition("*", "ExitSafeZone", "*") -- Player exists a safe zone.
|
self:AddTransition("*", "ExitSafeZone", "*") -- Player exists a safe zone.
|
||||||
|
self:AddTransition("Running", "Stop", "Stopped") -- Stop FOX script.
|
||||||
|
|
||||||
------------------------
|
------------------------
|
||||||
--- Pseudo Functions ---
|
--- Pseudo Functions ---
|
||||||
|
|||||||
@ -5,6 +5,10 @@
|
|||||||
-- ## Features:
|
-- ## Features:
|
||||||
--
|
--
|
||||||
-- * Hold fire of attacked units when being fired upon.
|
-- * Hold fire of attacked units when being fired upon.
|
||||||
|
-- * Retreat to a user defined zone.
|
||||||
|
-- * Fall back on hits.
|
||||||
|
-- * Take cover on hits.
|
||||||
|
-- * Gaussian distribution of suppression time.
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@ -44,6 +48,7 @@
|
|||||||
-- @type SUPPRESSION
|
-- @type SUPPRESSION
|
||||||
-- @field #string ClassName Name of the class.
|
-- @field #string ClassName Name of the class.
|
||||||
-- @field #boolean Debug Write Debug messages to DCS log file and send Debug messages to all players.
|
-- @field #boolean Debug Write Debug messages to DCS log file and send Debug messages to all players.
|
||||||
|
-- @field #string lid String for DCS log file.
|
||||||
-- @field #boolean flare Flare units when they get hit or die.
|
-- @field #boolean flare Flare units when they get hit or die.
|
||||||
-- @field #boolean smoke Smoke places to which the group retreats, falls back or hides.
|
-- @field #boolean smoke Smoke places to which the group retreats, falls back or hides.
|
||||||
-- @field #list DCSdesc Table containing all DCS descriptors of the group.
|
-- @field #list DCSdesc Table containing all DCS descriptors of the group.
|
||||||
@ -222,41 +227,42 @@
|
|||||||
--
|
--
|
||||||
-- @field #SUPPRESSION
|
-- @field #SUPPRESSION
|
||||||
SUPPRESSION={
|
SUPPRESSION={
|
||||||
ClassName = "SUPPRESSION",
|
ClassName = "SUPPRESSION",
|
||||||
Debug = false,
|
Debug = false,
|
||||||
flare = false,
|
lid = nil,
|
||||||
smoke = false,
|
flare = false,
|
||||||
DCSdesc = nil,
|
smoke = false,
|
||||||
Type = nil,
|
DCSdesc = nil,
|
||||||
IsInfantry=nil,
|
Type = nil,
|
||||||
SpeedMax = nil,
|
IsInfantry = nil,
|
||||||
Tsuppress_ave = 15,
|
SpeedMax = nil,
|
||||||
Tsuppress_min = 5,
|
Tsuppress_ave = 15,
|
||||||
Tsuppress_max = 25,
|
Tsuppress_min = 5,
|
||||||
TsuppressOver = nil,
|
Tsuppress_max = 25,
|
||||||
IniGroupStrength = nil,
|
TsuppressOver = nil,
|
||||||
Nhit = 0,
|
IniGroupStrength = nil,
|
||||||
Formation = "Off road",
|
Nhit = 0,
|
||||||
Speed = 4,
|
Formation = "Off road",
|
||||||
MenuON = false,
|
Speed = 4,
|
||||||
FallbackON = false,
|
MenuON = false,
|
||||||
FallbackWait = 60,
|
FallbackON = false,
|
||||||
FallbackDist = 100,
|
FallbackWait = 60,
|
||||||
FallbackHeading = nil,
|
FallbackDist = 100,
|
||||||
TakecoverON = false,
|
FallbackHeading = nil,
|
||||||
TakecoverWait = 120,
|
TakecoverON = false,
|
||||||
TakecoverRange = 300,
|
TakecoverWait = 120,
|
||||||
hideout = nil,
|
TakecoverRange = 300,
|
||||||
PminFlee = 10,
|
hideout = nil,
|
||||||
PmaxFlee = 90,
|
PminFlee = 10,
|
||||||
RetreatZone = nil,
|
PmaxFlee = 90,
|
||||||
RetreatDamage = nil,
|
RetreatZone = nil,
|
||||||
RetreatWait = 7200,
|
RetreatDamage = nil,
|
||||||
|
RetreatWait = 7200,
|
||||||
CurrentAlarmState = "unknown",
|
CurrentAlarmState = "unknown",
|
||||||
CurrentROE = "unknown",
|
CurrentROE = "unknown",
|
||||||
DefaultAlarmState = "Auto",
|
DefaultAlarmState = "Auto",
|
||||||
DefaultROE = "Weapon Free",
|
DefaultROE = "Weapon Free",
|
||||||
eventmoose = true,
|
eventmoose = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Enumerator of possible rules of engagement.
|
--- Enumerator of possible rules of engagement.
|
||||||
@ -279,13 +285,9 @@ SUPPRESSION.AlarmState={
|
|||||||
-- @field #string MenuF10
|
-- @field #string MenuF10
|
||||||
SUPPRESSION.MenuF10=nil
|
SUPPRESSION.MenuF10=nil
|
||||||
|
|
||||||
--- Some ID to identify who we are in output of the DCS.log file.
|
|
||||||
-- @field #string id
|
|
||||||
SUPPRESSION.id="SUPPRESSION | "
|
|
||||||
|
|
||||||
--- PSEUDOATC version.
|
--- PSEUDOATC version.
|
||||||
-- @field #number version
|
-- @field #number version
|
||||||
SUPPRESSION.version="0.9.0"
|
SUPPRESSION.version="0.9.1"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -302,22 +304,22 @@ SUPPRESSION.version="0.9.0"
|
|||||||
-- @return #SUPPRESSION SUPPRESSION object.
|
-- @return #SUPPRESSION SUPPRESSION object.
|
||||||
-- @return nil If group does not exist or is not a ground group.
|
-- @return nil If group does not exist or is not a ground group.
|
||||||
function SUPPRESSION:New(group)
|
function SUPPRESSION:New(group)
|
||||||
BASE:F2(group)
|
|
||||||
|
|
||||||
-- Inherits from FSM_CONTROLLABLE
|
-- Inherits from FSM_CONTROLLABLE
|
||||||
local self=BASE:Inherit(self, FSM_CONTROLLABLE:New()) -- #SUPPRESSION
|
local self=BASE:Inherit(self, FSM_CONTROLLABLE:New()) -- #SUPPRESSION
|
||||||
|
|
||||||
-- Check that group is present.
|
-- Check that group is present.
|
||||||
if group then
|
if group then
|
||||||
self:T(SUPPRESSION.id..string.format("SUPPRESSION version %s. Activating suppressive fire for group %s", SUPPRESSION.version, group:GetName()))
|
self.lid=string.format("SUPPRESSION %s | ", tostring(group:GetName()))
|
||||||
|
self:T(self.lid..string.format("SUPPRESSION version %s. Activating suppressive fire for group %s", SUPPRESSION.version, group:GetName()))
|
||||||
else
|
else
|
||||||
self:E(SUPPRESSION.id.."Suppressive fire: Requested group does not exist! (Has to be a MOOSE group.)")
|
self:E(self.lid.."SUPPRESSION | Requested group does not exist! (Has to be a MOOSE group.)")
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check that we actually have a GROUND group.
|
-- Check that we actually have a GROUND group.
|
||||||
if group:IsGround()==false then
|
if group:IsGround()==false then
|
||||||
self:E(SUPPRESSION.id..string.format("SUPPRESSION fire group %s has to be a GROUND group!", group:GetName()))
|
self:E(self.lid..string.format("SUPPRESSION fire group %s has to be a GROUND group!", group:GetName()))
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -350,6 +352,7 @@ function SUPPRESSION:New(group)
|
|||||||
|
|
||||||
-- Transitions
|
-- Transitions
|
||||||
self:AddTransition("*", "Start", "CombatReady")
|
self:AddTransition("*", "Start", "CombatReady")
|
||||||
|
self:AddTransition("*", "Status", "*")
|
||||||
self:AddTransition("CombatReady", "Hit", "Suppressed")
|
self:AddTransition("CombatReady", "Hit", "Suppressed")
|
||||||
self:AddTransition("Suppressed", "Hit", "Suppressed")
|
self:AddTransition("Suppressed", "Hit", "Suppressed")
|
||||||
self:AddTransition("Suppressed", "Recovered", "CombatReady")
|
self:AddTransition("Suppressed", "Recovered", "CombatReady")
|
||||||
@ -364,6 +367,38 @@ function SUPPRESSION:New(group)
|
|||||||
self:AddTransition("TakingCover", "Hit", "TakingCover")
|
self:AddTransition("TakingCover", "Hit", "TakingCover")
|
||||||
self:AddTransition("FallingBack", "Hit", "FallingBack")
|
self:AddTransition("FallingBack", "Hit", "FallingBack")
|
||||||
|
|
||||||
|
|
||||||
|
--- Trigger "Status" event.
|
||||||
|
-- @function [parent=#SUPPRESSION] Status
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
|
||||||
|
--- Trigger "Status" event after a delay.
|
||||||
|
-- @function [parent=#SUPPRESSION] __Status
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
-- @param #number Delay Delay in seconds.
|
||||||
|
|
||||||
|
--- User function for OnAfter "Status" event.
|
||||||
|
-- @function [parent=#SUPPRESSION] OnAfterStatus
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
-- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group.
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
|
||||||
|
|
||||||
|
--- Trigger "Hit" event.
|
||||||
|
-- @function [parent=#SUPPRESSION] Hit
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit Unit that was hit.
|
||||||
|
-- @param Wrapper.Unit#UNIT AttackUnit Unit that attacked.
|
||||||
|
|
||||||
|
--- Trigger "Hit" event after a delay.
|
||||||
|
-- @function [parent=#SUPPRESSION] __Hit
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
-- @param #number Delay Delay in seconds.
|
||||||
|
-- @param Wrapper.Unit#UNIT Unit Unit that was hit.
|
||||||
|
-- @param Wrapper.Unit#UNIT AttackUnit Unit that attacked.
|
||||||
|
|
||||||
--- User function for OnBefore "Hit" event.
|
--- User function for OnBefore "Hit" event.
|
||||||
-- @function [parent=#SUPPRESSION] OnBeforeHit
|
-- @function [parent=#SUPPRESSION] OnBeforeHit
|
||||||
-- @param #SUPPRESSION self
|
-- @param #SUPPRESSION self
|
||||||
@ -375,7 +410,7 @@ function SUPPRESSION:New(group)
|
|||||||
-- @param Wrapper.Unit#UNIT AttackUnit Unit that attacked.
|
-- @param Wrapper.Unit#UNIT AttackUnit Unit that attacked.
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
|
|
||||||
--- User function for OnAfer "Hit" event.
|
--- User function for OnAfter "Hit" event.
|
||||||
-- @function [parent=#SUPPRESSION] OnAfterHit
|
-- @function [parent=#SUPPRESSION] OnAfterHit
|
||||||
-- @param #SUPPRESSION self
|
-- @param #SUPPRESSION self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group.
|
-- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group.
|
||||||
@ -384,7 +419,16 @@ function SUPPRESSION:New(group)
|
|||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
-- @param Wrapper.Unit#UNIT Unit Unit that was hit.
|
-- @param Wrapper.Unit#UNIT Unit Unit that was hit.
|
||||||
-- @param Wrapper.Unit#UNIT AttackUnit Unit that attacked.
|
-- @param Wrapper.Unit#UNIT AttackUnit Unit that attacked.
|
||||||
|
|
||||||
|
|
||||||
|
--- Trigger "Recovered" event.
|
||||||
|
-- @function [parent=#SUPPRESSION] Recovered
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
|
||||||
|
--- Trigger "Recovered" event after a delay.
|
||||||
|
-- @function [parent=#SUPPRESSION] Recovered
|
||||||
|
-- @param #number Delay Delay in seconds.
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
|
||||||
--- User function for OnBefore "Recovered" event.
|
--- User function for OnBefore "Recovered" event.
|
||||||
-- @function [parent=#SUPPRESSION] OnBeforeRecovered
|
-- @function [parent=#SUPPRESSION] OnBeforeRecovered
|
||||||
@ -404,6 +448,17 @@ function SUPPRESSION:New(group)
|
|||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
|
|
||||||
|
|
||||||
|
--- Trigger "TakeCover" event.
|
||||||
|
-- @function [parent=#SUPPRESSION] TakeCover
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
-- @param Core.Point#COORDINATE Hideout Place where the group will hide.
|
||||||
|
|
||||||
|
--- Trigger "TakeCover" event after a delay.
|
||||||
|
-- @function [parent=#SUPPRESSION] __TakeCover
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
-- @param #number Delay Delay in seconds.
|
||||||
|
-- @param Core.Point#COORDINATE Hideout Place where the group will hide.
|
||||||
|
|
||||||
--- User function for OnBefore "TakeCover" event.
|
--- User function for OnBefore "TakeCover" event.
|
||||||
-- @function [parent=#SUPPRESSION] OnBeforeTakeCover
|
-- @function [parent=#SUPPRESSION] OnBeforeTakeCover
|
||||||
-- @param #SUPPRESSION self
|
-- @param #SUPPRESSION self
|
||||||
@ -424,6 +479,17 @@ function SUPPRESSION:New(group)
|
|||||||
-- @param Core.Point#COORDINATE Hideout Place where the group will hide.
|
-- @param Core.Point#COORDINATE Hideout Place where the group will hide.
|
||||||
|
|
||||||
|
|
||||||
|
--- Trigger "FallBack" event.
|
||||||
|
-- @function [parent=#SUPPRESSION] FallBack
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
-- @param Wrapper.Unit#UNIT AttackUnit Attacking unit. We will move away from this.
|
||||||
|
|
||||||
|
--- Trigger "FallBack" event after a delay.
|
||||||
|
-- @function [parent=#SUPPRESSION] __FallBack
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
-- @param #number Delay Delay in seconds.
|
||||||
|
-- @param Wrapper.Unit#UNIT AttackUnit Attacking unit. We will move away from this.
|
||||||
|
|
||||||
--- User function for OnBefore "FallBack" event.
|
--- User function for OnBefore "FallBack" event.
|
||||||
-- @function [parent=#SUPPRESSION] OnBeforeFallBack
|
-- @function [parent=#SUPPRESSION] OnBeforeFallBack
|
||||||
-- @param #SUPPRESSION self
|
-- @param #SUPPRESSION self
|
||||||
@ -444,6 +510,15 @@ function SUPPRESSION:New(group)
|
|||||||
-- @param Wrapper.Unit#UNIT AttackUnit Attacking unit. We will move away from this.
|
-- @param Wrapper.Unit#UNIT AttackUnit Attacking unit. We will move away from this.
|
||||||
|
|
||||||
|
|
||||||
|
--- Trigger "Retreat" event.
|
||||||
|
-- @function [parent=#SUPPRESSION] Retreat
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
|
||||||
|
--- Trigger "Retreat" event after a delay.
|
||||||
|
-- @function [parent=#SUPPRESSION] __Retreat
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
-- @param #number Delay Delay in seconds.
|
||||||
|
|
||||||
--- User function for OnBefore "Retreat" event.
|
--- User function for OnBefore "Retreat" event.
|
||||||
-- @function [parent=#SUPPRESSION] OnBeforeRetreat
|
-- @function [parent=#SUPPRESSION] OnBeforeRetreat
|
||||||
-- @param #SUPPRESSION self
|
-- @param #SUPPRESSION self
|
||||||
@ -462,6 +537,15 @@ function SUPPRESSION:New(group)
|
|||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
|
|
||||||
|
|
||||||
|
--- Trigger "Retreated" event.
|
||||||
|
-- @function [parent=#SUPPRESSION] Retreated
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
|
||||||
|
--- Trigger "Retreated" event after a delay.
|
||||||
|
-- @function [parent=#SUPPRESSION] __Retreated
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
-- @param #number Delay Delay in seconds.
|
||||||
|
|
||||||
--- User function for OnBefore "Retreated" event.
|
--- User function for OnBefore "Retreated" event.
|
||||||
-- @function [parent=#SUPPRESSION] OnBeforeRetreated
|
-- @function [parent=#SUPPRESSION] OnBeforeRetreated
|
||||||
-- @param #SUPPRESSION self
|
-- @param #SUPPRESSION self
|
||||||
@ -480,6 +564,15 @@ function SUPPRESSION:New(group)
|
|||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
|
|
||||||
|
|
||||||
|
--- Trigger "FightBack" event.
|
||||||
|
-- @function [parent=#SUPPRESSION] FightBack
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
|
||||||
|
--- Trigger "FightBack" event after a delay.
|
||||||
|
-- @function [parent=#SUPPRESSION] __FightBack
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
-- @param #number Delay Delay in seconds.
|
||||||
|
|
||||||
--- User function for OnBefore "FlightBack" event.
|
--- User function for OnBefore "FlightBack" event.
|
||||||
-- @function [parent=#SUPPRESSION] OnBeforeFightBack
|
-- @function [parent=#SUPPRESSION] OnBeforeFightBack
|
||||||
-- @param #SUPPRESSION self
|
-- @param #SUPPRESSION self
|
||||||
@ -498,6 +591,23 @@ function SUPPRESSION:New(group)
|
|||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
|
|
||||||
|
|
||||||
|
--- Trigger "Dead" event.
|
||||||
|
-- @function [parent=#SUPPRESSION] Dead
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
|
||||||
|
--- Trigger "Dead" event after a delay.
|
||||||
|
-- @function [parent=#SUPPRESSION] __Dead
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
-- @param #number Delay Delay in seconds.
|
||||||
|
|
||||||
|
--- User function for OnAfter "Dead" event.
|
||||||
|
-- @function [parent=#SUPPRESSION] OnAfterDead
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
-- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group.
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -524,9 +634,9 @@ function SUPPRESSION:SetSuppressionTime(Tave, Tmin, Tmax)
|
|||||||
self.Tsuppress_ave=math.max(self.Tsuppress_min)
|
self.Tsuppress_ave=math.max(self.Tsuppress_min)
|
||||||
self.Tsuppress_ave=math.min(self.Tsuppress_max)
|
self.Tsuppress_ave=math.min(self.Tsuppress_max)
|
||||||
|
|
||||||
self:T(SUPPRESSION.id..string.format("Set ave suppression time to %d seconds.", self.Tsuppress_ave))
|
self:T(self.lid..string.format("Set ave suppression time to %d seconds.", self.Tsuppress_ave))
|
||||||
self:T(SUPPRESSION.id..string.format("Set min suppression time to %d seconds.", self.Tsuppress_min))
|
self:T(self.lid..string.format("Set min suppression time to %d seconds.", self.Tsuppress_min))
|
||||||
self:T(SUPPRESSION.id..string.format("Set max suppression time to %d seconds.", self.Tsuppress_max))
|
self:T(self.lid..string.format("Set max suppression time to %d seconds.", self.Tsuppress_max))
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set the zone to which a group retreats after being damaged too much.
|
--- Set the zone to which a group retreats after being damaged too much.
|
||||||
@ -756,13 +866,14 @@ end
|
|||||||
--- Status of group. Current ROE, alarm state, life.
|
--- Status of group. Current ROE, alarm state, life.
|
||||||
-- @param #SUPPRESSION self
|
-- @param #SUPPRESSION self
|
||||||
-- @param #boolean message Send message to all players.
|
-- @param #boolean message Send message to all players.
|
||||||
function SUPPRESSION:Status(message)
|
function SUPPRESSION:StatusReport(message)
|
||||||
|
|
||||||
local name=self.Controllable:GetName()
|
local name=self.Controllable:GetName()
|
||||||
local nunits=#self.Controllable:GetUnits()
|
local nunits=#self.Controllable:GetUnits()
|
||||||
local roe=self.CurrentROE
|
local roe=self.CurrentROE
|
||||||
local state=self.CurrentAlarmState
|
local state=self.CurrentAlarmState
|
||||||
local life_min, life_max, life_ave, life_ave0, groupstrength=self:_GetLife()
|
local life_min, life_max, life_ave, life_ave0, groupstrength=self:_GetLife()
|
||||||
|
local at=self.Controllable:GetAmmunition()
|
||||||
|
|
||||||
local text=string.format("Status of group %s\n", name)
|
local text=string.format("Status of group %s\n", name)
|
||||||
text=text..string.format("Number of units: %d of %d\n", nunits, self.IniGroupStrength)
|
text=text..string.format("Number of units: %d of %d\n", nunits, self.IniGroupStrength)
|
||||||
@ -774,10 +885,11 @@ function SUPPRESSION:Status(message)
|
|||||||
text=text..string.format("Life max: %3.0f\n", life_max)
|
text=text..string.format("Life max: %3.0f\n", life_max)
|
||||||
text=text..string.format("Life ave: %3.0f\n", life_ave)
|
text=text..string.format("Life ave: %3.0f\n", life_ave)
|
||||||
text=text..string.format("Life ave0: %3.0f\n", life_ave0)
|
text=text..string.format("Life ave0: %3.0f\n", life_ave0)
|
||||||
|
text=text..string.format("Ammo tot: %d\n", at)
|
||||||
text=text..string.format("Group strength: %3.0f", groupstrength)
|
text=text..string.format("Group strength: %3.0f", groupstrength)
|
||||||
|
|
||||||
MESSAGE:New(text, 10):ToAllIf(message or self.Debug)
|
MESSAGE:New(text, 10):ToAllIf(message or self.Debug)
|
||||||
self:T(SUPPRESSION.id.."\n"..text)
|
self:I(self.lid.."\n"..text)
|
||||||
end
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -794,6 +906,7 @@ function SUPPRESSION:onafterStart(Controllable, From, Event, To)
|
|||||||
self:_EventFromTo("onafterStart", Event, From, To)
|
self:_EventFromTo("onafterStart", Event, From, To)
|
||||||
|
|
||||||
local text=string.format("Started SUPPRESSION for group %s.", Controllable:GetName())
|
local text=string.format("Started SUPPRESSION for group %s.", Controllable:GetName())
|
||||||
|
self:I(self.lid..text)
|
||||||
MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
||||||
|
|
||||||
local rzone="not defined"
|
local rzone="not defined"
|
||||||
@ -854,7 +967,7 @@ function SUPPRESSION:onafterStart(Controllable, From, Event, To)
|
|||||||
text=text..string.format("Speed max = %5.1f km/h\n", self.SpeedMax)
|
text=text..string.format("Speed max = %5.1f km/h\n", self.SpeedMax)
|
||||||
text=text..string.format("Formation = %s\n", self.Formation)
|
text=text..string.format("Formation = %s\n", self.Formation)
|
||||||
text=text..string.format("******************************************************\n")
|
text=text..string.format("******************************************************\n")
|
||||||
self:T(SUPPRESSION.id..text)
|
self:T(self.lid..text)
|
||||||
|
|
||||||
-- Add event handler.
|
-- Add event handler.
|
||||||
if self.eventmoose then
|
if self.eventmoose then
|
||||||
@ -863,9 +976,37 @@ function SUPPRESSION:onafterStart(Controllable, From, Event, To)
|
|||||||
else
|
else
|
||||||
world.addEventHandler(self)
|
world.addEventHandler(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
self:__Status(-1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- After "Status" event.
|
||||||
|
-- @param #SUPPRESSION self
|
||||||
|
-- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group.
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
function SUPPRESSION:onafterStatus(Controllable, From, Event, To)
|
||||||
|
|
||||||
|
--local text=string.format("State=%s, ROE %d, Life=%.1f", Controllable:GetName())
|
||||||
|
--MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
||||||
|
|
||||||
|
local group=self.Controllable --Wrapper.Group#GROUP
|
||||||
|
|
||||||
|
local n=group:GetAmmunition()
|
||||||
|
|
||||||
|
self:StatusReport(false)
|
||||||
|
|
||||||
|
-- Retreat if completely out of ammo and retreat zone defined.
|
||||||
|
if n==0 and self.RetreatZone then
|
||||||
|
|
||||||
|
self:Retreat()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
self:__Status(-30)
|
||||||
|
end
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- Before "Hit" event. (Of course, this is not really before the group got hit.)
|
--- Before "Hit" event. (Of course, this is not really before the group got hit.)
|
||||||
@ -881,7 +1022,7 @@ function SUPPRESSION:onbeforeHit(Controllable, From, Event, To, Unit, AttackUnit
|
|||||||
self:_EventFromTo("onbeforeHit", Event, From, To)
|
self:_EventFromTo("onbeforeHit", Event, From, To)
|
||||||
|
|
||||||
--local Tnow=timer.getTime()
|
--local Tnow=timer.getTime()
|
||||||
--env.info(SUPPRESSION.id..string.format("Last hit = %s %s", tostring(self.LastHit), tostring(Tnow)))
|
--env.info(self.lid..string.format("Last hit = %s %s", tostring(self.LastHit), tostring(Tnow)))
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -925,7 +1066,7 @@ function SUPPRESSION:onafterHit(Controllable, From, Event, To, Unit, AttackUnit)
|
|||||||
text=string.format("\nGroup %s: Life min=%5.1f, max=%5.1f, ave=%5.1f, ave0=%5.1f group=%5.1f\n", Controllable:GetName(), life_min, life_max, life_ave, life_ave0, groupstrength)
|
text=string.format("\nGroup %s: Life min=%5.1f, max=%5.1f, ave=%5.1f, ave0=%5.1f group=%5.1f\n", Controllable:GetName(), life_min, life_max, life_ave, life_ave0, groupstrength)
|
||||||
text=string.format("Group %s: Damage = %8.4f (%8.4f retreat threshold).\n", Controllable:GetName(), Damage, self.RetreatDamage)
|
text=string.format("Group %s: Damage = %8.4f (%8.4f retreat threshold).\n", Controllable:GetName(), Damage, self.RetreatDamage)
|
||||||
text=string.format("Group %s: P_Flee = %5.1f %5.1f=P_rand (P_Flee > Prand ==> Flee)\n", Controllable:GetName(), Pflee, P)
|
text=string.format("Group %s: P_Flee = %5.1f %5.1f=P_rand (P_Flee > Prand ==> Flee)\n", Controllable:GetName(), Pflee, P)
|
||||||
self:T(SUPPRESSION.id..text)
|
self:T(self.lid..text)
|
||||||
|
|
||||||
-- Group is obviously destroyed.
|
-- Group is obviously destroyed.
|
||||||
if Damage >= 99.9 then
|
if Damage >= 99.9 then
|
||||||
@ -957,11 +1098,6 @@ function SUPPRESSION:onafterHit(Controllable, From, Event, To, Unit, AttackUnit)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Give info on current status.
|
|
||||||
if self.Debug then
|
|
||||||
self:Status()
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -980,7 +1116,7 @@ function SUPPRESSION:onbeforeRecovered(Controllable, From, Event, To)
|
|||||||
local Tnow=timer.getTime()
|
local Tnow=timer.getTime()
|
||||||
|
|
||||||
-- Debug info
|
-- Debug info
|
||||||
self:T(SUPPRESSION.id..string.format("onbeforeRecovered: Time now: %d - Time over: %d", Tnow, self.TsuppressionOver))
|
self:T(self.lid..string.format("onbeforeRecovered: Time now: %d - Time over: %d", Tnow, self.TsuppressionOver))
|
||||||
|
|
||||||
-- Recovery is only possible if enough time since the last hit has passed.
|
-- Recovery is only possible if enough time since the last hit has passed.
|
||||||
if Tnow >= self.TsuppressionOver then
|
if Tnow >= self.TsuppressionOver then
|
||||||
@ -1005,7 +1141,7 @@ function SUPPRESSION:onafterRecovered(Controllable, From, Event, To)
|
|||||||
-- Debug message.
|
-- Debug message.
|
||||||
local text=string.format("Group %s has recovered!", Controllable:GetName())
|
local text=string.format("Group %s has recovered!", Controllable:GetName())
|
||||||
MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
||||||
self:T(SUPPRESSION.id..text)
|
self:T(self.lid..text)
|
||||||
|
|
||||||
-- Set ROE back to default.
|
-- Set ROE back to default.
|
||||||
self:_SetROE()
|
self:_SetROE()
|
||||||
@ -1066,7 +1202,7 @@ function SUPPRESSION:onafterFallBack(Controllable, From, Event, To, AttackUnit)
|
|||||||
self:_EventFromTo("onafterFallback", Event, From, To)
|
self:_EventFromTo("onafterFallback", Event, From, To)
|
||||||
|
|
||||||
-- Debug info
|
-- Debug info
|
||||||
self:T(SUPPRESSION.id..string.format("Group %s is falling back after %d hits.", Controllable:GetName(), self.Nhit))
|
self:T(self.lid..string.format("Group %s is falling back after %d hits.", Controllable:GetName(), self.Nhit))
|
||||||
|
|
||||||
-- Coordinate of the attacker and attacked unit.
|
-- Coordinate of the attacker and attacked unit.
|
||||||
local ACoord=AttackUnit:GetCoordinate()
|
local ACoord=AttackUnit:GetCoordinate()
|
||||||
@ -1174,8 +1310,8 @@ function SUPPRESSION:onbeforeRetreat(Controllable, From, Event, To)
|
|||||||
self:_EventFromTo("onbeforeRetreat", Event, From, To)
|
self:_EventFromTo("onbeforeRetreat", Event, From, To)
|
||||||
|
|
||||||
if From=="Retreating" then
|
if From=="Retreating" then
|
||||||
local text=string.format("Group %s is already retreating.")
|
local text=string.format("Group %s is already retreating.", tostring(Controllable:GetName()))
|
||||||
self:T2(SUPPRESSION.id..text)
|
self:T2(self.lid..text)
|
||||||
return false
|
return false
|
||||||
else
|
else
|
||||||
return true
|
return true
|
||||||
@ -1195,7 +1331,7 @@ function SUPPRESSION:onafterRetreat(Controllable, From, Event, To)
|
|||||||
-- Route the group to a zone.
|
-- Route the group to a zone.
|
||||||
local text=string.format("Group %s is retreating! Alarm state green.", Controllable:GetName())
|
local text=string.format("Group %s is retreating! Alarm state green.", Controllable:GetName())
|
||||||
MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
||||||
self:T(SUPPRESSION.id..text)
|
self:T(self.lid..text)
|
||||||
|
|
||||||
-- Get a random point in the retreat zone.
|
-- Get a random point in the retreat zone.
|
||||||
local ZoneCoord=self.RetreatZone:GetRandomCoordinate() -- Core.Point#COORDINATE
|
local ZoneCoord=self.RetreatZone:GetRandomCoordinate() -- Core.Point#COORDINATE
|
||||||
@ -1272,11 +1408,11 @@ function SUPPRESSION:onafterDead(Controllable, From, Event, To)
|
|||||||
|
|
||||||
local text=string.format("Group %s: One of our units just died! %d units left.", self.Controllable:GetName(), nunits)
|
local text=string.format("Group %s: One of our units just died! %d units left.", self.Controllable:GetName(), nunits)
|
||||||
MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
||||||
self:T(SUPPRESSION.id..text)
|
self:T(self.lid..text)
|
||||||
|
|
||||||
-- Go to stop state.
|
-- Go to stop state.
|
||||||
if nunits==0 then
|
if nunits==0 then
|
||||||
self:T(SUPPRESSION.id..string.format("Stopping SUPPRESSION for group %s.", Controllable:GetName()))
|
self:T(self.lid..string.format("Stopping SUPPRESSION for group %s.", Controllable:GetName()))
|
||||||
self:Stop()
|
self:Stop()
|
||||||
if self.mooseevents then
|
if self.mooseevents then
|
||||||
self:UnHandleEvent(EVENTS.Dead)
|
self:UnHandleEvent(EVENTS.Dead)
|
||||||
@ -1348,7 +1484,7 @@ function SUPPRESSION:_OnEventHit(EventData)
|
|||||||
-- Check that correct group was hit.
|
-- Check that correct group was hit.
|
||||||
if GroupNameTgt == GroupNameSelf then
|
if GroupNameTgt == GroupNameSelf then
|
||||||
|
|
||||||
self:T(SUPPRESSION.id..string.format("Hit event at t = %5.1f", timer.getTime()))
|
self:T(self.lid..string.format("Hit event at t = %5.1f", timer.getTime()))
|
||||||
|
|
||||||
-- Flare unit that was hit.
|
-- Flare unit that was hit.
|
||||||
if self.flare or self.Debug then
|
if self.flare or self.Debug then
|
||||||
@ -1359,11 +1495,11 @@ function SUPPRESSION:_OnEventHit(EventData)
|
|||||||
self.Nhit=self.Nhit+1
|
self.Nhit=self.Nhit+1
|
||||||
|
|
||||||
-- Info on hit times.
|
-- Info on hit times.
|
||||||
self:T(SUPPRESSION.id..string.format("Group %s has just been hit %d times.", self.Controllable:GetName(), self.Nhit))
|
self:T(self.lid..string.format("Group %s has just been hit %d times.", self.Controllable:GetName(), self.Nhit))
|
||||||
|
|
||||||
--self:Status()
|
--self:Status()
|
||||||
local life=tgt:getLife()/(tgt:getLife0()+1)*100
|
local life=tgt:getLife()/(tgt:getLife0()+1)*100
|
||||||
self:T2(SUPPRESSION.id..string.format("Target unit life = %5.1f", life))
|
self:T2(self.lid..string.format("Target unit life = %5.1f", life))
|
||||||
|
|
||||||
-- FSM Hit event.
|
-- FSM Hit event.
|
||||||
self:__Hit(3, TgtUnit, IniUnit)
|
self:__Hit(3, TgtUnit, IniUnit)
|
||||||
@ -1380,35 +1516,35 @@ function SUPPRESSION:_OnEventDead(EventData)
|
|||||||
local GroupNameIni=EventData.IniGroupName
|
local GroupNameIni=EventData.IniGroupName
|
||||||
|
|
||||||
-- Check for correct group.
|
-- Check for correct group.
|
||||||
if GroupNameIni== GroupNameSelf then
|
if GroupNameIni==GroupNameSelf then
|
||||||
|
|
||||||
-- Dead Unit.
|
-- Dead Unit.
|
||||||
local IniUnit=EventData.IniUnit --Wrapper.Unit#UNIT
|
local IniUnit=EventData.IniUnit --Wrapper.Unit#UNIT
|
||||||
local IniUnitName=EventData.IniUnitName
|
local IniUnitName=EventData.IniUnitName
|
||||||
|
|
||||||
if EventData.IniUnit then
|
if EventData.IniUnit then
|
||||||
self:T2(SUPPRESSION.id..string.format("Group %s: Dead MOOSE unit DOES exist! Unit name %s.", GroupNameIni, IniUnitName))
|
self:T2(self.lid..string.format("Group %s: Dead MOOSE unit DOES exist! Unit name %s.", GroupNameIni, IniUnitName))
|
||||||
else
|
else
|
||||||
self:T2(SUPPRESSION.id..string.format("Group %s: Dead MOOSE unit DOES NOT not exist! Unit name %s.", GroupNameIni, IniUnitName))
|
self:T2(self.lid..string.format("Group %s: Dead MOOSE unit DOES NOT not exist! Unit name %s.", GroupNameIni, IniUnitName))
|
||||||
end
|
end
|
||||||
|
|
||||||
if EventData.IniDCSUnit then
|
if EventData.IniDCSUnit then
|
||||||
self:T2(SUPPRESSION.id..string.format("Group %s: Dead DCS unit DOES exist! Unit name %s.", GroupNameIni, IniUnitName))
|
self:T2(self.lid..string.format("Group %s: Dead DCS unit DOES exist! Unit name %s.", GroupNameIni, IniUnitName))
|
||||||
else
|
else
|
||||||
self:T2(SUPPRESSION.id..string.format("Group %s: Dead DCS unit DOES NOT exist! Unit name %s.", GroupNameIni, IniUnitName))
|
self:T2(self.lid..string.format("Group %s: Dead DCS unit DOES NOT exist! Unit name %s.", GroupNameIni, IniUnitName))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Flare unit that died.
|
-- Flare unit that died.
|
||||||
if IniUnit and (self.flare or self.Debug) then
|
if IniUnit and (self.flare or self.Debug) then
|
||||||
IniUnit:FlareWhite()
|
IniUnit:FlareWhite()
|
||||||
self:T(SUPPRESSION.id..string.format("Flare Dead MOOSE unit."))
|
self:T(self.lid..string.format("Flare Dead MOOSE unit."))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Flare unit that died.
|
-- Flare unit that died.
|
||||||
if EventData.IniDCSUnit and (self.flare or self.Debug) then
|
if EventData.IniDCSUnit and (self.flare or self.Debug) then
|
||||||
local p=EventData.IniDCSUnit:getPosition().p
|
local p=EventData.IniDCSUnit:getPosition().p
|
||||||
trigger.action.signalFlare(p, trigger.flareColor.Yellow , 0)
|
trigger.action.signalFlare(p, trigger.flareColor.Yellow , 0)
|
||||||
self:T(SUPPRESSION.id..string.format("Flare Dead DCS unit."))
|
self:T(self.lid..string.format("Flare Dead DCS unit."))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Get status.
|
-- Get status.
|
||||||
@ -1462,7 +1598,7 @@ function SUPPRESSION:_Suppress()
|
|||||||
-- Debug message.
|
-- Debug message.
|
||||||
local text=string.format("Group %s is suppressed for %d seconds. Suppression ends at %d:%02d.", Controllable:GetName(), Tsuppress, self.TsuppressionOver/60, self.TsuppressionOver%60)
|
local text=string.format("Group %s is suppressed for %d seconds. Suppression ends at %d:%02d.", Controllable:GetName(), Tsuppress, self.TsuppressionOver/60, self.TsuppressionOver%60)
|
||||||
MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
||||||
self:T(SUPPRESSION.id..text)
|
self:T(self.lid..text)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1520,7 +1656,7 @@ function SUPPRESSION:_Run(fin, speed, formation, wait)
|
|||||||
local MarkerID=ini:MarkToAll(string.format("Waypoing %d of group %s (initial)", #wp, self.Controllable:GetName()))
|
local MarkerID=ini:MarkToAll(string.format("Waypoing %d of group %s (initial)", #wp, self.Controllable:GetName()))
|
||||||
end
|
end
|
||||||
|
|
||||||
self:T2(SUPPRESSION.id..string.format("Number of waypoints %d", nx))
|
self:T2(self.lid..string.format("Number of waypoints %d", nx))
|
||||||
for i=1,nx-2 do
|
for i=1,nx-2 do
|
||||||
|
|
||||||
local x=dx*i
|
local x=dx*i
|
||||||
@ -1529,13 +1665,13 @@ function SUPPRESSION:_Run(fin, speed, formation, wait)
|
|||||||
wp[#wp+1]=coord:WaypointGround(speed, formation)
|
wp[#wp+1]=coord:WaypointGround(speed, formation)
|
||||||
tasks[#tasks+1]=group:TaskFunction("SUPPRESSION._Passing_Waypoint", self, #wp, false)
|
tasks[#tasks+1]=group:TaskFunction("SUPPRESSION._Passing_Waypoint", self, #wp, false)
|
||||||
|
|
||||||
self:T2(SUPPRESSION.id..string.format("%d x = %4.1f", i, x))
|
self:T2(self.lid..string.format("%d x = %4.1f", i, x))
|
||||||
if self.Debug then
|
if self.Debug then
|
||||||
local MarkerID=coord:MarkToAll(string.format("Waypoing %d of group %s", #wp, self.Controllable:GetName()))
|
local MarkerID=coord:MarkToAll(string.format("Waypoing %d of group %s", #wp, self.Controllable:GetName()))
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
self:T2(SUPPRESSION.id..string.format("Total distance: %4.1f", dist))
|
self:T2(self.lid..string.format("Total distance: %4.1f", dist))
|
||||||
|
|
||||||
-- Final waypoint.
|
-- Final waypoint.
|
||||||
wp[#wp+1]=fin:WaypointGround(speed, formation)
|
wp[#wp+1]=fin:WaypointGround(speed, formation)
|
||||||
@ -1584,7 +1720,7 @@ function SUPPRESSION._Passing_Waypoint(group, Fsm, i, final)
|
|||||||
local text=string.format("Group %s passing waypoint %d (final=%s)", group:GetName(), i, tostring(final))
|
local text=string.format("Group %s passing waypoint %d (final=%s)", group:GetName(), i, tostring(final))
|
||||||
MESSAGE:New(text,10):ToAllIf(Fsm.Debug)
|
MESSAGE:New(text,10):ToAllIf(Fsm.Debug)
|
||||||
if Fsm.Debug then
|
if Fsm.Debug then
|
||||||
env.info(SUPPRESSION.id..text)
|
env.info(self.lid..text)
|
||||||
end
|
end
|
||||||
|
|
||||||
if final then
|
if final then
|
||||||
@ -1629,7 +1765,7 @@ function SUPPRESSION:_SearchHideout()
|
|||||||
-- Place markers on every possible scenery object.
|
-- Place markers on every possible scenery object.
|
||||||
local MarkerID=SceneryObject:GetCoordinate():MarkToAll(string.format("%s scenery object %s", self.Controllable:GetName(),SceneryObject:GetTypeName()))
|
local MarkerID=SceneryObject:GetCoordinate():MarkToAll(string.format("%s scenery object %s", self.Controllable:GetName(),SceneryObject:GetTypeName()))
|
||||||
local text=string.format("%s scenery: %s, Coord %s", self.Controllable:GetName(), SceneryObject:GetTypeName(), SceneryObject:GetCoordinate():ToStringLLDMS())
|
local text=string.format("%s scenery: %s, Coord %s", self.Controllable:GetName(), SceneryObject:GetTypeName(), SceneryObject:GetCoordinate():ToStringLLDMS())
|
||||||
self:T2(SUPPRESSION.id..text)
|
self:T2(self.lid..text)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Add to table.
|
-- Add to table.
|
||||||
@ -1642,7 +1778,7 @@ function SUPPRESSION:_SearchHideout()
|
|||||||
if #hideouts>0 then
|
if #hideouts>0 then
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T(SUPPRESSION.id.."Number of hideouts "..#hideouts)
|
self:T(self.lid.."Number of hideouts "..#hideouts)
|
||||||
|
|
||||||
-- Sort results table wrt number of hits.
|
-- Sort results table wrt number of hits.
|
||||||
local _sort = function(a,b) return a.distance < b.distance end
|
local _sort = function(a,b) return a.distance < b.distance end
|
||||||
@ -1655,7 +1791,7 @@ function SUPPRESSION:_SearchHideout()
|
|||||||
Hideout=hideouts[1].object:GetCoordinate()
|
Hideout=hideouts[1].object:GetCoordinate()
|
||||||
|
|
||||||
else
|
else
|
||||||
self:E(SUPPRESSION.id.."No hideouts found!")
|
self:E(self.lid.."No hideouts found!")
|
||||||
end
|
end
|
||||||
|
|
||||||
return Hideout
|
return Hideout
|
||||||
@ -1685,7 +1821,7 @@ function SUPPRESSION:_GetLife()
|
|||||||
|
|
||||||
local groupstrength=#units/self.IniGroupStrength*100
|
local groupstrength=#units/self.IniGroupStrength*100
|
||||||
|
|
||||||
self.T2(SUPPRESSION.id..string.format("Group %s _GetLife nunits = %d", self.Controllable:GetName(), #units))
|
self.T2(self.lid..string.format("Group %s _GetLife nunits = %d", self.Controllable:GetName(), #units))
|
||||||
|
|
||||||
for _,unit in pairs(units) do
|
for _,unit in pairs(units) do
|
||||||
|
|
||||||
@ -1702,7 +1838,7 @@ function SUPPRESSION:_GetLife()
|
|||||||
life_ave=life_ave+life
|
life_ave=life_ave+life
|
||||||
if self.Debug then
|
if self.Debug then
|
||||||
local text=string.format("n=%02d: Life = %3.1f, Life0 = %3.1f, min=%3.1f, max=%3.1f, ave=%3.1f, group=%3.1f", n, unit:GetLife(), unit:GetLife0(), life_min, life_max, life_ave/n,groupstrength)
|
local text=string.format("n=%02d: Life = %3.1f, Life0 = %3.1f, min=%3.1f, max=%3.1f, ave=%3.1f, group=%3.1f", n, unit:GetLife(), unit:GetLife0(), life_min, life_max, life_ave/n,groupstrength)
|
||||||
self:T2(SUPPRESSION.id..text)
|
self:T2(self.lid..text)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1795,13 +1931,13 @@ function SUPPRESSION:_SetROE(roe)
|
|||||||
elseif roe==SUPPRESSION.ROE.Return then
|
elseif roe==SUPPRESSION.ROE.Return then
|
||||||
group:OptionROEReturnFire()
|
group:OptionROEReturnFire()
|
||||||
else
|
else
|
||||||
self:E(SUPPRESSION.id.."Unknown ROE requested: "..tostring(roe))
|
self:E(self.lid.."Unknown ROE requested: "..tostring(roe))
|
||||||
group:OptionROEOpenFire()
|
group:OptionROEOpenFire()
|
||||||
self.CurrentROE=SUPPRESSION.ROE.Free
|
self.CurrentROE=SUPPRESSION.ROE.Free
|
||||||
end
|
end
|
||||||
|
|
||||||
local text=string.format("Group %s now has ROE %s.", self.Controllable:GetName(), self.CurrentROE)
|
local text=string.format("Group %s now has ROE %s.", self.Controllable:GetName(), self.CurrentROE)
|
||||||
self:T(SUPPRESSION.id..text)
|
self:T(self.lid..text)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets the alarm state of the group and updates the current alarm state variable.
|
--- Sets the alarm state of the group and updates the current alarm state variable.
|
||||||
@ -1824,13 +1960,13 @@ function SUPPRESSION:_SetAlarmState(state)
|
|||||||
elseif state==SUPPRESSION.AlarmState.Red then
|
elseif state==SUPPRESSION.AlarmState.Red then
|
||||||
group:OptionAlarmStateRed()
|
group:OptionAlarmStateRed()
|
||||||
else
|
else
|
||||||
self:E(SUPPRESSION.id.."Unknown alarm state requested: "..tostring(state))
|
self:E(self.lid.."Unknown alarm state requested: "..tostring(state))
|
||||||
group:OptionAlarmStateAuto()
|
group:OptionAlarmStateAuto()
|
||||||
self.CurrentAlarmState=SUPPRESSION.AlarmState.Auto
|
self.CurrentAlarmState=SUPPRESSION.AlarmState.Auto
|
||||||
end
|
end
|
||||||
|
|
||||||
local text=string.format("Group %s now has Alarm State %s.", self.Controllable:GetName(), self.CurrentAlarmState)
|
local text=string.format("Group %s now has Alarm State %s.", self.Controllable:GetName(), self.CurrentAlarmState)
|
||||||
self:T(SUPPRESSION.id..text)
|
self:T(self.lid..text)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Print event-from-to string to DCS log file.
|
--- Print event-from-to string to DCS log file.
|
||||||
@ -1841,7 +1977,7 @@ end
|
|||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
function SUPPRESSION:_EventFromTo(BA, Event, From, To)
|
function SUPPRESSION:_EventFromTo(BA, Event, From, To)
|
||||||
local text=string.format("\n%s: %s EVENT %s: %s --> %s", BA, self.Controllable:GetName(), Event, From, To)
|
local text=string.format("\n%s: %s EVENT %s: %s --> %s", BA, self.Controllable:GetName(), Event, From, To)
|
||||||
self:T2(SUPPRESSION.id..text)
|
self:T2(self.lid..text)
|
||||||
end
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -1046,6 +1046,45 @@ function GROUP:GetFuel()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the number of shells, rockets, bombs and missiles the whole group currently has.
|
||||||
|
-- @param #GROUP self
|
||||||
|
-- @return #number Total amount of ammo the group has left. This is the sum of shells, rockets, bombs and missiles of all units.
|
||||||
|
-- @return #number Number of shells left.
|
||||||
|
-- @return #number Number of rockets left.
|
||||||
|
-- @return #number Number of bombs left.
|
||||||
|
-- @return #number Number of missiles left.
|
||||||
|
function GROUP:GetAmmunition()
|
||||||
|
self:F( self.ControllableName )
|
||||||
|
|
||||||
|
local DCSControllable = self:GetDCSObject()
|
||||||
|
|
||||||
|
local Ntot=0
|
||||||
|
local Nshells=0
|
||||||
|
local Nrockets=0
|
||||||
|
local Nmissiles=0
|
||||||
|
|
||||||
|
if DCSControllable then
|
||||||
|
|
||||||
|
-- Loop over units.
|
||||||
|
for UnitID, UnitData in pairs( self:GetUnits() ) do
|
||||||
|
local Unit = UnitData -- Wrapper.Unit#UNIT
|
||||||
|
|
||||||
|
-- Get ammo of the unit
|
||||||
|
local ntot, nshells, nrockets, nmissiles = Unit:GetAmmunition()
|
||||||
|
|
||||||
|
Ntot=Ntot+ntot
|
||||||
|
Nshells=Nshells+nshells
|
||||||
|
Nrockets=Nrockets+nrockets
|
||||||
|
Nmissiles=Nmissiles+nmissiles
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return Ntot, Nshells, Nrockets, Nmissiles
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
do -- Is Zone methods
|
do -- Is Zone methods
|
||||||
|
|
||||||
--- Returns true if all units of the group are within a @{Zone}.
|
--- Returns true if all units of the group are within a @{Zone}.
|
||||||
|
|||||||
@ -493,6 +493,94 @@ function UNIT:GetAmmo()
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get the number of ammunition and in particular the number of shells, rockets, bombs and missiles a unit currently has.
|
||||||
|
-- @param #UNIT self
|
||||||
|
-- @return #number Total amount of ammo the unit has left. This is the sum of shells, rockets, bombs and missiles.
|
||||||
|
-- @return #number Number of shells left.
|
||||||
|
-- @return #number Number of rockets left.
|
||||||
|
-- @return #number Number of bombs left.
|
||||||
|
-- @return #number Number of missiles left.
|
||||||
|
function UNIT:GetAmmunition()
|
||||||
|
|
||||||
|
-- Init counter.
|
||||||
|
local nammo=0
|
||||||
|
local nshells=0
|
||||||
|
local nrockets=0
|
||||||
|
local nmissiles=0
|
||||||
|
local nbombs=0
|
||||||
|
|
||||||
|
local unit=self
|
||||||
|
|
||||||
|
-- Get ammo table.
|
||||||
|
local ammotable=unit:GetAmmo()
|
||||||
|
|
||||||
|
if ammotable then
|
||||||
|
|
||||||
|
local weapons=#ammotable
|
||||||
|
|
||||||
|
-- Loop over all weapons.
|
||||||
|
for w=1,weapons do
|
||||||
|
|
||||||
|
-- Number of current weapon.
|
||||||
|
local Nammo=ammotable[w]["count"]
|
||||||
|
|
||||||
|
-- Type name of current weapon.
|
||||||
|
local Tammo=ammotable[w]["desc"]["typeName"]
|
||||||
|
|
||||||
|
local _weaponString = UTILS.Split(Tammo,"%.")
|
||||||
|
local _weaponName = _weaponString[#_weaponString]
|
||||||
|
|
||||||
|
-- Get the weapon category: shell=0, missile=1, rocket=2, bomb=3
|
||||||
|
local Category=ammotable[w].desc.category
|
||||||
|
|
||||||
|
-- Get missile category: Weapon.MissileCategory AAM=1, SAM=2, BM=3, ANTI_SHIP=4, CRUISE=5, OTHER=6
|
||||||
|
local MissileCategory=nil
|
||||||
|
if Category==Weapon.Category.MISSILE then
|
||||||
|
MissileCategory=ammotable[w].desc.missileCategory
|
||||||
|
end
|
||||||
|
|
||||||
|
-- We are specifically looking for shells or rockets here.
|
||||||
|
if Category==Weapon.Category.SHELL then
|
||||||
|
|
||||||
|
-- Add up all shells.
|
||||||
|
nshells=nshells+Nammo
|
||||||
|
|
||||||
|
elseif Category==Weapon.Category.ROCKET then
|
||||||
|
|
||||||
|
-- Add up all rockets.
|
||||||
|
nrockets=nrockets+Nammo
|
||||||
|
|
||||||
|
elseif Category==Weapon.Category.BOMB then
|
||||||
|
|
||||||
|
-- Add up all rockets.
|
||||||
|
nbombs=nbombs+Nammo
|
||||||
|
|
||||||
|
elseif Category==Weapon.Category.MISSILE then
|
||||||
|
|
||||||
|
-- Add up all cruise missiles (category 5)
|
||||||
|
if MissileCategory==Weapon.MissileCategory.AAM then
|
||||||
|
nmissiles=nmissiles+Nammo
|
||||||
|
elseif MissileCategory==Weapon.MissileCategory.ANTI_SHIP then
|
||||||
|
nmissiles=nmissiles+Nammo
|
||||||
|
elseif MissileCategory==Weapon.MissileCategory.BM then
|
||||||
|
nmissiles=nmissiles+Nammo
|
||||||
|
elseif MissileCategory==Weapon.MissileCategory.OTHER then
|
||||||
|
nmissiles=nmissiles+Nammo
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Total amount of ammunition.
|
||||||
|
nammo=nshells+nrockets+nmissiles+nbombs
|
||||||
|
|
||||||
|
return nammo, nshells, nrockets, nbombs, nmissiles
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Returns the unit sensors.
|
--- Returns the unit sensors.
|
||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return DCS#Unit.Sensors
|
-- @return DCS#Unit.Sensors
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user