ESCORT Updated

This commit is contained in:
FlightControl
2016-06-14 15:04:08 +02:00
parent 29652a0edb
commit 8de64bc95a
77 changed files with 2002 additions and 330 deletions

View File

@@ -99,23 +99,31 @@
-- * @{#ESCORT.MenuEvasion: Creates a menu structure to set the evasion techniques when the escort is under threat.
-- * @{#ESCORT.MenuResumeMission}: Creates a menu structure so that the escort can resume from a waypoint.
--
--
-- @usage
-- -- Declare a new EscortPlanes object as follows:
--
-- -- First find the GROUP object and the CLIENT object.
-- local EscortClient = CLIENT:FindByName( "Unit Name" ) -- The Unit Name is the name of the unit flagged with the skill Client in the mission editor.
-- local EscortGroup = GROUP:FindByName( "Group Name" ) -- The Group Name is the name of the group that will escort the Escort Client.
--
-- -- Now use these 2 objects to construct the new EscortPlanes object.
-- EscortPlanes = ESCORT:New( EscortClient, EscortGroup, "Desert", "Welcome to the mission. You are escorted by a plane with code name 'Desert', which can be instructed through the F10 radio menu." )
--
--
--
-- @module Escort
-- @author FlightControl
---
--- ESCORT class
-- @type ESCORT
-- @extends Base#BASE
-- @field Client#CLIENT EscortClient
-- @field Group#GROUP EscortGroup
-- @field #string EscortName
-- @field #ESCORT.MODE EscortMode The mode the escort is in.
-- @field #number FollowScheduler The id of the _FollowScheduler function.
-- @field Scheduler#SCHEDULER FollowScheduler The instance of the SCHEDULER class.
-- @field #number FollowDistance The current follow distance.
-- @field #boolean ReportTargets If true, nearby targets are reported.
-- @Field DCSTypes#AI.Option.Air.val.ROE OptionROE Which ROE is set to the EscortGroup.
-- @field DCSTypes#AI.Option.Air.val.REACTION_ON_THREAT OptionReactionOnThreat Which REACTION_ON_THREAT is set to the EscortGroup.
@@ -125,7 +133,7 @@ ESCORT = {
EscortName = nil, -- The Escort Name
EscortClient = nil,
EscortGroup = nil,
EscortMode = nil,
EscortMode = 1,
MODE = {
FOLLOW = 1,
MISSION = 2,
@@ -135,6 +143,7 @@ ESCORT = {
ReportTargets = true,
OptionROE = AI.Option.Air.val.ROE.OPEN_FIRE,
OptionReactionOnThreat = AI.Option.Air.val.REACTION_ON_THREAT.ALLOW_ABORT_MISSION,
SmokeDirectionVector = false,
TaskPoints = {}
}
@@ -156,6 +165,15 @@ ESCORT = {
-- @param Group#GROUP EscortGroup The group AI escorting the EscortClient.
-- @param #string EscortName Name of the escort.
-- @return #ESCORT self
-- @usage
-- -- Declare a new EscortPlanes object as follows:
--
-- -- First find the GROUP object and the CLIENT object.
-- local EscortClient = CLIENT:FindByName( "Unit Name" ) -- The Unit Name is the name of the unit flagged with the skill Client in the mission editor.
-- local EscortGroup = GROUP:FindByName( "Group Name" ) -- The Group Name is the name of the group that will escort the Escort Client.
--
-- -- Now use these 2 objects to construct the new EscortPlanes object.
-- EscortPlanes = ESCORT:New( EscortClient, EscortGroup, "Desert", "Welcome to the mission. You are escorted by a plane with code name 'Desert', which can be instructed through the F10 radio menu." )
function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing )
local self = BASE:Inherit( self, BASE:New() )
self:F( { EscortClient, EscortGroup, EscortName } )
@@ -165,8 +183,6 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing )
self.EscortName = EscortName
self.EscortBriefing = EscortBriefing
self:T( EscortGroup:GetClassNameAndID() )
-- Set EscortGroup known at EscortClient.
if not self.EscortClient._EscortGroups then
self.EscortClient._EscortGroups = {}
@@ -177,10 +193,8 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing )
self.EscortClient._EscortGroups[EscortGroup:GetName()].EscortGroup = self.EscortGroup
self.EscortClient._EscortGroups[EscortGroup:GetName()].EscortName = self.EscortName
self.EscortClient._EscortGroups[EscortGroup:GetName()].Targets = {}
self.EscortMode = ESCORT.MODE.FOLLOW
end
self.EscortMenu = MENU_CLIENT:New( self.EscortClient, self.EscortName )
self.EscortGroup:WayPointInitialize(1)
@@ -194,9 +208,24 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing )
60, EscortClient
)
self.FollowDistance = 100
self.CT1 = 0
self.GT1 = 0
self.FollowScheduler = SCHEDULER:New( self, self._FollowScheduler, {}, 1, .5, .01 )
self.EscortMode = ESCORT.MODE.MISSION
self.FollowScheduler:Stop()
return self
end
--- This function is for test, it will put on the frequency of the FollowScheduler a red smoke at the direction vector calculated for the escort to fly to.
-- This allows to visualize where the escort is flying to.
-- @param #ESCORT self
-- @param #boolean SmokeDirection If true, then the direction vector will be smoked.
function ESCORT:TestSmokeDirectionVector( SmokeDirection )
self.SmokeDirectionVector = ( SmokeDirection == true ) and true or false
end
--- Defines the default menus
-- @param #ESCORT self
@@ -223,6 +252,7 @@ function ESCORT:Menus()
self:MenuEvasion()
self:MenuResumeMission()
return self
end
@@ -633,7 +663,7 @@ function ESCORT._HoldPosition( MenuParam )
local OrbitHeight = MenuParam.ParamHeight
local OrbitSeconds = MenuParam.ParamSeconds -- Not implemented yet
routines.removeFunction( self.FollowScheduler )
self.FollowScheduler:Stop()
local PointFrom = {}
local GroupPoint = EscortGroup:GetUnit(1):GetPointVec3()
@@ -662,6 +692,7 @@ function ESCORT._HoldPosition( MenuParam )
EscortGroup:SetTask( EscortGroup:TaskRoute( Points ) )
EscortGroup:MessageToClient( "Orbiting at location.", 10, EscortClient )
end
--- @param #MENUPARAM MenuParam
@@ -684,9 +715,7 @@ end
function ESCORT:JoinUpAndFollow( EscortGroup, EscortClient, Distance )
self:F( { EscortGroup, EscortClient, Distance } )
if self.FollowScheduler then
routines.removeFunction( self.FollowScheduler )
end
self.FollowScheduler:Stop()
EscortGroup:OptionROEHoldFire()
EscortGroup:OptionROTPassiveDefense()
@@ -695,8 +724,8 @@ function ESCORT:JoinUpAndFollow( EscortGroup, EscortClient, Distance )
self.CT1 = 0
self.GT1 = 0
--self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + 1, .5 )
self.FollowScheduler = SCHEDULER:New( self, self._FollowScheduler, { Distance }, 1, .5, .1 )
self.FollowScheduler:Start()
EscortGroup:MessageToClient( "Rejoining and Following at " .. Distance .. "!", 30, EscortClient )
end
@@ -768,11 +797,7 @@ function ESCORT._ScanTargets( MenuParam )
local ScanDuration = MenuParam.ParamScanDuration
if self.FollowScheduler then
routines.removeFunction( self.FollowScheduler )
end
self:T( { "FollowScheduler after removefunction: ", self.FollowScheduler } )
self.FollowScheduler:Stop()
if EscortGroup:IsHelicopter() then
SCHEDULER:New( EscortGroup, EscortGroup.PushTask,
@@ -797,16 +822,16 @@ function ESCORT._ScanTargets( MenuParam )
EscortGroup:MessageToClient( "Scanning targets for " .. ScanDuration .. " seconds.", ScanDuration, EscortClient )
if self.EscortMode == ESCORT.MODE.FOLLOW then
--self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + ScanDuration, 1 )
self.FollowScheduler:Start()
end
end
--- @param Group#GROUP EscortGroup
function _Resume( EscortGroup )
env.info( '_Resume' )
local Escort = EscortGroup.Escort -- #ESCORT
local Escort = EscortGroup:GetState( EscortGroup, "Escort" )
env.info( "EscortMode = " .. Escort.EscortMode )
if Escort.EscortMode == ESCORT.MODE.FOLLOW then
Escort:JoinUpAndFollow( EscortGroup, Escort.EscortClient, Escort.Distance )
@@ -819,19 +844,18 @@ function ESCORT._AttackTarget( MenuParam )
local self = MenuParam.ParamSelf
local EscortGroup = self.EscortGroup
local EscortClient = self.EscortClient
local AttackUnit = MenuParam.ParamUnit -- Unit#UNIT
if self.FollowScheduler then
routines.removeFunction( self.FollowScheduler )
end
self.FollowScheduler:Stop()
self:T( AttackUnit )
if EscortGroup:IsAir() then
EscortGroup:OptionROEOpenFire()
EscortGroup:OptionROTPassiveDefense()
EscortGroup.Escort = self -- Need to do this trick to get the reference for the escort in the _Resume function.
EscortGroup:SetState( EscortGroup, "Escort", self )
-- routines.scheduleFunction(
-- EscortGroup.PushTask,
-- { EscortGroup,
@@ -846,7 +870,7 @@ function ESCORT._AttackTarget( MenuParam )
EscortGroup.PushTask,
{ EscortGroup:TaskCombo(
{ EscortGroup:TaskAttackUnit( AttackUnit ),
EscortGroup:TaskFunction( 1, 2, "_Resume", {"''"} )
EscortGroup:TaskFunction( 1, 2, "_Resume", { "''" } )
}
)
}, 10
@@ -870,9 +894,9 @@ function ESCORT._AttackTarget( MenuParam )
}, 10
)
end
EscortGroup:MessageToClient( "Engaging Designated Unit!", 10, EscortClient )
end
--- @param #MENUPARAM MenuParam
@@ -884,10 +908,7 @@ function ESCORT._AssistTarget( MenuParam )
local EscortGroupAttack = MenuParam.ParamEscortGroup
local AttackUnit = MenuParam.ParamUnit -- Unit#UNIT
if self.FollowScheduler then
routines.removeFunction( self.FollowScheduler )
end
self.FollowScheduler:Stop()
self:T( AttackUnit )
@@ -973,8 +994,7 @@ function ESCORT._ResumeMission( MenuParam )
local WayPoint = MenuParam.ParamWayPoint
routines.removeFunction( self.FollowScheduler )
self.FollowScheduler = nil
self.FollowScheduler:Stop()
local WayPoints = EscortGroup:GetTaskRoute()
self:T( WayPoint, WayPoints )
@@ -1005,16 +1025,21 @@ function ESCORT:RegisterRoute()
end
--- @param Escort#ESCORT self
function ESCORT:_FollowScheduler( FollowDistance )
self:F( { FollowDistance })
function ESCORT:_FollowScheduler()
self:F( { self.FollowDistance } )
self:T( {self.EscortClient.UnitName, self.EscortGroup.GroupName } )
if self.EscortGroup:IsAlive() and self.EscortClient:IsAlive() then
local ClientUnit = self.EscortClient:GetClientGroupUnit()
local GroupUnit = self.EscortGroup:GetUnit( 1 )
local FollowDistance = self.FollowDistance
self:T( {ClientUnit.UnitName, GroupUnit.UnitName } )
if self.CT1 == 0 and self.GT1 == 0 then
self.CV1 = ClientUnit:GetPointVec3()
self:T( { "self.CV1", self.CV1 } )
self.CT1 = timer.getTime()
self.GV1 = GroupUnit:GetPointVec3()
self.GT1 = timer.getTime()
@@ -1074,7 +1099,10 @@ function ESCORT:_FollowScheduler( FollowDistance )
-- Now we can calculate the group destination vector GDV.
local GDV = { x = DVu.x * CS * 8 + CVI.x, y = CVI.y, z = DVu.z * CS * 8 + CVI.z }
--trigger.action.smoke( GDV, trigger.smokeColor.Red )
if self.SmokeDirectionVector == true then
trigger.action.smoke( GDV, trigger.smokeColor.Red )
end
self:T2( { "CV2:", CV2 } )
self:T2( { "CVI:", CVI } )
self:T2( { "GDV:", GDV } )
@@ -1092,11 +1120,12 @@ function ESCORT:_FollowScheduler( FollowDistance )
Speed = 0
end
self:T( { "Client Speed, Escort Speed, Speed, FlyDistance, Time:", CS, GS, Speed, Distance, Time } )
self:T( { "Client Speed, Escort Speed, Speed, FollowDistance, Time:", CS, GS, Speed, FollowDistance, Time } )
-- Now route the escort to the desired point with the desired speed.
self.EscortGroup:TaskRouteToVec3( GDV, Speed / 3.6 ) -- DCS models speed in Mps (Miles per second)
end
return true
end
@@ -1278,6 +1307,7 @@ function ESCORT:_ReportTargetsScheduler()
MENU_CLIENT_COMMAND:New( self.EscortClient, "Waypoint " .. WayPointID .. " at " .. string.format( "%.2f", Distance ).. "km", self.EscortMenuResumeMission, ESCORT._ResumeMission, { ParamSelf = self, ParamWayPoint = WayPointID } )
end
end
return true
end