diff --git a/Moose Development/Moose/AI/AI_A2A_Cap.lua b/Moose Development/Moose/AI/AI_A2A_Cap.lua index 93db27a38..0c8aff8fa 100644 --- a/Moose Development/Moose/AI/AI_A2A_Cap.lua +++ b/Moose Development/Moose/AI/AI_A2A_Cap.lua @@ -82,7 +82,7 @@ -- that will define when the AI will engage with the detected airborne enemy targets. -- The range can be beyond or smaller than the range of the Patrol Zone. -- The range is applied at the position of the AI. --- Use the method @{AI_Air_Patrol#AI_AIR_PATROL.SetEngageRange}() to define that range. +-- Use the method @{#AI_A2A_CAP.SetEngageRange}() to define that range. -- -- ## 4. Set the Zone of Engagement -- diff --git a/Moose Development/Moose/AI/AI_A2G_SEAD.lua b/Moose Development/Moose/AI/AI_A2G_SEAD.lua index 14806c2e0..42662862c 100644 --- a/Moose Development/Moose/AI/AI_A2G_SEAD.lua +++ b/Moose Development/Moose/AI/AI_A2G_SEAD.lua @@ -44,7 +44,7 @@ -- that will define when the AI will engage with the detected airborne enemy targets. -- The range can be beyond or smaller than the range of the Patrol Zone. -- The range is applied at the position of the AI. --- Use the method @{AI_Air_Patrol#AI_AIR_PATROL.SetEngageRange}() to define that range. +-- Use the method @{#AI_AIR_PATROL.SetEngageRange}() to define that range. -- -- # Developer Note -- diff --git a/Moose Development/Moose/AI/AI_Air_Patrol.lua b/Moose Development/Moose/AI/AI_Air_Patrol.lua index 00fc7f2d0..3185f987e 100644 --- a/Moose Development/Moose/AI/AI_Air_Patrol.lua +++ b/Moose Development/Moose/AI/AI_Air_Patrol.lua @@ -79,7 +79,7 @@ -- that will define when the AI will engage with the detected airborne enemy targets. -- The range can be beyond or smaller than the range of the Patrol Zone. -- The range is applied at the position of the AI. --- Use the method @{AI.AI_CAP#AI_AIR_PATROL.SetEngageRange}() to define that range. +-- Use the method @{#AI_AIR_PATROL.SetEngageRange}() to define that range. -- -- # Developer Note -- diff --git a/Moose Development/Moose/Core/Event.lua b/Moose Development/Moose/Core/Event.lua index d057805f3..e767a36d1 100644 --- a/Moose Development/Moose/Core/Event.lua +++ b/Moose Development/Moose/Core/Event.lua @@ -1080,9 +1080,9 @@ function EVENT:onEvent( Event ) if Event.initiator then - Event.IniObjectCategory = Event.initiator:getCategory() + Event.IniObjectCategory = Object.getCategory(Event.initiator) --Event.initiator:getCategory() - if Event.IniObjectCategory == Object.Category.STATIC then + if Event.IniObjectCategory == Object.Category.STATIC then --- -- Static --- @@ -1118,10 +1118,9 @@ function EVENT:onEvent( Event ) local Unit=UNIT:FindByName(Event.IniDCSUnitName) if Unit then Event.IniObjectCategory = Object.Category.UNIT - end - end + end - if Event.IniObjectCategory == Object.Category.UNIT then + elseif Event.IniObjectCategory == Object.Category.UNIT then --- -- Unit --- @@ -1147,9 +1146,8 @@ function EVENT:onEvent( Event ) Event.IniCoalition = Event.IniDCSUnit:getCoalition() Event.IniTypeName = Event.IniDCSUnit:getTypeName() Event.IniCategory = Event.IniDCSUnit:getDesc().category - end - if Event.IniObjectCategory == Object.Category.CARGO then + elseif Event.IniObjectCategory == Object.Category.CARGO then --- -- Cargo --- @@ -1160,9 +1158,8 @@ function EVENT:onEvent( Event ) Event.IniCoalition = Event.IniDCSUnit:getCoalition() Event.IniCategory = Event.IniDCSUnit:getDesc().category Event.IniTypeName = Event.IniDCSUnit:getTypeName() - end - if Event.IniObjectCategory == Object.Category.SCENERY then + elseif Event.IniObjectCategory == Object.Category.SCENERY then --- -- Scenery --- @@ -1172,9 +1169,8 @@ function EVENT:onEvent( Event ) Event.IniUnit = SCENERY:Register( Event.IniDCSUnitName, Event.initiator ) Event.IniCategory = Event.IniDCSUnit:getDesc().category Event.IniTypeName = Event.initiator:isExist() and Event.IniDCSUnit:getTypeName() or "SCENERY" - end - if Event.IniObjectCategory == Object.Category.BASE then + elseif Event.IniObjectCategory == Object.Category.BASE then --- -- Base Object --- @@ -1201,9 +1197,12 @@ function EVENT:onEvent( Event ) --- -- Target category. - Event.TgtObjectCategory = Event.target:getCategory() + Event.TgtObjectCategory = Object.getCategory(Event.target) --Event.target:getCategory() if Event.TgtObjectCategory == Object.Category.UNIT then + --- + -- UNIT + --- Event.TgtDCSUnit = Event.target Event.TgtDCSGroup = Event.TgtDCSUnit:getGroup() Event.TgtDCSUnitName = Event.TgtDCSUnit:getName() @@ -1219,10 +1218,11 @@ function EVENT:onEvent( Event ) Event.TgtCoalition = Event.TgtDCSUnit:getCoalition() Event.TgtCategory = Event.TgtDCSUnit:getDesc().category Event.TgtTypeName = Event.TgtDCSUnit:getTypeName() - end - if Event.TgtObjectCategory == Object.Category.STATIC then - -- get base data + elseif Event.TgtObjectCategory == Object.Category.STATIC then + --- + -- STATIC + --- Event.TgtDCSUnit = Event.target if Event.target:isExist() and Event.id ~= 33 then -- leave out ejected seat object Event.TgtDCSUnitName = Event.TgtDCSUnit:getName() @@ -1249,9 +1249,11 @@ function EVENT:onEvent( Event ) Event.TgtTypeName = "Static" end end - end - if Event.TgtObjectCategory == Object.Category.SCENERY then + elseif Event.TgtObjectCategory == Object.Category.SCENERY then + --- + -- SCENERY + --- Event.TgtDCSUnit = Event.target Event.TgtDCSUnitName = Event.TgtDCSUnit:getName() Event.TgtUnitName = Event.TgtDCSUnitName diff --git a/Moose Development/Moose/Core/Message.lua b/Moose Development/Moose/Core/Message.lua index 843f55d0b..39fb11060 100644 --- a/Moose Development/Moose/Core/Message.lua +++ b/Moose Development/Moose/Core/Message.lua @@ -521,7 +521,11 @@ end function MESSAGE:ToSRS(frequency,modulation,gender,culture,voice,coalition,volume,coordinate) if _MESSAGESRS.SRSQ then _MESSAGESRS.MSRS:SetVoice(voice or _MESSAGESRS.Voice) - _MESSAGESRS.SRSQ:NewTransmission(self.MessageText,nil,_MESSAGESRS.MSRS,nil,nil,nil,nil,nil,frequency,modulation,gender or _MESSAGESRS.Gender,culture or _MESSAGESRS.Culture,voice or _MESSAGESRS.Voice,volume,self.MessageCategory) + if coordinate then + _MESSAGESRS.MSRS:SetCoordinate(coordinate) + end + local category = string.gsub(self.MessageCategory,":","") + _MESSAGESRS.SRSQ:NewTransmission(self.MessageText,nil,_MESSAGESRS.MSRS,nil,nil,nil,nil,nil,frequency,modulation,gender or _MESSAGESRS.Gender,culture or _MESSAGESRS.Culture,voice or _MESSAGESRS.Voice,volume,category,coordinate) end return self end diff --git a/Moose Development/Moose/Ops/Airboss.lua b/Moose Development/Moose/Ops/Airboss.lua index d7250de3e..efdbfbbb7 100644 --- a/Moose Development/Moose/Ops/Airboss.lua +++ b/Moose Development/Moose/Ops/Airboss.lua @@ -1730,10 +1730,10 @@ AIRBOSS.Difficulty = { -- @field #table trapsheet Groove data table recorded every 0.5 seconds. -- @field #boolean trapon If true, save trap sheets. -- @field #string debriefschedulerID Debrief scheduler ID. --- +-- -- @field Sound.SRS#MSRS SRS -- @field Sound.SRS#MSRSQUEUE SRSQ --- +-- -- @extends #AIRBOSS.FlightGroup --- Main group level radio menu: F10 Other/Airboss. @@ -1746,7 +1746,7 @@ AIRBOSS.MenuF10Root = nil --- Airboss class version. -- @field #string version -AIRBOSS.version = "1.3.2" +AIRBOSS.version = "1.3.3" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -3053,7 +3053,7 @@ end -- @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 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. @@ -3071,6 +3071,7 @@ function AIRBOSS:EnableSRS(PathToSRS,Port,Culture,Gender,Voice,GoogleCreds,Volum self.SRS:SetPath(PathToSRS) self.SRS:SetPort(Port or 5002) self.SRS:SetLabel(self.AirbossRadio.alias or "AIRBOSS") + self.SRS:SetCoordinate(self.carrier:GetCoordinate()) --self.SRS:SetModulations(Modulations) if GoogleCreds then self.SRS:SetGoogle(GoogleCreds) @@ -3082,10 +3083,10 @@ function AIRBOSS:EnableSRS(PathToSRS,Port,Culture,Gender,Voice,GoogleCreds,Volum -- SRSQUEUE self.SRSQ = MSRSQUEUE:New("AIRBOSS") self.SRSQ:SetTransmitOnlyWithPlayers(true) - if not self.PilotRadio then + if not self.PilotRadio then self:SetSRSPilotVoice() end - return self + return self end --- Set LSO radio frequency and modulation. Default frequency is 264 MHz AM. @@ -10266,7 +10267,7 @@ function AIRBOSS:_GetSternCoord() elseif case==2 or case==1 then -- V/Stol: Translate 8 meters port. self.sterncoord:Translate(self.carrierparam.sterndist, hdg, true, true):Translate(8, FB-90, true, true) - end + end elseif self.carriertype==AIRBOSS.CarrierType.STENNIS then -- Stennis: translate 7 meters starboard wrt Final bearing. self.sterncoord:Translate( self.carrierparam.sterndist, hdg, true, true ):Translate( 7, FB + 90, true, true ) @@ -11553,7 +11554,7 @@ function AIRBOSS:GetHeadingIntoWind_old( 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 @@ -11568,7 +11569,7 @@ function AIRBOSS:GetHeadingIntoWind_old( magnetic, coord ) -- +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 @@ -11580,7 +11581,7 @@ function AIRBOSS:GetHeadingIntoWind_old( magnetic, coord ) elseif windSpeed >= 13 then degreesAdjustment = 0 end - + return degreesAdjustment end @@ -14824,12 +14825,12 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p if radio == nil or call == nil then return end - + if not self.SRS then - + -- Create a new radio transmission item. local transmission = {} -- #AIRBOSS.Radioitem - + transmission.radio = radio transmission.call = call transmission.Tplay = timer.getAbsTime() + (delay or 0) @@ -14837,12 +14838,12 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p transmission.isplaying = false transmission.Tstarted = nil transmission.loud = loud and call.loud - + -- Player onboard number if sender has one. if self:_IsOnboard( call.modexsender ) then self:_Number2Radio( radio, call.modexsender, delay, 0.3, pilotcall ) end - + -- Play onboard number if receiver has one. if self:_IsOnboard( call.modexreceiver ) then self:_Number2Radio( radio, call.modexreceiver, delay, 0.3, pilotcall ) @@ -14885,16 +14886,12 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p -- SRS transmission if call.subtitle ~= nil and string.len(call.subtitle) > 1 then - - 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 @@ -14902,13 +14899,13 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p 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 @@ -14916,7 +14913,7 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p gender = self.LSORadio.gender culture = self.LSORadio.culture end - + if pilotcall then voice = self.PilotRadio.voice gender = self.PilotRadio.gender @@ -14930,18 +14927,18 @@ function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, p 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) + self:T(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) + self.SRSQ:NewTransmission(srstext, call.duration, self.SRS, nil, 0.1, nil, call.subtitle, call.subduration, frequency, modulation, gender, culture, voice, volume, radio.alias) end end end @@ -15254,7 +15251,7 @@ end -- @param #boolean clear If true, clear screen from previous messages. -- @param #number delay Delay in seconds, before the message is displayed. function AIRBOSS:MessageToPlayer( playerData, message, sender, receiver, duration, clear, delay ) - self:I({sender,receiver,message}) + self:T({sender,receiver,message}) if playerData and message and message ~= "" then -- Default duration. @@ -15277,44 +15274,44 @@ function AIRBOSS:MessageToPlayer( playerData, message, sender, receiver, duratio -- SCHEDULER:New(nil, self.MessageToPlayer, {self, playerData, message, sender, receiver, duration, clear}, delay) self:ScheduleOnce( delay, self.MessageToPlayer, self, playerData, message, sender, receiver, duration, clear ) else - + if not self.SRS then -- Wait until previous sound finished. local wait = 0 - + -- Onboard number to get the attention. if receiver == playerData.onboard then - + -- Which voice over number to use. if sender and (sender == "LSO" or sender == "MARSHAL" or sender == "AIRBOSS") then - + -- User sound of board number. wait = wait + self:_Number2Sound( playerData, sender, receiver ) - + end end - + -- Negative. if string.find( text:lower(), "negative" ) then local filename = self:_RadioFilename( self.MarshalCall.NEGATIVE, false, "MARSHAL" ) USERSOUND:New( filename ):ToGroup( playerData.group, wait ) wait = wait + self.MarshalCall.NEGATIVE.duration end - + -- Affirm. if string.find( text:lower(), "affirm" ) then local filename = self:_RadioFilename( self.MarshalCall.AFFIRMATIVE, false, "MARSHAL" ) USERSOUND:New( filename ):ToGroup( playerData.group, wait ) wait = wait + self.MarshalCall.AFFIRMATIVE.duration end - + -- Roger. if string.find( text:lower(), "roger" ) then local filename = self:_RadioFilename( self.MarshalCall.ROGER, false, "MARSHAL" ) USERSOUND:New( filename ):ToGroup( playerData.group, wait ) wait = wait + self.MarshalCall.ROGER.duration end - + -- Play click sound to end message. if wait > 0 then local filename = self:_RadioFilename( self.MarshalCall.CLICK ) @@ -15327,7 +15324,7 @@ function AIRBOSS:MessageToPlayer( playerData, message, sender, receiver, duratio 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 @@ -15357,10 +15354,10 @@ function AIRBOSS:MessageToPlayer( playerData, message, sender, receiver, duratio --sender = "AIRBOSS" end - self:I(self.lid..text) - self:I({sender,frequency,modulation,voice}) + self:T(self.lid..text) + self:T({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) + self.SRSQ:NewTransmission(srstext,duration,self.SRS,nil,0.1,nil,nil,nil,frequency,modulation,gender,culture,voice,nil,sender) end -- Text message to player client. if playerData.client then diff --git a/Moose Development/Moose/Ops/Awacs.lua b/Moose Development/Moose/Ops/Awacs.lua index 5bff6cc86..88569b7e1 100644 --- a/Moose Development/Moose/Ops/Awacs.lua +++ b/Moose Development/Moose/Ops/Awacs.lua @@ -507,7 +507,7 @@ do -- @field #AWACS AWACS = { ClassName = "AWACS", -- #string - version = "0.2.57", -- #string + version = "0.2.58", -- #string lid = "", -- #string coalition = coalition.side.BLUE, -- #number coalitiontxt = "blue", -- #string @@ -971,6 +971,7 @@ AWACS.TaskStatus = { -- DONE - (WIP) Reporting -- DONE - Do not report non-airborne groups -- DONE - Added option for helos +-- DONE - Added setting a coordinate for SRS ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Constructor @@ -6191,6 +6192,16 @@ function AWACS:onafterStatus(From, Event, To) -- Check on AUFTRAG status for CAP AI if self:Is("Running") and (awacsalive or self.AwacsInZone) then + + -- update coord for SRS + + if self.AwacsSRS then + self.AwacsSRS:SetCoordinate(self.AwacsFG:GetCoordinate()) + if self.TacticalSRS then + self.TacticalSRS:SetCoordinate(self.AwacsFG:GetCoordinate()) + end + end + self:_CheckAICAPOnStation() self:_CleanUpContacts() diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index 0c1950e41..becdf6ec3 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -31,6 +31,7 @@ -- @image OPS_CSAR.jpg -- Date: May 2023 +-- Last: Update Oct 2024 ------------------------------------------------------------------------- --- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM @@ -116,21 +117,21 @@ -- mycsar.ADFRadioPwr = 1000 -- ADF Beacons sending with 1KW as default -- mycsar.PilotWeight = 80 -- Loaded pilots weigh 80kgs each -- --- ## 2.1 Experimental Features +-- ## 2.1 SRS Features and Other Features -- --- WARNING - Here\'ll be dragons! --- DANGER - For this to work you need to de-sanitize your mission environment (all three entries) in \Scripts\MissionScripting.lua --- Needs SRS => 1.9.6 to work (works on the **server** side of SRS) -- mycsar.useSRS = false -- Set true to use FF\'s SRS integration -- mycsar.SRSPath = "C:\\Progra~1\\DCS-SimpleRadio-Standalone\\" -- adjust your own path in your SRS installation -- server(!) -- mycsar.SRSchannel = 300 -- radio channel -- mycsar.SRSModulation = radio.modulation.AM -- modulation -- mycsar.SRSport = 5002 -- and SRS Server port -- mycsar.SRSCulture = "en-GB" -- SRS voice culture --- mycsar.SRSVoice = nil -- SRS voice, relevant for Google TTS +-- mycsar.SRSVoice = nil -- SRS voice for downed pilot, relevant for Google TTS -- mycsar.SRSGPathToCredentials = nil -- Path to your Google credentials json file, set this if you want to use Google TTS -- mycsar.SRSVolume = 1 -- Volume, between 0 and 1 -- mycsar.SRSGender = "male" -- male or female voice +-- mycsar.CSARVoice = MSRS.Voices.Google.Standard.en_US_Standard_A -- SRS voice for CSAR Controller, relevant for Google TTS +-- mycsar.CSARVoiceMS = MSRS.Voices.Microsoft.Hedda -- SRS voice for CSAR Controller, relevant for MS Desktop TTS +-- mycsar.coordinate -- Coordinate from which CSAR TTS is sending. Defaults to a random MASH object position -- -- -- mycsar.csarUsePara = false -- If set to true, will use the LandingAfterEjection Event instead of Ejection. Requires mycsar.enableForAI to be set to true. --shagrat -- mycsar.wetfeettemplate = "man in floating thingy" -- if you use a mod to have a pilot in a rescue float, put the template name in here for wet feet spawns. Note: in conjunction with csarUsePara this might create dual ejected pilots in edge cases. @@ -230,7 +231,7 @@ CSAR = { takenOff = {}, csarUnits = {}, -- table of unit names downedPilots = {}, - woundedGroups = {}, + -- = {}, landedStatus = {}, addedTo = {}, woundedGroups = {}, -- contains the new group of units @@ -465,7 +466,10 @@ function CSAR:New(Coalition, Template, Alias) self.SRSGPathToCredentials = nil self.SRSVolume = 1.0 -- volume 0.0 to 1.0 self.SRSGender = "male" -- male or female - + self.CSARVoice = MSRS.Voices.Google.Standard.en_US_Standard_A + self.CSARVoiceMS = MSRS.Voices.Microsoft.Hedda + self.coordinate = nil -- Core.Point#COORDINATE + local AliaS = string.gsub(self.alias," ","_") self.filename = string.format("CSAR_%s_Persist.csv",AliaS) @@ -1306,7 +1310,7 @@ end -- @param #string UnitName -- @return #string CallSign function CSAR:_GetCustomCallSign(UnitName) - local callsign = Unitname + local callsign = UnitName local unit = UNIT:FindByName(UnitName) if unit and unit:IsAlive() then local group = unit:GetGroup() @@ -1737,7 +1741,16 @@ function CSAR:_DisplayMessageToSAR(_unit, _text, _time, _clear, _speak, _overrid end -- integrate SRS if _speak and self.useSRS then - self.SRSQueue:NewTransmission(_text,nil,self.msrs,nil,2) + local coord = _unit:GetCoordinate() + if coord then + self.msrs:SetCoordinate(coord) + end + _text = string.gsub(_text,"km"," kilometer") + _text = string.gsub(_text,"nm"," nautical miles") + --self.msrs:SetVoice(self.SRSVoice) + --self.SRSQueue:NewTransmission(_text,nil,self.msrs,nil,1) + self:I("Voice = "..self.SRSVoice) + self.SRSQueue:NewTransmission(_text,duration,self.msrs,tstart,2,subgroups,subtitle,subduration,self.SRSchannel,self.SRSModulation,gender,culture,self.SRSVoice,volume,label,coord) end return self end @@ -1876,7 +1889,7 @@ function CSAR:_SignalFlare(_unitName) if _closest ~= nil and _closest.pilot ~= nil and _closest.distance > 0 and _closest.distance < smokedist then local _clockDir = self:_GetClockDirection(_heli, _closest.pilot) - local _distance = 0 + local _distance = "" if _SETTINGS:IsImperial() then _distance = string.format("%.1fnm",UTILS.MetersToNM(_closest.distance)) else @@ -1889,12 +1902,13 @@ function CSAR:_SignalFlare(_unitName) _coord:FlareRed(_clockDir) else local _distance = smokedist + local dtext = "" if _SETTINGS:IsImperial() then - _distance = string.format("%.1fnm",UTILS.MetersToNM(smokedist)) + dtext = string.format("%.1fnm",UTILS.MetersToNM(smokedist)) else - _distance = string.format("%.1fkm",smokedist/1000) + dtext = string.format("%.1fkm",smokedist/1000) end - self:_DisplayMessageToSAR(_heli, string.format("No Pilots within %s",_distance), self.messageTime, false, false, true) + self:_DisplayMessageToSAR(_heli, string.format("No Pilots within %s",dtext), self.messageTime, false, false, true) end return self end @@ -1907,6 +1921,14 @@ end function CSAR:_DisplayToAllSAR(_message, _side, _messagetime) self:T(self.lid .. " _DisplayToAllSAR") local messagetime = _messagetime or self.messageTime + if self.msrs then + local voice = self.CSARVoice or MSRS.Voices.Google.Standard.en_GB_Standard_F + if self.msrs.google == nil then + voice = self.CSARVoiceMS or MSRS.Voices.Microsoft.Hedda + end + self:I("Voice = "..voice) + self.SRSQueue:NewTransmission(_message,duration,self.msrs,tstart,2,subgroups,subtitle,subduration,self.SRSchannel,self.SRSModulation,gender,culture,voice,volume,label,self.coordinate) + end for _, _unitName in pairs(self.csarUnits) do local _unit = self:_GetSARHeli(_unitName) if _unit and not self.suppressmessages then @@ -1930,7 +1952,7 @@ function CSAR:_Reqsmoke( _unitName ) local _closest = self:_GetClosestDownedPilot(_heli) if _closest ~= nil and _closest.pilot ~= nil and _closest.distance > 0 and _closest.distance < smokedist then local _clockDir = self:_GetClockDirection(_heli, _closest.pilot) - local _distance = 0 + local _distance = string.format("%.1fkm",_closest.distance/1000) if _SETTINGS:IsImperial() then _distance = string.format("%.1fnm",UTILS.MetersToNM(_closest.distance)) else @@ -1942,7 +1964,7 @@ function CSAR:_Reqsmoke( _unitName ) local color = self.smokecolor _coord:Smoke(color) else - local _distance = 0 + local _distance = string.format("%.1fkm",smokedist/1000) if _SETTINGS:IsImperial() then _distance = string.format("%.1fnm",UTILS.MetersToNM(smokedist)) else @@ -2267,6 +2289,12 @@ function CSAR:onafterStart(From, Event, To) self.allheligroupset = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterCategoryHelicopter():FilterStart() end self.mash = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterStart() -- currently only GROUP objects, maybe support STATICs also? + if not self.coordinate then + local csarhq = self.mash:GetRandom() + if csarhq then + self.coordinate = csarhq:GetCoordinate() + end + end if self.wetfeettemplate then self.usewetfeet = true end @@ -2274,7 +2302,7 @@ function CSAR:onafterStart(From, Event, To) local path = self.SRSPath local modulation = self.SRSModulation local channel = self.SRSchannel - self.msrs = MSRS:New(path,channel,modulation) + self.msrs = MSRS:New(path,channel,modulation) -- Sound.SRS#MSRS self.msrs:SetPort(self.SRSport) self.msrs:SetLabel("CSAR") self.msrs:SetCulture(self.SRSCulture) @@ -2286,7 +2314,7 @@ function CSAR:onafterStart(From, Event, To) end self.msrs:SetVolume(self.SRSVolume) self.msrs:SetLabel("CSAR") - self.SRSQueue = MSRSQUEUE:New("CSAR") + self.SRSQueue = MSRSQUEUE:New("CSAR") -- Sound.SRS#MSRSQUEUE end self:__Status(-10) diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index e76d15bcf..e01911f59 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -220,7 +220,7 @@ FLIGHTGROUP.Players={} --- FLIGHTGROUP class version. -- @field #string version -FLIGHTGROUP.version="1.0.1" +FLIGHTGROUP.version="1.0.2" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list @@ -272,7 +272,7 @@ function FLIGHTGROUP:New(group) self:SetFuelLowThreshold() self:SetFuelLowRTB() self:SetFuelCriticalThreshold() - self:SetFuelCriticalRTB() + self:SetFuelCriticalRTB() -- Holding flag. self.flaghold=USERFLAG:New(string.format("%s_FlagHold", self.groupname)) @@ -743,7 +743,7 @@ function FLIGHTGROUP:SetProhibitAfterburner() if self:GetGroup():IsAlive() then self:GetGroup():SetOption(AI.Option.Air.id.PROHIBIT_AB, true) end - return self + return self end --- Set if aircraft is allowed to use afterburner. @@ -754,7 +754,7 @@ function FLIGHTGROUP:SetAllowAfterburner() if self:GetGroup():IsAlive() then self:GetGroup():SetOption(AI.Option.Air.id.PROHIBIT_AB, false) end - return self + return self end --- Set if aircraft is allowed to drop empty fuel tanks - set to true to allow, and false to forbid it. @@ -974,7 +974,7 @@ function FLIGHTGROUP:AddFlightPlan(FlightPlan) self:T(self.lid..string.format("Adding flight plan %s", FlightPlan:GetName() )) table.insert(self.flightplans, FlightPlan) - + return self end @@ -988,7 +988,7 @@ function FLIGHTGROUP:IsParking(Element) if Element then is=Element.status==OPSGROUP.ElementStatus.PARKING end - return is + return is end --- Check if is taxiing to the runway. @@ -1012,7 +1012,7 @@ function FLIGHTGROUP:IsAirborne(Element) if Element then is=Element.status==OPSGROUP.ElementStatus.AIRBORNE end - return is + return is end --- Check if flight is airborne or cruising. @@ -1032,7 +1032,7 @@ function FLIGHTGROUP:IsLanding(Element) if Element then is=Element.status==OPSGROUP.ElementStatus.LANDING end - return is + return is end --- Check if flight has landed and is now taxiing to its parking spot. @@ -1044,7 +1044,7 @@ function FLIGHTGROUP:IsLanded(Element) if Element then is=Element.status==OPSGROUP.ElementStatus.LANDED end - return is + return is end --- Check if flight has arrived at its destination parking spot. @@ -1056,7 +1056,7 @@ function FLIGHTGROUP:IsArrived(Element) if Element then is=Element.status==OPSGROUP.ElementStatus.ARRIVED end - return is + return is end --- Check if flight is inbound and traveling to holding pattern. @@ -1193,20 +1193,20 @@ function FLIGHTGROUP:ClearToLand(Delay) else if self:IsHolding() then - + -- Set flag. self:T(self.lid..string.format("Clear to land ==> setting holding flag to 1 (true)")) self.flaghold:Set(1) - + -- Not holding any more. self.Tholding=nil - + -- Clear holding stack. if self.stack then self.stack.flightgroup=nil self.stack=nil end - + end end @@ -1255,50 +1255,50 @@ function FLIGHTGROUP:Status() -- FSM state. local fsmstate=self:GetState() - + -- Is group alive? local alive=self:IsAlive() - + if alive then -- Update position. self:_UpdatePosition() - + -- Check if group has detected any units. self:_CheckDetectedUnits() - + -- Check ammo status. self:_CheckAmmoStatus() - + -- Check damage. self:_CheckDamage() - + + -- Get current mission (if any). + local mission=self:GetMissionCurrent() + -- TODO: Check if group is waiting? if self:IsWaiting() then if self.Twaiting and self.dTwait then if timer.getAbsTime()>self.Twaiting+self.dTwait then --self.Twaiting=nil --self.dTwait=nil - --self:Cruise() + --self:_CheckGroupDone() end end end - - -- Get current mission (if any). - local mission=self:GetMissionCurrent() - + -- If mission, check if DCS task needs to be updated. if mission and mission.updateDCSTask then - + -- Orbit missions might need updates. if (mission:GetType()==AUFTRAG.Type.ORBIT or mission:GetType()==AUFTRAG.Type.RECOVERYTANKER or mission:GetType()==AUFTRAG.Type.CAP) and mission.orbitVec2 then - + -- Get 2D vector of orbit target. local vec2=mission:GetTargetVec2() - + -- Heading. local hdg=mission:GetTargetHeading() - + -- Heading change? local hdgchange=false if mission.orbitLeg then @@ -1306,71 +1306,71 @@ function FLIGHTGROUP:Status() hdgchange=true end end - + -- Distance to previous position. local dist=UTILS.VecDist2D(vec2, mission.orbitVec2) - + -- Distance change? local distchange=dist>mission.orbitDeltaR - + -- Debug info. self:T3(self.lid..string.format("Checking orbit mission dist=%d meters", dist)) - + -- Check if distance is larger than threshold. if distchange or hdgchange then - + -- Debug info. self:T3(self.lid..string.format("Updating orbit!")) - + -- Update DCS task. This also sets the new mission.orbitVec2. local DCSTask=mission:GetDCSMissionTask() --DCS#Task - + -- Get task. local Task=mission:GetGroupWaypointTask(self) - + -- Reset current orbit task. self.controller:resetTask() - + -- Push task after one second. We need to give resetTask some time or it will not work! self:_SandwitchDCSTask(DCSTask, Task, false, 1) - + end elseif mission.type==AUFTRAG.Type.CAPTUREZONE then - + -- Get task. local Task=mission:GetGroupWaypointTask(self) - + -- Update task: Engage or get new zone. if mission:GetGroupStatus(self)==AUFTRAG.GroupStatus.EXECUTING or mission:GetGroupStatus(self)==AUFTRAG.GroupStatus.STARTED then self:_UpdateTask(Task, mission) end - - end + + end end - - + + -- TODO: _CheckParking() function - + -- Check if flight began to taxi (if it was parking). if self:IsParking() then for _,_element in pairs(self.elements) do local element=_element --Ops.OpsGroup#OPSGROUP.Element - + -- Check for parking spot. if element.parking then - + -- Get distance to assigned parking spot. local dist=self:_GetDistToParking(element.parking, element.unit:GetCoord()) - + -- Debug info. self:T(self.lid..string.format("Distance to parking spot %d = %.1f meters", element.parking.TerminalID, dist)) - + -- If distance >10 meters, we consider the unit as taxiing. At least for fighters, the initial distance seems to be around 1.8 meters. if dist>12 and element.engineOn then self:ElementTaxiing(element) end - + else --self:T(self.lid..string.format("Element %s is in PARKING queue but has no parking spot assigned!", element.name)) end @@ -1379,9 +1379,9 @@ function FLIGHTGROUP:Status() else -- Check damage. - self:_CheckDamage() + self:_CheckDamage() end - + --- -- Group --- @@ -1396,7 +1396,7 @@ function FLIGHTGROUP:Status() -- Get number of tasks and missions. local nTaskTot, nTaskSched, nTaskWP=self:CountRemainingTasks() local nMissions=self:CountRemainingMissison() - + -- ROE and Alarm State. local roe=self:GetROE() or -1 local rot=self:GetROT() or -1 @@ -1408,41 +1408,41 @@ function FLIGHTGROUP:Status() local wpuidNext=self:GetWaypointUIDFromIndex(wpidxNext) or 0 local wpN=#self.waypoints or 0 local wpF=tostring(self.passedfinalwp) - + -- Speed. local speed=UTILS.MpsToKnots(self.velocity or 0) local speedEx=UTILS.MpsToKnots(self:GetExpectedSpeed()) - + -- Altitude. local alt=self.position and self.position.y or 0 - + -- Heading in degrees. - local hdg=self.heading or 0 - + local hdg=self.heading or 0 + -- TODO: GetFormation function. local formation=self.option.Formation or "unknown" - + -- Life points. local life=self.life or 0 - + -- Total ammo. local ammo=self:GetAmmoTot().Total - + -- Detected units. local ndetected=self.detectionOn and tostring(self.detectedunits:Count()) or "Off" - + -- Get cargo weight. local cargo=0 for _,_element in pairs(self.elements) do local element=_element --Ops.OpsGroup#OPSGROUP.Element cargo=cargo+element.weightCargo end - + -- Home and destination base. local home=self.homebase and self.homebase:GetName() or "unknown" local dest=self.destbase and self.destbase:GetName() or "unknown" local curr=self.currbase and self.currbase:GetName() or "N/A" - + -- Info text. local text=string.format("%s [%d/%d]: ROE/ROT=%d/%d | T/M=%d/%d | Wp=%d[%d]-->%d[%d]/%d [%s] | Life=%.1f | v=%.1f (%d) | Hdg=%03d | Ammo=%d | Detect=%s | Cargo=%.1f | Base=%s [%s-->%s]", fsmstate, nelem, Nelem, roe, rot, nTaskTot, nMissions, wpidxCurr, wpuidCurr, wpidxNext, wpuidNext, wpN, wpF, life, speed, speedEx, hdg, ammo, ndetected, cargo, curr, home, dest) @@ -1486,7 +1486,7 @@ function FLIGHTGROUP:Status() --- if self.verbose>=4 and alive then - + -- TODO: _Check distance travelled. -- Travelled distance since last check. @@ -1533,34 +1533,34 @@ function FLIGHTGROUP:Status() end - --- + --- -- Track flight --- if false then - + for _,_element in pairs(self.elements) do local element=_element --Ops.OpsGroup#OPSGROUP.Element - + local unit=element.unit - + if unit and unit:IsAlive() then - + local vec3=unit:GetVec3() - + if vec3 and element.pos then - + local id=UTILS.GetMarkID() - + trigger.action.lineToAll(-1, id, vec3, element.pos, {1,1,1,0.5}, 1) - + end - + element.pos=vec3 - + end - + end - + end --- @@ -1633,13 +1633,19 @@ function FLIGHTGROUP:Status() --- self:_PrintTaskAndMissionStatus() - - -- Current mission. + + -- All done? + -- Get current mission (if any). local mission=self:GetMissionCurrent() - - if not (self.cargoTransport or mission) then + if not mission then + self.Twaiting=nil + self.dTwait=nil + self:_CheckGroupDone() + end + + if not (self.cargoTransport or mission) then self:_CheckFlightPlans() - end + end end @@ -1667,13 +1673,13 @@ function FLIGHTGROUP:OnEventEngineStartup(EventData) -- TODO: what? else self:T3(self.lid..string.format("EVENT: Element %s started engines ==> taxiing (if AI)", element.name)) - + -- Element started engies. self:ElementEngineOn(element) - + -- Engines are on. element.engineOn=true - + --[[ -- TODO: could be that this element is part of a human flight group. -- Problem: when player starts hot, the AI does too and starts to taxi immidiately :( @@ -1766,7 +1772,7 @@ function FLIGHTGROUP:OnEventEngineShutdown(EventData) local element=self:GetElementByName(unitname) if element then - + -- Engines are off. element.engineOn=false @@ -1857,7 +1863,7 @@ function FLIGHTGROUP:onafterElementSpawned(From, Event, To, Element) -- Debug info. self:T(self.lid..string.format("Element spawned %s", Element.name)) - + if Element.playerName then self:_InitPlayerData(Element.playerName) end @@ -1884,7 +1890,7 @@ function FLIGHTGROUP:onafterElementSpawned(From, Event, To, Element) self:__ElementParking(0.11, Element) end end - + end --- On after "ElementParking" event. @@ -1916,7 +1922,7 @@ function FLIGHTGROUP:onafterElementParking(From, Event, To, Element, Spot) self:__ElementEngineOn(0.5, Element) Element.engineOn=true end - + end --- On after "ElementEngineOn" event. @@ -1932,7 +1938,7 @@ function FLIGHTGROUP:onafterElementEngineOn(From, Event, To, Element) -- Set element status. self:_UpdateStatus(Element, OPSGROUP.ElementStatus.ENGINEON) - + end --- On after "ElementTaxiing" event. @@ -1954,7 +1960,7 @@ function FLIGHTGROUP:onafterElementTaxiing(From, Event, To, Element) -- Set element status. self:_UpdateStatus(Element, OPSGROUP.ElementStatus.TAXIING) - + end --- On after "ElementTakeoff" event. @@ -1977,7 +1983,7 @@ function FLIGHTGROUP:onafterElementTakeoff(From, Event, To, Element, airbase) -- Trigger element airborne event. self:__ElementAirborne(0.01, Element) - + end --- On after "ElementAirborne" event. @@ -1993,7 +1999,7 @@ function FLIGHTGROUP:onafterElementAirborne(From, Event, To, Element) -- Set element status. self:_UpdateStatus(Element, OPSGROUP.ElementStatus.AIRBORNE) - + end --- On after "ElementLanded" event. @@ -2007,7 +2013,7 @@ function FLIGHTGROUP:onafterElementLanded(From, Event, To, Element, airbase) -- Debug info. self:T2(self.lid..string.format("Element landed %s at %s airbase", Element.name, airbase and airbase:GetName() or "unknown")) - + -- Set element status. self:_UpdateStatus(Element, OPSGROUP.ElementStatus.LANDED, airbase) @@ -2021,15 +2027,15 @@ function FLIGHTGROUP:onafterElementLanded(From, Event, To, Element, airbase) self:_UpdateStatus(Element, OPSGROUP.ElementStatus.ARRIVED) end - end + end -- Despawn after landing. if self.despawnAfterLanding then - + if self.legion then - + if airbase and self.legion.airbase and airbase.AirbaseName==self.legion.airbase.AirbaseName then - + if self:IsLanded() then -- Everybody landed ==> Return to legion. Will despawn the last one. self:ReturnToLegion() @@ -2037,16 +2043,16 @@ function FLIGHTGROUP:onafterElementLanded(From, Event, To, Element, airbase) -- Despawn the element. self:DespawnElement(Element) end - + end - + else -- Despawn the element. self:DespawnElement(Element) - + end - end + end end --- On after "ElementArrived" event. @@ -2092,9 +2098,9 @@ function FLIGHTGROUP:onafterElementDead(From, Event, To, Element) if self.flightcontrol and Element.parking then self.flightcontrol:SetParkingFree(Element.parking) end - + -- Call OPSGROUP function. This will remove the flightcontrol. Therefore, has to be after setting parking free. - self:GetParent(self).onafterElementDead(self, From, Event, To, Element) + self:GetParent(self).onafterElementDead(self, From, Event, To, Element) -- Not parking any more. Element.parking=nil @@ -2109,7 +2115,7 @@ end -- @param #string To To state. function FLIGHTGROUP:onafterSpawned(From, Event, To) self:T(self.lid..string.format("Flight spawned")) - + -- Debug info. if self.verbose>=1 then local text=string.format("Initialized Flight Group %s:\n", self.groupname) @@ -2122,7 +2128,7 @@ function FLIGHTGROUP:onafterSpawned(From, Event, To) text=text..string.format("Tanker type = %s\n", tostring(self.tankertype)) text=text..string.format("Refuel type = %s\n", tostring(self.refueltype)) text=text..string.format("AI = %s\n", tostring(self.isAI)) - text=text..string.format("Has EPLRS = %s\n", tostring(self.isEPLRS)) + text=text..string.format("Has EPLRS = %s\n", tostring(self.isEPLRS)) text=text..string.format("Helicopter = %s\n", tostring(self.isHelo)) text=text..string.format("Elements = %d\n", #self.elements) text=text..string.format("Waypoints = %d\n", #self.waypoints) @@ -2142,7 +2148,7 @@ function FLIGHTGROUP:onafterSpawned(From, Event, To) text=text..string.format("\n[%d] %s: callsign=%s, modex=%s, player=%s", i, element.name, tostring(element.callsign), tostring(element.modex), tostring(element.playerName)) end self:I(self.lid..text) - end + end -- Update position. self:_UpdatePosition() @@ -2161,12 +2167,12 @@ function FLIGHTGROUP:onafterSpawned(From, Event, To) -- Set default EPLRS. self:SwitchEPLRS(self.option.EPLRS) - + -- Set default Invisible. - self:SwitchInvisible(self.option.Invisible) + self:SwitchInvisible(self.option.Invisible) -- Set default Immortal. - self:SwitchImmortal(self.option.Immortal) + self:SwitchImmortal(self.option.Immortal) -- Set Formation self:SwitchFormation(self.option.Formation) @@ -2191,7 +2197,7 @@ function FLIGHTGROUP:onafterSpawned(From, Event, To) -- TODO: make this input. self:GetGroup():SetOption(AI.Option.Air.id.PROHIBIT_JETT, self.jettisonWeapons) self:GetGroup():SetOption(AI.Option.Air.id.PROHIBIT_AB, self.prohibitAB) -- Does not seem to work. AI still used the after burner. - self:GetGroup():SetOption(AI.Option.Air.id.RTB_ON_BINGO, false) + self:GetGroup():SetOption(AI.Option.Air.id.RTB_ON_BINGO, false) self:GetGroup():SetOption(AI.Option.Air.id.JETT_TANKS_IF_EMPTY, self.jettisonEmptyTanks) --self.group:SetOption(AI.Option.Air.id.RADAR_USING, AI.Option.Air.val.RADAR_USING.FOR_CONTINUOUS_SEARCH) @@ -2199,7 +2205,7 @@ function FLIGHTGROUP:onafterSpawned(From, Event, To) self:__UpdateRoute(-0.5) else - + -- Set flightcontrol. if self.currbase then local flightcontrol=_DATABASE:GetFlightControl(self.currbase:GetName()) @@ -2207,12 +2213,12 @@ function FLIGHTGROUP:onafterSpawned(From, Event, To) self:SetFlightControl(flightcontrol) else -- F10 other menu. - self:_UpdateMenu(0.5) + self:_UpdateMenu(0.5) end else self:_UpdateMenu(0.5) end - + end end @@ -2227,13 +2233,13 @@ function FLIGHTGROUP:onafterParking(From, Event, To) -- Get closest airbase local airbase=self:GetClosestAirbase() local airbasename=airbase:GetName() or "unknown" - + -- Debug info - self:T(self.lid..string.format("Flight is parking at airbase %s", airbasename)) - + self:T(self.lid..string.format("Flight is parking at airbase %s", airbasename)) + -- Set current airbase. self.currbase=airbase - + -- Set homebase to current airbase if not defined yet. -- This is necessary, e.g, when flights are spawned at an airbase because they do not have a takeoff waypoint. if not self.homebase then @@ -2257,7 +2263,7 @@ function FLIGHTGROUP:onafterParking(From, Event, To) self.flightcontrol:SetFlightStatus(self, FLIGHTCONTROL.FlightStatus.PARKING) end - + else self:T3(self.lid.."INFO: No flight control in onAfterParking!") end @@ -2321,7 +2327,7 @@ function FLIGHTGROUP:onafterAirborne(From, Event, To) -- No current airbase any more. self.currbase=nil - + -- Cruising. self:__Cruise(-0.01) @@ -2340,24 +2346,24 @@ function FLIGHTGROUP:onafterCruise(From, Event, To) self.dTwait=nil if self.isAI then - + --- -- AI --- - + -- Check group Done. self:_CheckGroupDone(nil, 120) - + else - + --- -- CLIENT --- - + --self:_UpdateMenu(0.1) - + end - + end --- On after "Landing" event. @@ -2375,15 +2381,15 @@ function FLIGHTGROUP:onafterLanding(From, Event, To) -- Add flight to landing queue. self.flightcontrol:SetFlightStatus(self, FLIGHTCONTROL.FlightStatus.LANDING) end - + -- Not holding any more. self.Tholding=nil - + -- Clear holding stack. if self.stack then self.stack.flightgroup=nil self.stack=nil - end + end end @@ -2434,25 +2440,25 @@ function FLIGHTGROUP:onafterArrived(From, Event, To) -- Add flight to arrived queue. self.flightcontrol:SetFlightStatus(self, FLIGHTCONTROL.FlightStatus.ARRIVED) end - + if not self.isAI then -- Player landed. No despawn. return end - + --TODO: Check that current base is airwing base. local airwing=self:GetAirwing() --airwing:GetAirbaseName()==self.currbase:GetName() -- Check what to do. if airwing and not (self:IsPickingup() or self:IsTransporting()) then - + -- Debug info. self:T(self.lid..string.format("Airwing asset group %s arrived ==> Adding asset back to stock of airwing %s", self.groupname, airwing.alias)) - + -- Add the asset back to the airwing. --airwing:AddAsset(self.group, 1) self:ReturnToLegion(1) - + elseif self.isLandingAtAirbase then local Template=UTILS.DeepCopy(self.template) --DCS#Template @@ -2577,14 +2583,14 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n, N) allowed=false elseif self:IsInUtero() then self:T(self.lid.."Update route denied. Group is INUTERO!") - allowed=false + allowed=false else -- Not airborne yet. Try again in 5 sec. self:T(self.lid.."Update route denied ==> checking back in 5 sec") trepeat=-5 allowed=false end - + -- Check if group is uncontrolled. If so, the mission task cannot be set yet! if allowed and self:IsUncontrolled() then self:T(self.lid.."Update route denied. Group is UNCONTROLLED!") @@ -2594,7 +2600,7 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n, N) else trepeat=-5 end - allowed=false + allowed=false end -- Requested waypoint index <1. Something is seriously wrong here! @@ -2640,7 +2646,7 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n, N) self:T2(self.lid.."Allowing update route for Task: Hover") elseif task.dcstask.id==AUFTRAG.SpecialTask.RELOCATECOHORT then -- For relocate - self:T2(self.lid.."Allowing update route for Task: Relocate Cohort") + self:T2(self.lid.."Allowing update route for Task: Relocate Cohort") elseif task.description and task.description=="Task_Land_At" then -- We allow this self:T2(self.lid.."Allowing update route for Task: Task_Land_At") @@ -2690,7 +2696,7 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n, N) n=n or self.currentwp+1 -- Max index. - N=N or #self.waypoints + N=N or #self.waypoints N=math.min(N, #self.waypoints) -- Waypoints. @@ -2717,7 +2723,7 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n, N) for i=n, N do table.insert(wp, self.waypoints[i]) end - + if wp[2] then self.speedWp=wp[2].speed end @@ -2796,7 +2802,7 @@ function FLIGHTGROUP:_CheckGroupDone(delay, waittime) if delay and delay>0 then -- Debug info. self:T(self.lid..string.format("Check FLIGHTGROUP [state=%s] done in %.3f seconds... (t=%.4f)", fsmstate, delay, timer.getTime())) - + -- Delayed call. self:ScheduleOnce(delay, FLIGHTGROUP._CheckGroupDone, self) else @@ -2809,7 +2815,7 @@ function FLIGHTGROUP:_CheckGroupDone(delay, waittime) self:T(self.lid.."Engaging! Group NOT done...") return end - + -- Number of tasks remaining. local nTasks=self:CountRemainingTasks() @@ -2817,7 +2823,7 @@ function FLIGHTGROUP:_CheckGroupDone(delay, waittime) local nMissions=self:CountRemainingMissison() -- Number of cargo transports remaining. - local nTransports=self:CountRemainingTransports() + local nTransports=self:CountRemainingTransports() -- Number of paused missions. local nPaused=self:_CountPausedMissions() @@ -2835,11 +2841,11 @@ function FLIGHTGROUP:_CheckGroupDone(delay, waittime) self:T(self.lid..string.format("Landing at airbase %s! Group NOT done...", self.isLandingAtAirbase:GetName())) return end - + -- Group is waiting. if self:IsWaiting() then self:T(self.lid.."Waiting! Group NOT done...") - return + return end -- Debug info. @@ -2849,7 +2855,7 @@ function FLIGHTGROUP:_CheckGroupDone(delay, waittime) -- Or next waypoint index is the first waypoint. Could be that the group was on a mission and the mission waypoints were deleted. then the final waypoint is FALSE but no real waypoint left. -- Since we do not do ad infinitum, this leads to a rapid oscillation between UpdateRoute and CheckGroupDone! if self:HasPassedFinalWaypoint() or self:GetWaypointIndexNext()==1 then - + --- -- Final Waypoint PASSED --- @@ -2894,14 +2900,14 @@ function FLIGHTGROUP:_CheckGroupDone(delay, waittime) --- -- Final Waypoint NOT PASSED - --- - + --- + -- Debug info. self:T(self.lid..string.format("Flight (status=%s) did NOT pass the final waypoint yet ==> update route in -0.01 sec", self:GetState())) - + -- Update route. self:__UpdateRoute(-0.01) - + end end @@ -2937,16 +2943,16 @@ function FLIGHTGROUP:onbeforeRTB(From, Event, To, airbase, SpeedTo, SpeedHold) self:T(self.lid..string.format("ERROR: Wrong airbase coalition %d in RTB() call! We allow only same as group %d or neutral airbases 0", airbase:GetCoalition(), self.group:GetCoalition())) return false end - + if self.currbase and self.currbase:GetName()==airbase:GetName() then self:T(self.lid.."WARNING: Currbase is already same as RTB airbase. RTB canceled!") return false end - + -- Check if the group has landed at an airbase. If so, we lost control and RTBing is not possible (only after a respawn). if self:IsLanded() then self:T(self.lid.."WARNING: Flight has already landed. RTB canceled!") - return false + return false end if not self.group:IsAirborne(true) then @@ -2989,7 +2995,7 @@ function FLIGHTGROUP:onbeforeRTB(From, Event, To, airbase, SpeedTo, SpeedHold) Tsuspend=-10 allowed=false end - + if self.Twaiting and self.dTwait then self:T(self.lid..string.format("WARNING: Group is Waiting for a specific duration ==> RTB event is canceled", Nwp)) allowed=false @@ -3026,7 +3032,7 @@ function FLIGHTGROUP:onafterRTB(From, Event, To, airbase, SpeedTo, SpeedHold, Sp -- Set the destination base. self.destbase=airbase - + -- Cancel all missions. self:CancelAllMissions() @@ -3059,19 +3065,19 @@ function FLIGHTGROUP:onbeforeLandAtAirbase(From, Event, To, airbase) self:T(self.lid..string.format("ERROR: Wrong airbase coalition %d in LandAtAirbase() call! We allow only same as group %d or neutral airbases 0", airbase:GetCoalition(), self.group:GetCoalition())) return false end - + if self.currbase and self.currbase:GetName()==airbase:GetName() then self:T(self.lid.."WARNING: Currbase is already same as LandAtAirbase airbase. LandAtAirbase canceled!") return false end - + -- Check if the group has landed at an airbase. If so, we lost control and RTBing is not possible (only after a respawn). if self:IsLanded() then self:T(self.lid.."WARNING: Flight has already landed. LandAtAirbase canceled!") - return false + return false end - - if self:IsParking() then + + if self:IsParking() then allowed=false Tsuspend=-30 self:T(self.lid.."WARNING: Flight is parking. LandAtAirbase call delayed by 30 sec") @@ -3080,7 +3086,7 @@ function FLIGHTGROUP:onbeforeLandAtAirbase(From, Event, To, airbase) Tsuspend=-1 self:T(self.lid.."WARNING: Flight is parking. LandAtAirbase call delayed by 1 sec") end - + if Tsuspend and not allowed then self:__LandAtAirbase(Tsuspend, airbase) end @@ -3118,10 +3124,10 @@ function FLIGHTGROUP:_LandAtAirbase(airbase, SpeedTo, SpeedHold, SpeedLand) -- Set current airbase. self.currbase=airbase - + -- Passed final waypoint! self:_PassedFinalWaypoint(true, "_LandAtAirbase") - + -- Not waiting any more. self.Twaiting=nil self.dTwait=nil @@ -3149,29 +3155,29 @@ function FLIGHTGROUP:_LandAtAirbase(airbase, SpeedTo, SpeedHold, SpeedLand) -- Do we have a flight control? local fc=_DATABASE:GetFlightControl(airbase:GetName()) - + if fc and self.isAI then - + -- Get holding stack from flight control. local stack=fc:_GetHoldingStack(self) - - if stack then - + + if stack then + stack.flightgroup=self self.stack=stack - + -- Race track points. p0=stack.pos0 p1=stack.pos1 - + -- Debug marks. if false then p0:MarkToAll(string.format("%s: Holding stack P0, alt=%d meters", self:GetName(), p0.y)) p1:MarkToAll(string.format("%s: Holding stack P1, alt=%d meters", self:GetName(), p0.y)) end - + else - + end -- Set flightcontrol for this flight. @@ -3179,24 +3185,24 @@ function FLIGHTGROUP:_LandAtAirbase(airbase, SpeedTo, SpeedHold, SpeedLand) -- Add flight to inbound queue. self.flightcontrol:SetFlightStatus(self, FLIGHTCONTROL.FlightStatus.INBOUND) - + -- Callsign. local callsign=self:GetCallsignName() - + -- Pilot calls inbound for landing. local text=string.format("%s, %s, inbound for landing", fc.alias, callsign) - + -- Radio message. fc:TransmissionPilot(text, self) - + -- Message text. local text=string.format("%s, %s, roger, hold at angels %d. Report entering the pattern.", callsign, fc.alias, stack.angels) - + -- Send message. fc:TransmissionTower(text, self, 10) - + end - + -- Some intermediate coordinate to climb to the default cruise alitude. local c1=c0:GetIntermediateCoordinate(p0, 0.25):SetAltitude(self.altitudeCruise, true) local c2=c0:GetIntermediateCoordinate(p0, 0.75):SetAltitude(self.altitudeCruise, true) @@ -3273,7 +3279,7 @@ function FLIGHTGROUP:_LandAtAirbase(airbase, SpeedTo, SpeedHold, SpeedLand) --self:ClearTasks() -- Just route the group. Respawn might happen when going from holding to final. - -- NOTE: I have delayed that here because of RTB calling _LandAtAirbase which resets current task immediately. + -- NOTE: I have delayed that here because of RTB calling _LandAtAirbase which resets current task immediately. -- So the stop flag change to 1 will not trigger TaskDone() and a current mission is not done either! -- Looks like a delay of 0.1 sec was not enough for the stopflag to take effect. Increasing this to 1.0 sec. -- This delay is looking better. Hopefully not any unwanted side effects in other situations. @@ -3302,12 +3308,12 @@ function FLIGHTGROUP:onbeforeWait(From, Event, To, Duration, Altitude, Speed) Tsuspend=-30 allowed=false end - + -- Check for a current transport assignment. if self.cargoTransport and not self:IsLandedAt() then --self:T(self.lid..string.format("WARNING: Got current TRANSPORT assignment ==> WAIT event is suspended for 30 sec!")) --Tsuspend=-30 - --allowed=false + --allowed=false end -- Call wait again. @@ -3331,14 +3337,14 @@ function FLIGHTGROUP:onafterWait(From, Event, To, Duration, Altitude, Speed) -- Group will orbit at its current position. local Coord=self:GetCoordinate() - + -- Set altitude: 1000 ft for helos and 10,000 ft for panes. if Altitude then Altitude=UTILS.FeetToMeters(Altitude) else Altitude=self.altitudeCruise - end - + end + -- Set speed. Speed=Speed or (self.isHelo and 20 or 250) @@ -3354,7 +3360,7 @@ function FLIGHTGROUP:onafterWait(From, Event, To, Duration, Altitude, Speed) local TaskStop = self.group:TaskCondition(nil, self.flaghold.UserFlagName, 1, nil, Duration) local TaskCntr = self.group:TaskControlled(TaskOrbit, TaskStop) local TaskOver = self.group:TaskFunction("FLIGHTGROUP._FinishedWaiting", self) - + local DCSTasks if Duration or true then DCSTasks=self.group:TaskCombo({TaskCntr, TaskOver}) @@ -3362,15 +3368,15 @@ function FLIGHTGROUP:onafterWait(From, Event, To, Duration, Altitude, Speed) DCSTasks=self.group:TaskCombo({TaskOrbit, TaskOver}) end - + -- Set task. self:PushTask(DCSTasks) - + -- Set time stamp. self.Twaiting=timer.getAbsTime() -- Max waiting - self.dTwait=Duration + self.dTwait=Duration end @@ -3437,7 +3443,7 @@ function FLIGHTGROUP:onafterHolding(From, Event, To) -- Set holding flag to 0 (just in case). self.flaghold:Set(0) - + -- Despawn after holding. if self.despawnAfterHolding then if self.legion then @@ -3460,28 +3466,28 @@ function FLIGHTGROUP:onafterHolding(From, Event, To) -- Set flight status to holding. self.flightcontrol:SetFlightStatus(self, FLIGHTCONTROL.FlightStatus.HOLDING) - + if self.isAI then - + -- Callsign. local callsign=self:GetCallsignName() -- Pilot arrived at holding pattern. local text=string.format("%s, %s, arrived at holding pattern", self.flightcontrol.alias, callsign) - + if self.stack then text=text..string.format(", angels %d.", self.stack.angels) end - + -- Radio message. self.flightcontrol:TransmissionPilot(text, self) -- Message to flight local text=string.format("%s, roger, fly heading %d and wait for landing clearance", callsign, self.stack.heading) - + -- Radio message from tower. self.flightcontrol:TransmissionTower(text, self, 10) - + end elseif self.airboss then @@ -3614,7 +3620,7 @@ function FLIGHTGROUP:onafterLandAt(From, Event, To, Coordinate, Duration) -- Duration. --Duration=Duration or 600 - + self:T(self.lid..string.format("Landing at Coordinate for %s seconds", tostring(Duration))) Coordinate=Coordinate or self:GetCoordinate() @@ -3624,7 +3630,7 @@ function FLIGHTGROUP:onafterLandAt(From, Event, To, Coordinate, Duration) local Task=self:NewTaskScheduled(DCStask, 1, "Task_Land_At", 0) self:TaskExecute(Task) - + end --- On after "FuelLow" event. @@ -3711,22 +3717,22 @@ function FLIGHTGROUP:_SetFlightPlan(FlightPlan) self:I(self.lid..string.format("Setting flightplan %s", FlightPlan.alias)) self.flightplan=FlightPlan - + self:SetDestinationbase(self.flightplan.destinationAirbase) for i,_fix in pairs(FlightPlan.fixes) do local fix=_fix --Navigation.Point#NAVFIX - + --fix.coordinate local speed=fix:GetSpeed() or FlightPlan:GetCruiseSpeed() - + local altitude=fix:GetAltitude() or FlightPlan:GetCruiseAltitude() - + local wp=self:AddWaypoint(fix.vector, speed, nil, altitude or 10000, false) wp.flightplan=FlightPlan - + wp.name=fix.name - + end end @@ -3743,13 +3749,13 @@ function FLIGHTGROUP:_CheckFlightPlans() for i,_flightplan in pairs(self.flightplans) do local flightplan=_flightplan --Navigation.FlightPlan#FLIGHTPLAN - + if flightplan then - + self:_SetFlightPlan(flightplan) - + break - end + end end end @@ -3797,7 +3803,7 @@ function FLIGHTGROUP._OnFinal(group, flightgroup) flightgroup:T2(flightgroup.lid..string.format("Group on final approach")) local fc=flightgroup.flightcontrol - + if fc and fc:IsControlling(flightgroup) then fc:_FlightOnFinal(flightgroup) end @@ -3819,7 +3825,7 @@ end -- @param #FLIGHTGROUP flightgroup Flight group object. function FLIGHTGROUP._FinishedWaiting(group, flightgroup) flightgroup:T(flightgroup.lid..string.format("Group finished waiting")) - + -- Not waiting any more. flightgroup.Twaiting=nil flightgroup.dTwait=nil @@ -3861,13 +3867,13 @@ function FLIGHTGROUP:_InitGroup(Template) -- Max speed in km/h. self.speedMax=group:GetSpeedMax() - + -- Is group mobile? if self.speedMax>3.6 then self.isMobile=true else self.isMobile=false - end + end -- Cruise speed limit 380 kts for fixed and 110 knots for rotary wings. local speedCruiseLimit=self.isHelo and UTILS.KnotsToKmph(110) or UTILS.KnotsToKmph(380) @@ -3923,15 +3929,15 @@ function FLIGHTGROUP:_InitGroup(Template) -- Units of the group. local units=self.group:GetUnits() - + -- DCS group. local dcsgroup=Group.getByName(self.groupname) local size0=dcsgroup:getInitialSize() - + -- Quick check. if #units~=size0 then self:T(self.lid..string.format("ERROR: Got #units=%d but group consists of %d units!", #units, size0)) - end + end -- Add elemets. for _,unit in pairs(units) do @@ -3940,7 +3946,7 @@ function FLIGHTGROUP:_InitGroup(Template) -- Init done. self.groupinitialized=true - + return self end @@ -4151,7 +4157,7 @@ end -- @return #boolean Air start? function FLIGHTGROUP:IsTakeoffAir() - local wp=self.waypoints0 and self.waypoints0[1] or nil --self:GetWaypoint(1) + local wp=self.waypoints0 and self.waypoints0[1] or nil --self:GetWaypoint(1) if wp then @@ -4265,17 +4271,17 @@ end function FLIGHTGROUP:AddWaypoint(Coordinate, Speed, AfterWaypointWithID, Altitude, Updateroute) -- Create coordinate. - local coordinate=self:_CoordinateFromObject(Coordinate) + local coordinate=self:_CoordinateFromObject(Coordinate) -- Set waypoint index. local wpnumber=self:GetWaypointIndexAfterID(AfterWaypointWithID) - + -- Speed in knots. Speed=Speed or self:GetSpeedCruise() - + -- Debug info. self:T3(self.lid..string.format("Waypoint Speed=%.1f knots", Speed)) - + -- Alt type default is barometric (ASL). For helos we use radar (AGL). local alttype=COORDINATE.WaypointAltType.BARO if self.isHelo then @@ -4376,7 +4382,7 @@ end function FLIGHTGROUP:GetPlayerName() local playerElement=self:GetPlayerElement() - + if playerElement then return playerElement.playerName end @@ -4397,10 +4403,10 @@ function FLIGHTGROUP:_SetElementParkingAt(Element, Spot) -- Debug info. self:T(self.lid..string.format("Element %s is parking on spot %d", Element.name, Spot.TerminalID)) - + -- Get flightcontrol. local fc=_DATABASE:GetFlightControl(Spot.AirbaseName) - + if fc and not self.flightcontrol then self:SetFlightControl(fc) end @@ -4559,10 +4565,10 @@ function FLIGHTGROUP:GetParkingSpot(element, maxdist, airbase) local distmin=math.huge for _,_parking in pairs(parking) do local parking=_parking --Wrapper.Airbase#AIRBASE.ParkingSpot - + -- Distance to spot. dist=coord:Get2DDistance(parking.Coordinate) - + if dist=2 then - local text=string.format("Updating MENU: State=%s, ATC=%s [%s]", self:GetState(), + local text=string.format("Updating MENU: State=%s, ATC=%s [%s]", self:GetState(), self.flightcontrol and self.flightcontrol.airbasename or "None", self.flightcontrol and self.flightcontrol:GetFlightStatus(self) or "Unknown") - + -- Message to group. MESSAGE:New(text, 5):ToGroup(self.group) self:I(self.lid..text) end - + -- Get current position of player. local position=self:GetCoordinate(nil, player.name) - + -- Get all FLIGHTCONTROLS local fc={} for airbasename,_flightcontrol in pairs(_DATABASE.FLIGHTCONTROLS) do local flightcontrol=_flightcontrol --Ops.FlightControl#FLIGHTCONTROL - + -- Get coord of airbase. local coord=flightcontrol:GetCoordinate() - + -- Distance to flight. local dist=coord:Get2DDistance(position) - + -- Add to table. table.insert(fc, {airbasename=airbasename, dist=dist}) end - + -- Sort table wrt distance to airbases. local function _sort(a,b) return a.dist0 then - self:ScheduleOnce(Delay, MSRS.PlayText, self, Text, 0) + self:ScheduleOnce(Delay, MSRS.PlayText, self, Text, nil, Coordinate) else -- Get command line. - local command=self:_GetCommand() + local command=self:_GetCommand(nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,Coordinate) -- Append text. command=command..string.format(" --text=\"%s\"", tostring(Text)) @@ -856,11 +857,12 @@ end -- @param #string Voice Voice. -- @param #number Volume Volume. -- @param #string Label Label. +-- @param Core.Point#COORDINATE Coordinate Coordinate. -- @return #MSRS self -function MSRS:PlayTextExt(Text, Delay, Frequencies, Modulations, Gender, Culture, Voice, Volume, Label) +function MSRS:PlayTextExt(Text, Delay, Frequencies, Modulations, Gender, Culture, Voice, Volume, Label, Coordinate) if Delay and Delay>0 then - self:ScheduleOnce(Delay, MSRS.PlayTextExt, self, Text, 0, Frequencies, Modulations, Gender, Culture, Voice, Volume, Label) + self:ScheduleOnce(Delay, MSRS.PlayTextExt, self, Text, 0, Frequencies, Modulations, Gender, Culture, Voice, Volume, Label, Coordinate) else -- Ensure table. @@ -874,7 +876,7 @@ function MSRS:PlayTextExt(Text, Delay, Frequencies, Modulations, Gender, Culture end -- Get command line. - local command=self:_GetCommand(Frequencies, Modulations, nil, Gender, Voice, Culture, Volume, nil, nil, Label) + local command=self:_GetCommand(Frequencies, Modulations, nil, Gender, Voice, Culture, Volume, nil, nil, Label, Coordinate) -- Append text. command=command..string.format(" --text=\"%s\"", tostring(Text)) @@ -1065,8 +1067,9 @@ end -- @param #number speed Speed. -- @param #number port Port. -- @param #string label Label, defaults to "ROBOT" (displayed sender name in the radio overlay of SRS) - No spaces allowed! +-- @param Core.Point#COORDINATE coordinate Coordinate. -- @return #string Command. -function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, speed, port,label) +function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, speed, port,label,coordinate) local path=self:GetPath() or STTS.DIRECTORY local exe=STTS.EXECUTABLE or "DCS-SR-ExternalAudio.exe" @@ -1080,6 +1083,7 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp speed=speed or self.speed port=port or self.port label=label or self.Label + coordinate=coordinate or self.coordinate -- Replace modulation modus=modus:gsub("0", "AM") @@ -1104,8 +1108,8 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp end -- Set coordinate. - if self.coordinate then - local lat,lon,alt=self:_GetLatLongAlt(self.coordinate) + if coordinate then + local lat,lon,alt=self:_GetLatLongAlt(coordinate) command=command..string.format(" -L %.4f -O %.4f -A %d", lat, lon, alt) end @@ -1649,6 +1653,7 @@ MSRSQUEUE = { -- @field #string voice Voice if any -- @field #number volume Volume -- @field #string label Label to be used +-- @field Core.Point#COORDINATE coordinate Coordinate for this transmission --- Create a new MSRSQUEUE object for a given radio frequency/modulation. -- @param #MSRSQUEUE self @@ -1733,8 +1738,9 @@ end -- @param #string voice Specific voice -- @param #number volume Volume setting -- @param #string label Label to be used +-- @param Core.Point#COORDINATE coordinate Coordinate to be used -- @return #MSRSQUEUE.Transmission Radio transmission table. -function MSRSQUEUE:NewTransmission(text, duration, msrs, tstart, interval, subgroups, subtitle, subduration, frequency, modulation, gender, culture, voice, volume, label) +function MSRSQUEUE:NewTransmission(text, duration, msrs, tstart, interval, subgroups, subtitle, subduration, frequency, modulation, gender, culture, voice, volume, label,coordinate) if self.TransmitOnlyWithPlayers then if self.PlayerSet and self.PlayerSet:CountAlive() == 0 then @@ -1774,7 +1780,8 @@ function MSRSQUEUE:NewTransmission(text, duration, msrs, tstart, interval, subgr transmission.voice = voice transmission.gender = volume transmission.label = label - + transmission.coordinate = coordinate + -- Add transmission to queue. self:AddTransmission(transmission) @@ -1787,9 +1794,9 @@ end function MSRSQUEUE:Broadcast(transmission) if transmission.frequency then - transmission.msrs:PlayTextExt(transmission.text, nil, transmission.frequency, transmission.modulation, transmission.gender, transmission.culture, transmission.voice, transmission.volume, transmission.label) + transmission.msrs:PlayTextExt(transmission.text, nil, transmission.frequency, transmission.modulation, transmission.gender, transmission.culture, transmission.voice, transmission.volume, transmission.label, transmission.coordinate) else - transmission.msrs:PlayText(transmission.text) + transmission.msrs:PlayText(transmission.text,nil,transmission.coordinate) end local function texttogroup(gid) diff --git a/docker/build-docs/start.sh b/docker/build-docs/start.sh index 4773540be..0ebbe62f4 100644 --- a/docker/build-docs/start.sh +++ b/docker/build-docs/start.sh @@ -4,6 +4,7 @@ cd /moose/ mkdir -p build/tools mkdir -p build/doc +rm -f build/doc/* # Checkout luadocumentor cd /moose/build/tools @@ -18,7 +19,6 @@ lua luadocumentor.lua -d /moose/build/doc '/moose/Moose Development/Moose' # Copy generated files in the MOOSE_DOCS repo if it is already there if [ -d /moose/build/MOOSE_DOCS/Documentation ]; then - rm -rf /moose/build/MOOSE_DOCS/Documentation - mkdir -p /moose/build/MOOSE_DOCS/Documentation + rm -f /moose/build/MOOSE_DOCS/Documentation/* cp /moose/build/doc/* /moose/build/MOOSE_DOCS/Documentation/ fi