Merge branch 'develop' into FF/Ops

This commit is contained in:
Frank 2022-04-27 22:46:36 +02:00
commit 47e7364976
15 changed files with 2315 additions and 633 deletions

View File

@ -14,7 +14,7 @@
-- * Only create or delete menus when required, and keep existing menus persistent.
-- * Update menu structures.
-- * Refresh menu structures intelligently, based on a time stamp of updates.
-- - Delete obscolete menus.
-- - Delete obsolete menus.
-- - Create new one where required.
-- - Don't touch the existing ones.
-- * Provide a variable amount of parameters to menus.
@ -23,7 +23,7 @@
-- * Provide a great tool to manage menus in your code.
--
-- DCS Menus can be managed using the MENU classes.
-- The advantage of using MENU classes is that it hides the complexity of dealing with menu management in more advanced scanerios where you need to
-- The advantage of using MENU classes is that it hides the complexity of dealing with menu management in more advanced scenarios where you need to
-- set menus and later remove them, and later set them again. You'll find while using use normal DCS scripting functions, that setting and removing
-- menus is not a easy feat if you have complex menu hierarchies defined.
-- Using the MOOSE menu classes, the removal and refreshing of menus are nicely being handled within these classes, and becomes much more easy.
@ -53,7 +53,6 @@
-- @module Core.Menu
-- @image Core_Menu.JPG
MENU_INDEX = {}
MENU_INDEX.MenuMission = {}
MENU_INDEX.MenuMission.Menus = {}
@ -64,10 +63,7 @@ MENU_INDEX.Coalition[coalition.side.RED] = {}
MENU_INDEX.Coalition[coalition.side.RED].Menus = {}
MENU_INDEX.Group = {}
function MENU_INDEX:ParentPath( ParentMenu, MenuText )
local Path = ParentMenu and "@" .. table.concat( ParentMenu.MenuPath or {}, "@" ) or ""
if ParentMenu then
if ParentMenu:IsInstanceOf( "MENU_GROUP" ) or ParentMenu:IsInstanceOf( "MENU_GROUP_COMMAND" ) then
@ -95,20 +91,16 @@ function MENU_INDEX:ParentPath( ParentMenu, MenuText )
Path = Path .. "@" .. MenuText
return Path
end
function MENU_INDEX:PrepareMission()
self.MenuMission.Menus = self.MenuMission.Menus or {}
end
function MENU_INDEX:PrepareCoalition( CoalitionSide )
self.Coalition[CoalitionSide] = self.Coalition[CoalitionSide] or {}
self.Coalition[CoalitionSide].Menus = self.Coalition[CoalitionSide].Menus or {}
end
---
-- @param Wrapper.Group#GROUP Group
function MENU_INDEX:PrepareGroup( Group )
@ -119,42 +111,26 @@ function MENU_INDEX:PrepareGroup( Group )
end
end
function MENU_INDEX:HasMissionMenu( Path )
return self.MenuMission.Menus[Path]
end
function MENU_INDEX:SetMissionMenu( Path, Menu )
self.MenuMission.Menus[Path] = Menu
end
function MENU_INDEX:ClearMissionMenu( Path )
self.MenuMission.Menus[Path] = nil
end
function MENU_INDEX:HasCoalitionMenu( Coalition, Path )
return self.Coalition[Coalition].Menus[Path]
end
function MENU_INDEX:SetCoalitionMenu( Coalition, Path, Menu )
self.Coalition[Coalition].Menus[Path] = Menu
end
function MENU_INDEX:ClearCoalitionMenu( Coalition, Path )
self.Coalition[Coalition].Menus[Path] = nil
end
function MENU_INDEX:HasGroupMenu( Group, Path )
if Group and Group:IsAlive() then
local MenuGroupName = Group:GetName()
@ -162,53 +138,36 @@ function MENU_INDEX:HasGroupMenu( Group, Path )
end
return nil
end
function MENU_INDEX:SetGroupMenu( Group, Path, Menu )
local MenuGroupName = Group:GetName()
Group:F({MenuGroupName=MenuGroupName,Path=Path})
self.Group[MenuGroupName].Menus[Path] = Menu
end
function MENU_INDEX:ClearGroupMenu( Group, Path )
local MenuGroupName = Group:GetName()
self.Group[MenuGroupName].Menus[Path] = nil
end
function MENU_INDEX:Refresh( Group )
for MenuID, Menu in pairs( self.MenuMission.Menus ) do
Menu:Refresh()
end
for MenuID, Menu in pairs( self.Coalition[coalition.side.BLUE].Menus ) do
Menu:Refresh()
end
for MenuID, Menu in pairs( self.Coalition[coalition.side.RED].Menus ) do
Menu:Refresh()
end
local GroupName = Group:GetName()
for MenuID, Menu in pairs( self.Group[GroupName].Menus ) do
Menu:Refresh()
end
return self
end
do -- MENU_BASE
--- @type MENU_BASE
-- @extends Core.Base#BASE
--- Defines the main MENU class where other MENU classes are derived from.
-- This is an abstract class, so don't use it.
-- @field #MENU_BASE
@ -216,10 +175,10 @@ do -- MENU_BASE
ClassName = "MENU_BASE",
MenuPath = nil,
MenuText = "",
MenuParentPath = nil
MenuParentPath = nil,
}
--- Consructor
--- Constructor
-- @param #MENU_BASE
-- @return #MENU_BASE
function MENU_BASE:New( MenuText, ParentMenu )
@ -228,27 +187,25 @@ do -- MENU_BASE
if ParentMenu ~= nil then
MenuParentPath = ParentMenu.MenuPath
end
local self = BASE:Inherit( self, BASE:New() )
local self = BASE:Inherit( self, BASE:New() )
self.MenuPath = nil
self.MenuText = MenuText
self.ParentMenu = ParentMenu
self.MenuParentPath = MenuParentPath
self.Path = ( self.ParentMenu and "@" .. table.concat( self.MenuParentPath or {}, "@" ) or "" ) .. "@" .. self.MenuText
self.MenuPath = nil
self.MenuText = MenuText
self.ParentMenu = ParentMenu
self.MenuParentPath = MenuParentPath
self.Path = ( self.ParentMenu and "@" .. table.concat( self.MenuParentPath or {}, "@" ) or "" ) .. "@" .. self.MenuText
self.Menus = {}
self.MenuCount = 0
self.MenuStamp = timer.getTime()
self.MenuRemoveParent = false
if self.ParentMenu then
self.ParentMenu.Menus = self.ParentMenu.Menus or {}
self.ParentMenu.Menus[MenuText] = self
end
return self
return self
end
function MENU_BASE:SetParentMenu( MenuText, Menu )
if self.ParentMenu then
self.ParentMenu.Menus = self.ParentMenu.Menus or {}
@ -256,7 +213,6 @@ do -- MENU_BASE
self.ParentMenu.MenuCount = self.ParentMenu.MenuCount + 1
end
end
function MENU_BASE:ClearParentMenu( MenuText )
if self.ParentMenu and self.ParentMenu.Menus[MenuText] then
self.ParentMenu.Menus[MenuText] = nil
@ -266,7 +222,6 @@ do -- MENU_BASE
end
end
end
--- Sets a @{Menu} to remove automatically the parent menu when the menu removed is the last child menu of that parent @{Menu}.
-- @param #MENU_BASE self
-- @param #boolean RemoveParent If true, the parent menu is automatically removed when this menu is the last child menu of that parent @{Menu}.
@ -276,7 +231,6 @@ do -- MENU_BASE
self.MenuRemoveParent = RemoveParent
return self
end
--- Gets a @{Menu} from a parent @{Menu}
-- @param #MENU_BASE self
@ -285,7 +239,6 @@ do -- MENU_BASE
function MENU_BASE:GetMenu( MenuText )
return self.Menus[MenuText]
end
--- Sets a menu stamp for later prevention of menu removal.
-- @param #MENU_BASE self
-- @param MenuStamp
@ -323,9 +276,7 @@ do -- MENU_BASE
end
end
do -- MENU_COMMAND_BASE
--- @type MENU_COMMAND_BASE
-- @field #function MenuCallHandler
-- @extends Core.Menu#MENU_BASE
@ -346,8 +297,7 @@ do -- MENU_COMMAND_BASE
-- @return #MENU_COMMAND_BASE
function MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, CommandMenuArguments )
local self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) ) -- #MENU_COMMAND_BASE
local self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) ) -- #MENU_COMMAND_BASE
-- When a menu function goes into error, DCS displays an obscure menu message.
-- This error handler catches the menu error and displays the full call stack.
local ErrorHandler = function( errmsg )
@ -367,7 +317,7 @@ do -- MENU_COMMAND_BASE
local Status, Result = xpcall( MenuFunction, ErrorHandler )
end
return self
return self
end
--- This sets the new command function of a menu,
@ -380,7 +330,6 @@ do -- MENU_COMMAND_BASE
self.CommandMenuFunction = CommandMenuFunction
return self
end
--- This sets the new command arguments of a menu,
-- so that if a menu is regenerated, or if command arguments change,
-- that the arguments set for the menu are loosely coupled with the menu itself!!!
@ -391,35 +340,30 @@ do -- MENU_COMMAND_BASE
self.CommandMenuArguments = CommandMenuArguments
return self
end
end
do -- MENU_MISSION
--- @type MENU_MISSION
-- @extends Core.Menu#MENU_BASE
--- Manages the main menus for a complete mission.
--
-- You can add menus with the @{#MENU_MISSION.New} method, which constructs a MENU_MISSION object and returns you the object reference.
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_MISSION.Remove}.
-- @field #MENU_MISSION
MENU_MISSION = {
ClassName = "MENU_MISSION"
ClassName = "MENU_MISSION",
}
--- MENU_MISSION constructor. Creates a new MENU_MISSION object and creates the menu for a complete mission file.
-- @param #MENU_MISSION self
-- @param #string MenuText The text for the menu.
-- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the perent menu of DCS world (under F10 other).
-- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the parent menu of DCS world (under F10 other).
-- @return #MENU_MISSION
function MENU_MISSION:New( MenuText, ParentMenu )
MENU_INDEX:PrepareMission()
local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText )
local MissionMenu = MENU_INDEX:HasMissionMenu( Path )
if MissionMenu then
return MissionMenu
else
@ -432,17 +376,15 @@ do -- MENU_MISSION
end
end
--- Refreshes a radio item for a mission
-- @param #MENU_MISSION self
-- @return #MENU_MISSION
function MENU_MISSION:Refresh()
do
missionCommands.removeItem( self.MenuPath )
self.MenuPath = missionCommands.addSubMenu( self.MenuText, self.MenuParentPath )
end
return self
end
--- Removes the sub menus recursively of this MENU_MISSION. Note that the main menu is kept!
@ -466,7 +408,6 @@ do -- MENU_MISSION
MENU_INDEX:PrepareMission()
local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText )
local MissionMenu = MENU_INDEX:HasMissionMenu( Path )
if MissionMenu == self then
self:RemoveSubMenus()
if not MenuStamp or self.MenuStamp ~= MenuStamp then
@ -487,10 +428,7 @@ do -- MENU_MISSION
return self
end
end
do -- MENU_MISSION_COMMAND
--- @type MENU_MISSION_COMMAND
@ -503,7 +441,7 @@ do -- MENU_MISSION_COMMAND
--
-- @field #MENU_MISSION_COMMAND
MENU_MISSION_COMMAND = {
ClassName = "MENU_MISSION_COMMAND"
ClassName = "MENU_MISSION_COMMAND",
}
--- MENU_MISSION constructor. Creates a new radio command item for a complete mission file, which can invoke a function with parameters.
@ -518,7 +456,6 @@ do -- MENU_MISSION_COMMAND
MENU_INDEX:PrepareMission()
local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText )
local MissionMenu = MENU_INDEX:HasMissionMenu( Path )
if MissionMenu then
MissionMenu:SetCommandMenuFunction( CommandMenuFunction )
MissionMenu:SetCommandMenuArguments( arg )
@ -532,17 +469,15 @@ do -- MENU_MISSION_COMMAND
return self
end
end
--- Refreshes a radio item for a mission
-- @param #MENU_MISSION_COMMAND self
-- @return #MENU_MISSION_COMMAND
function MENU_MISSION_COMMAND:Refresh()
do
missionCommands.removeItem( self.MenuPath )
missionCommands.addCommand( self.MenuText, self.MenuParentPath, self.MenuCallHandler )
end
return self
end
--- Removes a radio command item for a coalition
@ -553,7 +488,6 @@ do -- MENU_MISSION_COMMAND
MENU_INDEX:PrepareMission()
local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText )
local MissionMenu = MENU_INDEX:HasMissionMenu( Path )
if MissionMenu == self then
if not MenuStamp or self.MenuStamp ~= MenuStamp then
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
@ -572,13 +506,8 @@ do -- MENU_MISSION_COMMAND
return self
end
end
do -- MENU_COALITION
--- @type MENU_COALITION
-- @extends Core.Menu#MENU_BASE
@ -634,18 +563,15 @@ do -- MENU_COALITION
-- @param #MENU_COALITION self
-- @param DCS#coalition.side Coalition The coalition owning the menu.
-- @param #string MenuText The text for the menu.
-- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the perent menu of DCS world (under F10 other).
-- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the parent menu of DCS world (under F10 other).
-- @return #MENU_COALITION self
function MENU_COALITION:New( Coalition, MenuText, ParentMenu )
MENU_INDEX:PrepareCoalition( Coalition )
local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText )
local CoalitionMenu = MENU_INDEX:HasCoalitionMenu( Coalition, Path )
if CoalitionMenu then
return CoalitionMenu
else
local self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) )
MENU_INDEX:SetCoalitionMenu( Coalition, Path, self )
@ -656,17 +582,15 @@ do -- MENU_COALITION
return self
end
end
--- Refreshes a radio item for a coalition
-- @param #MENU_COALITION self
-- @return #MENU_COALITION
function MENU_COALITION:Refresh()
do
missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath )
missionCommands.addSubMenuForCoalition( self.Coalition, self.MenuText, self.MenuParentPath )
end
return self
end
--- Removes the sub menus recursively of this MENU_COALITION. Note that the main menu is kept!
@ -689,7 +613,6 @@ do -- MENU_COALITION
MENU_INDEX:PrepareCoalition( self.Coalition )
local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText )
local CoalitionMenu = MENU_INDEX:HasCoalitionMenu( self.Coalition, Path )
if CoalitionMenu == self then
self:RemoveSubMenus()
if not MenuStamp or self.MenuStamp ~= MenuStamp then
@ -709,11 +632,7 @@ do -- MENU_COALITION
return self
end
end
do -- MENU_COALITION_COMMAND
--- @type MENU_COALITION_COMMAND
@ -742,7 +661,6 @@ do -- MENU_COALITION_COMMAND
MENU_INDEX:PrepareCoalition( Coalition )
local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText )
local CoalitionMenu = MENU_INDEX:HasCoalitionMenu( Coalition, Path )
if CoalitionMenu then
CoalitionMenu:SetCommandMenuFunction( CommandMenuFunction )
CoalitionMenu:SetCommandMenuArguments( arg )
@ -757,20 +675,17 @@ do -- MENU_COALITION_COMMAND
self:SetParentMenu( self.MenuText, self )
return self
end
end
--- Refreshes a radio item for a coalition
-- @param #MENU_COALITION_COMMAND self
-- @return #MENU_COALITION_COMMAND
function MENU_COALITION_COMMAND:Refresh()
do
missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath )
missionCommands.addCommandForCoalition( self.Coalition, self.MenuText, self.MenuParentPath, self.MenuCallHandler )
end
return self
end
--- Removes a radio command item for a coalition
@ -781,7 +696,6 @@ do -- MENU_COALITION_COMMAND
MENU_INDEX:PrepareCoalition( self.Coalition )
local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText )
local CoalitionMenu = MENU_INDEX:HasCoalitionMenu( self.Coalition, Path )
if CoalitionMenu == self then
if not MenuStamp or self.MenuStamp ~= MenuStamp then
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
@ -800,20 +714,16 @@ do -- MENU_COALITION_COMMAND
return self
end
end
--- MENU_GROUP
do
-- This local variable is used to cache the menus registered under groups.
-- Menus don't dissapear when groups for players are destroyed and restarted.
-- Menus don't disappear when groups for players are destroyed and restarted.
-- So every menu for a client created must be tracked so that program logic accidentally does not create.
-- the same menus twice during initialization logic.
-- These menu classes are handling this logic with this variable.
local _MENUGROUPS = {}
--- @type MENU_GROUP
-- @extends Core.Menu#MENU_BASE
@ -889,16 +799,13 @@ do
MENU_INDEX:PrepareGroup( Group )
local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText )
local GroupMenu = MENU_INDEX:HasGroupMenu( Group, Path )
if GroupMenu then
return GroupMenu
else
self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) )
MENU_INDEX:SetGroupMenu( Group, Path, self )
self.Group = Group
self.GroupID = Group:GetID()
self.MenuPath = missionCommands.addSubMenuForGroup( self.GroupID, MenuText, self.MenuParentPath )
self:SetParentMenu( self.MenuText, self )
@ -906,12 +813,10 @@ do
end
end
--- Refreshes a new radio item for a group and submenus
-- @param #MENU_GROUP self
-- @return #MENU_GROUP
function MENU_GROUP:Refresh()
do
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
missionCommands.addSubMenuForGroup( self.GroupID, self.MenuText, self.MenuParentPath )
@ -920,7 +825,8 @@ do
Menu:Refresh()
end
end
return self
end
--- Removes the sub menus recursively of this MENU_GROUP.
@ -929,7 +835,6 @@ do
-- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set.
-- @return #MENU_GROUP self
function MENU_GROUP:RemoveSubMenus( MenuStamp, MenuTag )
for MenuText, Menu in pairs( self.Menus or {} ) do
Menu:Remove( MenuStamp, MenuTag )
end
@ -938,18 +843,15 @@ do
end
--- Removes the main menu and sub menus recursively of this MENU_GROUP.
-- @param #MENU_GROUP self
-- @param MenuStamp
-- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set.
-- @return #nil
function MENU_GROUP:Remove( MenuStamp, MenuTag )
MENU_INDEX:PrepareGroup( self.Group )
local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText )
local GroupMenu = MENU_INDEX:HasGroupMenu( self.Group, Path )
if GroupMenu == self then
self:RemoveSubMenus( MenuStamp, MenuTag )
if not MenuStamp or self.MenuStamp ~= MenuStamp then
@ -993,18 +895,15 @@ do
-- @param CommandMenuArgument An argument for the function.
-- @return #MENU_GROUP_COMMAND
function MENU_GROUP_COMMAND:New( Group, MenuText, ParentMenu, CommandMenuFunction, ... )
MENU_INDEX:PrepareGroup( Group )
local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText )
local GroupMenu = MENU_INDEX:HasGroupMenu( Group, Path )
if GroupMenu then
GroupMenu:SetCommandMenuFunction( CommandMenuFunction )
GroupMenu:SetCommandMenuArguments( arg )
return GroupMenu
else
self = BASE:Inherit( self, MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, arg ) )
MENU_INDEX:SetGroupMenu( Group, Path, self )
self.Group = Group
@ -1015,19 +914,17 @@ do
self:SetParentMenu( self.MenuText, self )
return self
end
end
--- Refreshes a radio item for a group
-- @param #MENU_GROUP_COMMAND self
-- @return #MENU_GROUP_COMMAND
function MENU_GROUP_COMMAND:Refresh()
do
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
missionCommands.addCommandForGroup( self.GroupID, self.MenuText, self.MenuParentPath, self.MenuCallHandler )
end
return self
end
--- Removes a menu structure for a group.
@ -1036,11 +933,9 @@ do
-- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set.
-- @return #nil
function MENU_GROUP_COMMAND:Remove( MenuStamp, MenuTag )
MENU_INDEX:PrepareGroup( self.Group )
local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText )
local GroupMenu = MENU_INDEX:HasGroupMenu( self.Group, Path )
if GroupMenu == self then
if not MenuStamp or self.MenuStamp ~= MenuStamp then
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
@ -1059,13 +954,9 @@ do
return self
end
end
--- MENU_GROUP_DELAYED
do
--- @type MENU_GROUP_DELAYED
-- @extends Core.Menu#MENU_BASE
@ -1093,16 +984,13 @@ do
MENU_INDEX:PrepareGroup( Group )
local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText )
local GroupMenu = MENU_INDEX:HasGroupMenu( Group, Path )
if GroupMenu then
return GroupMenu
else
self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) )
MENU_INDEX:SetGroupMenu( Group, Path, self )
self.Group = Group
self.GroupID = Group:GetID()
if self.MenuParentPath then
self.MenuPath = UTILS.DeepCopy( self.MenuParentPath )
else
@ -1116,12 +1004,10 @@ do
end
--- Refreshes a new radio item for a group and submenus
-- @param #MENU_GROUP_DELAYED self
-- @return #MENU_GROUP_DELAYED
function MENU_GROUP_DELAYED:Set()
do
if not self.MenuSet then
missionCommands.addSubMenuForGroup( self.GroupID, self.MenuText, self.MenuParentPath )
@ -1132,15 +1018,12 @@ do
Menu:Set()
end
end
end
--- Refreshes a new radio item for a group and submenus
-- @param #MENU_GROUP_DELAYED self
-- @return #MENU_GROUP_DELAYED
function MENU_GROUP_DELAYED:Refresh()
do
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
missionCommands.addSubMenuForGroup( self.GroupID, self.MenuText, self.MenuParentPath )
@ -1149,7 +1032,8 @@ do
Menu:Refresh()
end
end
return self
end
--- Removes the sub menus recursively of this MENU_GROUP_DELAYED.
@ -1158,7 +1042,6 @@ do
-- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set.
-- @return #MENU_GROUP_DELAYED self
function MENU_GROUP_DELAYED:RemoveSubMenus( MenuStamp, MenuTag )
for MenuText, Menu in pairs( self.Menus or {} ) do
Menu:Remove( MenuStamp, MenuTag )
end
@ -1167,18 +1050,15 @@ do
end
--- Removes the main menu and sub menus recursively of this MENU_GROUP.
-- @param #MENU_GROUP_DELAYED self
-- @param MenuStamp
-- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set.
-- @return #nil
function MENU_GROUP_DELAYED:Remove( MenuStamp, MenuTag )
MENU_INDEX:PrepareGroup( self.Group )
local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText )
local GroupMenu = MENU_INDEX:HasGroupMenu( self.Group, Path )
if GroupMenu == self then
self:RemoveSubMenus( MenuStamp, MenuTag )
if not MenuStamp or self.MenuStamp ~= MenuStamp then
@ -1223,18 +1103,15 @@ do
-- @param CommandMenuArgument An argument for the function.
-- @return #MENU_GROUP_COMMAND_DELAYED
function MENU_GROUP_COMMAND_DELAYED:New( Group, MenuText, ParentMenu, CommandMenuFunction, ... )
MENU_INDEX:PrepareGroup( Group )
local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText )
local GroupMenu = MENU_INDEX:HasGroupMenu( Group, Path )
if GroupMenu then
GroupMenu:SetCommandMenuFunction( CommandMenuFunction )
GroupMenu:SetCommandMenuArguments( arg )
return GroupMenu
else
self = BASE:Inherit( self, MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, arg ) )
MENU_INDEX:SetGroupMenu( Group, Path, self )
self.Group = Group
@ -1250,33 +1127,29 @@ do
self:SetParentMenu( self.MenuText, self )
return self
end
end
--- Refreshes a radio item for a group
-- @param #MENU_GROUP_COMMAND_DELAYED self
-- @return #MENU_GROUP_COMMAND_DELAYED
function MENU_GROUP_COMMAND_DELAYED:Set()
do
if not self.MenuSet then
self.MenuPath = missionCommands.addCommandForGroup( self.GroupID, self.MenuText, self.MenuParentPath, self.MenuCallHandler )
self.MenuSet = true
end
end
end
--- Refreshes a radio item for a group
-- @param #MENU_GROUP_COMMAND_DELAYED self
-- @return #MENU_GROUP_COMMAND_DELAYED
function MENU_GROUP_COMMAND_DELAYED:Refresh()
do
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
missionCommands.addCommandForGroup( self.GroupID, self.MenuText, self.MenuParentPath, self.MenuCallHandler )
end
return self
end
--- Removes a menu structure for a group.
@ -1285,11 +1158,9 @@ do
-- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set.
-- @return #nil
function MENU_GROUP_COMMAND_DELAYED:Remove( MenuStamp, MenuTag )
MENU_INDEX:PrepareGroup( self.Group )
local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText )
local GroupMenu = MENU_INDEX:HasGroupMenu( self.Group, Path )
if GroupMenu == self then
if not MenuStamp or self.MenuStamp ~= MenuStamp then
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
@ -1308,6 +1179,4 @@ do
return self
end
end

