From 7b57bf3eceb3541f53a4292e59194c4bcc4d891b Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Thu, 9 Nov 2023 15:05:25 +0100 Subject: [PATCH] Fixes --- Moose Development/Moose/Core/Base.lua | 2 +- Moose Development/Moose/Core/ClientMenu.lua | 94 +++++++++++++++++++-- Moose Development/Moose/Core/Database.lua | 68 +++++++++------ Moose Development/Moose/Ops/PlayerTask.lua | 18 ++-- Moose Development/Moose/Utilities/Utils.lua | 2 +- 5 files changed, 144 insertions(+), 40 deletions(-) diff --git a/Moose Development/Moose/Core/Base.lua b/Moose Development/Moose/Core/Base.lua index ce3675189..595f89279 100644 --- a/Moose Development/Moose/Core/Base.lua +++ b/Moose Development/Moose/Core/Base.lua @@ -1341,7 +1341,7 @@ function BASE:I( Arguments ) env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)", LineCurrent, LineFrom, "I", self.ClassName, self.ClassID, Function, UTILS.BasicSerialize( Arguments ) ) ) else - env.info( string.format( "%1s:%30s%05d(%s)", "I", self.ClassName, self.ClassID, UTILS.BasicSerialize( Arguments ) ) ) + env.info( string.format( "%1s:%30s%05d(%s)", "I", self.ClassName, self.ClassID, UTILS.OneLineSerialize( Arguments ) ) ) end end diff --git a/Moose Development/Moose/Core/ClientMenu.lua b/Moose Development/Moose/Core/ClientMenu.lua index d5ace7d9e..ff52def04 100644 --- a/Moose Development/Moose/Core/ClientMenu.lua +++ b/Moose Development/Moose/Core/ClientMenu.lua @@ -20,7 +20,7 @@ -- -- @module Core.ClientMenu -- @image Core_Menu.JPG --- last change: Sept 2023 +-- last change: Oct 2023 -- TODO ---------------------------------------------------------------------------------------------------------------- @@ -304,6 +304,8 @@ end -- @field #table menutree -- @field #number entrycount -- @field #boolean debug +-- @field #table PlayerMenu +-- @field #number Coalition -- @extends Core.Base#BASE --- *As a child my family's menu consisted of two choices: take it, or leave it.* @@ -390,7 +392,7 @@ end CLIENTMENUMANAGER = { ClassName = "CLIENTMENUMANAGER", lid = "", - version = "0.1.1", + version = "0.1.3", name = nil, clientset = nil, menutree = {}, @@ -399,26 +401,108 @@ CLIENTMENUMANAGER = { entrycount = 0, rootentries = {}, debug = true, + PlayerMenu = {}, + Coalition = nil, } --- Create a new ClientManager instance. -- @param #CLIENTMENUMANAGER self -- @param Core.Set#SET_CLIENT ClientSet The set of clients to manage. -- @param #string Alias The name of this manager. +-- @param #number Coalition (Optional) Coalition of this Manager, defaults to coalition.side.BLUE -- @return #CLIENTMENUMANAGER self -function CLIENTMENUMANAGER:New(ClientSet, Alias) +function CLIENTMENUMANAGER:New(ClientSet, Alias, Coalition) -- Inherit everything from FSM class. local self=BASE:Inherit(self, BASE:New()) -- #CLIENTMENUMANAGER self.clientset = ClientSet + self.PlayerMenu = {} self.name = Alias or "Nightshift" + self.Coalition = Coalition or coalition.side.BLUE -- Log id. self.lid=string.format("CLIENTMENUMANAGER %s | %s | ", self.version, self.name) if self.debug then - self:T(self.lid.."Created") + self:I(self.lid.."Created") end return self end +--- [Internal] Event handling +-- @param #CLIENTMENUMANAGER self +-- @param Core.Event#EVENTDATA EventData +-- @return #CLIENTMENUMANAGER self +function CLIENTMENUMANAGER:_EventHandler(EventData) + self:T(self.lid.."_EventHandler: "..EventData.id) + --self:I(self.lid.."_EventHandler: "..tostring(EventData.IniPlayerName)) + if EventData.id == EVENTS.PlayerLeaveUnit or EventData.id == EVENTS.Ejection or EventData.id == EVENTS.Crash or EventData.id == EVENTS.PilotDead then + self:T(self.lid.."Leave event for player: "..tostring(EventData.IniPlayerName)) + local Client = _DATABASE:FindClient( EventData.IniPlayerName ) + if Client then + self:ResetMenu(Client) + end + elseif (EventData.id == EVENTS.PlayerEnterAircraft) and EventData.IniCoalition == self.Coalition then + if EventData.IniPlayerName and EventData.IniGroup then + if (not self.clientset:IsIncludeObject(_DATABASE:FindClient( EventData.IniPlayerName ))) then + self:T(self.lid.."Client not in SET: "..EventData.IniPlayerName) + return self + end + --self:I(self.lid.."Join event for player: "..EventData.IniPlayerName) + local player = _DATABASE:FindClient( EventData.IniPlayerName ) + self:Propagate(player) + end + elseif EventData.id == EVENTS.PlayerEnterUnit then + -- special for CA slots + local grp = GROUP:FindByName(EventData.IniGroupName) + if grp:IsGround() then + self:T(string.format("Player %s entered GROUND unit %s!",EventData.IniPlayerName,EventData.IniUnitName)) + local IsPlayer = EventData.IniDCSUnit:getPlayerName() + if IsPlayer then + + local client=_DATABASE.CLIENTS[EventData.IniDCSUnitName] --Wrapper.Client#CLIENT + + -- Add client in case it does not exist already. + if not client then + + -- Debug info. + self:I(string.format("Player '%s' joined ground unit '%s' of group '%s'", tostring(EventData.IniPlayerName), tostring(EventData.IniDCSUnitName), tostring(EventData.IniDCSGroupName))) + + client=_DATABASE:AddClient(EventData.IniDCSUnitName) + + -- Add player. + client:AddPlayer(EventData.IniPlayerName) + + -- Add player. + if not _DATABASE.PLAYERS[EventData.IniPlayerName] then + _DATABASE:AddPlayer( EventData.IniUnitName, EventData.IniPlayerName ) + end + + -- Player settings. + local Settings = SETTINGS:Set( EventData.IniPlayerName ) + Settings:SetPlayerMenu(EventData.IniUnit) + end + --local player = _DATABASE:FindClient( EventData.IniPlayerName ) + self:Propagate(client) + end + end + end + + return self +end + +--- Set this Client Manager to auto-propagate menus to newly joined players. Useful if you have **one** menu structure only. +-- @param #CLIENTMENUMANAGER self +-- @return #CLIENTMENUMANAGER self +function CLIENTMENUMANAGER:InitAutoPropagation() + -- Player Events + self:HandleEvent(EVENTS.PlayerLeaveUnit, self._EventHandler) + self:HandleEvent(EVENTS.Ejection, self._EventHandler) + self:HandleEvent(EVENTS.Crash, self._EventHandler) + self:HandleEvent(EVENTS.PilotDead, self._EventHandler) + self:HandleEvent(EVENTS.PlayerEnterAircraft, self._EventHandler) + self:HandleEvent(EVENTS.PlayerEnterUnit, self._EventHandler) + self:SetEventPriority(5) + return self +end + --- Create a new entry in the generic structure. -- @param #CLIENTMENUMANAGER self -- @param #string Text Text of the F10 menu entry. @@ -571,7 +655,7 @@ end -- @return #CLIENTMENU Entry function CLIENTMENUMANAGER:Propagate(Client) self:T(self.lid.."Propagate") - self:T(Client) + --self:I(UTILS.PrintTableToLog(Client,1)) local Set = self.clientset.Set if Client then Set = {Client} diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index 1e8bd40d4..75f7be002 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -126,6 +126,8 @@ function DATABASE:New() self:SetEventPriority( 1 ) self:HandleEvent( EVENTS.Birth, self._EventOnBirth ) + -- DCS 2.9 fixed CA event for players -- TODO: reset unit when leaving + self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit ) self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.RemoveUnit, self._EventOnDeadOrCrash ) @@ -810,6 +812,7 @@ function DATABASE:AddPlayer( UnitName, PlayerName ) self.PLAYERUNITS[PlayerName] = self:FindUnit( UnitName ) self.PLAYERSJOINED[PlayerName] = PlayerName end + end --- Deletes a player from the DATABASE based on the Player Name. @@ -1470,39 +1473,43 @@ function DATABASE:_EventOnDeadOrCrash( Event ) end ---- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied). +--- Handles the OnPlayerEnterUnit event to fill the active players table for CA units (with the unit filter applied). -- @param #DATABASE self -- @param Core.Event#EVENTDATA Event function DATABASE:_EventOnPlayerEnterUnit( Event ) self:F2( { Event } ) if Event.IniDCSUnit then - if Event.IniObjectCategory == 1 then + -- Player entering a CA slot + if Event.IniObjectCategory == 1 and Event.IniGroup and Event.IniGroup:IsGround() then + + local IsPlayer = Event.IniDCSUnit:getPlayerName() + if IsPlayer then - -- Add unit. - self:AddUnit( Event.IniDCSUnitName ) + -- Debug info. + self:I(string.format("Player '%s' joined GROUND unit '%s' of group '%s'", tostring(Event.IniPlayerName), tostring(Event.IniDCSUnitName), tostring(Event.IniDCSGroupName))) + + local client= self.CLIENTS[Event.IniDCSUnitName] --Wrapper.Client#CLIENT + + -- Add client in case it does not exist already. + if not client then + client=self:AddClient(Event.IniDCSUnitName) + end + + -- Add player. + client:AddPlayer(Event.IniPlayerName) - -- Ini unit. - Event.IniUnit = self:FindUnit( Event.IniDCSUnitName ) - - -- Add group. - self:AddGroup( Event.IniDCSGroupName ) - - -- Get player unit. - local PlayerName = Event.IniDCSUnit:getPlayerName() - - if PlayerName then - - if not self.PLAYERS[PlayerName] then - self:AddPlayer( Event.IniDCSUnitName, PlayerName ) + -- Add player. + if not self.PLAYERS[Event.IniPlayerName] then + self:AddPlayer( Event.IniUnitName, Event.IniPlayerName ) end - local Settings = SETTINGS:Set( PlayerName ) - Settings:SetPlayerMenu( Event.IniUnit ) + -- Player settings. + local Settings = SETTINGS:Set( Event.IniPlayerName ) + Settings:SetPlayerMenu(Event.IniUnit) - else - self:E("ERROR: getPlayerName() returned nil for event PlayerEnterUnit") end + end end end @@ -1513,15 +1520,26 @@ end -- @param Core.Event#EVENTDATA Event function DATABASE:_EventOnPlayerLeaveUnit( Event ) self:F2( { Event } ) - + + local function FindPlayerName(UnitName) + local playername = nil + for _name,_unitname in pairs(self.PLAYERS) do + if _unitname == UnitName then + playername = _name + break + end + end + return playername + end + if Event.IniUnit then if Event.IniObjectCategory == 1 then -- Try to get the player name. This can be buggy for multicrew aircraft! - local PlayerName = Event.IniUnit:GetPlayerName() - - if PlayerName then --and self.PLAYERS[PlayerName] then + local PlayerName = Event.IniUnit:GetPlayerName() or FindPlayerName(Event.IniUnitName) + + if PlayerName then -- Debug info. self:I(string.format("Player '%s' left unit %s", tostring(PlayerName), tostring(Event.IniUnitName))) diff --git a/Moose Development/Moose/Ops/PlayerTask.lua b/Moose Development/Moose/Ops/PlayerTask.lua index c840f5538..a4d019531 100644 --- a/Moose Development/Moose/Ops/PlayerTask.lua +++ b/Moose Development/Moose/Ops/PlayerTask.lua @@ -1552,7 +1552,7 @@ PLAYERTASKCONTROLLER.Messages = { --- PLAYERTASK class version. -- @field #string version -PLAYERTASKCONTROLLER.version="0.1.62" +PLAYERTASKCONTROLLER.version="0.1.63" --- Create and run a new TASKCONTROLLER instance. -- @param #PLAYERTASKCONTROLLER self @@ -1585,7 +1585,7 @@ function PLAYERTASKCONTROLLER:New(Name, Coalition, Type, ClientFilter) self.TaskQueue = FIFO:New() -- Utilities.FiFo#FIFO self.TasksPerPlayer = FIFO:New() -- Utilities.FiFo#FIFO self.PrecisionTasks = FIFO:New() -- Utilities.FiFo#FIFO - self.PlayerMenu = {} -- #table + --self.PlayerMenu = {} -- #table self.FlashPlayer = {} -- #table self.AllowFlash = false self.lasttaskcount = 0 @@ -2175,10 +2175,10 @@ function PLAYERTASKCONTROLLER:_EventHandler(EventData) if EventData.id == EVENTS.PlayerLeaveUnit or EventData.id == EVENTS.Ejection or EventData.id == EVENTS.Crash or EventData.id == EVENTS.PilotDead then if EventData.IniPlayerName then self:T(self.lid.."Event for player: "..EventData.IniPlayerName) - if self.PlayerMenu[EventData.IniPlayerName] then - self.PlayerMenu[EventData.IniPlayerName]:Remove() - self.PlayerMenu[EventData.IniPlayerName] = nil - end + --if self.PlayerMenu[EventData.IniPlayerName] then + --self.PlayerMenu[EventData.IniPlayerName]:Remove() + --self.PlayerMenu[EventData.IniPlayerName] = nil + --end local text = "" if self.TasksPerPlayer:HasUniqueID(EventData.IniPlayerName) then local task = self.TasksPerPlayer:PullByID(EventData.IniPlayerName) -- Ops.PlayerTask#PLAYERTASK @@ -2187,6 +2187,8 @@ function PLAYERTASKCONTROLLER:_EventHandler(EventData) task:RemoveClient(Client) --text = "Task aborted!" text = self.gettext:GetEntry("TASKABORT",self.locale) + self.ActiveTaskMenuTemplate:ResetMenu(Client) + self.JoinTaskMenuTemplate:ResetMenu(Client) else task:RemoveClient(nil,EventData.IniPlayerName) --text = "Task aborted!" @@ -2236,8 +2238,8 @@ function PLAYERTASKCONTROLLER:_EventHandler(EventData) self.SRSQueue:NewTransmission(text,nil,self.SRS,timer.getAbsTime()+60,2,{EventData.IniGroup},text,30,self.BCFrequency,self.BCModulation) end if EventData.IniPlayerName then - self.PlayerMenu[EventData.IniPlayerName] = nil - local player = CLIENT:FindByName(EventData.IniUnitName) + --self.PlayerMenu[EventData.IniPlayerName] = nil + local player = _DATABASE:FindClient( EventData.IniPlayerName ) self:_SwitchMenuForClient(player,"Info") end end diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index 24d29e0c9..33350e85e 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -443,7 +443,7 @@ end --- Print a table to log in a nice format -- @param #table table The table to print --- @param #number ident Number of idents +-- @param #number indent Number of idents function UTILS.PrintTableToLog(table, indent) if not table then env.warning("No table passed!")