diff --git a/Moose Development/LDT External Tools/Update ALL Moose Test Missions.launch b/Moose Development/LDT External Tools/Update ALL Moose Test Missions.launch index 1f0c932a8..465818763 100644 --- a/Moose Development/LDT External Tools/Update ALL Moose Test Missions.launch +++ b/Moose Development/LDT External Tools/Update ALL Moose Test Missions.launch @@ -1,5 +1,8 @@ + + + diff --git a/Moose Development/LDT External Tools/Update Moose Test Missions.launch b/Moose Development/LDT External Tools/Update Moose Test Missions.launch new file mode 100644 index 000000000..3fec0cfe5 --- /dev/null +++ b/Moose Development/LDT External Tools/Update Moose Test Missions.launch @@ -0,0 +1,6 @@ + + + + + + diff --git a/Moose Development/LDT External Tools/Update Single Moose Test Mission.launch b/Moose Development/LDT External Tools/Update Single Moose Test Mission.launch new file mode 100644 index 000000000..5a375b0f0 --- /dev/null +++ b/Moose Development/LDT External Tools/Update Single Moose Test Mission.launch @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/Moose Development/Moose/Core/Event.lua b/Moose Development/Moose/Core/Event.lua index 0e7d2b431..8f9a926b7 100644 --- a/Moose Development/Moose/Core/Event.lua +++ b/Moose Development/Moose/Core/Event.lua @@ -785,6 +785,11 @@ function EVENT:onEvent( Event ) if Event.weapon then Event.Weapon = Event.weapon Event.WeaponName = Event.Weapon:getTypeName() + Event.WeaponUNIT = CLIENT:Find( Event.Weapon, '', true ) -- Sometimes, the weapon is a player unit! + Event.WeaponPlayerName = Event.WeaponUNIT and Event.Weapon:getPlayerName() + Event.WeaponCoalition = Event.WeaponUNIT and Event.Weapon:getCoalition() + Event.WeaponCategory = Event.WeaponUNIT and Event.Weapon:getDesc().category + Event.WeaponTypeName = Event.WeaponUNIT and Event.Weapon:getTypeName() --Event.WeaponTgtDCSUnit = Event.Weapon:getTarget() end @@ -949,7 +954,7 @@ function EVENT:onEvent( Event ) -- If the EventData is not bound to a specific unit, then call the EventClass EventFunction. -- Note that here the EventFunction will need to implement and determine the logic for the relevant source- or target unit, or weapon. - if Event.IniDCSUnit and not EventData.EventUnit then + if (Event.IniDCSUnit or Event.WeaponUNIT) and not EventData.EventUnit then if EventClass == EventData.EventClass then diff --git a/Moose Development/Moose/Core/Radio.lua b/Moose Development/Moose/Core/Radio.lua new file mode 100644 index 000000000..88863ad86 --- /dev/null +++ b/Moose Development/Moose/Core/Radio.lua @@ -0,0 +1,311 @@ +--- **Core** - The RADIO class is responsible for **transmitting radio communications**. +-- +-- --- bitmap +-- +-- === +-- +-- What are radio communications in DCS ? +-- +-- * Radio transmissions consist of **sound files** that are broadcasted on a specific **frequency** (e.g. 115MHz) and **modulation** (e.g. AM), +-- * They can be **subtitled** for a specific **duration**, the **power** in Watts of the transmiter's antenna can be set, and the transmission can be **looped**. +-- +-- How to supply DCS my own Sound Files ? +-- +-- * Your sound files need to be encoded in **.ogg** or .wav, +-- * Your sound files should be **as tiny as possible**. It is suggested you encode in .ogg with low bitrate and sampling settings, +-- * They need to be added in .\l10n\DEFAULT\ in you .miz file (wich can be decompressed like a .zip file), +-- * For simplicty sake, you can **let DCS' Mission Editor add the file** itself, by creating a new Trigger with the action "Sound to Country", and choosing your sound file and a country you don't use in your mission. +-- +-- Due to weird DCS quirks, **radio communications behave differently** if sent by a @{Unit#UNIT} or a @{Group#GROUP} or by any other @{Positionable#POSITIONABLE} +-- +-- * If the transmitter is a @{Unit#UNIT} or a @{Group#GROUP}, DCS will set the power of the transmission automatically, +-- * If the transmitter is any other @{Positionable#POSITIONABLE}, the transmisison can't be subtitled or looped. +-- +-- Note that obviously, the **frequency** and the **modulation** of the transmission are important only if the players are piloting an **Advanced System Modelling** enabled aircraft, +-- like the A10C or the Mirage 2000C. They will **hear the transmission** if they are tuned on the **right frequency and modulation** (and if they are close enough - more on that below). +-- If a FC3 airacraft is used, it will **hear every communication, whatever the frequency and the modulation** is set to. +-- +-- === +-- +-- ### Authors: Hugues "Grey_Echo" Bousquet +-- +-- @module Radio + +--- # 1) RADIO class, extends @{Base#BASE} +-- +-- ## 1.1) RADIO usage +-- +-- There are 3 steps to a successful radio transmission. +-- +-- * First, you need to **"add" a @{#RADIO} object** to your @{Positionable#POSITIONABLE}. This is done using the @{Positionable#POSITIONABLE.GetRadio}() function, +-- * Then, you will **set the relevant parameters** to the transmission (see below), +-- * When done, you can actually **broadcast the transmission** (i.e. play the sound) with the @{Positionable#POSITIONABLE.Broadcast}() function. +-- +-- Methods to set relevant parameters for both a @{Unit#UNIT} or a @{Group#GROUP} or any other @{Positionable#POSITIONABLE} +-- +-- * @{#RADIO.SetFileName}() : Sets the file name of your sound file (e.g. "Noise.ogg"), +-- * @{#RADIO.SetFrequency}() : Sets the frequency of your transmission, +-- * @{#RADIO.SetModulation}() : Sets the modulation of your transmission. +-- +-- Additional Methods to set relevant parameters if the transmiter is a @{Unit#UNIT} or a @{Group#GROUP} +-- +-- * @{#RADIO.SetLoop}() : Choose if you want the transmission to be looped, +-- * @{#RADIO.SetSubtitle}() : Set both the subtitle and its duration, +-- * @{#RADIO.NewUnitTransmission}() : Shortcut to set all the relevant parameters in one method call +-- +-- Additional Methods to set relevant parameters if the transmiter is any other @{Wrapper.Positionable#POSITIONABLE} +-- +-- * @{#RADIO.SetPower}() : Sets the power of the antenna in Watts +-- * @{#RADIO.NewGenericTransmission}() : Shortcut to set all the relevant parameters in one method call +-- +-- What is this power thing ? +-- +-- * If your transmission is sent by a @{Positionable#POSITIONABLE} other than a @{Unit#UNIT} or a @{Group#GROUP}, you can set the power of the antenna, +-- * Otherwise, DCS sets it automatically, depending on what's available on your Unit, +-- * If the player gets **too far** from the transmiter, or if the antenna is **too weak**, the transmission will **fade** and **become noisyer**, +-- * This an automated DCS calculation you have no say on, +-- * For reference, a standard VOR station has a 100W antenna, a standard AA TACAN has a 120W antenna, and civilian ATC's antenna usually range between 300 and 500W, +-- * Note that if the transmission has a subtitle, it will be readable, regardless of the quality of the transmission. +-- +-- @type RADIO +-- @field Wrapper.Positionable#POSITIONABLE Positionable The transmiter +-- @field #string FileName Name of the sound file +-- @field #number Frequency Frequency of the transmission in Hz +-- @field #number Modulation Modulation of the transmission (either radio.modulation.AM or radio.modulation.FM) +-- @field #string Subtitle Subtitle of the transmission +-- @field #number SubtitleDuration Duration of the Subtitle in seconds +-- @field #number Power Power of the antenna is Watts +-- @field #boolean Loop +-- @extends Core.Base#BASE +RADIO = { + ClassName = "RADIO", + FileName = "", + Frequency = 0, + Modulation = radio.modulation.AM, + Subtitle = "", + SubtitleDuration = 0, + Power = 100, + Loop = 0, +} + +--- Create a new RADIO Object. This doesn't broadcast a transmission, though, use @{#RADIO.Broadcast} to actually broadcast +-- @param #RADIO self +-- @param Wrapper.Positionable#POSITIONABLE Positionable The @{Positionable} that will receive radio capabilities. +-- @return #RADIO Radio +-- @return #nil If Positionable is invalid +-- @usage +-- -- If you want to create a RADIO, you probably should use @{Positionable#POSITIONABLE.GetRadio}() instead +function RADIO:New(Positionable) + local self = BASE:Inherit( self, BASE:New() ) -- Core.Radio#RADIO + + self:F(Positionable) + + if Positionable:GetPointVec2() ~= nil then -- It's stupid, but the only way I found to make sure positionable is valid + self.Positionable = Positionable + return self + end + + self:E({"The passed positionable is invalid, no RADIO created", Positionable}) + return nil +end + +--- Check validity of the filename passed and sets RADIO.FileName +-- @param #RADIO self +-- @param #string FileName File name of the sound file (i.e. "Noise.ogg") +-- @return #RADIO self +function RADIO:SetFileName(FileName) + self:F2(FileName) + + if type(FileName) == "string" then + if FileName:find(".ogg") ~= nil or FileName:find(".wav") ~= nil then + if FileName:find("l10n/DEFAULT/") == nil then + FileName = "l10n/DEFAULT/" .. FileName + end + self.FileName = FileName + return self + end + end + + self:E({"File name invalid. Maybe something wrong with the extension ?", self.FileName}) + return self +end + +--- Check validity of the frequency passed and sets RADIO.Frequency +-- @param #RADIO self +-- @param #number Frequency in MHz (Ranges allowed for radio transmissions in DCS : 30-88 / 108-152 / 225-400MHz) +-- @return #RADIO self +function RADIO:SetFrequency(Frequency) + self:F2(Frequency) + if type(Frequency) == "number" then + -- If frequency is in range + if (Frequency >= 30 and Frequency < 88) or (Frequency >= 108 and Frequency < 152) or (Frequency >= 225 and Frequency < 400) then + self.Frequency = Frequency * 1000000 -- Conversion in Hz + -- If the RADIO is attached to a UNIT or a GROUP, we need to send the DCS Command "SetFrequency" to change the UNIT or GROUP frequency + if self.Positionable.ClassName == "UNIT" or self.Positionable.ClassName == "GROUP" then + self.Positionable:GetDCSObject():getController():setCommand({ + id = "SetFrequency", + params = { + frequency = self.Frequency, + modulation = self.Modulation, + } + }) + end + return self + end + end + self:E({"Frequency is outside of DCS Frequency ranges (30-80, 108-152, 225-400). Frequency unchanged.", self.Frequency}) + return self +end + +--- Check validity of the frequency passed and sets RADIO.Modulation +-- @param #RADIO self +-- @param #number Modulation either radio.modulation.AM or radio.modulation.FM +-- @return #RADIO self +function RADIO:SetModulation(Modulation) + self:F2(Modulation) + if type(Modulation) == "number" then + if Modulation == radio.modulation.AM or Modulation == radio.modulation.FM then --TODO Maybe make this future proof if ED decides to add an other modulation ? + self.Modulation = Modulation + return self + end + end + self:E({"Modulation is invalid. Use DCS's enum radio.modulation. Modulation unchanged.", self.Modulation}) + return self +end + +--- Check validity of the power passed and sets RADIO.Power +-- @param #RADIO self +-- @param #number Power in W +-- @return #RADIO self +function RADIO:SetPower(Power) + self:F2(Power) + if type(Power) == "number" then + self.Power = math.floor(math.abs(Power)) --TODO Find what is the maximum power allowed by DCS and limit power to that + return self + end + self:E({"Power is invalid. Power unchanged.", self.Power}) + return self +end + +--- Check validity of the loop passed and sets RADIO.Loop +-- @param #RADIO self +-- @param #boolean Loop +-- @return #RADIO self +-- @usage +function RADIO:SetLoop(Loop) + self:F2(Loop) + if type(Loop) == "boolean" then + self.Loop = Loop + return self + end + self:E({"Loop is invalid. Loop unchanged.", self.Loop}) + return self +end + +--- Check validity of the subtitle and the subtitleDuration passed and sets RADIO.subtitle and RADIO.subtitleDuration +-- @param #RADIO self +-- @param #string Subtitle +-- @param #number SubtitleDuration in s +-- @return #RADIO self +-- @usage +-- -- Both parameters are mandatory, since it wouldn't make much sense to change the Subtitle and not its duration +function RADIO:SetSubtitle(Subtitle, SubtitleDuration) + self:F2({Subtitle, SubtitleDuration}) + if type(Subtitle) == "string" then + self.Subtitle = Subtitle + else + self.Subtitle = "" + self:E({"Subtitle is invalid. Subtitle reset.", self.Subtitle}) + end + if type(SubtitleDuration) == "number" then + if math.floor(math.abs(SubtitleDuration)) == SubtitleDuration then + self.SubtitleDuration = SubtitleDuration + return self + end + end + self.SubtitleDuration = 0 + self:E({"SubtitleDuration is invalid. SubtitleDuration reset.", self.SubtitleDuration}) +end + +--- Create a new transmission, that is to say, populate the RADIO with relevant data +-- @param #RADIO self +-- @param #string FileName +-- @param #number Frequency in MHz +-- @param #number Modulation either radio.modulation.AM or radio.modulation.FM +-- @param #number Power in W +-- @return #RADIO self +-- @usage +-- -- In this function the data is especially relevant if the broadcaster is anything but a UNIT or a GROUP, +-- but it will work with a UNIT or a GROUP anyway +-- -- Only the RADIO and the Filename are mandatory +function RADIO:NewGenericTransmission(FileName, Frequency, Modulation, Power) + self:F({FileName, Frequency, Modulation, Power}) + + self:SetFileName(FileName) + if Frequency then self:SetFrequency(Frequency) end + if Modulation then self:SetModulation(Modulation) end + if Power then self:SetPower(Power) end + + return self +end + + +--- Create a new transmission, that is to say, populate the RADIO with relevant data +-- @param #RADIO self +-- @param #string FileName +-- @param #string Subtitle +-- @param #number SubtitleDuration in s +-- @param #number Frequency in MHz +-- @param #number Modulation either radio.modulation.AM or radio.modulation.FM +-- @param #boolean Loop +-- @return #RADIO self +-- @usage +-- -- In this function the data is especially relevant if the broadcaster is a UNIT or a GROUP, +-- but it will work for any POSITIONABLE +-- -- Only the RADIO and the Filename are mandatory +function RADIO:NewUnitTransmission(FileName, Subtitle, SubtitleDuration, Frequency, Modulation, Loop) + self:F({FileName, Subtitle, SubtitleDuration, Frequency, Modulation, Loop}) + + self:SetFileName(FileName) + if Subtitle then self:SetSubtitle(Subtitle) end + if SubtitleDuration then self:SetSubtitleDuration(SubtitleDuration) end + if Frequency then self:SetFrequency(Frequency) end + if Modulation then self:SetModulation(Modulation) end + if Loop then self:SetLoop(Loop) end + + return self +end + +--- Actually Broadcast the transmission +-- @param #RADIO self +-- @return #RADIO self +-- @usage +-- -- The Radio has to be populated with the new transmission before broadcasting. +-- -- Please use RADIO setters or either @{Radio#RADIO.NewGenericTransmission} or @{Radio#RADIO.NewUnitTransmission} +-- -- This class is in fact pretty smart, it determines the right DCS function to use depending on the type of POSITIONABLE +-- -- If the POSITIONABLE is not a UNIT or a GROUP, we use the generic (but limited) trigger.action.radioTransmission() +-- -- If the POSITIONABLE is a UNIT or a GROUP, we use the "TransmitMessage" Command +-- -- If your POSITIONABLE is a UNIT or a GROUP, the Power is ignored. +-- -- If your POSITIONABLE is not a UNIT or a GROUP, the Subtitle, SubtitleDuration and Loop are ignored +function RADIO:Broadcast() + self:F() + -- If the POSITIONABLE is actually a Unit or a Group, use the more complicated DCS command system + if self.Positionable.ClassName == "UNIT" or self.Positionable.ClassName == "GROUP" then + self:T2("Broadcasting from a UNIT or a GROUP") + self.Positionable:GetDCSObject():getController():setCommand({ + id = "TransmitMessage", + params = { + file = self.FileName, + duration = self.SubtitleDuration, + subtitle = self.Subtitle, + loop = self.Loop, + } + }) + else + -- If the POSITIONABLE is anything else, we revert to the general singleton function + self:T2("Broadcasting from a POSITIONABLE") + trigger.action.radioTransmission(self.FileName, self.Positionable:GetPositionVec3(), self.Modulation, false, self.Frequency, self.Power) + end + return self +end + diff --git a/Moose Development/Moose/Functional/Scoring.lua b/Moose Development/Moose/Functional/Scoring.lua index 1a50fb4ef..244b36957 100644 --- a/Moose Development/Moose/Functional/Scoring.lua +++ b/Moose Development/Moose/Functional/Scoring.lua @@ -5,8 +5,6 @@ -- -- === -- --- # 1) @{Scoring#SCORING} class, extends @{Base#BASE} --- -- The @{#SCORING} class administers the scoring of player achievements, -- and creates a CSV file logging the scoring events and results for use at team or squadron websites. -- @@ -57,6 +55,8 @@ -- Use the radio menu F10 to consult the scores while running the mission. -- Scores can be reported for your user, or an overall score can be reported of all players currently active in the mission. -- +-- # 1) @{Scoring#SCORING} class, extends @{Base#BASE} +-- -- ## 1.1) Set the destroy score or penalty scale -- -- Score scales can be set for scores granted when enemies or friendlies are destroyed. @@ -86,8 +86,6 @@ -- For example, this can be done as follows: -- -- Scoring:RemoveUnitScore( UNIT:FindByName( "Unit #001" ) ) --- --- -- -- ## 1.3) Define destruction zones that will give extra scores. -- @@ -546,6 +544,7 @@ function SCORING:_AddPlayerFromUnit( UnitData ) local UnitCategory = UnitDesc.category local UnitCoalition = UnitData:GetCoalition() local UnitTypeName = UnitData:GetTypeName() + local UnitThreatLevel, UnitThreatType = UnitData:GetThreatLevel() self:T( { PlayerName, UnitName, UnitCategory, UnitCoalition, UnitTypeName } ) @@ -586,6 +585,8 @@ function SCORING:_AddPlayerFromUnit( UnitData ) self.Players[PlayerName].UnitCategory = UnitCategory self.Players[PlayerName].UnitType = UnitTypeName self.Players[PlayerName].UNIT = UnitData + self.Players[PlayerName].ThreatLevel = UnitThreatLevel + self.Players[PlayerName].ThreatType = UnitThreatType if self.Players[PlayerName].Penalty > self.Fratricide * 0.50 then if self.Players[PlayerName].PenaltyWarning < 1 then @@ -844,6 +845,7 @@ function SCORING:_EventOnHit( Event ) PlayerHit.PenaltyHit = PlayerHit.PenaltyHit or 0 PlayerHit.TimeStamp = PlayerHit.TimeStamp or 0 PlayerHit.UNIT = PlayerHit.UNIT or TargetUNIT + PlayerHit.ThreatLevel, PlayerHit.ThreatType = PlayerHit.UNIT:GetThreatLevel() -- Only grant hit scores if there was more than one second between the last hit. if timer.getTime() - PlayerHit.TimeStamp > 1 then @@ -882,7 +884,7 @@ function SCORING:_EventOnHit( Event ) :ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() ) :ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() ) end - self:ScoreCSV( InitPlayerName, TargetPlayerName, "HIT_PENALTY", 1, -25, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) + self:ScoreCSV( InitPlayerName, TargetPlayerName, "HIT_PENALTY", 1, -10, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) else Player.Score = Player.Score + 1 PlayerHit.Score = PlayerHit.Score + 1 @@ -915,7 +917,7 @@ function SCORING:_EventOnHit( Event ) ) :ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() ) :ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() ) - self:ScoreCSV( InitPlayerName, "", "HIT_SCORE", 1, 1, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, "", "Scenery", TargetUnitType ) + self:ScoreCSV( InitPlayerName, "", "HIT_SCORE", 1, 0, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, "", "Scenery", TargetUnitType ) end end end @@ -923,6 +925,89 @@ function SCORING:_EventOnHit( Event ) elseif InitPlayerName == nil then -- It is an AI hitting a player??? end + + -- It is a weapon initiated by a player, that is hitting something + -- This seems to occur only with scenery and static objects. + if Event.WeaponPlayerName ~= nil then + self:_AddPlayerFromUnit( Event.WeaponUNIT ) + if self.Players[Event.WeaponPlayerName] then -- This should normally not happen, but i'll test it anyway. + if TargetPlayerName ~= nil then -- It is a player hitting another player ... + self:_AddPlayerFromUnit( TargetUNIT ) + end + + self:T( "Hitting Scenery" ) + + -- What is he hitting? + if TargetCategory then + + -- A scenery or static got hit, score it. + -- Player contains the score data from self.Players[WeaponPlayerName] + local Player = self.Players[Event.WeaponPlayerName] + + -- Ensure there is a hit table per TargetCategory and TargetUnitName. + Player.Hit[TargetCategory] = Player.Hit[TargetCategory] or {} + Player.Hit[TargetCategory][TargetUnitName] = Player.Hit[TargetCategory][TargetUnitName] or {} + + -- PlayerHit contains the score counters and data per unit that was hit. + local PlayerHit = Player.Hit[TargetCategory][TargetUnitName] + + PlayerHit.Score = PlayerHit.Score or 0 + PlayerHit.Penalty = PlayerHit.Penalty or 0 + PlayerHit.ScoreHit = PlayerHit.ScoreHit or 0 + PlayerHit.PenaltyHit = PlayerHit.PenaltyHit or 0 + PlayerHit.TimeStamp = PlayerHit.TimeStamp or 0 + PlayerHit.UNIT = PlayerHit.UNIT or TargetUNIT + PlayerHit.ThreatLevel, PlayerHit.ThreatType = PlayerHit.UNIT:GetThreatLevel() + + -- Only grant hit scores if there was more than one second between the last hit. + if timer.getTime() - PlayerHit.TimeStamp > 1 then + PlayerHit.TimeStamp = timer.getTime() + + local Score = 0 + + if InitCoalition then -- A coalition object was hit, probably a static. + if InitCoalition == TargetCoalition then + -- TODO: Penalty according scale + Player.Penalty = Player.Penalty + 10 + PlayerHit.Penalty = PlayerHit.Penalty + 10 + PlayerHit.PenaltyHit = PlayerHit.PenaltyHit + 1 + + MESSAGE + :New( "Player '" .. Event.WeaponPlayerName .. "' hit a friendly target " .. + TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.PenaltyHit .. " times. " .. + "Penalty: -" .. PlayerHit.Penalty .. ". Score Total:" .. Player.Score - Player.Penalty, + 2 + ) + :ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() ) + :ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() ) + self:ScoreCSV( Event.WeaponPlayerName, TargetPlayerName, "HIT_PENALTY", 1, -10, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) + else + Player.Score = Player.Score + 1 + PlayerHit.Score = PlayerHit.Score + 1 + PlayerHit.ScoreHit = PlayerHit.ScoreHit + 1 + MESSAGE + :New( "Player '" .. Event.WeaponPlayerName .. "' hit an enemy target " .. + TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.ScoreHit .. " times. " .. + "Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty, + 2 + ) + :ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() ) + :ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() ) + self:ScoreCSV( Event.WeaponPlayerName, TargetPlayerName, "HIT_SCORE", 1, 1, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) + end + else -- A scenery object was hit. + MESSAGE + :New( "Player '" .. Event.WeaponPlayerName .. "' hit a scenery object.", + 2 + ) + :ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() ) + :ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() ) + self:ScoreCSV( Event.WeaponPlayerName, "", "HIT_SCORE", 1, 0, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, "", "Scenery", TargetUnitType ) + end + end + end + end + end end --- Track DEAD or CRASH events for the scoring. @@ -979,8 +1064,13 @@ function SCORING:_EventOnDeadOrCrash( Event ) self:T( { InitUnitName, InitUnitType, InitUnitCoalition, InitCoalition, InitUnitCategory, InitCategory } ) + local Destroyed = false + -- What is the player destroying? - if Player and Player.Hit and Player.Hit[TargetCategory] and Player.Hit[TargetCategory][TargetUnitName] then -- Was there a hit for this unit for this player before registered??? + if Player and Player.Hit and Player.Hit[TargetCategory] and Player.Hit[TargetCategory][TargetUnitName] and Player.Hit[TargetCategory][TargetUnitName].TimeStamp ~= 0 then -- Was there a hit for this unit for this player before registered??? + + local TargetThreatLevel = Player.Hit[TargetCategory][TargetUnitName].ThreatLevel + local TargetThreatType = Player.Hit[TargetCategory][TargetUnitName].ThreatType Player.Destroy[TargetCategory] = Player.Destroy[TargetCategory] or {} Player.Destroy[TargetCategory][TargetType] = Player.Destroy[TargetCategory][TargetType] or {} @@ -994,8 +1084,9 @@ function SCORING:_EventOnDeadOrCrash( Event ) if TargetCoalition then if InitCoalition == TargetCoalition then - local ThreatLevelTarget, ThreatTypeTarget = TargetUnit:GetThreatLevel() - local ThreatLevelPlayer = Player.UNIT:GetThreatLevel() / 10 + 1 + local ThreatLevelTarget = TargetThreatLevel + local ThreatTypeTarget = TargetThreatType + local ThreatLevelPlayer = Player.ThreatLevel / 10 + 1 local ThreatPenalty = math.ceil( ( ThreatLevelTarget / ThreatLevelPlayer ) * self.ScaleDestroyPenalty / 10 ) self:E( { ThreatLevel = ThreatPenalty, ThreatLevelTarget = ThreatLevelTarget, ThreatTypeTarget = ThreatTypeTarget, ThreatLevelPlayer = ThreatLevelPlayer } ) @@ -1023,11 +1114,13 @@ function SCORING:_EventOnDeadOrCrash( Event ) :ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() ) end + Destroyed = true self:ScoreCSV( PlayerName, TargetPlayerName, "DESTROY_PENALTY", 1, ThreatPenalty, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) else - local ThreatLevelTarget, ThreatTypeTarget = TargetUnit:GetThreatLevel() - local ThreatLevelPlayer = Player.UNIT:GetThreatLevel() / 10 + 1 + local ThreatLevelTarget = TargetThreatLevel + local ThreatTypeTarget = TargetThreatType + local ThreatLevelPlayer = Player.ThreatLevel / 10 + 1 local ThreatScore = math.ceil( ( ThreatLevelTarget / ThreatLevelPlayer ) * self.ScaleDestroyScore / 10 ) self:E( { ThreatLevel = ThreatScore, ThreatLevelTarget = ThreatLevelTarget, ThreatTypeTarget = ThreatTypeTarget, ThreatLevelPlayer = ThreatLevelPlayer } ) @@ -1054,6 +1147,7 @@ function SCORING:_EventOnDeadOrCrash( Event ) :ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() ) :ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() ) end + Destroyed = true self:ScoreCSV( PlayerName, TargetPlayerName, "DESTROY_SCORE", 1, ThreatScore, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) local UnitName = TargetUnit:GetName() @@ -1069,6 +1163,7 @@ function SCORING:_EventOnDeadOrCrash( Event ) :ToAllIf( self:IfMessagesScore() and self:IfMessagesToAll() ) :ToCoalitionIf( InitCoalition, self:IfMessagesScore() and self:IfMessagesToCoalition() ) self:ScoreCSV( PlayerName, TargetPlayerName, "DESTROY_SCORE", 1, Score, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) + Destroyed = true end -- Check if there are Zones where the destruction happened. @@ -1087,6 +1182,7 @@ function SCORING:_EventOnDeadOrCrash( Event ) :ToAllIf( self:IfMessagesZone() and self:IfMessagesToAll() ) :ToCoalitionIf( InitCoalition, self:IfMessagesZone() and self:IfMessagesToCoalition() ) self:ScoreCSV( PlayerName, TargetPlayerName, "DESTROY_SCORE", 1, Score, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) + Destroyed = true end end @@ -1108,10 +1204,18 @@ function SCORING:_EventOnDeadOrCrash( Event ) ) :ToAllIf( self:IfMessagesZone() and self:IfMessagesToAll() ) :ToCoalitionIf( InitCoalition, self:IfMessagesZone() and self:IfMessagesToCoalition() ) + Destroyed = true self:ScoreCSV( PlayerName, "", "DESTROY_SCORE", 1, Score, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, "", "Scenery", TargetUnitType ) end end end + + -- Delete now the hit cache if the target was destroyed. + -- Otherwise points will be granted every time a target gets killed by the players that hit that target. + -- This is only relevant for player to player destroys. + if Destroyed then + Player.Hit[TargetCategory][TargetUnitName].TimeStamp = 0 + end end end end diff --git a/Moose Development/Moose/Moose.lua b/Moose Development/Moose/Moose.lua index 0b7d4658b..fe1d1e2bf 100644 --- a/Moose Development/Moose/Moose.lua +++ b/Moose Development/Moose/Moose.lua @@ -17,6 +17,7 @@ Include.File( "Core/Set" ) Include.File( "Core/Point" ) Include.File( "Core/Message" ) Include.File( "Core/Fsm" ) +Include.File( "Core/Radio" ) --- Wrapper Classes Include.File( "Wrapper/Object" ) diff --git a/Moose Development/Moose/Wrapper/Client.lua b/Moose Development/Moose/Wrapper/Client.lua index 4d08b3fea..afab71f1d 100644 --- a/Moose Development/Moose/Wrapper/Client.lua +++ b/Moose Development/Moose/Wrapper/Client.lua @@ -73,7 +73,7 @@ CLIENT = { -- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() ) -- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() ) -- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() ) -function CLIENT:Find( DCSUnit ) +function CLIENT:Find( DCSUnit, Error ) local ClientName = DCSUnit:getName() local ClientFound = _DATABASE:FindClient( ClientName ) @@ -82,7 +82,9 @@ function CLIENT:Find( DCSUnit ) return ClientFound end - error( "CLIENT not found for: " .. ClientName ) + if not Error then + error( "CLIENT not found for: " .. ClientName ) + end end diff --git a/Moose Development/Moose/Wrapper/Positionable.lua b/Moose Development/Moose/Wrapper/Positionable.lua index 9be429b8f..e4cf24038 100644 --- a/Moose Development/Moose/Wrapper/Positionable.lua +++ b/Moose Development/Moose/Wrapper/Positionable.lua @@ -432,7 +432,11 @@ function POSITIONABLE:Message( Message, Duration, Name ) return nil end - - - - +--- Create a @{Radio#RADIO}, to allow radio transmission for this POSITIONABLE. +-- Set parameters with the methods provided, then use RADIO:Broadcast() to actually broadcast the message +-- @param #POSITIONABLE self +-- @return #RADIO Radio +function POSITIONABLE:GetRadio() + self:F2(self) + return RADIO:New(self) +end diff --git a/Moose Test Missions/RAD - Radio/RAD-000 - Transmission from Static/RAD-000 - Transmission from Static.lua b/Moose Test Missions/RAD - Radio/RAD-000 - Transmission from Static/RAD-000 - Transmission from Static.lua new file mode 100644 index 000000000..296604a1d --- /dev/null +++ b/Moose Test Missions/RAD - Radio/RAD-000 - Transmission from Static/RAD-000 - Transmission from Static.lua @@ -0,0 +1,19 @@ +-- This test mission demonstrates the RADIO class, particularily when the transmiter is anything but a UNIT or a GROUP (a STATIC in this case) +-- The Player is in a Su25T parked on Batumi, and a Russian command center named "Russian Command Center" is placed 12km east of Batumi. + +-- Note that if you are not using an ASM aircraft (a clickable cockpit aircraft), then the frequency and the modulation is not important. +-- If you want to test the mission fully, replance the SU25T by an ASM aircraft you own and tune to the right frequency (108AM here) + +CommandCenter = STATIC:FindByName("Russian Command Center") + +-- Let's get a reference to the Command Center's RADIO +CommandCenterRadio = CommandCenter:GetRadio() + +-- Now, we'll set up the next transmission +CommandCenterRadio:SetFileName("Noise.ogg") -- We first need the file name of a sound, +CommandCenterRadio:SetFrequency(108) -- then a frequency in MHz, +CommandCenterRadio:SetModulation(radio.modulation.AM) -- a modulation (we use DCS' enumartion, this way we don't have to type numbers)... +CommandCenterRadio:SetPower(100) -- and finally a power in Watts. A "normal" ground TACAN station has a power of 120W. + +-- We have finished tinkering with our transmission, now is the time to broadcast it ! +CommandCenterRadio:Broadcast() \ No newline at end of file diff --git a/Moose Test Missions/RAD - Radio/RAD-000 - Transmission from Static/RAD-000 - Transmission from Static.miz b/Moose Test Missions/RAD - Radio/RAD-000 - Transmission from Static/RAD-000 - Transmission from Static.miz new file mode 100644 index 000000000..76b15f06a Binary files /dev/null and b/Moose Test Missions/RAD - Radio/RAD-000 - Transmission from Static/RAD-000 - Transmission from Static.miz differ diff --git a/Moose Test Missions/RAD - Radio/RAD-001 - Transmission from UNIT or GROUP/RAD-001 - Transmission from UNIT or GROUP.lua b/Moose Test Missions/RAD - Radio/RAD-001 - Transmission from UNIT or GROUP/RAD-001 - Transmission from UNIT or GROUP.lua new file mode 100644 index 000000000..53b86eccb --- /dev/null +++ b/Moose Test Missions/RAD - Radio/RAD-001 - Transmission from UNIT or GROUP/RAD-001 - Transmission from UNIT or GROUP.lua @@ -0,0 +1,25 @@ +-- This test mission demonstrates the RADIO class, particularily when the transmiter is a UNIT or a GROUP +-- The Player is in a Su25T parked on Batumi, and a Russian MiG-29 creatively named "Sergey" is placed above Kobuleti and is +-- inbound for a landing on Batumi + +-- Note that if you are not using an ASM aircraft (a clickable cockpit aircraft), then the frequency and the modulation is not important. +-- If you want to test the mission fully, replance the SU25T by an ASM aircraft you own and tune to the right frequency (108AM here) + +Sergey = UNIT:FindByName("Sergey") + +-- Let's get a reference to Sergey's RADIO +SergeyRadio = Sergey:GetRadio() + +-- Now, we'll set up the next transmission +SergeyRadio:SetFileName("Noise.ogg") -- We first need the file name of a sound, +SergeyRadio:SetFrequency(108) -- then a frequency in MHz, +SergeyRadio:SetModulation(radio.modulation.AM) -- and a modulation (we use DCS' enumartion, this way we don't have to type numbers). + +-- Since Sergey is a UNIT, we can add a subtitle (displayed on the top left) to the transmission, and loop the transmission +SergeyRadio:SetSubtitle("Hey, hear that noise ?", 5) -- The subtitle "Noise" will be displayed for 5 secs +SergeyRadio:SetLoop(false) + +-- Notice that we didn't have to imput a power ? If the broadcater is a UNIT or a GROUP, DCS automatically guesses the power to use depending on the type of UNIT or GROUP + +-- We have finished tinkering with our transmission, now is the time to broadcast it ! +SergeyRadio:Broadcast() \ No newline at end of file diff --git a/Moose Test Missions/RAD - Radio/RAD-001 - Transmission from UNIT or GROUP/RAD-001 - Transmission from UNIT or GROUP.miz b/Moose Test Missions/RAD - Radio/RAD-001 - Transmission from UNIT or GROUP/RAD-001 - Transmission from UNIT or GROUP.miz new file mode 100644 index 000000000..eaca4159a Binary files /dev/null and b/Moose Test Missions/RAD - Radio/RAD-001 - Transmission from UNIT or GROUP/RAD-001 - Transmission from UNIT or GROUP.miz differ diff --git a/Moose Test Missions/RAD - Radio/RAD-002 - Transmission Tips and Tricks/RAD-002 - Transmission Tips and Tricks.lua b/Moose Test Missions/RAD - Radio/RAD-002 - Transmission Tips and Tricks/RAD-002 - Transmission Tips and Tricks.lua new file mode 100644 index 000000000..600036db5 --- /dev/null +++ b/Moose Test Missions/RAD - Radio/RAD-002 - Transmission Tips and Tricks/RAD-002 - Transmission Tips and Tricks.lua @@ -0,0 +1,91 @@ +-- This test mission demonstrates the RADIO class in a practical scenario. +-- It also focuses on how to create transmissions faster and more efficiently +-- Please Read both RAD-000 and RAD-001, as well as SCH-000 code first. + +-- Note that if you are not using an ASM aircraft (a clickable cockpit aircraft), then the frequency and the modulation is not important. +-- If you want to test the mission fully, replance the SU25T by an ASM aircraft you own and tune to the right frequency (115AM here) + +-- The Player is in a Su25T parked on Batumi, and a Russian command center named "Batumi Tower" placed near Batumi will act as Batumi's Radio Tower. +-- This mission also features the "Viktor" flight, a Russian Su25, who is inbound for landing on Batumi. +-- The goal of this script is to manage the dialog between Viktor and Batumi Tower. + +-- The (short) conversation between Viktor and Batumi Tower will happen on 115 AM +-- Time 0 : Batumi Tower "Viktor flight, this is Batumi Tower, enter left base runway one two five, report 5 kilometers final. Over." +-- Time 10 : Viktor "Report 5 kilometers final, one two five, viktor" +-- Time 145 : Viktor "Batumi Tower, Viktor is 5 kilomters final, request landing clearance. Over?" +-- Time 154 : Batumi Tower "Viktor flight, you are claer to land, runway one two five. Check gear down." +-- Time 160 : Viktor "Clear to land, One two five, Viktor" +-- Time 210 : Viktor "Viktor, touchdown" +-- Time 215 : Batumi Tower "Viktor, confirmed touchdown, taxi to parking area, Batumi Tower out." + + +BatumiRadio = STATIC:FindByName("Batumi Tower"):GetRadio() +ViktorRadio = UNIT:FindByName("Viktor"):GetRadio() + +-- Let's first explore different shortcuts to setup a transmission before broadcastiong it +------------------------------------------------------------------------------------------------------------------------------------------------------ +-- First, the long way. +BatumiRadio:SetFileName("Batumi Tower - Enter left base.ogg") +BatumiRadio:SetFrequency(115) +BatumiRadio:SetModulation(radio.modulation.AM) +BatumiRadio:SetPower(100) + +-- Every RADIO.SetXXX() function returns the radio, so we can rewrite the code above this way : +BatumiRadio:SetFileName("Batumi Tower - Enter left base.ogg"):SetFrequency(115):SetModulation(radio.modulation.AM):SetPower(100) + +-- We can also use the shortcut RADIO:NewGenericTransmission() to set multiple parameters in one function call +-- If our broadcaster was a UNIT or a GROUP, the more appropriate shortcut to use would have been NewUnitTransmission() +-- it works for both UNIT and GROUP, despite its name ! +BatumiRadio:NewGenericTransmission("Batumi Tower - Enter left base.ogg", 115, radio.modulation.AM, 100) + +-- If you already set some parameters previously, you don't have to redo it ! +-- NewGenericTransmission's paramter have to be set in order +BatumiRadio:NewGenericTransmission("Batumi Tower - Enter left base.ogg", 115) -- Modulation is still AM and power is still 100 (set previously) + +--If you want to change only the sound file, the frequency and the power for exemple, you can still use the appropriate Set function +BatumiRadio:NewGenericTransmission("Batumi Tower - Enter left base.ogg", 115):SetPower(100) + +-- We have finished tinkering with our transmission, now is the time to broadcast it ! +BatumiRadio:Broadcast() + +-- Now, if Viktor answered imedately, the two radio broadcasts would overlap. We need to delay Viktor's answer. +------------------------------------------------------------------------------------------------------------------------------------------------------ +SCHEDULER:New( nil, + function() + ViktorRadio:SetFileName("Viktor - Enter left base ack.ogg"):SetFrequency(115):SetModulation(radio.modulation.AM):Broadcast() -- We don't specify a subtitle since we don't want one + end, {}, 10 -- 10s delay + ) + +-- Viktor takes 145s to be 5km final, and need to contact Batumi Tower. +------------------------------------------------------------------------------------------------------------------------------------------------------ +SCHEDULER:New( nil, + function() + ViktorRadio:SetFileName("Viktor - Request landing clearance.ogg"):Broadcast() --We only specify the new file name, since frequency and modulation didn't change + end, {}, 145 + ) + +-- Now that you understand everything about the RADIO class, the rest is pretty trivial +------------------------------------------------------------------------------------------------------------------------------------------------------- +SCHEDULER:New( nil, + function() + BatumiRadio:SetFileName("Batumi Tower - Clear to land.ogg"):Broadcast() + end, {}, 154 + ) + +SCHEDULER:New( nil, + function() + ViktorRadio:SetFileName("Viktor - Clear to land ack.ogg"):Broadcast() + end, {}, 160 + ) + +SCHEDULER:New( nil, + function() + ViktorRadio:SetFileName("Viktor - Touchdown.ogg"):Broadcast() + end, {}, 210 + ) + +SCHEDULER:New( nil, + function() + BatumiRadio:SetFileName("Batumi Tower - Taxi to parking.ogg"):Broadcast() + end, {}, 215 + ) \ No newline at end of file diff --git a/Moose Test Missions/RAD - Radio/RAD-002 - Transmission Tips and Tricks/RAD-002 - Transmission Tips and Tricks.miz b/Moose Test Missions/RAD - Radio/RAD-002 - Transmission Tips and Tricks/RAD-002 - Transmission Tips and Tricks.miz new file mode 100644 index 000000000..de1730acd Binary files /dev/null and b/Moose Test Missions/RAD - Radio/RAD-002 - Transmission Tips and Tricks/RAD-002 - Transmission Tips and Tricks.miz differ diff --git a/Moose Test Missions/SCO - Scoring/SCO-100 - Scoring of Statics/SCO-100 - Scoring of Statics.miz b/Moose Test Missions/SCO - Scoring/SCO-100 - Scoring of Statics/SCO-100 - Scoring of Statics.miz index d3ae3638f..8dcf03ff6 100644 Binary files a/Moose Test Missions/SCO - Scoring/SCO-100 - Scoring of Statics/SCO-100 - Scoring of Statics.miz and b/Moose Test Missions/SCO - Scoring/SCO-100 - Scoring of Statics/SCO-100 - Scoring of Statics.miz differ diff --git a/Moose Test Missions/SCO - Scoring/SCO-101 - Scoring Client to Client/SCO-101 - Scoring Client to Client.miz b/Moose Test Missions/SCO - Scoring/SCO-101 - Scoring Client to Client/SCO-101 - Scoring Client to Client.miz index 35cb34750..e38609bf5 100644 Binary files a/Moose Test Missions/SCO - Scoring/SCO-101 - Scoring Client to Client/SCO-101 - Scoring Client to Client.miz and b/Moose Test Missions/SCO - Scoring/SCO-101 - Scoring Client to Client/SCO-101 - Scoring Client to Client.miz differ diff --git a/Moose Test Missions/SCO - Scoring/SCO-500 - Scoring Multi Player Demo Mission 1/SCO-500 - Scoring Multi Player Demo Mission 1.miz b/Moose Test Missions/SCO - Scoring/SCO-500 - Scoring Multi Player Demo Mission 1/SCO-500 - Scoring Multi Player Demo Mission 1.miz index 0f7c7b374..f518c0537 100644 Binary files a/Moose Test Missions/SCO - Scoring/SCO-500 - Scoring Multi Player Demo Mission 1/SCO-500 - Scoring Multi Player Demo Mission 1.miz and b/Moose Test Missions/SCO - Scoring/SCO-500 - Scoring Multi Player Demo Mission 1/SCO-500 - Scoring Multi Player Demo Mission 1.miz differ diff --git a/Moose Test Missions/TAD - Task Dispatching/TAD-010 - A2G Task Dispatching Destroy Test/TAD-010 - A2G Task Dispatching Destroy Test.miz b/Moose Test Missions/TAD - Task Dispatching/TAD-010 - A2G Task Dispatching Destroy Test/TAD-010 - A2G Task Dispatching Destroy Test.miz index 305feef0d..2b8731c9e 100644 Binary files a/Moose Test Missions/TAD - Task Dispatching/TAD-010 - A2G Task Dispatching Destroy Test/TAD-010 - A2G Task Dispatching Destroy Test.miz and b/Moose Test Missions/TAD - Task Dispatching/TAD-010 - A2G Task Dispatching Destroy Test/TAD-010 - A2G Task Dispatching Destroy Test.miz differ diff --git a/Moose Test Missions/TAD - Task Dispatching/TAD-100 - A2G Task Dispatching DETECTION_AREAS/TAD-100 - A2G Task Dispatching DETECTION_AREAS.miz b/Moose Test Missions/TAD - Task Dispatching/TAD-100 - A2G Task Dispatching DETECTION_AREAS/TAD-100 - A2G Task Dispatching DETECTION_AREAS.miz index 0bb8becc6..5b09ac86a 100644 Binary files a/Moose Test Missions/TAD - Task Dispatching/TAD-100 - A2G Task Dispatching DETECTION_AREAS/TAD-100 - A2G Task Dispatching DETECTION_AREAS.miz and b/Moose Test Missions/TAD - Task Dispatching/TAD-100 - A2G Task Dispatching DETECTION_AREAS/TAD-100 - A2G Task Dispatching DETECTION_AREAS.miz differ diff --git a/Moose Test Missions/TAD - Task Dispatching/TAD-105 - A2G Task Dispatching DETECTION_AREAS/TAD-105 - A2G Task Dispatching DETECTION_AREAS.miz b/Moose Test Missions/TAD - Task Dispatching/TAD-105 - A2G Task Dispatching DETECTION_AREAS/TAD-105 - A2G Task Dispatching DETECTION_AREAS.miz index 4210bea55..4d38f78f5 100644 Binary files a/Moose Test Missions/TAD - Task Dispatching/TAD-105 - A2G Task Dispatching DETECTION_AREAS/TAD-105 - A2G Task Dispatching DETECTION_AREAS.miz and b/Moose Test Missions/TAD - Task Dispatching/TAD-105 - A2G Task Dispatching DETECTION_AREAS/TAD-105 - A2G Task Dispatching DETECTION_AREAS.miz differ diff --git a/Moose Test Missions/TAD - Task Dispatching/TAD-110 - A2G Task Dispatching DETECTION_TYPES/TAD-110 - A2G Task Dispatching DETECTION_TYPES.miz b/Moose Test Missions/TAD - Task Dispatching/TAD-110 - A2G Task Dispatching DETECTION_TYPES/TAD-110 - A2G Task Dispatching DETECTION_TYPES.miz index 4827922e7..a217fa731 100644 Binary files a/Moose Test Missions/TAD - Task Dispatching/TAD-110 - A2G Task Dispatching DETECTION_TYPES/TAD-110 - A2G Task Dispatching DETECTION_TYPES.miz and b/Moose Test Missions/TAD - Task Dispatching/TAD-110 - A2G Task Dispatching DETECTION_TYPES/TAD-110 - A2G Task Dispatching DETECTION_TYPES.miz differ diff --git a/Moose Test Missions/TAD - Task Dispatching/TAD-120 - A2G Task Dispatching DETECTION_UNITS/TAD-120 - A2G Task Dispatching DETECTION_UNITS.miz b/Moose Test Missions/TAD - Task Dispatching/TAD-120 - A2G Task Dispatching DETECTION_UNITS/TAD-120 - A2G Task Dispatching DETECTION_UNITS.miz index fb98865fc..f986b58dc 100644 Binary files a/Moose Test Missions/TAD - Task Dispatching/TAD-120 - A2G Task Dispatching DETECTION_UNITS/TAD-120 - A2G Task Dispatching DETECTION_UNITS.miz and b/Moose Test Missions/TAD - Task Dispatching/TAD-120 - A2G Task Dispatching DETECTION_UNITS/TAD-120 - A2G Task Dispatching DETECTION_UNITS.miz differ diff --git a/Moose Test Missions/TAD - Task Dispatching/TAD-200 - A2G Task Dispatching with SCORING/TAD-200 - A2G Task Dispatching with SCORING.miz b/Moose Test Missions/TAD - Task Dispatching/TAD-200 - A2G Task Dispatching with SCORING/TAD-200 - A2G Task Dispatching with SCORING.miz index c17d5e8df..e0bbd04af 100644 Binary files a/Moose Test Missions/TAD - Task Dispatching/TAD-200 - A2G Task Dispatching with SCORING/TAD-200 - A2G Task Dispatching with SCORING.miz and b/Moose Test Missions/TAD - Task Dispatching/TAD-200 - A2G Task Dispatching with SCORING/TAD-200 - A2G Task Dispatching with SCORING.miz differ diff --git a/Moose Test Missions/TAD - Task Dispatching/TAD-210 - A2G Task Dispatching per AREAS and SCORING/TAD-210 - A2G Task Dispatching per AREAS and SCORING.miz b/Moose Test Missions/TAD - Task Dispatching/TAD-210 - A2G Task Dispatching per AREAS and SCORING/TAD-210 - A2G Task Dispatching per AREAS and SCORING.miz index b82f55eca..76f3baa6e 100644 Binary files a/Moose Test Missions/TAD - Task Dispatching/TAD-210 - A2G Task Dispatching per AREAS and SCORING/TAD-210 - A2G Task Dispatching per AREAS and SCORING.miz and b/Moose Test Missions/TAD - Task Dispatching/TAD-210 - A2G Task Dispatching per AREAS and SCORING/TAD-210 - A2G Task Dispatching per AREAS and SCORING.miz differ diff --git a/Moose Test Missions/TAD - Task Dispatching/TAD-220 - A2G Task Dispatching per TYPE and SCORING/TAD-220 - A2G Task Dispatching per TYPE and SCORING.miz b/Moose Test Missions/TAD - Task Dispatching/TAD-220 - A2G Task Dispatching per TYPE and SCORING/TAD-220 - A2G Task Dispatching per TYPE and SCORING.miz index a9de6f0bf..41426668e 100644 Binary files a/Moose Test Missions/TAD - Task Dispatching/TAD-220 - A2G Task Dispatching per TYPE and SCORING/TAD-220 - A2G Task Dispatching per TYPE and SCORING.miz and b/Moose Test Missions/TAD - Task Dispatching/TAD-220 - A2G Task Dispatching per TYPE and SCORING/TAD-220 - A2G Task Dispatching per TYPE and SCORING.miz differ diff --git a/docs/Documentation/AI_Balancer.html b/docs/Documentation/AI_Balancer.html index c5b24c824..2b5f48f01 100644 --- a/docs/Documentation/AI_Balancer.html +++ b/docs/Documentation/AI_Balancer.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/AI_Cap.html b/docs/Documentation/AI_Cap.html index 2d9f1947a..b8571c7fd 100644 --- a/docs/Documentation/AI_Cap.html +++ b/docs/Documentation/AI_Cap.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/AI_Cas.html b/docs/Documentation/AI_Cas.html index be5f59f41..42ebf942e 100644 --- a/docs/Documentation/AI_Cas.html +++ b/docs/Documentation/AI_Cas.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/AI_Patrol.html b/docs/Documentation/AI_Patrol.html index dfe052794..e54ea6cf5 100644 --- a/docs/Documentation/AI_Patrol.html +++ b/docs/Documentation/AI_Patrol.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Account.html b/docs/Documentation/Account.html index e57572897..ad23ec3ca 100644 --- a/docs/Documentation/Account.html +++ b/docs/Documentation/Account.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Airbase.html b/docs/Documentation/Airbase.html index 6410f78fd..328b41564 100644 --- a/docs/Documentation/Airbase.html +++ b/docs/Documentation/Airbase.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/AirbasePolice.html b/docs/Documentation/AirbasePolice.html index c123060d6..93fdd0ae2 100644 --- a/docs/Documentation/AirbasePolice.html +++ b/docs/Documentation/AirbasePolice.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Assign.html b/docs/Documentation/Assign.html index 5b47c54ca..e352ed51e 100644 --- a/docs/Documentation/Assign.html +++ b/docs/Documentation/Assign.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Cargo.html b/docs/Documentation/Cargo.html index f3bcbd277..e522dd17f 100644 --- a/docs/Documentation/Cargo.html +++ b/docs/Documentation/Cargo.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/CleanUp.html b/docs/Documentation/CleanUp.html index b25737cbe..60829d2bc 100644 --- a/docs/Documentation/CleanUp.html +++ b/docs/Documentation/CleanUp.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Client.html b/docs/Documentation/Client.html index 81cdc7555..bd0f23bb2 100644 --- a/docs/Documentation/Client.html +++ b/docs/Documentation/Client.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/CommandCenter.html b/docs/Documentation/CommandCenter.html index 66094f398..3384b0fa4 100644 --- a/docs/Documentation/CommandCenter.html +++ b/docs/Documentation/CommandCenter.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Controllable.html b/docs/Documentation/Controllable.html index 51a3ecde6..5c1ba178a 100644 --- a/docs/Documentation/Controllable.html +++ b/docs/Documentation/Controllable.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Database.html b/docs/Documentation/Database.html index 4edfad744..0309494e8 100644 --- a/docs/Documentation/Database.html +++ b/docs/Documentation/Database.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Detection.html b/docs/Documentation/Detection.html index 193f1b55a..64ac45ee0 100644 --- a/docs/Documentation/Detection.html +++ b/docs/Documentation/Detection.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/DetectionManager.html b/docs/Documentation/DetectionManager.html index e968ee9b0..e31707159 100644 --- a/docs/Documentation/DetectionManager.html +++ b/docs/Documentation/DetectionManager.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Escort.html b/docs/Documentation/Escort.html index b3a03693c..d2890d3e0 100644 --- a/docs/Documentation/Escort.html +++ b/docs/Documentation/Escort.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Event.html b/docs/Documentation/Event.html index aa688f7c1..19fb2f047 100644 --- a/docs/Documentation/Event.html +++ b/docs/Documentation/Event.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Fsm.html b/docs/Documentation/Fsm.html index 92c994f6b..02ff1ee96 100644 --- a/docs/Documentation/Fsm.html +++ b/docs/Documentation/Fsm.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Group.html b/docs/Documentation/Group.html index c957c67c5..3e152da95 100644 --- a/docs/Documentation/Group.html +++ b/docs/Documentation/Group.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Identifiable.html b/docs/Documentation/Identifiable.html index 919816a08..338914a14 100644 --- a/docs/Documentation/Identifiable.html +++ b/docs/Documentation/Identifiable.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/MOVEMENT.html b/docs/Documentation/MOVEMENT.html index f81accb1c..2ec03bdbd 100644 --- a/docs/Documentation/MOVEMENT.html +++ b/docs/Documentation/MOVEMENT.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Menu.html b/docs/Documentation/Menu.html index 29a7ed739..898011d4b 100644 --- a/docs/Documentation/Menu.html +++ b/docs/Documentation/Menu.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Message.html b/docs/Documentation/Message.html index 935b571f5..db044781f 100644 --- a/docs/Documentation/Message.html +++ b/docs/Documentation/Message.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/MissileTrainer.html b/docs/Documentation/MissileTrainer.html index 735bef024..028f28dff 100644 --- a/docs/Documentation/MissileTrainer.html +++ b/docs/Documentation/MissileTrainer.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Mission.html b/docs/Documentation/Mission.html index ee06d4ddb..bb21a844f 100644 --- a/docs/Documentation/Mission.html +++ b/docs/Documentation/Mission.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Object.html b/docs/Documentation/Object.html index 99c3c8465..cb8608218 100644 --- a/docs/Documentation/Object.html +++ b/docs/Documentation/Object.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Point.html b/docs/Documentation/Point.html index d62614444..b1b50b793 100644 --- a/docs/Documentation/Point.html +++ b/docs/Documentation/Point.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Positionable.html b/docs/Documentation/Positionable.html index 0fbf409de..6ac05da3e 100644 --- a/docs/Documentation/Positionable.html +++ b/docs/Documentation/Positionable.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • @@ -164,6 +165,12 @@ POSITIONABLE:GetPositionVec3()

    Returns the DCSTypes#Position3 position vectors indicating the point and direction vectors in 3D of the POSITIONABLE within the mission.

    + + + + POSITIONABLE:GetRadio() + +

    Create a Radio#RADIO, to allow radio transmission for this POSITIONABLE.

    @@ -491,6 +498,27 @@ The POSITIONABLE is not existing or alive.

    + +POSITIONABLE:GetRadio() + +
    +
    + +

    Create a Radio#RADIO, to allow radio transmission for this POSITIONABLE.

    + + +

    Set parameters with the methods provided, then use RADIO:Broadcast() to actually broadcast the message

    + +

    Return value

    + +

    #RADIO: +Radio

    + +
    +
    +
    +
    + POSITIONABLE:GetRandomVec3(Radius) @@ -1014,6 +1042,8 @@ self

    +

    Type RADIO

    + diff --git a/docs/Documentation/Process_JTAC.html b/docs/Documentation/Process_JTAC.html index a6f640ee1..92c909e8f 100644 --- a/docs/Documentation/Process_JTAC.html +++ b/docs/Documentation/Process_JTAC.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Process_Pickup.html b/docs/Documentation/Process_Pickup.html index 7738af995..a031bed16 100644 --- a/docs/Documentation/Process_Pickup.html +++ b/docs/Documentation/Process_Pickup.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Radio.html b/docs/Documentation/Radio.html new file mode 100644 index 000000000..1046d3a15 --- /dev/null +++ b/docs/Documentation/Radio.html @@ -0,0 +1,803 @@ + + + + + + +
    +
    + +
    +
    +
    +
    + +
    +

    Module Radio

    + +

    Core - The RADIO class is responsible for transmitting radio communications.

    + + + +

    --- bitmap

    + +
    + +

    What are radio communications in DCS ?

    + +
      +
    • Radio transmissions consist of sound files that are broadcasted on a specific frequency (e.g. 115MHz) and modulation (e.g. AM),
    • +
    • They can be subtitled for a specific duration, the power in Watts of the transmiter's antenna can be set, and the transmission can be looped.
    • +
    + +

    How to supply DCS my own Sound Files ?

    + +
      +
    • Your sound files need to be encoded in .ogg or .wav,
    • +
    • Your sound files should be as tiny as possible. It is suggested you encode in .ogg with low bitrate and sampling settings,
    • +
    • They need to be added in .\l10n\DEFAULT\ in you .miz file (wich can be decompressed like a .zip file),
    • +
    • For simplicty sake, you can let DCS' Mission Editor add the file itself, by creating a new Trigger with the action "Sound to Country", and choosing your sound file and a country you don't use in your mission.
    • +
    + +

    Due to weird DCS quirks, radio communications behave differently if sent by a Unit#UNIT or a Group#GROUP or by any other Positionable#POSITIONABLE

    + + + +

    Note that obviously, the frequency and the modulation of the transmission are important only if the players are piloting an Advanced System Modelling enabled aircraft, +like the A10C or the Mirage 2000C. They will hear the transmission if they are tuned on the right frequency and modulation (and if they are close enough - more on that below). +If a FC3 airacraft is used, it will hear every communication, whatever the frequency and the modulation is set to.

    + +
    + +

    Authors: Hugues "Grey_Echo" Bousquet

    + + +

    Global(s)

    + + + + + +
    RADIO + +
    +

    Type RADIO

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    RADIO:Broadcast() +

    Actually Broadcast the transmission

    +
    RADIO.ClassName + +
    RADIO.FileName +

    Name of the sound file

    +
    RADIO.Frequency +

    Frequency of the transmission in Hz

    +
    RADIO.Loop + +
    RADIO.Modulation +

    Modulation of the transmission (either radio.modulation.AM or radio.modulation.FM)

    +
    RADIO:New(Positionable) +

    Create a new RADIO Object.

    +
    RADIO:NewGenericTransmission(Filename, Frequency, Modulation, Power, ...) +

    Create a new transmission, that is to say, populate the RADIO with relevant data

    +
    RADIO:NewUnitTransmission(Filename, Subtitle, SubtitleDuration, Frequency, Modulation, Loop, ...) +

    Create a new transmission, that is to say, populate the RADIO with relevant data

    +
    RADIO.Positionable +

    The transmiter

    +
    RADIO.Power +

    Power of the antenna is Watts

    +
    RADIO:SetFileName(FileName) +

    Check validity of the filename passed and sets RADIO.FileName

    +
    RADIO:SetFrequency(Frequency) +

    Check validity of the frequency passed and sets RADIO.Frequency

    +
    RADIO:SetLoop(Loop) +

    Check validity of the loop passed and sets RADIO.Loop

    +
    RADIO:SetModulation(Modulation) +

    Check validity of the frequency passed and sets RADIO.Modulation

    +
    RADIO:SetPower(Power) +

    Check validity of the power passed and sets RADIO.Power

    +
    RADIO:SetSubtitle(SubTitle, SubTitleDuration) +

    Check validity of the subtitle and the subtitleDuration passed and sets RADIO.subtitle and RADIO.subtitleDuration

    +
    RADIO.Subtitle +

    Subtitle of the transmission

    +
    RADIO.SubtitleDuration +

    Duration of the Subtitle in seconds

    +
    + +

    Global(s)

    +
    +
    + + #RADIO + +RADIO + +
    +
    + + + +
    +
    +

    Type Radio

    + +

    Type RADIO

    + +

    1) RADIO class, extends Base#BASE

    + +

    1.1) RADIO usage

    + +

    There are 3 steps to a successful radio transmission.

    + + + + + +

    Methods to set relevant parameters for both a Unit#UNIT or a Group#GROUP or any other Positionable#POSITIONABLE

    + + + +

    Additional Methods to set relevant parameters if the transmiter is a Unit#UNIT or a Group#GROUP

    + + + +

    Additional Methods to set relevant parameters if the transmiter is any other Wrapper.Positionable#POSITIONABLE

    + + + +

    What is this power thing ?

    + +
      +
    • If your transmission is sent by a Positionable#POSITIONABLE other than a Unit#UNIT or a Group#GROUP, you can set the power of the antenna,
    • +
    • Otherwise, DCS sets it automatically, depending on what's available on your Unit,
    • +
    • If the player gets too far from the transmiter, or if the antenna is too weak, the transmission will fade and become noisyer,
    • +
    • This an automated DCS calculation you have no say on,
    • +
    • For reference, a standard VOR station has a 100W antenna, a standard AA TACAN has a 120W antenna, and civilian ATC's antenna usually range between 300 and 500W,
    • +
    • Note that if the transmission has a subtitle, it will be readable, regardless of the quality of the transmission. +
    • +
    + +

    Field(s)

    +
    +
    + + +RADIO:Broadcast() + +
    +
    + +

    Actually Broadcast the transmission

    + +

    Return value

    + +

    #RADIO: +self

    + +

    Usage:

    +
    -- The Radio has to be populated with the new transmission before broadcasting.
    +-- Please use RADIO setters or either @{Radio#RADIO.NewGenericTransmission} or @{Radio#RADIO.NewUnitTransmission}
    +-- This class is in fact pretty smart, it determines the right DCS function to use depending on the type of POSITIONABLE
    +-- If the POSITIONABLE is not a UNIT or a GROUP, we use the generic (but limited) trigger.action.radioTransmission()
    +-- If the POSITIONABLE is a UNIT or a GROUP, we use the "TransmitMessage" Command
    +-- If your POSITIONABLE is a UNIT or a GROUP, the Power is ignored.
    +-- If your POSITIONABLE is not a UNIT or a GROUP, the Subtitle, SubtitleDuration and Loop are ignored
    + +
    +
    +
    +
    + + #string + +RADIO.ClassName + +
    +
    + + + +
    +
    +
    +
    + + #string + +RADIO.FileName + +
    +
    + +

    Name of the sound file

    + +
    +
    +
    +
    + + #number + +RADIO.Frequency + +
    +
    + +

    Frequency of the transmission in Hz

    + +
    +
    +
    +
    + + #boolean + +RADIO.Loop + +
    +
    + + + +
    +
    +
    +
    + + #number + +RADIO.Modulation + +
    +
    + +

    Modulation of the transmission (either radio.modulation.AM or radio.modulation.FM)

    + +
    +
    +
    +
    + + +RADIO:New(Positionable) + +
    +
    + +

    Create a new RADIO Object.

    + + +

    This doesn't broadcast a transmission, though, use RADIO.Broadcast to actually broadcast

    + +

    Parameter

    + +

    Return values

    +
      +
    1. + +

      #RADIO: +Radio

      + +
    2. +
    3. + +

      #nil: +If Positionable is invalid

      + +
    4. +
    +

    Usage:

    +
    -- If you want to create a RADIO, you probably should use @{Positionable#POSITIONABLE.GetRadio}() instead
    + +
    +
    +
    +
    + + +RADIO:NewGenericTransmission(Filename, Frequency, Modulation, Power, ...) + +
    +
    + +

    Create a new transmission, that is to say, populate the RADIO with relevant data

    + +

    Parameters

    +
      +
    • + +

      #string Filename :

      + +
    • +
    • + +

      #number Frequency : +in MHz

      + +
    • +
    • + +

      #number Modulation : +either radio.modulation.AM or radio.modulation.FM

      + +
    • +
    • + +

      #number Power : +in W

      + +
    • +
    • + +

      ... :

      + +
    • +
    +

    Return value

    + +

    #RADIO: +self

    + +

    Usage:

    +
    -- In this function the data is especially relevant if the broadcaster is anything but a UNIT or a GROUP,
    +but it will work with a UNIT or a GROUP anyway
    +-- Only the RADIO and the Filename are mandatory
    + +
    +
    +
    +
    + + +RADIO:NewUnitTransmission(Filename, Subtitle, SubtitleDuration, Frequency, Modulation, Loop, ...) + +
    +
    + +

    Create a new transmission, that is to say, populate the RADIO with relevant data

    + +

    Parameters

    +
      +
    • + +

      #string Filename :

      + +
    • +
    • + +

      #string Subtitle :

      + +
    • +
    • + +

      #number SubtitleDuration : +in s

      + +
    • +
    • + +

      #number Frequency : +in MHz

      + +
    • +
    • + +

      #number Modulation : +either radio.modulation.AM or radio.modulation.FM

      + +
    • +
    • + +

      #boolean Loop :

      + +
    • +
    • + +

      ... :

      + +
    • +
    +

    Return value

    + +

    #RADIO: +self

    + +

    Usage:

    +
    -- In this function the data is especially relevant if the broadcaster is a UNIT or a GROUP,
    +but it will work for any POSITIONABLE
    +-- Only the RADIO and the Filename are mandatory
    + +
    +
    +
    +
    + + Wrapper.Positionable#POSITIONABLE + +RADIO.Positionable + +
    +
    + +

    The transmiter

    + +
    +
    +
    +
    + + #number + +RADIO.Power + +
    +
    + +

    Power of the antenna is Watts

    + +
    +
    +
    +
    + + +RADIO:SetFileName(FileName) + +
    +
    + +

    Check validity of the filename passed and sets RADIO.FileName

    + +

    Parameter

    +
      +
    • + +

      #string FileName : +File name of the sound file (i.e. "Noise.ogg")

      + +
    • +
    +

    Return value

    + +

    #RADIO: +self

    + +
    +
    +
    +
    + + +RADIO:SetFrequency(Frequency) + +
    +
    + +

    Check validity of the frequency passed and sets RADIO.Frequency

    + +

    Parameter

    +
      +
    • + +

      #number Frequency : +in MHz (Ranges allowed for radio transmissions in DCS : 30-88 / 108-152 / 225-400MHz)

      + +
    • +
    +

    Return value

    + +

    #RADIO: +self

    + +
    +
    +
    +
    + + +RADIO:SetLoop(Loop) + +
    +
    + +

    Check validity of the loop passed and sets RADIO.Loop

    + +

    Parameter

    +
      +
    • + +

      #boolean Loop :

      + +
    • +
    +

    Return value

    + +

    #RADIO: +self

    + +

    Usage:

    +
    + +
    +
    +
    +
    + + +RADIO:SetModulation(Modulation) + +
    +
    + +

    Check validity of the frequency passed and sets RADIO.Modulation

    + +

    Parameter

    +
      +
    • + +

      #number Modulation : +either radio.modulation.AM or radio.modulation.FM

      + +
    • +
    +

    Return value

    + +

    #RADIO: +self

    + +
    +
    +
    +
    + + +RADIO:SetPower(Power) + +
    +
    + +

    Check validity of the power passed and sets RADIO.Power

    + +

    Parameter

    +
      +
    • + +

      #number Power : +in W

      + +
    • +
    +

    Return value

    + +

    #RADIO: +self

    + +
    +
    +
    +
    + + +RADIO:SetSubtitle(SubTitle, SubTitleDuration) + +
    +
    + +

    Check validity of the subtitle and the subtitleDuration passed and sets RADIO.subtitle and RADIO.subtitleDuration

    + +

    Parameters

    +
      +
    • + +

      #string SubTitle :

      + +
    • +
    • + +

      #number SubTitleDuration : +in s

      + +
    • +
    +

    Return value

    + +

    #RADIO: +self

    + +

    Usage:

    +
    -- Both parameters are mandatory, since it wouldn't make much sense to change the Subtitle and not its duration
    + +
    +
    +
    +
    + + #string + +RADIO.Subtitle + +
    +
    + +

    Subtitle of the transmission

    + +
    +
    +
    +
    + + #number + +RADIO.SubtitleDuration + +
    +
    + +

    Duration of the Subtitle in seconds

    + +
    +
    + +
    + +
    + + diff --git a/docs/Documentation/Route.html b/docs/Documentation/Route.html index 7a204a4c5..8d2ec52ea 100644 --- a/docs/Documentation/Route.html +++ b/docs/Documentation/Route.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Scenery.html b/docs/Documentation/Scenery.html index b9e8b4a3d..84704e530 100644 --- a/docs/Documentation/Scenery.html +++ b/docs/Documentation/Scenery.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/ScheduleDispatcher.html b/docs/Documentation/ScheduleDispatcher.html index c2bc197cc..887ea6292 100644 --- a/docs/Documentation/ScheduleDispatcher.html +++ b/docs/Documentation/ScheduleDispatcher.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Scheduler.html b/docs/Documentation/Scheduler.html index a975d1109..b8e42d2bb 100644 --- a/docs/Documentation/Scheduler.html +++ b/docs/Documentation/Scheduler.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Scoring.html b/docs/Documentation/Scoring.html index c869150bd..38fdb4cc8 100644 --- a/docs/Documentation/Scoring.html +++ b/docs/Documentation/Scoring.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Sead.html b/docs/Documentation/Sead.html index d2afd1e92..12a877b80 100644 --- a/docs/Documentation/Sead.html +++ b/docs/Documentation/Sead.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Set.html b/docs/Documentation/Set.html index 0f35628fd..cd519f39c 100644 --- a/docs/Documentation/Set.html +++ b/docs/Documentation/Set.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Smoke.html b/docs/Documentation/Smoke.html index f21743f78..f91a5703f 100644 --- a/docs/Documentation/Smoke.html +++ b/docs/Documentation/Smoke.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Spawn.html b/docs/Documentation/Spawn.html index b9f9cb7db..5a1b23f25 100644 --- a/docs/Documentation/Spawn.html +++ b/docs/Documentation/Spawn.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • @@ -1870,9 +1871,6 @@ The group that was spawned. You can use this group for further actions.

    - -

    Don't repeat the group from Take-Off till Landing and back Take-Off by ReSpawning.

    -
    diff --git a/docs/Documentation/Static.html b/docs/Documentation/Static.html index ebd47c91e..ff176e054 100644 --- a/docs/Documentation/Static.html +++ b/docs/Documentation/Static.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Task.html b/docs/Documentation/Task.html index 05b4eba8a..f2a503a07 100644 --- a/docs/Documentation/Task.html +++ b/docs/Documentation/Task.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Task_A2G.html b/docs/Documentation/Task_A2G.html index ae2b00495..46c91e395 100644 --- a/docs/Documentation/Task_A2G.html +++ b/docs/Documentation/Task_A2G.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Task_PICKUP.html b/docs/Documentation/Task_PICKUP.html index 3cd5f394a..fe83f60db 100644 --- a/docs/Documentation/Task_PICKUP.html +++ b/docs/Documentation/Task_PICKUP.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Task_SEAD.html b/docs/Documentation/Task_SEAD.html index b4befe7f4..a998527ee 100644 --- a/docs/Documentation/Task_SEAD.html +++ b/docs/Documentation/Task_SEAD.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Unit.html b/docs/Documentation/Unit.html index c87b8a3e7..269364c6c 100644 --- a/docs/Documentation/Unit.html +++ b/docs/Documentation/Unit.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/Utils.html b/docs/Documentation/Utils.html index ca23f3aa4..59585ad25 100644 --- a/docs/Documentation/Utils.html +++ b/docs/Documentation/Utils.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • diff --git a/docs/Documentation/index.html b/docs/Documentation/index.html index 76cf0ddb4..07f2692db 100644 --- a/docs/Documentation/index.html +++ b/docs/Documentation/index.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher
  • @@ -310,6 +311,12 @@ are design patterns allowing efficient (long-lasting) processes and workflows.Process_Pickup + + + + Radio + +

    Core - The RADIO class is responsible for transmitting radio communications.

    diff --git a/docs/Documentation/routines.html b/docs/Documentation/routines.html index 70d5e3c47..c2949d324 100644 --- a/docs/Documentation/routines.html +++ b/docs/Documentation/routines.html @@ -49,6 +49,7 @@
  • Positionable
  • Process_JTAC
  • Process_Pickup
  • +
  • Radio
  • Route
  • Scenery
  • ScheduleDispatcher