update to load embedded

This commit is contained in:
FlightControl 2016-03-24 12:27:34 +01:00
parent e7846e2978
commit 4e87256c9a
2 changed files with 572 additions and 56 deletions

View File

@ -27,5 +27,6 @@ copy /b ..\Moose\Trace.lua ^
+ ..\Moose\Spawn.lua ^
+ ..\Moose\Movement.lua ^
+ ..\Moose\Sead.lua ^
+ ..\Moose\Escort.lua ^
Moose_Embedded.lua /y

View File

@ -709,7 +709,7 @@ routines.tostringBR = function(az, dist, alt, metric)
dist = routines.utils.round(routines.utils.metersToNM(dist), 2)
end
local s = string.format('%03d°', az) .. ' for ' .. dist
local s = string.format('%03d', az) .. ' for ' .. dist
if alt then
if metric then
@ -2880,6 +2880,9 @@ _TraceClass = {
--CARGO_SLINGLOAD = true,
--CARGO_ZONE = true,
--CLEANUP = true,
--MENU_SUB_GROUP = true,
--MENU_COMMAND_GROUP = true,
--ESCORT = true,
}
--- The BASE Class
@ -3104,13 +3107,14 @@ function BASE:T( Arguments )
end
local LineCurrent = DebugInfoCurrent.currentline
local LineFrom = DebugInfoFrom.currentline
local LineFrom = 0
if DebugInfoFrom then
LineFrom = DebugInfoFrom.currentline
end
env.info( string.format( "%6d\(%6d\)/%1s:%20s%05d.%s\(%s\)" , LineCurrent, LineFrom, "T", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
end
end
-- Log an exception
function BASE:E( Arguments )
@ -3127,6 +3131,9 @@ function BASE:E( Arguments )
env.info( string.format( "%6d\(%6d\)/%1s:%20s%05d.%s\(%s\)" , LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
end
--- Encapsulation of DCS World Menu system in a set of MENU classes.
-- @module MENU
@ -3205,7 +3212,13 @@ MENU_SUB_GROUP = {
ClassName = "MENU_SUB_GROUP"
}
function MENU_SUB_GROUP:New( GroupID, MenuText, ParentMenu )
--- Creates a new menu item for a group
-- @param self
-- @param MenuGroup The group owning the menu.
-- @param MenuText The text for the menu.
-- @param ParentMenu The parent menu.
-- @return #MENU_SUB_GROUP self
function MENU_SUB_GROUP:New( MenuGroup, MenuText, ParentMenu )
-- Arrange meta tables
local MenuParentPath = nil
@ -3215,7 +3228,10 @@ function MENU_SUB_GROUP:New( GroupID, MenuText, ParentMenu )
local self = BASE:Inherit( self, MENU:New( MenuText, MenuParentPath ) )
self.MenuPath = missionCommands.addSubMenuForGroup( GroupID, MenuText, MenuParentPath )
self:T( { MenuGroup, MenuText, ParentMenu } )
self.MenuGroup = MenuGroup
self.MenuPath = missionCommands.addSubMenuForGroup( self.MenuGroup:GetID(), MenuText, MenuParentPath )
return self
end
@ -3225,7 +3241,15 @@ MENU_COMMAND_GROUP = {
ClassName = "MENU_COMMAND_GROUP"
}
function MENU_COMMAND_GROUP:New( GroupID, MenuText, ParentMenu, CommandMenuFunction, CommandMenuArgument )
--- Creates a new radio command item for a group
-- @param self
-- @param MenuGroup The group owning the menu.
-- @param MenuText The text for the menu.
-- @param ParentMenu The parent menu.
-- @param CommandMenuFunction A function that is called when the menu key is pressed.
-- @param CommandMenuArgument An argument for the function.
-- @return #MENU_COMMAND_GROUP self
function MENU_COMMAND_GROUP:New( MenuGroup, MenuText, ParentMenu, CommandMenuFunction, CommandMenuArgument )
-- Arrange meta tables
@ -3235,12 +3259,21 @@ function MENU_COMMAND_GROUP:New( GroupID, MenuText, ParentMenu, CommandMenuFunct
end
local self = BASE:Inherit( self, MENU:New( MenuText, MenuParentPath ) )
self:T( { MenuGroup, MenuText, ParentMenu, CommandMenuFunction, CommandMenuArgument } )
self.MenuPath = missionCommands.addCommandForGroup( GroupID, MenuText, MenuParentPath, CommandMenuFunction, CommandMenuArgument )
self.MenuGroup = MenuGroup
self.MenuPath = missionCommands.addCommandForGroup( self.MenuGroup:GetID(), MenuText, MenuParentPath, CommandMenuFunction, CommandMenuArgument )
self.CommandMenuFunction = CommandMenuFunction
self.CommandMenuArgument = CommandMenuArgument
return self
end
function MENU_COMMAND_GROUP:Remove()
missionCommands.removeItemForGroup( self.MenuGroup:GetID(), self.MenuPath )
return nil
end
--- A GROUP class abstraction of a DCSGroup class.
-- The GROUP class will take an abstraction of the DCSGroup class, providing more methods that can be done with a GROUP.
--
@ -3278,12 +3311,16 @@ GROUPS = {}
-- @return #GROUP self
function GROUP:New( DCSGroup )
local self = BASE:Inherit( self, BASE:New() )
self:T( DCSGroup:getName() )
self:T( DCSGroup )
self.DCSGroup = DCSGroup
self.GroupName = DCSGroup:getName()
self.GroupID = DCSGroup:getID()
self.Controller = DCSGroup:getController()
if self.DCSGroup and self.DCSGroup:isExist() then
self.GroupName = DCSGroup:getName()
self.GroupID = DCSGroup:getID()
self.Controller = DCSGroup:getController()
else
self:E( { "DCSGroup is nil or does not exist, cannot initialize GROUP!", self.DCSGroup } )
end
return self
end
@ -3354,6 +3391,15 @@ function GROUP:Activate()
return self:GetDCSGroup()
end
--- Gets the ID of the GROUP.
-- @param self
-- @return #number The ID of the GROUP.
function GROUP:GetID()
self:T( self.GroupName )
return self.GroupID
end
--- Gets the name of the GROUP.
-- @param self
-- @return #string The name of the GROUP.
@ -3373,6 +3419,16 @@ function GROUP:GetPoint()
return GroupPoint
end
--- Gets the current Point of the GROUP in VEC3 format.
-- @return #Vec3 Current Vec3 position of the group.
function GROUP:GetPositionVec3()
self:T( self.GroupName )
local GroupPoint = self:GetUnit(1):GetPositionVec3()
self:T( GroupPoint )
return GroupPoint
end
--- Destroy a GROUP
-- Note that this destroy method also raises a destroy event at run-time.
-- So all event listeners will catch the destroy event of this GROUP.
@ -3486,6 +3542,39 @@ self:T()
end
--- Hold position at the current position of the first unit of the group.
-- @param self
-- @param #number Duration The maximum duration in seconds to hold the position.
-- @return #GROUP self
function GROUP:HoldPosition( Duration )
trace.f( self.ClassName, { self.GroupName, Duration } )
local Controller = self:_GetController()
-- pattern = enum AI.Task.OribtPattern,
-- point = Vec2,
-- point2 = Vec2,
-- speed = Distance,
-- altitude = Distance
local GroupPoint = self:GetPoint()
--id = 'Orbit', params = { pattern = AI.Task.OrbitPattern.RACE_TRACK } }, stopCondition = { duration = 600 } }
Controller:pushTask( { id = 'ControlledTask',
params = { task = { id = 'Orbit',
params = { pattern = AI.Task.OrbitPattern.CIRCLE,
point = GroupPoint,
speed = 0,
altitude = 30
}
},
stopCondition = { duration = Duration
}
}
}
)
return self
end
--- Land the group at a Vec2Point.
-- @param self
-- @param #Vec2 Point The point where to land.
@ -3505,6 +3594,137 @@ trace.f( self.ClassName, { self.GroupName, Point, Duration } )
return self
end
--- Attack the Unit.
-- @param self
-- @param #UNIT The unit.
-- @return #GROUP self
function GROUP:AttackUnit( AttackUnit )
self:T( { self.GroupName, AttackUnit } )
local Controller = self:_GetController()
-- AttackUnit = {
-- id = 'AttackUnit',
-- params = {
-- unitId = Unit.ID,
-- weaponType = number,
-- expend = enum AI.Task.WeaponExpend
-- attackQty = number,
-- direction = Azimuth,
-- attackQtyLimit = boolean,
-- groupAttack = boolean,
-- }
-- }
Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.OPEN_FIRE )
Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.EVADE_FIRE )
Controller:pushTask( { id = 'AttackUnit',
params = { unitId = AttackUnit:GetID(),
expend = AI.Task.WeaponExpend.TWO,
groupAttack = true,
}
}
)
return self
end
--- Holding weapons.
-- @param self
-- @return #GROUP self
function GROUP:HoldFire()
self:T( { self.GroupName } )
local Controller = self:_GetController()
Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.WEAPON_HOLD )
return self
end
--- Return fire.
-- @param self
-- @return #GROUP self
function GROUP:ReturnFire()
self:T( { self.GroupName } )
local Controller = self:_GetController()
Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.RETURN_FIRE )
return self
end
--- Openfire.
-- @param self
-- @return #GROUP self
function GROUP:OpenFire()
self:T( { self.GroupName } )
local Controller = self:_GetController()
Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.OPEN_FIRE )
return self
end
--- Weapon free.
-- @param self
-- @return #GROUP self
function GROUP:WeaponFree()
self:T( { self.GroupName } )
local Controller = self:_GetController()
Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.WEAPON_FREE )
return self
end
--- No evasion on enemy threats.
-- @param self
-- @return #GROUP self
function GROUP:EvasionNoReaction()
self:T( { self.GroupName } )
local Controller = self:_GetController()
Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.NO_REACTION )
return self
end
--- Evasion passive defense.
-- @param self
-- @return #GROUP self
function GROUP:EvasionPassiveDefense()
self:T( { self.GroupName } )
local Controller = self:_GetController()
Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.PASSIVE_DEFENSE )
return self
end
--- Evade fire.
-- @param self
-- @return #GROUP self
function GROUP:EvasionEvadeFire()
self:T( { self.GroupName } )
local Controller = self:_GetController()
Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.EVADE_FIRE )
return self
end
--- Vertical manoeuvres.
-- @param self
-- @return #GROUP self
function GROUP:EvasionVertical()
self:T( { self.GroupName } )
local Controller = self:_GetController()
Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.BYPASS_AND_ESCAPE )
return self
end
--- Move the group to a Vec2 Point, wait for a defined duration and embark a group.
-- @param self
-- @param #Vec2 Point The point where to wait.
@ -3684,7 +3904,21 @@ function GROUP:_GetController()
return self.DCSGroup:getController()
end
--- UNIT Classes
function GROUP:GetDetectedTargets()
return self:_GetController():getDetectedTargets()
end
function GROUP:IsTargetDetected( DCSObject )
local TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity
= self:_GetController():isTargetDetected( DCSObject )
return TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity
end--- UNIT Classes
-- @module UNIT
Include.File( "Routines" )
@ -3695,6 +3929,13 @@ Include.File( "Message" )
-- @type
UNIT = {
ClassName="UNIT",
CategoryName = {
[Unit.Category.AIRPLANE] = "Airplane",
[Unit.Category.HELICOPTER] = "Helicoper",
[Unit.Category.GROUND_UNIT] = "Ground Unit",
[Unit.Category.SHIP] = "Ship",
[Unit.Category.STRUCTURE] = "Structure",
}
}
function UNIT:New( DCSUnit )
@ -3798,6 +4039,10 @@ function UNIT:OtherUnitInRadius( AwaitUnit, Radius )
return false
end
function UNIT:GetCategoryName()
return self.CategoryName[ self.DCSUnit:getDesc().category ]
end
--- ZONE Classes
-- @module ZONE
@ -3869,6 +4114,7 @@ end
--- Administers the Initial Sets of the Mission Templates as defined within the Mission Editor.
-- Administers the Spawning of new Groups within the DCSRTE and administers these new Groups within the DATABASE object(s).
-- @module DATABASE
-- @author FlightControl
Include.File( "Routines" )
Include.File( "Base" )
@ -5864,7 +6110,7 @@ CLIENT = {
-- Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() )
function CLIENT:New( ClientName, ClientBriefing )
local self = BASE:Inherit( self, BASE:New() )
self:T()
self:T( ClientName, ClientBriefing )
self.ClientName = ClientName
self:AddBriefing( ClientBriefing )
@ -5880,9 +6126,21 @@ self:T()
self._Menus = {}
end
--- ClientGroup returns the Group of a Client.
--- Return the Group of a Client.
-- This function is modified to deal with a couple of bugs in DCS 1.5.3
-- @return Group
-- @return #GROUP
function CLIENT:GetGroup()
if not self.ClientGroup then
self.ClientGroup = GROUP:New( self:GetDCSGroup() )
end
return self.ClientGroup
end
--- Return the DCSGroup of a Client.
-- This function is modified to deal with a couple of bugs in DCS 1.5.3
-- @return DCSGroup
function CLIENT:GetDCSGroup()
--self:T()
@ -5920,7 +6178,7 @@ function CLIENT:GetDCSGroup()
self:T( { tonumber(UnitData:getID()), ClientUnitData.unitId } )
if tonumber(UnitData:getID()) == ClientUnitData.unitId then
local ClientGroupTemplate = _Database.Groups[self.ClientName].Template
self.ClientGroupID = ClientGroupTemplate.groupId
self.ClientID = ClientGroupTemplate.groupId
self.ClientGroupUnit = UnitData
self:T( self.ClientName .. " : group found in bug 1.5 resolvement logic!" )
return ClientGroup
@ -5945,7 +6203,7 @@ function CLIENT:GetDCSGroup()
end
end
self.ClientGroupID = nil
self.ClientID = nil
self.ClientGroupUnit = nil
return nil
@ -5953,44 +6211,46 @@ end
function CLIENT:GetClientGroupID()
self:T()
ClientGroup = self:GetDCSGroup()
if ClientGroup then
if ClientGroup:isExist() then
return ClientGroup:getID()
else
return self.ClientGroupID
end
end
return nil
if not self.ClientID then
if not self.ClientGroup then
self.ClientGroup = GROUP:New( self:GetDCSGroup() )
end
if self.ClientGroup:IsAlive() then
self.ClientGroupID = self.ClientGroup:GetID()
else
self.ClientGroupID = self.ClientID
self.ClientGroup.GroupID = self.ClientID
end
end
self:T( self.ClientGroupID )
return self.ClientGroupID
end
function CLIENT:GetClientGroupName()
self:T()
ClientGroup = self:GetDCSGroup()
if ClientGroup then
if ClientGroup:isExist() then
self:T( ClientGroup:getName() )
return ClientGroup:getName()
else
self:T( self.ClientName )
return self.ClientName
end
end
return nil
if not self.ClientGroupName then
if not self.ClientGroup then
self.ClientGroup = GROUP:New( self:GetDCSGroup() )
end
if self.ClientGroup:IsAlive() then
self.ClientGroupName = self.ClientGroup:GetName()
else
self.ClientGroupName = self.ClientName
self.ClientGroup.GroupName = self.ClientGroupName
end
end
self:T( self.ClientGroupName )
return self.ClientGroupName
end
--- Returns the Unit of the @{CLIENT}.
-- @return Unit
function CLIENT:GetClientGroupUnit()
self:T()
self:T()
local ClientGroup = self:GetDCSGroup()
@ -6109,9 +6369,9 @@ self:T()
if not self.MenuMessages then
if self:GetClientGroupID() then
self.MenuMessages = MENU_SUB_GROUP:New( self:GetClientGroupID(), 'Messages' )
self.MenuRouteMessageOn = MENU_COMMAND_GROUP:New( self:GetClientGroupID(), 'Messages On', self.MenuMessages, CLIENT.SwitchMessages, { self, true } )
self.MenuRouteMessageOff = MENU_COMMAND_GROUP:New( self:GetClientGroupID(),'Messages Off', self.MenuMessages, CLIENT.SwitchMessages, { self, false } )
self.MenuMessages = MENU_SUB_GROUP:New( self:GetGroup(), 'Messages' )
self.MenuRouteMessageOn = MENU_COMMAND_GROUP:New( self:GetGroup(), 'Messages On', self.MenuMessages, CLIENT.SwitchMessages, { self, true } )
self.MenuRouteMessageOff = MENU_COMMAND_GROUP:New( self:GetGroup(),'Messages Off', self.MenuMessages, CLIENT.SwitchMessages, { self, false } )
end
end
@ -6168,11 +6428,12 @@ MESSAGE = {
--- Creates a new MESSAGE object. Note that these MESSAGE objects are not yet displayed on the display panel. You must use the functions @{ToClient} or @{ToCoalition} or @{ToAll} to send these Messages to the respective recipients.
-- @param string MessageText is the text of the Message.
-- @param string MessageCategory is a string expressing the Category of the Message. Messages are grouped on the display panel per Category to improve readability.
-- @param number MessageDuration is a number in seconds of how long the MESSAGE should be shown on the display panel.
-- @param string MessageID is a string expressing the ID of the Message.
-- @return MESSAGE
-- @param self
-- @param #string MessageText is the text of the Message.
-- @param #string MessageCategory is a string expressing the Category of the Message. Messages are grouped on the display panel per Category to improve readability.
-- @param #number MessageDuration is a number in seconds of how long the MESSAGE should be shown on the display panel.
-- @param #string MessageID is a string expressing the ID of the Message.
-- @return #MESSAGE
-- @usage
-- -- Create a series of new Messages.
-- -- MessageAll is meant to be sent to all players, for 25 seconds, and is classified as "Score".
@ -10152,7 +10413,7 @@ end
--- Get the index from a given group.
-- The function will search the name of the group for a #, and will return the number behind the #-mark.
function SPAWN:_GetGroupIndexFromGroup( SpawnGroup )
function SPAWN:GetSpawnIndexFromGroup( SpawnGroup )
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnGroup } )
local IndexString = string.match( SpawnGroup:GetName(), "#.*$" ):sub( 2 )
@ -10458,7 +10719,7 @@ function SPAWN:_OnLand( event )
self.Landed = true
self:T( "self.Landed = true" )
if self.Landed and self.RepeatOnLanding then
local SpawnGroupIndex = self:_GetGroupIndexFromGroup( SpawnGroup )
local SpawnGroupIndex = self:GetSpawnIndexFromGroup( SpawnGroup )
self:T( { "Landed:", "ReSpawn:", SpawnGroup:GetName(), SpawnGroupIndex } )
self:ReSpawn( SpawnGroupIndex )
end
@ -10479,7 +10740,7 @@ function SPAWN:_OnLand( event )
if SpawnGroup then
self:T( { "EngineShutDown event: " .. event.initiator:getName(), event } )
if self.Landed and self.RepeatOnEngineShutDown then
local SpawnGroupIndex = self:_GetGroupIndexFromGroup( SpawnGroup )
local SpawnGroupIndex = self:GetSpawnIndexFromGroup( SpawnGroup )
self:T( { "EngineShutDown: ", "ReSpawn:", SpawnGroup:GetName(), SpawnGroupIndex } )
self:ReSpawn( SpawnGroupIndex )
end
@ -10805,3 +11066,257 @@ self:T( { event } )
end
end
end
--- Taking the lead of AI escorting your flight.
-- The ESCORT class allows you to interact with escoring AI on your flight and take the lead.
-- The following commands will be available:
--
-- * Pop-up and Scan Area
-- * Re-Join Formation
-- * Hold Position in x km
-- * Report identified targets
-- * Perform tasks per identified target: Report vector to target, paint target, kill target
--
-- @module ESCORT
-- @author FlightControl
Include.File( "Routines" )
Include.File( "Base" )
Include.File( "Database" )
Include.File( "Group" )
Include.File( "Zone" )
--- ESCORT class
-- @type
--
ESCORT = {
ClassName = "ESCORT",
EscortName = nil, -- The Escort Name
Targets = {}, -- The identified targets
}
--- ESCORT class constructor for an AI group
-- @param self
-- @param #CLIENT EscortClient The client escorted by the EscortGroup.
-- @param #GROUP EscortGroup The group AI escorting the EscortClient.
-- @param #string EscortName Name of the escort.
-- @return #ESCORT self
function ESCORT:New( EscortClient, EscortGroup, EscortName )
local self = BASE:Inherit( self, BASE:New() )
self:T( { EscortClient, EscortGroup, EscortName } )
self.EscortClient = EscortClient
self.EscortGroup = EscortGroup
self.EscortName = EscortName
self.ReportTargets = true
-- Escort Navigation
self.EscortMenu = MENU_SUB_GROUP:New( self.EscortClient:GetGroup(), "Escort" .. self.EscortName )
self.EscortMenuHoldPosition = MENU_COMMAND_GROUP:New( self.EscortClient:GetGroup(), "Hold Position and Stay Low", self.EscortMenu, ESCORT._HoldPosition, { ParamSelf = self } )
-- Report Targets
self.EscortMenuReportNearbyTargets = MENU_SUB_GROUP:New( self.EscortClient:GetGroup(), "Report Targets", self.EscortMenu )
self.EscortMenuReportNearbyTargetsOn = MENU_COMMAND_GROUP:New( self.EscortClient:GetGroup(), "Report Targets On", self.EscortMenuReportNearbyTargets, ESCORT._ReportNearbyTargets, { ParamSelf = self, ParamReportTargets = true } )
self.EscortMenuReportNearbyTargetsOff = MENU_COMMAND_GROUP:New( self.EscortClient:GetGroup(), "Report Targets Off", self.EscortMenuReportNearbyTargets, ESCORT._ReportNearbyTargets, { ParamSelf = self, ParamReportTargets = false, } )
-- Attack Targets
self.EscortMenuAttackNearbyTargets = MENU_SUB_GROUP:New( self.EscortClient:GetGroup(), "Attack nearby targets", self.EscortMenu )
self.EscortMenuAttackTargets = {}
self.Targets = {}
-- Rules of Engagement
self.EscortMenuROE = MENU_SUB_GROUP:New( self.EscortClient:GetGroup(), "ROE", self.EscortMenu )
self.EscortMenuROEHoldFire = MENU_COMMAND_GROUP:New( self.EscortClient:GetGroup(), "Hold Fire", self.EscortMenuROE, ESCORT._ROEHoldFire, { ParamSelf = self, } )
self.EscortMenuROEReturnFire = MENU_COMMAND_GROUP:New( self.EscortClient:GetGroup(), "Return Fire", self.EscortMenuROE, ESCORT._ROEReturnFire, { ParamSelf = self, } )
self.EscortMenuROEOpenFire = MENU_COMMAND_GROUP:New( self.EscortClient:GetGroup(), "Open Fire", self.EscortMenuROE, ESCORT._ROEOpenFire, { ParamSelf = self, } )
self.EscortMenuROEWeaponFree = MENU_COMMAND_GROUP:New( self.EscortClient:GetGroup(), "Weapon Free", self.EscortMenuROE, ESCORT._ROEWeaponFree, { ParamSelf = self, } )
-- Reaction to Threats
self.EscortMenuEvasion = MENU_SUB_GROUP:New( self.EscortClient:GetGroup(), "Evasion", self.EscortMenu )
self.EscortMenuEvasionNoReaction = MENU_COMMAND_GROUP:New( self.EscortClient:GetGroup(), "Fight until death", self.EscortMenuEvasion, ESCORT._EvasionNoReaction, { ParamSelf = self, } )
self.EscortMenuEvasionPassiveDefense = MENU_COMMAND_GROUP:New( self.EscortClient:GetGroup(), "Use flares, chaff and jammers", self.EscortMenuEvasion, ESCORT._EvasionPassiveDefense, { ParamSelf = self, } )
self.EscortMenuEvasionEvadeFire = MENU_COMMAND_GROUP:New( self.EscortClient:GetGroup(), "Evade enemy fire", self.EscortMenuEvasion, ESCORT._EvasionEvadeFire, { ParamSelf = self, } )
self.EscortMenuEvasionVertical = MENU_COMMAND_GROUP:New( self.EscortClient:GetGroup(), "Go below radar and evade fire", self.EscortMenuEvasion, ESCORT._EvasionVertical, { ParamSelf = self, } )
self.ScanForTargetsFunction = routines.scheduleFunction( self._ScanForTargets, { self }, timer.getTime() + 1, 30 )
end
function ESCORT._HoldPosition( MenuParam )
MenuParam.ParamSelf.EscortGroup:HoldPosition( 300 )
MESSAGE:New( "Holding Position at ... for 5 minutes.", MenuParam.ParamSelf.EscortName, 10, "ESCORT/HoldPosition" ):ToClient( MenuParam.ParamSelf.EscortClient )
end
function ESCORT._ReportNearbyTargets( MenuParam )
MenuParam.ParamSelf:T()
MenuParam.ParamSelf.ReportTargets = MenuParam.ParamReportTargets
end
function ESCORT._AttackTarget( MenuParam )
MenuParam.ParamSelf.EscortGroup:AttackUnit( MenuParam.ParamUnit )
MESSAGE:New( "Attacking Unit", MenuParam.ParamSelf.EscortName, 10, "ESCORT/AttackUnit" ):ToClient( MenuParam.ParamSelf.EscortClient )
end
function ESCORT._ROEHoldFire( MenuParam )
MenuParam.ParamSelf.EscortGroup:HoldFire()
MESSAGE:New( "Holding weapons.", MenuParam.ParamSelf.EscortName, 10, "ESCORT/AttackUnit" ):ToClient( MenuParam.ParamSelf.EscortClient )
end
function ESCORT._ROEReturnFire( MenuParam )
MenuParam.ParamSelf.EscortGroup:ReturnFire()
MESSAGE:New( "Returning enemy fire.", MenuParam.ParamSelf.EscortName, 10, "ESCORT/AttackUnit" ):ToClient( MenuParam.ParamSelf.EscortClient )
end
function ESCORT._ROEOpenFire( MenuParam )
MenuParam.ParamSelf.EscortGroup:OpenFire()
MESSAGE:New( "Open fire on ordered targets.", MenuParam.ParamSelf.EscortName, 10, "ESCORT/AttackUnit" ):ToClient( MenuParam.ParamSelf.EscortClient )
end
function ESCORT._ROEWeaponFree( MenuParam )
MenuParam.ParamSelf.EscortGroup:WeaponFree()
MESSAGE:New( "Engaging targets.", MenuParam.ParamSelf.EscortName, 10, "ESCORT/AttackUnit" ):ToClient( MenuParam.ParamSelf.EscortClient )
end
function ESCORT._EvasionNoReaction( MenuParam )
MenuParam.ParamSelf.EscortGroup:EvasionNoReaction()
MESSAGE:New( "We'll fight until death.", MenuParam.ParamSelf.EscortName, 10, "ESCORT/AttackUnit" ):ToClient( MenuParam.ParamSelf.EscortClient )
end
function ESCORT._EvasionPassiveDefense( MenuParam )
MenuParam.ParamSelf.EscortGroup:EvasionPassiveDefense()
MESSAGE:New( "We will use flares, chaff and jammers.", MenuParam.ParamSelf.EscortName, 10, "ESCORT/AttackUnit" ):ToClient( MenuParam.ParamSelf.EscortClient )
end
function ESCORT._EvasionEvadeFire( MenuParam )
MenuParam.ParamSelf.EscortGroup:EvasionEvadeFire()
MESSAGE:New( "We'll evade enemy fire.", MenuParam.ParamSelf.EscortName, 10, "ESCORT/AttackUnit" ):ToClient( MenuParam.ParamSelf.EscortClient )
end
function ESCORT._EvasionVertical( MenuParam )
MenuParam.ParamSelf.EscortGroup:EvasionVertical()
MESSAGE:New( "We'll perform vertical evasive manoeuvres.", MenuParam.ParamSelf.EscortName, 10, "ESCORT/AttackUnit" ):ToClient( MenuParam.ParamSelf.EscortClient )
end
function ESCORT:_ScanForTargets()
self:T()
self.Targets = {}
if self.EscortGroup:IsAlive() then
local EscortTargets = self.EscortGroup:GetDetectedTargets()
local EscortTargetMessages = ""
for EscortTargetID, EscortTarget in pairs( EscortTargets ) do
local EscortObject = EscortTarget.object
self:T( EscortObject )
if EscortObject and EscortObject:isExist() and EscortObject.id_ < 50000000 then
local EscortTargetMessage = ""
local EscortTargetUnit = UNIT:New( EscortObject )
local EscortTargetCategoryName = EscortTargetUnit:GetCategoryName()
local EscortTargetCategoryType = EscortTargetUnit:GetTypeName()
-- local EscortTargetIsDetected,
-- EscortTargetIsVisible,
-- EscortTargetLastTime,
-- EscortTargetKnowType,
-- EscortTargetKnowDistance,
-- EscortTargetLastPos,
-- EscortTargetLastVelocity
-- = self.EscortGroup:IsTargetDetected( EscortObject )
--
-- self:T( { EscortTargetIsDetected,
-- EscortTargetIsVisible,
-- EscortTargetLastTime,
-- EscortTargetKnowType,
-- EscortTargetKnowDistance,
-- EscortTargetLastPos,
-- EscortTargetLastVelocity } )
if EscortTarget.distance then
local EscortTargetUnitPositionVec3 = EscortTargetUnit:GetPositionVec()
local EscortPositionVec3 = self.EscortGroup:GetPositionVec3()
local Distance = routines.utils.get3DDist( EscortTargetUnitPositionVec3, EscortPositionVec3 ) / 1000
self:T( { self.EscortGroup:GetName(), EscortTargetUnit:GetName(), Distance, EscortTarget.visible } )
if Distance <= 8 then
if EscortTarget.type then
EscortTargetMessage = EscortTargetMessage .. " - " .. EscortTargetCategoryName .. " (" .. EscortTargetCategoryType .. ") at "
else
EscortTargetMessage = EscortTargetMessage .. " - Unknown target at "
end
EscortTargetMessage = EscortTargetMessage .. string.format( "%.2f", Distance ) .. " km"
if EscortTarget.visible then
EscortTargetMessage = EscortTargetMessage .. ", visual"
end
local TargetIndex = Distance*1000
self.Targets[TargetIndex] = {}
self.Targets[TargetIndex].AttackMessage = EscortTargetMessage
self.Targets[TargetIndex].AttackUnit = EscortTargetUnit
end
end
if EscortTargetMessage ~= "" then
EscortTargetMessages = EscortTargetMessages .. EscortTargetMessage .. "\n"
end
end
end
if EscortTargetMessages ~= "" and self.ReportTargets == true then
self.EscortClient:Message( EscortTargetMessages:gsub("\n$",""), 20, "/ESCORT.DetectedTargets", self.EscortName .. " reporting detected targets within 8 km range:", 0 )
end
self:T()
self:T( { "Sorting Targets Table:", self.Targets } )
table.sort( self.Targets )
self:T( { "Sorted Targets Table:", self.Targets } )
for MenuIndex = 1, #self.EscortMenuAttackTargets do
self:T( { "Remove Menu:", self.EscortMenuAttackTargets[MenuIndex] } )
self.EscortMenuAttackTargets[MenuIndex] = self.EscortMenuAttackTargets[MenuIndex]:Remove()
end
local MenuIndex = 1
for TargetID, TargetData in pairs( self.Targets ) do
self:T( { "Adding menu:", TargetID, "for Unit", self.Targets[TargetID].AttackUnit } )
if MenuIndex <= 10 then
self.EscortMenuAttackTargets[MenuIndex] =
MENU_COMMAND_GROUP:New( self.EscortClient:GetGroup(),
self.Targets[TargetID].AttackMessage,
self.EscortMenuAttackNearbyTargets,
ESCORT._AttackTarget,
{ ParamSelf = self,
ParamUnit = self.Targets[TargetID].AttackUnit
}
)
self:T( { "New Menu:", self.EscortMenuAttackTargets[TargetID] } )
MenuIndex = MenuIndex + 1
else
break
end
end
else
routines.removeFunction( self.ScanForTargetsFunction )
end
end