#OPSGROUP

* Allow for customized CallSigns

#PLAYERTASK
* SRS output finetuning
This commit is contained in:
Applevangelist 2022-09-15 13:59:16 +02:00
parent af96e2f143
commit 7084d9e084
4 changed files with 108 additions and 49 deletions

View File

@ -327,7 +327,7 @@ FLIGHTCONTROL.FlightStatus={
--- FlightControl class version. --- FlightControl class version.
-- @field #string version -- @field #string version
FLIGHTCONTROL.version="0.7.2" FLIGHTCONTROL.version="0.7.3"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@ -357,8 +357,9 @@ FLIGHTCONTROL.version="0.7.2"
-- @param #number Frequency Radio frequency in MHz. Default 143.00 MHz. Can also be given as a `#table` of multiple frequencies. -- @param #number Frequency Radio frequency in MHz. Default 143.00 MHz. Can also be given as a `#table` of multiple frequencies.
-- @param #number Modulation Radio modulation: 0=AM (default), 1=FM. See `radio.modulation.AM` and `radio.modulation.FM` enumerators. Can also be given as a `#table` of multiple modulations. -- @param #number Modulation Radio modulation: 0=AM (default), 1=FM. See `radio.modulation.AM` and `radio.modulation.FM` enumerators. Can also be given as a `#table` of multiple modulations.
-- @param #string PathToSRS Path to the directory, where SRS is located. -- @param #string PathToSRS Path to the directory, where SRS is located.
-- @param #number Port Port of SRS Server, defaults to 5002
-- @return #FLIGHTCONTROL self -- @return #FLIGHTCONTROL self
function FLIGHTCONTROL:New(AirbaseName, Frequency, Modulation, PathToSRS) function FLIGHTCONTROL:New(AirbaseName, Frequency, Modulation, PathToSRS, Port)
-- Inherit everything from FSM class. -- Inherit everything from FSM class.
local self=BASE:Inherit(self, FSM:New()) -- #FLIGHTCONTROL local self=BASE:Inherit(self, FSM:New()) -- #FLIGHTCONTROL
@ -406,15 +407,23 @@ function FLIGHTCONTROL:New(AirbaseName, Frequency, Modulation, PathToSRS)
self:SetMarkHoldingPattern(true) self:SetMarkHoldingPattern(true)
self:SetRunwayRepairtime() self:SetRunwayRepairtime()
-- Set SRS Port
self:SetSRSPort(Port or 5002)
-- Set Callsign Options
self:SetCallSignOptions(true,true)
-- Init msrs queue. -- Init msrs queue.
self.msrsqueue=MSRSQUEUE:New(self.alias) self.msrsqueue=MSRSQUEUE:New(self.alias)
-- SRS for Tower. -- SRS for Tower.
self.msrsTower=MSRS:New(PathToSRS, Frequency, Modulation) self.msrsTower=MSRS:New(PathToSRS, Frequency, Modulation)
self.msrsTower:SetPort(self.Port)
self:SetSRSTower() self:SetSRSTower()
-- SRS for Pilot. -- SRS for Pilot.
self.msrsPilot=MSRS:New(PathToSRS, Frequency, Modulation) self.msrsPilot=MSRS:New(PathToSRS, Frequency, Modulation)
self.msrsPilot:SetPort(self.Port)
self:SetSRSPilot() self:SetSRSPilot()
-- Wait at least 10 seconds after last radio message before calling the next status update. -- Wait at least 10 seconds after last radio message before calling the next status update.
@ -567,6 +576,15 @@ function FLIGHTCONTROL:SetFrequency(Frequency, Modulation)
return self return self
end end
--- Set the SRS server port.
-- @param #FLIGHTCONTROL self
-- @param #number Port Port to be used. Defaults to 5002.
-- @return #FLIGHTCONTROL self
function FLIGHTCONTROL:SetSRSPort(Port)
self.Port = Port or 5002
return self
end
--- Set SRS options for a given MSRS object. --- Set SRS options for a given MSRS object.
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
-- @param Sound.SRS#MSRS msrs Moose SRS object. -- @param Sound.SRS#MSRS msrs Moose SRS object.
@ -576,8 +594,9 @@ end
-- @param #number Volume Volume. Default 1.0. -- @param #number Volume Volume. Default 1.0.
-- @param #string Label Name under which SRS transmitts. -- @param #string Label Name under which SRS transmitts.
-- @param #string PathToGoogleCredentials Path to google credentials json file. -- @param #string PathToGoogleCredentials Path to google credentials json file.
-- @param #number Port Server port for SRS
-- @return #FLIGHTCONTROL self -- @return #FLIGHTCONTROL self
function FLIGHTCONTROL:_SetSRSOptions(msrs, Gender, Culture, Voice, Volume, Label, PathToGoogleCredentials) function FLIGHTCONTROL:_SetSRSOptions(msrs, Gender, Culture, Voice, Volume, Label, PathToGoogleCredentials, Port)
-- Defaults: -- Defaults:
Gender=Gender or "female" Gender=Gender or "female"
@ -592,6 +611,7 @@ function FLIGHTCONTROL:_SetSRSOptions(msrs, Gender, Culture, Voice, Volume, Labe
msrs:SetLabel(Label) msrs:SetLabel(Label)
msrs:SetGoogle(PathToGoogleCredentials) msrs:SetGoogle(PathToGoogleCredentials)
msrs:SetCoalition(self:GetCoalition()) msrs:SetCoalition(self:GetCoalition())
msrs:SetPort(Port or self.Port or 5002)
end end
return self return self
@ -982,33 +1002,6 @@ end
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
function FLIGHTCONTROL:onbeforeStatusUpdate() function FLIGHTCONTROL:onbeforeStatusUpdate()
--[[
if self.Tlastmessage then
local Tnow=timer.getAbsTime()
-- Time interval between last radio message.
local dT=Tnow-self.Tlastmessage
if dT<self.dTmessage then
-- Time
local dt=self.dTmessage-dT+1
-- Debug info.
local text=string.format("Last message sent %d sec ago. Will call status again in %d sec", dT, dt)
self:T(self.lid..text)
-- Call status again in dt seconds.
self:__StatusUpdate(-dt)
-- Deny transition.
return false
else
self:T2(self.lid..string.format("Last radio sent %d>%d sec ago. Status update allowed", dT, self.dTmessage))
end
end
]]
local Tqueue=self.msrsqueue:CalcTransmisstionDuration() local Tqueue=self.msrsqueue:CalcTransmisstionDuration()
if Tqueue>0 then if Tqueue>0 then
@ -2633,8 +2626,18 @@ function FLIGHTCONTROL:_PlayerRadioCheck(groupname)
local callsign=self:_GetCallsignName(flight) local callsign=self:_GetCallsignName(flight)
-- Pilot radio check. -- Pilot radio check.
local text=string.format("%s, %s, radio check %.3f", self.alias, callsign, self.frequency) local text = ""
if type(self.frequency) == "table" then
local multifreq = ""
for _,_entry in pairs(self.frequency) do
multifreq = string.format("%s%.2f, ",multifreq,_entry)
end
multifreq = string.gsub(multifreq,", $","")
text=string.format("%s, %s, radio check %s", self.alias, callsign, multifreq)
else
text=string.format("%s, %s, radio check %.3f", self.alias, callsign, self.frequency)
end
-- Radio message. -- Radio message.
self:TransmissionPilot(text, flight) self:TransmissionPilot(text, flight)
@ -2713,7 +2716,17 @@ function FLIGHTCONTROL:_PlayerInfoAirbase(groupname)
local text=string.format("Airbase %s Info:", self.airbasename) local text=string.format("Airbase %s Info:", self.airbasename)
text=text..string.format("\nATC Status: %s", self:GetState()) text=text..string.format("\nATC Status: %s", self:GetState())
text=text..string.format("\nFrequency: %.3f %s", self.frequency, UTILS.GetModulationName(self.modulation))
if type(self.frequency) == "table" then
local multifreq = ""
for i=1,#self.frequency do
multifreq=string.format("%s%.2f %s, ",multifreq,self.frequency[i],UTILS.GetModulationName(self.modulation[i] or 0))
end
text=string.gsub(text,", $","")
text=text..string.format("\nFrequencies: %s", multifreq)
else
text=text..string.format("\nFrequency: %.3f %s", self.frequency, UTILS.GetModulationName(self.modulation))
end
text=text..string.format("\nRunway Landing: %s", self:GetActiveRunwayText()) text=text..string.format("\nRunway Landing: %s", self:GetActiveRunwayText())
text=text..string.format("\nRunway Takeoff: %s", self:GetActiveRunwayText(true)) text=text..string.format("\nRunway Takeoff: %s", self:GetActiveRunwayText(true))
@ -4458,13 +4471,31 @@ function FLIGHTCONTROL:_IsFlightOnRunway(flight)
return nil return nil
end end
--- [User] Set callsign options for TTS output. See @{Wrapper.Group#GROUP.GetCustomCallSign}() on how to set customized callsigns.
-- @param #FLIGHTCONTROL self
-- @param #boolean ShortCallsign If true, only call out the major flight number. Default = `true`.
-- @param #boolean Keepnumber If true, keep the **customized callsign** in the #GROUP name for players as-is, no amendments or numbers. Default = `true`.
-- @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.
-- @return #FLIGHTCONTROL self
function FLIGHTCONTROL:SetCallSignOptions(ShortCallsign,Keepnumber,CallsignTranslations)
if not ShortCallsign or ShortCallsign == false then
self.ShortCallsign = false
else
self.ShortCallsign = true
end
self.Keepnumber = Keepnumber or false
self.CallsignTranslations = CallsignTranslations
return self
end
--- Get callsign name of a given flight. --- Get callsign name of a given flight.
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
-- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group. -- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group.
-- @return #string Callsign or "Ghostrider 1-1". -- @return #string Callsign or "Ghostrider 1-1".
function FLIGHTCONTROL:_GetCallsignName(flight) function FLIGHTCONTROL:_GetCallsignName(flight)
local callsign=flight:GetCallsignName() local callsign=flight:GetCallsignName(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations)
--local name=string.match(callsign, "%a+") --local name=string.match(callsign, "%a+")
--local number=string.match(callsign, "%d+") --local number=string.match(callsign, "%d+")

View File

@ -4495,8 +4495,10 @@ function FLIGHTGROUP:_PlayerSubtitles()
-- Switch setting. -- Switch setting.
playerData.subtitles=not playerData.subtitles playerData.subtitles=not playerData.subtitles
local onoff = playerData.subtitles == true and "ON" or "OFF"
-- Display message. -- Display message.
MESSAGE:New(string.format("%s, subtitles are now %s", playerData.name, tostring(playerData.subtitles)), 10, nil, true):ToGroup(self.group) MESSAGE:New(string.format("%s, subtitles are now %s", playerData.name, onoff), 10, nil, true):ToGroup(self.group)
else else
--TODO: Error --TODO: Error

View File

@ -10123,7 +10123,7 @@ function OPSGROUP:_CheckDamage()
for _,_element in pairs(self.elements) do for _,_element in pairs(self.elements) do
local element=_element --Ops.OpsGroup#OPSGROUP.Element local element=_element --Ops.OpsGroup#OPSGROUP.Element
if element.status~=OPSGROUP.ElementStatus.DEAD and element.status~=OPSGROUP.ElementStatus.INUTERO then if element.status~=OPSGROUP.ElementStatus.DEAD and element.status~=OPSGROUP.ElementStatus.INUTERO then
-- Current life points. -- Current life points.
local life=element.unit:GetLife() local life=element.unit:GetLife()
@ -10136,7 +10136,7 @@ function OPSGROUP:_CheckDamage()
damaged=true damaged=true
end end
end end
end end
@ -11748,8 +11748,11 @@ end
--- Get callsign of the first element alive. --- Get callsign of the first element alive.
-- @param #OPSGROUP self -- @param #OPSGROUP self
-- @param #boolean ShortCallsign If true, append major flight number only
-- @param #boolean Keepnumber (Player only) If true, and using a customized callsign in the #GROUP name after an #-sign, use all of that information.
-- @param #table CallsignTranslations (optional) Translation table between callsigns
-- @return #string Callsign name, e.g. Uzi11, or "Ghostrider11". -- @return #string Callsign name, e.g. Uzi11, or "Ghostrider11".
function OPSGROUP:GetCallsignName() function OPSGROUP:GetCallsignName(ShortCallsign,Keepnumber,CallsignTranslations)
local element=self:GetElementAlive() local element=self:GetElementAlive()
@ -11757,6 +11760,9 @@ function OPSGROUP:GetCallsignName()
self:T2(self.lid..string.format("Callsign %s", tostring(element.callsign))) self:T2(self.lid..string.format("Callsign %s", tostring(element.callsign)))
local name=element.callsign or "Ghostrider11" local name=element.callsign or "Ghostrider11"
name=name:gsub("-", "") name=name:gsub("-", "")
if self.group:IsPlayer() or CallsignTranslations then
name=self.group:GetCustomCallSign(ShortCallsign,Keepnumber,CallsignTranslations)
end
return name return name
end end
@ -11778,7 +11784,7 @@ function OPSGROUP:_UpdatePosition()
self.positionLast=self.position or self:GetVec3() self.positionLast=self.position or self:GetVec3()
self.headingLast=self.heading or self:GetHeading() self.headingLast=self.heading or self:GetHeading()
self.orientXLast=self.orientX or self:GetOrientationX() self.orientXLast=self.orientX or self:GetOrientationX()
self.velocityLast=self.velocity or self.group:GetVelocityMPS() self.velocityLast=self.velocity or self.group:GetVelocityMPS()
-- Current state. -- Current state.
self.position=self:GetVec3() self.position=self:GetVec3()
@ -12433,7 +12439,7 @@ function OPSGROUP:GetAmmoUnit(unit, display)
local weapons=#ammotable local weapons=#ammotable
--self:I(ammotable) --self:I(ammotable)
-- Loop over all weapons. -- Loop over all weapons.
for w=1,weapons do for w=1,weapons do
@ -12441,9 +12447,9 @@ function OPSGROUP:GetAmmoUnit(unit, display)
-- Number of current weapon. -- Number of current weapon.
local Nammo=ammotable[w]["count"] local Nammo=ammotable[w]["count"]
-- Range in meters. Seems only to exist for missiles (not shells). -- Range in meters. Seems only to exist for missiles (not shells).
local rmin=ammotable[w]["desc"]["rangeMin"] or 0 local rmin=ammotable[w]["desc"]["rangeMin"] or 0
local rmax=ammotable[w]["desc"]["rangeMaxAltMin"] or 0 local rmax=ammotable[w]["desc"]["rangeMaxAltMin"] or 0
-- Type name of current weapon. -- Type name of current weapon.
local Tammo=ammotable[w]["desc"]["typeName"] local Tammo=ammotable[w]["desc"]["typeName"]
@ -12707,7 +12713,7 @@ function OPSGROUP:_AddElementByName(unitname)
element.gid=element.DCSunit:getNumber() element.gid=element.DCSunit:getNumber()
element.uid=element.DCSunit:getID() element.uid=element.DCSunit:getID()
--element.group=unit:GetGroup() --element.group=unit:GetGroup()
element.controller=element.DCSunit:getController() element.controller=element.DCSunit:getController()
element.Nhit=0 element.Nhit=0
element.opsgroup=self element.opsgroup=self

View File

@ -1213,7 +1213,7 @@ PLAYERTASKCONTROLLER.Messages = {
--- PLAYERTASK class version. --- PLAYERTASK class version.
-- @field #string version -- @field #string version
PLAYERTASKCONTROLLER.version="0.1.35" PLAYERTASKCONTROLLER.version="0.1.36"
--- Constructor --- Constructor
-- @param #PLAYERTASKCONTROLLER self -- @param #PLAYERTASKCONTROLLER self
@ -1391,7 +1391,7 @@ end
--- [User] Set callsign options for TTS output. See @{Wrapper.Group#GROUP.GetCustomCallSign}() on how to set customized callsigns. --- [User] Set callsign options for TTS output. See @{Wrapper.Group#GROUP.GetCustomCallSign}() on how to set customized callsigns.
-- @param #PLAYERTASKCONTROLLER self -- @param #PLAYERTASKCONTROLLER self
-- @param #boolean ShortCallsign If true, only call out the major flight number -- @param #boolean ShortCallsign If true, only call out the major flight number
-- @param #boolean Keepnumber If true, keep the **customized callsign** in the #GROUP name as-is, no amendments or numbers. -- @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 -- @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. -- callsigns from playername or group name.
-- @return #PLAYERTASKCONTROLLER self -- @return #PLAYERTASKCONTROLLER self
@ -1406,6 +1406,22 @@ function PLAYERTASKCONTROLLER:SetCallSignOptions(ShortCallsign,Keepnumber,Callsi
return self return self
end end
--- [Internal] Get text for text-to-speech.
-- Numbers are spaced out, e.g. "Heading 180" becomes "Heading 1 8 0 ".
-- @param #PLAYERTASKCONTROLLER self
-- @param #string text Original text.
-- @return #string Spoken text.
function PLAYERTASKCONTROLLER:_GetTextForSpeech(text)
-- Space out numbers.
text=string.gsub(text,"%d","%1 ")
-- get rid of leading or trailing spaces
text=string.gsub(text,"^%s*","")
text=string.gsub(text,"%s*$","")
return text
end
--- [User] Set repetition options for tasks --- [User] Set repetition options for tasks
-- @param #PLAYERTASKCONTROLLER self -- @param #PLAYERTASKCONTROLLER self
-- @param #boolean OnOff Set to `true` to switch on and `false` to switch off (defaults to true) -- @param #boolean OnOff Set to `true` to switch on and `false` to switch off (defaults to true)
@ -1531,7 +1547,9 @@ function PLAYERTASKCONTROLLER:_GetPlayerName(Client)
if not self.customcallsigns[playername] then if not self.customcallsigns[playername] then
local playergroup = Client:GetGroup() local playergroup = Client:GetGroup()
ttsplayername = playergroup:GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations) ttsplayername = playergroup:GetCustomCallSign(self.ShortCallsign,self.Keepnumber,self.CallsignTranslations)
self.customcallsigns[playername] = ttsplayername local newplayername = self:_GetTextForSpeech(ttsplayername)
self.customcallsigns[playername] = newplayername
ttsplayername = newplayername
else else
ttsplayername = self.customcallsigns[playername] ttsplayername = self.customcallsigns[playername]
end end
@ -1655,6 +1673,7 @@ function PLAYERTASKCONTROLLER:_EventHandler(EventData)
end end
playername = EventData.IniGroup:GetCustomCallSign(self.ShortCallsign,self.Keepnumber) playername = EventData.IniGroup:GetCustomCallSign(self.ShortCallsign,self.Keepnumber)
end 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) --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,self.MenuName or self.Name,playername,freqtext) local text = string.format(switchtext,self.MenuName or self.Name,playername,freqtext)
self.SRSQueue:NewTransmission(text,nil,self.SRS,timer.getAbsTime()+60,2,{EventData.IniGroup},text,30,self.BCFrequency,self.BCModulation) self.SRSQueue:NewTransmission(text,nil,self.SRS,timer.getAbsTime()+60,2,{EventData.IniGroup},text,30,self.BCFrequency,self.BCModulation)
@ -2289,6 +2308,7 @@ function PLAYERTASKCONTROLLER:_JoinTask(Group, Client, Task)
--local m=MESSAGE:New(text,"10","Tasking"):ToAll() --local m=MESSAGE:New(text,"10","Tasking"):ToAll()
end end
if self.UseSRS then if self.UseSRS then
self:I(self.lid..text)
self.SRSQueue:NewTransmission(text,nil,self.SRS,nil,2) self.SRSQueue:NewTransmission(text,nil,self.SRS,nil,2)
end end
self.TasksPerPlayer:Push(Task,playername) self.TasksPerPlayer:Push(Task,playername)