mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge branch 'develop' into FF/Ops
This commit is contained in:
@@ -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()
|
||||||
@@ -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
|
||||||
@@ -11448,8 +11550,42 @@ 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 ) + adjustDegreesForWindSpeed(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
|
||||||
@@ -13384,8 +13520,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
|
||||||
@@ -14589,58 +14725,139 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Create a new radio transmission item.
|
if not self.SRS then
|
||||||
local transmission = {} -- #AIRBOSS.Radioitem
|
|
||||||
|
|
||||||
transmission.radio = radio
|
-- Create a new radio transmission item.
|
||||||
transmission.call = call
|
local transmission = {} -- #AIRBOSS.Radioitem
|
||||||
transmission.Tplay = timer.getAbsTime() + (delay or 0)
|
|
||||||
transmission.interval = interval
|
|
||||||
transmission.isplaying = false
|
|
||||||
transmission.Tstarted = nil
|
|
||||||
transmission.loud = loud and call.loud
|
|
||||||
|
|
||||||
-- Player onboard number if sender has one.
|
transmission.radio = radio
|
||||||
if self:_IsOnboard( call.modexsender ) then
|
transmission.call = call
|
||||||
self:_Number2Radio( radio, call.modexsender, delay, 0.3, pilotcall )
|
transmission.Tplay = timer.getAbsTime() + (delay or 0)
|
||||||
end
|
transmission.interval = interval
|
||||||
|
transmission.isplaying = false
|
||||||
|
transmission.Tstarted = nil
|
||||||
|
transmission.loud = loud and call.loud
|
||||||
|
|
||||||
-- Play onboard number if receiver has one.
|
-- Player onboard number if sender has one.
|
||||||
if self:_IsOnboard( call.modexreceiver ) then
|
if self:_IsOnboard( call.modexsender ) then
|
||||||
self:_Number2Radio( radio, call.modexreceiver, delay, 0.3, pilotcall )
|
self:_Number2Radio( radio, call.modexsender, delay, 0.3, pilotcall )
|
||||||
end
|
|
||||||
|
|
||||||
-- Add transmission to the right queue.
|
|
||||||
local caller = ""
|
|
||||||
if radio.alias == "LSO" then
|
|
||||||
|
|
||||||
table.insert( self.RQLSO, transmission )
|
|
||||||
|
|
||||||
caller = "LSOCall"
|
|
||||||
|
|
||||||
-- Schedule radio queue checks.
|
|
||||||
if not self.RQLid then
|
|
||||||
self:T( self.lid .. string.format( "Starting LSO radio queue." ) )
|
|
||||||
self.RQLid = self.radiotimer:Schedule( nil, AIRBOSS._CheckRadioQueue, { self, self.RQLSO, "LSO" }, 0.02, 0.05 )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif radio.alias == "MARSHAL" then
|
-- Play onboard number if receiver has one.
|
||||||
|
if self:_IsOnboard( call.modexreceiver ) then
|
||||||
table.insert( self.RQMarshal, transmission )
|
self:_Number2Radio( radio, call.modexreceiver, delay, 0.3, pilotcall )
|
||||||
|
|
||||||
caller = "MarshalCall"
|
|
||||||
|
|
||||||
if not self.RQMid then
|
|
||||||
self:T( self.lid .. string.format( "Starting Marhal radio queue." ) )
|
|
||||||
self.RQMid = self.radiotimer:Schedule( nil, AIRBOSS._CheckRadioQueue, { self, self.RQMarshal, "MARSHAL" }, 0.02, 0.05 )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Add transmission to the right queue.
|
||||||
|
local caller = ""
|
||||||
|
if radio.alias == "LSO" then
|
||||||
|
|
||||||
|
table.insert( self.RQLSO, transmission )
|
||||||
|
|
||||||
|
caller = "LSOCall"
|
||||||
|
|
||||||
|
-- Schedule radio queue checks.
|
||||||
|
if not self.RQLid then
|
||||||
|
self:T( self.lid .. string.format( "Starting LSO radio queue." ) )
|
||||||
|
self.RQLid = self.radiotimer:Schedule( nil, AIRBOSS._CheckRadioQueue, { self, self.RQLSO, "LSO" }, 0.02, 0.05 )
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif radio.alias == "MARSHAL" then
|
||||||
|
|
||||||
|
table.insert( self.RQMarshal, transmission )
|
||||||
|
|
||||||
|
caller = "MarshalCall"
|
||||||
|
|
||||||
|
if not self.RQMid then
|
||||||
|
self:T( self.lid .. string.format( "Starting Marhal radio queue." ) )
|
||||||
|
self.RQMid = self.radiotimer:Schedule( nil, AIRBOSS._CheckRadioQueue, { self, self.RQMarshal, "MARSHAL" }, 0.02, 0.05 )
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Append radio click sound at the end of the transmission.
|
||||||
|
if click then
|
||||||
|
self:RadioTransmission( radio, self[caller].CLICK, false, delay )
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
-- SRS transmission
|
||||||
|
|
||||||
|
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:I(self.lid..text)
|
||||||
|
local srstext = self:_GetNiceSRSText(text)
|
||||||
|
self.SRSQ:NewTransmission(srstext, call.duration, self.SRS, tstart, 0.1, subgroups, call.subtitle, call.subduration, frequency, modulation, gender, culture, voice, volume, radio.alias)
|
||||||
|
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
|
end
|
||||||
|
|
||||||
-- Append radio click sound at the end of the transmission.
|
return self
|
||||||
if click then
|
|
||||||
self:RadioTransmission( radio, self[caller].CLICK, false, delay )
|
|
||||||
end
|
|
||||||
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.
|
||||||
@@ -14886,6 +15103,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
|
||||||
@@ -14897,7 +15147,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:I({sender,receiver,message})
|
||||||
if playerData and message and message ~= "" then
|
if playerData and message and message ~= "" then
|
||||||
|
|
||||||
-- Default duration.
|
-- Default duration.
|
||||||
@@ -14921,48 +15171,90 @@ 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
|
||||||
|
|
||||||
-- Wait until previous sound finished.
|
if not self.SRS then
|
||||||
local wait = 0
|
-- Wait until previous sound finished.
|
||||||
|
local wait = 0
|
||||||
|
|
||||||
-- Onboard number to get the attention.
|
-- Onboard number to get the attention.
|
||||||
if receiver == playerData.onboard then
|
if receiver == playerData.onboard then
|
||||||
|
|
||||||
-- Which voice over number to use.
|
-- Which voice over number to use.
|
||||||
if sender and (sender == "LSO" or sender == "MARSHAL" or sender == "AIRBOSS") then
|
if sender and (sender == "LSO" or sender == "MARSHAL" or sender == "AIRBOSS") then
|
||||||
|
|
||||||
-- User sound of board number.
|
-- User sound of board number.
|
||||||
wait = wait + self:_Number2Sound( playerData, sender, receiver )
|
wait = wait + self:_Number2Sound( playerData, sender, receiver )
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
-- Negative.
|
-- Negative.
|
||||||
if string.find( text:lower(), "negative" ) then
|
if string.find( text:lower(), "negative" ) then
|
||||||
local filename = self:_RadioFilename( self.MarshalCall.NEGATIVE, false, "MARSHAL" )
|
local filename = self:_RadioFilename( self.MarshalCall.NEGATIVE, false, "MARSHAL" )
|
||||||
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
||||||
wait = wait + self.MarshalCall.NEGATIVE.duration
|
wait = wait + self.MarshalCall.NEGATIVE.duration
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Affirm.
|
-- Affirm.
|
||||||
if string.find( text:lower(), "affirm" ) then
|
if string.find( text:lower(), "affirm" ) then
|
||||||
local filename = self:_RadioFilename( self.MarshalCall.AFFIRMATIVE, false, "MARSHAL" )
|
local filename = self:_RadioFilename( self.MarshalCall.AFFIRMATIVE, false, "MARSHAL" )
|
||||||
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
||||||
wait = wait + self.MarshalCall.AFFIRMATIVE.duration
|
wait = wait + self.MarshalCall.AFFIRMATIVE.duration
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Roger.
|
-- Roger.
|
||||||
if string.find( text:lower(), "roger" ) then
|
if string.find( text:lower(), "roger" ) then
|
||||||
local filename = self:_RadioFilename( self.MarshalCall.ROGER, false, "MARSHAL" )
|
local filename = self:_RadioFilename( self.MarshalCall.ROGER, false, "MARSHAL" )
|
||||||
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
USERSOUND:New( filename ):ToGroup( playerData.group, wait )
|
||||||
wait = wait + self.MarshalCall.ROGER.duration
|
wait = wait + self.MarshalCall.ROGER.duration
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Play click sound to end message.
|
-- Play click sound to end message.
|
||||||
if wait > 0 then
|
if wait > 0 then
|
||||||
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:I(self.lid..text)
|
||||||
|
self:I({sender,frequency,modulation,voice})
|
||||||
|
local srstext = self:_GetNiceSRSText(text)
|
||||||
|
self.SRSQ:NewTransmission(srstext,duration,self.SRS,tstart,0.1,subgroups,subtitle,subduration,frequency,modulation,gender,culture,voice,volume,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 )
|
||||||
@@ -16301,7 +16593,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
|
||||||
|
|||||||
@@ -114,6 +114,9 @@
|
|||||||
-- @field #number NcarriersMax Max number of required carrier assets.
|
-- @field #number NcarriersMax Max number of required carrier assets.
|
||||||
-- @field Core.Zone#ZONE transportDeployZone Deploy zone of an OPSTRANSPORT.
|
-- @field Core.Zone#ZONE transportDeployZone Deploy zone of an OPSTRANSPORT.
|
||||||
-- @field Core.Zone#ZONE transportDisembarkZone Disembark zone of an OPSTRANSPORT.
|
-- @field Core.Zone#ZONE transportDisembarkZone Disembark zone of an OPSTRANSPORT.
|
||||||
|
-- @param #table carrierCategories Transport group categories.
|
||||||
|
-- @field #table carrierAttributes Generalized attribute(s) of transport assets.
|
||||||
|
-- @field #table carrierProperties DCS attribute(s) of transport assets.
|
||||||
--
|
--
|
||||||
-- @field #number artyRadius Radius in meters.
|
-- @field #number artyRadius Radius in meters.
|
||||||
-- @field #number artyShots Number of shots fired.
|
-- @field #number artyShots Number of shots fired.
|
||||||
@@ -3056,15 +3059,18 @@ end
|
|||||||
-- @param #number NcarriersMin Number of carriers *at least* required. Default 1.
|
-- @param #number NcarriersMin Number of carriers *at least* required. Default 1.
|
||||||
-- @param #number NcarriersMax Number of carriers *at most* used for transportation. Default is same as `NcarriersMin`.
|
-- @param #number NcarriersMax Number of carriers *at most* used for transportation. Default is same as `NcarriersMin`.
|
||||||
-- @param Core.Zone#ZONE DisembarkZone Zone where assets are disembarked to.
|
-- @param Core.Zone#ZONE DisembarkZone Zone where assets are disembarked to.
|
||||||
|
-- @param #table Categories Group categories.
|
||||||
|
-- @param #table Attributes Generalizes group attributes.
|
||||||
|
-- @param #table Properties DCS attributes.
|
||||||
-- @return #AUFTRAG self
|
-- @return #AUFTRAG self
|
||||||
function AUFTRAG:SetRequiredTransport(DeployZone, NcarriersMin, NcarriersMax, DisembarkZone)
|
function AUFTRAG:SetRequiredTransport(DeployZone, NcarriersMin, NcarriersMax, DisembarkZone, Categories, Attributes, Properties)
|
||||||
|
|
||||||
-- OPS transport from pickup to deploy zone.
|
-- OPS transport from pickup to deploy zone.
|
||||||
self.transportDeployZone=DeployZone
|
self.transportDeployZone=DeployZone
|
||||||
self.transportDisembarkZone=DisembarkZone
|
self.transportDisembarkZone=DisembarkZone
|
||||||
|
|
||||||
-- Set required carriers.
|
-- Set required carriers.
|
||||||
self:SetRequiredCarriers(NcarriersMin, NcarriersMax)
|
self:SetRequiredCarriers(NcarriersMin, NcarriersMax, Categories, Attributes, Properties)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -3115,8 +3121,11 @@ end
|
|||||||
-- @param #AUFTRAG self
|
-- @param #AUFTRAG self
|
||||||
-- @param #number NcarriersMin Number of carriers *at least* required. Default 1.
|
-- @param #number NcarriersMin Number of carriers *at least* required. Default 1.
|
||||||
-- @param #number NcarriersMax Number of carriers *at most* used for transportation. Default is same as `NcarriersMin`.
|
-- @param #number NcarriersMax Number of carriers *at most* used for transportation. Default is same as `NcarriersMin`.
|
||||||
|
-- @param #table Categories Group categories.
|
||||||
|
-- @param #table Attributes Group attributes. See `GROUP.Attribute.`
|
||||||
|
-- @param #table Properties DCS attributes.
|
||||||
-- @return #AUFTRAG self
|
-- @return #AUFTRAG self
|
||||||
function AUFTRAG:SetRequiredCarriers(NcarriersMin, NcarriersMax)
|
function AUFTRAG:SetRequiredCarriers(NcarriersMin, NcarriersMax, Categories, Attributes, Properties)
|
||||||
|
|
||||||
self.NcarriersMin=NcarriersMin or 1
|
self.NcarriersMin=NcarriersMin or 1
|
||||||
|
|
||||||
@@ -3127,6 +3136,10 @@ function AUFTRAG:SetRequiredCarriers(NcarriersMin, NcarriersMax)
|
|||||||
self.NcarriersMax=self.NcarriersMin
|
self.NcarriersMax=self.NcarriersMin
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.carrierCategories = UTILS.EnsureTable(Categories, true)
|
||||||
|
self.carrierAttributes = UTILS.EnsureTable(Attributes, true)
|
||||||
|
self.carrierProperties = UTILS.EnsureTable(Properties, true)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1508,7 +1508,7 @@ function COMMANDER:CheckMissionQueue()
|
|||||||
local Transport=nil
|
local Transport=nil
|
||||||
local Legions=mission.transportLegions or self.legions
|
local Legions=mission.transportLegions or self.legions
|
||||||
|
|
||||||
TransportAvail, Transport=LEGION.AssignAssetsForTransport(self, Legions, assets, mission.NcarriersMin, mission.NcarriersMax, mission.transportDeployZone, mission.transportDisembarkZone)
|
TransportAvail, Transport=LEGION.AssignAssetsForTransport(self, Legions, assets, mission.NcarriersMin, mission.NcarriersMax, mission.transportDeployZone, mission.transportDisembarkZone, mission.carrierCategories, mission.carrierAttributes, mission.carrierProperties)
|
||||||
|
|
||||||
-- Add opstransport to mission.
|
-- Add opstransport to mission.
|
||||||
if TransportAvail and Transport then
|
if TransportAvail and Transport then
|
||||||
@@ -1702,8 +1702,7 @@ function COMMANDER:RecruitAssetsForMission(Mission)
|
|||||||
local cohort=_cohort --Ops.Cohort#COHORT
|
local cohort=_cohort --Ops.Cohort#COHORT
|
||||||
|
|
||||||
-- Check if cohort can perform transport to target.
|
-- Check if cohort can perform transport to target.
|
||||||
--TODO: Option to filter transport carrier asset categories, attributes and/or properties.
|
local can=LEGION._CohortCan(cohort, AUFTRAG.Type.OPSTRANSPORT, Mission.carrierCategories, Mission.carrierAttributes, Mission.carrierProperties, nil, TargetVec2)
|
||||||
local can=LEGION._CohortCan(cohort, AUFTRAG.Type.OPSTRANSPORT, Categories, Attributes, Properties, nil, TargetVec2)
|
|
||||||
|
|
||||||
-- MaxWeight of cargo assets is limited by the largets available cargo bay. We don't want to select, e.g., tanks that cannot be transported by APCs or helos.
|
-- MaxWeight of cargo assets is limited by the largets available cargo bay. We don't want to select, e.g., tanks that cannot be transported by APCs or helos.
|
||||||
if can and (MaxWeight==nil or cohort.cargobayLimit>MaxWeight) then
|
if can and (MaxWeight==nil or cohort.cargobayLimit>MaxWeight) then
|
||||||
|
|||||||
@@ -714,7 +714,7 @@ function LEGION:CheckMissionQueue()
|
|||||||
local Legions=mission.transportLegions or {self}
|
local Legions=mission.transportLegions or {self}
|
||||||
|
|
||||||
-- Assign carrier assets for transport.
|
-- Assign carrier assets for transport.
|
||||||
TransportAvail, Transport=self:AssignAssetsForTransport(Legions, assets, mission.NcarriersMin, mission.NcarriersMax, mission.transportDeployZone, mission.transportDisembarkZone)
|
TransportAvail, Transport=self:AssignAssetsForTransport(Legions, assets, mission.NcarriersMin, mission.NcarriersMax, mission.transportDeployZone, mission.transportDisembarkZone, mission.carrierCategories, mission.carrierAttributes, mission.carrierProperties)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Add opstransport to mission.
|
-- Add opstransport to mission.
|
||||||
@@ -2252,8 +2252,7 @@ function LEGION:RecruitAssetsForMission(Mission)
|
|||||||
local cohort=_cohort --Ops.Cohort#COHORT
|
local cohort=_cohort --Ops.Cohort#COHORT
|
||||||
|
|
||||||
-- Check if cohort can perform transport to target.
|
-- Check if cohort can perform transport to target.
|
||||||
--TODO: Option to filter transport carrier asset categories, attributes and/or properties.
|
local can=LEGION._CohortCan(cohort, AUFTRAG.Type.OPSTRANSPORT, Mission.carrierCategories, Mission.carrierAttributes, Mission.carrierProperties, nil, TargetVec2)
|
||||||
local can=LEGION._CohortCan(cohort, AUFTRAG.Type.OPSTRANSPORT, Categories, Attributes, Properties, nil, TargetVec2)
|
|
||||||
|
|
||||||
-- MaxWeight of cargo assets is limited by the largets available cargo bay. We don't want to select, e.g., tanks that cannot be transported by APCs or helos.
|
-- MaxWeight of cargo assets is limited by the largets available cargo bay. We don't want to select, e.g., tanks that cannot be transported by APCs or helos.
|
||||||
if can and (MaxWeight==nil or cohort.cargobayLimit>MaxWeight) then
|
if can and (MaxWeight==nil or cohort.cargobayLimit>MaxWeight) then
|
||||||
|
|||||||
@@ -1291,8 +1291,8 @@ function NAVYGROUP:onafterTurnIntoWind(From, Event, To, IntoWind)
|
|||||||
-- Convert to knots.
|
-- Convert to knots.
|
||||||
vwind=UTILS.MpsToKnots(vwind)
|
vwind=UTILS.MpsToKnots(vwind)
|
||||||
|
|
||||||
-- Speed of carrier relative to wind but at least 2 knots.
|
-- Speed of carrier relative to wind but at least 4 knots.
|
||||||
local speed=math.max(IntoWind.Speed-vwind, 2)
|
local speed=math.max(IntoWind.Speed-vwind, 4)
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T(self.lid..string.format("Steaming into wind: Heading=%03d Speed=%.1f Vwind=%.1f Vtot=%.1f knots, Tstart=%d Tstop=%d", IntoWind.Heading, speed, vwind, speed+vwind, IntoWind.Tstart, IntoWind.Tstop))
|
self:T(self.lid..string.format("Steaming into wind: Heading=%03d Speed=%.1f Vwind=%.1f Vtot=%.1f knots, Tstart=%d Tstop=%d", IntoWind.Heading, speed, vwind, speed+vwind, IntoWind.Tstart, IntoWind.Tstop))
|
||||||
|
|||||||
@@ -1536,7 +1536,7 @@ PLAYERTASKCONTROLLER.Messages = {
|
|||||||
|
|
||||||
--- PLAYERTASK class version.
|
--- PLAYERTASK class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
PLAYERTASKCONTROLLER.version="0.1.60"
|
PLAYERTASKCONTROLLER.version="0.1.60a"
|
||||||
|
|
||||||
--- Create and run a new TASKCONTROLLER instance.
|
--- Create and run a new TASKCONTROLLER instance.
|
||||||
-- @param #PLAYERTASKCONTROLLER self
|
-- @param #PLAYERTASKCONTROLLER self
|
||||||
@@ -2195,8 +2195,10 @@ function PLAYERTASKCONTROLLER:_EventHandler(EventData)
|
|||||||
--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,playername,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,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)
|
||||||
if EventData.IniUnitName then
|
if EventData.IniPlayerName then
|
||||||
self:_BuildMenus(CLIENT:FindByName(EventData.IniUnitName))
|
self.PlayerMenu[EventData.IniPlayerName] = nil
|
||||||
|
--self:_BuildMenus(CLIENT:FindByName(EventData.IniUnitName))
|
||||||
|
self:_BuildMenus(CLIENT:FindByPlayerName(EventData.IniPlayerName))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -3461,6 +3463,13 @@ end
|
|||||||
function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess)
|
function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess)
|
||||||
self:T(self.lid.."_BuildMenus")
|
self:T(self.lid.."_BuildMenus")
|
||||||
|
|
||||||
|
if self.MenuBuildLocked and (timer.getAbsTime() - self.MenuBuildLocked < 2) then
|
||||||
|
self:ScheduleOnce(2,self._BuildMenus,self,Client,enforced,fromsuccess)
|
||||||
|
return self
|
||||||
|
else
|
||||||
|
self.MenuBuildLocked = timer.getAbsTime()
|
||||||
|
end
|
||||||
|
|
||||||
local clients = self.ClientSet:GetAliveSet()
|
local clients = self.ClientSet:GetAliveSet()
|
||||||
local joinorabort = false
|
local joinorabort = false
|
||||||
local timedbuild = false
|
local timedbuild = false
|
||||||
@@ -3653,6 +3662,7 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
self.MenuBuildLocked = false
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1364,6 +1364,11 @@ MSRSQUEUE = {
|
|||||||
-- @field #number interval Interval in seconds before next transmission.
|
-- @field #number interval Interval in seconds before next transmission.
|
||||||
-- @field #boolean TransmitOnlyWithPlayers If true, only transmit if there are alive Players.
|
-- @field #boolean TransmitOnlyWithPlayers If true, only transmit if there are alive Players.
|
||||||
-- @field Core.Set#SET_CLIENT PlayerSet PlayerSet created when TransmitOnlyWithPlayers == true
|
-- @field Core.Set#SET_CLIENT PlayerSet PlayerSet created when TransmitOnlyWithPlayers == true
|
||||||
|
-- @field #string gender Voice gender
|
||||||
|
-- @field #string culture Voice culture
|
||||||
|
-- @field #string voice Voice if any
|
||||||
|
-- @field #number volume Volume
|
||||||
|
-- @field #string label Label to be used
|
||||||
|
|
||||||
--- Create a new MSRSQUEUE object for a given radio frequency/modulation.
|
--- Create a new MSRSQUEUE object for a given radio frequency/modulation.
|
||||||
-- @param #MSRSQUEUE self
|
-- @param #MSRSQUEUE self
|
||||||
@@ -1443,8 +1448,13 @@ end
|
|||||||
-- @param #number subduration Duration [sec] of the subtitle being displayed. Default 5 sec.
|
-- @param #number subduration Duration [sec] of the subtitle being displayed. Default 5 sec.
|
||||||
-- @param #number frequency Radio frequency if other than MSRS default.
|
-- @param #number frequency Radio frequency if other than MSRS default.
|
||||||
-- @param #number modulation Radio modulation if other then MSRS default.
|
-- @param #number modulation Radio modulation if other then MSRS default.
|
||||||
|
-- @param #string gender Gender of the voice
|
||||||
|
-- @param #string culture Culture of the voice
|
||||||
|
-- @param #string voice Specific voice
|
||||||
|
-- @param #number volume Volume setting
|
||||||
|
-- @param #string label Label to be used
|
||||||
-- @return #MSRSQUEUE.Transmission Radio transmission table.
|
-- @return #MSRSQUEUE.Transmission Radio transmission table.
|
||||||
function MSRSQUEUE:NewTransmission(text, duration, msrs, tstart, interval, subgroups, subtitle, subduration, frequency, modulation)
|
function MSRSQUEUE:NewTransmission(text, duration, msrs, tstart, interval, subgroups, subtitle, subduration, frequency, modulation, gender, culture, voice, volume, label)
|
||||||
|
|
||||||
if self.TransmitOnlyWithPlayers then
|
if self.TransmitOnlyWithPlayers then
|
||||||
if self.PlayerSet and self.PlayerSet:CountAlive() == 0 then
|
if self.PlayerSet and self.PlayerSet:CountAlive() == 0 then
|
||||||
@@ -1479,6 +1489,11 @@ function MSRSQUEUE:NewTransmission(text, duration, msrs, tstart, interval, subgr
|
|||||||
else
|
else
|
||||||
transmission.subduration=0 --nil
|
transmission.subduration=0 --nil
|
||||||
end
|
end
|
||||||
|
transmission.gender = gender
|
||||||
|
transmission.culture = culture
|
||||||
|
transmission.voice = voice
|
||||||
|
transmission.gender = volume
|
||||||
|
transmission.label = label
|
||||||
|
|
||||||
-- Add transmission to queue.
|
-- Add transmission to queue.
|
||||||
self:AddTransmission(transmission)
|
self:AddTransmission(transmission)
|
||||||
@@ -1492,7 +1507,7 @@ end
|
|||||||
function MSRSQUEUE:Broadcast(transmission)
|
function MSRSQUEUE:Broadcast(transmission)
|
||||||
|
|
||||||
if transmission.frequency then
|
if transmission.frequency then
|
||||||
transmission.msrs:PlayTextExt(transmission.text, nil, transmission.frequency, transmission.modulation, Gender, Culture, Voice, Volume, Label)
|
transmission.msrs:PlayTextExt(transmission.text, nil, transmission.frequency, transmission.modulation, transmission.gender, transmission.culture, transmission.voice, transmission.volume, transmission.label)
|
||||||
else
|
else
|
||||||
transmission.msrs:PlayText(transmission.text)
|
transmission.msrs:PlayText(transmission.text)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -426,7 +426,7 @@ AIRBASE.TheChannel = {
|
|||||||
-- * AIRBASE.Syria.Al_Dumayr
|
-- * AIRBASE.Syria.Al_Dumayr
|
||||||
-- * AIRBASE.Syria.Gazipasa
|
-- * AIRBASE.Syria.Gazipasa
|
||||||
-- * AIRBASE.Syria.Hatay
|
-- * AIRBASE.Syria.Hatay
|
||||||
-- * AIRBASE.Syria.Nicosia
|
-- * AIRBASE.Syria.Nicosia [Deactivated by ED as of June/2023]
|
||||||
-- * AIRBASE.Syria.Pinarbashi
|
-- * AIRBASE.Syria.Pinarbashi
|
||||||
-- * AIRBASE.Syria.Paphos
|
-- * AIRBASE.Syria.Paphos
|
||||||
-- * AIRBASE.Syria.Kingsfield
|
-- * AIRBASE.Syria.Kingsfield
|
||||||
@@ -491,7 +491,7 @@ AIRBASE.Syria={
|
|||||||
["Al_Dumayr"]="Al-Dumayr",
|
["Al_Dumayr"]="Al-Dumayr",
|
||||||
["Gazipasa"]="Gazipasa",
|
["Gazipasa"]="Gazipasa",
|
||||||
["Hatay"]="Hatay",
|
["Hatay"]="Hatay",
|
||||||
["Nicosia"]="Nicosia",
|
--["Nicosia"]="Nicosia",
|
||||||
["Pinarbashi"]="Pinarbashi",
|
["Pinarbashi"]="Pinarbashi",
|
||||||
["Paphos"]="Paphos",
|
["Paphos"]="Paphos",
|
||||||
["Kingsfield"]="Kingsfield",
|
["Kingsfield"]="Kingsfield",
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ do
|
|||||||
-- @field #number id
|
-- @field #number id
|
||||||
-- @field #number side
|
-- @field #number side
|
||||||
-- @field #number slot
|
-- @field #number slot
|
||||||
|
-- @field #numner timestamp
|
||||||
|
|
||||||
--- Encapsules multiplayer environment scripting functions from [net](https://wiki.hoggitworld.com/view/DCS_singleton_net)
|
--- Encapsules multiplayer environment scripting functions from [net](https://wiki.hoggitworld.com/view/DCS_singleton_net)
|
||||||
-- with some added FSM functions and options to block/unblock players in MP environments.
|
-- with some added FSM functions and options to block/unblock players in MP environments.
|
||||||
@@ -205,7 +206,7 @@ function NET:_EventHandler(EventData)
|
|||||||
|
|
||||||
-- Joining
|
-- Joining
|
||||||
if data.id == EVENTS.PlayerEnterUnit or data.id == EVENTS.PlayerEnterAircraft then
|
if data.id == EVENTS.PlayerEnterUnit or data.id == EVENTS.PlayerEnterAircraft then
|
||||||
self:T(self.lid.."Pilot Joining: "..name.." | UCID: "..ucid)
|
self:T(self.lid.."Pilot Joining: "..name.." | UCID: "..ucid.." | Event ID: "..data.id)
|
||||||
-- Check for blockages
|
-- Check for blockages
|
||||||
local blocked = self:IsAnyBlocked(ucid,name,PlayerID,PlayerSide,PlayerSlot)
|
local blocked = self:IsAnyBlocked(ucid,name,PlayerID,PlayerSide,PlayerSlot)
|
||||||
|
|
||||||
@@ -213,15 +214,18 @@ function NET:_EventHandler(EventData)
|
|||||||
-- block pilot
|
-- block pilot
|
||||||
local outcome = net.force_player_slot(tonumber(PlayerID), 0, '' )
|
local outcome = net.force_player_slot(tonumber(PlayerID), 0, '' )
|
||||||
else
|
else
|
||||||
self.KnownPilots[name] = {
|
|
||||||
name = name,
|
|
||||||
ucid = ucid,
|
|
||||||
id = PlayerID,
|
|
||||||
side = PlayerSide,
|
|
||||||
slot = PlayerSlot,
|
|
||||||
}
|
|
||||||
local client = CLIENT:FindByPlayerName(name) or data.IniUnit
|
local client = CLIENT:FindByPlayerName(name) or data.IniUnit
|
||||||
self:__PlayerJoined(1,client,name)
|
if not self.KnownPilots[name] or (self.KnownPilots[name] and TNow-self.KnownPilots[name].timestamp > 3) then
|
||||||
|
self:__PlayerJoined(1,client,name)
|
||||||
|
self.KnownPilots[name] = {
|
||||||
|
name = name,
|
||||||
|
ucid = ucid,
|
||||||
|
id = PlayerID,
|
||||||
|
side = PlayerSide,
|
||||||
|
slot = PlayerSlot,
|
||||||
|
timestamp = TNow,
|
||||||
|
}
|
||||||
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -239,19 +239,18 @@ end
|
|||||||
function POSITIONABLE:GetVec3()
|
function POSITIONABLE:GetVec3()
|
||||||
local DCSPositionable = self:GetDCSObject()
|
local DCSPositionable = self:GetDCSObject()
|
||||||
if DCSPositionable then
|
if DCSPositionable then
|
||||||
-- local status, vec3 = pcall(
|
--local status, vec3 = pcall(
|
||||||
-- function()
|
-- function()
|
||||||
-- local vec3 = DCSPositionable:getPoint()
|
-- local vec3 = DCSPositionable:getPoint()
|
||||||
-- return vec3
|
-- return vec3
|
||||||
-- end
|
--end
|
||||||
-- )
|
--)
|
||||||
local vec3 = DCSPositionable:getPoint()
|
local vec3 = DCSPositionable:getPoint()
|
||||||
return vec3
|
--if status then
|
||||||
-- if status then
|
return vec3
|
||||||
-- return vec3
|
--else
|
||||||
-- else
|
--self:E( { "Cannot get Vec3 from DCS Object", Positionable = self, Alive = self:IsAlive() } )
|
||||||
-- self:E( { "Cannot get Vec3 from DCS Object", Positionable = self, Alive = self:IsAlive() } )
|
--end
|
||||||
-- end
|
|
||||||
end
|
end
|
||||||
-- ERROR!
|
-- ERROR!
|
||||||
self:E( { "Cannot get the Positionable DCS Object for GetVec3", Positionable = self, Alive = self:IsAlive() } )
|
self:E( { "Cannot get the Positionable DCS Object for GetVec3", Positionable = self, Alive = self:IsAlive() } )
|
||||||
|
|||||||
@@ -703,15 +703,15 @@ function UNIT:GetAmmo()
|
|||||||
self:F2( self.UnitName )
|
self:F2( self.UnitName )
|
||||||
local DCSUnit = self:GetDCSObject()
|
local DCSUnit = self:GetDCSObject()
|
||||||
if DCSUnit then
|
if DCSUnit then
|
||||||
-- local status, unitammo = pcall(
|
--local status, unitammo = pcall(
|
||||||
-- function()
|
-- function()
|
||||||
-- local UnitAmmo = DCSUnit:getAmmo()
|
-- local UnitAmmo = DCSUnit:getAmmo()
|
||||||
-- return UnitAmmo
|
-- return UnitAmmo
|
||||||
-- end
|
--end
|
||||||
-- )
|
--)
|
||||||
-- if status then
|
--if status then
|
||||||
-- return unitammo
|
--return unitammo
|
||||||
-- end
|
--end
|
||||||
local UnitAmmo = DCSUnit:getAmmo()
|
local UnitAmmo = DCSUnit:getAmmo()
|
||||||
return UnitAmmo
|
return UnitAmmo
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user