mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
#AIRBASE, ATIS
* less noise in log #SRS * Added enumerator for voices MSRS.Voices.Microsoft... and MSRS.Voices.Google... #RANGE * Added SRS support, some bug fixing
This commit is contained in:
parent
b5186fa328
commit
450f4eaec0
@ -45,6 +45,7 @@
|
|||||||
-- ### Author: **[funkyfranky](https://forums.eagle.ru/member.php?u=115026)**
|
-- ### Author: **[funkyfranky](https://forums.eagle.ru/member.php?u=115026)**
|
||||||
--
|
--
|
||||||
-- ### Contributions: [FlightControl](https://forums.eagle.ru/member.php?u=89536), [Ciribob](https://forums.eagle.ru/member.php?u=112175)
|
-- ### Contributions: [FlightControl](https://forums.eagle.ru/member.php?u=89536), [Ciribob](https://forums.eagle.ru/member.php?u=112175)
|
||||||
|
-- ### SRS Additions: Applevangelist
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
-- @module Functional.Range
|
-- @module Functional.Range
|
||||||
@ -101,6 +102,10 @@
|
|||||||
-- @field #boolean targetsheet If true, players can save their target sheets. Rangeboss will not work if targetsheets do not save.
|
-- @field #boolean targetsheet If true, players can save their target sheets. Rangeboss will not work if targetsheets do not save.
|
||||||
-- @field #string targetpath Path where to save the target sheets.
|
-- @field #string targetpath Path where to save the target sheets.
|
||||||
-- @field #string targetprefix File prefix for target sheet files.
|
-- @field #string targetprefix File prefix for target sheet files.
|
||||||
|
-- @field Sound.SRS#MSRS controlmsrs
|
||||||
|
-- @field Sound.SRS#MSRSQUEUE controlsrsQ
|
||||||
|
-- @field Sound.SRS#MSRS instructmsrs
|
||||||
|
-- @field Sound.SRS#MSRSQUEUE instructsrsQ
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
--- *Don't only practice your art, but force your way into its secrets; art deserves that, for it and knowledge can raise man to the Divine.* - Ludwig van Beethoven
|
--- *Don't only practice your art, but force your way into its secrets; art deserves that, for it and knowledge can raise man to the Divine.* - Ludwig van Beethoven
|
||||||
@ -225,6 +230,11 @@
|
|||||||
--
|
--
|
||||||
-- By default, the sound files are placed in the "Range Soundfiles/" folder inside the mission (.miz) file. Another folder can be specified via the @{#RANGE.SetSoundfilesPath}(*path*) function.
|
-- By default, the sound files are placed in the "Range Soundfiles/" folder inside the mission (.miz) file. Another folder can be specified via the @{#RANGE.SetSoundfilesPath}(*path*) function.
|
||||||
--
|
--
|
||||||
|
-- ## Voice output via SRS
|
||||||
|
--
|
||||||
|
-- Alternatively, the voice output can be fully done via SRS, **no sound file additions needed**. Set up SRS with @{#RANGE.SetSRS}(). Range control and instructor frequencies and voices can then be
|
||||||
|
-- set via @{#RANGE.SetSRSRangeControl}() and @{#RANGE.SetSRSRangeInstructor}()
|
||||||
|
--
|
||||||
-- # Persistence
|
-- # Persistence
|
||||||
--
|
--
|
||||||
-- To automatically save bombing results to disk, use the @{#RANGE.SetAutosave}() function. Bombing results will be saved as csv file in your "Saved Games\DCS.openbeta\Logs" directory.
|
-- To automatically save bombing results to disk, use the @{#RANGE.SetAutosave}() function. Bombing results will be saved as csv file in your "Saved Games\DCS.openbeta\Logs" directory.
|
||||||
@ -568,7 +578,7 @@ RANGE.MenuF10Root = nil
|
|||||||
|
|
||||||
--- Range script version.
|
--- Range script version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
RANGE.version = "2.4.0"
|
RANGE.version = "2.5.0"
|
||||||
|
|
||||||
-- TODO list:
|
-- TODO list:
|
||||||
-- TODO: Verbosity level for messages.
|
-- TODO: Verbosity level for messages.
|
||||||
@ -833,7 +843,7 @@ function RANGE:onafterStart()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Init range control.
|
-- Init range control.
|
||||||
if self.rangecontrolfreq then
|
if self.rangecontrolfreq and not self.useSRS then
|
||||||
|
|
||||||
-- Radio queue.
|
-- Radio queue.
|
||||||
self.rangecontrol = RADIOQUEUE:New( self.rangecontrolfreq, nil, self.rangename )
|
self.rangecontrol = RADIOQUEUE:New( self.rangecontrolfreq, nil, self.rangename )
|
||||||
@ -859,7 +869,7 @@ function RANGE:onafterStart()
|
|||||||
self.rangecontrol:Start( 1, 0.1 )
|
self.rangecontrol:Start( 1, 0.1 )
|
||||||
|
|
||||||
-- Init range control.
|
-- Init range control.
|
||||||
if self.instructorfreq then
|
if self.instructorfreq and not self.useSRS then
|
||||||
|
|
||||||
-- Radio queue.
|
-- Radio queue.
|
||||||
self.instructor = RADIOQUEUE:New( self.instructorfreq, nil, self.rangename )
|
self.instructor = RADIOQUEUE:New( self.instructorfreq, nil, self.rangename )
|
||||||
@ -1177,7 +1187,91 @@ function RANGE:TrackMissilesOFF()
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Enable range control and set frequency.
|
--- Use SRS Simple-Text-To-Speech for transmissions. No sound files necessary.
|
||||||
|
-- @param #RANGE self
|
||||||
|
-- @param #string PathToSRS Path to SRS directory.
|
||||||
|
-- @param #number Port SRS port. Default 5002.
|
||||||
|
-- @param #number Coalition Coalition side, e.g. coalition.side.BLUE or coalition.side.RED
|
||||||
|
-- @param #number Frequency Frequency to use, defaults to 256 (same as rangecontrol)
|
||||||
|
-- @param #number Modulation Modulation to use, defaults to radio.modulation.AM
|
||||||
|
-- @param #number Volume Volume, between 0.0 and 1.0. Defaults to 1.0
|
||||||
|
-- @param #string PathToGoogleKey Path to Google TTS credentials.
|
||||||
|
-- @return #RANGE self
|
||||||
|
function RANGE:SetSRS(PathToSRS, Port, Coalition, Frequency, Modulation, Volume, PathToGoogleKey)
|
||||||
|
if PathToSRS then
|
||||||
|
|
||||||
|
self.useSRS=true
|
||||||
|
|
||||||
|
self.controlmsrs=MSRS:New(PathToSRS, Frequency or 256, Modulation or radio.modulation.AM, Volume or 1.0)
|
||||||
|
self.controlmsrs:SetPort(Port)
|
||||||
|
self.controlmsrs:SetCoalition(Coalition or coalition.side.BLUE)
|
||||||
|
self.controlmsrs:SetLabel("RANGEC")
|
||||||
|
self.controlsrsQ = MSRSQUEUE:New("CONTROL")
|
||||||
|
|
||||||
|
self.instructmsrs=MSRS:New(PathToSRS, Frequency or 305, Modulation or radio.modulation.AM, Volume or 1.0)
|
||||||
|
self.instructmsrs:SetPort(Port)
|
||||||
|
self.instructmsrs:SetCoalition(Coalition or coalition.side.BLUE)
|
||||||
|
self.instructmsrs:SetLabel("RANGEI")
|
||||||
|
self.instructsrsQ = MSRSQUEUE:New("INSTRUCT")
|
||||||
|
|
||||||
|
else
|
||||||
|
self:E(self.lid..string.format("ERROR: No SRS path specified!"))
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- (SRS) Set range control frequency and voice.
|
||||||
|
-- @param #RANGE self
|
||||||
|
-- @param #number frequency Frequency in MHz. Default 256 MHz.
|
||||||
|
-- @param #number modulation Modulation, defaults to radio.modulation.AM.
|
||||||
|
-- @param #string voice Voice.
|
||||||
|
-- @param #string culture Culture, defaults to "en-US".
|
||||||
|
-- @param #string gender Gender, defaults to "female".
|
||||||
|
-- @param #string relayunitname Name of the unit used for transmission location.
|
||||||
|
-- @return #RANGE self
|
||||||
|
function RANGE:SetSRSRangeControl( frequency, modulation, voice, culture, gender, relayunitname )
|
||||||
|
self.rangecontrolfreq = frequency or 256
|
||||||
|
self.controlmsrs:SetFrequencies(self.rangecontrolfreq)
|
||||||
|
self.controlmsrs:SetModulations(modulation or radio.modulation.AM)
|
||||||
|
self.controlmsrs:SetVoice(voice)
|
||||||
|
self.controlmsrs:SetCulture(culture or "en-US")
|
||||||
|
self.controlmsrs:SetGender(gender or "female")
|
||||||
|
self.rangecontrol = true
|
||||||
|
if relayunitname then
|
||||||
|
local unit = UNIT:FindByName(relayunitname)
|
||||||
|
local Coordinate = unit:GetCoordinate()
|
||||||
|
self.rangecontrolrelayname = relayunitname
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- (SRS) Set range instructor frequency and voice.
|
||||||
|
-- @param #RANGE self
|
||||||
|
-- @param #number frequency Frequency in MHz. Default 305 MHz.
|
||||||
|
-- @param #number modulation Modulation, defaults to radio.modulation.AM.
|
||||||
|
-- @param #string voice Voice.
|
||||||
|
-- @param #string culture Culture, defaults to "en-US".
|
||||||
|
-- @param #string gender Gender, defaults to "male".
|
||||||
|
-- @param #string relayunitname Name of the unit used for transmission location.
|
||||||
|
-- @return #RANGE self
|
||||||
|
function RANGE:SetSRSRangeInstructor( frequency, modulation, voice, culture, gender, relayunitname )
|
||||||
|
self.instructorfreq = frequency or 305
|
||||||
|
self.instructmsrs:SetFrequencies(self.instructorfreq)
|
||||||
|
self.instructmsrs:SetModulations(modulation or radio.modulation.AM)
|
||||||
|
self.instructmsrs:SetVoice(voice)
|
||||||
|
self.instructmsrs:SetCulture(culture or "en-US")
|
||||||
|
self.instructmsrs:SetGender(gender or "male")
|
||||||
|
self.instructor = true
|
||||||
|
if relayunitname then
|
||||||
|
local unit = UNIT:FindByName(relayunitname)
|
||||||
|
local Coordinate = unit:GetCoordinate()
|
||||||
|
self.instructmsrs:SetCoordinate(Coordinate)
|
||||||
|
self.instructorrelayname = relayunitname
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Enable range control and set frequency (non-SRS).
|
||||||
-- @param #RANGE self
|
-- @param #RANGE self
|
||||||
-- @param #number frequency Frequency in MHz. Default 256 MHz.
|
-- @param #number frequency Frequency in MHz. Default 256 MHz.
|
||||||
-- @param #string relayunitname Name of the unit used for transmission.
|
-- @param #string relayunitname Name of the unit used for transmission.
|
||||||
@ -1188,7 +1282,7 @@ function RANGE:SetRangeControl( frequency, relayunitname )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Enable instructor radio and set frequency.
|
--- Enable instructor radio and set frequency (non-SRS).
|
||||||
-- @param #RANGE self
|
-- @param #RANGE self
|
||||||
-- @param #number frequency Frequency in MHz. Default 305 MHz.
|
-- @param #number frequency Frequency in MHz. Default 305 MHz.
|
||||||
-- @param #string relayunitname Name of the unit used for transmission.
|
-- @param #string relayunitname Name of the unit used for transmission.
|
||||||
@ -1811,6 +1905,10 @@ function RANGE:OnEventShot( EventData )
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if EventData.IniPlayerName == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
-- Weapon data.
|
-- Weapon data.
|
||||||
local _weapon = EventData.Weapon:getTypeName() -- should be the same as Event.WeaponTypeName
|
local _weapon = EventData.Weapon:getTypeName() -- should be the same as Event.WeaponTypeName
|
||||||
local _weaponStrArray = UTILS.Split( _weapon, "%." )
|
local _weaponStrArray = UTILS.Split( _weapon, "%." )
|
||||||
@ -2003,8 +2101,12 @@ function RANGE:OnEventShot( EventData )
|
|||||||
|
|
||||||
if self.rangecontrol then
|
if self.rangecontrol then
|
||||||
-- weapon impacted too far from the nearest target! No Score!
|
-- weapon impacted too far from the nearest target! No Score!
|
||||||
|
if self.useSRS then
|
||||||
|
self.controlsrsQ:NewTransmission(_message,nil,self.controlmsrs,nil,1)
|
||||||
|
else
|
||||||
self.rangecontrol:NewTransmission( RANGE.Sound.RCWeaponImpactedTooFar.filename, RANGE.Sound.RCWeaponImpactedTooFar.duration, self.soundpath, nil, nil, _message, self.subduration )
|
self.rangecontrol:NewTransmission( RANGE.Sound.RCWeaponImpactedTooFar.filename, RANGE.Sound.RCWeaponImpactedTooFar.duration, self.soundpath, nil, nil, _message, self.subduration )
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
self:T( self.id .. "Weapon impacted outside range zone." )
|
self:T( self.id .. "Weapon impacted outside range zone." )
|
||||||
@ -2087,11 +2189,17 @@ function RANGE:onafterEnterRange( From, Event, To, player )
|
|||||||
|
|
||||||
if self.instructor and self.rangecontrol then
|
if self.instructor and self.rangecontrol then
|
||||||
|
|
||||||
|
if self.useSRS then
|
||||||
|
local text = string.format("You entered the bombing range. For hit assessment, contact the range controller at %.3f MHz", self.rangecontrolfreq)
|
||||||
|
local ttstext = string.format("You entered the bombing range. For hit assessment, contact the range controller at %.3f mega hertz.", self.rangecontrolfreq)
|
||||||
|
local group = player.client:GetGroup()
|
||||||
|
self.instructsrsQ:NewTransmission(ttstext,nil,self.instructmsrs,nil,1,{group},text,10)
|
||||||
|
else
|
||||||
-- Range control radio frequency split.
|
-- Range control radio frequency split.
|
||||||
local RF = UTILS.Split( string.format( "%.3f", self.rangecontrolfreq ), "." )
|
local RF = UTILS.Split( string.format( "%.3f", self.rangecontrolfreq ), "." )
|
||||||
|
|
||||||
-- Radio message that player entered the range
|
-- Radio message that player entered the range
|
||||||
-- You entered the bombing range. For hit assessment, contact the range controller.
|
-- You entered the bombing range. For hit assessment, contact the range controller at xy MHz
|
||||||
self.instructor:NewTransmission( RANGE.Sound.IREnterRange.filename, RANGE.Sound.IREnterRange.duration, self.soundpath )
|
self.instructor:NewTransmission( RANGE.Sound.IREnterRange.filename, RANGE.Sound.IREnterRange.duration, self.soundpath )
|
||||||
self.instructor:Number2Transmission( RF[1] )
|
self.instructor:Number2Transmission( RF[1] )
|
||||||
if tonumber( RF[2] ) > 0 then
|
if tonumber( RF[2] ) > 0 then
|
||||||
@ -2100,6 +2208,7 @@ function RANGE:onafterEnterRange( From, Event, To, player )
|
|||||||
end
|
end
|
||||||
self.instructor:NewTransmission( RANGE.Sound.IRMegaHertz.filename, RANGE.Sound.IRMegaHertz.duration, self.soundpath )
|
self.instructor:NewTransmission( RANGE.Sound.IRMegaHertz.filename, RANGE.Sound.IRMegaHertz.duration, self.soundpath )
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -2113,8 +2222,14 @@ function RANGE:onafterExitRange( From, Event, To, player )
|
|||||||
|
|
||||||
if self.instructor then
|
if self.instructor then
|
||||||
-- You left the bombing range zone. Have a nice day!
|
-- You left the bombing range zone. Have a nice day!
|
||||||
|
if self.useSRS then
|
||||||
|
local text = "You left the bombing range zone. Have a nice day!"
|
||||||
|
local group = player.client:GetGroup()
|
||||||
|
self.instructsrsQ:NewTransmission(text,nil,self.instructmsrs,nil,1,{group},text,10)
|
||||||
|
else
|
||||||
self.instructor:NewTransmission( RANGE.Sound.IRExitRange.filename, RANGE.Sound.IRExitRange.duration, self.soundpath )
|
self.instructor:NewTransmission( RANGE.Sound.IRExitRange.filename, RANGE.Sound.IRExitRange.duration, self.soundpath )
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -2143,6 +2258,11 @@ function RANGE:onafterImpact( From, Event, To, result, player )
|
|||||||
text = text .. string.format( " %s hit.", result.quality )
|
text = text .. string.format( " %s hit.", result.quality )
|
||||||
|
|
||||||
if self.rangecontrol then
|
if self.rangecontrol then
|
||||||
|
|
||||||
|
if self.useSRS then
|
||||||
|
local group = player.client:GetGroup()
|
||||||
|
self.controlsrsQ:NewTransmission(text,nil,self.controlmsrs,nil,1,{group},text,10)
|
||||||
|
else
|
||||||
self.rangecontrol:NewTransmission( RANGE.Sound.RCImpact.filename, RANGE.Sound.RCImpact.duration, self.soundpath, nil, nil, text, self.subduration )
|
self.rangecontrol:NewTransmission( RANGE.Sound.RCImpact.filename, RANGE.Sound.RCImpact.duration, self.soundpath, nil, nil, text, self.subduration )
|
||||||
self.rangecontrol:Number2Transmission( string.format( "%03d", result.radial ), nil, 0.1 )
|
self.rangecontrol:Number2Transmission( string.format( "%03d", result.radial ), nil, 0.1 )
|
||||||
self.rangecontrol:NewTransmission( RANGE.Sound.RCDegrees.filename, RANGE.Sound.RCDegrees.duration, self.soundpath )
|
self.rangecontrol:NewTransmission( RANGE.Sound.RCDegrees.filename, RANGE.Sound.RCDegrees.duration, self.soundpath )
|
||||||
@ -2158,11 +2278,11 @@ function RANGE:onafterImpact( From, Event, To, result, player )
|
|||||||
elseif result.quality == "EXCELLENT" then
|
elseif result.quality == "EXCELLENT" then
|
||||||
self.rangecontrol:NewTransmission( RANGE.Sound.RCExcellentHit.filename, RANGE.Sound.RCExcellentHit.duration, self.soundpath, nil, 0.5 )
|
self.rangecontrol:NewTransmission( RANGE.Sound.RCExcellentHit.filename, RANGE.Sound.RCExcellentHit.duration, self.soundpath, nil, 0.5 )
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Unit.
|
-- Unit.
|
||||||
if player.unitname then
|
if player.unitname and not self.useSRS then
|
||||||
|
|
||||||
-- Get unit.
|
-- Get unit.
|
||||||
local unit = UNIT:FindByName( player.unitname )
|
local unit = UNIT:FindByName( player.unitname )
|
||||||
@ -2680,7 +2800,7 @@ function RANGE:_DisplayRangeInfo( _unitname )
|
|||||||
|
|
||||||
-- Check if we have a player.
|
-- Check if we have a player.
|
||||||
if unit and playername then
|
if unit and playername then
|
||||||
|
self:I(playername)
|
||||||
-- Message text.
|
-- Message text.
|
||||||
local text = ""
|
local text = ""
|
||||||
|
|
||||||
@ -2749,7 +2869,8 @@ function RANGE:_DisplayRangeInfo( _unitname )
|
|||||||
if self.instructorrelayname then
|
if self.instructorrelayname then
|
||||||
local relay = UNIT:FindByName( self.instructorrelayname )
|
local relay = UNIT:FindByName( self.instructorrelayname )
|
||||||
if relay then
|
if relay then
|
||||||
alive = tostring( relay:IsAlive() )
|
--alive = tostring( relay:IsAlive() )
|
||||||
|
alive = relay:IsAlive() and "ok" or "N/A"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
text = text .. string.format( "Instructor %.3f MHz (Relay=%s)\n", self.instructorfreq, alive )
|
text = text .. string.format( "Instructor %.3f MHz (Relay=%s)\n", self.instructorfreq, alive )
|
||||||
@ -2760,6 +2881,7 @@ function RANGE:_DisplayRangeInfo( _unitname )
|
|||||||
local relay = UNIT:FindByName( self.rangecontrolrelayname )
|
local relay = UNIT:FindByName( self.rangecontrolrelayname )
|
||||||
if relay then
|
if relay then
|
||||||
alive = tostring( relay:IsAlive() )
|
alive = tostring( relay:IsAlive() )
|
||||||
|
alive = relay:IsAlive() and "ok" or "N/A"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
text = text .. string.format( "Control %.3f MHz (Relay=%s)\n", self.rangecontrolfreq, alive )
|
text = text .. string.format( "Control %.3f MHz (Relay=%s)\n", self.rangecontrolfreq, alive )
|
||||||
@ -3046,10 +3168,16 @@ function RANGE:_CheckInZone( _unitName )
|
|||||||
self:_DisplayMessageToGroup( _unit, _msg, nil, true )
|
self:_DisplayMessageToGroup( _unit, _msg, nil, true )
|
||||||
|
|
||||||
if self.rangecontrol then
|
if self.rangecontrol then
|
||||||
|
if self.useSRS then
|
||||||
|
local group = _unit:GetGroup()
|
||||||
|
local text = "You left the strafing zone too quickly! No score!"
|
||||||
|
--self.controlsrsQ:NewTransmission(text,nil,self.controlmsrs,nil,1,{group},text,10)
|
||||||
|
self.controlsrsQ:NewTransmission(text,nil,self.controlmsrs,nil,1)
|
||||||
|
else
|
||||||
-- You left the strafing zone too quickly! No score!
|
-- You left the strafing zone too quickly! No score!
|
||||||
self.rangecontrol:NewTransmission( RANGE.Sound.RCLeftStrafePitTooQuickly.filename, RANGE.Sound.RCLeftStrafePitTooQuickly.duration, self.soundpath )
|
self.rangecontrol:NewTransmission( RANGE.Sound.RCLeftStrafePitTooQuickly.filename, RANGE.Sound.RCLeftStrafePitTooQuickly.duration, self.soundpath )
|
||||||
end
|
end
|
||||||
|
end
|
||||||
else
|
else
|
||||||
|
|
||||||
-- Get current ammo.
|
-- Get current ammo.
|
||||||
@ -3113,10 +3241,13 @@ function RANGE:_CheckInZone( _unitName )
|
|||||||
|
|
||||||
-- Message text.
|
-- Message text.
|
||||||
local _text = string.format( "%s, hits on target %s: %d", self:_myname( _unitName ), _result.zone.name, _result.hits )
|
local _text = string.format( "%s, hits on target %s: %d", self:_myname( _unitName ), _result.zone.name, _result.hits )
|
||||||
|
local ttstext = string.format( "%s, hits on target %s: %d.", self:_myname( _unitName ), _result.zone.name, _result.hits )
|
||||||
if shots and accur then
|
if shots and accur then
|
||||||
_text = _text .. string.format( "\nTotal rounds fired %d. Accuracy %.1f %%.", shots, accur )
|
_text = _text .. string.format( "\nTotal rounds fired %d. Accuracy %.1f %%.", shots, accur )
|
||||||
|
ttstext = ttstext .. string.format( ". Total rounds fired %d. Accuracy %.1f percent.", shots, accur )
|
||||||
end
|
end
|
||||||
_text = _text .. string.format( "\n%s", resulttext )
|
_text = _text .. string.format( "\n%s", resulttext )
|
||||||
|
ttstext = ttstext .. string.format( " %s", resulttext )
|
||||||
|
|
||||||
-- Send message.
|
-- Send message.
|
||||||
self:_DisplayMessageToGroup( _unit, _text )
|
self:_DisplayMessageToGroup( _unit, _text )
|
||||||
@ -3148,6 +3279,9 @@ function RANGE:_CheckInZone( _unitName )
|
|||||||
|
|
||||||
-- Voice over.
|
-- Voice over.
|
||||||
if self.rangecontrol then
|
if self.rangecontrol then
|
||||||
|
if self.useSRS then
|
||||||
|
self.controlsrsQ:NewTransmission(ttstext,nil,self.controlmsrs,nil,1)
|
||||||
|
else
|
||||||
self.rangecontrol:NewTransmission( RANGE.Sound.RCHitsOnTarget.filename, RANGE.Sound.RCHitsOnTarget.duration, self.soundpath )
|
self.rangecontrol:NewTransmission( RANGE.Sound.RCHitsOnTarget.filename, RANGE.Sound.RCHitsOnTarget.duration, self.soundpath )
|
||||||
self.rangecontrol:Number2Transmission( string.format( "%d", _result.hits ) )
|
self.rangecontrol:Number2Transmission( string.format( "%d", _result.hits ) )
|
||||||
if shots and accur then
|
if shots and accur then
|
||||||
@ -3159,6 +3293,7 @@ function RANGE:_CheckInZone( _unitName )
|
|||||||
end
|
end
|
||||||
self.rangecontrol:NewTransmission( _sound.filename, _sound.duration, self.soundpath, nil, 0.5 )
|
self.rangecontrol:NewTransmission( _sound.filename, _sound.duration, self.soundpath, nil, 0.5 )
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Set strafe status to nil.
|
-- Set strafe status to nil.
|
||||||
self.strafeStatus[_unitID] = nil
|
self.strafeStatus[_unitID] = nil
|
||||||
@ -3196,8 +3331,12 @@ function RANGE:_CheckInZone( _unitName )
|
|||||||
local _msg = string.format( "%s, rolling in on strafe pit %s.", self:_myname( _unitName ), target.name )
|
local _msg = string.format( "%s, rolling in on strafe pit %s.", self:_myname( _unitName ), target.name )
|
||||||
|
|
||||||
if self.rangecontrol then
|
if self.rangecontrol then
|
||||||
|
if self.useSRS then
|
||||||
|
self.controlsrsQ:NewTransmission(_msg,nil,self.controlmsrs,nil,1)
|
||||||
|
else
|
||||||
self.rangecontrol:NewTransmission( RANGE.Sound.RCRollingInOnStrafeTarget.filename, RANGE.Sound.RCRollingInOnStrafeTarget.duration, self.soundpath )
|
self.rangecontrol:NewTransmission( RANGE.Sound.RCRollingInOnStrafeTarget.filename, RANGE.Sound.RCRollingInOnStrafeTarget.duration, self.soundpath )
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Send message.
|
-- Send message.
|
||||||
self:_DisplayMessageToGroup( _unit, _msg, 10, true )
|
self:_DisplayMessageToGroup( _unit, _msg, 10, true )
|
||||||
@ -3923,6 +4062,7 @@ function RANGE:_GetPlayerUnitAndName( _unitName )
|
|||||||
|
|
||||||
self:T2( { DCSunit = DCSunit, unit = unit, playername = playername } )
|
self:T2( { DCSunit = DCSunit, unit = unit, playername = playername } )
|
||||||
if DCSunit and unit and playername then
|
if DCSunit and unit and playername then
|
||||||
|
self:F2(playername)
|
||||||
return unit, playername
|
return unit, playername
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -3939,13 +4079,22 @@ end
|
|||||||
-- @param #string unitname Name of the player unit.
|
-- @param #string unitname Name of the player unit.
|
||||||
function RANGE:_myname( unitname )
|
function RANGE:_myname( unitname )
|
||||||
self:F2( unitname )
|
self:F2( unitname )
|
||||||
|
local pname = "Ghost 1 1"
|
||||||
local unit = UNIT:FindByName( unitname )
|
local unit = UNIT:FindByName( unitname )
|
||||||
|
if unit then
|
||||||
|
local grp = unit:GetGroup()
|
||||||
|
if grp then
|
||||||
|
pname = grp:GetCustomCallSign(true,true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--[[
|
||||||
local pname = unit:GetPlayerName()
|
local pname = unit:GetPlayerName()
|
||||||
-- local csign = unit:GetCallsign()
|
-- local csign = unit:GetCallsign()
|
||||||
|
|
||||||
-- return string.format("%s (%s)", csign, pname)
|
-- return string.format("%s (%s)", csign, pname)
|
||||||
return string.format( "%s", pname )
|
return string.format( "%s", pname )
|
||||||
|
--]]
|
||||||
|
return pname
|
||||||
end
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -745,7 +745,7 @@ end
|
|||||||
-- @return #ATIS self
|
-- @return #ATIS self
|
||||||
function ATIS:SetSoundfilesPath( path )
|
function ATIS:SetSoundfilesPath( path )
|
||||||
self.soundpath = tostring( path or "ATIS Soundfiles/" )
|
self.soundpath = tostring( path or "ATIS Soundfiles/" )
|
||||||
self:I( self.lid .. string.format( "Setting sound files path to %s", self.soundpath ) )
|
self:T( self.lid .. string.format( "Setting sound files path to %s", self.soundpath ) )
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -756,7 +756,7 @@ end
|
|||||||
-- @return #ATIS self
|
-- @return #ATIS self
|
||||||
function ATIS:SetRadioRelayUnitName( unitname )
|
function ATIS:SetRadioRelayUnitName( unitname )
|
||||||
self.relayunitname = unitname
|
self.relayunitname = unitname
|
||||||
self:I( self.lid .. string.format( "Setting radio relay unit to %s", self.relayunitname ) )
|
self:T( self.lid .. string.format( "Setting radio relay unit to %s", self.relayunitname ) )
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -851,7 +851,7 @@ function ATIS:SetRunwayHeadingsMagnetic( headings )
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Add runway heading to table.
|
-- Add runway heading to table.
|
||||||
self:I( self.lid .. string.format( "Adding user specified magnetic runway heading %s", heading ) )
|
self:T( self.lid .. string.format( "Adding user specified magnetic runway heading %s", heading ) )
|
||||||
table.insert( self.runwaymag, heading )
|
table.insert( self.runwaymag, heading )
|
||||||
|
|
||||||
local h = self:GetRunwayWithoutLR( heading )
|
local h = self:GetRunwayWithoutLR( heading )
|
||||||
@ -873,7 +873,7 @@ function ATIS:SetRunwayHeadingsMagnetic( headings )
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Add inverse runway heading to table.
|
-- Add inverse runway heading to table.
|
||||||
self:I( self.lid .. string.format( "Adding user specified magnetic runway heading %s (inverse)", head2 ) )
|
self:T( self.lid .. string.format( "Adding user specified magnetic runway heading %s (inverse)", head2 ) )
|
||||||
table.insert( self.runwaymag, head2 )
|
table.insert( self.runwaymag, head2 )
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1245,7 +1245,7 @@ function ATIS:onafterStatus( From, Event, To )
|
|||||||
else
|
else
|
||||||
text = text .. string.format( ", Relay unit=%s (alive=%s)", tostring( self.relayunitname ), relayunitstatus )
|
text = text .. string.format( ", Relay unit=%s (alive=%s)", tostring( self.relayunitname ), relayunitstatus )
|
||||||
end
|
end
|
||||||
self:I( self.lid .. text )
|
self:T( self.lid .. text )
|
||||||
|
|
||||||
self:__Status( -60 )
|
self:__Status( -60 )
|
||||||
end
|
end
|
||||||
@ -2433,7 +2433,7 @@ end
|
|||||||
-- @return #string Runway heading without left or right, *e.g.* "31".
|
-- @return #string Runway heading without left or right, *e.g.* "31".
|
||||||
function ATIS:GetRunwayWithoutLR( runway )
|
function ATIS:GetRunwayWithoutLR( runway )
|
||||||
local rwywo = runway:gsub( "%D+", "" )
|
local rwywo = runway:gsub( "%D+", "" )
|
||||||
-- self:I(string.format("FF runway=%s ==> rwywo=%s", runway, rwywo))
|
-- self:T(string.format("FF runway=%s ==> rwywo=%s", runway, rwywo))
|
||||||
return rwywo
|
return rwywo
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -143,6 +143,107 @@ MSRS = {
|
|||||||
-- @field #string version
|
-- @field #string version
|
||||||
MSRS.version="0.1.0"
|
MSRS.version="0.1.0"
|
||||||
|
|
||||||
|
--- Voices
|
||||||
|
-- @type Voices
|
||||||
|
MSRS.Voices = {
|
||||||
|
Microsoft = {
|
||||||
|
["Hedda"] = "Microsoft Hedda Desktop", -- de-DE
|
||||||
|
["Hazel"] = "Microsoft Hazel Desktop", -- en-GB
|
||||||
|
["David"] = "Microsoft David Desktop", -- en-US
|
||||||
|
["Zira"] = "Microsoft Zira Desktop", -- en-US
|
||||||
|
["Hortense"] = "Microsoft Hortense Desktop", --fr-FR
|
||||||
|
},
|
||||||
|
Google = {
|
||||||
|
Standard = {
|
||||||
|
["en-AU-Standard-A"] = 'en-AU-Standard-A', -- [1] FEMALE
|
||||||
|
["en-AU-Standard-B"] = 'en-AU-Standard-B', -- [2] MALE
|
||||||
|
["en-AU-Standard-C"] = 'en-AU-Standard-C', -- [3] FEMALE
|
||||||
|
["en-AU-Standard-D"] = 'en-AU-Standard-D', -- [4] MALE
|
||||||
|
["en-IN-Standard-A"] = 'en-IN-Standard-A', -- [5] FEMALE
|
||||||
|
["en-IN-Standard-B"] = 'en-IN-Standard-B', -- [6] MALE
|
||||||
|
["en-IN-Standard-C"] = 'en-IN-Standard-C', -- [7] MALE
|
||||||
|
["en-IN-Standard-D"] = 'en-IN-Standard-D', -- [8] FEMALE
|
||||||
|
["en-GB-Standard-A"] = 'en-GB-Standard-A', -- [9] FEMALE
|
||||||
|
["en-GB-Standard-B"] = 'en-GB-Standard-B', -- [10] MALE
|
||||||
|
["en-GB-Standard-C"] = 'en-GB-Standard-C', -- [11] FEMALE
|
||||||
|
["en-GB-Standard-D"] = 'en-GB-Standard-D', -- [12] MALE
|
||||||
|
["en-GB-Standard-F"] = 'en-GB-Standard-F', -- [13] FEMALE
|
||||||
|
["en-US-Standard-A"] = 'en-US-Standard-A', -- [14] MALE
|
||||||
|
["en-US-Standard-B"] = 'en-US-Standard-B', -- [15] MALE
|
||||||
|
["en-US-Standard-C"] = 'en-US-Standard-C', -- [16] FEMALE
|
||||||
|
["en-US-Standard-D"] = 'en-US-Standard-D', -- [17] MALE
|
||||||
|
["en-US-Standard-E"] = 'en-US-Standard-E', -- [18] FEMALE
|
||||||
|
["en-US-Standard-F"] = 'en-US-Standard-F', -- [19] FEMALE
|
||||||
|
["en-US-Standard-G"] = 'en-US-Standard-G', -- [20] FEMALE
|
||||||
|
["en-US-Standard-H"] = 'en-US-Standard-H', -- [21] FEMALE
|
||||||
|
["en-US-Standard-I"] = 'en-US-Standard-I', -- [22] MALE
|
||||||
|
["en-US-Standard-J"] = 'en-US-Standard-J', -- [23] MALE
|
||||||
|
["fr-FR-Standard-A"] = "fr-FR-Standard-A", -- Female
|
||||||
|
["fr-FR-Standard-B"] = "fr-FR-Standard-B", -- Male
|
||||||
|
["fr-FR-Standard-C"] = "fr-FR-Standard-C", -- Female
|
||||||
|
["fr-FR-Standard-D"] = "fr-FR-Standard-D", -- Male
|
||||||
|
["fr-FR-Standard-E"] = "fr-FR-Standard-E", -- Female
|
||||||
|
["de-DE-Standard-A"] = "de-DE-Standard-A", -- Female
|
||||||
|
["de-DE-Standard-B"] = "de-DE-Standard-B", -- Male
|
||||||
|
["de-DE-Standard-C"] = "de-DE-Standard-C", -- Female
|
||||||
|
["de-DE-Standard-D"] = "de-DE-Standard-D", -- Male
|
||||||
|
["de-DE-Standard-E"] = "de-DE-Standard-E", -- Male
|
||||||
|
["de-DE-Standard-F"] = "de-DE-Standard-F", -- Female
|
||||||
|
["es-ES-Standard-A"] = "es-ES-Standard-A", -- Female
|
||||||
|
["es-ES-Standard-B"] = "es-ES-Standard-B", -- Male
|
||||||
|
["es-ES-Standard-C"] = "es-ES-Standard-C", -- Female
|
||||||
|
["es-ES-Standard-D"] = "es-ES-Standard-D", -- Female
|
||||||
|
["it-IT-Standard-A"] = "it-IT-Standard-A", -- Female
|
||||||
|
["it-IT-Standard-B"] = "it-IT-Standard-B", -- Female
|
||||||
|
["it-IT-Standard-C"] = "it-IT-Standard-C", -- Male
|
||||||
|
["it-IT-Standard-D"] = "it-IT-Standard-D", -- Male
|
||||||
|
},
|
||||||
|
Wavenet = {
|
||||||
|
["en-AU-Wavenet-A"] = 'en-AU-Wavenet-A', -- [1] FEMALE
|
||||||
|
["en-AU-Wavenet-B"] = 'en-AU-Wavenet-B', -- [2] MALE
|
||||||
|
["en-AU-Wavenet-C"] = 'en-AU-Wavenet-C', -- [3] FEMALE
|
||||||
|
["en-AU-Wavenet-D"] = 'en-AU-Wavenet-D', -- [4] MALE
|
||||||
|
["en-IN-Wavenet-A"] = 'en-IN-Wavenet-A', -- [5] FEMALE
|
||||||
|
["en-IN-Wavenet-B"] = 'en-IN-Wavenet-B', -- [6] MALE
|
||||||
|
["en-IN-Wavenet-C"] = 'en-IN-Wavenet-C', -- [7] MALE
|
||||||
|
["en-IN-Wavenet-D"] = 'en-IN-Wavenet-D', -- [8] FEMALE
|
||||||
|
["en-GB-Wavenet-A"] = 'en-GB-Wavenet-A', -- [9] FEMALE
|
||||||
|
["en-GB-Wavenet-B"] = 'en-GB-Wavenet-B', -- [10] MALE
|
||||||
|
["en-GB-Wavenet-C"] = 'en-GB-Wavenet-C', -- [11] FEMALE
|
||||||
|
["en-GB-Wavenet-D"] = 'en-GB-Wavenet-D', -- [12] MALE
|
||||||
|
["en-GB-Wavenet-F"] = 'en-GB-Wavenet-F', -- [13] FEMALE
|
||||||
|
["en-US-Wavenet-A"] = 'en-US-Wavenet-A', -- [14] MALE
|
||||||
|
["en-US-Wavenet-B"] = 'en-US-Wavenet-B', -- [15] MALE
|
||||||
|
["en-US-Wavenet-C"] = 'en-US-Wavenet-C', -- [16] FEMALE
|
||||||
|
["en-US-Wavenet-D"] = 'en-US-Wavenet-D', -- [17] MALE
|
||||||
|
["en-US-Wavenet-E"] = 'en-US-Wavenet-E', -- [18] FEMALE
|
||||||
|
["en-US-Wavenet-F"] = 'en-US-Wavenet-F', -- [19] FEMALE
|
||||||
|
["en-US-Wavenet-G"] = 'en-US-Wavenet-G', -- [20] FEMALE
|
||||||
|
["en-US-Wavenet-H"] = 'en-US-Wavenet-H', -- [21] FEMALE
|
||||||
|
["en-US-Wavenet-I"] = 'en-US-Wavenet-I', -- [22] MALE
|
||||||
|
["en-US-Wavenet-J"] = 'en-US-Wavenet-J', -- [23] MALE
|
||||||
|
["fr-FR-Wavenet-A"] = "fr-FR-Wavenet-A", -- Female
|
||||||
|
["fr-FR-Wavenet-B"] = "fr-FR-Wavenet-B", -- Male
|
||||||
|
["fr-FR-Wavenet-C"] = "fr-FR-Wavenet-C", -- Female
|
||||||
|
["fr-FR-Wavenet-D"] = "fr-FR-Wavenet-D", -- Male
|
||||||
|
["fr-FR-Wavenet-E"] = "fr-FR-Wavenet-E", -- Female
|
||||||
|
["de-DE-Wavenet-A"] = "de-DE-Wavenet-A", -- Female
|
||||||
|
["de-DE-Wavenet-B"] = "de-DE-Wavenet-B", -- Male
|
||||||
|
["de-DE-Wavenet-C"] = "de-DE-Wavenet-C", -- Female
|
||||||
|
["de-DE-Wavenet-D"] = "de-DE-Wavenet-D", -- Male
|
||||||
|
["de-DE-Wavenet-E"] = "de-DE-Wavenet-E", -- Male
|
||||||
|
["de-DE-Wavenet-F"] = "de-DE-Wavenet-F", -- Female
|
||||||
|
["es-ES-Wavenet-B"] = "es-ES-Wavenet-B", -- Male
|
||||||
|
["es-ES-Wavenet-C"] = "es-ES-Wavenet-C", -- Female
|
||||||
|
["es-ES-Wavenet-D"] = "es-ES-Wavenet-D", -- Female
|
||||||
|
["it-IT-Wavenet-A"] = "it-IT-Wavenet-A", -- Female
|
||||||
|
["it-IT-Wavenet-B"] = "it-IT-Wavenet-B", -- Female
|
||||||
|
["it-IT-Wavenet-C"] = "it-IT-Wavenet-C", -- Male
|
||||||
|
["it-IT-Wavenet-D"] = "it-IT-Wavenet-D", -- Male
|
||||||
|
} ,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -1098,5 +1199,3 @@ end
|
|||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1455,14 +1455,14 @@ function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius,
|
|||||||
|
|
||||||
--_spot:MarkToAll(string.format("Parking spot %d free=%s", parkingspot.TerminalID, tostring(not occupied)))
|
--_spot:MarkToAll(string.format("Parking spot %d free=%s", parkingspot.TerminalID, tostring(not occupied)))
|
||||||
if occupied then
|
if occupied then
|
||||||
self:I(string.format("%s: Parking spot id %d occupied.", airport, _termid))
|
self:T(string.format("%s: Parking spot id %d occupied.", airport, _termid))
|
||||||
else
|
else
|
||||||
self:I(string.format("%s: Parking spot id %d free.", airport, _termid))
|
self:T(string.format("%s: Parking spot id %d free.", airport, _termid))
|
||||||
if nvalid<_nspots then
|
if nvalid<_nspots then
|
||||||
table.insert(validspots, {Coordinate=_spot, TerminalID=_termid})
|
table.insert(validspots, {Coordinate=_spot, TerminalID=_termid})
|
||||||
end
|
end
|
||||||
nvalid=nvalid+1
|
nvalid=nvalid+1
|
||||||
self:I(string.format("%s: Parking spot id %d free. Nfree=%d/%d.", airport, _termid, nvalid,_nspots))
|
self:T(string.format("%s: Parking spot id %d free. Nfree=%d/%d.", airport, _termid, nvalid,_nspots))
|
||||||
end
|
end
|
||||||
|
|
||||||
end -- loop over units
|
end -- loop over units
|
||||||
@ -1980,7 +1980,7 @@ function AIRBASE:SetActiveRunwayLanding(Name, PreferLeft)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if runway then
|
if runway then
|
||||||
self:I(string.format("%s: Setting active runway for landing as %s", self.AirbaseName, self:GetRunwayName(runway)))
|
self:T(string.format("%s: Setting active runway for landing as %s", self.AirbaseName, self:GetRunwayName(runway)))
|
||||||
else
|
else
|
||||||
self:E("ERROR: Could not set the runway for landing!")
|
self:E("ERROR: Could not set the runway for landing!")
|
||||||
end
|
end
|
||||||
@ -2028,7 +2028,7 @@ function AIRBASE:SetActiveRunwayTakeoff(Name, PreferLeft)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if runway then
|
if runway then
|
||||||
self:I(string.format("%s: Setting active runway for takeoff as %s", self.AirbaseName, self:GetRunwayName(runway)))
|
self:T(string.format("%s: Setting active runway for takeoff as %s", self.AirbaseName, self:GetRunwayName(runway)))
|
||||||
else
|
else
|
||||||
self:E("ERROR: Could not set the runway for takeoff!")
|
self:E("ERROR: Could not set the runway for takeoff!")
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user