diff --git a/Moose Development/Moose/Core/ClientMenu.lua b/Moose Development/Moose/Core/ClientMenu.lua index 7d4fecde6..1ec4f01a6 100644 --- a/Moose Development/Moose/Core/ClientMenu.lua +++ b/Moose Development/Moose/Core/ClientMenu.lua @@ -668,7 +668,7 @@ function CLIENTMENUMANAGER:Propagate(Client) for _,_client in pairs(Set) do local client = _client -- Wrapper.Client#CLIENT if client and client:IsAlive() then - local playername = client:GetPlayerName() + local playername = client:GetPlayerName() or "none" if not self.playertree[playername] then self.playertree[playername] = {} end diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index 6082a9fd6..e6e308c8d 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -4030,8 +4030,8 @@ do -- SET_CLIENT Countries = nil, ClientPrefixes = nil, Zones = nil, - Playernames = nil, - Callsigns = nil, + Playernames = nil, + Callsigns = nil, }, FilterMeta = { Coalitions = { @@ -4317,6 +4317,8 @@ do -- SET_CLIENT self:UnHandleEvent(EVENTS.Birth) self:UnHandleEvent(EVENTS.Dead) self:UnHandleEvent(EVENTS.Crash) + --self:UnHandleEvent(EVENTS.PlayerEnterUnit) + --self:UnHandleEvent(EVENTS.PlayerLeaveUnit) if self.Filter.Zones and self.ZoneTimer and self.ZoneTimer:IsRunning() then self.ZoneTimer:Stop() @@ -4335,6 +4337,9 @@ do -- SET_CLIENT self:HandleEvent( EVENTS.Birth, self._EventOnBirth ) self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash ) + --self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventPlayerEnterUnit) + --self:HandleEvent( EVENTS.PlayerLeaveUnit, self._EventPlayerLeaveUnit) + --self:SetEventPriority(1) if self.Filter.Zones then self.ZoneTimer = TIMER:New(self._ContinousZoneFilter,self) local timing = self.ZoneTimerInterval or 30 @@ -4345,6 +4350,43 @@ do -- SET_CLIENT return self end + + --- Handle CA slots addition + -- @param #SET_CLIENT self + -- @param Core.Event#EVENTDATA Event + -- @return #SET_CLIENT self + function SET_CLIENT:_EventPlayerEnterUnit(Event) + self:I( "_EventPlayerEnterUnit" ) + if Event.IniDCSUnit then + if Event.IniObjectCategory == 1 and Event.IniGroup and Event.IniGroup:IsGround() then + -- CA Slot entered + local ObjectName, Object = self:AddInDatabase( Event ) + self:I( ObjectName, UTILS.PrintTableToLog(Object) ) + if Object and self:IsIncludeObject( Object ) then + self:Add( ObjectName, Object ) + end + end + end + return self + end + + --- Handle CA slots removal + -- @param #SET_CLIENT self + -- @param Core.Event#EVENTDATA Event + -- @return #SET_CLIENT self + function SET_CLIENT:_EventPlayerLeaveUnit(Event) + self:I( "_EventPlayerLeaveUnit" ) + if Event.IniDCSUnit then + if Event.IniObjectCategory == 1 and Event.IniGroup and Event.IniGroup:IsGround() then + -- CA Slot left + local ObjectName, Object = self:FindInDatabase( Event ) + if ObjectName then + self:Remove( ObjectName ) + end + end + end + return self + end --- Handles the Database to check on an event (birth) that the Object was added in the Database. -- This is required, because sometimes the _DATABASE birth event gets called later than the SET_BASE birth event! @@ -4548,45 +4590,45 @@ do -- SET_CLIENT MClientInclude = MClientInclude and MClientPrefix end - if self.Filter.Zones then - local MClientZone = false - for ZoneName, Zone in pairs( self.Filter.Zones ) do - self:T3( "Zone:", ZoneName ) - local unit = MClient:GetClientGroupUnit() - if unit and unit:IsInZone(Zone) then - MClientZone = true - end - end - MClientInclude = MClientInclude and MClientZone - end - - if self.Filter.Playernames then - local MClientPlayername = false - local playername = MClient:GetPlayerName() or "Unknown" - --self:T(playername) - for _,_Playername in pairs(self.Filter.Playernames) do - if playername and string.find(playername,_Playername) then - MClientPlayername = true - end - end - self:T( { "Evaluated Playername", MClientPlayername } ) - MClientInclude = MClientInclude and MClientPlayername - end - - if self.Filter.Callsigns then - local MClientCallsigns = false - local callsign = MClient:GetCallsign() - --self:I(callsign) - for _,_Callsign in pairs(self.Filter.Callsigns) do - if callsign and string.find(callsign,_Callsign,1,true) then - MClientCallsigns = true - end - end - self:T( { "Evaluated Callsign", MClientCallsigns } ) - MClientInclude = MClientInclude and MClientCallsigns - end - - end + if self.Filter.Zones then + local MClientZone = false + for ZoneName, Zone in pairs( self.Filter.Zones ) do + self:T3( "Zone:", ZoneName ) + local unit = MClient:GetClientGroupUnit() + if unit and unit:IsInZone(Zone) then + MClientZone = true + end + end + MClientInclude = MClientInclude and MClientZone + end + + if self.Filter.Playernames then + local MClientPlayername = false + local playername = MClient:GetPlayerName() or "Unknown" + --self:T(playername) + for _,_Playername in pairs(self.Filter.Playernames) do + if playername and string.find(playername,_Playername) then + MClientPlayername = true + end + end + self:T( { "Evaluated Playername", MClientPlayername } ) + MClientInclude = MClientInclude and MClientPlayername + end + + if self.Filter.Callsigns then + local MClientCallsigns = false + local callsign = MClient:GetCallsign() + --self:I(callsign) + for _,_Callsign in pairs(self.Filter.Callsigns) do + if callsign and string.find(callsign,_Callsign,1,true) then + MClientCallsigns = true + end + end + self:T( { "Evaluated Callsign", MClientCallsigns } ) + MClientInclude = MClientInclude and MClientCallsigns + end + + end self:T2( MClientInclude ) return MClientInclude end diff --git a/Moose Development/Moose/Functional/Autolase.lua b/Moose Development/Moose/Functional/Autolase.lua index 109a5c335..381d013b9 100644 --- a/Moose Development/Moose/Functional/Autolase.lua +++ b/Moose Development/Moose/Functional/Autolase.lua @@ -74,7 +74,7 @@ -- @image Designation.JPG -- -- Date: 24 Oct 2021 --- Last Update: Aug 2022 +-- Last Update: Oct 2023 -- --- Class AUTOLASE -- @type AUTOLASE @@ -84,6 +84,9 @@ -- @field #string alias -- @field #boolean debug -- @field #string version +-- @field Core.Set#SET_GROUP RecceSet +-- @field #table LaserCodes +-- @field #table playermenus -- @extends Ops.Intel#INTEL --- @@ -109,9 +112,10 @@ AUTOLASE = { -- @field #string unittype -- @field Core.Point#COORDINATE coordinate + --- AUTOLASE class version. -- @field #string version -AUTOLASE.version = "0.1.21" +AUTOLASE.version = "0.1.22" ------------------------------------------------------------------- -- Begin Functional.Autolase.lua @@ -196,6 +200,8 @@ function AUTOLASE:New(RecceSet, Coalition, Alias, PilotSet) self.NoMenus = false self.minthreatlevel = 0 self.blacklistattributes = {} + self:SetLaserCodes( { 1688, 1130, 4785, 6547, 1465, 4578 } ) -- set self.LaserCodes + self.playermenus = {} -- Set some string id for output to DCS.log file. self.lid=string.format("AUTOLASE %s (%s) | ", self.alias, self.coalition and UTILS.GetCoalitionName(self.coalition) or "unknown") @@ -214,7 +220,7 @@ function AUTOLASE:New(RecceSet, Coalition, Alias, PilotSet) if PilotSet then self.usepilotset = true self.pilotset = PilotSet - self:HandleEvent(EVENTS.PlayerEnterAircraft) + self:HandleEvent(EVENTS.PlayerEnterAircraft,self._EventHandler) --self:SetPilotMenu() end --self.SetPilotMenu() @@ -298,6 +304,16 @@ end -- Helper Functions ------------------------------------------------------------------- +--- [User] Set a table of possible laser codes. +-- Each new RECCE can select a code from this table, default is { 1688, 1130, 4785, 6547, 1465, 4578 } . +-- @param #AUTOLASE self +-- @param #list<#number> LaserCodes +-- @return #AUTOLASE +function AUTOLASE:SetLaserCodes( LaserCodes ) + self.LaserCodes = ( type( LaserCodes ) == "table" ) and LaserCodes or { LaserCodes } + return self +end + --- (Internal) Function to set pilot menu. -- @param #AUTOLASE self -- @return #AUTOLASE self @@ -308,8 +324,28 @@ function AUTOLASE:SetPilotMenu() local Unit = _unit -- Wrapper.Unit#UNIT if Unit and Unit:IsAlive() then local Group = Unit:GetGroup() - local lasemenu = MENU_GROUP_COMMAND:New(Group,"Autolase Status",nil,self.ShowStatus,self,Group,Unit) - lasemenu:Refresh() + local unitname = Unit:GetName() + if self.playermenus[unitname] then self.playermenus[unitname]:Remove() end + local lasetopm = MENU_GROUP:New(Group,"Autolase",nil) + self.playermenus[unitname] = lasetopm + local lasemenu = MENU_GROUP_COMMAND:New(Group,"Status",lasetopm,self.ShowStatus,self,Group,Unit) + for _,_grp in pairs(self.RecceSet.Set) do + local grp = _grp -- Wrapper.Group#GROUP + local unit = grp:GetUnit(1) + --local name = grp:GetName() + if unit and unit:IsAlive() then + local name = unit:GetName() + local mname = string.gsub(name,".%d+.%d+$","") + local code = self:GetLaserCode(name) + local unittop = MENU_GROUP:New(Group,"Change laser code for "..mname,lasetopm) + for _,_code in pairs(self.LaserCodes) do + local text = tostring(_code) + if _code == code then text = text.."(*)" end + local changemenu = MENU_GROUP_COMMAND:New(Group,text,unittop,self.SetRecceLaserCode,self,name,_code,true) + end + end + end + --lasemenu:Refresh() end end else @@ -324,7 +360,7 @@ end -- @param #AUTOLASE self -- @param Core.Event#EVENTDATA EventData -- @return #AUTOLASE self -function AUTOLASE:OnEventPlayerEnterAircraft(EventData) +function AUTOLASE:_EventHandler(EventData) self:SetPilotMenu() return self end @@ -397,7 +433,7 @@ end --- (User) Function enable sending messages via SRS. -- @param #AUTOLASE self -- @param #boolean OnOff Switch usage on and off --- @param #string Path Path to SRS directory, e.g. C:\\Program Files\\DCS-SimpleRadio-Standalon +-- @param #string Path Path to SRS directory, e.g. C:\\Program Files\\DCS-SimpleRadio-Standalone -- @param #number Frequency Frequency to send, e.g. 243 -- @param #number Modulation Modulation i.e. radio.modulation.AM or radio.modulation.FM -- @param #string Label (Optional) Short label to be used on the SRS Client Overlay @@ -465,10 +501,20 @@ end -- @param #AUTOLASE self -- @param #string RecceName (Unit!) Name of the Recce -- @param #number Code The lase code +-- @param #boolean Refresh If true, refresh menu entries -- @return #AUTOLASE self -function AUTOLASE:SetRecceLaserCode(RecceName, Code) +function AUTOLASE:SetRecceLaserCode(RecceName, Code, Refresh) local code = Code or 1688 self.RecceLaserCode[RecceName] = code + if Refresh then + self:SetPilotMenu() + if self.notifypilots then + if string.find(RecceName,"#") then + RecceName = string.match(RecceName,"^(.*)#") + end + self:NotifyPilots(string.format("Code for %s set to: %d",RecceName,Code),15) + end + end return self end @@ -995,6 +1041,9 @@ end function AUTOLASE:onbeforeRecceKIA(From,Event,To,RecceName) self:T({From, Event, To, RecceName}) if self.notifypilots or self.debug then + if string.find(RecceName,"#") then + RecceName = string.match(RecceName,"^(.*)#") + end local text = string.format("Recce %s KIA!",RecceName) self:NotifyPilots(text,self.reporttimeshort) end @@ -1029,6 +1078,9 @@ end function AUTOLASE:onbeforeTargetLost(From,Event,To,UnitName,RecceName) self:T({From, Event, To, UnitName,RecceName}) if self.notifypilots or self.debug then + if string.find(RecceName,"#") then + RecceName = string.match(RecceName,"^(.*)#") + end local text = string.format("%s lost sight of unit %s.",RecceName,UnitName) self:NotifyPilots(text,self.reporttimeshort) end @@ -1046,6 +1098,9 @@ end function AUTOLASE:onbeforeLaserTimeout(From,Event,To,UnitName,RecceName) self:T({From, Event, To, UnitName,RecceName}) if self.notifypilots or self.debug then + if string.find(RecceName,"#") then + RecceName = string.match(RecceName,"^(.*)#") + end local text = string.format("%s laser timeout on unit %s.",RecceName,UnitName) self:NotifyPilots(text,self.reporttimeshort) end @@ -1063,10 +1118,9 @@ function AUTOLASE:onbeforeLasing(From,Event,To,LaserSpot) self:T({From, Event, To, LaserSpot.unittype}) if self.notifypilots or self.debug then local laserspot = LaserSpot -- #AUTOLASE.LaserSpot - local name = laserspot.reccename - if string.find(name,"#") then + local name = laserspot.reccename if string.find(name,"#") then name = string.match(name,"^(.*)#") - end + end local text = string.format("%s is lasing %s code %d\nat %s",name,laserspot.unittype,laserspot.lasercode,laserspot.location) self:NotifyPilots(text,self.reporttimeshort+5) end diff --git a/Moose Development/Moose/Ops/PlayerRecce.lua b/Moose Development/Moose/Ops/PlayerRecce.lua index d83d16183..f06edd09e 100644 --- a/Moose Development/Moose/Ops/PlayerRecce.lua +++ b/Moose Development/Moose/Ops/PlayerRecce.lua @@ -486,7 +486,7 @@ function PLAYERRECCE:_GetClockDirection(unit, target) end --- [User] Set a table of possible laser codes. --- Each new RECCE can select a code from this table, default is 1688. +-- Each new RECCE can select a code from this table, default is { 1688, 1130, 4785, 6547, 1465, 4578 }. -- @param #PLAYERRECCE self -- @param #list<#number> LaserCodes -- @return #PLAYERRECCE