mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
#AIRBOSS
* Suppress unnecessary SRS TTS calls with empty text
This commit is contained in:
parent
253cf0f5a5
commit
18afe9ad7a
@ -152,12 +152,16 @@
|
|||||||
-- @field #boolean ICLSon Automatic ICLS is activated.
|
-- @field #boolean ICLSon Automatic ICLS is activated.
|
||||||
-- @field #number ICLSchannel ICLS channel.
|
-- @field #number ICLSchannel ICLS channel.
|
||||||
-- @field #string ICLSmorse ICLS morse code, e.g. "STN".
|
-- @field #string ICLSmorse ICLS morse code, e.g. "STN".
|
||||||
|
-- @field #AIRBOSS.Radio PilotRadio Radio for Pilot calls.
|
||||||
-- @field #AIRBOSS.Radio LSORadio Radio for LSO calls.
|
-- @field #AIRBOSS.Radio LSORadio Radio for LSO calls.
|
||||||
-- @field #number LSOFreq LSO radio frequency in MHz.
|
-- @field #number LSOFreq LSO radio frequency in MHz.
|
||||||
-- @field #string LSOModu LSO radio modulation "AM" or "FM".
|
-- @field #string LSOModu LSO radio modulation "AM" or "FM".
|
||||||
-- @field #AIRBOSS.Radio MarshalRadio Radio for carrier calls.
|
-- @field #AIRBOSS.Radio MarshalRadio Radio for carrier calls.
|
||||||
-- @field #number MarshalFreq Marshal radio frequency in MHz.
|
-- @field #number MarshalFreq Marshal radio frequency in MHz.
|
||||||
-- @field #string MarshalModu Marshal radio modulation "AM" or "FM".
|
-- @field #string MarshalModu Marshal radio modulation "AM" or "FM".
|
||||||
|
-- @field #AIRBOSS.Radio AirbossRadio Radio for carrier calls.
|
||||||
|
-- @field #number AirbossFreq Airboss radio frequency in MHz.
|
||||||
|
-- @field #string AirbossModu Airboss radio modulation "AM" or "FM".
|
||||||
-- @field #number TowerFreq Tower radio frequency in MHz.
|
-- @field #number TowerFreq Tower radio frequency in MHz.
|
||||||
-- @field Core.Scheduler#SCHEDULER radiotimer Radio queue scheduler.
|
-- @field Core.Scheduler#SCHEDULER radiotimer Radio queue scheduler.
|
||||||
-- @field Core.Zone#ZONE_UNIT zoneCCA Carrier controlled area (CCA), i.e. a zone of 50 NM radius around the carrier.
|
-- @field Core.Zone#ZONE_UNIT zoneCCA Carrier controlled area (CCA), i.e. a zone of 50 NM radius around the carrier.
|
||||||
@ -1731,6 +1735,10 @@ AIRBOSS.Difficulty = {
|
|||||||
-- @field #table trapsheet Groove data table recorded every 0.5 seconds.
|
-- @field #table trapsheet Groove data table recorded every 0.5 seconds.
|
||||||
-- @field #boolean trapon If true, save trap sheets.
|
-- @field #boolean trapon If true, save trap sheets.
|
||||||
-- @field #string debriefschedulerID Debrief scheduler ID.
|
-- @field #string debriefschedulerID Debrief scheduler ID.
|
||||||
|
--
|
||||||
|
-- @field Sound.SRS#MSRS SRS
|
||||||
|
-- @field Sound.SRS#MSRSQUEUE SRSQ
|
||||||
|
--
|
||||||
-- @extends #AIRBOSS.FlightGroup
|
-- @extends #AIRBOSS.FlightGroup
|
||||||
|
|
||||||
--- Main group level radio menu: F10 Other/Airboss.
|
--- Main group level radio menu: F10 Other/Airboss.
|
||||||
@ -1743,7 +1751,7 @@ AIRBOSS.MenuF10Root = nil
|
|||||||
|
|
||||||
--- Airboss class version.
|
--- Airboss class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
AIRBOSS.version = "1.3.0"
|
AIRBOSS.version = "1.3.2"
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -1876,6 +1884,7 @@ function AIRBOSS:New( carriername, alias )
|
|||||||
|
|
||||||
-- Set up Airboss radio.
|
-- Set up Airboss radio.
|
||||||
self:SetMarshalRadio()
|
self:SetMarshalRadio()
|
||||||
|
self:SetAirbossRadio()
|
||||||
|
|
||||||
-- Set up LSO radio.
|
-- Set up LSO radio.
|
||||||
self:SetLSORadio()
|
self:SetLSORadio()
|
||||||
@ -2534,7 +2543,7 @@ function AIRBOSS:AddRecoveryWindow( starttime, stoptime, case, holdingoffset, tu
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
if Tstop <= Tnow then
|
if Tstop <= Tnow then
|
||||||
self:I( string.format( "WARNING: Recovery stop time %s already over. Tnow=%s! Recovery window rejected.", UTILS.SecondsToClock( Tstop ), UTILS.SecondsToClock( Tnow ) ) )
|
string.format( "WARNING: Recovery stop time %s already over. Tnow=%s! Recovery window rejected.", UTILS.SecondsToClock( Tstop ), UTILS.SecondsToClock( Tnow ) )
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -3043,12 +3052,56 @@ function AIRBOSS:SetBeaconRefresh( TimeInterval )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set up SRS for usage without sound files
|
||||||
|
-- @param #AIRBOSS self
|
||||||
|
-- @param #string PathToSRS Path to SRS folder, e.g. "C:\\Program Files\\DCS-SimpleRadio-Standalone".
|
||||||
|
-- @param #number Port Port of the SRS server, defaults to 5002.
|
||||||
|
-- @param #string Culture (Optional, Airboss Culture) Culture, defaults to "en-US".
|
||||||
|
-- @param #string Gender (Optional, Airboss Gender) Gender, e.g. "male" or "female". Defaults to "male".
|
||||||
|
-- @param #string Voice (Optional, Airboss Voice) Set to use a specific voice. Will **override gender and culture** settings.
|
||||||
|
-- @param #string GoogleCreds (Optional) Path to Google credentials, e.g. "C:\\Program Files\\DCS-SimpleRadio-Standalone\\yourgooglekey.json".
|
||||||
|
-- @param #number Volume (Optional) E.g. 0.75. Defaults to 1.0 (loudest).
|
||||||
|
-- @param #table AltBackend (Optional) See MSRS for details.
|
||||||
|
-- @return #AIRBOSS self
|
||||||
|
function AIRBOSS:EnableSRS(PathToSRS,Port,Culture,Gender,Voice,GoogleCreds,Volume,AltBackend)
|
||||||
|
-- SRS
|
||||||
|
local Frequency = self.AirbossRadio.frequency
|
||||||
|
local Modulation = self.AirbossRadio.modulation
|
||||||
|
self.SRS = MSRS:New(PathToSRS,Frequency,Modulation,Volume,AltBackend)
|
||||||
|
self.SRS:SetCoalition(self:GetCoalition())
|
||||||
|
self.SRS:SetCoordinate(self:GetCoordinate())
|
||||||
|
self.SRS:SetCulture(Culture or "en-US")
|
||||||
|
--self.SRS:SetFrequencies(Frequencies)
|
||||||
|
self.SRS:SetGender(Gender or "male")
|
||||||
|
self.SRS:SetPath(PathToSRS)
|
||||||
|
self.SRS:SetPort(Port or 5002)
|
||||||
|
self.SRS:SetLabel(self.AirbossRadio.alias or "AIRBOSS")
|
||||||
|
--self.SRS:SetModulations(Modulations)
|
||||||
|
if GoogleCreds then
|
||||||
|
self.SRS:SetGoogle(GoogleCreds)
|
||||||
|
end
|
||||||
|
if Voice then
|
||||||
|
self.SRS:SetVoice(Voice)
|
||||||
|
end
|
||||||
|
self.SRS:SetVolume(Volume or 1.0)
|
||||||
|
-- SRSQUEUE
|
||||||
|
self.SRSQ = MSRSQUEUE:New("AIRBOSS")
|
||||||
|
self.SRSQ:SetTransmitOnlyWithPlayers(true)
|
||||||
|
if not self.PilotRadio then
|
||||||
|
self:SetSRSPilotVoice()
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Set LSO radio frequency and modulation. Default frequency is 264 MHz AM.
|
--- Set LSO radio frequency and modulation. Default frequency is 264 MHz AM.
|
||||||
-- @param #AIRBOSS self
|
-- @param #AIRBOSS self
|
||||||
-- @param #number Frequency (Optional) Frequency in MHz. Default 264 MHz.
|
-- @param #number Frequency (Optional) Frequency in MHz. Default 264 MHz.
|
||||||
-- @param #string Modulation (Optional) Modulation, "AM" or "FM". Default "AM".
|
-- @param #string Modulation (Optional) Modulation, "AM" or "FM". Default "AM".
|
||||||
|
-- @param #string Voice (Optional) SRS specific voice
|
||||||
|
-- @param #string Gender (Optional) SRS specific gender
|
||||||
|
-- @param #string Culture (Optional) SRS specific culture
|
||||||
-- @return #AIRBOSS self
|
-- @return #AIRBOSS self
|
||||||
function AIRBOSS:SetLSORadio( Frequency, Modulation )
|
function AIRBOSS:SetLSORadio( Frequency, Modulation, Voice, Gender, Culture )
|
||||||
|
|
||||||
self.LSOFreq = (Frequency or 264)
|
self.LSOFreq = (Frequency or 264)
|
||||||
Modulation = Modulation or "AM"
|
Modulation = Modulation or "AM"
|
||||||
@ -3063,16 +3116,62 @@ function AIRBOSS:SetLSORadio( Frequency, Modulation )
|
|||||||
self.LSORadio.frequency = self.LSOFreq
|
self.LSORadio.frequency = self.LSOFreq
|
||||||
self.LSORadio.modulation = self.LSOModu
|
self.LSORadio.modulation = self.LSOModu
|
||||||
self.LSORadio.alias = "LSO"
|
self.LSORadio.alias = "LSO"
|
||||||
|
self.LSORadio.voice = Voice
|
||||||
|
self.LSORadio.gender = Gender or "male"
|
||||||
|
self.LSORadio.culture = Culture or "en-US"
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set carrier radio frequency and modulation. Default frequency is 305 MHz AM.
|
--- Set Airboss radio frequency and modulation. Default frequency is Tower frequency.
|
||||||
|
-- @param #AIRBOSS self
|
||||||
|
-- @param #number Frequency (Optional) Frequency in MHz. Default frequency is Tower frequency.
|
||||||
|
-- @param #string Modulation (Optional) Modulation, "AM" or "FM". Default "AM".
|
||||||
|
-- @param #string Voice (Optional) SRS specific voice
|
||||||
|
-- @param #string Gender (Optional) SRS specific gender
|
||||||
|
-- @param #string Culture (Optional) SRS specific culture
|
||||||
|
-- @return #AIRBOSS self
|
||||||
|
-- @usage
|
||||||
|
-- -- Set single frequency
|
||||||
|
-- myairboss:SetAirbossRadio(127.5,"AM",MSRS.Voices.Google.Standard.en_GB_Standard_F)
|
||||||
|
--
|
||||||
|
-- -- Set multiple frequencies, note you **need** to pass one modulation per frequency given!
|
||||||
|
-- myairboss:SetAirbossRadio({127.5,243},{radio.modulation.AM,radio.modulation.AM},MSRS.Voices.Google.Standard.en_GB_Standard_F)
|
||||||
|
function AIRBOSS:SetAirbossRadio( Frequency, Modulation, Voice, Gender, Culture )
|
||||||
|
|
||||||
|
self.AirbossFreq = Frequency or self:_GetTowerFrequency() or 127.5
|
||||||
|
Modulation = Modulation or "AM"
|
||||||
|
|
||||||
|
if type(Modulation) == "table" then
|
||||||
|
self.AirbossModu = Modulation
|
||||||
|
else
|
||||||
|
if Modulation == "FM" then
|
||||||
|
self.AirbossModu = radio.modulation.FM
|
||||||
|
else
|
||||||
|
self.AirbossModu = radio.modulation.AM
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.AirbossRadio = {} -- #AIRBOSS.Radio
|
||||||
|
self.AirbossRadio.frequency = self.AirbossFreq
|
||||||
|
self.AirbossRadio.modulation = self.AirbossModu
|
||||||
|
self.AirbossRadio.alias = "AIRBOSS"
|
||||||
|
self.AirbossRadio.voice = Voice
|
||||||
|
self.AirbossRadio.gender = Gender or "male"
|
||||||
|
self.AirbossRadio.culture = Culture or "en-US"
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set Marshal radio frequency and modulation. Default frequency is 305 MHz AM.
|
||||||
-- @param #AIRBOSS self
|
-- @param #AIRBOSS self
|
||||||
-- @param #number Frequency (Optional) Frequency in MHz. Default 305 MHz.
|
-- @param #number Frequency (Optional) Frequency in MHz. Default 305 MHz.
|
||||||
-- @param #string Modulation (Optional) Modulation, "AM" or "FM". Default "AM".
|
-- @param #string Modulation (Optional) Modulation, "AM" or "FM". Default "AM".
|
||||||
|
-- @param #string Voice (Optional) SRS specific voice
|
||||||
|
-- @param #string Gender (Optional) SRS specific gender
|
||||||
|
-- @param #string Culture (Optional) SRS specific culture
|
||||||
-- @return #AIRBOSS self
|
-- @return #AIRBOSS self
|
||||||
function AIRBOSS:SetMarshalRadio( Frequency, Modulation )
|
function AIRBOSS:SetMarshalRadio( Frequency, Modulation, Voice, Gender, Culture )
|
||||||
|
|
||||||
self.MarshalFreq = Frequency or 305
|
self.MarshalFreq = Frequency or 305
|
||||||
Modulation = Modulation or "AM"
|
Modulation = Modulation or "AM"
|
||||||
@ -3087,6 +3186,9 @@ function AIRBOSS:SetMarshalRadio( Frequency, Modulation )
|
|||||||
self.MarshalRadio.frequency = self.MarshalFreq
|
self.MarshalRadio.frequency = self.MarshalFreq
|
||||||
self.MarshalRadio.modulation = self.MarshalModu
|
self.MarshalRadio.modulation = self.MarshalModu
|
||||||
self.MarshalRadio.alias = "MARSHAL"
|
self.MarshalRadio.alias = "MARSHAL"
|
||||||
|
self.MarshalRadio.voice = Voice
|
||||||
|
self.MarshalRadio.gender = Gender or "male"
|
||||||
|
self.MarshalRadio.culture = Culture or "en-US"
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -3156,7 +3258,7 @@ function AIRBOSS:SoundCheckLSO( delay )
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
self:I( self.lid .. text )
|
self:T( self.lid .. text )
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -3191,7 +3293,7 @@ function AIRBOSS:SoundCheckMarshal( delay )
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
self:I( self.lid .. text )
|
self:T( self.lid .. text )
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -3582,7 +3684,7 @@ function AIRBOSS:onafterStatus( From, Event, To )
|
|||||||
if i == 0 then
|
if i == 0 then
|
||||||
text = text .. " none"
|
text = text .. " none"
|
||||||
end
|
end
|
||||||
self:I( self.lid .. text )
|
self:T( self.lid .. text )
|
||||||
|
|
||||||
-- Check for collision.
|
-- Check for collision.
|
||||||
if collision then
|
if collision then
|
||||||
@ -5357,6 +5459,7 @@ function AIRBOSS:_GetAircraftParameters( playerData, step )
|
|||||||
local skyhawk = playerData.actype == AIRBOSS.AircraftCarrier.A4EC
|
local skyhawk = playerData.actype == AIRBOSS.AircraftCarrier.A4EC
|
||||||
local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B
|
local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B
|
||||||
local harrier = playerData.actype == AIRBOSS.AircraftCarrier.AV8B
|
local harrier = playerData.actype == AIRBOSS.AircraftCarrier.AV8B
|
||||||
|
local goshawk = playerData.actype == AIRBOSS.AircraftCarrier.T45C
|
||||||
|
|
||||||
-- Return values.
|
-- Return values.
|
||||||
local alt
|
local alt
|
||||||
@ -5822,63 +5925,30 @@ function AIRBOSS:_ScanCarrierZone()
|
|||||||
-- Get aircraft type name.
|
-- Get aircraft type name.
|
||||||
local actype = group:GetTypeName()
|
local actype = group:GetTypeName()
|
||||||
|
|
||||||
|
-- Create a new flight group
|
||||||
if knownflight then
|
if knownflight then
|
||||||
|
|
||||||
-- Debug output.
|
-- Debug output.
|
||||||
self:T2(self.lid..string.format("Known flight group %s of type %s in CCA.", groupname, actype))
|
self:T2(self.lid..string.format("Known flight group %s of type %s in CCA.", groupname, actype))
|
||||||
|
|
||||||
-- Check if flight is AI and if we want to handle it at all.
|
-- Check if flight is AI and if we want to handle it at all.
|
||||||
if knownflight.ai and self.handleai then
|
if knownflight.ai and knownflight.flag == -100 and self.handleai then
|
||||||
|
|
||||||
-- Defines if AI group should be handled by the airboss.
|
local putintomarshal = false
|
||||||
local iscarriersquad=true
|
|
||||||
|
|
||||||
-- Check if AI group is part of the group set if a set was defined.
|
-- Get flight group.
|
||||||
if self.squadsetAI then
|
local flight = _DATABASE:GetOpsGroup( groupname )
|
||||||
local group=self.squadsetAI:FindGroup(groupname)
|
|
||||||
if group then
|
if flight and flight:IsInbound() and flight.destbase:GetName() == self.carrier:GetName() then
|
||||||
iscarriersquad=true
|
if flight.ishelo then
|
||||||
else
|
else
|
||||||
iscarriersquad=false
|
putintomarshal = true
|
||||||
end
|
end
|
||||||
|
flight.airboss = self
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check if group was explicitly excluded.
|
|
||||||
if self.excludesetAI then
|
|
||||||
local group=self.excludesetAI:FindGroup(groupname)
|
|
||||||
if group then
|
|
||||||
iscarriersquad=false
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Get distance to carrier.
|
|
||||||
local dist=knownflight.group:GetCoordinate():Get2DDistance(self:GetCoordinate())
|
|
||||||
|
|
||||||
-- Close in distance. Is >0 if AC comes closer wrt to first detected distance d0.
|
|
||||||
local closein=knownflight.dist0-dist
|
|
||||||
|
|
||||||
-- Debug info.
|
|
||||||
self:T3(self.lid..string.format("Known AI flight group %s closed in by %.1f NM", knownflight.groupname, UTILS.MetersToNM(closein)))
|
|
||||||
|
|
||||||
-- Is this group the tanker?
|
|
||||||
local istanker=self.tanker and self.tanker.tanker:GetName()==groupname
|
|
||||||
|
|
||||||
-- Is this group the AWACS?
|
|
||||||
local isawacs=self.awacs and self.awacs.tanker:GetName()==groupname
|
|
||||||
|
|
||||||
-- Send tanker to marshal stack?
|
|
||||||
local tanker2marshal = istanker and self.tanker:IsReturning() and self.tanker.airbase:GetName()==self.airbase:GetName() and knownflight.flag==-100 and self.tanker.recovery==true
|
|
||||||
|
|
||||||
-- Send AWACS to marhsal stack?
|
|
||||||
local awacs2marshal = isawacs and self.awacs:IsReturning() and self.awacs.airbase:GetName()==self.airbase:GetName() and knownflight.flag==-100 and self.awacs.recovery==true
|
|
||||||
|
|
||||||
-- Put flight into Marshal.
|
|
||||||
local putintomarshal=closein>UTILS.NMToMeters(5) and knownflight.flag==-100 and iscarriersquad and istanker==false and isawacs==false
|
|
||||||
|
|
||||||
-- Send AI flight to marshal stack if group closes in more than 5 and has initial flag value.
|
-- Send AI flight to marshal stack if group closes in more than 5 and has initial flag value.
|
||||||
if putintomarshal or tanker2marshal or awacs2marshal then
|
if putintomarshal then
|
||||||
|
|
||||||
|
|
||||||
-- Get the next free stack for current recovery case.
|
-- Get the next free stack for current recovery case.
|
||||||
@ -6890,7 +6960,7 @@ function AIRBOSS:_GetFreeStack( ai, case, empty )
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
self:I( self.lid .. string.format( "Returning free stack %s", tostring( nfree ) ) )
|
self:T( self.lid .. string.format( "Returning free stack %s", tostring( nfree ) ) )
|
||||||
return nfree
|
return nfree
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -7824,7 +7894,7 @@ function AIRBOSS:_RemoveFlight( flight, completely )
|
|||||||
-- Remove player from players table.
|
-- Remove player from players table.
|
||||||
local playerdata = self.players[flight.name]
|
local playerdata = self.players[flight.name]
|
||||||
if playerdata then
|
if playerdata then
|
||||||
self:I( self.lid .. string.format( "Removing player %s completely.", flight.name ) )
|
self:T( self.lid .. string.format( "Removing player %s completely.", flight.name ) )
|
||||||
self.players[flight.name] = nil
|
self.players[flight.name] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -11485,9 +11555,49 @@ end
|
|||||||
-- @return #number Carrier heading in degrees.
|
-- @return #number Carrier heading in degrees.
|
||||||
function AIRBOSS:GetHeadingIntoWind( magnetic, coord )
|
function AIRBOSS:GetHeadingIntoWind( magnetic, coord )
|
||||||
|
|
||||||
|
local function adjustDegreesForWindSpeed(windSpeed)
|
||||||
|
local degreesAdjustment = 0
|
||||||
|
-- the windspeeds are in m/s
|
||||||
|
|
||||||
|
-- +0 degrees at 15m/s = 37kts
|
||||||
|
-- +0 degrees at 14m/s = 35kts
|
||||||
|
-- +0 degrees at 13m/s = 33kts
|
||||||
|
-- +4 degrees at 12m/s = 31kts
|
||||||
|
-- +4 degrees at 11m/s = 29kts
|
||||||
|
-- +4 degrees at 10m/s = 27kts
|
||||||
|
-- +4 degrees at 9m/s = 27kts
|
||||||
|
-- +4 degrees at 8m/s = 27kts
|
||||||
|
-- +8 degrees at 7m/s = 27kts
|
||||||
|
-- +8 degrees at 6m/s = 27kts
|
||||||
|
-- +8 degrees at 5m/s = 26kts
|
||||||
|
-- +20 degrees at 4m/s = 26kts
|
||||||
|
-- +20 degrees at 3m/s = 26kts
|
||||||
|
-- +30 degrees at 2m/s = 26kts 1s
|
||||||
|
|
||||||
|
if windSpeed > 0 and windSpeed < 3 then
|
||||||
|
degreesAdjustment = 30
|
||||||
|
elseif windSpeed >= 3 and windSpeed < 5 then
|
||||||
|
degreesAdjustment = 20
|
||||||
|
elseif windSpeed >= 5 and windSpeed < 8 then
|
||||||
|
degreesAdjustment = 8
|
||||||
|
elseif windSpeed >= 8 and windSpeed < 13 then
|
||||||
|
degreesAdjustment = 4
|
||||||
|
elseif windSpeed >= 13 then
|
||||||
|
degreesAdjustment = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
return degreesAdjustment
|
||||||
|
end
|
||||||
|
|
||||||
-- Get direction the wind is blowing from. This is where we want to go.
|
-- Get direction the wind is blowing from. This is where we want to go.
|
||||||
local windfrom, vwind = self:GetWind( nil, nil, coord )
|
local windfrom, vwind = self:GetWind( nil, nil, coord )
|
||||||
|
|
||||||
|
--self:T("windfrom="..windfrom.." vwind="..vwind)
|
||||||
|
|
||||||
|
vwind = vwind + adjustDegreesForWindSpeed(vwind)
|
||||||
|
|
||||||
|
--self:T("windfrom="..windfrom.." (c)vwind="..vwind)
|
||||||
|
|
||||||
-- Actually, we want the runway in the wind.
|
-- Actually, we want the runway in the wind.
|
||||||
local intowind = windfrom - self.carrierparam.rwyangle
|
local intowind = windfrom - self.carrierparam.rwyangle
|
||||||
|
|
||||||
@ -13421,8 +13531,8 @@ function AIRBOSS:CarrierTurnIntoWind( time, vdeck, uturn )
|
|||||||
-- Wind speed.
|
-- Wind speed.
|
||||||
local _, vwind = self:GetWind()
|
local _, vwind = self:GetWind()
|
||||||
|
|
||||||
-- Speed of carrier in m/s but at least 2 knots.
|
-- Speed of carrier in m/s but at least 4 knots.
|
||||||
local vtot = math.max( vdeck - vwind, UTILS.KnotsToMps( 2 ) )
|
local vtot = math.max( vdeck - vwind, UTILS.KnotsToMps( 4 ) )
|
||||||
|
|
||||||
-- Distance to travel
|
-- Distance to travel
|
||||||
local dist = vtot * time
|
local dist = vtot * time
|
||||||
@ -14626,6 +14736,8 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not self.SRS then
|
||||||
|
|
||||||
-- Create a new radio transmission item.
|
-- Create a new radio transmission item.
|
||||||
local transmission = {} -- #AIRBOSS.Radioitem
|
local transmission = {} -- #AIRBOSS.Radioitem
|
||||||
|
|
||||||
@ -14678,6 +14790,87 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p
|
|||||||
if click then
|
if click then
|
||||||
self:RadioTransmission( radio, self[caller].CLICK, false, delay )
|
self:RadioTransmission( radio, self[caller].CLICK, false, delay )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
-- SRS transmission
|
||||||
|
if call.subtitle ~= nil and string.len(call.subtitle) > 1 then
|
||||||
|
|
||||||
|
local frequency = self.MarshalRadio.frequency
|
||||||
|
local modulation = self.MarshalRadio.modulation
|
||||||
|
local voice = nil
|
||||||
|
local gender = nil
|
||||||
|
local culture = nil
|
||||||
|
|
||||||
|
if radio.alias == "AIRBOSS" then
|
||||||
|
frequency = self.AirbossRadio.frequency
|
||||||
|
modulation = self.AirbossRadio.modulation
|
||||||
|
voice = self.AirbossRadio.voice
|
||||||
|
gender = self.AirbossRadio.gender
|
||||||
|
culture = self.AirbossRadio.culture
|
||||||
|
end
|
||||||
|
|
||||||
|
if radio.alias == "MARSHAL" then
|
||||||
|
voice = self.MarshalRadio.voice
|
||||||
|
gender = self.MarshalRadio.gender
|
||||||
|
culture = self.MarshalRadio.culture
|
||||||
|
end
|
||||||
|
|
||||||
|
if radio.alias == "LSO" then
|
||||||
|
frequency = self.LSORadio.frequency
|
||||||
|
modulation = self.LSORadio.modulation
|
||||||
|
voice = self.LSORadio.voice
|
||||||
|
gender = self.LSORadio.gender
|
||||||
|
culture = self.LSORadio.culture
|
||||||
|
end
|
||||||
|
|
||||||
|
if pilotcall then
|
||||||
|
voice = self.PilotRadio.voice
|
||||||
|
gender = self.PilotRadio.gender
|
||||||
|
culture = self.PilotRadio.culture
|
||||||
|
radio.alias = "PILOT"
|
||||||
|
end
|
||||||
|
|
||||||
|
if not radio.alias then
|
||||||
|
-- TODO - what freq to use here?
|
||||||
|
frequency = self.AirbossRadio.frequency
|
||||||
|
modulation = self.AirbossRadio.modulation
|
||||||
|
radio.alias = "AIRBOSS"
|
||||||
|
end
|
||||||
|
|
||||||
|
local volume = nil
|
||||||
|
|
||||||
|
if loud then
|
||||||
|
volume = 1.0
|
||||||
|
end
|
||||||
|
|
||||||
|
--local text = tostring(call.modexreceiver).."; "..radio.alias.."; "..call.subtitle
|
||||||
|
local text = call.subtitle
|
||||||
|
self:T(self.lid..text)
|
||||||
|
local srstext = self:_GetNiceSRSText(text)
|
||||||
|
self.SRSQ:NewTransmission(srstext, call.duration, self.SRS, nil, 0.1, nil, call.subtitle, call.subduration, frequency, modulation, gender, culture, voice, volume, radio.alias)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set SRS voice for the pilot calls.
|
||||||
|
-- @param #AIRBOSS self
|
||||||
|
-- @param #string Voice (Optional) SRS specific voice
|
||||||
|
-- @param #string Gender (Optional) SRS specific gender
|
||||||
|
-- @param #string Culture (Optional) SRS specific culture
|
||||||
|
-- @return #AIRBOSS self
|
||||||
|
function AIRBOSS:SetSRSPilotVoice( Voice, Gender, Culture )
|
||||||
|
|
||||||
|
self.PilotRadio = {} -- #AIRBOSS.Radio
|
||||||
|
self.PilotRadio.alias = "PILOT"
|
||||||
|
self.PilotRadio.voice = Voice or MSRS.Voices.Microsoft.David
|
||||||
|
self.PilotRadio.gender = Gender or "male"
|
||||||
|
self.PilotRadio.culture = Culture or "en-US"
|
||||||
|
|
||||||
|
if (not Voice) and self.SRS and self.SRS.google then
|
||||||
|
self.PilotRadio.voice = MSRS.Voices.Google.Standard.en_US_Standard_J
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Check if a call needs a subtitle because the complete voice overs are not available.
|
--- Check if a call needs a subtitle because the complete voice overs are not available.
|
||||||
@ -14923,6 +15116,39 @@ function AIRBOSS:_RadioFilename( call, loud, channel )
|
|||||||
return filename
|
return filename
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Format text into SRS friendly string
|
||||||
|
-- @param #AIRBOSS self
|
||||||
|
-- @param #string text
|
||||||
|
-- @return #string text
|
||||||
|
function AIRBOSS:_GetNiceSRSText(text)
|
||||||
|
text = string.gsub(text,"================================\n","")
|
||||||
|
text = string.gsub(text,"||","parallel")
|
||||||
|
text = string.gsub(text,"==","perpendicular")
|
||||||
|
text = string.gsub(text,"BRC","Base recovery")
|
||||||
|
--text = string.gsub(text,"#","Number")
|
||||||
|
text = string.gsub(text,"%((%a+)%)","Morse %1")
|
||||||
|
text = string.gsub(text,"°C","° Celsius")
|
||||||
|
text = string.gsub(text,"°"," degrees")
|
||||||
|
text = string.gsub(text," FB "," Final bearing ")
|
||||||
|
text = string.gsub(text," ops"," operations ")
|
||||||
|
text = string.gsub(text," kts"," knots")
|
||||||
|
text = string.gsub(text,"TACAN","Tackan")
|
||||||
|
text = string.gsub(text,"ICLS","I.C.L.S.")
|
||||||
|
text = string.gsub(text,"LSO","L.S.O.")
|
||||||
|
text = string.gsub(text,"inHg","inches of Mercury")
|
||||||
|
text = string.gsub(text,"QFE","Q.F.E.")
|
||||||
|
text = string.gsub(text,"hPa","hecto pascal")
|
||||||
|
text = string.gsub(text," NM"," nautical miles")
|
||||||
|
text = string.gsub(text," ft"," feet")
|
||||||
|
text = string.gsub(text,"A/C","aircraft")
|
||||||
|
text = string.gsub(text,"(#[%a%d%p%s]+)\n","")
|
||||||
|
text = string.gsub(text,"%.000"," dot zero")
|
||||||
|
text = string.gsub(text,"00"," double zero")
|
||||||
|
text = string.gsub(text," 0 "," zero " )
|
||||||
|
text = string.gsub(text,"\n","; ")
|
||||||
|
return text
|
||||||
|
end
|
||||||
|
|
||||||
--- Send text message to player client.
|
--- Send text message to player client.
|
||||||
-- Message format will be "SENDER: RECCEIVER, MESSAGE".
|
-- Message format will be "SENDER: RECCEIVER, MESSAGE".
|
||||||
-- @param #AIRBOSS self
|
-- @param #AIRBOSS self
|
||||||
@ -14934,7 +15160,7 @@ end
|
|||||||
-- @param #boolean clear If true, clear screen from previous messages.
|
-- @param #boolean clear If true, clear screen from previous messages.
|
||||||
-- @param #number delay Delay in seconds, before the message is displayed.
|
-- @param #number delay Delay in seconds, before the message is displayed.
|
||||||
function AIRBOSS:MessageToPlayer( playerData, message, sender, receiver, duration, clear, delay )
|
function AIRBOSS:MessageToPlayer( playerData, message, sender, receiver, duration, clear, delay )
|
||||||
|
self:T({sender,receiver,message})
|
||||||
if playerData and message and message ~= "" then
|
if playerData and message and message ~= "" then
|
||||||
|
|
||||||
-- Default duration.
|
-- Default duration.
|
||||||
@ -14958,6 +15184,7 @@ function AIRBOSS:MessageToPlayer( playerData, message, sender, receiver, duratio
|
|||||||
self:ScheduleOnce( delay, self.MessageToPlayer, self, playerData, message, sender, receiver, duration, clear )
|
self:ScheduleOnce( delay, self.MessageToPlayer, self, playerData, message, sender, receiver, duration, clear )
|
||||||
else
|
else
|
||||||
|
|
||||||
|
if not self.SRS then
|
||||||
-- Wait until previous sound finished.
|
-- Wait until previous sound finished.
|
||||||
local wait = 0
|
local wait = 0
|
||||||
|
|
||||||
@ -14999,7 +15226,48 @@ function AIRBOSS:MessageToPlayer( playerData, message, sender, receiver, duratio
|
|||||||
local filename = self:_RadioFilename( self.MarshalCall.CLICK )
|
local filename = self:_RadioFilename( self.MarshalCall.CLICK )
|
||||||
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
-- SRS transmission
|
||||||
|
local frequency = self.MarshalRadio.frequency
|
||||||
|
local modulation = self.MarshalRadio.modulation
|
||||||
|
local voice = self.MarshalRadio.voice
|
||||||
|
local gender = self.MarshalRadio.gender
|
||||||
|
local culture = self.MarshalRadio.culture
|
||||||
|
|
||||||
|
if not sender then sender = "AIRBOSS" end
|
||||||
|
|
||||||
|
if string.find(sender,"AIRBOSS" ) then
|
||||||
|
frequency = self.AirbossRadio.frequency
|
||||||
|
modulation = self.AirbossRadio.modulation
|
||||||
|
voice = self.AirbossRadio.voice
|
||||||
|
gender = self.AirbossRadio.gender
|
||||||
|
culture = self.AirbossRadio.culture
|
||||||
|
end
|
||||||
|
|
||||||
|
--if sender == "MARSHAL" then
|
||||||
|
--voice = self.MarshalRadio.voice
|
||||||
|
--gender = self.MarshalRadio.gender
|
||||||
|
--culture = self.MarshalRadio.culture
|
||||||
|
--end
|
||||||
|
|
||||||
|
if sender == "LSO" then
|
||||||
|
frequency = self.LSORadio.frequency
|
||||||
|
modulation = self.LSORadio.modulation
|
||||||
|
voice = self.LSORadio.voice
|
||||||
|
gender = self.LSORadio.gender
|
||||||
|
culture = self.LSORadio.culture
|
||||||
|
--elseif not sender then
|
||||||
|
-- TODO - what freq to use here?
|
||||||
|
--frequency = self.AirbossRadio.frequency
|
||||||
|
--modulation = self.AirbossRadio.modulation
|
||||||
|
--sender = "AIRBOSS"
|
||||||
|
end
|
||||||
|
|
||||||
|
self:T(self.lid..text)
|
||||||
|
self:T({sender,frequency,modulation,voice})
|
||||||
|
local srstext = self:_GetNiceSRSText(text)
|
||||||
|
self.SRSQ:NewTransmission(srstext,duration,self.SRS,nil,0.1,nil,nil,nil,frequency,modulation,gender,culture,voice,nil,sender)
|
||||||
|
end
|
||||||
-- Text message to player client.
|
-- Text message to player client.
|
||||||
if playerData.client then
|
if playerData.client then
|
||||||
MESSAGE:New( text, duration, sender, clear ):ToClient( playerData.client )
|
MESSAGE:New( text, duration, sender, clear ):ToClient( playerData.client )
|
||||||
@ -15368,7 +15636,7 @@ function AIRBOSS:_LSOCallAircraftBall( modex, nickname, fuelstate )
|
|||||||
local text = string.format( "%s Ball, %.1f.", nickname, fuelstate )
|
local text = string.format( "%s Ball, %.1f.", nickname, fuelstate )
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
self:I( self.lid .. text )
|
self:T( self.lid .. text )
|
||||||
|
|
||||||
-- Nickname UPPERCASE.
|
-- Nickname UPPERCASE.
|
||||||
local NICKNAME = nickname:upper()
|
local NICKNAME = nickname:upper()
|
||||||
@ -15404,7 +15672,7 @@ function AIRBOSS:_MarshalCallGasAtTanker( modex )
|
|||||||
local text = string.format( "Bingo fuel! Going for gas at the recovery tanker." )
|
local text = string.format( "Bingo fuel! Going for gas at the recovery tanker." )
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
self:I( self.lid .. text )
|
self:T( self.lid .. text )
|
||||||
|
|
||||||
|
|
||||||
-- Create new call to display complete subtitle.
|
-- Create new call to display complete subtitle.
|
||||||
@ -15428,7 +15696,7 @@ function AIRBOSS:_MarshalCallGasAtDivert( modex, divertname )
|
|||||||
local text = string.format( "Bingo fuel! Going for gas at divert field %s.", divertname )
|
local text = string.format( "Bingo fuel! Going for gas at divert field %s.", divertname )
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
self:I( self.lid .. text )
|
self:T( self.lid .. text )
|
||||||
|
|
||||||
-- Create new call to display complete subtitle.
|
-- Create new call to display complete subtitle.
|
||||||
local call = self:_NewRadioCall( self.PilotCall.BINGOFUEL, modex, text, self.Tmessage, nil, modex )
|
local call = self:_NewRadioCall( self.PilotCall.BINGOFUEL, modex, text, self.Tmessage, nil, modex )
|
||||||
@ -15450,7 +15718,7 @@ function AIRBOSS:_MarshalCallRecoveryStopped( case )
|
|||||||
local text = string.format( "Case %d recovery ops are stopped. Deck is closed.", case )
|
local text = string.format( "Case %d recovery ops are stopped. Deck is closed.", case )
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
self:I( self.lid .. text )
|
self:T( self.lid .. text )
|
||||||
|
|
||||||
-- Create new call to display complete subtitle.
|
-- Create new call to display complete subtitle.
|
||||||
local call = self:_NewRadioCall( self.MarshalCall.CASE, "AIRBOSS", text, self.Tmessage, "99" )
|
local call = self:_NewRadioCall( self.MarshalCall.CASE, "AIRBOSS", text, self.Tmessage, "99" )
|
||||||
@ -15491,7 +15759,7 @@ function AIRBOSS:_MarshalCallRecoveryPausedResumedAt( clock )
|
|||||||
local text = string.format( "aircraft recovery is paused and will be resumed at %s.", clock )
|
local text = string.format( "aircraft recovery is paused and will be resumed at %s.", clock )
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
self:I( self.lid .. text )
|
self:T( self.lid .. text )
|
||||||
|
|
||||||
-- Create new call with full subtitle.
|
-- Create new call with full subtitle.
|
||||||
local call = self:_NewRadioCall( self.MarshalCall.RECOVERYPAUSEDRESUMED, "AIRBOSS", text, self.Tmessage, "99" )
|
local call = self:_NewRadioCall( self.MarshalCall.RECOVERYPAUSEDRESUMED, "AIRBOSS", text, self.Tmessage, "99" )
|
||||||
@ -15518,7 +15786,7 @@ function AIRBOSS:_MarshalCallClearedForRecovery( modex, case )
|
|||||||
local text = string.format( "you're cleared for Case %d recovery.", case )
|
local text = string.format( "you're cleared for Case %d recovery.", case )
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
self:I( self.lid .. text )
|
self:T( self.lid .. text )
|
||||||
|
|
||||||
-- Create new call with full subtitle.
|
-- Create new call with full subtitle.
|
||||||
local call = self:_NewRadioCall( self.MarshalCall.CLEAREDFORRECOVERY, "MARSHAL", text, self.Tmessage, modex )
|
local call = self:_NewRadioCall( self.MarshalCall.CLEAREDFORRECOVERY, "MARSHAL", text, self.Tmessage, modex )
|
||||||
@ -15556,7 +15824,7 @@ function AIRBOSS:_MarshalCallNewFinalBearing( FB )
|
|||||||
local text = string.format( "new final bearing %03d°.", FB )
|
local text = string.format( "new final bearing %03d°.", FB )
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
self:I( self.lid .. text )
|
self:T( self.lid .. text )
|
||||||
|
|
||||||
-- Create new call with full subtitle.
|
-- Create new call with full subtitle.
|
||||||
local call = self:_NewRadioCall( self.MarshalCall.NEWFB, "AIRBOSS", text, self.Tmessage, "99" )
|
local call = self:_NewRadioCall( self.MarshalCall.NEWFB, "AIRBOSS", text, self.Tmessage, "99" )
|
||||||
@ -15579,7 +15847,7 @@ function AIRBOSS:_MarshalCallCarrierTurnTo( hdg )
|
|||||||
local text = string.format( "carrier is now starting turn to heading %03d°.", hdg )
|
local text = string.format( "carrier is now starting turn to heading %03d°.", hdg )
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
self:I( self.lid .. text )
|
self:T( self.lid .. text )
|
||||||
|
|
||||||
-- Create new call with full subtitle.
|
-- Create new call with full subtitle.
|
||||||
local call = self:_NewRadioCall( self.MarshalCall.CARRIERTURNTOHEADING, "AIRBOSS", text, self.Tmessage, "99" )
|
local call = self:_NewRadioCall( self.MarshalCall.CARRIERTURNTOHEADING, "AIRBOSS", text, self.Tmessage, "99" )
|
||||||
@ -15610,7 +15878,7 @@ function AIRBOSS:_MarshalCallStackFull( modex, nwaiting )
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
self:I( self.lid .. text )
|
self:T( self.lid .. text )
|
||||||
|
|
||||||
-- Create new call with full subtitle.
|
-- Create new call with full subtitle.
|
||||||
local call = self:_NewRadioCall( self.MarshalCall.STACKFULL, "AIRBOSS", text, self.Tmessage, modex )
|
local call = self:_NewRadioCall( self.MarshalCall.STACKFULL, "AIRBOSS", text, self.Tmessage, modex )
|
||||||
@ -15681,7 +15949,7 @@ function AIRBOSS:_MarshalCallArrived( modex, case, brc, altitude, charlie, qfe )
|
|||||||
local text = string.format( "Case %d, expected BRC %03d°, hold at angels %d. Expected Charlie Time %s. Altimeter %.2f. Report see me.", case, brc, angels, charlie, qfe )
|
local text = string.format( "Case %d, expected BRC %03d°, hold at angels %d. Expected Charlie Time %s. Altimeter %.2f. Report see me.", case, brc, angels, charlie, qfe )
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
self:I( self.lid .. text )
|
self:T( self.lid .. text )
|
||||||
|
|
||||||
-- Create new call to display complete subtitle.
|
-- Create new call to display complete subtitle.
|
||||||
local casecall = self:_NewRadioCall( self.MarshalCall.CASE, "MARSHAL", text, self.Tmessage, modex )
|
local casecall = self:_NewRadioCall( self.MarshalCall.CASE, "MARSHAL", text, self.Tmessage, modex )
|
||||||
@ -16338,7 +16606,7 @@ function AIRBOSS:_RequestSpinning( _unitName )
|
|||||||
-- Some advice.
|
-- Some advice.
|
||||||
if playerData.difficulty == AIRBOSS.Difficulty.EASY then
|
if playerData.difficulty == AIRBOSS.Difficulty.EASY then
|
||||||
local text = "Climb to 1200 feet and proceed to the initial again."
|
local text = "Climb to 1200 feet and proceed to the initial again."
|
||||||
self:MessageToPlayer( playerData, text, "INSTRUCTOR", "" )
|
self:MessageToPlayer( playerData, text, "AIRBOSS", "" )
|
||||||
end
|
end
|
||||||
|
|
||||||
return
|
return
|
||||||
@ -17093,7 +17361,7 @@ function AIRBOSS:_DisplayCarrierInfo( _unitname )
|
|||||||
state = "Deck closed"
|
state = "Deck closed"
|
||||||
end
|
end
|
||||||
if self.turning then
|
if self.turning then
|
||||||
state = state .. " (turning currently)"
|
state = state .. " (currently turning)"
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Message text.
|
-- Message text.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user