From dd588389838377cf2cba8094028af628f7527ea1 Mon Sep 17 00:00:00 2001 From: FlightControl_Master Date: Wed, 22 Nov 2017 06:22:36 +0100 Subject: [PATCH] * Rewritten the complete menu mechanism. * SetRemoveParent method on menus removed, made obsolete, to avoid menus being deleted that should not. * A2G reports now work again, and improved the reporting for successful or failed tasks. * Removed MENU_CLIENT and MENU_CLIENT_COMMAND * Improved the detection of new spawned groups within the TASK_A2G_DISPATCHER. * Improved how new detections and new target sets are reported and followed-up within the TASK_A2G mechanism. Pending: Improve the TASK_A2A_DISPATCHER and TASK_A2A mechanisms. --- Moose Development/Moose/AI/AI_Formation.lua | 1 - Moose Development/Moose/Core/Menu.lua | 813 ++++++++---------- .../Moose/Functional/Detection.lua | 9 +- Moose Development/Moose/Functional/Escort.lua | 101 ++- .../Moose/Functional/MissileTrainer.lua | 56 +- Moose Development/Moose/Tasking/Task.lua | 18 +- Moose Development/Moose/Tasking/Task_A2G.lua | 248 ++---- .../Moose/Tasking/Task_A2G_Dispatcher.lua | 2 +- Moose Mission Setup/Moose.lua | 2 +- Moose Mission Setup/Moose_.lua | 2 +- 10 files changed, 515 insertions(+), 737 deletions(-) diff --git a/Moose Development/Moose/AI/AI_Formation.lua b/Moose Development/Moose/AI/AI_Formation.lua index cc2dafad9..3b2012710 100644 --- a/Moose Development/Moose/AI/AI_Formation.lua +++ b/Moose Development/Moose/AI/AI_Formation.lua @@ -66,7 +66,6 @@ -- @field #boolean ReportTargets If true, nearby targets are reported. -- @Field DCSTypes#AI.Option.Air.val.ROE OptionROE Which ROE is set to the FollowGroup. -- @field DCSTypes#AI.Option.Air.val.REACTION_ON_THREAT OptionReactionOnThreat Which REACTION_ON_THREAT is set to the FollowGroup. --- @field Menu#MENU_CLIENT FollowMenuResumeMission --- # AI_FORMATION class, extends @{Fsm#FSM_SET} diff --git a/Moose Development/Moose/Core/Menu.lua b/Moose Development/Moose/Core/Menu.lua index 4faaa5507..900a65a5f 100644 --- a/Moose Development/Moose/Core/Menu.lua +++ b/Moose Development/Moose/Core/Menu.lua @@ -16,14 +16,12 @@ -- * @{Menu#MENU_MISSION}: Manages main menus for whole mission file. -- * @{Menu#MENU_COALITION}: Manages main menus for whole coalition. -- * @{Menu#MENU_GROUP}: Manages main menus for GROUPs. --- * @{Menu#MENU_CLIENT}: Manages main menus for CLIENTs. This manages menus for units with the skill level "Client". -- -- ### To manage **command menus**, which are menus that allow the player to issue **functions**, the classes begin with **MENU_COMMAND_**: -- -- * @{Menu#MENU_MISSION_COMMAND}: Manages command menus for whole mission file. -- * @{Menu#MENU_COALITION_COMMAND}: Manages command menus for whole coalition. -- * @{Menu#MENU_GROUP_COMMAND}: Manages command menus for GROUPs. --- * @{Menu#MENU_CLIENT_COMMAND}: Manages command menus for CLIENTs. This manages menus for units with the skill level "Client". -- -- === --- @@ -35,6 +33,124 @@ -- @module Menu +MENU_INDEX = {} +MENU_INDEX.MenuMission = {} +MENU_INDEX.MenuMission.Menus = {} +MENU_INDEX.Coalition = {} +MENU_INDEX.Coalition[coalition.side.BLUE] = {} +MENU_INDEX.Coalition[coalition.side.BLUE].Menus = {} +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 BASE:IsInstanceOf( "MENU_GROUP" ) or BASE:IsInstanceOf( "MENU_GROUP_COMMAND" ) then + local GroupName = ParentMenu.Group:GetName() + if not self.Group[GroupName].Menus[Path] then + BASE:E( { Path = Path, GroupName = GroupName } ) + error( "Parent path not found in menu index for group menu" ) + return nil + end + elseif BASE:IsInstanceOf( "MENU_COALITION" ) or BASE:IsInstanceOf( "MENU_COALITION_COMMAND" ) then + local Coalition = ParentMenu.Coalition + if not self.Coalition[Coalition].Menus[Path] then + BASE:E( { Path = Path, Coalition = Coalition } ) + error( "Parent path not found in menu index for coalition menu" ) + return nil + end + elseif BASE:IsInstanceOf( "MENU_MISSION" ) or BASE:IsInstanceOf( "MENU_MISSION_COMMAND" ) then + if not self.MenuMission.Menus[Path] then + BASE:E( { Path = Path } ) + error( "Parent path not found in menu index for mission menu" ) + return nil + end + end + end + + 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 + + +function MENU_INDEX:PrepareGroup( Group ) + local GroupName = Group:GetName() + self.Group[GroupName] = self.Group[GroupName] or {} + self.Group[GroupName].Menus = self.Group[GroupName].Menus or {} +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 ) + + local MenuGroupName = Group:GetName() + return self.Group[MenuGroupName].Menus[Path] +end + +function MENU_INDEX:SetGroupMenu( Group, Path, Menu ) + + local MenuGroupName = Group:GetName() + self.Group[MenuGroupName].Menus[Path] = Menu +end + +function MENU_INDEX:ClearGroupMenu( Group, Path ) + + local MenuGroupName = Group:GetName() + self.Group[MenuGroupName].Menus[Path] = nil +end + + + do -- MENU_BASE --- @type MENU_BASE @@ -65,35 +181,42 @@ do -- MENU_BASE 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.MenuRemoveParent = false self.MenuTime = timer.getTime() + if self.ParentMenu then + self.ParentMenu.Menus = self.ParentMenu.Menus or {} + self.ParentMenu.Menus[MenuText] = self + end + return self end + + function MENU_BASE:SetParentMenu( MenuText, Menu ) + if self.ParentMenu then + self.ParentMenu.Menus = self.ParentMenu.Menus or {} + self.ParentMenu.Menus[MenuText] = Menu + end + end + + function MENU_BASE:ClearParentMenu( MenuText ) + if self.ParentMenu and self.ParentMenu.Menus[MenuText] then + self.ParentMenu.Menus[MenuText] = nil + end + end --- Gets a @{Menu} from a parent @{Menu} -- @param #MENU_BASE self -- @param #string MenuText The text of the child menu. -- @return #MENU_BASE function MENU_BASE:GetMenu( MenuText ) - self:F2( { Menu = self.Menus[MenuText] } ) return self.Menus[MenuText] 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}. - -- @return #MENU_BASE - function MENU_BASE:SetRemoveParent( RemoveParent ) - self:F2( { RemoveParent } ) - self.MenuRemoveParent = RemoveParent - return self - end - - --- Sets a time stamp for later prevention of menu removal. -- @param #MENU_BASE self -- @param MenuTime @@ -158,7 +281,7 @@ do -- MENU_COMMAND_BASE end local Status, Result = xpcall( MenuFunction, ErrorHandler ) end - + return self end @@ -209,55 +332,62 @@ do -- MENU_MISSION -- @return #MENU_MISSION function MENU_MISSION:New( MenuText, ParentMenu ) - local self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) ) - - self:F( { MenuText, ParentMenu } ) - - self.MenuText = MenuText - self.ParentMenu = ParentMenu - - self.Menus = {} - - self:T( { MenuText } ) - - self.MenuPath = missionCommands.addSubMenu( MenuText, self.MenuParentPath ) - - self:T( { self.MenuPath } ) - - if ParentMenu and ParentMenu.Menus then - ParentMenu.Menus[self.MenuPath] = self - end + MENU_INDEX:PrepareMission() + local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText ) + local MissionMenu = MENU_INDEX:HasMissionMenu( Path ) - return self + if MissionMenu then + return MissionMenu + else + local self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) ) + MENU_INDEX:SetMissionMenu( Path, self ) + + self.MenuPath = missionCommands.addSubMenu( MenuText, self.MenuParentPath ) + self:SetParentMenu( self.MenuText, self ) + return self + end + end --- Removes the sub menus recursively of this MENU_MISSION. Note that the main menu is kept! -- @param #MENU_MISSION self -- @return #MENU_MISSION function MENU_MISSION:RemoveSubMenus() - self:F( self.MenuPath ) - for MenuID, Menu in pairs( self.Menus ) do + for MenuID, Menu in pairs( self.Menus or {} ) do Menu:Remove() end + + self.Menus = nil end --- Removes the main menu and the sub menus recursively of this MENU_MISSION. -- @param #MENU_MISSION self -- @return #nil - function MENU_MISSION:Remove() - self:F( self.MenuPath ) + function MENU_MISSION:Remove( MenuTime, MenuTag ) - self:RemoveSubMenus() - missionCommands.removeItem( self.MenuPath ) - if self.ParentMenu then - self.ParentMenu.Menus[self.MenuPath] = nil + 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 MenuTime or self.MenuTime ~= MenuTime then + if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then + missionCommands.removeItem( self.MenuPath ) + MENU_INDEX:ClearMissionMenu( self.Path ) + self:ClearParentMenu( self.MenuText ) + return nil + end + end end - return nil + return self end + + end do -- MENU_MISSION_COMMAND @@ -285,32 +415,45 @@ do -- MENU_MISSION_COMMAND -- @return #MENU_MISSION_COMMAND self function MENU_MISSION_COMMAND:New( MenuText, ParentMenu, CommandMenuFunction, ... ) - local self = BASE:Inherit( self, MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, arg ) ) - - self.MenuText = MenuText - self.ParentMenu = ParentMenu - - self:T( { MenuText, CommandMenuFunction, arg } ) - - - self.MenuPath = missionCommands.addCommand( MenuText, self.MenuParentPath, self.MenuCallHandler ) - - ParentMenu.Menus[self.MenuPath] = self - - return self + 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 ) + return MissionMenu + else + local self = BASE:Inherit( self, MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, arg ) ) + MENU_INDEX:SetMissionMenu( Path, self ) + + self.MenuPath = missionCommands.addCommand( MenuText, self.MenuParentPath, self.MenuCallHandler ) + self:SetParentMenu( self.MenuText, self ) + return self + end end --- Removes a radio command item for a coalition -- @param #MENU_MISSION_COMMAND self -- @return #nil function MENU_MISSION_COMMAND:Remove() - self:F( self.MenuPath ) - missionCommands.removeItem( self.MenuPath ) - if self.ParentMenu then - self.ParentMenu.Menus[self.MenuPath] = nil + MENU_INDEX:PrepareMission() + local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText ) + local MissionMenu = MENU_INDEX:HasMissionMenu( Path ) + + if MissionMenu == self then + if not MenuTime or self.MenuTime ~= MenuTime then + if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then + missionCommands.removeItem( self.MenuPath ) + MENU_INDEX:ClearMissionMenu( self.Path ) + self:ClearParentMenu( self.MenuText ) + return nil + end + end end - return nil + + return self end end @@ -378,59 +521,66 @@ do -- MENU_COALITION -- @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). -- @return #MENU_COALITION self function MENU_COALITION:New( Coalition, MenuText, ParentMenu ) - - local self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) ) - - self:F( { Coalition, MenuText, ParentMenu } ) - - self.Coalition = Coalition - self.MenuText = MenuText - self.ParentMenu = ParentMenu - - self.Menus = {} - - self:T( { MenuText } ) - - self.MenuPath = missionCommands.addSubMenuForCoalition( Coalition, MenuText, self.MenuParentPath ) - - self:T( { self.MenuPath } ) - - if ParentMenu and ParentMenu.Menus then - ParentMenu.Menus[self.MenuPath] = self - end - return self + 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 ) + + self.Coalition = Coalition + + self.MenuPath = missionCommands.addSubMenuForCoalition( Coalition, MenuText, self.MenuParentPath ) + self:SetParentMenu( self.MenuText, self ) + return self + end end --- Removes the sub menus recursively of this MENU_COALITION. Note that the main menu is kept! -- @param #MENU_COALITION self -- @return #MENU_COALITION function MENU_COALITION:RemoveSubMenus() - self:F( self.MenuPath ) - for MenuID, Menu in pairs( self.Menus ) do + for MenuID, Menu in pairs( self.Menus or {} ) do Menu:Remove() end - + + self.Menus = nil end --- Removes the main menu and the sub menus recursively of this MENU_COALITION. -- @param #MENU_COALITION self -- @return #nil - function MENU_COALITION:Remove() - self:F( self.MenuPath ) + function MENU_COALITION:Remove( MenuTime, MenuTag ) - self:RemoveSubMenus() - missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath ) - if self.ParentMenu then - self.ParentMenu.Menus[self.MenuPath] = nil + 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 MenuTime or self.MenuTime ~= MenuTime then + if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then + missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath ) + MENU_INDEX:ClearCoalitionMenu( self.Coalition, Path ) + self:ClearParentMenu( self.MenuText ) + return nil + end + end end - return nil + return self end end + + do -- MENU_COALITION_COMMAND --- @type MENU_COALITION_COMMAND @@ -457,279 +607,53 @@ do -- MENU_COALITION_COMMAND -- @return #MENU_COALITION_COMMAND function MENU_COALITION_COMMAND:New( Coalition, MenuText, ParentMenu, CommandMenuFunction, ... ) - local self = BASE:Inherit( self, MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, arg ) ) - - self.MenuCoalition = Coalition - self.MenuText = MenuText - self.ParentMenu = ParentMenu + 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 ) + return CoalitionMenu + else - self:T( { MenuText, CommandMenuFunction, arg } ) - - - self.MenuPath = missionCommands.addCommandForCoalition( self.MenuCoalition, MenuText, self.MenuParentPath, self.MenuCallHandler ) - - ParentMenu.Menus[self.MenuPath] = self - - return self + local self = BASE:Inherit( self, MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, arg ) ) + MENU_INDEX:SetCoalitionMenu( Coalition, Path, self ) + + self.Coalition = Coalition + self.MenuPath = missionCommands.addCommandForCoalition( self.Coalition, MenuText, self.MenuParentPath, self.MenuCallHandler ) + self:SetParentMenu( self.MenuText, self ) + return self + end + end --- Removes a radio command item for a coalition -- @param #MENU_COALITION_COMMAND self -- @return #nil - function MENU_COALITION_COMMAND:Remove() - self:F( self.MenuPath ) + function MENU_COALITION_COMMAND:Remove( MenuTime, MenuTag ) - missionCommands.removeItemForCoalition( self.MenuCoalition, self.MenuPath ) - if self.ParentMenu then - self.ParentMenu.Menus[self.MenuPath] = nil + 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 MenuTime or self.MenuTime ~= MenuTime then + if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then + missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath ) + MENU_INDEX:ClearCoalitionMenu( self.Coalition, Path ) + self:ClearParentMenu( self.MenuText ) + return nil + end + end end - return nil + + return self end end -do -- MENU_CLIENT - - -- This local variable is used to cache the menus registered under clients. - -- Menus don't dissapear when clients 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 _MENUCLIENTS = {} - - --- MENU_COALITION constructor. Creates a new radio command item for a coalition, which can invoke a function with parameters. - -- @type MENU_CLIENT - -- @extends Core.Menu#MENU_BASE - - - --- # MENU_CLIENT class, extends @{Menu#MENU_BASE} - -- - -- The MENU_CLIENT class manages the main menus for coalitions. - -- You can add menus with the @{#MENU_CLIENT.New} method, which constructs a MENU_CLIENT object and returns you the object reference. - -- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_CLIENT.Remove}. - -- - -- @usage - -- -- This demo creates a menu structure for the two clients of planes. - -- -- Each client will receive a different menu structure. - -- -- To test, join the planes, then look at the other radio menus (Option F10). - -- -- Then switch planes and check if the menu is still there. - -- -- And play with the Add and Remove menu options. - -- - -- -- Note that in multi player, this will only work after the DCS clients bug is solved. - -- - -- local function ShowStatus( PlaneClient, StatusText, Coalition ) - -- - -- MESSAGE:New( Coalition, 15 ):ToRed() - -- PlaneClient:Message( StatusText, 15 ) - -- end - -- - -- local MenuStatus = {} - -- - -- local function RemoveStatusMenu( MenuClient ) - -- local MenuClientName = MenuClient:GetName() - -- MenuStatus[MenuClientName]:Remove() - -- end - -- - -- --- @param Wrapper.Client#CLIENT MenuClient - -- local function AddStatusMenu( MenuClient ) - -- local MenuClientName = MenuClient:GetName() - -- -- This would create a menu for the red coalition under the MenuCoalitionRed menu object. - -- MenuStatus[MenuClientName] = MENU_CLIENT:New( MenuClient, "Status for Planes" ) - -- MENU_CLIENT_COMMAND:New( MenuClient, "Show Status", MenuStatus[MenuClientName], ShowStatus, MenuClient, "Status of planes is ok!", "Message to Red Coalition" ) - -- end - -- - -- SCHEDULER:New( nil, - -- function() - -- local PlaneClient = CLIENT:FindByName( "Plane 1" ) - -- if PlaneClient and PlaneClient:IsAlive() then - -- local MenuManage = MENU_CLIENT:New( PlaneClient, "Manage Menus" ) - -- MENU_CLIENT_COMMAND:New( PlaneClient, "Add Status Menu Plane 1", MenuManage, AddStatusMenu, PlaneClient ) - -- MENU_CLIENT_COMMAND:New( PlaneClient, "Remove Status Menu Plane 1", MenuManage, RemoveStatusMenu, PlaneClient ) - -- end - -- end, {}, 10, 10 ) - -- - -- SCHEDULER:New( nil, - -- function() - -- local PlaneClient = CLIENT:FindByName( "Plane 2" ) - -- if PlaneClient and PlaneClient:IsAlive() then - -- local MenuManage = MENU_CLIENT:New( PlaneClient, "Manage Menus" ) - -- MENU_CLIENT_COMMAND:New( PlaneClient, "Add Status Menu Plane 2", MenuManage, AddStatusMenu, PlaneClient ) - -- MENU_CLIENT_COMMAND:New( PlaneClient, "Remove Status Menu Plane 2", MenuManage, RemoveStatusMenu, PlaneClient ) - -- end - -- end, {}, 10, 10 ) - -- - -- @field #MENU_CLIENT - MENU_CLIENT = { - ClassName = "MENU_CLIENT" - } - - --- MENU_CLIENT constructor. Creates a new radio menu item for a client. - -- @param #MENU_CLIENT self - -- @param Wrapper.Client#CLIENT Client The Client owning the menu. - -- @param #string MenuText The text for the menu. - -- @param #table ParentMenu The parent menu. - -- @return #MENU_CLIENT self - function MENU_CLIENT:New( Client, MenuText, ParentMenu ) - - -- Arrange meta tables - local MenuParentPath = {} - if ParentMenu ~= nil then - MenuParentPath = ParentMenu.MenuPath - end - - local self = BASE:Inherit( self, MENU_BASE:New( MenuText, MenuParentPath ) ) - self:F( { Client, MenuText, ParentMenu } ) - - self.MenuClient = Client - self.MenuClientGroupID = Client:GetClientGroupID() - self.MenuParentPath = MenuParentPath - self.MenuText = MenuText - self.ParentMenu = ParentMenu - - self.Menus = {} - - if not _MENUCLIENTS[self.MenuClientGroupID] then - _MENUCLIENTS[self.MenuClientGroupID] = {} - end - - local MenuPath = _MENUCLIENTS[self.MenuClientGroupID] - - self:T( { Client:GetClientGroupName(), MenuPath[table.concat(MenuParentPath)], MenuParentPath, MenuText } ) - - local MenuPathID = table.concat(MenuParentPath) .. "/" .. MenuText - if MenuPath[MenuPathID] then - missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), MenuPath[MenuPathID] ) - end - - self.MenuPath = missionCommands.addSubMenuForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath ) - MenuPath[MenuPathID] = self.MenuPath - - self:T( { Client:GetClientGroupName(), self.MenuPath } ) - - if ParentMenu and ParentMenu.Menus then - ParentMenu.Menus[self.MenuPath] = self - end - return self - end - - --- Removes the sub menus recursively of this @{#MENU_CLIENT}. - -- @param #MENU_CLIENT self - -- @return #MENU_CLIENT self - function MENU_CLIENT:RemoveSubMenus() - self:F( self.MenuPath ) - - for MenuID, Menu in pairs( self.Menus ) do - Menu:Remove() - end - - end - - --- Removes the sub menus recursively of this MENU_CLIENT. - -- @param #MENU_CLIENT self - -- @return #nil - function MENU_CLIENT:Remove() - self:F( self.MenuPath ) - - self:RemoveSubMenus() - - if not _MENUCLIENTS[self.MenuClientGroupID] then - _MENUCLIENTS[self.MenuClientGroupID] = {} - end - - local MenuPath = _MENUCLIENTS[self.MenuClientGroupID] - - if MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] then - MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] = nil - end - - missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), self.MenuPath ) - self.ParentMenu.Menus[self.MenuPath] = nil - return nil - end - - - --- @type MENU_CLIENT_COMMAND - -- @extends Core.Menu#MENU_COMMAND - - --- # MENU_CLIENT_COMMAND class, extends @{Menu#MENU_COMMAND_BASE} - -- - -- The MENU_CLIENT_COMMAND class manages the command menus for coalitions, which allow players to execute functions during mission execution. - -- You can add menus with the @{#MENU_CLIENT_COMMAND.New} method, which constructs a MENU_CLIENT_COMMAND object and returns you the object reference. - -- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_CLIENT_COMMAND.Remove}. - -- - -- @field #MENU_CLIENT_COMMAND - MENU_CLIENT_COMMAND = { - ClassName = "MENU_CLIENT_COMMAND" - } - - --- MENU_CLIENT_COMMAND constructor. Creates a new radio command item for a client, which can invoke a function with parameters. - -- @param #MENU_CLIENT_COMMAND self - -- @param Wrapper.Client#CLIENT Client The Client owning the menu. - -- @param #string MenuText The text for the menu. - -- @param #MENU_BASE ParentMenu The parent menu. - -- @param CommandMenuFunction A function that is called when the menu key is pressed. - -- @return Menu#MENU_CLIENT_COMMAND self - function MENU_CLIENT_COMMAND:New( Client, MenuText, ParentMenu, CommandMenuFunction, ... ) - - -- Arrange meta tables - - local MenuParentPath = {} - if ParentMenu ~= nil then - MenuParentPath = ParentMenu.MenuPath - end - - local self = BASE:Inherit( self, MENU_COMMAND_BASE:New( MenuText, MenuParentPath, CommandMenuFunction, arg ) ) -- Menu#MENU_CLIENT_COMMAND - - self.MenuClient = Client - self.MenuClientGroupID = Client:GetClientGroupID() - self.MenuParentPath = MenuParentPath - self.MenuText = MenuText - self.ParentMenu = ParentMenu - - if not _MENUCLIENTS[self.MenuClientGroupID] then - _MENUCLIENTS[self.MenuClientGroupID] = {} - end - - local MenuPath = _MENUCLIENTS[self.MenuClientGroupID] - - self:T( { Client:GetClientGroupName(), MenuPath[table.concat(MenuParentPath)], MenuParentPath, MenuText, CommandMenuFunction, arg } ) - - local MenuPathID = table.concat(MenuParentPath) .. "/" .. MenuText - if MenuPath[MenuPathID] then - missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), MenuPath[MenuPathID] ) - end - - self.MenuPath = missionCommands.addCommandForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath, self.MenuCallHandler ) - MenuPath[MenuPathID] = self.MenuPath - - if ParentMenu and ParentMenu.Menus then - ParentMenu.Menus[self.MenuPath] = self - end - - return self - end - - --- Removes a menu structure for a client. - -- @param #MENU_CLIENT_COMMAND self - -- @return #nil - function MENU_CLIENT_COMMAND:Remove() - self:F( self.MenuPath ) - - if not _MENUCLIENTS[self.MenuClientGroupID] then - _MENUCLIENTS[self.MenuClientGroupID] = {} - end - - local MenuPath = _MENUCLIENTS[self.MenuClientGroupID] - - if MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] then - MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] = nil - end - - missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), self.MenuPath ) - self.ParentMenu.Menus[self.MenuPath] = nil - return nil - end -end --- MENU_GROUP @@ -808,44 +732,30 @@ do --- MENU_GROUP constructor. Creates a new radio menu item for a group. -- @param #MENU_GROUP self - -- @param Wrapper.Group#GROUP MenuGroup The Group owning the menu. + -- @param Wrapper.Group#GROUP Group The Group owning the menu. -- @param #string MenuText The text for the menu. -- @param #table ParentMenu The parent menu. -- @return #MENU_GROUP self - function MENU_GROUP:New( MenuGroup, MenuText, ParentMenu ) + function MENU_GROUP:New( Group, MenuText, ParentMenu ) - -- Determine if the menu was not already created and already visible at the group. - -- If it is visible, then return the cached self, otherwise, create self and cache it. - - MenuGroup._Menus = MenuGroup._Menus or {} - local Path = ( ParentMenu and ( table.concat( ParentMenu.MenuPath or {}, "@" ) .. "@" .. MenuText ) ) or MenuText - if MenuGroup._Menus[Path] then - self = MenuGroup._Menus[Path] + 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 ) ) - --if MenuGroup:IsAlive() then - MenuGroup._Menus[Path] = self - --end + MENU_INDEX:SetGroupMenu( Group, Path, self ) - self.MenuGroup = MenuGroup - self.Path = Path - self.MenuGroupID = MenuGroup:GetID() - self.MenuText = MenuText - self.ParentMenu = ParentMenu + self.Group = Group + self.GroupID = Group:GetID() - self:T( { "Adding Menu ", MenuText, self.MenuParentPath } ) - self.MenuPath = missionCommands.addSubMenuForGroup( self.MenuGroupID, MenuText, self.MenuParentPath ) - - if self.ParentMenu and self.ParentMenu.Menus then - self.ParentMenu.Menus[MenuText] = self - self:F( { self.ParentMenu.Menus, MenuText } ) - self.ParentMenu.MenuCount = self.ParentMenu.MenuCount + 1 - end + self.MenuPath = missionCommands.addSubMenuForGroup( self.GroupID, MenuText, self.MenuParentPath ) + self:SetParentMenu( self.MenuText, self ) + return self end - --self:F( { MenuGroup:GetName(), MenuText, ParentMenu.MenuPath } ) - - return self end --- Removes the sub menus recursively of this MENU_GROUP. @@ -854,12 +764,12 @@ 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( MenuTime, MenuTag ) - --self:F2( { self.MenuPath, MenuTime, self.MenuTime } ) - - self:T( { "Removing Group SubMenus:", MenuTime, MenuTag, self.MenuGroup:GetName(), self.MenuPath } ) - for MenuText, Menu in pairs( self.Menus ) do + + for MenuText, Menu in pairs( self.Menus or {} ) do Menu:Remove( MenuTime, MenuTag ) end + + self.Menus = nil end @@ -870,34 +780,27 @@ do -- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set. -- @return #nil function MENU_GROUP:Remove( MenuTime, MenuTag ) - --self:F2( { self.MenuGroupID, self.MenuPath, MenuTime, self.MenuTime } ) - - self:RemoveSubMenus( MenuTime, MenuTag ) - - if not MenuTime or self.MenuTime ~= MenuTime then - if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then - if self.MenuGroup._Menus[self.Path] then - self = self.MenuGroup._Menus[self.Path] - - missionCommands.removeItemForGroup( self.MenuGroupID, self.MenuPath ) - if self.ParentMenu then - self.ParentMenu.Menus[self.MenuText] = nil - self.ParentMenu.MenuCount = self.ParentMenu.MenuCount - 1 - if self.ParentMenu.MenuCount == 0 then - if self.MenuRemoveParent == true then - self:T2( "Removing Parent Menu " ) - self.ParentMenu:Remove() - end - end - end + + 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( MenuTime, MenuTag ) + if not MenuTime or self.MenuTime ~= MenuTime then + if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then + missionCommands.removeItemForGroup( self.GroupID, self.MenuPath ) + MENU_INDEX:ClearGroupMenu( self.Group, Path ) + self:ClearParentMenu( self.MenuText ) + return nil end - self:T( { "Removing Group Menu:", MenuGroup = self.MenuGroup:GetName() } ) - self.MenuGroup._Menus[self.Path] = nil - self = nil end + else + error( "Remove: Not a correct path" ) + return nil end - return nil + return self end @@ -917,48 +820,36 @@ do --- Creates a new radio command item for a group -- @param #MENU_GROUP_COMMAND self - -- @param Wrapper.Group#GROUP MenuGroup The Group owning the menu. + -- @param Wrapper.Group#GROUP Group 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_GROUP_COMMAND - function MENU_GROUP_COMMAND:New( MenuGroup, MenuText, ParentMenu, CommandMenuFunction, ... ) - - MenuGroup._Menus = MenuGroup._Menus or {} - local Path = ( ParentMenu and ( table.concat( ParentMenu.MenuPath or {}, "@" ) .. "@" .. MenuText ) ) or MenuText - if MenuGroup._Menus[Path] then - self = MenuGroup._Menus[Path] - --self:E( { Path=Path } ) - --self:E( { self.MenuTag, self.MenuTime, "Re-using Group Command Menu:", MenuGroup:GetName(), MenuText } ) - self:SetCommandMenuFunction( CommandMenuFunction ) - self:SetCommandMenuArguments( arg ) + 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 + self.GroupID = Group:GetID() + + self.MenuPath = missionCommands.addCommandForGroup( self.GroupID, MenuText, self.MenuParentPath, self.MenuCallHandler ) + + self:SetParentMenu( self.MenuText, self ) return self end - self = BASE:Inherit( self, MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, arg ) ) - - --if MenuGroup:IsAlive() then - MenuGroup._Menus[Path] = self - --end - --self:E({Path=Path}) - self.Path = Path - self.MenuGroup = MenuGroup - self.MenuGroupID = MenuGroup:GetID() - self.MenuText = MenuText - self.ParentMenu = ParentMenu - - self:F( { "Adding Group Command Menu:", MenuGroup = MenuGroup:GetName(), MenuText = MenuText, MenuPath = self.MenuParentPath } ) - self.MenuPath = missionCommands.addCommandForGroup( self.MenuGroupID, MenuText, self.MenuParentPath, self.MenuCallHandler ) - - if self.ParentMenu and self.ParentMenu.Menus then - self.ParentMenu.Menus[MenuText] = self - self.ParentMenu.MenuCount = self.ParentMenu.MenuCount + 1 - self:F2( { ParentMenu.Menus, MenuText } ) - end --- end - - return self end --- Removes a menu structure for a group. @@ -967,33 +858,23 @@ 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( MenuTime, MenuTag ) - --self:F2( { self.MenuGroupID, self.MenuPath, MenuTime, self.MenuTime } ) - --self:E( { MenuTag = MenuTag, MenuTime = self.MenuTime, Path = self.Path } ) - if not MenuTime or self.MenuTime ~= MenuTime then - if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then - if self.MenuGroup._Menus[self.Path] then - self = self.MenuGroup._Menus[self.Path] - - missionCommands.removeItemForGroup( self.MenuGroupID, self.MenuPath ) - --self:E( { "Removing Group Command Menu:", MenuGroup = self.MenuGroup:GetName(), MenuText = self.MenuText, MenuPath = self.Path } ) - - self.ParentMenu.Menus[self.MenuText] = nil - self.ParentMenu.MenuCount = self.ParentMenu.MenuCount - 1 - if self.ParentMenu.MenuCount == 0 then - if self.MenuRemoveParent == true then - self:T2( "Removing Parent Menu " ) - self.ParentMenu:Remove() - end - end - - self.MenuGroup._Menus[self.Path] = nil - self = nil + 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 MenuTime or self.MenuTime ~= MenuTime then + if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then + missionCommands.removeItemForGroup( self.GroupID, self.MenuPath ) + MENU_INDEX:ClearGroupMenu( self.Group, Path ) + self:ClearParentMenu( self.MenuText ) + return nil end end end - return nil + return self end end diff --git a/Moose Development/Moose/Functional/Detection.lua b/Moose Development/Moose/Functional/Detection.lua index 45bdc0b77..a8362e6d5 100644 --- a/Moose Development/Moose/Functional/Detection.lua +++ b/Moose Development/Moose/Functional/Detection.lua @@ -1356,12 +1356,10 @@ do -- DETECTION_BASE -- @param #DETECTION_BASE.DetectedObject DetectedObject -- @return #boolean true if already identified. function DETECTION_BASE:IsDetectedObjectIdentified( DetectedObject ) - --self:F3( DetectedObject.Name ) local DetectedObjectName = DetectedObject.Name if DetectedObjectName then local DetectedObjectIdentified = self.DetectedObjectsIdentified[DetectedObjectName] == true - self:T3( DetectedObjectIdentified ) return DetectedObjectIdentified else return nil @@ -1463,11 +1461,11 @@ do -- DETECTION_BASE if DetectedItemIndex then self.DetectedItems[DetectedItemIndex] = DetectedItem else - self.DetectedItems[self.DetectedItemCount] = DetectedItem + self.DetectedItems[self.DetectedItemMax] = DetectedItem end DetectedItem.Set = Set or SET_UNIT:New():FilterDeads():FilterCrashes() - DetectedItem.Index = DetectedItemIndex or self.DetectedItemCount + DetectedItem.Index = DetectedItemIndex or self.DetectedItemMax DetectedItem.ItemID = ItemPrefix .. "." .. self.DetectedItemMax DetectedItem.ID = self.DetectedItemMax DetectedItem.Removed = false @@ -2674,7 +2672,8 @@ do -- DETECTION_AREAS -- Yes, the DetectedUnit is within the DetectedItem.Zone, no changes, DetectedUnit can be kept within the Set. self:IdentifyDetectedObject( DetectedObject ) - + DetectedSet:AddUnit( DetectedUnit ) + else -- No, the DetectedUnit is not within the DetectedItem.Zone, remove DetectedUnit from the Set. DetectedSet:Remove( DetectedUnitName ) diff --git a/Moose Development/Moose/Functional/Escort.lua b/Moose Development/Moose/Functional/Escort.lua index 66496f973..f2a1e5d7b 100644 --- a/Moose Development/Moose/Functional/Escort.lua +++ b/Moose Development/Moose/Functional/Escort.lua @@ -129,8 +129,7 @@ -- @field #boolean ReportTargets If true, nearby targets are reported. -- @Field Dcs.DCSTypes#AI.Option.Air.val.ROE OptionROE Which ROE is set to the EscortGroup. -- @field Dcs.DCSTypes#AI.Option.Air.val.REACTION_ON_THREAT OptionReactionOnThreat Which REACTION_ON_THREAT is set to the EscortGroup. --- @field Core.Menu#MENU_CLIENT EscortMenuResumeMission --- @field Functional.Detection#DETECTION_BASE Detection +-- @field FunctionalMENU_GROUPDETECTION_BASE Detection ESCORT = { ClassName = "ESCORT", EscortName = nil, -- The Escort Name @@ -207,7 +206,7 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing ) self.EscortClient._EscortGroups[EscortGroup:GetName()].Detection = self.EscortGroup.Detection end - self.EscortMenu = MENU_CLIENT:New( self.EscortClient, self.EscortName ) + self.EscortMenu = MENU_GROUP:New( self.EscortClient:GetGroup(), self.EscortName ) self.EscortGroup:WayPointInitialize(1) @@ -303,14 +302,14 @@ function ESCORT:MenuFollowAt( Distance ) if self.EscortGroup:IsAir() then if not self.EscortMenuReportNavigation then - self.EscortMenuReportNavigation = MENU_CLIENT:New( self.EscortClient, "Navigation", self.EscortMenu ) + self.EscortMenuReportNavigation = MENU_GROUP:New( self.EscortClient:GetGroup(), "Navigation", self.EscortMenu ) end if not self.EscortMenuJoinUpAndFollow then self.EscortMenuJoinUpAndFollow = {} end - self.EscortMenuJoinUpAndFollow[#self.EscortMenuJoinUpAndFollow+1] = MENU_CLIENT_COMMAND:New( self.EscortClient, "Join-Up and Follow at " .. Distance, self.EscortMenuReportNavigation, ESCORT._JoinUpAndFollow, self, Distance ) + self.EscortMenuJoinUpAndFollow[#self.EscortMenuJoinUpAndFollow+1] = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Join-Up and Follow at " .. Distance, self.EscortMenuReportNavigation, ESCORT._JoinUpAndFollow, self, Distance ) self.EscortMode = ESCORT.MODE.FOLLOW end @@ -332,7 +331,7 @@ function ESCORT:MenuHoldAtEscortPosition( Height, Seconds, MenuTextFormat ) if self.EscortGroup:IsAir() then if not self.EscortMenuHold then - self.EscortMenuHold = MENU_CLIENT:New( self.EscortClient, "Hold position", self.EscortMenu ) + self.EscortMenuHold = MENU_GROUP:New( self.EscortClient:GetGroup(), "Hold position", self.EscortMenu ) end if not Height then @@ -362,9 +361,9 @@ function ESCORT:MenuHoldAtEscortPosition( Height, Seconds, MenuTextFormat ) self.EscortMenuHoldPosition = {} end - self.EscortMenuHoldPosition[#self.EscortMenuHoldPosition+1] = MENU_CLIENT_COMMAND + self.EscortMenuHoldPosition[#self.EscortMenuHoldPosition+1] = MENU_GROUP_COMMAND :New( - self.EscortClient, + self.EscortClient:GetGroup(), MenuText, self.EscortMenuHold, ESCORT._HoldPosition, @@ -393,7 +392,7 @@ function ESCORT:MenuHoldAtLeaderPosition( Height, Seconds, MenuTextFormat ) if self.EscortGroup:IsAir() then if not self.EscortMenuHold then - self.EscortMenuHold = MENU_CLIENT:New( self.EscortClient, "Hold position", self.EscortMenu ) + self.EscortMenuHold = MENU_GROUP:New( self.EscortClient:GetGroup(), "Hold position", self.EscortMenu ) end if not Height then @@ -423,9 +422,9 @@ function ESCORT:MenuHoldAtLeaderPosition( Height, Seconds, MenuTextFormat ) self.EscortMenuHoldAtLeaderPosition = {} end - self.EscortMenuHoldAtLeaderPosition[#self.EscortMenuHoldAtLeaderPosition+1] = MENU_CLIENT_COMMAND + self.EscortMenuHoldAtLeaderPosition[#self.EscortMenuHoldAtLeaderPosition+1] = MENU_GROUP_COMMAND :New( - self.EscortClient, + self.EscortClient:GetGroup(), MenuText, self.EscortMenuHold, ESCORT._HoldPosition, @@ -452,7 +451,7 @@ function ESCORT:MenuScanForTargets( Height, Seconds, MenuTextFormat ) if self.EscortGroup:IsAir() then if not self.EscortMenuScan then - self.EscortMenuScan = MENU_CLIENT:New( self.EscortClient, "Scan for targets", self.EscortMenu ) + self.EscortMenuScan = MENU_GROUP:New( self.EscortClient:GetGroup(), "Scan for targets", self.EscortMenu ) end if not Height then @@ -482,9 +481,9 @@ function ESCORT:MenuScanForTargets( Height, Seconds, MenuTextFormat ) self.EscortMenuScanForTargets = {} end - self.EscortMenuScanForTargets[#self.EscortMenuScanForTargets+1] = MENU_CLIENT_COMMAND + self.EscortMenuScanForTargets[#self.EscortMenuScanForTargets+1] = MENU_GROUP_COMMAND :New( - self.EscortClient, + self.EscortClient:GetGroup(), MenuText, self.EscortMenuScan, ESCORT._ScanTargets, @@ -508,7 +507,7 @@ function ESCORT:MenuFlare( MenuTextFormat ) self:F() if not self.EscortMenuReportNavigation then - self.EscortMenuReportNavigation = MENU_CLIENT:New( self.EscortClient, "Navigation", self.EscortMenu ) + self.EscortMenuReportNavigation = MENU_GROUP:New( self.EscortClient:GetGroup(), "Navigation", self.EscortMenu ) end local MenuText = "" @@ -519,11 +518,11 @@ function ESCORT:MenuFlare( MenuTextFormat ) end if not self.EscortMenuFlare then - self.EscortMenuFlare = MENU_CLIENT:New( self.EscortClient, MenuText, self.EscortMenuReportNavigation, ESCORT._Flare, self ) - self.EscortMenuFlareGreen = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release green flare", self.EscortMenuFlare, ESCORT._Flare, self, FLARECOLOR.Green, "Released a green flare!" ) - self.EscortMenuFlareRed = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release red flare", self.EscortMenuFlare, ESCORT._Flare, self, FLARECOLOR.Red, "Released a red flare!" ) - self.EscortMenuFlareWhite = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release white flare", self.EscortMenuFlare, ESCORT._Flare, self, FLARECOLOR.White, "Released a white flare!" ) - self.EscortMenuFlareYellow = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release yellow flare", self.EscortMenuFlare, ESCORT._Flare, self, FLARECOLOR.Yellow, "Released a yellow flare!" ) + self.EscortMenuFlare = MENU_GROUP:New( self.EscortClient:GetGroup(), MenuText, self.EscortMenuReportNavigation, ESCORT._Flare, self ) + self.EscortMenuFlareGreen = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release green flare", self.EscortMenuFlare, ESCORT._Flare, self, FLARECOLOR.Green, "Released a green flare!" ) + self.EscortMenuFlareRed = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release red flare", self.EscortMenuFlare, ESCORT._Flare, self, FLARECOLOR.Red, "Released a red flare!" ) + self.EscortMenuFlareWhite = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release white flare", self.EscortMenuFlare, ESCORT._Flare, self, FLARECOLOR.White, "Released a white flare!" ) + self.EscortMenuFlareYellow = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release yellow flare", self.EscortMenuFlare, ESCORT._Flare, self, FLARECOLOR.Yellow, "Released a yellow flare!" ) end return self @@ -541,7 +540,7 @@ function ESCORT:MenuSmoke( MenuTextFormat ) if not self.EscortGroup:IsAir() then if not self.EscortMenuReportNavigation then - self.EscortMenuReportNavigation = MENU_CLIENT:New( self.EscortClient, "Navigation", self.EscortMenu ) + self.EscortMenuReportNavigation = MENU_GROUP:New( self.EscortClient:GetGroup(), "Navigation", self.EscortMenu ) end local MenuText = "" @@ -552,12 +551,12 @@ function ESCORT:MenuSmoke( MenuTextFormat ) end if not self.EscortMenuSmoke then - self.EscortMenuSmoke = MENU_CLIENT:New( self.EscortClient, "Smoke", self.EscortMenuReportNavigation, ESCORT._Smoke, self ) - self.EscortMenuSmokeGreen = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release green smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.Green, "Releasing green smoke!" ) - self.EscortMenuSmokeRed = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release red smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.Red, "Releasing red smoke!" ) - self.EscortMenuSmokeWhite = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release white smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.White, "Releasing white smoke!" ) - self.EscortMenuSmokeOrange = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release orange smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.Orange, "Releasing orange smoke!" ) - self.EscortMenuSmokeBlue = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release blue smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.Blue, "Releasing blue smoke!" ) + self.EscortMenuSmoke = MENU_GROUP:New( self.EscortClient:GetGroup(), "Smoke", self.EscortMenuReportNavigation, ESCORT._Smoke, self ) + self.EscortMenuSmokeGreen = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release green smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.Green, "Releasing green smoke!" ) + self.EscortMenuSmokeRed = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release red smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.Red, "Releasing red smoke!" ) + self.EscortMenuSmokeWhite = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release white smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.White, "Releasing white smoke!" ) + self.EscortMenuSmokeOrange = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release orange smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.Orange, "Releasing orange smoke!" ) + self.EscortMenuSmokeBlue = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release blue smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.Blue, "Releasing blue smoke!" ) end end @@ -574,7 +573,7 @@ function ESCORT:MenuReportTargets( Seconds ) self:F( { Seconds } ) if not self.EscortMenuReportNearbyTargets then - self.EscortMenuReportNearbyTargets = MENU_CLIENT:New( self.EscortClient, "Report targets", self.EscortMenu ) + self.EscortMenuReportNearbyTargets = MENU_GROUP:New( self.EscortClient:GetGroup(), "Report targets", self.EscortMenu ) end if not Seconds then @@ -582,12 +581,12 @@ function ESCORT:MenuReportTargets( Seconds ) end -- Report Targets - self.EscortMenuReportNearbyTargetsNow = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets now!", self.EscortMenuReportNearbyTargets, ESCORT._ReportNearbyTargetsNow, self ) - self.EscortMenuReportNearbyTargetsOn = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets on", self.EscortMenuReportNearbyTargets, ESCORT._SwitchReportNearbyTargets, self, true ) - self.EscortMenuReportNearbyTargetsOff = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets off", self.EscortMenuReportNearbyTargets, ESCORT._SwitchReportNearbyTargets, self, false ) + self.EscortMenuReportNearbyTargetsNow = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Report targets now!", self.EscortMenuReportNearbyTargets, ESCORT._ReportNearbyTargetsNow, self ) + self.EscortMenuReportNearbyTargetsOn = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Report targets on", self.EscortMenuReportNearbyTargets, ESCORT._SwitchReportNearbyTargets, self, true ) + self.EscortMenuReportNearbyTargetsOff = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Report targets off", self.EscortMenuReportNearbyTargets, ESCORT._SwitchReportNearbyTargets, self, false ) -- Attack Targets - self.EscortMenuAttackNearbyTargets = MENU_CLIENT:New( self.EscortClient, "Attack targets", self.EscortMenu ) + self.EscortMenuAttackNearbyTargets = MENU_GROUP:New( self.EscortClient:GetGroup(), "Attack targets", self.EscortMenu ) self.ReportTargetsScheduler = SCHEDULER:New( self, self._ReportTargetsScheduler, {}, 1, Seconds ) @@ -605,7 +604,7 @@ function ESCORT:MenuAssistedAttack() -- Request assistance from other escorts. -- This is very useful to let f.e. an escorting ship attack a target detected by an escorting plane... - self.EscortMenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, "Request assistance from", self.EscortMenu ) + self.EscortMenuTargetAssistance = MENU_GROUP:New( self.EscortClient:GetGroup(), "Request assistance from", self.EscortMenu ) return self end @@ -619,18 +618,18 @@ function ESCORT:MenuROE( MenuTextFormat ) if not self.EscortMenuROE then -- Rules of Engagement - self.EscortMenuROE = MENU_CLIENT:New( self.EscortClient, "ROE", self.EscortMenu ) + self.EscortMenuROE = MENU_GROUP:New( self.EscortClient:GetGroup(), "ROE", self.EscortMenu ) if self.EscortGroup:OptionROEHoldFirePossible() then - self.EscortMenuROEHoldFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Hold Fire", self.EscortMenuROE, ESCORT._ROE, self, self.EscortGroup:OptionROEHoldFire(), "Holding weapons!" ) + self.EscortMenuROEHoldFire = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Hold Fire", self.EscortMenuROE, ESCORT._ROE, self, self.EscortGroup:OptionROEHoldFire(), "Holding weapons!" ) end if self.EscortGroup:OptionROEReturnFirePossible() then - self.EscortMenuROEReturnFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Return Fire", self.EscortMenuROE, ESCORT._ROE, self, self.EscortGroup:OptionROEReturnFire(), "Returning fire!" ) + self.EscortMenuROEReturnFire = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Return Fire", self.EscortMenuROE, ESCORT._ROE, self, self.EscortGroup:OptionROEReturnFire(), "Returning fire!" ) end if self.EscortGroup:OptionROEOpenFirePossible() then - self.EscortMenuROEOpenFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Open Fire", self.EscortMenuROE, ESCORT._ROE, self, self.EscortGroup:OptionROEOpenFire(), "Opening fire on designated targets!!" ) + self.EscortMenuROEOpenFire = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Open Fire", self.EscortMenuROE, ESCORT._ROE, self, self.EscortGroup:OptionROEOpenFire(), "Opening fire on designated targets!!" ) end if self.EscortGroup:OptionROEWeaponFreePossible() then - self.EscortMenuROEWeaponFree = MENU_CLIENT_COMMAND:New( self.EscortClient, "Weapon Free", self.EscortMenuROE, ESCORT._ROE, self, self.EscortGroup:OptionROEWeaponFree(), "Opening fire on targets of opportunity!" ) + self.EscortMenuROEWeaponFree = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Weapon Free", self.EscortMenuROE, ESCORT._ROE, self, self.EscortGroup:OptionROEWeaponFree(), "Opening fire on targets of opportunity!" ) end end @@ -648,18 +647,18 @@ function ESCORT:MenuEvasion( MenuTextFormat ) if self.EscortGroup:IsAir() then if not self.EscortMenuEvasion then -- Reaction to Threats - self.EscortMenuEvasion = MENU_CLIENT:New( self.EscortClient, "Evasion", self.EscortMenu ) + self.EscortMenuEvasion = MENU_GROUP:New( self.EscortClient:GetGroup(), "Evasion", self.EscortMenu ) if self.EscortGroup:OptionROTNoReactionPossible() then - self.EscortMenuEvasionNoReaction = MENU_CLIENT_COMMAND:New( self.EscortClient, "Fight until death", self.EscortMenuEvasion, ESCORT._ROT, self, self.EscortGroup:OptionROTNoReaction(), "Fighting until death!" ) + self.EscortMenuEvasionNoReaction = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Fight until death", self.EscortMenuEvasion, ESCORT._ROT, self, self.EscortGroup:OptionROTNoReaction(), "Fighting until death!" ) end if self.EscortGroup:OptionROTPassiveDefensePossible() then - self.EscortMenuEvasionPassiveDefense = MENU_CLIENT_COMMAND:New( self.EscortClient, "Use flares, chaff and jammers", self.EscortMenuEvasion, ESCORT._ROT, self, self.EscortGroup:OptionROTPassiveDefense(), "Defending using jammers, chaff and flares!" ) + self.EscortMenuEvasionPassiveDefense = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Use flares, chaff and jammers", self.EscortMenuEvasion, ESCORT._ROT, self, self.EscortGroup:OptionROTPassiveDefense(), "Defending using jammers, chaff and flares!" ) end if self.EscortGroup:OptionROTEvadeFirePossible() then - self.EscortMenuEvasionEvadeFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Evade enemy fire", self.EscortMenuEvasion, ESCORT._ROT, self, self.EscortGroup:OptionROTEvadeFire(), "Evading on enemy fire!" ) + self.EscortMenuEvasionEvadeFire = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Evade enemy fire", self.EscortMenuEvasion, ESCORT._ROT, self, self.EscortGroup:OptionROTEvadeFire(), "Evading on enemy fire!" ) end if self.EscortGroup:OptionROTVerticalPossible() then - self.EscortMenuOptionEvasionVertical = MENU_CLIENT_COMMAND:New( self.EscortClient, "Go below radar and evade fire", self.EscortMenuEvasion, ESCORT._ROT, self, self.EscortGroup:OptionROTVertical(), "Evading on enemy fire with vertical manoeuvres!" ) + self.EscortMenuOptionEvasionVertical = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Go below radar and evade fire", self.EscortMenuEvasion, ESCORT._ROT, self, self.EscortGroup:OptionROTVertical(), "Evading on enemy fire with vertical manoeuvres!" ) end end end @@ -676,7 +675,7 @@ function ESCORT:MenuResumeMission() if not self.EscortMenuResumeMission then -- Mission Resume Menu Root - self.EscortMenuResumeMission = MENU_CLIENT:New( self.EscortClient, "Resume mission from", self.EscortMenu ) + self.EscortMenuResumeMission = MENU_GROUP:New( self.EscortClient:GetGroup(), "Resume mission from", self.EscortMenu ) end return self @@ -1176,7 +1175,7 @@ function ESCORT:_ReportTargetsScheduler() self:T( DetectedMsg ) - MENU_CLIENT_COMMAND:New( self.EscortClient, + MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), DetectedMsg, self.EscortMenuAttackNearbyTargets, ESCORT._AttackTarget, @@ -1189,8 +1188,8 @@ function ESCORT:_ReportTargetsScheduler() local DetectedMsg = DetectedItemReportSummary:Text("\n") self:T( DetectedMsg ) - local MenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, EscortGroupData.EscortName, self.EscortMenuTargetAssistance ) - MENU_CLIENT_COMMAND:New( self.EscortClient, + local MenuTargetAssistance = MENU_GROUP:New( self.EscortClient:GetGroup(), EscortGroupData.EscortName, self.EscortMenuTargetAssistance ) + MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), DetectedMsg, MenuTargetAssistance, ESCORT._AssistTarget, @@ -1327,7 +1326,7 @@ function ESCORT:_ReportTargetsScheduler() -- -- if ClientEscortGroupName == EscortGroupName then -- --- MENU_CLIENT_COMMAND:New( self.EscortClient, +-- MENU_GROUP_COMMAND:New( self.EscortClient, -- EscortTargetMessage, -- self.EscortMenuAttackNearbyTargets, -- ESCORT._AttackTarget, @@ -1338,8 +1337,8 @@ function ESCORT:_ReportTargetsScheduler() -- EscortTargetMessages = EscortTargetMessages .. "\n - " .. EscortTargetMessage -- else -- if self.EscortMenuTargetAssistance then --- local MenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, EscortGroupData.EscortName, self.EscortMenuTargetAssistance ) --- MENU_CLIENT_COMMAND:New( self.EscortClient, +-- local MenuTargetAssistance = MENU_GROUP:New( self.EscortClient, EscortGroupData.EscortName, self.EscortMenuTargetAssistance ) +-- MENU_GROUP_COMMAND:New( self.EscortClient, -- EscortTargetMessage, -- MenuTargetAssistance, -- ESCORT._AssistTarget, @@ -1378,7 +1377,7 @@ function ESCORT:_ReportTargetsScheduler() -- local Distance = ( ( WayPoint.x - EscortVec3.x )^2 + -- ( WayPoint.y - EscortVec3.z )^2 -- ) ^ 0.5 / 1000 --- MENU_CLIENT_COMMAND:New( self.EscortClient, "Waypoint " .. WayPointID .. " at " .. string.format( "%.2f", Distance ).. "km", self.EscortMenuResumeMission, ESCORT._ResumeMission, { ParamSelf = self, ParamWayPoint = WayPointID } ) +-- MENU_GROUP_COMMAND:New( self.EscortClient, "Waypoint " .. WayPointID .. " at " .. string.format( "%.2f", Distance ).. "km", self.EscortMenuResumeMission, ESCORT._ResumeMission, { ParamSelf = self, ParamWayPoint = WayPointID } ) -- end -- end -- diff --git a/Moose Development/Moose/Functional/MissileTrainer.lua b/Moose Development/Moose/Functional/MissileTrainer.lua index b8511867d..2129b8477 100644 --- a/Moose Development/Moose/Functional/MissileTrainer.lua +++ b/Moose Development/Moose/Functional/MissileTrainer.lua @@ -99,39 +99,39 @@ function MISSILETRAINER._Alive( Client, self ) if self.MenusOnOff == true then Client:Message( "Use the 'Radio Menu' -> 'Other (F10)' -> 'Missile Trainer' menu options to change the Missile Trainer settings (for all players).", 15, "Trainer" ) - Client.MainMenu = MENU_CLIENT:New( Client, "Missile Trainer", nil ) -- Menu#MENU_CLIENT + Client.MainMenu = MENU_GROUP:New( Client:GetGroup(), "Missile Trainer", nil ) -- Menu#MENU_GROUP - Client.MenuMessages = MENU_CLIENT:New( Client, "Messages", Client.MainMenu ) - Client.MenuOn = MENU_CLIENT_COMMAND:New( Client, "Messages On", Client.MenuMessages, self._MenuMessages, { MenuSelf = self, MessagesOnOff = true } ) - Client.MenuOff = MENU_CLIENT_COMMAND:New( Client, "Messages Off", Client.MenuMessages, self._MenuMessages, { MenuSelf = self, MessagesOnOff = false } ) + Client.MenuMessages = MENU_GROUP:New( Client:GetGroup(), "Messages", Client.MainMenu ) + Client.MenuOn = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Messages On", Client.MenuMessages, self._MenuMessages, { MenuSelf = self, MessagesOnOff = true } ) + Client.MenuOff = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Messages Off", Client.MenuMessages, self._MenuMessages, { MenuSelf = self, MessagesOnOff = false } ) - Client.MenuTracking = MENU_CLIENT:New( Client, "Tracking", Client.MainMenu ) - Client.MenuTrackingToAll = MENU_CLIENT_COMMAND:New( Client, "To All", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingToAll = true } ) - Client.MenuTrackingToTarget = MENU_CLIENT_COMMAND:New( Client, "To Target", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingToAll = false } ) - Client.MenuTrackOn = MENU_CLIENT_COMMAND:New( Client, "Tracking On", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingOnOff = true } ) - Client.MenuTrackOff = MENU_CLIENT_COMMAND:New( Client, "Tracking Off", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingOnOff = false } ) - Client.MenuTrackIncrease = MENU_CLIENT_COMMAND:New( Client, "Frequency Increase", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingFrequency = -1 } ) - Client.MenuTrackDecrease = MENU_CLIENT_COMMAND:New( Client, "Frequency Decrease", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingFrequency = 1 } ) + Client.MenuTracking = MENU_GROUP:New( Client:GetGroup(), "Tracking", Client.MainMenu ) + Client.MenuTrackingToAll = MENU_GROUP_COMMAND:New( Client:GetGroup(), "To All", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingToAll = true } ) + Client.MenuTrackingToTarget = MENU_GROUP_COMMAND:New( Client:GetGroup(), "To Target", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingToAll = false } ) + Client.MenuTrackOn = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Tracking On", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingOnOff = true } ) + Client.MenuTrackOff = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Tracking Off", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingOnOff = false } ) + Client.MenuTrackIncrease = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Frequency Increase", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingFrequency = -1 } ) + Client.MenuTrackDecrease = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Frequency Decrease", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingFrequency = 1 } ) - Client.MenuAlerts = MENU_CLIENT:New( Client, "Alerts", Client.MainMenu ) - Client.MenuAlertsToAll = MENU_CLIENT_COMMAND:New( Client, "To All", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsToAll = true } ) - Client.MenuAlertsToTarget = MENU_CLIENT_COMMAND:New( Client, "To Target", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsToAll = false } ) - Client.MenuHitsOn = MENU_CLIENT_COMMAND:New( Client, "Hits On", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsHitsOnOff = true } ) - Client.MenuHitsOff = MENU_CLIENT_COMMAND:New( Client, "Hits Off", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsHitsOnOff = false } ) - Client.MenuLaunchesOn = MENU_CLIENT_COMMAND:New( Client, "Launches On", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsLaunchesOnOff = true } ) - Client.MenuLaunchesOff = MENU_CLIENT_COMMAND:New( Client, "Launches Off", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsLaunchesOnOff = false } ) + Client.MenuAlerts = MENU_GROUP:New( Client:GetGroup(), "Alerts", Client.MainMenu ) + Client.MenuAlertsToAll = MENU_GROUP_COMMAND:New( Client:GetGroup(), "To All", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsToAll = true } ) + Client.MenuAlertsToTarget = MENU_GROUP_COMMAND:New( Client:GetGroup(), "To Target", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsToAll = false } ) + Client.MenuHitsOn = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Hits On", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsHitsOnOff = true } ) + Client.MenuHitsOff = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Hits Off", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsHitsOnOff = false } ) + Client.MenuLaunchesOn = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Launches On", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsLaunchesOnOff = true } ) + Client.MenuLaunchesOff = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Launches Off", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsLaunchesOnOff = false } ) - Client.MenuDetails = MENU_CLIENT:New( Client, "Details", Client.MainMenu ) - Client.MenuDetailsDistanceOn = MENU_CLIENT_COMMAND:New( Client, "Range On", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsRangeOnOff = true } ) - Client.MenuDetailsDistanceOff = MENU_CLIENT_COMMAND:New( Client, "Range Off", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsRangeOnOff = false } ) - Client.MenuDetailsBearingOn = MENU_CLIENT_COMMAND:New( Client, "Bearing On", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsBearingOnOff = true } ) - Client.MenuDetailsBearingOff = MENU_CLIENT_COMMAND:New( Client, "Bearing Off", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsBearingOnOff = false } ) + Client.MenuDetails = MENU_GROUP:New( Client:GetGroup(), "Details", Client.MainMenu ) + Client.MenuDetailsDistanceOn = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Range On", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsRangeOnOff = true } ) + Client.MenuDetailsDistanceOff = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Range Off", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsRangeOnOff = false } ) + Client.MenuDetailsBearingOn = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Bearing On", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsBearingOnOff = true } ) + Client.MenuDetailsBearingOff = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Bearing Off", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsBearingOnOff = false } ) - Client.MenuDistance = MENU_CLIENT:New( Client, "Set distance to plane", Client.MainMenu ) - Client.MenuDistance50 = MENU_CLIENT_COMMAND:New( Client, "50 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 50 / 1000 } ) - Client.MenuDistance100 = MENU_CLIENT_COMMAND:New( Client, "100 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 100 / 1000 } ) - Client.MenuDistance150 = MENU_CLIENT_COMMAND:New( Client, "150 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 150 / 1000 } ) - Client.MenuDistance200 = MENU_CLIENT_COMMAND:New( Client, "200 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 200 / 1000 } ) + Client.MenuDistance = MENU_GROUP:New( Client:GetGroup(), "Set distance to plane", Client.MainMenu ) + Client.MenuDistance50 = MENU_GROUP_COMMAND:New( Client:GetGroup(), "50 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 50 / 1000 } ) + Client.MenuDistance100 = MENU_GROUP_COMMAND:New( Client:GetGroup(), "100 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 100 / 1000 } ) + Client.MenuDistance150 = MENU_GROUP_COMMAND:New( Client:GetGroup(), "150 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 150 / 1000 } ) + Client.MenuDistance200 = MENU_GROUP_COMMAND:New( Client:GetGroup(), "200 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 200 / 1000 } ) else if Client.MainMenu then Client.MainMenu:Remove() diff --git a/Moose Development/Moose/Tasking/Task.lua b/Moose Development/Moose/Tasking/Task.lua index 9bd94eaff..1fbd2fa5b 100644 --- a/Moose Development/Moose/Tasking/Task.lua +++ b/Moose Development/Moose/Tasking/Task.lua @@ -746,14 +746,14 @@ function TASK:SetPlannedMenuForGroup( TaskGroup, MenuTime ) self.MenuPlanned = self.MenuPlanned or {} self.MenuPlanned[TaskGroup] = MENU_GROUP:New( TaskGroup, "Join Planned Task", MissionMenu, Mission.MenuReportTasksPerStatus, Mission, TaskGroup, "Planned" ):SetTime( MenuTime ):SetTag( "Tasking" ) - local TaskTypeMenu = MENU_GROUP:New( TaskGroup, TaskType, self.MenuPlanned[TaskGroup] ):SetTime( MenuTime ):SetTag( "Tasking" ):SetRemoveParent( true ) - local TaskTypeMenu = MENU_GROUP:New( TaskGroup, TaskText, TaskTypeMenu ):SetTime( MenuTime ):SetTag( "Tasking" ):SetRemoveParent( true ) - local ReportTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Report Task Status" ), TaskTypeMenu, self.MenuTaskStatus, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" ):SetRemoveParent( true ) + local TaskTypeMenu = MENU_GROUP:New( TaskGroup, TaskType, self.MenuPlanned[TaskGroup] ):SetTime( MenuTime ):SetTag( "Tasking" ) + local TaskTypeMenu = MENU_GROUP:New( TaskGroup, TaskText, TaskTypeMenu ):SetTime( MenuTime ):SetTag( "Tasking" ) + local ReportTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Report Task Status" ), TaskTypeMenu, self.MenuTaskStatus, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" ) if not Mission:IsGroupAssigned( TaskGroup ) then self:F( { "Replacing Join Task menu" } ) - local JoinTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Join Task" ), TaskTypeMenu, self.MenuAssignToGroup, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" ):SetRemoveParent( true ) - local MarkTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Mark Task on Map" ), TaskTypeMenu, self.MenuMarkToGroup, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" ):SetRemoveParent( true ) + local JoinTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Join Task" ), TaskTypeMenu, self.MenuAssignToGroup, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" ) + local MarkTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Mark Task on Map" ), TaskTypeMenu, self.MenuMarkToGroup, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" ) end return self @@ -786,8 +786,8 @@ function TASK:SetAssignedMenuForGroup( TaskGroup, MenuTime ) self.MenuAssigned = self.MenuAssigned or {} self.MenuAssigned[TaskGroup] = MENU_GROUP:New( TaskGroup, string.format( "Assigned Task %s", TaskName ), MissionMenu ):SetTime( MenuTime ):SetTag( "Tasking" ) - local TaskTypeMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Report Task Status" ), self.MenuAssigned[TaskGroup], self.MenuTaskStatus, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" ):SetRemoveParent( true ) - local TaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Abort Group from Task" ), self.MenuAssigned[TaskGroup], self.MenuTaskAbort, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" ):SetRemoveParent( true ) + local TaskTypeMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Report Task Status" ), self.MenuAssigned[TaskGroup], self.MenuTaskStatus, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" ) + local TaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Abort Group from Task" ), self.MenuAssigned[TaskGroup], self.MenuTaskAbort, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" ) return self end @@ -829,11 +829,11 @@ function TASK:RefreshMenus( TaskGroup, MenuTime ) local AssignedMenu = self.MenuAssigned[TaskGroup] if PlannedMenu then - PlannedMenu:Remove( MenuTime , "Tasking") + self.MenuPlanned[TaskGroup] = PlannedMenu:Remove( MenuTime , "Tasking" ) end if AssignedMenu then - AssignedMenu:Remove( MenuTime, "Tasking" ) + self.MenuAssigned[TaskGroup] = AssignedMenu:Remove( MenuTime, "Tasking" ) end end diff --git a/Moose Development/Moose/Tasking/Task_A2G.lua b/Moose Development/Moose/Tasking/Task_A2G.lua index 02e442d2c..c2344e83e 100644 --- a/Moose Development/Moose/Tasking/Task_A2G.lua +++ b/Moose Development/Moose/Tasking/Task_A2G.lua @@ -316,6 +316,77 @@ do -- TASK_A2G end end + + --- Return the relative distance to the target vicinity from the player, in order to sort the targets in the reports per distance from the threats. + -- @param #TASK_A2G self + function TASK_A2G:ReportOrder( ReportGroup ) + local Coordinate = self:GetInfo( "Coordinate" ) + local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate ) + + return Distance + end + + + --- This method checks every 10 seconds if the goal has been reached of the task. + -- @param #TASK_A2G self + function TASK_A2G:onafterGoal( TaskUnit, From, Event, To ) + local TargetSetUnit = self.TargetSetUnit -- Core.Set#SET_UNIT + + if TargetSetUnit:Count() == 0 then + self:Success() + end + + self:__Goal( -10 ) + end + + + --- @param #TASK_A2G self + function TASK_A2G:UpdateTaskInfo() + + if self:IsStatePlanned() or self:IsStateAssigned() then + local TargetCoordinate = self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) or self.TargetSetUnit:GetFirst():GetCoordinate() + self:SetInfo( "Coordinate", TargetCoordinate, 0 ) + + local ThreatLevel, ThreatText + if self.Detection then + ThreatLevel, ThreatText = self.Detection:GetDetectedItemThreatLevel( self.DetectedItemIndex ) + else + ThreatLevel, ThreatText = self.TargetSetUnit:CalculateThreatLevelA2G() + end + self:SetInfo( "Threat", ThreatText .. " [" .. string.rep( "■", ThreatLevel ) .. "]", 11 ) + + if self.Detection then + local DetectedItemsCount = self.TargetSetUnit:Count() + local ReportTypes = REPORT:New() + local TargetTypes = {} + for TargetUnitName, TargetUnit in pairs( self.TargetSetUnit:GetSet() ) do + local TargetType = self.Detection:GetDetectedUnitTypeName( TargetUnit ) + if not TargetTypes[TargetType] then + TargetTypes[TargetType] = TargetType + ReportTypes:Add( TargetType ) + end + end + self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, ReportTypes:Text( ", " ) ), 10 ) + else + local DetectedItemsCount = self.TargetSetUnit:Count() + local DetectedItemsTypes = self.TargetSetUnit:GetTypeNames() + self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 10 ) + end + end + + --- Keep Threat and Targets of a task is planned for later use when the task is completed. + if self:IsStatePlanned() then + self.InitialThreat = self:GetInfo( "Threat" ) + self.InitialTargets = self:GetInfo( "Targets" ) + end + + if not self:IsStatePlanned() and not self:IsStateAssigned() then + self:SetInfo( "Targets", self.InitialTargets, 10 ) + self:SetInfo( "Threat", self.InitialThreat, 10 ) + end + + end + end @@ -361,60 +432,6 @@ do -- TASK_A2G_SEAD return self end - function TASK_A2G_SEAD:UpdateTaskInfo() - - - local TargetCoordinate = self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) or self.TargetSetUnit:GetFirst():GetCoordinate() - self:SetInfo( "Coordinate", TargetCoordinate, 0 ) - - local ThreatLevel, ThreatText - if self.Detection then - ThreatLevel, ThreatText = self.Detection:GetDetectedItemThreatLevel( self.DetectedItemIndex ) - else - ThreatLevel, ThreatText = self.TargetSetUnit:CalculateThreatLevelA2G() - end - self:SetInfo( "Threat", ThreatText .. " [" .. string.rep( "■", ThreatLevel ) .. "]", 11 ) - - if self.Detection then - local DetectedItemsCount = self.TargetSetUnit:Count() - local ReportTypes = REPORT:New() - local TargetTypes = {} - for TargetUnitName, TargetUnit in pairs( self.TargetSetUnit:GetSet() ) do - local TargetType = self.Detection:GetDetectedUnitTypeName( TargetUnit ) - if not TargetTypes[TargetType] then - TargetTypes[TargetType] = TargetType - ReportTypes:Add( TargetType ) - end - end - self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, ReportTypes:Text( ", " ) ), 10 ) - else - local DetectedItemsCount = self.TargetSetUnit:Count() - local DetectedItemsTypes = self.TargetSetUnit:GetTypeNames() - self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 10 ) - end - - end - - function TASK_A2G_SEAD:ReportOrder( ReportGroup ) - local Coordinate = self:GetInfo( "Coordinate" ) - --local Coordinate = self.TaskInfo.Coordinates.TaskInfoText - local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate ) - - return Distance - end - - - --- @param #TASK_A2G_SEAD self - function TASK_A2G_SEAD:onafterGoal( TaskUnit, From, Event, To ) - local TargetSetUnit = self.TargetSetUnit -- Core.Set#SET_UNIT - - if TargetSetUnit:Count() == 0 then - self:Success() - end - - self:__Goal( -10 ) - end - --- Set a score when a target in scope of the A2G attack, has been destroyed . -- @param #TASK_A2G_SEAD self -- @param #string PlayerName The name of the player. @@ -508,72 +525,6 @@ do -- TASK_A2G_BAI return self end - - function TASK_A2G_BAI:UpdateTaskInfo() - - self:E({self.Detection, self.DetectedItemIndex}) - - local TargetCoordinate = self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) or self.TargetSetUnit:GetFirst():GetCoordinate() - self:SetInfo( "Coordinate", TargetCoordinate, 0 ) - - local ThreatLevel, ThreatText - if self.Detection then - ThreatLevel, ThreatText = self.Detection:GetDetectedItemThreatLevel( self.DetectedItemIndex ) - else - ThreatLevel, ThreatText = self.TargetSetUnit:CalculateThreatLevelA2G() - end - self:SetInfo( "Threat", ThreatText .. " [" .. string.rep( "■", ThreatLevel ) .. "]", 11 ) - - if self.Detection then - local DetectedItemsCount = self.TargetSetUnit:Count() - local ReportTypes = REPORT:New() - local TargetTypes = {} - for TargetUnitName, TargetUnit in pairs( self.TargetSetUnit:GetSet() ) do - local TargetType = self.Detection:GetDetectedUnitTypeName( TargetUnit ) - if not TargetTypes[TargetType] then - TargetTypes[TargetType] = TargetType - ReportTypes:Add( TargetType ) - end - end - self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, ReportTypes:Text( ", " ) ), 10 ) - else - local DetectedItemsCount = self.TargetSetUnit:Count() - local DetectedItemsTypes = self.TargetSetUnit:GetTypeNames() - self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 10 ) - end - - local TargetCoordinate = self:GetInfo( "Coordinate" ) -- Core.Point#COORDINATE - - local Velocity = self.TargetSetUnit:GetVelocityVec3() - local Heading = self.TargetSetUnit:GetHeading() - - TargetCoordinate:SetHeading( Heading ) - TargetCoordinate:SetVelocity( Velocity ) - - self:SetInfo( "Position", "Targets are" .. TargetCoordinate:GetMovingText() .. ".", 12 ) - - end - - - function TASK_A2G_BAI:ReportOrder( ReportGroup ) - local Coordinate = self:GetInfo( "Coordinate" ) - --local Coordinate = self.TaskInfo.Coordinates.TaskInfoText - local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate ) - - return Distance - end - - - --- @param #TASK_A2G_BAI self - function TASK_A2G_BAI:onafterGoal( TaskUnit, From, Event, To ) - local TargetSetUnit = self.TargetSetUnit -- Core.Set#SET_UNIT - - if TargetSetUnit:Count() == 0 then - self:Success() - end - - self:__Goal( -10 ) - end --- Set a score when a target in scope of the A2G attack, has been destroyed . -- @param #TASK_A2G_BAI self @@ -623,9 +574,11 @@ do -- TASK_A2G_BAI return self end - end + + + do -- TASK_A2G_CAS --- The TASK_A2G_CAS class @@ -670,59 +623,6 @@ do -- TASK_A2G_CAS return self end - function TASK_A2G_CAS:UpdateTaskInfo() - - local TargetCoordinate = ( self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) ) or self.TargetSetUnit:GetFirst():GetCoordinate() - self:SetInfo( "Coordinate", TargetCoordinate, 0 ) - - local ThreatLevel, ThreatText - if self.Detection then - ThreatLevel, ThreatText = self.Detection:GetDetectedItemThreatLevel( self.DetectedItemIndex ) - else - ThreatLevel, ThreatText = self.TargetSetUnit:CalculateThreatLevelA2G() - end - self:SetInfo( "Threat", ThreatText .. " [" .. string.rep( "■", ThreatLevel ) .. "]", 11 ) - - if self.Detection then - local DetectedItemsCount = self.TargetSetUnit:Count() - local ReportTypes = REPORT:New() - local TargetTypes = {} - for TargetUnitName, TargetUnit in pairs( self.TargetSetUnit:GetSet() ) do - local TargetType = self.Detection:GetDetectedUnitTypeName( TargetUnit ) - if not TargetTypes[TargetType] then - TargetTypes[TargetType] = TargetType - ReportTypes:Add( TargetType ) - end - end - self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, ReportTypes:Text( ", " ) ), 10 ) - else - local DetectedItemsCount = self.TargetSetUnit:Count() - local DetectedItemsTypes = self.TargetSetUnit:GetTypeNames() - self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 10 ) - end - - end - - --- @param #TASK_A2G_CAS self - function TASK_A2G_CAS:ReportOrder( ReportGroup ) - - local Coordinate = self:GetInfo( "Coordinate" ) - local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate ) - - return Distance - end - - - --- @param #TASK_A2G_CAS self - function TASK_A2G_CAS:onafterGoal( TaskUnit, From, Event, To ) - local TargetSetUnit = self.TargetSetUnit -- Core.Set#SET_UNIT - - if TargetSetUnit:Count() == 0 then - self:Success() - end - - self:__Goal( -10 ) - end --- Set a score when a target in scope of the A2G attack, has been destroyed . -- @param #TASK_A2G_CAS self diff --git a/Moose Development/Moose/Tasking/Task_A2G_Dispatcher.lua b/Moose Development/Moose/Tasking/Task_A2G_Dispatcher.lua index 7613d7cad..646ad019f 100644 --- a/Moose Development/Moose/Tasking/Task_A2G_Dispatcher.lua +++ b/Moose Development/Moose/Tasking/Task_A2G_Dispatcher.lua @@ -238,7 +238,7 @@ do -- TASK_A2G_DISPATCHER --DetectedSet:Flush() local DetectedItemID = DetectedItem.ID - local TaskIndex = DetectedItem.Index + local TaskIndex = DetectedItem.ID local DetectedItemChanged = DetectedItem.Changed self:E( { DetectedItemChanged = DetectedItemChanged, DetectedItemID = DetectedItemID, TaskIndex = TaskIndex } ) diff --git a/Moose Mission Setup/Moose.lua b/Moose Mission Setup/Moose.lua index 539b24049..73093f60f 100644 --- a/Moose Mission Setup/Moose.lua +++ b/Moose Mission Setup/Moose.lua @@ -1,5 +1,5 @@ env.info( '*** MOOSE DYNAMIC INCLUDE START *** ' ) -env.info( 'Moose Generation Timestamp: 20171110_1045' ) +env.info( 'Moose Generation Timestamp: 20171122_0612' ) local base = _G diff --git a/Moose Mission Setup/Moose_.lua b/Moose Mission Setup/Moose_.lua index 404ecfc7b..bafc5cf9f 100644 --- a/Moose Mission Setup/Moose_.lua +++ b/Moose Mission Setup/Moose_.lua @@ -1,5 +1,5 @@ env.info('*** MOOSE DYNAMIC INCLUDE START *** ') -env.info('Moose Generation Timestamp: 20171110_1045') +env.info('Moose Generation Timestamp: 20171122_0612') local base=_G MOOSE={} MOOSE.Include=function(LuaPath,IncludeFile)