From 72bb23ed0d7111f92063073e332ef4cf5d621550 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Fri, 17 Jan 2025 09:55:12 +0100 Subject: [PATCH 1/3] xx --- .../Moose/Functional/Autolase.lua | 22 ++++- Moose Development/Moose/Ops/PlayerTask.lua | 85 +++++++++++++++++-- 2 files changed, 97 insertions(+), 10 deletions(-) diff --git a/Moose Development/Moose/Functional/Autolase.lua b/Moose Development/Moose/Functional/Autolase.lua index 423fc55fe..7a8545b79 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: May 2024 +-- Last Update: Jan 2025 -- --- Class AUTOLASE -- @type AUTOLASE @@ -89,6 +89,7 @@ -- @field #table playermenus -- @field #boolean smokemenu -- @field #boolean threatmenu +-- @field #number RoundingPrecision -- @extends Ops.Intel#INTEL --- @@ -100,6 +101,7 @@ AUTOLASE = { alias = "", debug = false, smokemenu = true, + RoundingPrecision = 0, } --- Laser spot info @@ -118,7 +120,7 @@ AUTOLASE = { --- AUTOLASE class version. -- @field #string version -AUTOLASE.version = "0.1.26" +AUTOLASE.version = "0.1.27" ------------------------------------------------------------------- -- Begin Functional.Autolase.lua @@ -207,6 +209,7 @@ function AUTOLASE:New(RecceSet, Coalition, Alias, PilotSet) self.playermenus = {} self.smokemenu = true self.threatmenu = true + self.RoundingPrecision = 0 -- 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") @@ -600,6 +603,15 @@ function AUTOLASE:SetSmokeTargets(OnOff,Color) return self end +--- (User) Function to set rounding precision for BR distance output. +-- @param #AUTOLASE self +-- @param #number IDP Rounding precision before/after the decimal sign. Defaults to zero. Positive values round right of the decimal sign, negative ones left of the decimal sign. +-- @return #AUTOLASE self +function AUTOLASE:SetRoundingPrecsion(IDP) + self.RoundingPrecision = IDP or 0 + return self +end + --- (User) Show the "Switch smoke target..." menu entry for pilots. On by default. -- @param #AUTOLASE self -- @return #AUTOLASE self @@ -786,8 +798,12 @@ function AUTOLASE:ShowStatus(Group,Unit) locationstring = entry.coordinate:ToStringMGRS(settings) elseif settings:IsA2G_LL_DMS() then locationstring = entry.coordinate:ToStringLLDMS(settings) + elseif settings:IsA2G_LL_DDM() then + locationstring = entry.coordinate:ToStringLLDDM(settings) elseif settings:IsA2G_BR() then - locationstring = entry.coordinate:ToStringBR(Group:GetCoordinate() or Unit:GetCoordinate(),settings) + -- attention this is the distance from the ASKING unit to target, not from RECCE to target! + local startcoordinate = Unit:GetCoordinate() or Group:GetCoordinate() + locationstring = entry.coordinate:ToStringBR(startcoordinate,settings,false,self.RoundingPrecision) end end end diff --git a/Moose Development/Moose/Ops/PlayerTask.lua b/Moose Development/Moose/Ops/PlayerTask.lua index 1258462a7..f30bc6f11 100644 --- a/Moose Development/Moose/Ops/PlayerTask.lua +++ b/Moose Development/Moose/Ops/PlayerTask.lua @@ -98,7 +98,7 @@ PLAYERTASK = { --- PLAYERTASK class version. -- @field #string version -PLAYERTASK.version="0.1.24" +PLAYERTASK.version="0.1.25" --- Generic task condition. -- @type PLAYERTASK.Condition @@ -700,6 +700,15 @@ function PLAYERTASK:IsDone() return IsDone end +--- [User] Check if task is NOT done +-- @param #PLAYERTASK self +-- @return #boolean done +function PLAYERTASK:IsNotDone() + self:T(self.lid.."IsNotDone?") + local IsNotDone = not self:IsDone() + return IsNotDone +end + --- [User] Check if PLAYERTASK has clients assigned to it. -- @param #PLAYERTASK self -- @return #boolean hasclients @@ -1156,7 +1165,7 @@ function PLAYERTASK:onafterCancel(From, Event, To) self.TaskController:__TaskCancelled(-1,self) end self.timestamp = timer.getAbsTime() - self.FinalState = "Cancel" + self.FinalState = "Cancelled" self:__Done(-1) return self end @@ -1308,6 +1317,8 @@ do -- @field Core.ClientMenu#CLIENTMENU ActiveTopMenu -- @field Core.ClientMenu#CLIENTMENU ActiveInfoMenu -- @field Core.ClientMenu#CLIENTMENU MenuNoTask +-- @field #boolean InformationMenu Show Radio Info Menu +-- @field #number TaskInfoDuration How long to show the briefing info on the screen -- @extends Core.Fsm#FSM --- @@ -1663,6 +1674,8 @@ PLAYERTASKCONTROLLER = { UseTypeNames = false, Scoring = nil, MenuNoTask = nil, + InformationMenu = false, + TaskInfoDuration = 30, } --- @@ -1799,6 +1812,7 @@ PLAYERTASKCONTROLLER.Messages = { CRUISER = "Cruiser", DESTROYER = "Destroyer", CARRIER = "Aircraft Carrier", + RADIOS = "Radios", }, DE = { TASKABORT = "Auftrag abgebrochen!", @@ -1882,12 +1896,13 @@ PLAYERTASKCONTROLLER.Messages = { CRUISER = "Kreuzer", DESTROYER = "Zerstörer", CARRIER = "Flugzeugträger", + RADIOS = "Frequenzen", }, } --- PLAYERTASK class version. -- @field #string version -PLAYERTASKCONTROLLER.version="0.1.67" +PLAYERTASKCONTROLLER.version="0.1.69" --- Create and run a new TASKCONTROLLER instance. -- @param #PLAYERTASKCONTROLLER self @@ -1949,6 +1964,10 @@ function PLAYERTASKCONTROLLER:New(Name, Coalition, Type, ClientFilter) self.UseTypeNames = false + self.InformationMenu = false + + self.TaskInfoDuration = 30 + self.IsClientSet = false if ClientFilter and type(ClientFilter) == "table" and ClientFilter.ClassName and ClientFilter.ClassName == "SET_CLIENT" then @@ -2166,6 +2185,16 @@ function PLAYERTASKCONTROLLER:SetAllowFlashDirection(OnOff) return self end +--- [User] Set to show a menu entry to retrieve the radio frequencies used. +-- @param #PLAYERTASKCONTROLLER self +-- @param #boolean OnOff Set to `true` to switch on and `false` to switch off. Default is OFF. +-- @return #PLAYERTASKCONTROLLER self +function PLAYERTASKCONTROLLER:SetShowRadioInfoMenu(OnOff) + self:T(self.lid.."SetAllowRadioInfoMenu") + self.InformationMenu = OnOff + return self +end + --- [User] Do not show menu entries to smoke or flare targets -- @param #PLAYERTASKCONTROLLER self -- @return #PLAYERTASKCONTROLLER self @@ -2261,7 +2290,7 @@ function PLAYERTASKCONTROLLER:_GetTextForSpeech(text) return text end ---- [User] Set repetition options for tasks +--- [User] Set repetition options for tasks. -- @param #PLAYERTASKCONTROLLER self -- @param #boolean OnOff Set to `true` to switch on and `false` to switch off (defaults to true) -- @param #number Repeats Number of repeats (defaults to 5) @@ -2279,6 +2308,16 @@ function PLAYERTASKCONTROLLER:SetTaskRepetition(OnOff, Repeats) return self end +--- [User] Set how long the briefing is shown on screen. +-- @param #PLAYERTASKCONTROLLER self +-- @param #number Seconds Duration in seconds. Defaults to 30 seconds. +-- @return #PLAYERTASKCONTROLLER self +function PLAYERTASKCONTROLLER:SetBriefingDuration(Seconds) + self:T(self.lid.."SetBriefingDuration") + self.TaskInfoDuration = Seconds or 30 + return self +end + --- [Internal] Send message to SET_CLIENT of players -- @param #PLAYERTASKCONTROLLER self -- @param #string Text the text to be send @@ -3464,6 +3503,32 @@ function PLAYERTASKCONTROLLER:_SwitchFlashing(Group, Client) return self end +function PLAYERTASKCONTROLLER:_ShowRadioInfo(Group, Client) + self:T(self.lid.."_ShowRadioInfo") + local playername, ttsplayername = self:_GetPlayerName(Client) + + if self.UseSRS then + local frequency = self.Frequency + local freqtext = "" + if type(frequency) == "table" then + freqtext = self.gettext:GetEntry("FREQUENCIES",self.locale) + freqtext = freqtext..table.concat(frequency,", ") + else + local freqt = self.gettext:GetEntry("FREQUENCY",self.locale) + freqtext = string.format(freqt,frequency) + end + + local switchtext = self.gettext:GetEntry("BROADCAST",self.locale) + + playername = ttsplayername or self:_GetTextForSpeech(playername) + --local text = string.format("%s, %s, switch to %s for task assignment!",EventData.IniPlayerName,self.MenuName or self.Name,freqtext) + local text = string.format(switchtext,playername,self.MenuName or self.Name,freqtext) + self.SRSQueue:NewTransmission(text,nil,self.SRS,nil,2,{Group},text,30,self.BCFrequency,self.BCModulation) + end + + return self +end + --- [Internal] Flashing directional info for a client -- @param #PLAYERTASKCONTROLLER self -- @return #PLAYERTASKCONTROLLER self @@ -3683,7 +3748,7 @@ function PLAYERTASKCONTROLLER:_ActiveTaskInfo(Task, Group, Client) text = self.gettext:GetEntry("NOACTIVETASK",self.locale) end if not self.NoScreenOutput then - local m=MESSAGE:New(text,15,"Tasking"):ToClient(Client) + local m=MESSAGE:New(text,self.TaskInfoDuration or 30,"Tasking"):ToClient(Client) end return self end @@ -4037,6 +4102,11 @@ function PLAYERTASKCONTROLLER:_CreateJoinMenuTemplate() self.MenuNoTask = nil end + if self.InformationMenu then + local radioinfo = self.gettext:GetEntry("RADIOS",self.locale) + JoinTaskMenuTemplate:NewEntry(radioinfo,self.JoinTopMenu,self._ShowRadioInfo,self) + end + self.JoinTaskMenuTemplate = JoinTaskMenuTemplate return self @@ -4376,8 +4446,9 @@ end -- @param #string PathToGoogleKey (Optional) Path to your google key if you want to use google TTS; if you use a config file for MSRS, hand in nil here. -- @param #string AccessKey (Optional) Your Google API access key. This is necessary if DCS-gRPC is used as backend; if you use a config file for MSRS, hand in nil here. -- @param Core.Point#COORDINATE Coordinate Coordinate from which the controller radio is sending +-- @param #string Backend (Optional) MSRS Backend to be used, can be MSRS.Backend.SRSEXE or MSRS.Backend.GRPC; if you use a config file for MSRS, hand in nil here. -- @return #PLAYERTASKCONTROLLER self -function PLAYERTASKCONTROLLER:SetSRS(Frequency,Modulation,PathToSRS,Gender,Culture,Port,Voice,Volume,PathToGoogleKey,AccessKey,Coordinate) +function PLAYERTASKCONTROLLER:SetSRS(Frequency,Modulation,PathToSRS,Gender,Culture,Port,Voice,Volume,PathToGoogleKey,AccessKey,Coordinate,Backend) self:T(self.lid.."SetSRS") self.PathToSRS = PathToSRS or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone" -- self.Gender = Gender or MSRS.gender or "male" -- @@ -4393,7 +4464,7 @@ function PLAYERTASKCONTROLLER:SetSRS(Frequency,Modulation,PathToSRS,Gender,Cultu self.Modulation = Modulation or {radio.modulation.FM,radio.modulation.AM} -- self.BCModulation = self.Modulation -- set up SRS - self.SRS=MSRS:New(self.PathToSRS,self.Frequency,self.Modulation) + self.SRS=MSRS:New(self.PathToSRS,self.Frequency,self.Modulation,Backend) self.SRS:SetCoalition(self.Coalition) self.SRS:SetLabel(self.MenuName or self.Name) self.SRS:SetGender(self.Gender) From 8d87531464ecca3c4dce54bce62c9bc2cd529540 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sat, 18 Jan 2025 15:32:08 +0100 Subject: [PATCH 2/3] #PLAYERRECCE - Add standard FOW for Kiowa --- Moose Development/Moose/Ops/PlayerRecce.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Moose Development/Moose/Ops/PlayerRecce.lua b/Moose Development/Moose/Ops/PlayerRecce.lua index 7091139cd..3ada7882c 100644 --- a/Moose Development/Moose/Ops/PlayerRecce.lua +++ b/Moose Development/Moose/Ops/PlayerRecce.lua @@ -106,7 +106,7 @@ PLAYERRECCE = { ClassName = "PLAYERRECCE", verbose = true, lid = nil, - version = "0.1.24", + version = "0.1.25", ViewZone = {}, ViewZoneVisual = {}, ViewZoneLaser = {}, @@ -166,7 +166,8 @@ PLAYERRECCE.MaxViewDistance = { ["SA342Minigun"] = 8000, ["SA342L"] = 8000, ["Ka-50"] = 8000, - ["Ka-50_3"] = 8000, + ["Ka-50_3"] = 8000, + ["OH58D"] = 8000, } --- From a3c13c8ceaad834b4cd838ec86885891d36c75ad Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sun, 19 Jan 2025 17:41:02 +0100 Subject: [PATCH 3/3] #PLAYERTASK - added option for custom player callsigns #PLAYERRECCE - added option for custom player callsigns #PLAYERRECCE - added KIOWA support --- Moose Development/Moose/Ops/PlayerRecce.lua | 151 +++++++++++++------- Moose Development/Moose/Ops/PlayerTask.lua | 12 +- 2 files changed, 110 insertions(+), 53 deletions(-) diff --git a/Moose Development/Moose/Ops/PlayerRecce.lua b/Moose Development/Moose/Ops/PlayerRecce.lua index 3ada7882c..1b518dbe2 100644 --- a/Moose Development/Moose/Ops/PlayerRecce.lua +++ b/Moose Development/Moose/Ops/PlayerRecce.lua @@ -106,7 +106,7 @@ PLAYERRECCE = { ClassName = "PLAYERRECCE", verbose = true, lid = nil, - version = "0.1.25", + version = "0.1.26", ViewZone = {}, ViewZoneVisual = {}, ViewZoneLaser = {}, @@ -154,7 +154,8 @@ PLAYERRECCE.LaserRelativePos = { ["SA342Minigun"] = { x = 1.7, y = 1.2, z = 0 }, ["SA342L"] = { x = 1.7, y = 1.2, z = 0 }, ["Ka-50"] = { x = 6.1, y = -0.85 , z = 0 }, - ["Ka-50_3"] = { x = 6.1, y = -0.85 , z = 0 } + ["Ka-50_3"] = { x = 6.1, y = -0.85 , z = 0 }, + ["OH58D"] = {x = 0, y = 2.8, z = 0}, } --- @@ -179,7 +180,8 @@ PLAYERRECCE.Cameraheight = { ["SA342Minigun"] = 2.85, ["SA342L"] = 2.85, ["Ka-50"] = 0.5, - ["Ka-50_3"] = 0.5, + ["Ka-50_3"] = 0.5, + ["OH58D"] = 4.25, } --- @@ -191,7 +193,8 @@ PLAYERRECCE.CanLase = { ["SA342Minigun"] = false, -- no optics ["SA342L"] = true, ["Ka-50"] = true, - ["Ka-50_3"] = true, + ["Ka-50_3"] = true, + ["OH58D"] = false, -- has onboard and useable laser } --- @@ -547,7 +550,7 @@ function PLAYERRECCE:SetAttackSet(AttackSet) return self end ----[Internal] Check Gazelle camera in on +---[Internal] Check Helicopter camera in on -- @param #PLAYERRECCE self -- @param Wrapper.Client#CLIENT client -- @param #string playername @@ -563,6 +566,12 @@ function PLAYERRECCE:_CameraOn(client,playername) if vivihorizontal < -0.7 or vivihorizontal > 0.7 then camera = false end + elseif string.find(typename,"OH58") then + local dcsunit = Unit.getByName(client:GetName()) + local vivihorizontal = dcsunit:getDrawArgumentValue(528) or 0 -- Kiow + if vivihorizontal < -0.527 or vivihorizontal > 0.527 then + camera = false + end elseif string.find(typename,"Ka-50") then camera = true end @@ -570,6 +579,52 @@ function PLAYERRECCE:_CameraOn(client,playername) return camera end +--- [Internal] Get the view parameters from a Kiowa MMS camera +-- @param #PLAYERRECCE self +-- @param Wrapper.Unit#UNIT Kiowa +-- @return #number cameraheading in degrees. +-- @return #number cameranodding in degrees. +-- @return #number maxview in meters. +-- @return #boolean cameraison If true, camera is on, else off. +function PLAYERRECCE:_GetKiowaMMSSight(Kiowa) + self:T(self.lid.."_GetKiowaMMSSight") + local unit = Kiowa -- Wrapper.Unit#UNIT + if unit and unit:IsAlive() then + local dcsunit = Unit.getByName(Kiowa:GetName()) + --[[ + shagrat — 01/01/2025 23:13 + Found the necessary ARGS for the Kiowa MMS angle and rotation: + Arg 527 vertical movement + 0 = neutral + -1.0 = max depression (30° max depression angle) + +1.0 = max elevation angle (30° max elevation angle) + + Arg 528 horizontal movement + 0 = forward (0 degr) + -0.25 = 90° left + -0.5 = rear (180°) left (max 190° = -0.527 + +0.25 = 90° right + +0.5 = 180° right (max 190° = 0.527) + --]] + local mmshorizontal = dcsunit:getDrawArgumentValue(528) or 0 + local mmsvertical = dcsunit:getDrawArgumentValue(527) or 0 + self:T(string.format("Kiowa MMS Arguments Read: H %.3f V %.3f",mmshorizontal,mmsvertical)) + local mmson = true + if mmshorizontal < -0.527 or mmshorizontal > 0.527 then mmson = false end + local horizontalview = mmshorizontal / 0.527 * 190 + local heading = unit:GetHeading() + local mmsheading = (heading+horizontalview)%360 + --local mmsyaw = mmsvertical * 30 + local mmsyaw = math.atan(mmsvertical)*40 + local maxview = self:_GetActualMaxLOSight(unit,mmsheading, mmsyaw,not mmson) + if maxview > 8000 then maxview = 8000 end + self:T(string.format("Kiowa MMS Heading %d, Yaw %d, MaxView %dm MMS On %s",mmsheading,mmsyaw,maxview,tostring(mmson))) + return mmsheading,mmsyaw,maxview,mmson + end + return 0,0,0,false +end + + --- [Internal] Get the view parameters from a Gazelle camera -- @param #PLAYERRECCE self -- @param Wrapper.Unit#UNIT Gazelle @@ -598,40 +653,15 @@ function PLAYERRECCE:_GetGazelleVivianneSight(Gazelle) vivioff = true return 0,0,0,false end - vivivertical = vivivertical / 1.10731 -- normalize + local horizontalview = vivihorizontal * -180 - local verticalview = vivivertical * 30 -- ca +/- 30° - --self:I(string.format("vivihorizontal=%.5f | vivivertical=%.5f",vivihorizontal,vivivertical)) - --self:I(string.format("horizontal=%.5f | vertical=%.5f",horizontalview,verticalview)) + --local verticalview = vivivertical * 30 -- ca +/- 30° + local verticalview = math.atan(vivivertical) + local heading = unit:GetHeading() local viviheading = (heading+horizontalview)%360 local maxview = self:_GetActualMaxLOSight(unit,viviheading, verticalview,vivioff) - --self:I(string.format("maxview=%.5f",maxview)) - -- visual skew - local factor = 3.15 - self.GazelleViewFactors = { - [1]=1.18, - [2]=1.32, - [3]=1.46, - [4]=1.62, - [5]=1.77, - [6]=1.85, - [7]=2.05, - [8]=2.05, - [9]=2.3, - [10]=2.3, - [11]=2.27, - [12]=2.27, - [13]=2.43, - } - local lfac = UTILS.Round(maxview,-2) - if lfac <= 1300 then - --factor = self.GazelleViewFactors[lfac/100] - factor = 3.15 - maxview = math.ceil((maxview*factor)/100)*100 - end if maxview > 8000 then maxview = 8000 end - --self:I(string.format("corrected maxview=%.5f",maxview)) return viviheading, verticalview,maxview, not vivioff end return 0,0,0,false @@ -652,20 +682,20 @@ function PLAYERRECCE:_GetActualMaxLOSight(unit,vheading, vnod, vivoff) if unit and unit:IsAlive() then local typename = unit:GetTypeName() maxview = self.MaxViewDistance[typename] or 8000 - local CamHeight = self.Cameraheight[typename] or 0 - if vnod < 0 then + local CamHeight = self.Cameraheight[typename] or 1 + if vnod < -2 then -- Looking down -- determine max distance we're looking at local beta = 90 - local gamma = math.floor(90-vnod) - local alpha = math.floor(180-beta-gamma) + local gamma = 90-math.abs(vnod) + local alpha = 90-gamma local a = unit:GetHeight()-unit:GetCoordinate():GetLandHeight()+CamHeight local b = a / math.sin(math.rad(alpha)) local c = b * math.sin(math.rad(gamma)) maxview = c*1.2 -- +20% end end - return math.abs(maxview) + return math.ceil(math.abs(maxview)) end --- [User] Set callsign options for TTS output. See @{Wrapper.Group#GROUP.GetCustomCallSign}() on how to set customized callsigns. @@ -674,8 +704,10 @@ end -- @param #boolean Keepnumber If true, keep the **customized callsign** in the #GROUP name for players as-is, no amendments or numbers. -- @param #table CallsignTranslations (optional) Table to translate between DCS standard callsigns and bespoke ones. Does not apply if using customized -- callsigns from playername or group name. +-- @param #func CallsignCustomFunc (Optional) For player names only(!). If given, this function will return the callsign. Needs to take the groupname and the playername as first two arguments. +-- @param #arg ... (Optional) Comma separated arguments to add to the custom function call after groupname and playername. -- @return #PLAYERRECCE self -function PLAYERRECCE:SetCallSignOptions(ShortCallsign,Keepnumber,CallsignTranslations) +function PLAYERRECCE:SetCallSignOptions(ShortCallsign,Keepnumber,CallsignTranslations,CallsignCustomFunc,...) if not ShortCallsign or ShortCallsign == false then self.ShortCallsign = false else @@ -683,6 +715,8 @@ function PLAYERRECCE:SetCallSignOptions(ShortCallsign,Keepnumber,CallsignTransla end self.Keepnumber = Keepnumber or false self.CallsignTranslations = CallsignTranslations + self.CallsignCustomFunc = CallsignCustomFunc + self.CallsignCustomArgs = arg or {} return self end @@ -818,6 +852,14 @@ function PLAYERRECCE:_GetTargetSet(unit,camera,laser) nod,maxview,camon = 10,1000,true angle = 10 maxview = self.MaxViewDistance[typename] or 5000 + elseif string.find(typename,"OH58") and camera then + --heading = unit:GetHeading() + nod,maxview,camon = 0,8000,true + heading,nod,maxview,camon = self:_GetKiowaMMSSight(unit) + angle = 8 + if maxview == 0 then + maxview = self.MaxViewDistance[typename] or 5000 + end else -- visual heading = unit:GetHeading() @@ -1362,6 +1404,7 @@ function PLAYERRECCE:_BuildMenus(Client) local client = _client -- Wrapper.Client#CLIENT if client and client:IsAlive() then local playername = client:GetPlayerName() + self:T("Menu for "..playername) if not self.UnitLaserCodes[playername] then self:_SetClientLaserCode(nil,nil,playername,1688) end @@ -1370,6 +1413,7 @@ function PLAYERRECCE:_BuildMenus(Client) end local group = client:GetGroup() if not self.ClientMenus[playername] then + self:T("Start Menubuild for "..playername) local canlase = self.CanLase[client:GetTypeName()] self.ClientMenus[playername] = MENU_GROUP:New(group,self.MenuName or self.Name or "RECCE") local txtonstation = self.OnStation[playername] and "ON" or "OFF" @@ -1586,6 +1630,15 @@ function PLAYERRECCE:EnableSmokeOwnPosition() return self end +--- [User] Enable auto lasing for the Kiowa OH-58D. +-- @param #PLAYERRECCE self +-- @return #PLAYERRECCE self +function PLAYERRECCE:EnableKiowaAutolase() + self:T(self.lid.."EnableKiowaAutolase") + self.CanLase.OH58D = true + return self +end + --- [User] Disable smoking of own position -- @param #PLAYERRECCE self -- @return #PLAYERRECCE @@ -1743,7 +1796,7 @@ end -- @return #PLAYERRECCE self function PLAYERRECCE:onafterRecceOnStation(From, Event, To, Client, Playername) self:T({From, Event, To}) - local callsign = Client:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations) + local callsign = Client:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations,self.CallsignCustomFunc,self.CallsignCustomArgs) local coord = Client:GetCoordinate() local coordtext = coord:ToStringBULLS(self.Coalition) if self.ReferencePoint then @@ -1752,7 +1805,7 @@ function PLAYERRECCE:onafterRecceOnStation(From, Event, To, Client, Playername) end local text1 = "Party time!" local text2 = string.format("All stations, FACA %s on station\nat %s!",callsign, coordtext) - local text2tts = string.format("All stations, FACA %s on station at %s!",callsign, coordtext) + local text2tts = string.format(" All stations, FACA %s on station at %s!",callsign, coordtext) text2tts = self:_GetTextForSpeech(text2tts) if self.debug then self:T(text2.."\n"..text2tts) @@ -1783,7 +1836,7 @@ end -- @return #PLAYERRECCE self function PLAYERRECCE:onafterRecceOffStation(From, Event, To, Client, Playername) self:T({From, Event, To}) - local callsign = Client:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations) + local callsign = Client:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations,self.CallsignCustomFunc,self.CallsignCustomArgs) local coord = Client:GetCoordinate() local coordtext = coord:ToStringBULLS(self.Coalition) if self.ReferencePoint then @@ -1923,7 +1976,7 @@ end -- @return #PLAYERRECCE self function PLAYERRECCE:onafterIllumination(From, Event, To, Client, Playername, TargetSet) self:T({From, Event, To}) - local callsign = Client:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations) + local callsign = Client:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations,self.CallsignCustomFunc,self.CallsignCustomArgs) local coord = Client:GetCoordinate() local coordtext = coord:ToStringBULLS(self.Coalition) if self.AttackSet then @@ -1966,7 +2019,7 @@ end -- @return #PLAYERRECCE self function PLAYERRECCE:onafterTargetsSmoked(From, Event, To, Client, Playername, TargetSet) self:T({From, Event, To}) - local callsign = Client:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations) + local callsign = Client:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations,self.CallsignCustomFunc,self.CallsignCustomArgs) local coord = Client:GetCoordinate() local coordtext = coord:ToStringBULLS(self.Coalition) if self.AttackSet then @@ -2009,7 +2062,7 @@ end -- @return #PLAYERRECCE self function PLAYERRECCE:onafterTargetsFlared(From, Event, To, Client, Playername, TargetSet) self:T({From, Event, To}) - local callsign = Client:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations) + local callsign = Client:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations,self.CallsignCustomFunc,self.CallsignCustomArgs) local coord = Client:GetCoordinate() local coordtext = coord:ToStringBULLS(self.Coalition) if self.AttackSet then @@ -2053,7 +2106,7 @@ end -- @return #PLAYERRECCE self function PLAYERRECCE:onafterTargetLasing(From, Event, To, Client, Target, Lasercode, Lasingtime) self:T({From, Event, To}) - local callsign = Client:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations) + local callsign = Client:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations,self.CallsignCustomFunc,self.CallsignCustomArgs) local Settings = ( Client and _DATABASE:GetPlayerSettings( Client:GetPlayerName() ) ) or _SETTINGS local coord = Client:GetCoordinate() local coordtext = coord:ToStringBULLS(self.Coalition,Settings) @@ -2100,7 +2153,7 @@ end -- @return #PLAYERRECCE self function PLAYERRECCE:onafterShack(From, Event, To, Client, Target) self:T({From, Event, To}) - local callsign = Client:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations) + local callsign = Client:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations,self.CallsignCustomFunc,self.CallsignCustomArgs) local Settings = ( Client and _DATABASE:GetPlayerSettings( Client:GetPlayerName() ) ) or _SETTINGS local coord = Client:GetCoordinate() local coordtext = coord:ToStringBULLS(self.Coalition,Settings) @@ -2147,7 +2200,7 @@ end -- @return #PLAYERRECCE self function PLAYERRECCE:onafterTargetLOSLost(From, Event, To, Client, Target) self:T({From, Event, To}) - local callsign = Client:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations) + local callsign = Client:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations,self.CallsignCustomFunc,self.CallsignCustomArgs) local Settings = ( Client and _DATABASE:GetPlayerSettings( Client:GetPlayerName() ) ) or _SETTINGS local coord = Client:GetCoordinate() local coordtext = coord:ToStringBULLS(self.Coalition,Settings) diff --git a/Moose Development/Moose/Ops/PlayerTask.lua b/Moose Development/Moose/Ops/PlayerTask.lua index f30bc6f11..dd9c18b52 100644 --- a/Moose Development/Moose/Ops/PlayerTask.lua +++ b/Moose Development/Moose/Ops/PlayerTask.lua @@ -2261,8 +2261,10 @@ end -- @param #boolean Keepnumber If true, keep the **customized callsign** in the #GROUP name for players as-is, no amendments or numbers. -- @param #table CallsignTranslations (optional) Table to translate between DCS standard callsigns and bespoke ones. Does not apply if using customized -- callsigns from playername or group name. +-- @param #func CallsignCustomFunc (Optional) For player names only(!). If given, this function will return the callsign. Needs to take the groupname and the playername as first two arguments. +-- @param #arg ... (Optional) Comma separated arguments to add to the custom function call after groupname and playername. -- @return #PLAYERTASKCONTROLLER self -function PLAYERTASKCONTROLLER:SetCallSignOptions(ShortCallsign,Keepnumber,CallsignTranslations) +function PLAYERTASKCONTROLLER:SetCallSignOptions(ShortCallsign,Keepnumber,CallsignTranslations,CallsignCustomFunc,...) if not ShortCallsign or ShortCallsign == false then self.ShortCallsign = false else @@ -2270,6 +2272,8 @@ function PLAYERTASKCONTROLLER:SetCallSignOptions(ShortCallsign,Keepnumber,Callsi end self.Keepnumber = Keepnumber or false self.CallsignTranslations = CallsignTranslations + self.CallsignCustomFunc = CallsignCustomFunc + self.CallsignCustomArgs = arg or {} return self end @@ -2481,7 +2485,7 @@ function PLAYERTASKCONTROLLER:_GetPlayerName(Client) if not self.customcallsigns[playername] then local playergroup = Client:GetGroup() if playergroup ~= nil then - ttsplayername = playergroup:GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations) + ttsplayername = playergroup:GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations,self.CallsignCustomFunc,self.CallsignCustomArgs) local newplayername = self:_GetTextForSpeech(ttsplayername) self.customcallsigns[playername] = newplayername ttsplayername = newplayername @@ -2621,7 +2625,7 @@ function PLAYERTASKCONTROLLER:_EventHandler(EventData) if self.customcallsigns[playername] then self.customcallsigns[playername] = nil end - playername = EventData.IniGroup:GetCustomCallSign(self.ShortCallsign,self.Keepnumber) + playername = EventData.IniGroup:GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations,self.CallsignCustomFunc,self.CallsignCustomArgs) end playername = self:_GetTextForSpeech(playername) --local text = string.format("%s, %s, switch to %s for task assignment!",EventData.IniPlayerName,self.MenuName or self.Name,freqtext) @@ -3641,7 +3645,7 @@ function PLAYERTASKCONTROLLER:_ActiveTaskInfo(Task, Group, Client) local pcoord = player:GetCoordinate() if pcoord:Get2DDistance(Coordinate) <= reachdist then inreach = true - local callsign = player:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations) + local callsign = player:GetGroup():GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations,self.CallsignCustomFunc,self.CallsignCustomArgs) local playername = player:GetPlayerName() local islasing = no if self.PlayerRecce.CanLase[player:GetTypeName()] and self.PlayerRecce.AutoLase[playername] then