diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index 8ab8ed17d..836c840ed 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -1368,7 +1368,7 @@ function DATABASE:_EventOnBirth( Event ) if PlayerName then -- Debug info. - self:I(string.format("Player '%s' joint unit '%s' of group '%s'", tostring(PlayerName), tostring(Event.IniDCSUnitName), tostring(Event.IniDCSGroupName))) + self:I(string.format("Player '%s' joined unit '%s' of group '%s'", tostring(PlayerName), tostring(Event.IniDCSUnitName), tostring(Event.IniDCSGroupName))) -- Add client in case it does not exist already. if not client then diff --git a/Moose Development/Moose/Core/Settings.lua b/Moose Development/Moose/Core/Settings.lua index 671b4cfb0..4a97a35eb 100644 --- a/Moose Development/Moose/Core/Settings.lua +++ b/Moose Development/Moose/Core/Settings.lua @@ -744,7 +744,7 @@ do -- SETTINGS self.PlayerMenu = PlayerMenu - self:I( string.format( "Setting menu for player %s", tostring( PlayerName ) ) ) + self:T( string.format( "Setting menu for player %s", tostring( PlayerName ) ) ) local submenu = MENU_GROUP:New( PlayerGroup, "LL Accuracy", PlayerMenu ) MENU_GROUP_COMMAND:New( PlayerGroup, "LL 0 Decimals", submenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 0 ) @@ -989,7 +989,7 @@ do -- SETTINGS do --- @param #SETTINGS self function SETTINGS:MenuGroupA2GSystem( PlayerUnit, PlayerGroup, PlayerName, A2GSystem ) - BASE:E( { self, PlayerUnit:GetName(), A2GSystem } ) + --BASE:E( {PlayerUnit:GetName(), A2GSystem } ) self.A2GSystem = A2GSystem MESSAGE:New( string.format( "Settings: A2G format set to %s for player %s.", A2GSystem, PlayerName ), 5 ):ToGroup( PlayerGroup ) if _SETTINGS.MenuStatic == false then diff --git a/Moose Development/Moose/Core/Spawn.lua b/Moose Development/Moose/Core/Spawn.lua index f74302e35..adcafc31f 100644 --- a/Moose Development/Moose/Core/Spawn.lua +++ b/Moose Development/Moose/Core/Spawn.lua @@ -328,6 +328,8 @@ function SPAWN:New( SpawnTemplatePrefix ) self.SpawnInitModu = nil -- No special modulation. self.SpawnInitRadio = nil -- No radio comms setting. self.SpawnInitModex = nil + self.SpawnInitModexPrefix = nil + self.SpawnInitModexPostfix = nil self.SpawnInitAirbase = nil self.TweakedTemplate = false -- Check if the user is using self made template. @@ -382,6 +384,8 @@ function SPAWN:NewWithAlias( SpawnTemplatePrefix, SpawnAliasPrefix ) self.SpawnInitModu = nil -- No special modulation. self.SpawnInitRadio = nil -- No radio communication setting. self.SpawnInitModex = nil + self.SpawnInitModexPrefix = nil + self.SpawnInitModexPostfix = nil self.SpawnInitAirbase = nil self.TweakedTemplate = false -- Check if the user is using self made template. @@ -541,6 +545,8 @@ function SPAWN:NewFromTemplate( SpawnTemplate, SpawnTemplatePrefix, SpawnAliasPr self.SpawnInitModu = nil -- No special modulation. self.SpawnInitRadio = nil -- No radio communication setting. self.SpawnInitModex = nil + self.SpawnInitModexPrefix = nil + self.SpawnInitModexPostfix = nil self.SpawnInitAirbase = nil self.TweakedTemplate = true -- Check if the user is using self made template. self.MooseNameing = true @@ -812,12 +818,17 @@ end --- Sets the modex of the first unit of the group. If more units are in the group, the number is increased by one with every unit. -- @param #SPAWN self -- @param #number modex Modex of the first unit. +-- @param #string prefix (optional) String to prefix to modex, e.g. for French AdA Modex, eg. -L-102 then "-L-" would be the prefix. +-- @param #string postfix (optional) String to postfix to modex, example tbd. -- @return #SPAWN self -function SPAWN:InitModex( modex ) +function SPAWN:InitModex( modex, prefix, postfix ) if modex then self.SpawnInitModex = tonumber( modex ) end + + self.SpawnInitModexPrefix = prefix + self.SpawnInitModexPostfix = postfix return self end @@ -1571,7 +1582,10 @@ function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth ) -- Set tail number. if self.SpawnInitModex then for UnitID = 1, #SpawnTemplate.units do - SpawnTemplate.units[UnitID].onboard_num = string.format( "%03d", self.SpawnInitModex + (UnitID - 1) ) + local modexnumber = string.format( "%03d", self.SpawnInitModex + (UnitID - 1) ) + if self.SpawnInitModexPrefix then modexnumber = self.SpawnInitModexPrefix..modexnumber end + if self.SpawnInitModexPostfix then modexnumber = modexnumber..self.SpawnInitModexPostfix end + SpawnTemplate.units[UnitID].onboard_num = modexnumber end end @@ -2178,14 +2192,18 @@ end -- @param #table Spots Table of parking spot IDs. Note that these in general are different from the numbering in the mission editor! -- @param #SPAWN.Takeoff Takeoff (Optional) Takeoff type, i.e. either SPAWN.Takeoff.Cold or SPAWN.Takeoff.Hot. Default is Hot. -- @return Wrapper.Group#GROUP The group that was spawned or nil when nothing was spawned. -function SPAWN:SpawnAtParkingSpot( Airbase, Spots, Takeoff ) -- R2.5 +function SPAWN:SpawnAtParkingSpot( Airbase, Spots, Takeoff ) self:F( { Airbase = Airbase, Spots = Spots, Takeoff = Takeoff } ) - + -- Ensure that Spots parameter is a table. if type( Spots ) ~= "table" then Spots = { Spots } end - + + if type(Airbase) == "string" then + Airbase = AIRBASE:FindByName(Airbase) + end + -- Get template group. local group = GROUP:FindByName( self.SpawnTemplatePrefix ) diff --git a/Moose Development/Moose/Functional/RAT.lua b/Moose Development/Moose/Functional/RAT.lua index 86f74409a..f5b262277 100644 --- a/Moose Development/Moose/Functional/RAT.lua +++ b/Moose Development/Moose/Functional/RAT.lua @@ -3483,7 +3483,7 @@ function RAT:Status(message, forID) -- Get group. local group=ratcraft.group --Wrapper.Group#GROUP - if group and group:IsAlive() then + if group and group:IsAlive() and (group:GetCoordinate() or group:GetVec3()) then nalive=nalive+1 -- Gather some information. diff --git a/Moose Development/Moose/Functional/Sead.lua b/Moose Development/Moose/Functional/Sead.lua index ebcd2228c..b80246523 100644 --- a/Moose Development/Moose/Functional/Sead.lua +++ b/Moose Development/Moose/Functional/Sead.lua @@ -1,4 +1,4 @@ ---- **Functional** - Make SAM sites execute evasive and defensive behaviour when being fired upon. +--- **Functional** - Make SAM sites evasive and execute defensive behaviour when being fired upon. -- -- === -- @@ -19,7 +19,7 @@ -- -- ### Authors: **FlightControl**, **applevangelist** -- --- Last Update: Feb 2022 +-- Last Update: September 2023 -- -- === -- @@ -66,7 +66,7 @@ SEAD = { -- @field Harms SEAD.Harms = { ["AGM_88"] = "AGM_88", - ["AGM_45"] = "AGM_45", + --["AGM_45"] = "AGM_45", ["AGM_122"] = "AGM_122", ["AGM_84"] = "AGM_84", ["AGM_45"] = "AGM_45", @@ -143,7 +143,7 @@ function SEAD:New( SEADGroupPrefixes, Padding ) self:AddTransition("*", "ManageEvasion", "*") self:AddTransition("*", "CalculateHitZone", "*") - self:I("*** SEAD - Started Version 0.4.3") + self:I("*** SEAD - Started Version 0.4.4") return self end @@ -203,7 +203,7 @@ function SEAD:SwitchEmissions(Switch) return self end ---- Add an object to call back when going evasive. +--- Set an object to call back when going evasive. -- @param #SEAD self -- @param #table Object The object to call. Needs to have object functions as follows: -- `:SeadSuppressionPlanned(Group, Name, SuppressionStartTime, SuppressionEndTime)` @@ -369,7 +369,7 @@ function SEAD:onafterManageEvasion(From,Event,To,_targetskill,_targetgroup,SEADP local reach = 10 if hit then local wpndata = SEAD.HarmData[data] - reach = wpndata[1] * 1,1 + reach = wpndata[1] * 1.1 local mach = wpndata[2] wpnspeed = math.floor(mach * 340.29) end @@ -405,7 +405,7 @@ function SEAD:onafterManageEvasion(From,Event,To,_targetskill,_targetgroup,SEADP local function SuppressionStop(args) self:T(string.format("*** SEAD - %s Radar On",args[2])) local grp = args[1] -- Wrapper.Group#GROUP - local name = args[2] -- #string Group Nam + local name = args[2] -- #string Group Name if self.UseEmissionsOnOff then grp:EnableEmission(true) end @@ -424,7 +424,7 @@ function SEAD:onafterManageEvasion(From,Event,To,_targetskill,_targetgroup,SEADP if _tti > 600 then delay = _tti - 90 end -- shot from afar, 600 is default shorad ontime local SuppressionStartTime = timer.getTime() + delay - local SuppressionEndTime = timer.getTime() + _tti + self.Padding + local SuppressionEndTime = timer.getTime() + delay + _tti + self.Padding + delay local _targetgroupname = _targetgroup:GetName() if not self.SuppressedGroups[_targetgroupname] then self:T(string.format("*** SEAD - %s | Parameters TTI %ds | Switch-Off in %ds",_targetgroupname,_tti,delay)) diff --git a/Moose Development/Moose/Ops/ATIS.lua b/Moose Development/Moose/Ops/ATIS.lua index b90973b05..1c6f4e6bc 100644 --- a/Moose Development/Moose/Ops/ATIS.lua +++ b/Moose Development/Moose/Ops/ATIS.lua @@ -9,7 +9,7 @@ -- * Visibility -- * Cloud coverage, base and ceiling -- * Temperature --- * Dew point (approximate as there is no relative humidity in DCS yet) +-- * Dew point (approximate as there is no relative humidity in DCS yet) -- * Pressure QNH/QFE -- * Weather phenomena: rain, thunderstorm, fog, dust -- * Active runway based on wind direction @@ -97,6 +97,8 @@ -- @field #boolean TransmitOnlyWithPlayers For SRS - If true, only transmit if there are alive Players. -- @field #string SRSText Text of the complete SRS message (if done at least once, else nil) -- @field #boolean ATISforFARPs Will be set to true if the base given is a FARP/Helipad +-- @field Core.TextAndSound#TEXTANDSOUND gettext Gettext for localization +-- @field #string locale Current locale -- @extends Core.Fsm#FSM --- *It is a very sad thing that nowadays there is so little useless information.* - Oscar Wilde @@ -130,6 +132,8 @@ -- -- ## Subtitles -- +-- **Note** Subtitles are not displayed when using SRS. The DCS mechanic to show subtitles (top left screen), is via the function call that plays a sound file from a UNIT, hence this doesn't work here. +-- -- Currently, DCS allows for displaying subtitles of radio transmissions only from airborne units, *i.e.* airplanes and helicopters. Therefore, if you want to have subtitles, it is necessary to place an -- additional aircraft on the ATIS airport and set it to uncontrolled. This unit can then function as a radio relay to transmit messages with subtitles. These subtitles will only be displayed, if the -- player has tuned in the correct ATIS frequency. @@ -309,14 +313,86 @@ -- -- atis=ATIS:New("Batumi", 305, radio.modulation.AM) -- atis:SetSRS("D:\\DCS\\_SRS\\", "male", "en-US") --- atis:Start() +-- atis:Start() -- --- This uses a male voice with US accent. It requires SRS to be installed in the `D:\DCS\_SRS\` directory. Not that backslashes need to be escaped or simply use slashes (as in linux). +-- This uses a male voice with US accent. It requires SRS to be installed in the `D:\DCS\_SRS\` directory. Note that backslashes need to be escaped or simply use slashes (as in linux). -- +-- ### SRS Localization +-- +-- You can localize the SRS output, all you need is to provide a table of translations and set the `locale` of your instance. You need to provide the translations in your script **before you instantiate your ATIS**. +-- The German localization (already provided in the code) e.g. looks like follows: +-- +-- ATIS.Messages.DE = +-- { +-- HOURS = "Uhr", +-- TIME = "Zeit", +-- NOCLOUDINFO = "Informationen über Wolken nicht verfuegbar", +-- OVERCAST = "Geschlossene Wolkendecke", +-- BROKEN = "Stark bewoelkt", +-- SCATTERED = "Bewoelkt", +-- FEWCLOUDS = "Leicht bewoelkt", +-- NOCLOUDS = "Klar", +-- AIRPORT = "Flughafen", +-- INFORMATION ="Information", +-- SUNRISEAT = "Sonnenaufgang um %s lokaler Zeit", +-- SUNSETAT = "Sonnenuntergang um %s lokaler Zeit", +-- WINDFROMMS = "Wind aus %s mit %s m/s", +-- WINDFROMKNOTS = "Wind aus %s mit %s Knoten", +-- GUSTING = "boeig", +-- VISIKM = "Sichtweite %s km", +-- VISISM = "Sichtweite %s Meilen", +-- RAIN = "Regen", +-- TSTORM = "Gewitter", +-- SNOW = "Schnee", +-- SSTROM = "Schneesturm", +-- FOG = "Nebel", +-- DUST = "Staub", +-- PHENOMENA = "Wetter Phaenomene", +-- CLOUDBASEM = "Wolkendecke von %s bis %s Meter", +-- CLOUDBASEFT = "Wolkendecke von %s bis %s Fuß", +-- TEMPERATURE = "Temperatur", +-- DEWPOINT = "Taupunkt", +-- ALTIMETER = "Hoehenmesser", +-- ACTIVERUN = "Aktive Startbahn", +-- LEFT = "Links", +-- RIGHT = "Rechts", +-- RWYLENGTH = "Startbahn", +-- METERS = "Meter", +-- FEET = "Fuß", +-- ELEVATION = "Hoehe", +-- TOWERFREQ = "Kontrollturm Frequenz", +-- ILSFREQ = "ILS Frequenz", +-- OUTERNDB = "Aeussere NDB Frequenz", +-- INNERNDB = "Innere NDB Frequenz", +-- VORFREQ = "VOR Frequenz", +-- VORFREQTTS = "V O R Frequenz", +-- TACANCH = "TACAN Kanal %d Xaver", +-- RSBNCH = "RSBN Kanal", +-- PRMGCH = "PRMG Kanal", +-- ADVISE = "Hinweis bei Erstkontakt, Sie haben Informationen", +-- STATUTE = "englische Meilen", +-- DEGREES = "Grad Celsius", +-- FAHRENHEIT = "Grad Fahrenheit", +-- INCHHG = "Inches H G", +-- MMHG = "Millimeter H G", +-- HECTO = "Hektopascal", +-- METERSPER = "Meter pro Sekunde", +-- TACAN = "Tackan", +-- FARP = "Farp", +-- DELIMITER = "Komma", -- decimal delimiter +-- } +-- +-- Then set up your ATIS and set the locale: +-- +-- atis=ATIS:New("Batumi", 305, radio.modulation.AM) +-- atis:SetSRS("D:\\DCS\\_SRS\\", "female", "de_DE") +-- atis:SetLocale("de") +-- atis:Start() +-- -- ## FARPS --- +-- -- ATIS is working with FARPS, but this requires the usage of SRS. The airbase name for the `New()-method` is the UNIT name of the FARP: --- +-- -- atis = ATIS:New("FARP Gold",119,radio.modulation.AM) -- atis:SetMetricUnits() -- atis:SetTransmitOnlyWithPlayers(true) @@ -367,7 +443,8 @@ ATIS = { relHumidity = nil, ReportmBar = false, TransmitOnlyWithPlayers = false, - ATISforFARPs = false, + ATISforFARPs = false, + locale = "en", } --- NATO alphabet. @@ -412,6 +489,7 @@ ATIS.Alphabet = { -- @field #number TheChannel -10° (West). -- @field #number Syria +5° (East). -- @field #number MarianaIslands +2° (East). +-- @field #number SinaiMao +5° (East). ATIS.RunwayM2T = { Caucasus = 0, Nevada = 12, @@ -421,7 +499,7 @@ ATIS.RunwayM2T = { Syria = 5, MarianaIslands = 2, Falklands = 12, - Sinai = 5, + SinaiMap = 5, } --- Whether ICAO phraseology is used for ATIS broadcasts. @@ -434,7 +512,7 @@ ATIS.RunwayM2T = { -- @field #boolean Syria true. -- @field #boolean MarianaIslands true. -- @field #boolean Falklands true. --- @field #boolean Sinai true. +-- @field #boolean SinaiMap true. ATIS.ICAOPhraseology = { Caucasus = true, Nevada = false, @@ -444,7 +522,7 @@ ATIS.ICAOPhraseology = { Syria = true, MarianaIslands = true, Falklands = true, - Sinai = true, + SinaiMap = true, } --- Nav point data. @@ -610,13 +688,140 @@ ATIS.Sound = { Zulu = { filename = "Zulu.ogg", duration = 0.62 }, } +--- +-- @field Messages +ATIS.Messages = { + EN = + { + HOURS = "hours", + TIME = "hours", + NOCLOUDINFO = "Cloud coverage information not available", + OVERCAST = "Overcast", + BROKEN = "Broken clouds", + SCATTERED = "Scattered clouds", + FEWCLOUDS = "Few clouds", + NOCLOUDS = "No clouds", + AIRPORT = "Airport", + INFORMATION ="Information", + SUNRISEAT = "Sunrise at %s local time", + SUNSETAT = "Sunset at %s local time", + WINDFROMMS = "Wind from %s at %s m/s", + WINDFROMKNOTS = "Wind from %s at %s knots", + GUSTING = "gusting", + VISIKM = "Visibility %s km", + VISISM = "Visibility %s SM", + RAIN = "rain", + TSTORM = "thunderstorm", + SNOW = "snow", + SSTROM = "snowstorm", + FOG = "fog", + DUST = "dust", + PHENOMENA = "Weather phenomena", + CLOUDBASEM = "Cloud base %s, ceiling %s meters", + CLOUDBASEFT = "Cloud base %s, ceiling %s feet", + TEMPERATURE = "Temperature", + DEWPOINT = "Dew point", + ALTIMETER = "Altimeter", + ACTIVERUN = "Active runway", + LEFT = "Left", + RIGHT = "Right", + RWYLENGTH = "Runway length", + METERS = "meters", + FEET = "feet", + ELEVATION = "Elevation", + TOWERFREQ = "Tower frequency", + ILSFREQ = "ILS frequency", + OUTERNDB = "Outer NDB frequency", + INNERNDB = "Inner NDB frequency", + VORFREQ = "VOR frequency", + VORFREQTTS = "V O R frequency", + TACANCH = "TACAN channel %dX Ray", + RSBNCH = "RSBN channel", + PRMGCH = "PRMG channel", + ADVISE = "Advise on initial contact, you have information", + STATUTE = "statute miles", + DEGREES = "degrees Celsius", + FAHRENHEIT = "degrees Fahrenheit", + INCHHG = "inches of Mercury", + MMHG = "millimeters of Mercury", + HECTO = "hectopascals", + METERSPER = "meters per second", + TACAN = "tackan", + FARP = "farp", + DELIMITER = "point", -- decimal delimiter + }, + DE = + { + HOURS = "Uhr", + TIME = "Zeit", + NOCLOUDINFO = "Informationen über Wolken nicht verfuegbar", + OVERCAST = "Geschlossene Wolkendecke", + BROKEN = "Stark bewoelkt", + SCATTERED = "Bewoelkt", + FEWCLOUDS = "Leicht bewoelkt", + NOCLOUDS = "Klar", + AIRPORT = "Flughafen", + INFORMATION ="Information", + SUNRISEAT = "Sonnenaufgang um %s lokaler Zeit", + SUNSETAT = "Sonnenuntergang um %s lokaler Zeit", + WINDFROMMS = "Wind aus %s mit %s m/s", + WINDFROMKNOTS = "Wind aus %s mit %s Knoten", + GUSTING = "boeig", + VISIKM = "Sichtweite %s km", + VISISM = "Sichtweite %s Meilen", + RAIN = "Regen", + TSTORM = "Gewitter", + SNOW = "Schnee", + SSTROM = "Schneesturm", + FOG = "Nebel", + DUST = "Staub", + PHENOMENA = "Wetter Phaenomene", + CLOUDBASEM = "Wolkendecke von %s bis %s Meter", + CLOUDBASEFT = "Wolkendecke von %s bis %s Fuß", + TEMPERATURE = "Temperatur", + DEWPOINT = "Taupunkt", + ALTIMETER = "Hoehenmesser", + ACTIVERUN = "Aktive Startbahn", + LEFT = "Links", + RIGHT = "Rechts", + RWYLENGTH = "Startbahn", + METERS = "Meter", + FEET = "Fuß", + ELEVATION = "Hoehe", + TOWERFREQ = "Kontrollturm Frequenz", + ILSFREQ = "ILS Frequenz", + OUTERNDB = "Aeussere NDB Frequenz", + INNERNDB = "Innere NDB Frequenz", + VORFREQ = "VOR Frequenz", + VORFREQTTS = "V O R Frequenz", + TACANCH = "TACAN Kanal %d Xaver", + RSBNCH = "RSBN Kanal", + PRMGCH = "PRMG Kanal", + ADVISE = "Hinweis bei Erstkontakt, Sie haben Informationen", + STATUTE = "englische Meilen", + DEGREES = "Grad Celsius", + FAHRENHEIT = "Grad Fahrenheit", + INCHHG = "Inches H G", + MMHG = "Millimeter H G", + HECTO = "Hektopascal", + METERSPER = "Meter pro Sekunde", + TACAN = "Tackan", + FARP = "Farp", + DELIMITER = "Komma", -- decimal delimiter + } +} + +--- +-- @field locale +ATIS.locale = "en" + --- ATIS table containing all defined ATISes. -- @field #table _ATIS _ATIS = {} --- ATIS class version. -- @field #string version -ATIS.version = "0.9.16" +ATIS.version = "0.10.1" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list @@ -637,7 +842,7 @@ ATIS.version = "0.9.16" -- DONE: Set UTC correction. -- DONE: Set magnetic variation. -- DONE: New DCS 2.7 weather presets. --- DONE: whatever +-- DONE: Added TextAndSound localization ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Constructor @@ -686,6 +891,7 @@ function ATIS:New(AirbaseName, Frequency, Modulation) self:SetRelativeHumidity() self:SetQueueUpdateTime() self:SetReportmBar(false) + self:_InitLocalization() -- Start State. self:SetStartState( "Stopped" ) @@ -774,6 +980,33 @@ end -- User Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +--- [Internal] Init localization +-- @param #ATIS self +-- @return #ATIS self +function ATIS:_InitLocalization() + self:T(self.lid.."_InitLocalization") + self.gettext = TEXTANDSOUND:New("AWACS","en") -- Core.TextAndSound#TEXTANDSOUND + self.locale = "en" + for locale,table in pairs(self.Messages) do + local Locale = string.lower(tostring(locale)) + self:T("**** Adding locale: "..Locale) + for ID,Text in pairs(table) do + self:T(string.format('Adding ID %s',tostring(ID))) + self.gettext:AddEntry(Locale,tostring(ID),Text) + end + end + return self +end + +--- Set locale for localized text-to-sound output via SRS, defaults to "en". +-- @param #ATIS self +-- @param #string locale Locale for localized text-to-sound output via SRS, defaults to "en". +-- @return #ATIS self +function ATIS:SetLocale(locale) + self.locale = string.lower(locale) + return self +end + --- Set sound files folder within miz file. -- @param #ATIS self -- @param #string path Path for sound files. Default "ATIS Soundfiles/". Mind the slash "/" at the end! @@ -801,7 +1034,7 @@ end -- @return #ATIS self function ATIS:SetTowerFrequencies( freqs ) if type( freqs ) == "table" then - -- nothing to do + -- nothing to do else freqs = { freqs } end @@ -829,9 +1062,9 @@ end function ATIS:SetActiveRunway( runway ) self.activerunway = tostring( runway ) local prefer = nil - if string.find(string.lower(runway),"l") then + if string.find(string.lower(runway),"l") then prefer = true - elseif string.find(string.lower(runway),"r") then + elseif string.find(string.lower(runway),"r") then prefer = false end self.airbase:SetActiveRunway(runway,prefer) @@ -920,7 +1153,7 @@ function ATIS:SetRunwayHeadingsMagnetic( headings ) -- First make sure, we have a table. if type( headings ) == "table" then - -- nothing to do + -- nothing to do else headings = { headings } end @@ -1004,9 +1237,9 @@ function ATIS:SetTemperatureFahrenheit() end --- Set relative humidity. This is used to approximately calculate the dew point. --- Note that the dew point is only an artificial information as DCS does not have an atmospheric model that includes humidity (yet). +-- Note that the dew point is only an artificial information as DCS does not have an atmospheric model that includes humidity (yet). -- @param #ATIS self --- @param #number Humidity Relative Humidity, i.e. a number between 0 and 100 %. Default is 50 %. +-- @param #number Humidity Relative Humidity, i.e. a number between 0 and 100 %. Default is 50 %. -- @return #ATIS self function ATIS:SetRelativeHumidity( Humidity ) self.relHumidity = Humidity or 50 @@ -1077,7 +1310,7 @@ end -- * 182° on the Persian Gulf map -- -- Likewise, to convert *true* into *magnetic* heading, one has to substract easterly and add westerly variation. --- +-- -- Or you make your life simple and just include the sign so you don't have to bother about East/West. -- -- @param #ATIS self @@ -1281,20 +1514,20 @@ end function ATIS:onafterStart( From, Event, To ) self:T({From, Event, To}) self:T("Airbase category is "..self.airbase:GetAirbaseCategory()) - + -- Check that this is an airdrome. if self.airbase:GetAirbaseCategory() == Airbase.Category.SHIP then self:E( self.lid .. string.format( "ERROR: Cannot start ATIS for airbase %s! Only AIRDROMES are supported but NOT SHIPS.", self.airbasename ) ) return end - + -- Check that if is a Helipad. if self.airbase:GetAirbaseCategory() == Airbase.Category.HELIPAD then self:E( self.lid .. string.format( "EXPERIMENTAL: Starting ATIS for Helipad %s! SRS must be ON", self.airbasename ) ) self.ATISforFARPs = true self.useSRS = true end - + -- Info. self:I( self.lid .. string.format( "Starting ATIS v%s for airbase %s on %.3f MHz Modulation=%d", ATIS.version, self.airbasename, self.frequency, self.modulation ) ) @@ -1362,7 +1595,7 @@ function ATIS:onafterStatus( From, Event, To ) text = text .. string.format( ", Relay unit=%s (alive=%s)", tostring( self.relayunitname ), relayunitstatus ) end self:T( self.lid .. text ) - + if not self:Is("Stopped") then self:__Status( 60 ) end @@ -1394,9 +1627,9 @@ function ATIS:onafterCheckQueue( From, Event, To ) end end - - -- Check back in 5 seconds. + + -- Check back in 5 seconds. self:__CheckQueue( math.abs( self.dTQueueCheck ) ) end end @@ -1507,11 +1740,11 @@ function ATIS:onafterBroadcast( From, Event, To ) -------------- --- Runway --- -------------- - - + + local runwayLanding, rwyLandingLeft local runwayTakeoff, rwyTakeoffLeft - + if self.airbase:GetAirbaseCategory() == Airbase.Category.HELIPAD then runwayLanding, rwyLandingLeft="PAD 01",false runwayTakeoff, rwyTakeoffLeft="PAD 02",false @@ -1519,7 +1752,7 @@ function ATIS:onafterBroadcast( From, Event, To ) runwayLanding, rwyLandingLeft=self:GetActiveRunway() runwayTakeoff, rwyTakeoffLeft=self:GetActiveRunway(true) end - + ------------ --- Time --- ------------ @@ -1540,8 +1773,9 @@ function ATIS:onafterBroadcast( From, Event, To ) local clock = UTILS.SecondsToClock( time ) local zulu = UTILS.Split( clock, ":" ) local ZULU = string.format( "%s%s", zulu[1], zulu[2] ) + local hours = self.gettext:GetEntry("TIME",self.locale) if self.useSRS then - ZULU = string.format( "%s hours", zulu[1] ) + ZULU = string.format( "%s %s", hours, zulu[1] ) end -- NATO time stamp. 0=Alfa, 1=Bravo, 2=Charlie, etc. @@ -1557,19 +1791,20 @@ function ATIS:onafterBroadcast( From, Event, To ) -------------------------- --- Sunrise and Sunset --- -------------------------- - + + local hours = self.gettext:GetEntry("HOURS",self.locale) local sunrise = coord:GetSunrise() sunrise = UTILS.Split( sunrise, ":" ) local SUNRISE = string.format( "%s%s", sunrise[1], sunrise[2] ) if self.useSRS then - SUNRISE = string.format( "%s %s hours", sunrise[1], sunrise[2] ) + SUNRISE = string.format( "%s %s %s", sunrise[1], sunrise[2], hours ) end local sunset = coord:GetSunset() sunset = UTILS.Split( sunset, ":" ) local SUNSET = string.format( "%s%s", sunset[1], sunset[2] ) if self.useSRS then - SUNSET = string.format( "%s %s hours", sunset[1], sunset[2] ) + SUNSET = string.format( "%s %s %s", sunset[1], sunset[2], hours ) end --------------------------------- @@ -1654,7 +1889,7 @@ function ATIS:onafterBroadcast( From, Event, To ) local cloudceil = clouds.base + clouds.thickness local clouddens = clouds.density - -- Cloud preset (DCS 2.7) + -- Cloud preset (DCS 2.7) local cloudspreset = clouds.preset or "Nothing" -- Precepitation: 0=None, 1=Rain, 2=Thunderstorm, 3=Snow, 4=Snowstorm. @@ -1795,32 +2030,37 @@ function ATIS:onafterBroadcast( From, Event, To ) -- No cloud info for dynamic weather. local CloudCover = {} -- #ATIS.Soundfile CloudCover = ATIS.Sound.CloudsNotAvailable - local CLOUDSsub = "Cloud coverage information not available" - + --local CLOUDSsub = "Cloud coverage information not available" + local CLOUDSsub = self.gettext:GetEntry("NOCLOUDINFO",self.locale) -- Only valid for static weather. if static then if clouddens >= 9 then -- Overcast 9,10 CloudCover = ATIS.Sound.CloudsOvercast - CLOUDSsub = "Overcast" + --CLOUDSsub = "Overcast" + CLOUDSsub = self.gettext:GetEntry("OVERCAST",self.locale) elseif clouddens >= 7 then -- Broken 7,8 CloudCover = ATIS.Sound.CloudsBroken - CLOUDSsub = "Broken clouds" + --CLOUDSsub = "Broken clouds" + CLOUDSsub = self.gettext:GetEntry("BROKEN",self.locale) elseif clouddens >= 4 then -- Scattered 4,5,6 CloudCover = ATIS.Sound.CloudsScattered - CLOUDSsub = "Scattered clouds" + --CLOUDSsub = "Scattered clouds" + CLOUDSsub = self.gettext:GetEntry("SCATTERED",self.locale) elseif clouddens >= 1 then -- Few 1,2,3 CloudCover = ATIS.Sound.CloudsFew - CLOUDSsub = "Few clouds" + --CLOUDSsub = "Few clouds" + CLOUDSsub = self.gettext:GetEntry("FEWCLOUDS",self.locale) else -- No clouds CLOUDBASE = nil CLOUDCEIL = nil CloudCover = ATIS.Sound.CloudsNo - CLOUDSsub = "No clouds" + --CLOUDSsub = "No clouds" + CLOUDSsub = self.gettext:GetEntry("NOCLOUDS",self.locale) end end @@ -1833,19 +2073,23 @@ function ATIS:onafterBroadcast( From, Event, To ) -- Airbase name subtitle = string.format( "%s", self.airbasename ) - if (not self.ATISforFARPs) and self.airbasename:find( "AFB" ) == nil and self.airbasename:find( "Airport" ) == nil - and self.airbasename:find( "Airstrip" ) == nil and self.airbasename:find( "airfield" ) == nil and self.airbasename:find( "AB" ) == nil - and self.airbasename:find( "Field" ) == nil - then - subtitle = subtitle .. " Airport" + if (not self.ATISforFARPs) and self.airbasename:find( "AFB" ) == nil and self.airbasename:find( "Airport" ) == nil + and self.airbasename:find( "Airstrip" ) == nil and self.airbasename:find( "airfield" ) == nil and self.airbasename:find( "AB" ) == nil + and self.airbasename:find( "Field" ) == nil + then + --subtitle = subtitle .. " Airport" + subtitle = subtitle .. " "..self.gettext:GetEntry("AIRPORT",self.locale) end if not self.useSRS then + --self:I(string.format( "%s/%s.ogg", self.theatre, self.airbasename )) self.radioqueue:NewTransmission( string.format( "%s/%s.ogg", self.theatre, self.airbasename ), 3.0, self.soundpath, nil, nil, subtitle, self.subduration ) end local alltext = subtitle -- Information tag - subtitle = string.format( "Information %s", NATO ) + local information = self.gettext:GetEntry("INFORMATION",self.locale) + --subtitle = string.format( "Information %s", NATO ) + subtitle = string.format( "%s %s", information, NATO ) local _INFORMATION = subtitle if not self.useSRS then self:Transmission( ATIS.Sound.Information, 0.5, subtitle ) @@ -1864,7 +2108,9 @@ function ATIS:onafterBroadcast( From, Event, To ) if not self.zulutimeonly then -- Sunrise Time - subtitle = string.format( "Sunrise at %s local time", SUNRISE ) + local sunrise = self.gettext:GetEntry("SUNRISEAT",self.locale) + --subtitle = string.format( "Sunrise at %s local time", SUNRISE ) + subtitle = string.format( sunrise, SUNRISE ) if not self.useSRS then self:Transmission( ATIS.Sound.SunriseAt, 0.5, subtitle ) self.radioqueue:Number2Transmission( SUNRISE, nil, 0.2 ) @@ -1873,7 +2119,9 @@ function ATIS:onafterBroadcast( From, Event, To ) alltext = alltext .. ";\n" .. subtitle -- Sunset Time - subtitle = string.format( "Sunset at %s local time", SUNSET ) + local sunset = self.gettext:GetEntry("SUNSETAT",self.locale) + --subtitle = string.format( "Sunset at %s local time", SUNSET ) + subtitle = string.format( sunset, SUNSET ) if not self.useSRS then self:Transmission( ATIS.Sound.SunsetAt, 0.5, subtitle ) self.radioqueue:Number2Transmission( SUNSET, nil, 0.5 ) @@ -1883,17 +2131,22 @@ function ATIS:onafterBroadcast( From, Event, To ) end -- Wind - -- Adding a space after each digit of WINDFROM to convert this to aviation-speak for TTS via SRS + -- Adding a space after each digit of WINDFROM to convert this to aviation-speak for TTS via SRS if self.useSRS then WINDFROM = string.gsub(WINDFROM,".", "%1 ") - end + end if self.metric then - subtitle = string.format( "Wind from %s at %s m/s", WINDFROM, WINDSPEED ) + local windfrom = self.gettext:GetEntry("WINDFROMMS",self.locale) + --subtitle = string.format( "Wind from %s at %s m/s", WINDFROM, WINDSPEED ) + subtitle = string.format( windfrom, WINDFROM, WINDSPEED ) else - subtitle = string.format( "Wind from %s at %s knots", WINDFROM, WINDSPEED ) + local windfrom = self.gettext:GetEntry("WINDFROMKNOTS",self.locale) + --subtitle = string.format( "Wind from %s at %s m/s", WINDFROM, WINDSPEED ) + subtitle = string.format( windfrom, WINDFROM, WINDSPEED ) end if turbulence > 0 then - subtitle = subtitle .. ", gusting" + --subtitle = subtitle .. ", gusting" + subtitle = subtitle .. ", "..self.gettext:GetEntry("GUSTING",self.locale) end local _WIND = subtitle if not self.useSRS then @@ -1911,12 +2164,16 @@ function ATIS:onafterBroadcast( From, Event, To ) end end alltext = alltext .. ";\n" .. subtitle - + -- Visibility if self.metric then - subtitle = string.format( "Visibility %s km", VISIBILITY ) + local visi = self.gettext:GetEntry("VISIKM",self.locale) + --subtitle = string.format( "Visibility %s km", VISIBILITY ) + subtitle = string.format( visi, VISIBILITY ) else - subtitle = string.format( "Visibility %s SM", VISIBILITY ) + local visi = self.gettext:GetEntry("VISISM",self.locale) + --subtitle = string.format( "Visibility %s SM", VISIBILITY ) + subtitle = string.format( visi, VISIBILITY ) end if not self.useSRS then self:Transmission( ATIS.Sound.Visibilty, 1.0, subtitle ) @@ -1928,44 +2185,52 @@ function ATIS:onafterBroadcast( From, Event, To ) end end alltext = alltext .. ";\n" .. subtitle - + subtitle = "" -- Weather phenomena local wp = false local wpsub = "" if precepitation == 1 then wp = true - wpsub = wpsub .. " rain" + --wpsub = wpsub .. " rain" + wpsub = wpsub .. " "..self.gettext:GetEntry("RAIN",self.locale) elseif precepitation == 2 then if wp then wpsub = wpsub .. "," end - wpsub = wpsub .. " thunderstorm" + --wpsub = wpsub .. " thunderstorm" + wpsub = wpsub .. " "..self.gettext:GetEntry("TSTORM",self.locale) wp = true elseif precepitation == 3 then - wpsub = wpsub .. " snow" + --wpsub = wpsub .. " snow" + wpsub = wpsub .. " "..self.gettext:GetEntry("SNOW",self.locale) wp = true elseif precepitation == 4 then - wpsub = wpsub .. " snowstorm" + --wpsub = wpsub .. " snowstorm" + wpsub = wpsub .. " "..self.gettext:GetEntry("SSTROM",self.locale) wp = true end if fog then if wp then wpsub = wpsub .. "," end - wpsub = wpsub .. " fog" + --wpsub = wpsub .. " fog" + wpsub = wpsub .. " "..self.gettext:GetEntry("FOG",self.locale) wp = true end if dust then if wp then wpsub = wpsub .. "," end - wpsub = wpsub .. " dust" + --wpsub = wpsub .. " dust" + wpsub = wpsub .. " "..self.gettext:GetEntry("DUST",self.locale) wp = true end -- Actual output if wp then - subtitle = string.format( "Weather phenomena:%s", wpsub ) + local phenos = self.gettext:GetEntry("PHENOMENA",self.locale) + --subtitle = string.format( "Weather phenomena: %s", wpsub ) + subtitle = string.format( "%s: %s", phenos, wpsub ) if not self.useSRS then self:Transmission( ATIS.Sound.WeatherPhenomena, 1.0, subtitle ) if precepitation == 1 then @@ -1997,10 +2262,14 @@ function ATIS:onafterBroadcast( From, Event, To ) local cceil = tostring( tonumber( CLOUDCEIL1000 ) * 1000 + tonumber( CLOUDCEIL0100 ) * 100 ) if self.metric then -- subtitle=string.format("Cloud base %s, ceiling %s meters", CLOUDBASE, CLOUDCEIL) - subtitle = string.format( "Cloud base %s, ceiling %s meters", cbase, cceil ) + local cloudbase = self.gettext:GetEntry("CLOUDBASEM",self.locale) + --subtitle = string.format( "Cloud base %s, ceiling %s meters", cbase, cceil ) + subtitle = string.format( cloudbase, cbase, cceil ) else -- subtitle=string.format("Cloud base %s, ceiling %s feet", CLOUDBASE, CLOUDCEIL) - subtitle = string.format( "Cloud base %s, ceiling %s feet", cbase, cceil ) + local cloudbase = self.gettext:GetEntry("CLOUDBASEFT",self.locale) + --subtitle = string.format( "Cloud base %s, ceiling %s feet", cbase, cceil ) + subtitle = string.format( cloudbase, cbase, cceil ) end if not self.useSRS then self:Transmission( ATIS.Sound.CloudBase, 1.0, subtitle ) @@ -2033,17 +2302,22 @@ function ATIS:onafterBroadcast( From, Event, To ) alltext = alltext .. ";\n" .. subtitle subtitle = "" -- Temperature + local temptext = self.gettext:GetEntry("TEMPERATURE",self.locale) if self.TDegF then if temperature < 0 then - subtitle = string.format( "Temperature -%s °F", TEMPERATURE ) + --subtitle = string.format( "Temperature -%s °F", TEMPERATURE ) + subtitle = string.format( "%s -%s °F", temptext, TEMPERATURE ) else - subtitle = string.format( "Temperature %s °F", TEMPERATURE ) + --subtitle = string.format( "Temperature %s °F", TEMPERATURE ) + subtitle = string.format( "%s %s °F", temptext, TEMPERATURE ) end else if temperature < 0 then - subtitle = string.format( "Temperature -%s °C", TEMPERATURE ) + --subtitle = string.format( "Temperature -%s °C", TEMPERATURE ) + subtitle = string.format( "%s -%s °C", temptext, TEMPERATURE ) else - subtitle = string.format( "Temperature %s °C", TEMPERATURE ) + --subtitle = string.format( "Temperature %s °C", TEMPERATURE ) + subtitle = string.format( "%s %s °C", temptext, TEMPERATURE ) end end local _TEMPERATURE = subtitle @@ -2060,19 +2334,24 @@ function ATIS:onafterBroadcast( From, Event, To ) end end alltext = alltext .. ";\n" .. subtitle - + -- Dew point + local dewtext = self.gettext:GetEntry("DEWPOINT",self.locale) if self.TDegF then if dewpoint < 0 then - subtitle = string.format( "Dew point -%s °F", DEWPOINT ) + --subtitle = string.format( "Dew point -%s °F", DEWPOINT ) + subtitle = string.format( "%s -%s °F", dewtext, DEWPOINT ) else - subtitle = string.format( "Dew point %s °F", DEWPOINT ) + --subtitle = string.format( "Dew point %s °F", DEWPOINT ) + subtitle = string.format( "%s %s °F", dewtext, DEWPOINT ) end else if dewpoint < 0 then - subtitle = string.format( "Dew point -%s °C", DEWPOINT ) + --subtitle = string.format( "Dew point -%s °C", DEWPOINT ) + subtitle = string.format( "%s -%s °C", dewtext, DEWPOINT ) else - subtitle = string.format( "Dew point %s °C", DEWPOINT ) + --subtitle = string.format( "Dew point %s °C", DEWPOINT ) + subtitle = string.format( "%s %s °C", dewtext, DEWPOINT ) end end local _DEWPOINT = subtitle @@ -2091,36 +2370,45 @@ function ATIS:onafterBroadcast( From, Event, To ) alltext = alltext .. ";\n" .. subtitle -- Altimeter QNH/QFE. + local altim = self.gettext:GetEntry("ALTIMETER",self.locale) if self.PmmHg then if self.qnhonly then - subtitle = string.format( "Altimeter %s.%s mmHg", QNH[1], QNH[2] ) + --subtitle = string.format( "Altimeter %s.%s mmHg", QNH[1], QNH[2] ) + subtitle = string.format( "%s %s.%s mmHg", altim, QNH[1], QNH[2] ) else - subtitle = string.format( "Altimeter: QNH %s.%s, QFE %s.%s mmHg", QNH[1], QNH[2], QFE[1], QFE[2] ) + --subtitle = string.format( "Altimeter: QNH %s.%s, QFE %s.%s mmHg", QNH[1], QNH[2], QFE[1], QFE[2] ) + subtitle = string.format( "%s: QNH %s.%s, QFE %s.%s mmHg", altim, QNH[1], QNH[2], QFE[1], QFE[2] ) end else if self.metric then if self.qnhonly then - subtitle = string.format( "Altimeter %s.%s hPa", QNH[1], QNH[2] ) + --subtitle = string.format( "Altimeter %s.%s hPa", QNH[1], QNH[2] ) + subtitle = string.format( "%s %s.%s hPa", altim, QNH[1], QNH[2] ) else - subtitle = string.format( "Altimeter: QNH %s.%s, QFE %s.%s hPa", QNH[1], QNH[2], QFE[1], QFE[2] ) + --subtitle = string.format( "Altimeter: QNH %s.%s, QFE %s.%s hPa", QNH[1], QNH[2], QFE[1], QFE[2] ) + subtitle = string.format( "%s: QNH %s.%s, QFE %s.%s hPa", altim, QNH[1], QNH[2], QFE[1], QFE[2] ) end else if self.qnhonly then - subtitle = string.format( "Altimeter %s.%s inHg", QNH[1], QNH[2] ) + --subtitle = string.format( "Altimeter %s.%s inHg", QNH[1], QNH[2] ) + subtitle = string.format( "%s %s.%s inHg", altim, QNH[1], QNH[2] ) else - subtitle = string.format( "Altimeter: QNH %s.%s, QFE %s.%s inHg", QNH[1], QNH[2], QFE[1], QFE[2] ) + --subtitle = string.format( "Altimeter: QNH %s.%s, QFE %s.%s inHg", QNH[1], QNH[2], QFE[1], QFE[2] ) + subtitle = string.format( "%s: QNH %s.%s, QFE %s.%s inHg", altim, QNH[1], QNH[2], QFE[1], QFE[2] ) end end end - + if self.ReportmBar and not self.metric then if self.qnhonly then - subtitle = string.format( "%s;\nAltimeter %d hPa", subtitle, mBarqnh ) + --subtitle = string.format( "%s;\nAltimeter %d hPa", subtitle, mBarqnh ) + subtitle = string.format( "%s;\n%s %d hPa", subtitle, altim, mBarqnh ) else - subtitle = string.format( "%s;\nAltimeter: QNH %d, QFE %d hPa", subtitle, mBarqnh, mBarqfe) + --subtitle = string.format( "%s;\nAltimeter: QNH %d, QFE %d hPa", subtitle, mBarqnh, mBarqfe) + subtitle = string.format( "%s;\n%s: QNH %d, QFE %d hPa", subtitle, altim, mBarqnh, mBarqfe) end end - + local _ALTIMETER = subtitle if not self.useSRS then self:Transmission( ATIS.Sound.Altimeter, 1.0, subtitle ) @@ -2154,18 +2442,22 @@ function ATIS:onafterBroadcast( From, Event, To ) end end alltext = alltext .. ";\n" .. subtitle - + local _RUNACT if not self.ATISforFARPs then -- Active runway. local subtitle if runwayLanding then - subtitle=string.format("Active runway %s", runwayLanding) + local actrun = self.gettext:GetEntry("ACTIVERUN",self.locale) + --subtitle=string.format("Active runway %s", runwayLanding) + subtitle=string.format("%s %s", actrun, runwayLanding) if rwyLandingLeft==true then - subtitle=subtitle.." Left" + --subtitle=subtitle.." Left" + subtitle=subtitle.." "..self.gettext:GetEntry("LEFT",self.locale) elseif rwyLandingLeft==false then - subtitle=subtitle.." Right" + --subtitle=subtitle.." Right" + subtitle=subtitle.." "..self.gettext:GetEntry("RIGHT",self.locale) end end _RUNACT = subtitle @@ -2179,27 +2471,31 @@ function ATIS:onafterBroadcast( From, Event, To ) end end alltext = alltext .. ";\n" .. subtitle - + -- Runway length. if self.rwylength then - + local runact = self.airbase:GetActiveRunway( self.runwaym2t ) local length = runact.length if not self.metric then length = UTILS.MetersToFeet( length ) end - + -- Length in thousands and hundrets of ft/meters. local L1000, L0100 = self:_GetThousandsAndHundreds( length ) - + -- Subtitle. - local subtitle = string.format( "Runway length %d", length ) + local rwyl = self.gettext:GetEntry("RWYLENGTH",self.locale) + local meters = self.gettext:GetEntry("METERS",self.locale) + local feet = self.gettext:GetEntry("FEET",self.locale) + --local subtitle = string.format( "Runway length %d", length ) + local subtitle = string.format( "%s %d", rwyl, length ) if self.metric then - subtitle = subtitle .. " meters" + subtitle = subtitle .. " "..meters else - subtitle = subtitle .. " feet" + subtitle = subtitle .. " "..feet end - + -- Transmit. if not self.useSRS then self:Transmission( ATIS.Sound.RunwayLength, 1.0, subtitle ) @@ -2222,7 +2518,11 @@ function ATIS:onafterBroadcast( From, Event, To ) end -- Airfield elevation if self.elevation then - + + local elev = self.gettext:GetEntry("ELEVATION",self.locale) + local meters = self.gettext:GetEntry("METERS",self.locale) + local feet = self.gettext:GetEntry("FEET",self.locale) + local elevation = self.airbase:GetHeight() if not self.metric then elevation = UTILS.MetersToFeet( elevation ) @@ -2232,11 +2532,12 @@ function ATIS:onafterBroadcast( From, Event, To ) local L1000, L0100 = self:_GetThousandsAndHundreds( elevation ) -- Subtitle. - local subtitle = string.format( "Elevation %d", elevation ) + --local subtitle = string.format( "Elevation %d", elevation ) + local subtitle = string.format( "%s %d", elev, elevation ) if self.metric then - subtitle = subtitle .. " meters" + subtitle = subtitle .. " "..meters else - subtitle = subtitle .. " feet" + subtitle = subtitle .. " "..feet end -- Transmit. @@ -2268,7 +2569,9 @@ function ATIS:onafterBroadcast( From, Event, To ) freqs = freqs .. ", " end end - subtitle = string.format( "Tower frequency %s", freqs ) + local twrfrq = self.gettext:GetEntry("TOWERFREQ",self.locale) + --subtitle = string.format( "Tower frequency %s", freqs ) + subtitle = string.format( "%s %s", twrfrq, freqs ) if not self.useSRS then self:Transmission( ATIS.Sound.TowerFrequency, 1.0, subtitle ) for _, freq in pairs( self.towerfrequency ) do @@ -2288,7 +2591,9 @@ function ATIS:onafterBroadcast( From, Event, To ) -- ILS local ils=self:GetNavPoint(self.ils, runwayLanding, rwyLandingLeft) if ils then - subtitle = string.format( "ILS frequency %.2f MHz", ils.frequency ) + local ilstxt = self.gettext:GetEntry("ILSFREQ",self.locale) + --subtitle = string.format( "ILS frequency %.2f MHz", ils.frequency ) + subtitle = string.format( "%s %.2f MHz", ilstxt, ils.frequency ) if not self.useSRS then self:Transmission( ATIS.Sound.ILSFrequency, 1.0, subtitle ) local f = string.format( "%.2f", ils.frequency ) @@ -2306,7 +2611,9 @@ function ATIS:onafterBroadcast( From, Event, To ) -- Outer NDB local ndb=self:GetNavPoint(self.ndbouter, runwayLanding, rwyLandingLeft) if ndb then - subtitle = string.format( "Outer NDB frequency %.2f MHz", ndb.frequency ) + local ndbtxt = self.gettext:GetEntry("OUTERNDB",self.locale) + --subtitle = string.format( "Outer NDB frequency %.2f MHz", ndb.frequency ) + subtitle = string.format( "%s %.2f MHz", ndbtxt, ndb.frequency ) if not self.useSRS then self:Transmission( ATIS.Sound.OuterNDBFrequency, 1.0, subtitle ) local f = string.format( "%.2f", ndb.frequency ) @@ -2324,7 +2631,9 @@ function ATIS:onafterBroadcast( From, Event, To ) -- Inner NDB local ndb=self:GetNavPoint(self.ndbinner, runwayLanding, rwyLandingLeft) if ndb then - subtitle = string.format( "Inner NDB frequency %.2f MHz", ndb.frequency ) + local ndbtxt = self.gettext:GetEntry("INNERNDB",self.locale) + --subtitle = string.format( "Inner NDB frequency %.2f MHz", ndb.frequency ) + subtitle = string.format( "%s %.2f MHz", ndbtxt, ndb.frequency ) if not self.useSRS then self:Transmission( ATIS.Sound.InnerNDBFrequency, 1.0, subtitle ) local f = string.format( "%.2f", ndb.frequency ) @@ -2341,9 +2650,13 @@ function ATIS:onafterBroadcast( From, Event, To ) -- VOR if self.vor then - subtitle = string.format( "VOR frequency %.2f MHz", self.vor ) + local vortxt = self.gettext:GetEntry("VORFREQ",self.locale) + local vorttstxt = self.gettext:GetEntry("VORFREQTTS",self.locale) + --subtitle = string.format( "VOR frequency %.2f MHz", self.vor ) + subtitle = string.format( "%s %.2f MHz", vortxt, self.vor ) if self.useSRS then - subtitle = string.format( "V O R frequency %.2f MHz", self.vor ) + --subtitle = string.format( "V O R frequency %.2f MHz", self.vor ) + subtitle = string.format( "%s %.2f MHz", vorttstxt, self.vor ) end if not self.useSRS then self:Transmission( ATIS.Sound.VORFrequency, 1.0, subtitle ) @@ -2361,7 +2674,9 @@ function ATIS:onafterBroadcast( From, Event, To ) -- TACAN if self.tacan then - subtitle=string.format("TACAN channel %dX Ray", self.tacan) + local tactxt = self.gettext:GetEntry("TACANCH",self.locale) + --subtitle=string.format("TACAN channel %dX Ray", self.tacan) + subtitle=string.format(tactxt, self.tacan) if not self.useSRS then self:Transmission( ATIS.Sound.TACANChannel, 1.0, subtitle ) self.radioqueue:Number2Transmission( tostring( self.tacan ), nil, 0.2 ) @@ -2372,7 +2687,9 @@ function ATIS:onafterBroadcast( From, Event, To ) -- RSBN if self.rsbn then - subtitle = string.format( "RSBN channel %d", self.rsbn ) + local rsbntxt = self.gettext:GetEntry("RSBNCH",self.locale) + --subtitle = string.format( "RSBN channel %d", self.rsbn ) + subtitle = string.format( "%s %d", rsbntxt, self.rsbn ) if not self.useSRS then self:Transmission( ATIS.Sound.RSBNChannel, 1.0, subtitle ) self.radioqueue:Number2Transmission( tostring( self.rsbn ), nil, 0.2 ) @@ -2383,21 +2700,25 @@ function ATIS:onafterBroadcast( From, Event, To ) -- PRMG local ndb=self:GetNavPoint(self.prmg, runwayLanding, rwyLandingLeft) if ndb then - subtitle = string.format( "PRMG channel %d", ndb.frequency ) + local prmtxt = self.gettext:GetEntry("PRMGCH",self.locale) + --subtitle = string.format( "PRMG channel %d", ndb.frequency ) + subtitle = string.format( "%s %d", prmtxt, ndb.frequency ) if not self.useSRS then self:Transmission( ATIS.Sound.PRMGChannel, 1.0, subtitle ) self.radioqueue:Number2Transmission( tostring( ndb.frequency ), nil, 0.5 ) end alltext = alltext .. ";\n" .. subtitle end - + -- additional info, if any if self.useSRS and self.AdditionalInformation then alltext = alltext .. ";\n"..self.AdditionalInformation end - + -- Advice on initial... - subtitle = string.format( "Advise on initial contact, you have information %s", NATO ) + local advtxt = self.gettext:GetEntry("ADVISE",self.locale) + --subtitle = string.format( "Advise on initial contact, you have information %s", NATO ) + subtitle = string.format( "%s %s", advtxt, NATO ) if not self.useSRS then self:Transmission( ATIS.Sound.AdviceOnInitial, 0.5, subtitle ) self.radioqueue:NewTransmission( string.format( "NATO Alphabet/%s.ogg", NATO ), 0.75, self.soundpath ) @@ -2430,16 +2751,33 @@ function ATIS:onafterReport( From, Event, To, Text ) local text = string.gsub( Text, "[\r\n]", "" ) -- Replace other stuff. - local text = string.gsub( text, "SM", "statute miles" ) - local text = string.gsub( text, "°C", "degrees Celsius" ) - local text = string.gsub( text, "°F", "degrees Fahrenheit" ) - local text = string.gsub( text, "inHg", "inches of Mercury" ) - local text = string.gsub( text, "mmHg", "millimeters of Mercury" ) - local text = string.gsub( text, "hPa", "hectopascals" ) - local text = string.gsub( text, "m/s", "meters per second" ) - local text = string.gsub( text, "TACAN", "tackan" ) - local text = string.gsub( text, "FARP", "farp" ) - + local statute = self.gettext:GetEntry("STATUTE",self.locale) + local degc = self.gettext:GetEntry("DEGREES",self.locale) + local degf = self.gettext:GetEntry("FAHRENHEIT",self.locale) + local inhg = self.gettext:GetEntry("INCHHG",self.locale) + local mmhg = self.gettext:GetEntry("MMHG",self.locale) + local hpa = self.gettext:GetEntry("HECTO",self.locale) + local emes = self.gettext:GetEntry("METERSPER",self.locale) + local tacan = self.gettext:GetEntry("TACAN",self.locale) + local farp = self.gettext:GetEntry("FARP",self.locale) + + + local text = string.gsub( text, "SM", statute ) + text = string.gsub( text, "°C", degc ) + text = string.gsub( text, "°F", degf ) + text = string.gsub( text, "inHg", inhg ) + text = string.gsub( text, "mmHg", mmhg ) + text = string.gsub( text, "hPa", hpa ) + text = string.gsub( text, "m/s", emes ) + text = string.gsub( text, "TACAN", tacan ) + text = string.gsub( text, "FARP", farp ) + + local delimiter = self.gettext:GetEntry("DELIMITER",self.locale) + + if string.lower(self.locale) ~= "en" then + text = string.gsub(text,"(%d+)(%.)(%d+)","%1 "..delimiter.." %3") + end + -- Replace ";" by "." local text = string.gsub( text, ";", " . " ) @@ -2448,10 +2786,10 @@ function ATIS:onafterReport( From, Event, To, Text ) -- Play text-to-speech report. local duration = STTS.getSpeechTime(text,0.95) - self.msrsQ:NewTransmission(text,duration,self.msrs,nil,2) + self.msrsQ:NewTransmission(text,duration,self.msrs,nil,2) --self.msrs:PlayText( text ) self.SRSText = text - + end end @@ -2523,7 +2861,7 @@ end -- @return #string Active runway, e.g. "31" for 310 deg. -- @return #boolean Use Left=true, Right=false, or nil. function ATIS:GetActiveRunway(Takeoff) - + local runway=nil --Wrapper.Airbase#AIRBASE.Runway if Takeoff then runway=self.airbase:GetActiveRunwayTakeoff() @@ -2586,7 +2924,7 @@ function ATIS:GetNavPoint( navpoints, runway, left ) if hdgD <= 15 then -- We allow an error of +-15° here. if navL == nil or (navL == true and left == true) or (navL == false and left == false) then return nav - end + end end end end diff --git a/Moose Development/Moose/Ops/OpsGroup.lua b/Moose Development/Moose/Ops/OpsGroup.lua index 12465ecf2..c46d4545f 100644 --- a/Moose Development/Moose/Ops/OpsGroup.lua +++ b/Moose Development/Moose/Ops/OpsGroup.lua @@ -8128,7 +8128,7 @@ function OPSGROUP:_CheckCargoTransport() for _,_cargo in pairs(self.cargoTZC.Cargos) do local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup - if cargo.type==OPSTRANSPORT.CargoType.OPSTRANPORT then + if cargo.type==OPSTRANSPORT.CargoType.OPSGROUP then -- Check if anyone is still boarding. if cargo.opsgroup and cargo.opsgroup:IsBoarding(self.groupname) then diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index 469fabeea..786e48c26 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -406,8 +406,8 @@ function UTILS._OneLineSerialize(tbl) elseif type(val) == 'nil' then -- won't ever happen, right? tbl_str[#tbl_str + 1] = 'nil, ' elseif type(val) == 'table' then - tbl_str[#tbl_str + 1] = UTILS._OneLineSerialize(val) - tbl_str[#tbl_str + 1] = ', ' --I think this is right, I just added it + --tbl_str[#tbl_str + 1] = UTILS._OneLineSerialize(val) + --tbl_str[#tbl_str + 1] = ', ' --I think this is right, I just added it else --log:warn('Unable to serialize value type $1 at index $2', mist.utils.basicSerialize(type(val)), tostring(ind)) end