View File

@ -2752,7 +2752,7 @@ do -- COORDINATE
return "BR, " .. self:GetBRText( AngleRadians, Distance, Settings )
end
--- Return a BRAA string from a COORDINATE to the COORDINATE.
--- Return a BRA string from a COORDINATE to the COORDINATE.
-- @param #COORDINATE self
-- @param #COORDINATE FromCoordinate The coordinate to measure the distance and the bearing from.
-- @param Core.Settings#SETTINGS Settings (optional) The settings. Can be nil, and in this case the default settings are used. If you want to specify your own settings, use the _SETTINGS object.
@ -2765,7 +2765,7 @@ do -- COORDINATE
return "BRA, " .. self:GetBRAText( AngleRadians, Distance, Settings, Language )
end
--- Create a BRAA NATO call string to this COORDINATE from the FromCOORDINATE.
--- Create a BRAA NATO call string to this COORDINATE from the FromCOORDINATE. Note - BRA delivered if no aspect can be obtained and "Merged" if range < 3nm
-- @param #COORDINATE self
-- @param #COORDINATE FromCoordinate The coordinate to measure the distance and the bearing from.
-- @param #boolean Spades Add "Spades" at the end if true (no IFF/VID ID yet known)
@ -2788,10 +2788,14 @@ do -- COORDINATE
local alt = UTILS.Round(UTILS.MetersToFeet(self.y)/1000,0)--*1000
local track = Utils.BearingToCardinal(bearing)
local track = UTILS.BearingToCardinal(bearing) or "North"
if rangeNM > 3 then
BRAANATO = string.format("BRAA, %s, %d miles, Angels %d, %s, Track %s",bearing, rangeNM, alt, aspect, track)
if aspect == "" then
BRAANATO = string.format("BRA, %03d, %d miles, Angels %d, Track %s",bearing, rangeNM, alt, track)
else
BRAANATO = string.format("BRAA, %03d, %d miles, Angels %d, %s, Track %s",bearing, rangeNM, alt, aspect, track)
end
if Spades then
BRAANATO = BRAANATO..", Spades."
else

