mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
#AICSAR
* Fixed issue with underlying OpsTransport * Added FSM Transition OnAfterPilotUnloaded() * Added options for SRS TTS output - no sound files * Added voice options for downed pilot and operator - these can have different voices
This commit is contained in:
parent
c97f1791b0
commit
28c25816a6
@ -147,7 +147,7 @@
|
||||
--
|
||||
-- Switch on radio transmissions via **either** SRS **or** "normal" DCS radio e.g. like so:
|
||||
--
|
||||
-- my_aicsar:SetSRSRadio(true,"C:\\Program Files\\DCS-SimpleRadio-Standalone",270,radio.modulation.AM,5002)
|
||||
-- my_aicsar:SetSRSRadio(true,"C:\\Program Files\\DCS-SimpleRadio-Standalone",270,radio.modulation.AM,nil,5002)
|
||||
--
|
||||
-- or
|
||||
--
|
||||
@ -161,7 +161,7 @@
|
||||
-- @field #AICSAR
|
||||
AICSAR = {
|
||||
ClassName = "AICSAR",
|
||||
version = "0.0.8",
|
||||
version = "0.1.9",
|
||||
lid = "",
|
||||
coalition = coalition.side.BLUE,
|
||||
template = "",
|
||||
@ -173,7 +173,7 @@ AICSAR = {
|
||||
pilotqueue = {},
|
||||
pilotindex = 0,
|
||||
helos = {},
|
||||
verbose = true,
|
||||
verbose = false,
|
||||
rescuezoneradius = 200,
|
||||
rescued = {},
|
||||
autoonoff = true,
|
||||
@ -194,6 +194,13 @@ AICSAR = {
|
||||
helonumber = 3,
|
||||
gettext = nil,
|
||||
locale ="en", -- default text language
|
||||
SRSTTSRadio = false,
|
||||
SRSGoogle = false,
|
||||
SRSQ = nil,
|
||||
SRSPilot = nil,
|
||||
SRSPilotVoice = false,
|
||||
SRSOperator = nil,
|
||||
SRSOperatorVoice = false,
|
||||
}
|
||||
|
||||
-- TODO Messages
|
||||
@ -203,7 +210,7 @@ AICSAR.Messages = {
|
||||
EN = {
|
||||
INITIALOK = "Roger, Pilot, we hear you. Stay where you are, a helo is on the way!",
|
||||
INITIALNOTOK = "Sorry, Pilot. You're behind maximum operational distance! Good Luck!",
|
||||
PILOTDOWN = "Pilot down at ",
|
||||
PILOTDOWN = "Mayday, mayday, mayday! Pilot down at ",
|
||||
PILOTKIA = "Pilot KIA!",
|
||||
HELODOWN = "CSAR Helo Down!",
|
||||
PILOTRESCUED = "Pilot rescued!",
|
||||
@ -212,7 +219,7 @@ AICSAR.Messages = {
|
||||
DE = {
|
||||
INITIALOK = "Copy, Pilot, wir hören Sie. Bleiben Sie, wo Sie sind!\nEin Hubschrauber sammelt Sie auf!",
|
||||
INITIALNOTOK = "Verstehe, Pilot. Sie sind zu weit weg von uns.\nViel Glück!",
|
||||
PILOTDOWN = "Pilot abgestürzt: ",
|
||||
PILOTDOWN = "Mayday, mayday, mayday! Pilot abgestürzt: ",
|
||||
PILOTKIA = "Pilot gefallen!",
|
||||
HELODOWN = "CSAR Hubschrauber verloren!",
|
||||
PILOTRESCUED = "Pilot gerettet!",
|
||||
@ -309,6 +316,9 @@ function AICSAR:New(Alias,Coalition,Pilottemplate,Helotemplate,FARP,MASHZone)
|
||||
-- Radio
|
||||
self.SRS = nil
|
||||
self.SRSRadio = false
|
||||
self.SRSTTSRadio = false
|
||||
self.SRSGoogle = false
|
||||
self.SRSQ = nil
|
||||
self.SRSFrequency = 243
|
||||
self.SRSPath = "\\"
|
||||
self.SRSModulation = radio.modulation.AM
|
||||
@ -343,6 +353,7 @@ function AICSAR:New(Alias,Coalition,Pilottemplate,Helotemplate,FARP,MASHZone)
|
||||
self:AddTransition("*", "Status", "*") -- CSAR status update.
|
||||
self:AddTransition("*", "PilotDown", "*") -- Pilot down
|
||||
self:AddTransition("*", "PilotPickedUp", "*") -- Pilot in helo
|
||||
self:AddTransition("*", "PilotUnloaded", "*") -- Pilot Unloaded from helo
|
||||
self:AddTransition("*", "PilotRescued", "*") -- Pilot Rescued
|
||||
self:AddTransition("*", "PilotKIA", "*") -- Pilot dead
|
||||
self:AddTransition("*", "HeloDown", "*") -- Helo dead
|
||||
@ -404,6 +415,15 @@ function AICSAR:New(Alias,Coalition,Pilottemplate,Helotemplate,FARP,MASHZone)
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
|
||||
--- On after "PilotUnloaded" event.
|
||||
-- @function [parent=#AICSAR] OnAfterPilotUnloaded
|
||||
-- @param #AICSAR self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Ops.FlightGroup#FLIGHTGROUP Helo
|
||||
-- @param Ops.OpsGroup#OPSGROUP OpsGroup
|
||||
|
||||
--- On after "PilotKIA" event.
|
||||
-- @function [parent=#AICSAR] OnAfterPilotKIA
|
||||
-- @param #AICSAR self
|
||||
@ -453,7 +473,7 @@ function AICSAR:InitLocalization()
|
||||
return self
|
||||
end
|
||||
|
||||
--- [User] Switch sound output on and use SRS
|
||||
--- [User] Switch sound output on and use SRS output for sound files.
|
||||
-- @param #AICSAR self
|
||||
-- @param #boolean OnOff Switch on (true) or off (false).
|
||||
-- @param #string Path Path to your SRS Server Component, e.g. "E:\\\\Program Files\\\\DCS-SimpleRadio-Standalone"
|
||||
@ -464,10 +484,12 @@ end
|
||||
-- @return #AICSAR self
|
||||
function AICSAR:SetSRSRadio(OnOff,Path,Frequency,Modulation,SoundPath,Port)
|
||||
self:T(self.lid .. "SetSRSRadio")
|
||||
self:T(self.lid .. "SetSRSRadio to "..tostring(OnOff))
|
||||
self.SRSRadio = OnOff and true
|
||||
self.SRSTTSRadio = false
|
||||
self.SRSFrequency = Frequency or 243
|
||||
self.SRSPath = Path or "c:\\"
|
||||
self.SRS:SetLabel("ACSR")
|
||||
self.SRS:SetCoalition(self.coalition)
|
||||
self.SRSModulation = Modulation or radio.modulation.AM
|
||||
local soundpath = os.getenv('TMP') .. "\\DCS\\Mission\\l10n\\DEFAULT" -- defaults to "l10n/DEFAULT/", i.e. add messages by "Sound to..." in the ME
|
||||
self.SRSSoundPath = SoundPath or soundpath
|
||||
@ -479,6 +501,88 @@ function AICSAR:SetSRSRadio(OnOff,Path,Frequency,Modulation,SoundPath,Port)
|
||||
return self
|
||||
end
|
||||
|
||||
--- [User] Switch sound output on and use SRS-TTS output. The voice will be used across all outputs, unless you define an extra voice for downed pilots and/or the operator.
|
||||
-- See `AICSAR:SetPilotTTSVoice()` and `AICSAR:SetOperatorTTSVoice()`
|
||||
-- @param #AICSAR self
|
||||
-- @param #boolean OnOff Switch on (true) or off (false).
|
||||
-- @param #string Path Path to your SRS Server Component, e.g. "E:\\\\Program Files\\\\DCS-SimpleRadio-Standalone"
|
||||
-- @param #number Frequency (Optional) Defaults to 243 (guard)
|
||||
-- @param #number Modulation (Optional) Radio modulation. Defaults to radio.modulation.AM
|
||||
-- @param #number Port (Optional) Port of the SRS, defaults to 5002.
|
||||
-- @param #string Voice (Optional) The voice to be used.
|
||||
-- @param #string Culture (Optional) The culture to be used, defaults to "en-GB"
|
||||
-- @param #string Gender (Optional) The gender to be used, defaults to "male"
|
||||
-- @param #string GoogleCredentials (Optional) Path to google credentials
|
||||
-- @return #AICSAR self
|
||||
function AICSAR:SetSRSTTSRadio(OnOff,Path,Frequency,Modulation,Port,Voice,Culture,Gender,GoogleCredentials)
|
||||
self:T(self.lid .. "SetSRSTTSRadio")
|
||||
self.SRSTTSRadio = OnOff and true
|
||||
self.SRSRadio = false
|
||||
self.SRSFrequency = Frequency or 243
|
||||
self.SRSPath = Path or "C:\\Program Files\\DCS-SimpleRadio-Standalone"
|
||||
self.SRSModulation = Modulation or radio.modulation.AM
|
||||
self.SRSPort = Port or 5002
|
||||
if OnOff then
|
||||
self.SRS = MSRS:New(Path,Frequency,Modulation,1)
|
||||
self.SRS:SetPort(self.SRSPort)
|
||||
self.SRS:SetCoalition(self.coalition)
|
||||
self.SRS:SetLabel("ACSR")
|
||||
self.SRS:SetVoice(Voice)
|
||||
self.SRS:SetCulture(Culture)
|
||||
self.SRS:SetGender(Gender)
|
||||
if GoogleCredentials then
|
||||
self.SRS:SetGoogle(GoogleCredentials)
|
||||
self.SRSGoogle = true
|
||||
end
|
||||
self.SRSQ = MSRSQUEUE:New(self.alias)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- [User] Set SRS TTS Voice of downed pilot. `AICSAR:SetSRSTTSRadio()` needs to be set first!
|
||||
-- @param #AICSAR self
|
||||
-- @param #string Voice The voice to be used, e.g. `MSRS.Voices.Google.Standard.en_US_Standard_J` for Google or `MSRS.Voices.Microsoft.David` for Microsoft.
|
||||
-- Specific voices override culture and gender!
|
||||
-- @param #string Culture (Optional) The culture to be used, defaults to "en-US"
|
||||
-- @param #string Gender (Optional) The gender to be used, defaults to "male"
|
||||
-- @return #AICSAR self
|
||||
function AICSAR:SetPilotTTSVoice(Voice,Culture,Gender)
|
||||
self:T(self.lid .. "SetPilotTTSVoice")
|
||||
self.SRSPilotVoice = true
|
||||
self.SRSPilot = MSRS:New(self.SRSPath,self.SRSFrequency,self.SRSModulation,1)
|
||||
self.SRSPilot:SetCoalition(self.coalition)
|
||||
self.SRSPilot:SetVoice(Voice)
|
||||
self.SRSPilot:SetCulture(Culture or "en-US")
|
||||
self.SRSPilot:SetGender(Gender or "male")
|
||||
self.SRSPilot:SetLabel("PILOT")
|
||||
if self.SRS.google then
|
||||
self.SRSPilot:SetGoogle(self.SRS.google)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- [User] Set SRS TTS Voice of the rescue operator. `AICSAR:SetSRSTTSRadio()` needs to be set first!
|
||||
-- @param #AICSAR self
|
||||
-- @param #string Voice The voice to be used, e.g. `MSRS.Voices.Google.Standard.en_US_Standard_J` for Google or `MSRS.Voices.Microsoft.David` for Microsoft.
|
||||
-- Specific voices override culture and gender!
|
||||
-- @param #string Culture (Optional) The culture to be used, defaults to "en-GB"
|
||||
-- @param #string Gender (Optional) The gender to be used, defaults to "female"
|
||||
-- @return #AICSAR self
|
||||
function AICSAR:SetOperatorTTSVoice(Voice,Culture,Gender)
|
||||
self:T(self.lid .. "SetOperatorTTSVoice")
|
||||
self.SRSOperatorVoice = true
|
||||
self.SRSOperator = MSRS:New(self.SRSPath,self.SRSFrequency,self.SRSModulation,1)
|
||||
self.SRSOperator:SetCoalition(self.coalition)
|
||||
self.SRSOperator:SetVoice(Voice)
|
||||
self.SRSOperator:SetCulture(Culture or "en-GB")
|
||||
self.SRSOperator:SetGender(Gender or "female")
|
||||
self.SRSPilot:SetLabel("RESCUE")
|
||||
if self.SRS.google then
|
||||
self.SRSOperator:SetGoogle(self.SRS.google)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- [User] Switch sound output on and use normale (DCS) radio
|
||||
-- @param #AICSAR self
|
||||
-- @param #boolean OnOff Switch on (true) or off (false).
|
||||
@ -545,13 +649,25 @@ function AICSAR:OnEventLandingAfterEjection(EventData)
|
||||
-- Mayday Message
|
||||
local Text,Soundfile,Soundlength,Subtitle = self.gettext:GetEntry("PILOTDOWN",self.locale)
|
||||
local text = ""
|
||||
local setting = {}
|
||||
setting.MGRS_Accuracy = self.MGRS_Accuracy
|
||||
local location = _LandingPos:ToStringMGRS(setting)
|
||||
local msgtxt = Text..location.."!"
|
||||
location = string.gsub(location,"MGRS ","")
|
||||
location = string.gsub(location,"%s+","")
|
||||
location = string.gsub(location,"([%a%d])","%1;") -- "0 5 1 "
|
||||
location = string.gsub(location,"0","zero")
|
||||
location = string.gsub(location,"9","niner")
|
||||
location = "MGRS;"..location
|
||||
if self.SRSGoogle then
|
||||
location = string.format("<say-as interpret-as='characters'>%s</say-as>",location)
|
||||
end
|
||||
text = Text .. location .. "!"
|
||||
local ttstext = Text .. location .. "! Repeat! "..location
|
||||
if _coalition == self.coalition then
|
||||
if self.verbose then
|
||||
local setting = {}
|
||||
setting.MGRS_Accuracy = self.MGRS_Accuracy
|
||||
local location = _LandingPos:ToStringMGRS(setting)
|
||||
text = Text .. location .. "!"
|
||||
MESSAGE:New(text,15,"AICSAR"):ToCoalition(self.coalition)
|
||||
MESSAGE:New(msgtxt,15,"AICSAR"):ToCoalition(self.coalition)
|
||||
-- MESSAGE:New(msgtxt,15,"AICSAR"):ToLog()
|
||||
end
|
||||
if self.SRSRadio then
|
||||
local sound = SOUNDFILE:New(Soundfile,self.SRSSoundPath,Soundlength)
|
||||
@ -559,6 +675,12 @@ function AICSAR:OnEventLandingAfterEjection(EventData)
|
||||
self.SRS:PlaySoundFile(sound,2)
|
||||
elseif self.DCSRadio then
|
||||
self:DCSRadioBroadcast(Soundfile,Soundlength,text)
|
||||
elseif self.SRSTTSRadio then
|
||||
if self.SRSPilotVoice then
|
||||
self.SRSQ:NewTransmission(ttstext,nil,self.SRSPilot,nil,1)
|
||||
else
|
||||
self.SRSQ:NewTransmission(ttstext,nil,self.SRS,nil,1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -634,6 +756,10 @@ function AICSAR:_InitMission(Pilot,Index)
|
||||
self:__HeloDown(2,Helo,Index)
|
||||
end
|
||||
|
||||
local function AICHeloUnloaded(Helo,OpsGroup)
|
||||
self:__PilotUnloaded(2,Helo,OpsGroup)
|
||||
end
|
||||
|
||||
function helo:OnAfterLoadingDone(From,Event,To)
|
||||
AICPickedUp(helo,helo:GetCargoGroups(),Index)
|
||||
end
|
||||
@ -642,6 +768,10 @@ function AICSAR:_InitMission(Pilot,Index)
|
||||
AICHeloDead(helo,Index)
|
||||
end
|
||||
|
||||
function helo:OnAfterUnloaded(From,Event,To,OpsGroupCargo)
|
||||
AICHeloUnloaded(helo,OpsGroupCargo)
|
||||
end
|
||||
|
||||
self.helos[Index] = helo
|
||||
|
||||
return self
|
||||
@ -652,7 +782,7 @@ end
|
||||
-- @param Wrapper.Group#GROUP Pilot The pilot to be rescued.
|
||||
-- @return #boolean outcome
|
||||
function AICSAR:_CheckInMashZone(Pilot)
|
||||
self:T(self.lid .. "_CheckQueue")
|
||||
self:T(self.lid .. "_CheckInMashZone")
|
||||
if Pilot:IsInZone(self.farpzone) then
|
||||
return true
|
||||
else
|
||||
@ -696,8 +826,9 @@ end
|
||||
|
||||
--- [Internal] Check pilot queue for next mission
|
||||
-- @param #AICSAR self
|
||||
-- @param Ops.OpsGroup#OPSGROUP OpsGroup
|
||||
-- @return #AICSAR self
|
||||
function AICSAR:_CheckQueue()
|
||||
function AICSAR:_CheckQueue(OpsGroup)
|
||||
self:T(self.lid .. "_CheckQueue")
|
||||
for _index, _pilot in pairs(self.pilotqueue) do
|
||||
local classname = _pilot.ClassName and _pilot.ClassName or "NONE"
|
||||
@ -709,8 +840,12 @@ function AICSAR:_CheckQueue()
|
||||
local flightgroup = self.helos[_index] -- Ops.FlightGroup#FLIGHTGROUP
|
||||
-- rescued?
|
||||
if self:_CheckInMashZone(_pilot) then
|
||||
self:T("Pilot" .. _pilot.GroupName .. " rescued!")
|
||||
_pilot:Destroy(false)
|
||||
self:T("Pilot" .. _pilot.GroupName .. " rescued!")
|
||||
if OpsGroup then
|
||||
OpsGroup:Despawn(10)
|
||||
else
|
||||
_pilot:Destroy(true,10)
|
||||
end
|
||||
self.pilotqueue[_index] = nil
|
||||
self.rescued[_index] = true
|
||||
self:__PilotRescued(2)
|
||||
@ -767,7 +902,7 @@ end
|
||||
-- @return #AICSAR self
|
||||
function AICSAR:onafterStatus(From, Event, To)
|
||||
self:T({From, Event, To})
|
||||
self:_CheckQueue()
|
||||
--self:_CheckQueue()
|
||||
self:_CheckHelos()
|
||||
self:__Status(30)
|
||||
return self
|
||||
@ -814,6 +949,12 @@ function AICSAR:onafterPilotDown(From, Event, To, Coordinate, InReach)
|
||||
self.SRS:PlaySoundFile(sound,2)
|
||||
elseif self.DCSRadio then
|
||||
self:DCSRadioBroadcast(Soundfile,Soundlength,text)
|
||||
elseif self.SRSTTSRadio then
|
||||
if self.SRSOperatorVoice then
|
||||
self.SRSQ:NewTransmission(text,nil,self.SRSOperator,nil,1)
|
||||
else
|
||||
self.SRSQ:NewTransmission(text,nil,self.SRS,nil,1)
|
||||
end
|
||||
end
|
||||
else
|
||||
local text,Soundfile,Soundlength,Subtitle = self.gettext:GetEntry("INITIALNOTOK",self.locale)
|
||||
@ -828,8 +969,15 @@ function AICSAR:onafterPilotDown(From, Event, To, Coordinate, InReach)
|
||||
self.SRS:PlaySoundFile(sound,2)
|
||||
elseif self.DCSRadio then
|
||||
self:DCSRadioBroadcast(Soundfile,Soundlength,text)
|
||||
elseif self.SRSTTSRadio then
|
||||
if self.SRSOperatorVoice then
|
||||
self.SRSQ:NewTransmission(text,nil,self.SRSOperator,nil,1)
|
||||
else
|
||||
self.SRSQ:NewTransmission(text,nil,self.SRS,nil,1)
|
||||
end
|
||||
end
|
||||
end
|
||||
self:_CheckQueue()
|
||||
return self
|
||||
end
|
||||
|
||||
@ -851,7 +999,9 @@ function AICSAR:onafterPilotKIA(From, Event, To)
|
||||
self.SRS:PlaySoundFile(sound,2)
|
||||
elseif self.DCSRadio then
|
||||
self:DCSRadioBroadcast(Soundfile,Soundlength,text)
|
||||
end
|
||||
elseif self.SRSTTSRadio then
|
||||
self.SRSQ:NewTransmission(text,nil,self.SRS,nil,1)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
@ -875,6 +1025,8 @@ function AICSAR:onafterHeloDown(From, Event, To, Helo, Index)
|
||||
self.SRS:PlaySoundFile(sound,2)
|
||||
elseif self.DCSRadio then
|
||||
self:DCSRadioBroadcast(Soundfile,Soundlength,text)
|
||||
elseif self.SRSTTSRadio then
|
||||
self.SRSQ:NewTransmission(text,nil,self.SRS,nil,1)
|
||||
end
|
||||
local findex = 0
|
||||
local fhname = Helo:GetName()
|
||||
@ -927,10 +1079,26 @@ function AICSAR:onafterPilotRescued(From, Event, To)
|
||||
self.SRS:PlaySoundFile(sound,2)
|
||||
elseif self.DCSRadio then
|
||||
self:DCSRadioBroadcast(Soundfile,Soundlength,text)
|
||||
elseif self.SRSTTSRadio then
|
||||
self.SRSQ:NewTransmission(text,nil,self.SRS,nil,1)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- [Internal] onafterPilotUnloaded
|
||||
-- @param #AICSAR self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @param Ops.FlightGroup#FLIGHTGROUP Helo
|
||||
-- @param Ops.OpsGroup#OPSGROUP OpsGroup
|
||||
-- @return #AICSAR self
|
||||
function AICSAR:onafterPilotUnloaded(From, Event, To, Helo, OpsGroup)
|
||||
self:T({From, Event, To})
|
||||
self:_CheckQueue(OpsGroup)
|
||||
return self
|
||||
end
|
||||
|
||||
--- [Internal] onafterPilotPickedUp
|
||||
-- @param #AICSAR self
|
||||
-- @param #string From
|
||||
@ -952,6 +1120,8 @@ function AICSAR:onafterPilotPickedUp(From, Event, To, Helo, CargoTable, Index)
|
||||
self.SRS:PlaySoundFile(sound,2)
|
||||
elseif self.DCSRadio then
|
||||
self:DCSRadioBroadcast(Soundfile,Soundlength,text)
|
||||
elseif self.SRSTTSRadio then
|
||||
self.SRSQ:NewTransmission(text,nil,self.SRS,nil,1)
|
||||
end
|
||||
local findex = 0
|
||||
local fhname = Helo:GetName()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user