From 5ee1f5d3afd8f7d357c749624cd2e33c66fc076c Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sun, 10 Apr 2022 09:28:38 +0200 Subject: [PATCH 01/13] CSAR/AICSAR - added port options for SRS --- Moose Development/Moose/Functional/AICSAR.lua | 11 ++++++++--- Moose Development/Moose/Ops/CSAR.lua | 5 ++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Moose Development/Moose/Functional/AICSAR.lua b/Moose Development/Moose/Functional/AICSAR.lua index 8d79999e5..ef8d154f6 100644 --- a/Moose Development/Moose/Functional/AICSAR.lua +++ b/Moose Development/Moose/Functional/AICSAR.lua @@ -145,7 +145,7 @@ -- -- Switch on radio transmissions via **either** SRS **or** "normal" DCS radio e.g. like so: -- --- my_aicsar:SetSRSRadio(true,"C:\\Program Files\\DCS-SimpleRadio-Standalone",270,radio.modulation.AM) +-- my_aicsar:SetSRSRadio(true,"C:\\Program Files\\DCS-SimpleRadio-Standalone",270,radio.modulation.AM,5002) -- -- or -- @@ -159,7 +159,7 @@ -- @field #AICSAR AICSAR = { ClassName = "AICSAR", - version = "0.0.5", + version = "0.0.6", lid = "", coalition = coalition.side.BLUE, template = "", @@ -183,6 +183,7 @@ AICSAR = { SRSPath = "\\", SRSModulation = radio.modulation.AM, SRSSoundPath = nil, -- defaults to "l10n/DEFAULT/", i.e. add messages via "Sount to..." in the ME + SRSPort = 5002, DCSRadio = false, DCSFrequency = 243, DCSModulation = radio.modulation.AM, @@ -310,6 +311,7 @@ function AICSAR:New(Alias,Coalition,Pilottemplate,Helotemplate,FARP,MASHZone) self.SRSPath = "\\" self.SRSModulation = radio.modulation.AM self.SRSSoundPath = nil -- defaults to "l10n/DEFAULT/", i.e. add messages via "Sound to..." in the ME + self.SRSPort = 5002 -- DCS Radio - add messages via "Sound to..." in the ME self.DCSRadio = false @@ -456,8 +458,9 @@ end -- @param #number Frequency Defaults to 243 (guard) -- @param #number Modulation Radio modulation. Defaults to radio.modulation.AM -- @param #string SoundPath Where to find the audio files. Defaults to nil, i.e. add messages via "Sound to..." in the Mission Editor. +-- @param #number Port Port of the SRS, defaults to 5002. -- @return #AICSAR self -function AICSAR:SetSRSRadio(OnOff,Path,Frequency,Modulation,SoundPath) +function AICSAR:SetSRSRadio(OnOff,Path,Frequency,Modulation,SoundPath,Port) self:T(self.lid .. "SetSRSRadio") self:T(self.lid .. "SetSRSRadio to "..tostring(OnOff)) self.SRSRadio = OnOff and true @@ -465,8 +468,10 @@ function AICSAR:SetSRSRadio(OnOff,Path,Frequency,Modulation,SoundPath) self.SRSPath = Path or "c:\\" self.SRSModulation = Modulation or radio.modulation.AM self.SRSSoundPath = SoundPath or nil -- defaults to "l10n/DEFAULT/", i.e. add messages by "Sound to..." in the ME + self.SRSPort = Port or 5002 if OnOff then self.SRS = MSRS:New(Path,Frequency,Modulation) + self.SRS:SetPort(self.SRSPort) end return self end diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index 8b71f4195..a213f5632 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -124,6 +124,7 @@ -- self.SRSPath = "E:\\Progra~1\\DCS-SimpleRadio-Standalone\\" -- adjust your own path in your SRS installation -- server(!) -- self.SRSchannel = 300 -- radio channel -- self.SRSModulation = radio.modulation.AM -- modulation +-- self.SRSport = 5002 -- and SRS port -- -- -- self.csarUsePara = false -- If set to true, will use the LandingAfterEjection Event instead of Ejection --shagrat -- self.wetfeettemplate = "man in floating thingy" -- if you use a mod to have a pilot in a rescue float, put the template name in here for wet feet spawns. Note: in conjunction with csarUsePara this might create dual ejected pilots in edge cases. @@ -259,7 +260,7 @@ CSAR.AircraftType["AH-64D_BLK_II"] = 2 --- CSAR class version. -- @field #string version -CSAR.version="1.0.4d" +CSAR.version="1.0.4e" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- ToDo list @@ -413,6 +414,7 @@ function CSAR:New(Coalition, Template, Alias) self.SRSPath = "E:\\Progra~1\\DCS-SimpleRadio-Standalone\\" -- adjust your own path in your server(!) self.SRSchannel = 300 -- radio channel self.SRSModulation = radio.modulation.AM -- modulation + self.SRSport = 5002 -- port ------------------------ --- Pseudo Functions --- @@ -1523,6 +1525,7 @@ function CSAR:_DisplayMessageToSAR(_unit, _text, _time, _clear, _speak, _overrid local modulation = self.SRSModulation local channel = self.SRSchannel local msrs = MSRS:New(path,channel,modulation) + msrs:SetPort(self.SRSport) msrs:PlaySoundText(srstext, 2) end return self From d1f1f14bc399ee42cb40aaaedb3b32ce105d049b Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sun, 10 Apr 2022 10:18:26 +0200 Subject: [PATCH 02/13] SRS - add port to docu --- Moose Development/Moose/Sound/SRS.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Moose Development/Moose/Sound/SRS.lua b/Moose Development/Moose/Sound/SRS.lua index e1b8e5637..6c2b2660b 100644 --- a/Moose Development/Moose/Sound/SRS.lua +++ b/Moose Development/Moose/Sound/SRS.lua @@ -106,6 +106,10 @@ -- -- Use @{#MSRS.SetCoordinate} to define the origin from where the transmission is broadcasted. -- +-- ## Set SRS Port +-- +-- Use @{#MSRS.SetPort} to define the SRS port. Defaults to 5002. +-- -- @field #MSRS MSRS = { ClassName = "MSRS", From 277409a807b43e7875c2350cc728186493b5f336 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sun, 10 Apr 2022 14:58:47 +0200 Subject: [PATCH 03/13] Text and Sound: Spelling error --- Moose Development/Moose/Core/TextAndSound.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose Development/Moose/Core/TextAndSound.lua b/Moose Development/Moose/Core/TextAndSound.lua index edd4a79d8..8a9ea69b5 100644 --- a/Moose Development/Moose/Core/TextAndSound.lua +++ b/Moose Development/Moose/Core/TextAndSound.lua @@ -75,7 +75,7 @@ function TEXTANDSOUND:New(ClassName,Defaultlocale) initentry.Data = {} initentry.Locale = self.locale self.entries[self.locale] = initentry - self:I(self.lid .. "Instatiated.") + self:I(self.lid .. "Instantiated.") self:T({self.entries[self.locale]}) return self end From bfc284994acb9a1c6496099350d9adc4b644cbe5 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sun, 10 Apr 2022 14:59:05 +0200 Subject: [PATCH 04/13] SRS - port set not honored --- Moose Development/Moose/Sound/SRS.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Moose Development/Moose/Sound/SRS.lua b/Moose Development/Moose/Sound/SRS.lua index 6c2b2660b..294244e5f 100644 --- a/Moose Development/Moose/Sound/SRS.lua +++ b/Moose Development/Moose/Sound/SRS.lua @@ -212,6 +212,7 @@ end -- @return #MSRS self function MSRS:SetPort(Port) self.port=Port or 5002 + return self end --- Get port. @@ -227,6 +228,7 @@ end -- @return #MSRS self function MSRS:SetCoalition(Coalition) self.coalition=Coalition or 0 + return self end --- Get coalition. From 3dc284335ed1b306d2c267385c78f080375f7056 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sun, 10 Apr 2022 14:59:54 +0200 Subject: [PATCH 05/13] SoundOutput - Honor self.useSRS to find a path to sound files located inside the miz folder --- Moose Development/Moose/Sound/SoundOutput.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Moose Development/Moose/Sound/SoundOutput.lua b/Moose Development/Moose/Sound/SoundOutput.lua index 01fd00483..7788c0574 100644 --- a/Moose Development/Moose/Sound/SoundOutput.lua +++ b/Moose Development/Moose/Sound/SoundOutput.lua @@ -189,7 +189,11 @@ do -- Sound File -- Init path. self.path=Path or "l10n/DEFAULT/" - + + if not Path and self.useSRS then -- use path to mission temp dir + self.path = os.getenv('TMP') .. "\\DCS\\Mission\\l10n\DEFAULT" + end + -- Remove (back)slashes. local nmax=1000 ; local n=1 while (self.path:sub(-1)=="/" or self.path:sub(-1)==[[\]]) and n<=nmax do From 369425bec17f6c7f4abf30203af9898da5a6e5c0 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sun, 10 Apr 2022 15:12:51 +0200 Subject: [PATCH 06/13] Some SRS changes --- Moose Development/Moose/Functional/AICSAR.lua | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Moose Development/Moose/Functional/AICSAR.lua b/Moose Development/Moose/Functional/AICSAR.lua index ef8d154f6..b5f2f175d 100644 --- a/Moose Development/Moose/Functional/AICSAR.lua +++ b/Moose Development/Moose/Functional/AICSAR.lua @@ -159,7 +159,7 @@ -- @field #AICSAR AICSAR = { ClassName = "AICSAR", - version = "0.0.6", + version = "0.0.7", lid = "", coalition = coalition.side.BLUE, template = "", @@ -467,7 +467,8 @@ function AICSAR:SetSRSRadio(OnOff,Path,Frequency,Modulation,SoundPath,Port) self.SRSFrequency = Frequency or 243 self.SRSPath = Path or "c:\\" self.SRSModulation = Modulation or radio.modulation.AM - self.SRSSoundPath = SoundPath or nil -- defaults to "l10n/DEFAULT/", i.e. add messages by "Sound to..." in the ME + local soundpath = os.getenv('TMP') .. "\\DCS\\Mission\\l10n\DEFAULT" -- defaults to "l10n/DEFAULT/", i.e. add messages by "Sound to..." in the ME + self.SRSSoundPath = SoundPath or soundpath self.SRSPort = Port or 5002 if OnOff then self.SRS = MSRS:New(Path,Frequency,Modulation) @@ -551,7 +552,8 @@ function AICSAR:OnEventLandingAfterEjection(EventData) MESSAGE:New(text,15,"AICSAR"):ToCoalition(self.coalition) end if self.SRSRadio then - local sound = SOUNDFILE:New(Soundfile,nil,Soundlength) + local sound = SOUNDFILE:New(Soundfile,self.SRSSoundPath,Soundlength) + sound:SetPlayWithSRS(true) self.SRS:PlaySoundFile(sound,2) elseif self.DCSRadio then self:DCSRadioBroadcast(Soundfile,Soundlength,text) @@ -805,7 +807,8 @@ function AICSAR:onafterPilotDown(From, Event, To, Coordinate, InReach) MESSAGE:New(text,15,"AICSAR"):ToCoalition(self.coalition) end if self.SRSRadio then - local sound = SOUNDFILE:New(Soundfile,nil,Soundlength) + local sound = SOUNDFILE:New(Soundfile,self.SRSSoundPath,Soundlength) + sound:SetPlayWithSRS(true) self.SRS:PlaySoundFile(sound,2) elseif self.DCSRadio then self:DCSRadioBroadcast(Soundfile,Soundlength,text) @@ -818,7 +821,8 @@ function AICSAR:onafterPilotDown(From, Event, To, Coordinate, InReach) MESSAGE:New(text,15,"AICSAR"):ToCoalition(self.coalition) end if self.SRSRadio then - local sound = SOUNDFILE:New(Soundfile,nil,Soundlength) + local sound = SOUNDFILE:New(Soundfile,self.SRSSoundPath,Soundlength) + sound:SetPlayWithSRS(true) self.SRS:PlaySoundFile(sound,2) elseif self.DCSRadio then self:DCSRadioBroadcast(Soundfile,Soundlength,text) @@ -840,7 +844,8 @@ function AICSAR:onafterPilotKIA(From, Event, To) MESSAGE:New(text,15,"AICSAR"):ToCoalition(self.coalition) end if self.SRSRadio then - local sound = SOUNDFILE:New(Soundfile,nil,Soundlength) + local sound = SOUNDFILE:New(Soundfile,self.SRSSoundPath,Soundlength) + sound:SetPlayWithSRS(true) self.SRS:PlaySoundFile(sound,2) elseif self.DCSRadio then self:DCSRadioBroadcast(Soundfile,Soundlength,text) @@ -863,7 +868,8 @@ function AICSAR:onafterHeloDown(From, Event, To, Helo, Index) MESSAGE:New(text,15,"AICSAR"):ToCoalition(self.coalition) end if self.SRSRadio then - local sound = SOUNDFILE:New(Soundfile,nil,Soundlength) + local sound = SOUNDFILE:New(Soundfile,self.SRSSoundPath,Soundlength) + sound:SetPlayWithSRS(true) self.SRS:PlaySoundFile(sound,2) elseif self.DCSRadio then self:DCSRadioBroadcast(Soundfile,Soundlength,text) @@ -914,7 +920,8 @@ function AICSAR:onafterPilotRescued(From, Event, To) MESSAGE:New(text,15,"AICSAR"):ToCoalition(self.coalition) end if self.SRSRadio then - local sound = SOUNDFILE:New(Soundfile,nil,Soundlength) + local sound = SOUNDFILE:New(Soundfile,self.SRSSoundPath,Soundlength) + sound:SetPlayWithSRS(true) self.SRS:PlaySoundFile(sound,2) elseif self.DCSRadio then self:DCSRadioBroadcast(Soundfile,Soundlength,text) @@ -938,7 +945,8 @@ function AICSAR:onafterPilotPickedUp(From, Event, To, Helo, CargoTable, Index) MESSAGE:New(text,15,"AICSAR"):ToCoalition(self.coalition) end if self.SRSRadio then - local sound = SOUNDFILE:New(Soundfile,nil,Soundlength) + local sound = SOUNDFILE:New(Soundfile,self.SRSSoundPath,Soundlength) + sound:SetPlayWithSRS(true) self.SRS:PlaySoundFile(sound,2) elseif self.DCSRadio then self:DCSRadioBroadcast(Soundfile,Soundlength,text) From 44f7a27387a7d53dbe4bfd9e9e054f61e50fafc5 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sun, 10 Apr 2022 18:22:31 +0200 Subject: [PATCH 07/13] AICSAR - missing \ in path --- Moose Development/Moose/Functional/AICSAR.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Moose Development/Moose/Functional/AICSAR.lua b/Moose Development/Moose/Functional/AICSAR.lua index b5f2f175d..922ae567e 100644 --- a/Moose Development/Moose/Functional/AICSAR.lua +++ b/Moose Development/Moose/Functional/AICSAR.lua @@ -159,7 +159,7 @@ -- @field #AICSAR AICSAR = { ClassName = "AICSAR", - version = "0.0.7", + version = "0.0.8", lid = "", coalition = coalition.side.BLUE, template = "", @@ -467,7 +467,7 @@ function AICSAR:SetSRSRadio(OnOff,Path,Frequency,Modulation,SoundPath,Port) self.SRSFrequency = Frequency or 243 self.SRSPath = Path or "c:\\" self.SRSModulation = Modulation or radio.modulation.AM - local soundpath = os.getenv('TMP') .. "\\DCS\\Mission\\l10n\DEFAULT" -- defaults to "l10n/DEFAULT/", i.e. add messages by "Sound to..." in the ME + local soundpath = os.getenv('TMP') .. "\\DCS\\Mission\\l10n\\DEFAULT" -- defaults to "l10n/DEFAULT/", i.e. add messages by "Sound to..." in the ME self.SRSSoundPath = SoundPath or soundpath self.SRSPort = Port or 5002 if OnOff then From 4c79349b8d3b137344449eb24d2006215c493e84 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sun, 10 Apr 2022 18:23:20 +0200 Subject: [PATCH 08/13] MSRS - repair command string for .bat processing --- Moose Development/Moose/Sound/SRS.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Moose Development/Moose/Sound/SRS.lua b/Moose Development/Moose/Sound/SRS.lua index 294244e5f..2c4411ac1 100644 --- a/Moose Development/Moose/Sound/SRS.lua +++ b/Moose Development/Moose/Sound/SRS.lua @@ -397,7 +397,7 @@ function MSRS:PlaySoundFile(Soundfile, Delay) local command=self:_GetCommand() -- Append file. - command=command.." --file="..tostring(soundfile) + command=command..' --file="'..tostring(soundfile)..'"' self:_ExecCommand(command) @@ -663,12 +663,12 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp --local command=string.format("%s --freqs=%s --modulations=%s --coalition=%d --port=%d --volume=%.2f --speed=%d", exe, freqs, modus, coal, port, volume, speed) -- Command from orig STTS script. Works better for some unknown reason! - local command=string.format("start /min \"\" /d \"%s\" /b \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -h", path, exe, freqs, modus, coal, port, "ROBOT") + --local command=string.format("start /min \"\" /d \"%s\" /b \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -h", path, exe, freqs, modus, coal, port, "ROBOT") --local command=string.format('start /b "" /d "%s" "%s" -f %s -m %s -c %s -p %s -n "%s" > bla.txt', path, exe, freqs, modus, coal, port, "ROBOT") -- Command. - local command=string.format('%s/%s -f %s -m %s -c %s -p %s -n "%s"', path, exe, freqs, modus, coal, port, "ROBOT") + local command=string.format('"%s\\%s" -f %s -m %s -c %s -p %s -n "%s"', path, exe, freqs, modus, coal, port, "ROBOT") -- Set voice or gender/culture. if voice then From b24f31922f6ec16a9c781fa43ddd19886f4da00a Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sun, 10 Apr 2022 18:26:27 +0200 Subject: [PATCH 09/13] Soundfile - missing backslash --- Moose Development/Moose/Sound/SoundOutput.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Moose Development/Moose/Sound/SoundOutput.lua b/Moose Development/Moose/Sound/SoundOutput.lua index 7788c0574..57ce2f9a4 100644 --- a/Moose Development/Moose/Sound/SoundOutput.lua +++ b/Moose Development/Moose/Sound/SoundOutput.lua @@ -183,7 +183,7 @@ do -- Sound File --- Set path, where the sound file is located. -- @param #SOUNDFILE self - -- @param #string Path Path to the directory, where the sound file is located. + -- @param #string Path Path to the directory, where the sound file is located. In case this is nil, it defaults to the DCS mission temp directory. -- @return #SOUNDFILE self function SOUNDFILE:SetPath(Path) @@ -191,7 +191,7 @@ do -- Sound File self.path=Path or "l10n/DEFAULT/" if not Path and self.useSRS then -- use path to mission temp dir - self.path = os.getenv('TMP') .. "\\DCS\\Mission\\l10n\DEFAULT" + self.path = os.getenv('TMP') .. "\\DCS\\Mission\\l10n\\DEFAULT" end -- Remove (back)slashes. From 7525fe935747c15376f98cce040ff80bb3d5e872 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Tue, 12 Apr 2022 08:23:37 +0200 Subject: [PATCH 10/13] UTILS - corrected door check for AH64 --- Moose Development/Moose/Utilities/Utils.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index 78ab74e58..54a58639c 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -1773,7 +1773,7 @@ function UTILS.IsLoadingDoorOpen( unit_name ) ret_val = true end - if string.find(type_name, "AH-64D") then + if type_name == "AH-64D_BLK_II" then BASE:T(unit_name .. " front door(s) are open") ret_val = true -- no doors on this one ;) end From 32bdaf4f244fdb6eba2c64e3bcfed5770782a01c Mon Sep 17 00:00:00 2001 From: Penecruz <73371761+Penecruz@users.noreply.github.com> Date: Wed, 13 Apr 2022 17:35:18 +1000 Subject: [PATCH 11/13] Update Ops Airboss for develop (#1711) * Update Airboss.lua * Revert "Update Airboss.lua" This reverts commit 61b0f843eb14170d6332bc039c23e33ad3b0270c. * Update Airboss.lua --- Moose Development/Moose/Ops/Airboss.lua | 12373 ++++++++++------------ 1 file changed, 5831 insertions(+), 6542 deletions(-) diff --git a/Moose Development/Moose/Ops/Airboss.lua b/Moose Development/Moose/Ops/Airboss.lua index ff5571e36..967f54e61 100644 --- a/Moose Development/Moose/Ops/Airboss.lua +++ b/Moose Development/Moose/Ops/Airboss.lua @@ -32,9 +32,11 @@ -- * [USS George Washington](https://en.wikipedia.org/wiki/USS_George_Washington_(CVN-73)) (CVN-73) [Super Carrier Module] -- * [USS Harry S. Truman](https://en.wikipedia.org/wiki/USS_Harry_S._Truman) (CVN-75) [Super Carrier Module] -- * [USS Forrestal](https://en.wikipedia.org/wiki/USS_Forrestal_(CV-59)) (CV-59) [Heatblur Carrier Module] +-- * [HMS Hermes](https://en.wikipedia.org/wiki/HMS_Hermes_(R12)) (R12) [**WIP**] -- * [USS Tarawa](https://en.wikipedia.org/wiki/USS_Tarawa_(LHA-1)) (LHA-1) [**WIP**] -- * [USS America](https://en.wikipedia.org/wiki/USS_America_(LHA-6)) (LHA-6) [**WIP**] -- * [Juan Carlos I](https://en.wikipedia.org/wiki/Spanish_amphibious_assault_ship_Juan_Carlos_I) (L61) [**WIP**] +-- * [HMAS Canberra](https://en.wikipedia.org/wiki/HMAS_Canberra_(L02)) (L02) [**WIP**] -- -- **Supported Aircraft:** -- @@ -51,9 +53,9 @@ -- -- At the moment, optimized parameters are available for the F/A-18C Hornet (Lot 20) and A-4E community mod as aircraft and the USS John C. Stennis as carrier. -- --- The AV-8B Harrier, the USS Tarawa, USS America, HMAS Canberra and Juan Carlos I are WIP. The AV-8B harrier and the LHA's and LHD can only be used together, i.e. these ships are the only carriers the harrier is supposed to land on and +-- The AV-8B Harrier, HMS Hermes, the USS Tarawa, USS America, HMAS Canberra, and Juan Carlos I are WIP. The AV-8B harrier and the LHA's and LHD can only be used together, i.e. these ships are the only carriers the harrier is supposed to land on and -- no other fixed wing aircraft (human or AI controlled) are supposed to land on these ships. Currently only Case I is supported. Case II/III take slightly different steps from the CVN carrier. --- However, the two Case II/III pattern are very similar so this is not a big drawback. +-- However, if no offset is used for the holding radial this provides a very close representation of the V/STOL Case III, allowing for an approach to over the deck and a vertical landing. -- -- Heatblur's mighty F-14B Tomcat has been added (March 13th 2019) as well. Same goes for the A version. -- @@ -113,10 +115,11 @@ -- * [Harrier Ship Landing Mission with Auto LSO!](https://www.youtube.com/watch?v=lqmVvpunk2c) -- * [Updated Airboss V/STOL Features USS Tarawa](https://youtu.be/K7I4pU6j718) -- * [Harrier Practice pattern USS America](https://youtu.be/99NigITYmcI) +-- * [Harrier CASE III TACAN Approach USS Tarawa](https://www.youtube.com/watch?v=wWHag5WpNZ0) -- -- === -- --- ### Author: **funkyfranky** +-- ### Author: **funkyfranky** LHA and LHD V/STOL additions by **Pene** -- ### Special Thanks To **Bankler** -- For his great [Recovery Trainer](https://forums.eagle.ru/showthread.php?t=221412) mission and script! -- His work was the initial inspiration for this class. Also note that this implementation uses some routines for determining the player position in Case I recoveries he developed. @@ -303,7 +306,6 @@ -- The AV-8B Harrier pattern is very similar, the only differences are as there is no angled deck there is no wake check. from the ninety you wil fly a straight approach offset 26 ft to port (left) of the tram line. -- The aim is to arrive abeam the landing spot in a stable hover at 120 ft with forward speed matched to the boat. From there the LSO will call "cleared to land". You then level cross to the tram line at the designated landing spot at land vertcally. When you stabalise over the landing spot LSO will call Stabalise to indicate you are centered at the correct spot. -- --- -- ## CASE III -- -- ![Banner Image](..\Presentations\AIRBOSS\Airboss_Case3.png) @@ -865,7 +867,7 @@ -- * *Points*: Current points for the pass. -- * *Details*: Detailed grading analysis. -- ---## Lineup Error +-- ## Lineup Error -- -- ![Banner Image](..\Presentations\AIRBOSS\Airboss_TrapSheetLUE.png) -- @@ -958,8 +960,6 @@ -- -- Again, changing the file name, subtitle, subtitle duration is not required if you name the file exactly like the original one, which is this case would be "LSO-RogerBall.ogg". -- --- --- -- ## The Radio Dilemma -- -- DCS offers two (actually three) ways to send radio messages. Each one has its advantages and disadvantages and it is important to understand the differences. @@ -1265,7 +1265,7 @@ AIRBOSS = { --- Aircraft types capable of landing on carrier (human+AI). -- @type AIRBOSS.AircraftCarrier --- @field #string AV8B AV-8B Night Harrier. Works only with the USS Tarawa, USS America and Juan Carlos I. +-- @field #string AV8B AV-8B Night Harrier. Works only with the HMS Hermes, USS Tarawa, USS America, and Juan Carlos I. -- @field #string A4EC A-4E Community mod. -- @field #string HORNET F/A-18C Lot 20 Hornet by Eagle Dynamics. -- @field #string F14A F-14A by Heatblur. @@ -1301,24 +1301,26 @@ AIRBOSS.AircraftCarrier={ -- @field #string TRUMAN USS Harry S. Truman (CVN-75) [Super Carrier Module] -- @field #string FORRESTAL USS Forrestal (CV-59) [Heatblur Carrier Module] -- @field #string VINSON USS Carl Vinson (CVN-70) [Obsolete] +-- @field #string HERMES HMS Hermes (R12) [V/STOL Carrier] -- @field #string TARAWA USS Tarawa (LHA-1) [V/STOL Carrier] -- @field #string AMERICA USS America (LHA-6) [V/STOL Carrier] -- @field #string JCARLOS Juan Carlos I (L61) [V/STOL Carrier] -- @field #string HMAS Canberra (L02) [V/STOL Carrier] -- @field #string KUZNETSOV Admiral Kuznetsov (CV 1143.5) -AIRBOSS.CarrierType={ - ROOSEVELT="CVN_71", - LINCOLN="CVN_72", - WASHINGTON="CVN_73", - TRUMAN="CVN_75", - STENNIS="Stennis", - FORRESTAL="Forrestal", - VINSON="VINSON", - TARAWA="LHA_Tarawa", - AMERICA="USS America LHA-6", - JCARLOS="L61", - CANBERRA="L02", - KUZNETSOV="KUZNECOW", +AIRBOSS.CarrierType = { + ROOSEVELT = "CVN_71", + LINCOLN = "CVN_72", + WASHINGTON = "CVN_73", + TRUMAN = "CVN_75", + STENNIS = "Stennis", + FORRESTAL = "Forrestal", + VINSON = "VINSON", + HERMES = "HERMES81", + TARAWA = "LHA_Tarawa", + AMERICA = "USS America LHA-6", + JCARLOS = "L61", + CANBERRA = "L02", + KUZNETSOV = "KUZNECOW", } --- Carrier specific parameters. @@ -1366,7 +1368,6 @@ AIRBOSS.CarrierType={ -- @field #number LEFT LUR threshold. Default -3.0 deg. -- @field #number RIGHT LUL threshold. Default 3.0 deg. - --- Pattern steps. -- @type AIRBOSS.PatternStep -- @field #string UNDEFINED "Undefined". @@ -1398,36 +1399,36 @@ AIRBOSS.CarrierType={ -- @field #string BOLTER "Bolter Pattern". -- @field #string EMERGENCY "Emergency Landing". -- @field #string DEBRIEF "Debrief". -AIRBOSS.PatternStep={ - UNDEFINED="Undefined", - REFUELING="Refueling", - SPINNING="Spinning", - COMMENCING="Commencing", - HOLDING="Holding", - WAITING="Waiting for free Marshal stack", - PLATFORM="Platform", - ARCIN="Arc Turn In", - ARCOUT="Arc Turn Out", - DIRTYUP="Dirty Up", - BULLSEYE="Bullseye", - INITIAL="Initial", - BREAKENTRY="Break Entry", - EARLYBREAK="Early Break", - LATEBREAK="Late Break", - ABEAM="Abeam", - NINETY="Ninety", - WAKE="Wake", - FINAL="Turn Final", - GROOVE_XX="Groove X", - GROOVE_IM="Groove In the Middle", - GROOVE_IC="Groove In Close", - GROOVE_AR="Groove At the Ramp", - GROOVE_IW="Groove In the Wires", - GROOVE_AL="Groove Abeam Landing Spot", - GROOVE_LC="Groove Level Cross", - BOLTER="Bolter Pattern", - EMERGENCY="Emergency Landing", - DEBRIEF="Debrief", +AIRBOSS.PatternStep = { + UNDEFINED = "Undefined", + REFUELING = "Refueling", + SPINNING = "Spinning", + COMMENCING = "Commencing", + HOLDING = "Holding", + WAITING = "Waiting for free Marshal stack", + PLATFORM = "Platform", + ARCIN = "Arc Turn In", + ARCOUT = "Arc Turn Out", + DIRTYUP = "Dirty Up", + BULLSEYE = "Bullseye", + INITIAL = "Initial", + BREAKENTRY = "Break Entry", + EARLYBREAK = "Early Break", + LATEBREAK = "Late Break", + ABEAM = "Abeam", + NINETY = "Ninety", + WAKE = "Wake", + FINAL = "Turn Final", + GROOVE_XX = "Groove X", + GROOVE_IM = "Groove In the Middle", + GROOVE_IC = "Groove In Close", + GROOVE_AR = "Groove At the Ramp", + GROOVE_IW = "Groove In the Wires", + GROOVE_AL = "Groove Abeam Landing Spot", + GROOVE_LC = "Groove Level Cross", + BOLTER = "Bolter Pattern", + EMERGENCY = "Emergency Landing", + DEBRIEF = "Debrief", } --- Groove position. @@ -1440,15 +1441,15 @@ AIRBOSS.PatternStep={ -- @field #string AL "AL": Abeam landing position (V/STOL). -- @field #string LC "LC": Level crossing (V/STOL). -- @field #string IW "IW": In the wires. -AIRBOSS.GroovePos={ - X0="X0", - XX="XX", - IM="IM", - IC="IC", - AR="AR", - AL="AL", - LC="LC", - IW="IW", +AIRBOSS.GroovePos = { + X0 = "X0", + XX = "XX", + IM = "IM", + IC = "IC", + AR = "AR", + AL = "AL", + LC = "LC", + IW = "IW", } --- Radio. @@ -1577,16 +1578,15 @@ AIRBOSS.GroovePos={ -- @field #AIRBOSS.RadioCall CLICK Radio end transmission click sound. -- @field #AIRBOSS.RadioCall NOISE Static noise sound. - --- Difficulty level. -- @type AIRBOSS.Difficulty -- @field #string EASY Flight Student. Shows tips and hints in important phases of the approach. -- @field #string NORMAL Naval aviator. Moderate number of hints but not really zip lip. -- @field #string HARD TOPGUN graduate. For people who know what they are doing. Nearly *ziplip*. -AIRBOSS.Difficulty={ - EASY="Flight Student", - NORMAL="Naval Aviator", - HARD="TOPGUN Graduate", +AIRBOSS.Difficulty = { + EASY = "Flight Student", + NORMAL = "Naval Aviator", + HARD = "TOPGUN Graduate", } --- Recovery window parameters. @@ -1723,16 +1723,15 @@ AIRBOSS.Difficulty={ --- Main group level radio menu: F10 Other/Airboss. -- @field #table MenuF10 -AIRBOSS.MenuF10={} +AIRBOSS.MenuF10 = {} --- Airboss mission level F10 root menu. -- @field #table MenuF10Root -AIRBOSS.MenuF10Root=nil +AIRBOSS.MenuF10Root = nil --- Airboss class version. -- @field #string version -AIRBOSS.version="1.2.1" - +AIRBOSS.version = "1.2.1" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -1805,56 +1804,56 @@ AIRBOSS.version="1.2.1" -- @param carriername Name of the aircraft carrier unit as defined in the mission editor. -- @param alias (Optional) Alias for the carrier. This will be used for radio messages and the F10 radius menu. Default is the carrier name as defined in the mission editor. -- @return #AIRBOSS self or nil if carrier unit does not exist. -function AIRBOSS:New(carriername, alias) +function AIRBOSS:New( carriername, alias ) -- Inherit everthing from FSM class. - local self=BASE:Inherit(self, FSM:New()) -- #AIRBOSS + local self = BASE:Inherit( self, FSM:New() ) -- #AIRBOSS -- Debug. - self:F2({carriername=carriername, alias=alias}) + self:F2( { carriername = carriername, alias = alias } ) -- Set carrier unit. - self.carrier=UNIT:FindByName(carriername) + self.carrier = UNIT:FindByName( carriername ) -- Check if carrier unit exists. - if self.carrier==nil then + if self.carrier == nil then -- Error message. - local text=string.format("ERROR: Carrier unit %s could not be found! Make sure this UNIT is defined in the mission editor and check the spelling of the unit name carefully.", carriername) - MESSAGE:New(text, 120):ToAll() - self:E(text) + local text = string.format( "ERROR: Carrier unit %s could not be found! Make sure this UNIT is defined in the mission editor and check the spelling of the unit name carefully.", carriername ) + MESSAGE:New( text, 120 ):ToAll() + self:E( text ) return nil end -- Set some string id for output to DCS.log file. - self.lid=string.format("AIRBOSS %s | ", carriername) + self.lid = string.format( "AIRBOSS %s | ", carriername ) -- Current map. - self.theatre=env.mission.theatre - self:T2(self.lid..string.format("Theatre = %s.", tostring(self.theatre))) + self.theatre = env.mission.theatre + self:T2( self.lid .. string.format( "Theatre = %s.", tostring( self.theatre ) ) ) -- Get carrier type. - self.carriertype=self.carrier:GetTypeName() + self.carriertype = self.carrier:GetTypeName() -- Set alias. - self.alias=alias or carriername + self.alias = alias or carriername -- Set carrier airbase object. - self.airbase=AIRBASE:FindByName(carriername) + self.airbase = AIRBASE:FindByName( carriername ) -- Create carrier beacon. - self.beacon=BEACON:New(self.carrier) + self.beacon = BEACON:New( self.carrier ) -- Set Tower Frequency of carrier. self:_GetTowerFrequency() -- Init player scores table. - self.playerscores={} + self.playerscores = {} -- Initialize ME waypoints. self:_InitWaypoints() -- Current waypoint. - self.currentwp=1 + self.currentwp = 1 -- Patrol route. self:_PatrolRoute() @@ -1873,7 +1872,7 @@ function AIRBOSS:New(carriername, alias) self:SetLSOCallInterval() -- Radio scheduler. - self.radiotimer=SCHEDULER:New() + self.radiotimer = SCHEDULER:New() -- Set magnetic declination. self:SetMagneticDeclination() @@ -1915,10 +1914,10 @@ function AIRBOSS:New(carriername, alias) self:SetEmergencyLandings() -- No despawn after engine shutdown by default. - self:SetDespawnOnEngineShutdown(false) + self:SetDespawnOnEngineShutdown( false ) -- No respawning of AI groups when entering the CCA. - self:SetRespawnAI(false) + self:SetRespawnAI( false ) -- Mission uses static weather by default. self:SetStaticWeather() @@ -1939,7 +1938,7 @@ function AIRBOSS:New(carriername, alias) self:SetInitialMaxAlt() -- Default player skill EASY. - self:SetDefaultPlayerSkill(AIRBOSS.Difficulty.EASY) + self:SetDefaultPlayerSkill( AIRBOSS.Difficulty.EASY ) -- Default glideslope error thresholds. self:SetGlideslopeErrorThresholds() @@ -1954,7 +1953,7 @@ function AIRBOSS:New(carriername, alias) self:SetCarrierControlledZone() -- Carrier patrols its waypoints until the end of time. - self:SetPatrolAdInfinitum(true) + self:SetPatrolAdInfinitum( true ) -- Collision check distance. Default 5 NM. self:SetCollisionDistance() @@ -1967,49 +1966,52 @@ function AIRBOSS:New(carriername, alias) -- Menu options. self:SetMenuMarkZones() self:SetMenuSmokeZones() - self:SetMenuSingleCarrier(false) + self:SetMenuSingleCarrier( false ) -- Welcome players. - self:SetWelcomePlayers(true) + self:SetWelcomePlayers( true ) -- Coordinates - self.landingcoord=COORDINATE:New(0,0,0) --Core.Point#COORDINATE - self.sterncoord=COORDINATE:New(0, 0, 0) --Core.Point#COORDINATE - self.landingspotcoord=COORDINATE:New(0,0,0) --Core.Point#COORDINATE + self.landingcoord = COORDINATE:New( 0, 0, 0 ) -- Core.Point#COORDINATE + self.sterncoord = COORDINATE:New( 0, 0, 0 ) -- Core.Point#COORDINATE + self.landingspotcoord = COORDINATE:New( 0, 0, 0 ) -- Core.Point#COORDINATE -- Init carrier parameters. - if self.carriertype==AIRBOSS.CarrierType.STENNIS then + if self.carriertype == AIRBOSS.CarrierType.STENNIS then self:_InitStennis() - elseif self.carriertype==AIRBOSS.CarrierType.ROOSEVELT then + elseif self.carriertype == AIRBOSS.CarrierType.ROOSEVELT then self:_InitNimitz() - elseif self.carriertype==AIRBOSS.CarrierType.LINCOLN then + elseif self.carriertype == AIRBOSS.CarrierType.LINCOLN then self:_InitNimitz() - elseif self.carriertype==AIRBOSS.CarrierType.WASHINGTON then + elseif self.carriertype == AIRBOSS.CarrierType.WASHINGTON then self:_InitNimitz() - elseif self.carriertype==AIRBOSS.CarrierType.TRUMAN then + elseif self.carriertype == AIRBOSS.CarrierType.TRUMAN then self:_InitNimitz() - elseif self.carriertype==AIRBOSS.CarrierType.FORRESTAL then + elseif self.carriertype == AIRBOSS.CarrierType.FORRESTAL then self:_InitForrestal() - elseif self.carriertype==AIRBOSS.CarrierType.VINSON then + elseif self.carriertype == AIRBOSS.CarrierType.VINSON then -- TODO: Carl Vinson parameters. self:_InitStennis() - elseif self.carriertype==AIRBOSS.CarrierType.TARAWA then + elseif self.carriertype == AIRBOSS.CarrierType.HERMES then + -- Hermes parameters. + self:_InitHermes() + elseif self.carriertype == AIRBOSS.CarrierType.TARAWA then -- Tarawa parameters. self:_InitTarawa() - elseif self.carriertype==AIRBOSS.CarrierType.AMERICA then + elseif self.carriertype == AIRBOSS.CarrierType.AMERICA then -- Use America parameters. self:_InitAmerica() - elseif self.carriertype==AIRBOSS.CarrierType.JCARLOS then + elseif self.carriertype == AIRBOSS.CarrierType.JCARLOS then -- Use Juan Carlos parameters. self:_InitJcarlos() - elseif self.carriertype==AIRBOSS.CarrierType.CANBERRA then + elseif self.carriertype == AIRBOSS.CarrierType.CANBERRA then -- Use Juan Carlos parameters at this stage --TODO Check primary Landing spot. self:_InitJcarlos() - elseif self.carriertype==AIRBOSS.CarrierType.KUZNETSOV then + elseif self.carriertype == AIRBOSS.CarrierType.KUZNETSOV then -- Kusnetsov parameters - maybe... self:_InitStennis() else - self:E(self.lid..string.format("ERROR: Unknown carrier type %s!", tostring(self.carriertype))) + self:E( self.lid .. string.format( "ERROR: Unknown carrier type %s!", tostring( self.carriertype ) ) ) return nil end @@ -2022,48 +2024,48 @@ function AIRBOSS:New(carriername, alias) -- Debug trace. if false then - self.Debug=true - BASE:TraceOnOff(true) - BASE:TraceClass(self.ClassName) - BASE:TraceLevel(3) - --self.dTstatus=0.1 + self.Debug = true + BASE:TraceOnOff( true ) + BASE:TraceClass( self.ClassName ) + BASE:TraceLevel( 3 ) + -- self.dTstatus=0.1 end -- Smoke zones. if false then - local case=3 - self.holdingoffset=30 - self:_GetZoneGroove():SmokeZone(SMOKECOLOR.Red, 5) - self:_GetZoneLineup():SmokeZone(SMOKECOLOR.Green, 5) - self:_GetZoneBullseye(case):SmokeZone(SMOKECOLOR.White, 45) - self:_GetZoneDirtyUp(case):SmokeZone(SMOKECOLOR.Orange, 45) - self:_GetZoneArcIn(case):SmokeZone(SMOKECOLOR.Blue, 45) - self:_GetZoneArcOut(case):SmokeZone(SMOKECOLOR.Blue, 45) - self:_GetZonePlatform(case):SmokeZone(SMOKECOLOR.Blue, 45) - self:_GetZoneCorridor(case):SmokeZone(SMOKECOLOR.Green, 45) - self:_GetZoneHolding(case, 1):SmokeZone(SMOKECOLOR.White, 45) - self:_GetZoneHolding(case, 2):SmokeZone(SMOKECOLOR.White, 45) - self:_GetZoneInitial(case):SmokeZone(SMOKECOLOR.Orange, 45) - self:_GetZoneCommence(case, 1):SmokeZone(SMOKECOLOR.Red, 45) - self:_GetZoneCommence(case, 2):SmokeZone(SMOKECOLOR.Red, 45) - self:_GetZoneAbeamLandingSpot():SmokeZone(SMOKECOLOR.Red, 5) - self:_GetZoneLandingSpot():SmokeZone(SMOKECOLOR.Red, 5) + local case = 3 + self.holdingoffset = 30 + self:_GetZoneGroove():SmokeZone( SMOKECOLOR.Red, 5 ) + self:_GetZoneLineup():SmokeZone( SMOKECOLOR.Green, 5 ) + self:_GetZoneBullseye( case ):SmokeZone( SMOKECOLOR.White, 45 ) + self:_GetZoneDirtyUp( case ):SmokeZone( SMOKECOLOR.Orange, 45 ) + self:_GetZoneArcIn( case ):SmokeZone( SMOKECOLOR.Blue, 45 ) + self:_GetZoneArcOut( case ):SmokeZone( SMOKECOLOR.Blue, 45 ) + self:_GetZonePlatform( case ):SmokeZone( SMOKECOLOR.Blue, 45 ) + self:_GetZoneCorridor( case ):SmokeZone( SMOKECOLOR.Green, 45 ) + self:_GetZoneHolding( case, 1 ):SmokeZone( SMOKECOLOR.White, 45 ) + self:_GetZoneHolding( case, 2 ):SmokeZone( SMOKECOLOR.White, 45 ) + self:_GetZoneInitial( case ):SmokeZone( SMOKECOLOR.Orange, 45 ) + self:_GetZoneCommence( case, 1 ):SmokeZone( SMOKECOLOR.Red, 45 ) + self:_GetZoneCommence( case, 2 ):SmokeZone( SMOKECOLOR.Red, 45 ) + self:_GetZoneAbeamLandingSpot():SmokeZone( SMOKECOLOR.Red, 5 ) + self:_GetZoneLandingSpot():SmokeZone( SMOKECOLOR.Red, 5 ) end -- Carrier parameter debug tests. if false then - -- Stern coordinate. - local FB=self:GetFinalBearing(false) - local hdg=self:GetHeading(false) + -- Stern coordinate. + local FB = self:GetFinalBearing( false ) + local hdg = self:GetHeading( false ) -- Stern pos. - local stern=self:_GetSternCoord() + local stern = self:_GetSternCoord() -- Bow pos. - local bow=stern:Translate(self.carrierparam.totlength, hdg, true) + local bow = stern:Translate( self.carrierparam.totlength, hdg, true ) -- End of rwy. - local rwy=stern:Translate(self.carrierparam.rwylength, FB, true) + local rwy = stern:Translate( self.carrierparam.rwylength, FB, true ) --- Flare points and zones. local function flareme() @@ -2078,31 +2080,30 @@ function AIRBOSS:New(carriername, alias) bow:FlareYellow() -- Runway half width = 10 m. - local r1=stern:Translate(self.carrierparam.rwywidth*0.5, FB+90, true) - local r2=stern:Translate(self.carrierparam.rwywidth*0.5, FB-90, true) - --r1:FlareWhite() - --r2:FlareWhite() + local r1 = stern:Translate( self.carrierparam.rwywidth * 0.5, FB + 90, true ) + local r2 = stern:Translate( self.carrierparam.rwywidth * 0.5, FB - 90, true ) + -- r1:FlareWhite() + -- r2:FlareWhite() -- End of runway. rwy:FlareRed() -- Right 30 meters from stern. - local cR=stern:Translate(self.carrierparam.totwidthstarboard, hdg+90, true) - --cR:FlareYellow() + local cR = stern:Translate( self.carrierparam.totwidthstarboard, hdg + 90, true ) + -- cR:FlareYellow() -- Left 40 meters from stern. - local cL=stern:Translate(self.carrierparam.totwidthport, hdg-90, true) - --cL:FlareYellow() - + local cL = stern:Translate( self.carrierparam.totwidthport, hdg - 90, true ) + -- cL:FlareYellow() -- Carrier specific. - if self.carrier:GetTypeName()~=AIRBOSS.CarrierType.TARAWA or self.carrier:GetTypeName()~=AIRBOSS.CarrierType.AMERICA or self.carrier:GetTypeName()~=AIRBOSS.CarrierType.JCARLOS or self.carrier:GetTypeName()~=AIRBOSS.CarrierType.CANBERRA then + if self.carrier:GetTypeName() ~= AIRBOSS.CarrierType.HERMES or self.carrier:GetTypeName() ~= AIRBOSS.CarrierType.TARAWA or self.carrier:GetTypeName() ~= AIRBOSS.CarrierType.AMERICA or self.carrier:GetTypeName() ~= AIRBOSS.CarrierType.JCARLOS or self.carrier:GetTypeName() ~= AIRBOSS.CarrierType.CANBERRA then -- Flare wires. - local w1=stern:Translate(self.carrierparam.wire1, FB, true) - local w2=stern:Translate(self.carrierparam.wire2, FB, true) - local w3=stern:Translate(self.carrierparam.wire3, FB, true) - local w4=stern:Translate(self.carrierparam.wire4, FB, true) + local w1 = stern:Translate( self.carrierparam.wire1, FB, true ) + local w2 = stern:Translate( self.carrierparam.wire2, FB, true ) + local w3 = stern:Translate( self.carrierparam.wire3, FB, true ) + local w4 = stern:Translate( self.carrierparam.wire4, FB, true ) w1:FlareWhite() w2:FlareYellow() w3:FlareWhite() @@ -2111,27 +2112,27 @@ function AIRBOSS:New(carriername, alias) else -- Abeam landing spot zone. - local ALSPT=self:_GetZoneAbeamLandingSpot() - ALSPT:FlareZone(FLARECOLOR.Red, 5, nil, UTILS.FeetToMeters(120)) + local ALSPT = self:_GetZoneAbeamLandingSpot() + ALSPT:FlareZone( FLARECOLOR.Red, 5, nil, UTILS.FeetToMeters( 120 ) ) -- Primary landing spot zone. - local LSPT=self:_GetZoneLandingSpot() - LSPT:FlareZone(FLARECOLOR.Green, 5, nil, self.carrierparam.deckheight) + local LSPT = self:_GetZoneLandingSpot() + LSPT:FlareZone( FLARECOLOR.Green, 5, nil, self.carrierparam.deckheight ) -- Landing spot coordinate. - local PLSC=self:_GetLandingSpotCoordinate() + local PLSC = self:_GetLandingSpotCoordinate() PLSC:FlareWhite() end -- Flare carrier and landing runway. - local cbox=self:_GetZoneCarrierBox() - local rbox=self:_GetZoneRunwayBox() - cbox:FlareZone(FLARECOLOR.Green, 5, nil, self.carrierparam.deckheight) - rbox:FlareZone(FLARECOLOR.White, 5, nil, self.carrierparam.deckheight) + local cbox = self:_GetZoneCarrierBox() + local rbox = self:_GetZoneRunwayBox() + cbox:FlareZone( FLARECOLOR.Green, 5, nil, self.carrierparam.deckheight ) + rbox:FlareZone( FLARECOLOR.White, 5, nil, self.carrierparam.deckheight ) end -- Flare points every 3 seconds for 3 minutes. - SCHEDULER:New(nil, flareme, {}, 1, 3, nil, 180) + SCHEDULER:New( nil, flareme, {}, 1, 3, nil, 180 ) end ----------------------- @@ -2139,7 +2140,7 @@ function AIRBOSS:New(carriername, alias) ----------------------- -- Start State. - self:SetStartState("Stopped") + self:SetStartState( "Stopped" ) -- Add FSM transitions. -- From State --> Event --> To State @@ -2175,7 +2176,6 @@ function AIRBOSS:New(carriername, alias) -- @param #string Event Event. -- @param #string To To state. - --- Triggers the FSM event "Idle" that puts the carrier into state "Idle" where no recoveries are carried out. -- @function [parent=#AIRBOSS] Idle -- @param #AIRBOSS self @@ -2185,7 +2185,6 @@ function AIRBOSS:New(carriername, alias) -- @param #AIRBOSS self -- @param #number delay Delay in seconds. - --- Triggers the FSM event "RecoveryStart" that starts the recovery of aircraft. Marshalling aircraft are send to the landing pattern. -- @function [parent=#AIRBOSS] RecoveryStart -- @param #AIRBOSS self @@ -2208,7 +2207,6 @@ function AIRBOSS:New(carriername, alias) -- @param #number Case The recovery case (1, 2 or 3) to start. -- @param #number Offset Holding pattern offset angle in degrees for CASE II/III recoveries. - --- Triggers the FSM event "RecoveryStop" that stops the recovery of aircraft. -- @function [parent=#AIRBOSS] RecoveryStop -- @param #AIRBOSS self @@ -2225,7 +2223,6 @@ function AIRBOSS:New(carriername, alias) -- @param #string Event Event. -- @param #string To To state. - --- Triggers the FSM event "RecoveryPause" that pauses the recovery of aircraft. -- @function [parent=#AIRBOSS] RecoveryPause -- @param #AIRBOSS self @@ -2246,7 +2243,6 @@ function AIRBOSS:New(carriername, alias) -- @param #AIRBOSS self -- @param #number delay Delay in seconds. - --- Triggers the FSM event "RecoveryCase" that switches the aircraft recovery case. -- @function [parent=#AIRBOSS] RecoveryCase -- @param #AIRBOSS self @@ -2260,7 +2256,6 @@ function AIRBOSS:New(carriername, alias) -- @param #number Case The new recovery case (1, 2 or 3). -- @param #number Offset Holding pattern offset angle in degrees for CASE II/III recoveries. - --- Triggers the FSM event "PassingWaypoint". Called when the carrier passes a waypoint. -- @function [parent=#AIRBOSS] PassingWaypoint -- @param #AIRBOSS self @@ -2281,7 +2276,6 @@ function AIRBOSS:New(carriername, alias) -- @param #string To To state. -- @param #number waypoint Number of waypoint. - --- Triggers the FSM event "Save" that saved the player scores to a file. -- @function [parent=#AIRBOSS] Save -- @param #AIRBOSS self @@ -2304,7 +2298,6 @@ function AIRBOSS:New(carriername, alias) -- @param #string path Path where the file is saved. Default is the DCS installation root directory or your "Saved Games\DCS" folder if lfs was desanitized. -- @param #string filename (Optional) File name. Default is AIRBOSS-*ALIAS*_LSOgrades.csv. - --- Triggers the FSM event "Load" that loads the player scores from a file. AIRBOSS FSM must **not** be started at this point. -- @function [parent=#AIRBOSS] Load -- @param #AIRBOSS self @@ -2327,7 +2320,6 @@ function AIRBOSS:New(carriername, alias) -- @param #string path Path where the file is located. Default is the DCS installation root directory or your "Saved Games\DCS" folder if lfs was desanitized. -- @param #string filename (Optional) File name. Default is AIRBOSS-*ALIAS*_LSOgrades.csv. - --- Triggers the FSM event "LSOGrade". Called when the LSO grades a player -- @function [parent=#AIRBOSS] LSOGrade -- @param #AIRBOSS self @@ -2350,7 +2342,6 @@ function AIRBOSS:New(carriername, alias) -- @param #AIRBOSS.PlayerData playerData Player Data. -- @param #AIRBOSS.LSOgrade grade LSO grade. - --- Triggers the FSM event "Marshal". Called when a flight is send to the Marshal stack. -- @function [parent=#AIRBOSS] Marshal -- @param #AIRBOSS self @@ -2370,7 +2361,6 @@ function AIRBOSS:New(carriername, alias) -- @param #string To To state. -- @param #AIRBOSS.FlightGroup flight The flight group data. - --- Triggers the FSM event "Stop" that stops the airboss. Event handlers are stopped. -- @function [parent=#AIRBOSS] Stop -- @param #AIRBOSS self @@ -2389,26 +2379,25 @@ end --- Set welcome messages for players. -- @param #AIRBOSS self --- @param #boolean switch If true, display welcome message to player. +-- @param #boolean Switch If true, display welcome message to player. -- @return #AIRBOSS self -function AIRBOSS:SetWelcomePlayers(switch) +function AIRBOSS:SetWelcomePlayers( Switch ) - self.welcome=switch + self.welcome = Switch return self end - --- Set carrier controlled area (CCA). -- This is a large zone around the carrier, which is constantly updated wrt the carrier position. -- @param #AIRBOSS self --- @param #number radius Radius of zone in nautical miles (NM). Default 50 NM. +-- @param #number Radius Radius of zone in nautical miles (NM). Default 50 NM. -- @return #AIRBOSS self -function AIRBOSS:SetCarrierControlledArea(radius) +function AIRBOSS:SetCarrierControlledArea( Radius ) - radius=UTILS.NMToMeters(radius or 50) + Radius = UTILS.NMToMeters( Radius or 50 ) - self.zoneCCA=ZONE_UNIT:New("Carrier Controlled Area", self.carrier, radius) + self.zoneCCA = ZONE_UNIT:New( "Carrier Controlled Area", self.carrier, Radius ) return self end @@ -2416,37 +2405,37 @@ end --- Set carrier controlled zone (CCZ). -- This is a small zone (usually 5 NM radius) around the carrier, which is constantly updated wrt the carrier position. -- @param #AIRBOSS self --- @param #number radius Radius of zone in nautical miles (NM). Default 5 NM. +-- @param #number Radius Radius of zone in nautical miles (NM). Default 5 NM. -- @return #AIRBOSS self -function AIRBOSS:SetCarrierControlledZone(radius) +function AIRBOSS:SetCarrierControlledZone( Radius ) - radius=UTILS.NMToMeters(radius or 5) + Radius = UTILS.NMToMeters( Radius or 5 ) - self.zoneCCZ=ZONE_UNIT:New("Carrier Controlled Zone", self.carrier, radius) + self.zoneCCZ = ZONE_UNIT:New( "Carrier Controlled Zone", self.carrier, Radius ) return self end --- Set distance up to which water ahead is scanned for collisions. -- @param #AIRBOSS self --- @param #number dist Distance in NM. Default 5 NM. +-- @param #number Distance Distance in NM. Default 5 NM. -- @return #AIRBOSS self -function AIRBOSS:SetCollisionDistance(distance) - self.collisiondist=UTILS.NMToMeters(distance or 5) +function AIRBOSS:SetCollisionDistance( Distance ) + self.collisiondist = UTILS.NMToMeters( Distance or 5 ) return self end --- Set the default recovery case. -- @param #AIRBOSS self --- @param #number case Case of recovery. Either 1, 2 or 3. Default 1. +-- @param #number Case Case of recovery. Either 1, 2 or 3. Default 1. -- @return #AIRBOSS self -function AIRBOSS:SetRecoveryCase(case) +function AIRBOSS:SetRecoveryCase( Case ) -- Set default case or 1. - self.defaultcase=case or 1 + self.defaultcase = Case or 1 -- Current case init. - self.case=self.defaultcase + self.case = self.defaultcase return self end @@ -2455,37 +2444,37 @@ end -- Usually, this is +-15 or +-30 degrees. You should not use and offset angle >= 90 degrees, because this will cause a devision by zero in some of the equations used to calculate the approach corridor. -- So best stick to the defaults up to 30 degrees. -- @param #AIRBOSS self --- @param #number offset Offset angle in degrees. Default 0. +-- @param #number Offset Offset angle in degrees. Default 0. -- @return #AIRBOSS self -function AIRBOSS:SetHoldingOffsetAngle(offset) +function AIRBOSS:SetHoldingOffsetAngle( Offset ) -- Set default angle or 0. - self.defaultoffset=offset or 0 + self.defaultoffset = Offset or 0 -- Current offset init. - self.holdingoffset=self.defaultoffset + self.holdingoffset = self.defaultoffset return self end --- Enable F10 menu to manually start recoveries. -- @param #AIRBOSS self --- @param #number duration Default duration of the recovery in minutes. Default 30 min. --- @param #number windondeck Default wind on deck in knots. Default 25 knots. --- @param #boolean uturn U-turn after recovery window closes on=true or off=false/nil. Default off. --- @param #number offset Relative Marshal radial in degrees for Case II/III recoveries. Default 30°. +-- @param #number Duration Default duration of the recovery in minutes. Default 30 min. +-- @param #number WindOnDeck Default wind on deck in knots. Default 25 knots. +-- @param #boolean Uturn U-turn after recovery window closes on=true or off=false/nil. Default off. +-- @param #number Offset Relative Marshal radial in degrees for Case II/III recoveries. Default 30°. -- @return #AIRBOSS self -function AIRBOSS:SetMenuRecovery(duration, windondeck, uturn, offset) +function AIRBOSS:SetMenuRecovery( Duration, WindOnDeck, Uturn, Offset ) - self.skipperMenu=true - self.skipperTime=duration or 30 - self.skipperSpeed=windondeck or 25 - self.skipperOffset=offset or 30 + self.skipperMenu = true + self.skipperTime = Duration or 30 + self.skipperSpeed = WindOnDeck or 25 + self.skipperOffset = Offset or 30 - if uturn then - self.skipperUturn=true + if Uturn then + self.skipperUturn = true else - self.skipperUturn=false + self.skipperUturn = false end return self @@ -2501,136 +2490,135 @@ end -- @param #number speed Speed in knots during turn into wind leg. -- @param #boolean uturn If true (or nil), carrier wil perform a U-turn and go back to where it came from before resuming its route to the next waypoint. If false, it will go directly to the next waypoint. -- @return #AIRBOSS.Recovery Recovery window. -function AIRBOSS:AddRecoveryWindow(starttime, stoptime, case, holdingoffset, turnintowind, speed, uturn) +function AIRBOSS:AddRecoveryWindow( starttime, stoptime, case, holdingoffset, turnintowind, speed, uturn ) -- Absolute mission time in seconds. - local Tnow=timer.getAbsTime() + local Tnow = timer.getAbsTime() - if starttime and type(starttime)=="number" then - starttime=UTILS.SecondsToClock(Tnow+starttime) + if starttime and type( starttime ) == "number" then + starttime = UTILS.SecondsToClock( Tnow + starttime ) end - if stoptime and type(stoptime)=="number" then - stoptime=UTILS.SecondsToClock(Tnow+stoptime) + if stoptime and type( stoptime ) == "number" then + stoptime = UTILS.SecondsToClock( Tnow + stoptime ) end - -- Input or now. - starttime=starttime or UTILS.SecondsToClock(Tnow) + starttime = starttime or UTILS.SecondsToClock( Tnow ) -- Set start time. - local Tstart=UTILS.ClockToSeconds(starttime) + local Tstart = UTILS.ClockToSeconds( starttime ) -- Set stop time. - local Tstop=stoptime and UTILS.ClockToSeconds(stoptime) or Tstart+90*60 + local Tstop = stoptime and UTILS.ClockToSeconds( stoptime ) or Tstart + 90 * 60 -- Consistancy check for timing. - if Tstart>Tstop then - self:E(string.format("ERROR: Recovery stop time %s lies before recovery start time %s! Recovery window rejected.", UTILS.SecondsToClock(Tstart), UTILS.SecondsToClock(Tstop))) + if Tstart > Tstop then + self:E( string.format( "ERROR: Recovery stop time %s lies before recovery start time %s! Recovery window rejected.", UTILS.SecondsToClock( Tstart ), UTILS.SecondsToClock( Tstop ) ) ) return self end - if Tstop<=Tnow then - self:I(string.format("WARNING: Recovery stop time %s already over. Tnow=%s! Recovery window rejected.", UTILS.SecondsToClock(Tstop), UTILS.SecondsToClock(Tnow))) + if Tstop <= Tnow then + self:I( string.format( "WARNING: Recovery stop time %s already over. Tnow=%s! Recovery window rejected.", UTILS.SecondsToClock( Tstop ), UTILS.SecondsToClock( Tnow ) ) ) return self end -- Case or default value. - case=case or self.defaultcase + case = case or self.defaultcase -- Holding offset or default value. - holdingoffset=holdingoffset or self.defaultoffset + holdingoffset = holdingoffset or self.defaultoffset -- Offset zero for case I. - if case==1 then - holdingoffset=0 + if case == 1 then + holdingoffset = 0 end -- Increase counter. - self.windowcount=self.windowcount+1 + self.windowcount = self.windowcount + 1 -- Recovery window. - local recovery={} --#AIRBOSS.Recovery - recovery.START=Tstart - recovery.STOP=Tstop - recovery.CASE=case - recovery.OFFSET=holdingoffset - recovery.OPEN=false - recovery.OVER=false - recovery.WIND=turnintowind - recovery.SPEED=speed or 20 - recovery.ID=self.windowcount + local recovery = {} -- #AIRBOSS.Recovery + recovery.START = Tstart + recovery.STOP = Tstop + recovery.CASE = case + recovery.OFFSET = holdingoffset + recovery.OPEN = false + recovery.OVER = false + recovery.WIND = turnintowind + recovery.SPEED = speed or 20 + recovery.ID = self.windowcount - if uturn==nil or uturn==true then - recovery.UTURN=true + if uturn == nil or uturn == true then + recovery.UTURN = true else - recovery.UTURN=false + recovery.UTURN = false end -- Add to table - table.insert(self.recoverytimes, recovery) + table.insert( self.recoverytimes, recovery ) return recovery end --- Define a set of AI groups that are handled by the airboss. -- @param #AIRBOSS self --- @param Core.Set#SET_GROUP setgroup The set of AI groups which are handled by the airboss. +-- @param Core.Set#SET_GROUP SetGroup The set of AI groups which are handled by the airboss. -- @return #AIRBOSS self -function AIRBOSS:SetSquadronAI(setgroup) - self.squadsetAI=setgroup +function AIRBOSS:SetSquadronAI( SetGroup ) + self.squadsetAI = SetGroup return self end --- Define a set of AI groups that excluded from AI handling. Members of this set will be left allone by the airboss and not forced into the Marshal pattern. -- @param #AIRBOSS self --- @param Core.Set#SET_GROUP setgroup The set of AI groups which are excluded. +-- @param Core.Set#SET_GROUP SetGroup The set of AI groups which are excluded. -- @return #AIRBOSS self -function AIRBOSS:SetExcludeAI(setgroup) - self.excludesetAI=setgroup +function AIRBOSS:SetExcludeAI( SetGroup ) + self.excludesetAI = SetGroup return self end --- Add a group to the exclude set. If no set exists, it is created. -- @param #AIRBOSS self --- @param Wrapper.Group#GROUP group The group to be excluded. +-- @param Wrapper.Group#GROUP Group The group to be excluded. -- @return #AIRBOSS self -function AIRBOSS:AddExcludeAI(group) +function AIRBOSS:AddExcludeAI( Group ) - self.excludesetAI=self.excludesetAI or SET_GROUP:New() + self.excludesetAI = self.excludesetAI or SET_GROUP:New() - self.excludesetAI:AddGroup(group) + self.excludesetAI:AddGroup( Group ) return self end --- Close currently running recovery window and stop recovery ops. Recovery window is deleted. -- @param #AIRBOSS self --- @param #number delay (Optional) Delay in seconds before the window is deleted. -function AIRBOSS:CloseCurrentRecoveryWindow(delay) +-- @param #number Delay (Optional) Delay in seconds before the window is deleted. +function AIRBOSS:CloseCurrentRecoveryWindow( Delay ) - if delay and delay>0 then - --SCHEDULER:New(nil, self.CloseCurrentRecoveryWindow, {self}, delay) - self:ScheduleOnce(delay, self.CloseCurrentRecoveryWindow, self) + if Delay and Delay > 0 then + -- SCHEDULER:New(nil, self.CloseCurrentRecoveryWindow, {self}, delay) + self:ScheduleOnce( Delay, self.CloseCurrentRecoveryWindow, self ) else if self:IsRecovering() and self.recoverywindow and self.recoverywindow.OPEN then self:RecoveryStop() - self.recoverywindow.OPEN=false - self.recoverywindow.OVER=true - self:DeleteRecoveryWindow(self.recoverywindow) + self.recoverywindow.OPEN = false + self.recoverywindow.OVER = true + self:DeleteRecoveryWindow( self.recoverywindow ) end end end --- Delete all recovery windows. -- @param #AIRBOSS self --- @param #number delay (Optional) Delay in seconds before the windows are deleted. +-- @param #number Delay (Optional) Delay in seconds before the windows are deleted. -- @return #AIRBOSS self -function AIRBOSS:DeleteAllRecoveryWindows(delay) +function AIRBOSS:DeleteAllRecoveryWindows( Delay ) -- Loop over all recovery windows. - for _,recovery in pairs(self.recoverytimes) do - self:T(self.lid..string.format("Deleting recovery window ID %s", tostring(recovery.ID))) - self:DeleteRecoveryWindow(recovery, delay) + for _, recovery in pairs( self.recoverytimes ) do + self:I( self.lid .. string.format( "Deleting recovery window ID %s", tostring( recovery.ID ) ) ) + self:DeleteRecoveryWindow( recovery, Delay ) end return self @@ -2640,11 +2628,11 @@ end -- @param #AIRBOSS self -- @param #number id The ID of the recovery window. -- @return #AIRBOSS.Recovery Recovery window with the right ID or nil if no such window exists. -function AIRBOSS:GetRecoveryWindowByID(id) +function AIRBOSS:GetRecoveryWindowByID( id ) if id then - for _,_window in pairs(self.recoverytimes) do - local window=_window --#AIRBOSS.Recovery - if window and window.ID==id then + for _, _window in pairs( self.recoverytimes ) do + local window = _window -- #AIRBOSS.Recovery + if window and window.ID == id then return window end end @@ -2654,25 +2642,25 @@ end --- Delete a recovery window. If the window is currently open, it is closed and the recovery stopped. -- @param #AIRBOSS self --- @param #AIRBOSS.Recovery window Recovery window. --- @param #number delay Delay in seconds, before the window is deleted. -function AIRBOSS:DeleteRecoveryWindow(window, delay) +-- @param #AIRBOSS.Recovery Window Recovery window. +-- @param #number Delay Delay in seconds, before the window is deleted. +function AIRBOSS:DeleteRecoveryWindow( Window, Delay ) - if delay and delay>0 then + if Delay and Delay > 0 then -- Delayed call. - --SCHEDULER:New(nil, self.DeleteRecoveryWindow, {self, window}, delay) - self:ScheduleOnce(delay, self.DeleteRecoveryWindow, self, window) + -- SCHEDULER:New(nil, self.DeleteRecoveryWindow, {self, window}, delay) + self:ScheduleOnce( Delay, self.DeleteRecoveryWindow, self, Window ) else - for i,_recovery in pairs(self.recoverytimes) do - local recovery=_recovery --#AIRBOSS.Recovery + for i, _recovery in pairs( self.recoverytimes ) do + local recovery = _recovery -- #AIRBOSS.Recovery - if window and window.ID==recovery.ID then - if window.OPEN then + if Window and Window.ID == recovery.ID then + if Window.OPEN then -- Window is currently open. self:RecoveryStop() else - table.remove(self.recoverytimes, i) + table.remove( self.recoverytimes, i ) end end @@ -2682,10 +2670,10 @@ end --- Set time before carrier turns and recovery window opens. -- @param #AIRBOSS self --- @param #number interval Time interval in seconds. Default 300 sec. +-- @param #number Interval Time interval in seconds. Default 300 sec. -- @return #AIRBOSS self -function AIRBOSS:SetRecoveryTurnTime(interval) - self.dTturn=interval or 300 +function AIRBOSS:SetRecoveryTurnTime( Interval ) + self.dTturn = Interval or 300 return self end @@ -2693,145 +2681,142 @@ end -- @param #AIRBOSS self -- @param #number Dcorr Correction distance in meters. Default 12 m. -- @return #AIRBOSS self -function AIRBOSS:SetMPWireCorrection(Dcorr) - self.mpWireCorrection=Dcorr or 12 +function AIRBOSS:SetMPWireCorrection( Dcorr ) + self.mpWireCorrection = Dcorr or 12 return self end --- Set time interval for updating queues and other stuff. -- @param #AIRBOSS self --- @param #number interval Time interval in seconds. Default 30 sec. +-- @param #number TimeInterval Time interval in seconds. Default 30 sec. -- @return #AIRBOSS self -function AIRBOSS:SetQueueUpdateTime(interval) - self.dTqueue=interval or 30 +function AIRBOSS:SetQueueUpdateTime( TimeInterval ) + self.dTqueue = TimeInterval or 30 return self end --- Set time interval between LSO calls. Optimal time in the groove is ~16 seconds. So the default of 4 seconds gives around 3-4 correction calls in the groove. -- @param #AIRBOSS self --- @param #number interval Time interval in seconds between LSO calls. Default 4 sec. +-- @param #number TimeInterval Time interval in seconds between LSO calls. Default 4 sec. -- @return #AIRBOSS self -function AIRBOSS:SetLSOCallInterval(timeinterval) - self.LSOdT=timeinterval or 4 +function AIRBOSS:SetLSOCallInterval( TimeInterval ) + self.LSOdT = TimeInterval or 4 return self end --- Airboss is a rather nice guy and not strictly following the rules. Fore example, he does allow you into the landing pattern if you are not coming from the Marshal stack. -- @param #AIRBOSS self --- @param #boolean switch If true or nil, Airboss bends the rules a bit. +-- @param #boolean Switch If true or nil, Airboss bends the rules a bit. -- @return #AIRBOSS self -function AIRBOSS:SetAirbossNiceGuy(switch) - if switch==true or switch==nil then - self.airbossnice=true +function AIRBOSS:SetAirbossNiceGuy( Switch ) + if Switch == true or Switch == nil then + self.airbossnice = true else - self.airbossnice=false + self.airbossnice = false end return self end --- Allow emergency landings, i.e. bypassing any pattern and go directly to final approach. -- @param #AIRBOSS self --- @param #boolean switch If true or nil, emergency landings are okay. +-- @param #boolean Switch If true or nil, emergency landings are okay. -- @return #AIRBOSS self -function AIRBOSS:SetEmergencyLandings(switch) - if switch==true or switch==nil then - self.emergency=true +function AIRBOSS:SetEmergencyLandings( Switch ) + if Switch == true or Switch == nil then + self.emergency = true else - self.emergency=false + self.emergency = false end return self end - --- Despawn AI groups after they they shut down their engines. -- @param #AIRBOSS self --- @param #boolean switch If true or nil, AI groups are despawned. +-- @param #boolean Switch If true or nil, AI groups are despawned. -- @return #AIRBOSS self -function AIRBOSS:SetDespawnOnEngineShutdown(switch) - if switch==true or switch==nil then - self.despawnshutdown=true +function AIRBOSS:SetDespawnOnEngineShutdown( Switch ) + if Switch == true or Switch == nil then + self.despawnshutdown = true else - self.despawnshutdown=false + self.despawnshutdown = false end return self end --- Respawn AI groups once they reach the CCA. Clears any attached airbases and allows making them land on the carrier via script. -- @param #AIRBOSS self --- @param #boolean switch If true or nil, AI groups are respawned. +-- @param #boolean Switch If true or nil, AI groups are respawned. -- @return #AIRBOSS self -function AIRBOSS:SetRespawnAI(switch) - if switch==true or switch==nil then - self.respawnAI=true +function AIRBOSS:SetRespawnAI( Switch ) + if Switch == true or Switch == nil then + self.respawnAI = true else - self.respawnAI=false + self.respawnAI = false end return self end --- Give AI aircraft the refueling task if a recovery tanker is present or send them to the nearest divert airfield. -- @param #AIRBOSS self --- @param #number lowfuelthreshold Low fuel threshold in percent. AI will go refueling if their fuel level drops below this value. Default 10 %. +-- @param #number LowFuelThreshold Low fuel threshold in percent. AI will go refueling if their fuel level drops below this value. Default 10 %. -- @return #AIRBOSS self -function AIRBOSS:SetRefuelAI(lowfuelthreshold) - self.lowfuelAI=lowfuelthreshold or 10 +function AIRBOSS:SetRefuelAI( LowFuelThreshold ) + self.lowfuelAI = LowFuelThreshold or 10 return self end --- Set max alitude to register flights in the initial zone. Aircraft above this altitude will not be registerered. -- @param #AIRBOSS self --- @param #number altitude Max alitude in feet. Default 1300 ft. +-- @param #number MaxAltitude Max alitude in feet. Default 1300 ft. -- @return #AIRBOSS self -function AIRBOSS:SetInitialMaxAlt(altitude) - self.initialmaxalt=UTILS.FeetToMeters(altitude or 1300) +function AIRBOSS:SetInitialMaxAlt( MaxAltitude ) + self.initialmaxalt = UTILS.FeetToMeters( MaxAltitude or 1300 ) return self end - ---- Set folder where the airboss sound files are located **within you mission (miz) file**. +--- Set folder path where the airboss sound files are located **within you mission (miz) file**. -- The default path is "l10n/DEFAULT/" but sound files simply copied there will be removed by DCS the next time you save the mission. -- However, if you create a new folder inside the miz file, which contains the sounds, it will not be deleted and can be used. -- @param #AIRBOSS self --- @param #string folderpath The path to the sound files, e.g. "Airboss Soundfiles/". +-- @param #string FolderPath The path to the sound files, e.g. "Airboss Soundfiles/". -- @return #AIRBOSS self -function AIRBOSS:SetSoundfilesFolder(folderpath) +function AIRBOSS:SetSoundfilesFolder( FolderPath ) -- Check that it ends with / - if folderpath then - local lastchar=string.sub(folderpath, -1) - if lastchar~="/" then - folderpath=folderpath.."/" + if FolderPath then + local lastchar = string.sub( FolderPath, -1 ) + if lastchar ~= "/" then + FolderPath = FolderPath .. "/" end end -- Folderpath. - self.soundfolder=folderpath + self.soundfolder = FolderPath -- Info message. - self:I(self.lid..string.format("Setting sound files folder to: %s", self.soundfolder)) + self:I( self.lid .. string.format( "Setting sound files folder to: %s", self.soundfolder ) ) return self end --- Set time interval for updating player status and other things. -- @param #AIRBOSS self --- @param #number interval Time interval in seconds. Default 0.5 sec. +-- @param #number TimeInterval Time interval in seconds. Default 0.5 sec. -- @return #AIRBOSS self -function AIRBOSS:SetStatusUpdateTime(interval) - self.dTstatus=interval or 0.5 +function AIRBOSS:SetStatusUpdateTime( TimeInterval ) + self.dTstatus = TimeInterval or 0.5 return self end --- Set duration how long messages are displayed to players. -- @param #AIRBOSS self --- @param #number duration Duration in seconds. Default 10 sec. +-- @param #number Duration Duration in seconds. Default 10 sec. -- @return #AIRBOSS self -function AIRBOSS:SetDefaultMessageDuration(duration) - self.Tmessage=duration or 10 +function AIRBOSS:SetDefaultMessageDuration( Duration ) + self.Tmessage = Duration or 10 return self end - --- Set glideslope error thresholds. -- @param #AIRBOSS self -- @param #number _max @@ -2841,13 +2826,29 @@ end -- @param #number Low -- @param #number LOW -- @return #AIRBOSS self + function AIRBOSS:SetGlideslopeErrorThresholds(_max,_min, High, HIGH, Low, LOW) + + --Check if V/STOL Carrier + if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then + + -- allow a larger GSE for V/STOL operations --Pene Testing + self.gle._max=_max or 0.7 + self.gle.High=High or 1.4 + self.gle.HIGH=HIGH or 1.9 + self.gle._min=_min or -0.5 + self.gle.Low=Low or -1.2 + self.gle.LOW=LOW or -1.5 + -- CVN values + else self.gle._max=_max or 0.4 self.gle.High=High or 0.8 self.gle.HIGH=HIGH or 1.5 self.gle._min=_min or -0.3 self.gle.Low=Low or -0.6 self.gle.LOW=LOW or -0.9 + end + return self end @@ -2862,7 +2863,23 @@ end -- @param #number RightMed -- @param #number RIGHT -- @return #AIRBOSS self + function AIRBOSS:SetLineupErrorThresholds(_max,_min, Left, LeftMed, LEFT, Right, RightMed, RIGHT) + + --Check if V/STOL Carrier -- Pene testing + if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then + + -- V/STOL Values -- allow a larger LUE for V/STOL operations + self.lue._max=_max or 1.8 + self.lue._min=_min or -1.8 + self.lue.Left=Left or -2.8 + self.lue.LeftMed=LeftMed or -3.8 + self.lue.LEFT=LEFT or -4.5 + self.lue.Right=Right or 2.8 + self.lue.RightMed=RightMed or 3.8 + self.lue.RIGHT=RIGHT or 4.5 + -- CVN Values + else self.lue._max=_max or 0.5 self.lue._min=_min or -0.5 self.lue.Left=Left or -1.0 @@ -2871,109 +2888,110 @@ function AIRBOSS:SetLineupErrorThresholds(_max,_min, Left, LeftMed, LEFT, Right, self.lue.Right=Right or 1.0 self.lue.RightMed=RightMed or 2.0 self.lue.RIGHT=RIGHT or 3.0 + end + return self end --- Set Case I Marshal radius. This is the radius of the valid zone around "the post" aircraft are supposed to be holding in the Case I Marshal stack. -- The post is 2.5 NM port of the carrier. -- @param #AIRBOSS self --- @param #number Radius in NM. Default 2.8 NM, which gives a diameter of 5.6 NM. +-- @param #number Radius Radius in NM. Default 2.8 NM, which gives a diameter of 5.6 NM. -- @return #AIRBOSS self -function AIRBOSS:SetMarshalRadius(radius) - self.marshalradius=UTILS.NMToMeters(radius or 2.8) +function AIRBOSS:SetMarshalRadius( Radius ) + self.marshalradius = UTILS.NMToMeters( Radius or 2.8 ) return self end --- Optimized F10 radio menu for a single carrier. The menu entries will be stored directly under F10 Other/Airboss/ and not F10 Other/Airboss/"Carrier Alias"/. -- **WARNING**: If you use this with two airboss objects/carriers, the radio menu will be screwed up! -- @param #AIRBOSS self --- @param #boolean switch If true or nil single menu is enabled. If false, menu is for multiple carriers in the mission. +-- @param #boolean Switch If true or nil single menu is enabled. If false, menu is for multiple carriers in the mission. -- @return #AIRBOSS self -function AIRBOSS:SetMenuSingleCarrier(switch) - if switch==true or switch==nil then - self.menusingle=true +function AIRBOSS:SetMenuSingleCarrier( Switch ) + if Switch == true or Switch == nil then + self.menusingle = true else - self.menusingle=false + self.menusingle = false end return self end --- Enable or disable F10 radio menu for marking zones via smoke or flares. -- @param #AIRBOSS self --- @param #boolean switch If true or nil, menu is enabled. If false, menu is not available to players. +-- @param #boolean Switch If true or nil, menu is enabled. If false, menu is not available to players. -- @return #AIRBOSS self -function AIRBOSS:SetMenuMarkZones(switch) - if switch==nil or switch==true then - self.menumarkzones=true +function AIRBOSS:SetMenuMarkZones( Switch ) + if Switch == nil or Switch == true then + self.menumarkzones = true else - self.menumarkzones=false + self.menumarkzones = false end return self end --- Enable or disable F10 radio menu for marking zones via smoke. -- @param #AIRBOSS self --- @param #boolean switch If true or nil, menu is enabled. If false, menu is not available to players. +-- @param #boolean Switch If true or nil, menu is enabled. If false, menu is not available to players. -- @return #AIRBOSS self -function AIRBOSS:SetMenuSmokeZones(switch) - if switch==nil or switch==true then - self.menusmokezones=true +function AIRBOSS:SetMenuSmokeZones( Switch ) + if Switch == nil or Switch == true then + self.menusmokezones = true else - self.menusmokezones=false + self.menusmokezones = false end return self end --- Enable saving of player's trap sheets and specify an optional directory path. -- @param #AIRBOSS self --- @param #string path (Optional) Path where to save the trap sheets. --- @param #string prefix (Optional) Prefix for trap sheet files. File name will be saved as *prefix_aircrafttype-0001.csv*, *prefix_aircrafttype-0002.csv*, etc. +-- @param #string Path (Optional) Path where to save the trap sheets. +-- @param #string Prefix (Optional) Prefix for trap sheet files. File name will be saved as *prefix_aircrafttype-0001.csv*, *prefix_aircrafttype-0002.csv*, etc. -- @return #AIRBOSS self -function AIRBOSS:SetTrapSheet(path, prefix) +function AIRBOSS:SetTrapSheet( Path, Prefix ) if io then - self.trapsheet=true - self.trappath=path - self.trapprefix=prefix + self.trapsheet = true + self.trappath = Path + self.trapprefix = Prefix else - self:E(self.lid.."ERROR: io is not desanitized. Cannot save trap sheet.") + self:E( self.lid .. "ERROR: io is not desanitized. Cannot save trap sheet." ) end return self end --- Specify weather the mission has set static or dynamic weather. -- @param #AIRBOSS self --- @param #boolean switch If true or nil, mission uses static weather. If false, dynamic weather is used in this mission. +-- @param #boolean Switch If true or nil, mission uses static weather. If false, dynamic weather is used in this mission. -- @return #AIRBOSS self -function AIRBOSS:SetStaticWeather(switch) - if switch==nil or switch==true then - self.staticweather=true +function AIRBOSS:SetStaticWeather( Switch ) + if Switch == nil or Switch == true then + self.staticweather = true else - self.staticweather=false + self.staticweather = false end return self end - --- Disable automatic TACAN activation -- @param #AIRBOSS self -- @return #AIRBOSS self function AIRBOSS:SetTACANoff() - self.TACANon=false + self.TACANon = false return self end ---- Set TACAN channel of carrier. +--- Set TACAN channel of carrier and switches TACAN on. -- @param #AIRBOSS self --- @param #number channel TACAN channel. Default 74. --- @param #string mode TACAN mode, i.e. "X" or "Y". Default "X". --- @param #string morsecode Morse code identifier. Three letters, e.g. "STN". +-- @param #number Channel (Optional) TACAN channel. Default 74. +-- @param #string Mode (Optional) TACAN mode, i.e. "X" or "Y". Default "X". +-- @param #string MorseCode (Optional) Morse code identifier. Three letters, e.g. "STN". Default "STN". -- @return #AIRBOSS self -function AIRBOSS:SetTACAN(channel, mode, morsecode) +function AIRBOSS:SetTACAN( Channel, Mode, MorseCode ) - self.TACANchannel=channel or 74 - self.TACANmode=mode or "X" - self.TACANmorse=morsecode or "STN" - self.TACANon=true + self.TACANchannel = Channel or 74 + self.TACANmode = Mode or "X" + self.TACANmorse = MorseCode or "STN" + self.TACANon = true return self end @@ -2982,79 +3000,78 @@ end -- @param #AIRBOSS self -- @return #AIRBOSS self function AIRBOSS:SetICLSoff() - self.ICLSon=false + self.ICLSon = false return self end --- Set ICLS channel of carrier. -- @param #AIRBOSS self --- @param #number channel ICLS channel. Default 1. --- @param #string morsecode Morse code identifier. Three letters, e.g. "STN". Default "STN". +-- @param #number Channel (Optional) ICLS channel. Default 1. +-- @param #string MorseCode (Optional) Morse code identifier. Three letters, e.g. "STN". Default "STN". -- @return #AIRBOSS self -function AIRBOSS:SetICLS(channel, morsecode) +function AIRBOSS:SetICLS( Channel, MorseCode ) - self.ICLSchannel=channel or 1 - self.ICLSmorse=morsecode or "STN" - self.ICLSon=true + self.ICLSchannel = Channel or 1 + self.ICLSmorse = MorseCode or "STN" + self.ICLSon = true return self end - --- Set beacon (TACAN/ICLS) time refresh interfal in case the beacons die. -- @param #AIRBOSS self --- @param #number interval Time interval in seconds. Default 1200 sec = 20 min. +-- @param #number TimeInterval (Optional) Time interval in seconds. Default 1200 sec = 20 min. -- @return #AIRBOSS self -function AIRBOSS:SetBeaconRefresh(interval) - self.dTbeacon=interval or (20*60) + +function AIRBOSS:SetBeaconRefresh( TimeInterval ) + self.dTbeacon = TimeInterval or (20 * 60) return self end - --- Set LSO radio frequency and modulation. Default frequency is 264 MHz AM. -- @param #AIRBOSS self --- @param #number frequency Frequency in MHz. Default 264 MHz. --- @param #string modulation Modulation, i.e. "AM" (default) or "FM". +-- @param #number Frequency (Optional) Frequency in MHz. Default 264 MHz. +-- @param #string Modulation (Optional) Modulation, "AM" or "FM". Default "AM". -- @return #AIRBOSS self -function AIRBOSS:SetLSORadio(frequency, modulation) +function AIRBOSS:SetLSORadio( Frequency, Modulation ) - self.LSOFreq=(frequency or 264) - modulation=modulation or "AM" + self.LSOFreq = (Frequency or 264) + Modulation = Modulation or "AM" - if modulation=="FM" then - self.LSOModu=radio.modulation.FM + if Modulation == "FM" then + self.LSOModu = radio.modulation.FM else - self.LSOModu=radio.modulation.AM + self.LSOModu = radio.modulation.AM end - self.LSORadio={} --#AIRBOSS.Radio - self.LSORadio.frequency=self.LSOFreq - self.LSORadio.modulation=self.LSOModu - self.LSORadio.alias="LSO" + self.LSORadio = {} -- #AIRBOSS.Radio + self.LSORadio.frequency = self.LSOFreq + self.LSORadio.modulation = self.LSOModu + self.LSORadio.alias = "LSO" return self end --- Set carrier radio frequency and modulation. Default frequency is 305 MHz AM. -- @param #AIRBOSS self --- @param #number frequency Frequency in MHz. Default 305 MHz. --- @param #string modulation Modulation, i.e. "AM" (default) or "FM". +-- @param #number Frequency (Optional) Frequency in MHz. Default 305 MHz. +-- @param #string Modulation (Optional) Modulation, "AM" or "FM". Default "AM". -- @return #AIRBOSS self -function AIRBOSS:SetMarshalRadio(frequency, modulation) +function AIRBOSS:SetMarshalRadio( Frequency, Modulation ) - self.MarshalFreq=frequency or 305 - modulation=modulation or "AM" + self.MarshalFreq = Frequency or 305 + Modulation = Modulation or "AM" - if modulation=="FM" then - self.MarshalModu=radio.modulation.FM + if Modulation == "FM" then + self.MarshalModu = radio.modulation.FM else - self.MarshalModu=radio.modulation.AM + self.MarshalModu = radio.modulation.AM end - self.MarshalRadio={} --#AIRBOSS.Radio - self.MarshalRadio.frequency=self.MarshalFreq - self.MarshalRadio.modulation=self.MarshalModu - self.MarshalRadio.alias="MARSHAL" + self.MarshalRadio = {} -- #AIRBOSS.Radio + self.MarshalRadio.frequency = self.MarshalFreq + self.MarshalRadio.modulation = self.MarshalModu + self.MarshalRadio.alias = "MARSHAL" return self end @@ -3063,8 +3080,8 @@ end -- @param #AIRBOSS self -- @param #string unitname Name of the unit. -- @return #AIRBOSS self -function AIRBOSS:SetRadioUnitName(unitname) - self.senderac=unitname +function AIRBOSS:SetRadioUnitName( unitname ) + self.senderac = unitname return self end @@ -3072,8 +3089,8 @@ end -- @param #AIRBOSS self -- @param #string unitname Name of the unit. -- @return #AIRBOSS self -function AIRBOSS:SetRadioRelayLSO(unitname) - self.radiorelayLSO=unitname +function AIRBOSS:SetRadioRelayLSO( unitname ) + self.radiorelayLSO = unitname return self end @@ -3081,17 +3098,16 @@ end -- @param #AIRBOSS self -- @param #string unitname Name of the unit. -- @return #AIRBOSS self -function AIRBOSS:SetRadioRelayMarshal(unitname) - self.radiorelayMSH=unitname +function AIRBOSS:SetRadioRelayMarshal( unitname ) + self.radiorelayMSH = unitname return self end - --- Use user sound output instead of radio transmission for messages. Might be handy if radio transmissions are broken. -- @param #AIRBOSS self -- @return #AIRBOSS self function AIRBOSS:SetUserSoundRadio() - self.usersoundradio=true + self.usersoundradio = true return self end @@ -3099,34 +3115,33 @@ end -- @param #AIRBOSS self -- @param #number delay Delay in seconds be sound check starts. -- @return #AIRBOSS self -function AIRBOSS:SoundCheckLSO(delay) +function AIRBOSS:SoundCheckLSO( delay ) - if delay and delay>0 then + if delay and delay > 0 then -- Delayed call. - --SCHEDULER:New(nil, AIRBOSS.SoundCheckLSO, {self}, delay) - self:ScheduleOnce(delay, AIRBOSS.SoundCheckLSO, self) + -- SCHEDULER:New(nil, AIRBOSS.SoundCheckLSO, {self}, delay) + self:ScheduleOnce( delay, AIRBOSS.SoundCheckLSO, self ) else + local text = "Playing LSO sound files:" - local text="Playing LSO sound files:" - - for _name,_call in pairs(self.LSOCall) do - local call=_call --#AIRBOSS.RadioCall + for _name, _call in pairs( self.LSOCall ) do + local call = _call -- #AIRBOSS.RadioCall -- Debug text. - text=text..string.format("\nFile=%s.%s, duration=%.2f sec, loud=%s, subtitle=\"%s\".", call.file, call.suffix, call.duration, tostring(call.loud), call.subtitle) + text = text .. string.format( "\nFile=%s.%s, duration=%.2f sec, loud=%s, subtitle=\"%s\".", call.file, call.suffix, call.duration, tostring( call.loud ), call.subtitle ) -- Radio transmission to queue. - self:RadioTransmission(self.LSORadio, call, false) + self:RadioTransmission( self.LSORadio, call, false ) -- Also play the loud version. if call.loud then - self:RadioTransmission(self.LSORadio, call, true) + self:RadioTransmission( self.LSORadio, call, true ) end end -- Debug message. - self:T(self.lid..text) + self:I( self.lid .. text ) end end @@ -3135,34 +3150,33 @@ end -- @param #AIRBOSS self -- @param #number delay Delay in seconds be sound check starts. -- @return #AIRBOSS self -function AIRBOSS:SoundCheckMarshal(delay) +function AIRBOSS:SoundCheckMarshal( delay ) - if delay and delay>0 then + if delay and delay > 0 then -- Delayed call. - --SCHEDULER:New(nil, AIRBOSS.SoundCheckMarshal, {self}, delay) - self:ScheduleOnce(delay, AIRBOSS.SoundCheckMarshal, self) + -- SCHEDULER:New(nil, AIRBOSS.SoundCheckMarshal, {self}, delay) + self:ScheduleOnce( delay, AIRBOSS.SoundCheckMarshal, self ) else + local text = "Playing Marshal sound files:" - local text="Playing Marshal sound files:" - - for _name,_call in pairs(self.MarshalCall) do - local call=_call --#AIRBOSS.RadioCall + for _name, _call in pairs( self.MarshalCall ) do + local call = _call -- #AIRBOSS.RadioCall -- Debug text. - text=text..string.format("\nFile=%s.%s, duration=%.2f sec, loud=%s, subtitle=\"%s\".", call.file, call.suffix, call.duration, tostring(call.loud), call.subtitle) + text = text .. string.format( "\nFile=%s.%s, duration=%.2f sec, loud=%s, subtitle=\"%s\".", call.file, call.suffix, call.duration, tostring( call.loud ), call.subtitle ) -- Radio transmission to queue. - self:RadioTransmission(self.MarshalRadio, call, false) + self:RadioTransmission( self.MarshalRadio, call, false ) -- Also play the loud version. if call.loud then - self:RadioTransmission(self.MarshalRadio, call, true) + self:RadioTransmission( self.MarshalRadio, call, true ) end end -- Debug message. - self:T(self.lid..text) + self:I( self.lid .. text ) end end @@ -3171,11 +3185,11 @@ end -- @param #AIRBOSS self -- @param #number nmax Max number. Default 4. Minimum is 1, maximum is 6. -- @return #AIRBOSS self -function AIRBOSS:SetMaxLandingPattern(nmax) - nmax=nmax or 4 - nmax=math.max(nmax,1) - nmax=math.min(nmax,6) - self.Nmaxpattern=nmax +function AIRBOSS:SetMaxLandingPattern( nmax ) + nmax = nmax or 4 + nmax = math.max( nmax, 1 ) + nmax = math.min( nmax, 6 ) + self.Nmaxpattern = nmax return self end @@ -3184,9 +3198,9 @@ end -- @param #AIRBOSS self -- @param #number nmax Max number of stacks available to players and AI flights. Default 3, i.e. angels 2, 3, 4. Minimum is 1. -- @return #AIRBOSS self -function AIRBOSS:SetMaxMarshalStacks(nmax) - self.Nmaxmarshal=nmax or 3 - self.Nmaxmarshal=math.max(self.Nmaxmarshal, 1) +function AIRBOSS:SetMaxMarshalStacks( nmax ) + self.Nmaxmarshal = nmax or 3 + self.Nmaxmarshal = math.max( self.Nmaxmarshal, 1 ) return self end @@ -3194,11 +3208,11 @@ end -- @param #AIRBOSS self -- @param #number nmax Number of max allowed members including the lead itself. For example, Nmax=2 means a section lead plus one member. -- @return #AIRBOSS self -function AIRBOSS:SetMaxSectionSize(nmax) - nmax=nmax or 2 - nmax=math.max(nmax,1) - nmax=math.min(nmax,4) - self.NmaxSection=nmax-1 -- We substract one because internally the section lead is not counted! +function AIRBOSS:SetMaxSectionSize( nmax ) + nmax = nmax or 2 + nmax = math.max( nmax, 1 ) + nmax = math.min( nmax, 4 ) + self.NmaxSection = nmax - 1 -- We substract one because internally the section lead is not counted! return self end @@ -3206,20 +3220,19 @@ end -- @param #AIRBOSS self -- @param #number nmax Number of max allowed flights per stack. Default is two. Minimum is one, maximum is 4. -- @return #AIRBOSS self -function AIRBOSS:SetMaxFlightsPerStack(nmax) - nmax=nmax or 2 - nmax=math.max(nmax,1) - nmax=math.min(nmax,4) - self.NmaxStack=nmax +function AIRBOSS:SetMaxFlightsPerStack( nmax ) + nmax = nmax or 2 + nmax = math.max( nmax, 1 ) + nmax = math.min( nmax, 4 ) + self.NmaxStack = nmax return self end - --- Handle AI aircraft. -- @param #AIRBOSS self -- @return #AIRBOSS self function AIRBOSS:SetHandleAION() - self.handleai=true + self.handleai = true return self end @@ -3245,17 +3258,16 @@ end -- @param #AIRBOSS self -- @return #AIRBOSS self function AIRBOSS:SetHandleAIOFF() - self.handleai=false + self.handleai = false return self end - --- Define recovery tanker associated with the carrier. -- @param #AIRBOSS self -- @param Ops.RecoveryTanker#RECOVERYTANKER recoverytanker Recovery tanker object. -- @return #AIRBOSS self -function AIRBOSS:SetRecoveryTanker(recoverytanker) - self.tanker=recoverytanker +function AIRBOSS:SetRecoveryTanker( recoverytanker ) + self.tanker = recoverytanker return self end @@ -3263,8 +3275,8 @@ end -- @param #AIRBOSS self -- @param Ops.RecoveryTanker#RECOVERYTANKER awacs AWACS (recovery tanker) object. -- @return #AIRBOSS self -function AIRBOSS:SetAWACS(awacs) - self.awacs=awacs +function AIRBOSS:SetAWACS( awacs ) + self.awacs = awacs return self end @@ -3276,23 +3288,23 @@ end -- @param #AIRBOSS self -- @param #string skill Player skill. Default "Naval Aviator". -- @return #AIRBOSS self -function AIRBOSS:SetDefaultPlayerSkill(skill) +function AIRBOSS:SetDefaultPlayerSkill( skill ) -- Set skill or normal. - self.defaultskill=skill or AIRBOSS.Difficulty.NORMAL + self.defaultskill = skill or AIRBOSS.Difficulty.NORMAL -- Check that defualt skill is valid. - local gotit=false - for _,_skill in pairs(AIRBOSS.Difficulty) do - if _skill==self.defaultskill then - gotit=true + local gotit = false + for _, _skill in pairs( AIRBOSS.Difficulty ) do + if _skill == self.defaultskill then + gotit = true end end -- If invalid user input, fall back to normal. if not gotit then - self.defaultskill=AIRBOSS.Difficulty.NORMAL - self:E(self.lid..string.format("ERROR: Invalid default skill = %s. Resetting to Naval Aviator.", tostring(skill))) + self.defaultskill = AIRBOSS.Difficulty.NORMAL + self:E( self.lid .. string.format( "ERROR: Invalid default skill = %s. Resetting to Naval Aviator.", tostring( skill ) ) ) end return self @@ -3303,10 +3315,10 @@ end -- @param #string path Path where to save the asset data file. Default is the DCS root installation directory or your "Saved Games\\DCS" folder if lfs was desanitized. -- @param #string filename File name. Default is generated automatically from airboss carrier name/alias. -- @return #AIRBOSS self -function AIRBOSS:SetAutoSave(path, filename) - self.autosave=true - self.autosavepath=path - self.autosavefile=filename +function AIRBOSS:SetAutoSave( path, filename ) + self.autosave = true + self.autosavepath = path + self.autosavefile = filename return self end @@ -3314,7 +3326,7 @@ end -- @param #AIRBOSS self -- @return #AIRBOSS self function AIRBOSS:SetDebugModeON() - self.Debug=true + self.Debug = true return self end @@ -3322,11 +3334,11 @@ end -- @param #AIRBOSS self -- @param #boolean switch If true or nil, patrol until the end of time. If false, go along the waypoints once and stop. -- @return #AIRBOSS self -function AIRBOSS:SetPatrolAdInfinitum(switch) - if switch==false then - self.adinfinitum=false +function AIRBOSS:SetPatrolAdInfinitum( switch ) + if switch == false then + self.adinfinitum = false else - self.adinfinitum=true + self.adinfinitum = true end return self end @@ -3335,8 +3347,8 @@ end -- @param #AIRBOSS self -- @param #number declination Declination in degrees or nil for default declination of the map. -- @return #AIRBOSS self -function AIRBOSS:SetMagneticDeclination(declination) - self.magvar=declination or UTILS.GetMagneticDeclination() +function AIRBOSS:SetMagneticDeclination( declination ) + self.magvar = declination or UTILS.GetMagneticDeclination() return self end @@ -3344,7 +3356,7 @@ end -- @param #AIRBOSS self -- @return #AIRBOSS self function AIRBOSS:SetDebugModeOFF() - self.Debug=false + self.Debug = false return self end @@ -3353,12 +3365,12 @@ end -- @param #boolean InSeconds If true, abs. mission time seconds is returned. Default is a clock #string. -- @return #string Clock start (or start time in abs. seconds). -- @return #string Clock stop (or stop time in abs. seconds). -function AIRBOSS:GetNextRecoveryTime(InSeconds) +function AIRBOSS:GetNextRecoveryTime( InSeconds ) if self.recoverywindow then if InSeconds then return self.recoverywindow.START, self.recoverywindow.STOP else - return UTILS.SecondsToClock(self.recoverywindow.START), UTILS.SecondsToClock(self.recoverywindow.STOP) + return UTILS.SecondsToClock( self.recoverywindow.START ), UTILS.SecondsToClock( self.recoverywindow.STOP ) end else if InSeconds then @@ -3373,42 +3385,42 @@ end -- @param #AIRBOSS self -- @return #boolean If true, time slot for recovery is open. function AIRBOSS:IsRecovering() - return self:is("Recovering") + return self:is( "Recovering" ) end --- Check if carrier is idle, i.e. no operations are carried out. -- @param #AIRBOSS self -- @return #boolean If true, carrier is in idle state. function AIRBOSS:IsIdle() - return self:is("Idle") + return self:is( "Idle" ) end --- Check if recovery of aircraft is paused. -- @param #AIRBOSS self -- @return #boolean If true, recovery is paused function AIRBOSS:IsPaused() - return self:is("Paused") + return self:is( "Paused" ) end --- Activate TACAN and ICLS beacons. -- @param #AIRBOSS self function AIRBOSS:_ActivateBeacons() - self:T(self.lid..string.format("Activating Beacons (TACAN=%s, ICLS=%s)", tostring(self.TACANon), tostring(self.ICLSon))) + self:T( self.lid .. string.format( "Activating Beacons (TACAN=%s, ICLS=%s)", tostring( self.TACANon ), tostring( self.ICLSon ) ) ) -- Activate TACAN. if self.TACANon then - self:I(self.lid..string.format("Activating TACAN Channel %d%s (%s)", self.TACANchannel, self.TACANmode, self.TACANmorse)) - self.beacon:ActivateTACAN(self.TACANchannel, self.TACANmode, self.TACANmorse, true) + self:I( self.lid .. string.format( "Activating TACAN Channel %d%s (%s)", self.TACANchannel, self.TACANmode, self.TACANmorse ) ) + self.beacon:ActivateTACAN( self.TACANchannel, self.TACANmode, self.TACANmorse, true ) end -- Activate ICLS. if self.ICLSon then - self:I(self.lid..string.format("Activating ICLS Channel %d (%s)", self.ICLSchannel, self.ICLSmorse)) - self.beacon:ActivateICLS(self.ICLSchannel, self.ICLSmorse) + self:I( self.lid .. string.format( "Activating ICLS Channel %d (%s)", self.ICLSchannel, self.ICLSmorse ) ) + self.beacon:ActivateICLS( self.ICLSchannel, self.ICLSmorse ) end -- Set time stamp. - self.Tbeacon=timer.getTime() + self.Tbeacon = timer.getTime() end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -3420,63 +3432,63 @@ end -- @param #string From From state. -- @param #string Event Event. -- @param #string To To state. -function AIRBOSS:onafterStart(From, Event, To) +function AIRBOSS:onafterStart( From, Event, To ) -- Events are handled my MOOSE. - self:I(self.lid..string.format("Starting AIRBOSS v%s for carrier unit %s of type %s on map %s", AIRBOSS.version, self.carrier:GetName(), self.carriertype, self.theatre)) + self:I( self.lid .. string.format( "Starting AIRBOSS v%s for carrier unit %s of type %s on map %s", AIRBOSS.version, self.carrier:GetName(), self.carriertype, self.theatre ) ) -- Activate TACAN and ICLS if desired. self:_ActivateBeacons() -- Schedule radio queue checks. - --self.RQLid=self.radiotimer:Schedule(nil, AIRBOSS._CheckRadioQueue, {self, self.RQLSO, "LSO"}, 1, 0.1) - --self.RQMid=self.radiotimer:Schedule(nil, AIRBOSS._CheckRadioQueue, {self, self.RQMarshal, "MARSHAL"}, 1, 0.1) + -- self.RQLid=self.radiotimer:Schedule(nil, AIRBOSS._CheckRadioQueue, {self, self.RQLSO, "LSO"}, 1, 0.1) + -- self.RQMid=self.radiotimer:Schedule(nil, AIRBOSS._CheckRadioQueue, {self, self.RQMarshal, "MARSHAL"}, 1, 0.1) - --self:I("FF: starting timer.scheduleFunction") - --timer.scheduleFunction(AIRBOSS._CheckRadioQueueT, {airboss=self, radioqueue=self.RQLSO, name="LSO"}, timer.getTime()+1) - --timer.scheduleFunction(AIRBOSS._CheckRadioQueueT, {airboss=self, radioqueue=self.RQMarshal, name="MARSHAL"}, timer.getTime()+1) + -- self:I("FF: starting timer.scheduleFunction") + -- timer.scheduleFunction(AIRBOSS._CheckRadioQueueT, {airboss=self, radioqueue=self.RQLSO, name="LSO"}, timer.getTime()+1) + -- timer.scheduleFunction(AIRBOSS._CheckRadioQueueT, {airboss=self, radioqueue=self.RQMarshal, name="MARSHAL"}, timer.getTime()+1) -- Initial carrier position and orientation. - self.Cposition=self:GetCoordinate() - self.Corientation=self.carrier:GetOrientationX() - self.Corientlast=self.Corientation - self.Tpupdate=timer.getTime() + self.Cposition = self:GetCoordinate() + self.Corientation = self.carrier:GetOrientationX() + self.Corientlast = self.Corientation + self.Tpupdate = timer.getTime() -- Check if no recovery window is set. DISABLED! - if #self.recoverytimes==0 and false then + if #self.recoverytimes == 0 and false then -- Open window in 15 minutes for 3 hours. - local Topen=timer.getAbsTime()+15*60 - local Tclose=Topen+3*60*60 + local Topen = timer.getAbsTime() + 15 * 60 + local Tclose = Topen + 3 * 60 * 60 -- Add window. - self:AddRecoveryWindow(UTILS.SecondsToClock(Topen), UTILS.SecondsToClock(Tclose)) + self:AddRecoveryWindow( UTILS.SecondsToClock( Topen ), UTILS.SecondsToClock( Tclose ) ) end -- Check Recovery time.s self:_CheckRecoveryTimes() -- Time stamp for checking queues. We substract 60 seconds so the routine is called right after status is called the first time. - self.Tqueue=timer.getTime()-60 + self.Tqueue = timer.getTime() - 60 -- Handle events. - self:HandleEvent(EVENTS.Birth) - self:HandleEvent(EVENTS.Land) - self:HandleEvent(EVENTS.EngineShutdown) - self:HandleEvent(EVENTS.Takeoff) - self:HandleEvent(EVENTS.Crash) - self:HandleEvent(EVENTS.Ejection) - self:HandleEvent(EVENTS.PlayerLeaveUnit, self._PlayerLeft) - self:HandleEvent(EVENTS.MissionEnd) - self:HandleEvent(EVENTS.RemoveUnit) + self:HandleEvent( EVENTS.Birth ) + self:HandleEvent( EVENTS.Land ) + self:HandleEvent( EVENTS.EngineShutdown ) + self:HandleEvent( EVENTS.Takeoff ) + self:HandleEvent( EVENTS.Crash ) + self:HandleEvent( EVENTS.Ejection ) + self:HandleEvent( EVENTS.PlayerLeaveUnit, self._PlayerLeft ) + self:HandleEvent( EVENTS.MissionEnd ) + self:HandleEvent( EVENTS.RemoveUnit ) - --self.StatusScheduler=SCHEDULER:New(self) - --self.StatusScheduler:Schedule(self, self._Status, {}, 1, 0.5) + -- self.StatusScheduler=SCHEDULER:New(self) + -- self.StatusScheduler:Schedule(self, self._Status, {}, 1, 0.5) - self.StatusTimer=TIMER:New(self._Status, self):Start(2, 0.5) + self.StatusTimer = TIMER:New( self._Status, self ):Start( 2, 0.5 ) -- Start status check in 1 second. - self:__Status(1) + self:__Status( 1 ) end --- On after Status event. Checks for new flights, updates queue and checks player status. @@ -3484,65 +3496,64 @@ end -- @param #string From From state. -- @param #string Event Event. -- @param #string To To state. -function AIRBOSS:onafterStatus(From, Event, To) +function AIRBOSS:onafterStatus( From, Event, To ) -- Get current time. - local time=timer.getTime() + local time = timer.getTime() -- Update marshal and pattern queue every 30 seconds. - if time-self.Tqueue>self.dTqueue then + if time - self.Tqueue > self.dTqueue then -- Get time. - local clock=UTILS.SecondsToClock(timer.getAbsTime()) - local eta=UTILS.SecondsToClock(self:_GetETAatNextWP()) + local clock = UTILS.SecondsToClock( timer.getAbsTime() ) + local eta = UTILS.SecondsToClock( self:_GetETAatNextWP() ) -- Current heading and position of the carrier. - local hdg=self:GetHeading() - local pos=self:GetCoordinate() - local speed=self.carrier:GetVelocityKNOTS() + local hdg = self:GetHeading() + local pos = self:GetCoordinate() + local speed = self.carrier:GetVelocityKNOTS() -- Check water is ahead. - local collision=false --self:_CheckCollisionCoord(pos:Translate(self.collisiondist, hdg)) + local collision = false -- self:_CheckCollisionCoord(pos:Translate(self.collisiondist, hdg)) - local holdtime=0 + local holdtime = 0 if self.holdtimestamp then - holdtime=timer.getTime()-self.holdtimestamp + holdtime = timer.getTime() - self.holdtimestamp end -- Check if carrier is stationary. - local NextWP=self:_GetNextWaypoint() - local ExpectedSpeed=UTILS.MpsToKnots(NextWP:GetVelocity()) - if speed<0.5 and ExpectedSpeed>0 and not (self.detour or self.turnintowind) then + local NextWP = self:_GetNextWaypoint() + local ExpectedSpeed = UTILS.MpsToKnots( NextWP:GetVelocity() ) + if speed < 0.5 and ExpectedSpeed > 0 and not (self.detour or self.turnintowind) then if not self.holdtimestamp then - self:E(self.lid..string.format("Carrier came to an unexpected standstill. Trying to re-route in 3 min. Speed=%.1f knots, expected=%.1f knots", speed, ExpectedSpeed)) - self.holdtimestamp=timer.getTime() + self:E( self.lid .. string.format( "Carrier came to an unexpected standstill. Trying to re-route in 3 min. Speed=%.1f knots, expected=%.1f knots", speed, ExpectedSpeed ) ) + self.holdtimestamp = timer.getTime() else - if holdtime>3*60 then - local coord=self:GetCoordinate():Translate(500, hdg+10) - --coord:MarkToAll("Re-route after standstill.") - self:CarrierResumeRoute(coord) - self.holdtimestamp=nil + if holdtime > 3 * 60 then + local coord = self:GetCoordinate():Translate( 500, hdg + 10 ) + -- coord:MarkToAll("Re-route after standstill.") + self:CarrierResumeRoute( coord ) + self.holdtimestamp = nil end end end -- Debug info. - local text=string.format("Time %s - Status %s (case=%d) - Speed=%.1f kts - Heading=%d - WP=%d - ETA=%s - Turning=%s - Collision Warning=%s - Detour=%s - Turn Into Wind=%s - Holdtime=%d sec", - clock, self:GetState(), self.case, speed, hdg, self.currentwp, eta, tostring(self.turning), tostring(collision), tostring(self.detour), tostring(self.turnintowind), holdtime) - self:T(self.lid..text) + local text = string.format( "Time %s - Status %s (case=%d) - Speed=%.1f kts - Heading=%d - WP=%d - ETA=%s - Turning=%s - Collision Warning=%s - Detour=%s - Turn Into Wind=%s - Holdtime=%d sec", clock, self:GetState(), self.case, speed, hdg, self.currentwp, eta, tostring( self.turning ), tostring( collision ), tostring( self.detour ), tostring( self.turnintowind ), holdtime ) + self:T( self.lid .. text ) -- Players online: - text="Players:" - local i=0 - for _name,_player in pairs(self.players) do - i=i+1 - local player=_player --#AIRBOSS.FlightGroup - text=text..string.format("\n%d.) %s: Step=%s, Unit=%s, Airframe=%s", i, tostring(player.name), tostring(player.step), tostring(player.unitname), tostring(player.actype)) + text = "Players:" + local i = 0 + for _name, _player in pairs( self.players ) do + i = i + 1 + local player = _player -- #AIRBOSS.FlightGroup + text = text .. string.format( "\n%d.) %s: Step=%s, Unit=%s, Airframe=%s", i, tostring( player.name ), tostring( player.step ), tostring( player.unitname ), tostring( player.actype ) ) end - if i==0 then - text=text.." none" + if i == 0 then + text = text .. " none" end - self:T(self.lid..text) + self:I( self.lid .. text ) -- Check for collision. if collision then @@ -3551,24 +3562,23 @@ function AIRBOSS:onafterStatus(From, Event, To) if self.turnintowind then -- Carrier resumes its initial route. This disables turnintowind switch. - self:CarrierResumeRoute(self.Creturnto) + self:CarrierResumeRoute( self.Creturnto ) -- Since current window would stay open, we disable the WIND switch. if self:IsRecovering() and self.recoverywindow and self.recoverywindow.WIND then -- Disable turn into the wind for this window so that we do not do this all over again. - self.recoverywindow.WIND=false + self.recoverywindow.WIND = false end end end - -- Check recovery times and start/stop recovery mode if necessary. self:_CheckRecoveryTimes() -- Remove dead/zombie flight groups. Player leaving the server whilst in pattern etc. - --self:_RemoveDeadFlightGroups() + -- self:_RemoveDeadFlightGroups() -- Scan carrier zone for new aircraft. self:_ScanCarrierZone() @@ -3583,16 +3593,16 @@ function AIRBOSS:onafterStatus(From, Event, To) self:_CheckPatternUpdate() -- Time stamp. - self.Tqueue=time + self.Tqueue = time end -- (Re-)activate TACAN and ICLS channels. - if time-self.Tbeacon>self.dTbeacon then + if time - self.Tbeacon > self.dTbeacon then self:_ActivateBeacons() end -- Call status every ~0.5 seconds. - self:__Status(-30) + self:__Status( -30 ) end @@ -3613,27 +3623,27 @@ end function AIRBOSS:_CheckAIStatus() -- Loop over all flights in Marshal stack. - for _,_flight in pairs(self.Qmarshal) do - local flight=_flight --#AIRBOSS.FlightGroup + for _, _flight in pairs( self.Qmarshal ) do + local flight = _flight -- #AIRBOSS.FlightGroup -- Only AI! if flight.ai then -- Get fuel amount in %. - local fuel=flight.group:GetFuelMin()*100 + local fuel = flight.group:GetFuelMin() * 100 -- Debug text. - local text=string.format("Group %s fuel=%.1f %%", flight.groupname, fuel) - self:T3(self.lid..text) + local text = string.format( "Group %s fuel=%.1f %%", flight.groupname, fuel ) + self:T3( self.lid .. text ) -- Check if flight is low on fuel and not yet refueling. - if self.lowfuelAI and fuel=recovery.START then + if time >= recovery.START then -- Start time has passed. - if time0 then + if npattern > 0 then -- Extend recovery time. 5 min per flight. - local extmin=5*npattern - recovery.STOP=recovery.STOP+extmin*60 + local extmin = 5 * npattern + recovery.STOP = recovery.STOP + extmin * 60 - local text=string.format("We still got flights in the pattern.\nRecovery time prolonged by %d minutes.\nNow get your act together and no more bolters!", extmin) - self:MessageToPattern(text, "AIRBOSS", "99", 10, false, nil) + local text = string.format( "We still got flights in the pattern.\nRecovery time prolonged by %d minutes.\nNow get your act together and no more bolters!", extmin ) + self:MessageToPattern( text, "AIRBOSS", "99", 10, false, nil ) else -- Set carrier to idle. self:RecoveryStop() - state="closing now" + state = "closing now" -- Closed. - recovery.OPEN=false + recovery.OPEN = false -- Window just closed. - recovery.OVER=true + recovery.OVER = true end else -- Carrier is already idle. - state="closed" + state = "closed" end end else -- This recovery is in the future. - state="in the future" + state = "in the future" -- This is the next to come as we sorted by start time. - if nextwindow==nil then - nextwindow=recovery - state="next in line" + if nextwindow == nil then + nextwindow = recovery + state = "next in line" end end -- Debug text. - text=text..string.format("\n- Start=%s Stop=%s Case=%d Offset=%d Open=%s Closed=%s Status=\"%s\"", Cstart, Cstop, recovery.CASE, recovery.OFFSET, tostring(recovery.OPEN), tostring(recovery.OVER), state) + text = text .. string.format( "\n- Start=%s Stop=%s Case=%d Offset=%d Open=%s Closed=%s Status=\"%s\"", Cstart, Cstop, recovery.CASE, recovery.OFFSET, tostring( recovery.OPEN ), tostring( recovery.OVER ), state ) end -- Debug output. - self:T(self.lid..text) + self:T( self.lid .. text ) -- Current recovery window. - self.recoverywindow=nil - + self.recoverywindow = nil if self:IsIdle() then ----------------------------------------------------------------------------------------------------------------- @@ -3929,48 +3937,48 @@ function AIRBOSS:_CheckRecoveryTimes() if nextwindow then -- Set case and offset of the next window. - self:RecoveryCase(nextwindow.CASE, nextwindow.OFFSET) + self:RecoveryCase( nextwindow.CASE, nextwindow.OFFSET ) -- Check if time is less than 5 minutes. - if nextwindow.WIND and nextwindow.START-time 5° different from the current heading. - local hdg=self:GetHeading() - local wind=self:GetHeadingIntoWind() - local delta=self:_GetDeltaHeading(hdg, wind) - local uturn=delta>5 + local hdg = self:GetHeading() + local wind = self:GetHeadingIntoWind() + local delta = self:_GetDeltaHeading( hdg, wind ) + local uturn = delta > 5 -- Check if wind is actually blowing (0.1 m/s = 0.36 km/h = 0.2 knots) - local _,vwind=self:GetWind() - if vwind<0.1 then - uturn=false + local _, vwind = self:GetWind() + if vwind < 0.1 then + uturn = false end -- U-turn disabled by user input. if not nextwindow.UTURN then - uturn=false + uturn = false end - --Debug info - self:T(self.lid..string.format("Heading=%03d°, Wind=%03d° %.1f kts, Delta=%03d° ==> U-turn=%s", hdg, wind,UTILS.MpsToKnots(vwind), delta, tostring(uturn))) + -- Debug info + self:T( self.lid .. string.format( "Heading=%03d°, Wind=%03d° %.1f kts, Delta=%03d° ==> U-turn=%s", hdg, wind, UTILS.MpsToKnots( vwind ), delta, tostring( uturn ) ) ) -- Time into the wind 1 day or if longer recovery time + the 5 min early. - local t=math.max(nextwindow.STOP-nextwindow.START+self.dTturn, 60*60*24) + local t = math.max( nextwindow.STOP - nextwindow.START + self.dTturn, 60 * 60 * 24 ) -- Recovery wind on deck in knots. - local v=UTILS.KnotsToMps(nextwindow.SPEED) + local v = UTILS.KnotsToMps( nextwindow.SPEED ) -- Check that we do not go above max possible speed. - local vmax=self.carrier:GetSpeedMax()/3.6 -- convert to m/s - v=math.min(v,vmax) + local vmax = self.carrier:GetSpeedMax() / 3.6 -- convert to m/s + v = math.min( v, vmax ) -- Route carrier into the wind. Sets self.turnintowind=true - self:CarrierTurnIntoWind(t, v, uturn) + self:CarrierTurnIntoWind( t, v, uturn ) end -- Set current recovery window. - self.recoverywindow=nextwindow + self.recoverywindow = nextwindow else -- No next window. Set default values. @@ -3983,29 +3991,29 @@ function AIRBOSS:_CheckRecoveryTimes() ------------------------------------------------------------------------------------- if currwindow then - self.recoverywindow=currwindow + self.recoverywindow = currwindow else - self.recoverywindow=nextwindow + self.recoverywindow = nextwindow end end - self:T2({"FF", recoverywindow=self.recoverywindow}) + self:T2( { "FF", recoverywindow = self.recoverywindow } ) end --- Get section lead of a flight. ---@param #AIRBOSS self ---@param #AIRBOSS.FlightGroup flight ---@return #AIRBOSS.FlightGroup The leader of the section. Could be the flight itself. ---@return #boolean If true, flight is lead. -function AIRBOSS:_GetFlightLead(flight) +-- @param #AIRBOSS self +-- @param #AIRBOSS.FlightGroup flight +-- @return #AIRBOSS.FlightGroup The leader of the section. Could be the flight itself. +-- @return #boolean If true, flight is lead. +function AIRBOSS:_GetFlightLead( flight ) - if flight.name~=flight.seclead then + if flight.name ~= flight.seclead then -- Section lead of flight. - local lead=self.players[flight.seclead] - return lead,false + local lead = self.players[flight.seclead] + return lead, false else -- Flight without section or section lead. - return flight,true + return flight, true end end @@ -4017,15 +4025,15 @@ end -- @param #string To To state. -- @param #number Case The recovery case (1, 2 or 3) to switch to. -- @param #number Offset Holding pattern offset angle in degrees for CASE II/III recoveries. -function AIRBOSS:onbeforeRecoveryCase(From, Event, To, Case, Offset) +function AIRBOSS:onbeforeRecoveryCase( From, Event, To, Case, Offset ) -- Input or default value. - Case=Case or self.defaultcase + Case = Case or self.defaultcase -- Input or default value - Offset=Offset or self.defaultoffset + Offset = Offset or self.defaultoffset - if Case==self.case and Offset==self.holdingoffset then + if Case == self.case and Offset == self.holdingoffset then return false end @@ -4039,46 +4047,46 @@ end -- @param #string To To state. -- @param #number Case The recovery case (1, 2 or 3) to switch to. -- @param #number Offset Holding pattern offset angle in degrees for CASE II/III recoveries. -function AIRBOSS:onafterRecoveryCase(From, Event, To, Case, Offset) +function AIRBOSS:onafterRecoveryCase( From, Event, To, Case, Offset ) -- Input or default value. - Case=Case or self.defaultcase + Case = Case or self.defaultcase -- Input or default value - Offset=Offset or self.defaultoffset + Offset = Offset or self.defaultoffset -- Debug output. - local text=string.format("Switching recovery case %d ==> %d", self.case, Case) - if Case>1 then - text=text..string.format(" Holding offset angle %d degrees.", Offset) + local text = string.format( "Switching recovery case %d ==> %d", self.case, Case ) + if Case > 1 then + text = text .. string.format( " Holding offset angle %d degrees.", Offset ) end - MESSAGE:New(text, 20, self.alias):ToAllIf(self.Debug) - self:T(self.lid..text) + MESSAGE:New( text, 20, self.alias ):ToAllIf( self.Debug ) + self:T( self.lid .. text ) -- Set new recovery case. - self.case=Case + self.case = Case -- Set holding offset. - self.holdingoffset=Offset + self.holdingoffset = Offset -- Update case of all flights not in Marshal or Pattern queue. - for _,_flight in pairs(self.flights) do - local flight=_flight --#AIRBOSS.FlightGroup - if not (self:_InQueue(self.Qmarshal, flight.group) or self:_InQueue(self.Qpattern, flight.group)) then + for _, _flight in pairs( self.flights ) do + local flight = _flight -- #AIRBOSS.FlightGroup + if not (self:_InQueue( self.Qmarshal, flight.group ) or self:_InQueue( self.Qpattern, flight.group )) then -- Also not for section members. These are not in the marshal or pattern queue if the lead is. - if flight.name~=flight.seclead then - local lead=self.players[flight.seclead] + if flight.name ~= flight.seclead then + local lead = self.players[flight.seclead] - if lead and not (self:_InQueue(self.Qmarshal, lead.group) or self:_InQueue(self.Qpattern, lead.group)) then + if lead and not (self:_InQueue( self.Qmarshal, lead.group ) or self:_InQueue( self.Qpattern, lead.group )) then -- This is section member and the lead is not in the Marshal or Pattern queue. - flight.case=self.case + flight.case = self.case end else -- This is a flight without section or the section lead. - flight.case=self.case + flight.case = self.case end @@ -4093,19 +4101,19 @@ end -- @param #string To To state. -- @param #number Case The recovery case (1, 2 or 3) to start. -- @param #number Offset Holding pattern offset angle in degrees for CASE II/III recoveries. -function AIRBOSS:onafterRecoveryStart(From, Event, To, Case, Offset) +function AIRBOSS:onafterRecoveryStart( From, Event, To, Case, Offset ) -- Input or default value. - Case=Case or self.defaultcase + Case = Case or self.defaultcase -- Input or default value. - Offset=Offset or self.defaultoffset + Offset = Offset or self.defaultoffset -- Radio message: "99, starting aircraft recovery case X ops. (Marshal radial XYZ degrees)" - self:_MarshalCallRecoveryStart(Case) + self:_MarshalCallRecoveryStart( Case ) -- Switch to case. - self:RecoveryCase(Case, Offset) + self:RecoveryCase( Case, Offset ) end --- On after "RecoveryStop" event. Recovery of aircraft is stopped and carrier switches to state "Idle". Running recovery window is deleted. @@ -4113,65 +4121,64 @@ end -- @param #string From From state. -- @param #string Event Event. -- @param #string To To state. -function AIRBOSS:onafterRecoveryStop(From, Event, To) +function AIRBOSS:onafterRecoveryStop( From, Event, To ) -- Debug output. - self:T(self.lid..string.format("Stopping aircraft recovery.")) + self:T( self.lid .. string.format( "Stopping aircraft recovery." ) ) -- Recovery ops stopped message. - self:_MarshalCallRecoveryStopped(self.case) + self:_MarshalCallRecoveryStopped( self.case ) -- If carrier is currently heading into the wind, we resume the original route. if self.turnintowind then -- Coordinate to return to. - local coord=self.Creturnto + local coord = self.Creturnto -- No U-turn. - if self.recoverywindow and self.recoverywindow.UTURN==false then - coord=nil + if self.recoverywindow and self.recoverywindow.UTURN == false then + coord = nil end -- Carrier resumes route. - self:CarrierResumeRoute(coord) + self:CarrierResumeRoute( coord ) end -- Delete current recovery window if open. - if self.recoverywindow and self.recoverywindow.OPEN==true then - self.recoverywindow.OPEN=false - self.recoverywindow.OVER=true - self:DeleteRecoveryWindow(self.recoverywindow) + if self.recoverywindow and self.recoverywindow.OPEN == true then + self.recoverywindow.OPEN = false + self.recoverywindow.OVER = true + self:DeleteRecoveryWindow( self.recoverywindow ) end -- Check recovery windows. This sets self.recoverywindow to the next window. self:_CheckRecoveryTimes() end - --- On after "RecoveryPause" event. Recovery of aircraft is paused. Marshal queue stays intact. -- @param #AIRBOSS self -- @param #string From From state. -- @param #string Event Event. -- @param #string To To state. -- @param #number duration Duration of pause in seconds. After that recovery is resumed automatically. -function AIRBOSS:onafterRecoveryPause(From, Event, To, duration) +function AIRBOSS:onafterRecoveryPause( From, Event, To, duration ) -- Debug output. - self:T(self.lid..string.format("Pausing aircraft recovery.")) + self:T( self.lid .. string.format( "Pausing aircraft recovery." ) ) -- Message text if duration then -- Auto resume. - self:__RecoveryUnpause(duration) + self:__RecoveryUnpause( duration ) -- Time to resume. - local clock=UTILS.SecondsToClock(timer.getAbsTime()+duration) + local clock = UTILS.SecondsToClock( timer.getAbsTime() + duration ) -- Marshal call: "99, aircraft recovery paused and will be resume at XX:YY." - self:_MarshalCallRecoveryPausedResumedAt(clock) + self:_MarshalCallRecoveryPausedResumedAt( clock ) else - local text=string.format("aircraft recovery is paused until further notice.") + local text = string.format( "aircraft recovery is paused until further notice." ) -- Marshal call: "99, aircraft recovery paused until further notice." self:_MarshalCallRecoveryPausedNotice() @@ -4185,9 +4192,9 @@ end -- @param #string From From state. -- @param #string Event Event. -- @param #string To To state. -function AIRBOSS:onafterRecoveryUnpause(From, Event, To) +function AIRBOSS:onafterRecoveryUnpause( From, Event, To ) -- Debug output. - self:T(self.lid..string.format("Unpausing aircraft recovery.")) + self:T( self.lid .. string.format( "Unpausing aircraft recovery." ) ) -- Resume recovery. self:_MarshalCallResumeRecovery() @@ -4200,9 +4207,9 @@ end -- @param #string Event Event. -- @param #string To To state. -- @param #number n Number of waypoint that was passed. -function AIRBOSS:onafterPassingWaypoint(From, Event, To, n) +function AIRBOSS:onafterPassingWaypoint( From, Event, To, n ) -- Debug output. - self:T(self.lid..string.format("Carrier passed waypoint %d.", n)) + self:I( self.lid .. string.format( "Carrier passed waypoint %d.", n ) ) end --- On after "Idle" event. Carrier goes to state "Idle". @@ -4210,9 +4217,9 @@ end -- @param #string From From state. -- @param #string Event Event. -- @param #string To To state. -function AIRBOSS:onafterIdle(From, Event, To) +function AIRBOSS:onafterIdle( From, Event, To ) -- Debug output. - self:T(self.lid..string.format("Carrier goes to idle.")) + self:T( self.lid .. string.format( "Carrier goes to idle." ) ) end --- On after Stop event. Unhandle events. @@ -4220,18 +4227,18 @@ end -- @param #string From From state. -- @param #string Event Event. -- @param #string To To state. -function AIRBOSS:onafterStop(From, Event, To) - self:T(self.lid..string.format("Stopping airboss script.")) +function AIRBOSS:onafterStop( From, Event, To ) + self:I( self.lid .. string.format( "Stopping airboss script." ) ) -- Unhandle events. - self:UnHandleEvent(EVENTS.Birth) - self:UnHandleEvent(EVENTS.Land) - self:UnHandleEvent(EVENTS.EngineShutdown) - self:UnHandleEvent(EVENTS.Takeoff) - self:UnHandleEvent(EVENTS.Crash) - self:UnHandleEvent(EVENTS.Ejection) - self:UnHandleEvent(EVENTS.PlayerLeaveUnit) - self:UnHandleEvent(EVENTS.MissionEnd) + self:UnHandleEvent( EVENTS.Birth ) + self:UnHandleEvent( EVENTS.Land ) + self:UnHandleEvent( EVENTS.EngineShutdown ) + self:UnHandleEvent( EVENTS.Takeoff ) + self:UnHandleEvent( EVENTS.Crash ) + self:UnHandleEvent( EVENTS.Ejection ) + self:UnHandleEvent( EVENTS.PlayerLeaveUnit ) + self:UnHandleEvent( EVENTS.MissionEnd ) self.CallScheduler:Clear() end @@ -4245,146 +4252,145 @@ end function AIRBOSS:_InitStennis() -- Carrier Parameters. - self.carrierparam.sterndist =-153 - self.carrierparam.deckheight = 19.06 + self.carrierparam.sterndist = -153 + self.carrierparam.deckheight = 19.06 -- Total size of the carrier (approx as rectangle). - self.carrierparam.totlength=310 -- Wiki says 332.8 meters overall length. - self.carrierparam.totwidthport=40 -- Wiki says 76.8 meters overall beam. - self.carrierparam.totwidthstarboard=30 + self.carrierparam.totlength = 310 -- Wiki says 332.8 meters overall length. + self.carrierparam.totwidthport = 40 -- Wiki says 76.8 meters overall beam. + self.carrierparam.totwidthstarboard = 30 -- Landing runway. - self.carrierparam.rwyangle = -9.1359 - self.carrierparam.rwylength = 225 - self.carrierparam.rwywidth = 20 + self.carrierparam.rwyangle = -9.1359 + self.carrierparam.rwylength = 225 + self.carrierparam.rwywidth = 20 -- Wires. - self.carrierparam.wire1 = 46 -- Distance from stern to first wire. - self.carrierparam.wire2 = 46+12 - self.carrierparam.wire3 = 46+24 - self.carrierparam.wire4 = 46+35 -- Last wire is strangely one meter closer. - + self.carrierparam.wire1 = 46 -- Distance from stern to first wire. + self.carrierparam.wire2 = 46 + 12 + self.carrierparam.wire3 = 46 + 24 + self.carrierparam.wire4 = 46 + 35 -- Last wire is strangely one meter closer. -- Platform at 5k. Reduce descent rate to 2000 ft/min to 1200 dirty up level flight. - self.Platform.name="Platform 5k" - self.Platform.Xmin=-UTILS.NMToMeters(22) -- Not more than 22 NM behind the boat. Last check was at 21 NM. - self.Platform.Xmax =nil - self.Platform.Zmin=-UTILS.NMToMeters(30) -- Not more than 30 NM port of boat. - self.Platform.Zmax= UTILS.NMToMeters(30) -- Not more than 30 NM starboard of boat. - self.Platform.LimitXmin=nil -- Limits via zone - self.Platform.LimitXmax=nil - self.Platform.LimitZmin=nil - self.Platform.LimitZmax=nil + self.Platform.name = "Platform 5k" + self.Platform.Xmin = -UTILS.NMToMeters( 22 ) -- Not more than 22 NM behind the boat. Last check was at 21 NM. + self.Platform.Xmax = nil + self.Platform.Zmin = -UTILS.NMToMeters( 30 ) -- Not more than 30 NM port of boat. + self.Platform.Zmax = UTILS.NMToMeters( 30 ) -- Not more than 30 NM starboard of boat. + self.Platform.LimitXmin = nil -- Limits via zone + self.Platform.LimitXmax = nil + self.Platform.LimitZmin = nil + self.Platform.LimitZmax = nil -- Level out at 1200 ft and dirty up. - self.DirtyUp.name="Dirty Up" - self.DirtyUp.Xmin=-UTILS.NMToMeters(21) -- Not more than 21 NM behind the boat. - self.DirtyUp.Xmax= nil - self.DirtyUp.Zmin=-UTILS.NMToMeters(30) -- Not more than 30 NM port of boat. - self.DirtyUp.Zmax= UTILS.NMToMeters(30) -- Not more than 30 NM starboard of boat. - self.DirtyUp.LimitXmin=nil -- Limits via zone - self.DirtyUp.LimitXmax=nil - self.DirtyUp.LimitZmin=nil - self.DirtyUp.LimitZmax=nil + self.DirtyUp.name = "Dirty Up" + self.DirtyUp.Xmin = -UTILS.NMToMeters( 21 ) -- Not more than 21 NM behind the boat. + self.DirtyUp.Xmax = nil + self.DirtyUp.Zmin = -UTILS.NMToMeters( 30 ) -- Not more than 30 NM port of boat. + self.DirtyUp.Zmax = UTILS.NMToMeters( 30 ) -- Not more than 30 NM starboard of boat. + self.DirtyUp.LimitXmin = nil -- Limits via zone + self.DirtyUp.LimitXmax = nil + self.DirtyUp.LimitZmin = nil + self.DirtyUp.LimitZmax = nil -- Intercept glide slope and follow bullseye. - self.Bullseye.name="Bullseye" - self.Bullseye.Xmin=-UTILS.NMToMeters(11) -- Not more than 11 NM behind the boat. Last check was at 10 NM. - self.Bullseye.Xmax= nil - self.Bullseye.Zmin=-UTILS.NMToMeters(30) -- Not more than 30 NM port. - self.Bullseye.Zmax= UTILS.NMToMeters(30) -- Not more than 30 NM starboard. - self.Bullseye.LimitXmin=nil -- Limits via zone. - self.Bullseye.LimitXmax=nil - self.Bullseye.LimitZmin=nil - self.Bullseye.LimitZmax=nil + self.Bullseye.name = "Bullseye" + self.Bullseye.Xmin = -UTILS.NMToMeters( 11 ) -- Not more than 11 NM behind the boat. Last check was at 10 NM. + self.Bullseye.Xmax = nil + self.Bullseye.Zmin = -UTILS.NMToMeters( 30 ) -- Not more than 30 NM port. + self.Bullseye.Zmax = UTILS.NMToMeters( 30 ) -- Not more than 30 NM starboard. + self.Bullseye.LimitXmin = nil -- Limits via zone. + self.Bullseye.LimitXmax = nil + self.Bullseye.LimitZmin = nil + self.Bullseye.LimitZmax = nil -- Break entry. - self.BreakEntry.name="Break Entry" - self.BreakEntry.Xmin=-UTILS.NMToMeters(4) -- Not more than 4 NM behind the boat. Check for initial is at 3 NM with a radius of 500 m and 100 m starboard. - self.BreakEntry.Xmax= nil - self.BreakEntry.Zmin=-UTILS.NMToMeters(0.5) -- Not more than 0.5 NM port of boat. - self.BreakEntry.Zmax= UTILS.NMToMeters(1.5) -- Not more than 1.5 NM starboard. - self.BreakEntry.LimitXmin=0 -- Check and next step when at carrier and starboard of carrier. - self.BreakEntry.LimitXmax=nil - self.BreakEntry.LimitZmin=nil - self.BreakEntry.LimitZmax=nil + self.BreakEntry.name = "Break Entry" + self.BreakEntry.Xmin = -UTILS.NMToMeters( 4 ) -- Not more than 4 NM behind the boat. Check for initial is at 3 NM with a radius of 500 m and 100 m starboard. + self.BreakEntry.Xmax = nil + self.BreakEntry.Zmin = -UTILS.NMToMeters( 0.5 ) -- Not more than 0.5 NM port of boat. + self.BreakEntry.Zmax = UTILS.NMToMeters( 1.5 ) -- Not more than 1.5 NM starboard. + self.BreakEntry.LimitXmin = 0 -- Check and next step when at carrier and starboard of carrier. + self.BreakEntry.LimitXmax = nil + self.BreakEntry.LimitZmin = nil + self.BreakEntry.LimitZmax = nil -- Early break. - self.BreakEarly.name="Early Break" - self.BreakEarly.Xmin=-UTILS.NMToMeters(1) -- Not more than 1 NM behind the boat. Last check was at 0. - self.BreakEarly.Xmax= UTILS.NMToMeters(5) -- Not more than 5 NM in front of the boat. Enough for late breaks? - self.BreakEarly.Zmin=-UTILS.NMToMeters(2) -- Not more than 2 NM port. - self.BreakEarly.Zmax= UTILS.NMToMeters(1) -- Not more than 1 NM starboard. - self.BreakEarly.LimitXmin= 0 -- Check and next step 0.2 NM port and in front of boat. - self.BreakEarly.LimitXmax= nil - self.BreakEarly.LimitZmin=-UTILS.NMToMeters(0.2) -- -370 m port - self.BreakEarly.LimitZmax= nil + self.BreakEarly.name = "Early Break" + self.BreakEarly.Xmin = -UTILS.NMToMeters( 1 ) -- Not more than 1 NM behind the boat. Last check was at 0. + self.BreakEarly.Xmax = UTILS.NMToMeters( 5 ) -- Not more than 5 NM in front of the boat. Enough for late breaks? + self.BreakEarly.Zmin = -UTILS.NMToMeters( 2 ) -- Not more than 2 NM port. + self.BreakEarly.Zmax = UTILS.NMToMeters( 1 ) -- Not more than 1 NM starboard. + self.BreakEarly.LimitXmin = 0 -- Check and next step 0.2 NM port and in front of boat. + self.BreakEarly.LimitXmax = nil + self.BreakEarly.LimitZmin = -UTILS.NMToMeters( 0.2 ) -- -370 m port + self.BreakEarly.LimitZmax = nil -- Late break. - self.BreakLate.name="Late Break" - self.BreakLate.Xmin=-UTILS.NMToMeters(1) -- Not more than 1 NM behind the boat. Last check was at 0. - self.BreakLate.Xmax= UTILS.NMToMeters(5) -- Not more than 5 NM in front of the boat. Enough for late breaks? - self.BreakLate.Zmin=-UTILS.NMToMeters(2) -- Not more than 2 NM port. - self.BreakLate.Zmax= UTILS.NMToMeters(1) -- Not more than 1 NM starboard. - self.BreakLate.LimitXmin= 0 -- Check and next step 0.8 NM port and in front of boat. - self.BreakLate.LimitXmax= nil - self.BreakLate.LimitZmin=-UTILS.NMToMeters(0.8) -- -1470 m port - self.BreakLate.LimitZmax= nil + self.BreakLate.name = "Late Break" + self.BreakLate.Xmin = -UTILS.NMToMeters( 1 ) -- Not more than 1 NM behind the boat. Last check was at 0. + self.BreakLate.Xmax = UTILS.NMToMeters( 5 ) -- Not more than 5 NM in front of the boat. Enough for late breaks? + self.BreakLate.Zmin = -UTILS.NMToMeters( 2 ) -- Not more than 2 NM port. + self.BreakLate.Zmax = UTILS.NMToMeters( 1 ) -- Not more than 1 NM starboard. + self.BreakLate.LimitXmin = 0 -- Check and next step 0.8 NM port and in front of boat. + self.BreakLate.LimitXmax = nil + self.BreakLate.LimitZmin = -UTILS.NMToMeters( 0.8 ) -- -1470 m port + self.BreakLate.LimitZmax = nil -- Abeam position. - self.Abeam.name="Abeam Position" - self.Abeam.Xmin=-UTILS.NMToMeters(5) -- Not more then 5 NM astern of boat. Should be LIG call anyway. - self.Abeam.Xmax= UTILS.NMToMeters(5) -- Not more then 5 NM ahead of boat. - self.Abeam.Zmin=-UTILS.NMToMeters(2) -- Not more than 2 NM port. - self.Abeam.Zmax= 500 -- Not more than 500 m starboard. Must be port! - self.Abeam.LimitXmin=-200 -- Check and next step 200 meters behind the ship. - self.Abeam.LimitXmax= nil - self.Abeam.LimitZmin= nil - self.Abeam.LimitZmax= nil + self.Abeam.name = "Abeam Position" + self.Abeam.Xmin = -UTILS.NMToMeters( 5 ) -- Not more then 5 NM astern of boat. Should be LIG call anyway. + self.Abeam.Xmax = UTILS.NMToMeters( 5 ) -- Not more then 5 NM ahead of boat. + self.Abeam.Zmin = -UTILS.NMToMeters( 2 ) -- Not more than 2 NM port. + self.Abeam.Zmax = 500 -- Not more than 500 m starboard. Must be port! + self.Abeam.LimitXmin = -200 -- Check and next step 200 meters behind the ship. + self.Abeam.LimitXmax = nil + self.Abeam.LimitZmin = nil + self.Abeam.LimitZmax = nil -- At the Ninety. - self.Ninety.name="Ninety" - self.Ninety.Xmin=-UTILS.NMToMeters(4) -- Not more than 4 NM behind the boat. LIG check anyway. - self.Ninety.Xmax= 0 -- Must be behind the boat. - self.Ninety.Zmin=-UTILS.NMToMeters(2) -- Not more than 2 NM port of boat. - self.Ninety.Zmax= nil - self.Ninety.LimitXmin=nil - self.Ninety.LimitXmax=nil - self.Ninety.LimitZmin=nil - self.Ninety.LimitZmax=-UTILS.NMToMeters(0.6) -- Check and next step when 0.6 NM port. + self.Ninety.name = "Ninety" + self.Ninety.Xmin = -UTILS.NMToMeters( 4 ) -- Not more than 4 NM behind the boat. LIG check anyway. + self.Ninety.Xmax = 0 -- Must be behind the boat. + self.Ninety.Zmin = -UTILS.NMToMeters( 2 ) -- Not more than 2 NM port of boat. + self.Ninety.Zmax = nil + self.Ninety.LimitXmin = nil + self.Ninety.LimitXmax = nil + self.Ninety.LimitZmin = nil + self.Ninety.LimitZmax = -UTILS.NMToMeters( 0.6 ) -- Check and next step when 0.6 NM port. -- At the Wake. - self.Wake.name="Wake" - self.Wake.Xmin=-UTILS.NMToMeters(4) -- Not more than 4 NM behind the boat. - self.Wake.Xmax= 0 -- Must be behind the boat. - self.Wake.Zmin=-2000 -- Not more than 2 km port of boat. - self.Wake.Zmax= nil - self.Wake.LimitXmin=nil - self.Wake.LimitXmax=nil - self.Wake.LimitZmin=0 -- Check and next step when directly behind the boat. - self.Wake.LimitZmax=nil + self.Wake.name = "Wake" + self.Wake.Xmin = -UTILS.NMToMeters( 4 ) -- Not more than 4 NM behind the boat. + self.Wake.Xmax = 0 -- Must be behind the boat. + self.Wake.Zmin = -2000 -- Not more than 2 km port of boat. + self.Wake.Zmax = nil + self.Wake.LimitXmin = nil + self.Wake.LimitXmax = nil + self.Wake.LimitZmin = 0 -- Check and next step when directly behind the boat. + self.Wake.LimitZmax = nil -- Turn to final. - self.Final.name="Final" - self.Final.Xmin=-UTILS.NMToMeters(4) -- Not more than 4 NM behind the boat. - self.Final.Xmax= 0 -- Must be behind the boat. - self.Final.Zmin=-2000 -- Not more than 2 km port. - self.Final.Zmax= nil - self.Final.LimitXmin=nil -- No limits. Check is carried out differently. - self.Final.LimitXmax=nil - self.Final.LimitZmin=nil - self.Final.LimitZmax=nil + self.Final.name = "Final" + self.Final.Xmin = -UTILS.NMToMeters( 4 ) -- Not more than 4 NM behind the boat. + self.Final.Xmax = 0 -- Must be behind the boat. + self.Final.Zmin = -2000 -- Not more than 2 km port. + self.Final.Zmax = nil + self.Final.LimitXmin = nil -- No limits. Check is carried out differently. + self.Final.LimitXmax = nil + self.Final.LimitZmin = nil + self.Final.LimitZmax = nil -- In the Groove. - self.Groove.name="Groove" - self.Groove.Xmin=-UTILS.NMToMeters(4) -- Not more than 4 NM behind the boat. - self.Groove.Xmax= nil - self.Groove.Zmin=-UTILS.NMToMeters(2) -- Not more than 2 NM port - self.Groove.Zmax= UTILS.NMToMeters(2) -- Not more than 2 NM starboard. - self.Groove.LimitXmin=nil -- No limits. Check is carried out differently. - self.Groove.LimitXmax=nil - self.Groove.LimitZmin=nil - self.Groove.LimitZmax=nil + self.Groove.name = "Groove" + self.Groove.Xmin = -UTILS.NMToMeters( 4 ) -- Not more than 4 NM behind the boat. + self.Groove.Xmax = nil + self.Groove.Zmin = -UTILS.NMToMeters( 2 ) -- Not more than 2 NM port + self.Groove.Zmax = UTILS.NMToMeters( 2 ) -- Not more than 2 NM starboard. + self.Groove.LimitXmin = nil -- No limits. Check is carried out differently. + self.Groove.LimitXmax = nil + self.Groove.LimitZmin = nil + self.Groove.LimitZmax = nil end @@ -4396,24 +4402,24 @@ function AIRBOSS:_InitNimitz() self:_InitStennis() -- Carrier Parameters. - self.carrierparam.sterndist =-164 - self.carrierparam.deckheight = 20.1494 --DCS World OpenBeta\CoreMods\tech\USS_Nimitz\Database\USS_CVN_7X.lua + self.carrierparam.sterndist = -164 + self.carrierparam.deckheight = 20.1494 -- DCS World OpenBeta\CoreMods\tech\USS_Nimitz\Database\USS_CVN_7X.lua -- Total size of the carrier (approx as rectangle). - self.carrierparam.totlength=332.8 -- Wiki says 332.8 meters overall length. - self.carrierparam.totwidthport=45 -- Wiki says 76.8 meters overall beam. - self.carrierparam.totwidthstarboard=35 + self.carrierparam.totlength = 332.8 -- Wiki says 332.8 meters overall length. + self.carrierparam.totwidthport = 45 -- Wiki says 76.8 meters overall beam. + self.carrierparam.totwidthstarboard = 35 -- Landing runway. - self.carrierparam.rwyangle = -9.1359 --DCS World OpenBeta\CoreMods\tech\USS_Nimitz\scripts\USS_Nimitz_RunwaysAndRoutes.lua - self.carrierparam.rwylength = 250 - self.carrierparam.rwywidth = 25 + self.carrierparam.rwyangle = -9.1359 -- DCS World OpenBeta\CoreMods\tech\USS_Nimitz\scripts\USS_Nimitz_RunwaysAndRoutes.lua + self.carrierparam.rwylength = 250 + self.carrierparam.rwywidth = 25 -- Wires. - self.carrierparam.wire1 = 55 -- Distance from stern to first wire. - self.carrierparam.wire2 = 67 - self.carrierparam.wire3 = 79 - self.carrierparam.wire4 = 92 + self.carrierparam.wire1 = 55 -- Distance from stern to first wire. + self.carrierparam.wire2 = 67 + self.carrierparam.wire3 = 79 + self.carrierparam.wire4 = 92 end @@ -4425,24 +4431,64 @@ function AIRBOSS:_InitForrestal() self:_InitNimitz() -- Carrier Parameters. - self.carrierparam.sterndist =-135.5 - self.carrierparam.deckheight = 20 --20.1494 --DCS World OpenBeta\CoreMods\tech\USS_Nimitz\Database\USS_CVN_7X.lua + self.carrierparam.sterndist = -135.5 + self.carrierparam.deckheight = 20 -- 20.1494 --DCS World OpenBeta\CoreMods\tech\USS_Nimitz\Database\USS_CVN_7X.lua -- Total size of the carrier (approx as rectangle). - self.carrierparam.totlength=315 -- Wiki says 325 meters overall length. - self.carrierparam.totwidthport=45 -- Wiki says 73 meters overall beam. - self.carrierparam.totwidthstarboard=35 + self.carrierparam.totlength = 315 -- Wiki says 325 meters overall length. + self.carrierparam.totwidthport = 45 -- Wiki says 73 meters overall beam. + self.carrierparam.totwidthstarboard = 35 -- Landing runway. - self.carrierparam.rwyangle = -9.1359 --DCS World OpenBeta\CoreMods\tech\USS_Nimitz\scripts\USS_Nimitz_RunwaysAndRoutes.lua - self.carrierparam.rwylength = 212 - self.carrierparam.rwywidth = 25 + self.carrierparam.rwyangle = -9.1359 -- DCS World OpenBeta\CoreMods\tech\USS_Nimitz\scripts\USS_Nimitz_RunwaysAndRoutes.lua + self.carrierparam.rwylength = 212 + self.carrierparam.rwywidth = 25 -- Wires. - self.carrierparam.wire1 = 44 -- Distance from stern to first wire. Original from Frank - 42 - self.carrierparam.wire2 = 54 --51.5 - self.carrierparam.wire3 = 64 --62 - self.carrierparam.wire4 = 74 --72.5 + self.carrierparam.wire1 = 44 -- Distance from stern to first wire. Original from Frank - 42 + self.carrierparam.wire2 = 54 -- 51.5 + self.carrierparam.wire3 = 64 -- 62 + self.carrierparam.wire4 = 74 -- 72.5 + +end + +--- Init parameters for R12 HMS Hermes carrier. +-- @param #AIRBOSS self +function AIRBOSS:_InitHermes() + + -- Init Stennis as default. + self:_InitStennis() + + -- Carrier Parameters. + self.carrierparam.sterndist = -105 + self.carrierparam.deckheight = 12 -- From model viewer WL0. + + -- Total size of the carrier (approx as rectangle). + self.carrierparam.totlength = 228.19 + self.carrierparam.totwidthport = 20.5 + self.carrierparam.totwidthstarboard = 24.5 + + -- Landing runway. + self.carrierparam.rwyangle = 0 + self.carrierparam.rwylength = 215 + self.carrierparam.rwywidth = 13 + + -- Wires. + self.carrierparam.wire1 = nil + self.carrierparam.wire2 = nil + self.carrierparam.wire3 = nil + self.carrierparam.wire4 = nil + + -- Late break. + self.BreakLate.name = "Late Break" + self.BreakLate.Xmin = -UTILS.NMToMeters( 1 ) -- Not more than 1 NM behind the boat. Last check was at 0. + self.BreakLate.Xmax = UTILS.NMToMeters( 5 ) -- Not more than 5 NM in front of the boat. Enough for late breaks? + self.BreakLate.Zmin = -UTILS.NMToMeters( 0.25 ) -- Not more than 0.25 NM port. + self.BreakLate.Zmax = UTILS.NMToMeters( 0.5 ) -- Not more than 0.5 NM starboard. + self.BreakLate.LimitXmin = 0 -- Check and next step 0.8 NM port and in front of boat. + self.BreakLate.LimitXmax = nil + self.BreakLate.LimitZmin = -UTILS.NMToMeters( 0.5 ) -- 926 m port, closer than the stennis as abeam is 0.8-1.0 rather than 1.2 + self.BreakLate.LimitZmax = nil end @@ -4454,35 +4500,35 @@ function AIRBOSS:_InitTarawa() self:_InitStennis() -- Carrier Parameters. - self.carrierparam.sterndist =-125 - self.carrierparam.deckheight = 21 --69 ft + self.carrierparam.sterndist = -125 + self.carrierparam.deckheight = 21 -- 69 ft -- Total size of the carrier (approx as rectangle). - self.carrierparam.totlength=245 - self.carrierparam.totwidthport=10 - self.carrierparam.totwidthstarboard=25 + self.carrierparam.totlength = 245 + self.carrierparam.totwidthport = 10 + self.carrierparam.totwidthstarboard = 25 -- Landing runway. - self.carrierparam.rwyangle = 0 + self.carrierparam.rwyangle = 0 self.carrierparam.rwylength = 225 - self.carrierparam.rwywidth = 15 + self.carrierparam.rwywidth = 15 -- Wires. - self.carrierparam.wire1=nil - self.carrierparam.wire2=nil - self.carrierparam.wire3=nil - self.carrierparam.wire4=nil + self.carrierparam.wire1 = nil + self.carrierparam.wire2 = nil + self.carrierparam.wire3 = nil + self.carrierparam.wire4 = nil -- Late break. - self.BreakLate.name="Late Break" - self.BreakLate.Xmin=-UTILS.NMToMeters(1) -- Not more than 1 NM behind the boat. Last check was at 0. - self.BreakLate.Xmax= UTILS.NMToMeters(5) -- Not more than 5 NM in front of the boat. Enough for late breaks? - self.BreakLate.Zmin=-UTILS.NMToMeters(1.6) -- Not more than 1.6 NM port. - self.BreakLate.Zmax= UTILS.NMToMeters(1) -- Not more than 1 NM starboard. - self.BreakLate.LimitXmin= 0 -- Check and next step 0.8 NM port and in front of boat. - self.BreakLate.LimitXmax= nil - self.BreakLate.LimitZmin=-UTILS.NMToMeters(0.5) -- 926 m port, closer than the stennis as abeam is 0.8-1.0 rather than 1.2 - self.BreakLate.LimitZmax= nil + self.BreakLate.name = "Late Break" + self.BreakLate.Xmin = -UTILS.NMToMeters( 1 ) -- Not more than 1 NM behind the boat. Last check was at 0. + self.BreakLate.Xmax = UTILS.NMToMeters( 5 ) -- Not more than 5 NM in front of the boat. Enough for late breaks? + self.BreakLate.Zmin = -UTILS.NMToMeters( 1.6 ) -- Not more than 1.6 NM port. + self.BreakLate.Zmax = UTILS.NMToMeters( 1 ) -- Not more than 1 NM starboard. + self.BreakLate.LimitXmin = 0 -- Check and next step 0.8 NM port and in front of boat. + self.BreakLate.LimitXmax = nil + self.BreakLate.LimitZmin = -UTILS.NMToMeters( 0.5 ) -- 926 m port, closer than the stennis as abeam is 0.8-1.0 rather than 1.2 + self.BreakLate.LimitZmax = nil end @@ -4494,35 +4540,35 @@ function AIRBOSS:_InitAmerica() self:_InitStennis() -- Carrier Parameters. - self.carrierparam.sterndist =-125 - self.carrierparam.deckheight = 20 --67 ft + self.carrierparam.sterndist = -125 + self.carrierparam.deckheight = 20 -- 67 ft -- Total size of the carrier (approx as rectangle). - self.carrierparam.totlength=257 - self.carrierparam.totwidthport=11 - self.carrierparam.totwidthstarboard=25 + self.carrierparam.totlength = 257 + self.carrierparam.totwidthport = 11 + self.carrierparam.totwidthstarboard = 25 -- Landing runway. - self.carrierparam.rwyangle = 0 + self.carrierparam.rwyangle = 0 self.carrierparam.rwylength = 240 - self.carrierparam.rwywidth = 15 + self.carrierparam.rwywidth = 15 -- Wires. - self.carrierparam.wire1=nil - self.carrierparam.wire2=nil - self.carrierparam.wire3=nil - self.carrierparam.wire4=nil + self.carrierparam.wire1 = nil + self.carrierparam.wire2 = nil + self.carrierparam.wire3 = nil + self.carrierparam.wire4 = nil -- Late break. - self.BreakLate.name="Late Break" - self.BreakLate.Xmin=-UTILS.NMToMeters(1) -- Not more than 1 NM behind the boat. Last check was at 0. - self.BreakLate.Xmax= UTILS.NMToMeters(5) -- Not more than 5 NM in front of the boat. Enough for late breaks? - self.BreakLate.Zmin=-UTILS.NMToMeters(1.6) -- Not more than 1.6 NM port. - self.BreakLate.Zmax= UTILS.NMToMeters(1) -- Not more than 1 NM starboard. - self.BreakLate.LimitXmin= 0 -- Check and next step 0.8 NM port and in front of boat. - self.BreakLate.LimitXmax= nil - self.BreakLate.LimitZmin=-UTILS.NMToMeters(0.5) -- 926 m port, closer than the stennis as abeam is 0.8-1.0 rather than 1.2 - self.BreakLate.LimitZmax= nil + self.BreakLate.name = "Late Break" + self.BreakLate.Xmin = -UTILS.NMToMeters( 1 ) -- Not more than 1 NM behind the boat. Last check was at 0. + self.BreakLate.Xmax = UTILS.NMToMeters( 5 ) -- Not more than 5 NM in front of the boat. Enough for late breaks? + self.BreakLate.Zmin = -UTILS.NMToMeters( 1.6 ) -- Not more than 1.6 NM port. + self.BreakLate.Zmax = UTILS.NMToMeters( 1 ) -- Not more than 1 NM starboard. + self.BreakLate.LimitXmin = 0 -- Check and next step 0.8 NM port and in front of boat. + self.BreakLate.LimitXmax = nil + self.BreakLate.LimitZmin = -UTILS.NMToMeters( 0.5 ) -- 926 m port, closer than the stennis as abeam is 0.8-1.0 rather than 1.2 + self.BreakLate.LimitZmax = nil end @@ -4534,338 +4580,334 @@ function AIRBOSS:_InitJcarlos() self:_InitStennis() -- Carrier Parameters. - self.carrierparam.sterndist =-125 - self.carrierparam.deckheight = 20 --67 ft + self.carrierparam.sterndist = -125 + self.carrierparam.deckheight = 20 -- 67 ft -- Total size of the carrier (approx as rectangle). - self.carrierparam.totlength=231 - self.carrierparam.totwidthport=10 - self.carrierparam.totwidthstarboard=22 + self.carrierparam.totlength = 231 + self.carrierparam.totwidthport = 10 + self.carrierparam.totwidthstarboard = 22 -- Landing runway. - self.carrierparam.rwyangle = 0 + self.carrierparam.rwyangle = 0 self.carrierparam.rwylength = 202 - self.carrierparam.rwywidth = 14 + self.carrierparam.rwywidth = 14 -- Wires. - self.carrierparam.wire1=nil - self.carrierparam.wire2=nil - self.carrierparam.wire3=nil - self.carrierparam.wire4=nil + self.carrierparam.wire1 = nil + self.carrierparam.wire2 = nil + self.carrierparam.wire3 = nil + self.carrierparam.wire4 = nil -- Late break. - self.BreakLate.name="Late Break" - self.BreakLate.Xmin=-UTILS.NMToMeters(1) -- Not more than 1 NM behind the boat. Last check was at 0. - self.BreakLate.Xmax= UTILS.NMToMeters(5) -- Not more than 5 NM in front of the boat. Enough for late breaks? - self.BreakLate.Zmin=-UTILS.NMToMeters(1.6) -- Not more than 1.6 NM port. - self.BreakLate.Zmax= UTILS.NMToMeters(1) -- Not more than 1 NM starboard. - self.BreakLate.LimitXmin= 0 -- Check and next step 0.8 NM port and in front of boat. - self.BreakLate.LimitXmax= nil - self.BreakLate.LimitZmin=-UTILS.NMToMeters(0.5) -- 926 m port, closer than the stennis as abeam is 0.8-1.0 rather than 1.2 - self.BreakLate.LimitZmax= nil + self.BreakLate.name = "Late Break" + self.BreakLate.Xmin = -UTILS.NMToMeters( 1 ) -- Not more than 1 NM behind the boat. Last check was at 0. + self.BreakLate.Xmax = UTILS.NMToMeters( 5 ) -- Not more than 5 NM in front of the boat. Enough for late breaks? + self.BreakLate.Zmin = -UTILS.NMToMeters( 1.6 ) -- Not more than 1.6 NM port. + self.BreakLate.Zmax = UTILS.NMToMeters( 1 ) -- Not more than 1 NM starboard. + self.BreakLate.LimitXmin = 0 -- Check and next step 0.8 NM port and in front of boat. + self.BreakLate.LimitXmax = nil + self.BreakLate.LimitZmin = -UTILS.NMToMeters( 0.5 ) -- 926 m port, closer than the stennis as abeam is 0.8-1.0 rather than 1.2 + self.BreakLate.LimitZmax = nil end --- Init parameters for Marshal Voice overs *Gabriella* by HighwaymanEd. -- @param #AIRBOSS self -- @param #string mizfolder (Optional) Folder within miz file where the sound files are located. -function AIRBOSS:SetVoiceOversMarshalByGabriella(mizfolder) +function AIRBOSS:SetVoiceOversMarshalByGabriella( mizfolder ) -- Set sound files folder. if mizfolder then - local lastchar=string.sub(mizfolder, -1) - if lastchar~="/" then - mizfolder=mizfolder.."/" + local lastchar = string.sub( mizfolder, -1 ) + if lastchar ~= "/" then + mizfolder = mizfolder .. "/" end - self.soundfolderMSH=mizfolder + self.soundfolderMSH = mizfolder else -- Default is the general folder. - self.soundfolderMSH=self.soundfolder + self.soundfolderMSH = self.soundfolder end -- Report for duty. - self:I(self.lid..string.format("Marshal Gabriella reporting for duty! Soundfolder=%s", tostring(self.soundfolderMSH))) + self:I( self.lid .. string.format( "Marshal Gabriella reporting for duty! Soundfolder=%s", tostring( self.soundfolderMSH ) ) ) - self.MarshalCall.AFFIRMATIVE.duration=0.65 - self.MarshalCall.ALTIMETER.duration=0.60 - self.MarshalCall.BRC.duration=0.67 - self.MarshalCall.CARRIERTURNTOHEADING.duration=1.62 - self.MarshalCall.CASE.duration=0.30 - self.MarshalCall.CHARLIETIME.duration=0.77 - self.MarshalCall.CLEAREDFORRECOVERY.duration=0.93 - self.MarshalCall.DECKCLOSED.duration=0.73 - self.MarshalCall.DEGREES.duration=0.48 - self.MarshalCall.EXPECTED.duration=0.50 - self.MarshalCall.FLYNEEDLES.duration=0.89 - self.MarshalCall.HOLDATANGELS.duration=0.81 - self.MarshalCall.HOURS.duration=0.41 - self.MarshalCall.MARSHALRADIAL.duration=0.95 - self.MarshalCall.N0.duration=0.41 - self.MarshalCall.N1.duration=0.30 - self.MarshalCall.N2.duration=0.34 - self.MarshalCall.N3.duration=0.31 - self.MarshalCall.N4.duration=0.34 - self.MarshalCall.N5.duration=0.30 - self.MarshalCall.N6.duration=0.33 - self.MarshalCall.N7.duration=0.38 - self.MarshalCall.N8.duration=0.35 - self.MarshalCall.N9.duration=0.35 - self.MarshalCall.NEGATIVE.duration=0.60 - self.MarshalCall.NEWFB.duration=0.95 - self.MarshalCall.OPS.duration=0.23 - self.MarshalCall.POINT.duration=0.38 - self.MarshalCall.RADIOCHECK.duration=1.27 - self.MarshalCall.RECOVERY.duration=0.60 - self.MarshalCall.RECOVERYOPSSTOPPED.duration=1.25 - self.MarshalCall.RECOVERYPAUSEDNOTICE.duration=2.55 - self.MarshalCall.RECOVERYPAUSEDRESUMED.duration=2.55 - self.MarshalCall.REPORTSEEME.duration=0.87 - self.MarshalCall.RESUMERECOVERY.duration=1.55 - self.MarshalCall.ROGER.duration=0.50 - self.MarshalCall.SAYNEEDLES.duration=0.82 - self.MarshalCall.STACKFULL.duration=5.70 - self.MarshalCall.STARTINGRECOVERY.duration=1.61 + self.MarshalCall.AFFIRMATIVE.duration = 0.65 + self.MarshalCall.ALTIMETER.duration = 0.60 + self.MarshalCall.BRC.duration = 0.67 + self.MarshalCall.CARRIERTURNTOHEADING.duration = 1.62 + self.MarshalCall.CASE.duration = 0.30 + self.MarshalCall.CHARLIETIME.duration = 0.77 + self.MarshalCall.CLEAREDFORRECOVERY.duration = 0.93 + self.MarshalCall.DECKCLOSED.duration = 0.73 + self.MarshalCall.DEGREES.duration = 0.48 + self.MarshalCall.EXPECTED.duration = 0.50 + self.MarshalCall.FLYNEEDLES.duration = 0.89 + self.MarshalCall.HOLDATANGELS.duration = 0.81 + self.MarshalCall.HOURS.duration = 0.41 + self.MarshalCall.MARSHALRADIAL.duration = 0.95 + self.MarshalCall.N0.duration = 0.41 + self.MarshalCall.N1.duration = 0.30 + self.MarshalCall.N2.duration = 0.34 + self.MarshalCall.N3.duration = 0.31 + self.MarshalCall.N4.duration = 0.34 + self.MarshalCall.N5.duration = 0.30 + self.MarshalCall.N6.duration = 0.33 + self.MarshalCall.N7.duration = 0.38 + self.MarshalCall.N8.duration = 0.35 + self.MarshalCall.N9.duration = 0.35 + self.MarshalCall.NEGATIVE.duration = 0.60 + self.MarshalCall.NEWFB.duration = 0.95 + self.MarshalCall.OPS.duration = 0.23 + self.MarshalCall.POINT.duration = 0.38 + self.MarshalCall.RADIOCHECK.duration = 1.27 + self.MarshalCall.RECOVERY.duration = 0.60 + self.MarshalCall.RECOVERYOPSSTOPPED.duration = 1.25 + self.MarshalCall.RECOVERYPAUSEDNOTICE.duration = 2.55 + self.MarshalCall.RECOVERYPAUSEDRESUMED.duration = 2.55 + self.MarshalCall.REPORTSEEME.duration = 0.87 + self.MarshalCall.RESUMERECOVERY.duration = 1.55 + self.MarshalCall.ROGER.duration = 0.50 + self.MarshalCall.SAYNEEDLES.duration = 0.82 + self.MarshalCall.STACKFULL.duration = 5.70 + self.MarshalCall.STARTINGRECOVERY.duration = 1.61 end - - --- Init parameters for Marshal Voice overs by *Raynor*. -- @param #AIRBOSS self -- @param #string mizfolder (Optional) Folder within miz file where the sound files are located. -function AIRBOSS:SetVoiceOversMarshalByRaynor(mizfolder) +function AIRBOSS:SetVoiceOversMarshalByRaynor( mizfolder ) -- Set sound files folder. if mizfolder then - local lastchar=string.sub(mizfolder, -1) - if lastchar~="/" then - mizfolder=mizfolder.."/" + local lastchar = string.sub( mizfolder, -1 ) + if lastchar ~= "/" then + mizfolder = mizfolder .. "/" end - self.soundfolderMSH=mizfolder + self.soundfolderMSH = mizfolder else -- Default is the general folder. - self.soundfolderMSH=self.soundfolder + self.soundfolderMSH = self.soundfolder end -- Report for duty. - self:I(self.lid..string.format("Marshal Raynor reporting for duty! Soundfolder=%s", tostring(self.soundfolderMSH))) + self:I( self.lid .. string.format( "Marshal Raynor reporting for duty! Soundfolder=%s", tostring( self.soundfolderMSH ) ) ) - self.MarshalCall.AFFIRMATIVE.duration=0.70 - self.MarshalCall.ALTIMETER.duration=0.60 - self.MarshalCall.BRC.duration=0.60 - self.MarshalCall.CARRIERTURNTOHEADING.duration=1.87 - self.MarshalCall.CASE.duration=0.60 - self.MarshalCall.CHARLIETIME.duration=0.81 - self.MarshalCall.CLEAREDFORRECOVERY.duration=1.21 - self.MarshalCall.DECKCLOSED.duration=0.86 - self.MarshalCall.DEGREES.duration=0.55 - self.MarshalCall.EXPECTED.duration=0.61 - self.MarshalCall.FLYNEEDLES.duration=0.90 - self.MarshalCall.HOLDATANGELS.duration=0.91 - self.MarshalCall.HOURS.duration=0.54 - self.MarshalCall.MARSHALRADIAL.duration=0.80 - self.MarshalCall.N0.duration=0.38 - self.MarshalCall.N1.duration=0.30 - self.MarshalCall.N2.duration=0.30 - self.MarshalCall.N3.duration=0.30 - self.MarshalCall.N4.duration=0.32 - self.MarshalCall.N5.duration=0.41 - self.MarshalCall.N6.duration=0.48 - self.MarshalCall.N7.duration=0.51 - self.MarshalCall.N8.duration=0.38 - self.MarshalCall.N9.duration=0.34 - self.MarshalCall.NEGATIVE.duration=0.60 - self.MarshalCall.NEWFB.duration=1.10 - self.MarshalCall.OPS.duration=0.46 - self.MarshalCall.POINT.duration=0.21 - self.MarshalCall.RADIOCHECK.duration=0.95 - self.MarshalCall.RECOVERY.duration=0.63 - self.MarshalCall.RECOVERYOPSSTOPPED.duration=1.36 - self.MarshalCall.RECOVERYPAUSEDNOTICE.duration=2.8 -- Strangely the file is actually a shorter ~2.4 sec. - self.MarshalCall.RECOVERYPAUSEDRESUMED.duration=2.75 - self.MarshalCall.REPORTSEEME.duration=1.06 --0.96 - self.MarshalCall.RESUMERECOVERY.duration=1.41 - self.MarshalCall.ROGER.duration=0.41 - self.MarshalCall.SAYNEEDLES.duration=0.79 - self.MarshalCall.STACKFULL.duration=4.70 - self.MarshalCall.STARTINGRECOVERY.duration=2.06 + self.MarshalCall.AFFIRMATIVE.duration = 0.70 + self.MarshalCall.ALTIMETER.duration = 0.60 + self.MarshalCall.BRC.duration = 0.60 + self.MarshalCall.CARRIERTURNTOHEADING.duration = 1.87 + self.MarshalCall.CASE.duration = 0.60 + self.MarshalCall.CHARLIETIME.duration = 0.81 + self.MarshalCall.CLEAREDFORRECOVERY.duration = 1.21 + self.MarshalCall.DECKCLOSED.duration = 0.86 + self.MarshalCall.DEGREES.duration = 0.55 + self.MarshalCall.EXPECTED.duration = 0.61 + self.MarshalCall.FLYNEEDLES.duration = 0.90 + self.MarshalCall.HOLDATANGELS.duration = 0.91 + self.MarshalCall.HOURS.duration = 0.54 + self.MarshalCall.MARSHALRADIAL.duration = 0.80 + self.MarshalCall.N0.duration = 0.38 + self.MarshalCall.N1.duration = 0.30 + self.MarshalCall.N2.duration = 0.30 + self.MarshalCall.N3.duration = 0.30 + self.MarshalCall.N4.duration = 0.32 + self.MarshalCall.N5.duration = 0.41 + self.MarshalCall.N6.duration = 0.48 + self.MarshalCall.N7.duration = 0.51 + self.MarshalCall.N8.duration = 0.38 + self.MarshalCall.N9.duration = 0.34 + self.MarshalCall.NEGATIVE.duration = 0.60 + self.MarshalCall.NEWFB.duration = 1.10 + self.MarshalCall.OPS.duration = 0.46 + self.MarshalCall.POINT.duration = 0.21 + self.MarshalCall.RADIOCHECK.duration = 0.95 + self.MarshalCall.RECOVERY.duration = 0.63 + self.MarshalCall.RECOVERYOPSSTOPPED.duration = 1.36 + self.MarshalCall.RECOVERYPAUSEDNOTICE.duration = 2.8 -- Strangely the file is actually a shorter ~2.4 sec. + self.MarshalCall.RECOVERYPAUSEDRESUMED.duration = 2.75 + self.MarshalCall.REPORTSEEME.duration = 1.06 -- 0.96 + self.MarshalCall.RESUMERECOVERY.duration = 1.41 + self.MarshalCall.ROGER.duration = 0.41 + self.MarshalCall.SAYNEEDLES.duration = 0.79 + self.MarshalCall.STACKFULL.duration = 4.70 + self.MarshalCall.STARTINGRECOVERY.duration = 2.06 end --- Set parameters for LSO Voice overs by *Raynor*. -- @param #AIRBOSS self -- @param #string mizfolder (Optional) Folder within miz file where the sound files are located. -function AIRBOSS:SetVoiceOversLSOByRaynor(mizfolder) +function AIRBOSS:SetVoiceOversLSOByRaynor( mizfolder ) -- Set sound files folder. if mizfolder then - local lastchar=string.sub(mizfolder, -1) - if lastchar~="/" then - mizfolder=mizfolder.."/" + local lastchar = string.sub( mizfolder, -1 ) + if lastchar ~= "/" then + mizfolder = mizfolder .. "/" end - self.soundfolderLSO=mizfolder + self.soundfolderLSO = mizfolder else -- Default is the general folder. - self.soundfolderLSO=self.soundfolder + self.soundfolderLSO = self.soundfolder end -- Report for duty. - self:I(self.lid..string.format("LSO Raynor reporting for duty! Soundfolder=%s", tostring(self.soundfolderLSO))) + self:I( self.lid .. string.format( "LSO Raynor reporting for duty! Soundfolder=%s", tostring( self.soundfolderLSO ) ) ) - self.LSOCall.BOLTER.duration=0.75 - self.LSOCall.CALLTHEBALL.duration=0.625 - self.LSOCall.CHECK.duration=0.40 - self.LSOCall.CLEAREDTOLAND.duration=0.85 - self.LSOCall.COMELEFT.duration=0.60 - self.LSOCall.DEPARTANDREENTER.duration=1.10 - self.LSOCall.EXPECTHEAVYWAVEOFF.duration=1.30 - self.LSOCall.EXPECTSPOT75.duration=1.85 - self.LSOCall.EXPECTSPOT5.duration=1.3 - self.LSOCall.FAST.duration=0.75 - self.LSOCall.FOULDECK.duration=0.75 - self.LSOCall.HIGH.duration=0.65 - self.LSOCall.IDLE.duration=0.40 - self.LSOCall.LONGINGROOVE.duration=1.25 - self.LSOCall.LOW.duration=0.60 - self.LSOCall.N0.duration=0.38 - self.LSOCall.N1.duration=0.30 - self.LSOCall.N2.duration=0.30 - self.LSOCall.N3.duration=0.30 - self.LSOCall.N4.duration=0.32 - self.LSOCall.N5.duration=0.41 - self.LSOCall.N6.duration=0.48 - self.LSOCall.N7.duration=0.51 - self.LSOCall.N8.duration=0.38 - self.LSOCall.N9.duration=0.34 - self.LSOCall.PADDLESCONTACT.duration=0.91 - self.LSOCall.POWER.duration=0.45 - self.LSOCall.RADIOCHECK.duration=0.90 - self.LSOCall.RIGHTFORLINEUP.duration=0.70 - self.LSOCall.ROGERBALL.duration=0.72 - self.LSOCall.SLOW.duration=0.63 - --self.LSOCall.SLOW.duration=0.59 --TODO - self.LSOCall.STABILIZED.duration=0.75 - self.LSOCall.WAVEOFF.duration=0.55 - self.LSOCall.WELCOMEABOARD.duration=0.80 + self.LSOCall.BOLTER.duration = 0.75 + self.LSOCall.CALLTHEBALL.duration = 0.625 + self.LSOCall.CHECK.duration = 0.40 + self.LSOCall.CLEAREDTOLAND.duration = 0.85 + self.LSOCall.COMELEFT.duration = 0.60 + self.LSOCall.DEPARTANDREENTER.duration = 1.10 + self.LSOCall.EXPECTHEAVYWAVEOFF.duration = 1.30 + self.LSOCall.EXPECTSPOT75.duration = 1.85 + self.LSOCall.EXPECTSPOT5.duration = 1.3 + self.LSOCall.FAST.duration = 0.75 + self.LSOCall.FOULDECK.duration = 0.75 + self.LSOCall.HIGH.duration = 0.65 + self.LSOCall.IDLE.duration = 0.40 + self.LSOCall.LONGINGROOVE.duration = 1.25 + self.LSOCall.LOW.duration = 0.60 + self.LSOCall.N0.duration = 0.38 + self.LSOCall.N1.duration = 0.30 + self.LSOCall.N2.duration = 0.30 + self.LSOCall.N3.duration = 0.30 + self.LSOCall.N4.duration = 0.32 + self.LSOCall.N5.duration = 0.41 + self.LSOCall.N6.duration = 0.48 + self.LSOCall.N7.duration = 0.51 + self.LSOCall.N8.duration = 0.38 + self.LSOCall.N9.duration = 0.34 + self.LSOCall.PADDLESCONTACT.duration = 0.91 + self.LSOCall.POWER.duration = 0.45 + self.LSOCall.RADIOCHECK.duration = 0.90 + self.LSOCall.RIGHTFORLINEUP.duration = 0.70 + self.LSOCall.ROGERBALL.duration = 0.72 + self.LSOCall.SLOW.duration = 0.63 + -- self.LSOCall.SLOW.duration=0.59 --TODO + self.LSOCall.STABILIZED.duration = 0.75 + self.LSOCall.WAVEOFF.duration = 0.55 + self.LSOCall.WELCOMEABOARD.duration = 0.80 end - - --- Set parameters for LSO Voice overs by *funkyfranky*. -- @param #AIRBOSS self -- @param #string mizfolder (Optional) Folder within miz file where the sound files are located. -function AIRBOSS:SetVoiceOversLSOByFF(mizfolder) +function AIRBOSS:SetVoiceOversLSOByFF( mizfolder ) -- Set sound files folder. if mizfolder then - local lastchar=string.sub(mizfolder, -1) - if lastchar~="/" then - mizfolder=mizfolder.."/" + local lastchar = string.sub( mizfolder, -1 ) + if lastchar ~= "/" then + mizfolder = mizfolder .. "/" end - self.soundfolderLSO=mizfolder + self.soundfolderLSO = mizfolder else -- Default is the general folder. - self.soundfolderLSO=self.soundfolder + self.soundfolderLSO = self.soundfolder end -- Report for duty. - self:I(self.lid..string.format("LSO FF reporting for duty! Soundfolder=%s", tostring(self.soundfolderLSO))) + self:I( self.lid .. string.format( "LSO FF reporting for duty! Soundfolder=%s", tostring( self.soundfolderLSO ) ) ) - self.LSOCall.BOLTER.duration=0.75 - self.LSOCall.CALLTHEBALL.duration=0.60 - self.LSOCall.CHECK.duration=0.45 - self.LSOCall.CLEAREDTOLAND.duration=1.00 - self.LSOCall.COMELEFT.duration=0.60 - self.LSOCall.DEPARTANDREENTER.duration=1.10 - self.LSOCall.EXPECTHEAVYWAVEOFF.duration=1.20 - self.LSOCall.EXPECTSPOT75.duration=2.00 - self.LSOCall.EXPECTSPOT5.duration=1.3 - self.LSOCall.FAST.duration=0.70 - self.LSOCall.FOULDECK.duration=0.62 - self.LSOCall.HIGH.duration=0.65 - self.LSOCall.IDLE.duration=0.45 - self.LSOCall.LONGINGROOVE.duration=1.20 - self.LSOCall.LOW.duration=0.50 - self.LSOCall.N0.duration=0.40 - self.LSOCall.N1.duration=0.25 - self.LSOCall.N2.duration=0.37 - self.LSOCall.N3.duration=0.37 - self.LSOCall.N4.duration=0.39 - self.LSOCall.N5.duration=0.39 - self.LSOCall.N6.duration=0.40 - self.LSOCall.N7.duration=0.40 - self.LSOCall.N8.duration=0.37 - self.LSOCall.N9.duration=0.40 - self.LSOCall.PADDLESCONTACT.duration=1.00 - self.LSOCall.POWER.duration=0.50 - self.LSOCall.RADIOCHECK.duration=1.10 - self.LSOCall.RIGHTFORLINEUP.duration=0.80 - self.LSOCall.ROGERBALL.duration=1.00 - self.LSOCall.SLOW.duration=0.65 - self.LSOCall.SLOW.duration=0.59 - self.LSOCall.STABILIZED.duration=0.90 - self.LSOCall.WAVEOFF.duration=0.60 - self.LSOCall.WELCOMEABOARD.duration=1.00 + self.LSOCall.BOLTER.duration = 0.75 + self.LSOCall.CALLTHEBALL.duration = 0.60 + self.LSOCall.CHECK.duration = 0.45 + self.LSOCall.CLEAREDTOLAND.duration = 1.00 + self.LSOCall.COMELEFT.duration = 0.60 + self.LSOCall.DEPARTANDREENTER.duration = 1.10 + self.LSOCall.EXPECTHEAVYWAVEOFF.duration = 1.20 + self.LSOCall.EXPECTSPOT75.duration = 2.00 + self.LSOCall.EXPECTSPOT5.duration = 1.3 + self.LSOCall.FAST.duration = 0.70 + self.LSOCall.FOULDECK.duration = 0.62 + self.LSOCall.HIGH.duration = 0.65 + self.LSOCall.IDLE.duration = 0.45 + self.LSOCall.LONGINGROOVE.duration = 1.20 + self.LSOCall.LOW.duration = 0.50 + self.LSOCall.N0.duration = 0.40 + self.LSOCall.N1.duration = 0.25 + self.LSOCall.N2.duration = 0.37 + self.LSOCall.N3.duration = 0.37 + self.LSOCall.N4.duration = 0.39 + self.LSOCall.N5.duration = 0.39 + self.LSOCall.N6.duration = 0.40 + self.LSOCall.N7.duration = 0.40 + self.LSOCall.N8.duration = 0.37 + self.LSOCall.N9.duration = 0.40 + self.LSOCall.PADDLESCONTACT.duration = 1.00 + self.LSOCall.POWER.duration = 0.50 + self.LSOCall.RADIOCHECK.duration = 1.10 + self.LSOCall.RIGHTFORLINEUP.duration = 0.80 + self.LSOCall.ROGERBALL.duration = 1.00 + self.LSOCall.SLOW.duration = 0.65 + self.LSOCall.SLOW.duration = 0.59 + self.LSOCall.STABILIZED.duration = 0.90 + self.LSOCall.WAVEOFF.duration = 0.60 + self.LSOCall.WELCOMEABOARD.duration = 1.00 end --- Intit parameters for Marshal Voice overs by *funkyfranky*. -- @param #AIRBOSS self -- @param #string mizfolder (Optional) Folder within miz file where the sound files are located. -function AIRBOSS:SetVoiceOversMarshalByFF(mizfolder) +function AIRBOSS:SetVoiceOversMarshalByFF( mizfolder ) -- Set sound files folder. if mizfolder then - local lastchar=string.sub(mizfolder, -1) - if lastchar~="/" then - mizfolder=mizfolder.."/" + local lastchar = string.sub( mizfolder, -1 ) + if lastchar ~= "/" then + mizfolder = mizfolder .. "/" end - self.soundfolderMSH=mizfolder + self.soundfolderMSH = mizfolder else -- Default is the general folder. - self.soundfolderMSH=self.soundfolder + self.soundfolderMSH = self.soundfolder end -- Report for duty. - self:I(self.lid..string.format("Marshal FF reporting for duty! Soundfolder=%s", tostring(self.soundfolderMSH))) + self:I( self.lid .. string.format( "Marshal FF reporting for duty! Soundfolder=%s", tostring( self.soundfolderMSH ) ) ) - self.MarshalCall.AFFIRMATIVE.duration=0.90 - self.MarshalCall.ALTIMETER.duration=0.85 - self.MarshalCall.BRC.duration=0.80 - self.MarshalCall.CARRIERTURNTOHEADING.duration=2.48 - self.MarshalCall.CASE.duration=0.40 - self.MarshalCall.CHARLIETIME.duration=0.90 - self.MarshalCall.CLEAREDFORRECOVERY.duration=1.25 - self.MarshalCall.DECKCLOSED.duration=1.10 - self.MarshalCall.DEGREES.duration=0.60 - self.MarshalCall.EXPECTED.duration=0.55 - self.MarshalCall.FLYNEEDLES.duration=0.90 - self.MarshalCall.HOLDATANGELS.duration=1.10 - self.MarshalCall.HOURS.duration=0.60 - self.MarshalCall.MARSHALRADIAL.duration=1.10 - self.MarshalCall.N0.duration=0.40 - self.MarshalCall.N1.duration=0.25 - self.MarshalCall.N2.duration=0.37 - self.MarshalCall.N3.duration=0.37 - self.MarshalCall.N4.duration=0.39 - self.MarshalCall.N5.duration=0.39 - self.MarshalCall.N6.duration=0.40 - self.MarshalCall.N7.duration=0.40 - self.MarshalCall.N8.duration=0.37 - self.MarshalCall.N9.duration=0.40 - self.MarshalCall.NEGATIVE.duration=0.80 - self.MarshalCall.NEWFB.duration=1.35 - self.MarshalCall.OPS.duration=0.48 - self.MarshalCall.POINT.duration=0.33 - self.MarshalCall.RADIOCHECK.duration=1.20 - self.MarshalCall.RECOVERY.duration=0.70 - self.MarshalCall.RECOVERYOPSSTOPPED.duration=1.65 - self.MarshalCall.RECOVERYPAUSEDNOTICE.duration=2.9 -- Strangely the file is actually a shorter ~2.4 sec. - self.MarshalCall.RECOVERYPAUSEDRESUMED.duration=3.40 - self.MarshalCall.REPORTSEEME.duration=0.95 - self.MarshalCall.RESUMERECOVERY.duration=1.75 - self.MarshalCall.ROGER.duration=0.53 - self.MarshalCall.SAYNEEDLES.duration=0.90 - self.MarshalCall.STACKFULL.duration=6.35 - self.MarshalCall.STARTINGRECOVERY.duration=2.65 + self.MarshalCall.AFFIRMATIVE.duration = 0.90 + self.MarshalCall.ALTIMETER.duration = 0.85 + self.MarshalCall.BRC.duration = 0.80 + self.MarshalCall.CARRIERTURNTOHEADING.duration = 2.48 + self.MarshalCall.CASE.duration = 0.40 + self.MarshalCall.CHARLIETIME.duration = 0.90 + self.MarshalCall.CLEAREDFORRECOVERY.duration = 1.25 + self.MarshalCall.DECKCLOSED.duration = 1.10 + self.MarshalCall.DEGREES.duration = 0.60 + self.MarshalCall.EXPECTED.duration = 0.55 + self.MarshalCall.FLYNEEDLES.duration = 0.90 + self.MarshalCall.HOLDATANGELS.duration = 1.10 + self.MarshalCall.HOURS.duration = 0.60 + self.MarshalCall.MARSHALRADIAL.duration = 1.10 + self.MarshalCall.N0.duration = 0.40 + self.MarshalCall.N1.duration = 0.25 + self.MarshalCall.N2.duration = 0.37 + self.MarshalCall.N3.duration = 0.37 + self.MarshalCall.N4.duration = 0.39 + self.MarshalCall.N5.duration = 0.39 + self.MarshalCall.N6.duration = 0.40 + self.MarshalCall.N7.duration = 0.40 + self.MarshalCall.N8.duration = 0.37 + self.MarshalCall.N9.duration = 0.40 + self.MarshalCall.NEGATIVE.duration = 0.80 + self.MarshalCall.NEWFB.duration = 1.35 + self.MarshalCall.OPS.duration = 0.48 + self.MarshalCall.POINT.duration = 0.33 + self.MarshalCall.RADIOCHECK.duration = 1.20 + self.MarshalCall.RECOVERY.duration = 0.70 + self.MarshalCall.RECOVERYOPSSTOPPED.duration = 1.65 + self.MarshalCall.RECOVERYPAUSEDNOTICE.duration = 2.9 -- Strangely the file is actually a shorter ~2.4 sec. + self.MarshalCall.RECOVERYPAUSEDRESUMED.duration = 3.40 + self.MarshalCall.REPORTSEEME.duration = 0.95 + self.MarshalCall.RESUMERECOVERY.duration = 1.75 + self.MarshalCall.ROGER.duration = 0.53 + self.MarshalCall.SAYNEEDLES.duration = 0.90 + self.MarshalCall.STACKFULL.duration = 6.35 + self.MarshalCall.STARTINGRECOVERY.duration = 2.65 end @@ -4878,291 +4920,44 @@ function AIRBOSS:_InitVoiceOvers() --------------- -- LSO Radio Calls. - self.LSOCall={ - BOLTER={ - file="LSO-BolterBolter", - suffix="ogg", - loud=false, - subtitle="Bolter, Bolter", - duration=0.75, - subduration=5, - }, - CALLTHEBALL={ - file="LSO-CallTheBall", - suffix="ogg", - loud=false, - subtitle="Call the ball", - duration=0.6, - subduration=2, - }, - CHECK={ - file="LSO-Check", - suffix="ogg", - loud=false, - subtitle="Check", - duration=0.45, - subduration=2.5, - }, - CLEAREDTOLAND={ - file="LSO-ClearedToLand", - suffix="ogg", - loud=false, - subtitle="Cleared to land", - duration=1.0, - subduration=5, - }, - COMELEFT={ - file="LSO-ComeLeft", - suffix="ogg", - loud=true, - subtitle="Come left", - duration=0.60, - subduration=1, - }, - RADIOCHECK={ - file="LSO-RadioCheck", - suffix="ogg", - loud=false, - subtitle="Paddles, radio check", - duration=1.1, - subduration=5, - }, - RIGHTFORLINEUP={ - file="LSO-RightForLineup", - suffix="ogg", - loud=true, - subtitle="Right for line up", - duration=0.80, - subduration=1, - }, - HIGH={ - file="LSO-High", - suffix="ogg", - loud=true, - subtitle="You're high", - duration=0.65, - subduration=1, - }, - LOW={ - file="LSO-Low", - suffix="ogg", - loud=true, - subtitle="You're low", - duration=0.50, - subduration=1, - }, - POWER={ - file="LSO-Power", - suffix="ogg", - loud=true, - subtitle="Power", - duration=0.50, --0.45 was too short - subduration=1, - }, - SLOW={ - file="LSO-Slow", - suffix="ogg", - loud=true, - subtitle="You're slow", - duration=0.65, - subduration=1, - }, - FAST={ - file="LSO-Fast", - suffix="ogg", - loud=true, - subtitle="You're fast", - duration=0.70, - subduration=1, - }, - ROGERBALL={ - file="LSO-RogerBall", - suffix="ogg", - loud=false, - subtitle="Roger ball", - duration=1.00, - subduration=2, - }, - WAVEOFF={ - file="LSO-WaveOff", - suffix="ogg", - loud=false, - subtitle="Wave off", - duration=0.6, - subduration=5, - }, - LONGINGROOVE={ - file="LSO-LongInTheGroove", - suffix="ogg", - loud=false, - subtitle="You're long in the groove", - duration=1.2, - subduration=5, - }, - FOULDECK={ - file="LSO-FoulDeck", - suffix="ogg", - loud=false, - subtitle="Foul deck", - duration=0.62, - subduration=5, - }, - DEPARTANDREENTER={ - file="LSO-DepartAndReenter", - suffix="ogg", - loud=false, - subtitle="Depart and re-enter", - duration=1.1, - subduration=5, - }, - PADDLESCONTACT={ - file="LSO-PaddlesContact", - suffix="ogg", - loud=false, - subtitle="Paddles, contact", - duration=1.0, - subduration=5, - }, - WELCOMEABOARD={ - file="LSO-WelcomeAboard", - suffix="ogg", - loud=false, - subtitle="Welcome aboard", - duration=1.0, - subduration=5, - }, - EXPECTHEAVYWAVEOFF={ - file="LSO-ExpectHeavyWaveoff", - suffix="ogg", - loud=false, - subtitle="Expect heavy waveoff", - duration=1.2, - subduration=5, - }, - EXPECTSPOT75={ - file="LSO-ExpectSpot75", - suffix="ogg", - loud=false, - subtitle="Expect spot 7.5", - duration=2.0, - subduration=5, - }, - EXPECTSPOT5={ - file="LSO-ExpectSpot5", - suffix="ogg", - loud=false, - subtitle="Expect spot 5", - duration=1.3, - subduration=5, - }, - STABILIZED={ - file="LSO-Stabilized", - suffix="ogg", - loud=false, - subtitle="Stabilized", - duration=0.9, - subduration=5, - }, - IDLE={ - file="LSO-Idle", - suffix="ogg", - loud=false, - subtitle="Idle", - duration=0.45, - subduration=5, - }, - N0={ - file="LSO-N0", - suffix="ogg", - loud=false, - subtitle="", - duration=0.40, - }, - N1={ - file="LSO-N1", - suffix="ogg", - loud=false, - subtitle="", - duration=0.25, - }, - N2={ - file="LSO-N2", - suffix="ogg", - loud=false, - subtitle="", - duration=0.37, - }, - N3={ - file="LSO-N3", - suffix="ogg", - loud=false, - subtitle="", - duration=0.37, - }, - N4={ - file="LSO-N4", - suffix="ogg", - loud=false, - subtitle="", - duration=0.39, - }, - N5={ - file="LSO-N5", - suffix="ogg", - loud=false, - subtitle="", - duration=0.39, - }, - N6={ - file="LSO-N6", - suffix="ogg", - loud=false, - subtitle="", - duration=0.40, - }, - N7={ - file="LSO-N7", - suffix="ogg", - loud=false, - subtitle="", - duration=0.40, - }, - N8={ - file="LSO-N8", - suffix="ogg", - loud=false, - subtitle="", - duration=0.37, - }, - N9={ - file="LSO-N9", - suffix="ogg", - loud=false, - subtitle="", - duration=0.40, - }, - CLICK={ - file="AIRBOSS-RadioClick", - suffix="ogg", - loud=false, - subtitle="", - duration=0.35, - }, - NOISE={ - file="AIRBOSS-Noise", - suffix="ogg", - loud=false, - subtitle="", - duration=3.6, - }, - SPINIT={ - file="AIRBOSS-SpinIt", - suffix="ogg", - loud=false, - subtitle="", - duration=0.73, - subduration=5, - }, + self.LSOCall = { + BOLTER = { file = "LSO-BolterBolter", suffix = "ogg", loud = false, subtitle = "Bolter, Bolter", duration = 0.75, subduration = 5 }, + CALLTHEBALL = { file = "LSO-CallTheBall", suffix = "ogg", loud = false, subtitle = "Call the ball", duration = 0.6, subduration = 2 }, + CHECK = { file = "LSO-Check", suffix = "ogg", loud = false, subtitle = "Check", duration = 0.45, subduration = 2.5 }, + CLEAREDTOLAND = { file = "LSO-ClearedToLand", suffix = "ogg", loud = false, subtitle = "Cleared to land", duration = 1.0, subduration = 5 }, + COMELEFT = { file = "LSO-ComeLeft", suffix = "ogg", loud = true, subtitle = "Come left", duration = 0.60, subduration = 1 }, + RADIOCHECK = { file = "LSO-RadioCheck", suffix = "ogg", loud = false, subtitle = "Paddles, radio check", duration = 1.1, subduration = 5 }, + RIGHTFORLINEUP = { file = "LSO-RightForLineup", suffix = "ogg", loud = true, subtitle = "Right for line up", duration = 0.80, subduration = 1 }, + HIGH = { file = "LSO-High", suffix = "ogg", loud = true, subtitle = "You're high", duration = 0.65, subduration = 1 }, + LOW = { file = "LSO-Low", suffix = "ogg", loud = true, subtitle = "You're low", duration = 0.50, subduration = 1 }, + POWER = { file = "LSO-Power", suffix = "ogg", loud = true, subtitle = "Power", duration = 0.50, subduration = 1 }, -- duration 0.45 was too short + SLOW = { file = "LSO-Slow", suffix = "ogg", loud = true, subtitle = "You're slow", duration = 0.65, subduration = 1 }, + FAST = { file = "LSO-Fast", suffix = "ogg", loud = true, subtitle = "You're fast", duration = 0.70, subduration = 1 }, + ROGERBALL = { file = "LSO-RogerBall", suffix = "ogg", loud = false, subtitle = "Roger ball", duration = 1.00, subduration = 2 }, + WAVEOFF = { file = "LSO-WaveOff", suffix = "ogg", loud = false, subtitle = "Wave off", duration = 0.6, subduration = 5 }, + LONGINGROOVE = { file = "LSO-LongInTheGroove", suffix = "ogg", loud = false, subtitle = "You're long in the groove", duration = 1.2, subduration = 5 }, + FOULDECK = { file = "LSO-FoulDeck", suffix = "ogg", loud = false, subtitle = "Foul deck", duration = 0.62, subduration = 5 }, + DEPARTANDREENTER = { file = "LSO-DepartAndReenter", suffix = "ogg", loud = false, subtitle = "Depart and re-enter", duration = 1.1, subduration = 5 }, + PADDLESCONTACT = { file = "LSO-PaddlesContact", suffix = "ogg", loud = false, subtitle = "Paddles, contact", duration = 1.0, subduration = 5 }, + WELCOMEABOARD = { file = "LSO-WelcomeAboard", suffix = "ogg", loud = false, subtitle = "Welcome aboard", duration = 1.0, subduration = 5 }, + EXPECTHEAVYWAVEOFF = { file = "LSO-ExpectHeavyWaveoff", suffix = "ogg", loud = false, subtitle = "Expect heavy waveoff", duration = 1.2, subduration = 5 }, + EXPECTSPOT75 = { file = "LSO-ExpectSpot75", suffix = "ogg", loud = false, subtitle = "Expect spot 7.5", duration = 2.0, subduration = 5 }, + EXPECTSPOT5 = { file = "LSO-ExpectSpot5", suffix = "ogg", loud = false, subtitle = "Expect spot 5", duration = 1.3, subduration = 5 }, + STABILIZED = { file = "LSO-Stabilized", suffix = "ogg", loud = false, subtitle = "Stabilized", duration = 0.9, subduration = 5 }, + IDLE = { file = "LSO-Idle", suffix = "ogg", loud = false, subtitle = "Idle", duration = 0.45, subduration = 5 }, + N0 = { file = "LSO-N0", suffix = "ogg", loud = false, subtitle = "", duration = 0.40 }, + N1 = { file = "LSO-N1", suffix = "ogg", loud = false, subtitle = "", duration = 0.25 }, + N2 = { file = "LSO-N2", suffix = "ogg", loud = false, subtitle = "", duration = 0.37 }, + N3 = { file = "LSO-N3", suffix = "ogg", loud = false, subtitle = "", duration = 0.37 }, + N4 = { file = "LSO-N4", suffix = "ogg", loud = false, subtitle = "", duration = 0.39 }, + N5 = { file = "LSO-N5", suffix = "ogg", loud = false, subtitle = "", duration = 0.39 }, + N6 = { file = "LSO-N6", suffix = "ogg", loud = false, subtitle = "", duration = 0.40 }, + N7 = { file = "LSO-N7", suffix = "ogg", loud = false, subtitle = "", duration = 0.40 }, + N8 = { file = "LSO-N8", suffix = "ogg", loud = false, subtitle = "", duration = 0.37 }, + N9 = { file = "LSO-N9", suffix = "ogg", loud = false, subtitle = "", duration = 0.40 }, + CLICK = { file = "AIRBOSS-RadioClick", suffix = "ogg", loud = false, subtitle = "", duration = 0.35 }, + NOISE = { file = "AIRBOSS-Noise", suffix = "ogg", loud = false, subtitle = "", duration = 3.6 }, + SPINIT = { file = "AIRBOSS-SpinIt", suffix = "ogg", loud = false, subtitle = "", duration = 0.73, subduration = 5 }, } ----------------- @@ -5170,203 +4965,28 @@ function AIRBOSS:_InitVoiceOvers() ----------------- -- Pilot Radio Calls. - self.PilotCall={ - N0={ - file="PILOT-N0", - suffix="ogg", - loud=false, - subtitle="", - duration=0.40, - }, - N1={ - file="PILOT-N1", - suffix="ogg", - loud=false, - subtitle="", - duration=0.25, - }, - N2={ - file="PILOT-N2", - suffix="ogg", - loud=false, - subtitle="", - duration=0.37, - }, - N3={ - file="PILOT-N3", - suffix="ogg", - loud=false, - subtitle="", - duration=0.37, - }, - N4={ - file="PILOT-N4", - suffix="ogg", - loud=false, - subtitle="", - duration=0.39, - }, - N5={ - file="PILOT-N5", - suffix="ogg", - loud=false, - subtitle="", - duration=0.39, - }, - N6={ - file="PILOT-N6", - suffix="ogg", - loud=false, - subtitle="", - duration=0.40, - }, - N7={ - file="PILOT-N7", - suffix="ogg", - loud=false, - subtitle="", - duration=0.40, - }, - N8={ - file="PILOT-N8", - suffix="ogg", - loud=false, - subtitle="", - duration=0.37, - }, - N9={ - file="PILOT-N9", - suffix="ogg", - loud=false, - subtitle="", - duration=0.40, - }, - POINT={ - file="PILOT-Point", - suffix="ogg", - loud=false, - subtitle="", - duration=0.33, - }, - SKYHAWK={ - file="PILOT-Skyhawk", - suffix="ogg", - loud=false, - subtitle="", - duration=0.95, - subduration=5, - }, - HARRIER={ - file="PILOT-Harrier", - suffix="ogg", - loud=false, - subtitle="", - duration=0.58, - subduration=5, - }, - HAWKEYE={ - file="PILOT-Hawkeye", - suffix="ogg", - loud=false, - subtitle="", - duration=0.63, - subduration=5, - }, - TOMCAT={ - file="PILOT-Tomcat", - suffix="ogg", - loud=false, - subtitle="", - duration=0.66, - subduration=5, - }, - HORNET={ - file="PILOT-Hornet", - suffix="ogg", - loud=false, - subtitle="", - duration=0.56, - subduration=5, - }, - VIKING={ - file="PILOT-Viking", - suffix="ogg", - loud=false, - subtitle="", - duration=0.61, - subduration=5, - }, - BALL={ - file="PILOT-Ball", - suffix="ogg", - loud=false, - subtitle="", - duration=0.50, - subduration=5, - }, - BINGOFUEL={ - file="PILOT-BingoFuel", - suffix="ogg", - loud=false, - subtitle="", - duration=0.80, - }, - GASATDIVERT={ - file="PILOT-GasAtDivert", - suffix="ogg", - loud=false, - subtitle="", - duration=1.80, - }, - GASATTANKER={ - file="PILOT-GasAtTanker", - suffix="ogg", - loud=false, - subtitle="", - duration=1.95, - }, - MARSHAL={ - file="PILOT-Marshal", - suffix="ogg", - loud=false, - subtitle="", - duration=0.50, - }, - MARKINGMOMS={ - file="PILOT-MarkingMoms", - suffix="ogg", - loud=false, - subtitle="", - duration=0.90, - }, - FOR={ - file="PILOT-For", - suffix="ogg", - loud=false, - subtitle="", - duration=0.29, - }, - ANGELS={ - file="PILOT-Angels", - suffix="ogg", - loud=false, - subtitle="", - duration=0.50, - }, - STATE={ - file="PILOT-State", - suffix="ogg", - loud=false, - subtitle="", - duration=0.40, - }, - COMMENCING={ - file="PILOT-Commencing", - suffix="ogg", - loud=false, - subtitle="", - duration=0.45, - }, + self.PilotCall = { + N0 = { file = "PILOT-N0", suffix = "ogg", loud = false, subtitle = "", duration = 0.40 }, + N1 = { file = "PILOT-N1", suffix = "ogg", loud = false, subtitle = "", duration = 0.25 }, + N2 = { file = "PILOT-N2", suffix = "ogg", loud = false, subtitle = "", duration = 0.37 }, + N3 = { file = "PILOT-N3", suffix = "ogg", loud = false, subtitle = "", duration = 0.37 }, + N4 = { file = "PILOT-N4", suffix = "ogg", loud = false, subtitle = "", duration = 0.39 }, + N5 = { file = "PILOT-N5", suffix = "ogg", loud = false, subtitle = "", duration = 0.39 }, + N6 = { file = "PILOT-N6", suffix = "ogg", loud = false, subtitle = "", duration = 0.40 }, + N7 = { file = "PILOT-N7", suffix = "ogg", loud = false, subtitle = "", duration = 0.40 }, + N8 = { file = "PILOT-N8", suffix = "ogg", loud = false, subtitle = "", duration = 0.37 }, + N9 = { file = "PILOT-N9", suffix = "ogg", loud = false, subtitle = "", duration = 0.40 }, + POINT = { file = "PILOT-Point", suffix = "ogg", loud = false, subtitle = "", duration = 0.33 }, + SKYHAWK = { file = "PILOT-Skyhawk", suffix = "ogg", loud = false, subtitle = "", duration = 0.95, subduration = 5 }, + HARRIER = { file = "PILOT-Harrier", suffix = "ogg", loud = false, subtitle = "", duration = 0.58, subduration = 5 }, + HAWKEYE = { file = "PILOT-Hawkeye", suffix = "ogg", loud = false, subtitle = "", duration = 0.63, subduration = 5 }, + TOMCAT = { file = "PILOT-Tomcat", suffix = "ogg", loud = false, subtitle = "", duration = 0.66, subduration = 5 }, + HORNET = { file = "PILOT-Hornet", suffix = "ogg", loud = false, subtitle = "", duration = 0.56, subduration = 5 }, + VIKING = { file = "PILOT-Viking", suffix = "ogg", loud = false, subtitle = "", duration = 0.61, subduration = 5 }, + BALL = { file = "PILOT-Ball", suffix = "ogg", loud = false, subtitle = "", duration = 0.50, subduration = 5 }, + BINGOFUEL = { file = "PILOT-BingoFuel", suffix = "ogg", loud = false, subtitle = "", duration = 0.80 }, + GASATDIVERT = { file = "PILOT-GasAtDivert", suffix = "ogg", loud = false, subtitle = "", duration = 1.80 }, + GASATTANKER = { file = "PILOT-GasAtTanker", suffix = "ogg", loud = false, subtitle = "", duration = 1.95 }, } ------------------- @@ -5374,309 +4994,48 @@ function AIRBOSS:_InitVoiceOvers() ------------------- -- MARSHAL Radio Calls. - self.MarshalCall={ - AFFIRMATIVE={ - file="MARSHAL-Affirmative", - suffix="ogg", - loud=false, - subtitle="", - duration=0.90, - }, - ALTIMETER={ - file="MARSHAL-Altimeter", - suffix="ogg", - loud=false, - subtitle="", - duration=0.85, - }, - BRC={ - file="MARSHAL-BRC", - suffix="ogg", - loud=false, - subtitle="", - duration=0.80, - }, - CARRIERTURNTOHEADING={ - file="MARSHAL-CarrierTurnToHeading", - suffix="ogg", - loud=false, - subtitle="", - duration=2.48, - subduration=5, - }, - CASE={ - file="MARSHAL-Case", - suffix="ogg", - loud=false, - subtitle="", - duration=0.40, - }, - CHARLIETIME={ - file="MARSHAL-CharlieTime", - suffix="ogg", - loud=false, - subtitle="", - duration=0.90, - }, - CLEAREDFORRECOVERY={ - file="MARSHAL-ClearedForRecovery", - suffix="ogg", - loud=false, - subtitle="", - duration=1.25, - }, - DECKCLOSED={ - file="MARSHAL-DeckClosed", - suffix="ogg", - loud=false, - subtitle="", - duration=1.10, - subduration=5, - }, - DEGREES={ - file="MARSHAL-Degrees", - suffix="ogg", - loud=false, - subtitle="", - duration=0.60, - }, - EXPECTED={ - file="MARSHAL-Expected", - suffix="ogg", - loud=false, - subtitle="", - duration=0.55, - }, - FLYNEEDLES={ - file="MARSHAL-FlyYourNeedles", - suffix="ogg", - loud=false, - subtitle="Fly your needles", - duration=0.9, - subduration=5, - }, - HOLDATANGELS={ - file="MARSHAL-HoldAtAngels", - suffix="ogg", - loud=false, - subtitle="", - duration=1.10, - }, - HOURS={ - file="MARSHAL-Hours", - suffix="ogg", - loud=false, - subtitle="", - duration=0.60, - subduration=5, - }, - MARSHALRADIAL={ - file="MARSHAL-MarshalRadial", - suffix="ogg", - loud=false, - subtitle="", - duration=1.10, - }, - N0={ - file="MARSHAL-N0", - suffix="ogg", - loud=false, - subtitle="", - duration=0.40, - }, - N1={ - file="MARSHAL-N1", - suffix="ogg", - loud=false, - subtitle="", - duration=0.25, - }, - N2={ - file="MARSHAL-N2", - suffix="ogg", - loud=false, - subtitle="", - duration=0.37, - }, - N3={ - file="MARSHAL-N3", - suffix="ogg", - loud=false, - subtitle="", - duration=0.37, - }, - N4={ - file="MARSHAL-N4", - suffix="ogg", - loud=false, - subtitle="", - duration=0.39, - }, - N5={ - file="MARSHAL-N5", - suffix="ogg", - loud=false, - subtitle="", - duration=0.39, - }, - N6={ - file="MARSHAL-N6", - suffix="ogg", - loud=false, - subtitle="", - duration=0.40, - }, - N7={ - file="MARSHAL-N7", - suffix="ogg", - loud=false, - subtitle="", - duration=0.40, - }, - N8={ - file="MARSHAL-N8", - suffix="ogg", - loud=false, - subtitle="", - duration=0.37, - }, - N9={ - file="MARSHAL-N9", - suffix="ogg", - loud=false, - subtitle="", - duration=0.40, - }, - NEGATIVE={ - file="MARSHAL-Negative", - suffix="ogg", - loud=false, - subtitle="", - duration=0.80, - subduration=5, - }, - NEWFB={ - file="MARSHAL-NewFB", - suffix="ogg", - loud=false, - subtitle="", - duration=1.35, - }, - OPS={ - file="MARSHAL-Ops", - suffix="ogg", - loud=false, - subtitle="", - duration=0.48, - }, - POINT={ - file="MARSHAL-Point", - suffix="ogg", - loud=false, - subtitle="", - duration=0.33, - }, - RADIOCHECK={ - file="MARSHAL-RadioCheck", - suffix="ogg", - loud=false, - subtitle="Radio check", - duration=1.20, - subduration=5, - }, - RECOVERY={ - file="MARSHAL-Recovery", - suffix="ogg", - loud=false, - subtitle="", - duration=0.70, - subduration=5, - }, - RECOVERYOPSSTOPPED={ - file="MARSHAL-RecoveryOpsStopped", - suffix="ogg", - loud=false, - subtitle="", - duration=1.65, - subduration=5, - }, - RECOVERYPAUSEDNOTICE={ - file="MARSHAL-RecoveryPausedNotice", - suffix="ogg", - loud=false, - subtitle="aircraft recovery paused until further notice", - duration=2.90, - subduration=5, - }, - RECOVERYPAUSEDRESUMED={ - file="MARSHAL-RecoveryPausedResumed", - suffix="ogg", - loud=false, - subtitle="", - duration=3.40, - subduration=5, - }, - REPORTSEEME={ - file="MARSHAL-ReportSeeMe", - suffix="ogg", - loud=false, - subtitle="", - duration=0.95, - }, - RESUMERECOVERY={ - file="MARSHAL-ResumeRecovery", - suffix="ogg", - loud=false, - subtitle="resuming aircraft recovery", - duration=1.75, - subduraction=5, - }, - ROGER={ - file="MARSHAL-Roger", - suffix="ogg", - loud=false, - subtitle="", - duration=0.53, - subduration=5, - }, - SAYNEEDLES={ - file="MARSHAL-SayNeedles", - suffix="ogg", - loud=false, - subtitle="Say needles", - duration=0.90, - subduration=5, - }, - STACKFULL={ - file="MARSHAL-StackFull", - suffix="ogg", - loud=false, - subtitle="Marshal Stack is currently full. Hold outside 10 NM zone and wait for further instructions", - duration=6.35, - subduration=10, - }, - STARTINGRECOVERY={ - file="MARSHAL-StartingRecovery", - suffix="ogg", - loud=false, - subtitle="", - duration=2.65, - subduration=5, - }, - CLICK={ - file="AIRBOSS-RadioClick", - suffix="ogg", - loud=false, - subtitle="", - duration=0.35, - }, - NOISE={ - file="AIRBOSS-Noise", - suffix="ogg", - loud=false, - subtitle="", - duration=3.6, - }, + self.MarshalCall = { + AFFIRMATIVE = { file = "MARSHAL-Affirmative", suffix = "ogg", loud = false, subtitle = "", duration = 0.90 }, + ALTIMETER = { file = "MARSHAL-Altimeter", suffix = "ogg", loud = false, subtitle = "", duration = 0.85 }, + BRC = { file = "MARSHAL-BRC", suffix = "ogg", loud = false, subtitle = "", duration = 0.80 }, + CARRIERTURNTOHEADING = { file = "MARSHAL-CarrierTurnToHeading", suffix = "ogg", loud = false, subtitle = "", duration = 2.48, subduration = 5 }, + CASE = { file = "MARSHAL-Case", suffix = "ogg", loud = false, subtitle = "", duration = 0.40 }, + CHARLIETIME = { file = "MARSHAL-CharlieTime", suffix = "ogg", loud = false, subtitle = "", duration = 0.90 }, + CLEAREDFORRECOVERY = { file = "MARSHAL-ClearedForRecovery", suffix = "ogg", loud = false, subtitle = "", duration = 1.25 }, + DECKCLOSED = { file = "MARSHAL-DeckClosed", suffix = "ogg", loud = false, subtitle = "", duration = 1.10, subduration = 5 }, + DEGREES = { file = "MARSHAL-Degrees", suffix = "ogg", loud = false, subtitle = "", duration = 0.60 }, + EXPECTED = { file = "MARSHAL-Expected", suffix = "ogg", loud = false, subtitle = "", duration = 0.55 }, + FLYNEEDLES = { file = "MARSHAL-FlyYourNeedles", suffix = "ogg", loud = false, subtitle = "Fly your needles", duration = 0.9, subduration = 5 }, + HOLDATANGELS = { file = "MARSHAL-HoldAtAngels", suffix = "ogg", loud = false, subtitle = "", duration = 1.10 }, + HOURS = { file = "MARSHAL-Hours", suffix = "ogg", loud = false, subtitle = "", duration = 0.60, subduration = 5 }, + MARSHALRADIAL = { file = "MARSHAL-MarshalRadial", suffix = "ogg", loud = false, subtitle = "", duration = 1.10 }, + N0 = { file = "MARSHAL-N0", suffix = "ogg", loud = false, subtitle = "", duration = 0.40 }, + N1 = { file = "MARSHAL-N1", suffix = "ogg", loud = false, subtitle = "", duration = 0.25 }, + N2 = { file = "MARSHAL-N2", suffix = "ogg", loud = false, subtitle = "", duration = 0.37 }, + N3 = { file = "MARSHAL-N3", suffix = "ogg", loud = false, subtitle = "", duration = 0.37 }, + N4 = { file = "MARSHAL-N4", suffix = "ogg", loud = false, subtitle = "", duration = 0.39 }, + N5 = { file = "MARSHAL-N5", suffix = "ogg", loud = false, subtitle = "", duration = 0.39 }, + N6 = { file = "MARSHAL-N6", suffix = "ogg", loud = false, subtitle = "", duration = 0.40 }, + N7 = { file = "MARSHAL-N7", suffix = "ogg", loud = false, subtitle = "", duration = 0.40 }, + N8 = { file = "MARSHAL-N8", suffix = "ogg", loud = false, subtitle = "", duration = 0.37 }, + N9 = { file = "MARSHAL-N9", suffix = "ogg", loud = false, subtitle = "", duration = 0.40 }, + NEGATIVE = { file = "MARSHAL-Negative", suffix = "ogg", loud = false, subtitle = "", duration = 0.80, subduration = 5 }, + NEWFB = { file = "MARSHAL-NewFB", suffix = "ogg", loud = false, subtitle = "", duration = 1.35 }, + OPS = { file = "MARSHAL-Ops", suffix = "ogg", loud = false, subtitle = "", duration = 0.48 }, + POINT = { file = "MARSHAL-Point", suffix = "ogg", loud = false, subtitle = "", duration = 0.33 }, + RADIOCHECK = { file = "MARSHAL-RadioCheck", suffix = "ogg", loud = false, subtitle = "Radio check", duration = 1.20, subduration = 5 }, + RECOVERY = { file = "MARSHAL-Recovery", suffix = "ogg", loud = false, subtitle = "", duration = 0.70, subduration = 5 }, + RECOVERYOPSSTOPPED = { file = "MARSHAL-RecoveryOpsStopped", suffix = "ogg", loud = false, subtitle = "", duration = 1.65, subduration = 5 }, + RECOVERYPAUSEDNOTICE = { file = "MARSHAL-RecoveryPausedNotice", suffix = "ogg", loud = false, subtitle = "aircraft recovery paused until further notice", duration = 2.90, subduration = 5 }, + RECOVERYPAUSEDRESUMED = { file = "MARSHAL-RecoveryPausedResumed", suffix = "ogg", loud = false, subtitle = "", duration = 3.40, subduration = 5 }, + REPORTSEEME = { file = "MARSHAL-ReportSeeMe", suffix = "ogg", loud = false, subtitle = "", duration = 0.95 }, + RESUMERECOVERY = { file = "MARSHAL-ResumeRecovery", suffix = "ogg", loud = false, subtitle = "resuming aircraft recovery", duration = 1.75, subduraction = 5 }, + ROGER = { file = "MARSHAL-Roger", suffix = "ogg", loud = false, subtitle = "", duration = 0.53, subduration = 5 }, + SAYNEEDLES = { file = "MARSHAL-SayNeedles", suffix = "ogg", loud = false, subtitle = "Say needles", duration = 0.90, subduration = 5 }, + STACKFULL = { file = "MARSHAL-StackFull", suffix = "ogg", loud = false, subtitle = "Marshal Stack is currently full. Hold outside 10 NM zone and wait for further instructions", duration = 6.35, subduration = 10 }, + STARTINGRECOVERY = { file = "MARSHAL-StartingRecovery", suffix = "ogg", loud = false, subtitle = "", duration = 2.65, subduration = 5 }, + CLICK = { file = "AIRBOSS-RadioClick", suffix = "ogg", loud = false, subtitle = "", duration = 0.35 }, + NOISE = { file = "AIRBOSS-Noise", suffix = "ogg", loud = false, subtitle = "", duration = 3.6 }, } -- Default timings by Raynor @@ -5693,77 +5052,79 @@ end -- @param #number subduration (Optional) Duration how long the subtitle is displayed. -- @param #string filename (Optional) Name of the voice over sound file. -- @param #string suffix (Optional) Extention of file. Default ".ogg". -function AIRBOSS:SetVoiceOver(radiocall, duration, subtitle, subduration, filename, suffix) - radiocall.duration=duration - radiocall.subtitle=subtitle or radiocall.subtitle - radiocall.file=filename - radiocall.suffix=suffix or ".ogg" +function AIRBOSS:SetVoiceOver( radiocall, duration, subtitle, subduration, filename, suffix ) + radiocall.duration = duration + radiocall.subtitle = subtitle or radiocall.subtitle + radiocall.file = filename + radiocall.suffix = suffix or ".ogg" end --- Get optimal aircraft AoA parameters.. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data table. -- @return #AIRBOSS.AircraftAoA AoA parameters for the given aircraft type. -function AIRBOSS:_GetAircraftAoA(playerData) +function AIRBOSS:_GetAircraftAoA( playerData ) -- Get AC type. - local hornet=playerData.actype==AIRBOSS.AircraftCarrier.HORNET - local goshawk=playerData.actype==AIRBOSS.AircraftCarrier.T45C - local skyhawk=playerData.actype==AIRBOSS.AircraftCarrier.A4EC - local harrier=playerData.actype==AIRBOSS.AircraftCarrier.AV8B - local tomcat=playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B + local hornet = playerData.actype == AIRBOSS.AircraftCarrier.HORNET + local goshawk = playerData.actype == AIRBOSS.AircraftCarrier.T45C + local skyhawk = playerData.actype == AIRBOSS.AircraftCarrier.A4EC + local harrier = playerData.actype == AIRBOSS.AircraftCarrier.AV8B + local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B -- Table with AoA values. - local aoa={} -- #AIRBOSS.AircraftAoA + local aoa = {} -- #AIRBOSS.AircraftAoA if hornet then -- F/A-18C Hornet parameters. - aoa.SLOW = 9.8 - aoa.Slow = 9.3 + aoa.SLOW = 9.8 + aoa.Slow = 9.3 aoa.OnSpeedMax = 8.8 - aoa.OnSpeed = 8.1 + aoa.OnSpeed = 8.1 aoa.OnSpeedMin = 7.4 - aoa.Fast = 6.9 - aoa.FAST = 6.3 + aoa.Fast = 6.9 + aoa.FAST = 6.3 elseif tomcat then -- F-14A/B Tomcat parameters (taken from NATOPS). Converted from units 0-30 to degrees. -- Currently assuming a linear relationship with 0=-10 degrees and 30=+40 degrees as stated in NATOPS. - aoa.SLOW = self:_AoAUnit2Deg(playerData, 17.0) --18.33 --17.0 units - aoa.Slow = self:_AoAUnit2Deg(playerData, 16.0) --16.67 --16.0 units - aoa.OnSpeedMax = self:_AoAUnit2Deg(playerData, 15.5) --15.83 --15.5 units - aoa.OnSpeed = self:_AoAUnit2Deg(playerData, 15.0) --15.0 --15.0 units - aoa.OnSpeedMin = self:_AoAUnit2Deg(playerData, 14.5) --14.17 --14.5 units - aoa.Fast = self:_AoAUnit2Deg(playerData, 14.0) --13.33 --14.0 units - aoa.FAST = self:_AoAUnit2Deg(playerData, 13.0) --11.67 --13.0 units + aoa.SLOW = self:_AoAUnit2Deg( playerData, 17.0 ) -- 18.33 --17.0 units + aoa.Slow = self:_AoAUnit2Deg( playerData, 16.0 ) -- 16.67 --16.0 units + aoa.OnSpeedMax = self:_AoAUnit2Deg( playerData, 15.5 ) -- 15.83 --15.5 units + aoa.OnSpeed = self:_AoAUnit2Deg( playerData, 15.0 ) -- 15.0 --15.0 units + aoa.OnSpeedMin = self:_AoAUnit2Deg( playerData, 14.5 ) -- 14.17 --14.5 units + aoa.Fast = self:_AoAUnit2Deg( playerData, 14.0 ) -- 13.33 --14.0 units + aoa.FAST = self:_AoAUnit2Deg( playerData, 13.0 ) -- 11.67 --13.0 units elseif goshawk then -- T-45C Goshawk parameters. - aoa.SLOW = 8.00 --19 - aoa.Slow = 7.75 --18 - aoa.OnSpeedMax = 7.25 --17.5 - aoa.OnSpeed = 7.00 --17 - aoa.OnSpeedMin = 6.75 --16.5 - aoa.Fast = 6.25 --16 - aoa.FAST = 6.00 --15 + aoa.SLOW = 8.00 -- 19 + aoa.Slow = 7.75 -- 18 + aoa.OnSpeedMax = 7.25 -- 17.5 + aoa.OnSpeed = 7.00 -- 17 + aoa.OnSpeedMin = 6.75 -- 16.5 + aoa.Fast = 6.25 -- 16 + aoa.FAST = 6.00 -- 15 elseif skyhawk then -- A-4E-C Skyhawk parameters from https://forums.eagle.ru/showpost.php?p=3703467&postcount=390 -- Note that these are arbitrary UNITS and not degrees. We need a conversion formula! -- Github repo suggests they simply use a factor of two to get from degrees to units. - aoa.SLOW = 9.50 --=19.0/2 - aoa.Slow = 9.25 --=18.5/2 - aoa.OnSpeedMax = 9.00 --=18.0/2 - aoa.OnSpeed = 8.75 --=17.5/2 8.1 - aoa.OnSpeedMin = 8.50 --=17.0/2 - aoa.Fast = 8.25 --=17.5/2 - aoa.FAST = 8.00 --=16.5/2 + aoa.SLOW = 9.50 -- =19.0/2 + aoa.Slow = 9.25 -- =18.5/2 + aoa.OnSpeedMax = 9.00 -- =18.0/2 + aoa.OnSpeed = 8.75 -- =17.5/2 8.1 + aoa.OnSpeedMin = 8.50 -- =17.0/2 + aoa.Fast = 8.25 -- =17.5/2 + aoa.FAST = 8.00 -- =16.5/2 elseif harrier then - -- AV-8B Harrier parameters. Tuning done on the Fast AoA to allow for abeam and ninety at Nozzles 60 - 73. - aoa.SLOW = 14.0 - aoa.Slow = 13.0 - aoa.OnSpeedMax = 12.0 - aoa.OnSpeed = 11.0 - aoa.OnSpeedMin = 10.0 + + -- AV-8B Harrier parameters. Tuning done on the Fast AoA to allow for abeam and ninety at Nozzles 55. Pene testing + aoa.SLOW = 16.0 + aoa.Slow = 13.5 + aoa.OnSpeedMax = 12.5 + aoa.OnSpeed = 10.0 + aoa.OnSpeedMin = 9.5 aoa.Fast = 8.0 aoa.FAST = 7.5 + end return aoa @@ -5774,13 +5135,13 @@ end -- @param #AIRBOSS.PlayerData playerData Player data table. -- @param #number aoaunits AoA in arbitrary units. -- @return #number AoA in degrees. -function AIRBOSS:_AoAUnit2Deg(playerData, aoaunits) +function AIRBOSS:_AoAUnit2Deg( playerData, aoaunits ) -- Init. - local degrees=aoaunits + local degrees = aoaunits -- Check aircraft type of player. - if playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then + if playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B then ------------- -- F-14A/B -- @@ -5792,20 +5153,20 @@ function AIRBOSS:_AoAUnit2Deg(playerData, aoaunits) -- Assuming a linear relationship between these to points of the graph. -- However: AoA=15 Units ==> 15 degrees, which is too much. - degrees=-10+50/30*aoaunits + degrees = -10 + 50 / 30 * aoaunits -- HB Facebook page https://www.facebook.com/heatblur/photos/a.683612385159716/754368278084126 -- AoA=15 Units <==> AoA=10.359 degrees. - degrees=0.918*aoaunits-3.411 + degrees = 0.918 * aoaunits - 3.411 - elseif playerData.actype==AIRBOSS.AircraftCarrier.A4EC then + elseif playerData.actype == AIRBOSS.AircraftCarrier.A4EC then ---------- -- A-4E -- ---------- -- A-4E-C source code suggests a simple factor of 1/2 for conversion. - degrees=0.5*aoaunits + degrees = 0.5 * aoaunits end @@ -5817,13 +5178,13 @@ end -- @param #AIRBOSS.PlayerData playerData Player data table. -- @param #number degrees AoA in degrees. -- @return #number AoA in arbitrary units. -function AIRBOSS:_AoADeg2Units(playerData, degrees) +function AIRBOSS:_AoADeg2Units( playerData, degrees ) -- Init. - local aoaunits=degrees + local aoaunits = degrees -- Check aircraft type of player. - if playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then + if playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B then ------------- -- F-14A/B -- @@ -5834,20 +5195,20 @@ function AIRBOSS:_AoADeg2Units(playerData, degrees) -- unit=30 ==> alpha=+40 degrees. -- Assuming a linear relationship between these to points of the graph. - aoaunits=(degrees+10)*30/50 + aoaunits = (degrees + 10) * 30 / 50 -- HB Facebook page https://www.facebook.com/heatblur/photos/a.683612385159716/754368278084126 -- AoA=15 Units <==> AoA=10.359 degrees. - aoaunits=1.089*degrees+3.715 + aoaunits = 1.089 * degrees + 3.715 - elseif playerData.actype==AIRBOSS.AircraftCarrier.A4EC then + elseif playerData.actype == AIRBOSS.AircraftCarrier.A4EC then ---------- -- A-4E -- ---------- -- A-4E source code suggests a simple factor of two as conversion. - aoaunits=2*degrees + aoaunits = 2 * degrees end @@ -5862,17 +5223,16 @@ end -- @return #number Angle of Attack or nil. -- @return #number Distance to carrier in meters or nil. -- @return #number Speed in m/s or nil. -function AIRBOSS:_GetAircraftParameters(playerData, step) +function AIRBOSS:_GetAircraftParameters( playerData, step ) -- Get parameters depended on step. - step=step or playerData.step + step = step or playerData.step -- Get AC type. - local hornet=playerData.actype==AIRBOSS.AircraftCarrier.HORNET - local skyhawk=playerData.actype==AIRBOSS.AircraftCarrier.A4EC - local tomcat=playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B - local harrier=playerData.actype==AIRBOSS.AircraftCarrier.AV8B - local goshawk=playerData.actype==AIRBOSS.AircraftCarrier.T45C + local hornet = playerData.actype == AIRBOSS.AircraftCarrier.HORNET + local skyhawk = playerData.actype == AIRBOSS.AircraftCarrier.A4EC + local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B + local harrier = playerData.actype == AIRBOSS.AircraftCarrier.AV8B -- Return values. local alt @@ -5881,153 +5241,154 @@ function AIRBOSS:_GetAircraftParameters(playerData, step) local speed -- Aircraft specific AoA. - local aoaac=self:_GetAircraftAoA(playerData) + local aoaac = self:_GetAircraftAoA( playerData ) - if step==AIRBOSS.PatternStep.PLATFORM then + if step == AIRBOSS.PatternStep.PLATFORM then - alt=UTILS.FeetToMeters(5000) + alt = UTILS.FeetToMeters( 5000 ) - --dist=UTILS.NMToMeters(20) + -- dist=UTILS.NMToMeters(20) - speed=UTILS.KnotsToMps(250) + speed = UTILS.KnotsToMps( 250 ) - elseif step==AIRBOSS.PatternStep.ARCIN then + elseif step == AIRBOSS.PatternStep.ARCIN then - if tomcat then - speed=UTILS.KnotsToMps(150) - else - speed=UTILS.KnotsToMps(250) - end + if tomcat then + speed = UTILS.KnotsToMps( 150 ) + else + speed = UTILS.KnotsToMps( 250 ) + end - elseif step==AIRBOSS.PatternStep.ARCOUT then + elseif step == AIRBOSS.PatternStep.ARCOUT then - if tomcat then - speed=UTILS.KnotsToMps(150) - else - speed=UTILS.KnotsToMps(250) - end + if tomcat then + speed = UTILS.KnotsToMps( 150 ) + else + speed = UTILS.KnotsToMps( 250 ) + end - elseif step==AIRBOSS.PatternStep.DIRTYUP then + elseif step == AIRBOSS.PatternStep.DIRTYUP then - alt=UTILS.FeetToMeters(1200) + alt = UTILS.FeetToMeters( 1200 ) - --speed=UTILS.KnotsToMps(250) + -- speed=UTILS.KnotsToMps(250) - elseif step==AIRBOSS.PatternStep.BULLSEYE then + elseif step == AIRBOSS.PatternStep.BULLSEYE then - alt=UTILS.FeetToMeters(1200) + alt = UTILS.FeetToMeters( 1200 ) - dist=-UTILS.NMToMeters(3) + dist = -UTILS.NMToMeters( 3 ) - aoa=aoaac.OnSpeed + aoa = aoaac.OnSpeed - elseif step==AIRBOSS.PatternStep.INITIAL then + elseif step == AIRBOSS.PatternStep.INITIAL then if hornet or tomcat or harrier then - alt=UTILS.FeetToMeters(800) - speed=UTILS.KnotsToMps(350) + alt = UTILS.FeetToMeters( 800 ) + speed = UTILS.KnotsToMps( 350 ) elseif skyhawk then - alt=UTILS.FeetToMeters(600) - speed=UTILS.KnotsToMps(250) - elseif goshawk then - alt=UTILS.FeetToMeters(800) - speed=UTILS.KnotsToMps(300) + + alt = UTILS.FeetToMeters( 600 ) + speed = UTILS.KnotsToMps( 250 ) + elseif goshawk then + alt = UTILS.FeetToMeters( 800 ) + speed = UTILS.KnotsToMps( 300 ) end - elseif step==AIRBOSS.PatternStep.BREAKENTRY then + elseif step == AIRBOSS.PatternStep.BREAKENTRY then if hornet or tomcat or harrier then - alt=UTILS.FeetToMeters(800) - speed=UTILS.KnotsToMps(350) + alt = UTILS.FeetToMeters( 800 ) + speed = UTILS.KnotsToMps( 350 ) elseif skyhawk then - alt=UTILS.FeetToMeters(600) - speed=UTILS.KnotsToMps(250) - elseif goshawk then - alt=UTILS.FeetToMeters(800) - speed=UTILS.KnotsToMps(300) + alt = UTILS.FeetToMeters( 600 ) + speed = UTILS.KnotsToMps( 250 ) + elseif goshawk then + alt = UTILS.FeetToMeters( 800 ) + speed = UTILS.KnotsToMps( 300 ) end - elseif step==AIRBOSS.PatternStep.EARLYBREAK then + elseif step == AIRBOSS.PatternStep.EARLYBREAK then if hornet or tomcat or harrier or goshawk then - alt=UTILS.FeetToMeters(800) + alt = UTILS.FeetToMeters( 800 ) elseif skyhawk then - alt=UTILS.FeetToMeters(600) + alt = UTILS.FeetToMeters( 600 ) end - elseif step==AIRBOSS.PatternStep.LATEBREAK then + elseif step == AIRBOSS.PatternStep.LATEBREAK then if hornet or tomcat or harrier or goshawk then - alt=UTILS.FeetToMeters(800) + alt = UTILS.FeetToMeters( 800 ) elseif skyhawk then - alt=UTILS.FeetToMeters(600) + alt = UTILS.FeetToMeters( 600 ) end - elseif step==AIRBOSS.PatternStep.ABEAM then + elseif step == AIRBOSS.PatternStep.ABEAM then if hornet or tomcat or harrier or goshawk then - alt=UTILS.FeetToMeters(600) + alt = UTILS.FeetToMeters( 600 ) elseif skyhawk then - alt=UTILS.FeetToMeters(500) + alt = UTILS.FeetToMeters( 500 ) end - aoa=aoaac.OnSpeed + aoa = aoaac.OnSpeed if harrier then -- 0.8 to 1.0 NM - dist=UTILS.NMToMeters(0.9) + dist = UTILS.NMToMeters( 0.9 ) else - dist=UTILS.NMToMeters(1.2) + dist = UTILS.NMToMeters( 1.2 ) end - if goshawk then + if goshawk then -- 0.9 to 1.1 NM per natops ch.4 page 48 - dist=UTILS.NMToMeters(0.9) + dist = UTILS.NMToMeters( 0.9 ) else - dist=UTILS.NMToMeters(1.1) + dist = UTILS.NMToMeters( 1.1 ) end - elseif step==AIRBOSS.PatternStep.NINETY then + elseif step == AIRBOSS.PatternStep.NINETY then if hornet or tomcat then - alt=UTILS.FeetToMeters(500) - elseif goshawk then - alt=UTILS.FeetToMeters(450) + alt = UTILS.FeetToMeters( 500 ) + elseif goshawk then + alt = UTILS.FeetToMeters( 450 ) elseif skyhawk then - alt=UTILS.FeetToMeters(500) + alt = UTILS.FeetToMeters( 500 ) elseif harrier then - alt=UTILS.FeetToMeters(425) + alt = UTILS.FeetToMeters( 425 ) end - aoa=aoaac.OnSpeed + aoa = aoaac.OnSpeed - elseif step==AIRBOSS.PatternStep.WAKE then + elseif step == AIRBOSS.PatternStep.WAKE then if hornet or goshawk then - alt=UTILS.FeetToMeters(370) + alt = UTILS.FeetToMeters( 370 ) elseif tomcat then - alt=UTILS.FeetToMeters(430) -- Tomcat should be a bit higher as it intercepts the GS a bit higher. + alt = UTILS.FeetToMeters( 430 ) -- Tomcat should be a bit higher as it intercepts the GS a bit higher. elseif skyhawk then - alt=UTILS.FeetToMeters(370) --? + alt = UTILS.FeetToMeters( 370 ) -- ? end -- Harrier wont get into wake pos. Runway is not angled and it stays port. - aoa=aoaac.OnSpeed + aoa = aoaac.OnSpeed - elseif step==AIRBOSS.PatternStep.FINAL then + elseif step == AIRBOSS.PatternStep.FINAL then if hornet or goshawk then - alt=UTILS.FeetToMeters(300) + alt = UTILS.FeetToMeters( 300 ) elseif tomcat then - alt=UTILS.FeetToMeters(360) + alt = UTILS.FeetToMeters( 360 ) elseif skyhawk then - alt=UTILS.FeetToMeters(300) --? + alt = UTILS.FeetToMeters( 300 ) -- ? elseif harrier then - -- 300-325 ft - alt=UTILS.FeetToMeters(300)-- Need to verify + alt=UTILS.FeetToMeters(312)-- 300-325 ft + end - aoa=aoaac.OnSpeed + aoa = aoaac.OnSpeed end @@ -6044,30 +5405,30 @@ end function AIRBOSS:_GetNextMarshalFight() -- Loop over all marshal flights. - for _,_flight in pairs(self.Qmarshal) do - local flight=_flight --#AIRBOSS.FlightGroup + for _, _flight in pairs( self.Qmarshal ) do + local flight = _flight -- #AIRBOSS.FlightGroup -- Current stack. - local stack=flight.flag + local stack = flight.flag -- Total marshal time in seconds. - local Tmarshal=timer.getAbsTime()-flight.time + local Tmarshal = timer.getAbsTime() - flight.time -- Min time in marshal stack. - local TmarshalMin=2*60 --Two minutes for human players. + local TmarshalMin = 2 * 60 -- Two minutes for human players. if flight.ai then - TmarshalMin=3*60 -- Three minutes for AI. + TmarshalMin = 3 * 60 -- Three minutes for AI. end -- Check if conditions are right. - if flight.holding~=nil and Tmarshal>=TmarshalMin then - if flight.case==1 and stack==1 or flight.case>1 then + if flight.holding ~= nil and Tmarshal >= TmarshalMin then + if flight.case == 1 and stack == 1 or flight.case > 1 then if flight.ai then -- Return AI flight. return flight else -- Check for human player if they are already commencing. - if flight.step~=AIRBOSS.PatternStep.COMMENCING then + if flight.step ~= AIRBOSS.PatternStep.COMMENCING then return flight end end @@ -6084,34 +5445,34 @@ function AIRBOSS:_CheckQueue() -- Print queues. if self.Debug then - self:_PrintQueue(self.flights, "All Flights") + self:_PrintQueue( self.flights, "All Flights" ) end - self:_PrintQueue(self.Qmarshal, "Marshal") - self:_PrintQueue(self.Qpattern, "Pattern") - self:_PrintQueue(self.Qwaiting, "Waiting") - self:_PrintQueue(self.Qspinning, "Spinning") + self:_PrintQueue( self.Qmarshal, "Marshal" ) + self:_PrintQueue( self.Qpattern, "Pattern" ) + self:_PrintQueue( self.Qwaiting, "Waiting" ) + self:_PrintQueue( self.Qspinning, "Spinning" ) -- If flights are waiting outside 10 NM zone and carrier switches from Case I to Case II/III, they should be added to the Marshal stack as now there is no stack limit any more. - if self.case>1 then - for _,_flight in pairs(self.Qwaiting) do - local flight=_flight --#AIRBOSS.FlightGroup + if self.case > 1 then + for _, _flight in pairs( self.Qwaiting ) do + local flight = _flight -- #AIRBOSS.FlightGroup -- Remove flight from waiting queue. - local removed=self:_RemoveFlightFromQueue(self.Qwaiting, flight) + local removed = self:_RemoveFlightFromQueue( self.Qwaiting, flight ) if removed then -- Get free stack - local stack=self:_GetFreeStack(flight.ai) + local stack = self:_GetFreeStack( flight.ai ) -- Debug info. - self:T(self.lid..string.format("Moving flight %s onboard %s from Waiting queue to Case %d Marshal stack %d", flight.groupname, flight.onboard, self.case, stack)) + self:T( self.lid .. string.format( "Moving flight %s onboard %s from Waiting queue to Case %d Marshal stack %d", flight.groupname, flight.onboard, self.case, stack ) ) -- Send flight to marshal stack. if flight.ai then - self:_MarshalAI(flight, stack) + self:_MarshalAI( flight, stack ) else - self:_MarshalPlayer(flight, stack) + self:_MarshalPlayer( flight, stack ) end -- Break the loop so that only one flight per 30 seconds is removed. @@ -6129,40 +5490,40 @@ function AIRBOSS:_CheckQueue() ----------------------------- -- Loop over all flights currently in the marshal queue. - for _,_flight in pairs(self.Qmarshal) do - local flight=_flight --#AIRBOSS.FlightGroup + for _, _flight in pairs( self.Qmarshal ) do + local flight = _flight -- #AIRBOSS.FlightGroup -- TODO: In principle this should be done/necessary only if case 1-->2/3 or 2/3-->1, right? -- When recovery switches from 2->3 or 3-->2 nothing changes in the marshal stack. -- Check if a change of stack is necessary. - if (flight.case==1 and self.case>1) or (flight.case>1 and self.case==1) then + if (flight.case == 1 and self.case > 1) or (flight.case > 1 and self.case == 1) then -- Remove flight from marshal queue. - local removed=self:_RemoveFlightFromQueue(self.Qmarshal, flight) + local removed = self:_RemoveFlightFromQueue( self.Qmarshal, flight ) if removed then -- Get free stack - local stack=self:_GetFreeStack(flight.ai) + local stack = self:_GetFreeStack( flight.ai ) -- Debug output. - self:T(self.lid..string.format("Moving flight %s onboard %s from Marshal Case %d ==> %d Marshal stack %d", flight.groupname, flight.onboard, flight.case, self.case, stack)) + self:T( self.lid .. string.format( "Moving flight %s onboard %s from Marshal Case %d ==> %d Marshal stack %d", flight.groupname, flight.onboard, flight.case, self.case, stack ) ) -- Send flight to marshal queue. if flight.ai then - self:_MarshalAI(flight, stack) + self:_MarshalAI( flight, stack ) else - self:_MarshalPlayer(flight, stack) + self:_MarshalPlayer( flight, stack ) end -- Break the loop so that only one flight per 30 seconds is removed. No spam of messages, no conflict with the loop over queue entries. break - elseif flight.case~=self.case then + elseif flight.case ~= self.case then -- This should handle 2-->3 or 3-->2 - flight.case=self.case + flight.case = self.case end @@ -6174,74 +5535,73 @@ function AIRBOSS:_CheckQueue() end -- Get number of airborne aircraft units(!) currently in pattern. - local _,npattern=self:_GetQueueInfo(self.Qpattern) + local _, npattern = self:_GetQueueInfo( self.Qpattern ) -- Get number of aircraft units spinning. - local _,nspinning=self:_GetQueueInfo(self.Qspinning) + local _, nspinning = self:_GetQueueInfo( self.Qspinning ) -- Get next marshal flight. - local marshalflight=self:_GetNextMarshalFight() + local marshalflight = self:_GetNextMarshalFight() -- Check if there are flights waiting in the Marshal stack and if the pattern is free. No one should be spinning. - if marshalflight and npattern0 then + local Tpattern = 9999 + local npunits = 1 + local pcase = 1 + if npattern > 0 then -- Last flight group send to pattern. - local patternflight=self.Qpattern[#self.Qpattern] --#AIRBOSS.FlightGroup + local patternflight = self.Qpattern[#self.Qpattern] -- #AIRBOSS.FlightGroup -- Recovery case of pattern flight. - pcase=patternflight.case + pcase = patternflight.case -- Number of airborne aircraft in this group. Count includes section members. - local npunits=self:_GetFlightUnits(patternflight, false) + local npunits = self:_GetFlightUnits( patternflight, false ) -- Get time in pattern. - Tpattern=timer.getAbsTime()-patternflight.time - self:T(self.lid..string.format("Pattern time of last group %s = %d seconds. # of units=%d.", patternflight.groupname, Tpattern, npunits)) + Tpattern = timer.getAbsTime() - patternflight.time + self:T( self.lid .. string.format( "Pattern time of last group %s = %d seconds. # of units=%d.", patternflight.groupname, Tpattern, npunits ) ) end -- Min time in pattern before next aircraft is allowed. local TpatternMin - if pcase==1 then - TpatternMin=2*60*npunits --45*npunits -- 45 seconds interval per plane! + if pcase == 1 then + TpatternMin = 2 * 60 * npunits -- 45*npunits -- 45 seconds interval per plane! else - TpatternMin=2*60*npunits --120*npunits -- 120 seconds interval per plane! + TpatternMin = 2 * 60 * npunits -- 120*npunits -- 120 seconds interval per plane! end -- Check interval to last pattern flight. - if Tpattern>TpatternMin then - self:T(self.lid..string.format("Sending marshal flight %s to pattern.", marshalflight.groupname)) - self:_ClearForLanding(marshalflight) + if Tpattern > TpatternMin then + self:T( self.lid .. string.format( "Sending marshal flight %s to pattern.", marshalflight.groupname ) ) + self:_ClearForLanding( marshalflight ) end end end - --- Clear flight for landing. AI are removed from Marshal queue and the Marshal stack is collapsed. -- If next in line is an AI flight, this is done. If human player is next, we wait for "Commence" via F10 radio menu command. -- @param #AIRBOSS self -- @param #AIRBOSS.FlightGroup flight Flight to go to pattern. -function AIRBOSS:_ClearForLanding(flight) +function AIRBOSS:_ClearForLanding( flight ) -- Check if flight is AI or human. If AI, we collapse the stack and commence. If human, we suggest to commence. if flight.ai then -- Collapse stack and send AI to pattern. - self:_RemoveFlightFromMarshalQueue(flight, false) - self:_LandAI(flight) + self:_RemoveFlightFromMarshalQueue( flight, false ) + self:_LandAI( flight ) -- Cleared for Case X recovery. - self:_MarshalCallClearedForRecovery(flight.onboard, flight.case) + self:_MarshalCallClearedForRecovery( flight.onboard, flight.case ) -- Voice over of the commencing simulated call from AI if self.xtVoiceOversAI then @@ -6252,13 +5612,13 @@ function AIRBOSS:_ClearForLanding(flight) else -- Cleared for Case X recovery. - if flight.step~=AIRBOSS.PatternStep.COMMENCING then - self:_MarshalCallClearedForRecovery(flight.onboard, flight.case) - flight.time=timer.getAbsTime() + if flight.step ~= AIRBOSS.PatternStep.COMMENCING then + self:_MarshalCallClearedForRecovery( flight.onboard, flight.case ) + flight.time = timer.getAbsTime() end -- Set step to commencing. This will trigger the zone check until the player is in the right place. - self:_SetPlayerStep(flight, AIRBOSS.PatternStep.COMMENCING, 3) + self:_SetPlayerStep( flight, AIRBOSS.PatternStep.COMMENCING, 3 ) end @@ -6269,25 +5629,25 @@ end -- @param #AIRBOSS.PlayerData playerData Player data. -- @param #string step Next step. -- @param #number delay (Optional) Set set after a delay in seconds. -function AIRBOSS:_SetPlayerStep(playerData, step, delay) +function AIRBOSS:_SetPlayerStep( playerData, step, delay ) - if delay and delay>0 then + if delay and delay > 0 then -- Delayed call. - --SCHEDULER:New(nil, self._SetPlayerStep, {self, playerData, step}, delay) - self:ScheduleOnce(delay, self._SetPlayerStep, self, playerData, step) + -- SCHEDULER:New(nil, self._SetPlayerStep, {self, playerData, step}, delay) + self:ScheduleOnce( delay, self._SetPlayerStep, self, playerData, step ) else -- Check if player still exists after possible delay. if playerData then -- Set player step. - playerData.step=step + playerData.step = step -- Erase warning. - playerData.warning=nil + playerData.warning = nil -- Next step hint. - self:_StepHint(playerData) + self:_StepHint( playerData ) end end @@ -6299,97 +5659,89 @@ end function AIRBOSS:_ScanCarrierZone() -- Carrier position. - local coord=self:GetCoordinate() + local coord = self:GetCoordinate() -- Scan radius = radius of the CCA. - local RCCZ=self.zoneCCA:GetRadius() + local RCCZ = self.zoneCCA:GetRadius() -- Debug info. - self:T(self.lid..string.format("Scanning Carrier Controlled Area. Radius=%.1f NM.", UTILS.MetersToNM(RCCZ))) + self:T( self.lid .. string.format( "Scanning Carrier Controlled Area. Radius=%.1f NM.", UTILS.MetersToNM( RCCZ ) ) ) -- Scan units in carrier zone. - local _,_,_,unitscan=coord:ScanObjects(RCCZ, true, false, false) - + local _, _, _, unitscan = coord:ScanObjects( RCCZ, true, false, false ) -- Make a table with all groups currently in the CCA zone. - local insideCCA={} - for _,_unit in pairs(unitscan) do - local unit=_unit --Wrapper.Unit#UNIT + local insideCCA = {} + for _, _unit in pairs( unitscan ) do + local unit = _unit -- Wrapper.Unit#UNIT -- Necessary conditions to be met: - local airborne=unit:IsAir() --and unit:InAir() - local inzone=unit:IsInZone(self.zoneCCA) - local friendly=self:GetCoalition()==unit:GetCoalition() - local carrierac=self:_IsCarrierAircraft(unit) + local airborne = unit:IsAir() -- and unit:InAir() + local inzone = unit:IsInZone( self.zoneCCA ) + local friendly = self:GetCoalition() == unit:GetCoalition() + local carrierac = self:_IsCarrierAircraft( unit ) -- Check if this an aircraft and that it is airborne and closing in. if airborne and inzone and friendly and carrierac then - local group=unit:GetGroup() - local groupname=group:GetName() + local group = unit:GetGroup() + local groupname = group:GetName() - if insideCCA[groupname]==nil then - insideCCA[groupname]=group + if insideCCA[groupname] == nil then + insideCCA[groupname] = group end end end -- Find new flights that are inside CCA. - for groupname,_group in pairs(insideCCA) do - local group=_group --Wrapper.Group#GROUP + for groupname, _group in pairs( insideCCA ) do + local group = _group -- Wrapper.Group#GROUP -- Get flight group if possible. - local knownflight=self:_GetFlightFromGroupInQueue(group, self.flights) - - -- Unknown new AI flight. Create a new flight group. - if not knownflight and not self:_IsHuman(group) then - knownflight=self:_CreateFlightGroup(group) - end + local knownflight = self:_GetFlightFromGroupInQueue( group, self.flights ) -- Get aircraft type name. - local actype=group:GetTypeName() + local actype = group:GetTypeName() -- Create a new flight group if knownflight then -- Check if flight is AI and if we want to handle it at all. - if knownflight.ai and knownflight.flag==-100 and self.handleai then + if knownflight.ai and knownflight.flag == -100 and self.handleai then - local putintomarshal=false + local putintomarshal = false -- Get flight group. - local flight=_DATABASE:GetOpsGroup(groupname) + local flight = _DATABASE:GetFlightGroup( groupname ) - if flight and flight:IsInbound() and flight.destbase:GetName()==self.carrier:GetName() then - if flight.isHelo then + if flight and flight:IsInbound() and flight.destbase:GetName() == self.carrier:GetName() then + if flight.ishelo then else - putintomarshal=true + putintomarshal = true end - flight.airboss=self + flight.airboss = self end - - -- Send AI flight to marshal stack. if putintomarshal then -- Get the next free stack for current recovery case. - local stack=self:_GetFreeStack(knownflight.ai) + local stack = self:_GetFreeStack( knownflight.ai ) -- Repawn. - local respawn=self.respawnAI + local respawn = self.respawnAI if stack then -- Send AI to marshal stack. We respawn the group to clean possible departure and destination airbases. - self:_MarshalAI(knownflight, stack, respawn) + self:_MarshalAI( knownflight, stack, respawn ) else -- Send AI to orbit outside 10 NM zone and wait until the next Marshal stack is available. - if not self:_InQueue(self.Qwaiting, knownflight.group) then - self:_WaitAI(knownflight, respawn) -- Group is respawned to clear any attached airfields. + if not self:_InQueue( self.Qwaiting, knownflight.group ) then + self:_WaitAI( knownflight, respawn ) -- Group is respawned to clear any attached airfields. end end @@ -6397,33 +5749,35 @@ function AIRBOSS:_ScanCarrierZone() -- Break the loop to not have all flights at once! Spams the message screen. break - end -- Closed in or tanker/AWACS + end -- Closed in or tanker/AWACS end else - - + -- Unknown new AI flight. Create a new flight group. + if not self:_IsHuman( group ) then + self:_CreateFlightGroup( group ) + end end end -- Find flights that are not in CCA. - local remove={} - for _,_flight in pairs(self.flights) do - local flight=_flight --#AIRBOSS.FlightGroup - if insideCCA[flight.groupname]==nil then + local remove = {} + for _, _flight in pairs( self.flights ) do + local flight = _flight -- #AIRBOSS.FlightGroup + if insideCCA[flight.groupname] == nil then -- Do not remove flights in marshal pattern. At least for case 2 & 3. If zone is set small, they might be outside in the holding pattern. - if flight.ai and not (self:_InQueue(self.Qmarshal, flight.group) or self:_InQueue(self.Qpattern, flight.group)) then - table.insert(remove, flight) + if flight.ai and not (self:_InQueue( self.Qmarshal, flight.group ) or self:_InQueue( self.Qpattern, flight.group )) then + table.insert( remove, flight ) end end end -- Remove flight groups outside CCA. - for _,flight in pairs(remove) do - self:_RemoveFlightFromQueue(self.flights, flight) + for _, flight in pairs( remove ) do + self:_RemoveFlightFromQueue( self.flights, flight ) end end @@ -6431,82 +5785,81 @@ end --- Tell player to wait outside the 10 NM zone until a Marshal stack is available. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data. -function AIRBOSS:_WaitPlayer(playerData) +function AIRBOSS:_WaitPlayer( playerData ) -- Check if flight is known to the airboss already. if playerData then -- Number of waiting flights - local nwaiting=#self.Qwaiting + local nwaiting = #self.Qwaiting -- Radio message: Stack is full. - self:_MarshalCallStackFull(playerData.onboard, nwaiting) + self:_MarshalCallStackFull( playerData.onboard, nwaiting ) -- Add player flight to waiting queue. - table.insert(self.Qwaiting, playerData) + table.insert( self.Qwaiting, playerData ) -- Set time stamp. - playerData.time=timer.getAbsTime() + playerData.time = timer.getAbsTime() -- Set step to waiting. - playerData.step=AIRBOSS.PatternStep.WAITING - playerData.warning=nil + playerData.step = AIRBOSS.PatternStep.WAITING + playerData.warning = nil -- Set all flights in section to waiting. - for _,_flight in pairs(playerData.section) do - local flight=_flight --#AIRBOSS.PlayerData - flight.step=AIRBOSS.PatternStep.WAITING - flight.time=timer.getAbsTime() - flight.warning=nil + for _, _flight in pairs( playerData.section ) do + local flight = _flight -- #AIRBOSS.PlayerData + flight.step = AIRBOSS.PatternStep.WAITING + flight.time = timer.getAbsTime() + flight.warning = nil end end end - --- Orbit at a specified position at a specified altitude with a specified speed. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data. -- @param #number stack The Marshal stack the player gets. -function AIRBOSS:_MarshalPlayer(playerData, stack) +function AIRBOSS:_MarshalPlayer( playerData, stack ) -- Check if flight is known to the airboss already. if playerData then -- Add group to marshal stack. - self:_AddMarshalGroup(playerData, stack) + self:_AddMarshalGroup( playerData, stack ) -- Set step to holding. - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.HOLDING) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.HOLDING ) -- Holding switch to nil until player arrives in the holding zone. - playerData.holding=nil + playerData.holding = nil -- Set same stack for all flights in section. - for _,_flight in pairs(playerData.section) do - local flight=_flight --#AIRBOSS.PlayerData + for _, _flight in pairs( playerData.section ) do + local flight = _flight -- #AIRBOSS.PlayerData -- XXX: Inform player? Should be done by lead via radio? -- Set step. - self:_SetPlayerStep(flight, AIRBOSS.PatternStep.HOLDING) + self:_SetPlayerStep( flight, AIRBOSS.PatternStep.HOLDING ) -- Holding to nil, until arrived. - flight.holding=nil + flight.holding = nil -- Set case to that of lead. - flight.case=playerData.case + flight.case = playerData.case -- Set stack flag. - flight.flag=stack + flight.flag = stack - -- Trigger Marshal event. - self:Marshal(flight) + -- Trigger Marshal event. + self:Marshal( flight ) end else - self:E(self.lid.."ERROR: Could not add player to Marshal stack! playerData=nil") + self:E( self.lid .. "ERROR: Could not add player to Marshal stack! playerData=nil" ) end end @@ -6516,61 +5869,61 @@ end -- @param #AIRBOSS self -- @param #AIRBOSS.FlightGroup flight Flight group. -- @param #boolean respawn If true respawn the group. Otherwise reset the mission task with new waypoints. -function AIRBOSS:_WaitAI(flight, respawn) +function AIRBOSS:_WaitAI( flight, respawn ) -- Set flag to something other than -100 and <0 - flight.flag=-99 + flight.flag = -99 -- Add AI flight to waiting queue. - table.insert(self.Qwaiting, flight) + table.insert( self.Qwaiting, flight ) -- Flight group name. - local group=flight.group - local groupname=flight.groupname + local group = flight.group + local groupname = flight.groupname -- Aircraft speed 274 knots TAS ~= 250 KIAS when orbiting the pattern. (Orbit expects m/s.) - local speedOrbitMps=UTILS.KnotsToMps(274) + local speedOrbitMps = UTILS.KnotsToMps( 274 ) -- Orbit speed in km/h for waypoints. - local speedOrbitKmh=UTILS.KnotsToKmph(274) + local speedOrbitKmh = UTILS.KnotsToKmph( 274 ) -- Aircraft speed 400 knots when transiting to holding zone. (Waypoint expects km/h.) - local speedTransit=UTILS.KnotsToKmph(370) + local speedTransit = UTILS.KnotsToKmph( 370 ) -- Carrier coordinate - local cv=self:GetCoordinate() + local cv = self:GetCoordinate() -- Coordinate of flight group - local fc=group:GetCoordinate() + local fc = group:GetCoordinate() -- Carrier heading - local hdg=self:GetHeading(false) + local hdg = self:GetHeading( false ) -- Heading from carrier to flight group - local hdgto=cv:HeadingTo(fc) + local hdgto = cv:HeadingTo( fc ) -- Holding alitude between angels 6 and 10 (random). - local angels=math.random(6,10) - local altitude=UTILS.FeetToMeters(angels*1000) + local angels = math.random( 6, 10 ) + local altitude = UTILS.FeetToMeters( angels * 1000 ) -- Point outsize 10 NM zone of the carrier. - local p0=cv:Translate(UTILS.NMToMeters(11), hdgto):Translate(UTILS.NMToMeters(5), hdg):SetAltitude(altitude) + local p0 = cv:Translate( UTILS.NMToMeters( 11 ), hdgto ):Translate( UTILS.NMToMeters( 5 ), hdg ):SetAltitude( altitude ) -- Waypoints array to be filled depending on case etc. - local wp={} + local wp = {} -- Current position. Always good for as the first waypoint. - wp[1]=group:GetCoordinate():WaypointAirTurningPoint(nil, speedTransit, {}, "Current Position") + wp[1] = group:GetCoordinate():WaypointAirTurningPoint( nil, speedTransit, {}, "Current Position" ) -- Set orbit task. - local taskorbit=group:TaskOrbit(p0, altitude, speedOrbitMps) + local taskorbit = group:TaskOrbit( p0, altitude, speedOrbitMps ) -- Orbit at waypoint. - wp[#wp+1]=p0:WaypointAirTurningPoint(nil, speedOrbitKmh, {taskorbit}, string.format("Waiting Orbit at Angels %d", angels)) + wp[#wp + 1] = p0:WaypointAirTurningPoint( nil, speedOrbitKmh, { taskorbit }, string.format( "Waiting Orbit at Angels %d", angels ) ) -- Debug markers. if self.Debug then - p0:MarkToAll(string.format("Waiting Orbit of flight %s at Angels %s", groupname, angels)) + p0:MarkToAll( string.format( "Waiting Orbit of flight %s at Angels %s", groupname, angels ) ) end if respawn then @@ -6579,21 +5932,21 @@ function AIRBOSS:_WaitAI(flight, respawn) -- Note: This resets the weapons and the fuel state. But not the units fortunately. -- Get group template. - local Template=group:GetTemplate() + local Template = group:GetTemplate() -- Set route points. - Template.route.points=wp + Template.route.points = wp -- Respawn the group. - group=group:Respawn(Template, true) + group = group:Respawn( Template, true ) end -- Reinit waypoints. - group:WayPointInitialize(wp) + group:WayPointInitialize( wp ) -- Route group. - group:Route(wp, 1) + group:Route( wp, 1 ) end @@ -6603,18 +5956,18 @@ end -- @param #AIRBOSS.FlightGroup flight Flight group. -- @param #number nstack Stack number of group. Can also be the current stack if AI position needs to be updated wrt to changed carrier position. -- @param #boolean respawn If true, respawn the flight otherwise update mission task with new waypoints. -function AIRBOSS:_MarshalAI(flight, nstack, respawn) - self:F2({flight=flight, nstack=nstack, respawn=respawn}) +function AIRBOSS:_MarshalAI( flight, nstack, respawn ) + self:F2( { flight = flight, nstack = nstack, respawn = respawn } ) -- Nil check. - if flight==nil or flight.group==nil then - self:E(self.lid.."ERROR: flight or flight.group is nil.") + if flight == nil or flight.group == nil then + self:E( self.lid .. "ERROR: flight or flight.group is nil." ) return end -- Nil check. - if flight.group:GetCoordinate()==nil then - self:E(self.lid.."ERROR: cannot get coordinate of flight group.") + if flight.group:GetCoordinate() == nil then + self:E( self.lid .. "ERROR: cannot get coordinate of flight group." ) return end @@ -6626,51 +5979,51 @@ function AIRBOSS:_MarshalAI(flight, nstack, respawn) self:_MarshallInboundCall(leader, flight.onboard) end -- Add group to marshal stack queue. - self:_AddMarshalGroup(flight, nstack) + self:_AddMarshalGroup( flight, nstack ) end -- Explode unit for testing. Worked! - --local u1=flight.group:GetUnit(1) --Wrapper.Unit#UNIT - --u1:Explode(500, 10) + -- local u1=flight.group:GetUnit(1) --Wrapper.Unit#UNIT + -- u1:Explode(500, 10) -- Recovery case. - local case=flight.case + local case = flight.case -- Get old/current stack. - local ostack=flight.flag + local ostack = flight.flag -- Flight group name. - local group=flight.group - local groupname=flight.groupname + local group = flight.group + local groupname = flight.groupname -- Set new stack. - flight.flag=nstack + flight.flag = nstack -- Current carrier position. - local Carrier=self:GetCoordinate() + local Carrier = self:GetCoordinate() -- Carrier heading. - local hdg=self:GetHeading() + local hdg = self:GetHeading() -- Aircraft speed 274 knots TAS ~= 250 KIAS when orbiting the pattern. (Orbit expects m/s.) - local speedOrbitMps=UTILS.KnotsToMps(274) + local speedOrbitMps = UTILS.KnotsToMps( 274 ) -- Orbit speed in km/h for waypoints. - local speedOrbitKmh=UTILS.KnotsToKmph(274) + local speedOrbitKmh = UTILS.KnotsToKmph( 274 ) -- Aircraft speed 400 knots when transiting to holding zone. (Waypoint expects km/h.) - local speedTransit=UTILS.KnotsToKmph(370) + local speedTransit = UTILS.KnotsToKmph( 370 ) local altitude - local p0 --Core.Point#COORDINATE - local p1 --Core.Point#COORDINATE - local p2 --Core.Point#COORDINATE + local p0 -- Core.Point#COORDINATE + local p1 -- Core.Point#COORDINATE + local p2 -- Core.Point#COORDINATE -- Get altitude and positions. - altitude, p1, p2=self:_GetMarshalAltitude(nstack, case) + altitude, p1, p2 = self:_GetMarshalAltitude( nstack, case ) -- Waypoints array to be filled depending on case etc. - local wp={} + local wp = {} -- If flight has not arrived in the holding zone, we guide it there. if not flight.holding then @@ -6680,36 +6033,36 @@ function AIRBOSS:_MarshalAI(flight, nstack, respawn) ---------------------- -- Debug info. - self:T(self.lid..string.format("Guiding AI flight %s to marshal stack %d-->%d.", groupname, ostack, nstack)) + self:T( self.lid .. string.format( "Guiding AI flight %s to marshal stack %d-->%d.", groupname, ostack, nstack ) ) -- Current position. Always good for as the first waypoint. - wp[1]=group:GetCoordinate():WaypointAirTurningPoint(nil, speedTransit, {}, "Current Position") + wp[1] = group:GetCoordinate():WaypointAirTurningPoint( nil, speedTransit, {}, "Current Position" ) -- Task function when arriving at the holding zone. This will set flight.holding=true. - local TaskArrivedHolding=flight.group:TaskFunction("AIRBOSS._ReachedHoldingZone", self, flight) + local TaskArrivedHolding = flight.group:TaskFunction( "AIRBOSS._ReachedHoldingZone", self, flight ) -- Select case. - if case==1 then + if case == 1 then -- Initial point 7 NM and a bit port of carrier. - local pE=Carrier:Translate(UTILS.NMToMeters(7), hdg-30):SetAltitude(altitude) + local pE = Carrier:Translate( UTILS.NMToMeters( 7 ), hdg - 30 ):SetAltitude( altitude ) -- Entry point 5 NM port and slightly astern the boat. - p0=Carrier:Translate(UTILS.NMToMeters(5), hdg-135):SetAltitude(altitude) + p0 = Carrier:Translate( UTILS.NMToMeters( 5 ), hdg - 135 ):SetAltitude( altitude ) -- Waypoint ahead of carrier's holding zone. - wp[#wp+1]=pE:WaypointAirTurningPoint(nil, speedTransit, {TaskArrivedHolding}, "Entering Case I Marshal Pattern") + wp[#wp + 1] = pE:WaypointAirTurningPoint( nil, speedTransit, { TaskArrivedHolding }, "Entering Case I Marshal Pattern" ) else -- Get correct radial depending on recovery case including offset. - local radial=self:GetRadial(case, false, true) + local radial = self:GetRadial( case, false, true ) -- Point in the middle of the race track and a 5 NM more port perpendicular. - p0=p2:Translate(UTILS.NMToMeters(5), radial+90):Translate(UTILS.NMToMeters(5), radial, true) + p0 = p2:Translate( UTILS.NMToMeters( 5 ), radial + 90 ):Translate( UTILS.NMToMeters( 5 ), radial, true ) -- Entering Case II/III marshal pattern waypoint. - wp[#wp+1]=p0:WaypointAirTurningPoint(nil, speedTransit, {TaskArrivedHolding}, "Entering Case II/III Marshal Pattern") + wp[#wp + 1] = p0:WaypointAirTurningPoint( nil, speedTransit, { TaskArrivedHolding }, "Entering Case II/III Marshal Pattern" ) end @@ -6720,27 +6073,27 @@ function AIRBOSS:_MarshalAI(flight, nstack, respawn) ------------------------ -- Debug info. - self:T(self.lid..string.format("Updating AI flight %s at marshal stack %d-->%d.", groupname, ostack, nstack)) + self:T( self.lid .. string.format( "Updating AI flight %s at marshal stack %d-->%d.", groupname, ostack, nstack ) ) -- Current position. Speed expected in km/h. - wp[1]=group:GetCoordinate():WaypointAirTurningPoint(nil, speedOrbitKmh, {}, "Current Position") + wp[1] = group:GetCoordinate():WaypointAirTurningPoint( nil, speedOrbitKmh, {}, "Current Position" ) -- Create new waypoint 0.2 Nm ahead of current positon. - p0=group:GetCoordinate():Translate(UTILS.NMToMeters(0.2), group:GetHeading(), true) + p0 = group:GetCoordinate():Translate( UTILS.NMToMeters( 0.2 ), group:GetHeading(), true ) end -- Set orbit task. - local taskorbit=group:TaskOrbit(p1, altitude, speedOrbitMps, p2) + local taskorbit = group:TaskOrbit( p1, altitude, speedOrbitMps, p2 ) -- Orbit at waypoint. - wp[#wp+1]=p0:WaypointAirTurningPoint(nil, speedOrbitKmh, {taskorbit}, string.format("Marshal Orbit Stack %d", nstack)) + wp[#wp + 1] = p0:WaypointAirTurningPoint( nil, speedOrbitKmh, { taskorbit }, string.format( "Marshal Orbit Stack %d", nstack ) ) -- Debug markers. if self.Debug then - p0:MarkToAll("WP P0 "..groupname) - p1:MarkToAll("RT P1 "..groupname) - p2:MarkToAll("RT P2 "..groupname) + p0:MarkToAll( "WP P0 " .. groupname ) + p1:MarkToAll( "RT P1 " .. groupname ) + p2:MarkToAll( "RT P2 " .. groupname ) end if respawn then @@ -6749,40 +6102,40 @@ function AIRBOSS:_MarshalAI(flight, nstack, respawn) -- Note: This resets the weapons and the fuel state. But not the units fortunately. -- Get group template. - local Template=group:GetTemplate() + local Template = group:GetTemplate() -- Set route points. - Template.route.points=wp + Template.route.points = wp -- Respawn the group. - flight.group=group:Respawn(Template, true) + flight.group = group:Respawn( Template, true ) end -- Reinit waypoints. - flight.group:WayPointInitialize(wp) + flight.group:WayPointInitialize( wp ) -- Route group. - flight.group:Route(wp, 1) + flight.group:Route( wp, 1 ) -- Trigger Marshal event. - self:Marshal(flight) + self:Marshal( flight ) end --- Tell AI to refuel. Either at the recovery tanker or at the nearest divert airfield. -- @param #AIRBOSS self -- @param #AIRBOSS.FlightGroup flight Flight group. -function AIRBOSS:_RefuelAI(flight) +function AIRBOSS:_RefuelAI( flight ) -- Waypoints array. - local wp={} + local wp = {} -- Current speed. - local CurrentSpeed=flight.group:GetVelocityKMH() + local CurrentSpeed = flight.group:GetVelocityKMH() -- Current positon. - wp[#wp+1]=flight.group:GetCoordinate():WaypointAirTurningPoint(nil, CurrentSpeed, {}, "Current position") + wp[#wp + 1] = flight.group:GetCoordinate():WaypointAirTurningPoint( nil, CurrentSpeed, {}, "Current position" ) -- Check if aircraft can be refueled. -- TODO: This should also depend on the tanker type AC. @@ -6800,25 +6153,25 @@ function AIRBOSS:_RefuelAI(flight) end -- Message. - local text="" + local text = "" -- Refuel or divert? if self.tanker and refuelac then -- Current Tanker position. - local tankerpos=self.tanker.tanker:GetCoordinate() + local tankerpos = self.tanker.tanker:GetCoordinate() -- Task refueling. - local TaskRefuel=flight.group:TaskRefueling() + local TaskRefuel = flight.group:TaskRefueling() -- Task to go back to Marshal. - local TaskMarshal=flight.group:TaskFunction("AIRBOSS._TaskFunctionMarshalAI", self, flight) + local TaskMarshal = flight.group:TaskFunction( "AIRBOSS._TaskFunctionMarshalAI", self, flight ) -- Waypoint with tasks. - wp[#wp+1]=tankerpos:WaypointAirTurningPoint(nil, CurrentSpeed, {TaskRefuel, TaskMarshal}, "Refueling") + wp[#wp + 1] = tankerpos:WaypointAirTurningPoint( nil, CurrentSpeed, { TaskRefuel, TaskMarshal }, "Refueling" ) -- Marshal Message. - self:_MarshalCallGasAtTanker(flight.onboard) + self:_MarshalCallGasAtTanker( flight.onboard ) else @@ -6826,109 +6179,109 @@ function AIRBOSS:_RefuelAI(flight) -- Guide AI to divert field -- ------------------------------ - -- Closest Airfield of the coaliton. - local divertfield=self:GetCoordinate():GetClosestAirbase(Airbase.Category.AIRDROME, self:GetCoalition()) + -- Closest Airfield of the coalition. + local divertfield = self:GetCoordinate():GetClosestAirbase( Airbase.Category.AIRDROME, self:GetCoalition() ) -- Handle case where there is no divert field of the own coalition and try neutral instead. - if divertfield==nil then - divertfield=self:GetCoordinate():GetClosestAirbase(Airbase.Category.AIRDROME, 0) + if divertfield == nil then + divertfield = self:GetCoordinate():GetClosestAirbase( Airbase.Category.AIRDROME, 0 ) end if divertfield then -- Coordinate. - local divertcoord=divertfield:GetCoordinate() + local divertcoord = divertfield:GetCoordinate() -- Landing waypoint. - wp[#wp+1]=divertcoord:WaypointAirLanding(UTILS.KnotsToKmph(300), divertfield, {}, "Divert Field") + wp[#wp + 1] = divertcoord:WaypointAirLanding( UTILS.KnotsToKmph( 300 ), divertfield, {}, "Divert Field" ) -- Marshal Message. - self:_MarshalCallGasAtDivert(flight.onboard, divertfield:GetName()) + self:_MarshalCallGasAtDivert( flight.onboard, divertfield:GetName() ) -- Respawn! -- Get group template. - local Template=flight.group:GetTemplate() + local Template = flight.group:GetTemplate() -- Set route points. - Template.route.points=wp + Template.route.points = wp -- Respawn the group. - flight.group=flight.group:Respawn(Template, true) + flight.group = flight.group:Respawn( Template, true ) else -- Set flight to refueling so this is not called again. - self:E(self.lid..string.format("WARNING: No recovery tanker or divert field available for group %s.", flight.groupname)) - flight.refueling=true + self:E( self.lid .. string.format( "WARNING: No recovery tanker or divert field available for group %s.", flight.groupname ) ) + flight.refueling = true return end end -- Reinit waypoints. - flight.group:WayPointInitialize(wp) + flight.group:WayPointInitialize( wp ) -- Route group. - flight.group:Route(wp, 1) + flight.group:Route( wp, 1 ) -- Set refueling switch. - flight.refueling=true + flight.refueling = true end --- Tell AI to land on the carrier. -- @param #AIRBOSS self -- @param #AIRBOSS.FlightGroup flight Flight group. -function AIRBOSS:_LandAI(flight) +function AIRBOSS:_LandAI( flight ) - -- Debug info. - self:T(self.lid..string.format("Landing AI flight %s.", flight.groupname)) + -- Debug info. + self:T( self.lid .. string.format( "Landing AI flight %s.", flight.groupname ) ) -- NOTE: Looks like the AI needs to approach at the "correct" speed. If they are too fast, they fly an unnecessary circle to bleed of speed first. -- Unfortunately, the correct speed depends on the aircraft type! -- Aircraft speed when flying the pattern. - local Speed=UTILS.KnotsToKmph(200) + local Speed = UTILS.KnotsToKmph( 200 ) - if flight.actype==AIRBOSS.AircraftCarrier.HORNET or flight.actype==AIRBOSS.AircraftCarrier.FA18C then - Speed=UTILS.KnotsToKmph(200) - elseif flight.actype==AIRBOSS.AircraftCarrier.E2D then - Speed=UTILS.KnotsToKmph(150) - elseif flight.actype==AIRBOSS.AircraftCarrier.F14A_AI or flight.actype==AIRBOSS.AircraftCarrier.F14A or flight.actype==AIRBOSS.AircraftCarrier.F14B then - Speed=UTILS.KnotsToKmph(175) - elseif flight.actype==AIRBOSS.AircraftCarrier.S3B or flight.actype==AIRBOSS.AircraftCarrier.S3BTANKER then - Speed=UTILS.KnotsToKmph(140) + if flight.actype == AIRBOSS.AircraftCarrier.HORNET or flight.actype == AIRBOSS.AircraftCarrier.FA18C then + Speed = UTILS.KnotsToKmph( 200 ) + elseif flight.actype == AIRBOSS.AircraftCarrier.E2D then + Speed = UTILS.KnotsToKmph( 150 ) + elseif flight.actype == AIRBOSS.AircraftCarrier.F14A_AI or flight.actype == AIRBOSS.AircraftCarrier.F14A or flight.actype == AIRBOSS.AircraftCarrier.F14B then + Speed = UTILS.KnotsToKmph( 175 ) + elseif flight.actype == AIRBOSS.AircraftCarrier.S3B or flight.actype == AIRBOSS.AircraftCarrier.S3BTANKER then + Speed = UTILS.KnotsToKmph( 140 ) end -- Carrier position. - local Carrier=self:GetCoordinate() + local Carrier = self:GetCoordinate() -- Carrier heading. - local hdg=self:GetHeading() + local hdg = self:GetHeading() -- Waypoints array. - local wp={} + local wp = {} - local CurrentSpeed=flight.group:GetVelocityKMH() + local CurrentSpeed = flight.group:GetVelocityKMH() -- Current positon. - wp[#wp+1]=flight.group:GetCoordinate():WaypointAirTurningPoint(nil, CurrentSpeed, {}, "Current position") + wp[#wp + 1] = flight.group:GetCoordinate():WaypointAirTurningPoint( nil, CurrentSpeed, {}, "Current position" ) -- Altitude 800 ft. Looks like this works best. - local alt=UTILS.FeetToMeters(800) + local alt = UTILS.FeetToMeters( 800 ) -- Landing waypoint 5 NM behind carrier at 2000 ft = 610 meters ASL. - wp[#wp+1]=Carrier:Translate(UTILS.NMToMeters(4), hdg-160):SetAltitude(alt):WaypointAirLanding(Speed, self.airbase, nil, "Landing") - --wp[#wp+1]=Carrier:Translate(UTILS.NMToMeters(4), hdg-160):SetAltitude(alt):WaypointAirLandingReFu(Speed, self.airbase, nil, "Landing") + wp[#wp + 1] = Carrier:Translate( UTILS.NMToMeters( 4 ), hdg - 160 ):SetAltitude( alt ):WaypointAirLanding( Speed, self.airbase, nil, "Landing" ) + -- wp[#wp+1]=Carrier:Translate(UTILS.NMToMeters(4), hdg-160):SetAltitude(alt):WaypointAirLandingReFu(Speed, self.airbase, nil, "Landing") - --wp[#wp+1]=self:GetCoordinate():Translate(UTILS.NMToMeters(3), hdg-160):SetAltitude(alt):WaypointAirTurningPoint(nil,Speed, {}, "Before Initial") ---WaypointAirLanding(Speed, self.airbase, nil, "Landing") - --wp[#wp+1]=self:GetCoordinate():WaypointAirLanding(Speed, self.airbase, nil, "Landing") + -- wp[#wp+1]=self:GetCoordinate():Translate(UTILS.NMToMeters(3), hdg-160):SetAltitude(alt):WaypointAirTurningPoint(nil,Speed, {}, "Before Initial") ---WaypointAirLanding(Speed, self.airbase, nil, "Landing") + -- wp[#wp+1]=self:GetCoordinate():WaypointAirLanding(Speed, self.airbase, nil, "Landing") -- Reinit waypoints. - flight.group:WayPointInitialize(wp) + flight.group:WayPointInitialize( wp ) -- Route group. - flight.group:Route(wp, 0) + flight.group:Route( wp, 0 ) end --- Get marshal altitude and two positions of a counter-clockwise race track pattern. @@ -6938,83 +6291,83 @@ end -- @return #number Holding altitude in meters. -- @return Core.Point#COORDINATE First race track coordinate. -- @return Core.Point#COORDINATE Second race track coordinate. -function AIRBOSS:_GetMarshalAltitude(stack, case) +function AIRBOSS:_GetMarshalAltitude( stack, case ) -- Stack <= 0. - if stack<=0 then - return 0,nil,nil + if stack <= 0 then + return 0, nil, nil end -- Recovery case. - case=case or self.case + case = case or self.case -- Carrier position. - local Carrier=self:GetCoordinate() + local Carrier = self:GetCoordinate() -- Altitude of first stack. Depends on recovery case. local angels0 local Dist - local p1=nil --Core.Point#COORDINATE - local p2=nil --Core.Point#COORDINATE + local p1 = nil -- Core.Point#COORDINATE + local p2 = nil -- Core.Point#COORDINATE -- Stack number. - local nstack=stack-1 + local nstack = stack - 1 - if case==1 then + if case == 1 then -- CASE I: Holding at 2000 ft on a circular pattern port of the carrier. Interval +1000 ft for next stack. - angels0=2 + angels0 = 2 -- Get true heading of carrier. - local hdg=self.carrier:GetHeading() + local hdg = self.carrier:GetHeading() -- For CCW pattern: First point astern, second ahead of the carrier. -- First point over carrier. - p1=Carrier + p1 = Carrier -- Second point 1.5 NM ahead. - p2=Carrier:Translate(UTILS.NMToMeters(1.5), hdg) + p2 = Carrier:Translate( UTILS.NMToMeters( 1.5 ), hdg ) -- Tarawa,LHA,LHD Delta patterns. - if self.carriertype==AIRBOSS.CarrierType.TARAWA or self.carriertype==AIRBOSS.CarrierType.AMERICA or self.carriertype==AIRBOSS.CarrierType.JCARLOS or self.carriertype==AIRBOSS.CarrierType.CANBERRA then + if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then -- Pattern is directly overhead the carrier. - p1=Carrier:Translate(UTILS.NMToMeters(1.0), hdg+90) - p2=p1:Translate(2.5, hdg) + p1 = Carrier:Translate( UTILS.NMToMeters( 1.0 ), hdg + 90 ) + p2 = p1:Translate( 2.5, hdg ) end else -- CASE II/III: Holding at 6000 ft on a racetrack pattern astern the carrier. - angels0=6 + angels0 = 6 -- Distance: d=n*angels0+15 NM, so first stack is at 15+6=21 NM - Dist=UTILS.NMToMeters(nstack+angels0+15) + Dist = UTILS.NMToMeters( nstack + angels0 + 15 ) -- Get correct radial depending on recovery case including offset. - local radial=self:GetRadial(case, false, true) + local radial = self:GetRadial( case, false, true ) -- For CCW pattern: p1 further astern than p2. -- Length of the race track pattern. - local l=UTILS.NMToMeters(10) + local l = UTILS.NMToMeters( 10 ) -- First point of race track pattern. - p1=Carrier:Translate(Dist+l, radial) + p1 = Carrier:Translate( Dist + l, radial ) -- Second point. - p2=Carrier:Translate(Dist, radial) + p2 = Carrier:Translate( Dist, radial ) end -- Pattern altitude. - local altitude=UTILS.FeetToMeters((nstack+angels0)*1000) + local altitude = UTILS.FeetToMeters( (nstack + angels0) * 1000 ) -- Set altitude of coordinate. - p1:SetAltitude(altitude, true) - p2:SetAltitude(altitude, true) + p1:SetAltitude( altitude, true ) + p2:SetAltitude( altitude, true ) return altitude, p1, p2 end @@ -7023,95 +6376,95 @@ end -- @param #AIRBOSS self -- @param #AIRBOSS.FlightGroup flightgroup Flight data. -- @return #number Charlie (abs) time in seconds. Or nil, if stack<0 or no recovery window will open. -function AIRBOSS:_GetCharlieTime(flightgroup) +function AIRBOSS:_GetCharlieTime( flightgroup ) -- Get current stack of player. - local stack=flightgroup.flag + local stack = flightgroup.flag -- Flight is not in marshal stack. - if stack<=0 then + if stack <= 0 then return nil end -- Current abs time. - local Tnow=timer.getAbsTime() + local Tnow = timer.getAbsTime() -- Time the player has to spend in marshal stack until all lower stacks are emptied. - local Tcharlie=0 + local Tcharlie = 0 - local Trecovery=0 + local Trecovery = 0 if self.recoverywindow then -- Time in seconds until the next recovery starts or 0 if window is already open. - Trecovery=math.max(self.recoverywindow.START-Tnow, 0) + Trecovery = math.max( self.recoverywindow.START - Tnow, 0 ) else -- Set ~7 min if no future recovery window is defined. Otherwise radio call function crashes. - Trecovery=7*60 + Trecovery = 7 * 60 end -- Loop over flights currently in the marshal queue. - for _,_flight in pairs(self.Qmarshal) do - local flight=_flight --#AIRBOSS.FlightGroup + for _, _flight in pairs( self.Qmarshal ) do + local flight = _flight -- #AIRBOSS.FlightGroup -- Stack of marshal flight. - local mstack=flight.flag + local mstack = flight.flag -- Time to get to the marshal stack if not holding already. - local Tarrive=0 + local Tarrive = 0 -- Minimum holding time per stack. - local Tholding=3*60 + local Tholding = 3 * 60 - if stack>0 and mstack>0 and mstack<=stack then + if stack > 0 and mstack > 0 and mstack <= stack then -- Check if flight is already holding or just on its way. - if flight.holding==nil then + if flight.holding == nil then -- Flight is on its way to the marshal stack. -- Coordinate of the holding zone. - local holdingzone=self:_GetZoneHolding(flight.case, 1):GetCoordinate() + local holdingzone = self:_GetZoneHolding( flight.case, 1 ):GetCoordinate() -- Distance to holding zone. - local d0=holdingzone:Get2DDistance(flight.group:GetCoordinate()) + local d0 = holdingzone:Get2DDistance( flight.group:GetCoordinate() ) -- Current velocity. - local v0=flight.group:GetVelocityMPS() + local v0 = flight.group:GetVelocityMPS() -- Time to get to the carrier. - Tarrive=d0/v0 + Tarrive = d0 / v0 - self:T3(self.lid..string.format("Tarrive=%.1f seconds, Clock %s", Tarrive, UTILS.SecondsToClock(Tnow+Tarrive))) + self:T3( self.lid .. string.format( "Tarrive=%.1f seconds, Clock %s", Tarrive, UTILS.SecondsToClock( Tnow + Tarrive ) ) ) else -- Flight is already holding. -- Next in line. - if mstack==1 then + if mstack == 1 then -- Current holding time. flight.time stamp should be when entering holding or last time the stack collapsed. - local tholding=timer.getAbsTime()-flight.time + local tholding = timer.getAbsTime() - flight.time -- Deduce current holding time. Ensure that is >=0. - Tholding=math.max(3*60-tholding, 0) + Tholding = math.max( 3 * 60 - tholding, 0 ) end end -- This is the approx time needed to get to the pattern. If we are already there, it is the time until the recovery window opens or 0 if it is already open. - local Tmin=math.max(Tarrive, Trecovery) + local Tmin = math.max( Tarrive, Trecovery ) -- Charlie time + 2 min holding in stack 1. - Tcharlie=math.max(Tmin, Tcharlie)+Tholding + Tcharlie = math.max( Tmin, Tcharlie ) + Tholding end end -- Convert to abs time. - Tcharlie=Tcharlie+Tnow + Tcharlie = Tcharlie + Tnow -- Debug info. - local text=string.format("Charlie time for flight %s (%s) %s", flightgroup.onboard, flightgroup.groupname, UTILS.SecondsToClock(Tcharlie)) - MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug) - self:T(self.lid..text) + local text = string.format( "Charlie time for flight %s (%s) %s", flightgroup.onboard, flightgroup.groupname, UTILS.SecondsToClock( Tcharlie ) ) + MESSAGE:New( text, 10, "DEBUG" ):ToAllIf( self.Debug ) + self:T( self.lid .. text ) return Tcharlie end @@ -7120,51 +6473,51 @@ end -- @param #AIRBOSS self -- @param #AIRBOSS.FlightGroup flight Flight group. -- @param #number stack Marshal stack. This (re-)sets the flag value. -function AIRBOSS:_AddMarshalGroup(flight, stack) +function AIRBOSS:_AddMarshalGroup( flight, stack ) -- Set flag value. This corresponds to the stack number which starts at 1. - flight.flag=stack + flight.flag = stack -- Set recovery case. - flight.case=self.case + flight.case = self.case -- Add to marshal queue. - table.insert(self.Qmarshal, flight) + table.insert( self.Qmarshal, flight ) -- Pressure. - local P=UTILS.hPa2inHg(self:GetCoordinate():GetPressure()) + local P = UTILS.hPa2inHg( self:GetCoordinate():GetPressure() ) -- Stack altitude. - --local alt=UTILS.MetersToFeet(self:_GetMarshalAltitude(stack, flight.case)) - local alt=self:_GetMarshalAltitude(stack, flight.case) + -- local alt=UTILS.MetersToFeet(self:_GetMarshalAltitude(stack, flight.case)) + local alt = self:_GetMarshalAltitude( stack, flight.case ) -- Current BRC. - local brc=self:GetBRC() + local brc = self:GetBRC() -- If the carrier is supposed to turn into the wind, we take the wind coordinate. if self.recoverywindow and self.recoverywindow.WIND then - brc=self:GetBRCintoWind() + brc = self:GetBRCintoWind() end -- Get charlie time estimate. - flight.Tcharlie=self:_GetCharlieTime(flight) + flight.Tcharlie = self:_GetCharlieTime( flight ) -- Convert to clock string. - local Ccharlie=UTILS.SecondsToClock(flight.Tcharlie) + local Ccharlie = UTILS.SecondsToClock( flight.Tcharlie ) -- Combined marshal call. - self:_MarshalCallArrived(flight.onboard, flight.case, brc, alt, Ccharlie, P) + self:_MarshalCallArrived( flight.onboard, flight.case, brc, alt, Ccharlie, P ) -- Hint about TACAN bearing. - if self.TACANon and (not flight.ai) and flight.difficulty==AIRBOSS.Difficulty.EASY then + if self.TACANon and (not flight.ai) and flight.difficulty == AIRBOSS.Difficulty.EASY then -- Get inverse magnetic radial potential offset. - local radial=self:GetRadial(flight.case, true, true, true) - if flight.case==1 then + local radial = self:GetRadial( flight.case, true, true, true ) + if flight.case == 1 then -- For case 1 we want the BRC but above routine return FB. - radial=self:GetBRC() + radial = self:GetBRC() end - local text=string.format("Select TACAN %03d°, channel %d%s (%s)", radial, self.TACANchannel,self.TACANmode, self.TACANmorse) - self:MessageToPlayer(flight, text, nil, "") + local text = string.format( "Select TACAN %03d°, channel %d%s (%s)", radial, self.TACANchannel, self.TACANmode, self.TACANmorse ) + self:MessageToPlayer( flight, text, nil, "" ) end end @@ -7173,87 +6526,87 @@ end -- @param #AIRBOSS self -- @param #AIRBOSS.FlightGroup flight Flight that left the marshal stack. -- @param #boolean nopattern If true, flight does not go to pattern. -function AIRBOSS:_CollapseMarshalStack(flight, nopattern) - self:F2({flight=flight, nopattern=nopattern}) +function AIRBOSS:_CollapseMarshalStack( flight, nopattern ) + self:F2( { flight = flight, nopattern = nopattern } ) -- Recovery case of flight. - local case=flight.case + local case = flight.case -- Stack of flight. - local stack=flight.flag + local stack = flight.flag -- Check that stack > 0. - if stack<=0 then - self:E(self.lid..string.format("ERROR: Flight %s is has stack value %d<0. Cannot collapse stack!", flight.groupname, stack)) + if stack <= 0 then + self:E( self.lid .. string.format( "ERROR: Flight %s is has stack value %d<0. Cannot collapse stack!", flight.groupname, stack ) ) return end -- Memorize time when stack collapsed. Should better depend on case but for now we assume there are no two different stacks Case I or II/III. - self.Tcollapse=timer.getTime() + self.Tcollapse = timer.getTime() -- Decrease flag values of all flight groups in marshal stack. - for _,_flight in pairs(self.Qmarshal) do - local mflight=_flight --#AIRBOSS.PlayerData + for _, _flight in pairs( self.Qmarshal ) do + local mflight = _flight -- #AIRBOSS.PlayerData -- Only collapse stack of which the flight left. CASE II/III stacks are not collapsed. - if (case==1 and mflight.case==1) then --or (case>1 and mflight.case>1) then + if (case == 1 and mflight.case == 1) then -- or (case>1 and mflight.case>1) then -- Get current flag/stack value. - local mstack=mflight.flag + local mstack = mflight.flag -- Only collapse stacks above the new pattern flight. - if mstack>stack then + if mstack > stack then -- TODO: Is this now right as we allow more flights per stack? -- Question is, does the stack collapse if the lower stack is completely empty or do aircraft descent if just one flight leaves. -- For now, assuming that the stack must be completely empty before the next higher AC are allowed to descent. - local newstack=self:_GetFreeStack(mflight.ai, mflight.case, true) + local newstack = self:_GetFreeStack( mflight.ai, mflight.case, true ) -- Free stack has to be below. - if newstack and newstack %d.", mflight.groupname, mflight.case, mstack, newstack)) + self:T( self.lid .. string.format( "Collapse Marshal: Flight %s (case %d) is changing marshal stack %d --> %d.", mflight.groupname, mflight.case, mstack, newstack ) ) if mflight.ai then -- Command AI to decrease stack. Flag is set in the routine. - self:_MarshalAI(mflight, newstack) + self:_MarshalAI( mflight, newstack ) else -- Decrease stack/flag. Human player needs to take care himself. - mflight.flag=newstack + mflight.flag = newstack -- Angels of new stack. - local angels=self:_GetAngels(self:_GetMarshalAltitude(newstack, case)) + local angels = self:_GetAngels( self:_GetMarshalAltitude( newstack, case ) ) -- Inform players. - if mflight.difficulty~=AIRBOSS.Difficulty.HARD then + if mflight.difficulty ~= AIRBOSS.Difficulty.HARD then -- Send message to all non-pros that they can descent. - local text=string.format("descent to stack at Angels %d.", angels) - self:MessageToPlayer(mflight, text, "MARSHAL") + local text = string.format( "descent to stack at Angels %d.", angels ) + self:MessageToPlayer( mflight, text, "MARSHAL" ) end -- Set time stamp. - mflight.time=timer.getAbsTime() + mflight.time = timer.getAbsTime() -- Loop over section members. - for _,_sec in pairs(mflight.section) do - local sec=_sec --#AIRBOSS.PlayerData + for _, _sec in pairs( mflight.section ) do + local sec = _sec -- #AIRBOSS.PlayerData -- Also decrease flag for section members of flight. - sec.flag=newstack + sec.flag = newstack -- Set new time stamp. - sec.time=timer.getAbsTime() + sec.time = timer.getAbsTime() -- Inform section member. - if sec.difficulty~=AIRBOSS.Difficulty.HARD then - local text=string.format("descent to stack at Angels %d.", angels) - self:MessageToPlayer(sec, text, "MARSHAL") + if sec.difficulty ~= AIRBOSS.Difficulty.HARD then + local text = string.format( "descent to stack at Angels %d.", angels ) + self:MessageToPlayer( sec, text, "MARSHAL" ) end end @@ -7265,28 +6618,27 @@ function AIRBOSS:_CollapseMarshalStack(flight, nopattern) end end - if nopattern then -- Debug message. - self:T(self.lid..string.format("Flight %s is leaving stack but not going to pattern.", flight.groupname)) + self:T( self.lid .. string.format( "Flight %s is leaving stack but not going to pattern.", flight.groupname ) ) else -- Debug message. - local Tmarshal=UTILS.SecondsToClock(timer.getAbsTime()-flight.time) - self:T(self.lid..string.format("Flight %s is leaving marshal after %s and going pattern.", flight.groupname, Tmarshal)) + local Tmarshal = UTILS.SecondsToClock( timer.getAbsTime() - flight.time ) + self:T( self.lid .. string.format( "Flight %s is leaving marshal after %s and going pattern.", flight.groupname, Tmarshal ) ) -- Add flight to pattern queue. - self:_AddFlightToPatternQueue(flight) + self:_AddFlightToPatternQueue( flight ) end -- Set flag to -1 (-1 is rather arbitrary but it should not be positive or -100 or -42). - flight.flag=-1 + flight.flag = -1 -- New time stamp for time in pattern. - flight.time=timer.getAbsTime() + flight.time = timer.getAbsTime() end @@ -7296,87 +6648,87 @@ end -- @param #number case Recovery case. Default current (self) case in progress. -- @param #boolean empty Return lowest stack that is completely empty. -- @return #number Lowest free stack available for the given case or nil if all Case I stacks are taken. -function AIRBOSS:_GetFreeStack(ai, case, empty) +function AIRBOSS:_GetFreeStack( ai, case, empty ) -- Recovery case. - case=case or self.case + case = case or self.case - if case==1 then - return self:_GetFreeStack_Old(ai, case, empty) + if case == 1 then + return self:_GetFreeStack_Old( ai, case, empty ) end -- Max number of stacks available. - local nmaxstacks=100 - if case==1 then - nmaxstacks=self.Nmaxmarshal + local nmaxstacks = 100 + if case == 1 then + nmaxstacks = self.Nmaxmarshal end -- Assume up to two (human) flights per stack. All are free. - local stack={} - for i=1,nmaxstacks do - stack[i]=self.NmaxStack -- Number of human flights per stack. + local stack = {} + for i = 1, nmaxstacks do + stack[i] = self.NmaxStack -- Number of human flights per stack. end - local nmax=1 + local nmax = 1 -- Loop over all flights in marshal stack. - for _,_flight in pairs(self.Qmarshal) do - local flight=_flight --#AIRBOSS.FlightGroup + for _, _flight in pairs( self.Qmarshal ) do + local flight = _flight -- #AIRBOSS.FlightGroup -- Check that the case is right. - if flight.case==case then + if flight.case == case then -- Get stack of flight. - local n=flight.flag + local n = flight.flag - if n>nmax then - nmax=n + if n > nmax then + nmax = n end - if n>0 then - if flight.ai or flight.case>1 then - stack[n]=0 -- AI get one stack on their own. Also CASE II/III get one stack each. + if n > 0 then + if flight.ai or flight.case > 1 then + stack[n] = 0 -- AI get one stack on their own. Also CASE II/III get one stack each. else - stack[n]=stack[n]-1 + stack[n] = stack[n] - 1 end else - self:E(string.format("ERROR: Flight %s in marshal stack has stack value <= 0. Stack value is %d.", flight.groupname, n)) + self:E( string.format( "ERROR: Flight %s in marshal stack has stack value <= 0. Stack value is %d.", flight.groupname, n ) ) end end end - local nfree=nil - if stack[nmax]==0 then + local nfree = nil + if stack[nmax] == 0 then -- Max occupied stack is completely full! - if case==1 then - if nmax>=nmaxstacks then + if case == 1 then + if nmax >= nmaxstacks then -- Already all Case I stacks are occupied ==> wait outside 10 NM zone. - nfree=nil + nfree = nil else -- Return next free stack. - nfree=nmax+1 + nfree = nmax + 1 end else -- Case II/III return next stack - nfree=nmax+1 + nfree = nmax + 1 end - elseif stack[nmax]==self.NmaxStack then + elseif stack[nmax] == self.NmaxStack then -- Max occupied stack is completely empty! This should happen only when there is no other flight in the marshal queue. - self:E(self.lid..string.format("ERROR: Max occupied stack is empty. Should not happen! Nmax=%d, stack[nmax]=%d", nmax, stack[nmax])) - nfree=nmax + self:E( self.lid .. string.format( "ERROR: Max occupied stack is empty. Should not happen! Nmax=%d, stack[nmax]=%d", nmax, stack[nmax] ) ) + nfree = nmax else -- Max occupied stack is partly full. - if ai or empty or case>1 then - nfree=nmax+1 + if ai or empty or case > 1 then + nfree = nmax + 1 else - nfree=nmax + nfree = nmax end end - self:T(self.lid..string.format("Returning free stack %s", tostring(nfree))) + self:I( self.lid .. string.format( "Returning free stack %s", tostring( nfree ) ) ) return nfree end @@ -7386,60 +6738,60 @@ end -- @param #number case Recovery case. Default current (self) case in progress. -- @param #boolean empty Return lowest stack that is completely empty. -- @return #number Lowest free stack available for the given case or nil if all Case I stacks are taken. -function AIRBOSS:_GetFreeStack_Old(ai, case, empty) +function AIRBOSS:_GetFreeStack_Old( ai, case, empty ) -- Recovery case. - case=case or self.case + case = case or self.case -- Max number of stacks available. - local nmaxstacks=100 - if case==1 then - nmaxstacks=self.Nmaxmarshal + local nmaxstacks = 100 + if case == 1 then + nmaxstacks = self.Nmaxmarshal end -- Assume up to two (human) flights per stack. All are free. - local stack={} - for i=1,nmaxstacks do - stack[i]=self.NmaxStack -- Number of human flights per stack. + local stack = {} + for i = 1, nmaxstacks do + stack[i] = self.NmaxStack -- Number of human flights per stack. end -- Loop over all flights in marshal stack. - for _,_flight in pairs(self.Qmarshal) do - local flight=_flight --#AIRBOSS.FlightGroup + for _, _flight in pairs( self.Qmarshal ) do + local flight = _flight -- #AIRBOSS.FlightGroup -- Check that the case is right. - if flight.case==case then + if flight.case == case then -- Get stack of flight. - local n=flight.flag + local n = flight.flag - if n>0 then - if flight.ai or flight.case>1 then - stack[n]=0 -- AI get one stack on their own. Also CASE II/III get one stack each. + if n > 0 then + if flight.ai or flight.case > 1 then + stack[n] = 0 -- AI get one stack on their own. Also CASE II/III get one stack each. else - stack[n]=stack[n]-1 + stack[n] = stack[n] - 1 end else - self:E(string.format("ERROR: Flight %s in marshal stack has stack value <= 0. Stack value is %d.", flight.groupname, n)) + self:E( string.format( "ERROR: Flight %s in marshal stack has stack value <= 0. Stack value is %d.", flight.groupname, n ) ) end end end -- Loop over stacks and check which one has a place left. - local nfree=nil - for i=1,nmaxstacks do - self:T2(self.lid..string.format("FF Stack[%d]=%d", i, stack[i])) - if ai or empty or case>1 then + local nfree = nil + for i = 1, nmaxstacks do + self:T2( self.lid .. string.format( "FF Stack[%d]=%d", i, stack[i] ) ) + if ai or empty or case > 1 then -- AI need the whole stack. - if stack[i]==self.NmaxStack then - nfree=i + if stack[i] == self.NmaxStack then + nfree = i return i end else -- Human players only need one free spot. - if stack[i]>0 then - nfree=i + if stack[i] > 0 then + nfree = i return i end end @@ -7455,32 +6807,32 @@ end -- @return #number Number of units in flight including section members. -- @return #number Number of units in flight excluding section members. -- @return #number Number of section members. -function AIRBOSS:_GetFlightUnits(flight, onground) +function AIRBOSS:_GetFlightUnits( flight, onground ) -- Default is only airborne. - local inair=true - if onground==true then - inair=false + local inair = true + if onground == true then + inair = false end --- Count units of a group which are alive and in the air. - local function countunits(_group, inair) - local group=_group --Wrapper.Group#GROUP - local units=group:GetUnits() - local n=0 + local function countunits( _group, inair ) + local group = _group -- Wrapper.Group#GROUP + local units = group:GetUnits() + local n = 0 if units then - for _,_unit in pairs(units) do - local unit=_unit --Wrapper.Unit#UNIT - if unit and unit:IsAlive() then + for _, _unit in pairs( units ) do + local unit = _unit -- Wrapper.Unit#UNIT + if unit and unit:IsAlive() then if inair then -- Only count units in air. if unit:InAir() then - self:T2(self.lid..string.format("Unit %s is in AIR", unit:GetName())) - n=n+1 + self:T2( self.lid .. string.format( "Unit %s is in AIR", unit:GetName() ) ) + n = n + 1 end else -- Count units in air or on the ground. - n=n+1 + n = n + 1 end end end @@ -7488,19 +6840,18 @@ function AIRBOSS:_GetFlightUnits(flight, onground) return n end - -- Count units of the group itself (alive units in air). - local nunits=countunits(flight.group, inair) + local nunits = countunits( flight.group, inair ) -- Count section members. - local nsection=0 - for _,sec in pairs(flight.section) do - local secflight=sec --#AIRBOSS.PlayerData + local nsection = 0 + for _, sec in pairs( flight.section ) do + local secflight = sec -- #AIRBOSS.PlayerData -- Count alive units in air. - nsection=nsection+countunits(secflight.group, inair) + nsection = nsection + countunits( secflight.group, inair ) end - return nunits+nsection, nunits, nsection + return nunits + nsection, nunits, nsection end --- Get number of groups and units in queue, which are alive and airborne. In units we count the section members as well. @@ -7509,14 +6860,14 @@ end -- @param #number case (Optional) Only count flights, which are in a specific recovery case. Note that you can use case=23 for flights that are either in Case II or III. By default all groups/units regardless of case are counted. -- @return #number Total number of flight groups in queue. -- @return #number Total number of aircraft in queue since each flight group can contain multiple aircraft. -function AIRBOSS:_GetQueueInfo(queue, case) +function AIRBOSS:_GetQueueInfo( queue, case ) - local ngroup=0 - local Nunits=0 + local ngroup = 0 + local Nunits = 0 -- Loop over flight groups. - for _,_flight in pairs(queue) do - local flight=_flight --#AIRBOSS.FlightGroup + for _, _flight in pairs( queue ) do + local flight = _flight -- #AIRBOSS.FlightGroup -- Check if a specific case was requested. if case then @@ -7525,17 +6876,17 @@ function AIRBOSS:_GetQueueInfo(queue, case) -- Only count specific case with special 23 = CASE II and III combined. ------------------------------------------------------------------------ - if (flight.case==case) or (case==23 and (flight.case==2 or flight.case==3)) then + if (flight.case == case) or (case == 23 and (flight.case == 2 or flight.case == 3)) then -- Number of total units, units in flight and section members ALIVE and AIRBORNE. - local ntot,nunits,nsection=self:_GetFlightUnits(flight) + local ntot, nunits, nsection = self:_GetFlightUnits( flight ) -- Add up total unit number. - Nunits=Nunits+ntot + Nunits = Nunits + ntot -- Increase group count. - if ntot>0 then - ngroup=ngroup+1 + if ntot > 0 then + ngroup = ngroup + 1 end end @@ -7547,14 +6898,14 @@ function AIRBOSS:_GetQueueInfo(queue, case) --------------------------------------------------------------------------- -- Number of total units, units in flight and section members ALIVE and AIRBORNE. - local ntot,nunits,nsection=self:_GetFlightUnits(flight) + local ntot, nunits, nsection = self:_GetFlightUnits( flight ) -- Add up total unit number. - Nunits=Nunits+ntot + Nunits = Nunits + ntot -- Increase group count. - if ntot>0 then - ngroup=ngroup+1 + if ntot > 0 then + ngroup = ngroup + 1 end end @@ -7568,47 +6919,45 @@ end -- @param #AIRBOSS self -- @param #table queue Queue to print. -- @param #string name Queue name. -function AIRBOSS:_PrintQueue(queue, name) +function AIRBOSS:_PrintQueue( queue, name ) - --local nqueue=#queue - local Nqueue, nqueue=self:_GetQueueInfo(queue) + -- local nqueue=#queue + local Nqueue, nqueue = self:_GetQueueInfo( queue ) - local text=string.format("%s Queue N=%d (#%d), n=%d:", name, Nqueue, #queue, nqueue) - if #queue==0 then - text=text.." empty." + local text = string.format( "%s Queue N=%d (#%d), n=%d:", name, Nqueue, #queue, nqueue ) + if #queue == 0 then + text = text .. " empty." else - for i,_flight in pairs(queue) do - local flight=_flight --#AIRBOSS.FlightGroup + for i, _flight in pairs( queue ) do + local flight = _flight -- #AIRBOSS.FlightGroup - local clock=UTILS.SecondsToClock(timer.getAbsTime()-flight.time) - local case=flight.case - local stack=flight.flag - local fuel=flight.group:GetFuelMin()*100 - local ai=tostring(flight.ai) - local lead=flight.seclead - local Nsec=#flight.section - local actype=self:_GetACNickname(flight.actype) - local onboard=flight.onboard - local holding=tostring(flight.holding) + local clock = UTILS.SecondsToClock( timer.getAbsTime() - flight.time ) + local case = flight.case + local stack = flight.flag + local fuel = flight.group:GetFuelMin() * 100 + local ai = tostring( flight.ai ) + local lead = flight.seclead + local Nsec = #flight.section + local actype = self:_GetACNickname( flight.actype ) + local onboard = flight.onboard + local holding = tostring( flight.holding ) -- Airborne units. - local _, nunits, nsec=self:_GetFlightUnits(flight, false) + local _, nunits, nsec = self:_GetFlightUnits( flight, false ) -- Text. - text=text..string.format("\n[%d] %s*%d (%s): lead=%s (%d/%d), onboard=%s, flag=%d, case=%d, time=%s, fuel=%d, ai=%s, holding=%s", - i, flight.groupname, nunits, actype, lead, nsec, Nsec, onboard, stack, case, clock, fuel, ai, holding) - if stack>0 then - local alt=UTILS.MetersToFeet(self:_GetMarshalAltitude(stack, case)) - text=text..string.format(" stackalt=%d ft", alt) + text = text .. string.format( "\n[%d] %s*%d (%s): lead=%s (%d/%d), onboard=%s, flag=%d, case=%d, time=%s, fuel=%d, ai=%s, holding=%s", i, flight.groupname, nunits, actype, lead, nsec, Nsec, onboard, stack, case, clock, fuel, ai, holding ) + if stack > 0 then + local alt = UTILS.MetersToFeet( self:_GetMarshalAltitude( stack, case ) ) + text = text .. string.format( " stackalt=%d ft", alt ) end - for j,_element in pairs(flight.elements) do - local element=_element --#AIRBOSS.FlightElement - text=text..string.format("\n (%d) %s (%s): ai=%s, ballcall=%s, recovered=%s", - j, element.onboard, element.unitname, tostring(element.ai), tostring(element.ballcall), tostring(element.recovered)) + for j, _element in pairs( flight.elements ) do + local element = _element -- #AIRBOSS.FlightElement + text = text .. string.format( "\n (%d) %s (%s): ai=%s, ballcall=%s, recovered=%s", j, element.onboard, element.unitname, tostring( element.ai ), tostring( element.ballcall ), tostring( element.recovered ) ) end end end - self:T(self.lid..text) + self:T( self.lid .. text ) end ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -7619,159 +6968,158 @@ end -- @param #AIRBOSS self -- @param Wrapper.Group#GROUP group Aircraft group. -- @return #AIRBOSS.FlightGroup Flight group. -function AIRBOSS:_CreateFlightGroup(group) +function AIRBOSS:_CreateFlightGroup( group ) -- Debug info. - self:T(self.lid..string.format("Creating new flight for group %s of aircraft type %s.", group:GetName(), group:GetTypeName())) + self:T( self.lid .. string.format( "Creating new flight for group %s of aircraft type %s.", group:GetName(), group:GetTypeName() ) ) -- New flight. - local flight={} --#AIRBOSS.FlightGroup + local flight = {} -- #AIRBOSS.FlightGroup -- Check if not already in flights - if not self:_InQueue(self.flights, group) then + if not self:_InQueue( self.flights, group ) then -- Flight group name - local groupname=group:GetName() - local human, playername=self:_IsHuman(group) + local groupname = group:GetName() + local human, playername = self:_IsHuman( group ) -- Queue table item. - flight.group=group - flight.groupname=group:GetName() - flight.nunits=#group:GetUnits() - flight.time=timer.getAbsTime() - flight.dist0=group:GetCoordinate():Get2DDistance(self:GetCoordinate()) - flight.flag=-100 - flight.ai=not human - flight.actype=group:GetTypeName() - flight.onboardnumbers=self:_GetOnboardNumbers(group) - flight.seclead=flight.group:GetUnit(1):GetName() -- Sec lead is first unitname of group but player name for players. - flight.section={} - flight.ballcall=false - flight.refueling=false - flight.holding=nil - flight.name=flight.group:GetUnit(1):GetName() --Will be overwritten in _Newplayer with player name if human player in the group. + flight.group = group + flight.groupname = group:GetName() + flight.nunits = #group:GetUnits() + flight.time = timer.getAbsTime() + flight.dist0 = group:GetCoordinate():Get2DDistance( self:GetCoordinate() ) + flight.flag = -100 + flight.ai = not human + flight.actype = group:GetTypeName() + flight.onboardnumbers = self:_GetOnboardNumbers( group ) + flight.seclead = flight.group:GetUnit( 1 ):GetName() -- Sec lead is first unitname of group but player name for players. + flight.section = {} + flight.ballcall = false + flight.refueling = false + flight.holding = nil + flight.name = flight.group:GetUnit( 1 ):GetName() -- Will be overwritten in _Newplayer with player name if human player in the group. -- Note, this should be re-set elsewhere! - flight.case=self.case + flight.case = self.case -- Flight elements. - local text=string.format("Flight elements of group %s:", flight.groupname) - flight.elements={} - local units=group:GetUnits() - for i,_unit in pairs(units) do - local unit=_unit --Wrapper.Unit#UNIT - local element={} --#AIRBOSS.FlightElement - element.unit=unit - element.unitname=unit:GetName() - element.onboard=flight.onboardnumbers[element.unitname] - element.ballcall=false - element.ai=not self:_IsHumanUnit(unit) - element.recovered=nil - text=text..string.format("\n[%d] %s onboard #%s, AI=%s", i, element.unitname, tostring(element.onboard), tostring(element.ai)) - table.insert(flight.elements, element) + local text = string.format( "Flight elements of group %s:", flight.groupname ) + flight.elements = {} + local units = group:GetUnits() + for i, _unit in pairs( units ) do + local unit = _unit -- Wrapper.Unit#UNIT + local element = {} -- #AIRBOSS.FlightElement + element.unit = unit + element.unitname = unit:GetName() + element.onboard = flight.onboardnumbers[element.unitname] + element.ballcall = false + element.ai = not self:_IsHumanUnit( unit ) + element.recovered = nil + text = text .. string.format( "\n[%d] %s onboard #%s, AI=%s", i, element.unitname, tostring( element.onboard ), tostring( element.ai ) ) + table.insert( flight.elements, element ) end - self:T(self.lid..text) + self:T( self.lid .. text ) -- Onboard if flight.ai then - local onboard=flight.onboardnumbers[flight.seclead] - flight.onboard=onboard + local onboard = flight.onboardnumbers[flight.seclead] + flight.onboard = onboard else - flight.onboard=self:_GetOnboardNumberPlayer(group) + flight.onboard = self:_GetOnboardNumberPlayer( group ) end -- Add to known flights. - table.insert(self.flights, flight) + table.insert( self.flights, flight ) else - self:E(self.lid..string.format("ERROR: Flight group %s already exists in self.flights!", group:GetName())) + self:E( self.lid .. string.format( "ERROR: Flight group %s already exists in self.flights!", group:GetName() ) ) return nil end return flight end - --- Initialize player data after birth event of player unit. -- @param #AIRBOSS self -- @param #string unitname Name of the player unit. -- @return #AIRBOSS.PlayerData Player data. -function AIRBOSS:_NewPlayer(unitname) +function AIRBOSS:_NewPlayer( unitname ) -- Get player unit and name. - local playerunit, playername=self:_GetPlayerUnitAndName(unitname) + local playerunit, playername = self:_GetPlayerUnitAndName( unitname ) if playerunit and playername then -- Get group. - local group=playerunit:GetGroup() + local group = playerunit:GetGroup() -- Player data. - local playerData --#AIRBOSS.PlayerData + local playerData -- #AIRBOSS.PlayerData -- Create a flight group for the player. - playerData=self:_CreateFlightGroup(group) + playerData = self:_CreateFlightGroup( group ) -- Nil check. if playerData then -- Player unit, client and callsign. - playerData.unit = playerunit + playerData.unit = playerunit playerData.unitname = unitname - playerData.name = playername + playerData.name = playername playerData.callsign = playerData.unit:GetCallsign() - playerData.client = CLIENT:FindByName(unitname, nil, true) - playerData.seclead = playername + playerData.client = CLIENT:FindByName( unitname, nil, true ) + playerData.seclead = playername -- Number of passes done by player in this slot. - playerData.passes=0 --playerData.passes or 0 + playerData.passes = 0 -- playerData.passes or 0 -- Messages for player. - playerData.messages={} + playerData.messages = {} -- Debriefing tables. - playerData.lastdebrief=playerData.lastdebrief or {} + playerData.lastdebrief = playerData.lastdebrief or {} -- Attitude monitor. - playerData.attitudemonitor=false + playerData.attitudemonitor = false -- Trap sheet save. - if playerData.trapon==nil then - playerData.trapon=self.trapsheet + if playerData.trapon == nil then + playerData.trapon = self.trapsheet end -- Set difficulty level. - playerData.difficulty=playerData.difficulty or self.defaultskill + playerData.difficulty = playerData.difficulty or self.defaultskill -- Subtitles of player. - if playerData.subtitles==nil then - playerData.subtitles=true + if playerData.subtitles == nil then + playerData.subtitles = true end -- Show step hints. - if playerData.showhints==nil then - if playerData.difficulty==AIRBOSS.Difficulty.HARD then - playerData.showhints=false + if playerData.showhints == nil then + if playerData.difficulty == AIRBOSS.Difficulty.HARD then + playerData.showhints = false else - playerData.showhints=true + playerData.showhints = true end end -- Points rewarded. - playerData.points={} + playerData.points = {} -- Init stuff for this round. - playerData=self:_InitPlayer(playerData) + playerData = self:_InitPlayer( playerData ) -- Init player data. - self.players[playername]=playerData + self.players[playername] = playerData -- Init player grades table if necessary. - self.playerscores[playername]=self.playerscores[playername] or {} + self.playerscores[playername] = self.playerscores[playername] or {} -- Welcome player message. if self.welcome then - self:MessageToPlayer(playerData, string.format("Welcome, %s %s!", playerData.difficulty, playerData.name), string.format("AIRBOSS %s", self.alias), "", 5) + self:MessageToPlayer( playerData, string.format( "Welcome, %s %s!", playerData.difficulty, playerData.name ), string.format( "AIRBOSS %s", self.alias ), "", 5 ) end end @@ -7788,72 +7136,71 @@ end -- @param #AIRBOSS.PlayerData playerData Player data. -- @param #string step (Optional) New player step. Default UNDEFINED. -- @return #AIRBOSS.PlayerData Initialized player data. -function AIRBOSS:_InitPlayer(playerData, step) - self:T(self.lid..string.format("Initializing player data for %s callsign %s.", playerData.name, playerData.callsign)) +function AIRBOSS:_InitPlayer( playerData, step ) + self:T( self.lid .. string.format( "Initializing player data for %s callsign %s.", playerData.name, playerData.callsign ) ) - playerData.step=step or AIRBOSS.PatternStep.UNDEFINED - playerData.groove={} - playerData.debrief={} - playerData.trapsheet={} - playerData.warning=nil - playerData.holding=nil - playerData.refueling=false - playerData.valid=false - playerData.lig=false - playerData.wop=false - playerData.waveoff=false - playerData.wofd=false - playerData.owo=false - playerData.boltered=false - playerData.hover=false - playerData.stable=false - playerData.landed=false - playerData.Tlso=timer.getTime() - playerData.Tgroove=nil - playerData.TIG0=nil - playerData.wire=nil - playerData.flag=-100 - playerData.debriefschedulerID=nil + playerData.step = step or AIRBOSS.PatternStep.UNDEFINED + playerData.groove = {} + playerData.debrief = {} + playerData.trapsheet = {} + playerData.warning = nil + playerData.holding = nil + playerData.refueling = false + playerData.valid = false + playerData.lig = false + playerData.wop = false + playerData.waveoff = false + playerData.wofd = false + playerData.owo = false + playerData.boltered = false + playerData.hover = false + playerData.stable = false + playerData.landed = false + playerData.Tlso = timer.getTime() + playerData.Tgroove = nil + playerData.TIG0 = nil + playerData.wire = nil + playerData.flag = -100 + playerData.debriefschedulerID = nil -- Set us up on final if group name contains "Groove". But only for the first pass. - if playerData.group:GetName():match("Groove") and playerData.passes==0 then - self:MessageToPlayer(playerData, "Group name contains \"Groove\". Happy groove testing.") - playerData.attitudemonitor=true - playerData.step=AIRBOSS.PatternStep.FINAL - self:_AddFlightToPatternQueue(playerData) - self.dTstatus=0.1 + if playerData.group:GetName():match( "Groove" ) and playerData.passes == 0 then + self:MessageToPlayer( playerData, "Group name contains \"Groove\". Happy groove testing." ) + playerData.attitudemonitor = true + playerData.step = AIRBOSS.PatternStep.FINAL + self:_AddFlightToPatternQueue( playerData ) + self.dTstatus = 0.1 end return playerData end - --- Get flight from group in a queue. -- @param #AIRBOSS self -- @param Wrapper.Group#GROUP group Group that will be removed from queue. -- @param #table queue The queue from which the group will be removed. -- @return #AIRBOSS.FlightGroup Flight group or nil. -- @return #number Queue index or nil. -function AIRBOSS:_GetFlightFromGroupInQueue(group, queue) +function AIRBOSS:_GetFlightFromGroupInQueue( group, queue ) if group then -- Group name - local name=group:GetName() + local name = group:GetName() -- Loop over all flight groups in queue - for i,_flight in pairs(queue) do - local flight=_flight --#AIRBOSS.FlightGroup + for i, _flight in pairs( queue ) do + local flight = _flight -- #AIRBOSS.FlightGroup - if flight.groupname==name then + if flight.groupname == name then return flight, i end end - self:T2(self.lid..string.format("WARNING: Flight group %s could not be found in queue.", name)) + self:T2( self.lid .. string.format( "WARNING: Flight group %s could not be found in queue.", name ) ) end - self:T2(self.lid..string.format("WARNING: Flight group could not be found in queue. Group is nil!")) + self:T2( self.lid .. string.format( "WARNING: Flight group could not be found in queue. Group is nil!" ) ) return nil, nil end @@ -7863,30 +7210,30 @@ end -- @return #AIRBOSS.FlightElement Element of the flight or nil. -- @return #number Element index or nil. -- @return #AIRBOSS.FlightGroup The Flight group or nil -function AIRBOSS:_GetFlightElement(unitname) +function AIRBOSS:_GetFlightElement( unitname ) -- Get the unit. - local unit=UNIT:FindByName(unitname) + local unit = UNIT:FindByName( unitname ) -- Check if unit exists. if unit then -- Get flight element from all flights. - local flight=self:_GetFlightFromGroupInQueue(unit:GetGroup(), self.flights) + local flight = self:_GetFlightFromGroupInQueue( unit:GetGroup(), self.flights ) -- Check if fight exists. if flight then -- Loop over all elements in flight group. - for i,_element in pairs(flight.elements) do - local element=_element --#AIRBOSS.FlightElement + for i, _element in pairs( flight.elements ) do + local element = _element -- #AIRBOSS.FlightElement - if element.unit:GetName()==unitname then + if element.unit:GetName() == unitname then return element, i, flight end end - self:T2(self.lid..string.format("WARNING: Flight element %s could not be found in flight group.", unitname, flight.groupname)) + self:T2( self.lid .. string.format( "WARNING: Flight element %s could not be found in flight group.", unitname, flight.groupname ) ) end end @@ -7897,16 +7244,16 @@ end -- @param #AIRBOSS self -- @param #string unitname Name of the unit. -- @return #boolean If true, element could be removed or nil otherwise. -function AIRBOSS:_RemoveFlightElement(unitname) +function AIRBOSS:_RemoveFlightElement( unitname ) -- Get table index. - local element,idx, flight=self:_GetFlightElement(unitname) + local element, idx, flight = self:_GetFlightElement( unitname ) if idx then - table.remove(flight.elements, idx) + table.remove( flight.elements, idx ) return true else - self:T("WARNING: Flight element could not be removed from flight group. Index=nil!") + self:T( "WARNING: Flight element could not be removed from flight group. Index=nil!" ) return nil end end @@ -7916,11 +7263,11 @@ end -- @param #table queue The queue to check. -- @param Wrapper.Group#GROUP group The group to be checked. -- @return #boolean If true, group is in the queue. False otherwise. -function AIRBOSS:_InQueue(queue, group) - local name=group:GetName() - for _,_flight in pairs(queue) do - local flight=_flight --#AIRBOSS.FlightGroup - if name==flight.groupname then +function AIRBOSS:_InQueue( queue, group ) + local name = group:GetName() + for _, _flight in pairs( queue ) do + local flight = _flight -- #AIRBOSS.FlightGroup + if name == flight.groupname then return true end end @@ -7934,29 +7281,29 @@ end function AIRBOSS:_RemoveDeadFlightGroups() -- Remove dead flights from all flights table. - for i=#self.flight,1,-1 do - local flight=self.flights[i] --#AIRBOSS.FlightGroup + for i = #self.flight, 1, -1 do + local flight = self.flights[i] -- #AIRBOSS.FlightGroup if not flight.group:IsAlive() then - self:T(string.format("Removing dead flight group %s from ALL flights table.", flight.groupname)) - table.remove(self.flights, i) + self:T( string.format( "Removing dead flight group %s from ALL flights table.", flight.groupname ) ) + table.remove( self.flights, i ) end end -- Remove dead flights from Marhal queue table. - for i=#self.Qmarshal,1,-1 do - local flight=self.Qmarshal[i] --#AIRBOSS.FlightGroup + for i = #self.Qmarshal, 1, -1 do + local flight = self.Qmarshal[i] -- #AIRBOSS.FlightGroup if not flight.group:IsAlive() then - self:T(string.format("Removing dead flight group %s from Marshal Queue table.", flight.groupname)) - table.remove(self.Qmarshal, i) + self:T( string.format( "Removing dead flight group %s from Marshal Queue table.", flight.groupname ) ) + table.remove( self.Qmarshal, i ) end end -- Remove dead flights from Pattern queue table. - for i=#self.Qpattern,1,-1 do - local flight=self.Qpattern[i] --#AIRBOSS.FlightGroup + for i = #self.Qpattern, 1, -1 do + local flight = self.Qpattern[i] -- #AIRBOSS.FlightGroup if not flight.group:IsAlive() then - self:T(string.format("Removing dead flight group %s from Pattern Queue table.", flight.groupname)) - table.remove(self.Qpattern, i) + self:T( string.format( "Removing dead flight group %s from Pattern Queue table.", flight.groupname ) ) + table.remove( self.Qpattern, i ) end end @@ -7966,14 +7313,14 @@ end -- @param #AIRBOSS self -- @param #AIRBOSS.FlightGroup flight Flight group to check. -- @return #AIRBOSS.FlightGroup Flight group of the leader or flight itself if no other leader. -function AIRBOSS:_GetLeadFlight(flight) +function AIRBOSS:_GetLeadFlight( flight ) -- Init. - local lead=flight + local lead = flight -- Only human players can be section leads of other players. - if flight.name~=flight.seclead then - lead=self.players[flight.seclead] + if flight.name ~= flight.seclead then + lead = self.players[flight.seclead] end return lead @@ -7984,31 +7331,31 @@ end -- @param #AIRBOSS self -- @param #AIRBOSS.FlightGroup flight Flight group to check. -- @return #boolean If true, all elements landed. -function AIRBOSS:_CheckSectionRecovered(flight) +function AIRBOSS:_CheckSectionRecovered( flight ) -- Nil check. - if flight==nil then + if flight == nil then return true end -- Get the lead flight first, so that we can also check all section members. - local lead=self:_GetLeadFlight(flight) + local lead = self:_GetLeadFlight( flight ) -- Check all elements of the lead flight group. - for _,_element in pairs(lead.elements) do - local element=_element --#AIRBOSS.FlightElement + for _, _element in pairs( lead.elements ) do + local element = _element -- #AIRBOSS.FlightElement if not element.recovered then return false end end -- Now check all section members, if any. - for _,_section in pairs(lead.section) do - local sectionmember=_section --#AIRBOSS.FlightGroup + for _, _section in pairs( lead.section ) do + local sectionmember = _section -- #AIRBOSS.FlightGroup -- Check all elements of the secmember flight group. - for _,_element in pairs(sectionmember.elements) do - local element=_element --#AIRBOSS.FlightElement + for _, _element in pairs( sectionmember.elements ) do + local element = _element -- #AIRBOSS.FlightElement if not element.recovered then return false end @@ -8016,17 +7363,17 @@ function AIRBOSS:_CheckSectionRecovered(flight) end -- Remove lead flight from pattern queue. It is this flight who is added to the queue. - self:_RemoveFlightFromQueue(self.Qpattern, lead) + self:_RemoveFlightFromQueue( self.Qpattern, lead ) -- Just for now, check if it is in other queues as well. - if self:_InQueue(self.Qmarshal, lead.group) then - self:E(self.lid..string.format("ERROR: lead flight group %s should not be in marshal queue", lead.groupname)) - self:_RemoveFlightFromMarshalQueue(lead, true) + if self:_InQueue( self.Qmarshal, lead.group ) then + self:E( self.lid .. string.format( "ERROR: lead flight group %s should not be in marshal queue", lead.groupname ) ) + self:_RemoveFlightFromMarshalQueue( lead, true ) end -- Just for now, check if it is in other queues as well. - if self:_InQueue(self.Qwaiting, lead.group) then - self:E(self.lid..string.format("ERROR: lead flight group %s should not be in pattern queue", lead.groupname)) - self:_RemoveFlightFromQueue(self.Qwaiting, lead) + if self:_InQueue( self.Qwaiting, lead.group ) then + self:E( self.lid .. string.format( "ERROR: lead flight group %s should not be in pattern queue", lead.groupname ) ) + self:_RemoveFlightFromQueue( self.Qwaiting, lead ) end return true @@ -8035,29 +7382,29 @@ end --- Add flight to pattern queue and set recoverd to false for all elements of the flight and its section members. -- @param #AIRBOSS self -- @param #AIRBOSS.FlightGroup Flight group of element. -function AIRBOSS:_AddFlightToPatternQueue(flight) +function AIRBOSS:_AddFlightToPatternQueue( flight ) -- Add flight to table. - table.insert(self.Qpattern, flight) + table.insert( self.Qpattern, flight ) -- Set flag to -1 (-1 is rather arbitrary but it should not be positive or -100 or -42). - flight.flag=-1 + flight.flag = -1 -- New time stamp for time in pattern. - flight.time=timer.getAbsTime() + flight.time = timer.getAbsTime() -- Init recovered switch. - flight.recovered=false - for _,elem in pairs(flight.elements) do - elem.recoverd=false + flight.recovered = false + for _, elem in pairs( flight.elements ) do + elem.recoverd = false end -- Set recovered for all section members. - for _,sec in pairs(flight.section) do + for _, sec in pairs( flight.section ) do -- Set flag and timestamp for section members - sec.flag=-1 - sec.time=timer.getAbsTime() - for _,elem in pairs(sec.elements) do - elem.recoverd=false + sec.flag = -1 + sec.time = timer.getAbsTime() + for _, elem in pairs( sec.elements ) do + elem.recoverd = false end end end @@ -8066,14 +7413,14 @@ end -- @param #AIRBOSS self -- @param Wrapper.Unit#UNIT unit The aircraft unit that was recovered. -- @return #AIRBOSS.FlightGroup Flight group of element. -function AIRBOSS:_RecoveredElement(unit) +function AIRBOSS:_RecoveredElement( unit ) -- Get element of flight. - local element, idx, flight=self:_GetFlightElement(unit:GetName()) --#AIRBOSS.FlightElement + local element, idx, flight = self:_GetFlightElement( unit:GetName() ) -- #AIRBOSS.FlightElement -- Nil check. Could be if a helo landed or something else we dont know! if element then - element.recovered=true + element.recovered = true end return flight @@ -8085,44 +7432,44 @@ end -- @param #boolean nopattern If true, flight is NOT going to landing pattern. -- @return #boolean True, flight was removed or false otherwise. -- @return #number Table index of the flight in the Marshal queue. -function AIRBOSS:_RemoveFlightFromMarshalQueue(flight, nopattern) +function AIRBOSS:_RemoveFlightFromMarshalQueue( flight, nopattern ) -- Remove flight from marshal queue if it is in. - local removed, idx=self:_RemoveFlightFromQueue(self.Qmarshal, flight) + local removed, idx = self:_RemoveFlightFromQueue( self.Qmarshal, flight ) -- Collapse marshal stack if flight was removed. if removed then -- Flight is not holding any more. - flight.holding=nil + flight.holding = nil -- Collapse marshal stack if flight was removed. - self:_CollapseMarshalStack(flight, nopattern) + self:_CollapseMarshalStack( flight, nopattern ) -- Stacks are only limited for Case I. - if flight.case==1 and #self.Qwaiting>0 then + if flight.case == 1 and #self.Qwaiting > 0 then -- Next flight in line waiting. - local nextflight=self.Qwaiting[1] --#AIRBOSS.FlightGroup + local nextflight = self.Qwaiting[1] -- #AIRBOSS.FlightGroup -- Get free stack. - local freestack=self:_GetFreeStack(nextflight.ai) + local freestack = self:_GetFreeStack( nextflight.ai ) -- Send next flight to marshal stack. if nextflight.ai then -- Send AI to Marshal Stack. - self:_MarshalAI(nextflight, freestack) + self:_MarshalAI( nextflight, freestack ) else -- Send player to Marshal stack. - self:_MarshalPlayer(nextflight, freestack) + self:_MarshalPlayer( nextflight, freestack ) end -- Remove flight from waiting queue. - self:_RemoveFlightFromQueue(self.Qwaiting, nextflight) + self:_RemoveFlightFromQueue( self.Qwaiting, nextflight ) end end @@ -8136,16 +7483,16 @@ end -- @param #AIRBOSS.FlightGroup flight Flight group that will be removed from queue. -- @return #boolean True, flight was in Queue and removed. False otherwise. -- @return #number Table index of removed queue element or nil. -function AIRBOSS:_RemoveFlightFromQueue(queue, flight) +function AIRBOSS:_RemoveFlightFromQueue( queue, flight ) -- Loop over all flights in group. - for i,_flight in pairs(queue) do - local qflight=_flight --#AIRBOSS.FlightGroup + for i, _flight in pairs( queue ) do + local qflight = _flight -- #AIRBOSS.FlightGroup -- Check for name. - if qflight.groupname==flight.groupname then - self:T(self.lid..string.format("Removing flight group %s from queue.", flight.groupname)) - table.remove(queue, i) + if qflight.groupname == flight.groupname then + self:T( self.lid .. string.format( "Removing flight group %s from queue.", flight.groupname ) ) + table.remove( queue, i ) return true, i end end @@ -8156,41 +7503,41 @@ end --- Remove a unit and its element from a flight group (e.g. when landed) and update all queues if the whole flight group is gone. -- @param #AIRBOSS self -- @param Wrapper.Unit#UNIT unit The unit to be removed. -function AIRBOSS:_RemoveUnitFromFlight(unit) +function AIRBOSS:_RemoveUnitFromFlight( unit ) -- Check if unit exists. - if unit and unit:IsInstanceOf("UNIT") then + if unit and unit:IsInstanceOf( "UNIT" ) then -- Get group. - local group=unit:GetGroup() + local group = unit:GetGroup() -- Check if group exists. if group then -- Get flight. - local flight=self:_GetFlightFromGroupInQueue(group, self.flights) + local flight = self:_GetFlightFromGroupInQueue( group, self.flights ) -- Check if flight exists. if flight then -- Remove element from flight group. - local removed=self:_RemoveFlightElement(unit:GetName()) + local removed = self:_RemoveFlightElement( unit:GetName() ) if removed then -- Get number of units (excluding section members). For AI only those that are still in air as we assume once they landed, they are out of the game. - local _,nunits=self:_GetFlightUnits(flight, not flight.ai) + local _, nunits = self:_GetFlightUnits( flight, not flight.ai ) -- Number of flight elements still left. - local nelements=#flight.elements + local nelements = #flight.elements -- Debug info. - self:T(self.lid..string.format("Removed unit %s: nunits=%d, nelements=%d", unit:GetName(), nunits, nelements)) + self:T( self.lid .. string.format( "Removed unit %s: nunits=%d, nelements=%d", unit:GetName(), nunits, nelements ) ) -- Check if no units are left. - if nunits==0 or nelements==0 then + if nunits == 0 or nelements == 0 then -- Remove flight from all queues. - self:_RemoveFlight(flight) + self:_RemoveFlight( flight ) end end @@ -8203,18 +7550,18 @@ end --- Remove a flight, which is a member of a section, from this section. -- @param #AIRBOSS self -- @param #AIRBOSS.FlightGroup flight The flight to be removed from the section -function AIRBOSS:_RemoveFlightFromSection(flight) +function AIRBOSS:_RemoveFlightFromSection( flight ) -- First check if player is not the lead. - if flight.name~=flight.seclead then + if flight.name ~= flight.seclead then -- Remove this flight group from the section of the leader. - local lead=self.players[flight.seclead] --#AIRBOSS.FlightGroup + local lead = self.players[flight.seclead] -- #AIRBOSS.FlightGroup if lead then - for i,sec in pairs(lead.section) do - local sectionmember=sec --#AIRBOSS.FlightGroup - if sectionmember.name==flight.name then - table.remove(lead.section, i) + for i, sec in pairs( lead.section ) do + local sectionmember = sec -- #AIRBOSS.FlightGroup + if sectionmember.name == flight.name then + table.remove( lead.section, i ) break end end @@ -8228,37 +7575,37 @@ end -- If removed flight is the section lead, we try to find a new leader. -- @param #AIRBOSS self -- @param #AIRBOSS.FlightGroup flight The flight to be removed. -function AIRBOSS:_UpdateFlightSection(flight) +function AIRBOSS:_UpdateFlightSection( flight ) -- Check if this player is the leader of a section. - if flight.seclead==flight.name then + if flight.seclead == flight.name then -------------------- -- Section Leader -- -------------------- -- This player is the leader ==> We need a new one. - if #flight.section>=1 then + if #flight.section >= 1 then -- New leader. - local newlead=flight.section[1] --#AIRBOSS.FlightGroup - newlead.seclead=newlead.name + local newlead = flight.section[1] -- #AIRBOSS.FlightGroup + newlead.seclead = newlead.name -- Adjust new section members. - for i=2,#flight.section do - local member=flight.section[i] --#AIRBOSS.FlightGroup + for i = 2, #flight.section do + local member = flight.section[i] -- #AIRBOSS.FlightGroup -- Add remaining members new leaders table. - table.insert(newlead.section, member) + table.insert( newlead.section, member ) -- Set new section lead of member. - member.seclead=newlead.name + member.seclead = newlead.name end end -- Flight section empty - flight.section={} + flight.section = {} else @@ -8267,7 +7614,7 @@ function AIRBOSS:_UpdateFlightSection(flight) -------------------- -- Remove flight from its leaders section. - self:_RemoveFlightFromSection(flight) + self:_RemoveFlightFromSection( flight ) end @@ -8278,28 +7625,28 @@ end -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData flight The flight to be removed. -- @param #boolean completely If true, also remove human flight from all flights table. -function AIRBOSS:_RemoveFlight(flight, completely) - self:F(self.lid.. string.format("Removing flight %s, ai=%s completely=%s.", tostring(flight.groupname), tostring(flight.ai), tostring(completely))) +function AIRBOSS:_RemoveFlight( flight, completely ) + self:F( self.lid .. string.format( "Removing flight %s, ai=%s completely=%s.", tostring( flight.groupname ), tostring( flight.ai ), tostring( completely ) ) ) -- Remove flight from all queues. - self:_RemoveFlightFromMarshalQueue(flight, true) - self:_RemoveFlightFromQueue(self.Qpattern, flight) - self:_RemoveFlightFromQueue(self.Qwaiting, flight) - self:_RemoveFlightFromQueue(self.Qspinning, flight) + self:_RemoveFlightFromMarshalQueue( flight, true ) + self:_RemoveFlightFromQueue( self.Qpattern, flight ) + self:_RemoveFlightFromQueue( self.Qwaiting, flight ) + self:_RemoveFlightFromQueue( self.Qspinning, flight ) -- Check if player or AI if flight.ai then -- Remove AI flight completely. Pure AI flights have no sections and cannot be members. - self:_RemoveFlightFromQueue(self.flights, flight) + self:_RemoveFlightFromQueue( self.flights, flight ) else -- Remove all grades until a final grade is reached. - local grades=self.playerscores[flight.name] - if grades and #grades>0 then - while #grades>0 and grades[#grades].finalscore==nil do - table.remove(grades, #grades) + local grades = self.playerscores[flight.name] + if grades and #grades > 0 then + while #grades > 0 and grades[#grades].finalscore == nil do + table.remove( grades, #grades ) end end @@ -8307,36 +7654,36 @@ function AIRBOSS:_RemoveFlight(flight, completely) if completely then -- Update flight section. Remove flight from section or find new section leader if flight was the lead. - self:_UpdateFlightSection(flight) + self:_UpdateFlightSection( flight ) -- Remove completely. - self:_RemoveFlightFromQueue(self.flights, flight) + self:_RemoveFlightFromQueue( self.flights, flight ) -- Remove player from players table. - local playerdata=self.players[flight.name] + local playerdata = self.players[flight.name] if playerdata then - self:T(self.lid..string.format("Removing player %s completely.", flight.name)) - self.players[flight.name]=nil + self:I( self.lid .. string.format( "Removing player %s completely.", flight.name ) ) + self.players[flight.name] = nil end -- Remove flight. - flight=nil + flight = nil else -- Set player step to undefined. - self:_SetPlayerStep(flight, AIRBOSS.PatternStep.UNDEFINED) + self:_SetPlayerStep( flight, AIRBOSS.PatternStep.UNDEFINED ) -- Also set this for the section members as they are in the same boat. - for _,sectionmember in pairs(flight.section) do - self:_SetPlayerStep(sectionmember, AIRBOSS.PatternStep.UNDEFINED) + for _, sectionmember in pairs( flight.section ) do + self:_SetPlayerStep( sectionmember, AIRBOSS.PatternStep.UNDEFINED ) -- Also remove section member in case they are in the spinning queue. - self:_RemoveFlightFromQueue(self.Qspinning, sectionmember) + self:_RemoveFlightFromQueue( self.Qspinning, sectionmember ) end -- What if flight is member of a section. His status is now undefined. Should he be removed from the section? -- I think yes, if he pulls the trigger. - self:_RemoveFlightFromSection(flight) + self:_RemoveFlightFromSection( flight ) end end @@ -8352,212 +7699,211 @@ end function AIRBOSS:_CheckPlayerStatus() -- Loop over all players. - for _playerName,_playerData in pairs(self.players) do - local playerData=_playerData --#AIRBOSS.PlayerData + for _playerName, _playerData in pairs( self.players ) do + local playerData = _playerData -- #AIRBOSS.PlayerData if playerData then -- Player unit. - local unit=playerData.unit + local unit = playerData.unit -- Check if unit is alive. if unit and unit:IsAlive() then -- Check if player is in carrier controlled area (zone with R=50 NM around the carrier). -- TODO: This might cause problems if the CCA is set to be very small! - if unit:IsInZone(self.zoneCCA) then + if unit:IsInZone( self.zoneCCA ) then -- Display aircraft attitude and other parameters as message text. if playerData.attitudemonitor then - self:_AttitudeMonitor(playerData) + self:_AttitudeMonitor( playerData ) end -- Check distance to other flights. - self:_CheckPlayerPatternDistance(playerData) + self:_CheckPlayerPatternDistance( playerData ) -- Foul deck check. - self:_CheckFoulDeck(playerData) + self:_CheckFoulDeck( playerData ) -- Check current step. - if playerData.step==AIRBOSS.PatternStep.UNDEFINED then + if playerData.step == AIRBOSS.PatternStep.UNDEFINED then -- Status undefined. - --local time=timer.getAbsTime() - --local clock=UTILS.SecondsToClock(time) - --self:T3(string.format("Player status undefined. Waiting for next step. Time %s", clock)) + -- local time=timer.getAbsTime() + -- local clock=UTILS.SecondsToClock(time) + -- self:T3(string.format("Player status undefined. Waiting for next step. Time %s", clock)) - elseif playerData.step==AIRBOSS.PatternStep.REFUELING then + elseif playerData.step == AIRBOSS.PatternStep.REFUELING then -- Nothing to do here at the moment. - elseif playerData.step==AIRBOSS.PatternStep.SPINNING then + elseif playerData.step == AIRBOSS.PatternStep.SPINNING then -- Player is spinning. - self:_Spinning(playerData) + self:_Spinning( playerData ) - elseif playerData.step==AIRBOSS.PatternStep.HOLDING then + elseif playerData.step == AIRBOSS.PatternStep.HOLDING then -- CASE I/II/III: In holding pattern. - self:_Holding(playerData) + self:_Holding( playerData ) - elseif playerData.step==AIRBOSS.PatternStep.WAITING then + elseif playerData.step == AIRBOSS.PatternStep.WAITING then -- CASE I: Waiting outside 10 NM zone for next free Marshal stack. - self:_Waiting(playerData) + self:_Waiting( playerData ) - elseif playerData.step==AIRBOSS.PatternStep.COMMENCING then + elseif playerData.step == AIRBOSS.PatternStep.COMMENCING then -- CASE I/II/III: New approach. - self:_Commencing(playerData, true) + self:_Commencing( playerData, true ) - elseif playerData.step==AIRBOSS.PatternStep.BOLTER then + elseif playerData.step == AIRBOSS.PatternStep.BOLTER then -- CASE I/II/III: Bolter pattern. - self:_BolterPattern(playerData) + self:_BolterPattern( playerData ) - elseif playerData.step==AIRBOSS.PatternStep.PLATFORM then + elseif playerData.step == AIRBOSS.PatternStep.PLATFORM then -- CASE II/III: Player has reached 5k "Platform". - self:_Platform(playerData) + self:_Platform( playerData ) - elseif playerData.step==AIRBOSS.PatternStep.ARCIN then + elseif playerData.step == AIRBOSS.PatternStep.ARCIN then -- Case II/III if offset. - self:_ArcInTurn(playerData) + self:_ArcInTurn( playerData ) - elseif playerData.step==AIRBOSS.PatternStep.ARCOUT then + elseif playerData.step == AIRBOSS.PatternStep.ARCOUT then -- Case II/III if offset. - self:_ArcOutTurn(playerData) + self:_ArcOutTurn( playerData ) - elseif playerData.step==AIRBOSS.PatternStep.DIRTYUP then + elseif playerData.step == AIRBOSS.PatternStep.DIRTYUP then -- CASE III: Player has descended to 1200 ft and is going level from now on. - self:_DirtyUp(playerData) + self:_DirtyUp( playerData ) - elseif playerData.step==AIRBOSS.PatternStep.BULLSEYE then + elseif playerData.step == AIRBOSS.PatternStep.BULLSEYE then -- CASE III: Player has intercepted the glide slope and should follow "Bullseye" (ICLS). - self:_Bullseye(playerData) + self:_Bullseye( playerData ) - elseif playerData.step==AIRBOSS.PatternStep.INITIAL then + elseif playerData.step == AIRBOSS.PatternStep.INITIAL then -- CASE I/II: Player is at the initial position entering the landing pattern. - self:_Initial(playerData) + self:_Initial( playerData ) - elseif playerData.step==AIRBOSS.PatternStep.BREAKENTRY then + elseif playerData.step == AIRBOSS.PatternStep.BREAKENTRY then -- CASE I/II: Break entry. - self:_BreakEntry(playerData) + self:_BreakEntry( playerData ) - elseif playerData.step==AIRBOSS.PatternStep.EARLYBREAK then + elseif playerData.step == AIRBOSS.PatternStep.EARLYBREAK then -- CASE I/II: Early break. - self:_Break(playerData, AIRBOSS.PatternStep.EARLYBREAK) + self:_Break( playerData, AIRBOSS.PatternStep.EARLYBREAK ) - elseif playerData.step==AIRBOSS.PatternStep.LATEBREAK then + elseif playerData.step == AIRBOSS.PatternStep.LATEBREAK then -- CASE I/II: Late break. - self:_Break(playerData, AIRBOSS.PatternStep.LATEBREAK) + self:_Break( playerData, AIRBOSS.PatternStep.LATEBREAK ) - elseif playerData.step==AIRBOSS.PatternStep.ABEAM then + elseif playerData.step == AIRBOSS.PatternStep.ABEAM then -- CASE I/II: Abeam position. - self:_Abeam(playerData) + self:_Abeam( playerData ) - elseif playerData.step==AIRBOSS.PatternStep.NINETY then + elseif playerData.step == AIRBOSS.PatternStep.NINETY then -- CASE:I/II: Check long down wind leg. - self:_CheckForLongDownwind(playerData) + self:_CheckForLongDownwind( playerData ) -- At the ninety. - self:_Ninety(playerData) + self:_Ninety( playerData ) - elseif playerData.step==AIRBOSS.PatternStep.WAKE then + elseif playerData.step == AIRBOSS.PatternStep.WAKE then -- CASE I/II: In the wake. - self:_Wake(playerData) + self:_Wake( playerData ) - elseif playerData.step==AIRBOSS.PatternStep.EMERGENCY then + elseif playerData.step == AIRBOSS.PatternStep.EMERGENCY then -- Emergency landing. Player pos is not checked. - self:_Final(playerData, true) + self:_Final( playerData, true ) - elseif playerData.step==AIRBOSS.PatternStep.FINAL then + elseif playerData.step == AIRBOSS.PatternStep.FINAL then -- CASE I/II: Turn to final and enter the groove. - self:_Final(playerData) + self:_Final( playerData ) - elseif playerData.step==AIRBOSS.PatternStep.GROOVE_XX or - playerData.step==AIRBOSS.PatternStep.GROOVE_IM or - playerData.step==AIRBOSS.PatternStep.GROOVE_IC or - playerData.step==AIRBOSS.PatternStep.GROOVE_AR or - playerData.step==AIRBOSS.PatternStep.GROOVE_AL or - playerData.step==AIRBOSS.PatternStep.GROOVE_LC or - playerData.step==AIRBOSS.PatternStep.GROOVE_IW then + elseif playerData.step == AIRBOSS.PatternStep.GROOVE_XX or + playerData.step == AIRBOSS.PatternStep.GROOVE_IM or + playerData.step == AIRBOSS.PatternStep.GROOVE_IC or + playerData.step == AIRBOSS.PatternStep.GROOVE_AR or + playerData.step == AIRBOSS.PatternStep.GROOVE_AL or + playerData.step == AIRBOSS.PatternStep.GROOVE_LC or + playerData.step == AIRBOSS.PatternStep.GROOVE_IW then -- CASE I/II: In the groove. - self:_Groove(playerData) + self:_Groove( playerData ) - elseif playerData.step==AIRBOSS.PatternStep.DEBRIEF then + elseif playerData.step == AIRBOSS.PatternStep.DEBRIEF then -- Debriefing in 5 seconds. - --SCHEDULER:New(nil, self._Debrief, {self, playerData}, 5) - playerData.debriefschedulerID=self:ScheduleOnce(5, self._Debrief, self, playerData) + -- SCHEDULER:New(nil, self._Debrief, {self, playerData}, 5) + playerData.debriefschedulerID = self:ScheduleOnce( 5, self._Debrief, self, playerData ) -- Undefined status. - playerData.step=AIRBOSS.PatternStep.UNDEFINED + playerData.step = AIRBOSS.PatternStep.UNDEFINED else -- Error, unknown step! - self:E(self.lid..string.format("ERROR: Unknown player step %s. Please report!", tostring(playerData.step))) + self:E( self.lid .. string.format( "ERROR: Unknown player step %s. Please report!", tostring( playerData.step ) ) ) end -- Check if player missed a step during Case II/III and allow him to enter the landing pattern. - self:_CheckMissedStepOnEntry(playerData) + self:_CheckMissedStepOnEntry( playerData ) else - self:T2(self.lid.."WARNING: Player unit not inside the CCA!") + self:T2( self.lid .. "WARNING: Player unit not inside the CCA!" ) end else -- Unit not alive. - self:T(self.lid.."WARNING: Player unit is not alive!") + self:T( self.lid .. "WARNING: Player unit is not alive!" ) end end end end - --- Checks if a player is in the pattern queue and has missed a step in Case II/III approach. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data. -function AIRBOSS:_CheckMissedStepOnEntry(playerData) +function AIRBOSS:_CheckMissedStepOnEntry( playerData ) -- Conditions to be met: Case II/III, in pattern queue, flag!=42 (will be set to 42 at the end if player missed a step). - local rightcase=playerData.case>1 - local rightqueue=self:_InQueue(self.Qpattern, playerData.group) - local rightflag=playerData.flag~=-42 + local rightcase = playerData.case > 1 + local rightqueue = self:_InQueue( self.Qpattern, playerData.group ) + local rightflag = playerData.flag ~= -42 -- Steps that the player could have missed during Case II/III. - local step=playerData.step - local missedstep=step==AIRBOSS.PatternStep.PLATFORM or step==AIRBOSS.PatternStep.ARCIN or step==AIRBOSS.PatternStep.ARCOUT or step==AIRBOSS.PatternStep.DIRTYUP + local step = playerData.step + local missedstep = step == AIRBOSS.PatternStep.PLATFORM or step == AIRBOSS.PatternStep.ARCIN or step == AIRBOSS.PatternStep.ARCOUT or step == AIRBOSS.PatternStep.DIRTYUP -- Check if player is about to enter the initial or bullseye zones and maybe has missed a step in the pattern. if rightcase and rightqueue and rightflag then -- Get right zone. - local zone=nil - if playerData.case==2 and missedstep then + local zone = nil + if playerData.case == 2 and missedstep then - zone=self:_GetZoneInitial(playerData.case) + zone = self:_GetZoneInitial( playerData.case ) - elseif playerData.case==3 and missedstep then + elseif playerData.case == 3 and missedstep then - zone=self:_GetZoneBullseye(playerData.case) + zone = self:_GetZoneBullseye( playerData.case ) end @@ -8565,28 +7911,28 @@ function AIRBOSS:_CheckMissedStepOnEntry(playerData) if zone then -- Check if player is in initial or bullseye zone. - local inzone=playerData.unit:IsInZone(zone) + local inzone = playerData.unit:IsInZone( zone ) -- Relative heading to carrier direction. - local relheading=self:_GetRelativeHeading(playerData.unit, false) + local relheading = self:_GetRelativeHeading( playerData.unit, false ) -- Check if player is in zone and flying roughly in the right direction. - if inzone and math.abs(relheading)<60 then + if inzone and math.abs( relheading ) < 60 then -- Player is in one of the initial zones short before the landing pattern. - local text=string.format("you missed an important step in the pattern!\nYour next step would have been %s.", playerData.step) - self:MessageToPlayer(playerData, text, "AIRBOSS", nil, 5) + local text = string.format( "you missed an important step in the pattern!\nYour next step would have been %s.", playerData.step ) + self:MessageToPlayer( playerData, text, "AIRBOSS", nil, 5 ) - if playerData.case==2 then + if playerData.case == 2 then -- Set next step to initial. - playerData.step=AIRBOSS.PatternStep.INITIAL - elseif playerData.case==3 then + playerData.step = AIRBOSS.PatternStep.INITIAL + elseif playerData.case == 3 then -- Set next step to bullseye. - playerData.step=AIRBOSS.PatternStep.BULLSEYE + playerData.step = AIRBOSS.PatternStep.BULLSEYE end -- Set flag value to -42. This is the value to ensure that this routine is not called again! - playerData.flag=-42 + playerData.flag = -42 end end end @@ -8595,13 +7941,13 @@ end --- Set time in the groove for player. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data. -function AIRBOSS:_SetTimeInGroove(playerData) +function AIRBOSS:_SetTimeInGroove( playerData ) -- Set time in the groove if playerData.TIG0 then - playerData.Tgroove=timer.getTime()-playerData.TIG0 + playerData.Tgroove = timer.getTime() - playerData.TIG0 else - playerData.Tgroove=999 + playerData.Tgroove = 999 end end @@ -8610,19 +7956,18 @@ end -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data. -- @return #number Player's time in groove in seconds. -function AIRBOSS:_GetTimeInGroove(playerData) +function AIRBOSS:_GetTimeInGroove( playerData ) - local Tgroove=999 + local Tgroove = 999 -- Get time in the groove. if playerData.TIG0 then - Tgroove=timer.getTime()-playerData.TIG0 + Tgroove = timer.getTime() - playerData.TIG0 end return Tgroove end - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- EVENT functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -8630,62 +7975,62 @@ end --- Airboss event handler for event birth. -- @param #AIRBOSS self -- @param Core.Event#EVENTDATA EventData -function AIRBOSS:OnEventBirth(EventData) - self:F3({eventbirth = EventData}) +function AIRBOSS:OnEventBirth( EventData ) + self:F3( { eventbirth = EventData } ) -- Nil checks. - if EventData==nil then - self:E(self.lid.."ERROR: EventData=nil in event BIRTH!") - self:E(EventData) + if EventData == nil then + self:E( self.lid .. "ERROR: EventData=nil in event BIRTH!" ) + self:E( EventData ) return end - if EventData.IniUnit==nil then - self:E(self.lid.."ERROR: EventData.IniUnit=nil in event BIRTH!") - self:E(EventData) + if EventData.IniUnit == nil then + self:E( self.lid .. "ERROR: EventData.IniUnit=nil in event BIRTH!" ) + self:E( EventData ) return end - local _unitName=EventData.IniUnitName - local _unit, _playername=self:_GetPlayerUnitAndName(_unitName) + local _unitName = EventData.IniUnitName + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) - self:T(self.lid.."BIRTH: unit = "..tostring(EventData.IniUnitName)) - self:T(self.lid.."BIRTH: group = "..tostring(EventData.IniGroupName)) - self:T(self.lid.."BIRTH: player = "..tostring(_playername)) + self:T( self.lid .. "BIRTH: unit = " .. tostring( EventData.IniUnitName ) ) + self:T( self.lid .. "BIRTH: group = " .. tostring( EventData.IniGroupName ) ) + self:T( self.lid .. "BIRTH: player = " .. tostring( _playername ) ) if _unit and _playername then - local _uid=_unit:GetID() - local _group=_unit:GetGroup() - local _callsign=_unit:GetCallsign() + local _uid = _unit:GetID() + local _group = _unit:GetGroup() + local _callsign = _unit:GetCallsign() -- Debug output. - local text=string.format("Pilot %s, callsign %s entered unit %s of group %s.", _playername, _callsign, _unitName, _group:GetName()) - self:T(self.lid..text) - MESSAGE:New(text, 5):ToAllIf(self.Debug) + local text = string.format( "Pilot %s, callsign %s entered unit %s of group %s.", _playername, _callsign, _unitName, _group:GetName() ) + self:T( self.lid .. text ) + MESSAGE:New( text, 5 ):ToAllIf( self.Debug ) -- Check if aircraft type the player occupies is carrier capable. - local rightaircraft=self:_IsCarrierAircraft(_unit) - if rightaircraft==false then - local text=string.format("Player aircraft type %s not supported by AIRBOSS class.", _unit:GetTypeName()) - MESSAGE:New(text, 30):ToAllIf(self.Debug) - self:T2(self.lid..text) + local rightaircraft = self:_IsCarrierAircraft( _unit ) + if rightaircraft == false then + local text = string.format( "Player aircraft type %s not supported by AIRBOSS class.", _unit:GetTypeName() ) + MESSAGE:New( text, 30 ):ToAllIf( self.Debug ) + self:T2( self.lid .. text ) return end -- Check that coalition of the carrier and aircraft match. - if self:GetCoalition()~=_unit:GetCoalition() then - local text=string.format("Player entered aircraft of other coalition.") - MESSAGE:New(text, 30):ToAllIf(self.Debug) - self:T(self.lid..text) + if self:GetCoalition() ~= _unit:GetCoalition() then + local text = string.format( "Player entered aircraft of other coalition." ) + MESSAGE:New( text, 30 ):ToAllIf( self.Debug ) + self:T( self.lid .. text ) return end -- Add Menu commands. - self:_AddF10Commands(_unitName) + self:_AddF10Commands( _unitName ) -- Delaying the new player for a second, because AI units of the flight would not be registered correctly. - --SCHEDULER:New(nil, self._NewPlayer, {self, _unitName}, 1) - self:ScheduleOnce(1, self._NewPlayer, self, _unitName) + -- SCHEDULER:New(nil, self._NewPlayer, {self, _unitName}, 1) + self:ScheduleOnce( 1, self._NewPlayer, self, _unitName ) end end @@ -8693,51 +8038,51 @@ end --- Airboss event handler for event land. -- @param #AIRBOSS self -- @param Core.Event#EVENTDATA EventData -function AIRBOSS:OnEventLand(EventData) - self:F3({eventland = EventData}) +function AIRBOSS:OnEventLand( EventData ) + self:F3( { eventland = EventData } ) -- Nil checks. - if EventData==nil then - self:E(self.lid.."ERROR: EventData=nil in event LAND!") - self:E(EventData) + if EventData == nil then + self:E( self.lid .. "ERROR: EventData=nil in event LAND!" ) + self:E( EventData ) return end - if EventData.IniUnit==nil then - self:E(self.lid.."ERROR: EventData.IniUnit=nil in event LAND!") - self:E(EventData) + if EventData.IniUnit == nil then + self:E( self.lid .. "ERROR: EventData.IniUnit=nil in event LAND!" ) + self:E( EventData ) return end -- Get unit name that landed. - local _unitName=EventData.IniUnitName + local _unitName = EventData.IniUnitName -- Check if this was a player. - local _unit, _playername=self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Debug output. - self:T(self.lid.."LAND: unit = "..tostring(EventData.IniUnitName)) - self:T(self.lid.."LAND: group = "..tostring(EventData.IniGroupName)) - self:T(self.lid.."LAND: player = "..tostring(_playername)) + self:T( self.lid .. "LAND: unit = " .. tostring( EventData.IniUnitName ) ) + self:T( self.lid .. "LAND: group = " .. tostring( EventData.IniGroupName ) ) + self:T( self.lid .. "LAND: player = " .. tostring( _playername ) ) -- This would be the closest airbase. - local airbase=EventData.Place + local airbase = EventData.Place -- Nil check for airbase. Crashed as player gave me no airbase. - if airbase==nil then + if airbase == nil then return end -- Get airbase name. - local airbasename=tostring(airbase:GetName()) + local airbasename = tostring( airbase:GetName() ) -- Check if aircraft landed on the right airbase. - if airbasename==self.airbase:GetName() then + if airbasename == self.airbase:GetName() then -- Stern coordinate at the rundown. - local stern=self:_GetSternCoord() + local stern = self:_GetSternCoord() -- Polygon zone close around the carrier. - local zoneCarrier=self:_GetZoneCarrierBox() + local zoneCarrier = self:_GetZoneCarrierBox() -- Check if player or AI landed. if _unit and _playername then @@ -8747,41 +8092,41 @@ function AIRBOSS:OnEventLand(EventData) ------------------------- -- Get info. - local _uid=_unit:GetID() - local _group=_unit:GetGroup() - local _callsign=_unit:GetCallsign() + local _uid = _unit:GetID() + local _group = _unit:GetGroup() + local _callsign = _unit:GetCallsign() -- Debug output. - local text=string.format("Player %s, callsign %s unit %s (ID=%d) of group %s landed at airbase %s", _playername, _callsign, _unitName, _uid, _group:GetName(), airbasename) - self:T(self.lid..text) - MESSAGE:New(text, 5, "DEBUG"):ToAllIf(self.Debug) + local text = string.format( "Player %s, callsign %s unit %s (ID=%d) of group %s landed at airbase %s", _playername, _callsign, _unitName, _uid, _group:GetName(), airbasename ) + self:T( self.lid .. text ) + MESSAGE:New( text, 5, "DEBUG" ):ToAllIf( self.Debug ) -- Player data. - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData -- Check if playerData is okay. - if playerData==nil then - self:E(self.lid..string.format("ERROR: playerData nil in landing event. unit=%s player=%s", tostring(_unitName), tostring(_playername))) + if playerData == nil then + self:E( self.lid .. string.format( "ERROR: playerData nil in landing event. unit=%s player=%s", tostring( _unitName ), tostring( _playername ) ) ) return end -- Check that player landed on the carrier. - if _unit:IsInZone(zoneCarrier) then + if _unit:IsInZone( zoneCarrier ) then -- Check if this was a valid approach. if not playerData.valid then -- Player missed at least one step in the pattern. - local text=string.format("you missed at least one important step in the pattern!\nYour next step would have been %s.\nThis pass is INVALID.", playerData.step) - self:MessageToPlayer(playerData, text, "AIRBOSS", nil, 30, true, 5) + local text = string.format( "you missed at least one important step in the pattern!\nYour next step would have been %s.\nThis pass is INVALID.", playerData.step ) + self:MessageToPlayer( playerData, text, "AIRBOSS", nil, 30, true, 5 ) -- Clear queues just in case. - self:_RemoveFlightFromMarshalQueue(playerData, true) - self:_RemoveFlightFromQueue(self.Qpattern, playerData) - self:_RemoveFlightFromQueue(self.Qwaiting, playerData) - self:_RemoveFlightFromQueue(self.Qspinning, playerData) + self:_RemoveFlightFromMarshalQueue( playerData, true ) + self:_RemoveFlightFromQueue( self.Qpattern, playerData ) + self:_RemoveFlightFromQueue( self.Qwaiting, playerData ) + self:_RemoveFlightFromQueue( self.Qspinning, playerData ) -- Reinitialize player data. - self:_InitPlayer(playerData) + self:_InitPlayer( playerData ) return end @@ -8789,57 +8134,57 @@ function AIRBOSS:OnEventLand(EventData) -- Check if player already landed. We dont need a second time. if playerData.landed then - self:E(self.lid..string.format("Player %s just landed a second time.", _playername)) + self:E( self.lid .. string.format( "Player %s just landed a second time.", _playername ) ) else -- We did land. - playerData.landed=true + playerData.landed = true -- Switch attitude monitor off if on. - playerData.attitudemonitor=false + playerData.attitudemonitor = false -- Coordinate at landing event. - local coord=playerData.unit:GetCoordinate() + local coord = playerData.unit:GetCoordinate() -- Get distances relative to - local X,Z,rho,phi=self:_GetDistances(_unit) + local X, Z, rho, phi = self:_GetDistances( _unit ) -- Landing distance wrt to stern position. - local dist=coord:Get2DDistance(stern) + local dist = coord:Get2DDistance( stern ) -- Debug mark of player landing coord. if self.Debug and false then -- Debug mark of player landing coord. - local lp=coord:MarkToAll("Landing coord.") + local lp = coord:MarkToAll( "Landing coord." ) coord:SmokeGreen() end -- Set time in the groove of player. - self:_SetTimeInGroove(playerData) + self:_SetTimeInGroove( playerData ) -- Debug text. - local text=string.format("Player %s AC type %s landed at dist=%.1f m. Tgroove=%.1f sec.", playerData.name, playerData.actype, dist, self:_GetTimeInGroove(playerData)) - text=text..string.format(" X=%.1f m, Z=%.1f m, rho=%.1f m.", X, Z, rho) - self:T(self.lid..text) + local text = string.format( "Player %s AC type %s landed at dist=%.1f m. Tgroove=%.1f sec.", playerData.name, playerData.actype, dist, self:_GetTimeInGroove( playerData ) ) + text = text .. string.format( " X=%.1f m, Z=%.1f m, rho=%.1f m.", X, Z, rho ) + self:T( self.lid .. text ) -- Check carrier type. - if self.carriertype==AIRBOSS.CarrierType.TARAWA or self.carriertype==AIRBOSS.CarrierType.AMERICA or self.carriertype==AIRBOSS.CarrierType.JCARLOS or self.carriertype==AIRBOSS.CarrierType.CANBERRA then + if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then -- Power "Idle". - self:RadioTransmission(self.LSORadio, self.LSOCall.IDLE, false, 1, nil, true) + self:RadioTransmission( self.LSORadio, self.LSOCall.IDLE, false, 1, nil, true ) -- Next step debrief. - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.DEBRIEF) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.DEBRIEF ) else -- Next step undefined until we know more. - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.UNDEFINED) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.UNDEFINED ) -- Call trapped function in 1 second to make sure we did not bolter. - --SCHEDULER:New(nil, self._Trapped, {self, playerData}, 1) - self:ScheduleOnce(1, self._Trapped, self, playerData) + -- SCHEDULER:New(nil, self._Trapped, {self, playerData}, 1) + self:ScheduleOnce( 1, self._Trapped, self, playerData ) end @@ -8849,7 +8194,7 @@ function AIRBOSS:OnEventLand(EventData) -- Handle case where player did not land on the carrier. -- Well, I guess, he leaves the slot or ejects. Both should be handled. if playerData then - self:E(self.lid..string.format("Player %s did not land in carrier box zone. Maybe in the water near the carrier?", playerData.name)) + self:E( self.lid .. string.format( "Player %s did not land in carrier box zone. Maybe in the water near the carrier?", playerData.name ) ) end end @@ -8859,31 +8204,32 @@ function AIRBOSS:OnEventLand(EventData) -- AI unit landed -- -------------------- - if self.carriertype~=AIRBOSS.CarrierType.TARAWA or self.carriertype~=AIRBOSS.CarrierType.AMERICA or self.carriertype~=AIRBOSS.CarrierType.JCARLOS or self.carriertype~=AIRBOSS.CarrierType.CANBERRA then + if self.carriertype ~= AIRBOSS.CarrierType.HERMES or self.carriertype ~= AIRBOSS.CarrierType.TARAWA or self.carriertype ~= AIRBOSS.CarrierType.AMERICA or self.carriertype ~= AIRBOSS.CarrierType.JCARLOS or self.carriertype ~= AIRBOSS.CarrierType.CANBERRA then + -- Coordinate at landing event - local coord=EventData.IniUnit:GetCoordinate() + local coord = EventData.IniUnit:GetCoordinate() -- Debug mark of player landing coord. - local dist=coord:Get2DDistance(self:GetCoordinate()) + local dist = coord:Get2DDistance( self:GetCoordinate() ) -- Get wire - local wire=self:_GetWire(coord, 0) + local wire = self:_GetWire( coord, 0 ) -- Aircraft type. - local _type=EventData.IniUnit:GetTypeName() + local _type = EventData.IniUnit:GetTypeName() -- Debug text. - local text=string.format("AI unit %s of type %s landed at dist=%.1f m. Trapped wire=%d.", _unitName, _type, dist, wire) - self:T(self.lid..text) + local text = string.format( "AI unit %s of type %s landed at dist=%.1f m. Trapped wire=%d.", _unitName, _type, dist, wire ) + self:T( self.lid .. text ) end -- AI always lands ==> remove unit from flight group and queues. - local flight=self:_RecoveredElement(EventData.IniUnit) + local flight = self:_RecoveredElement( EventData.IniUnit ) -- Check if all were recovered. If so update pattern queue. - self:_CheckSectionRecovered(flight) + self:_CheckSectionRecovered( flight ) end end @@ -8892,62 +8238,61 @@ end --- Airboss event handler for event that a unit shuts down its engines. -- @param #AIRBOSS self -- @param Core.Event#EVENTDATA EventData -function AIRBOSS:OnEventEngineShutdown(EventData) - self:F3({eventengineshutdown=EventData}) +function AIRBOSS:OnEventEngineShutdown( EventData ) + self:F3( { eventengineshutdown = EventData } ) -- Nil checks. - if EventData==nil then - self:E(self.lid.."ERROR: EventData=nil in event ENGINESHUTDOWN!") - self:E(EventData) + if EventData == nil then + self:E( self.lid .. "ERROR: EventData=nil in event ENGINESHUTDOWN!" ) + self:E( EventData ) return end - if EventData.IniUnit==nil then - self:E(self.lid.."ERROR: EventData.IniUnit=nil in event ENGINESHUTDOWN!") - self:E(EventData) + if EventData.IniUnit == nil then + self:E( self.lid .. "ERROR: EventData.IniUnit=nil in event ENGINESHUTDOWN!" ) + self:E( EventData ) return end + local _unitName = EventData.IniUnitName + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) - local _unitName=EventData.IniUnitName - local _unit, _playername=self:_GetPlayerUnitAndName(_unitName) - - self:T3(self.lid.."ENGINESHUTDOWN: unit = "..tostring(EventData.IniUnitName)) - self:T3(self.lid.."ENGINESHUTDOWN: group = "..tostring(EventData.IniGroupName)) - self:T3(self.lid.."ENGINESHUTDOWN: player = "..tostring(_playername)) + self:T3( self.lid .. "ENGINESHUTDOWN: unit = " .. tostring( EventData.IniUnitName ) ) + self:T3( self.lid .. "ENGINESHUTDOWN: group = " .. tostring( EventData.IniGroupName ) ) + self:T3( self.lid .. "ENGINESHUTDOWN: player = " .. tostring( _playername ) ) if _unit and _playername then -- Debug message. - self:T(self.lid..string.format("Player %s shut down its engines!",_playername)) + self:T( self.lid .. string.format( "Player %s shut down its engines!", _playername ) ) else -- Debug message. - self:T(self.lid..string.format("AI unit %s shut down its engines!", _unitName)) + self:T( self.lid .. string.format( "AI unit %s shut down its engines!", _unitName ) ) -- Get flight. - local flight=self:_GetFlightFromGroupInQueue(EventData.IniGroup, self.flights) + local flight = self:_GetFlightFromGroupInQueue( EventData.IniGroup, self.flights ) -- Only AI flights. if flight and flight.ai then -- Check if all elements were recovered. - local recovered=self:_CheckSectionRecovered(flight) + local recovered = self:_CheckSectionRecovered( flight ) -- Despawn group and completely remove flight. if recovered then - self:T(self.lid..string.format("AI group %s completely recovered. Despawning group after engine shutdown event as requested in 5 seconds.", tostring(EventData.IniGroupName))) + self:T( self.lid .. string.format( "AI group %s completely recovered. Despawning group after engine shutdown event as requested in 5 seconds.", tostring( EventData.IniGroupName ) ) ) -- Remove flight. - self:_RemoveFlight(flight) + self:_RemoveFlight( flight ) -- Check if this is a tanker or AWACS associated with the carrier. - local istanker=self.tanker and self.tanker.tanker:GetName()==EventData.IniGroupName - local isawacs=self.awacs and self.awacs.tanker:GetName()==EventData.IniGroupName + local istanker = self.tanker and self.tanker.tanker:GetName() == EventData.IniGroupName + local isawacs = self.awacs and self.awacs.tanker:GetName() == EventData.IniGroupName -- Destroy group if desired. Recovery tankers have their own logic for despawning. if self.despawnshutdown and not (istanker or isawacs) then - EventData.IniGroup:Destroy(nil, 5) + EventData.IniGroup:Destroy( nil, 5 ) end end @@ -8959,61 +8304,60 @@ end --- Airboss event handler for event that a unit takes off. -- @param #AIRBOSS self -- @param Core.Event#EVENTDATA EventData -function AIRBOSS:OnEventTakeoff(EventData) - self:F3({eventtakeoff=EventData}) +function AIRBOSS:OnEventTakeoff( EventData ) + self:F3( { eventtakeoff = EventData } ) -- Nil checks. - if EventData==nil then - self:E(self.lid.."ERROR: EventData=nil in event TAKEOFF!") - self:E(EventData) + if EventData == nil then + self:E( self.lid .. "ERROR: EventData=nil in event TAKEOFF!" ) + self:E( EventData ) return end - if EventData.IniUnit==nil then - self:E(self.lid.."ERROR: EventData.IniUnit=nil in event TAKEOFF!") - self:E(EventData) + if EventData.IniUnit == nil then + self:E( self.lid .. "ERROR: EventData.IniUnit=nil in event TAKEOFF!" ) + self:E( EventData ) return end + local _unitName = EventData.IniUnitName + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) - local _unitName=EventData.IniUnitName - local _unit, _playername=self:_GetPlayerUnitAndName(_unitName) - - self:T3(self.lid.."TAKEOFF: unit = "..tostring(EventData.IniUnitName)) - self:T3(self.lid.."TAKEOFF: group = "..tostring(EventData.IniGroupName)) - self:T3(self.lid.."TAKEOFF: player = "..tostring(_playername)) + self:T3( self.lid .. "TAKEOFF: unit = " .. tostring( EventData.IniUnitName ) ) + self:T3( self.lid .. "TAKEOFF: group = " .. tostring( EventData.IniGroupName ) ) + self:T3( self.lid .. "TAKEOFF: player = " .. tostring( _playername ) ) -- Airbase. - local airbase=EventData.Place + local airbase = EventData.Place -- Airbase name. - local airbasename="unknown" + local airbasename = "unknown" if airbase then - airbasename=airbase:GetName() + airbasename = airbase:GetName() end -- Check right airbase. - if airbasename==self.airbase:GetName() then + if airbasename == self.airbase:GetName() then if _unit and _playername then -- Debug message. - self:T(self.lid..string.format("Player %s took off at %s!",_playername, airbasename)) + self:T( self.lid .. string.format( "Player %s took off at %s!", _playername, airbasename ) ) else -- Debug message. - self:T2(self.lid..string.format("AI unit %s took off at %s!", _unitName, airbasename)) + self:T2( self.lid .. string.format( "AI unit %s took off at %s!", _unitName, airbasename ) ) -- Get flight. - local flight=self:_GetFlightFromGroupInQueue(EventData.IniGroup, self.flights) + local flight = self:_GetFlightFromGroupInQueue( EventData.IniGroup, self.flights ) if flight then -- Set ballcall and recoverd status. - for _,elem in pairs(flight.elements) do - local element=elem --#AIRBOSS.FlightElement - element.ballcall=false - element.recovered=nil + for _, elem in pairs( flight.elements ) do + local element = elem -- #AIRBOSS.FlightElement + element.ballcall = false + element.recovered = nil end end end @@ -9024,48 +8368,47 @@ end --- Airboss event handler for event crash. -- @param #AIRBOSS self -- @param Core.Event#EVENTDATA EventData -function AIRBOSS:OnEventCrash(EventData) - self:F3({eventcrash = EventData}) +function AIRBOSS:OnEventCrash( EventData ) + self:F3( { eventcrash = EventData } ) -- Nil checks. - if EventData==nil then - self:E(self.lid.."ERROR: EventData=nil in event CRASH!") - self:E(EventData) + if EventData == nil then + self:E( self.lid .. "ERROR: EventData=nil in event CRASH!" ) + self:E( EventData ) return end - if EventData.IniUnit==nil then - self:E(self.lid.."ERROR: EventData.IniUnit=nil in event CRASH!") - self:E(EventData) + if EventData.IniUnit == nil then + self:E( self.lid .. "ERROR: EventData.IniUnit=nil in event CRASH!" ) + self:E( EventData ) return end + local _unitName = EventData.IniUnitName + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) - local _unitName=EventData.IniUnitName - local _unit, _playername=self:_GetPlayerUnitAndName(_unitName) - - self:T3(self.lid.."CRASH: unit = "..tostring(EventData.IniUnitName)) - self:T3(self.lid.."CRASH: group = "..tostring(EventData.IniGroupName)) - self:T3(self.lid.."CARSH: player = "..tostring(_playername)) + self:T3( self.lid .. "CRASH: unit = " .. tostring( EventData.IniUnitName ) ) + self:T3( self.lid .. "CRASH: group = " .. tostring( EventData.IniGroupName ) ) + self:T3( self.lid .. "CARSH: player = " .. tostring( _playername ) ) if _unit and _playername then -- Debug message. - self:T(self.lid..string.format("Player %s crashed!",_playername)) + self:T( self.lid .. string.format( "Player %s crashed!", _playername ) ) -- Get player flight. - local flight=self.players[_playername] + local flight = self.players[_playername] -- Remove flight completely from all queues and collapse marshal if necessary. -- This also updates the section, if any and removes any unfinished gradings of the player. if flight then - self:_RemoveFlight(flight, true) + self:_RemoveFlight( flight, true ) end else -- Debug message. - self:T2(self.lid..string.format("AI unit %s crashed!", EventData.IniUnitName)) + self:T2( self.lid .. string.format( "AI unit %s crashed!", EventData.IniUnitName ) ) -- Remove unit from flight and queues. - self:_RemoveUnitFromFlight(EventData.IniUnit) + self:_RemoveUnitFromFlight( EventData.IniUnit ) end end @@ -9073,51 +8416,50 @@ end --- Airboss event handler for event Ejection. -- @param #AIRBOSS self -- @param Core.Event#EVENTDATA EventData -function AIRBOSS:OnEventEjection(EventData) - self:F3({eventland = EventData}) +function AIRBOSS:OnEventEjection( EventData ) + self:F3( { eventland = EventData } ) -- Nil checks. - if EventData==nil then - self:E(self.lid.."ERROR: EventData=nil in event EJECTION!") - self:E(EventData) + if EventData == nil then + self:E( self.lid .. "ERROR: EventData=nil in event EJECTION!" ) + self:E( EventData ) return end - if EventData.IniUnit==nil then - self:E(self.lid.."ERROR: EventData.IniUnit=nil in event EJECTION!") - self:E(EventData) + if EventData.IniUnit == nil then + self:E( self.lid .. "ERROR: EventData.IniUnit=nil in event EJECTION!" ) + self:E( EventData ) return end + local _unitName = EventData.IniUnitName + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) - local _unitName=EventData.IniUnitName - local _unit, _playername=self:_GetPlayerUnitAndName(_unitName) - - self:T3(self.lid.."EJECT: unit = "..tostring(EventData.IniUnitName)) - self:T3(self.lid.."EJECT: group = "..tostring(EventData.IniGroupName)) - self:T3(self.lid.."EJECT: player = "..tostring(_playername)) + self:T3( self.lid .. "EJECT: unit = " .. tostring( EventData.IniUnitName ) ) + self:T3( self.lid .. "EJECT: group = " .. tostring( EventData.IniGroupName ) ) + self:T3( self.lid .. "EJECT: player = " .. tostring( _playername ) ) if _unit and _playername then - self:T(self.lid..string.format("Player %s ejected!",_playername)) + self:T( self.lid .. string.format( "Player %s ejected!", _playername ) ) -- Get player flight. - local flight=self.players[_playername] + local flight = self.players[_playername] -- Remove flight completely from all queues and collapse marshal if necessary. if flight then - self:_RemoveFlight(flight, true) + self:_RemoveFlight( flight, true ) end else -- Debug message. - self:T(self.lid..string.format("AI unit %s ejected!", EventData.IniUnitName)) + self:T( self.lid .. string.format( "AI unit %s ejected!", EventData.IniUnitName ) ) -- Remove element/unit from flight group and from all queues if no elements alive. - self:_RemoveUnitFromFlight(EventData.IniUnit) + self:_RemoveUnitFromFlight( EventData.IniUnit ) -- What could happen is, that another element has landed (recovered) already and this one crashes. -- This would mean that the flight would not be deleted from the queue ==> Check if section recovered. - local flight=self:_GetFlightFromGroupInQueue(EventData.IniGroup, self.flights) - self:_CheckSectionRecovered(flight) + local flight = self:_GetFlightFromGroupInQueue( EventData.IniGroup, self.flights ) + self:_CheckSectionRecovered( flight ) end end @@ -9125,51 +8467,50 @@ end --- Airboss event handler for event REMOVEUNIT. -- @param #AIRBOSS self -- @param Core.Event#EVENTDATA EventData -function AIRBOSS:OnEventRemoveUnit(EventData) - self:F3({eventland = EventData}) +function AIRBOSS:OnEventRemoveUnit( EventData ) + self:F3( { eventland = EventData } ) -- Nil checks. - if EventData==nil then - self:E(self.lid.."ERROR: EventData=nil in event REMOVEUNIT!") - self:E(EventData) + if EventData == nil then + self:E( self.lid .. "ERROR: EventData=nil in event REMOVEUNIT!" ) + self:E( EventData ) return end - if EventData.IniUnit==nil then - self:E(self.lid.."ERROR: EventData.IniUnit=nil in event REMOVEUNIT!") - self:E(EventData) + if EventData.IniUnit == nil then + self:E( self.lid .. "ERROR: EventData.IniUnit=nil in event REMOVEUNIT!" ) + self:E( EventData ) return end + local _unitName = EventData.IniUnitName + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) - local _unitName=EventData.IniUnitName - local _unit, _playername=self:_GetPlayerUnitAndName(_unitName) - - self:T3(self.lid.."EJECT: unit = "..tostring(EventData.IniUnitName)) - self:T3(self.lid.."EJECT: group = "..tostring(EventData.IniGroupName)) - self:T3(self.lid.."EJECT: player = "..tostring(_playername)) + self:T3( self.lid .. "EJECT: unit = " .. tostring( EventData.IniUnitName ) ) + self:T3( self.lid .. "EJECT: group = " .. tostring( EventData.IniGroupName ) ) + self:T3( self.lid .. "EJECT: player = " .. tostring( _playername ) ) if _unit and _playername then - self:T(self.lid..string.format("Player %s removed!",_playername)) + self:T( self.lid .. string.format( "Player %s removed!", _playername ) ) -- Get player flight. - local flight=self.players[_playername] + local flight = self.players[_playername] -- Remove flight completely from all queues and collapse marshal if necessary. if flight then - self:_RemoveFlight(flight, true) + self:_RemoveFlight( flight, true ) end else -- Debug message. - self:T(self.lid..string.format("AI unit %s removed!", EventData.IniUnitName)) + self:T( self.lid .. string.format( "AI unit %s removed!", EventData.IniUnitName ) ) -- Remove element/unit from flight group and from all queues if no elements alive. - self:_RemoveUnitFromFlight(EventData.IniUnit) + self:_RemoveUnitFromFlight( EventData.IniUnit ) -- What could happen is, that another element has landed (recovered) already and this one crashes. -- This would mean that the flight would not be deleted from the queue ==> Check if section recovered. - local flight=self:_GetFlightFromGroupInQueue(EventData.IniGroup, self.flights) - self:_CheckSectionRecovered(flight) + local flight = self:_GetFlightFromGroupInQueue( EventData.IniGroup, self.flights ) + self:_CheckSectionRecovered( flight ) end end @@ -9177,41 +8518,40 @@ end --- Airboss event handler for event player leave unit. -- @param #AIRBOSS self -- @param Core.Event#EVENTDATA EventData ---function AIRBOSS:OnEventPlayerLeaveUnit(EventData) -function AIRBOSS:_PlayerLeft(EventData) - self:F3({eventleave=EventData}) +-- function AIRBOSS:OnEventPlayerLeaveUnit(EventData) +function AIRBOSS:_PlayerLeft( EventData ) + self:F3( { eventleave = EventData } ) -- Nil checks. - if EventData==nil then - self:E(self.lid.."ERROR: EventData=nil in event PLAYERLEFTUNIT!") - self:E(EventData) + if EventData == nil then + self:E( self.lid .. "ERROR: EventData=nil in event PLAYERLEFTUNIT!" ) + self:E( EventData ) return end - if EventData.IniUnit==nil then - self:E(self.lid.."ERROR: EventData.IniUnit=nil in event PLAYERLEFTUNIT!") - self:E(EventData) + if EventData.IniUnit == nil then + self:E( self.lid .. "ERROR: EventData.IniUnit=nil in event PLAYERLEFTUNIT!" ) + self:E( EventData ) return end + local _unitName = EventData.IniUnitName + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) - local _unitName=EventData.IniUnitName - local _unit, _playername=self:_GetPlayerUnitAndName(_unitName) - - self:T3(self.lid.."PLAYERLEAVEUNIT: unit = "..tostring(EventData.IniUnitName)) - self:T3(self.lid.."PLAYERLEAVEUNIT: group = "..tostring(EventData.IniGroupName)) - self:T3(self.lid.."PLAYERLEAVEUNIT: player = "..tostring(_playername)) + self:T3( self.lid .. "PLAYERLEAVEUNIT: unit = " .. tostring( EventData.IniUnitName ) ) + self:T3( self.lid .. "PLAYERLEAVEUNIT: group = " .. tostring( EventData.IniGroupName ) ) + self:T3( self.lid .. "PLAYERLEAVEUNIT: player = " .. tostring( _playername ) ) if _unit and _playername then -- Debug info. - self:T(self.lid..string.format("Player %s left unit %s!",_playername, _unitName)) + self:T( self.lid .. string.format( "Player %s left unit %s!", _playername, _unitName ) ) -- Get player flight. - local flight=self.players[_playername] + local flight = self.players[_playername] -- Remove flight completely from all queues and collapse marshal if necessary. if flight then - self:_RemoveFlight(flight, true) + self:_RemoveFlight( flight, true ) end end @@ -9222,8 +8562,8 @@ end -- Handles the case when the mission is ended. -- @param #AIRBOSS self -- @param Core.Event#EVENTDATA EventData Event data. -function AIRBOSS:OnEventMissionEnd(EventData) - self:T3(self.lid.."Mission Ended") +function AIRBOSS:OnEventMissionEnd( EventData ) + self:T3( self.lid .. "Mission Ended" ) end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -9233,31 +8573,31 @@ end --- Spinning -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data. -function AIRBOSS:_Spinning(playerData) +function AIRBOSS:_Spinning( playerData ) -- Early break. - local SpinIt={} - SpinIt.name="Spinning" - SpinIt.Xmin=-UTILS.NMToMeters(6) -- Not more than 5 NM behind the boat. - SpinIt.Xmax= UTILS.NMToMeters(5) -- Not more than 5 NM in front of the boat. - SpinIt.Zmin=-UTILS.NMToMeters(6) -- Not more than 5 NM port. - SpinIt.Zmax= UTILS.NMToMeters(2) -- Not more than 3 NM starboard. - SpinIt.LimitXmin=-100 -- 100 meters behind the boat - SpinIt.LimitXmax=nil - SpinIt.LimitZmin=-UTILS.NMToMeters(1) -- 1 NM port - SpinIt.LimitZmax=nil + local SpinIt = {} + SpinIt.name = "Spinning" + SpinIt.Xmin = -UTILS.NMToMeters( 6 ) -- Not more than 5 NM behind the boat. + SpinIt.Xmax = UTILS.NMToMeters( 5 ) -- Not more than 5 NM in front of the boat. + SpinIt.Zmin = -UTILS.NMToMeters( 6 ) -- Not more than 5 NM port. + SpinIt.Zmax = UTILS.NMToMeters( 2 ) -- Not more than 3 NM starboard. + SpinIt.LimitXmin = -100 -- 100 meters behind the boat + SpinIt.LimitXmax = nil + SpinIt.LimitZmin = -UTILS.NMToMeters( 1 ) -- 1 NM port + SpinIt.LimitZmax = nil -- Get distances between carrier and player unit (parallel and perpendicular to direction of movement of carrier) - local X, Z, rho, phi=self:_GetDistances(playerData.unit) + local X, Z, rho, phi = self:_GetDistances( playerData.unit ) -- Check if we are in front of the boat (diffX > 0). - if self:_CheckLimits(X, Z, SpinIt) then + if self:_CheckLimits( X, Z, SpinIt ) then -- Player is "de-spinned". Should go to initial again. - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.INITIAL) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.INITIAL ) -- Remove player from spinning queue. - self:_RemoveFlightFromQueue(self.Qspinning, playerData) + self:_RemoveFlightFromQueue( self.Qspinning, playerData ) end @@ -9266,28 +8606,28 @@ end --- Waiting outside 10 NM zone for free Marshal stack. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data. -function AIRBOSS:_Waiting(playerData) +function AIRBOSS:_Waiting( playerData ) -- Create 10 NM zone around the carrier. - local radius=UTILS.NMToMeters(10) - local zone=ZONE_RADIUS:New("Carrier 10 NM Zone", self.carrier:GetVec2(), radius) + local radius = UTILS.NMToMeters( 10 ) + local zone = ZONE_RADIUS:New( "Carrier 10 NM Zone", self.carrier:GetVec2(), radius ) -- Check if player is inside 10 NM radius of the carrier. - local inzone=playerData.unit:IsInZone(zone) + local inzone = playerData.unit:IsInZone( zone ) -- Time player is waiting. - local Twaiting=timer.getAbsTime()-playerData.time + local Twaiting = timer.getAbsTime() - playerData.time -- Warning if player is inside the zone. - if inzone and Twaiting>3*60 and not playerData.warning then - local text=string.format("You are supposed to wait outside the 10 NM zone.") - self:MessageToPlayer(playerData, text, "AIRBOSS") - playerData.warning=true + if inzone and Twaiting > 3 * 60 and not playerData.warning then + local text = string.format( "You are supposed to wait outside the 10 NM zone." ) + self:MessageToPlayer( playerData, text, "AIRBOSS" ) + playerData.warning = true end -- Reset warning. - if inzone==false and playerData.warning==true then - playerData.warning=nil + if inzone == false and playerData.warning == true then + playerData.warning = nil end end @@ -9295,18 +8635,18 @@ end --- Holding. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data. -function AIRBOSS:_Holding(playerData) +function AIRBOSS:_Holding( playerData ) -- Player unit and flight. - local unit=playerData.unit + local unit = playerData.unit -- Current stack. - local stack=playerData.flag + local stack = playerData.flag -- Check for reported error. - if stack<=0 then - local text=string.format("ERROR: player %s in step %s is holding but has stack=%s (<=0)", playerData.name, playerData.step, tostring(stack)) - self:E(self.lid..text) + if stack <= 0 then + local text = string.format( "ERROR: player %s in step %s is holding but has stack=%s (<=0)", playerData.name, playerData.step, tostring( stack ) ) + self:E( self.lid .. text ) end --------------------------- @@ -9314,99 +8654,99 @@ function AIRBOSS:_Holding(playerData) --------------------------- -- Pattern altitude. - local patternalt=self:_GetMarshalAltitude(stack, playerData.case) + local patternalt = self:_GetMarshalAltitude( stack, playerData.case ) -- Player altitude. - local playeralt=unit:GetAltitude() + local playeralt = unit:GetAltitude() -- Get holding zone of player. - local zoneHolding=self:_GetZoneHolding(playerData.case, stack) + local zoneHolding = self:_GetZoneHolding( playerData.case, stack ) -- Nil check. - if zoneHolding==nil then - self:E(self.lid.."ERROR: zoneHolding is nil!") - self:E({playerData=playerData}) + if zoneHolding == nil then + self:E( self.lid .. "ERROR: zoneHolding is nil!" ) + self:E( { playerData = playerData } ) return end -- Check if player is in holding zone. - local inholdingzone=unit:IsInZone(zoneHolding) + local inholdingzone = unit:IsInZone( zoneHolding ) -- Altitude difference between player and assigned stack. - local altdiff=playeralt-patternalt + local altdiff = playeralt - patternalt -- Acceptable altitude depending on player skill. - local altgood=UTILS.FeetToMeters(500) - if playerData.difficulty==AIRBOSS.Difficulty.HARD then + local altgood = UTILS.FeetToMeters( 500 ) + if playerData.difficulty == AIRBOSS.Difficulty.HARD then -- Pros can be expected to be within +-200 ft. - altgood=UTILS.FeetToMeters(200) - elseif playerData.difficulty==AIRBOSS.Difficulty.NORMAL then + altgood = UTILS.FeetToMeters( 200 ) + elseif playerData.difficulty == AIRBOSS.Difficulty.NORMAL then -- Normal guys should be within +-350 ft. - altgood=UTILS.FeetToMeters(350) - elseif playerData.difficulty==AIRBOSS.Difficulty.EASY then + altgood = UTILS.FeetToMeters( 350 ) + elseif playerData.difficulty == AIRBOSS.Difficulty.EASY then -- Students should be within +-500 ft. - altgood=UTILS.FeetToMeters(500) + altgood = UTILS.FeetToMeters( 500 ) end -- When back to good altitude = 50%. - local altback=altgood*0.5 + local altback = altgood * 0.5 -- Check if stack just collapsed and give the player one minute to change the altitude. - local justcollapsed=false + local justcollapsed = false if self.Tcollapse then -- Time since last stack change. - local dT=timer.getTime()-self.Tcollapse + local dT = timer.getTime() - self.Tcollapse -- TODO: check if this works. - --local dT=timer.getAbsTime()-playerData.time + -- local dT=timer.getAbsTime()-playerData.time -- Check if less then 90 seconds. - if dT<=90 then - justcollapsed=true + if dT <= 90 then + justcollapsed = true end end -- Check if altitude is acceptable. - local goodalt=math.abs(altdiff)altgood then + if altdiff > altgood then -- Issue warning for being too high. if not playerData.warning then - text=text..string.format("You left your assigned altitude. Descent to angels %d.", angels) - playerData.warning=true + text = text .. string.format( "You left your assigned altitude. Descent to angels %d.", angels ) + playerData.warning = true end - elseif altdiff<-altgood then + elseif altdiff < -altgood then -- Issue warning for being too low. if not playerData.warning then - text=text..string.format("You left your assigned altitude. Climb to angels %d.", angels) - playerData.warning=true + text = text .. string.format( "You left your assigned altitude. Climb to angels %d.", angels ) + playerData.warning = true end end @@ -9414,62 +8754,61 @@ function AIRBOSS:_Holding(playerData) end -- Back to assigned altitude. - if playerData.warning and math.abs(altdiff)<=altback then - text=text..string.format("Altitude is looking good again.") - playerData.warning=nil + if playerData.warning and math.abs( altdiff ) <= altback then + text = text .. string.format( "Altitude is looking good again." ) + playerData.warning = nil end - elseif playerData.holding==false then + elseif playerData.holding == false then -- Player left holding zone if inholdingzone then -- Player is back in the holding zone. - text=text..string.format("You are back in the holding zone. Now stay there!") - playerData.holding=true + text = text .. string.format( "You are back in the holding zone. Now stay there!" ) + playerData.holding = true else -- Player is still outside the holding zone. - self:T3("Player still outside the holding zone. What are you doing man?!") + self:T3( "Player still outside the holding zone. What are you doing man?!" ) end - elseif playerData.holding==nil then + elseif playerData.holding == nil then -- Player did not entered the holding zone yet. if inholdingzone then -- Player arrived in holding zone. - playerData.holding=true + playerData.holding = true -- Inform player. - text=text..string.format("You arrived at the holding zone.") + text = text .. string.format( "You arrived at the holding zone." ) -- Feedback on altitude. if goodalt then - text=text..string.format(" Altitude is good.") + text = text .. string.format( " Altitude is good." ) else - if altdiff<0 then - text=text..string.format(" But you're too low.") + if altdiff < 0 then + text = text .. string.format( " But you're too low." ) else - text=text..string.format(" But you're too high.") + text = text .. string.format( " But you're too high." ) end - text=text..string.format("\nCurrently assigned altitude is %d ft.", UTILS.MetersToFeet(patternalt)) - playerData.warning=true + text = text .. string.format( "\nCurrently assigned altitude is %d ft.", UTILS.MetersToFeet( patternalt ) ) + playerData.warning = true end else -- Player did not yet arrive in holding zone. - self:T3("Waiting for player to arrive in the holding zone.") + self:T3( "Waiting for player to arrive in the holding zone." ) end end -- Send message. if playerData.showhints then - self:MessageToPlayer(playerData, text, "MARSHAL") + self:MessageToPlayer( playerData, text, "MARSHAL" ) end end - --- Commence approach. This step initializes the player data. Section members are also set to commence. Next step depends on recovery case: -- -- * Case 1: Initial @@ -9478,24 +8817,24 @@ end -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data. -- @param #boolean zonecheck If true, zone is checked before player is released. -function AIRBOSS:_Commencing(playerData, zonecheck) +function AIRBOSS:_Commencing( playerData, zonecheck ) -- Check for auto commence if zonecheck then -- Get auto commence zone. - local zoneCommence=self:_GetZoneCommence(playerData.case, playerData.flag) + local zoneCommence = self:_GetZoneCommence( playerData.case, playerData.flag ) -- Check if unit is in the zone. - local inzone=playerData.unit:IsInZone(zoneCommence) + local inzone = playerData.unit:IsInZone( zoneCommence ) -- Skip the rest if not in the zone yet. if not inzone then -- Friendly reminder. - if timer.getAbsTime()-playerData.time>180 then - self:_MarshalCallClearedForRecovery(playerData.onboard, playerData.case) - playerData.time=timer.getAbsTime() + if timer.getAbsTime() - playerData.time > 180 then + self:_MarshalCallClearedForRecovery( playerData.onboard, playerData.case ) + playerData.time = timer.getAbsTime() end -- Skip the rest. @@ -9505,48 +8844,48 @@ function AIRBOSS:_Commencing(playerData, zonecheck) end -- Remove flight from Marshal queue. If flight was in queue, stack is collapsed and flight added to the pattern queue. - self:_RemoveFlightFromMarshalQueue(playerData) + self:_RemoveFlightFromMarshalQueue( playerData ) -- Initialize player data for new approach. - self:_InitPlayer(playerData) + self:_InitPlayer( playerData ) -- Commencing message to player only. - if playerData.difficulty~=AIRBOSS.Difficulty.HARD then + if playerData.difficulty ~= AIRBOSS.Difficulty.HARD then -- Text - local text="" + local text = "" -- Positive response. - if playerData.case==1 then - text=text.."Proceed to initial." + if playerData.case == 1 then + text = text .. "Proceed to initial." else - text=text.."Descent to platform." - if playerData.difficulty==AIRBOSS.Difficulty.EASY and playerData.showhints then - text=text.." VSI 4000 ft/min until you reach 5000 ft." + text = text .. "Descent to platform." + if playerData.difficulty == AIRBOSS.Difficulty.EASY and playerData.showhints then + text = text .. " VSI 4000 ft/min until you reach 5000 ft." end end -- Message to player. - self:MessageToPlayer(playerData, text, "MARSHAL") + self:MessageToPlayer( playerData, text, "MARSHAL" ) end -- Next step: depends on case recovery. local nextstep - if playerData.case==1 then + if playerData.case == 1 then -- CASE I: Player has to fly to the initial which is 3 NM DME astern of the boat. - nextstep=AIRBOSS.PatternStep.INITIAL + nextstep = AIRBOSS.PatternStep.INITIAL else -- CASE II/III: Player has to start the descent at 4000 ft/min to the platform at 5k ft. - nextstep=AIRBOSS.PatternStep.PLATFORM + nextstep = AIRBOSS.PatternStep.PLATFORM end -- Next step hint. - self:_SetPlayerStep(playerData, nextstep) + self:_SetPlayerStep( playerData, nextstep ) -- Commence section members as well but dont check the zone. - for i,_flight in pairs(playerData.section) do - local flight=_flight --#AIRBOSS.PlayerData - self:_Commencing(flight, false) + for i, _flight in pairs( playerData.section ) do + local flight = _flight -- #AIRBOSS.PlayerData + self:_Commencing( flight, false ) end end @@ -9555,40 +8894,40 @@ end -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data table. -- @return #boolean True if player is in the initial zone. -function AIRBOSS:_Initial(playerData) +function AIRBOSS:_Initial( playerData ) -- Check if player is in initial zone and entering the CASE I pattern. - local inzone=playerData.unit:IsInZone(self:_GetZoneInitial(playerData.case)) + local inzone = playerData.unit:IsInZone( self:_GetZoneInitial( playerData.case ) ) -- Relative heading to carrier direction. - local relheading=self:_GetRelativeHeading(playerData.unit, false) + local relheading = self:_GetRelativeHeading( playerData.unit, false ) -- Alitude of player in feet. - local altitude=playerData.unit:GetAltitude() + local altitude = playerData.unit:GetAltitude() -- Check if player is in zone and flying roughly in the right direction. - if inzone and math.abs(relheading)<60 and altitude<=self.initialmaxalt then + if inzone and math.abs( relheading ) < 60 and altitude <= self.initialmaxalt then -- Send message for normal and easy difficulty. if playerData.showhints then -- Inform player. - local hint=string.format("Initial") + local hint = string.format( "Initial" ) -- Hook down for students. - if playerData.difficulty==AIRBOSS.Difficulty.EASY and playerData.actype~=AIRBOSS.AircraftCarrier.AV8B then - if playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then - hint=hint.." - Hook down, SAS on, Wing Sweep 68°!" + if playerData.difficulty == AIRBOSS.Difficulty.EASY and playerData.actype ~= AIRBOSS.AircraftCarrier.AV8B then + if playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B then + hint = hint .. " - Hook down, SAS on, Wing Sweep 68°!" else - hint=hint.." - Hook down!" + hint = hint .. " - Hook down!" end end - self:MessageToPlayer(playerData, hint, "MARSHAL") + self:MessageToPlayer( playerData, hint, "MARSHAL" ) end -- Next step: Break entry. - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.BREAKENTRY) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.BREAKENTRY ) return true end @@ -9599,24 +8938,24 @@ end --- Check if player is in CASE II/III approach corridor. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data table. -function AIRBOSS:_CheckCorridor(playerData) +function AIRBOSS:_CheckCorridor( playerData ) -- Check if player is in valid zone - local validzone=self:_GetZoneCorridor(playerData.case) + local validzone = self:_GetZoneCorridor( playerData.case ) -- Check if we are inside the moving zone. - local invalid=playerData.unit:IsNotInZone(validzone) + local invalid = playerData.unit:IsNotInZone( validzone ) -- Issue warning. if invalid and (not playerData.warning) then - self:MessageToPlayer(playerData, "you left the approach corridor!", "AIRBOSS") - playerData.warning=true + self:MessageToPlayer( playerData, "you left the approach corridor!", "AIRBOSS" ) + playerData.warning = true end -- Back in zone. if (not invalid) and playerData.warning then - self:MessageToPlayer(playerData, "you're back in the approach corridor.", "AIRBOSS") - playerData.warning=false + self:MessageToPlayer( playerData, "you're back in the approach corridor.", "AIRBOSS" ) + playerData.warning = false end end @@ -9624,60 +8963,59 @@ end --- Platform at 5k ft for case II/III recoveries. Descent at 2000 ft/min. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data table. -function AIRBOSS:_Platform(playerData) +function AIRBOSS:_Platform( playerData ) -- Check if player left or got back to the approach corridor. - self:_CheckCorridor(playerData) + self:_CheckCorridor( playerData ) -- Check if we are inside the moving zone. - local inzone=playerData.unit:IsInZone(self:_GetZonePlatform(playerData.case)) + local inzone = playerData.unit:IsInZone( self:_GetZonePlatform( playerData.case ) ) -- Check if we are in zone. if inzone then -- Hint for player about altitude, AoA etc. - self:_PlayerHint(playerData) + self:_PlayerHint( playerData ) -- Next step: depends. local nextstep - if math.abs(self.holdingoffset)>0 and playerData.case>1 then + if math.abs( self.holdingoffset ) > 0 and playerData.case > 1 then -- Turn to BRC (case II) or FB (case III). - nextstep=AIRBOSS.PatternStep.ARCIN + nextstep = AIRBOSS.PatternStep.ARCIN else - if playerData.case==2 then + if playerData.case == 2 then -- Case II: Initial zone then Case I recovery. - nextstep=AIRBOSS.PatternStep.INITIAL - elseif playerData.case==3 then + nextstep = AIRBOSS.PatternStep.INITIAL + elseif playerData.case == 3 then -- CASE III: Dirty up. - nextstep=AIRBOSS.PatternStep.DIRTYUP + nextstep = AIRBOSS.PatternStep.DIRTYUP end end -- Next step hint. - self:_SetPlayerStep(playerData, nextstep) + self:_SetPlayerStep( playerData, nextstep ) end end - --- Arc in turn for case II/III recoveries. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data table. -function AIRBOSS:_ArcInTurn(playerData) +function AIRBOSS:_ArcInTurn( playerData ) -- Check if player left or got back to the approach corridor. - self:_CheckCorridor(playerData) + self:_CheckCorridor( playerData ) -- Check if we are inside the moving zone. - local inzone=playerData.unit:IsInZone(self:_GetZoneArcIn(playerData.case)) + local inzone = playerData.unit:IsInZone( self:_GetZoneArcIn( playerData.case ) ) if inzone then -- Hint for player about altitude, AoA etc. - self:_PlayerHint(playerData) + self:_PlayerHint( playerData ) -- Next step: Arc Out Turn. - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.ARCOUT) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.ARCOUT ) end end @@ -9685,62 +9023,62 @@ end --- Arc out turn for case II/III recoveries. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data table. -function AIRBOSS:_ArcOutTurn(playerData) +function AIRBOSS:_ArcOutTurn( playerData ) -- Check if player left or got back to the approach corridor. - self:_CheckCorridor(playerData) + self:_CheckCorridor( playerData ) -- Check if we are inside the moving zone. - local inzone=playerData.unit:IsInZone(self:_GetZoneArcOut(playerData.case)) + local inzone = playerData.unit:IsInZone( self:_GetZoneArcOut( playerData.case ) ) if inzone then -- Hint for player about altitude, AoA etc. - self:_PlayerHint(playerData) + self:_PlayerHint( playerData ) -- Next step: local nextstep - if playerData.case==3 then + if playerData.case == 3 then -- Case III: Dirty up. - nextstep=AIRBOSS.PatternStep.DIRTYUP + nextstep = AIRBOSS.PatternStep.DIRTYUP else -- Case II: Initial. - nextstep=AIRBOSS.PatternStep.INITIAL + nextstep = AIRBOSS.PatternStep.INITIAL end -- Next step hint. - self:_SetPlayerStep(playerData, nextstep) + self:_SetPlayerStep( playerData, nextstep ) end end --- Dirty up and level out at 1200 ft for case III recovery. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data table. -function AIRBOSS:_DirtyUp(playerData) +function AIRBOSS:_DirtyUp( playerData ) -- Check if player left or got back to the approach corridor. - self:_CheckCorridor(playerData) + self:_CheckCorridor( playerData ) -- Check if we are inside the moving zone. - local inzone=playerData.unit:IsInZone(self:_GetZoneDirtyUp(playerData.case)) + local inzone = playerData.unit:IsInZone( self:_GetZoneDirtyUp( playerData.case ) ) if inzone then -- Hint for player about altitude, AoA etc. - self:_PlayerHint(playerData) + self:_PlayerHint( playerData ) -- Radio call "Say/Fly needles". Delayed by 10/15 seconds. - if playerData.actype==AIRBOSS.AircraftCarrier.HORNET or playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then - local callsay=self:_NewRadioCall(self.MarshalCall.SAYNEEDLES, nil, nil, 5, playerData.onboard) - local callfly=self:_NewRadioCall(self.MarshalCall.FLYNEEDLES, nil, nil, 5, playerData.onboard) - self:RadioTransmission(self.MarshalRadio, callsay, false, 55, nil, true) - self:RadioTransmission(self.MarshalRadio, callfly, false, 60, nil, true) + if playerData.actype == AIRBOSS.AircraftCarrier.HORNET or playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B then + local callsay = self:_NewRadioCall( self.MarshalCall.SAYNEEDLES, nil, nil, 5, playerData.onboard ) + local callfly = self:_NewRadioCall( self.MarshalCall.FLYNEEDLES, nil, nil, 5, playerData.onboard ) + self:RadioTransmission( self.MarshalRadio, callsay, false, 55, nil, true ) + self:RadioTransmission( self.MarshalRadio, callfly, false, 60, nil, true ) end -- TODO: Make Fly Bullseye call if no automatic ICLS is active. -- Next step: CASE III: Intercept glide slope and follow bullseye (ICLS). - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.BULLSEYE) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.BULLSEYE ) end end @@ -9749,34 +9087,34 @@ end -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data table. -- @return #boolean If true, player is in bullseye zone. -function AIRBOSS:_Bullseye(playerData) +function AIRBOSS:_Bullseye( playerData ) -- Check if player left or got back to the approach corridor. - self:_CheckCorridor(playerData) + self:_CheckCorridor( playerData ) -- Check if we are inside the moving zone. - local inzone=playerData.unit:IsInZone(self:_GetZoneBullseye(playerData.case)) + local inzone = playerData.unit:IsInZone( self:_GetZoneBullseye( playerData.case ) ) -- Relative heading to carrier direction of the runway. - local relheading=self:_GetRelativeHeading(playerData.unit, true) + local relheading = self:_GetRelativeHeading( playerData.unit, true ) -- Check if player is in zone and flying roughly in the right direction. - if inzone and math.abs(relheading)<60 then + if inzone and math.abs( relheading ) < 60 then -- Hint for player about altitude, AoA etc. - self:_PlayerHint(playerData) + self:_PlayerHint( playerData ) -- LSO expect spot 5 or 7.5 call - if playerData.actype==AIRBOSS.AircraftCarrier.AV8B and self.carriertype==AIRBOSS.CarrierType.JCARLOS then - self:RadioTransmission(self.LSORadio, self.LSOCall.EXPECTSPOT5, nil, nil, nil, true) - elseif playerData.actype==AIRBOSS.AircraftCarrier.AV8B and self.carriertype==AIRBOSS.CarrierType.CANBERRA then - self:RadioTransmission(self.LSORadio, self.LSOCall.EXPECTSPOT5, nil, nil, nil, true) - elseif playerData.actype==AIRBOSS.AircraftCarrier.AV8B then - self:RadioTransmission(self.LSORadio, self.LSOCall.EXPECTSPOT75, nil, nil, nil, true) + if playerData.actype == AIRBOSS.AircraftCarrier.AV8B and self.carriertype == AIRBOSS.CarrierType.JCARLOS then + self:RadioTransmission( self.LSORadio, self.LSOCall.EXPECTSPOT5, nil, nil, nil, true ) + elseif playerData.actype == AIRBOSS.AircraftCarrier.AV8B and self.carriertype == AIRBOSS.CarrierType.CANBERRA then + self:RadioTransmission( self.LSORadio, self.LSOCall.EXPECTSPOT5, nil, nil, nil, true ) + elseif playerData.actype == AIRBOSS.AircraftCarrier.AV8B then + self:RadioTransmission( self.LSORadio, self.LSOCall.EXPECTSPOT75, nil, nil, nil, true ) end -- Next step: Groove Call the ball. - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.GROOVE_XX) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.GROOVE_XX ) end end @@ -9784,150 +9122,147 @@ end --- Bolter pattern. Sends player to abeam for Case I/II or Bullseye for Case III ops. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data table. -function AIRBOSS:_BolterPattern(playerData) +function AIRBOSS:_BolterPattern( playerData ) -- Get distances between carrier and player unit (parallel and perpendicular to direction of movement of carrier) - local X, Z, rho, phi=self:_GetDistances(playerData.unit) + local X, Z, rho, phi = self:_GetDistances( playerData.unit ) -- Bolter Pattern thresholds. - local Bolter={} - Bolter.name="Bolter Pattern" - Bolter.Xmin=-UTILS.NMToMeters(5) -- Not more then 5 NM astern of boat. - Bolter.Xmax= UTILS.NMToMeters(3) -- Not more then 3 NM ahead of boat. - Bolter.Zmin=-UTILS.NMToMeters(5) -- Not more than 2 NM port. - Bolter.Zmax= UTILS.NMToMeters(1) -- Not more than 1 NM starboard. - Bolter.LimitXmin= 100 -- Check that 100 meter ahead and port - Bolter.LimitXmax= nil - Bolter.LimitZmin= nil - Bolter.LimitZmax= nil + local Bolter = {} + Bolter.name = "Bolter Pattern" + Bolter.Xmin = -UTILS.NMToMeters( 5 ) -- Not more then 5 NM astern of boat. + Bolter.Xmax = UTILS.NMToMeters( 3 ) -- Not more then 3 NM ahead of boat. + Bolter.Zmin = -UTILS.NMToMeters( 5 ) -- Not more than 2 NM port. + Bolter.Zmax = UTILS.NMToMeters( 1 ) -- Not more than 1 NM starboard. + Bolter.LimitXmin = 100 -- Check that 100 meter ahead and port + Bolter.LimitXmax = nil + Bolter.LimitZmin = nil + Bolter.LimitZmax = nil -- Check if we are in front of the boat (diffX > 0). - if self:_CheckLimits(X, Z, Bolter) then + if self:_CheckLimits( X, Z, Bolter ) then local nextstep - if playerData.case<3 then - nextstep=AIRBOSS.PatternStep.ABEAM + if playerData.case < 3 then + nextstep = AIRBOSS.PatternStep.ABEAM else - nextstep=AIRBOSS.PatternStep.BULLSEYE + nextstep = AIRBOSS.PatternStep.BULLSEYE end - self:_SetPlayerStep(playerData, nextstep) + self:_SetPlayerStep( playerData, nextstep ) end end - - --- Break entry for case I/II recoveries. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data table. -function AIRBOSS:_BreakEntry(playerData) +function AIRBOSS:_BreakEntry( playerData ) -- Get distances between carrier and player unit (parallel and perpendicular to direction of movement of carrier) - local X, Z=self:_GetDistances(playerData.unit) + local X, Z = self:_GetDistances( playerData.unit ) -- Abort condition check. - if self:_CheckAbort(X, Z, self.BreakEntry) then - self:_AbortPattern(playerData, X, Z, self.BreakEntry, true) + if self:_CheckAbort( X, Z, self.BreakEntry ) then + self:_AbortPattern( playerData, X, Z, self.BreakEntry, true ) return end -- Check if we are in front of the boat (diffX > 0). - if self:_CheckLimits(X, Z, self.BreakEntry) then + if self:_CheckLimits( X, Z, self.BreakEntry ) then -- Hint for player about altitude, AoA etc. - self:_PlayerHint(playerData) + self:_PlayerHint( playerData ) -- Next step: Early Break. - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.EARLYBREAK) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.EARLYBREAK ) end end - --- Break. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data table. -- @param #string part Part of the break. -function AIRBOSS:_Break(playerData, part) +function AIRBOSS:_Break( playerData, part ) -- Get distances between carrier and player unit (parallel and perpendicular to direction of movement of carrier) - local X, Z=self:_GetDistances(playerData.unit) + local X, Z = self:_GetDistances( playerData.unit ) -- Early or late break. local breakpoint = self.BreakEarly - if part==AIRBOSS.PatternStep.LATEBREAK then + if part == AIRBOSS.PatternStep.LATEBREAK then breakpoint = self.BreakLate end -- Check abort conditions. - if self:_CheckAbort(X, Z, breakpoint) then - self:_AbortPattern(playerData, X, Z, breakpoint, true) + if self:_CheckAbort( X, Z, breakpoint ) then + self:_AbortPattern( playerData, X, Z, breakpoint, true ) return end -- Player made a very tight turn and did not trigger the latebreak threshold at 0.8 NM. - local tooclose=false - if part==AIRBOSS.PatternStep.LATEBREAK then - local close=0.8 - if playerData.actype==AIRBOSS.AircraftCarrier.AV8B then - close=0.5 + local tooclose = false + if part == AIRBOSS.PatternStep.LATEBREAK then + local close = 0.8 + if playerData.actype == AIRBOSS.AircraftCarrier.AV8B then + close = 0.5 end - if X<0 and Z90 and self:_CheckLimits(X, Z, self.Wake) then + elseif relheading > 90 and self:_CheckLimits( X, Z, self.Wake ) then -- Message to player. - self:MessageToPlayer(playerData, "you are already at the wake and have not passed the 90. Turn faster next time!", "LSO") - self:RadioTransmission(self.LSORadio, self.LSOCall.DEPARTANDREENTER, nil, nil, nil, true) - playerData.wop=true + self:MessageToPlayer( playerData, "you are already at the wake and have not passed the 90. Turn faster next time!", "LSO" ) + self:RadioTransmission( self.LSORadio, self.LSOCall.DEPARTANDREENTER, nil, nil, nil, true ) + playerData.wop = true -- Debrief. - self:_AddToDebrief(playerData, "Overshoot at wake - Pattern Waveoff!") - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.DEBRIEF) + self:_AddToDebrief( playerData, "Overshoot at wake - Pattern Waveoff!" ) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.DEBRIEF ) end end --- At the Wake. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data table. -function AIRBOSS:_Wake(playerData) +function AIRBOSS:_Wake( playerData ) -- Get distances between carrier and player unit (parallel and perpendicular to direction of movement of carrier) - local X, Z=self:_GetDistances(playerData.unit) + local X, Z = self:_GetDistances( playerData.unit ) -- Check abort conditions. - if self:_CheckAbort(X, Z, self.Wake) then - self:_AbortPattern(playerData, X, Z, self.Wake, true) + if self:_CheckAbort( X, Z, self.Wake ) then + self:_AbortPattern( playerData, X, Z, self.Wake, true ) return end -- Right behind the wake of the carrier dZ>0. - if self:_CheckLimits(X, Z, self.Wake) then + if self:_CheckLimits( X, Z, self.Wake ) then -- Hint for player about altitude, AoA etc. - self:_PlayerHint(playerData) + self:_PlayerHint( playerData ) -- Next step: Final. - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.FINAL) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.FINAL ) end end @@ -10043,53 +9379,53 @@ end -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data table. -- @return #AIRBOSS.GrooveData Groove data table. -function AIRBOSS:_GetGrooveData(playerData) +function AIRBOSS:_GetGrooveData( playerData ) -- Get distances between carrier and player unit (parallel and perpendicular to direction of movement of carrier). - local X, Z=self:_GetDistances(playerData.unit) + local X, Z = self:_GetDistances( playerData.unit ) -- Stern position at the rundown. - local stern=self:_GetSternCoord() + local stern = self:_GetSternCoord() -- Distance from rundown to player aircraft. - local rho=stern:Get2DDistance(playerData.unit:GetCoordinate()) + local rho = stern:Get2DDistance( playerData.unit:GetCoordinate() ) -- Aircraft is behind the carrier. - local astern=X5. This would mean the player has not turned in correctly! -- Groove data. - playerData.groove.X0=UTILS.DeepCopy(groovedata) + playerData.groove.X0 = UTILS.DeepCopy( groovedata ) -- Set time stamp. Next call in 4 seconds. - playerData.Tlso=timer.getTime() + playerData.Tlso = timer.getTime() -- Next step: X start. - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.GROOVE_XX) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.GROOVE_XX ) end -- Groovedata step. - groovedata.Step=playerData.step + groovedata.Step = playerData.step end --- In the groove. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data table. -function AIRBOSS:_Groove(playerData) +function AIRBOSS:_Groove( playerData ) -- Ranges in the groove. - local RX0=UTILS.NMToMeters(1.000) -- Everything before X 1.00 = 1852 m - local RXX=UTILS.NMToMeters(0.750) -- Start of groove. 0.75 = 1389 m - local RIM=UTILS.NMToMeters(0.500) -- In the Middle 0.50 = 926 m (middle one third of the glideslope) - local RIC=UTILS.NMToMeters(0.250) -- In Close 0.25 = 463 m (last one third of the glideslope) - local RAR=UTILS.NMToMeters(0.040) -- At the Ramp. 0.04 = 75 m + local RX0 = UTILS.NMToMeters( 1.000 ) -- Everything before X 1.00 = 1852 m + local RXX = UTILS.NMToMeters( 0.750 ) -- Start of groove. 0.75 = 1389 m + local RIM = UTILS.NMToMeters( 0.500 ) -- In the Middle 0.50 = 926 m (middle one third of the glideslope) + local RIC = UTILS.NMToMeters( 0.250 ) -- In Close 0.25 = 463 m (last one third of the glideslope) + local RAR = UTILS.NMToMeters( 0.040 ) -- At the Ramp. 0.04 = 75 m -- Groove data. - local groovedata=self:_GetGrooveData(playerData) + local groovedata = self:_GetGrooveData( playerData ) -- Add data to trapsheet. - table.insert(playerData.trapsheet, groovedata) + table.insert( playerData.trapsheet, groovedata ) -- Coords. - local X=groovedata.X - local Z=groovedata.Z + local X = groovedata.X + local Z = groovedata.Z -- Check abort conditions. - if self:_CheckAbort(groovedata.X, groovedata.Z, self.Groove) then - self:_AbortPattern(playerData, groovedata.X, groovedata.Z, self.Groove, true) + if self:_CheckAbort( groovedata.X, groovedata.Z, self.Groove ) then + self:_AbortPattern( playerData, groovedata.X, groovedata.Z, self.Groove, true ) return end -- Shortcuts. - local rho=groovedata.Rho - local lineupError=groovedata.LUE - local glideslopeError=groovedata.GSE - local AoA=groovedata.AoA + local rho = groovedata.Rho + local lineupError = groovedata.LUE + local glideslopeError = groovedata.GSE + local AoA = groovedata.AoA - - if rho<=RXX and playerData.step==AIRBOSS.PatternStep.GROOVE_XX and (math.abs(groovedata.Roll)<=4.0 or playerData.unit:IsInZone(self:_GetZoneLineup())) then + if rho <= RXX and playerData.step == AIRBOSS.PatternStep.GROOVE_XX and (math.abs( groovedata.Roll ) <= 4.0 or playerData.unit:IsInZone( self:_GetZoneLineup() )) then -- Start time in groove - playerData.TIG0=timer.getTime() + playerData.TIG0 = timer.getTime() -- LSO "Call the ball" call. - self:RadioTransmission(self.LSORadio, self.LSOCall.CALLTHEBALL, nil, nil, nil, true) - playerData.Tlso=timer.getTime() + self:RadioTransmission( self.LSORadio, self.LSOCall.CALLTHEBALL, nil, nil, nil, true ) + playerData.Tlso = timer.getTime() -- Pilot "405, Hornet Ball, 3.2". -- LSO "Roger ball" call in three seconds. - self:RadioTransmission(self.LSORadio, self.LSOCall.ROGERBALL, false, nil, 2, true) + self:RadioTransmission( self.LSORadio, self.LSOCall.ROGERBALL, false, nil, 2, true ) -- Store data. - playerData.groove.XX=UTILS.DeepCopy(groovedata) + playerData.groove.XX = UTILS.DeepCopy( groovedata ) -- This is a valid approach and player did not miss any important steps in the pattern. - playerData.valid=true + playerData.valid = true -- Next step: in the middle. - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.GROOVE_IM) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.GROOVE_IM ) - elseif rho<=RIM and playerData.step==AIRBOSS.PatternStep.GROOVE_IM then + elseif rho <= RIM and playerData.step == AIRBOSS.PatternStep.GROOVE_IM then -- Store data. - playerData.groove.IM=UTILS.DeepCopy(groovedata) + playerData.groove.IM = UTILS.DeepCopy( groovedata ) -- Next step: in close. - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.GROOVE_IC) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.GROOVE_IC ) - elseif rho<=RIC and playerData.step==AIRBOSS.PatternStep.GROOVE_IC then + elseif rho <= RIC and playerData.step == AIRBOSS.PatternStep.GROOVE_IC then -- Store data. - playerData.groove.IC=UTILS.DeepCopy(groovedata) + playerData.groove.IC = UTILS.DeepCopy( groovedata ) -- Next step: AR at the ramp. - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.GROOVE_AR) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.GROOVE_AR ) - elseif rho<=RAR and playerData.step==AIRBOSS.PatternStep.GROOVE_AR then + elseif rho <= RAR and playerData.step == AIRBOSS.PatternStep.GROOVE_AR then -- Store data. - playerData.groove.AR=UTILS.DeepCopy(groovedata) + playerData.groove.AR = UTILS.DeepCopy( groovedata ) -- Next step: in the wires. - if playerData.actype==AIRBOSS.AircraftCarrier.AV8B then - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.GROOVE_AL) + if playerData.actype == AIRBOSS.AircraftCarrier.AV8B then + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.GROOVE_AL ) else - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.GROOVE_IW) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.GROOVE_IW ) end - elseif rho<=RAR and playerData.step==AIRBOSS.PatternStep.GROOVE_AL then + elseif rho <= RAR and playerData.step == AIRBOSS.PatternStep.GROOVE_AL then -- Store data. - playerData.groove.AL=UTILS.DeepCopy(groovedata) + playerData.groove.AL = UTILS.DeepCopy( groovedata ) -- Get zone abeam LDG spot. - local ZoneALS=self:_GetZoneAbeamLandingSpot() + local ZoneALS = self:_GetZoneAbeamLandingSpot() -- Get player velocity in km/h. - local vplayer=playerData.unit:GetVelocityKMH() + local vplayer = playerData.unit:GetVelocityKMH() -- Get carrier velocity in km/h. - local vcarrier=self.carrier:GetVelocityKMH() + local vcarrier = self.carrier:GetVelocityKMH() -- Speed difference. - local dv=math.abs(vplayer-vcarrier) + local dv = math.abs( vplayer - vcarrier ) - -- Stable when speed difference < 20 km/h. - local stable=dv<20 + + -- Stable when speed difference < 30 km/h.(16 Kts)Pene Testing + local stable=dv<30 -- Check if player is inside the zone. - if playerData.unit:IsInZone(ZoneALS) and stable then + if playerData.unit:IsInZone( ZoneALS ) and stable then -- Radio Transmission "Cleared to land" once the aircraft is inside the zone. - self:RadioTransmission(self.LSORadio, self.LSOCall.CLEAREDTOLAND, nil, nil, nil, true) + self:RadioTransmission( self.LSORadio, self.LSOCall.CLEAREDTOLAND, nil, nil, nil, true ) -- Next step: Level cross. - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.GROOVE_LC) - -- Set Stable Hover - playerData.stable=true - playerData.hover=true + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.GROOVE_LC ) + -- Set Stable Hover + playerData.stable = true + playerData.hover = true end - elseif rho<=RAR and playerData.step==AIRBOSS.PatternStep.GROOVE_LC then + elseif rho <= RAR and playerData.step == AIRBOSS.PatternStep.GROOVE_LC then -- Store data. - playerData.groove.LC=UTILS.DeepCopy(groovedata) + playerData.groove.LC = UTILS.DeepCopy( groovedata ) -- Get zone primary LDG spot. - local ZoneLS=self:_GetZoneLandingSpot() + local ZoneLS = self:_GetZoneLandingSpot() -- Get player velocity in km/h. - local vplayer=playerData.unit:GetVelocityKMH() + local vplayer = playerData.unit:GetVelocityKMH() -- Get carrier velocity in km/h. - local vcarrier=self.carrier:GetVelocityKMH() + local vcarrier = self.carrier:GetVelocityKMH() -- Speed difference. - local dv=math.abs(vplayer-vcarrier) + local dv = math.abs( vplayer - vcarrier ) - -- Stable when v<10 km/h. - local stable=dv<10 + -- Stable when v<15 km/h. + local stable=dv<15 -- Radio Transmission "Stabilized" once the aircraft has been cleared to cross and is over the Landing Spot and stable. - if playerData.unit:IsInZone(ZoneLS) and stable and playerData.stable==true then - self:RadioTransmission(self.LSORadio, self.LSOCall.STABILIZED, nil, nil, nil, false) - playerData.stable=false - playerData.warning=true + if playerData.unit:IsInZone( ZoneLS ) and stable and playerData.stable == true then + self:RadioTransmission( self.LSORadio, self.LSOCall.STABILIZED, nil, nil, nil, false ) + playerData.stable = false + playerData.warning = true end -- We keep it in this step until landed. @@ -10304,127 +9640,128 @@ function AIRBOSS:_Groove(playerData) -------------- -- Between IC and AR check for wave off. - if rho>=RAR and rho<=RIC and not playerData.waveoff then + if rho >= RAR and rho <= RIC and not playerData.waveoff then -- Check if player should wave off. - local waveoff=self:_CheckWaveOff(glideslopeError, lineupError, AoA, playerData) + local waveoff = self:_CheckWaveOff( glideslopeError, lineupError, AoA, playerData ) -- Let's see.. if waveoff then -- Debug info. - self:T3(self.lid..string.format("Waveoff distance rho=%.1f m", rho)) + self:T3( self.lid .. string.format( "Waveoff distance rho=%.1f m", rho ) ) -- LSO Wave off! - self:RadioTransmission(self.LSORadio, self.LSOCall.WAVEOFF, nil, nil, nil, true) - playerData.Tlso=timer.getTime() + self:RadioTransmission( self.LSORadio, self.LSOCall.WAVEOFF, nil, nil, nil, true ) + playerData.Tlso = timer.getTime() -- Player was waved off! - playerData.waveoff=true + playerData.waveoff = true -- Nothing else necessary. return end + end - - -- Long V/STOL groove time Wave Off over 75 seconds to IC - TOPGUN level Only. --pene testing (WIP) - + + -- Long V/STOL groove time Wave Off over 75 seconds to IC - TOPGUN level Only. --pene testing (WIP)--- Need to think more about this. + --if rho>=RAR and rho<=RIC and not playerData.waveoff and playerData.difficulty==AIRBOSS.Difficulty.HARD and playerData.actype== AIRBOSS.AircraftCarrier.AV8B then -- Get groove time --local vSlow=groovedata.time -- If too slow wave off. --if vSlow >75 then - + -- LSO Wave off! --self:RadioTransmission(self.LSORadio, self.LSOCall.WAVEOFF, nil, nil, nil, true) --playerData.Tlso=timer.getTime() - + -- Player was waved Off --playerData.waveoff=true --return - --end + --end --end -- Groovedata step. - groovedata.Step=playerData.step + groovedata.Step = playerData.step ----------------- -- Groove Data -- ----------------- -- Check if we are beween 3/4 NM and end of ship. - if rho>=RAR and rho= RAR and rho < RX0 and playerData.waveoff == false then -- Get groove step short hand of the previous step. - local gs=self:_GS(playerData.step, -1) + local gs = self:_GS( playerData.step, -1 ) -- Get current groove data. - local gd=playerData.groove[gs] --#AIRBOSS.GrooveData + local gd = playerData.groove[gs] -- #AIRBOSS.GrooveData if gd then - self:T3(gd) + self:T3( gd ) -- Distance in NM. - local d=UTILS.MetersToNM(rho) + local d = UTILS.MetersToNM( rho ) - -- Drift on lineup. - if rho>=RAR and rho<=RIM then - if gd.LUE>0.22 and lineupError<-0.22 then - env.info" Drift Right across centre ==> DR-" - gd.Drift=" DR" - self:T(self.lid..string.format("Got Drift Right across centre step %s, d=%.3f: Max LUE=%.3f, lower LUE=%.3f", gs, d, gd.LUE, lineupError)) - elseif gd.LUE<-0.22 and lineupError>0.22 then - env.info" Drift Left ==> DL-" - gd.Drift=" DL" - self:T(self.lid..string.format("Got Drift Left across centre at step %s, d=%.3f: Min LUE=%.3f, lower LUE=%.3f", gs, d, gd.LUE, lineupError)) - elseif gd.LUE>0.13 and lineupError<-0.14 then - env.info" Little Drift Right across centre ==> (DR-)" - gd.Drift=" (DR)" - self:T(self.lid..string.format("Got Little Drift Right across centre at step %s, d=%.3f: Max LUE=%.3f, lower LUE=%.3f", gs, d, gd.LUE, lineupError)) - elseif gd.LUE<-0.13 and lineupError>0.14 then - env.info" Little Drift Left across centre ==> (DL-)" - gd.Drift=" (DL)" - self:E(self.lid..string.format("Got Little Drift Left across centre at step %s, d=%.3f: Min LUE=%.3f, lower LUE=%.3f", gs, d, gd.LUE, lineupError)) - end + -- Drift on lineup. + if rho >= RAR and rho <= RIM then + if gd.LUE > 0.22 and lineupError < -0.22 then + env.info " Drift Right across centre ==> DR-" + gd.Drift = " DR" + self:T( self.lid .. string.format( "Got Drift Right across centre step %s, d=%.3f: Max LUE=%.3f, lower LUE=%.3f", gs, d, gd.LUE, lineupError ) ) + elseif gd.LUE < -0.22 and lineupError > 0.22 then + env.info " Drift Left ==> DL-" + gd.Drift = " DL" + self:T( self.lid .. string.format( "Got Drift Left across centre at step %s, d=%.3f: Min LUE=%.3f, lower LUE=%.3f", gs, d, gd.LUE, lineupError ) ) + elseif gd.LUE > 0.13 and lineupError < -0.14 then + env.info " Little Drift Right across centre ==> (DR-)" + gd.Drift = " (DR)" + self:T( self.lid .. string.format( "Got Little Drift Right across centre at step %s, d=%.3f: Max LUE=%.3f, lower LUE=%.3f", gs, d, gd.LUE, lineupError ) ) + elseif gd.LUE < -0.13 and lineupError > 0.14 then + env.info " Little Drift Left across centre ==> (DL-)" + gd.Drift = " (DL)" + self:E( self.lid .. string.format( "Got Little Drift Left across centre at step %s, d=%.3f: Min LUE=%.3f, lower LUE=%.3f", gs, d, gd.LUE, lineupError ) ) + end end -- Update max deviation of line up error. - if math.abs(lineupError)>math.abs(gd.LUE) then - self:T(self.lid..string.format("Got bigger LUE at step %s, d=%.3f: LUE %.3f>%.3f", gs, d, lineupError, gd.LUE)) - gd.LUE=lineupError + if math.abs( lineupError ) > math.abs( gd.LUE ) then + self:T( self.lid .. string.format( "Got bigger LUE at step %s, d=%.3f: LUE %.3f>%.3f", gs, d, lineupError, gd.LUE ) ) + gd.LUE = lineupError end -- Fly through good window of glideslope. - if gd.GSE>0.4 and glideslopeError<-0.3 then + if gd.GSE > 0.4 and glideslopeError < -0.3 then -- Fly through down ==> "\" - gd.FlyThrough="\\" - self:T(self.lid..string.format("Got Fly through DOWN at step %s, d=%.3f: Max GSE=%.3f, lower GSE=%.3f", gs, d, gd.GSE, glideslopeError)) - elseif gd.GSE<-0.3 and glideslopeError>0.4 then + gd.FlyThrough = "\\" + self:T( self.lid .. string.format( "Got Fly through DOWN at step %s, d=%.3f: Max GSE=%.3f, lower GSE=%.3f", gs, d, gd.GSE, glideslopeError ) ) + elseif gd.GSE < -0.3 and glideslopeError > 0.4 then -- Fly through up ==> "/" - gd.FlyThrough="/" - self:E(self.lid..string.format("Got Fly through UP at step %s, d=%.3f: Min GSE=%.3f, lower GSE=%.3f", gs, d, gd.GSE, glideslopeError)) + gd.FlyThrough = "/" + self:E( self.lid .. string.format( "Got Fly through UP at step %s, d=%.3f: Min GSE=%.3f, lower GSE=%.3f", gs, d, gd.GSE, glideslopeError ) ) end -- Update max deviation of glideslope error. - if math.abs(glideslopeError)>math.abs(gd.GSE) then - self:T(self.lid..string.format("Got bigger GSE at step %s, d=%.3f: GSE |%.3f|>|%.3f|", gs, d, glideslopeError, gd.GSE)) - gd.GSE=glideslopeError + if math.abs( glideslopeError ) > math.abs( gd.GSE ) then + self:T( self.lid .. string.format( "Got bigger GSE at step %s, d=%.3f: GSE |%.3f|>|%.3f|", gs, d, glideslopeError, gd.GSE ) ) + gd.GSE = glideslopeError end -- Get aircraft AoA parameters. - local aircraftaoa=self:_GetAircraftAoA(playerData) + local aircraftaoa = self:_GetAircraftAoA( playerData ) -- On Speed AoA. - local aoaopt=aircraftaoa.OnSpeed + local aoaopt = aircraftaoa.OnSpeed -- Compare AoAs wrt on speed AoA and update max deviation. - if math.abs(AoA-aoaopt)>math.abs(gd.AoA-aoaopt) then - self:T(self.lid..string.format("Got bigger AoA error at step %s, d=%.3f: AoA %.3f>%.3f.", gs, d, AoA, gd.AoA)) - gd.AoA=AoA + if math.abs( AoA - aoaopt ) > math.abs( gd.AoA - aoaopt ) then + self:T( self.lid .. string.format( "Got bigger AoA error at step %s, d=%.3f: AoA %.3f>%.3f.", gs, d, AoA, gd.AoA ) ) + gd.AoA = AoA end - --local gs2=self:_GS(groovedata.Step, -1) - --env.info(string.format("groovestep %s %s d=%.3f NM: GSE=%.3f %.3f, LUE=%.3f %.3f, AoA=%.3f %.3f", gs, gs2, d, groovedata.GSE, gd.GSE, groovedata.LUE, gd.LUE, groovedata.AoA, gd.AoA)) + -- local gs2=self:_GS(groovedata.Step, -1) + -- env.info(string.format("groovestep %s %s d=%.3f NM: GSE=%.3f %.3f, LUE=%.3f %.3f, AoA=%.3f %.3f", gs, gs2, d, groovedata.GSE, gd.GSE, groovedata.LUE, gd.LUE, groovedata.AoA, gd.AoA)) end @@ -10433,17 +9770,17 @@ function AIRBOSS:_Groove(playerData) --------------- -- Time since last LSO call. - local deltaT=timer.getTime()-playerData.Tlso + local deltaT = timer.getTime() - playerData.Tlso -- Wait until player passed the 0.75 NM distance. - local _advice=true - if playerData.TIG0==nil and playerData.difficulty~=AIRBOSS.Difficulty.EASY then --rho>RXX - _advice=false + local _advice = true + if playerData.TIG0 == nil and playerData.difficulty ~= AIRBOSS.Difficulty.EASY then -- rho>RXX + _advice = false end -- LSO call if necessary. - if deltaT>=self.LSOdT and _advice then - self:_LSOadvice(playerData, glideslopeError, lineupError) + if deltaT >= self.LSOdT and _advice then + self:_LSOadvice( playerData, glideslopeError, lineupError ) end end @@ -10453,37 +9790,37 @@ function AIRBOSS:_Groove(playerData) ---------------------------------------------------------- -- Player infront of the carrier X>~77 m. - if X>self.carrierparam.totlength+self.carrierparam.sterndist then + if X > self.carrierparam.totlength + self.carrierparam.sterndist then if playerData.waveoff then if playerData.landed then -- This should not happen because landing event was triggered. - self:_AddToDebrief(playerData, "You were waved off but landed anyway. Airboss wants to talk to you!") + self:_AddToDebrief( playerData, "You were waved off but landed anyway. Airboss wants to talk to you!" ) else - self:_AddToDebrief(playerData, "You were waved off.") + self:_AddToDebrief( playerData, "You were waved off." ) end elseif playerData.boltered then -- This should not happen because landing event was triggered. - self:_AddToDebrief(playerData, "You boltered.") + self:_AddToDebrief( playerData, "You boltered." ) else -- This should not happen. - self:T("Player was not waved off but flew past the carrier without landing ==> Own wave off!") + self:T( "Player was not waved off but flew past the carrier without landing ==> Own wave off!" ) -- We count this as OWO. - self:_AddToDebrief(playerData, "Own waveoff.") + self:_AddToDebrief( playerData, "Own waveoff." ) -- Set Owo - playerData.owo=true + playerData.owo = true end - -- Next step: debrief. - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.DEBRIEF) + -- Next step: debrief. + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.DEBRIEF ) end @@ -10501,62 +9838,62 @@ end -- @param #number AoA Angle of attack of player aircraft. -- @param #AIRBOSS.PlayerData playerData Player data. -- @return #boolean If true, player should wave off! -function AIRBOSS:_CheckWaveOff(glideslopeError, lineupError, AoA, playerData) +function AIRBOSS:_CheckWaveOff( glideslopeError, lineupError, AoA, playerData ) -- Assume we're all good. - local waveoff=false + local waveoff = false -- Parameters - local glMax= 1.8 - local glMin=-1.2 - local luAbs= 3.0 + local glMax = 1.8 + local glMin = -1.2 + local luAbs = 3.0 -- For the harrier, we allow a bit more room. - if playerData.actype==AIRBOSS.AircraftCarrier.AV8B then - glMax= 2.6 - glMin=-2.0 - luAbs= 4.1 -- Testing Pene (WIP) needs feedback to tighten up tolerences. - + if playerData.actype == AIRBOSS.AircraftCarrier.AV8B then + glMax = 2.6 + glMin = -2.2 -- Testing, @Engines may be just dragging it in on Hermes, or the carrier parameters need adjusting. + luAbs = 4.1 -- Testing Pene. + end -- Too high or too low? - if glideslopeError>glMax then - local text=string.format("\n- Waveoff due to glideslope error %.2f > %.1f degrees!", glideslopeError, glMax) - self:T(self.lid..string.format("%s: %s", playerData.name, text)) - self:_AddToDebrief(playerData, text) - waveoff=true - elseif glideslopeError glMax then + local text = string.format( "\n- Waveoff due to glideslope error %.2f > %.1f degrees!", glideslopeError, glMax ) + self:T( self.lid .. string.format( "%s: %s", playerData.name, text ) ) + self:_AddToDebrief( playerData, text ) + waveoff = true + elseif glideslopeError < glMin then + local text = string.format( "\n- Waveoff due to glideslope error %.2f < %.1f degrees!", glideslopeError, glMin ) + self:T( self.lid .. string.format( "%s: %s", playerData.name, text ) ) + self:_AddToDebrief( playerData, text ) + waveoff = true end -- Too far from centerline? - if math.abs(lineupError)>luAbs then - local text=string.format("\n- Waveoff due to line up error |%.1f| > %.1f degrees!", lineupError, luAbs) - self:T(self.lid..string.format("%s: %s", playerData.name, text)) - self:_AddToDebrief(playerData, text) - waveoff=true + if math.abs( lineupError ) > luAbs then + local text = string.format( "\n- Waveoff due to line up error |%.1f| > %.1f degrees!", lineupError, luAbs ) + self:T( self.lid .. string.format( "%s: %s", playerData.name, text ) ) + self:_AddToDebrief( playerData, text ) + waveoff = true end -- Too slow or too fast? Only for pros. - - if playerData.difficulty==AIRBOSS.Difficulty.HARD and playerData.actype~=AIRBOSS.AircraftCarrier.AV8B then + + if playerData.difficulty == AIRBOSS.Difficulty.HARD and playerData.actype ~= AIRBOSS.AircraftCarrier.AV8B then -- Get aircraft specific AoA values. Not for AV-8B due to transition to Stable Hover. - local aoaac=self:_GetAircraftAoA(playerData) + local aoaac = self:_GetAircraftAoA( playerData ) -- Check too slow or too fast. - if AoAaoaac.SLOW then - local text=string.format("\n- Waveoff due to AoA %.1f > %.1f!", AoA, aoaac.SLOW) - self:T(self.lid..string.format("%s: %s", playerData.name, text)) - self:_AddToDebrief(playerData, text) - waveoff=true - + if AoA < aoaac.FAST then + local text = string.format( "\n- Waveoff due to AoA %.1f < %.1f!", AoA, aoaac.FAST ) + self:T( self.lid .. string.format( "%s: %s", playerData.name, text ) ) + self:_AddToDebrief( playerData, text ) + waveoff = true + elseif AoA > aoaac.SLOW then + local text = string.format( "\n- Waveoff due to AoA %.1f > %.1f!", AoA, aoaac.SLOW ) + self:T( self.lid .. string.format( "%s: %s", playerData.name, text ) ) + self:_AddToDebrief( playerData, text ) + waveoff = true + end end @@ -10567,107 +9904,104 @@ end -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data. -- @return boolean If true, we have a foul deck. -function AIRBOSS:_CheckFoulDeck(playerData) +function AIRBOSS:_CheckFoulDeck( playerData ) -- Assume no check necessary. - local check=false + local check = false -- CVN: Check at IM and IC. - if playerData.step==AIRBOSS.PatternStep.GROOVE_IM or - playerData.step==AIRBOSS.PatternStep.GROOVE_IC then - check=true + if playerData.step == AIRBOSS.PatternStep.GROOVE_IM or playerData.step == AIRBOSS.PatternStep.GROOVE_IC then + check = true end -- AV-8B check until - if playerData.actype==AIRBOSS.AircraftCarrier.AV8B then - if playerData.step==AIRBOSS.PatternStep.GROOVE_AR or - playerData.step==AIRBOSS.PatternStep.GROOVE_AL then - check=true + if playerData.actype == AIRBOSS.AircraftCarrier.AV8B then + if playerData.step == AIRBOSS.PatternStep.GROOVE_AR or playerData.step == AIRBOSS.PatternStep.GROOVE_AL then + check = true end end -- Check if player was already waved off. Should not be necessary as player step is set to debrief afterwards! - if playerData.wofd==true or check==false then + if playerData.wofd == true or check == false then -- Player was already waved off. return end -- Landing runway zone. - local runway=self:_GetZoneRunwayBox() + local runway = self:_GetZoneRunwayBox() -- For AB-8B we just check the primary landing spot. - if playerData.actype==AIRBOSS.AircraftCarrier.AV8B then - runway=self:_GetZoneLandingSpot() + if playerData.actype == AIRBOSS.AircraftCarrier.AV8B then + runway = self:_GetZoneLandingSpot() end -- Scan radius. - local R=250 + local R = 250 -- Debug info. - self:T(self.lid..string.format("Foul deck check: Scanning Carrier Runway Area. Radius=%.1f m.", R)) + self:T( self.lid .. string.format( "Foul deck check: Scanning Carrier Runway Area. Radius=%.1f m.", R ) ) -- Scan units in carrier zone. - local _,_,_,unitscan=self:GetCoordinate():ScanObjects(R, true, false, false) + local _, _, _, unitscan = self:GetCoordinate():ScanObjects( R, true, false, false ) -- Loop over all scanned units and check if they are on the runway. - local fouldeck=false - local foulunit=nil --Wrapper.Unit#UNIT - for _,_unit in pairs(unitscan) do - local unit=_unit --Wrapper.Unit#UNIT + local fouldeck = false + local foulunit = nil -- Wrapper.Unit#UNIT + for _, _unit in pairs( unitscan ) do + local unit = _unit -- Wrapper.Unit#UNIT -- Check if unit is in zone. - local inzone=unit:IsInZone(runway) + local inzone = unit:IsInZone( runway ) -- Check if aircraft and in air. - local isaircraft=unit:IsAir() - local isairborn =unit:InAir() + local isaircraft = unit:IsAir() + local isairborn = unit:InAir() if inzone and isaircraft and not isairborn then - local text=string.format("Unit %s on landing runway ==> Foul deck!", unit:GetName()) - self:T(self.lid..text) - MESSAGE:New(text, 10):ToAllIf(self.Debug) + local text = string.format( "Unit %s on landing runway ==> Foul deck!", unit:GetName() ) + self:T( self.lid .. text ) + MESSAGE:New( text, 10 ):ToAllIf( self.Debug ) if self.Debug then - runway:FlareZone(FLARECOLOR.Red, 30) + runway:FlareZone( FLARECOLOR.Red, 30 ) end - fouldeck=true - foulunit=unit + fouldeck = true + foulunit = unit end end - -- Add to debrief and if playerData and fouldeck then -- Debrief text. - local text=string.format("Foul deck waveoff due to aircraft %s!", foulunit:GetName()) - self:T(self.lid..string.format("%s: %s", playerData.name, text)) - self:_AddToDebrief(playerData, text) + local text = string.format( "Foul deck waveoff due to aircraft %s!", foulunit:GetName() ) + self:T( self.lid .. string.format( "%s: %s", playerData.name, text ) ) + self:_AddToDebrief( playerData, text ) -- Foul deck + wave off radio message. - self:RadioTransmission(self.LSORadio, self.LSOCall.FOULDECK, false, 1) - self:RadioTransmission(self.LSORadio, self.LSOCall.WAVEOFF, false, 1.2, nil, true) + self:RadioTransmission( self.LSORadio, self.LSOCall.FOULDECK, false, 1 ) + self:RadioTransmission( self.LSORadio, self.LSOCall.WAVEOFF, false, 1.2, nil, true ) -- Player hint for flight students. if playerData.showhints then - local text=string.format("overfly landing area and enter bolter pattern.") - self:MessageToPlayer(playerData, text, "LSO", nil, nil, false, 3) + local text = string.format( "overfly landing area and enter bolter pattern." ) + self:MessageToPlayer( playerData, text, "LSO", nil, nil, false, 3 ) end -- Set player parameters for foul deck. - playerData.wofd=true + playerData.wofd = true -- Debrief. - playerData.step=AIRBOSS.PatternStep.DEBRIEF - playerData.warning=nil + playerData.step = AIRBOSS.PatternStep.DEBRIEF + playerData.warning = nil -- Pass would be invalid if the player lands. - playerData.valid=false + playerData.valid = false -- Send a message to the player that blocks the runway. if foulunit then - local foulflight=self:_GetFlightFromGroupInQueue(foulunit:GetGroup(), self.flights) + local foulflight = self:_GetFlightFromGroupInQueue( foulunit:GetGroup(), self.flights ) if foulflight and not foulflight.ai then - self:MessageToPlayer(foulflight, "move your ass from my runway. NOW!", "AIRBOSS") + self:MessageToPlayer( foulflight, "move your ass from my runway. NOW!", "AIRBOSS" ) end end end @@ -10681,32 +10015,38 @@ end function AIRBOSS:_GetSternCoord() -- Heading of carrier (true). - local hdg=self.carrier:GetHeading() + local hdg = self.carrier:GetHeading() -- Final bearing (true). local FB=self:GetFinalBearing() + local case=self.case -- Stern coordinate (sterndist<0). Also translate 10 meters starboard wrt Final bearing. - self.sterncoord:UpdateFromCoordinate(self:GetCoordinate()) - --local stern=self:GetCoordinate() + self.sterncoord:UpdateFromCoordinate( self:GetCoordinate() ) + -- local stern=self:GetCoordinate() - -- Stern coordinate (sterndist<0). - if self.carriertype==AIRBOSS.CarrierType.TARAWA or self.carriertype==AIRBOSS.CarrierType.AMERICA or self.carriertype==AIRBOSS.CarrierType.JCARLOS or self.carriertype==AIRBOSS.CarrierType.CANBERRA then - -- Tarawa: Translate 8 meters port. + -- Stern coordinate (sterndist<0). --Pene testing Case III + if self.carriertype==AIRBOSS.CarrierType.HERMES or self.carriertype==AIRBOSS.CarrierType.TARAWA or self.carriertype==AIRBOSS.CarrierType.AMERICA or self.carriertype==AIRBOSS.CarrierType.JCARLOS or self.carriertype==AIRBOSS.CarrierType.CANBERRA then + if case==3 then + -- CASE III V/STOL translation Due over deck approach if needed. self.sterncoord:Translate(self.carrierparam.sterndist, hdg, true, true):Translate(8, FB-90, true, true) + elseif case==2 or case==1 then + -- V/Stol: Translate 8 meters port. + self.sterncoord:Translate(self.carrierparam.sterndist, hdg, true, true):Translate(8, FB-90, true, true) + end elseif self.carriertype==AIRBOSS.CarrierType.STENNIS then -- Stennis: translate 7 meters starboard wrt Final bearing. - self.sterncoord:Translate(self.carrierparam.sterndist, hdg, true, true):Translate(7, FB+90, true, true) - elseif self.carriertype==AIRBOSS.CarrierType.FORRESTAL then + self.sterncoord:Translate( self.carrierparam.sterndist, hdg, true, true ):Translate( 7, FB + 90, true, true ) + elseif self.carriertype == AIRBOSS.CarrierType.FORRESTAL then -- Forrestal - self.sterncoord:Translate(self.carrierparam.sterndist, hdg, true, true):Translate(7.5, FB+90, true, true) + self.sterncoord:Translate( self.carrierparam.sterndist, hdg, true, true ):Translate( 7.5, FB + 90, true, true ) else -- Nimitz SC: translate 8 meters starboard wrt Final bearing. - self.sterncoord:Translate(self.carrierparam.sterndist, hdg, true, true):Translate(9.5, FB+90, true, true) + self.sterncoord:Translate( self.carrierparam.sterndist, hdg, true, true ):Translate( 9.5, FB + 90, true, true ) end -- Set altitude. - self.sterncoord:SetAltitude(self.carrierparam.deckheight) + self.sterncoord:SetAltitude( self.carrierparam.deckheight ) return self.sterncoord end @@ -10716,73 +10056,74 @@ end -- @param Core.Point#COORDINATE Lcoord Landing position. -- @param #number dc Distance correction. Shift the landing coord back if dc>0 and forward if dc<0. -- @return #number Trapped wire (1-4) or 99 if no wire was trapped. -function AIRBOSS:_GetWire(Lcoord, dc) +function AIRBOSS:_GetWire( Lcoord, dc ) -- Final bearing (true). - local FB=self:GetFinalBearing() + local FB = self:GetFinalBearing() -- Stern coordinate (sterndist<0). Also translate 10 meters starboard wrt Final bearing. - local Scoord=self:_GetSternCoord() + local Scoord = self:_GetSternCoord() -- Distance to landing coord. - local Ldist=Lcoord:Get2DDistance(Scoord) + local Ldist = Lcoord:Get2DDistance( Scoord ) -- For human (not AI) the lading event is delayed unfortunately. Therefore, we need another correction factor. - dc= dc or 65 + dc = dc or 65 -- Corrected landing distance wrt to stern. Landing distance needs to be reduced due to delayed landing event for human players. - local d=Ldist-dc + local d = Ldist - dc -- Multiplayer wire correction. if self.mpWireCorrection then - d=d-self.mpWireCorrection + d = d - self.mpWireCorrection + end -- Shift wires from stern to their correct position. - local w1=self.carrierparam.wire1 - local w2=self.carrierparam.wire2 - local w3=self.carrierparam.wire3 - local w4=self.carrierparam.wire4 + local w1 = self.carrierparam.wire1 + local w2 = self.carrierparam.wire2 + local w3 = self.carrierparam.wire3 + local w4 = self.carrierparam.wire4 -- Which wire was caught? local wire - if d wire=%d (dc=%.1f)", Ldist, Ldist-dc, wire, dc)) + self:T( string.format( "GetWire: L=%.1f, L-dc=%.1f ==> wire=%d (dc=%.1f)", Ldist, Ldist - dc, wire, dc ) ) return wire end @@ -10798,61 +10139,61 @@ end --- Trapped? Check if in air or not after landing event. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data table. -function AIRBOSS:_Trapped(playerData) +function AIRBOSS:_Trapped( playerData ) - if playerData.unit:InAir()==false then + if playerData.unit:InAir() == false then -- Seems we have successfully landed. -- Lets see if we can get a good wire. - local unit=playerData.unit + local unit = playerData.unit -- Coordinate of player aircraft. - local coord=unit:GetCoordinate() + local coord = unit:GetCoordinate() -- Get velocity in km/h. We need to substrackt the carrier velocity. - local v=unit:GetVelocityKMH()-self.carrier:GetVelocityKMH() + local v = unit:GetVelocityKMH() - self.carrier:GetVelocityKMH() -- Stern coordinate. - local stern=self:_GetSternCoord() + local stern = self:_GetSternCoord() -- Distance to stern pos. - local s=stern:Get2DDistance(coord) + local s = stern:Get2DDistance( coord ) -- Get current wire (estimate). This now based on the position where the player comes to a standstill which should reflect the trapped wire better. - local dcorr=100 - if playerData.actype==AIRBOSS.AircraftCarrier.HORNET then - dcorr=100 - elseif playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then + local dcorr = 100 + if playerData.actype == AIRBOSS.AircraftCarrier.HORNET then + dcorr = 100 + elseif playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B then -- TODO: Check Tomcat. - dcorr=100 - elseif playerData.actype==AIRBOSS.AircraftCarrier.A4EC then + dcorr = 100 + elseif playerData.actype == AIRBOSS.AircraftCarrier.A4EC then -- A-4E gets slowed down much faster the the F/A-18C! - dcorr=56 - elseif playerData.actype==AIRBOSS.AircraftCarrier.T45C then - -- T-45 also gets slowed down much faster the the F/A-18C. - dcorr=56 + dcorr = 56 + elseif playerData.actype == AIRBOSS.AircraftCarrier.T45C then + -- T-45 also gets slowed down much faster the the F/A-18C. + dcorr = 56 end -- Get wire. - local wire=self:_GetWire(coord, dcorr) + local wire = self:_GetWire( coord, dcorr ) -- Debug. - local text=string.format("Player %s _Trapped: v=%.1f km/h, s-dcorr=%.1f m ==> wire=%d (dcorr=%d)", playerData.name, v, s-dcorr, wire, dcorr) - self:T(self.lid..text) + local text = string.format( "Player %s _Trapped: v=%.1f km/h, s-dcorr=%.1f m ==> wire=%d (dcorr=%d)", playerData.name, v, s - dcorr, wire, dcorr ) + self:T( self.lid .. text ) -- Call this function again until v < threshold. Player comes to a standstill ==> Get wire! - if v>5 then + if v > 5 then -- Check if we passed all wires. - if wire>4 and v>10 and not playerData.warning then + if wire > 4 and v > 10 and not playerData.warning then -- Looks like we missed the wires ==> Bolter! - self:RadioTransmission(self.LSORadio, self.LSOCall.BOLTER, nil, nil, nil, true) - playerData.warning=true + self:RadioTransmission( self.LSORadio, self.LSOCall.BOLTER, nil, nil, nil, true ) + playerData.warning = true end -- Call function again and check if converged or back in air. - --SCHEDULER:New(nil, self._Trapped, {self, playerData}, 0.1) - self:ScheduleOnce(0.1, self._Trapped, self, playerData) + -- SCHEDULER:New(nil, self._Trapped, {self, playerData}, 0.1) + self:ScheduleOnce( 0.1, self._Trapped, self, playerData ) return end @@ -10863,47 +10204,47 @@ function AIRBOSS:_Trapped(playerData) -- Put some smoke and a mark. if self.Debug then coord:SmokeBlue() - coord:MarkToAll(text) - stern:MarkToAll("Stern") + coord:MarkToAll( text ) + stern:MarkToAll( "Stern" ) end -- Set player wire. - playerData.wire=wire + playerData.wire = wire -- Message to player. - local text=string.format("Trapped %d-wire.", wire) - if wire==3 then - text=text.." Well done!" - elseif wire==2 then - text=text.." Not bad, maybe you even get the 3rd next time." - elseif wire==4 then - text=text.." That was scary. You can do better than this!" - elseif wire==1 then - text=text.." Try harder next time!" + local text = string.format( "Trapped %d-wire.", wire ) + if wire == 3 then + text = text .. " Well done!" + elseif wire == 2 then + text = text .. " Not bad, maybe you even get the 3rd next time." + elseif wire == 4 then + text = text .. " That was scary. You can do better than this!" + elseif wire == 1 then + text = text .. " Try harder next time!" end -- Message to player. - self:MessageToPlayer(playerData, text, "LSO", "") + self:MessageToPlayer( playerData, text, "LSO", "" ) -- Debrief. - local hint = string.format("Trapped %d-wire.", wire) - self:_AddToDebrief(playerData, hint, "Groove: IW") + local hint = string.format( "Trapped %d-wire.", wire ) + self:_AddToDebrief( playerData, hint, "Groove: IW" ) else - --Again in air ==> Boltered! - local text=string.format("Player %s boltered in trapped function.", playerData.name) - self:T(self.lid..text) - MESSAGE:New(text, 5, "DEBUG"):ToAllIf(self.debug) + -- Again in air ==> Boltered! + local text = string.format( "Player %s boltered in trapped function.", playerData.name ) + self:T( self.lid .. text ) + MESSAGE:New( text, 5, "DEBUG" ):ToAllIf( self.debug ) -- Bolter switch on. - playerData.boltered=true + playerData.boltered = true end -- Next step: debriefing. - playerData.step=AIRBOSS.PatternStep.DEBRIEF - playerData.warning=nil + playerData.step = AIRBOSS.PatternStep.DEBRIEF + playerData.warning = nil end ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -10914,53 +10255,53 @@ end -- @param #AIRBOSS self -- @param #number case Recovery Case. -- @return Core.Zone#ZONE_POLYGON_BASE Initial zone. -function AIRBOSS:_GetZoneInitial(case) +function AIRBOSS:_GetZoneInitial( case ) - self.zoneInitial=self.zoneInitial or ZONE_POLYGON_BASE:New("Zone CASE I/II Initial") + self.zoneInitial = self.zoneInitial or ZONE_POLYGON_BASE:New( "Zone CASE I/II Initial" ) -- Get radial, i.e. inverse of BRC. - local radial=self:GetRadial(2, false, false) + local radial = self:GetRadial( 2, false, false ) -- Carrier coordinate. - local cv=self:GetCoordinate() + local cv = self:GetCoordinate() -- Vec2 array. - local vec2={} + local vec2 = {} - if case==1 then + if case == 1 then -- Case I - local c1=cv:Translate(UTILS.NMToMeters(0.5), radial-90) -- 0.0 0.5 starboard - local c2=cv:Translate(UTILS.NMToMeters(1.3), radial-90):Translate(UTILS.NMToMeters(3), radial) -- -3.0 1.3 starboard, astern - local c3=cv:Translate(UTILS.NMToMeters(0.4), radial+90):Translate(UTILS.NMToMeters(3), radial) -- -3.0 -0.4 port, astern - local c4=cv:Translate(UTILS.NMToMeters(1.0), radial) - local c5=cv + local c1 = cv:Translate( UTILS.NMToMeters( 0.5 ), radial - 90 ) -- 0.0 0.5 starboard + local c2 = cv:Translate( UTILS.NMToMeters( 1.3 ), radial - 90 ):Translate( UTILS.NMToMeters( 3 ), radial ) -- -3.0 1.3 starboard, astern + local c3 = cv:Translate( UTILS.NMToMeters( 0.4 ), radial + 90 ):Translate( UTILS.NMToMeters( 3 ), radial ) -- -3.0 -0.4 port, astern + local c4 = cv:Translate( UTILS.NMToMeters( 1.0 ), radial ) + local c5 = cv -- Vec2 array. - vec2={c1:GetVec2(), c2:GetVec2(), c3:GetVec2(), c4:GetVec2(), c5:GetVec2()} + vec2 = { c1:GetVec2(), c2:GetVec2(), c3:GetVec2(), c4:GetVec2(), c5:GetVec2() } else -- Case II -- Funnel. - local c1=cv:Translate(UTILS.NMToMeters(0.5), radial-90) -- 0.0, 0.5 - local c2=c1:Translate(UTILS.NMToMeters(0.5), radial) -- 0.5, 0.5 - local c3=cv:Translate(UTILS.NMToMeters(1.2), radial-90):Translate(UTILS.NMToMeters(3), radial) -- 3.0, 1.2 - local c4=cv:Translate(UTILS.NMToMeters(1.2), radial+90):Translate(UTILS.NMToMeters(3), radial) -- 3.0,-1.2 - local c5=cv:Translate(UTILS.NMToMeters(0.5), radial) - local c6=cv + local c1 = cv:Translate( UTILS.NMToMeters( 0.5 ), radial - 90 ) -- 0.0, 0.5 + local c2 = c1:Translate( UTILS.NMToMeters( 0.5 ), radial ) -- 0.5, 0.5 + local c3 = cv:Translate( UTILS.NMToMeters( 1.2 ), radial - 90 ):Translate( UTILS.NMToMeters( 3 ), radial ) -- 3.0, 1.2 + local c4 = cv:Translate( UTILS.NMToMeters( 1.2 ), radial + 90 ):Translate( UTILS.NMToMeters( 3 ), radial ) -- 3.0,-1.2 + local c5 = cv:Translate( UTILS.NMToMeters( 0.5 ), radial ) + local c6 = cv -- Vec2 array. - vec2={c1:GetVec2(), c2:GetVec2(), c3:GetVec2(), c4:GetVec2(), c5:GetVec2(), c6:GetVec2()} + vec2 = { c1:GetVec2(), c2:GetVec2(), c3:GetVec2(), c4:GetVec2(), c5:GetVec2(), c6:GetVec2() } end -- Polygon zone. - --local zone=ZONE_POLYGON_BASE:New("Zone CASE I/II Initial", vec2) + -- local zone=ZONE_POLYGON_BASE:New("Zone CASE I/II Initial", vec2) - self.zoneInitial:UpdateFromVec2(vec2) + self.zoneInitial:UpdateFromVec2( vec2 ) - --return zone + -- return zone return self.zoneInitial end @@ -10969,70 +10310,69 @@ end -- @return Core.Zone#ZONE_POLYGON_BASE Lineup zone. function AIRBOSS:_GetZoneLineup() - self.zoneLineup=self.zoneLineup or ZONE_POLYGON_BASE:New("Zone Lineup") + self.zoneLineup = self.zoneLineup or ZONE_POLYGON_BASE:New( "Zone Lineup" ) -- Get radial, i.e. inverse of BRC. - local fbi=self:GetRadial(1, false, false) + local fbi = self:GetRadial( 1, false, false ) -- Stern coordinate. - local st=self:_GetOptLandingCoordinate() + local st = self:_GetOptLandingCoordinate() -- Zone points. - local c1=st - local c2=st:Translate(UTILS.NMToMeters(0.50), fbi+15) - local c3=st:Translate(UTILS.NMToMeters(0.50), fbi+self.lue._max-0.05) - local c4=st:Translate(UTILS.NMToMeters(0.77), fbi+self.lue._max-0.05) - local c5=c4:Translate(UTILS.NMToMeters(0.25), fbi-90) + local c1 = st + local c2 = st:Translate( UTILS.NMToMeters( 0.50 ), fbi + 15 ) + local c3 = st:Translate( UTILS.NMToMeters( 0.50 ), fbi + self.lue._max - 0.05 ) + local c4 = st:Translate( UTILS.NMToMeters( 0.77 ), fbi + self.lue._max - 0.05 ) + local c5 = c4:Translate( UTILS.NMToMeters( 0.25 ), fbi - 90 ) -- Vec2 array. - local vec2={c1:GetVec2(), c2:GetVec2(), c3:GetVec2(), c4:GetVec2(), c5:GetVec2()} + local vec2 = { c1:GetVec2(), c2:GetVec2(), c3:GetVec2(), c4:GetVec2(), c5:GetVec2() } - self.zoneLineup:UpdateFromVec2(vec2) + self.zoneLineup:UpdateFromVec2( vec2 ) -- Polygon zone. - --local zone=ZONE_POLYGON_BASE:New("Zone Lineup", vec2) - --return zone + -- local zone=ZONE_POLYGON_BASE:New("Zone Lineup", vec2) + -- return zone return self.zoneLineup end - --- Get groove zone. -- @param #AIRBOSS self -- @param #number l Length of the groove in NM. Default 1.5 NM. -- @param #number w Width of the groove in NM. Default 0.25 NM. -- @param #number b Width of the beginning in NM. Default 0.10 NM. -- @return Core.Zone#ZONE_POLYGON_BASE Groove zone. -function AIRBOSS:_GetZoneGroove(l, w, b) +function AIRBOSS:_GetZoneGroove( l, w, b ) - self.zoneGroove=self.zoneGroove or ZONE_POLYGON_BASE:New("Zone Groove") + self.zoneGroove = self.zoneGroove or ZONE_POLYGON_BASE:New( "Zone Groove" ) - l=l or 1.50 - w=w or 0.25 - b=b or 0.10 + l = l or 1.50 + w = w or 0.25 + b = b or 0.10 -- Get radial, i.e. inverse of BRC. - local fbi=self:GetRadial(1, false, false) + local fbi = self:GetRadial( 1, false, false ) -- Stern coordinate. - local st=self:_GetSternCoord() + local st = self:_GetSternCoord() -- Zone points. - local c1=st:Translate(self.carrierparam.totwidthstarboard, fbi-90) - local c2=st:Translate(UTILS.NMToMeters(0.10), fbi-90):Translate(UTILS.NMToMeters(0.3), fbi) - local c3=st:Translate(UTILS.NMToMeters(0.25), fbi-90):Translate(UTILS.NMToMeters(l), fbi) - local c4=st:Translate(UTILS.NMToMeters(w/2), fbi+90):Translate(UTILS.NMToMeters(l), fbi) - local c5=st:Translate(UTILS.NMToMeters(b), fbi+90):Translate(UTILS.NMToMeters(0.3), fbi) - local c6=st:Translate(self.carrierparam.totwidthport, fbi+90) + local c1 = st:Translate( self.carrierparam.totwidthstarboard, fbi - 90 ) + local c2 = st:Translate( UTILS.NMToMeters( 0.10 ), fbi - 90 ):Translate( UTILS.NMToMeters( 0.3 ), fbi ) + local c3 = st:Translate( UTILS.NMToMeters( 0.25 ), fbi - 90 ):Translate( UTILS.NMToMeters( l ), fbi ) + local c4 = st:Translate( UTILS.NMToMeters( w / 2 ), fbi + 90 ):Translate( UTILS.NMToMeters( l ), fbi ) + local c5 = st:Translate( UTILS.NMToMeters( b ), fbi + 90 ):Translate( UTILS.NMToMeters( 0.3 ), fbi ) + local c6 = st:Translate( self.carrierparam.totwidthport, fbi + 90 ) -- Vec2 array. - local vec2={c1:GetVec2(), c2:GetVec2(), c3:GetVec2(), c4:GetVec2(), c5:GetVec2(), c6:GetVec2()} + local vec2 = { c1:GetVec2(), c2:GetVec2(), c3:GetVec2(), c4:GetVec2(), c5:GetVec2(), c6:GetVec2() } - self.zoneGroove:UpdateFromVec2(vec2) + self.zoneGroove:UpdateFromVec2( vec2 ) -- Polygon zone. - --local zone=ZONE_POLYGON_BASE:New("Zone Groove", vec2) - --return zone + -- local zone=ZONE_POLYGON_BASE:New("Zone Groove", vec2) + -- return zone return self.zoneGroove end @@ -11041,49 +10381,49 @@ end -- @param #AIRBOSS self -- @param #number case Recovery case. -- @return Core.Zone#ZONE_RADIUS Arc in zone. -function AIRBOSS:_GetZoneBullseye(case) +function AIRBOSS:_GetZoneBullseye( case ) -- Radius = 1 NM. - local radius=UTILS.NMToMeters(1) + local radius = UTILS.NMToMeters( 1 ) -- Distance = 3 NM - local distance=UTILS.NMToMeters(3) + local distance = UTILS.NMToMeters( 3 ) -- Zone depends on Case recovery. - local radial=self:GetRadial(case, false, false) + local radial = self:GetRadial( case, false, false ) -- Get coordinate and vec2. - local coord=self:GetCoordinate():Translate(distance, radial) - local vec2=coord:GetVec2() + local coord = self:GetCoordinate():Translate( distance, radial ) + local vec2 = coord:GetVec2() -- Create zone. - local zone=ZONE_RADIUS:New("Zone Bullseye", vec2, radius) + local zone = ZONE_RADIUS:New( "Zone Bullseye", vec2, radius ) return zone - --self.zoneBullseye=self.zoneBullseye or ZONE_RADIUS:New("Zone Bullseye", vec2, radius) + -- self.zoneBullseye=self.zoneBullseye or ZONE_RADIUS:New("Zone Bullseye", vec2, radius) end --- Get dirty up zone with radius 1 NM and DME 9 NM from the carrier. Radial depends on recovery case. -- @param #AIRBOSS self -- @param #number case Recovery case. -- @return Core.Zone#ZONE_RADIUS Dirty up zone. -function AIRBOSS:_GetZoneDirtyUp(case) +function AIRBOSS:_GetZoneDirtyUp( case ) -- Radius = 1 NM. - local radius=UTILS.NMToMeters(1) + local radius = UTILS.NMToMeters( 1 ) -- Distance = 9 NM - local distance=UTILS.NMToMeters(9) + local distance = UTILS.NMToMeters( 9 ) -- Zone depends on Case recovery. - local radial=self:GetRadial(case, false, false) + local radial = self:GetRadial( case, false, false ) -- Get coordinate and vec2. - local coord=self:GetCoordinate():Translate(distance, radial) - local vec2=coord:GetVec2() + local coord = self:GetCoordinate():Translate( distance, radial ) + local vec2 = coord:GetVec2() -- Create zone. - local zone=ZONE_RADIUS:New("Zone Dirty Up", vec2, radius) + local zone = ZONE_RADIUS:New( "Zone Dirty Up", vec2, radius ) return zone end @@ -11092,22 +10432,22 @@ end -- @param #AIRBOSS self -- @param #number case Recovery case. -- @return Core.Zone#ZONE_RADIUS Arc in zone. -function AIRBOSS:_GetZoneArcOut(case) +function AIRBOSS:_GetZoneArcOut( case ) -- Radius = 1.25 NM. - local radius=UTILS.NMToMeters(1.25) + local radius = UTILS.NMToMeters( 1.25 ) -- Distance = 12 NM - local distance=UTILS.NMToMeters(11.75) + local distance = UTILS.NMToMeters( 11.75 ) -- Zone depends on Case recovery. - local radial=self:GetRadial(case, false, false) + local radial = self:GetRadial( case, false, false ) -- Get coordinate of carrier and translate. - local coord=self:GetCoordinate():Translate(distance, radial) + local coord = self:GetCoordinate():Translate( distance, radial ) -- Create zone. - local zone=ZONE_RADIUS:New("Zone Arc Out", coord:GetVec2(), radius) + local zone = ZONE_RADIUS:New( "Zone Arc Out", coord:GetVec2(), radius ) return zone end @@ -11116,28 +10456,28 @@ end -- @param #AIRBOSS self -- @param #number case Recovery case. -- @return Core.Zone#ZONE_RADIUS Arc in zone. -function AIRBOSS:_GetZoneArcIn(case) +function AIRBOSS:_GetZoneArcIn( case ) -- Radius = 1.25 NM. - local radius=UTILS.NMToMeters(1.25) + local radius = UTILS.NMToMeters( 1.25 ) -- Zone depends on Case recovery. - local radial=self:GetRadial(case, false, true) + local radial = self:GetRadial( case, false, true ) -- Angle between FB/BRC and holding zone. - local alpha=math.rad(self.holdingoffset) + local alpha = math.rad( self.holdingoffset ) -- 14+x NM from carrier - local x=14 --/math.cos(alpha) + local x = 14 -- /math.cos(alpha) -- Distance = 14 NM - local distance=UTILS.NMToMeters(x) + local distance = UTILS.NMToMeters( x ) -- Get coordinate. - local coord=self:GetCoordinate():Translate(distance, radial) + local coord = self:GetCoordinate():Translate( distance, radial ) -- Create zone. - local zone=ZONE_RADIUS:New("Zone Arc In", coord:GetVec2(), radius) + local zone = ZONE_RADIUS:New( "Zone Arc In", coord:GetVec2(), radius ) return zone end @@ -11146,79 +10486,78 @@ end -- @param #AIRBOSS self -- @param #number case Recovery case. -- @return Core.Zone#ZONE_RADIUS Circular platform zone. -function AIRBOSS:_GetZonePlatform(case) +function AIRBOSS:_GetZonePlatform( case ) -- Radius = 1 NM. - local radius=UTILS.NMToMeters(1) + local radius = UTILS.NMToMeters( 1 ) -- Zone depends on Case recovery. - local radial=self:GetRadial(case, false, true) + local radial = self:GetRadial( case, false, true ) -- Angle between FB/BRC and holding zone. - local alpha=math.rad(self.holdingoffset) + local alpha = math.rad( self.holdingoffset ) -- Distance = 19 NM - local distance=UTILS.NMToMeters(19) --/math.cos(alpha) + local distance = UTILS.NMToMeters( 19 ) -- /math.cos(alpha) -- Get coordinate. - local coord=self:GetCoordinate():Translate(distance, radial) + local coord = self:GetCoordinate():Translate( distance, radial ) -- Create zone. - local zone=ZONE_RADIUS:New("Zone Platform", coord:GetVec2(), radius) + local zone = ZONE_RADIUS:New( "Zone Platform", coord:GetVec2(), radius ) return zone end - --- Get approach corridor zone. Shape depends on recovery case. -- @param #AIRBOSS self -- @param #number case Recovery case. -- @param #number l Length of the zone in NM. Default 31 (=21+10) NM. -- @return Core.Zone#ZONE_POLYGON_BASE Box zone. -function AIRBOSS:_GetZoneCorridor(case, l) +function AIRBOSS:_GetZoneCorridor( case, l ) -- Total length. - l=l or 31 + l = l or 31 -- Radial and offset. - local radial=self:GetRadial(case, false, false) - local offset=self:GetRadial(case, false, true) + local radial = self:GetRadial( case, false, false ) + local offset = self:GetRadial( case, false, true ) -- Distance shift ahead of carrier to allow for some space to bolter. - local dx=5 + local dx = 5 -- Width of the box in NM. - local w=2 - local w2=w/2 + local w = 2 + local w2 = w / 2 -- Distance from carrier to arc out zone. - local d=12 + local d = 12 -- Carrier position. - local cv=self:GetCoordinate() + local cv = self:GetCoordinate() -- Polygon points. - local c={} + local c = {} -- First point. Carrier coordinate translated 5 NM in direction of travel to allow for bolter space. - c[1]=cv:Translate(-UTILS.NMToMeters(dx), radial) + c[1] = cv:Translate( -UTILS.NMToMeters( dx ), radial ) - if math.abs(self.holdingoffset)>=5 then + if math.abs( self.holdingoffset ) >= 5 then ----------------- -- Angled Case -- ----------------- - c[2]=c[1]:Translate( UTILS.NMToMeters(w2), radial-90) -- 1 Right of carrier, dx ahead. - c[3]=c[2]:Translate( UTILS.NMToMeters(d+dx+w2), radial) -- 13 "south" @ 1 right + c[2] = c[1]:Translate( UTILS.NMToMeters( w2 ), radial - 90 ) -- 1 Right of carrier, dx ahead. + c[3] = c[2]:Translate( UTILS.NMToMeters( d + dx + w2 ), radial ) -- 13 "south" @ 1 right - c[4]=cv:Translate(UTILS.NMToMeters(15), offset):Translate(UTILS.NMToMeters(1), offset-90) - c[5]=cv:Translate(UTILS.NMToMeters(l), offset):Translate(UTILS.NMToMeters(1), offset-90) - c[6]=cv:Translate(UTILS.NMToMeters(l), offset):Translate(UTILS.NMToMeters(1), offset+90) - c[7]=cv:Translate(UTILS.NMToMeters(13), offset):Translate(UTILS.NMToMeters(1), offset+90) - c[8]=cv:Translate(UTILS.NMToMeters(11), radial):Translate(UTILS.NMToMeters(1), radial+90) + c[4] = cv:Translate( UTILS.NMToMeters( 15 ), offset ):Translate( UTILS.NMToMeters( 1 ), offset - 90 ) + c[5] = cv:Translate( UTILS.NMToMeters( l ), offset ):Translate( UTILS.NMToMeters( 1 ), offset - 90 ) + c[6] = cv:Translate( UTILS.NMToMeters( l ), offset ):Translate( UTILS.NMToMeters( 1 ), offset + 90 ) + c[7] = cv:Translate( UTILS.NMToMeters( 13 ), offset ):Translate( UTILS.NMToMeters( 1 ), offset + 90 ) + c[8] = cv:Translate( UTILS.NMToMeters( 11 ), radial ):Translate( UTILS.NMToMeters( 1 ), radial + 90 ) - c[9]=c[1]:Translate(UTILS.NMToMeters(w2), radial+90) + c[9] = c[1]:Translate( UTILS.NMToMeters( w2 ), radial + 90 ) else @@ -11226,70 +10565,68 @@ function AIRBOSS:_GetZoneCorridor(case, l) -- Easy case of a long box -- ----------------------------- - c[2]=c[1]:Translate( UTILS.NMToMeters(w2), radial-90) - c[3]=c[2]:Translate( UTILS.NMToMeters(dx+l), radial) -- Stack 1 starts at 21 and is 7 NM. - c[4]=c[3]:Translate( UTILS.NMToMeters(w), radial+90) - c[5]=c[1]:Translate( UTILS.NMToMeters(w2), radial+90) + c[2] = c[1]:Translate( UTILS.NMToMeters( w2 ), radial - 90 ) + c[3] = c[2]:Translate( UTILS.NMToMeters( dx + l ), radial ) -- Stack 1 starts at 21 and is 7 NM. + c[4] = c[3]:Translate( UTILS.NMToMeters( w ), radial + 90 ) + c[5] = c[1]:Translate( UTILS.NMToMeters( w2 ), radial + 90 ) end - -- Create an array of a square! - local p={} - for _i,_c in ipairs(c) do + local p = {} + for _i, _c in ipairs( c ) do if self.Debug then - --_c:SmokeBlue() + -- _c:SmokeBlue() end - p[_i]=_c:GetVec2() + p[_i] = _c:GetVec2() end -- Square zone length=10NM width=6 NM behind the carrier starting at angels+15 NM behind the carrier. -- So stay 0-5 NM (+1 NM error margin) port of carrier. - local zone=ZONE_POLYGON_BASE:New("CASE II/III Approach Corridor", p) + local zone = ZONE_POLYGON_BASE:New( "CASE II/III Approach Corridor", p ) return zone end - --- Get zone of carrier. Carrier is approximated as rectangle. -- @param #AIRBOSS self -- @return Core.Zone#ZONE Zone surrounding the carrier. function AIRBOSS:_GetZoneCarrierBox() - self.zoneCarrierbox=self.zoneCarrierbox or ZONE_POLYGON_BASE:New("Carrier Box Zone") + self.zoneCarrierbox = self.zoneCarrierbox or ZONE_POLYGON_BASE:New( "Carrier Box Zone" ) -- Stern coordinate. - local S=self:_GetSternCoord() + local S = self:_GetSternCoord() -- Current carrier heading. - local hdg=self:GetHeading(false) + local hdg = self:GetHeading( false ) -- Coordinate array. - local p={} + local p = {} -- Starboard stern point. - p[1]=S:Translate(self.carrierparam.totwidthstarboard, hdg+90) + p[1] = S:Translate( self.carrierparam.totwidthstarboard, hdg + 90 ) -- Starboard bow point. - p[2]=p[1]:Translate(self.carrierparam.totlength, hdg) + p[2] = p[1]:Translate( self.carrierparam.totlength, hdg ) -- Port bow point. - p[3]=p[2]:Translate(self.carrierparam.totwidthstarboard+self.carrierparam.totwidthport, hdg-90) + p[3] = p[2]:Translate( self.carrierparam.totwidthstarboard + self.carrierparam.totwidthport, hdg - 90 ) -- Port stern point. - p[4]=p[3]:Translate(self.carrierparam.totlength, hdg-180) + p[4] = p[3]:Translate( self.carrierparam.totlength, hdg - 180 ) -- Convert to vec2. - local vec2={} - for _,coord in ipairs(p) do - table.insert(vec2, coord:GetVec2()) + local vec2 = {} + for _, coord in ipairs( p ) do + table.insert( vec2, coord:GetVec2() ) end -- Create polygon zone. - --local zone=ZONE_POLYGON_BASE:New("Carrier Box Zone", vec2) - --return zone + -- local zone=ZONE_POLYGON_BASE:New("Carrier Box Zone", vec2) + -- return zone - self.zoneCarrierbox:UpdateFromVec2(vec2) + self.zoneCarrierbox:UpdateFromVec2( vec2 ) return self.zoneCarrierbox end @@ -11299,168 +10636,165 @@ end -- @return Core.Zone#ZONE_POLYGON Zone surrounding landing runway. function AIRBOSS:_GetZoneRunwayBox() - self.zoneRunwaybox=self.zoneRunwaybox or ZONE_POLYGON_BASE:New("Landing Runway Zone") + self.zoneRunwaybox = self.zoneRunwaybox or ZONE_POLYGON_BASE:New( "Landing Runway Zone" ) -- Stern coordinate. - local S=self:_GetSternCoord() + local S = self:_GetSternCoord() -- Current carrier heading. - local FB=self:GetFinalBearing(false) + local FB = self:GetFinalBearing( false ) -- Coordinate array. - local p={} + local p = {} -- Points. - p[1]=S:Translate(self.carrierparam.rwywidth*0.5, FB+90) - p[2]=p[1]:Translate(self.carrierparam.rwylength, FB) - p[3]=p[2]:Translate(self.carrierparam.rwywidth, FB-90) - p[4]=p[3]:Translate(self.carrierparam.rwylength, FB-180) + p[1] = S:Translate( self.carrierparam.rwywidth * 0.5, FB + 90 ) + p[2] = p[1]:Translate( self.carrierparam.rwylength, FB ) + p[3] = p[2]:Translate( self.carrierparam.rwywidth, FB - 90 ) + p[4] = p[3]:Translate( self.carrierparam.rwylength, FB - 180 ) -- Convert to vec2. - local vec2={} - for _,coord in ipairs(p) do - table.insert(vec2, coord:GetVec2()) + local vec2 = {} + for _, coord in ipairs( p ) do + table.insert( vec2, coord:GetVec2() ) end -- Create polygon zone. - --local zone=ZONE_POLYGON_BASE:New("Landing Runway Zone", vec2) - --return zone + -- local zone=ZONE_POLYGON_BASE:New("Landing Runway Zone", vec2) + -- return zone - self.zoneRunwaybox:UpdateFromVec2(vec2) + self.zoneRunwaybox:UpdateFromVec2( vec2 ) return self.zoneRunwaybox end +--- Get zone of primary abeam landing position of HMS Hermes, USS Tarawa, USS America and Juan Carlos. Box length 50 meters and width 30 meters. ---- Get zone of primary abeam landing position of USS Tarawa, USS America and Juan Carlos. Box length 50 meters and width 30 meters. --- Allow for Clear to land call from LSO approaching abeam the landing spot if stable as per NATOPS 00-80T -- @param #AIRBOSS self -- @return Core.Zone#ZONE_POLYGON Zone surrounding landing runway. function AIRBOSS:_GetZoneAbeamLandingSpot() -- Primary landing Spot coordinate. - local S=self:_GetOptLandingCoordinate() + local S = self:_GetOptLandingCoordinate() -- Current carrier heading. - local FB=self:GetFinalBearing(false) + local FB = self:GetFinalBearing( false ) - -- Coordinate array. + -- Coordinate array. Pene Testing extended Abeam landing spot V/STOL. local p={} - + -- Points. - p[1]=S:Translate( 15, FB):Translate(15, FB+90) -- Top-Right - p[2]=S:Translate(-45, FB):Translate(15, FB+90) -- Bottom-Right - p[3]=S:Translate(-45, FB):Translate(15, FB-90) -- Bottom-Left - p[4]=S:Translate( 15, FB):Translate(15, FB-90) -- Top-Left + p[1] = S:Translate( 15, FB ):Translate( 15, FB + 90 ) -- Top-Right + p[2] = S:Translate( -45, FB ):Translate( 15, FB + 90 ) -- Bottom-Right + p[3] = S:Translate( -45, FB ):Translate( 15, FB - 90 ) -- Bottom-Left + p[4] = S:Translate( 15, FB ):Translate( 15, FB - 90 ) -- Top-Left -- Convert to vec2. - local vec2={} - for _,coord in ipairs(p) do - table.insert(vec2, coord:GetVec2()) + local vec2 = {} + for _, coord in ipairs( p ) do + table.insert( vec2, coord:GetVec2() ) end -- Create polygon zone. - local zone=ZONE_POLYGON_BASE:New("Abeam Landing Spot Zone", vec2) + local zone = ZONE_POLYGON_BASE:New( "Abeam Landing Spot Zone", vec2 ) return zone end - --- Get zone of the primary landing spot of the USS Tarawa. -- @param #AIRBOSS self -- @return Core.Zone#ZONE_POLYGON Zone surrounding landing runway. function AIRBOSS:_GetZoneLandingSpot() -- Primary landing Spot coordinate. - local S=self:_GetLandingSpotCoordinate() + local S = self:_GetLandingSpotCoordinate() -- Current carrier heading. - local FB=self:GetFinalBearing(false) + local FB = self:GetFinalBearing( false ) -- Coordinate array. - local p={} + local p = {} -- Points. - p[1]=S:Translate( 10, FB):Translate(10, FB+90) -- Top-Right - p[2]=S:Translate(-10, FB):Translate(10, FB+90) -- Bottom-Right - p[3]=S:Translate(-10, FB):Translate(10, FB-90) -- Bottom-Left - p[4]=S:Translate( 10, FB):Translate(10, FB-90) -- Top-left + p[1] = S:Translate( 10, FB ):Translate( 10, FB + 90 ) -- Top-Right + p[2] = S:Translate( -10, FB ):Translate( 10, FB + 90 ) -- Bottom-Right + p[3] = S:Translate( -10, FB ):Translate( 10, FB - 90 ) -- Bottom-Left + p[4] = S:Translate( 10, FB ):Translate( 10, FB - 90 ) -- Top-left -- Convert to vec2. - local vec2={} - for _,coord in ipairs(p) do - table.insert(vec2, coord:GetVec2()) + local vec2 = {} + for _, coord in ipairs( p ) do + table.insert( vec2, coord:GetVec2() ) end -- Create polygon zone. - local zone=ZONE_POLYGON_BASE:New("Landing Spot Zone", vec2) + local zone = ZONE_POLYGON_BASE:New( "Landing Spot Zone", vec2 ) return zone end - --- Get holding zone of player. -- @param #AIRBOSS self -- @param #number case Recovery case. -- @param #number stack Marshal stack number. -- @return Core.Zone#ZONE Holding zone. -function AIRBOSS:_GetZoneHolding(case, stack) +function AIRBOSS:_GetZoneHolding( case, stack ) -- Holding zone. - local zoneHolding=nil --Core.Zone#ZONE + local zoneHolding = nil -- Core.Zone#ZONE -- Stack is <= 0 ==> no marshal zone. - if stack<=0 then - self:E(self.lid.."ERROR: Stack <= 0 in _GetZoneHolding!") - self:E({case=case, stack=stack}) + if stack <= 0 then + self:E( self.lid .. "ERROR: Stack <= 0 in _GetZoneHolding!" ) + self:E( { case = case, stack = stack } ) return nil end -- Pattern altitude. - local patternalt, c1, c2=self:_GetMarshalAltitude(stack, case) + local patternalt, c1, c2 = self:_GetMarshalAltitude( stack, case ) -- Select case. - if case==1 then + if case == 1 then -- CASE I -- Get current carrier heading. - local hdg=self:GetHeading() + local hdg = self:GetHeading() -- Distance to the post. - local D=UTILS.NMToMeters(2.5) + local D = UTILS.NMToMeters( 2.5 ) -- Post 2.5 NM port of carrier. - local Post=self:GetCoordinate():Translate(D, hdg+270) + local Post = self:GetCoordinate():Translate( D, hdg + 270 ) - --TODO: update zone not creating a new one. + -- TODO: update zone not creating a new one. -- Create holding zone. - self.zoneHolding=ZONE_RADIUS:New("CASE I Holding Zone", Post:GetVec2(), self.marshalradius) + self.zoneHolding = ZONE_RADIUS:New( "CASE I Holding Zone", Post:GetVec2(), self.marshalradius ) -- Delta pattern. - if self.carriertype==AIRBOSS.CarrierType.TARAWA or self.carriertype==AIRBOSS.CarrierType.AMERICA or self.carriertype==AIRBOSS.CarrierType.JCARLOS or self.carriertype==AIRBOSS.CarrierType.CANBERRA then - self.zoneHolding=ZONE_RADIUS:New("CASE I Holding Zone", self.carrier:GetVec2(), UTILS.NMToMeters(5)) + if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then + self.zoneHolding = ZONE_RADIUS:New( "CASE I Holding Zone", self.carrier:GetVec2(), UTILS.NMToMeters( 5 ) ) end - else -- CASE II/II -- Get radial. - local radial=self:GetRadial(case, false, true) + local radial = self:GetRadial( case, false, true ) -- Create an array of a rectangle. Length is 7 NM, width is 8 NM. One NM starboard to line up with the approach corridor. - local p={} - p[1]=c2:Translate(UTILS.NMToMeters(1), radial-90):GetVec2() --c2 is at (angels+15) NM directly behind the carrier. We translate it 1 NM starboard. - p[2]=c1:Translate(UTILS.NMToMeters(1), radial-90):GetVec2() --c1 is 7 NM further behind. Also translated 1 NM starboard. - p[3]=c1:Translate(UTILS.NMToMeters(7), radial+90):GetVec2() --p3 7 NM port of carrier. - p[4]=c2:Translate(UTILS.NMToMeters(7), radial+90):GetVec2() --p4 7 NM port of carrier. + local p = {} + p[1] = c2:Translate( UTILS.NMToMeters( 1 ), radial - 90 ):GetVec2() -- c2 is at (angels+15) NM directly behind the carrier. We translate it 1 NM starboard. + p[2] = c1:Translate( UTILS.NMToMeters( 1 ), radial - 90 ):GetVec2() -- c1 is 7 NM further behind. Also translated 1 NM starboard. + p[3] = c1:Translate( UTILS.NMToMeters( 7 ), radial + 90 ):GetVec2() -- p3 7 NM port of carrier. + p[4] = c2:Translate( UTILS.NMToMeters( 7 ), radial + 90 ):GetVec2() -- p4 7 NM port of carrier. -- Square zone length=7NM width=6 NM behind the carrier starting at angels+15 NM behind the carrier. -- So stay 0-5 NM (+1 NM error margin) port of carrier. - self.zoneHolding=self.zoneHolding or ZONE_POLYGON_BASE:New("CASE II/III Holding Zone") + self.zoneHolding = self.zoneHolding or ZONE_POLYGON_BASE:New( "CASE II/III Holding Zone" ) - self.zoneHolding:UpdateFromVec2(p) + self.zoneHolding:UpdateFromVec2( p ) end return self.zoneHolding @@ -11471,75 +10805,74 @@ end -- @param #number case Recovery case. -- @param #number stack Stack for Case II/III as we commence from stack>=1. -- @return Core.Zone#ZONE Holding zone. -function AIRBOSS:_GetZoneCommence(case, stack) +function AIRBOSS:_GetZoneCommence( case, stack ) -- Commence zone. local zone - if case==1 then + if case == 1 then -- Case I -- Get current carrier heading. - local hdg=self:GetHeading() + local hdg = self:GetHeading() -- Distance to the zone. - local D=UTILS.NMToMeters(4.75) + local D = UTILS.NMToMeters( 4.75 ) -- Zone radius. - local R=UTILS.NMToMeters(1) + local R = UTILS.NMToMeters( 1 ) -- Three position - local Three=self:GetCoordinate():Translate(D, hdg+275) + local Three = self:GetCoordinate():Translate( D, hdg + 275 ) - if self.carriertype==AIRBOSS.CarrierType.TARAWA or self.carriertype==AIRBOSS.CarrierType.AMERICA or self.carriertype==AIRBOSS.CarrierType.JCARLOS or self.carriertype==AIRBOSS.CarrierType.CANBERRA then + if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then + local Dx = UTILS.NMToMeters( 2.25 ) - local Dx=UTILS.NMToMeters(2.25) + local Dz = UTILS.NMToMeters( 2.25 ) - local Dz=UTILS.NMToMeters(2.25) + R = UTILS.NMToMeters( 1 ) - R=UTILS.NMToMeters(1) - - Three=self:GetCoordinate():Translate(Dz, hdg-90):Translate(Dx, hdg-180) + Three = self:GetCoordinate():Translate( Dz, hdg - 90 ):Translate( Dx, hdg - 180 ) end -- Create holding zone. - self.zoneCommence=self.zoneCommence or ZONE_RADIUS:New("CASE I Commence Zone") + self.zoneCommence = self.zoneCommence or ZONE_RADIUS:New( "CASE I Commence Zone" ) - self.zoneCommence:UpdateFromVec2(Three:GetVec2(), R) + self.zoneCommence:UpdateFromVec2( Three:GetVec2(), R ) else -- Case II/III - stack=stack or 1 + stack = stack or 1 - -- Start point at 21 NM for stack=1. - local l=20+stack + -- Start point at 21 NM for stack=1. + local l = 20 + stack -- Offset angle - local offset=self:GetRadial(case, false, true) + local offset = self:GetRadial( case, false, true ) -- Carrier position. - local cv=self:GetCoordinate() + local cv = self:GetCoordinate() -- Polygon points. - local c={} + local c = {} - c[1]=cv:Translate(UTILS.NMToMeters(l), offset):Translate(UTILS.NMToMeters(1), offset-90) - c[2]=cv:Translate(UTILS.NMToMeters(l+2.5), offset):Translate(UTILS.NMToMeters(1), offset-90) - c[3]=cv:Translate(UTILS.NMToMeters(l+2.5), offset):Translate(UTILS.NMToMeters(1), offset+90) - c[4]=cv:Translate(UTILS.NMToMeters(l), offset):Translate(UTILS.NMToMeters(1), offset+90) + c[1] = cv:Translate( UTILS.NMToMeters( l ), offset ):Translate( UTILS.NMToMeters( 1 ), offset - 90 ) + c[2] = cv:Translate( UTILS.NMToMeters( l + 2.5 ), offset ):Translate( UTILS.NMToMeters( 1 ), offset - 90 ) + c[3] = cv:Translate( UTILS.NMToMeters( l + 2.5 ), offset ):Translate( UTILS.NMToMeters( 1 ), offset + 90 ) + c[4] = cv:Translate( UTILS.NMToMeters( l ), offset ):Translate( UTILS.NMToMeters( 1 ), offset + 90 ) -- Create an array of a square! - local p={} - for _i,_c in ipairs(c) do - p[_i]=_c:GetVec2() + local p = {} + for _i, _c in ipairs( c ) do + p[_i] = _c:GetVec2() end -- Zone polygon. - self.zoneCommence=self.zoneCommence or ZONE_POLYGON_BASE:New("CASE II/III Commence Zone") + self.zoneCommence = self.zoneCommence or ZONE_POLYGON_BASE:New( "CASE II/III Commence Zone" ) - self.zoneCommence:UpdateFromVec2(p) + self.zoneCommence:UpdateFromVec2( p ) end @@ -11553,90 +10886,90 @@ end --- Provide info about player status on the fly. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data. -function AIRBOSS:_AttitudeMonitor(playerData) +function AIRBOSS:_AttitudeMonitor( playerData ) -- Player unit. - local unit=playerData.unit + local unit = playerData.unit -- Aircraft attitude. - local aoa=unit:GetAoA() - local yaw=unit:GetYaw() - local roll=unit:GetRoll() - local pitch=unit:GetPitch() + local aoa = unit:GetAoA() + local yaw = unit:GetYaw() + local roll = unit:GetRoll() + local pitch = unit:GetPitch() -- Distance to the boat. - local dist=playerData.unit:GetCoordinate():Get2DDistance(self:GetCoordinate()) - local dx,dz,rho,phi=self:_GetDistances(unit) + local dist = playerData.unit:GetCoordinate():Get2DDistance( self:GetCoordinate() ) + local dx, dz, rho, phi = self:_GetDistances( unit ) -- Wind vector. - local wind=unit:GetCoordinate():GetWindWithTurbulenceVec3() + local wind = unit:GetCoordinate():GetWindWithTurbulenceVec3() -- Aircraft veloecity vector. - local velo=unit:GetVelocityVec3() - local vabs=UTILS.VecNorm(velo) + local velo = unit:GetVelocityVec3() + local vabs = UTILS.VecNorm( velo ) - local rwy=false - local step=playerData.step - if playerData.step==AIRBOSS.PatternStep.FINAL or - playerData.step==AIRBOSS.PatternStep.GROOVE_XX or - playerData.step==AIRBOSS.PatternStep.GROOVE_IM or - playerData.step==AIRBOSS.PatternStep.GROOVE_IC or - playerData.step==AIRBOSS.PatternStep.GROOVE_AR or - playerData.step==AIRBOSS.PatternStep.GROOVE_AL or - playerData.step==AIRBOSS.PatternStep.GROOVE_LC or - playerData.step==AIRBOSS.PatternStep.GROOVE_IW then - step=self:_GS(step,-1) - rwy=true + local rwy = false + local step = playerData.step + if playerData.step == AIRBOSS.PatternStep.FINAL or + playerData.step == AIRBOSS.PatternStep.GROOVE_XX or + playerData.step == AIRBOSS.PatternStep.GROOVE_IM or + playerData.step == AIRBOSS.PatternStep.GROOVE_IC or + playerData.step == AIRBOSS.PatternStep.GROOVE_AR or + playerData.step == AIRBOSS.PatternStep.GROOVE_AL or + playerData.step == AIRBOSS.PatternStep.GROOVE_LC or + playerData.step == AIRBOSS.PatternStep.GROOVE_IW then + step = self:_GS( step, -1 ) + rwy = true end -- Relative heading Aircraft to Carrier. - local relhead=self:_GetRelativeHeading(playerData.unit, rwy) + local relhead = self:_GetRelativeHeading( playerData.unit, rwy ) - --local lc=self:_GetOptLandingCoordinate() - --lc:FlareRed() + -- local lc=self:_GetOptLandingCoordinate() + -- lc:FlareRed() -- Output - local text=string.format("Pattern step: %s", step) - text=text..string.format("\nAoA=%.1f° = %.1f Units | |V|=%.1f knots", aoa, self:_AoADeg2Units(playerData, aoa), UTILS.MpsToKnots(vabs)) + local text = string.format( "Pattern step: %s", step ) + text = text .. string.format( "\nAoA=%.1f° = %.1f Units | |V|=%.1f knots", aoa, self:_AoADeg2Units( playerData, aoa ), UTILS.MpsToKnots( vabs ) ) if self.Debug then -- Velocity vector. - text=text..string.format("\nVx=%.1f Vy=%.1f Vz=%.1f m/s", velo.x, velo.y, velo.z) - --Wind vector. - text=text..string.format("\nWind Vx=%.1f Vy=%.1f Vz=%.1f m/s", wind.x, wind.y, wind.z) + text = text .. string.format( "\nVx=%.1f Vy=%.1f Vz=%.1f m/s", velo.x, velo.y, velo.z ) + -- Wind vector. + text = text .. string.format( "\nWind Vx=%.1f Vy=%.1f Vz=%.1f m/s", wind.x, wind.y, wind.z ) end - text=text..string.format("\nPitch=%.1f° | Roll=%.1f° | Yaw=%.1f°", pitch, roll, yaw) - text=text..string.format("\nClimb Angle=%.1f° | Rate=%d ft/min", unit:GetClimbAngle(), velo.y*196.85) - local dist=self:_GetOptLandingCoordinate():Get3DDistance(playerData.unit) + text = text .. string.format( "\nPitch=%.1f° | Roll=%.1f° | Yaw=%.1f°", pitch, roll, yaw ) + text = text .. string.format( "\nClimb Angle=%.1f° | Rate=%d ft/min", unit:GetClimbAngle(), velo.y * 196.85 ) + local dist = self:_GetOptLandingCoordinate():Get3DDistance( playerData.unit ) -- Get player velocity in km/h. - local vplayer=playerData.unit:GetVelocityKMH() + local vplayer = playerData.unit:GetVelocityKMH() -- Get carrier velocity in km/h. - local vcarrier=self.carrier:GetVelocityKMH() + local vcarrier = self.carrier:GetVelocityKMH() -- Speed difference. - local dv=math.abs(vplayer-vcarrier) - local alt=self:_GetAltCarrier(playerData.unit) - text=text..string.format("\nDist=%.1f m Alt=%.1f m delta|V|=%.1f km/h", dist, alt, dv) + local dv = math.abs( vplayer - vcarrier ) + local alt = self:_GetAltCarrier( playerData.unit ) + text = text .. string.format( "\nDist=%.1f m Alt=%.1f m delta|V|=%.1f km/h", dist, alt, dv ) -- If in the groove, provide line up and glide slope error. - if playerData.step==AIRBOSS.PatternStep.FINAL or - playerData.step==AIRBOSS.PatternStep.GROOVE_XX or - playerData.step==AIRBOSS.PatternStep.GROOVE_IM or - playerData.step==AIRBOSS.PatternStep.GROOVE_IC or - playerData.step==AIRBOSS.PatternStep.GROOVE_AR or - playerData.step==AIRBOSS.PatternStep.GROOVE_AL or - playerData.step==AIRBOSS.PatternStep.GROOVE_LC or - playerData.step==AIRBOSS.PatternStep.GROOVE_IW then - local lue=self:_Lineup(playerData.unit, true) - local gle=self:_Glideslope(playerData.unit) - text=text..string.format("\nGamma=%.1f° | Rho=%.1f°", relhead, phi) - text=text..string.format("\nLineUp=%.2f° | GlideSlope=%.2f° | AoA=%.1f Units", lue, gle, self:_AoADeg2Units(playerData, aoa)) - local grade, points, analysis=self:_LSOgrade(playerData) - text=text..string.format("\nTgroove=%.1f sec", self:_GetTimeInGroove(playerData)) - text=text..string.format("\nGrade: %s %.1f PT - %s", grade, points, analysis) + if playerData.step == AIRBOSS.PatternStep.FINAL or + playerData.step == AIRBOSS.PatternStep.GROOVE_XX or + playerData.step == AIRBOSS.PatternStep.GROOVE_IM or + playerData.step == AIRBOSS.PatternStep.GROOVE_IC or + playerData.step == AIRBOSS.PatternStep.GROOVE_AR or + playerData.step == AIRBOSS.PatternStep.GROOVE_AL or + playerData.step == AIRBOSS.PatternStep.GROOVE_LC or + playerData.step == AIRBOSS.PatternStep.GROOVE_IW then + local lue = self:_Lineup( playerData.unit, true ) + local gle = self:_Glideslope( playerData.unit ) + text = text .. string.format( "\nGamma=%.1f° | Rho=%.1f°", relhead, phi ) + text = text .. string.format( "\nLineUp=%.2f° | GlideSlope=%.2f° | AoA=%.1f Units", lue, gle, self:_AoADeg2Units( playerData, aoa ) ) + local grade, points, analysis = self:_LSOgrade( playerData ) + text = text .. string.format( "\nTgroove=%.1f sec", self:_GetTimeInGroove( playerData ) ) + text = text .. string.format( "\nGrade: %s %.1f PT - %s", grade, points, analysis ) else - text=text..string.format("\nR=%.2f NM | X=%d Z=%d m", UTILS.MetersToNM(rho), dx, dz) - text=text..string.format("\nGamma=%.1f° | Rho=%.1f°", relhead, phi) + text = text .. string.format( "\nR=%.2f NM | X=%d Z=%d m", UTILS.MetersToNM( rho ), dx, dz ) + text = text .. string.format( "\nGamma=%.1f° | Rho=%.1f°", relhead, phi ) end - MESSAGE:New(text, 1, nil , true):ToClient(playerData.client) + MESSAGE:New( text, 1, nil, true ):ToClient( playerData.client ) end --- Get glide slope of aircraft unit. @@ -11644,34 +10977,34 @@ end -- @param Wrapper.Unit#UNIT unit Aircraft unit. -- @param #number optangle (Optional) Return glide slope relative to this angle, i.e. the error from the optimal glide slope ~3.5 degrees. -- @return #number Glide slope angle in degrees measured from the deck of the carrier and third wire. -function AIRBOSS:_Glideslope(unit, optangle) +function AIRBOSS:_Glideslope( unit, optangle ) - if optangle==nil then - if unit:GetTypeName()==AIRBOSS.AircraftCarrier.AV8B then - optangle=3.0 + if optangle == nil then + if unit:GetTypeName() == AIRBOSS.AircraftCarrier.AV8B then + optangle = 3.0 else - optangle=3.5 + optangle = 3.5 end end - -- Landing coordinate - local landingcoord=self:_GetOptLandingCoordinate() + -- Landing coordinate + local landingcoord = self:_GetOptLandingCoordinate() -- Distance from stern to aircraft. - local x=unit:GetCoordinate():Get2DDistance(landingcoord) + local x = unit:GetCoordinate():Get2DDistance( landingcoord ) -- Altitude of unit corrected by the deck height of the carrier. - local h=self:_GetAltCarrier(unit) + local h = self:_GetAltCarrier( unit ) -- Harrier should be 40-50 ft above the deck. - if unit:GetTypeName()==AIRBOSS.AircraftCarrier.AV8B then - h=unit:GetAltitude()-(UTILS.FeetToMeters(50)+self.carrierparam.deckheight+2) + if unit:GetTypeName() == AIRBOSS.AircraftCarrier.AV8B then + h = unit:GetAltitude() - (UTILS.FeetToMeters( 50 ) + self.carrierparam.deckheight + 2) end -- Glide slope. - local glideslope=math.atan(h/x) + local glideslope = math.atan( h / x ) -- Glide slope (error) in degrees. - local gs=math.deg(glideslope)-optangle + local gs = math.deg( glideslope ) - optangle return gs end @@ -11681,37 +11014,37 @@ end -- @param Wrapper.Unit#UNIT unit Aircraft unit. -- @param #number optangle (Optional) Return glide slope relative to this angle, i.e. the error from the optimal glide slope ~3.5 degrees. -- @return #number Glide slope angle in degrees measured from the deck of the carrier and third wire. -function AIRBOSS:_Glideslope2(unit, optangle) +function AIRBOSS:_Glideslope2( unit, optangle ) - if optangle==nil then - if unit:GetTypeName()==AIRBOSS.AircraftCarrier.AV8B then - optangle=3.0 + if optangle == nil then + if unit:GetTypeName() == AIRBOSS.AircraftCarrier.AV8B then + optangle = 3.0 else - optangle=3.5 + optangle = 3.5 end end - -- Landing coordinate - local landingcoord=self:_GetOptLandingCoordinate() + -- Landing coordinate + local landingcoord = self:_GetOptLandingCoordinate() -- Distance from stern to aircraft. - local x=unit:GetCoordinate():Get3DDistance(landingcoord) + local x = unit:GetCoordinate():Get3DDistance( landingcoord ) -- Altitude of unit corrected by the deck height of the carrier. - local h=self:_GetAltCarrier(unit) + local h = self:_GetAltCarrier( unit ) -- Harrier should be 40-50 ft above the deck. - if unit:GetTypeName()==AIRBOSS.AircraftCarrier.AV8B then - h=unit:GetAltitude()-(UTILS.FeetToMeters(50)+self.carrierparam.deckheight+2) + if unit:GetTypeName() == AIRBOSS.AircraftCarrier.AV8B then + h = unit:GetAltitude() - (UTILS.FeetToMeters( 50 ) + self.carrierparam.deckheight + 2) end -- Glide slope. - local glideslope=math.asin(h/x) + local glideslope = math.asin( h / x ) -- Glide slope (error) in degrees. - local gs=math.deg(glideslope)-optangle + local gs = math.deg( glideslope ) - optangle -- Debug. - self:T3(self.lid..string.format("Glide slope error = %.1f, x=%.1f h=%.1f", gs, x, h)) + self:T3( self.lid .. string.format( "Glide slope error = %.1f, x=%.1f h=%.1f", gs, x, h ) ) return gs end @@ -11721,49 +11054,49 @@ end -- @param Wrapper.Unit#UNIT unit Aircraft unit. -- @param #boolean runway If true, include angled runway. -- @return #number Line up with runway heading in degrees. 0 degrees = perfect line up. +1 too far left. -1 too far right. -function AIRBOSS:_Lineup(unit, runway) +function AIRBOSS:_Lineup( unit, runway ) -- Landing coordinate - local landingcoord=self:_GetOptLandingCoordinate() + local landingcoord = self:_GetOptLandingCoordinate() -- Vector to landing coord. - local A=landingcoord:GetVec3() + local A = landingcoord:GetVec3() -- Vector to player. - local B=unit:GetVec3() + local B = unit:GetVec3() -- Vector from player to carrier. - local C=UTILS.VecSubstract(A, B) + local C = UTILS.VecSubstract( A, B ) -- Only in 2D plane. - C.y=0.0 + C.y = 0.0 -- Orientation of carrier. - local X=self.carrier:GetOrientationX() - X.y=0.0 + local X = self.carrier:GetOrientationX() + X.y = 0.0 -- Rotate orientation to angled runway. if runway then - X=UTILS.Rotate2D(X, -self.carrierparam.rwyangle) + X = UTILS.Rotate2D( X, -self.carrierparam.rwyangle ) end -- Projection of player pos on x component. - local x=UTILS.VecDot(X, C) + local x = UTILS.VecDot( X, C ) -- Orientation of carrier. - local Z=self.carrier:GetOrientationZ() - Z.y=0.0 + local Z = self.carrier:GetOrientationZ() + Z.y = 0.0 -- Rotate orientation to angled runway. if runway then - Z=UTILS.Rotate2D(Z, -self.carrierparam.rwyangle) + Z = UTILS.Rotate2D( Z, -self.carrierparam.rwyangle ) end -- Projection of player pos on z component. - local z=UTILS.VecDot(Z, C) + local z = UTILS.VecDot( Z, C ) --- - local lineup=math.deg(math.atan2(z, x)) + local lineup = math.deg( math.atan2( z, x ) ) return lineup end @@ -11772,76 +11105,59 @@ end -- @param #AIRBOSS self -- @param Wrapper.Unit#UNIT unit Aircraft unit. -- @return #number Altitude in meters wrt carrier height. -function AIRBOSS:_GetAltCarrier(unit) +function AIRBOSS:_GetAltCarrier( unit ) -- TODO: Value 4 meters is for the Hornet. Adjust for Harrier, A4E and -- Altitude of unit corrected by the deck height of the carrier. - local h=unit:GetAltitude()-self.carrierparam.deckheight-2 + local h = unit:GetAltitude() - self.carrierparam.deckheight - 2 return h end ---- Get optimal landing position of the aircraft. Usually between second and third wire. In case of Tarawa and America we take the abeam landing spot 120 ft abeam the 7.5 position, for the Juan Carlos I it is 120 ft and abeam the 5 position. +--- Get optimal landing position of the aircraft. Usually between second and third wire. In case of Tarawa, Canberrra, Juan Carlos and America we take the abeam landing spot 120 ft above and 21 ft abeam the 7.5 position, for the Juan Carlos I and HMS Hermes it is 120 ft above and 21 ft abeam the 5 position. For CASE III it is 120ft directly above the landing spot. -- @param #AIRBOSS self -- @return Core.Point#COORDINATE Optimal landing coordinate. function AIRBOSS:_GetOptLandingCoordinate() -- Start with stern coordiante. - self.landingcoord:UpdateFromCoordinate(self:_GetSternCoord()) + self.landingcoord:UpdateFromCoordinate( self:_GetSternCoord() ) -- Stern coordinate. - --local stern=self:_GetSternCoord() - + -- local stern=self:_GetSternCoord() -- Final bearing. + local FB=self:GetFinalBearing(false) - - if self.carriertype==AIRBOSS.CarrierType.TARAWA then - - -- Landing 100 ft abeam, 120 ft alt. - self.landingcoord:UpdateFromCoordinate(self:_GetLandingSpotCoordinate()):Translate(35, FB-90, true, true) - --stern=self:_GetLandingSpotCoordinate():Translate(35, FB-90) - - -- Alitude 120 ft. - self.landingcoord:SetAltitude(UTILS.FeetToMeters(120)) - elseif self.carriertype==AIRBOSS.CarrierType.AMERICA then - - -- Landing 100 ft abeam, 120 ft alt. To allow adjustments to match different deck configurations. - self.landingcoord:UpdateFromCoordinate(self:_GetLandingSpotCoordinate()):Translate(35, FB-90, true, true) - --stern=self:_GetLandingSpotCoordinate():Translate(35, FB-90) - - -- Alitude 120 ft. - self.landingcoord:SetAltitude(UTILS.FeetToMeters(120)) - - elseif self.carriertype==AIRBOSS.CarrierType.JCARLOS then - - -- Landing 100 ft abeam, 120 ft alt. - self.landingcoord:UpdateFromCoordinate(self:_GetLandingSpotCoordinate()):Translate(35, FB-90, true, true) - --stern=self:_GetLandingSpotCoordinate():Translate(35, FB-90) - - -- Alitude 120 ft. - self.landingcoord:SetAltitude(UTILS.FeetToMeters(120)) + local case=self.case + -- set Case III V/STOL abeam landing spot over deck -- Pene Testing + if self.carriertype==AIRBOSS.CarrierType.HERMES or self.carriertype==AIRBOSS.CarrierType.TARAWA or self.carriertype==AIRBOSS.CarrierType.AMERICA or self.carriertype==AIRBOSS.CarrierType.JCARLOS or self.carriertype==AIRBOSS.CarrierType.CANBERRA then - elseif self.carriertype==AIRBOSS.CarrierType.CANBERRA then + if case==3 then + self.landingcoord:UpdateFromCoordinate(self:_GetLandingSpotCoordinate()) + -- Altitude 120ft -- is this corect for Case III? + self.landingcoord:SetAltitude(UTILS.FeetToMeters(120)) + + elseif case==2 or case==1 then -- Landing 100 ft abeam, 120 ft alt. - self.landingcoord:UpdateFromCoordinate(self:_GetLandingSpotCoordinate()):Translate(35, FB-90, true, true) + self.landingcoord:UpdateFromCoordinate(self:_GetLandingSpotCoordinate()):Translate(35, FB-90, true, true) --stern=self:_GetLandingSpotCoordinate():Translate(35, FB-90) -- Alitude 120 ft. self.landingcoord:SetAltitude(UTILS.FeetToMeters(120)) - + end + else -- Ideally we want to land between 2nd and 3rd wire. if self.carrierparam.wire3 then -- We take the position of the 3rd wire to approximately account for the length of the aircraft. - local w3=self.carrierparam.wire3 - self.landingcoord:Translate(w3, FB, true, true) + local w3 = self.carrierparam.wire3 + self.landingcoord:Translate( w3, FB, true, true ) end -- Add 2 meters to account for aircraft height. - self.landingcoord.y=self.landingcoord.y+2 + self.landingcoord.y = self.landingcoord.y + 2 end @@ -11853,41 +11169,48 @@ end -- @return Core.Point#COORDINATE Primary landing spot coordinate. function AIRBOSS:_GetLandingSpotCoordinate() - self.landingspotcoord:UpdateFromCoordinate(self:_GetSternCoord()) + self.landingspotcoord:UpdateFromCoordinate( self:_GetSternCoord() ) -- Stern coordinate. - --local stern=self:_GetSternCoord() + -- local stern=self:_GetSternCoord() - if self.carriertype==AIRBOSS.CarrierType.TARAWA then + if self.carriertype==AIRBOSS.CarrierType.HERMES then + + -- Landing 100 ft abeam, 100 alt. + local hdg = self:GetHeading() + + -- Primary landing spot 5 + self.landingspotcoord:Translate( 69, hdg, true, true ):SetAltitude( self.carrierparam.deckheight ) + elseif self.carriertype == AIRBOSS.CarrierType.TARAWA then -- Landing 100 ft abeam, 120 alt. - local hdg=self:GetHeading() + local hdg = self:GetHeading() -- Primary landing spot 7.5 - self.landingspotcoord:Translate(57, hdg, true, true):SetAltitude(self.carrierparam.deckheight) - elseif self.carriertype==AIRBOSS.CarrierType.AMERICA then + self.landingspotcoord:Translate( 57, hdg, true, true ):SetAltitude( self.carrierparam.deckheight ) + elseif self.carriertype == AIRBOSS.CarrierType.AMERICA then -- Landing 100 ft abeam, 120 alt. - local hdg=self:GetHeading() + local hdg = self:GetHeading() -- Primary landing spot 7.5 a little further forwad on the America - self.landingspotcoord:Translate(59, hdg, true, true):SetAltitude(self.carrierparam.deckheight) + self.landingspotcoord:Translate( 59, hdg, true, true ):SetAltitude( self.carrierparam.deckheight ) - elseif self.carriertype==AIRBOSS.CarrierType.JCARLOS then + elseif self.carriertype == AIRBOSS.CarrierType.JCARLOS then -- Landing 100 ft abeam, 120 alt. - local hdg=self:GetHeading() + local hdg = self:GetHeading() -- Primary landing spot 5.0 -- Done voice for different landing Spots. - self.landingspotcoord:Translate(89, hdg, true, true):SetAltitude(self.carrierparam.deckheight) - - elseif self.carriertype==AIRBOSS.CarrierType.CANBERRA then + self.landingspotcoord:Translate( 89, hdg, true, true ):SetAltitude( self.carrierparam.deckheight ) + + elseif self.carriertype == AIRBOSS.CarrierType.CANBERRA then -- Landing 100 ft abeam, 120 alt. - local hdg=self:GetHeading() + local hdg = self:GetHeading() -- Primary landing spot 5.0 -- Done voice for different landing Spots. - self.landingspotcoord:Translate(89, hdg, true, true):SetAltitude(self.carrierparam.deckheight) + self.landingspotcoord:Translate( 89, hdg, true, true ):SetAltitude( self.carrierparam.deckheight ) end return self.landingspotcoord @@ -11897,20 +11220,20 @@ end -- @param #AIRBOSS self -- @param #boolean magnetic If true, calculate magnetic heading. By default true heading is returned. -- @return #number Carrier heading in degrees. -function AIRBOSS:GetHeading(magnetic) - self:F3({magnetic=magnetic}) +function AIRBOSS:GetHeading( magnetic ) + self:F3( { magnetic = magnetic } ) -- Carrier heading - local hdg=self.carrier:GetHeading() + local hdg = self.carrier:GetHeading() -- Include magnetic declination. if magnetic then - hdg=hdg-self.magvar + hdg = hdg - self.magvar end -- Adjust negative values. - if hdg<0 then - hdg=hdg+360 + if hdg < 0 then + hdg = hdg + 360 end return hdg @@ -11921,7 +11244,7 @@ end -- @param #AIRBOSS self -- @return #number BRC in degrees. function AIRBOSS:GetBRC() - return self:GetHeading(true) + return self:GetHeading( true ) end --- Get wind direction and speed at carrier position. @@ -11931,20 +11254,20 @@ end -- @param Core.Point#COORDINATE coord (Optional) Coordinate at which to get the wind. Default is current carrier position. -- @return #number Direction the wind is blowing **from** in degrees. -- @return #number Wind speed in m/s. -function AIRBOSS:GetWind(alt, magnetic, coord) +function AIRBOSS:GetWind( alt, magnetic, coord ) -- Current position of the carrier or input. - local cv=coord or self:GetCoordinate() + local cv = coord or self:GetCoordinate() -- Wind direction and speed. By default at 50 meters ASL. - local Wdir, Wspeed=cv:GetWind(alt or 50) + local Wdir, Wspeed = cv:GetWind( alt or 50 ) -- Include magnetic declination. if magnetic then - Wdir=Wdir-self.magvar + Wdir = Wdir - self.magvar -- Adjust negative values. - if Wdir<0 then - Wdir=Wdir+360 + if Wdir < 0 then + Wdir = Wdir + 360 end end @@ -11957,72 +11280,71 @@ end -- @return #number Wind component parallel to runway im m/s. -- @return #number Wind component perpendicular to runway in m/s. -- @return #number Total wind strength in m/s. -function AIRBOSS:GetWindOnDeck(alt) +function AIRBOSS:GetWindOnDeck( alt ) -- Position of carrier. - local cv=self:GetCoordinate() + local cv = self:GetCoordinate() -- Velocity vector of carrier. - local vc=self.carrier:GetVelocityVec3() + local vc = self.carrier:GetVelocityVec3() -- Carrier orientation X. - local xc=self.carrier:GetOrientationX() + local xc = self.carrier:GetOrientationX() -- Carrier orientation Z. - local zc=self.carrier:GetOrientationZ() + local zc = self.carrier:GetOrientationZ() -- Rotate back so that angled deck points to wind. - xc=UTILS.Rotate2D(xc, -self.carrierparam.rwyangle) - zc=UTILS.Rotate2D(zc, -self.carrierparam.rwyangle) + xc = UTILS.Rotate2D( xc, -self.carrierparam.rwyangle ) + zc = UTILS.Rotate2D( zc, -self.carrierparam.rwyangle ) -- Wind (from) vector - local vw=cv:GetWindWithTurbulenceVec3(alt or 15) + local vw = cv:GetWindWithTurbulenceVec3( alt or 15 ) -- Total wind velocity vector. -- Carrier velocity has to be negative. If carrier drives in the direction the wind is blowing from, we have less wind in total. - local vT=UTILS.VecSubstract(vw, vc) + local vT = UTILS.VecSubstract( vw, vc ) -- || Parallel component. - local vpa=UTILS.VecDot(vT,xc) + local vpa = UTILS.VecDot( vT, xc ) -- == Perpendicular component. - local vpp=UTILS.VecDot(vT,zc) + local vpp = UTILS.VecDot( vT, zc ) -- Strength. - local vabs=UTILS.VecNorm(vT) + local vabs = UTILS.VecNorm( vT ) -- We return positive values as head wind and negative values as tail wind. - --TODO: Check minus sign. + -- TODO: Check minus sign. return -vpa, vpp, vabs end - --- Get true (or magnetic) heading of carrier into the wind. This accounts for the angled runway. -- @param #AIRBOSS self -- @param #boolean magnetic If true, calculate magnetic heading. By default true heading is returned. -- @param Core.Point#COORDINATE coord (Optional) Coodinate from which heading is calculated. Default is current carrier position. -- @return #number Carrier heading in degrees. -function AIRBOSS:GetHeadingIntoWind(magnetic, coord) +function AIRBOSS:GetHeadingIntoWind( magnetic, coord ) -- Get direction the wind is blowing from. This is where we want to go. - local windfrom, vwind=self:GetWind(nil, nil, coord) + local windfrom, vwind = self:GetWind( nil, nil, coord ) -- Actually, we want the runway in the wind. - local intowind=windfrom-self.carrierparam.rwyangle + local intowind = windfrom - self.carrierparam.rwyangle -- If no wind, take current heading. - if vwind<0.1 then - intowind=self:GetHeading() + if vwind < 0.1 then + intowind = self:GetHeading() end -- Magnetic heading. if magnetic then - intowind=intowind-self.magvar + intowind = intowind - self.magvar end -- Adjust negative values. - if intowind<0 then - intowind=intowind+360 + if intowind < 0 then + intowind = intowind + 360 end return intowind @@ -12034,27 +11356,26 @@ end -- @return #number BRC into the wind in degrees. function AIRBOSS:GetBRCintoWind() -- BRC is the magnetic heading. - return self:GetHeadingIntoWind(true) + return self:GetHeadingIntoWind( true ) end - --- Get final bearing (FB) of carrier. -- By default, the routine returns the magnetic FB depending on the current map (Caucasus, NTTR, Normandy, Persion Gulf etc). -- The true bearing can be obtained by setting the *TrueNorth* parameter to true. -- @param #AIRBOSS self -- @param #boolean magnetic If true, magnetic FB is returned. -- @return #number FB in degrees. -function AIRBOSS:GetFinalBearing(magnetic) +function AIRBOSS:GetFinalBearing( magnetic ) -- First get the heading. - local fb=self:GetHeading(magnetic) + local fb = self:GetHeading( magnetic ) -- Final baring = BRC including angled deck. - fb=fb+self.carrierparam.rwyangle + fb = fb + self.carrierparam.rwyangle -- Adjust negative values. - if fb<0 then - fb=fb+360 + if fb < 0 then + fb = fb + 360 end return fb @@ -12072,56 +11393,56 @@ end -- @param #boolean offset If true, inlcude holding offset. -- @param #boolean inverse Return inverse, i.e. radial-180 degrees. -- @return #number Radial in degrees. -function AIRBOSS:GetRadial(case, magnetic, offset, inverse) +function AIRBOSS:GetRadial( case, magnetic, offset, inverse ) -- Case or current case. - case=case or self.case + case = case or self.case -- Radial. local radial -- Select case. - if case==1 then + if case == 1 then -- Get radial. - radial=self:GetFinalBearing(magnetic)-180 + radial = self:GetFinalBearing( magnetic ) - 180 - elseif case==2 then + elseif case == 2 then -- Radial wrt to heading of carrier. - radial=self:GetHeading(magnetic)-180 + radial = self:GetHeading( magnetic ) - 180 -- Holding offset angle (+-15 or 30 degrees usually) if offset then - radial=radial+self.holdingoffset + radial = radial + self.holdingoffset end - elseif case==3 then + elseif case == 3 then -- Radial wrt angled runway. - radial=self:GetFinalBearing(magnetic)-180 + radial = self:GetFinalBearing( magnetic ) - 180 -- Holding offset angle (+-15 or 30 degrees usually) if offset then - radial=radial+self.holdingoffset + radial = radial + self.holdingoffset end end -- Adjust for negative values. - if radial<0 then - radial=radial+360 + if radial < 0 then + radial = radial + 360 end -- Inverse? if inverse then -- Inverse radial - radial=radial-180 + radial = radial - 180 -- Adjust for negative values. - if radial<0 then - radial=radial+360 + if radial < 0 then + radial = radial + 360 end end @@ -12134,19 +11455,19 @@ end -- @param #number hdg1 Heading one. -- @param #number hdg2 Heading two. -- @return #number Difference between the two headings in degrees. -function AIRBOSS:_GetDeltaHeading(hdg1, hdg2) +function AIRBOSS:_GetDeltaHeading( hdg1, hdg2 ) - local V={} --DCS#Vec3 - V.x=math.cos(math.rad(hdg1)) - V.y=0 - V.z=math.sin(math.rad(hdg1)) + local V = {} -- DCS#Vec3 + V.x = math.cos( math.rad( hdg1 ) ) + V.y = 0 + V.z = math.sin( math.rad( hdg1 ) ) - local W={} --DCS#Vec3 - W.x=math.cos(math.rad(hdg2)) - W.y=0 - W.z=math.sin(math.rad(hdg2)) + local W = {} -- DCS#Vec3 + W.x = math.cos( math.rad( hdg2 ) ) + W.y = 0 + W.z = math.sin( math.rad( hdg2 ) ) - local alpha=UTILS.VecAngle(V,W) + local alpha = UTILS.VecAngle( V, W ) return alpha end @@ -12158,24 +11479,25 @@ end -- @param Wrapper.Unit#UNIT unit Player unit. -- @param #boolean runway (Optional) If true, return relative heading of unit wrt to angled runway of the carrier. -- @return #number Relative heading in degrees. An angle of 0 means, unit fly parallel to carrier. An angle of + or - 90 degrees means, unit flies perpendicular to carrier. -function AIRBOSS:_GetRelativeHeading(unit, runway) +function AIRBOSS:_GetRelativeHeading( unit, runway ) -- Direction vector of the carrier. - local vC=self.carrier:GetOrientationX() + local vC = self.carrier:GetOrientationX() -- Include runway angle. if runway then - vC=UTILS.Rotate2D(vC, -self.carrierparam.rwyangle) + vC = UTILS.Rotate2D( vC, -self.carrierparam.rwyangle ) end -- Direction vector of the unit. - local vP=unit:GetOrientationX() + local vP = unit:GetOrientationX() -- We only want the X-Z plane. Aircraft could fly parallel but ballistic and we dont want the "pitch" angle. - vC.y=0 ; vP.y=0 + vC.y = 0; + vP.y = 0 -- Get angle between the two orientation vectors in degrees. - local rhdg=UTILS.VecAngle(vC,vP) + local rhdg = UTILS.VecAngle( vC, vP ) -- Return heading in degrees. return rhdg @@ -12185,20 +11507,20 @@ end -- @param #AIRBOSS self -- @param Wrapper.Unit#UNIT unit Player unit. -- @return #number Relative velocity in m/s. -function AIRBOSS:_GetRelativeVelocity(unit) +function AIRBOSS:_GetRelativeVelocity( unit ) - local vC=self.carrier:GetVelocityVec3() - local vP=unit:GetVelocityVec3() + local vC = self.carrier:GetVelocityVec3() + local vP = unit:GetVelocityVec3() -- Only X-Z plane is necessary here. - vC.y=0 ; vP.y=0 + vC.y = 0; + vP.y = 0 - local v=UTILS.VecSubstract(vP, vC) + local v = UTILS.VecSubstract( vP, vC ) - return UTILS.VecNorm(v),v + return UTILS.VecNorm( v ), v end - --- Calculate distances between carrier and aircraft unit. -- @param #AIRBOSS self -- @param Wrapper.Unit#UNIT unit Aircraft unit. @@ -12206,42 +11528,41 @@ end -- @return #number Distance [m] perpendicular to the orientation of the carrier. -- @return #number Distance [m] to the carrier. -- @return #number Angle [Deg] from carrier to plane. Phi=0 if the plane is directly behind the carrier, phi=90 if the plane is starboard, phi=180 if the plane is in front of the carrier. -function AIRBOSS:_GetDistances(unit) +function AIRBOSS:_GetDistances( unit ) -- Vector to carrier - local a=self.carrier:GetVec3() + local a = self.carrier:GetVec3() -- Vector to player - local b=unit:GetVec3() + local b = unit:GetVec3() -- Vector from carrier to player. - local c={x=b.x-a.x, y=0, z=b.z-a.z} + local c = { x = b.x - a.x, y = 0, z = b.z - a.z } -- Orientation of carrier. - local x=self.carrier:GetOrientationX() + local x = self.carrier:GetOrientationX() -- Projection of player pos on x component. - local dx=UTILS.VecDot(x,c) + local dx = UTILS.VecDot( x, c ) -- Orientation of carrier. - local z=self.carrier:GetOrientationZ() + local z = self.carrier:GetOrientationZ() -- Projection of player pos on z component. - local dz=UTILS.VecDot(z,c) + local dz = UTILS.VecDot( z, c ) -- Polar coordinates. - local rho=math.sqrt(dx*dx+dz*dz) - + local rho = math.sqrt( dx * dx + dz * dz ) -- Not exactly sure any more what I wanted to calculate here. - local phi=math.deg(math.atan2(dz,dx)) + local phi = math.deg( math.atan2( dz, dx ) ) -- Correct for negative values. - if phi<0 then - phi=phi+360 + if phi < 0 then + phi = phi + 360 end - return dx,dz,rho,phi + return dx, dz, rho, phi end --- Check limits for reaching next step. @@ -12250,26 +11571,24 @@ end -- @param #number Z Z position of player unit. -- @param #AIRBOSS.Checkpoint check Checkpoint. -- @return #boolean If true, checkpoint condition for next step was reached. -function AIRBOSS:_CheckLimits(X, Z, check) +function AIRBOSS:_CheckLimits( X, Z, check ) -- Limits - local nextXmin=check.LimitXmin==nil or (check.LimitXmin and (check.LimitXmin<0 and X<=check.LimitXmin or check.LimitXmin>=0 and X>=check.LimitXmin)) - local nextXmax=check.LimitXmax==nil or (check.LimitXmax and (check.LimitXmax<0 and X>=check.LimitXmax or check.LimitXmax>=0 and X<=check.LimitXmax)) - local nextZmin=check.LimitZmin==nil or (check.LimitZmin and (check.LimitZmin<0 and Z<=check.LimitZmin or check.LimitZmin>=0 and Z>=check.LimitZmin)) - local nextZmax=check.LimitZmax==nil or (check.LimitZmax and (check.LimitZmax<0 and Z>=check.LimitZmax or check.LimitZmax>=0 and Z<=check.LimitZmax)) + local nextXmin = check.LimitXmin == nil or (check.LimitXmin and (check.LimitXmin < 0 and X <= check.LimitXmin or check.LimitXmin >= 0 and X >= check.LimitXmin)) + local nextXmax = check.LimitXmax == nil or (check.LimitXmax and (check.LimitXmax < 0 and X >= check.LimitXmax or check.LimitXmax >= 0 and X <= check.LimitXmax)) + local nextZmin = check.LimitZmin == nil or (check.LimitZmin and (check.LimitZmin < 0 and Z <= check.LimitZmin or check.LimitZmin >= 0 and Z >= check.LimitZmin)) + local nextZmax = check.LimitZmax == nil or (check.LimitZmax and (check.LimitZmax < 0 and Z >= check.LimitZmax or check.LimitZmax >= 0 and Z <= check.LimitZmax)) -- Proceed to next step if all conditions are fullfilled. - local next=nextXmin and nextXmax and nextZmin and nextZmax + local next = nextXmin and nextXmax and nextZmin and nextZmax -- Debug info. - local text=string.format("step=%s: next=%s: X=%d Xmin=%s Xmax=%s | Z=%d Zmin=%s Zmax=%s", - check.name, tostring(next), X, tostring(check.LimitXmin), tostring(check.LimitXmax), Z, tostring(check.LimitZmin), tostring(check.LimitZmax)) - self:T3(self.lid..text) + local text = string.format( "step=%s: next=%s: X=%d Xmin=%s Xmax=%s | Z=%d Zmin=%s Zmax=%s", check.name, tostring( next ), X, tostring( check.LimitXmin ), tostring( check.LimitXmax ), Z, tostring( check.LimitZmin ), tostring( check.LimitZmax ) ) + self:T3( self.lid .. text ) return next end - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- LSO functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -12279,93 +11598,92 @@ end -- @param #AIRBOSS.PlayerData playerData Player data table. -- @param #number glideslopeError Error in degrees. -- @param #number lineupError Error in degrees. -function AIRBOSS:_LSOadvice(playerData, glideslopeError, lineupError) +function AIRBOSS:_LSOadvice( playerData, glideslopeError, lineupError ) -- Advice time. - local advice=0 + local advice = 0 -- Glideslope high/low calls. - if glideslopeError>self.gle.HIGH then --1.5 then + if glideslopeError > self.gle.HIGH then -- 1.5 then -- "You're high!" - self:RadioTransmission(self.LSORadio, self.LSOCall.HIGH, true, nil, nil, true) - advice=advice+self.LSOCall.HIGH.duration - elseif glideslopeError>self.gle.High then --0.8 then + self:RadioTransmission( self.LSORadio, self.LSOCall.HIGH, true, nil, nil, true ) + advice = advice + self.LSOCall.HIGH.duration + elseif glideslopeError > self.gle.High then -- 0.8 then -- "You're high." - self:RadioTransmission(self.LSORadio, self.LSOCall.HIGH, false, nil, nil, true) - advice=advice+self.LSOCall.HIGH.duration - elseif glideslopeErrorself.lue.RIGHT then --3 then + self:RadioTransmission( self.LSORadio, self.LSOCall.COMELEFT, false, nil, nil, true ) + advice = advice + self.LSOCall.COMELEFT.duration + elseif lineupError > self.lue.RIGHT then -- 3 then -- "Right for lineup!" - self:RadioTransmission(self.LSORadio, self.LSOCall.RIGHTFORLINEUP, true, nil, nil, true) - advice=advice+self.LSOCall.RIGHTFORLINEUP.duration - elseif lineupError>self.lue.Right then -- 1 then + self:RadioTransmission( self.LSORadio, self.LSOCall.RIGHTFORLINEUP, true, nil, nil, true ) + advice = advice + self.LSOCall.RIGHTFORLINEUP.duration + elseif lineupError > self.lue.Right then -- 1 then -- "Right for lineup." - self:RadioTransmission(self.LSORadio, self.LSOCall.RIGHTFORLINEUP, false, nil, nil, true) - advice=advice+self.LSOCall.RIGHTFORLINEUP.duration + self:RadioTransmission( self.LSORadio, self.LSOCall.RIGHTFORLINEUP, false, nil, nil, true ) + advice = advice + self.LSOCall.RIGHTFORLINEUP.duration else -- "Good lineup." end -- Get current AoA. - local AOA=playerData.unit:GetAoA() + local AOA = playerData.unit:GetAoA() -- Get aircraft AoA parameters. - local acaoa=self:_GetAircraftAoA(playerData) + local acaoa = self:_GetAircraftAoA( playerData ) -- Speed via AoA - not for the Harrier. - if playerData.actype~=AIRBOSS.AircraftCarrier.AV8B then - if AOA>acaoa.SLOW then + if playerData.actype ~= AIRBOSS.AircraftCarrier.AV8B then + if AOA > acaoa.SLOW then -- "Your're slow!" - self:RadioTransmission(self.LSORadio, self.LSOCall.SLOW, true, nil, nil, true) - advice=advice+self.LSOCall.SLOW.duration - --S=underline("SLO") - elseif AOA>acaoa.Slow then + self:RadioTransmission( self.LSORadio, self.LSOCall.SLOW, true, nil, nil, true ) + advice = advice + self.LSOCall.SLOW.duration + -- S=underline("SLO") + elseif AOA > acaoa.Slow then -- "Your're slow." - self:RadioTransmission(self.LSORadio, self.LSOCall.SLOW, false, nil, nil, true) - advice=advice+self.LSOCall.SLOW.duration - --S="SLO" - elseif AOA>acaoa.OnSpeedMax then + self:RadioTransmission( self.LSORadio, self.LSOCall.SLOW, false, nil, nil, true ) + advice = advice + self.LSOCall.SLOW.duration + -- S="SLO" + elseif AOA > acaoa.OnSpeedMax then -- No call. - --S=little("SLO") - elseif AOA=76 then -- VSTOL Early Hover stop selection slow to Abeam LDG Spot AV-8B. - grade="SLOW V/STOL Groove" + local grade = "" + if t < 9 then + grade = "_NESA_" + elseif t < 15 then + grade = "NESA" + elseif t < 19 then + grade = "OK Groove" + elseif t <= 24 then + grade = "(LIG)" + -- Time in groove for AV-8B + elseif playerData.actype == AIRBOSS.AircraftCarrier.AV8B and t < 55 then -- VSTOL Late Hover stop selection too fast to Abeam LDG Spot AV-8B. + grade = "FAST V/STOL Groove" + elseif playerData.actype == AIRBOSS.AircraftCarrier.AV8B and t < 75 then -- VSTOL Operations with AV-8B. + grade = "OK V/STOL Groove" + elseif playerData.actype == AIRBOSS.AircraftCarrier.AV8B and t >= 76 then -- VSTOL Early Hover stop selection slow to Abeam LDG Spot AV-8B. + grade = "SLOW V/STOL Groove" else - grade="LIG" + grade = "LIG" end -- The unicorn! - if t>=16.4 and t<=16.6 then - grade="_OK_" + if t >= 16.4 and t <= 16.6 then + grade = "_OK_" end -- V/STOL Unicorn! - if playerData.actype==AIRBOSS.AircraftCarrier.AV8B and (t>=60.0 and t<=65.0) then - grade="_OK_ V/STOL" + if playerData.actype == AIRBOSS.AircraftCarrier.AV8B and (t >= 60.0 and t <= 65.0) then + grade = "_OK_ V/STOL" end return grade @@ -12436,82 +11754,88 @@ end -- @return #string LSO grade, i.g. _OK_, OK, (OK), --, etc. -- @return #number Points. -- @return #string LSO analysis of flight path. -function AIRBOSS:_LSOgrade(playerData) +function AIRBOSS:_LSOgrade( playerData ) --- Count deviations. - local function count(base, pattern) - return select(2, string.gsub(base, pattern, "")) + local function count( base, pattern ) + return select( 2, string.gsub( base, pattern, "" ) ) end -- Analyse flight data and convert to LSO text. - local GXX,nXX=self:_Flightdata2Text(playerData, AIRBOSS.GroovePos.XX) - local GIM,nIM=self:_Flightdata2Text(playerData, AIRBOSS.GroovePos.IM) - local GIC,nIC=self:_Flightdata2Text(playerData, AIRBOSS.GroovePos.IC) - local GAR,nAR=self:_Flightdata2Text(playerData, AIRBOSS.GroovePos.AR) + local GXX, nXX = self:_Flightdata2Text( playerData, AIRBOSS.GroovePos.XX ) + local GIM, nIM = self:_Flightdata2Text( playerData, AIRBOSS.GroovePos.IM ) + local GIC, nIC = self:_Flightdata2Text( playerData, AIRBOSS.GroovePos.IC ) + local GAR, nAR = self:_Flightdata2Text( playerData, AIRBOSS.GroovePos.AR ) -- Put everything together. - local G=GXX.." "..GIM.." ".." "..GIC.." "..GAR + local G = GXX .. " " .. GIM .. " " .. " " .. GIC .. " " .. GAR -- Count number of minor, normal and major deviations. local N=nXX+nIM+nIC+nAR + local Nv=nXX+nIM local nL=count(G, '_')/2 local nS=count(G, '%(') local nN=N-nS-nL - - -- Groove time 15-18.99 sec for a unicorn. Or 65-70 for V/STOL unicorn. + local nNv=Nv-nS-nL + + -- Groove time 15-18.99 sec for a unicorn. Or 60-65 for V/STOL unicorn. local Tgroove=playerData.Tgroove local TgrooveUnicorn=Tgroove and (Tgroove>=15.0 and Tgroove<=18.99) or false local TgrooveVstolUnicorn=Tgroove and (Tgroove>=60.0 and Tgroove<=65.0)and playerData.actype==AIRBOSS.AircraftCarrier.AV8B or false local grade local points - if N==0 and (TgrooveUnicorn or TgrooveVstolUnicorn ) then + if N == 0 and (TgrooveUnicorn or TgrooveVstolUnicorn) then -- No deviations, should be REALLY RARE! - grade="_OK_" - points=5.0 - G="Unicorn" + grade = "_OK_" + points = 5.0 + G = "Unicorn" else - -- Add AV-8B Harrier devation allowances due to lower groundspeed and 3x conventional groove time, this allows to maintain LSO tolerances while respecting the deviations are not unsafe. (WIP requires feedback) + -- Add AV-8B Harrier devation allowances due to lower groundspeed and 3x conventional groove time, this allows to maintain LSO tolerances while respecting the deviations are not unsafe.--Pene testing -- Large devaitions still result in a No Grade, A Unicorn still requires a clean pass with no deviation. - if nL>3 and playerData.actype==AIRBOSS.AircraftCarrier.AV8B then + if nL > 1 and playerData.actype==AIRBOSS.AircraftCarrier.AV8B then -- Larger deviations ==> "No grade" 2.0 points. grade="--" points=2.0 - elseif nN>2 and playerData.actype==AIRBOSS.AircraftCarrier.AV8B then + elseif nNv >= 1 and playerData.actype==AIRBOSS.AircraftCarrier.AV8B then -- Only average deviations ==> "Fair Pass" Pass with average deviations and corrections. grade="(OK)" points=3.0 - elseif nL>0 then + elseif nNv < 1 and playerData.actype==AIRBOSS.AircraftCarrier.AV8B then + -- Only minor average deviations ==> "OK" Pass with minor deviations and corrections. (test nNv<=1 and) + grade="OK" + points=4.0 + elseif nL > 0 then -- Larger deviations ==> "No grade" 2.0 points. grade="--" points=2.0 - elseif nN>0 then + elseif nN> 0 then -- No larger but average deviations ==> "Fair Pass" Pass with average deviations and corrections. grade="(OK)" points=3.0 - else + else -- Only minor corrections grade="OK" points=4.0 - end + end -end + end -- Replace" )"( and "__" - G=G:gsub("%)%(", "") - G=G:gsub("__","") + G = G:gsub( "%)%(", "" ) + G = G:gsub( "__", "" ) -- Debug info - local text="LSO grade:\n" - text=text..G.."\n" - text=text.."Grade = "..grade.." points = "..points.."\n" - text=text.."# of total deviations = "..N.."\n" - text=text.."# of large deviations _ = "..nL.."\n" - text=text.."# of normal deviations = "..nN.."\n" - text=text.."# of small deviations ( = "..nS.."\n" - self:T2(self.lid..text) - + local text = "LSO grade:\n" + text = text .. G .. "\n" + text = text .. "Grade = " .. grade .. " points = " .. points .. "\n" + text = text .. "# of total deviations = " .. N .. "\n" + text = text .. "# of large deviations _ = " .. nL .. "\n" + text = text .. "# of normal deviations = " .. nN .. "\n" + text = text .. "# of small deviations ( = " .. nS .. "\n" + self:T2( self.lid .. text ) + -- Special cases. if playerData.wop then --------------------- @@ -12520,65 +11844,65 @@ end if playerData.lig then -- Long In the Groove (LIG). -- According to Stingers this is a CUT pass and gives 1.0 points. - grade="WO" - points=1.0 - G="LIG" + grade = "WO" + points = 1.0 + G = "LIG" else -- Other pattern WO - grade="WOP" - points=2.0 - G="n/a" + grade = "WOP" + points = 2.0 + G = "n/a" end elseif playerData.wofd then ----------------------- -- Foul Deck Waveoff -- ----------------------- if playerData.landed then - --AIRBOSS wants to talk to you! - grade="CUT" - points=0.0 + -- AIRBOSS wants to talk to you! + grade = "CUT" + points = 0.0 else - grade="WOFD" - points=-1.0 + grade = "WOFD" + points = -1.0 end - G="n/a" + G = "n/a" elseif playerData.owo then ----------------- -- Own Waveoff -- ----------------- - grade="OWO" - points=2.0 - if N==0 then - G="n/a" + grade = "OWO" + points = 2.0 + if N == 0 then + G = "n/a" end elseif playerData.waveoff then ------------- -- Waveoff -- ------------- if playerData.landed then - --AIRBOSS wants to talk to you! - grade="CUT" - points=0.0 + -- AIRBOSS wants to talk to you! + grade = "CUT" + points = 0.0 else - grade="WO" - points=1.0 + grade = "WO" + points = 1.0 end elseif playerData.boltered then -- Bolter - grade="-- (BOLTER)" - points=2.5 - - elseif not playerData.hover and playerData.actype==AIRBOSS.AircraftCarrier.AV8B then + grade = "-- (BOLTER)" + points = 2.5 + + elseif not playerData.hover and playerData.actype == AIRBOSS.AircraftCarrier.AV8B then ------------------------------- -- AV-8B not cleared to land -- -- Landing clearence is carrier from LC to Landing - ------------------------------- + ------------------------------- if playerData.landed then -- AIRBOSS wants your balls! - grade="CUT" - points=0.0 + grade = "CUT" + points = 0.0 end - - end + + end return grade, points, G end @@ -12589,175 +11913,171 @@ end -- @param #AIRBOSS.GrooveData fdata Flight data in the groove. -- @return #string LSO grade or empty string if flight data table is nil. -- @return #number Number of deviations from perfect flight path. -function AIRBOSS:_Flightdata2Text(playerData, groovestep) +function AIRBOSS:_Flightdata2Text( playerData, groovestep ) - local function little(text) - return string.format("(%s)",text) + local function little( text ) + return string.format( "(%s)", text ) end - local function underline(text) - return string.format("_%s_", text) + local function underline( text ) + return string.format( "_%s_", text ) end -- Groove Data. - local fdata=playerData.groove[groovestep] --#AIRBOSS.GrooveData + local fdata = playerData.groove[groovestep] -- #AIRBOSS.GrooveData -- No flight data ==> return empty string. - if fdata==nil then - self:T3(self.lid.."Flight data is nil.") + if fdata == nil then + self:T3( self.lid .. "Flight data is nil." ) return "", 0 end -- Flight data. - local step=fdata.Step - local AOA=fdata.AoA - local GSE=fdata.GSE - local LUE=fdata.LUE - local ROL=fdata.Roll + local step = fdata.Step + local AOA = fdata.AoA + local GSE = fdata.GSE + local LUE = fdata.LUE + local ROL = fdata.Roll -- Aircraft specific AoA values. - local acaoa=self:_GetAircraftAoA(playerData) + local acaoa = self:_GetAircraftAoA( playerData ) - --Angled Approach. - local P=nil - if step==AIRBOSS.PatternStep.GROOVE_XX and ROL<=4.0 and playerData.case<3 then - if LUE>self.lue.RIGHT then - P=underline("AA") - elseif - LUE>self.lue.RightMed then - P="AA " - elseif - LUE>self.lue.Right then - P=little("AA") + -- Angled Approach. + local P = nil + if step == AIRBOSS.PatternStep.GROOVE_XX and ROL <= 4.0 and playerData.case < 3 then + if LUE > self.lue.RIGHT then + P = underline( "AA" ) + elseif LUE > self.lue.RightMed then + P = "AA " + elseif LUE > self.lue.Right then + P = little( "AA" ) end end - --Overshoot Start. - local O=nil - if step==AIRBOSS.PatternStep.GROOVE_XX then - if LUEacaoa.SLOW then - S=underline("SLO") - elseif AOA>acaoa.Slow then - S="SLO" - elseif AOA>acaoa.OnSpeedMax then - S=little("SLO") - elseif AOA acaoa.SLOW then + S = underline( "SLO" ) + elseif AOA > acaoa.Slow then + S = "SLO" + elseif AOA > acaoa.OnSpeedMax then + S = little( "SLO" ) + elseif AOA < acaoa.FAST then + S = underline( "F" ) + elseif AOA < acaoa.Fast then + S = "F" + elseif AOA < acaoa.OnSpeedMin then + S = little( "F" ) end -- Glideslope/altitude. Good [-0.3, 0.4] asymmetric! - local A=nil - if GSE>self.gle.HIGH then - A=underline("H") - elseif GSE>self.gle.High then - A="H" - elseif GSE>self.gle._max then - A=little("H") - elseif GSE self.gle.HIGH then + A = underline( "H" ) + elseif GSE > self.gle.High then + A = "H" + elseif GSE > self.gle._max then + A = little( "H" ) + elseif GSE < self.gle.LOW then + A = underline( "LO" ) + elseif GSE < self.gle.Low then + A = "LO" + elseif GSE < self.gle._min then + A = little( "LO" ) end -- Line up. XX Step replaced by Overshoot start (OS). Good [-0.5, 0.5] - local D=nil - if LUE>self.lue.RIGHT then - D=underline("LUL") - elseif LUE>self.lue.Right then - D="LUL" - elseif LUE>self.lue._max then - D=little("LUL") - elseif playerData.case<3 then - if LUE self.lue.RIGHT then + D = underline( "LUL" ) + elseif LUE > self.lue.Right then + D = "LUL" + elseif LUE > self.lue._max then + D = little( "LUL" ) + elseif playerData.case < 3 then + if LUE < self.lue.LEFT and step ~= AIRBOSS.PatternStep.GROOVE_XX then + D = underline( "LUR" ) + elseif LUE < self.lue.Left and step ~= AIRBOSS.PatternStep.GROOVE_XX then + D = "LUR" + elseif LUE < self.lue._min and step ~= AIRBOSS.PatternStep.GROOVE_XX then + D = little( "LUR" ) + end + elseif playerData.case == 3 then + if LUE < self.lue.LEFT then + D = underline( "LUR" ) + elseif LUE < self.lue.Left then + D = "LUR" + elseif LUE < self.lue._min then + D = little( "LUR" ) + end end -- Compile. - local G="" - local n=0 + local G = "" + local n = 0 -- Fly trough. if fdata.FlyThrough then - G=G..fdata.FlyThrough + G = G .. fdata.FlyThrough end -- Angled Approach - doesn't affect score, advisory only. if P then - G=G..P - n=n + G = G .. P + n = n end -- Speed. if S then - G=G..S - n=n+1 + G = G .. S + n = n + 1 end -- Glide slope. if A then - G=G..A - n=n+1 + G = G .. A + n = n + 1 end -- Line up. if D then - G=G..D - n=n+1 + G = G .. D + n = n + 1 end - --Drift in Lineup + -- Drift in Lineup if fdata.Drift then - G=G..fdata.Drift - n=n -- Drift doesn't affect score, advisory only. + G = G .. fdata.Drift + n = n -- Drift doesn't affect score, advisory only. end -- Overshoot. if O then - G=G..O - n=n+1 + G = G .. O + n = n + 1 end -- Add current step. - local step=self:_GS(step) - step=step:gsub("XX","X") - if G~="" then - G=G..step + local step = self:_GS( step ) + step = step:gsub( "XX", "X" ) + if G ~= "" then + G = G .. step end -- Debug info. - local text=string.format("LSO Grade at %s:\n", step) - text=text..string.format("AOA=%.1f\n",AOA) - text=text..string.format("GSE=%.1f\n",GSE) - text=text..string.format("LUE=%.1f\n",LUE) - text=text..string.format("ROL=%.1f\n",ROL) - text=text..G - self:T3(self.lid..text) + local text = string.format( "LSO Grade at %s:\n", step ) + text = text .. string.format( "AOA=%.1f\n", AOA ) + text = text .. string.format( "GSE=%.1f\n", GSE ) + text = text .. string.format( "LUE=%.1f\n", LUE ) + text = text .. string.format( "ROL=%.1f\n", ROL ) + text = text .. G + self:T3( self.lid .. text ) - return G,n + return G, n end --- Get short name of the grove step. @@ -12765,69 +12085,69 @@ end -- @param #string step Player step. -- @param #number n Use -1 for previous or +1 for next. Default 0. -- @return #string Shortcut name "X", "RB", "IM", "AR", "IW". -function AIRBOSS:_GS(step, n) +function AIRBOSS:_GS( step, n ) local gp - n=n or 0 + n = n or 0 - if step==AIRBOSS.PatternStep.FINAL then - gp=AIRBOSS.GroovePos.X0 --"X0" -- Entering the groove. - if n==-1 then - gp=AIRBOSS.GroovePos.X0 -- There is no previous step. - elseif n==1 then - gp=AIRBOSS.GroovePos.XX + if step == AIRBOSS.PatternStep.FINAL then + gp = AIRBOSS.GroovePos.X0 -- "X0" -- Entering the groove. + if n == -1 then + gp = AIRBOSS.GroovePos.X0 -- There is no previous step. + elseif n == 1 then + gp = AIRBOSS.GroovePos.XX end - elseif step==AIRBOSS.PatternStep.GROOVE_XX then - gp=AIRBOSS.GroovePos.XX --"XX" -- Starting the groove. - if n==-1 then - gp=AIRBOSS.GroovePos.X0 - elseif n==1 then - gp=AIRBOSS.GroovePos.IM + elseif step == AIRBOSS.PatternStep.GROOVE_XX then + gp = AIRBOSS.GroovePos.XX -- "XX" -- Starting the groove. + if n == -1 then + gp = AIRBOSS.GroovePos.X0 + elseif n == 1 then + gp = AIRBOSS.GroovePos.IM end - elseif step==AIRBOSS.PatternStep.GROOVE_IM then - gp=AIRBOSS.GroovePos.IM --"IM" -- In the middle. - if n==-1 then - gp=AIRBOSS.GroovePos.XX - elseif n==1 then - gp=AIRBOSS.GroovePos.IC + elseif step == AIRBOSS.PatternStep.GROOVE_IM then + gp = AIRBOSS.GroovePos.IM -- "IM" -- In the middle. + if n == -1 then + gp = AIRBOSS.GroovePos.XX + elseif n == 1 then + gp = AIRBOSS.GroovePos.IC end - elseif step==AIRBOSS.PatternStep.GROOVE_IC then - gp=AIRBOSS.GroovePos.IC --"IC" -- In close. - if n==-1 then - gp=AIRBOSS.GroovePos.IM - elseif n==1 then - gp=AIRBOSS.GroovePos.AR + elseif step == AIRBOSS.PatternStep.GROOVE_IC then + gp = AIRBOSS.GroovePos.IC -- "IC" -- In close. + if n == -1 then + gp = AIRBOSS.GroovePos.IM + elseif n == 1 then + gp = AIRBOSS.GroovePos.AR end - elseif step==AIRBOSS.PatternStep.GROOVE_AR then - gp=AIRBOSS.GroovePos.AR --"AR" -- At the ramp. - if n==-1 then - gp=AIRBOSS.GroovePos.IC - elseif n==1 then - if self.carriertype==AIRBOSS.CarrierType.TARAWA or self.carriertype==AIRBOSS.CarrierType.AMERICA or self.carriertype==AIRBOSS.CarrierType.JCARLOS or self.carriertype==AIRBOSS.CarrierType.CANBERRA then - gp=AIRBOSS.GroovePos.AL + elseif step == AIRBOSS.PatternStep.GROOVE_AR then + gp = AIRBOSS.GroovePos.AR -- "AR" -- At the ramp. + if n == -1 then + gp = AIRBOSS.GroovePos.IC + elseif n == 1 then + if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then + gp = AIRBOSS.GroovePos.AL else - gp=AIRBOSS.GroovePos.IW + gp = AIRBOSS.GroovePos.IW end end - elseif step==AIRBOSS.PatternStep.GROOVE_AL then - gp=AIRBOSS.GroovePos.AL --"AL" -- Abeam landing spot. - if n==-1 then - gp=AIRBOSS.GroovePos.AR - elseif n==1 then - gp=AIRBOSS.GroovePos.LC + elseif step == AIRBOSS.PatternStep.GROOVE_AL then + gp = AIRBOSS.GroovePos.AL -- "AL" -- Abeam landing spot. + if n == -1 then + gp = AIRBOSS.GroovePos.AR + elseif n == 1 then + gp = AIRBOSS.GroovePos.LC end - elseif step==AIRBOSS.PatternStep.GROOVE_LC then - gp=AIRBOSS.GroovePos.LC --"LC" -- Level crossing. - if n==-1 then - gp=AIRBOSS.GroovePos.AL - elseif n==1 then - gp=AIRBOSS.GroovePos.LC + elseif step == AIRBOSS.PatternStep.GROOVE_LC then + gp = AIRBOSS.GroovePos.LC -- "LC" -- Level crossing. + if n == -1 then + gp = AIRBOSS.GroovePos.AL + elseif n == 1 then + gp = AIRBOSS.GroovePos.LC end - elseif step==AIRBOSS.PatternStep.GROOVE_IW then - gp=AIRBOSS.GroovePos.IW --"IW" -- In the wires. - if n==-1 then - gp=AIRBOSS.GroovePos.AR - elseif n==1 then - gp=AIRBOSS.GroovePos.IW -- There is no next step. + elseif step == AIRBOSS.PatternStep.GROOVE_IW then + gp = AIRBOSS.GroovePos.IW -- "IW" -- In the wires. + if n == -1 then + gp = AIRBOSS.GroovePos.AR + elseif n == 1 then + gp = AIRBOSS.GroovePos.IW -- There is no next step. end end return gp @@ -12839,21 +12159,21 @@ end -- @param #number Z Z distance player to carrier. -- @param #AIRBOSS.Checkpoint pos Position data limits. -- @return #boolean If true, approach should be aborted. -function AIRBOSS:_CheckAbort(X, Z, pos) +function AIRBOSS:_CheckAbort( X, Z, pos ) - local abort=false - if pos.Xmin and Xpos.Xmax then - self:T(string.format("Xmax: X=%d > %d=Xmax", X, pos.Xmax)) - abort=true - elseif pos.Zmin and Zpos.Zmax then - self:T(string.format("Zmax: Z=%d > %d=Zmax", Z, pos.Zmax)) - abort=true + local abort = false + if pos.Xmin and X < pos.Xmin then + self:T( string.format( "Xmin: X=%d < %d=Xmin", X, pos.Xmin ) ) + abort = true + elseif pos.Xmax and X > pos.Xmax then + self:T( string.format( "Xmax: X=%d > %d=Xmax", X, pos.Xmax ) ) + abort = true + elseif pos.Zmin and Z < pos.Zmin then + self:T( string.format( "Zmin: Z=%d < %d=Zmin", Z, pos.Zmin ) ) + abort = true + elseif pos.Zmax and Z > pos.Zmax then + self:T( string.format( "Zmax: Z=%d > %d=Zmax", Z, pos.Zmax ) ) + abort = true end return abort @@ -12864,58 +12184,58 @@ end -- @param #number X X distance player to carrier. -- @param #number Z Z distance player to carrier. -- @param #AIRBOSS.Checkpoint posData Checkpoint data. -function AIRBOSS:_TooFarOutText(X, Z, posData) +function AIRBOSS:_TooFarOutText( X, Z, posData ) -- Intro. - local text="you are too " + local text = "you are too " -- X text. - local xtext=nil - if posData.Xmin and XposData.Xmax then - if posData.Xmax>=0 then - xtext="far ahead of " + elseif posData.Xmax and X > posData.Xmax then + if posData.Xmax >= 0 then + xtext = "far ahead of " else - xtext="close to " + xtext = "close to " end end -- Z text. - local ztext=nil - if posData.Zmin and ZposData.Zmax then - if posData.Zmax>=0 then - ztext="far starboard of " + elseif posData.Zmax and Z > posData.Zmax then + if posData.Zmax >= 0 then + ztext = "far starboard of " else - ztext="too close to " + ztext = "too close to " end end -- Combine X-Z text. if xtext and ztext then - text=text..xtext.." and "..ztext + text = text .. xtext .. " and " .. ztext elseif xtext then - text=text..xtext + text = text .. xtext elseif ztext then - text=text..ztext + text = text .. ztext end -- Complete the sentence - text=text.."the carrier." + text = text .. "the carrier." -- If no case could be identified. - if xtext==nil and ztext==nil then - text="you are too far from where you should be!" + if xtext == nil and ztext == nil then + text = "you are too far from where you should be!" end return text @@ -12928,33 +12248,33 @@ end -- @param #number Z Z distance player to carrier. -- @param #AIRBOSS.Checkpoint posData Checkpoint data. -- @param #boolean patternwo (Optional) Pattern wave off. -function AIRBOSS:_AbortPattern(playerData, X, Z, posData, patternwo) +function AIRBOSS:_AbortPattern( playerData, X, Z, posData, patternwo ) -- Text where we are wrong. - local text=self:_TooFarOutText(X, Z, posData) + local text = self:_TooFarOutText( X, Z, posData ) -- Debug. - local dtext=string.format("Abort: X=%d Xmin=%s, Xmax=%s | Z=%d Zmin=%s Zmax=%s", X, tostring(posData.Xmin), tostring(posData.Xmax), Z, tostring(posData.Zmin), tostring(posData.Zmax)) - self:T(self.lid..dtext) + local dtext = string.format( "Abort: X=%d Xmin=%s, Xmax=%s | Z=%d Zmin=%s Zmax=%s", X, tostring( posData.Xmin ), tostring( posData.Xmax ), Z, tostring( posData.Zmin ), tostring( posData.Zmax ) ) + self:T( self.lid .. dtext ) -- Message to player. - self:MessageToPlayer(playerData, text, "LSO") + self:MessageToPlayer( playerData, text, "LSO" ) if patternwo then -- Pattern wave off! - playerData.wop=true + playerData.wop = true -- Add to debrief. - self:_AddToDebrief(playerData, string.format("Pattern wave off: %s", text)) + self:_AddToDebrief( playerData, string.format( "Pattern wave off: %s", text ) ) -- Depart and re-enter radio message. -- TODO: Radio should depend on player step. - self:RadioTransmission(self.LSORadio, self.LSOCall.DEPARTANDREENTER, false, 3, nil, nil, true) + self:RadioTransmission( self.LSORadio, self.LSOCall.DEPARTANDREENTER, false, 3, nil, nil, true ) -- Next step debrief. - playerData.step=AIRBOSS.PatternStep.DEBRIEF - playerData.warning=nil + playerData.step = AIRBOSS.PatternStep.DEBRIEF + playerData.warning = nil end end @@ -12964,7 +12284,7 @@ end -- @param #AIRBOSS.PlayerData playerData Player data table. -- @param #number delay Delay before playing sound messages. Default 0 sec. -- @param #boolean soundoff If true, don't play and sound hint. -function AIRBOSS:_PlayerHint(playerData, delay, soundoff) +function AIRBOSS:_PlayerHint( playerData, delay, soundoff ) -- No hint for the pros. if not playerData.showhints then @@ -12972,195 +12292,193 @@ function AIRBOSS:_PlayerHint(playerData, delay, soundoff) end -- Get optimal altitude, distance and speed. - local alt, aoa, dist, speed=self:_GetAircraftParameters(playerData) + local alt, aoa, dist, speed = self:_GetAircraftParameters( playerData ) -- Get altitude hint. - local hintAlt,debriefAlt,callAlt=self:_AltitudeCheck(playerData, alt) + local hintAlt, debriefAlt, callAlt = self:_AltitudeCheck( playerData, alt ) -- Get speed hint. - local hintSpeed,debriefSpeed,callSpeed=self:_SpeedCheck(playerData, speed) + local hintSpeed, debriefSpeed, callSpeed = self:_SpeedCheck( playerData, speed ) -- Get AoA hint. - local hintAoA,debriefAoA,callAoA=self:_AoACheck(playerData, aoa) + local hintAoA, debriefAoA, callAoA = self:_AoACheck( playerData, aoa ) -- Get distance to the boat hint. - local hintDist,debriefDist,callDist=self:_DistanceCheck(playerData, dist) + local hintDist, debriefDist, callDist = self:_DistanceCheck( playerData, dist ) -- Message to player. - local hint="" - if hintAlt and hintAlt~="" then - hint=hint.."\n"..hintAlt + local hint = "" + if hintAlt and hintAlt ~= "" then + hint = hint .. "\n" .. hintAlt end - if hintSpeed and hintSpeed~="" then - hint=hint.."\n"..hintSpeed + if hintSpeed and hintSpeed ~= "" then + hint = hint .. "\n" .. hintSpeed end - if hintAoA and hintAoA~="" then - hint=hint.."\n"..hintAoA + if hintAoA and hintAoA ~= "" then + hint = hint .. "\n" .. hintAoA end - if hintDist and hintDist~="" then - hint=hint.."\n"..hintDist + if hintDist and hintDist ~= "" then + hint = hint .. "\n" .. hintDist end -- Debriefing text. - local debrief="" - if debriefAlt and debriefAlt~="" then - debrief=debrief.."\n- "..debriefAlt + local debrief = "" + if debriefAlt and debriefAlt ~= "" then + debrief = debrief .. "\n- " .. debriefAlt end - if debriefSpeed and debriefSpeed~="" then - debrief=debrief.."\n- "..debriefSpeed + if debriefSpeed and debriefSpeed ~= "" then + debrief = debrief .. "\n- " .. debriefSpeed end - if debriefAoA and debriefAoA~="" then - debrief=debrief.."\n- "..debriefAoA + if debriefAoA and debriefAoA ~= "" then + debrief = debrief .. "\n- " .. debriefAoA end - if debriefDist and debriefDist~="" then - debrief=debrief.."\n- "..debriefDist + if debriefDist and debriefDist ~= "" then + debrief = debrief .. "\n- " .. debriefDist end -- Add step to debriefing. - if debrief~="" then - self:_AddToDebrief(playerData, debrief) + if debrief ~= "" then + self:_AddToDebrief( playerData, debrief ) end -- Voice hint. - delay=delay or 0 + delay = delay or 0 if not soundoff then if callAlt then - self:Sound2Player(playerData, self.LSORadio, callAlt, false, delay) - delay=delay+callAlt.duration+0.5 + self:Sound2Player( playerData, self.LSORadio, callAlt, false, delay ) + delay = delay + callAlt.duration + 0.5 end if callSpeed then - self:Sound2Player(playerData, self.LSORadio, callSpeed, false, delay) - delay=delay+callSpeed.duration+0.5 + self:Sound2Player( playerData, self.LSORadio, callSpeed, false, delay ) + delay = delay + callSpeed.duration + 0.5 end if callAoA then - self:Sound2Player(playerData, self.LSORadio, callAoA, false, delay) - delay=delay+callAoA.duration+0.5 + self:Sound2Player( playerData, self.LSORadio, callAoA, false, delay ) + delay = delay + callAoA.duration + 0.5 end if callDist then - self:Sound2Player(playerData, self.LSORadio, callDist, false, delay) - delay=delay+callDist.duration+0.5 + self:Sound2Player( playerData, self.LSORadio, callDist, false, delay ) + delay = delay + callDist.duration + 0.5 end end -- ARC IN info. - if playerData.step==AIRBOSS.PatternStep.ARCIN then + if playerData.step == AIRBOSS.PatternStep.ARCIN then -- Hint turn and set TACAN. - if playerData.difficulty==AIRBOSS.Difficulty.EASY then + if playerData.difficulty == AIRBOSS.Difficulty.EASY then -- Get inverse magnetic radial without offset ==> FB for Case II or BRC for Case III. - local radial=self:GetRadial(playerData.case, true, false, true) - local turn="right" - if self.holdingoffset<0 then - turn="left" + local radial = self:GetRadial( playerData.case, true, false, true ) + local turn = "right" + if self.holdingoffset < 0 then + turn = "left" end - hint=hint..string.format("\nTurn %s and select TACAN %03d°.", turn, radial) + hint = hint .. string.format( "\nTurn %s and select TACAN %03d°.", turn, radial ) end end -- DIRTUP additonal info. - if playerData.step==AIRBOSS.PatternStep.DIRTYUP then - if playerData.difficulty==AIRBOSS.Difficulty.EASY then - if playerData.actype==AIRBOSS.AircraftCarrier.AV8B then - hint=hint.."\nFAF! Checks completed. Nozzles 50°." + if playerData.step == AIRBOSS.PatternStep.DIRTYUP then + if playerData.difficulty == AIRBOSS.Difficulty.EASY then + if playerData.actype == AIRBOSS.AircraftCarrier.AV8B then + hint = hint .. "\nFAF! Checks completed. Nozzles 50°." else - --TODO: Tomcat? - hint=hint.."\nDirty up! Hook, gear and flaps down." + -- TODO: Tomcat? + hint = hint .. "\nDirty up! Hook, gear and flaps down." end end end -- BULLSEYE additonal info. - if playerData.step==AIRBOSS.PatternStep.BULLSEYE then + if playerData.step == AIRBOSS.PatternStep.BULLSEYE then -- Hint follow the needles. - if playerData.difficulty==AIRBOSS.Difficulty.EASY then - if playerData.actype==AIRBOSS.AircraftCarrier.HORNET then - hint=hint..string.format("\nIntercept glideslope and follow the needles.") + if playerData.difficulty == AIRBOSS.Difficulty.EASY then + if playerData.actype == AIRBOSS.AircraftCarrier.HORNET then + hint = hint .. string.format( "\nIntercept glideslope and follow the needles." ) else - hint=hint..string.format("\nIntercept glideslope.") + hint = hint .. string.format( "\nIntercept glideslope." ) end end end -- Message to player. - if hint~="" then - local text=string.format("%s%s", playerData.step, hint) - self:MessageToPlayer(playerData, hint, "AIRBOSS", "") + if hint ~= "" then + local text = string.format( "%s%s", playerData.step, hint ) + self:MessageToPlayer( playerData, hint, "AIRBOSS", "" ) end end - --- Display hint for flight students about the (next) step. Message is displayed after one second. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data. -- @param #string step Step for which hint is given. -function AIRBOSS:_StepHint(playerData, step) +function AIRBOSS:_StepHint( playerData, step ) -- Set step. - step=step or playerData.step + step = step or playerData.step -- Message is only for "Flight Students". - if playerData.difficulty==AIRBOSS.Difficulty.EASY and playerData.showhints then + if playerData.difficulty == AIRBOSS.Difficulty.EASY and playerData.showhints then -- Get optimal parameters at step. - local alt, aoa, dist, speed=self:_GetAircraftParameters(playerData, step) + local alt, aoa, dist, speed = self:_GetAircraftParameters( playerData, step ) -- Hint: - local hint="" + local hint = "" -- Altitude. if alt then - hint=hint..string.format("\nAltitude %d ft", UTILS.MetersToFeet(alt)) + hint = hint .. string.format( "\nAltitude %d ft", UTILS.MetersToFeet( alt ) ) end -- AoA. if aoa then - hint=hint..string.format("\nAoA %.1f", self:_AoADeg2Units(playerData, aoa)) + hint = hint .. string.format( "\nAoA %.1f", self:_AoADeg2Units( playerData, aoa ) ) end -- Speed. if speed then - hint=hint..string.format("\nSpeed %d knots", UTILS.MpsToKnots(speed)) + hint = hint .. string.format( "\nSpeed %d knots", UTILS.MpsToKnots( speed ) ) end -- Distance to the boat. if dist then - hint=hint..string.format("\nDistance to the boat %.1f NM", UTILS.MetersToNM(dist)) + hint = hint .. string.format( "\nDistance to the boat %.1f NM", UTILS.MetersToNM( dist ) ) end -- Late break. - if step==AIRBOSS.PatternStep.LATEBREAK then - if playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then - hint=hint.."\nWing Sweep 20°, Gear DOWN < 280 KIAS." + if step == AIRBOSS.PatternStep.LATEBREAK then + if playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B then + hint = hint .. "\nWing Sweep 20°, Gear DOWN < 280 KIAS." end end -- Abeam. - if step==AIRBOSS.PatternStep.ABEAM then - if playerData.actype==AIRBOSS.AircraftCarrier.AV8B then - hint=hint.."\nNozzles 50°-60°. Antiskid OFF. Lights OFF." - elseif playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then - hint=hint.."\nSlats/Flaps EXTENDED < 225 KIAS. DLC SELECTED. Auto Throttle IF DESIRED." + if step == AIRBOSS.PatternStep.ABEAM then + if playerData.actype == AIRBOSS.AircraftCarrier.AV8B then + hint = hint .. "\nNozzles 50°-60°. Antiskid OFF. Lights OFF." + elseif playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B then + hint = hint .. "\nSlats/Flaps EXTENDED < 225 KIAS. DLC SELECTED. Auto Throttle IF DESIRED." else - hint=hint.."\nDirty up! Gear DOWN, flaps DOWN. Check hook down." + hint = hint .. "\nDirty up! Gear DOWN, flaps DOWN. Check hook down." end end -- Check if there was actually anything to tell. - if hint~="" then + if hint ~= "" then -- Compile text if any. - local text=string.format("Optimal setup at next step %s:%s", step, hint) + local text = string.format( "Optimal setup at next step %s:%s", step, hint ) -- Send hint to player. - self:MessageToPlayer(playerData, text, "AIRBOSS", "", nil, false, 1) + self:MessageToPlayer( playerData, text, "AIRBOSS", "", nil, false, 1 ) end end end - --- Evaluate player's altitude at checkpoint. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data table. @@ -13168,57 +12486,57 @@ end -- @return #string Feedback text. -- @return #string Debriefing text. -- @return #AIRBOSS.RadioCall Radio call. -function AIRBOSS:_AltitudeCheck(playerData, altopt) +function AIRBOSS:_AltitudeCheck( playerData, altopt ) - if altopt==nil then + if altopt == nil then return nil, nil end -- Player altitude. - local altitude=playerData.unit:GetAltitude() + local altitude = playerData.unit:GetAltitude() -- Get relative score. - local lowscore, badscore=self:_GetGoodBadScore(playerData) + local lowscore, badscore = self:_GetGoodBadScore( playerData ) -- Altitude error +-X% - local _error=(altitude-altopt)/altopt*100 + local _error = (altitude - altopt) / altopt * 100 -- Radio call for flight students. - local radiocall=nil --#AIRBOSS.RadioCall + local radiocall = nil -- #AIRBOSS.RadioCall - local hint="" - if _error>badscore then - --hint=string.format("You're high.") - radiocall=self:_NewRadioCall(self.LSOCall.HIGH, "Paddles", "") - elseif _error>lowscore then - --hint= string.format("You're slightly high.") - radiocall=self:_NewRadioCall(self.LSOCall.HIGH, "Paddles", "") - elseif _error<-badscore then - --hint=string.format("You're low. ") - radiocall=self:_NewRadioCall(self.LSOCall.LOW, "Paddles", "") - elseif _error<-lowscore then - --hint=string.format("You're slightly low.") - radiocall=self:_NewRadioCall(self.LSOCall.LOW, "Paddles", "") + local hint = "" + if _error > badscore then + -- hint=string.format("You're high.") + radiocall = self:_NewRadioCall( self.LSOCall.HIGH, "Paddles", "" ) + elseif _error > lowscore then + -- hint= string.format("You're slightly high.") + radiocall = self:_NewRadioCall( self.LSOCall.HIGH, "Paddles", "" ) + elseif _error < -badscore then + -- hint=string.format("You're low. ") + radiocall = self:_NewRadioCall( self.LSOCall.LOW, "Paddles", "" ) + elseif _error < -lowscore then + -- hint=string.format("You're slightly low.") + radiocall = self:_NewRadioCall( self.LSOCall.LOW, "Paddles", "" ) else - hint=string.format("Good altitude. ") + hint = string.format( "Good altitude. " ) end -- Extend or decrease depending on skill. - if playerData.difficulty==AIRBOSS.Difficulty.EASY then + if playerData.difficulty == AIRBOSS.Difficulty.EASY then -- Also inform students about the optimal altitude. - hint=hint..string.format("Optimal altitude is %d ft.", UTILS.MetersToFeet(altopt)) - elseif playerData.difficulty==AIRBOSS.Difficulty.NORMAL then + hint = hint .. string.format( "Optimal altitude is %d ft.", UTILS.MetersToFeet( altopt ) ) + elseif playerData.difficulty == AIRBOSS.Difficulty.NORMAL then -- We keep it short normally. - hint="" - elseif playerData.difficulty==AIRBOSS.Difficulty.HARD then + hint = "" + elseif playerData.difficulty == AIRBOSS.Difficulty.HARD then -- No hint at all for the pros. - hint="" + hint = "" end -- Debrief text. - local debrief=string.format("Altitude %d ft = %d%% deviation from %d ft.", UTILS.MetersToFeet(altitude), _error, UTILS.MetersToFeet(altopt)) + local debrief = string.format( "Altitude %d ft = %d%% deviation from %d ft.", UTILS.MetersToFeet( altitude ), _error, UTILS.MetersToFeet( altopt ) ) - return hint, debrief,radiocall + return hint, debrief, radiocall end --- Score for correct AoA. @@ -13228,65 +12546,65 @@ end -- @return #string Feedback message text or easy and normal difficulty level or nil for hard. -- @return #string Debriefing text. -- @return #AIRBOSS.RadioCall Radio call. -function AIRBOSS:_AoACheck(playerData, optaoa) +function AIRBOSS:_AoACheck( playerData, optaoa ) - if optaoa==nil then + if optaoa == nil then return nil, nil end -- Get relative score. - local lowscore, badscore = self:_GetGoodBadScore(playerData) + local lowscore, badscore = self:_GetGoodBadScore( playerData ) -- Player AoA - local aoa=playerData.unit:GetAoA() + local aoa = playerData.unit:GetAoA() -- Altitude error +-X% - local _error=(aoa-optaoa)/optaoa*100 + local _error = (aoa - optaoa) / optaoa * 100 -- Get aircraft AoA parameters. - local aircraftaoa=self:_GetAircraftAoA(playerData) + local aircraftaoa = self:_GetAircraftAoA( playerData ) - -- Radio call for flight students. - local radiocall=nil --#AIRBOSS.RadioCall + -- Radio call for flight students. + local radiocall = nil -- #AIRBOSS.RadioCall -- Rate aoa. - local hint="" - if aoa>=aircraftaoa.SLOW then - --hint="Your're slow!" - radiocall=self:_NewRadioCall(self.LSOCall.SLOW, "Paddles", "") - elseif aoa>=aircraftaoa.Slow then - --hint="Your're slow." - radiocall=self:_NewRadioCall(self.LSOCall.SLOW, "Paddles", "") - elseif aoa>=aircraftaoa.OnSpeedMax then - hint="Your're a little slow. " - elseif aoa>=aircraftaoa.OnSpeedMin then - hint="You're on speed. " - elseif aoa>=aircraftaoa.Fast then - hint="You're a little fast. " - elseif aoa>=aircraftaoa.FAST then - --hint="Your're fast." - radiocall=self:_NewRadioCall(self.LSOCall.FAST, "Paddles", "") + local hint = "" + if aoa >= aircraftaoa.SLOW then + -- hint="Your're slow!" + radiocall = self:_NewRadioCall( self.LSOCall.SLOW, "Paddles", "" ) + elseif aoa >= aircraftaoa.Slow then + -- hint="Your're slow." + radiocall = self:_NewRadioCall( self.LSOCall.SLOW, "Paddles", "" ) + elseif aoa >= aircraftaoa.OnSpeedMax then + hint = "Your're a little slow. " + elseif aoa >= aircraftaoa.OnSpeedMin then + hint = "You're on speed. " + elseif aoa >= aircraftaoa.Fast then + hint = "You're a little fast. " + elseif aoa >= aircraftaoa.FAST then + -- hint="Your're fast." + radiocall = self:_NewRadioCall( self.LSOCall.FAST, "Paddles", "" ) else - --hint="You're fast!" - radiocall=self:_NewRadioCall(self.LSOCall.FAST, "Paddles", "") + -- hint="You're fast!" + radiocall = self:_NewRadioCall( self.LSOCall.FAST, "Paddles", "" ) end -- Extend or decrease depending on skill. - if playerData.difficulty==AIRBOSS.Difficulty.EASY then + if playerData.difficulty == AIRBOSS.Difficulty.EASY then -- Also inform students about optimal value. - hint=hint..string.format("Optimal AoA is %.1f.", self:_AoADeg2Units(playerData, optaoa)) - elseif playerData.difficulty==AIRBOSS.Difficulty.NORMAL then + hint = hint .. string.format( "Optimal AoA is %.1f.", self:_AoADeg2Units( playerData, optaoa ) ) + elseif playerData.difficulty == AIRBOSS.Difficulty.NORMAL then -- We keep is short normally. - hint="" - elseif playerData.difficulty==AIRBOSS.Difficulty.HARD then + hint = "" + elseif playerData.difficulty == AIRBOSS.Difficulty.HARD then -- No hint at all for the pros. - hint="" + hint = "" end -- Debriefing text. - local debrief=string.format("AoA %.1f = %d%% deviation from %.1f.", self:_AoADeg2Units(playerData, aoa), _error, self:_AoADeg2Units(playerData, optaoa)) + local debrief = string.format( "AoA %.1f = %d%% deviation from %.1f.", self:_AoADeg2Units( playerData, aoa ), _error, self:_AoADeg2Units( playerData, optaoa ) ) - return hint, debrief,radiocall + return hint, debrief, radiocall end --- Evaluate player's speed. @@ -13296,54 +12614,54 @@ end -- @return #string Feedback text. -- @return #string Debriefing text. -- @return #AIRBOSS.RadioCall Radio call. -function AIRBOSS:_SpeedCheck(playerData, speedopt) +function AIRBOSS:_SpeedCheck( playerData, speedopt ) - if speedopt==nil then + if speedopt == nil then return nil, nil end -- Player altitude. - local speed=playerData.unit:GetVelocityMPS() + local speed = playerData.unit:GetVelocityMPS() -- Get relative score. - local lowscore, badscore=self:_GetGoodBadScore(playerData) + local lowscore, badscore = self:_GetGoodBadScore( playerData ) -- Altitude error +-X% - local _error=(speed-speedopt)/speedopt*100 + local _error = (speed - speedopt) / speedopt * 100 - -- Radio call for flight students. - local radiocall=nil --#AIRBOSS.RadioCall + -- Radio call for flight students. + local radiocall = nil -- #AIRBOSS.RadioCall - local hint="" - if _error>badscore then - --hint=string.format("You're fast.") - radiocall=self:_NewRadioCall(self.LSOCall.FAST, "AIRBOSS", "") - elseif _error>lowscore then - --hint= string.format("You're slightly fast.") - radiocall=self:_NewRadioCall(self.LSOCall.FAST, "AIRBOSS", "") - elseif _error<-badscore then - --hint=string.format("You're slow.") - radiocall=self:_NewRadioCall(self.LSOCall.SLOW, "AIRBOSS", "") - elseif _error<-lowscore then - --hint=string.format("You're slightly slow.") - radiocall=self:_NewRadioCall(self.LSOCall.SLOW, "AIRBOSS", "") + local hint = "" + if _error > badscore then + -- hint=string.format("You're fast.") + radiocall = self:_NewRadioCall( self.LSOCall.FAST, "AIRBOSS", "" ) + elseif _error > lowscore then + -- hint= string.format("You're slightly fast.") + radiocall = self:_NewRadioCall( self.LSOCall.FAST, "AIRBOSS", "" ) + elseif _error < -badscore then + -- hint=string.format("You're slow.") + radiocall = self:_NewRadioCall( self.LSOCall.SLOW, "AIRBOSS", "" ) + elseif _error < -lowscore then + -- hint=string.format("You're slightly slow.") + radiocall = self:_NewRadioCall( self.LSOCall.SLOW, "AIRBOSS", "" ) else - hint=string.format("Good speed. ") + hint = string.format( "Good speed. " ) end -- Extend or decrease depending on skill. - if playerData.difficulty==AIRBOSS.Difficulty.EASY then - hint=hint..string.format("Optimal speed is %d knots.", UTILS.MpsToKnots(speedopt)) - elseif playerData.difficulty==AIRBOSS.Difficulty.NORMAL then + if playerData.difficulty == AIRBOSS.Difficulty.EASY then + hint = hint .. string.format( "Optimal speed is %d knots.", UTILS.MpsToKnots( speedopt ) ) + elseif playerData.difficulty == AIRBOSS.Difficulty.NORMAL then -- We keep is short normally. - hint="" - elseif playerData.difficulty==AIRBOSS.Difficulty.HARD then + hint = "" + elseif playerData.difficulty == AIRBOSS.Difficulty.HARD then -- No hint at all for pros. - hint="" + hint = "" end -- Debrief text. - local debrief=string.format("Speed %d knots = %d%% deviation from %d knots.", UTILS.MpsToKnots(speed), _error, UTILS.MpsToKnots(speedopt)) + local debrief = string.format( "Speed %d knots = %d%% deviation from %d knots.", UTILS.MpsToKnots( speed ), _error, UTILS.MpsToKnots( speedopt ) ) return hint, debrief, radiocall end @@ -13355,48 +12673,48 @@ end -- @return #string Feedback message text. -- @return #string Debriefing text. -- @return #AIRBOSS.RadioCall Distance radio call. Not implemented yet. -function AIRBOSS:_DistanceCheck(playerData, optdist) +function AIRBOSS:_DistanceCheck( playerData, optdist ) - if optdist==nil then + if optdist == nil then return nil, nil end -- Distance to carrier. - local distance=playerData.unit:GetCoordinate():Get2DDistance(self:GetCoordinate()) + local distance = playerData.unit:GetCoordinate():Get2DDistance( self:GetCoordinate() ) -- Get relative score. - local lowscore, badscore = self:_GetGoodBadScore(playerData) + local lowscore, badscore = self:_GetGoodBadScore( playerData ) -- Altitude error +-X% - local _error=(distance-optdist)/optdist*100 + local _error = (distance - optdist) / optdist * 100 local hint - if _error>badscore then - hint=string.format("You're too far from the boat!") - elseif _error>lowscore then - hint=string.format("You're slightly too far from the boat.") - elseif _error<-badscore then - hint=string.format( "You're too close to the boat!") - elseif _error<-lowscore then - hint=string.format("You're slightly too far from the boat.") + if _error > badscore then + hint = string.format( "You're too far from the boat!" ) + elseif _error > lowscore then + hint = string.format( "You're slightly too far from the boat." ) + elseif _error < -badscore then + hint = string.format( "You're too close to the boat!" ) + elseif _error < -lowscore then + hint = string.format( "You're slightly too far from the boat." ) else - hint=string.format("Good distance to the boat.") + hint = string.format( "Good distance to the boat." ) end -- Extend or decrease depending on skill. - if playerData.difficulty==AIRBOSS.Difficulty.EASY then + if playerData.difficulty == AIRBOSS.Difficulty.EASY then -- Also inform students about optimal value. - hint=hint..string.format(" Optimal distance is %.1f NM.", UTILS.MetersToNM(optdist)) - elseif playerData.difficulty==AIRBOSS.Difficulty.NORMAL then + hint = hint .. string.format( " Optimal distance is %.1f NM.", UTILS.MetersToNM( optdist ) ) + elseif playerData.difficulty == AIRBOSS.Difficulty.NORMAL then -- We keep it short normally. - hint="" - elseif playerData.difficulty==AIRBOSS.Difficulty.HARD then + hint = "" + elseif playerData.difficulty == AIRBOSS.Difficulty.HARD then -- No hint at all for the pros. - hint="" + hint = "" end -- Debriefing text. - local debrief=string.format("Distance %.1f NM = %d%% deviation from %.1f NM.",UTILS.MetersToNM(distance), _error, UTILS.MetersToNM(optdist)) + local debrief = string.format( "Distance %.1f NM = %d%% deviation from %.1f NM.", UTILS.MetersToNM( distance ), _error, UTILS.MetersToNM( optdist ) ) return hint, debrief, nil end @@ -13410,122 +12728,120 @@ end -- @param #AIRBOSS.PlayerData playerData Player data. -- @param #string hint Debrief text of this step. -- @param #string step (Optional) Current step in the pattern. Default from playerData. -function AIRBOSS:_AddToDebrief(playerData, hint, step) - step=step or playerData.step - table.insert(playerData.debrief, {step=step, hint=hint}) +function AIRBOSS:_AddToDebrief( playerData, hint, step ) + step = step or playerData.step + table.insert( playerData.debrief, { step = step, hint = hint } ) end --- Debrief player and set next step. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data. -function AIRBOSS:_Debrief(playerData) - self:F(self.lid..string.format("Debriefing of player %s.", playerData.name)) +function AIRBOSS:_Debrief( playerData ) + self:F( self.lid .. string.format( "Debriefing of player %s.", playerData.name ) ) -- Delete scheduler ID. - playerData.debriefschedulerID=nil + playerData.debriefschedulerID = nil -- Switch attitude monitor off if on. - playerData.attitudemonitor=false + playerData.attitudemonitor = false -- LSO grade, points, and flight data analyis. - local grade, points, analysis=self:_LSOgrade(playerData) + local grade, points, analysis = self:_LSOgrade( playerData ) -- Insert points to table of all points until player landed. - if points and points>=0 then - table.insert(playerData.points, points) + if points and points >= 0 then + table.insert( playerData.points, points ) end -- Player has landed and is not airborne any more. - local Points=0 + local Points = 0 if playerData.landed and not playerData.unit:InAir() then -- Average over all points received so far. - for _,_points in pairs(playerData.points) do - Points=Points+_points + for _, _points in pairs( playerData.points ) do + Points = Points + _points end -- This is the final points. - Points=Points/#playerData.points + Points = Points / #playerData.points -- Reset points array. - playerData.points={} + playerData.points = {} else -- Player boltered or was waved off ==> We display the normal points. - Points=points + Points = points end -- My LSO grade. - local mygrade={} --#AIRBOSS.LSOgrade - mygrade.grade=grade - mygrade.points=points - mygrade.details=analysis - mygrade.wire=playerData.wire - mygrade.Tgroove=playerData.Tgroove + local mygrade = {} -- #AIRBOSS.LSOgrade + mygrade.grade = grade + mygrade.points = points + mygrade.details = analysis + mygrade.wire = playerData.wire + mygrade.Tgroove = playerData.Tgroove if playerData.landed and not playerData.unit:InAir() then - mygrade.finalscore=Points + mygrade.finalscore = Points end - mygrade.case=playerData.case - local windondeck=self:GetWindOnDeck() - mygrade.wind=tostring(UTILS.Round(UTILS.MpsToKnots(windondeck), 1)) - mygrade.modex=playerData.onboard - mygrade.airframe=playerData.actype - mygrade.carriertype=self.carriertype - mygrade.carriername=self.alias - mygrade.theatre=self.theatre - mygrade.mitime=UTILS.SecondsToClock(timer.getAbsTime()) - mygrade.midate=UTILS.GetDCSMissionDate() - mygrade.osdate="n/a" + mygrade.case = playerData.case + local windondeck = self:GetWindOnDeck() + mygrade.wind = tostring( UTILS.Round( UTILS.MpsToKnots( windondeck ), 1 ) ) + mygrade.modex = playerData.onboard + mygrade.airframe = playerData.actype + mygrade.carriertype = self.carriertype + mygrade.carriername = self.alias + mygrade.theatre = self.theatre + mygrade.mitime = UTILS.SecondsToClock( timer.getAbsTime() ) + mygrade.midate = UTILS.GetDCSMissionDate() + mygrade.osdate = "n/a" if os then - mygrade.osdate=os.date() --os.date("%d.%m.%Y") + mygrade.osdate = os.date() -- os.date("%d.%m.%Y") end -- Save trap sheet. if playerData.trapon and self.trapsheet then - self:_SaveTrapSheet(playerData, mygrade) + self:_SaveTrapSheet( playerData, mygrade ) end -- Add LSO grade to player grades table. - table.insert(self.playerscores[playerData.name], mygrade) + table.insert( self.playerscores[playerData.name], mygrade ) -- Trigger grading event. - self:LSOGrade(playerData, mygrade) + self:LSOGrade( playerData, mygrade ) -- LSO grade: (OK) 3.0 PT - LURIM - local text=string.format("%s %.1f PT - %s", grade, Points, analysis) - if Points==-1 then - text=string.format("%s n/a PT - Foul deck", grade, Points, analysis) + local text = string.format( "%s %.1f PT - %s", grade, Points, analysis ) + if Points == -1 then + text = string.format( "%s n/a PT - Foul deck", grade, Points, analysis ) end -- Wire and Groove time only if not pattern WO. if not (playerData.wop or playerData.wofd) then -- Wire trapped. Not if pattern WI. - if playerData.wire and playerData.wire<=4 then - text=text..string.format(" %d-wire", playerData.wire) + if playerData.wire and playerData.wire <= 4 then + text = text .. string.format( " %d-wire", playerData.wire ) end -- Time in the groove. Only Case I/II and not pattern WO. - if playerData.Tgroove and playerData.Tgroove<=360 and playerData.case<3 then - text=text..string.format("\nTime in the groove %.1f seconds: %s", playerData.Tgroove, self:_EvalGrooveTime(playerData)) + if playerData.Tgroove and playerData.Tgroove <= 360 and playerData.case < 3 then + text = text .. string.format( "\nTime in the groove %.1f seconds: %s", playerData.Tgroove, self:_EvalGrooveTime( playerData ) ) end end -- Copy debriefing text. - playerData.lastdebrief=UTILS.DeepCopy(playerData.debrief) + playerData.lastdebrief = UTILS.DeepCopy( playerData.debrief ) -- Info text. - if playerData.difficulty==AIRBOSS.Difficulty.EASY then - text=text..string.format("\nYour detailed debriefing can be found via the F10 radio menu.") + if playerData.difficulty == AIRBOSS.Difficulty.EASY then + text = text .. string.format( "\nYour detailed debriefing can be found via the F10 radio menu." ) end -- Message. - self:MessageToPlayer(playerData, text, "LSO", "", 30, true) - + self:MessageToPlayer( playerData, text, "LSO", "", 30, true ) -- Set step to undefined and check if other cases apply. - playerData.step=AIRBOSS.PatternStep.UNDEFINED - + playerData.step = AIRBOSS.PatternStep.UNDEFINED -- Check what happened? if playerData.wop then @@ -13546,41 +12862,41 @@ function AIRBOSS:_Debrief(playerData) -- Heading and distance tip. local heading, distance - if playerData.case==1 or playerData.case==2 then + if playerData.case == 1 or playerData.case == 2 then -- Next step: Initial again. - playerData.step=AIRBOSS.PatternStep.INITIAL + playerData.step = AIRBOSS.PatternStep.INITIAL -- Create a point 3.0 NM astern for re-entry. - local initial=self:GetCoordinate():Translate(UTILS.NMToMeters(3.5), self:GetRadial(2, false, false, false)) + local initial = self:GetCoordinate():Translate( UTILS.NMToMeters( 3.5 ), self:GetRadial( 2, false, false, false ) ) -- Get heading and distance to initial zone ~3 NM astern. - heading=playerData.unit:GetCoordinate():HeadingTo(initial) - distance=playerData.unit:GetCoordinate():Get2DDistance(initial) + heading = playerData.unit:GetCoordinate():HeadingTo( initial ) + distance = playerData.unit:GetCoordinate():Get2DDistance( initial ) - elseif playerData.case==3 then + elseif playerData.case == 3 then -- Next step? Bullseye for now. -- TODO: Could be DIRTY UP or PLATFORM or even back to MARSHAL STACK? - playerData.step=AIRBOSS.PatternStep.BULLSEYE + playerData.step = AIRBOSS.PatternStep.BULLSEYE -- Get heading and distance to bullseye zone ~3 NM astern. - local zone=self:_GetZoneBullseye(playerData.case) + local zone = self:_GetZoneBullseye( playerData.case ) - heading=playerData.unit:GetCoordinate():HeadingTo(zone:GetCoordinate()) - distance=playerData.unit:GetCoordinate():Get2DDistance(zone:GetCoordinate()) + heading = playerData.unit:GetCoordinate():HeadingTo( zone:GetCoordinate() ) + distance = playerData.unit:GetCoordinate():Get2DDistance( zone:GetCoordinate() ) end -- Re-enter message. - local text=string.format("fly heading %03d° for %d NM to re-enter the pattern.", heading, UTILS.MetersToNM(distance)) - self:MessageToPlayer(playerData, text, "LSO", nil, nil, false, 5) + local text = string.format( "fly heading %03d° for %d NM to re-enter the pattern.", heading, UTILS.MetersToNM( distance ) ) + self:MessageToPlayer( playerData, text, "LSO", nil, nil, false, 5 ) else -- Unit does not seem to be alive! -- TODO: What now? - self:E(self.lid..string.format("ERROR: Player unit not alive!")) + self:E( self.lid .. string.format( "ERROR: Player unit not alive!" ) ) end @@ -13593,16 +12909,16 @@ function AIRBOSS:_Debrief(playerData) if playerData.unit:InAir() then -- Bolter pattern. Then Abeam or bullseye. - playerData.step=AIRBOSS.PatternStep.BOLTER + playerData.step = AIRBOSS.PatternStep.BOLTER else -- Welcome aboard! - self:Sound2Player(playerData, self.LSORadio, self.LSOCall.WELCOMEABOARD) + self:Sound2Player( playerData, self.LSORadio, self.LSOCall.WELCOMEABOARD ) -- Airboss talkto! - local text=string.format("deck was fouled but you landed anyway. Airboss wants to talk to you!") - self:MessageToPlayer(playerData, text, "LSO", nil, nil, false, 3) + local text = string.format( "deck was fouled but you landed anyway. Airboss wants to talk to you!" ) + self:MessageToPlayer( playerData, text, "LSO", nil, nil, false, 3 ) end @@ -13615,18 +12931,17 @@ function AIRBOSS:_Debrief(playerData) if playerData.unit:InAir() then -- Bolter pattern. Then Abeam or bullseye. - playerData.step=AIRBOSS.PatternStep.BOLTER + playerData.step = AIRBOSS.PatternStep.BOLTER else -- Welcome aboard! -- NOTE: This should not happen as owo is only triggered if player flew past the carrier. - self:E(self.lid.."ERROR: player landed when OWO was issues. This should not happen. Please report!") - self:Sound2Player(playerData, self.LSORadio, self.LSOCall.WELCOMEABOARD) + self:E( self.lid .. "ERROR: player landed when OWO was issues. This should not happen. Please report!" ) + self:Sound2Player( playerData, self.LSORadio, self.LSOCall.WELCOMEABOARD ) end - elseif playerData.waveoff then -------------- @@ -13636,16 +12951,16 @@ function AIRBOSS:_Debrief(playerData) if playerData.unit:InAir() then -- Bolter pattern. Then Abeam or bullseye. - playerData.step=AIRBOSS.PatternStep.BOLTER + playerData.step = AIRBOSS.PatternStep.BOLTER else -- Welcome aboard! - self:Sound2Player(playerData, self.LSORadio, self.LSOCall.WELCOMEABOARD) + self:Sound2Player( playerData, self.LSORadio, self.LSOCall.WELCOMEABOARD ) -- Airboss talkto! - local text=string.format("you were waved off but landed anyway. Airboss wants to talk to you!") - self:MessageToPlayer(playerData, text, "LSO", nil, nil, false, 3) + local text = string.format( "you were waved off but landed anyway. Airboss wants to talk to you!" ) + self:MessageToPlayer( playerData, text, "LSO", nil, nil, false, 3 ) end @@ -13658,7 +12973,7 @@ function AIRBOSS:_Debrief(playerData) if playerData.unit:InAir() then -- Bolter pattern. Then Abeam or bullseye. - playerData.step=AIRBOSS.PatternStep.BOLTER + playerData.step = AIRBOSS.PatternStep.BOLTER end @@ -13668,47 +12983,47 @@ function AIRBOSS:_Debrief(playerData) -- Landed -- ------------ - if not playerData.unit:InAir() then + if not playerData.unit:InAir() then -- Welcome aboard! - self:Sound2Player(playerData, self.LSORadio, self.LSOCall.WELCOMEABOARD) + self:Sound2Player( playerData, self.LSORadio, self.LSOCall.WELCOMEABOARD ) end else -- Message to player. - self:MessageToPlayer(playerData, "Undefined state after landing! Please report.", "ERROR", nil, 20) + self:MessageToPlayer( playerData, "Undefined state after landing! Please report.", "ERROR", nil, 20 ) -- Next step. - playerData.step=AIRBOSS.PatternStep.UNDEFINED + playerData.step = AIRBOSS.PatternStep.UNDEFINED end -- Player landed and is not in air anymore. if playerData.landed and not playerData.unit:InAir() then -- Set recovered flag. - self:_RecoveredElement(playerData.unit) + self:_RecoveredElement( playerData.unit ) -- Check if all elements - self:_CheckSectionRecovered(playerData) + self:_CheckSectionRecovered( playerData ) end -- Increase number of passes. - playerData.passes=playerData.passes+1 + playerData.passes = playerData.passes + 1 -- Next step hint for students if any. - self:_StepHint(playerData) + self:_StepHint( playerData ) -- Reinitialize player data for new approach. - self:_InitPlayer(playerData, playerData.step) + self:_InitPlayer( playerData, playerData.step ) -- Debug message. - MESSAGE:New(string.format("Player step %s.", playerData.step), 5, "DEBUG"):ToAllIf(self.Debug) + MESSAGE:New( string.format( "Player step %s.", playerData.step ), 5, "DEBUG" ):ToAllIf( self.Debug ) -- Auto save player results. if self.autosave and mygrade.finalscore then - self:Save(self.autosavepath, self.autosavefile) + self:Save( self.autosavepath, self.autosavefile ) end end @@ -13722,80 +13037,79 @@ end -- @param Core.Point#COORDINATE coordfrom Coordinate from which the collision is check. -- @return #boolean If true, surface type ahead is not deep water. -- @return #number Max free distance in meters. -function AIRBOSS:_CheckCollisionCoord(coordto, coordfrom) +function AIRBOSS:_CheckCollisionCoord( coordto, coordfrom ) -- Increment in meters. - local dx=100 + local dx = 100 -- From coordinate. Default 500 in front of the carrier. - local d=0 + local d = 0 if coordfrom then - d=0 + d = 0 else - d=250 - coordfrom=self:GetCoordinate():Translate(d, self:GetHeading()) + d = 250 + coordfrom = self:GetCoordinate():Translate( d, self:GetHeading() ) end -- Distance between the two coordinates. - local dmax=coordfrom:Get2DDistance(coordto) + local dmax = coordfrom:Get2DDistance( coordto ) -- Direction. - local direction=coordfrom:HeadingTo(coordto) + local direction = coordfrom:HeadingTo( coordto ) -- Scan path between the two coordinates. - local clear=true - while d<=dmax do + local clear = true + while d <= dmax do -- Check point. - local cp=coordfrom:Translate(d, direction) + local cp = coordfrom:Translate( d, direction ) -- Check if surface type is water. if not cp:IsSurfaceTypeWater() then -- Debug mark points. if self.Debug then - local st=cp:GetSurfaceType() - cp:MarkToAll(string.format("Collision check surface type %d", st)) + local st = cp:GetSurfaceType() + cp:MarkToAll( string.format( "Collision check surface type %d", st ) ) end -- Collision WARNING! - clear=false + clear = false break end -- Increase distance. - d=d+dx + d = d + dx end - local text="" + local text = "" if clear then - text=string.format("Path into direction %03d° is clear for the next %.1f NM.", direction, UTILS.MetersToNM(d)) + text = string.format( "Path into direction %03d° is clear for the next %.1f NM.", direction, UTILS.MetersToNM( d ) ) else - text=string.format("Detected obstacle at distance %.1f NM into direction %03d°.", UTILS.MetersToNM(d), direction) + text = string.format( "Detected obstacle at distance %.1f NM into direction %03d°.", UTILS.MetersToNM( d ), direction ) end - self:T2(self.lid..text) + self:T2( self.lid .. text ) return not clear, d end - --- Check Collision. -- @param #AIRBOSS self -- @param Core.Point#COORDINATE fromcoord Coordinate from which the path to the next WP is calculated. Default current carrier position. -- @return #boolean If true, surface type ahead is not deep water. -function AIRBOSS:_CheckFreePathToNextWP(fromcoord) +function AIRBOSS:_CheckFreePathToNextWP( fromcoord ) -- Position. - fromcoord=fromcoord or self:GetCoordinate():Translate(250, self:GetHeading()) + fromcoord = fromcoord or self:GetCoordinate():Translate( 250, self:GetHeading() ) -- Next wp = current+1 (or last) - local Nnextwp=math.min(self.currentwp+1, #self.waypoints) + local Nnextwp = math.min( self.currentwp + 1, #self.waypoints ) -- Next waypoint. - local nextwp=self.waypoints[Nnextwp] --Core.Point#COORDINATE + local nextwp = self.waypoints[Nnextwp] -- Core.Point#COORDINATE -- Check for collision. - local collision=self:_CheckCollisionCoord(nextwp, fromcoord) + local collision = self:_CheckCollisionCoord( nextwp, fromcoord ) return collision end @@ -13805,59 +13119,57 @@ end function AIRBOSS:_Pathfinder() -- Heading and current coordiante. - local hdg=self:GetHeading() - local cv=self:GetCoordinate() + local hdg = self:GetHeading() + local cv = self:GetCoordinate() -- Possible directions. - local directions={-20, 20, -30, 30, -40, 40, -50, 50, -60, 60, -70, 70, -80, 80, -90, 90, -100, 100} + local directions = { -20, 20, -30, 30, -40, 40, -50, 50, -60, 60, -70, 70, -80, 80, -90, 90, -100, 100 } -- Starboard turns up to 90 degrees. - for _,_direction in pairs(directions) do + for _, _direction in pairs( directions ) do -- New direction. - local direction=hdg+_direction + local direction = hdg + _direction -- Check for collisions in the next 20 NM of the current direction. - local _, dfree=self:_CheckCollisionCoord(cv:Translate(UTILS.NMToMeters(20), direction), cv) + local _, dfree = self:_CheckCollisionCoord( cv:Translate( UTILS.NMToMeters( 20 ), direction ), cv ) -- Loop over distances and find the first one which gives a clear path to the next waypoint. - local distance=500 - while distance<=dfree do + local distance = 500 + while distance <= dfree do -- Coordinate from which we calculate the path. - local fromcoord=cv:Translate(distance, direction) + local fromcoord = cv:Translate( distance, direction ) -- Check for collision between point and next waypoint. - local collision=self:_CheckFreePathToNextWP(fromcoord) + local collision = self:_CheckFreePathToNextWP( fromcoord ) -- Debug info. - self:T2(self.lid..string.format("Pathfinder d=%.1f m, direction=%03d°, collision=%s", distance, direction, tostring(collision))) + self:T2( self.lid .. string.format( "Pathfinder d=%.1f m, direction=%03d°, collision=%s", distance, direction, tostring( collision ) ) ) -- If path is clear, we start a little detour. if not collision then - self:CarrierDetour(fromcoord) + self:CarrierDetour( fromcoord ) return end - distance=distance+500 + distance = distance + 500 end end end - --- Carrier resumes the route at its next waypoint. ---@param #AIRBOSS self ---@param Core.Point#COORDINATE gotocoord (Optional) First goto this coordinate before resuming route. ---@return #AIRBOSS self -function AIRBOSS:CarrierResumeRoute(gotocoord) +-- @param #AIRBOSS self +-- @param Core.Point#COORDINATE gotocoord (Optional) First goto this coordinate before resuming route. +-- @return #AIRBOSS self +function AIRBOSS:CarrierResumeRoute( gotocoord ) -- Make carrier resume its route. - AIRBOSS._ResumeRoute(self.carrier:GetGroup(), self, gotocoord) + AIRBOSS._ResumeRoute( self.carrier:GetGroup(), self, gotocoord ) return self end - --- Let the carrier make a detour to a given point. When it reaches the point, it will resume its normal route. -- @param #AIRBOSS self -- @param Core.Point#COORDINATE coord Coordinate of the detour. @@ -13866,70 +13178,70 @@ end -- @param #number uspeed Speed in knots after U-turn. Default is same as before. -- @param Core.Point#COORDINATE tcoord Additional coordinate to make turn smoother. -- @return #AIRBOSS self -function AIRBOSS:CarrierDetour(coord, speed, uturn, uspeed, tcoord) +function AIRBOSS:CarrierDetour( coord, speed, uturn, uspeed, tcoord ) -- Current coordinate of the carrier. - local pos0=self:GetCoordinate() + local pos0 = self:GetCoordinate() -- Current speed in knots. - local vel0=self.carrier:GetVelocityKNOTS() + local vel0 = self.carrier:GetVelocityKNOTS() -- Default. If speed is not given we take the current speed but at least 5 knots. - speed=speed or math.max(vel0, 5) + speed = speed or math.max( vel0, 5 ) -- Speed in km/h. At least 2 knots. - local speedkmh=math.max(UTILS.KnotsToKmph(speed), UTILS.KnotsToKmph(2)) + local speedkmh = math.max( UTILS.KnotsToKmph( speed ), UTILS.KnotsToKmph( 2 ) ) -- Turn speed in km/h. At least 10 knots. - local cspeedkmh=math.max(self.carrier:GetVelocityKMH(), UTILS.KnotsToKmph(10)) + local cspeedkmh = math.max( self.carrier:GetVelocityKMH(), UTILS.KnotsToKmph( 10 ) ) -- U-turn speed in km/h. - local uspeedkmh=UTILS.KnotsToKmph(uspeed or speed) + local uspeedkmh = UTILS.KnotsToKmph( uspeed or speed ) -- Waypoint table. - local wp={} + local wp = {} -- Waypoint at current position. - table.insert(wp, pos0:WaypointGround(cspeedkmh)) + table.insert( wp, pos0:WaypointGround( cspeedkmh ) ) -- Waypooint to help the turn. if tcoord then - table.insert(wp, tcoord:WaypointGround(cspeedkmh)) + table.insert( wp, tcoord:WaypointGround( cspeedkmh ) ) end -- Detour waypoint. - table.insert(wp, coord:WaypointGround(speedkmh)) + table.insert( wp, coord:WaypointGround( speedkmh ) ) -- U-turn waypoint. If enabled, go back to where you came from. if uturn then - table.insert(wp, pos0:WaypointGround(uspeedkmh)) + table.insert( wp, pos0:WaypointGround( uspeedkmh ) ) end -- Get carrier group. - local group=self.carrier:GetGroup() + local group = self.carrier:GetGroup() -- Passing waypoint taskfunction - local TaskResumeRoute=group:TaskFunction("AIRBOSS._ResumeRoute", self) + local TaskResumeRoute = group:TaskFunction( "AIRBOSS._ResumeRoute", self ) -- Set task to restart route at the last point. - group:SetTaskWaypoint(wp[#wp], TaskResumeRoute) + group:SetTaskWaypoint( wp[#wp], TaskResumeRoute ) -- Debug mark. if self.Debug then if tcoord then - tcoord:MarkToAll(string.format("Detour Turn Help WP. Speed %.1f knots", UTILS.KmphToKnots(cspeedkmh))) + tcoord:MarkToAll( string.format( "Detour Turn Help WP. Speed %.1f knots", UTILS.KmphToKnots( cspeedkmh ) ) ) end - coord:MarkToAll(string.format("Detour Waypoint. Speed %.1f knots", UTILS.KmphToKnots(speedkmh))) + coord:MarkToAll( string.format( "Detour Waypoint. Speed %.1f knots", UTILS.KmphToKnots( speedkmh ) ) ) if uturn then - pos0:MarkToAll(string.format("Detour U-turn WP. Speed %.1f knots", UTILS.KmphToKnots(uspeedkmh))) + pos0:MarkToAll( string.format( "Detour U-turn WP. Speed %.1f knots", UTILS.KmphToKnots( uspeedkmh ) ) ) end end -- Detour switch true. - self.detour=true + self.detour = true -- Route carrier into the wind. - self.carrier:Route(wp) + self.carrier:Route( wp ) end --- Let the carrier turn into the wind. @@ -13938,109 +13250,108 @@ end -- @param #number vdeck Speed on deck m/s. Carrier will -- @param #boolean uturn Make U-turn and go back to initial after downwind leg. -- @return #AIRBOSS self -function AIRBOSS:CarrierTurnIntoWind(time, vdeck, uturn) +function AIRBOSS:CarrierTurnIntoWind( time, vdeck, uturn ) -- Wind speed. - local _,vwind=self:GetWind() + local _, vwind = self:GetWind() -- Speed of carrier in m/s but at least 2 knots. - local vtot=math.max(vdeck-vwind, UTILS.KnotsToMps(2)) + local vtot = math.max( vdeck - vwind, UTILS.KnotsToMps( 2 ) ) -- Distance to travel - local dist=vtot*time + local dist = vtot * time -- Speed in knots - local speedknots=UTILS.MpsToKnots(vtot) - local distNM=UTILS.MetersToNM(dist) + local speedknots = UTILS.MpsToKnots( vtot ) + local distNM = UTILS.MetersToNM( dist ) -- Debug output - self:T(self.lid..string.format("Carrier steaming into the wind (%.1f kts). Distance=%.1f NM, Speed=%.1f knots, Time=%d sec.", UTILS.MpsToKnots(vwind), distNM, speedknots, time)) + self:I( self.lid .. string.format( "Carrier steaming into the wind (%.1f kts). Distance=%.1f NM, Speed=%.1f knots, Time=%d sec.", UTILS.MpsToKnots( vwind ), distNM, speedknots, time ) ) -- Get heading into the wind accounting for angled runway. - local hiw=self:GetHeadingIntoWind() + local hiw = self:GetHeadingIntoWind() -- Current heading. - local hdg=self:GetHeading() + local hdg = self:GetHeading() -- Heading difference. - local deltaH=self:_GetDeltaHeading(hdg, hiw) + local deltaH = self:_GetDeltaHeading( hdg, hiw ) - local Cv=self:GetCoordinate() + local Cv = self:GetCoordinate() - local Ctiw=nil --Core.Point#COORDINATE - local Csoo=nil --Core.Point#COORDINATE + local Ctiw = nil -- Core.Point#COORDINATE + local Csoo = nil -- Core.Point#COORDINATE -- Define path depending on turn angle. - if deltaH<45 then + if deltaH < 45 then -- Small turn. -- Point in the right direction to help turning. - Csoo=Cv:Translate(750, hdg):Translate(750, hiw) + Csoo = Cv:Translate( 750, hdg ):Translate( 750, hiw ) -- Heading into wind from Csoo. - local hsw=self:GetHeadingIntoWind(false, Csoo) + local hsw = self:GetHeadingIntoWind( false, Csoo ) -- Into the wind coord. - Ctiw=Csoo:Translate(dist, hsw) + Ctiw = Csoo:Translate( dist, hsw ) - elseif deltaH<90 then + elseif deltaH < 90 then -- Medium turn. - -- Point in the right direction to help turning. - Csoo=Cv:Translate(900, hdg):Translate(900, hiw) + -- Point in the right direction to help turning. + Csoo = Cv:Translate( 900, hdg ):Translate( 900, hiw ) -- Heading into wind from Csoo. - local hsw=self:GetHeadingIntoWind(false, Csoo) + local hsw = self:GetHeadingIntoWind( false, Csoo ) -- Into the wind coord. - Ctiw=Csoo:Translate(dist, hsw) + Ctiw = Csoo:Translate( dist, hsw ) - elseif deltaH<135 then + elseif deltaH < 135 then -- Large turn backwards. -- Point in the right direction to help turning. - Csoo=Cv:Translate(1100, hdg-90):Translate(1000, hiw) + Csoo = Cv:Translate( 1100, hdg - 90 ):Translate( 1000, hiw ) -- Heading into wind from Csoo. - local hsw=self:GetHeadingIntoWind(false, Csoo) + local hsw = self:GetHeadingIntoWind( false, Csoo ) -- Into the wind coord. - Ctiw=Csoo:Translate(dist, hsw) + Ctiw = Csoo:Translate( dist, hsw ) else -- Huge turn backwards. -- Point in the right direction to help turning. - Csoo=Cv:Translate(1200, hdg-90):Translate(1000, hiw) + Csoo = Cv:Translate( 1200, hdg - 90 ):Translate( 1000, hiw ) -- Heading into wind from Csoo. - local hsw=self:GetHeadingIntoWind(false, Csoo) + local hsw = self:GetHeadingIntoWind( false, Csoo ) -- Into the wind coord. - Ctiw=Csoo:Translate(dist, hsw) + Ctiw = Csoo:Translate( dist, hsw ) end - -- Return to coordinate if collision is detected. - self.Creturnto=self:GetCoordinate() + self.Creturnto = self:GetCoordinate() -- Next waypoint. - local nextwp=self:_GetNextWaypoint() + local nextwp = self:_GetNextWaypoint() -- For downwind, we take the velocity at the next WP. - local vdownwind=UTILS.MpsToKnots(nextwp:GetVelocity()) + local vdownwind = UTILS.MpsToKnots( nextwp:GetVelocity() ) -- Make sure we move at all in case the speed at the waypoint is zero. - if vdownwind<1 then - vdownwind=10 + if vdownwind < 1 then + vdownwind = 10 end -- Let the carrier make a detour from its route but return to its current position. - self:CarrierDetour(Ctiw, speedknots, uturn, vdownwind, Csoo) + self:CarrierDetour( Ctiw, speedknots, uturn, vdownwind, Csoo ) -- Set switch that we are currently turning into the wind. - self.turnintowind=true + self.turnintowind = true return self end @@ -14052,50 +13363,49 @@ end function AIRBOSS:_GetNextWaypoint() -- Next waypoint. - local Nextwp=nil - if self.currentwp==#self.waypoints then - Nextwp=1 + local Nextwp = nil + if self.currentwp == #self.waypoints then + Nextwp = 1 else - Nextwp=self.currentwp+1 + Nextwp = self.currentwp + 1 end -- Debug output - local text=string.format("Current WP=%d/%d, next WP=%d", self.currentwp, #self.waypoints, Nextwp) - self:T2(self.lid..text) + local text = string.format( "Current WP=%d/%d, next WP=%d", self.currentwp, #self.waypoints, Nextwp ) + self:T2( self.lid .. text ) -- Next waypoint. - local nextwp=self.waypoints[Nextwp] --Core.Point#COORDINATE + local nextwp = self.waypoints[Nextwp] -- Core.Point#COORDINATE - return nextwp,Nextwp + return nextwp, Nextwp end - --- Initialize Mission Editor waypoints. -- @param #AIRBOSS self -- @return #AIRBOSS self function AIRBOSS:_InitWaypoints() -- Waypoints of group as defined in the ME. - local Waypoints=self.carrier:GetGroup():GetTemplateRoutePoints() + local Waypoints = self.carrier:GetGroup():GetTemplateRoutePoints() -- Init array. - self.waypoints={} + self.waypoints = {} -- Set waypoint table. - for i,point in ipairs(Waypoints) do + for i, point in ipairs( Waypoints ) do -- Coordinate of the waypoint - local coord=COORDINATE:New(point.x, point.alt, point.y) + local coord = COORDINATE:New( point.x, point.alt, point.y ) -- Set velocity of the coordinate. - coord:SetVelocity(point.speed) + coord:SetVelocity( point.speed ) -- Add to table. - table.insert(self.waypoints, coord) + table.insert( self.waypoints, coord ) -- Debug info. if self.Debug then - coord:MarkToAll(string.format("Carrier Waypoint %d, Speed=%.1f knots", i, UTILS.MpsToKnots(point.speed))) + coord:MarkToAll( string.format( "Carrier Waypoint %d, Speed=%.1f knots", i, UTILS.MpsToKnots( point.speed ) ) ) end end @@ -14107,86 +13417,83 @@ end -- @param #AIRBOSS self -- @param #number n Next waypoint number. -- @return #AIRBOSS self -function AIRBOSS:_PatrolRoute(n) +function AIRBOSS:_PatrolRoute( n ) -- Get next waypoint coordinate and number. - local nextWP, N=self:_GetNextWaypoint() + local nextWP, N = self:_GetNextWaypoint() -- Default resume is to next waypoint. - n=n or N + n = n or N -- Get carrier group. - local CarrierGroup=self.carrier:GetGroup() + local CarrierGroup = self.carrier:GetGroup() -- Waypoints table. - local Waypoints={} + local Waypoints = {} -- Create a waypoint from the current coordinate. - local wp=self:GetCoordinate():WaypointGround(CarrierGroup:GetVelocityKMH()) + local wp = self:GetCoordinate():WaypointGround( CarrierGroup:GetVelocityKMH() ) -- Add current position as first waypoint. - table.insert(Waypoints, wp) + table.insert( Waypoints, wp ) -- Loop over waypoints. - for i=n,#self.waypoints do - local coord=self.waypoints[i] --Core.Point#COORDINATE + for i = n, #self.waypoints do + local coord = self.waypoints[i] -- Core.Point#COORDINATE -- Create a waypoint from the coordinate. - local wp=coord:WaypointGround(UTILS.MpsToKmph(coord.Velocity)) + local wp = coord:WaypointGround( UTILS.MpsToKmph( coord.Velocity ) ) -- Passing waypoint taskfunction - local TaskPassingWP=CarrierGroup:TaskFunction("AIRBOSS._PassingWaypoint", self, i, #self.waypoints) + local TaskPassingWP = CarrierGroup:TaskFunction( "AIRBOSS._PassingWaypoint", self, i, #self.waypoints ) -- Call task function when carrier arrives at waypoint. - CarrierGroup:SetTaskWaypoint(wp, TaskPassingWP) + CarrierGroup:SetTaskWaypoint( wp, TaskPassingWP ) -- Add waypoint to table. - table.insert(Waypoints, wp) + table.insert( Waypoints, wp ) end -- Route carrier group. - CarrierGroup:Route(Waypoints) + CarrierGroup:Route( Waypoints ) return self end - - - --- Estimated the carrier position at some point in the future given the current waypoints and speeds. -- @param #AIRBOSS self -- @return DCS#time ETA abs. time in seconds. function AIRBOSS:_GetETAatNextWP() -- Current waypoint - local cwp=self.currentwp + local cwp = self.currentwp -- Current abs. time. - local tnow=timer.getAbsTime() + local tnow = timer.getAbsTime() -- Current position. - local p=self:GetCoordinate() + local p = self:GetCoordinate() -- Current velocity [m/s]. - local v=self.carrier:GetVelocityMPS() + local v = self.carrier:GetVelocityMPS() -- Next waypoint. - local nextWP=self:_GetNextWaypoint() + local nextWP = self:_GetNextWaypoint() -- Distance to next waypoint. - local s=p:Get2DDistance(nextWP) + local s = p:Get2DDistance( nextWP ) -- Distance to next waypoint. - --local s=0 - --if #self.waypoints>cwp then + -- local s=0 + -- if #self.waypoints>cwp then -- s=p:Get2DDistance(self.waypoints[cwp+1]) - --end + -- end -- v=s/t <==> t=s/v - local t=s/v + local t = s / v -- ETA - local eta=t+tnow + local eta = t + tnow return eta end @@ -14196,31 +13503,32 @@ end function AIRBOSS:_CheckCarrierTurning() -- Current orientation of carrier. - local vNew=self.carrier:GetOrientationX() + local vNew = self.carrier:GetOrientationX() -- Last orientation from 30 seconds ago. - local vLast=self.Corientlast + local vLast = self.Corientlast -- We only need the X-Z plane. - vNew.y=0 ; vLast.y=0 + vNew.y = 0; + vLast.y = 0 -- Angle between current heading and last time we checked ~30 seconds ago. - local deltaLast=math.deg(math.acos(UTILS.VecDot(vNew,vLast)/UTILS.VecNorm(vNew)/UTILS.VecNorm(vLast))) + local deltaLast = math.deg( math.acos( UTILS.VecDot( vNew, vLast ) / UTILS.VecNorm( vNew ) / UTILS.VecNorm( vLast ) ) ) -- Last orientation becomes new orientation - self.Corientlast=vNew + self.Corientlast = vNew -- Carrier is turning when its heading changed by at least one degree since last check. - local turning=math.abs(deltaLast)>=1 + local turning = math.abs( deltaLast ) >= 1 -- Check if turning stopped. (Carrier was turning but is not any more.) if self.turning and not turning then -- Get final bearing. - local FB=self:GetFinalBearing(true) + local FB = self:GetFinalBearing( true ) -- Marshal radio call: "99, new final bearing XYZ degrees." - self:_MarshalCallNewFinalBearing(FB) + self:_MarshalCallNewFinalBearing( FB ) end @@ -14231,24 +13539,24 @@ function AIRBOSS:_CheckCarrierTurning() local hdg if self.turnintowind then -- We are now steaming into the wind. - hdg=self:GetHeadingIntoWind(false) + hdg = self:GetHeadingIntoWind( false ) else -- We turn towards the next waypoint. - hdg=self:GetCoordinate():HeadingTo(self:_GetNextWaypoint()) + hdg = self:GetCoordinate():HeadingTo( self:_GetNextWaypoint() ) end -- Magnetic! - hdg=hdg-self.magvar - if hdg<0 then - hdg=360+hdg + hdg = hdg - self.magvar + if hdg < 0 then + hdg = 360 + hdg end -- Radio call: "99, Carrier starting turn to heading XYZ degrees". - self:_MarshalCallCarrierTurnTo(hdg) + self:_MarshalCallCarrierTurnTo( hdg ) end -- Update turning. - self.turning=turning + self.turning = turning end --- Check if heading or position of carrier have changed significantly. @@ -14260,23 +13568,23 @@ function AIRBOSS:_CheckPatternUpdate() ---------------------------------------- -- Min 10 min between pattern updates. - local dTPupdate=10*60 + local dTPupdate = 10 * 60 -- Update if carrier moves by more than 2.5 NM. - local Dupdate=UTILS.NMToMeters(2.5) + local Dupdate = UTILS.NMToMeters( 2.5 ) -- Update if carrier turned by more than 5°. - local Hupdate=5 + local Hupdate = 5 ----------------------- -- Time Update Check -- ----------------------- -- Time since last pattern update - local dt=timer.getTime()-self.Tpupdate + local dt = timer.getTime() - self.Tpupdate -- Check whether at least 10 min between updates and not turning currently. - if dt=Hupdate then - self:T(self.lid..string.format("Carrier heading changed by %d°.", deltaHeading)) - Hchange=true + local Hchange = false + if math.abs( deltaHeading ) >= Hupdate then + self:T( self.lid .. string.format( "Carrier heading changed by %d°.", deltaHeading ) ) + Hchange = true end --------------------------- @@ -14308,16 +13617,16 @@ function AIRBOSS:_CheckPatternUpdate() --------------------------- -- Get current position and orientation of carrier. - local pos=self:GetCoordinate() + local pos = self:GetCoordinate() -- Get distance to saved position. - local dist=pos:Get2DDistance(self.Cposition) + local dist = pos:Get2DDistance( self.Cposition ) -- Check if carrier moved more than ~10 km. - local Dchange=false - if dist>=Dupdate then - self:T(self.lid..string.format("Carrier position changed by %.1f NM.", UTILS.MetersToNM(dist))) - Dchange=true + local Dchange = false + if dist >= Dupdate then + self:T( self.lid .. string.format( "Carrier position changed by %.1f NM.", UTILS.MetersToNM( dist ) ) ) + Dchange = true end ---------------------------- @@ -14328,228 +13637,227 @@ function AIRBOSS:_CheckPatternUpdate() if Hchange or Dchange then -- Loop over all marshal flights - for _,_flight in pairs(self.Qmarshal) do - local flight=_flight --#AIRBOSS.FlightGroup + for _, _flight in pairs( self.Qmarshal ) do + local flight = _flight -- #AIRBOSS.FlightGroup -- Update marshal pattern of AI keeping the same stack. if flight.ai then - self:_MarshalAI(flight, flight.flag) + self:_MarshalAI( flight, flight.flag ) end end -- Reset parameters for next update check. - self.Corientation=vNew - self.Cposition=pos - self.Tpupdate=timer.getTime() + self.Corientation = vNew + self.Cposition = pos + self.Tpupdate = timer.getTime() end end --- Function called when a group is passing a waypoint. ---@param Wrapper.Group#GROUP group Group that passed the waypoint ---@param #AIRBOSS airboss Airboss object. ---@param #number i Waypoint number that has been reached. ---@param #number final Final waypoint number. -function AIRBOSS._PassingWaypoint(group, airboss, i, final) +-- @param Wrapper.Group#GROUP group Group that passed the waypoint +-- @param #AIRBOSS airboss Airboss object. +-- @param #number i Waypoint number that has been reached. +-- @param #number final Final waypoint number. +function AIRBOSS._PassingWaypoint( group, airboss, i, final ) -- Debug message. - local text=string.format("Group %s passing waypoint %d of %d.", group:GetName(), i, final) + local text = string.format( "Group %s passing waypoint %d of %d.", group:GetName(), i, final ) -- Debug smoke and marker. if airboss.Debug and false then - local pos=group:GetCoordinate() + local pos = group:GetCoordinate() pos:SmokeRed() - local MarkerID=pos:MarkToAll(string.format("Group %s reached waypoint %d", group:GetName(), i)) + local MarkerID = pos:MarkToAll( string.format( "Group %s reached waypoint %d", group:GetName(), i ) ) end -- Debug message. - MESSAGE:New(text,10):ToAllIf(airboss.Debug) - airboss:T(airboss.lid..text) + MESSAGE:New( text, 10 ):ToAllIf( airboss.Debug ) + airboss:T( airboss.lid .. text ) -- Set current waypoint. - airboss.currentwp=i + airboss.currentwp = i -- Passing Waypoint event. - airboss:PassingWaypoint(i) + airboss:PassingWaypoint( i ) -- Reactivate beacons. - --airboss:_ActivateBeacons() + -- airboss:_ActivateBeacons() -- If final waypoint reached, do route all over again. - if i==final and final>1 and airboss.adinfinitum then + if i == final and final > 1 and airboss.adinfinitum then airboss:_PatrolRoute() end end --- Carrier Strike Group resumes the route of the waypoints defined in the mission editor. ---@param Wrapper.Group#GROUP group Carrier Strike Group that passed the waypoint. ---@param #AIRBOSS airboss Airboss object. ---@param Core.Point#COORDINATE gotocoord Go to coordinate before route is resumed. -function AIRBOSS._ResumeRoute(group, airboss, gotocoord) +-- @param Wrapper.Group#GROUP group Carrier Strike Group that passed the waypoint. +-- @param #AIRBOSS airboss Airboss object. +-- @param Core.Point#COORDINATE gotocoord Go to coordinate before route is resumed. +function AIRBOSS._ResumeRoute( group, airboss, gotocoord ) -- Get next waypoint - local nextwp,Nextwp=airboss:_GetNextWaypoint() + local nextwp, Nextwp = airboss:_GetNextWaypoint() -- Speed set at waypoint. - local speedkmh=nextwp.Velocity*3.6 + local speedkmh = nextwp.Velocity * 3.6 -- If speed at waypoint is zero, we set it to 10 knots. - if speedkmh<1 then - speedkmh=UTILS.KnotsToKmph(10) + if speedkmh < 1 then + speedkmh = UTILS.KnotsToKmph( 10 ) end -- Waypoints array. - local waypoints={} + local waypoints = {} -- Current position. - local c0=group:GetCoordinate() + local c0 = group:GetCoordinate() -- Current positon as first waypoint. - local wp0=c0:WaypointGround(speedkmh) - table.insert(waypoints, wp0) + local wp0 = c0:WaypointGround( speedkmh ) + table.insert( waypoints, wp0 ) -- First goto this coordinate. if gotocoord then - --gotocoord:MarkToAll(string.format("Goto waypoint speed=%.1f km/h", speedkmh)) + -- gotocoord:MarkToAll(string.format("Goto waypoint speed=%.1f km/h", speedkmh)) - local headingto=c0:HeadingTo(gotocoord) + local headingto = c0:HeadingTo( gotocoord ) - local hdg1=airboss:GetHeading() - local hdg2=c0:HeadingTo(gotocoord) - local delta=airboss:_GetDeltaHeading(hdg1, hdg2) - - --env.info(string.format("FF hdg1=%d, hdg2=%d, delta=%d", hdg1, hdg2, delta)) + local hdg1 = airboss:GetHeading() + local hdg2 = c0:HeadingTo( gotocoord ) + local delta = airboss:_GetDeltaHeading( hdg1, hdg2 ) + -- env.info(string.format("FF hdg1=%d, hdg2=%d, delta=%d", hdg1, hdg2, delta)) -- Add additional turn points - if delta>90 then + if delta > 90 then -- Turn radius 3 NM. - local turnradius=UTILS.NMToMeters(3) + local turnradius = UTILS.NMToMeters( 3 ) - local gotocoordh=c0:Translate(turnradius, hdg1+45) - --gotocoordh:MarkToAll(string.format("Goto help waypoint 1 speed=%.1f km/h", speedkmh)) + local gotocoordh = c0:Translate( turnradius, hdg1 + 45 ) + -- gotocoordh:MarkToAll(string.format("Goto help waypoint 1 speed=%.1f km/h", speedkmh)) - local wp=gotocoordh:WaypointGround(speedkmh) - table.insert(waypoints, wp) + local wp = gotocoordh:WaypointGround( speedkmh ) + table.insert( waypoints, wp ) - gotocoordh=c0:Translate(turnradius, hdg1+90) - --gotocoordh:MarkToAll(string.format("Goto help waypoint 2 speed=%.1f km/h", speedkmh)) + gotocoordh = c0:Translate( turnradius, hdg1 + 90 ) + -- gotocoordh:MarkToAll(string.format("Goto help waypoint 2 speed=%.1f km/h", speedkmh)) - wp=gotocoordh:WaypointGround(speedkmh) - table.insert(waypoints, wp) + wp = gotocoordh:WaypointGround( speedkmh ) + table.insert( waypoints, wp ) end - local wp1=gotocoord:WaypointGround(speedkmh) - table.insert(waypoints, wp1) + local wp1 = gotocoord:WaypointGround( speedkmh ) + table.insert( waypoints, wp1 ) end -- Debug message. - local text=string.format("Carrier is resuming route. Next waypoint %d, Speed=%.1f knots.", Nextwp, UTILS.KmphToKnots(speedkmh)) + local text = string.format( "Carrier is resuming route. Next waypoint %d, Speed=%.1f knots.", Nextwp, UTILS.KmphToKnots( speedkmh ) ) -- Debug message. - MESSAGE:New(text,10):ToAllIf(airboss.Debug) - airboss:I(airboss.lid..text) + MESSAGE:New( text, 10 ):ToAllIf( airboss.Debug ) + airboss:I( airboss.lid .. text ) -- Loop over all remaining waypoints. - for i=Nextwp, #airboss.waypoints do + for i = Nextwp, #airboss.waypoints do -- Coordinate of the next WP. - local coord=airboss.waypoints[i] --Core.Point#COORDINATE + local coord = airboss.waypoints[i] -- Core.Point#COORDINATE -- Speed in km/h of that WP. Velocity is in m/s. - local speed=coord.Velocity*3.6 + local speed = coord.Velocity * 3.6 -- If speed is zero we set it to 10 knots. - if speed<1 then - speed=UTILS.KnotsToKmph(10) + if speed < 1 then + speed = UTILS.KnotsToKmph( 10 ) end - --coord:MarkToAll(string.format("Resume route WP %d, speed=%.1f km/h", i, speed)) + -- coord:MarkToAll(string.format("Resume route WP %d, speed=%.1f km/h", i, speed)) -- Create waypoint. - local wp=coord:WaypointGround(speed) + local wp = coord:WaypointGround( speed ) -- Passing waypoint task function. - local TaskPassingWP=group:TaskFunction("AIRBOSS._PassingWaypoint", airboss, i, #airboss.waypoints) + local TaskPassingWP = group:TaskFunction( "AIRBOSS._PassingWaypoint", airboss, i, #airboss.waypoints ) -- Call task function when carrier arrives at waypoint. - group:SetTaskWaypoint(wp, TaskPassingWP) + group:SetTaskWaypoint( wp, TaskPassingWP ) -- Add waypoints to table. - table.insert(waypoints, wp) + table.insert( waypoints, wp ) end -- Set turn into wind switch false. - airboss.turnintowind=false - airboss.detour=false + airboss.turnintowind = false + airboss.detour = false -- Route group. - group:Route(waypoints) + group:Route( waypoints ) end --- Function called when a group has reached the holding zone. ---@param Wrapper.Group#GROUP group Group that reached the holding zone. ---@param #AIRBOSS airboss Airboss object. ---@param #AIRBOSS.FlightGroup flight Flight group that has reached the holding zone. -function AIRBOSS._ReachedHoldingZone(group, airboss, flight) +-- @param Wrapper.Group#GROUP group Group that reached the holding zone. +-- @param #AIRBOSS airboss Airboss object. +-- @param #AIRBOSS.FlightGroup flight Flight group that has reached the holding zone. +function AIRBOSS._ReachedHoldingZone( group, airboss, flight ) -- Debug message. - local text=string.format("Flight %s reached holding zone.", group:GetName()) - MESSAGE:New(text,10):ToAllIf(airboss.Debug) - airboss:T(airboss.lid..text) + local text = string.format( "Flight %s reached holding zone.", group:GetName() ) + MESSAGE:New( text, 10 ):ToAllIf( airboss.Debug ) + airboss:T( airboss.lid .. text ) -- Debug mark. if airboss.Debug then - group:GetCoordinate():MarkToAll(text) + group:GetCoordinate():MarkToAll( text ) end -- Set holding flag true and set timestamp for marshal time check. if flight then - flight.holding=true - flight.time=timer.getAbsTime() + flight.holding = true + flight.time = timer.getAbsTime() end end --- Function called when a group should be send to the Marshal stack. If stack is full, it is send to wait. ---@param Wrapper.Group#GROUP group Group that reached the holding zone. ---@param #AIRBOSS airboss Airboss object. ---@param #AIRBOSS.FlightGroup flight Flight group that has reached the holding zone. -function AIRBOSS._TaskFunctionMarshalAI(group, airboss, flight) +-- @param Wrapper.Group#GROUP group Group that reached the holding zone. +-- @param #AIRBOSS airboss Airboss object. +-- @param #AIRBOSS.FlightGroup flight Flight group that has reached the holding zone. +function AIRBOSS._TaskFunctionMarshalAI( group, airboss, flight ) -- Debug message. - local text=string.format("Flight %s is send to marshal.", group:GetName()) - MESSAGE:New(text,10):ToAllIf(airboss.Debug) - airboss:T(airboss.lid..text) + local text = string.format( "Flight %s is send to marshal.", group:GetName() ) + MESSAGE:New( text, 10 ):ToAllIf( airboss.Debug ) + airboss:T( airboss.lid .. text ) -- Get the next free stack for current recovery case. - local stack=airboss:_GetFreeStack(flight.ai) + local stack = airboss:_GetFreeStack( flight.ai ) if stack then -- Send AI to marshal stack. - airboss:_MarshalAI(flight, stack) + airboss:_MarshalAI( flight, stack ) else -- Send AI to orbit outside 10 NM zone and wait until the next Marshal stack is available. - if not airboss:_InQueue(airboss.Qwaiting, flight.group) then - airboss:_WaitAI(flight) + if not airboss:_InQueue( airboss.Qwaiting, flight.group ) then + airboss:_WaitAI( flight ) end end -- If it came from refueling. - if flight.refueling==true then - airboss:I(airboss.lid..string.format("Flight group %s finished refueling task.", flight.groupname)) + if flight.refueling == true then + airboss:I( airboss.lid .. string.format( "Flight group %s finished refueling task.", flight.groupname ) ) end -- Not refueling any more in case it was. - flight.refueling=false + flight.refueling = false end @@ -14561,23 +13869,23 @@ end -- @param #AIRBOSS self -- @param #string actype Aircraft type name. -- @return #string Aircraft nickname. E.g. "Hornet" for the F/A-18C or "Tomcat" For the F-14A. -function AIRBOSS:_GetACNickname(actype) +function AIRBOSS:_GetACNickname( actype ) - local nickname="unknown" - if actype==AIRBOSS.AircraftCarrier.A4EC then - nickname="Skyhawk" - elseif actype==AIRBOSS.AircraftCarrier.T45C then - nickname="Goshawk" - elseif actype==AIRBOSS.AircraftCarrier.AV8B then - nickname="Harrier" - elseif actype==AIRBOSS.AircraftCarrier.E2D then - nickname="Hawkeye" - elseif actype==AIRBOSS.AircraftCarrier.F14A_AI or actype==AIRBOSS.AircraftCarrier.F14A or actype==AIRBOSS.AircraftCarrier.F14B then - nickname="Tomcat" - elseif actype==AIRBOSS.AircraftCarrier.FA18C or actype==AIRBOSS.AircraftCarrier.HORNET then - nickname="Hornet" - elseif actype==AIRBOSS.AircraftCarrier.S3B or actype==AIRBOSS.AircraftCarrier.S3BTANKER then - nickname="Viking" + local nickname = "unknown" + if actype == AIRBOSS.AircraftCarrier.A4EC then + nickname = "Skyhawk" + elseif actype == AIRBOSS.AircraftCarrier.T45C then + nickname = "Goshawk" + elseif actype == AIRBOSS.AircraftCarrier.AV8B then + nickname = "Harrier" + elseif actype == AIRBOSS.AircraftCarrier.E2D then + nickname = "Hawkeye" + elseif actype == AIRBOSS.AircraftCarrier.F14A_AI or actype == AIRBOSS.AircraftCarrier.F14A or actype == AIRBOSS.AircraftCarrier.F14B then + nickname = "Tomcat" + elseif actype == AIRBOSS.AircraftCarrier.FA18C or actype == AIRBOSS.AircraftCarrier.HORNET then + nickname = "Hornet" + elseif actype == AIRBOSS.AircraftCarrier.S3B or actype == AIRBOSS.AircraftCarrier.S3BTANKER then + nickname = "Viking" end return nickname @@ -14587,8 +13895,8 @@ end -- @param #AIRBOSS self -- @param Wrapper.Group#GROUP group Aircraft group. -- @return #string Onboard number as string. -function AIRBOSS:_GetOnboardNumberPlayer(group) - return self:_GetOnboardNumbers(group, true) +function AIRBOSS:_GetOnboardNumberPlayer( group ) + return self:_GetOnboardNumbers( group, true ) end --- Get onboard numbers of all units in a group. @@ -14596,60 +13904,59 @@ end -- @param Wrapper.Group#GROUP group Aircraft group. -- @param #boolean playeronly If true, return the onboard number for player or client skill units. -- @return #table Table of onboard numbers. -function AIRBOSS:_GetOnboardNumbers(group, playeronly) - --self:F({groupname=group:GetName}) +function AIRBOSS:_GetOnboardNumbers( group, playeronly ) + -- self:F({groupname=group:GetName}) -- Get group name. - local groupname=group:GetName() + local groupname = group:GetName() -- Debug text. - local text=string.format("Onboard numbers of group %s:", groupname) + local text = string.format( "Onboard numbers of group %s:", groupname ) -- Units of template group. - local units=group:GetTemplate().units + local units = group:GetTemplate().units -- Get numbers. - local numbers={} - for _,unit in pairs(units) do + local numbers = {} + for _, unit in pairs( units ) do -- Onboard number and unit name. - local n=tostring(unit.onboard_num) - local name=unit.name - local skill=unit.skill or "Unknown" + local n = tostring( unit.onboard_num ) + local name = unit.name + local skill = unit.skill or "Unknown" -- Debug text. - text=text..string.format("\n- unit %s: onboard #=%s skill=%s", name, n, tostring(skill)) + text = text .. string.format( "\n- unit %s: onboard #=%s skill=%s", name, n, tostring( skill ) ) - if playeronly and skill=="Client" or skill=="Player" then + if playeronly and skill == "Client" or skill == "Player" then -- There can be only one player in the group, so we skip everything else. return n end -- Table entry. - numbers[name]=n + numbers[name] = n end -- Debug info. - self:T2(self.lid..text) + self:T2( self.lid .. text ) return numbers end - --- Get Tower frequency of carrier. -- @param #AIRBOSS self function AIRBOSS:_GetTowerFrequency() -- Tower frequency in MHz - self.TowerFreq=0 + self.TowerFreq = 0 -- Get Template of Strike Group - local striketemplate=self.carrier:GetGroup():GetTemplate() + local striketemplate = self.carrier:GetGroup():GetTemplate() -- Find the carrier unit. - for _,unit in pairs(striketemplate.units) do - if self.carrier:GetName()==unit.name then - self.TowerFreq=unit.frequency/1000000 + for _, unit in pairs( striketemplate.units ) do + if self.carrier:GetName() == unit.name then + self.TowerFreq = unit.frequency / 1000000 return end end @@ -14665,19 +13972,19 @@ end -- @param #AIRBOSS.PlayerData playerData Player data table. -- @return #number Error margin for still being okay. -- @return #number Error margin for really sucking. -function AIRBOSS:_GetGoodBadScore(playerData) +function AIRBOSS:_GetGoodBadScore( playerData ) local lowscore local badscore - if playerData.difficulty==AIRBOSS.Difficulty.EASY then - lowscore=10 - badscore=20 - elseif playerData.difficulty==AIRBOSS.Difficulty.NORMAL then - lowscore=5 - badscore=10 - elseif playerData.difficulty==AIRBOSS.Difficulty.HARD then - lowscore=2.5 - badscore=5 + if playerData.difficulty == AIRBOSS.Difficulty.EASY then + lowscore = 10 + badscore = 20 + elseif playerData.difficulty == AIRBOSS.Difficulty.NORMAL then + lowscore = 5 + badscore = 10 + elseif playerData.difficulty == AIRBOSS.Difficulty.HARD then + lowscore = 2.5 + badscore = 5 end return lowscore, badscore @@ -14687,14 +13994,14 @@ end -- @param #AIRBOSS self -- @param Wrapper.Unit#UNIT unit Aircraft unit. (Will also work with groups as given parameter.) -- @return #boolean If true, aircraft can land on a carrier. -function AIRBOSS:_IsCarrierAircraft(unit) +function AIRBOSS:_IsCarrierAircraft( unit ) -- Get aircraft type name - local aircrafttype=unit:GetTypeName() + local aircrafttype = unit:GetTypeName() -- Special case for Harrier which can only land on Tarawa, LHA and LHD. - if aircrafttype==AIRBOSS.AircraftCarrier.AV8B then - if self.carriertype==AIRBOSS.CarrierType.TARAWA or self.carriertype==AIRBOSS.CarrierType.AMERICA or self.carriertype==AIRBOSS.CarrierType.JCARLOS or self.carriertype==AIRBOSS.CarrierType.CANBERRA then + if aircrafttype == AIRBOSS.AircraftCarrier.AV8B then + if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then return true else return false @@ -14702,17 +14009,17 @@ function AIRBOSS:_IsCarrierAircraft(unit) end -- Also only Harriers can land on the Tarawa, LHA and LHD. - if self.carriertype==AIRBOSS.CarrierType.TARAWA or self.carriertype==AIRBOSS.CarrierType.AMERICA or self.carriertype==AIRBOSS.CarrierType.JCARLOS or self.carriertype==AIRBOSS.CarrierType.CANBERRA then - if aircrafttype~=AIRBOSS.AircraftCarrier.AV8B then + if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then + if aircrafttype ~= AIRBOSS.AircraftCarrier.AV8B then return false end end -- Loop over all other known carrier capable aircraft. - for _,actype in pairs(AIRBOSS.AircraftCarrier) do + for _, actype in pairs( AIRBOSS.AircraftCarrier ) do -- Check if this is a carrier capable aircraft type. - if actype==aircrafttype then + if actype == aircrafttype then return true end end @@ -14725,10 +14032,10 @@ end -- @param #AIRBOSS self -- @param Wrapper.Unit#UNIT unit Aircraft unit. -- @return #boolean If true, human player inside the unit. -function AIRBOSS:_IsHumanUnit(unit) +function AIRBOSS:_IsHumanUnit( unit ) -- Get player unit or nil if no player unit. - local playerunit=self:_GetPlayerUnitAndName(unit:GetName()) + local playerunit = self:_GetPlayerUnitAndName( unit:GetName() ) if playerunit then return true @@ -14741,15 +14048,15 @@ end -- @param #AIRBOSS self -- @param Wrapper.Group#GROUP group Aircraft group. -- @return #boolean If true, human player inside group. -function AIRBOSS:_IsHuman(group) +function AIRBOSS:_IsHuman( group ) -- Get all units of the group. - local units=group:GetUnits() + local units = group:GetUnits() -- Loop over all units. - for _,_unit in pairs(units) do + for _, _unit in pairs( units ) do -- Check if unit is human. - local human=self:_IsHumanUnit(_unit) + local human = self:_IsHumanUnit( _unit ) if human then return true end @@ -14762,31 +14069,31 @@ end -- @param #AIRBOSS self -- @param Wrapper.Unit#UNIT unit The unit for which the mass is determined. -- @return #number Fuel state in pounds. -function AIRBOSS:_GetFuelState(unit) +function AIRBOSS:_GetFuelState( unit ) -- Get relative fuel [0,1]. - local fuel=unit:GetFuel() + local fuel = unit:GetFuel() -- Get max weight of fuel in kg. - local maxfuel=self:_GetUnitMasses(unit) + local maxfuel = self:_GetUnitMasses( unit ) -- Fuel state, i.e. what let's - local fuelstate=fuel*maxfuel + local fuelstate = fuel * maxfuel -- Debug info. - self:T2(self.lid..string.format("Unit %s fuel state = %.1f kg = %.1f lbs", unit:GetName(), fuelstate, UTILS.kg2lbs(fuelstate))) + self:T2( self.lid .. string.format( "Unit %s fuel state = %.1f kg = %.1f lbs", unit:GetName(), fuelstate, UTILS.kg2lbs( fuelstate ) ) ) - return UTILS.kg2lbs(fuelstate) + return UTILS.kg2lbs( fuelstate ) end --- Convert altitude from meters to angels (thousands of feet). -- @param #AIRBOSS self -- @param alt Alitude in meters. -- @return #number Altitude in Anglels = thousands of feet using math.floor(). -function AIRBOSS:_GetAngels(alt) +function AIRBOSS:_GetAngels( alt ) if alt then - local angels=UTILS.Round(UTILS.MetersToFeet(alt)/1000, 0) + local angels = UTILS.Round( UTILS.MetersToFeet( alt ) / 1000, 0 ) return angels else return 0 @@ -14801,25 +14108,25 @@ end -- @return #number Empty weight of unit in kg. -- @return #number Max weight of unit in kg. -- @return #number Max cargo weight in kg. -function AIRBOSS:_GetUnitMasses(unit) +function AIRBOSS:_GetUnitMasses( unit ) -- Get DCS descriptors table. - local Desc=unit:GetDesc() + local Desc = unit:GetDesc() -- Mass of fuel in kg. - local massfuel=Desc.fuelMassMax or 0 + local massfuel = Desc.fuelMassMax or 0 -- Mass of empty unit in km. - local massempty=Desc.massEmpty or 0 + local massempty = Desc.massEmpty or 0 -- Max weight of unit in kg. - local massmax=Desc.massMax or 0 + local massmax = Desc.massMax or 0 -- Rest is cargo. - local masscargo=massmax-massfuel-massempty + local masscargo = massmax - massfuel - massempty -- Debug info. - self:T2(self.lid..string.format("Unit %s mass fuel=%.1f kg, empty=%.1f kg, max=%.1f kg, cargo=%.1f kg", unit:GetName(), massfuel, massempty, massmax, masscargo)) + self:T2( self.lid .. string.format( "Unit %s mass fuel=%.1f kg, empty=%.1f kg, max=%.1f kg, cargo=%.1f kg", unit:GetName(), massfuel, massempty, massmax, masscargo ) ) return massfuel, massempty, massmax, masscargo end @@ -14828,10 +14135,10 @@ end -- @param #AIRBOSS self -- @param Wrapper.Unit#UNIT unit Unit in question. -- @return #AIRBOSS.PlayerData Player data or nil if not player with this name or unit exists. -function AIRBOSS:_GetPlayerDataUnit(unit) +function AIRBOSS:_GetPlayerDataUnit( unit ) if unit:IsAlive() then - local unitname=unit:GetName() - local playerunit,playername=self:_GetPlayerUnitAndName(unitname) + local unitname = unit:GetName() + local playerunit, playername = self:_GetPlayerUnitAndName( unitname ) if playerunit and playername then return self.players[playername] end @@ -14839,15 +14146,14 @@ function AIRBOSS:_GetPlayerDataUnit(unit) return nil end - --- Get player data from group object. -- @param #AIRBOSS self -- @param Wrapper.Group#GROUP group Group in question. -- @return #AIRBOSS.PlayerData Player data or nil if not player with this name or unit exists. -function AIRBOSS:_GetPlayerDataGroup(group) - local units=group:GetUnits() - for _,unit in pairs(units) do - local playerdata=self:_GetPlayerDataUnit(unit) +function AIRBOSS:_GetPlayerDataGroup( group ) + local units = group:GetUnits() + for _, unit in pairs( units ) do + local playerdata = self:_GetPlayerDataUnit( unit ) if playerdata then return playerdata end @@ -14860,20 +14166,20 @@ end -- @param #string _unitName Name of the player unit. -- @return Wrapper.Unit#UNIT Unit of player or nil. -- @return #string Name of player or nil. -function AIRBOSS:_GetPlayerUnit(_unitName) +function AIRBOSS:_GetPlayerUnit( _unitName ) - for _,_player in pairs(self.players) do + for _, _player in pairs( self.players ) do - local player=_player --#AIRBOSS.PlayerData + local player = _player -- #AIRBOSS.PlayerData - if player.unit and player.unit:GetName()==_unitName then - self:T(self.lid..string.format("Found player=%s unit=%s in players table.", tostring(player.name), tostring(_unitName))) + if player.unit and player.unit:GetName() == _unitName then + self:T( self.lid .. string.format( "Found player=%s unit=%s in players table.", tostring( player.name ), tostring( _unitName ) ) ) return player.unit, player.name end end - return nil,nil + return nil, nil end --- Returns the unit of a player and the player name. If the unit does not belong to a player, nil is returned. @@ -14881,13 +14187,13 @@ end -- @param #string _unitName Name of the player unit. -- @return Wrapper.Unit#UNIT Unit of player or nil. -- @return #string Name of the player or nil. -function AIRBOSS:_GetPlayerUnitAndName(_unitName) - self:F2(_unitName) +function AIRBOSS:_GetPlayerUnitAndName( _unitName ) + self:F2( _unitName ) if _unitName ~= nil then -- First, let's look up all current players. - local u,pn=self:_GetPlayerUnit(_unitName) + local u, pn = self:_GetPlayerUnit( _unitName ) -- Return if u and pn then @@ -14895,22 +14201,22 @@ function AIRBOSS:_GetPlayerUnitAndName(_unitName) end -- Get DCS unit from its name. - local DCSunit=Unit.getByName(_unitName) + local DCSunit = Unit.getByName( _unitName ) if DCSunit then -- Get player name if any. - local playername=DCSunit:getPlayerName() + local playername = DCSunit:getPlayerName() -- Unit object. - local unit=UNIT:Find(DCSunit) + local unit = UNIT:Find( DCSunit ) -- Debug. - self:T2({DCSunit=DCSunit, unit=unit, playername=playername}) + self:T2( { DCSunit = DCSunit, unit = unit, playername = playername } ) -- Check if enverything is there. if DCSunit and unit and playername then - self:T(self.lid..string.format("Found DCS unit %s with player %s.", tostring(_unitName), tostring(playername))) + self:T( self.lid .. string.format( "Found DCS unit %s with player %s.", tostring( _unitName ), tostring( playername ) ) ) return unit, playername end @@ -14919,7 +14225,7 @@ function AIRBOSS:_GetPlayerUnitAndName(_unitName) end -- Return nil if we could not find a player. - return nil,nil + return nil, nil end --- Get carrier coalition. @@ -14952,7 +14258,7 @@ end function AIRBOSS:_GetStaticWeather() -- Weather data from mission file. - local weather=env.mission.weather + local weather = env.mission.weather -- Clouds --[[ @@ -14964,19 +14270,19 @@ function AIRBOSS:_GetStaticWeather() ["iprecptns"] = 1, }, -- end of ["clouds"] ]] - local clouds=weather.clouds + local clouds = weather.clouds -- Visibilty distance in meters. - local visibility=weather.visibility.distance + local visibility = weather.visibility.distance -- Dust --[[ ["enable_dust"] = false, ["dust_density"] = 0, ]] - local dust=nil - if weather.enable_dust==true then - dust=weather.dust_density + local dust = nil + if weather.enable_dust == true then + dust = weather.dust_density end -- Fog @@ -14988,12 +14294,11 @@ function AIRBOSS:_GetStaticWeather() ["visibility"] = 25, }, -- end of ["fog"] ]] - local fog=nil - if weather.enable_fog==true then - fog=weather.fog + local fog = nil + if weather.enable_fog == true then + fog = weather.fog end - return clouds, visibility, fog, dust end @@ -15004,9 +14309,9 @@ end --- Function called by DCS timer. Unused. -- @param #table param Parameters. -- @param #number time Time. -function AIRBOSS._CheckRadioQueueT(param, time) - AIRBOSS._CheckRadioQueue(param.airboss, param.radioqueue, param.name) - return time+0.05 +function AIRBOSS._CheckRadioQueueT( param, time ) + AIRBOSS._CheckRadioQueue( param.airboss, param.radioqueue, param.name ) + return time + 0.05 end --- Radio queue item. @@ -15023,83 +14328,83 @@ end -- @param #AIRBOSS self -- @param #table radioqueue The radio queue. -- @param #string name Name of the queue. -function AIRBOSS:_CheckRadioQueue(radioqueue, name) +function AIRBOSS:_CheckRadioQueue( radioqueue, name ) - --env.info(string.format("FF %s #radioqueue %d", name, #radioqueue)) + -- env.info(string.format("FF %s #radioqueue %d", name, #radioqueue)) -- Check if queue is empty. - if #radioqueue==0 then + if #radioqueue == 0 then - if name=="LSO" then - self:T(self.lid..string.format("Stopping LSO radio queue.")) - self.radiotimer:Stop(self.RQLid) - self.RQLid=nil - elseif name=="MARSHAL" then - self:T(self.lid..string.format("Stopping Marshal radio queue.")) - self.radiotimer:Stop(self.RQMid) - self.RQMid=nil + if name == "LSO" then + self:T( self.lid .. string.format( "Stopping LSO radio queue." ) ) + self.radiotimer:Stop( self.RQLid ) + self.RQLid = nil + elseif name == "MARSHAL" then + self:T( self.lid .. string.format( "Stopping Marshal radio queue." ) ) + self.radiotimer:Stop( self.RQMid ) + self.RQMid = nil end return end -- Get current abs time. - local _time=timer.getAbsTime() + local _time = timer.getAbsTime() - local playing=false - local next=nil --#AIRBOSS.Radioitem - local _remove=nil - for i,_transmission in ipairs(radioqueue) do - local transmission=_transmission --#AIRBOSS.Radioitem + local playing = false + local next = nil -- #AIRBOSS.Radioitem + local _remove = nil + for i, _transmission in ipairs( radioqueue ) do + local transmission = _transmission -- #AIRBOSS.Radioitem -- Check if transmission time has passed. - if _time>=transmission.Tplay then + if _time >= transmission.Tplay then -- Check if transmission is currently playing. if transmission.isplaying then -- Check if transmission is finished. - if _time>=transmission.Tstarted+transmission.call.duration then + if _time >= transmission.Tstarted + transmission.call.duration then -- Transmission over. - transmission.isplaying=false - _remove=i + transmission.isplaying = false + _remove = i - if transmission.radio.alias=="LSO" then - self.TQLSO=_time - elseif transmission.radio.alias=="MARSHAL" then - self.TQMarshal=_time + if transmission.radio.alias == "LSO" then + self.TQLSO = _time + elseif transmission.radio.alias == "MARSHAL" then + self.TQMarshal = _time end else -- still playing -- Transmission is still playing. - playing=true + playing = true end else -- not playing yet - local Tlast=nil + local Tlast = nil if transmission.interval then - if transmission.radio.alias=="LSO" then - Tlast=self.TQLSO - elseif transmission.radio.alias=="MARSHAL" then - Tlast=self.TQMarshal + if transmission.radio.alias == "LSO" then + Tlast = self.TQLSO + elseif transmission.radio.alias == "MARSHAL" then + Tlast = self.TQMarshal end end - if transmission.interval==nil then + if transmission.interval == nil then -- Not playing ==> this will be next. - if next==nil then - next=transmission + if next == nil then + next = transmission end else - if _time-Tlast>=transmission.interval then - next=transmission + if _time - Tlast >= transmission.interval then + next = transmission else end @@ -15114,21 +14419,21 @@ function AIRBOSS:_CheckRadioQueue(radioqueue, name) else - -- Transmission not due yet. + -- Transmission not due yet. end end -- Found a new transmission. - if next~=nil and not playing then - self:Broadcast(next.radio, next.call, next.loud) - next.isplaying=true - next.Tstarted=_time + if next ~= nil and not playing then + self:Broadcast( next.radio, next.call, next.loud ) + next.isplaying = true + next.Tstarted = _time end -- Remove completed calls from queue. if _remove then - table.remove(radioqueue, _remove) + table.remove( radioqueue, _remove ) end return @@ -15143,76 +14448,75 @@ end -- @param #number interval Interval in seconds after the last sound has been played. -- @param #boolean click If true, play radio click at the end. -- @param #boolean pilotcall If true, it's a pilot call. -function AIRBOSS:RadioTransmission(radio, call, loud, delay, interval, click, pilotcall) - self:F2({radio=radio, call=call, loud=loud, delay=delay, interval=interval, click=click}) +function AIRBOSS:RadioTransmission( radio, call, loud, delay, interval, click, pilotcall ) + self:F2( { radio = radio, call = call, loud = loud, delay = delay, interval = interval, click = click } ) -- Nil check. - if radio==nil or call==nil then + if radio == nil or call == nil then return end -- Create a new radio transmission item. - local transmission={} --#AIRBOSS.Radioitem + local transmission = {} -- #AIRBOSS.Radioitem - transmission.radio=radio - transmission.call=call - transmission.Tplay=timer.getAbsTime()+(delay or 0) - transmission.interval=interval - transmission.isplaying=false - transmission.Tstarted=nil - transmission.loud=loud and call.loud + transmission.radio = radio + transmission.call = call + transmission.Tplay = timer.getAbsTime() + (delay or 0) + transmission.interval = interval + transmission.isplaying = false + transmission.Tstarted = nil + transmission.loud = loud and call.loud -- Player onboard number if sender has one. - if self:_IsOnboard(call.modexsender) then - self:_Number2Radio(radio, call.modexsender, delay, 0.3, pilotcall) + if self:_IsOnboard( call.modexsender ) then + self:_Number2Radio( radio, call.modexsender, delay, 0.3, pilotcall ) end -- Play onboard number if receiver has one. - if self:_IsOnboard(call.modexreceiver) then - self:_Number2Radio(radio, call.modexreceiver, delay, 0.3, pilotcall) + if self:_IsOnboard( call.modexreceiver ) then + self:_Number2Radio( radio, call.modexreceiver, delay, 0.3, pilotcall ) end -- Add transmission to the right queue. - local caller="" - if radio.alias=="LSO" then + local caller = "" + if radio.alias == "LSO" then - table.insert(self.RQLSO, transmission) + table.insert( self.RQLSO, transmission ) - caller="LSOCall" + caller = "LSOCall" -- Schedule radio queue checks. if not self.RQLid then - self:T(self.lid..string.format("Starting LSO radio queue.")) - self.RQLid=self.radiotimer:Schedule(nil, AIRBOSS._CheckRadioQueue, {self, self.RQLSO, "LSO"}, 0.02, 0.05) + self:T( self.lid .. string.format( "Starting LSO radio queue." ) ) + self.RQLid = self.radiotimer:Schedule( nil, AIRBOSS._CheckRadioQueue, { self, self.RQLSO, "LSO" }, 0.02, 0.05 ) end - elseif radio.alias=="MARSHAL" then + elseif radio.alias == "MARSHAL" then - table.insert(self.RQMarshal, transmission) + table.insert( self.RQMarshal, transmission ) - caller="MarshalCall" + caller = "MarshalCall" if not self.RQMid then - self:T(self.lid..string.format("Starting Marhal radio queue.")) - self.RQMid=self.radiotimer:Schedule(nil, AIRBOSS._CheckRadioQueue, {self, self.RQMarshal, "MARSHAL"}, 0.02, 0.05) + self:T( self.lid .. string.format( "Starting Marhal radio queue." ) ) + self.RQMid = self.radiotimer:Schedule( nil, AIRBOSS._CheckRadioQueue, { self, self.RQMarshal, "MARSHAL" }, 0.02, 0.05 ) end end -- Append radio click sound at the end of the transmission. if click then - self:RadioTransmission(radio, self[caller].CLICK, false, delay) + self:RadioTransmission( radio, self[caller].CLICK, false, delay ) end end - --- Check if a call needs a subtitle because the complete voice overs are not available. -- @param #AIRBOSS self -- @param #AIRBOSS.RadioCall call Radio sound files and subtitles. -- @return #boolean If true, call needs a subtitle. -function AIRBOSS:_NeedsSubtitle(call) +function AIRBOSS:_NeedsSubtitle( call ) -- Currently we play the noise file. - if call.file==self.MarshalCall.NOISE.file or call.file==self.LSOCall.NOISE.file then + if call.file == self.MarshalCall.NOISE.file or call.file == self.LSOCall.NOISE.file then return true else return false @@ -15224,8 +14528,8 @@ end -- @param #AIRBOSS.Radio radio Radio sending transmission. -- @param #AIRBOSS.RadioCall call Radio sound files and subtitles. -- @param #boolean loud Play loud version of file. -function AIRBOSS:Broadcast(radio, call, loud) - self:F(call) +function AIRBOSS:Broadcast( radio, call, loud ) + self:F( call ) -- Check which sound output method to use. if not self.usersoundradio then @@ -15235,72 +14539,74 @@ function AIRBOSS:Broadcast(radio, call, loud) ---------------------------- -- Get unit sending the transmission. - local sender=self:_GetRadioSender(radio) + local sender = self:_GetRadioSender( radio ) -- Construct file name and subtitle. - local filename=self:_RadioFilename(call, loud, radio.alias) + local filename = self:_RadioFilename( call, loud, radio.alias ) -- Create subtitle for transmission. - local subtitle=self:_RadioSubtitle(radio, call, loud) + local subtitle = self:_RadioSubtitle( radio, call, loud ) -- Debug. - self:T({filename=filename, subtitle=subtitle}) + self:T( { filename = filename, subtitle = subtitle } ) if sender then -- Broadcasting from aircraft. Only players tuned in to the right frequency will see the message. - self:T(self.lid..string.format("Broadcasting from aircraft %s", sender:GetName())) + self:T( self.lid .. string.format( "Broadcasting from aircraft %s", sender:GetName() ) ) -- Command to set the Frequency for the transmission. - local commandFrequency={ - id="SetFrequency", - params={ - frequency=radio.frequency*1000000, -- Frequency in Hz. - modulation=radio.modulation, - }} + local commandFrequency = { + id = "SetFrequency", + params = { + frequency = radio.frequency * 1000000, -- Frequency in Hz. + modulation = radio.modulation, + }, + } -- Command to tranmit the call. - local commandTransmit={ + local commandTransmit = { id = "TransmitMessage", params = { - file=filename, - duration=call.subduration or 5, - subtitle=subtitle, - loop=false, - }} + file = filename, + duration = call.subduration or 5, + subtitle = subtitle, + loop = false, + }, + } -- Set commend for frequency - sender:SetCommand(commandFrequency) + sender:SetCommand( commandFrequency ) -- Set command for radio transmission. - sender:SetCommand(commandTransmit) + sender:SetCommand( commandTransmit ) else -- Broadcasting from carrier. No subtitle possible. Need to send messages to players. - self:T(self.lid..string.format("Broadcasting from carrier via trigger.action.radioTransmission().")) + self:T( self.lid .. string.format( "Broadcasting from carrier via trigger.action.radioTransmission()." ) ) -- Transmit from carrier position. - local vec3=self.carrier:GetPositionVec3() + local vec3 = self.carrier:GetPositionVec3() -- Transmit via trigger. - trigger.action.radioTransmission(filename, vec3, radio.modulation, false, radio.frequency*1000000, 100) + trigger.action.radioTransmission( filename, vec3, radio.modulation, false, radio.frequency * 1000000, 100 ) -- Display subtitle of message to players. - for _,_player in pairs(self.players) do - local playerData=_player --#AIRBOSS.PlayerData + for _, _player in pairs( self.players ) do + local playerData = _player -- #AIRBOSS.PlayerData -- Message to all players in CCA that have subtites on. - if playerData.unit:IsInZone(self.zoneCCA) and playerData.actype~=AIRBOSS.AircraftCarrier.A4EC then + if playerData.unit:IsInZone( self.zoneCCA ) and playerData.actype ~= AIRBOSS.AircraftCarrier.A4EC then -- Only to players with subtitle on or if noise is played. - if playerData.subtitles or self:_NeedsSubtitle(call) then + if playerData.subtitles or self:_NeedsSubtitle( call ) then -- Messages to marshal to everyone. Messages on LSO radio only to those in the pattern. - if radio.alias=="MARSHAL" or (radio.alias=="LSO" and self:_InQueue(self.Qpattern, playerData.group)) then + if radio.alias == "MARSHAL" or (radio.alias == "LSO" and self:_InQueue( self.Qpattern, playerData.group )) then -- Message to player. - self:MessageToPlayer(playerData, subtitle, nil, "", call.subduration or 5) + self:MessageToPlayer( playerData, subtitle, nil, "", call.subduration or 5 ) end @@ -15316,17 +14622,17 @@ function AIRBOSS:Broadcast(radio, call, loud) ---------------- -- Workaround for the community A-4E-C as long as their radios are not functioning properly. - for _,_player in pairs(self.players) do - local playerData=_player --#AIRBOSS.PlayerData + for _, _player in pairs( self.players ) do + local playerData = _player -- #AIRBOSS.PlayerData -- Easy comms if globally activated but definitly for all player in the community A-4E. - if self.usersoundradio or playerData.actype==AIRBOSS.AircraftCarrier.A4EC then + if self.usersoundradio or playerData.actype == AIRBOSS.AircraftCarrier.A4EC then -- Messages to marshal to everyone. Messages on LSO radio only to those in the pattern. - if radio.alias=="MARSHAL" or (radio.alias=="LSO" and self:_InQueue(self.Qpattern, playerData.group)) then + if radio.alias == "MARSHAL" or (radio.alias == "LSO" and self:_InQueue( self.Qpattern, playerData.group )) then -- User sound to players (inside CCA). - self:Sound2Player(playerData, radio, call, loud) + self:Sound2Player( playerData, radio, call, loud ) end end @@ -15341,23 +14647,23 @@ end -- @param #AIRBOSS.RadioCall call Radio sound files and subtitles. -- @param #boolean loud If true, play loud sound file version. -- @param #number delay Delay in seconds, before the message is broadcasted. -function AIRBOSS:Sound2Player(playerData, radio, call, loud, delay) +function AIRBOSS:Sound2Player( playerData, radio, call, loud, delay ) -- Only to players inside the CCA. - if playerData.unit:IsInZone(self.zoneCCA) and call then + if playerData.unit:IsInZone( self.zoneCCA ) and call then -- Construct file name. - local filename=self:_RadioFilename(call, loud, radio.alias) + local filename = self:_RadioFilename( call, loud, radio.alias ) -- Get Subtitle - local subtitle=self:_RadioSubtitle(radio, call, loud) + local subtitle = self:_RadioSubtitle( radio, call, loud ) -- Play sound file via usersound trigger. - USERSOUND:New(filename):ToGroup(playerData.group, delay) + USERSOUND:New( filename ):ToGroup( playerData.group, delay ) -- Only to players with subtitle on or if noise is played. - if playerData.subtitles or self:_NeedsSubtitle(call) then - self:MessageToPlayer(playerData, subtitle, nil, "", call.subduration, false, delay) + if playerData.subtitles or self:_NeedsSubtitle( call ) then + self:MessageToPlayer( playerData, subtitle, nil, "", call.subduration, false, delay ) end end @@ -15369,44 +14675,44 @@ end -- @param #AIRBOSS.RadioCall call Radio sound files and subtitles. -- @param #boolean loud If true, append "!" else ".". -- @return #string Subtitle to be displayed. -function AIRBOSS:_RadioSubtitle(radio, call, loud) +function AIRBOSS:_RadioSubtitle( radio, call, loud ) -- No subtitle if call is nil, or subtitle is nil or subtitle is empty. - if call==nil or call.subtitle==nil or call.subtitle=="" then + if call == nil or call.subtitle == nil or call.subtitle == "" then return "" end -- Sender - local sender=call.sender or radio.alias + local sender = call.sender or radio.alias if call.modexsender then - sender=call.modexsender + sender = call.modexsender end -- Modex of receiver. - local receiver=call.modexreceiver or "" + local receiver = call.modexreceiver or "" -- Init subtitle. - local subtitle=string.format("%s: %s", sender, call.subtitle) - if receiver and receiver~="" then - subtitle=string.format("%s: %s, %s", sender, receiver, call.subtitle) + local subtitle = string.format( "%s: %s", sender, call.subtitle ) + if receiver and receiver ~= "" then + subtitle = string.format( "%s: %s, %s", sender, receiver, call.subtitle ) end -- Last character of the string. - local lastchar=string.sub(subtitle, -1) + local lastchar = string.sub( subtitle, -1 ) -- Append ! or . if loud then - if lastchar=="." or lastchar=="!" then - subtitle=string.sub(subtitle, 1,-1) + if lastchar == "." or lastchar == "!" then + subtitle = string.sub( subtitle, 1, -1 ) end - subtitle=subtitle.."!" + subtitle = subtitle .. "!" else - if lastchar=="!" then + if lastchar == "!" then -- This also okay. - elseif lastchar=="." then + elseif lastchar == "." then -- Nothing to do. else - subtitle=subtitle.."." + subtitle = subtitle .. "." end end @@ -15419,30 +14725,30 @@ end -- @param #boolean loud Use loud version of file if available. -- @param #string channel Radio channel alias "LSO" or "LSOCall", "MARSHAL" or "MarshalCall". -- @return #string The file name of the radio sound. -function AIRBOSS:_RadioFilename(call, loud, channel) +function AIRBOSS:_RadioFilename( call, loud, channel ) -- Construct file name and subtitle. - local prefix=call.file or "" - local suffix=call.suffix or "ogg" + local prefix = call.file or "" + local suffix = call.suffix or "ogg" -- Path to sound files. Default is in the ME - local path=self.soundfolder or "l10n/DEFAULT/" + local path = self.soundfolder or "l10n/DEFAULT/" -- Check for special LSO and Marshal sound folders. - if string.find(call.file, "LSO-") and channel and (channel=="LSO" or channel=="LSOCall") then - path=self.soundfolderLSO or path + if string.find( call.file, "LSO-" ) and channel and (channel == "LSO" or channel == "LSOCall") then + path = self.soundfolderLSO or path end - if string.find(call.file, "MARSHAL-") and channel and (channel=="MARSHAL" or channel=="MarshalCall") then - path=self.soundfolderMSH or path + if string.find( call.file, "MARSHAL-" ) and channel and (channel == "MARSHAL" or channel == "MarshalCall") then + path = self.soundfolderMSH or path end -- Loud version. if loud then - prefix=prefix.."_Loud" + prefix = prefix .. "_Loud" end -- File name inclusing path in miz file. - local filename=string.format("%s%s.%s", path, prefix, suffix) + local filename = string.format( "%s%s.%s", path, prefix, suffix ) return filename end @@ -15457,76 +14763,76 @@ end -- @param #number duration Display message duration. Default 10 seconds. -- @param #boolean clear If true, clear screen from previous messages. -- @param #number delay Delay in seconds, before the message is displayed. -function AIRBOSS:MessageToPlayer(playerData, message, sender, receiver, duration, clear, delay) +function AIRBOSS:MessageToPlayer( playerData, message, sender, receiver, duration, clear, delay ) - if playerData and message and message~="" then + if playerData and message and message ~= "" then -- Default duration. - duration=duration or self.Tmessage + duration = duration or self.Tmessage -- Format message. local text - if receiver and receiver=="" then + if receiver and receiver == "" then -- No (blank) receiver. - text=string.format("%s", message) + text = string.format( "%s", message ) else -- Default "receiver" is onboard number of player. - receiver=receiver or playerData.onboard - text=string.format("%s, %s", receiver, message) + receiver = receiver or playerData.onboard + text = string.format( "%s, %s", receiver, message ) end - self:T(self.lid..text) + self:T( self.lid .. text ) - if delay and delay>0 then + if delay and delay > 0 then -- Delayed call. - --SCHEDULER:New(nil, self.MessageToPlayer, {self, playerData, message, sender, receiver, duration, clear}, delay) - self:ScheduleOnce(delay, self.MessageToPlayer, self, playerData, message, sender, receiver, duration, clear) + -- SCHEDULER:New(nil, self.MessageToPlayer, {self, playerData, message, sender, receiver, duration, clear}, delay) + self:ScheduleOnce( delay, self.MessageToPlayer, self, playerData, message, sender, receiver, duration, clear ) else -- Wait until previous sound finished. - local wait=0 + local wait = 0 -- Onboard number to get the attention. - if receiver==playerData.onboard then + if receiver == playerData.onboard then -- Which voice over number to use. - if sender and (sender=="LSO" or sender=="MARSHAL" or sender=="AIRBOSS") then + if sender and (sender == "LSO" or sender == "MARSHAL" or sender == "AIRBOSS") then -- User sound of board number. - wait=wait+self:_Number2Sound(playerData, sender, receiver) + wait = wait + self:_Number2Sound( playerData, sender, receiver ) end end -- Negative. - if string.find(text:lower(), "negative") then - local filename=self:_RadioFilename(self.MarshalCall.NEGATIVE, false, "MARSHAL") - USERSOUND:New(filename):ToGroup(playerData.group, wait) - wait=wait+self.MarshalCall.NEGATIVE.duration + if string.find( text:lower(), "negative" ) then + local filename = self:_RadioFilename( self.MarshalCall.NEGATIVE, false, "MARSHAL" ) + USERSOUND:New( filename ):ToGroup( playerData.group, wait ) + wait = wait + self.MarshalCall.NEGATIVE.duration end -- Affirm. - if string.find(text:lower(), "affirm") then - local filename=self:_RadioFilename(self.MarshalCall.AFFIRMATIVE, false, "MARSHAL") - USERSOUND:New(filename):ToGroup(playerData.group, wait) - wait=wait+self.MarshalCall.AFFIRMATIVE.duration + if string.find( text:lower(), "affirm" ) then + local filename = self:_RadioFilename( self.MarshalCall.AFFIRMATIVE, false, "MARSHAL" ) + USERSOUND:New( filename ):ToGroup( playerData.group, wait ) + wait = wait + self.MarshalCall.AFFIRMATIVE.duration end -- Roger. - if string.find(text:lower(), "roger") then - local filename=self:_RadioFilename(self.MarshalCall.ROGER, false, "MARSHAL") - USERSOUND:New(filename):ToGroup(playerData.group, wait) - wait=wait+self.MarshalCall.ROGER.duration + if string.find( text:lower(), "roger" ) then + local filename = self:_RadioFilename( self.MarshalCall.ROGER, false, "MARSHAL" ) + USERSOUND:New( filename ):ToGroup( playerData.group, wait ) + wait = wait + self.MarshalCall.ROGER.duration end -- Play click sound to end message. - if wait>0 then - local filename=self:_RadioFilename(self.MarshalCall.CLICK) - USERSOUND:New(filename):ToGroup(playerData.group, wait) + if wait > 0 then + local filename = self:_RadioFilename( self.MarshalCall.CLICK ) + USERSOUND:New( filename ):ToGroup( playerData.group, wait ) end -- Text message to player client. if playerData.client then - MESSAGE:New(text, duration, sender, clear):ToClient(playerData.client) + MESSAGE:New( text, duration, sender, clear ):ToClient( playerData.client ) end end @@ -15534,7 +14840,6 @@ function AIRBOSS:MessageToPlayer(playerData, message, sender, receiver, duration end end - --- Send text message to all players in the pattern queue. -- Message format will be "SENDER: RECCEIVER, MESSAGE". -- @param #AIRBOSS self @@ -15544,13 +14849,13 @@ end -- @param #number duration Display message duration. Default 10 seconds. -- @param #boolean clear If true, clear screen from previous messages. -- @param #number delay Delay in seconds, before the message is displayed. -function AIRBOSS:MessageToPattern(message, sender, receiver, duration, clear, delay) +function AIRBOSS:MessageToPattern( message, sender, receiver, duration, clear, delay ) -- Create new (fake) radio call to show the subtitile. - local call=self:_NewRadioCall(self.LSOCall.NOISE, sender or "LSO", message, duration, receiver, sender) + local call = self:_NewRadioCall( self.LSOCall.NOISE, sender or "LSO", message, duration, receiver, sender ) -- Dummy radio transmission to display subtitle only to those who tuned in. - self:RadioTransmission(self.LSORadio, call, false, delay, nil, true) + self:RadioTransmission( self.LSORadio, call, false, delay, nil, true ) end @@ -15563,13 +14868,13 @@ end -- @param #number duration Display message duration. Default 10 seconds. -- @param #boolean clear If true, clear screen from previous messages. -- @param #number delay Delay in seconds, before the message is displayed. -function AIRBOSS:MessageToMarshal(message, sender, receiver, duration, clear, delay) +function AIRBOSS:MessageToMarshal( message, sender, receiver, duration, clear, delay ) -- Create new (fake) radio call to show the subtitile. - local call=self:_NewRadioCall(self.MarshalCall.NOISE, sender or "MARSHAL", message, duration, receiver, sender) + local call = self:_NewRadioCall( self.MarshalCall.NOISE, sender or "MARSHAL", message, duration, receiver, sender ) -- Dummy radio transmission to display subtitle only to those who tuned in. - self:RadioTransmission(self.MarshalRadio, call, false, delay, nil, true) + self:RadioTransmission( self.MarshalRadio, call, false, delay, nil, true ) end @@ -15581,28 +14886,28 @@ end -- @param #number subduration Time in seconds the subtitle is displayed. Default 10 seconds. -- @param #string modexreceiver Onboard number of the receiver or nil. -- @param #string modexsender Onboard number of the sender or nil. -function AIRBOSS:_NewRadioCall(call, sender, subtitle, subduration, modexreceiver, modexsender) +function AIRBOSS:_NewRadioCall( call, sender, subtitle, subduration, modexreceiver, modexsender ) -- Create a new call - local newcall=UTILS.DeepCopy(call) --#AIRBOSS.RadioCall + local newcall = UTILS.DeepCopy( call ) -- #AIRBOSS.RadioCall -- Sender for displaying the subtitle. - newcall.sender=sender + newcall.sender = sender -- Subtitle of the message. - newcall.subtitle=subtitle or call.subtitle + newcall.subtitle = subtitle or call.subtitle -- Duration of subtitle display. - newcall.subduration=subduration or self.Tmessage + newcall.subduration = subduration or self.Tmessage -- Tail number of the receiver. - if self:_IsOnboard(modexreceiver) then - newcall.modexreceiver=modexreceiver + if self:_IsOnboard( modexreceiver ) then + newcall.modexreceiver = modexreceiver end -- Tail number of the sender. - if self:_IsOnboard(modexsender) then - newcall.modexsender=modexsender + if self:_IsOnboard( modexsender ) then + newcall.modexsender = modexsender end return newcall @@ -15612,27 +14917,27 @@ end -- @param #AIRBOSS self -- @param #AIRBOSS.Radio radio Airboss radio data. -- @return Wrapper.Unit#UNIT Sending aircraft unit or nil if was not setup, is not an aircraft or is not alive. -function AIRBOSS:_GetRadioSender(radio) +function AIRBOSS:_GetRadioSender( radio ) -- Check if we have a sending aircraft. - local sender=nil --Wrapper.Unit#UNIT + local sender = nil -- Wrapper.Unit#UNIT -- Try the general default. if self.senderac then - sender=UNIT:FindByName(self.senderac) + sender = UNIT:FindByName( self.senderac ) end -- Try the specific marshal unit. - if radio.alias=="MARSHAL" then + if radio.alias == "MARSHAL" then if self.radiorelayMSH then - sender=UNIT:FindByName(self.radiorelayMSH) + sender = UNIT:FindByName( self.radiorelayMSH ) end end -- Try the specific LSO unit. - if radio.alias=="LSO" then + if radio.alias == "LSO" then if self.radiorelayLSO then - sender=UNIT:FindByName(self.radiorelayLSO) + sender = UNIT:FindByName( self.radiorelayLSO ) end end @@ -15648,25 +14953,25 @@ end -- @param #AIRBOSS self -- @param #string text Text to check. -- @return #boolean If true, text is an onboard number of a flight. -function AIRBOSS:_IsOnboard(text) +function AIRBOSS:_IsOnboard( text ) -- Nil check. - if text==nil then + if text == nil then return false end -- Message to all. - if text=="99" then + if text == "99" then return true end -- Loop over all flights. - for _,_flight in pairs(self.flights) do - local flight=_flight --#AIRBOSS.FlightGroup + for _, _flight in pairs( self.flights ) do + local flight = _flight -- #AIRBOSS.FlightGroup -- Loop over all onboard number of that flight. - for _,onboard in pairs(flight.onboardnumbers) do - if text==onboard then + for _, onboard in pairs( flight.onboardnumbers ) do + if text == onboard then return true end end @@ -15683,55 +14988,55 @@ end -- @param #string number Number string, e.g. "032" or "183". -- @param #number delay Delay before transmission in seconds. -- @return #number Duration of the call in seconds. -function AIRBOSS:_Number2Sound(playerData, sender, number, delay) +function AIRBOSS:_Number2Sound( playerData, sender, number, delay ) -- Default. - delay=delay or 0 + delay = delay or 0 --- Split string into characters. - local function _split(str) - local chars={} - for i=1,#str do - local c=str:sub(i,i) - table.insert(chars, c) + local function _split( str ) + local chars = {} + for i = 1, #str do + local c = str:sub( i, i ) + table.insert( chars, c ) end return chars end -- Sender local Sender - if sender=="LSO" then - Sender="LSOCall" - elseif sender=="MARSHAL" or sender=="AIRBOSS" then - Sender="MarshalCall" + if sender == "LSO" then + Sender = "LSOCall" + elseif sender == "MARSHAL" or sender == "AIRBOSS" then + Sender = "MarshalCall" else - self:E(self.lid..string.format("ERROR: Unknown radio sender %s!", tostring(sender))) + self:E( self.lid .. string.format( "ERROR: Unknown radio sender %s!", tostring( sender ) ) ) return end -- Split string into characters. - local numbers=_split(number) + local numbers = _split( number ) - local wait=0 - for i=1,#numbers do + local wait = 0 + for i = 1, #numbers do -- Current number - local n=numbers[i] + local n = numbers[i] -- Convert to N0, N1, ... - local N=string.format("N%s", n) + local N = string.format( "N%s", n ) -- Radio call. - local call=self[Sender][N] --#AIRBOSS.RadioCall + local call = self[Sender][N] -- #AIRBOSS.RadioCall -- Create file name. - local filename=self:_RadioFilename(call, false, Sender) + local filename = self:_RadioFilename( call, false, Sender ) -- Play sound. - USERSOUND:New(filename):ToGroup(playerData.group, delay+wait) + USERSOUND:New( filename ):ToGroup( playerData.group, delay + wait ) -- Wait until this call is over before playing the next. - wait=wait+call.duration + wait = wait + call.duration end return wait @@ -15746,56 +15051,56 @@ end -- @param #number interval Interval between the next call. -- @param #boolean pilotcall If true, use pilot sound files. -- @return #number Duration of the call in seconds. -function AIRBOSS:_Number2Radio(radio, number, delay, interval, pilotcall) +function AIRBOSS:_Number2Radio( radio, number, delay, interval, pilotcall ) --- Split string into characters. - local function _split(str) - local chars={} - for i=1,#str do - local c=str:sub(i,i) - table.insert(chars, c) + local function _split( str ) + local chars = {} + for i = 1, #str do + local c = str:sub( i, i ) + table.insert( chars, c ) end return chars end -- Sender. - local Sender="" - if radio.alias=="LSO" then - Sender="LSOCall" - elseif radio.alias=="MARSHAL" then - Sender="MarshalCall" + local Sender = "" + if radio.alias == "LSO" then + Sender = "LSOCall" + elseif radio.alias == "MARSHAL" then + Sender = "MarshalCall" else - self:E(self.lid..string.format("ERROR: Unknown radio alias %s!", tostring(radio.alias))) + self:E( self.lid .. string.format( "ERROR: Unknown radio alias %s!", tostring( radio.alias ) ) ) end if pilotcall then - Sender="PilotCall" + Sender = "PilotCall" end -- Split string into characters. - local numbers=_split(number) + local numbers = _split( number ) - local wait=0 - for i=1,#numbers do + local wait = 0 + for i = 1, #numbers do -- Current number - local n=numbers[i] + local n = numbers[i] -- Convert to N0, N1, ... - local N=string.format("N%s", n) + local N = string.format( "N%s", n ) -- Radio call. - local call=self[Sender][N] --#AIRBOSS.RadioCall + local call = self[Sender][N] -- #AIRBOSS.RadioCall - if interval and i==1 then + if interval and i == 1 then -- Transmit. - self:RadioTransmission(radio, call, false, delay, interval) + self:RadioTransmission( radio, call, false, delay, interval ) else - self:RadioTransmission(radio, call, false, delay) + self:RadioTransmission( radio, call, false, delay ) end -- Add up duration of the number. - wait=wait+call.duration + wait = wait + call.duration end -- Return the total duration of the call. @@ -15887,58 +15192,59 @@ end -- @param #string modex Tail number. -- @param #string nickname Aircraft nickname. -- @param #number fuelstate Aircraft fuel state in thouthands of pounds. -function AIRBOSS:_LSOCallAircraftBall(modex, nickname, fuelstate) +function AIRBOSS:_LSOCallAircraftBall( modex, nickname, fuelstate ) -- Pilot: "405, Hornet Ball, 3.2" - local text=string.format("%s Ball, %.1f.", nickname, fuelstate) + local text = string.format( "%s Ball, %.1f.", nickname, fuelstate ) -- Debug message. - self:T(self.lid..text) + self:I( self.lid .. text ) -- Nickname UPPERCASE. - local NICKNAME=nickname:upper() + local NICKNAME = nickname:upper() -- Fuel state. - local FS=UTILS.Split(string.format("%.1f", fuelstate), ".") + local FS = UTILS.Split( string.format( "%.1f", fuelstate ), "." ) -- Create new call to display complete subtitle. - local call=self:_NewRadioCall(self.PilotCall[NICKNAME], modex, text, self.Tmessage, nil, modex) + local call = self:_NewRadioCall( self.PilotCall[NICKNAME], modex, text, self.Tmessage, nil, modex ) -- Hornet .. - self:RadioTransmission(self.LSORadio, call, nil, nil, nil, nil, true) + self:RadioTransmission( self.LSORadio, call, nil, nil, nil, nil, true ) -- Ball, - self:RadioTransmission(self.LSORadio, self.PilotCall.BALL, nil, nil, nil, nil, true) + self:RadioTransmission( self.LSORadio, self.PilotCall.BALL, nil, nil, nil, nil, true ) -- X.. - self:_Number2Radio(self.LSORadio, FS[1], nil, nil, true) + self:_Number2Radio( self.LSORadio, FS[1], nil, nil, true ) -- Point.. - self:RadioTransmission(self.LSORadio, self.PilotCall.POINT, nil, nil, nil, nil, true) + self:RadioTransmission( self.LSORadio, self.PilotCall.POINT, nil, nil, nil, nil, true ) -- Y. - self:_Number2Radio(self.LSORadio, FS[2], nil, nil, true) + self:_Number2Radio( self.LSORadio, FS[2], nil, nil, true ) -- CLICK! - self:RadioTransmission(self.LSORadio, self.LSOCall.CLICK) + self:RadioTransmission( self.LSORadio, self.LSOCall.CLICK ) end --- AI is bingo and goes to the recovery tanker. -- @param #AIRBOSS self -- @param #string modex Tail number. -function AIRBOSS:_MarshalCallGasAtTanker(modex) +function AIRBOSS:_MarshalCallGasAtTanker( modex ) -- Subtitle. - local text=string.format("Bingo fuel! Going for gas at the recovery tanker.") + local text = string.format( "Bingo fuel! Going for gas at the recovery tanker." ) -- Debug message. - self:T(self.lid..text) + self:I( self.lid .. text ) + -- Create new call to display complete subtitle. - local call=self:_NewRadioCall(self.PilotCall.BINGOFUEL, modex, text, self.Tmessage, nil, modex) + local call = self:_NewRadioCall( self.PilotCall.BINGOFUEL, modex, text, self.Tmessage, nil, modex ) -- MODEX, bingo fuel! - self:RadioTransmission(self.MarshalRadio, call, nil, nil, nil, nil, true) + self:RadioTransmission( self.MarshalRadio, call, nil, nil, nil, nil, true ) -- Going for fuel at the recovery tanker. Click! - self:RadioTransmission(self.MarshalRadio, self.PilotCall.GASATTANKER, nil, nil, nil, true, true) + self:RadioTransmission( self.MarshalRadio, self.PilotCall.GASATTANKER, nil, nil, nil, true, true ) end @@ -15946,48 +15252,47 @@ end -- @param #AIRBOSS self -- @param #string modex Tail number. -- @param #string divertname Name of the divert field. -function AIRBOSS:_MarshalCallGasAtDivert(modex, divertname) +function AIRBOSS:_MarshalCallGasAtDivert( modex, divertname ) -- Subtitle. - local text=string.format("Bingo fuel! Going for gas at divert field %s.", divertname) + local text = string.format( "Bingo fuel! Going for gas at divert field %s.", divertname ) -- Debug message. - self:T(self.lid..text) + self:I( self.lid .. text ) -- Create new call to display complete subtitle. - local call=self:_NewRadioCall(self.PilotCall.BINGOFUEL, modex, text, self.Tmessage, nil, modex) + local call = self:_NewRadioCall( self.PilotCall.BINGOFUEL, modex, text, self.Tmessage, nil, modex ) -- MODEX, bingo fuel! - self:RadioTransmission(self.MarshalRadio, call, nil, nil, nil, nil, true) + self:RadioTransmission( self.MarshalRadio, call, nil, nil, nil, nil, true ) -- Going for fuel at the divert field. Click! - self:RadioTransmission(self.MarshalRadio, self.PilotCall.GASATDIVERT, nil, nil, nil, true, true) + self:RadioTransmission( self.MarshalRadio, self.PilotCall.GASATDIVERT, nil, nil, nil, true, true ) end - --- Inform everyone that recovery ops are stopped and deck is closed. -- @param #AIRBOSS self -- @param #number case Recovery case. -function AIRBOSS:_MarshalCallRecoveryStopped(case) +function AIRBOSS:_MarshalCallRecoveryStopped( case ) -- Subtitle. - local text=string.format("Case %d recovery ops are stopped. Deck is closed.", case) + local text = string.format( "Case %d recovery ops are stopped. Deck is closed.", case ) -- Debug message. - self:T(self.lid..text) + self:I( self.lid .. text ) -- Create new call to display complete subtitle. - local call=self:_NewRadioCall(self.MarshalCall.CASE, "AIRBOSS", text, self.Tmessage, "99") + local call = self:_NewRadioCall( self.MarshalCall.CASE, "AIRBOSS", text, self.Tmessage, "99" ) -- 99, Case.. - self:RadioTransmission(self.MarshalRadio, call) + self:RadioTransmission( self.MarshalRadio, call ) -- X. - self:_Number2Radio(self.MarshalRadio, tostring(case)) + self:_Number2Radio( self.MarshalRadio, tostring( case ) ) -- recovery ops are stopped. - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.RECOVERYOPSSTOPPED, nil, nil, 0.2) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.RECOVERYOPSSTOPPED, nil, nil, 0.2 ) -- Deck is closed. Click! - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.DECKCLOSED, nil, nil, nil, true) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.DECKCLOSED, nil, nil, nil, true ) end @@ -15996,68 +15301,67 @@ end function AIRBOSS:_MarshalCallRecoveryPausedUntilFurtherNotice() -- Create new call. Subtitle already set. - local call=self:_NewRadioCall(self.MarshalCall.RECOVERYPAUSEDNOTICE, "AIRBOSS", nil, self.Tmessage, "99") + local call = self:_NewRadioCall( self.MarshalCall.RECOVERYPAUSEDNOTICE, "AIRBOSS", nil, self.Tmessage, "99" ) -- 99, aircraft recovery is paused until further notice. - self:RadioTransmission(self.MarshalRadio, call, nil, nil, nil, true) + self:RadioTransmission( self.MarshalRadio, call, nil, nil, nil, true ) end --- Inform everyone that recovery is paused and will resume at a certain time. -- @param #AIRBOSS self -- @param #string clock Time. -function AIRBOSS:_MarshalCallRecoveryPausedResumedAt(clock) +function AIRBOSS:_MarshalCallRecoveryPausedResumedAt( clock ) -- Get relevant part of clock. - local _clock=UTILS.Split(clock, "+") - local CT=UTILS.Split(_clock[1], ":") + local _clock = UTILS.Split( clock, "+" ) + local CT = UTILS.Split( _clock[1], ":" ) -- Subtitle. - local text=string.format("aircraft recovery is paused and will be resumed at %s.", clock) + local text = string.format( "aircraft recovery is paused and will be resumed at %s.", clock ) -- Debug message. - self:T(self.lid..text) + self:I( self.lid .. text ) -- Create new call with full subtitle. - local call=self:_NewRadioCall(self.MarshalCall.RECOVERYPAUSEDRESUMED, "AIRBOSS", text, self.Tmessage, "99") + local call = self:_NewRadioCall( self.MarshalCall.RECOVERYPAUSEDRESUMED, "AIRBOSS", text, self.Tmessage, "99" ) -- 99, aircraft recovery is paused and will resume at... - self:RadioTransmission(self.MarshalRadio, call) + self:RadioTransmission( self.MarshalRadio, call ) -- XY.. (hours) - self:_Number2Radio(self.MarshalRadio, CT[1]) + self:_Number2Radio( self.MarshalRadio, CT[1] ) -- XY (minutes).. - self:_Number2Radio(self.MarshalRadio, CT[2]) + self:_Number2Radio( self.MarshalRadio, CT[2] ) -- hours. Click! - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.HOURS, nil, nil, nil, true) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.HOURS, nil, nil, nil, true ) end - --- Inform flight that he is cleared for recovery. -- @param #AIRBOSS self -- @param #string modex Tail number. -- @param #number case Recovery case. -function AIRBOSS:_MarshalCallClearedForRecovery(modex, case) +function AIRBOSS:_MarshalCallClearedForRecovery( modex, case ) -- Subtitle. - local text=string.format("you're cleared for Case %d recovery.", case) + local text = string.format( "you're cleared for Case %d recovery.", case ) -- Debug message. - self:T(self.lid..text) + self:I( self.lid .. text ) -- Create new call with full subtitle. - local call=self:_NewRadioCall(self.MarshalCall.CLEAREDFORRECOVERY, "MARSHAL", text, self.Tmessage, modex) + local call = self:_NewRadioCall( self.MarshalCall.CLEAREDFORRECOVERY, "MARSHAL", text, self.Tmessage, modex ) -- Two second delay. - local delay=2 + local delay = 2 -- XYZ, you're cleared for case.. - self:RadioTransmission(self.MarshalRadio, call, nil, delay) + self:RadioTransmission( self.MarshalRadio, call, nil, delay ) -- X.. - self:_Number2Radio(self.MarshalRadio, tostring(case), delay) + self:_Number2Radio( self.MarshalRadio, tostring( case ), delay ) -- recovery. Click! - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.RECOVERY, nil, delay, nil, true) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.RECOVERY, nil, delay, nil, true ) end @@ -16066,56 +15370,56 @@ end function AIRBOSS:_MarshalCallResumeRecovery() -- Create new call with full subtitle. - local call=self:_NewRadioCall(self.MarshalCall.RESUMERECOVERY, "AIRBOSS", nil, self.Tmessage, "99") + local call = self:_NewRadioCall( self.MarshalCall.RESUMERECOVERY, "AIRBOSS", nil, self.Tmessage, "99" ) -- 99, aircraft recovery resumed. Click! - self:RadioTransmission(self.MarshalRadio, call, nil, nil, nil, true) + self:RadioTransmission( self.MarshalRadio, call, nil, nil, nil, true ) end --- Inform everyone about new final bearing. -- @param #AIRBOSS self -- @param #number FB Final Bearing in degrees. -function AIRBOSS:_MarshalCallNewFinalBearing(FB) +function AIRBOSS:_MarshalCallNewFinalBearing( FB ) -- Subtitle. - local text=string.format("new final bearing %03d°.", FB) + local text = string.format( "new final bearing %03d°.", FB ) -- Debug message. - self:T(self.lid..text) + self:I( self.lid .. text ) -- Create new call with full subtitle. - local call=self:_NewRadioCall(self.MarshalCall.NEWFB, "AIRBOSS", text, self.Tmessage, "99") + local call = self:_NewRadioCall( self.MarshalCall.NEWFB, "AIRBOSS", text, self.Tmessage, "99" ) -- 99, new final bearing.. - self:RadioTransmission(self.MarshalRadio, call) + self:RadioTransmission( self.MarshalRadio, call ) -- XYZ.. - self:_Number2Radio(self.MarshalRadio, string.format("%03d", FB), nil, 0.2) + self:_Number2Radio( self.MarshalRadio, string.format( "%03d", FB ), nil, 0.2 ) -- Degrees. Click! - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.DEGREES, nil, nil, nil, true) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.DEGREES, nil, nil, nil, true ) end --- Compile a radio call when Marshal tells a flight the holding alitude. -- @param #AIRBOSS self -- @param #number hdg Heading in degrees. -function AIRBOSS:_MarshalCallCarrierTurnTo(hdg) +function AIRBOSS:_MarshalCallCarrierTurnTo( hdg ) -- Subtitle. - local text=string.format("carrier is now starting turn to heading %03d°.", hdg) + local text = string.format( "carrier is now starting turn to heading %03d°.", hdg ) -- Debug message. - self:T(self.lid..text) + self:I( self.lid .. text ) -- Create new call with full subtitle. - local call=self:_NewRadioCall(self.MarshalCall.CARRIERTURNTOHEADING, "AIRBOSS", text, self.Tmessage, "99") + local call = self:_NewRadioCall( self.MarshalCall.CARRIERTURNTOHEADING, "AIRBOSS", text, self.Tmessage, "99" ) -- 99, turning to heading... - self:RadioTransmission(self.MarshalRadio, call) + self:RadioTransmission( self.MarshalRadio, call ) -- XYZ.. - self:_Number2Radio(self.MarshalRadio, string.format("%03d", hdg), nil, 0.2) + self:_Number2Radio( self.MarshalRadio, string.format( "%03d", hdg ), nil, 0.2 ) -- Degrees. Click! - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.DEGREES, nil, nil, nil, true) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.DEGREES, nil, nil, nil, true ) end @@ -16123,64 +15427,64 @@ end -- @param #AIRBOSS self -- @param #string modex Tail number. -- @param #number nwaiting Number of flights already waiting. -function AIRBOSS:_MarshalCallStackFull(modex, nwaiting) +function AIRBOSS:_MarshalCallStackFull( modex, nwaiting ) -- Subtitle. - local text=string.format("Marshal stack is currently full. Hold outside 10 NM zone and wait for further instructions. ") - if nwaiting==1 then - text=text..string.format("There is one flight ahead of you.") - elseif nwaiting>1 then - text=text..string.format("There are %d flights ahead of you.", nwaiting) + local text = string.format( "Marshal stack is currently full. Hold outside 10 NM zone and wait for further instructions. " ) + if nwaiting == 1 then + text = text .. string.format( "There is one flight ahead of you." ) + elseif nwaiting > 1 then + text = text .. string.format( "There are %d flights ahead of you.", nwaiting ) else - text=text..string.format("You are next in line.") + text = text .. string.format( "You are next in line." ) end -- Debug message. - self:T(self.lid..text) + self:I( self.lid .. text ) -- Create new call with full subtitle. - local call=self:_NewRadioCall(self.MarshalCall.STACKFULL, "AIRBOSS", text, self.Tmessage, modex) + local call = self:_NewRadioCall( self.MarshalCall.STACKFULL, "AIRBOSS", text, self.Tmessage, modex ) -- XYZ, Marshal stack is currently full. - self:RadioTransmission(self.MarshalRadio, call, nil, nil, nil, true) + self:RadioTransmission( self.MarshalRadio, call, nil, nil, nil, true ) end --- Compile a radio call when Marshal tells a flight the holding alitude. -- @param #AIRBOSS self -function AIRBOSS:_MarshalCallRecoveryStart(case) +function AIRBOSS:_MarshalCallRecoveryStart( case ) -- Marshal radial. - local radial=self:GetRadial(case, true, true, false) + local radial = self:GetRadial( case, true, true, false ) -- Debug output. - local text=string.format("Starting aircraft recovery Case %d ops.", case) - if case==1 then - text=text..string.format(" BRC %03d°.", self:GetBRC()) - elseif case==2 then - text=text..string.format(" Marshal radial %03d°. BRC %03d°.", radial, self:GetBRC()) - elseif case==3 then - text=text..string.format(" Marshal radial %03d°. Final heading %03d°.", radial, self:GetFinalBearing(false)) + local text = string.format( "Starting aircraft recovery Case %d ops.", case ) + if case == 1 then + text = text .. string.format( " BRC %03d°.", self:GetBRC() ) + elseif case == 2 then + text = text .. string.format( " Marshal radial %03d°. BRC %03d°.", radial, self:GetBRC() ) + elseif case == 3 then + text = text .. string.format( " Marshal radial %03d°. Final heading %03d°.", radial, self:GetFinalBearing( false ) ) end - self:T(self.lid..text) + self:T( self.lid .. text ) -- New call including the subtitle. - local call=self:_NewRadioCall(self.MarshalCall.STARTINGRECOVERY, "AIRBOSS", text, self.Tmessage, "99") + local call = self:_NewRadioCall( self.MarshalCall.STARTINGRECOVERY, "AIRBOSS", text, self.Tmessage, "99" ) -- 99, Starting aircraft recovery case.. - self:RadioTransmission(self.MarshalRadio, call) + self:RadioTransmission( self.MarshalRadio, call ) -- X.. - self:_Number2Radio(self.MarshalRadio,tostring(case), nil, 0.1) + self:_Number2Radio( self.MarshalRadio, tostring( case ), nil, 0.1 ) -- ops. - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.OPS) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.OPS ) - --Marshal Radial - if case>1 then + -- Marshal Radial + if case > 1 then -- Marshal radial.. - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.MARSHALRADIAL) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.MARSHALRADIAL ) -- XYZ.. - self:_Number2Radio(self.MarshalRadio, string.format("%03d", radial), nil, 0.2) + self:_Number2Radio( self.MarshalRadio, string.format( "%03d", radial ), nil, 0.2 ) -- Degrees. - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.DEGREES, nil, nil, nil, true) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.DEGREES, nil, nil, nil, true ) end end @@ -16193,68 +15497,66 @@ end -- @param #number altitude Holding alitude. -- @param #string charlie Charlie Time estimate. -- @param #number qfe Alitmeter inHg. -function AIRBOSS:_MarshalCallArrived(modex, case, brc, altitude, charlie, qfe) - self:F({modex=modex,case=case,brc=brc,altitude=altitude,charlie=charlie,qfe=qfe}) +function AIRBOSS:_MarshalCallArrived( modex, case, brc, altitude, charlie, qfe ) + self:F( { modex = modex, case = case, brc = brc, altitude = altitude, charlie = charlie, qfe = qfe } ) -- Split strings etc. - local angels=self:_GetAngels(altitude) - --local QFE=UTILS.Split(tostring(UTILS.Round(qfe,2)), ".") - local QFE=UTILS.Split(string.format("%.2f", qfe), ".") - local clock=UTILS.Split(charlie, "+") - local CT=UTILS.Split(clock[1], ":") + local angels = self:_GetAngels( altitude ) + -- local QFE=UTILS.Split(tostring(UTILS.Round(qfe,2)), ".") + local QFE = UTILS.Split( string.format( "%.2f", qfe ), "." ) + local clock = UTILS.Split( charlie, "+" ) + local CT = UTILS.Split( clock[1], ":" ) -- Subtitle text. - local text=string.format("Case %d, expected BRC %03d°, hold at angels %d. Expected Charlie Time %s. Altimeter %.2f. Report see me.", case, brc, angels, charlie, qfe) + local text = string.format( "Case %d, expected BRC %03d°, hold at angels %d. Expected Charlie Time %s. Altimeter %.2f. Report see me.", case, brc, angels, charlie, qfe ) -- Debug message. - self:T(self.lid..text) + self:I( self.lid .. text ) -- Create new call to display complete subtitle. - local casecall=self:_NewRadioCall(self.MarshalCall.CASE, "MARSHAL", text, self.Tmessage, modex) + local casecall = self:_NewRadioCall( self.MarshalCall.CASE, "MARSHAL", text, self.Tmessage, modex ) -- Case.. - self:RadioTransmission(self.MarshalRadio, casecall) + self:RadioTransmission( self.MarshalRadio, casecall ) -- X. - self:_Number2Radio(self.MarshalRadio, tostring(case)) + self:_Number2Radio( self.MarshalRadio, tostring( case ) ) -- Expected.. - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.EXPECTED, nil, nil, 0.5) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.EXPECTED, nil, nil, 0.5 ) -- BRC.. - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.BRC) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.BRC ) -- XYZ... - self:_Number2Radio(self.MarshalRadio, string.format("%03d", brc)) + self:_Number2Radio( self.MarshalRadio, string.format( "%03d", brc ) ) -- Degrees. - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.DEGREES) - + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.DEGREES ) -- Hold at.. - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.HOLDATANGELS, nil, nil, 0.5) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.HOLDATANGELS, nil, nil, 0.5 ) -- X. - self:_Number2Radio(self.MarshalRadio, tostring(angels)) + self:_Number2Radio( self.MarshalRadio, tostring( angels ) ) -- Expected.. - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.EXPECTED, nil, nil, 0.5) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.EXPECTED, nil, nil, 0.5 ) -- Charlie time.. - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.CHARLIETIME) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.CHARLIETIME ) -- XY.. (hours) - self:_Number2Radio(self.MarshalRadio, CT[1]) + self:_Number2Radio( self.MarshalRadio, CT[1] ) -- XY (minutes). - self:_Number2Radio(self.MarshalRadio, CT[2]) + self:_Number2Radio( self.MarshalRadio, CT[2] ) -- hours. - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.HOURS) - + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.HOURS ) -- Altimeter.. - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.ALTIMETER, nil, nil, 0.5) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.ALTIMETER, nil, nil, 0.5 ) -- XY.. - self:_Number2Radio(self.MarshalRadio, QFE[1]) + self:_Number2Radio( self.MarshalRadio, QFE[1] ) -- Point.. - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.POINT) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.POINT ) -- XY. - self:_Number2Radio(self.MarshalRadio, QFE[2]) + self:_Number2Radio( self.MarshalRadio, QFE[2] ) -- Report see me. Click! - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.REPORTSEEME, nil, nil, 0.5, true) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.REPORTSEEME, nil, nil, 0.5, true ) end @@ -16265,28 +15567,28 @@ end --- Add menu commands for player. -- @param #AIRBOSS self -- @param #string _unitName Name of player unit. -function AIRBOSS:_AddF10Commands(_unitName) - self:F(_unitName) +function AIRBOSS:_AddF10Commands( _unitName ) + self:F( _unitName ) -- Get player unit and name. - local _unit, playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, playername = self:_GetPlayerUnitAndName( _unitName ) -- Check for player unit. if _unit and playername then -- Get group and ID. - local group=_unit:GetGroup() - local gid=group:GetID() + local group = _unit:GetGroup() + local gid = group:GetID() if group and gid then if not self.menuadded[gid] then -- Enable switch so we don't do this twice. - self.menuadded[gid]=true + self.menuadded[gid] = true -- Set menu root path. - local _rootPath=nil + local _rootPath = nil if AIRBOSS.MenuF10Root then ------------------------ -- MISSON LEVEL MENUE -- @@ -16294,10 +15596,10 @@ function AIRBOSS:_AddF10Commands(_unitName) if self.menusingle then -- F10/Airboss/... - _rootPath=AIRBOSS.MenuF10Root + _rootPath = AIRBOSS.MenuF10Root else -- F10/Airboss//... - _rootPath=missionCommands.addSubMenuForGroup(gid, self.alias, AIRBOSS.MenuF10Root) + _rootPath = missionCommands.addSubMenuForGroup( gid, self.alias, AIRBOSS.MenuF10Root ) end else @@ -16306,116 +15608,114 @@ function AIRBOSS:_AddF10Commands(_unitName) ------------------------ -- Main F10 menu: F10/Airboss/ - if AIRBOSS.MenuF10[gid]==nil then - AIRBOSS.MenuF10[gid]=missionCommands.addSubMenuForGroup(gid, "Airboss") + if AIRBOSS.MenuF10[gid] == nil then + AIRBOSS.MenuF10[gid] = missionCommands.addSubMenuForGroup( gid, "Airboss" ) end - if self.menusingle then -- F10/Airboss/... - _rootPath=AIRBOSS.MenuF10[gid] + _rootPath = AIRBOSS.MenuF10[gid] else -- F10/Airboss//... - _rootPath=missionCommands.addSubMenuForGroup(gid, self.alias, AIRBOSS.MenuF10[gid]) + _rootPath = missionCommands.addSubMenuForGroup( gid, self.alias, AIRBOSS.MenuF10[gid] ) end end - -------------------------------- -- F10/Airboss//F1 Help -------------------------------- - local _helpPath=missionCommands.addSubMenuForGroup(gid, "Help", _rootPath) + local _helpPath = missionCommands.addSubMenuForGroup( gid, "Help", _rootPath ) -- F10/Airboss//F1 Help/F1 Mark Zones if self.menumarkzones then - local _markPath=missionCommands.addSubMenuForGroup(gid, "Mark Zones", _helpPath) + local _markPath = missionCommands.addSubMenuForGroup( gid, "Mark Zones", _helpPath ) -- F10/Airboss//F1 Help/F1 Mark Zones/ if self.menusmokezones then - missionCommands.addCommandForGroup(gid, "Smoke Pattern Zones", _markPath, self._MarkCaseZones, self, _unitName, false) -- F1 + missionCommands.addCommandForGroup( gid, "Smoke Pattern Zones", _markPath, self._MarkCaseZones, self, _unitName, false ) -- F1 end - missionCommands.addCommandForGroup(gid, "Flare Pattern Zones", _markPath, self._MarkCaseZones, self, _unitName, true) -- F2 + missionCommands.addCommandForGroup( gid, "Flare Pattern Zones", _markPath, self._MarkCaseZones, self, _unitName, true ) -- F2 if self.menusmokezones then - missionCommands.addCommandForGroup(gid, "Smoke Marshal Zone", _markPath, self._MarkMarshalZone, self, _unitName, false) -- F3 + missionCommands.addCommandForGroup( gid, "Smoke Marshal Zone", _markPath, self._MarkMarshalZone, self, _unitName, false ) -- F3 end - missionCommands.addCommandForGroup(gid, "Flare Marshal Zone", _markPath, self._MarkMarshalZone, self, _unitName, true) -- F4 + missionCommands.addCommandForGroup( gid, "Flare Marshal Zone", _markPath, self._MarkMarshalZone, self, _unitName, true ) -- F4 end -- F10/Airboss//F1 Help/F2 Skill Level - local _skillPath=missionCommands.addSubMenuForGroup(gid, "Skill Level", _helpPath) + local _skillPath = missionCommands.addSubMenuForGroup( gid, "Skill Level", _helpPath ) -- F10/Airboss//F1 Help/F2 Skill Level/ - missionCommands.addCommandForGroup(gid, "Flight Student", _skillPath, self._SetDifficulty, self, _unitName, AIRBOSS.Difficulty.EASY) -- F1 - missionCommands.addCommandForGroup(gid, "Naval Aviator", _skillPath, self._SetDifficulty, self, _unitName, AIRBOSS.Difficulty.NORMAL) -- F2 - missionCommands.addCommandForGroup(gid, "TOPGUN Graduate", _skillPath, self._SetDifficulty, self, _unitName, AIRBOSS.Difficulty.HARD) -- F3 - missionCommands.addCommandForGroup(gid, "Hints On/Off", _skillPath, self._SetHintsOnOff, self, _unitName) -- F4 + missionCommands.addCommandForGroup( gid, "Flight Student", _skillPath, self._SetDifficulty, self, _unitName, AIRBOSS.Difficulty.EASY ) -- F1 + missionCommands.addCommandForGroup( gid, "Naval Aviator", _skillPath, self._SetDifficulty, self, _unitName, AIRBOSS.Difficulty.NORMAL ) -- F2 + missionCommands.addCommandForGroup( gid, "TOPGUN Graduate", _skillPath, self._SetDifficulty, self, _unitName, AIRBOSS.Difficulty.HARD ) -- F3 + missionCommands.addCommandForGroup( gid, "Hints On/Off", _skillPath, self._SetHintsOnOff, self, _unitName ) -- F4 -- F10/Airboss//F1 Help/ - missionCommands.addCommandForGroup(gid, "My Status", _helpPath, self._DisplayPlayerStatus, self, _unitName) -- F3 - missionCommands.addCommandForGroup(gid, "Attitude Monitor", _helpPath, self._DisplayAttitude, self, _unitName) -- F4 - missionCommands.addCommandForGroup(gid, "Radio Check LSO", _helpPath, self._LSORadioCheck, self, _unitName) -- F5 - missionCommands.addCommandForGroup(gid, "Radio Check Marshal", _helpPath, self._MarshalRadioCheck, self, _unitName) -- F6 - missionCommands.addCommandForGroup(gid, "Subtitles On/Off", _helpPath, self._SubtitlesOnOff, self, _unitName) -- F7 - missionCommands.addCommandForGroup(gid, "Trapsheet On/Off", _helpPath, self._TrapsheetOnOff, self, _unitName) -- F8 + missionCommands.addCommandForGroup( gid, "My Status", _helpPath, self._DisplayPlayerStatus, self, _unitName ) -- F3 + missionCommands.addCommandForGroup( gid, "Attitude Monitor", _helpPath, self._DisplayAttitude, self, _unitName ) -- F4 + missionCommands.addCommandForGroup( gid, "Radio Check LSO", _helpPath, self._LSORadioCheck, self, _unitName ) -- F5 + missionCommands.addCommandForGroup( gid, "Radio Check Marshal", _helpPath, self._MarshalRadioCheck, self, _unitName ) -- F6 + missionCommands.addCommandForGroup( gid, "Subtitles On/Off", _helpPath, self._SubtitlesOnOff, self, _unitName ) -- F7 + missionCommands.addCommandForGroup( gid, "Trapsheet On/Off", _helpPath, self._TrapsheetOnOff, self, _unitName ) -- F8 ------------------------------------- -- F10/Airboss//F2 Kneeboard ------------------------------------- - local _kneeboardPath=missionCommands.addSubMenuForGroup(gid, "Kneeboard", _rootPath) + local _kneeboardPath = missionCommands.addSubMenuForGroup( gid, "Kneeboard", _rootPath ) -- F10/Airboss//F2 Kneeboard/F1 Results - local _resultsPath=missionCommands.addSubMenuForGroup(gid, "Results", _kneeboardPath) + local _resultsPath = missionCommands.addSubMenuForGroup( gid, "Results", _kneeboardPath ) -- F10/Airboss//F2 Kneeboard/F1 Results/ - missionCommands.addCommandForGroup(gid, "Greenie Board", _resultsPath, self._DisplayScoreBoard, self, _unitName) -- F1 - missionCommands.addCommandForGroup(gid, "My LSO Grades", _resultsPath, self._DisplayPlayerGrades, self, _unitName) -- F2 - missionCommands.addCommandForGroup(gid, "Last Debrief", _resultsPath, self._DisplayDebriefing, self, _unitName) -- F3 + missionCommands.addCommandForGroup( gid, "Greenie Board", _resultsPath, self._DisplayScoreBoard, self, _unitName ) -- F1 + missionCommands.addCommandForGroup( gid, "My LSO Grades", _resultsPath, self._DisplayPlayerGrades, self, _unitName ) -- F2 + missionCommands.addCommandForGroup( gid, "Last Debrief", _resultsPath, self._DisplayDebriefing, self, _unitName ) -- F3 -- F10/Airboss//F2 Kneeboard/F2 Skipper/ if self.skipperMenu then - local _skipperPath =missionCommands.addSubMenuForGroup(gid, "Skipper", _kneeboardPath) - local _menusetspeed=missionCommands.addSubMenuForGroup(gid, "Set Speed", _skipperPath) - missionCommands.addCommandForGroup(gid, "10 knots", _menusetspeed, self._SkipperRecoverySpeed, self, _unitName, 10) - missionCommands.addCommandForGroup(gid, "15 knots", _menusetspeed, self._SkipperRecoverySpeed, self, _unitName, 15) - missionCommands.addCommandForGroup(gid, "20 knots", _menusetspeed, self._SkipperRecoverySpeed, self, _unitName, 20) - missionCommands.addCommandForGroup(gid, "25 knots", _menusetspeed, self._SkipperRecoverySpeed, self, _unitName, 25) - missionCommands.addCommandForGroup(gid, "30 knots", _menusetspeed, self._SkipperRecoverySpeed, self, _unitName, 30) - local _menusetrtime=missionCommands.addSubMenuForGroup(gid, "Set Time", _skipperPath) - missionCommands.addCommandForGroup(gid, "15 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 15) - missionCommands.addCommandForGroup(gid, "30 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 30) - missionCommands.addCommandForGroup(gid, "45 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 45) - missionCommands.addCommandForGroup(gid, "60 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 60) - missionCommands.addCommandForGroup(gid, "90 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 90) - local _menusetrtime=missionCommands.addSubMenuForGroup(gid, "Set Marshal Radial", _skipperPath) - missionCommands.addCommandForGroup(gid, "+30°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 30) - missionCommands.addCommandForGroup(gid, "+15°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 15) - missionCommands.addCommandForGroup(gid, "0°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 0) - missionCommands.addCommandForGroup(gid, "-15°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, -15) - missionCommands.addCommandForGroup(gid, "-30°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, -30) - missionCommands.addCommandForGroup(gid, "U-turn On/Off", _skipperPath, self._SkipperRecoveryUturn, self, _unitName) - missionCommands.addCommandForGroup(gid, "Start CASE I", _skipperPath, self._SkipperStartRecovery, self, _unitName, 1) - missionCommands.addCommandForGroup(gid, "Start CASE II", _skipperPath, self._SkipperStartRecovery, self, _unitName, 2) - missionCommands.addCommandForGroup(gid, "Start CASE III",_skipperPath, self._SkipperStartRecovery, self, _unitName, 3) - missionCommands.addCommandForGroup(gid, "Stop Recovery", _skipperPath, self._SkipperStopRecovery, self, _unitName) + local _skipperPath = missionCommands.addSubMenuForGroup( gid, "Skipper", _kneeboardPath ) + local _menusetspeed = missionCommands.addSubMenuForGroup( gid, "Set Speed", _skipperPath ) + missionCommands.addCommandForGroup( gid, "10 knots", _menusetspeed, self._SkipperRecoverySpeed, self, _unitName, 10 ) + missionCommands.addCommandForGroup( gid, "15 knots", _menusetspeed, self._SkipperRecoverySpeed, self, _unitName, 15 ) + missionCommands.addCommandForGroup( gid, "20 knots", _menusetspeed, self._SkipperRecoverySpeed, self, _unitName, 20 ) + missionCommands.addCommandForGroup( gid, "25 knots", _menusetspeed, self._SkipperRecoverySpeed, self, _unitName, 25 ) + missionCommands.addCommandForGroup( gid, "30 knots", _menusetspeed, self._SkipperRecoverySpeed, self, _unitName, 30 ) + local _menusetrtime = missionCommands.addSubMenuForGroup( gid, "Set Time", _skipperPath ) + missionCommands.addCommandForGroup( gid, "15 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 15 ) + missionCommands.addCommandForGroup( gid, "30 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 30 ) + missionCommands.addCommandForGroup( gid, "45 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 45 ) + missionCommands.addCommandForGroup( gid, "60 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 60 ) + missionCommands.addCommandForGroup( gid, "90 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 90 ) + local _menusetrtime = missionCommands.addSubMenuForGroup( gid, "Set Marshal Radial", _skipperPath ) + missionCommands.addCommandForGroup( gid, "+30°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 30 ) + missionCommands.addCommandForGroup( gid, "+15°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 15 ) + missionCommands.addCommandForGroup( gid, "0°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 0 ) + missionCommands.addCommandForGroup( gid, "-15°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, -15 ) + missionCommands.addCommandForGroup( gid, "-30°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, -30 ) + missionCommands.addCommandForGroup( gid, "U-turn On/Off", _skipperPath, self._SkipperRecoveryUturn, self, _unitName ) + missionCommands.addCommandForGroup( gid, "Start CASE I", _skipperPath, self._SkipperStartRecovery, self, _unitName, 1 ) + missionCommands.addCommandForGroup( gid, "Start CASE II", _skipperPath, self._SkipperStartRecovery, self, _unitName, 2 ) + missionCommands.addCommandForGroup( gid, "Start CASE III", _skipperPath, self._SkipperStartRecovery, self, _unitName, 3 ) + missionCommands.addCommandForGroup( gid, "Stop Recovery", _skipperPath, self._SkipperStopRecovery, self, _unitName ) end -- F10/Airboss// ------------------------- - missionCommands.addCommandForGroup(gid, "Request Marshal", _rootPath, self._RequestMarshal, self, _unitName) -- F3 - missionCommands.addCommandForGroup(gid, "Request Commence", _rootPath, self._RequestCommence, self, _unitName) -- F4 - missionCommands.addCommandForGroup(gid, "Request Refueling", _rootPath, self._RequestRefueling, self, _unitName) -- F5 - missionCommands.addCommandForGroup(gid, "Spinning", _rootPath, self._RequestSpinning, self, _unitName) -- F6 - missionCommands.addCommandForGroup(gid, "Emergency Landing", _rootPath, self._RequestEmergency, self, _unitName) -- F7 - missionCommands.addCommandForGroup(gid, "[Reset My Status]", _rootPath, self._ResetPlayerStatus, self, _unitName) -- F8 + missionCommands.addCommandForGroup( gid, "Request Marshal", _rootPath, self._RequestMarshal, self, _unitName ) -- F3 + missionCommands.addCommandForGroup( gid, "Request Commence", _rootPath, self._RequestCommence, self, _unitName ) -- F4 + missionCommands.addCommandForGroup( gid, "Request Refueling", _rootPath, self._RequestRefueling, self, _unitName ) -- F5 + missionCommands.addCommandForGroup( gid, "Spinning", _rootPath, self._RequestSpinning, self, _unitName ) -- F6 + missionCommands.addCommandForGroup( gid, "Emergency Landing", _rootPath, self._RequestEmergency, self, _unitName ) -- F7 + missionCommands.addCommandForGroup( gid, "[Reset My Status]", _rootPath, self._ResetPlayerStatus, self, _unitName ) -- F8 end else - self:E(self.lid..string.format("ERROR: Could not find group or group ID in AddF10Menu() function. Unit name: %s.", _unitName)) + self:E( self.lid .. string.format( "ERROR: Could not find group or group ID in AddF10Menu() function. Unit name: %s.", _unitName ) ) end else - self:E(self.lid..string.format("ERROR: Player unit does not exist in AddF10Menu() function. Unit name: %s.", _unitName)) + self:E( self.lid .. string.format( "ERROR: Player unit does not exist in AddF10Menu() function. Unit name: %s.", _unitName ) ) end end @@ -16428,37 +15728,37 @@ end -- @param #AIRBOSS self -- @param #string _unitName Name fo the player unit. -- @param #number case Recovery case. -function AIRBOSS:_SkipperStartRecovery(_unitName, case) +function AIRBOSS:_SkipperStartRecovery( _unitName, case ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then -- Inform player. - local text=string.format("affirm, Case %d recovery will start in 5 min for %d min. Wind on deck %d knots. U-turn=%s.", case, self.skipperTime, self.skipperSpeed, tostring(self.skipperUturn)) - if case>1 then - text=text..string.format(" Marshal radial %d°.", self.skipperOffset) - end + local text = string.format( "affirm, Case %d recovery will start in 5 min for %d min. Wind on deck %d knots. U-turn=%s.", case, self.skipperTime, self.skipperSpeed, tostring( self.skipperUturn ) ) + if case > 1 then + text = text .. string.format( " Marshal radial %d°.", self.skipperOffset ) + end if self:IsRecovering() then - text="negative, carrier is already recovering." - self:MessageToPlayer(playerData, text, "AIRBOSS") + text = "negative, carrier is already recovering." + self:MessageToPlayer( playerData, text, "AIRBOSS" ) return end - self:MessageToPlayer(playerData, text, "AIRBOSS") + self:MessageToPlayer( playerData, text, "AIRBOSS" ) -- Recovery staring in 5 min for 30 min. - local t0=timer.getAbsTime()+5*60 - local t9=t0+self.skipperTime*60 - local C0=UTILS.SecondsToClock(t0) - local C9=UTILS.SecondsToClock(t9) + local t0 = timer.getAbsTime() + 5 * 60 + local t9 = t0 + self.skipperTime * 60 + local C0 = UTILS.SecondsToClock( t0 ) + local C9 = UTILS.SecondsToClock( t9 ) -- Carrier will turn into the wind. Wind on deck 25 knots. U-turn on. - self:AddRecoveryWindow(C0, C9, case, self.skipperOffset, true, self.skipperSpeed, self.skipperUturn) + self:AddRecoveryWindow( C0, C9, case, self.skipperOffset, true, self.skipperSpeed, self.skipperUturn ) end end @@ -16467,25 +15767,25 @@ end --- Skipper Stop recovery function. -- @param #AIRBOSS self -- @param #string _unitName Name fo the player unit. -function AIRBOSS:_SkipperStopRecovery(_unitName) +function AIRBOSS:_SkipperStopRecovery( _unitName ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then -- Inform player. - local text="roger, stopping recovery right away." + local text = "roger, stopping recovery right away." if not self:IsRecovering() then - text="negative, carrier is currently not recovering." - self:MessageToPlayer(playerData, text, "AIRBOSS") + text = "negative, carrier is currently not recovering." + self:MessageToPlayer( playerData, text, "AIRBOSS" ) return end - self:MessageToPlayer(playerData, text, "AIRBOSS") + self:MessageToPlayer( playerData, text, "AIRBOSS" ) self:RecoveryStop() end @@ -16496,22 +15796,22 @@ end -- @param #AIRBOSS self -- @param #string _unitName Name fo the player unit. -- @param #number offset Recovery holding offset angle in degrees for Case II/III. -function AIRBOSS:_SkipperRecoveryOffset(_unitName, offset) +function AIRBOSS:_SkipperRecoveryOffset( _unitName, offset ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then -- Inform player. - local text=string.format("roger, relative CASE II/III Marshal radial set to %d°.", offset) - self:MessageToPlayer(playerData, text, "AIRBOSS") + local text = string.format( "roger, relative CASE II/III Marshal radial set to %d°.", offset ) + self:MessageToPlayer( playerData, text, "AIRBOSS" ) - self.skipperOffset=offset + self.skipperOffset = offset end end end @@ -16520,22 +15820,22 @@ end -- @param #AIRBOSS self -- @param #string _unitName Name fo the player unit. -- @param #number time Recovery time in minutes. -function AIRBOSS:_SkipperRecoveryTime(_unitName, time) +function AIRBOSS:_SkipperRecoveryTime( _unitName, time ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then -- Inform player. - local text=string.format("roger, manual recovery time set to %d min.", time) - self:MessageToPlayer(playerData, text, "AIRBOSS") + local text = string.format( "roger, manual recovery time set to %d min.", time ) + self:MessageToPlayer( playerData, text, "AIRBOSS" ) - self.skipperTime=time + self.skipperTime = time end end @@ -16545,22 +15845,22 @@ end -- @param #AIRBOSS self -- @param #string _unitName Name fo the player unit. -- @param #number speed Recovery speed in knots. -function AIRBOSS:_SkipperRecoverySpeed(_unitName, speed) +function AIRBOSS:_SkipperRecoverySpeed( _unitName, speed ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then -- Inform player. - local text=string.format("roger, wind on deck set to %d knots.", speed) - self:MessageToPlayer(playerData, text, "AIRBOSS") + local text = string.format( "roger, wind on deck set to %d knots.", speed ) + self:MessageToPlayer( playerData, text, "AIRBOSS" ) - self.skipperSpeed=speed + self.skipperSpeed = speed end end end @@ -16568,28 +15868,27 @@ end --- Skipper set recovery speed. -- @param #AIRBOSS self -- @param #string _unitName Name fo the player unit. -function AIRBOSS:_SkipperRecoveryUturn(_unitName) +function AIRBOSS:_SkipperRecoveryUturn( _unitName ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then - self.skipperUturn=not self.skipperUturn + self.skipperUturn = not self.skipperUturn -- Inform player. - local text=string.format("roger, U-turn is now %s.", tostring(self.skipperUturn)) - self:MessageToPlayer(playerData, text, "AIRBOSS") + local text = string.format( "roger, U-turn is now %s.", tostring( self.skipperUturn ) ) + self:MessageToPlayer( playerData, text, "AIRBOSS" ) end end end - ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- ROOT MENU ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -16597,33 +15896,33 @@ end --- Reset player status. Player is removed from all queues and its status is set to undefined. -- @param #AIRBOSS self -- @param #string _unitName Name fo the player unit. -function AIRBOSS:_ResetPlayerStatus(_unitName) - self:F(_unitName) +function AIRBOSS:_ResetPlayerStatus( _unitName ) + self:F( _unitName ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then -- Inform player. - local text="roger, status reset executed! You have been removed from all queues." - self:MessageToPlayer(playerData, text, "AIRBOSS") + local text = "roger, status reset executed! You have been removed from all queues." + self:MessageToPlayer( playerData, text, "AIRBOSS" ) -- Remove flight from queues. Collapse marshal stack if necessary. -- Section members are removed from the Spinning queue. If flight is member, he is removed from the section. - self:_RemoveFlight(playerData) + self:_RemoveFlight( playerData ) -- Stop pending debrief scheduler. if playerData.debriefschedulerID and self.Scheduler then - self.Scheduler:Stop(playerData.debriefschedulerID) + self.Scheduler:Stop( playerData.debriefschedulerID ) end -- Initialize player data. - self:_InitPlayer(playerData) + self:_InitPlayer( playerData ) end end @@ -16632,15 +15931,15 @@ end --- Request marshal. -- @param #AIRBOSS self -- @param #string _unitName Name fo the player unit. -function AIRBOSS:_RequestMarshal(_unitName) - self:F(_unitName) +function AIRBOSS:_RequestMarshal( _unitName ) + self:F( _unitName ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) - + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) + -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then @@ -16650,55 +15949,55 @@ function AIRBOSS:_RequestMarshal(_unitName) end -- Check if player is in CCA - local inCCA=playerData.unit:IsInZone(self.zoneCCA) + local inCCA = playerData.unit:IsInZone( self.zoneCCA ) if inCCA then - if self:_InQueue(self.Qmarshal, playerData.group) then + if self:_InQueue( self.Qmarshal, playerData.group ) then -- Flight group is already in marhal queue. - local text=string.format("negative, you are already in the Marshal queue. New marshal request denied!") - self:MessageToPlayer(playerData, text, "MARSHAL") + local text = string.format( "negative, you are already in the Marshal queue. New marshal request denied!" ) + self:MessageToPlayer( playerData, text, "MARSHAL" ) - elseif self:_InQueue(self.Qpattern, playerData.group) then + elseif self:_InQueue( self.Qpattern, playerData.group ) then -- Flight group is already in pattern queue. - local text=string.format("negative, you are already in the Pattern queue. Marshal request denied!") - self:MessageToPlayer(playerData, text, "MARSHAL") + local text = string.format( "negative, you are already in the Pattern queue. Marshal request denied!" ) + self:MessageToPlayer( playerData, text, "MARSHAL" ) - elseif self:_InQueue(self.Qwaiting, playerData.group) then + elseif self:_InQueue( self.Qwaiting, playerData.group ) then -- Flight group is already in pattern queue. - local text=string.format("negative, you are in the Waiting queue with %d flights ahead of you. Marshal request denied!", #self.Qwaiting) - self:MessageToPlayer(playerData, text, "MARSHAL") + local text = string.format( "negative, you are in the Waiting queue with %d flights ahead of you. Marshal request denied!", #self.Qwaiting ) + self:MessageToPlayer( playerData, text, "MARSHAL" ) elseif not _unit:InAir() then -- Flight group is already in pattern queue. - local text=string.format("negative, you are not airborne. Marshal request denied!") - self:MessageToPlayer(playerData, text, "MARSHAL") + local text = string.format( "negative, you are not airborne. Marshal request denied!" ) + self:MessageToPlayer( playerData, text, "MARSHAL" ) - elseif playerData.name~=playerData.seclead then + elseif playerData.name ~= playerData.seclead then -- Flight group is already in pattern queue. - local text=string.format("negative, your section lead %s needs to request Marshal.", playerData.seclead) - self:MessageToPlayer(playerData, text, "MARSHAL") + local text = string.format( "negative, your section lead %s needs to request Marshal.", playerData.seclead ) + self:MessageToPlayer( playerData, text, "MARSHAL" ) else -- Get next free Marshal stack. - local freestack=self:_GetFreeStack(playerData.ai) + local freestack = self:_GetFreeStack( playerData.ai ) -- Check if stack is available. For Case I the number is limited. if freestack then -- Add flight to marshal stack. - self:_MarshalPlayer(playerData, freestack) + self:_MarshalPlayer( playerData, freestack ) else -- Add flight to waiting queue. - self:_WaitPlayer(playerData) + self:_WaitPlayer( playerData ) end @@ -16707,8 +16006,8 @@ function AIRBOSS:_RequestMarshal(_unitName) else -- Flight group is not in CCA yet. - local text=string.format("negative, you are not inside CCA. Marshal request denied!") - self:MessageToPlayer(playerData, text, "MARSHAL") + local text = string.format( "negative, you are not inside CCA. Marshal request denied!" ) + self:MessageToPlayer( playerData, text, "MARSHAL" ) end end @@ -16718,102 +16017,102 @@ end --- Request emergency landing. -- @param #AIRBOSS self -- @param #string _unitName Name fo the player unit. -function AIRBOSS:_RequestEmergency(_unitName) - self:F(_unitName) +function AIRBOSS:_RequestEmergency( _unitName ) + self:F( _unitName ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then - local text="" + local text = "" if not self.emergency then -- Mission designer did not allow emergency landing. - text="negative, no emergency landings on my carrier. We are currently busy. See how you get along!" + text = "negative, no emergency landings on my carrier. We are currently busy. See how you get along!" elseif not _unit:InAir() then -- Carrier zone. - local zone=self:_GetZoneCarrierBox() + local zone = self:_GetZoneCarrierBox() -- Check if player is on the carrier. - if playerData.unit:IsInZone(zone) then + if playerData.unit:IsInZone( zone ) then -- Bolter pattern. - text="roger, you are now technically in the bolter pattern. Your next step after takeoff is abeam!" + text = "roger, you are now technically in the bolter pattern. Your next step after takeoff is abeam!" -- Get flight lead. - local lead=self:_GetFlightLead(playerData) + local lead = self:_GetFlightLead( playerData ) -- Set set for lead. - self:_SetPlayerStep(lead, AIRBOSS.PatternStep.BOLTER) + self:_SetPlayerStep( lead, AIRBOSS.PatternStep.BOLTER ) -- Also set bolter pattern for all members. - for _,sec in pairs(lead.section) do - local sectionmember=sec --#AIRBOSS.PlayerData - self:_SetPlayerStep(sectionmember, AIRBOSS.PatternStep.BOLTER) + for _, sec in pairs( lead.section ) do + local sectionmember = sec -- #AIRBOSS.PlayerData + self:_SetPlayerStep( sectionmember, AIRBOSS.PatternStep.BOLTER ) end -- Remove flight from waiting queue just in case. - self:_RemoveFlightFromQueue(self.Qwaiting, lead) + self:_RemoveFlightFromQueue( self.Qwaiting, lead ) - if self:_InQueue(self.Qmarshal, lead.group) then + if self:_InQueue( self.Qmarshal, lead.group ) then -- Remove flight from Marshal queue and add to pattern. - self:_RemoveFlightFromMarshalQueue(lead) + self:_RemoveFlightFromMarshalQueue( lead ) else -- Add flight to pattern if he was not. - if not self:_InQueue(self.Qpattern, lead.group) then - self:_AddFlightToPatternQueue(lead) + if not self:_InQueue( self.Qpattern, lead.group ) then + self:_AddFlightToPatternQueue( lead ) end end else -- Flight group is not in air. - text=string.format("negative, you are not airborne. Request denied!") + text = string.format( "negative, you are not airborne. Request denied!" ) end else -- Cleared. - text="affirmative, you can bypass the pattern and are cleared for final approach!" + text = "affirmative, you can bypass the pattern and are cleared for final approach!" -- Now, if player is in the marshal or waiting queue he will be removed. But the new leader should stay in or not. - local lead=self:_GetFlightLead(playerData) + local lead = self:_GetFlightLead( playerData ) -- Set set for lead. - self:_SetPlayerStep(lead, AIRBOSS.PatternStep.EMERGENCY) + self:_SetPlayerStep( lead, AIRBOSS.PatternStep.EMERGENCY ) -- Also set emergency landing for all members. - for _,sec in pairs(lead.section) do - local sectionmember=sec --#AIRBOSS.PlayerData - self:_SetPlayerStep(sectionmember, AIRBOSS.PatternStep.EMERGENCY) + for _, sec in pairs( lead.section ) do + local sectionmember = sec -- #AIRBOSS.PlayerData + self:_SetPlayerStep( sectionmember, AIRBOSS.PatternStep.EMERGENCY ) -- Remove flight from spinning queue just in case (everone can spin on his own). - self:_RemoveFlightFromQueue(self.Qspinning, sectionmember) + self:_RemoveFlightFromQueue( self.Qspinning, sectionmember ) end -- Remove flight from waiting queue just in case. - self:_RemoveFlightFromQueue(self.Qwaiting, lead) + self:_RemoveFlightFromQueue( self.Qwaiting, lead ) - if self:_InQueue(self.Qmarshal, lead.group) then + if self:_InQueue( self.Qmarshal, lead.group ) then -- Remove flight from Marshal queue and add to pattern. - self:_RemoveFlightFromMarshalQueue(lead) + self:_RemoveFlightFromMarshalQueue( lead ) else -- Add flight to pattern if he was not. - if not self:_InQueue(self.Qpattern, lead.group) then - self:_AddFlightToPatternQueue(lead) + if not self:_InQueue( self.Qpattern, lead.group ) then + self:_AddFlightToPatternQueue( lead ) end end end -- Send message. - self:MessageToPlayer(playerData, text, "AIRBOSS") + self:MessageToPlayer( playerData, text, "AIRBOSS" ) end @@ -16823,60 +16122,60 @@ end --- Request spinning. -- @param #AIRBOSS self -- @param #string _unitName Name fo the player unit. -function AIRBOSS:_RequestSpinning(_unitName) - self:F(_unitName) +function AIRBOSS:_RequestSpinning( _unitName ) + self:F( _unitName ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then - local text="" - if not self:_InQueue(self.Qpattern, playerData.group) then + local text = "" + if not self:_InQueue( self.Qpattern, playerData.group ) then -- Player not in pattern queue. - text="negative, you have to be in the pattern to spin it!" + text = "negative, you have to be in the pattern to spin it!" - elseif playerData.step==AIRBOSS.PatternStep.SPINNING then + elseif playerData.step == AIRBOSS.PatternStep.SPINNING then -- Player is already spinning. - text="negative, you are already spinning." + text = "negative, you are already spinning." - -- Check if player is in the right step. - elseif not (playerData.step==AIRBOSS.PatternStep.BREAKENTRY or - playerData.step==AIRBOSS.PatternStep.EARLYBREAK or - playerData.step==AIRBOSS.PatternStep.LATEBREAK) then + -- Check if player is in the right step. + elseif not (playerData.step == AIRBOSS.PatternStep.BREAKENTRY or + playerData.step == AIRBOSS.PatternStep.EARLYBREAK or + playerData.step == AIRBOSS.PatternStep.LATEBREAK) then -- Player is not in the right step. - text="negative, you have to be in the right step to spin it!" + text = "negative, you have to be in the right step to spin it!" else -- Set player step. - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.SPINNING) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.SPINNING ) -- Add player to spinning queue. - table.insert(self.Qspinning, playerData) + table.insert( self.Qspinning, playerData ) -- 405, Spin it! Click. - local call=self:_NewRadioCall(self.LSOCall.SPINIT, "AIRBOSS", "Spin it!", self.Tmessage, playerData.onboard) - self:RadioTransmission(self.LSORadio, call, nil, nil, nil, true) + local call = self:_NewRadioCall( self.LSOCall.SPINIT, "AIRBOSS", "Spin it!", self.Tmessage, playerData.onboard ) + self:RadioTransmission( self.LSORadio, call, nil, nil, nil, true ) -- Some advice. - if playerData.difficulty==AIRBOSS.Difficulty.EASY then - local text="Climb to 1200 feet and proceed to the initial again." - self:MessageToPlayer(playerData, text, "INSTRUCTOR", "") + if playerData.difficulty == AIRBOSS.Difficulty.EASY then + local text = "Climb to 1200 feet and proceed to the initial again." + self:MessageToPlayer( playerData, text, "INSTRUCTOR", "" ) end return end -- Send message. - self:MessageToPlayer(playerData, text, "AIRBOSS") + self:MessageToPlayer( playerData, text, "AIRBOSS" ) end end @@ -16885,15 +16184,15 @@ end --- Request to commence landing approach. -- @param #AIRBOSS self -- @param #string _unitName Name fo the player unit. -function AIRBOSS:_RequestCommence(_unitName) - self:F(_unitName) +function AIRBOSS:_RequestCommence( _unitName ) + self:F( _unitName ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) - + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) + -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then @@ -16903,56 +16202,56 @@ function AIRBOSS:_RequestCommence(_unitName) end -- Check if unit is in CCA. - local text="" - local cleared=false - if _unit:IsInZone(self.zoneCCA) then + local text = "" + local cleared = false + if _unit:IsInZone( self.zoneCCA ) then -- Get stack value. - local stack=playerData.flag + local stack = playerData.flag -- Number of airborne aircraft currently in pattern. - local _,npattern=self:_GetQueueInfo(self.Qpattern) + local _, npattern = self:_GetQueueInfo( self.Qpattern ) -- TODO: Check distance to initial or platform. Only allow commence if < max distance. Otherwise say bearing. - if self:_InQueue(self.Qpattern, playerData.group) then + if self:_InQueue( self.Qpattern, playerData.group ) then -- Flight group is already in pattern queue. - text=string.format("negative, %s, you are already in the Pattern queue.", playerData.name) + text = string.format( "negative, %s, you are already in the Pattern queue.", playerData.name ) elseif not _unit:InAir() then -- Flight group is already in pattern queue. - text=string.format("negative, %s, you are not airborne.", playerData.name) + text = string.format( "negative, %s, you are not airborne.", playerData.name ) - elseif playerData.seclead~=playerData.name then + elseif playerData.seclead ~= playerData.name then -- Flight group is already in pattern queue. - text=string.format("negative, %s, your section leader %s has to request commence!", playerData.name, playerData.seclead) + text = string.format( "negative, %s, your section leader %s has to request commence!", playerData.name, playerData.seclead ) - elseif stack>1 then + elseif stack > 1 then -- We are in a higher stack. - text=string.format("negative, %s, it's not your turn yet! You are in stack no. %s.", playerData.name, stack) + text = string.format( "negative, %s, it's not your turn yet! You are in stack no. %s.", playerData.name, stack ) - elseif npattern>=self.Nmaxpattern then + elseif npattern >= self.Nmaxpattern then -- Patern is full! - text=string.format("negative ghostrider, pattern is full!\nThere are %d aircraft currently in the pattern.", npattern) + text = string.format( "negative ghostrider, pattern is full!\nThere are %d aircraft currently in the pattern.", npattern ) - elseif self:IsRecovering()==false and not self.airbossnice then + elseif self:IsRecovering() == false and not self.airbossnice then -- Carrier is not recovering right now. if self.recoverywindow then - local clock=UTILS.SecondsToClock(self.recoverywindow.START) - text=string.format("negative, carrier is currently not recovery. Next window will open at %s.", clock) + local clock = UTILS.SecondsToClock( self.recoverywindow.START ) + text = string.format( "negative, carrier is currently not recovery. Next window will open at %s.", clock ) else - text=string.format("negative, carrier is not recovering. No future windows planned.") + text = string.format( "negative, carrier is not recovering. No future windows planned." ) end - elseif not self:_InQueue(self.Qmarshal, playerData.group) and not self.airbossnice then + elseif not self:_InQueue( self.Qmarshal, playerData.group ) and not self.airbossnice then - text="negative, you have to request Marshal before you can commence." + text = "negative, you have to request Marshal before you can commence." else @@ -16960,60 +16259,60 @@ function AIRBOSS:_RequestCommence(_unitName) -- Positive Response -- ----------------------- - text=text.."roger." + text = text .. "roger." -- Carrier is not recovering but Airboss has a good day. if not self:IsRecovering() then - text=text.." Carrier is not recovering currently! However, you are cleared anyway as I have a nice day." + text = text .. " Carrier is not recovering currently! However, you are cleared anyway as I have a nice day." end -- If player is not in the Marshal queue set player case to current case. - if not self:_InQueue(self.Qmarshal, playerData.group) then + if not self:_InQueue( self.Qmarshal, playerData.group ) then -- Set current case. - playerData.case=self.case + playerData.case = self.case -- Hint about TACAN bearing. - if self.TACANon and playerData.difficulty~=AIRBOSS.Difficulty.HARD then + if self.TACANon and playerData.difficulty ~= AIRBOSS.Difficulty.HARD then -- Get inverse magnetic radial potential offset. - local radial=self:GetRadial(playerData.case, true, true, true) - if playerData.case==1 then + local radial = self:GetRadial( playerData.case, true, true, true ) + if playerData.case == 1 then -- For case 1 we want the BRC but above routine return FB. - radial=self:GetBRC() + radial = self:GetBRC() end - text=text..string.format("\nSelect TACAN %03d°, Channel %d%s (%s).\n", radial, self.TACANchannel,self.TACANmode, self.TACANmorse) + text = text .. string.format( "\nSelect TACAN %03d°, Channel %d%s (%s).\n", radial, self.TACANchannel, self.TACANmode, self.TACANmorse ) end -- TODO: Inform section members. -- Set case of section members as well. Not sure if necessary any more since it is set as soon as the recovery case is changed. - for _,flight in pairs(playerData.section) do - flight.case=playerData.case + for _, flight in pairs( playerData.section ) do + flight.case = playerData.case end -- Add player to pattern queue. Usually this is done when the stack is collapsed but this player is not in the Marshal queue. - self:_AddFlightToPatternQueue(playerData) + self:_AddFlightToPatternQueue( playerData ) end -- Clear player for commence. - cleared=true + cleared = true end else -- This flight is not yet registered! - text=string.format("negative, %s, you are not inside the CCA!", playerData.name) + text = string.format( "negative, %s, you are not inside the CCA!", playerData.name ) end -- Debug - self:T(self.lid..text) + self:T( self.lid .. text ) -- Send message. - self:MessageToPlayer(playerData, text, "MARSHAL") + self:MessageToPlayer( playerData, text, "MARSHAL" ) -- Check if player was cleard. Need to do this after the message above is displayed. if cleared then -- Call commence routine. No zone check. NOTE: Commencing will set step for all section members as well. - self:_Commencing(playerData, false) + self:_Commencing( playerData, false ) end end end @@ -17022,14 +16321,14 @@ end --- Player requests refueling. -- @param #AIRBOSS self -- @param #string _unitName Name of the player unit. -function AIRBOSS:_RequestRefueling(_unitName) +function AIRBOSS:_RequestRefueling( _unitName ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then @@ -17038,72 +16337,71 @@ function AIRBOSS:_RequestRefueling(_unitName) if self.tanker then -- Check if player is in CCA. - if _unit:IsInZone(self.zoneCCA) then + if _unit:IsInZone( self.zoneCCA ) then -- Check if tanker is running or refueling or returning. if self.tanker:IsRunning() or self.tanker:IsRefueling() then -- Get alt of tanker in angels. - --local angels=UTILS.Round(UTILS.MetersToFeet(self.tanker.altitude)/1000, 0) - local angels=self:_GetAngels(self.tanker.altitude) + -- local angels=UTILS.Round(UTILS.MetersToFeet(self.tanker.altitude)/1000, 0) + local angels = self:_GetAngels( self.tanker.altitude ) -- Tanker is up and running. - text=string.format("affirmative, proceed to tanker at angels %d.", angels) + text = string.format( "affirmative, proceed to tanker at angels %d.", angels ) -- State TACAN channel of tanker if defined. if self.tanker.TACANon then - text=text..string.format("\nTanker TACAN channel %d%s (%s).", self.tanker.TACANchannel, self.tanker.TACANmode, self.tanker.TACANmorse) - text=text..string.format("\nRadio frequency %.3f MHz AM.", self.tanker.RadioFreq) + text = text .. string.format( "\nTanker TACAN channel %d%s (%s).", self.tanker.TACANchannel, self.tanker.TACANmode, self.tanker.TACANmorse ) + text = text .. string.format( "\nRadio frequency %.3f MHz AM.", self.tanker.RadioFreq ) end -- Tanker is currently refueling. Inform player. if self.tanker:IsRefueling() then - text=text.."\nTanker is currently refueling. You might have to queue up." + text = text .. "\nTanker is currently refueling. You might have to queue up." end -- Collapse marshal stack if player is in queue. - self:_RemoveFlightFromMarshalQueue(playerData, true) + self:_RemoveFlightFromMarshalQueue( playerData, true ) -- Set step to refueling. - self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.REFUELING) + self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.REFUELING ) -- Inform section and set step. - for _,sec in pairs(playerData.section) do - local sectext="follow your section leader to the tanker." - self:MessageToPlayer(sec, sectext, "MARSHAL") - self:_SetPlayerStep(sec, AIRBOSS.PatternStep.REFUELING) + for _, sec in pairs( playerData.section ) do + local sectext = "follow your section leader to the tanker." + self:MessageToPlayer( sec, sectext, "MARSHAL" ) + self:_SetPlayerStep( sec, AIRBOSS.PatternStep.REFUELING ) end elseif self.tanker:IsReturning() then -- Tanker is RTB. - text="negative, tanker is RTB. Request denied!\nWait for the tanker to be back on station if you can." + text = "negative, tanker is RTB. Request denied!\nWait for the tanker to be back on station if you can." end else - text="negative, you are not inside the CCA yet." + text = "negative, you are not inside the CCA yet." end else - text="negative, no refueling tanker available." + text = "negative, no refueling tanker available." end -- Send message. - self:MessageToPlayer(playerData, text, "MARSHAL") + self:MessageToPlayer( playerData, text, "MARSHAL" ) end end end - --- Remove a member from the player's section. -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player -- @param #AIRBOSS.PlayerData sectionmember The section member to be removed. -- @return #boolean If true, flight was a section member and could be removed. False otherwise. -function AIRBOSS:_RemoveSectionMember(playerData, sectionmember) +function AIRBOSS:_RemoveSectionMember( playerData, sectionmember ) -- Loop over all flights in player's section - for i,_flight in pairs(playerData.section) do - local flight=_flight --#AIRBOSS.PlayerData - if flight.name==sectionmember.name then - table.remove(playerData.section, i) + for i, _flight in pairs( playerData.section ) do + local flight = _flight -- #AIRBOSS.PlayerData + if flight.name == sectionmember.name then + table.remove( playerData.section, i ) return true end end @@ -17113,148 +16411,150 @@ end --- Set all flights within 100 meters to be part of my section. -- @param #AIRBOSS self -- @param #string _unitName Name of the player unit. -function AIRBOSS:_SetSection(_unitName) +function AIRBOSS:_SetSection( _unitName ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then -- Coordinate of flight lead. - local mycoord=_unit:GetCoordinate() + local mycoord = _unit:GetCoordinate() -- Max distance up to which section members are allowed. - local dmax=100 + local dmax = 100 -- Check if player is in Marshal or pattern queue already. local text - if self.NmaxSection==0 then - text=string.format("negative, setting sections is disabled in this mission. You stay alone.") - elseif self:_InQueue(self.Qmarshal,playerData.group) then - text=string.format("negative, you are already in the Marshal queue. Setting section not possible any more!") - elseif self:_InQueue(self.Qpattern, playerData.group) then - text=string.format("negative, you are already in the Pattern queue. Setting section not possible any more!") + if self.NmaxSection == 0 then + text = string.format( "negative, setting sections is disabled in this mission. You stay alone." ) + elseif self:_InQueue( self.Qmarshal, playerData.group ) then + text = string.format( "negative, you are already in the Marshal queue. Setting section not possible any more!" ) + elseif self:_InQueue( self.Qpattern, playerData.group ) then + text = string.format( "negative, you are already in the Pattern queue. Setting section not possible any more!" ) else -- Check if player is member of another section already. If so, remove him from his current section. - if playerData.seclead~=playerData.name then - local lead=self.players[playerData.seclead] --#AIRBOSS.PlayerData + if playerData.seclead ~= playerData.name then + local lead = self.players[playerData.seclead] -- #AIRBOSS.PlayerData if lead then -- Remove player from his old section lead. - local removed=self:_RemoveSectionMember(lead, playerData) + local removed = self:_RemoveSectionMember( lead, playerData ) if removed then - self:MessageToPlayer(lead, string.format("Flight %s has been removed from your section.", playerData.name), "AIRBOSS", "", 5) - self:MessageToPlayer(playerData, string.format("You have been removed from %s's section.", lead.name), "AIRBOSS", "", 5) + self:MessageToPlayer( lead, string.format( "Flight %s has been removed from your section.", playerData.name ), "AIRBOSS", "", 5 ) + self:MessageToPlayer( playerData, string.format( "You have been removed from %s's section.", lead.name ), "AIRBOSS", "", 5 ) end end end -- Potential section members. - local section={} + local section = {} -- Loop over all registered flights. - for _,_flight in pairs(self.flights) do - local flight=_flight --#AIRBOSS.FlightGroup + for _, _flight in pairs( self.flights ) do + local flight = _flight -- #AIRBOSS.FlightGroup -- Only human flight groups excluding myself. Also only flights that dont have a section itself (would get messy) or are part of another section (no double membership). - if flight.ai==false and flight.groupname~=playerData.groupname and #flight.section==0 and flight.seclead==flight.name then + if flight.ai == false and flight.groupname ~= playerData.groupname and #flight.section == 0 and flight.seclead == flight.name then -- Distance (3D) to other flight group. - local distance=flight.group:GetCoordinate():Get3DDistance(mycoord) + local distance = flight.group:GetCoordinate():Get3DDistance( mycoord ) -- Check distance. - if distance remove it. if not gotit then - self:MessageToPlayer(flight, string.format("you were removed from %s's section and are on your own now.", playerData.name), "AIRBOSS", "", 5) - flight.seclead=flight.name - self:_RemoveSectionMember(playerData, flight) + self:MessageToPlayer( flight, string.format( "you were removed from %s's section and are on your own now.", playerData.name ), "AIRBOSS", "", 5 ) + flight.seclead = flight.name + self:_RemoveSectionMember( playerData, flight ) end end -- Remove all flights that are currently in the player's section already from scanned potential new section members. - for i,_new in pairs(section) do - local newflight=_new.flight --#AIRBOSS.PlayerData - for _,_flight in pairs(playerData.section) do - local currentflight=_flight --#AIRBOSS.PlayerData - if newflight.name==currentflight.name then - table.remove(section, i) + for i, _new in pairs( section ) do + local newflight = _new.flight -- #AIRBOSS.PlayerData + for _, _flight in pairs( playerData.section ) do + local currentflight = _flight -- #AIRBOSS.PlayerData + if newflight.name == currentflight.name then + table.remove( section, i ) end end end -- Init section table. Should not be necessary as all members are removed anyhow above. - --playerData.section={} + -- playerData.section={} -- Output text. - text=string.format("Registered flight section:") - text=text..string.format("\n- %s (lead)", playerData.seclead) + text = string.format( "Registered flight section:" ) + text = text .. string.format( "\n- %s (lead)", playerData.seclead ) -- Old members that stay (if any). - for _,_flight in pairs(playerData.section) do - local flight=_flight --#AIRBOSS.PlayerData - text=text..string.format("\n- %s", flight.name) + for _, _flight in pairs( playerData.section ) do + local flight = _flight -- #AIRBOSS.PlayerData + text = text .. string.format( "\n- %s", flight.name ) end -- New members (if any). - for i=1,math.min(self.NmaxSection-#playerData.section, #section) do - local flight=section[i].flight --#AIRBOSS.PlayerData + for i = 1, math.min( self.NmaxSection - #playerData.section, #section ) do + local flight = section[i].flight -- #AIRBOSS.PlayerData -- New flight members. - text=text..string.format("\n- %s", flight.name) + text = text .. string.format( "\n- %s", flight.name ) -- Set section lead of player flight. - flight.seclead=playerData.name + flight.seclead = playerData.name -- Set case of f - flight.case=playerData.case + flight.case = playerData.case -- Inform player that he is now part of a section. - self:MessageToPlayer(flight, string.format("your section lead is now %s.", playerData.name), "AIRBOSS") + self:MessageToPlayer( flight, string.format( "your section lead is now %s.", playerData.name ), "AIRBOSS" ) -- Add flight to section table. - table.insert(playerData.section, flight) + table.insert( playerData.section, flight ) end -- Section is empty. - if #playerData.section==0 then - text=text..string.format("\n- No other human flights found within radius of %.1f meters!", dmax) + if #playerData.section == 0 then + text = text .. string.format( "\n- No other human flights found within radius of %.1f meters!", dmax ) end end -- Message to section lead. - self:MessageToPlayer(playerData, text, "MARSHAL") + self:MessageToPlayer( playerData, text, "MARSHAL" ) end end end @@ -17266,33 +16566,33 @@ end --- Display top 10 player scores. -- @param #AIRBOSS self -- @param #string _unitName Name fo the player unit. -function AIRBOSS:_DisplayScoreBoard(_unitName) - self:F(_unitName) +function AIRBOSS:_DisplayScoreBoard( _unitName ) + self:F( _unitName ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then -- Results table. - local _playerResults={} + local _playerResults = {} -- Calculate average points for all players. - for playerName,playerGrades in pairs(self.playerscores) do + for playerName, playerGrades in pairs( self.playerscores ) do if playerGrades then -- Loop over all grades - local Paverage=0 - local n=0 - for _,_grade in pairs(playerGrades) do - local grade=_grade --#AIRBOSS.LSOgrade + local Paverage = 0 + local n = 0 + for _, _grade in pairs( playerGrades ) do + local grade = _grade -- #AIRBOSS.LSOgrade -- Add up only final scores for the average. - if grade.finalscore then --grade.points>=0 then - Paverage=Paverage+grade.finalscore - n=n+1 + if grade.finalscore then -- grade.points>=0 then + Paverage = Paverage + grade.finalscore + n = n + 1 else -- Case when the player just leaves after an unfinished pass, e.g bolter, without landing. -- But this should now be solved by deleteing all unfinished results. @@ -17300,50 +16600,52 @@ function AIRBOSS:_DisplayScoreBoard(_unitName) end -- We dont want to devide by zero. - if n>0 then - _playerResults[playerName]=Paverage/n + if n > 0 then + _playerResults[playerName] = Paverage / n end end end -- Message text. - local text = string.format("Greenie Board (top ten):") - local i=1 - for _playerName,_points in UTILS.spairs(_playerResults, function(t, a, b) return t[b] < t[a] end) do + local text = string.format( "Greenie Board (top ten):" ) + local i = 1 + for _playerName, _points in UTILS.spairs( _playerResults, function( t, a, b ) + return t[b] < t[a] + end ) do -- Text. - text=text..string.format("\n[%d] %s %.1f||", i,_playerName, _points) + text = text .. string.format( "\n[%d] %s %.1f||", i, _playerName, _points ) -- All player grades. - local playerGrades=self.playerscores[_playerName] + local playerGrades = self.playerscores[_playerName] -- Add grades of passes. We use the actual grade of each pass here and not the average after player has landed. - for _,_grade in pairs(playerGrades) do - local grade=_grade --#AIRBOSS.LSOgrade + for _, _grade in pairs( playerGrades ) do + local grade = _grade -- #AIRBOSS.LSOgrade if grade.finalscore then - text=text..string.format("%.1f|", grade.points) - elseif grade.points>=0 then -- Only points >=0 as foul deck gives -1. - text=text..string.format("(%.1f)", grade.points) + text = text .. string.format( "%.1f|", grade.points ) + elseif grade.points >= 0 then -- Only points >=0 as foul deck gives -1. + text = text .. string.format( "(%.1f)", grade.points ) end end -- Display only the top ten. - i=i+1 - if i>10 then + i = i + 1 + if i > 10 then break end end -- If no results yet. - if i==1 then - text=text.."\nNo results yet." + if i == 1 then + text = text .. "\nNo results yet." end -- Send message. - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData.client then - MESSAGE:New(text, 30, nil, true):ToClient(playerData.client) + MESSAGE:New( text, 30, nil, true ):ToClient( playerData.client ) end end @@ -17352,74 +16654,73 @@ end --- Display top 10 player scores. -- @param #AIRBOSS self -- @param #string _unitName Name fo the player unit. -function AIRBOSS:_DisplayPlayerGrades(_unitName) - self:F(_unitName) +function AIRBOSS:_DisplayPlayerGrades( _unitName ) + self:F( _unitName ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then -- Grades of player: - local text=string.format("Your last 10 grades, %s:", _playername) + local text = string.format( "Your last 10 grades, %s:", _playername ) -- All player grades. - local playerGrades=self.playerscores[_playername] or {} + local playerGrades = self.playerscores[_playername] or {} - local p=0 -- Average points. - local n=0 -- Number of final passes. - local m=0 -- Number of total passes. - --for i,_grade in pairs(playerGrades) do - for i=#playerGrades,1,-1 do - --local grade=_grade --#AIRBOSS.LSOgrade - local grade=playerGrades[i] --#AIRBOSS.LSOgrade + local p = 0 -- Average points. + local n = 0 -- Number of final passes. + local m = 0 -- Number of total passes. + -- for i,_grade in pairs(playerGrades) do + for i = #playerGrades, 1, -1 do + -- local grade=_grade --#AIRBOSS.LSOgrade + local grade = playerGrades[i] -- #AIRBOSS.LSOgrade -- Check if points >=0. For foul deck WO we give -1 and pass is not counted. - if grade.points>=0 then + if grade.points >= 0 then -- Show final points or points of pass. - local points=grade.finalscore or grade.points + local points = grade.finalscore or grade.points -- Display max 10 results. - if m<10 then - text=text..string.format("\n[%d] %s %.1f PT - %s", i, grade.grade, points, grade.details) + if m < 10 then + text = text .. string.format( "\n[%d] %s %.1f PT - %s", i, grade.grade, points, grade.details ) -- Wire trapped if any. - if grade.wire and grade.wire<=4 then - text=text..string.format(" %d-wire", grade.wire) + if grade.wire and grade.wire <= 4 then + text = text .. string.format( " %d-wire", grade.wire ) end -- Time in the groove if any. - if grade.Tgroove and grade.Tgroove<=360 then - text=text..string.format(" Tgroove=%.1f s", grade.Tgroove) + if grade.Tgroove and grade.Tgroove <= 360 then + text = text .. string.format( " Tgroove=%.1f s", grade.Tgroove ) end end -- Add up final points. if grade.finalscore then - p=p+grade.finalscore - n=n+1 + p = p + grade.finalscore + n = n + 1 end -- Total passes - m=m+1 + m = m + 1 end end - - if n>0 then - text=text..string.format("\nAverage points = %.1f", p/n) + if n > 0 then + text = text .. string.format( "\nAverage points = %.1f", p / n ) else - text=text..string.format("\nNo data available.") + text = text .. string.format( "\nNo data available." ) end -- Send message. if playerData.client then - MESSAGE:New(text, 30, nil, true):ToClient(playerData.client) + MESSAGE:New( text, 30, nil, true ):ToClient( playerData.client ) end end end @@ -17428,36 +16729,36 @@ end --- Display last debriefing. -- @param #AIRBOSS self -- @param #string _unitName Name fo the player unit. -function AIRBOSS:_DisplayDebriefing(_unitName) - self:F(_unitName) +function AIRBOSS:_DisplayDebriefing( _unitName ) + self:F( _unitName ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then -- Debriefing text. - local text=string.format("Debriefing:") + local text = string.format( "Debriefing:" ) -- Check if data is present. - if #playerData.lastdebrief>0 then - text=text..string.format("\n================================\n") - for _,_data in pairs(playerData.lastdebrief) do - local step=_data.step - local comment=_data.hint - text=text..string.format("* %s:",step) - text=text..string.format("%s\n", comment) + if #playerData.lastdebrief > 0 then + text = text .. string.format( "\n================================\n" ) + for _, _data in pairs( playerData.lastdebrief ) do + local step = _data.step + local comment = _data.hint + text = text .. string.format( "* %s:", step ) + text = text .. string.format( "%s\n", comment ) end else - text=text.." Nothing to show yet." + text = text .. " Nothing to show yet." end -- Send debrief message to player - self:MessageToPlayer(playerData, text, nil , "", 30, true) + self:MessageToPlayer( playerData, text, nil, "", 30, true ) end end @@ -17471,134 +16772,133 @@ end -- @param #AIRBOSS self -- @param #string _unitname Name of the player unit. -- @param #string qname Name of the queue. -function AIRBOSS:_DisplayQueue(_unitname, qname) +function AIRBOSS:_DisplayQueue( _unitname, qname ) -- Get player unit and player name. - local unit, playername = self:_GetPlayerUnitAndName(_unitname) + local unit, playername = self:_GetPlayerUnitAndName( _unitname ) -- Check if we have a player. if unit and playername then -- Player data. - local playerData=self.players[playername] --#AIRBOSS.PlayerData + local playerData = self.players[playername] -- #AIRBOSS.PlayerData if playerData then -- Queue to display. - local queue=nil - if qname=="Marshal" then - queue=self.Qmarshal - elseif qname=="Pattern" then - queue=self.Qpattern - elseif qname=="Waiting" then - queue=self.Qwaiting + local queue = nil + if qname == "Marshal" then + queue = self.Qmarshal + elseif qname == "Pattern" then + queue = self.Qpattern + elseif qname == "Waiting" then + queue = self.Qwaiting end -- Number of group and units in queue - local Nqueue,nqueue=self:_GetQueueInfo(queue, playerData.case) + local Nqueue, nqueue = self:_GetQueueInfo( queue, playerData.case ) - local text=string.format("%s Queue:", qname) - if #queue==0 then - text=text.." empty" + local text = string.format( "%s Queue:", qname ) + if #queue == 0 then + text = text .. " empty" else - local N=0 - if qname=="Marshal" then - for i,_flight in pairs(queue) do - local flight=_flight --#AIRBOSS.FlightGroup - local charlie=self:_GetCharlieTime(flight) - local Charlie=UTILS.SecondsToClock(charlie) - local stack=flight.flag - local angels=self:_GetAngels(self:_GetMarshalAltitude(stack, flight.case)) - local _,nunit,nsec=self:_GetFlightUnits(flight, true) - local nick=self:_GetACNickname(flight.actype) - N=N+nunit - text=text..string.format("\n[Stack %d] %s (%s*%d+%d): Case %d, Angels %d, Charlie %s", stack, flight.onboard, nick, nunit, nsec, flight.case, angels, tostring(Charlie)) + local N = 0 + if qname == "Marshal" then + for i, _flight in pairs( queue ) do + local flight = _flight -- #AIRBOSS.FlightGroup + local charlie = self:_GetCharlieTime( flight ) + local Charlie = UTILS.SecondsToClock( charlie ) + local stack = flight.flag + local angels = self:_GetAngels( self:_GetMarshalAltitude( stack, flight.case ) ) + local _, nunit, nsec = self:_GetFlightUnits( flight, true ) + local nick = self:_GetACNickname( flight.actype ) + N = N + nunit + text = text .. string.format( "\n[Stack %d] %s (%s*%d+%d): Case %d, Angels %d, Charlie %s", stack, flight.onboard, nick, nunit, nsec, flight.case, angels, tostring( Charlie ) ) end - elseif qname=="Pattern" or qname=="Waiting" then - for i,_flight in pairs(queue) do - local flight=_flight --#AIRBOSS.FlightGroup - local _,nunit,nsec=self:_GetFlightUnits(flight, true) - local nick=self:_GetACNickname(flight.actype) - local ptime=UTILS.SecondsToClock(timer.getAbsTime()-flight.time) - N=N+nunit - text=text..string.format("\n[%d] %s (%s*%d+%d): Case %d, T=%s", i, flight.onboard, nick, nunit, nsec, flight.case, ptime) + elseif qname == "Pattern" or qname == "Waiting" then + for i, _flight in pairs( queue ) do + local flight = _flight -- #AIRBOSS.FlightGroup + local _, nunit, nsec = self:_GetFlightUnits( flight, true ) + local nick = self:_GetACNickname( flight.actype ) + local ptime = UTILS.SecondsToClock( timer.getAbsTime() - flight.time ) + N = N + nunit + text = text .. string.format( "\n[%d] %s (%s*%d+%d): Case %d, T=%s", i, flight.onboard, nick, nunit, nsec, flight.case, ptime ) end end - text=text..string.format("\nTotal AC: %d (airborne %d)", N, nqueue) + text = text .. string.format( "\nTotal AC: %d (airborne %d)", N, nqueue ) end -- Send message. - self:MessageToPlayer(playerData, text, nil, "", nil, true) + self:MessageToPlayer( playerData, text, nil, "", nil, true ) end end end - --- Report information about carrier. -- @param #AIRBOSS self -- @param #string _unitname Name of the player unit. -function AIRBOSS:_DisplayCarrierInfo(_unitname) - self:F2(_unitname) +function AIRBOSS:_DisplayCarrierInfo( _unitname ) + self:F2( _unitname ) -- Get player unit and player name. - local unit, playername = self:_GetPlayerUnitAndName(_unitname) + local unit, playername = self:_GetPlayerUnitAndName( _unitname ) -- Check if we have a player. if unit and playername then -- Player data. - local playerData=self.players[playername] --#AIRBOSS.PlayerData + local playerData = self.players[playername] -- #AIRBOSS.PlayerData if playerData then -- Current coordinates. - local coord=self:GetCoordinate() + local coord = self:GetCoordinate() -- Carrier speed and heading. - local carrierheading=self.carrier:GetHeading() - local carrierspeed=UTILS.MpsToKnots(self.carrier:GetVelocityMPS()) + local carrierheading = self.carrier:GetHeading() + local carrierspeed = UTILS.MpsToKnots( self.carrier:GetVelocityMPS() ) -- TACAN/ICLS. - local tacan="unknown" - local icls="unknown" - if self.TACANon and self.TACANchannel~=nil then - tacan=string.format("%d%s (%s)", self.TACANchannel, self.TACANmode, self.TACANmorse) + local tacan = "unknown" + local icls = "unknown" + if self.TACANon and self.TACANchannel ~= nil then + tacan = string.format( "%d%s (%s)", self.TACANchannel, self.TACANmode, self.TACANmorse ) end - if self.ICLSon and self.ICLSchannel~=nil then - icls=string.format("%d (%s)", self.ICLSchannel, self.ICLSmorse) + if self.ICLSon and self.ICLSchannel ~= nil then + icls = string.format( "%d (%s)", self.ICLSchannel, self.ICLSmorse ) end -- Wind on flight deck - local wind=UTILS.MpsToKnots(select(1, self:GetWindOnDeck())) + local wind = UTILS.MpsToKnots( select( 1, self:GetWindOnDeck() ) ) -- Get groups, units in queues. - local Nmarshal,nmarshal = self:_GetQueueInfo(self.Qmarshal, playerData.case) - local Npattern,npattern = self:_GetQueueInfo(self.Qpattern) - local Nspinning,nspinning = self:_GetQueueInfo(self.Qspinning) - local Nwaiting,nwaiting = self:_GetQueueInfo(self.Qwaiting) - local Ntotal,ntotal = self:_GetQueueInfo(self.flights) + local Nmarshal, nmarshal = self:_GetQueueInfo( self.Qmarshal, playerData.case ) + local Npattern, npattern = self:_GetQueueInfo( self.Qpattern ) + local Nspinning, nspinning = self:_GetQueueInfo( self.Qspinning ) + local Nwaiting, nwaiting = self:_GetQueueInfo( self.Qwaiting ) + local Ntotal, ntotal = self:_GetQueueInfo( self.flights ) -- Current abs time. - local Tabs=timer.getAbsTime() + local Tabs = timer.getAbsTime() -- Get recovery times of carrier. - local recoverytext="Recovery time windows (max 5):" - if #self.recoverytimes==0 then - recoverytext=recoverytext.." none." + local recoverytext = "Recovery time windows (max 5):" + if #self.recoverytimes == 0 then + recoverytext = recoverytext .. " none." else -- Loop over recovery windows. - local rw=0 - for _,_recovery in pairs(self.recoverytimes) do - local recovery=_recovery --#AIRBOSS.Recovery + local rw = 0 + for _, _recovery in pairs( self.recoverytimes ) do + local recovery = _recovery -- #AIRBOSS.Recovery -- Only include current and future recovery windows. - if Tabs=5 then + rw = rw + 1 + if rw >= 5 then -- Break the loop after 5 recovery times. break end @@ -17607,140 +16907,139 @@ function AIRBOSS:_DisplayCarrierInfo(_unitname) end -- Recovery tanker TACAN text. - local tankertext=nil + local tankertext = nil if self.tanker then - tankertext=string.format("Recovery tanker frequency %.3f MHz\n", self.tanker.RadioFreq) + tankertext = string.format( "Recovery tanker frequency %.3f MHz\n", self.tanker.RadioFreq ) if self.tanker.TACANon then - tankertext=tankertext..string.format("Recovery tanker TACAN %d%s (%s)",self.tanker.TACANchannel, self.tanker.TACANmode, self.tanker.TACANmorse) + tankertext = tankertext .. string.format( "Recovery tanker TACAN %d%s (%s)", self.tanker.TACANchannel, self.tanker.TACANmode, self.tanker.TACANmorse ) else - tankertext=tankertext.."Recovery tanker TACAN n/a" + tankertext = tankertext .. "Recovery tanker TACAN n/a" end end -- Carrier FSM state. Idle is not clear enough. - local state=self:GetState() - if state=="Idle" then - state="Deck closed" + local state = self:GetState() + if state == "Idle" then + state = "Deck closed" end if self.turning then - state=state.." (turning currently)" + state = state .. " (turning currently)" end -- Message text. - local text=string.format("%s info:\n", self.alias) - text=text..string.format("================================\n") - text=text..string.format("Carrier state: %s\n", state) - if self.case==1 then - text=text..string.format("Case %d recovery ops\n", self.case) + local text = string.format( "%s info:\n", self.alias ) + text = text .. string.format( "================================\n" ) + text = text .. string.format( "Carrier state: %s\n", state ) + if self.case == 1 then + text = text .. string.format( "Case %d recovery ops\n", self.case ) else - local radial=self:GetRadial(self.case, true, true, false) - text=text..string.format("Case %d recovery ops\nMarshal radial %03d°\n", self.case, radial) + local radial = self:GetRadial( self.case, true, true, false ) + text = text .. string.format( "Case %d recovery ops\nMarshal radial %03d°\n", self.case, radial ) end - text=text..string.format("BRC %03d° - FB %03d°\n", self:GetBRC(), self:GetFinalBearing(true)) - text=text..string.format("Speed %.1f kts - Wind on deck %.1f kts\n", carrierspeed, wind) - text=text..string.format("Tower frequency %.3f MHz\n", self.TowerFreq) - text=text..string.format("Marshal radio %.3f MHz\n", self.MarshalFreq) - text=text..string.format("LSO radio %.3f MHz\n", self.LSOFreq) - text=text..string.format("TACAN Channel %s\n", tacan) - text=text..string.format("ICLS Channel %s\n", icls) + text = text .. string.format( "BRC %03d° - FB %03d°\n", self:GetBRC(), self:GetFinalBearing( true ) ) + text = text .. string.format( "Speed %.1f kts - Wind on deck %.1f kts\n", carrierspeed, wind ) + text = text .. string.format( "Tower frequency %.3f MHz\n", self.TowerFreq ) + text = text .. string.format( "Marshal radio %.3f MHz\n", self.MarshalFreq ) + text = text .. string.format( "LSO radio %.3f MHz\n", self.LSOFreq ) + text = text .. string.format( "TACAN Channel %s\n", tacan ) + text = text .. string.format( "ICLS Channel %s\n", icls ) if tankertext then - text=text..tankertext.."\n" + text = text .. tankertext .. "\n" end - text=text..string.format("# A/C total %d (%d)\n", Ntotal, ntotal) - text=text..string.format("# A/C marshal %d (%d)\n", Nmarshal, nmarshal) - text=text..string.format("# A/C pattern %d (%d) - spinning %d (%d)\n", Npattern, npattern, Nspinning, nspinning) - text=text..string.format("# A/C waiting %d (%d)\n", Nwaiting, nwaiting) - text=text..string.format(recoverytext) - self:T2(self.lid..text) + text = text .. string.format( "# A/C total %d (%d)\n", Ntotal, ntotal ) + text = text .. string.format( "# A/C marshal %d (%d)\n", Nmarshal, nmarshal ) + text = text .. string.format( "# A/C pattern %d (%d) - spinning %d (%d)\n", Npattern, npattern, Nspinning, nspinning ) + text = text .. string.format( "# A/C waiting %d (%d)\n", Nwaiting, nwaiting ) + text = text .. string.format( recoverytext ) + self:T2( self.lid .. text ) -- Send message. - self:MessageToPlayer(playerData, text, nil, "", 30, true) + self:MessageToPlayer( playerData, text, nil, "", 30, true ) else - self:E(self.lid..string.format("ERROR: Could not get player data for player %s.", playername)) + self:E( self.lid .. string.format( "ERROR: Could not get player data for player %s.", playername ) ) end end end - --- Report weather conditions at the carrier location. Temperature, QFE pressure and wind data. -- @param #AIRBOSS self -- @param #string _unitname Name of the player unit. -function AIRBOSS:_DisplayCarrierWeather(_unitname) - self:F2(_unitname) +function AIRBOSS:_DisplayCarrierWeather( _unitname ) + self:F2( _unitname ) -- Get player unit and player name. - local unit, playername = self:_GetPlayerUnitAndName(_unitname) + local unit, playername = self:_GetPlayerUnitAndName( _unitname ) -- Check if we have a player. if unit and playername then -- Message text. - local text="" + local text = "" -- Current coordinates. - local coord=self:GetCoordinate() + local coord = self:GetCoordinate() -- Get atmospheric data at carrier location. - local T=coord:GetTemperature() - local P=coord:GetPressure() + local T = coord:GetTemperature() + local P = coord:GetPressure() -- Get wind direction (magnetic) and strength. - local Wd,Ws=self:GetWind(nil, true) + local Wd, Ws = self:GetWind( nil, true ) -- Get Beaufort wind scale. - local Bn,Bd=UTILS.BeaufortScale(Ws) + local Bn, Bd = UTILS.BeaufortScale( Ws ) -- Wind on flight deck. - local WodPA,WodPP=self:GetWindOnDeck() - local WodPA=UTILS.MpsToKnots(WodPA) - local WodPP=UTILS.MpsToKnots(WodPP) + local WodPA, WodPP = self:GetWindOnDeck() + local WodPA = UTILS.MpsToKnots( WodPA ) + local WodPP = UTILS.MpsToKnots( WodPP ) - local WD=string.format('%03d°', Wd) - local Ts=string.format("%d°C",T) + local WD = string.format( '%03d°', Wd ) + local Ts = string.format( "%d°C", T ) - local tT=string.format("%d°C",T) - local tW=string.format("%.1f knots", UTILS.MpsToKnots(Ws)) - local tP=string.format("%.2f inHg", UTILS.hPa2inHg(P)) + local tT = string.format( "%d°C", T ) + local tW = string.format( "%.1f knots", UTILS.MpsToKnots( Ws ) ) + local tP = string.format( "%.2f inHg", UTILS.hPa2inHg( P ) ) -- Report text. - text=text..string.format("Weather Report at Carrier %s:\n", self.alias) - text=text..string.format("================================\n") - text=text..string.format("Temperature %s\n", tT) - text=text..string.format("Wind from %s at %s (%s)\n", WD, tW, Bd) - text=text..string.format("Wind on deck || %.1f kts, == %.1f kts\n", WodPA, WodPP) - text=text..string.format("QFE %.1f hPa = %s", P, tP) + text = text .. string.format( "Weather Report at Carrier %s:\n", self.alias ) + text = text .. string.format( "================================\n" ) + text = text .. string.format( "Temperature %s\n", tT ) + text = text .. string.format( "Wind from %s at %s (%s)\n", WD, tW, Bd ) + text = text .. string.format( "Wind on deck || %.1f kts, == %.1f kts\n", WodPA, WodPP ) + text = text .. string.format( "QFE %.1f hPa = %s", P, tP ) -- More info only reliable if Mission uses static weather. if self.staticweather then - local clouds, visibility, fog, dust=self:_GetStaticWeather() - text=text..string.format("\nVisibility %.1f NM", UTILS.MetersToNM(visibility)) - text=text..string.format("\nCloud base %d ft", UTILS.MetersToFeet(clouds.base)) - text=text..string.format("\nCloud thickness %d ft", UTILS.MetersToFeet(clouds.thickness)) - text=text..string.format("\nCloud density %d", clouds.density) - text=text..string.format("\nPrecipitation %d", clouds.iprecptns) + local clouds, visibility, fog, dust = self:_GetStaticWeather() + text = text .. string.format( "\nVisibility %.1f NM", UTILS.MetersToNM( visibility ) ) + text = text .. string.format( "\nCloud base %d ft", UTILS.MetersToFeet( clouds.base ) ) + text = text .. string.format( "\nCloud thickness %d ft", UTILS.MetersToFeet( clouds.thickness ) ) + text = text .. string.format( "\nCloud density %d", clouds.density ) + text = text .. string.format( "\nPrecipitation %d", clouds.iprecptns ) if fog then - text=text..string.format("\nFog thickness %d ft", UTILS.MetersToFeet(fog.thickness)) - text=text..string.format("\nFog visibility %d ft", UTILS.MetersToFeet(fog.visibility)) + text = text .. string.format( "\nFog thickness %d ft", UTILS.MetersToFeet( fog.thickness ) ) + text = text .. string.format( "\nFog visibility %d ft", UTILS.MetersToFeet( fog.visibility ) ) else - text=text..string.format("\nNo fog") + text = text .. string.format( "\nNo fog" ) end if dust then - text=text..string.format("\nDust density %d", dust) + text = text .. string.format( "\nDust density %d", dust ) else - text=text..string.format("\nNo dust") + text = text .. string.format( "\nNo dust" ) end end -- Debug output. - self:T2(self.lid..text) + self:T2( self.lid .. text ) -- Send message to player group. - self:MessageToPlayer(self.players[playername], text, nil, "", 30, true) + self:MessageToPlayer( self.players[playername], text, nil, "", 30, true ) else - self:E(self.lid..string.format("ERROR! Could not find player unit in CarrierWeather! Unit name = %s", _unitname)) + self:E( self.lid .. string.format( "ERROR! Could not find player unit in CarrierWeather! Unit name = %s", _unitname ) ) end end @@ -17752,31 +17051,31 @@ end -- @param #AIRBOSS self -- @param #string _unitname Name of the player unit. -- @param #AIRBOSS.Difficulty difficulty Difficulty level. -function AIRBOSS:_SetDifficulty(_unitname, difficulty) - self:T2({difficulty=difficulty, unitname=_unitname}) +function AIRBOSS:_SetDifficulty( _unitname, difficulty ) + self:T2( { difficulty = difficulty, unitname = _unitname } ) -- Get player unit and player name. - local unit, playername = self:_GetPlayerUnitAndName(_unitname) + local unit, playername = self:_GetPlayerUnitAndName( _unitname ) -- Check if we have a player. if unit and playername then -- Player data. - local playerData=self.players[playername] --#AIRBOSS.PlayerData + local playerData = self.players[playername] -- #AIRBOSS.PlayerData if playerData then - playerData.difficulty=difficulty - local text=string.format("roger, your skill level is now: %s.", difficulty) - self:MessageToPlayer(playerData, text, nil, playerData.name, 5) + playerData.difficulty = difficulty + local text = string.format( "roger, your skill level is now: %s.", difficulty ) + self:MessageToPlayer( playerData, text, nil, playerData.name, 5 ) else - self:E(self.lid..string.format("ERROR: Could not get player data for player %s.", playername)) + self:E( self.lid .. string.format( "ERROR: Could not get player data for player %s.", playername ) ) end -- Set hints as well. - if playerData.difficulty==AIRBOSS.Difficulty.HARD then - playerData.showhints=false + if playerData.difficulty == AIRBOSS.Difficulty.HARD then + playerData.showhints = false else - playerData.showhints=true + playerData.showhints = true end end @@ -17785,31 +17084,31 @@ end --- Turn player's aircraft attitude display on or off. -- @param #AIRBOSS self -- @param #string _unitname Name of the player unit. -function AIRBOSS:_SetHintsOnOff(_unitname) - self:F2(_unitname) +function AIRBOSS:_SetHintsOnOff( _unitname ) + self:F2( _unitname ) -- Get player unit and player name. - local unit, playername = self:_GetPlayerUnitAndName(_unitname) + local unit, playername = self:_GetPlayerUnitAndName( _unitname ) -- Check if we have a player. if unit and playername then -- Player data. - local playerData=self.players[playername] --#AIRBOSS.PlayerData + local playerData = self.players[playername] -- #AIRBOSS.PlayerData if playerData then -- Invert hints. - playerData.showhints=not playerData.showhints + playerData.showhints = not playerData.showhints -- Inform player. - local text="" - if playerData.showhints==true then - text=string.format("roger, hints are now ON.") + local text = "" + if playerData.showhints == true then + text = string.format( "roger, hints are now ON." ) else - text=string.format("affirm, hints are now OFF.") + text = string.format( "affirm, hints are now OFF." ) end - self:MessageToPlayer(playerData, text, nil, playerData.name, 5) + self:MessageToPlayer( playerData, text, nil, playerData.name, 5 ) end end @@ -17818,20 +17117,20 @@ end --- Turn player's aircraft attitude display on or off. -- @param #AIRBOSS self -- @param #string _unitname Name of the player unit. -function AIRBOSS:_DisplayAttitude(_unitname) - self:F2(_unitname) +function AIRBOSS:_DisplayAttitude( _unitname ) + self:F2( _unitname ) -- Get player unit and player name. - local unit, playername = self:_GetPlayerUnitAndName(_unitname) + local unit, playername = self:_GetPlayerUnitAndName( _unitname ) -- Check if we have a player. if unit and playername then -- Player data. - local playerData=self.players[playername] --#AIRBOSS.PlayerData + local playerData = self.players[playername] -- #AIRBOSS.PlayerData if playerData then - playerData.attitudemonitor=not playerData.attitudemonitor + playerData.attitudemonitor = not playerData.attitudemonitor end end @@ -17840,28 +17139,28 @@ end --- Turn radio subtitles of player on or off. -- @param #AIRBOSS self -- @param #string _unitname Name of the player unit. -function AIRBOSS:_SubtitlesOnOff(_unitname) - self:F2(_unitname) +function AIRBOSS:_SubtitlesOnOff( _unitname ) + self:F2( _unitname ) -- Get player unit and player name. - local unit, playername = self:_GetPlayerUnitAndName(_unitname) + local unit, playername = self:_GetPlayerUnitAndName( _unitname ) -- Check if we have a player. if unit and playername then -- Player data. - local playerData=self.players[playername] --#AIRBOSS.PlayerData + local playerData = self.players[playername] -- #AIRBOSS.PlayerData if playerData then - playerData.subtitles=not playerData.subtitles + playerData.subtitles = not playerData.subtitles -- Inform player. - local text="" - if playerData.subtitles==true then - text=string.format("roger, subtitiles are now ON.") - elseif playerData.subtitles==false then - text=string.format("affirm, subtitiles are now OFF.") + local text = "" + if playerData.subtitles == true then + text = string.format( "roger, subtitiles are now ON." ) + elseif playerData.subtitles == false then + text = string.format( "affirm, subtitiles are now OFF." ) end - self:MessageToPlayer(playerData, text, nil, playerData.name, 5) + self:MessageToPlayer( playerData, text, nil, playerData.name, 5 ) end end @@ -17870,154 +17169,152 @@ end --- Turn radio subtitles of player on or off. -- @param #AIRBOSS self -- @param #string _unitname Name of the player unit. -function AIRBOSS:_TrapsheetOnOff(_unitname) - self:F2(_unitname) +function AIRBOSS:_TrapsheetOnOff( _unitname ) + self:F2( _unitname ) -- Get player unit and player name. - local unit, playername = self:_GetPlayerUnitAndName(_unitname) + local unit, playername = self:_GetPlayerUnitAndName( _unitname ) -- Check if we have a player. if unit and playername then -- Player data. - local playerData=self.players[playername] --#AIRBOSS.PlayerData + local playerData = self.players[playername] -- #AIRBOSS.PlayerData if playerData then -- Check if option is enabled at all. - local text="" + local text = "" if self.trapsheet then -- Invert current setting. - playerData.trapon=not playerData.trapon + playerData.trapon = not playerData.trapon -- Inform player. - if playerData.trapon==true then - text=string.format("roger, your trapsheets are now SAVED.") + if playerData.trapon == true then + text = string.format( "roger, your trapsheets are now SAVED." ) else - text=string.format("affirm, your trapsheets are NOT SAVED.") + text = string.format( "affirm, your trapsheets are NOT SAVED." ) end else - text="negative, trap sheet data recorder is broken on this carrier." + text = "negative, trap sheet data recorder is broken on this carrier." end -- Message to player. - self:MessageToPlayer(playerData, text, nil, playerData.name, 5) + self:MessageToPlayer( playerData, text, nil, playerData.name, 5 ) end end end - --- Display player status. -- @param #AIRBOSS self -- @param #string _unitName Name of the player unit. -function AIRBOSS:_DisplayPlayerStatus(_unitName) +function AIRBOSS:_DisplayPlayerStatus( _unitName ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then -- Pattern step text. - local steptext=playerData.step - if playerData.step==AIRBOSS.PatternStep.HOLDING then - if playerData.holding==nil then - steptext="Transit to Marshal" - elseif playerData.holding==false then - steptext="Marshal (outside zone)" - elseif playerData.holding==true then - steptext="Marshal Stack Holding" + local steptext = playerData.step + if playerData.step == AIRBOSS.PatternStep.HOLDING then + if playerData.holding == nil then + steptext = "Transit to Marshal" + elseif playerData.holding == false then + steptext = "Marshal (outside zone)" + elseif playerData.holding == true then + steptext = "Marshal Stack Holding" end end -- Stack. - local stack=playerData.flag + local stack = playerData.flag -- Stack text. - local stacktext=nil - if stack>0 then - local stackalt=self:_GetMarshalAltitude(stack) - local angels=self:_GetAngels(stackalt) - stacktext=string.format("Marshal Stack %d, Angels %d\n", stack, angels) - + local stacktext = nil + if stack > 0 then + local stackalt = self:_GetMarshalAltitude( stack ) + local angels = self:_GetAngels( stackalt ) + stacktext = string.format( "Marshal Stack %d, Angels %d\n", stack, angels ) -- Hint about TACAN bearing. - if playerData.step==AIRBOSS.PatternStep.HOLDING and playerData.case>1 then + if playerData.step == AIRBOSS.PatternStep.HOLDING and playerData.case > 1 then -- Get inverse magnetic radial potential offset. - local radial=self:GetRadial(playerData.case, true, true, true) - stacktext=stacktext..string.format("Select TACAN %03d°, %d DME\n", radial, angels+15) + local radial = self:GetRadial( playerData.case, true, true, true ) + stacktext = stacktext .. string.format( "Select TACAN %03d°, %d DME\n", radial, angels + 15 ) end end -- Fuel and fuel state. - local fuel=playerData.unit:GetFuel()*100 - local fuelstate=self:_GetFuelState(playerData.unit) + local fuel = playerData.unit:GetFuel() * 100 + local fuelstate = self:_GetFuelState( playerData.unit ) -- Number of units in group. - local _,nunitsGround=self:_GetFlightUnits(playerData, true) - local _,nunitsAirborne=self:_GetFlightUnits(playerData, false) + local _, nunitsGround = self:_GetFlightUnits( playerData, true ) + local _, nunitsAirborne = self:_GetFlightUnits( playerData, false ) -- Player data. - local text=string.format("Status of player %s (%s)\n", playerData.name, playerData.callsign) - text=text..string.format("================================\n") - text=text..string.format("Step: %s\n", steptext) + local text = string.format( "Status of player %s (%s)\n", playerData.name, playerData.callsign ) + text = text .. string.format( "================================\n" ) + text = text .. string.format( "Step: %s\n", steptext ) if stacktext then - text=text..stacktext + text = text .. stacktext end - text=text..string.format("Recovery Case: %d\n", playerData.case) - text=text..string.format("Skill Level: %s\n", playerData.difficulty) - text=text..string.format("Modex: %s (%s)\n", playerData.onboard, self:_GetACNickname(playerData.actype)) - text=text..string.format("Fuel State: %.1f lbs/1000 (%.1f %%)\n", fuelstate/1000, fuel) - text=text..string.format("# units: %d (%d airborne)\n", nunitsGround, nunitsAirborne) - text=text..string.format("Section Lead: %s (%d/%d)", tostring(playerData.seclead), #playerData.section+1, self.NmaxSection+1) - for _,_sec in pairs(playerData.section) do - local sec=_sec --#AIRBOSS.PlayerData - text=text..string.format("\n- %s", sec.name) + text = text .. string.format( "Recovery Case: %d\n", playerData.case ) + text = text .. string.format( "Skill Level: %s\n", playerData.difficulty ) + text = text .. string.format( "Modex: %s (%s)\n", playerData.onboard, self:_GetACNickname( playerData.actype ) ) + text = text .. string.format( "Fuel State: %.1f lbs/1000 (%.1f %%)\n", fuelstate / 1000, fuel ) + text = text .. string.format( "# units: %d (%d airborne)\n", nunitsGround, nunitsAirborne ) + text = text .. string.format( "Section Lead: %s (%d/%d)", tostring( playerData.seclead ), #playerData.section + 1, self.NmaxSection + 1 ) + for _, _sec in pairs( playerData.section ) do + local sec = _sec -- #AIRBOSS.PlayerData + text = text .. string.format( "\n- %s", sec.name ) end - if playerData.step==AIRBOSS.PatternStep.INITIAL then + if playerData.step == AIRBOSS.PatternStep.INITIAL then -- Create a point 3.0 NM astern for re-entry. - local zoneinitial=self:GetCoordinate():Translate(UTILS.NMToMeters(3.5), self:GetRadial(2, false, false, false)) + local zoneinitial = self:GetCoordinate():Translate( UTILS.NMToMeters( 3.5 ), self:GetRadial( 2, false, false, false ) ) -- Heading and distance to initial zone. - local flyhdg=playerData.unit:GetCoordinate():HeadingTo(zoneinitial) - local flydist=UTILS.MetersToNM(playerData.unit:GetCoordinate():Get2DDistance(zoneinitial)) - local brc=self:GetBRC() + local flyhdg = playerData.unit:GetCoordinate():HeadingTo( zoneinitial ) + local flydist = UTILS.MetersToNM( playerData.unit:GetCoordinate():Get2DDistance( zoneinitial ) ) + local brc = self:GetBRC() -- Help player to find its way to the initial zone. - text=text..string.format("\nTo Initial: Fly heading %03d° for %.1f NM and turn to BRC %03d°", flyhdg, flydist, brc) + text = text .. string.format( "\nTo Initial: Fly heading %03d° for %.1f NM and turn to BRC %03d°", flyhdg, flydist, brc ) - elseif playerData.step==AIRBOSS.PatternStep.PLATFORM then + elseif playerData.step == AIRBOSS.PatternStep.PLATFORM then -- Coordinate of the platform zone. - local zoneplatform=self:_GetZonePlatform(playerData.case):GetCoordinate() + local zoneplatform = self:_GetZonePlatform( playerData.case ):GetCoordinate() -- Heading and distance to platform zone. - local flyhdg=playerData.unit:GetCoordinate():HeadingTo(zoneplatform) - local flydist=UTILS.MetersToNM(playerData.unit:GetCoordinate():Get2DDistance(zoneplatform)) + local flyhdg = playerData.unit:GetCoordinate():HeadingTo( zoneplatform ) + local flydist = UTILS.MetersToNM( playerData.unit:GetCoordinate():Get2DDistance( zoneplatform ) ) -- Get heading. - local hdg=self:GetRadial(playerData.case, true, true, true) + local hdg = self:GetRadial( playerData.case, true, true, true ) -- Help player to find its way to the initial zone. - text=text..string.format("\nTo Platform: Fly heading %03d° for %.1f NM and turn to %03d°", flyhdg, flydist, hdg) + text = text .. string.format( "\nTo Platform: Fly heading %03d° for %.1f NM and turn to %03d°", flyhdg, flydist, hdg ) end -- Send message. - self:MessageToPlayer(playerData, text, nil, "", 30, true) + self:MessageToPlayer( playerData, text, nil, "", 30, true ) else - self:E(self.lid..string.format("ERROR: playerData=nil. Unit name=%s, player name=%s", _unitName, _playername)) + self:E( self.lid .. string.format( "ERROR: playerData=nil. Unit name=%s, player name=%s", _unitName, _playername ) ) end else - self:E(self.lid..string.format("ERROR: could not find player for unit %s", _unitName)) + self:E( self.lid .. string.format( "ERROR: could not find player for unit %s", _unitName ) ) end end @@ -18026,92 +17323,91 @@ end -- @param #AIRBOSS self -- @param #string _unitName Name of the player unit. -- @param #boolean flare If true, flare the zone. If false, smoke the zone. -function AIRBOSS:_MarkMarshalZone(_unitName, flare) +function AIRBOSS:_MarkMarshalZone( _unitName, flare ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then -- Get player stack and recovery case. - local stack=playerData.flag - local case=playerData.case + local stack = playerData.flag + local case = playerData.case - local text="" - if stack>0 then + local text = "" + if stack > 0 then -- Get current holding zone. - local zoneHolding=self:_GetZoneHolding(case, stack) + local zoneHolding = self:_GetZoneHolding( case, stack ) -- Get Case I commence zone at three position. - local zoneThree=self:_GetZoneCommence(case, stack) + local zoneThree = self:_GetZoneCommence( case, stack ) -- Pattern alitude. - local patternalt=self:_GetMarshalAltitude(stack, case) + local patternalt = self:_GetMarshalAltitude( stack, case ) -- Flare and smoke at the ground. - patternalt=5 + patternalt = 5 -- Roger! - text="roger, marking" + text = "roger, marking" if flare then -- Marshal WHITE flares. - text=text..string.format("\n* Marshal zone stack %d with WHITE flares.", stack) - zoneHolding:FlareZone(FLARECOLOR.White, 45, nil, patternalt) + text = text .. string.format( "\n* Marshal zone stack %d with WHITE flares.", stack ) + zoneHolding:FlareZone( FLARECOLOR.White, 45, nil, patternalt ) -- Commence RED flares. - text=text.."\n* Commence zone with RED flares." - zoneThree:FlareZone(FLARECOLOR.Red, 45, nil, patternalt) + text = text .. "\n* Commence zone with RED flares." + zoneThree:FlareZone( FLARECOLOR.Red, 45, nil, patternalt ) else -- Marshal WHITE smoke. - text=text..string.format("\n* Marshal zone stack %d with WHITE smoke.", stack) - zoneHolding:SmokeZone(SMOKECOLOR.White, 45, patternalt) + text = text .. string.format( "\n* Marshal zone stack %d with WHITE smoke.", stack ) + zoneHolding:SmokeZone( SMOKECOLOR.White, 45, patternalt ) -- Commence RED smoke - text=text.."\n* Commence zone with RED smoke." - zoneThree:SmokeZone(SMOKECOLOR.Red, 45, patternalt) + text = text .. "\n* Commence zone with RED smoke." + zoneThree:SmokeZone( SMOKECOLOR.Red, 45, patternalt ) end else - text="negative, you are currently not in a Marshal stack. No zones will be marked!" + text = "negative, you are currently not in a Marshal stack. No zones will be marked!" end -- Send message to player. - self:MessageToPlayer(playerData, text, "MARSHAL", playerData.name) + self:MessageToPlayer( playerData, text, "MARSHAL", playerData.name ) end end end - --- Mark CASE I or II/II zones by either smoke or flares. -- @param #AIRBOSS self -- @param #string _unitName Name of the player unit. -- @param #boolean flare If true, flare the zone. If false, smoke the zone. -function AIRBOSS:_MarkCaseZones(_unitName, flare) +function AIRBOSS:_MarkCaseZones( _unitName, flare ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then -- Player's recovery case. - local case=playerData.case + local case = playerData.case -- Initial - local text=string.format("affirm, marking CASE %d zones", case) + local text = string.format( "affirm, marking CASE %d zones", case ) -- Flare or smoke? if flare then @@ -18121,55 +17417,55 @@ function AIRBOSS:_MarkCaseZones(_unitName, flare) ----------- -- Case I/II: Initial - if case==1 or case==2 then - text=text.."\n* initial with GREEN flares" - self:_GetZoneInitial(case):FlareZone(FLARECOLOR.Green, 45) + if case == 1 or case == 2 then + text = text .. "\n* initial with GREEN flares" + self:_GetZoneInitial( case ):FlareZone( FLARECOLOR.Green, 45 ) end -- Case II/III: approach corridor - if case==2 or case==3 then - text=text.."\n* approach corridor with GREEN flares" - self:_GetZoneCorridor(case):FlareZone(FLARECOLOR.Green, 45) + if case == 2 or case == 3 then + text = text .. "\n* approach corridor with GREEN flares" + self:_GetZoneCorridor( case ):FlareZone( FLARECOLOR.Green, 45 ) end -- Case II/III: platform - if case==2 or case==3 then - text=text.."\n* platform with RED flares" - self:_GetZonePlatform(case):FlareZone(FLARECOLOR.Red, 45) + if case == 2 or case == 3 then + text = text .. "\n* platform with RED flares" + self:_GetZonePlatform( case ):FlareZone( FLARECOLOR.Red, 45 ) end -- Case III: dirty up - if case==3 then - text=text.."\n* dirty up with YELLOW flares" - self:_GetZoneDirtyUp(case):FlareZone(FLARECOLOR.Yellow, 45) + if case == 3 then + text = text .. "\n* dirty up with YELLOW flares" + self:_GetZoneDirtyUp( case ):FlareZone( FLARECOLOR.Yellow, 45 ) end -- Case II/III: arc in/out - if case==2 or case==3 then - if math.abs(self.holdingoffset)>0 then - self:_GetZoneArcIn(case):FlareZone(FLARECOLOR.White, 45) - text=text.."\n* arc turn in with WHITE flares" - self:_GetZoneArcOut(case):FlareZone(FLARECOLOR.White, 45) - text=text.."\n* arc trun out with WHITE flares" + if case == 2 or case == 3 then + if math.abs( self.holdingoffset ) > 0 then + self:_GetZoneArcIn( case ):FlareZone( FLARECOLOR.White, 45 ) + text = text .. "\n* arc turn in with WHITE flares" + self:_GetZoneArcOut( case ):FlareZone( FLARECOLOR.White, 45 ) + text = text .. "\n* arc trun out with WHITE flares" end end -- Case III: bullseye - if case==3 then - text=text.."\n* bullseye with GREEN flares" - self:_GetZoneBullseye(case):FlareZone(FLARECOLOR.Green, 45) + if case == 3 then + text = text .. "\n* bullseye with GREEN flares" + self:_GetZoneBullseye( case ):FlareZone( FLARECOLOR.Green, 45 ) end -- Tarawa, LHA and LHD landing spots. - if self.carriertype==AIRBOSS.CarrierType.TARAWA or self.carriertype==AIRBOSS.CarrierType.AMERICA or self.carriertype==AIRBOSS.CarrierType.JCARLOS or self.carriertype==AIRBOSS.CarrierType.CANBERRA then - text=text.."\n* abeam landing stop with RED flares" + if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then + text = text .. "\n* abeam landing stop with RED flares" -- Abeam landing spot zone. - local ALSPT=self:_GetZoneAbeamLandingSpot() - ALSPT:FlareZone(FLARECOLOR.Red, 5, nil, UTILS.FeetToMeters(110)) + local ALSPT = self:_GetZoneAbeamLandingSpot() + ALSPT:FlareZone( FLARECOLOR.Red, 5, nil, UTILS.FeetToMeters( 110 ) ) -- Primary landing spot zone. - text=text.."\n* primary landing spot with GREEN flares" - local LSPT=self:_GetZoneLandingSpot() - LSPT:FlareZone(FLARECOLOR.Green, 5, nil, self.carrierparam.deckheight) + text = text .. "\n* primary landing spot with GREEN flares" + local LSPT = self:_GetZoneLandingSpot() + LSPT:FlareZone( FLARECOLOR.Green, 5, nil, self.carrierparam.deckheight ) end else @@ -18179,49 +17475,49 @@ function AIRBOSS:_MarkCaseZones(_unitName, flare) ----------- -- Case I/II: Initial - if case==1 or case==2 then - text=text.."\n* initial with GREEN smoke" - self:_GetZoneInitial(case):SmokeZone(SMOKECOLOR.Green, 45) + if case == 1 or case == 2 then + text = text .. "\n* initial with GREEN smoke" + self:_GetZoneInitial( case ):SmokeZone( SMOKECOLOR.Green, 45 ) end -- Case II/III: Approach Corridor - if case==2 or case==3 then - text=text.."\n* approach corridor with GREEN smoke" - self:_GetZoneCorridor(case):SmokeZone(SMOKECOLOR.Green, 45) + if case == 2 or case == 3 then + text = text .. "\n* approach corridor with GREEN smoke" + self:_GetZoneCorridor( case ):SmokeZone( SMOKECOLOR.Green, 45 ) end -- Case II/III: platform - if case==2 or case==3 then - text=text.."\n* platform with RED smoke" - self:_GetZonePlatform(case):SmokeZone(SMOKECOLOR.Red, 45) + if case == 2 or case == 3 then + text = text .. "\n* platform with RED smoke" + self:_GetZonePlatform( case ):SmokeZone( SMOKECOLOR.Red, 45 ) end -- Case II/III: arc in/out if offset>0. - if case==2 or case==3 then - if math.abs(self.holdingoffset)>0 then - self:_GetZoneArcIn(case):SmokeZone(SMOKECOLOR.Blue, 45) - text=text.."\n* arc turn in with BLUE smoke" - self:_GetZoneArcOut(case):SmokeZone(SMOKECOLOR.Blue, 45) - text=text.."\n* arc trun out with BLUE smoke" + if case == 2 or case == 3 then + if math.abs( self.holdingoffset ) > 0 then + self:_GetZoneArcIn( case ):SmokeZone( SMOKECOLOR.Blue, 45 ) + text = text .. "\n* arc turn in with BLUE smoke" + self:_GetZoneArcOut( case ):SmokeZone( SMOKECOLOR.Blue, 45 ) + text = text .. "\n* arc trun out with BLUE smoke" end end -- Case III: dirty up - if case==3 then - text=text.."\n* dirty up with ORANGE smoke" - self:_GetZoneDirtyUp(case):SmokeZone(SMOKECOLOR.Orange, 45) + if case == 3 then + text = text .. "\n* dirty up with ORANGE smoke" + self:_GetZoneDirtyUp( case ):SmokeZone( SMOKECOLOR.Orange, 45 ) end -- Case III: bullseye - if case==3 then - text=text.."\n* bullseye with GREEN smoke" - self:_GetZoneBullseye(case):SmokeZone(SMOKECOLOR.Green, 45) + if case == 3 then + text = text .. "\n* bullseye with GREEN smoke" + self:_GetZoneBullseye( case ):SmokeZone( SMOKECOLOR.Green, 45 ) end end -- Send message to player. - self:MessageToPlayer(playerData, text, "MARSHAL", playerData.name) + self:MessageToPlayer( playerData, text, "MARSHAL", playerData.name ) end end @@ -18230,18 +17526,18 @@ end --- LSO radio check. Will broadcase LSO message at given LSO frequency. -- @param #AIRBOSS self -- @param #string _unitName Name fo the player unit. -function AIRBOSS:_LSORadioCheck(_unitName) - self:F(_unitName) +function AIRBOSS:_LSORadioCheck( _unitName ) + self:F( _unitName ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then -- Broadcase LSO radio check message on LSO radio. - self:RadioTransmission(self.LSORadio, self.LSOCall.RADIOCHECK, nil, nil, nil, true) + self:RadioTransmission( self.LSORadio, self.LSOCall.RADIOCHECK, nil, nil, nil, true ) end end end @@ -18249,23 +17545,22 @@ end --- Marshal radio check. Will broadcase Marshal message at given Marshal frequency. -- @param #AIRBOSS self -- @param #string _unitName Name fo the player unit. -function AIRBOSS:_MarshalRadioCheck(_unitName) - self:F(_unitName) +function AIRBOSS:_MarshalRadioCheck( _unitName ) + self:F( _unitName ) -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) + local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) -- Check if we have a unit which is a player. if _unit and _playername then - local playerData=self.players[_playername] --#AIRBOSS.PlayerData + local playerData = self.players[_playername] -- #AIRBOSS.PlayerData if playerData then -- Broadcase Marshal radio check message on Marshal radio. - self:RadioTransmission(self.MarshalRadio, self.MarshalCall.RADIOCHECK, nil, nil, nil, true) + self:RadioTransmission( self.MarshalRadio, self.MarshalCall.RADIOCHECK, nil, nil, nil, true ) end end end - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -- Persistence Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ @@ -18274,94 +17569,92 @@ end -- @param #AIRBOSS self -- @param #AIRBOSS.PlayerData playerData Player data table. -- @param #AIRBOSS.LSOgrade grade LSO grad data. -function AIRBOSS:_SaveTrapSheet(playerData, grade) +function AIRBOSS:_SaveTrapSheet( playerData, grade ) -- Nothing to save. - if playerData.trapsheet==nil or #playerData.trapsheet==0 or not io then + if playerData.trapsheet == nil or #playerData.trapsheet == 0 or not io then return end --- Function that saves data to file - local function _savefile(filename, data) - local f = io.open(filename, "wb") + local function _savefile( filename, data ) + local f = io.open( filename, "wb" ) if f then - f:write(data) + f:write( data ) f:close() else - self:E(self.lid..string.format("ERROR: could not save trap sheet to file %s.\nFile may contain invalid characters.", tostring(filename))) + self:E( self.lid .. string.format( "ERROR: could not save trap sheet to file %s.\nFile may contain invalid characters.", tostring( filename ) ) ) end end -- Set path or default. - local path=self.trappath + local path = self.trappath if lfs then - path=path or lfs.writedir() + path = path or lfs.writedir() end - -- Create unused file name. - local filename=nil - for i=1,9999 do + local filename = nil + for i = 1, 9999 do -- Create file name - if self.trapprefix then - filename=string.format("%s_%s-%04d.csv", self.trapprefix, playerData.actype, i) - else - local name=UTILS.ReplaceIllegalCharacters(playerData.name, "_") - filename=string.format("AIRBOSS-%s_Trapsheet-%s_%s-%04d.csv", self.alias, name, playerData.actype, i) - end + if self.trapprefix then + filename = string.format( "%s_%s-%04d.csv", self.trapprefix, playerData.actype, i ) + else + local name = UTILS.ReplaceIllegalCharacters( playerData.name, "_" ) + filename = string.format( "AIRBOSS-%s_Trapsheet-%s_%s-%04d.csv", self.alias, name, playerData.actype, i ) + end -- Set path. - if path~=nil then - filename=path.."\\"..filename + if path ~= nil then + filename = path .. "\\" .. filename end -- Check if file exists. - local _exists=UTILS.FileExists(filename) + local _exists = UTILS.FileExists( filename ) if not _exists then break end end - -- Info - local text=string.format("Saving player %s trapsheet to file %s", playerData.name, filename) - self:I(self.lid..text) + local text = string.format( "Saving player %s trapsheet to file %s", playerData.name, filename ) + self:I( self.lid .. text ) -- Header line - local data="#Time,Rho,X,Z,Alt,AoA,GSE,LUE,Vtot,Vy,Gamma,Pitch,Roll,Yaw,Step,Grade,Points,Details\n" + local data = "#Time,Rho,X,Z,Alt,AoA,GSE,LUE,Vtot,Vy,Gamma,Pitch,Roll,Yaw,Step,Grade,Points,Details\n" - local g0=playerData.trapsheet[1] --#AIRBOSS.GrooveData - local T0=g0.Time + local g0 = playerData.trapsheet[1] -- #AIRBOSS.GrooveData + local T0 = g0.Time - --for _,_groove in ipairs(playerData.trapsheet) do - for i=1,#playerData.trapsheet do - --local groove=_groove --#AIRBOSS.GrooveData - local groove=playerData.trapsheet[i] - local t=groove.Time-T0 - local a=UTILS.MetersToNM(groove.Rho or 0) - local b=-groove.X or 0 - local c=groove.Z or 0 - local d=UTILS.MetersToFeet(groove.Alt or 0) - local e=groove.AoA or 0 - local f=groove.GSE or 0 - local g=-groove.LUE or 0 - local h=UTILS.MpsToKnots(groove.Vel or 0) - local i=(groove.Vy or 0)*196.85 - local j=groove.Gamma or 0 - local k=groove.Pitch or 0 - local l=groove.Roll or 0 - local m=groove.Yaw or 0 - local n=self:_GS(groove.Step, -1) or "n/a" - local o=groove.Grade or "n/a" - local p=groove.GradePoints or 0 - local q=groove.GradeDetail or "n/a" - -- t a b c d e f g h i j k l m n o p q - data=data..string.format("%.2f,%.3f,%.1f,%.1f,%.1f,%.2f,%.2f,%.2f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%s,%s,%.1f,%s\n",t,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) + -- for _,_groove in ipairs(playerData.trapsheet) do + for i = 1, #playerData.trapsheet do + -- local groove=_groove --#AIRBOSS.GrooveData + local groove = playerData.trapsheet[i] + local t = groove.Time - T0 + local a = UTILS.MetersToNM( groove.Rho or 0 ) + local b = -groove.X or 0 + local c = groove.Z or 0 + local d = UTILS.MetersToFeet( groove.Alt or 0 ) + local e = groove.AoA or 0 + local f = groove.GSE or 0 + local g = -groove.LUE or 0 + local h = UTILS.MpsToKnots( groove.Vel or 0 ) + local i = (groove.Vy or 0) * 196.85 + local j = groove.Gamma or 0 + local k = groove.Pitch or 0 + local l = groove.Roll or 0 + local m = groove.Yaw or 0 + local n = self:_GS( groove.Step, -1 ) or "n/a" + local o = groove.Grade or "n/a" + local p = groove.GradePoints or 0 + local q = groove.GradeDetail or "n/a" + -- t a b c d e f g h i j k l m n o p q + data = data .. string.format( "%.2f,%.3f,%.1f,%.1f,%.1f,%.2f,%.2f,%.2f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%s,%s,%.1f,%s\n", t, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q ) end -- Save file. - _savefile(filename, data) + _savefile( filename, data ) end --- On before "Save" event. Checks if io and lfs are available. @@ -18371,17 +17664,17 @@ end -- @param #string To To state. -- @param #string path (Optional) Path where the file is saved. Default is the DCS root installation folder or your "Saved Games\\DCS" folder if the lfs module is desanitized. -- @param #string filename (Optional) File name for saving the player grades. Default is "AIRBOSS-_LSOgrades.csv". -function AIRBOSS:onbeforeSave(From, Event, To, path, filename) +function AIRBOSS:onbeforeSave( From, Event, To, path, filename ) -- Check io module is available. if not io then - self:E(self.lid.."ERROR: io not desanitized. Can't save player grades.") + self:E( self.lid .. "ERROR: io not desanitized. Can't save player grades." ) return false end -- Check default path. - if path==nil and not lfs then - self:E(self.lid.."WARNING: lfs not desanitized. Results will be saved in DCS installation root directory rather than your \"Saved Games\\DCS\" folder.") + if path == nil and not lfs then + self:E( self.lid .. "WARNING: lfs not desanitized. Results will be saved in DCS installation root directory rather than your \"Saved Games\\DCS\" folder." ) end return true @@ -18394,72 +17687,69 @@ end -- @param #string To To state. -- @param #string path Path where the file is saved. If nil, file is saved in the DCS root installtion directory or your "Saved Games" folder if lfs was desanitized. -- @param #string filename (Optional) File name for saving the player grades. Default is "AIRBOSS-_LSOgrades.csv". -function AIRBOSS:onafterSave(From, Event, To, path, filename) +function AIRBOSS:onafterSave( From, Event, To, path, filename ) --- Function that saves data to file - local function _savefile(filename, data) - local f = assert(io.open(filename, "wb")) - f:write(data) + local function _savefile( filename, data ) + local f = assert( io.open( filename, "wb" ) ) + f:write( data ) f:close() end -- Set path or default. if lfs then - path=path or lfs.writedir() + path = path or lfs.writedir() end -- Set file name. - filename=filename or string.format("AIRBOSS-%s_LSOgrades.csv", self.alias) + filename = filename or string.format( "AIRBOSS-%s_LSOgrades.csv", self.alias ) -- Set path. - if path~=nil then - filename=path.."\\"..filename + if path ~= nil then + filename = path .. "\\" .. filename end -- Header line - local scores="Name,Pass,Points Final,Points Pass,Grade,Details,Wire,Tgroove,Case,Wind,Modex,Airframe,Carrier Type,Carrier Name,Theatre,Mission Time,Mission Date,OS Date\n" + local scores = "Name,Pass,Points Final,Points Pass,Grade,Details,Wire,Tgroove,Case,Wind,Modex,Airframe,Carrier Type,Carrier Name,Theatre,Mission Time,Mission Date,OS Date\n" -- Loop over all players. - local n=0 - for playername,grades in pairs(self.playerscores) do + local n = 0 + for playername, grades in pairs( self.playerscores ) do -- Loop over player grades table. - for i,_grade in pairs(grades) do - local grade=_grade --#AIRBOSS.LSOgrade + for i, _grade in pairs( grades ) do + local grade = _grade -- #AIRBOSS.LSOgrade -- Check some stuff that could be nil. - local wire="n/a" - if grade.wire and grade.wire<=4 then - wire=tostring(grade.wire) + local wire = "n/a" + if grade.wire and grade.wire <= 4 then + wire = tostring( grade.wire ) end - local Tgroove="n/a" - if grade.Tgroove and grade.Tgroove<=360 and grade.case<3 then - Tgroove=tostring(UTILS.Round(grade.Tgroove, 1)) + local Tgroove = "n/a" + if grade.Tgroove and grade.Tgroove <= 360 and grade.case < 3 then + Tgroove = tostring( UTILS.Round( grade.Tgroove, 1 ) ) end - local finalscore="n/a" + local finalscore = "n/a" if grade.finalscore then - finalscore=tostring(UTILS.Round(grade.finalscore, 1)) + finalscore = tostring( UTILS.Round( grade.finalscore, 1 ) ) end -- Compile grade line. - scores=scores..string.format("%s,%d,%s,%.1f,%s,%s,%s,%s,%d,%s,%s,%s,%s,%s,%s,%s,%s,%s\n", - playername, i, finalscore, grade.points, grade.grade, grade.details, wire, Tgroove, grade.case, - grade.wind, grade.modex, grade.airframe, grade.carriertype, grade.carriername, grade.theatre, grade.mitime, grade.midate, grade.osdate) - n=n+1 + scores = scores .. string.format( "%s,%d,%s,%.1f,%s,%s,%s,%s,%d,%s,%s,%s,%s,%s,%s,%s,%s,%s\n", playername, i, finalscore, grade.points, grade.grade, grade.details, wire, Tgroove, grade.case, grade.wind, grade.modex, grade.airframe, grade.carriertype, grade.carriername, grade.theatre, grade.mitime, grade.midate, grade.osdate ) + n = n + 1 end end -- Info - local text=string.format("Saving %d player LSO grades to file %s", n, filename) - self:I(self.lid..text) + local text = string.format( "Saving %d player LSO grades to file %s", n, filename ) + self:I( self.lid .. text ) -- Save file. - _savefile(filename, scores) + _savefile( filename, scores ) end - --- On before "Load" event. Checks if the file that the player grades from exists. -- @param #AIRBOSS self -- @param #string From From state. @@ -18467,13 +17757,13 @@ end -- @param #string To To state. -- @param #string path (Optional) Path where the file is loaded from. Default is the DCS installation root directory or your "Saved Games\\DCS" folder if lfs was desanizized. -- @param #string filename (Optional) File name for saving the player grades. Default is "AIRBOSS-_LSOgrades.csv". -function AIRBOSS:onbeforeLoad(From, Event, To, path, filename) +function AIRBOSS:onbeforeLoad( From, Event, To, path, filename ) --- Function that check if a file exists. - local function _fileexists(name) - local f=io.open(name,"r") - if f~=nil then - io.close(f) + local function _fileexists( name ) + local f = io.open( name, "r" ) + if f ~= nil then + io.close( f ) return true else return false @@ -18482,41 +17772,40 @@ function AIRBOSS:onbeforeLoad(From, Event, To, path, filename) -- Check io module is available. if not io then - self:E(self.lid.."WARNING: io not desanitized. Can't load player grades.") + self:E( self.lid .. "WARNING: io not desanitized. Can't load player grades." ) return false end -- Check default path. - if path==nil and not lfs then - self:E(self.lid.."WARNING: lfs not desanitized. Results will be saved in DCS installation root directory rather than your \"Saved Games\\DCS\" folder.") + if path == nil and not lfs then + self:E( self.lid .. "WARNING: lfs not desanitized. Results will be saved in DCS installation root directory rather than your \"Saved Games\\DCS\" folder." ) end -- Set path or default. if lfs then - path=path or lfs.writedir() + path = path or lfs.writedir() end -- Set file name. - filename=filename or string.format("AIRBOSS-%s_LSOgrades.csv", self.alias) + filename = filename or string.format( "AIRBOSS-%s_LSOgrades.csv", self.alias ) -- Set path. - if path~=nil then - filename=path.."\\"..filename + if path ~= nil then + filename = path .. "\\" .. filename end -- Check if file exists. - local exists=_fileexists(filename) + local exists = _fileexists( filename ) if exists then return true else - self:E(self.lid..string.format("WARNING: Player LSO grades file %s does not exist.", filename)) + self:E( self.lid .. string.format( "WARNING: Player LSO grades file %s does not exist.", filename ) ) return false end end - --- On after "Load" event. Loads grades of all players from file. -- @param #AIRBOSS self -- @param #string From From state. @@ -18524,102 +17813,102 @@ end -- @param #string To To state. -- @param #string path Path where the file is loaded from. Default is the DCS root installation folder or your "Saved Games\\DCS" folder if lfs was desanizied. -- @param #string filename (Optional) File name for saving the player grades. Default is "AIRBOSS-_LSOgrades.csv". -function AIRBOSS:onafterLoad(From, Event, To, path, filename) +function AIRBOSS:onafterLoad( From, Event, To, path, filename ) --- Function that load data from a file. - local function _loadfile(filename) - local f=assert(io.open(filename, "rb")) - local data=f:read("*all") + local function _loadfile( filename ) + local f = assert( io.open( filename, "rb" ) ) + local data = f:read( "*all" ) f:close() return data end -- Set path or default. if lfs then - path=path or lfs.writedir() + path = path or lfs.writedir() end -- Set file name. - filename=filename or string.format("AIRBOSS-%s_LSOgrades.csv", self.alias) + filename = filename or string.format( "AIRBOSS-%s_LSOgrades.csv", self.alias ) -- Set path. - if path~=nil then - filename=path.."\\"..filename + if path ~= nil then + filename = path .. "\\" .. filename end -- Info message. - local text=string.format("Loading player LSO grades from file %s", filename) - MESSAGE:New(text,10):ToAllIf(self.Debug) - self:I(self.lid..text) + local text = string.format( "Loading player LSO grades from file %s", filename ) + MESSAGE:New( text, 10 ):ToAllIf( self.Debug ) + self:I( self.lid .. text ) -- Load asset data from file. - local data=_loadfile(filename) + local data = _loadfile( filename ) -- Split by line break. - local playergrades=UTILS.Split(data,"\n") + local playergrades = UTILS.Split( data, "\n" ) -- Remove first header line. - table.remove(playergrades, 1) + table.remove( playergrades, 1 ) -- Init player scores table. - self.playerscores={} + self.playerscores = {} -- Loop over all lines. - local n=0 - for _,gradeline in pairs(playergrades) do + local n = 0 + for _, gradeline in pairs( playergrades ) do -- Parameters are separated by commata. - local gradedata=UTILS.Split(gradeline, ",") + local gradedata = UTILS.Split( gradeline, "," ) -- Debug info. - self:T2(gradedata) + self:T2( gradedata ) -- Grade table - local grade={} --#AIRBOSS.LSOgrade + local grade = {} -- #AIRBOSS.LSOgrade --- Line format: -- playername, i, grade.finalscore, grade.points, grade.grade, grade.details, wire, Tgroove, case, -- time, wind, airframe, modex, carriertype, carriername, theatre, date - local playername=gradedata[1] - if gradedata[3]~=nil and gradedata[3]~="n/a" then - grade.finalscore=tonumber(gradedata[3]) + local playername = gradedata[1] + if gradedata[3] ~= nil and gradedata[3] ~= "n/a" then + grade.finalscore = tonumber( gradedata[3] ) end - grade.points=tonumber(gradedata[4]) - grade.grade=tostring(gradedata[5]) - grade.details=tostring(gradedata[6]) - if gradedata[7]~=nil and gradedata[7]~="n/a" then - grade.wire=tonumber(gradedata[7]) + grade.points = tonumber( gradedata[4] ) + grade.grade = tostring( gradedata[5] ) + grade.details = tostring( gradedata[6] ) + if gradedata[7] ~= nil and gradedata[7] ~= "n/a" then + grade.wire = tonumber( gradedata[7] ) end - if gradedata[8]~=nil and gradedata[8]~="n/a" then - grade.Tgroove=tonumber(gradedata[8]) + if gradedata[8] ~= nil and gradedata[8] ~= "n/a" then + grade.Tgroove = tonumber( gradedata[8] ) end - grade.case=tonumber(gradedata[9]) + grade.case = tonumber( gradedata[9] ) -- new - grade.wind=gradedata[10] or "n/a" - grade.modex=gradedata[11] or "n/a" - grade.airframe=gradedata[12] or "n/a" - grade.carriertype=gradedata[13] or "n/a" - grade.carriername=gradedata[14] or "n/a" - grade.theatre=gradedata[15] or "n/a" - grade.mitime=gradedata[16] or "n/a" - grade.midate=gradedata[17] or "n/a" - grade.osdate=gradedata[18] or "n/a" + grade.wind = gradedata[10] or "n/a" + grade.modex = gradedata[11] or "n/a" + grade.airframe = gradedata[12] or "n/a" + grade.carriertype = gradedata[13] or "n/a" + grade.carriername = gradedata[14] or "n/a" + grade.theatre = gradedata[15] or "n/a" + grade.mitime = gradedata[16] or "n/a" + grade.midate = gradedata[17] or "n/a" + grade.osdate = gradedata[18] or "n/a" -- Init player table if necessary. - self.playerscores[playername]=self.playerscores[playername] or {} + self.playerscores[playername] = self.playerscores[playername] or {} -- Add grade to table. - table.insert(self.playerscores[playername], grade) + table.insert( self.playerscores[playername], grade ) - n=n+1 + n = n + 1 -- Debug info. - self:T2({playername, self.playerscores[playername]}) + self:T2( { playername, self.playerscores[playername] } ) end -- Info message. - local text=string.format("Loaded %d player LSO grades from file %s", n, filename) - self:I(self.lid..text) + local text = string.format( "Loaded %d player LSO grades from file %s", n, filename ) + self:I( self.lid .. text ) end From eadeaae6db77cd1fbd9462f6682717891f572353 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Wed, 13 Apr 2022 15:30:30 +0200 Subject: [PATCH 12/13] CTLD Corrected imperial hover message to say ft not m --- Moose Development/Moose/Ops/CTLD.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose Development/Moose/Ops/CTLD.lua b/Moose Development/Moose/Ops/CTLD.lua index 7ca809bab..4a7a5e66c 100644 --- a/Moose Development/Moose/Ops/CTLD.lua +++ b/Moose Development/Moose/Ops/CTLD.lua @@ -3848,7 +3848,7 @@ end else local minheight = UTILS.MetersToFeet(self.minimumHoverHeight) local maxheight = UTILS.MetersToFeet(self.maximumHoverHeight) - text = string.format("Hover parameters (autoload/drop):\n - Min height %dm \n - Max height %dm \n - Max speed 6fts \n - In parameter: %s", minheight, maxheight, htxt) + text = string.format("Hover parameters (autoload/drop):\n - Min height %dft \n - Max height %dft \n - Max speed 6ftps \n - In parameter: %s", minheight, maxheight, htxt) end self:_SendMessage(text, 10, false, Group) return self From 34153308717a276c9396434c2bf8af840fe33572 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Wed, 13 Apr 2022 16:13:02 +0200 Subject: [PATCH 13/13] UTILS - added FiFo --- Moose Development/Moose/Utilities/Utils.lua | 212 ++++++++++++++++++++ 1 file changed, 212 insertions(+) diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index 54a58639c..f78dda58f 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -2355,3 +2355,215 @@ function UTILS.LoadStationaryListOfStatics(Path,Filename,Reduce) end return datatable end + +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- FIFO +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +do +--- **UTILS** - FiFo Stack. +-- +-- **Main Features:** +-- +-- * Build a simple multi-purpose FiFo (First-In, First-Out) stack for generic data. +-- +-- === +-- +-- ### Author: **applevangelist** +-- @module Utils.FiFo +-- @image MOOSE.JPG + + +--- FIFO class. +-- @type FIFO +-- @field #string ClassName Name of the class. +-- @field #boolean debug +-- @field #string lid Class id string for output to DCS log file. +-- @field #string version Version of FiFo +-- @field #number counter +-- @field #number pointer +-- @field #number nextin +-- @field #number nextout +-- @field #table stackbypointer +-- @field #table stackbyid +-- @extends Core.Base#BASE +-- + +--- +-- @type FIFO.IDEntry +-- @field #number pointer +-- @field #table data +-- @field #table uniqueID + +--- +-- @field #FIFO +FIFO = { + ClassName = "FIFO", + debug = true, + lid = "", + version = "0.0.1", + counter = 0, + pointer = 0, + nextin = 0, + nextout = 0, + stackbypointer = {}, + stackbyid = {} +} + +--- Instantiate a new FIFO Stack +-- @param #FIFO self +-- @return #FIFO self +function FIFO:New() + -- Inherit everything from BASE class. + local self=BASE:Inherit(self, BASE:New()) -- #INTEL + self.pointer = 0 + self.counter = 0 + self.stackbypointer = {} + self.stackbyid = {} + -- Set some string id for output to DCS.log file. + self.lid=string.format("%s (%s) | ", "FiFo", self.version) + self:I(self.lid .."Created.") + return self +end + +--- FIFO Push Object to Stack +-- @param #FIFO self +-- @param #table Object +-- @param #string UniqueID (optional) - will default to current pointer + 1 +-- @return #FIFO self +function FIFO:Push(Object,UniqueID) + self:T(self.lid.."Push") + self:T({Object,UniqueID}) + self.pointer = self.pointer + 1 + self.counter = self.counter + 1 + self.stackbypointer[self.pointer] = { pointer = self.pointer, data = Object, uniqueID = UniqueID } + if UniqueID then + self.stackbyid[UniqueID] = { pointer = self.pointer, data = Object, uniqueID = UniqueID } + else + self.stackbyid[self.pointer] = { pointer = self.pointer, data = Object, uniqueID = UniqueID } + end + return self +end + +--- FIFO Pull Object from Stack +-- @param #FIFO self +-- @return #table Object or nil if stack is empty +function FIFO:Pull() + self:T(self.lid.."Pull") + if self.counter == 0 then return nil end + local object = self.stackbypointer[self.pointer].data + self.stackbypointer[self.pointer] = nil + self.counter = self.counter - 1 + self.pointer = self.pointer - 1 + self:Flatten() + return object +end + +--- FIFO Pull Object from Stack by Pointer +-- @param #FIFO self +-- @param #number Pointer +-- @return #table Object or nil if stack is empty +function FIFO:PullByPointer(Pointer) + self:T(self.lid.."PullByPointer " .. tostring(Pointer)) + if self.counter == 0 then return nil end + local object = self.stackbypointer[Pointer] -- #FIFO.IDEntry + self.stackbypointer[Pointer] = nil + self.stackbyid[object.uniqueID] = nil + self.counter = self.counter - 1 + self:Flatten() + return object.data +end + +--- FIFO Pull Object from Stack by UniqueID +-- @param #FIFO self +-- @param #tableUniqueID +-- @return #table Object or nil if stack is empty +function FIFO:PullByID(UniqueID) + self:T(self.lid.."PullByID " .. tostring(UniqueID)) + if self.counter == 0 then return nil end + local object = self.stackbyid[UniqueID] -- #FIFO.IDEntry + --self.stackbyid[UniqueID] = nil + return self:PullByPointer(object.pointer) +end + +--- FIFO Housekeeping +-- @param #FIFO self +-- @return #FIFO self +function FIFO:Flatten() + self:T(self.lid.."Flatten") + -- rebuild stacks + local pointerstack = {} + local idstack = {} + local counter = 0 + for _ID,_entry in pairs(self.stackbypointer) do + counter = counter + 1 + pointerstack[counter] = { pointer = counter, data = _entry.data, uniqueID = _entry.uniqueID} + end + for _ID,_entry in pairs(pointerstack) do + idstack[_entry.uniqueID] = { pointer = _entry.pointer , data = _entry.data, uniqueID = _entry.uniqueID} + end + self.stackbypointer = nil + self.stackbypointer = pointerstack + self.stackbyid = nil + self.stackbyid = idstack + self.counter = counter + self.pointer = counter + return self +end + +--- FIFO Check Stack is empty +-- @param #FIFO self +-- @return #boolean empty +function FIFO:IsEmpty() + self:T(self.lid.."IsEmpty") + return self.counter == 0 and true or false +end + +--- FIFO Check Stack is NOT empty +-- @param #FIFO self +-- @return #boolean notempty +function FIFO:IsNotEmpty() + self:T(self.lid.."IsNotEmpty") + return not self:IsEmpty() +end + +--- FIFO Get the data stack by pointer +-- @param #FIFO self +-- @return #table Table of #FIFO.IDEntry entries +function FIFO:GetPointerStack() + self:T(self.lid.."GetPointerStack") + return self.stackbypointer +end + +--- FIFO Get the data stack by UniqueID +-- @param #FIFO self +-- @return #table Table of #FIFO.IDEntry entries +function FIFO:GetIDStack() + self:T(self.lid.."GetIDStack") + return self.stackbyid +end + +--- FIFO Print stacks to dcs.log +-- @param #FIFO self +-- @return #FIFO self +function FIFO:Flush() + self:T(self.lid.."FiFo Flush") + self:I("FIFO Flushing Stack by Pointer") + for _id,_data in pairs (self.stackbypointer) do + local data = _data -- #FIFO.IDEntry + self:I(string.format("Pointer: %s | Entry: Number = %s Data = %s UniID = %s",tostring(_id),tostring(data.pointer),tostring(data.data),tostring(data.uniqueID))) + end + self:I("FIFO Flushing Stack by ID") + for _id,_data in pairs (self.stackbyid) do + local data = _data -- #FIFO.IDEntry + self:I(string.format("ID: %s | Entry: Number = %s Data = %s UniID = %s",tostring(_id),tostring(data.pointer),tostring(data.data),tostring(data.uniqueID))) + end + self:I("Counter = " .. self.counter) + self:I("Pointer = ".. self.pointer) + return self +end + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- End FIFO +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +end \ No newline at end of file