View File

@ -1998,6 +1998,18 @@ function ZONE_POLYGON_BASE:IsVec2InZone( Vec2 )
return InPolygon
end
--- Returns if a point is within the zone.
-- @param #ZONE_POLYGON_BASE self
-- @param DCS#Vec3 Vec3 The point to test.
-- @return #boolean true if the point is within the zone.
function ZONE_POLYGON_BASE:IsVec3InZone( Vec3 )
self:F2( Vec3 )
local InZone = self:IsVec2InZone( { x = Vec3.x, y = Vec3.z } )
return InZone
end
--- Define a random @{DCS#Vec2} within the zone.
-- @param #ZONE_POLYGON_BASE self
-- @return DCS#Vec2 The Vec2 coordinate.

View File

@ -3259,9 +3259,9 @@ function AUFTRAG:IsSuccess()
return self.status==AUFTRAG.Status.SUCCESS
end
--- Check if mission is over. This could be state DONE or CANCELLED.
--- Check if mission is over. This could be state DONE, CANCELLED, SUCCESS, FAILED.
-- @param #AUFTRAG self
-- @return #boolean If true, mission is currently executing.
-- @return #boolean If true, mission is over.
function AUFTRAG:IsOver()
local over = self.status==AUFTRAG.Status.DONE or self.status==AUFTRAG.Status.CANCELLED or self.status==AUFTRAG.Status.SUCCESS or self.status==AUFTRAG.Status.FAILED
return over

File diff suppressed because it is too large Load Diff

View File

@ -123,6 +123,7 @@ INTEL = {
-- @field Ops.Target#TARGET target The Target attached to this contact.
-- @field #string recce The name of the recce unit that detected this contact.
-- @field #string ctype Contact type.
-- @field #string platform [AIR] Contact platform name, e.g. Foxbat, Flanker_E, defaults to Bogey if unknown
--- Cluster info.
-- @type INTEL.Cluster
@ -153,7 +154,7 @@ INTEL.Ctype={
--- INTEL class version.
-- @field #string version
INTEL.version="0.3.0"
INTEL.version="0.3.1"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list
@ -866,7 +867,12 @@ function INTEL:_CreateContact(Positionable, RecceName)
item.isground = group:IsGround() or false
item.isship = group:IsShip() or false
item.isStatic=false
if group:IsAir() then
item.platform=group:GetNatoReportingName()
else
-- TODO optionally add ground types?
item.platform="Unknown"
end
if item.category==Group.Category.AIRPLANE or item.category==Group.Category.HELICOPTER then
item.ctype=INTEL.Ctype.AIRCRAFT
elseif item.category==Group.Category.GROUND or item.category==Group.Category.TRAIN then

View File

@ -2038,14 +2038,16 @@ end
-- @param #string Voice Specific voice. Overrides `Gender` and `Culture`.
-- @param #number Port SRS port. Default 5002.
-- @param #string PathToGoogleKey Full path to the google credentials JSON file, e.g. `"C:\Users\myUsername\Downloads\key.json"`.
-- @param #string Label Label of the SRS comms for the SRS Radio overlay. Defaults to "ROBOT". No spaces allowed!
-- @return #OPSGROUP self
function OPSGROUP:SetSRS(PathToSRS, Gender, Culture, Voice, Port, PathToGoogleKey)
function OPSGROUP:SetSRS(PathToSRS, Gender, Culture, Voice, Port, PathToGoogleKey, Label)
self.useSRS=true
self.msrs=MSRS:New(PathToSRS, self.frequency, self.modulation)
self.msrs:SetGender(Gender)
self.msrs:SetCulture(Culture)
self.msrs:SetVoice(Voice)
self.msrs:SetPort(Port)
self.msrs:SetLabel(Label)
if PathToGoogleKey then
self.msrs:SetGoogle(PathToGoogleKey)
end
@ -2058,8 +2060,9 @@ end
-- @param #string Text Text of transmission.
-- @param #number Delay Delay in seconds before the transmission is started.
-- @param #boolean SayCallsign If `true`, the callsign is prepended to the given text. Default `false`.
-- @param #number Frequency Override sender frequency, helpful when you need multiple radios from the same sender. Default is the frequency set for the OpsGroup.
-- @return #OPSGROUP self
function OPSGROUP:RadioTransmission(Text, Delay, SayCallsign)
function OPSGROUP:RadioTransmission(Text, Delay, SayCallsign, Frequency)
if Delay and Delay>0 then
self:ScheduleOnce(Delay, OPSGROUP.RadioTransmission, self, Text, 0, SayCallsign)
@ -2068,8 +2071,12 @@ function OPSGROUP:RadioTransmission(Text, Delay, SayCallsign)
if self.useSRS and self.msrs then
local freq, modu, radioon=self:GetRadio()
self.msrs:SetFrequencies(freq)
if Frequency then
self.msrs:SetFrequencies(Frequency)
else
self.msrs:SetFrequencies(freq)
end
self.msrs:SetModulations(modu)
if SayCallsign then
@ -2078,7 +2085,7 @@ function OPSGROUP:RadioTransmission(Text, Delay, SayCallsign)
end
-- Debug info.
self:T(self.lid..string.format("Radio transmission on %.3f MHz %s: %s", freq, UTILS.GetModulationName(modu), Text))
self:I(self.lid..string.format("Radio transmission on %.3f MHz %s: %s", freq, UTILS.GetModulationName(modu), Text))
self.msrs:PlayText(Text)
end

View File

@ -92,9 +92,15 @@ OPSZONE.version="0.3.0"
--- Create a new OPSZONE class object.
-- @param #OPSZONE self
-- @param Core.Zone#ZONE Zone The zone.
-- @param Core.Zone#ZONE Zone The zone. Needs to be a ZONE\_RADIUS (round) zone. Can be passed as ZONE\_AIRBASE or simply as the name of the airbase.
-- @param #number CoalitionOwner Initial owner of the coaliton. Default `coalition.side.NEUTRAL`.
-- @return #OPSZONE self
-- @usage
-- myopszone = OPSZONE:New(ZONE:FindByName("OpsZoneOne"),coalition.side.RED) -- base zone from the mission editor
-- myopszone = OPSZONE:New(ZONE_RADIUS:New("OpsZoneTwo",mycoordinate:GetVec2(),5000),coalition.side.BLUE) -- radius zone of 5km at a coordinate
-- myopszone = OPSZONE:New(ZONE_RADIUS:New("Batumi")) -- airbase zone from Batumi Airbase, ca 2500m radius
-- myopszone = OPSZONE:New(ZONE_AIRBASE:New("Batumi",6000),coalition.side.BLUE) -- airbase zone from Batumi Airbase, but with a specific radius of 6km
--
function OPSZONE:New(Zone, CoalitionOwner)
-- Inherit everything from LEGION class.

View File

@ -45,6 +45,7 @@
-- @field Core.Point#COORDINATE coordinate Coordinate from where the transmission is send.
-- @field #string path Path to the SRS exe. This includes the final slash "/".
-- @field #string google Full path google credentials JSON file, e.g. "C:\Users\username\Downloads\service-account-file.json".
-- @field #string Label Label showing up on the SRS radio overlay. Default is "ROBOT". No spaces allowed.
-- @extends Core.Base#BASE
--- *It is a very sad thing that nowadays there is so little useless information.* - Oscar Wilde
@ -125,11 +126,12 @@ MSRS = {
volume = 1,
speed = 1,
coordinate = nil,
Label = "ROBOT",
}
--- MSRS class version.
-- @field #string version
MSRS.version="0.0.3"
MSRS.version="0.0.4"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
@ -164,6 +166,7 @@ function MSRS:New(PathToSRS, Frequency, Modulation)
self:SetModulations(Modulation)
self:SetGender()
self:SetCoalition()
self:SetLabel()
return self
end
@ -206,6 +209,22 @@ function MSRS:GetPath()
return self.path
end
--- Set label.
-- @param #MSRS self
-- @param #number Label. Default "ROBOT"
-- @return #MSRS self
function MSRS:SetLabel(Label)
self.Label=Label or "ROBOT"
return self
end
--- Get label.
-- @param #MSRS self
-- @return #number Label.
function MSRS:GetLabel()
return self.Label
end
--- Set port.
-- @param #MSRS self
-- @param #number Port Port. Default 5002.
@ -640,8 +659,9 @@ end
-- @param #number volume Volume.
-- @param #number speed Speed.
-- @param #number port Port.
-- @param #string label Label, defaults to "ROBOT" (displayed sender name in the radio overlay of SRS) - No spaces allowed!
-- @return #string Command.
function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, speed, port)
function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, speed, port,label)
local path=self:GetPath() or STTS.DIRECTORY
local exe=STTS.EXECUTABLE or "DCS-SR-ExternalAudio.exe"
@ -654,6 +674,7 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp
volume=volume or self.volume
speed=speed or self.speed
port=port or self.port
label=label or self.Label
-- Replace modulation
modus=modus:gsub("0", "AM")
@ -668,7 +689,7 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp
--local command=string.format('start /b "" /d "%s" "%s" -f %s -m %s -c %s -p %s -n "%s" > bla.txt', path, exe, freqs, modus, coal, port, "ROBOT")
-- Command.
local command=string.format('"%s\\%s" -f %s -m %s -c %s -p %s -n "%s"', path, exe, freqs, modus, coal, port, "ROBOT")
local command=string.format('"%s\\%s" -f %s -m %s -c %s -p %s -n "%s"', path, exe, freqs, modus, coal, port, label)
-- Set voice or gender/culture.
if voice then

View File

@ -11,7 +11,7 @@
--
-- DCS itself provides a lot of enumerators for various things. See [Enumerators](https://wiki.hoggitworld.com/view/Category:Enumerators) on Hoggit.
--
-- Other Moose classe also have enumerators. For example, the AIRBASE class has enumerators for airbase names.
-- Other Moose classes also have enumerators. For example, the AIRBASE class has enumerators for airbase names.
--
-- @module ENUMS
-- @image MOOSE.JPG
@ -448,4 +448,113 @@ ENUMS.Phonetic =
X = 'Xray',
Y = 'Yankee',
Z = 'Zulu',
}
}
--- Reporting Names (NATO). See the [Wikipedia](https://en.wikipedia.org/wiki/List_of_NATO_reporting_names_for_fighter_aircraft).
-- DCS known aircraft types
--
-- @type ENUMS.ReportingName
ENUMS.ReportingName =
{
NATO = {
-- Fighters
Dragon = "JF-17", -- China, correctly Fierce Dragon, Thunder for PAC
Fagot = "MiG-15",
Farmer = "MiG-19", -- Shenyang J-6 and Mikoyan-Gurevich MiG-19
Felon = "Su-57",
Fencer = "Su-24",
Fishbed = "MiG-21",
Fitter = "Su-17", -- Sukhoi Su-7 and Su-17/Su-20/Su-22
Flogger = "MiG-23", --and MiG-27
Flogger_D = "MiG-27", --and MiG-23
Flagon = "Su-15",
Foxbat = "MiG-25",
Fulcrum = "MiG-29",
Foxhound = "MiG-31",
Flanker = "Su-27", -- Sukhoi Su-27/Su-30/Su-33/Su-35/Su-37 and Shenyang J-11/J-15/J-16
Flanker_C = "Su-30",
Flanker_E = "Su-35",
Flanker_F = "Su-37",
Flanker_L = "J-11A",
Firebird = "J-10",
Sea_Flanker = "Su-33",
Fullback = "Su-34", -- also Su-32
Frogfoot = "Su-25",
Tomcat = "F-14", -- Iran
Mirage = "Mirage", -- various non-NATO
Codling = "Yak-40",
Maya = "L-39",
-- Fighters US/NATO
Warthog = "A-10",
--Mosquito = "A-20",
Skyhawk = "A-4E",
Viggen = "AJS37",
Harrier = "AV-8B",
Spirit = "B-2",
Aviojet = "C-101",
Nighthawk = "F-117A",
Eagle = "F-15C",
Mudhen = "F-15E",
Viper = "F-16",
Phantom = "F-4E",
Tiger = "F-5", -- was thinkg to name this MiG-25 ;)
Sabre = "F-86",
Hornet = "A-18", -- avoiding the slash
Hawk = "Hawk",
Albatros = "L-39",
Goshawk = "T-45",
Starfighter = "F-104",
Tornado = "Tornado",
-- Transport / Bomber / Others
Atlas = "A400",
Lancer = "B1-B",
Stratofortress = "B-52H",
Hercules = "C-130", -- modded version has type name "Hercules", unfortunately
Globemaster = "C-17",
Greyhound = "C-2A",
Galaxy = "C-5",
Hawkexe = "E-2D",
Sentry = "E-3A",
Stratotanker = "KC-135",
Extender = "KC-10",
Orion = "P-3C",
Viking = "S-3B",
Osprey = "V-22",
-- Bomber Rus
Badger = "H6-J",
Bear_J = "Tu-142", -- also Tu-95
Bear = "Tu-95", -- also Tu-142
Blinder = "Tu-22",
Blackjack = "Tu-160",
-- AIC / Transport / Other
Clank = "An-30",
Curl = "An-26",
Candid = "IL-76",
Midas = "IL-78",
Mainstay = "A-50",
Mainring = "KJ-2000", -- A-50 China
Yak = "Yak-52",
-- Helos
Helix = "Ka-27",
Shark = "Ka-50",
Hind = "Mi-24",
Halo = "Mi-26",
Hip = "Mi-8",
Havoc = "Mi-28",
Gazelle = "SA342",
-- Helos US
Huey = "UH-1H",
Cobra = "AH-1",
Apache = "AH-64",
Chinook = "CH-47",
Sea_Stallion = "CH-53",
Kiowa = "OH-58",
Seahawk = "SH-60",
Blackhawk = "UH-60",
Sea_King = "S-61",
-- Drones
UCAV = "WingLoong",
Reaper = "MQ-9",
Predator = "MQ-1A",
}
}

View File

@ -38,7 +38,7 @@ do
FIFO = {
ClassName = "FIFO",
lid = "",
version = "0.0.3",
version = "0.0.5",
counter = 0,
pointer = 0,
stackbypointer = {},
@ -141,7 +141,11 @@ function FIFO:ReadByPointer(Pointer)
self:T(self.lid.."ReadByPointer " .. tostring(Pointer))
if self.counter == 0 or not Pointer or not self.stackbypointer[Pointer] then return nil end
local object = self.stackbypointer[Pointer] -- #FIFO.IDEntry
return object.data
if object then
return object.data
else
return nil
end
end
--- FIFO Read, not Pull, Object from Stack by UniqueID
@ -152,7 +156,11 @@ function FIFO:ReadByID(UniqueID)
self:T(self.lid.."ReadByID " .. tostring(UniqueID))
if self.counter == 0 or not UniqueID or not self.stackbyid[UniqueID] then return nil end
local object = self.stackbyid[UniqueID] -- #FIFO.IDEntry
return object.data
if object then
return object.data
else
return nil
end
end
--- FIFO Pull Object from Stack by UniqueID
@ -164,7 +172,11 @@ function FIFO:PullByID(UniqueID)
if self.counter == 0 then return nil end
local object = self.stackbyid[UniqueID] -- #FIFO.IDEntry
--self.stackbyid[UniqueID] = nil
return self:PullByPointer(object.pointer)
if object then
return self:PullByPointer(object.pointer)
else
return nil
end
end
--- FIFO Housekeeping
@ -410,7 +422,7 @@ do
LIFO = {
ClassName = "LIFO",
lid = "",
version = "0.0.2",
version = "0.0.5",
counter = 0,
pointer = 0,
stackbypointer = {},
@ -512,7 +524,11 @@ function LIFO:ReadByPointer(Pointer)
self:T(self.lid.."ReadByPointer " .. tostring(Pointer))
if self.counter == 0 or not Pointer or not self.stackbypointer[Pointer] then return nil end
local object = self.stackbypointer[Pointer] -- #LIFO.IDEntry
return object.data
if object then
return object.data
else
return nil
end
end
--- LIFO Read, not Pull, Object from Stack by UniqueID
@ -523,7 +539,11 @@ function LIFO:ReadByID(UniqueID)
self:T(self.lid.."ReadByID " .. tostring(UniqueID))
if self.counter == 0 or not UniqueID or not self.stackbyid[UniqueID] then return nil end
local object = self.stackbyid[UniqueID] -- #LIFO.IDEntry
return object.data
if object then
return object.data
else
return nil
end
end
--- LIFO Pull Object from Stack by UniqueID
@ -535,7 +555,11 @@ function LIFO:PullByID(UniqueID)
if self.counter == 0 then return nil end
local object = self.stackbyid[UniqueID] -- #LIFO.IDEntry
--self.stackbyid[UniqueID] = nil
return self:PullByPointer(object.pointer)
if object then
return self:PullByPointer(object.pointer)
else
return nil
end
end
--- LIFO Housekeeping

View File

@ -1447,6 +1447,23 @@ function UTILS.GetModulationName(Modulation)
end
--- Get the NATO reporting name of a unit type name
-- @param #number Typename The type name.
-- @return #string The Reporting name or "Bogey".
function UTILS.GetReportingName(Typename)
local typename = string.lower(Typename)
for name, value in pairs(ENUMS.ReportingName.NATO) do
local svalue = string.lower(value)
if string.find(typename,svalue,1,true) then
return name
end
end
return "Bogey"
end
--- Get the callsign name from its enumerator value
-- @param #number Callsign The enumerator callsign.
-- @return #string The callsign name or "Ghostrider".
@ -2436,7 +2453,11 @@ function UTILS.ToStringBRAANATO(FromGrp,ToGrp)
local alt = UTILS.Round(UTILS.MetersToFeet(grpLeadUnit:GetAltitude())/1000,0)--*1000
local track = UTILS.BearingToCardinal(hdg)
if rangeNM > 3 then
BRAANATO = string.format("%s, BRAA, %s, %d miles, Angels %d, %s, Track %s, Spades.",GroupWords,bearing, rangeNM, alt, aspect, track)
if aspect == "" then
BRAANATO = string.format("%s, BRA, %03d, %d miles, Angels %d, Track %s",GroupWords,bearing, rangeNM, alt, track)
else
BRAANATO = string.format("%s, BRAA, %03d, %d miles, Angels %d, %s, Track %s",GroupWords, bearing, rangeNM, alt, aspect, track)
end
end
return BRAANATO
end

View File

@ -805,11 +805,19 @@ function GROUP:GetVelocityVec3()
return nil
end
--- Returns the average group altitude in meters.
-- @param Wrapper.Group#GROUP self
-- @param #boolean FromGround Measure from the ground or from sea level (ASL). Provide **true** for measuring from the ground (AGL). **false** or **nil** if you measure from sea level.
-- @return #number The altitude of the group or nil if is not existing or alive.
function GROUP:GetAltitude(FromGround)
self:F2( self.GroupName )
return self:GetHeight(FromGround)
end
--- Returns the average group height in meters.
-- @param Wrapper.Group#GROUP self
-- @param #boolean FromGround Measure from the ground or from sea level. Provide **true** for measuring from the ground. **false** or **nil** if you measure from sea level.
-- @return DCS#Vec3 The height of the group or nil if is not existing or alive.
-- @param #boolean FromGround Measure from the ground or from sea level (ASL). Provide **true** for measuring from the ground (AGL). **false** or **nil** if you measure from sea level.
-- @return #number The height of the group or nil if is not existing or alive.
function GROUP:GetHeight( FromGround )
self:F2( self.GroupName )
@ -909,6 +917,24 @@ function GROUP:GetTypeName()
return nil
end
--- [AIRPLANE] Get the NATO reporting name (platform, e.g. "Flanker") of a GROUP (note - first unit the group). "Bogey" if not found. Currently airplanes only!
--@param #GROUP self
--@return #string NatoReportingName or "Bogey" if unknown.
function GROUP:GetNatoReportingName()
self:F2( self.GroupName )
local DCSGroup = self:GetDCSObject()
if DCSGroup then
local GroupTypeName = DCSGroup:getUnit(1):getTypeName()
self:T3( GroupTypeName )
return UTILS.GetReportingName(GroupTypeName)
end
return "Bogey"
end
--- Gets the player name of the group.
-- @param #GROUP self
-- @return #string The player name of the group.
@ -1006,6 +1032,8 @@ function GROUP:GetCoordinate()
if FirstUnit then
local FirstUnitCoordinate = FirstUnit:GetCoordinate()
local Heading = self:GetHeading()
FirstUnitCoordinate.Heading = Heading
return FirstUnitCoordinate
end
@ -1068,7 +1096,7 @@ end
-- amount of fuel in the group.
-- @param #GROUP self
-- @return #number The fuel state of the unit with the least amount of fuel.
-- @return #Unit reference to #Unit object for further processing.
-- @return Wrapper.Unit#UNIT reference to #Unit object for further processing.
function GROUP:GetFuelMin()
self:F3(self.ControllableName)

View File

@ -376,7 +376,8 @@ function POSITIONABLE:GetCoordinate()
local PositionableVec3 = self:GetVec3()
local coord=COORDINATE:NewFromVec3(PositionableVec3)
local heading = self:GetHeading()
coord.Heading = heading
-- Return a new coordiante object.
return coord

View File

@ -408,6 +408,17 @@ function UNIT:GetClient()
return nil
end
--- [AIRPLANE] Get the NATO reporting name of a UNIT. Currently airplanes only!
--@param #UNIT self
--@return #string NatoReportingName or "Bogey" if unknown.
function UNIT:GetNatoReportingName()
local typename = self:GetTypeName()
return UTILS.GetReportingName(typename)
end
--- Returns the unit's number in the group.
-- The number is the same number the unit has in ME.
-- It may not be changed during the mission.