diff --git a/Moose Development/Moose/Core/Point.lua b/Moose Development/Moose/Core/Point.lua index 6358341ef..65022dec4 100644 --- a/Moose Development/Moose/Core/Point.lua +++ b/Moose Development/Moose/Core/Point.lua @@ -655,6 +655,28 @@ do -- COORDINATE return Angle end + --- Return an intermediate COORDINATE between this an another coordinate. + -- @param #COORDINATE self + -- @param #COORDINATE ToCoordinate The other coordinate. + -- @param #number Fraction The fraction (0,1) where the new coordinate is created. Default 0.5, i.e. in the middle. + -- @return #COORDINATE Coordinate between this and the other coordinate. + function COORDINATE:GetIntermediateCoordinate( ToCoordinate, Fraction ) + + local f=Fraction or 0.5 + + -- Get the vector from A to B + local vec=UTILS.VecSubstract(ToCoordinate, self) + + -- Scale the vector. + vec.x=f*vec.x + vec.y=f*vec.y + vec.z=f*vec.z + + -- Move the vector to start at the end of A. + vec=UTILS.VecAdd(self, vec) + + return self:New(vec.x,vec.y,vec.z) + end --- Return the 2D distance in meters between the target COORDINATE and the COORDINATE. -- @param #COORDINATE self diff --git a/Moose Development/Moose/Core/RadioQueue.lua b/Moose Development/Moose/Core/RadioQueue.lua index 2166c54fa..33857ba43 100644 --- a/Moose Development/Moose/Core/RadioQueue.lua +++ b/Moose Development/Moose/Core/RadioQueue.lua @@ -113,18 +113,20 @@ end -- @param #number dt (Optional) Time step in seconds for checking the queue. Default 0.01 sec. -- @return #RADIOQUEUE self The RADIOQUEUE object. function RADIOQUEUE:Start(delay, dt) - + + -- Delay before start. self.delay=delay or 1 + -- Time interval for queue check. self.dt=dt or 0.01 + -- Debug message. self:I(self.lid..string.format("Starting RADIOQUEUE %s on Frequency %.2f MHz [modulation=%d] in %.1f seconds (dt=%.3f sec)", self.alias, self.frequency/1000000, self.modulation, delay, dt)) - + -- Start Scheduler. if self.schedonce then - self:_CheckRadioQueueDelayed(self.delta) + self:_CheckRadioQueueDelayed(delay) else - --self.RQid=self.scheduler:Schedule(self, self._CheckRadioQueue, {}, delay, dt) self.RQid=self.scheduler:Schedule(nil, RADIOQUEUE._CheckRadioQueue, {self}, delay, dt) end @@ -279,10 +281,6 @@ end -- @return #number Duration of the call in seconds. function RADIOQUEUE:Number2Transmission(number, delay, interval) - if not number then - self:E("ERROR: Number is nil!") - end - --- Split string into characters. local function _split(str) local chars={} diff --git a/Moose Development/Moose/Core/Settings.lua b/Moose Development/Moose/Core/Settings.lua index fd1aca413..3a557de65 100644 --- a/Moose Development/Moose/Core/Settings.lua +++ b/Moose Development/Moose/Core/Settings.lua @@ -1,9 +1,9 @@ --- **Core** - Manages various settings for running missions, consumed by moose classes and provides a menu system for players to tweak settings in running missions. -- -- === --- +-- -- ## Features: --- +-- -- * Provide a settings menu system to the players. -- * Provide a player settings menu and an overall mission settings menu. -- * Mission settings provide default settings, while player settings override mission settings. @@ -11,19 +11,19 @@ -- * Provide a menu to select between different coordinate formats for A2A coordinates. -- * Provide a menu to select between different message time duration options. -- * Provide a menu to select between different metric systems. --- +-- -- === --- +-- -- The documentation of the SETTINGS class can be found further in this document. --- +-- -- === --- +-- -- # **AUTHORS and CONTRIBUTIONS** --- --- ### Contributions: --- --- ### Authors: --- +-- +-- ### Contributions: +-- +-- ### Authors: +-- -- * **FlightControl**: Design & Programming -- -- @module Core.Settings @@ -34,185 +34,187 @@ -- @extends Core.Base#BASE --- Takes care of various settings that influence the behaviour of certain functionalities and classes within the MOOSE framework. --- +-- -- === --- +-- -- The SETTINGS class takes care of various settings that influence the behaviour of certain functionalities and classes within the MOOSE framework. -- SETTINGS can work on 2 levels: --- --- - **Default settings**: A running mission has **Default settings**. +-- +-- - **Default settings**: A running mission has **Default settings**. -- - **Player settings**: For each player its own **Player settings** can be defined, overriding the **Default settings**. --- +-- -- So, when there isn't any **Player setting** defined for a player for a specific setting, or, the player cannot be identified, the **Default setting** will be used instead. --- +-- -- # 1) \_SETTINGS object --- +-- -- MOOSE defines by default a singleton object called **\_SETTINGS**. Use this object to modify all the **Default settings** for a running mission. -- For each player, MOOSE will automatically allocate also a **player settings** object, and will expose a radio menu to allow the player to adapt the settings to his own preferences. --- +-- -- # 2) SETTINGS Menu --- +-- -- Settings can be adapted by the Players and by the Mission Administrator through **radio menus, which are automatically available in the mission**. -- These menus can be found **on level F10 under "Settings"**. There are two kinds of menus generated by the system. --- +-- -- ## 2.1) Default settings menu --- +-- -- A menu is created automatically per Command Center that allows to modify the **Default** settings. -- So, when joining a CC unit, a menu will be available that allows to change the settings parameters **FOR ALL THE PLAYERS**! -- Note that the **Default settings** will only be used when a player has not choosen its own settings. --- +-- -- ## 2.2) Player settings menu --- +-- -- A menu is created automatically per Player Slot (group) that allows to modify the **Player** settings. -- So, when joining a slot, a menu wil be available that allows to change the settings parameters **FOR THE PLAYER ONLY**! -- Note that when a player has not chosen a specific setting, the **Default settings** will be used. --- +-- -- ## 2.3) Show or Hide the Player Setting menus --- +-- -- Of course, it may be requried not to show any setting menus. In this case, a method is available on the **\_SETTINGS object**. -- Use @{#SETTINGS.SetPlayerMenuOff}() to hide the player menus, and use @{#SETTINGS.SetPlayerMenuOn}() show the player menus. -- Note that when this method is used, any player already in a slot will not have its menus visibility changed. --- The option will only have effect when a player enters a new slot or changes a slot. --- +-- The option will only have effect when a player enters a new slot or changes a slot. +-- -- Example: --- +-- -- _SETTINGS:SetPlayerMenuOff() -- will disable the player menus. -- _SETTINGS:SetPlayerMenuOn() -- will enable the player menus. -- -- But only when a player exits and reenters the slot these settings will have effect! --- --- +-- +-- -- # 3) Settings --- +-- -- There are different settings that are managed and applied within the MOOSE framework. -- See below a comprehensive description of each. --- +-- -- ## 3.1) **A2G coordinates** display formatting --- +-- -- ### 3.1.1) A2G coordinates setting **types** --- +-- -- Will customize which display format is used to indicate A2G coordinates in text as part of the Command Center communications. --- +-- -- - A2G BR: [Bearing Range](https://en.wikipedia.org/wiki/Bearing_(navigation)). -- - A2G MGRS: The [Military Grid Reference System](https://en.wikipedia.org/wiki/Military_Grid_Reference_System). The accuracy can also be adapted. -- - A2G LL DMS: Lattitude Longitude [Degrees Minutes Seconds](https://en.wikipedia.org/wiki/Geographic_coordinate_conversion). The accuracy can also be adapted. -- - A2G LL DDM: Lattitude Longitude [Decimal Degrees Minutes](https://en.wikipedia.org/wiki/Decimal_degrees). The accuracy can also be adapted. --- +-- -- ### 3.1.2) A2G coordinates setting **menu** --- +-- -- The settings can be changed by using the **Default settings menu** on the Command Center or the **Player settings menu** on the Player Slot. --- +-- -- ### 3.1.3) A2G coordinates setting **methods** --- +-- -- There are different methods that can be used to change the **System settings** using the \_SETTINGS object. --- +-- -- - @{#SETTINGS.SetA2G_BR}(): Enable the BR display formatting by default. -- - @{#SETTINGS.SetA2G_MGRS}(): Enable the MGRS display formatting by default. Use @{SETTINGS.SetMGRS_Accuracy}() to adapt the accuracy of the MGRS formatting. --- - @{#SETTINGS.SetA2G_LL_DMS}(): Enable the LL DMS display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting. +-- - @{#SETTINGS.SetA2G_LL_DMS}(): Enable the LL DMS display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting. -- - @{#SETTINGS.SetA2G_LL_DDM}(): Enable the LL DDM display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting. --- +-- -- ### 3.1.4) A2G coordinates setting - additional notes --- --- One additional note on BR. In a situation when a BR coordinate should be given, +-- +-- One additional note on BR. In a situation when a BR coordinate should be given, -- but there isn't any player context (no player unit to reference from), the MGRS formatting will be applied! --- +-- -- ## 3.2) **A2A coordinates** formatting --- +-- -- ### 3.2.1) A2A coordinates setting **types** --- +-- -- Will customize which display format is used to indicate A2A coordinates in text as part of the Command Center communications. --- +-- -- - A2A BRAA: [Bearing Range Altitude Aspect](https://en.wikipedia.org/wiki/Bearing_(navigation)). -- - A2A MGRS: The [Military Grid Reference System](https://en.wikipedia.org/wiki/Military_Grid_Reference_System). The accuracy can also be adapted. -- - A2A LL DMS: Lattitude Longitude [Degrees Minutes Seconds](https://en.wikipedia.org/wiki/Geographic_coordinate_conversion). The accuracy can also be adapted. -- - A2A LL DDM: Lattitude Longitude [Decimal Degrees and Minutes](https://en.wikipedia.org/wiki/Decimal_degrees). The accuracy can also be adapted. -- - A2A BULLS: [Bullseye](http://falcon4.wikidot.com/concepts:bullseye). --- +-- -- ### 3.2.2) A2A coordinates setting **menu** --- +-- -- The settings can be changed by using the **Default settings menu** on the Command Center or the **Player settings menu** on the Player Slot. --- +-- -- ### 3.2.3) A2A coordinates setting **methods** --- +-- -- There are different methods that can be used to change the **System settings** using the \_SETTINGS object. --- +-- -- - @{#SETTINGS.SetA2A_BRAA}(): Enable the BR display formatting by default. -- - @{#SETTINGS.SetA2A_MGRS}(): Enable the MGRS display formatting by default. Use @{SETTINGS.SetMGRS_Accuracy}() to adapt the accuracy of the MGRS formatting. --- - @{#SETTINGS.SetA2A_LL_DMS}(): Enable the LL DMS display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting. +-- - @{#SETTINGS.SetA2A_LL_DMS}(): Enable the LL DMS display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting. -- - @{#SETTINGS.SetA2A_LL_DDM}(): Enable the LL DDM display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting. -- - @{#SETTINGS.SetA2A_BULLS}(): Enable the BULLSeye display formatting by default. --- +-- -- ### 3.2.4) A2A coordinates settings - additional notes --- --- One additional note on BRAA. In a situation when a BRAA coordinate should be given, +-- +-- One additional note on BRAA. In a situation when a BRAA coordinate should be given, -- but there isn't any player context (no player unit to reference from), the MGRS formatting will be applied! --- +-- -- ## 3.3) **Measurements** formatting --- +-- -- ### 3.3.1) Measurements setting **types** --- +-- -- Will customize the measurements system being used as part as part of the Command Center communications. --- +-- -- - **Metrics** system: Applies the [Metrics system](https://en.wikipedia.org/wiki/Metric_system) ... --- - **Imperial** system: Applies the [Imperial system](https://en.wikipedia.org/wiki/Imperial_units) ... --- +-- - **Imperial** system: Applies the [Imperial system](https://en.wikipedia.org/wiki/Imperial_units) ... +-- -- ### 3.3.2) Measurements setting **menu** --- +-- -- The settings can be changed by using the **Default settings menu** on the Command Center or the **Player settings menu** on the Player Slot. --- +-- -- ### 3.3.3) Measurements setting **methods** --- +-- -- There are different methods that can be used to change the **Default settings** using the \_SETTINGS object. --- +-- -- - @{#SETTINGS.SetMetric}(): Enable the Metric system. -- - @{#SETTINGS.SetImperial}(): Enable the Imperial system. --- +-- -- ## 3.4) **Message** display times --- +-- -- ### 3.4.1) Message setting **types** --- +-- -- There are various **Message Types** that will influence the duration how long a message will appear as part of the Command Center communications. --- +-- -- - **Update** message: A short update message. -- - **Information** message: Provides new information **while** executing a mission. -- - **Briefing** message: Provides a complete briefing **before** executing a mission. -- - **Overview report**: Provides a short report overview, the summary of the report. -- - **Detailed report**: Provides a complete report. --- +-- -- ### 3.4.2) Message setting **menu** --- +-- -- The settings can be changed by using the **Default settings menu** on the Command Center or the **Player settings menu** on the Player Slot. --- +-- -- Each Message Type has specific timings that will be applied when the message is displayed. -- The Settings Menu will provide for each Message Type a selection of proposed durations from which can be choosen. -- So the player can choose its own amount of seconds how long a message should be displayed of a certain type. -- Note that **Update** messages can be chosen not to be displayed at all! --- +-- -- ### 3.4.3) Message setting **methods** --- +-- -- There are different methods that can be used to change the **System settings** using the \_SETTINGS object. --- --- - @{#SETTINGS.SetMessageTime}(): Define for a specific @{Message.MESSAGE.MessageType} the duration to be displayed in seconds. --- - @{#SETTINGS.GetMessageTime}(): Retrieves for a specific @{Message.MESSAGE.MessageType} the duration to be displayed in seconds. --- +-- +-- - @{#SETTINGS.SetMessageTime}(): Define for a specific @{Message.MESSAGE.MessageType} the duration to be displayed in seconds. +-- - @{#SETTINGS.GetMessageTime}(): Retrieves for a specific @{Message.MESSAGE.MessageType} the duration to be displayed in seconds. +-- -- ## 3.5) **Era** of the battle --- +-- -- The threat level metric is scaled according the era of the battle. A target that is AAA, will pose a much greather threat in WWII than on modern warfare. -- Therefore, there are 4 era that are defined within the settings: --- +-- -- - **WWII** era: Use for warfare with equipment during the world war II time. -- - **Korea** era: Use for warfare with equipment during the Korea war time. --- - **Cold War** era: Use for warfare with equipment during the cold war time. +-- - **Cold War** era: Use for warfare with equipment during the cold war time. -- - **Modern** era: Use for warfare with modern equipment in the 2000s. --- --- There are different API defined that you can use with the _SETTINGS object to configure your mission script to work in one of the 4 era: +-- +-- There are different API defined that you can use with the _SETTINGS object to configure your mission script to work in one of the 4 era: -- @{#SETTINGS.SetEraWWII}(), @{#SETTINGS.SetEraKorea}(), @{#SETTINGS.SetEraCold}(), @{#SETTINGS.SetEraModern}() --- +-- -- === --- +-- -- @field #SETTINGS SETTINGS = { ClassName = "SETTINGS", ShowPlayerMenu = true, + MenuShort = false, + MenuStatic = false, } SETTINGS.__Enum = {} @@ -235,7 +237,7 @@ do -- SETTINGS --- SETTINGS constructor. -- @param #SETTINGS self -- @return #SETTINGS - function SETTINGS:Set( PlayerName ) + function SETTINGS:Set( PlayerName ) if PlayerName == nil then local self = BASE:Inherit( self, BASE:New() ) -- #SETTINGS @@ -260,14 +262,28 @@ do -- SETTINGS return Settings end end - - + + --- Set short text for menus on (*true*) or off (*false*). + -- Short text are better suited for, e.g., VR. + -- @param #SETTINGS self + -- @param #boolean onoff If *true* use short menu texts. If *false* long ones (default). + function SETTINGS:SetMenutextShort(onoff) + _SETTINGS.MenuShort = onoff + end + + --- Set menu to be static. + -- @param #SETTINGS self + -- @param #boolean onoff If *true* menu is static. If *false* menu will be updated after changes (default). + function SETTINGS:SetMenuStatic(onoff) + _SETTINGS.MenuStatic = onoff + end + --- Sets the SETTINGS metric. -- @param #SETTINGS self function SETTINGS:SetMetric() self.Metric = true end - + --- Gets if the SETTINGS is metric. -- @param #SETTINGS self -- @return #boolean true if metric. @@ -280,7 +296,7 @@ do -- SETTINGS function SETTINGS:SetImperial() self.Metric = false end - + --- Gets if the SETTINGS is imperial. -- @param #SETTINGS self -- @return #boolean true if imperial. @@ -317,7 +333,7 @@ do -- SETTINGS function SETTINGS:GetMGRS_Accuracy() return self.MGRS_Accuracy or _SETTINGS:GetMGRS_Accuracy() end - + --- Sets the SETTINGS Message Display Timing of a MessageType -- @param #SETTINGS self -- @param Core.Message#MESSAGE MessageType The type of the message. @@ -326,8 +342,8 @@ do -- SETTINGS self.MessageTypeTimings = self.MessageTypeTimings or {} self.MessageTypeTimings[MessageType] = MessageTime end - - + + --- Gets the SETTINGS Message Display Timing of a MessageType -- @param #SETTINGS self -- @param Core.Message#MESSAGE MessageType The type of the message. @@ -463,40 +479,77 @@ do -- SETTINGS end --- @param #SETTINGS self + -- @param Wrapper.Group#GROUP MenuGroup Group for which to add menus. + -- @param #table RootMenu Root menu table -- @return #SETTINGS function SETTINGS:SetSystemMenu( MenuGroup, RootMenu ) local MenuText = "System Settings" - + local MenuTime = timer.getTime() - + local SettingsMenu = MENU_GROUP:New( MenuGroup, MenuText, RootMenu ):SetTime( MenuTime ) - local A2GCoordinateMenu = MENU_GROUP:New( MenuGroup, "A2G Coordinate System", SettingsMenu ):SetTime( MenuTime ) - - - if not self:IsA2G_LL_DMS() then - MENU_GROUP_COMMAND:New( MenuGroup, "Lat/Lon Degree Min Sec (LL DMS)", A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "LL DMS" ):SetTime( MenuTime ) + ------- + -- A2G Coordinate System + ------- + + local text="A2G Coordinate System" + if _SETTINGS.MenuShort then + text="A2G Coordinates" end - + local A2GCoordinateMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime ) + + -- Set LL DMS + if not self:IsA2G_LL_DMS() then + local text="Lat/Lon Degree Min Sec (LL DMS)" + if _SETTINGS.MenuShort then + text="LL DMS" + end + MENU_GROUP_COMMAND:New( MenuGroup, text, A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "LL DMS" ):SetTime( MenuTime ) + end + + -- Set LL DDM if not self:IsA2G_LL_DDM() then + local text="Lat/Lon Degree Dec Min (LL DDM)" + if _SETTINGS.MenuShort then + text="LL DDM" + end MENU_GROUP_COMMAND:New( MenuGroup, "Lat/Lon Degree Dec Min (LL DDM)", A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "LL DDM" ):SetTime( MenuTime ) end - + + -- Set LL DMS accuracy. if self:IsA2G_LL_DDM() then + local text1="LL DDM Accuracy 1" + local text2="LL DDM Accuracy 2" + local text3="LL DDM Accuracy 3" + if _SETTINGS.MenuShort then + text1="LL DDM" + end MENU_GROUP_COMMAND:New( MenuGroup, "LL DDM Accuracy 1", A2GCoordinateMenu, self.MenuLL_DDM_Accuracy, self, MenuGroup, RootMenu, 1 ):SetTime( MenuTime ) MENU_GROUP_COMMAND:New( MenuGroup, "LL DDM Accuracy 2", A2GCoordinateMenu, self.MenuLL_DDM_Accuracy, self, MenuGroup, RootMenu, 2 ):SetTime( MenuTime ) MENU_GROUP_COMMAND:New( MenuGroup, "LL DDM Accuracy 3", A2GCoordinateMenu, self.MenuLL_DDM_Accuracy, self, MenuGroup, RootMenu, 3 ):SetTime( MenuTime ) end - + + -- Set BR. if not self:IsA2G_BR() then - MENU_GROUP_COMMAND:New( MenuGroup, "Bearing, Range (BR)", A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "BR" ):SetTime( MenuTime ) + local text="Bearing, Range (BR)" + if _SETTINGS.MenuShort then + text="BR" + end + MENU_GROUP_COMMAND:New( MenuGroup, text , A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "BR" ):SetTime( MenuTime ) end - + + -- Set MGRS. if not self:IsA2G_MGRS() then - MENU_GROUP_COMMAND:New( MenuGroup, "Military Grid (MGRS)", A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "MGRS" ):SetTime( MenuTime ) + local text="Military Grid (MGRS)" + if _SETTINGS.MenuShort then + text="MGRS" + end + MENU_GROUP_COMMAND:New( MenuGroup, text, A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "MGRS" ):SetTime( MenuTime ) end - + + -- Set MGRS accuracy. if self:IsA2G_MGRS() then MENU_GROUP_COMMAND:New( MenuGroup, "MGRS Accuracy 1", A2GCoordinateMenu, self.MenuMGRS_Accuracy, self, MenuGroup, RootMenu, 1 ):SetTime( MenuTime ) MENU_GROUP_COMMAND:New( MenuGroup, "MGRS Accuracy 2", A2GCoordinateMenu, self.MenuMGRS_Accuracy, self, MenuGroup, RootMenu, 2 ):SetTime( MenuTime ) @@ -505,32 +558,61 @@ do -- SETTINGS MENU_GROUP_COMMAND:New( MenuGroup, "MGRS Accuracy 5", A2GCoordinateMenu, self.MenuMGRS_Accuracy, self, MenuGroup, RootMenu, 5 ):SetTime( MenuTime ) end - local A2ACoordinateMenu = MENU_GROUP:New( MenuGroup, "A2A Coordinate System", SettingsMenu ):SetTime( MenuTime ) + ------- + -- A2A Coordinate System + ------- + + local text="A2A Coordinate System" + if _SETTINGS.MenuShort then + text="A2A Coordinates" + end + local A2ACoordinateMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime ) if not self:IsA2A_LL_DMS() then - MENU_GROUP_COMMAND:New( MenuGroup, "Lat/Lon Degree Min Sec (LL DMS)", A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "LL DMS" ):SetTime( MenuTime ) + local text="Lat/Lon Degree Min Sec (LL DMS)" + if _SETTINGS.MenuShort then + text="LL DMS" + end + MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "LL DMS" ):SetTime( MenuTime ) end if not self:IsA2A_LL_DDM() then - MENU_GROUP_COMMAND:New( MenuGroup, "Lat/Lon Degree Dec Min (LL DDM)", A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "LL DDM" ):SetTime( MenuTime ) + local text="Lat/Lon Degree Dec Min (LL DDM)" + if _SETTINGS.MenuShort then + text="LL DDM" + end + MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "LL DDM" ):SetTime( MenuTime ) end - if self:IsA2A_LL_DDM() then - MENU_GROUP_COMMAND:New( MenuGroup, "LL DDM Accuracy 1", A2ACoordinateMenu, self.MenuLL_DDM_Accuracy, self, MenuGroup, RootMenu, 1 ):SetTime( MenuTime ) - MENU_GROUP_COMMAND:New( MenuGroup, "LL DDM Accuracy 2", A2ACoordinateMenu, self.MenuLL_DDM_Accuracy, self, MenuGroup, RootMenu, 2 ):SetTime( MenuTime ) - MENU_GROUP_COMMAND:New( MenuGroup, "LL DDM Accuracy 3", A2ACoordinateMenu, self.MenuLL_DDM_Accuracy, self, MenuGroup, RootMenu, 3 ):SetTime( MenuTime ) - end + if self:IsA2A_LL_DDM() or self:IsA2A_LL_DMS() then + MENU_GROUP_COMMAND:New( MenuGroup, "LL Accuracy 0", A2ACoordinateMenu, self.MenuLL_DDM_Accuracy, self, MenuGroup, RootMenu, 0 ):SetTime( MenuTime ) + MENU_GROUP_COMMAND:New( MenuGroup, "LL Accuracy 1", A2ACoordinateMenu, self.MenuLL_DDM_Accuracy, self, MenuGroup, RootMenu, 1 ):SetTime( MenuTime ) + MENU_GROUP_COMMAND:New( MenuGroup, "LL Accuracy 2", A2ACoordinateMenu, self.MenuLL_DDM_Accuracy, self, MenuGroup, RootMenu, 2 ):SetTime( MenuTime ) + MENU_GROUP_COMMAND:New( MenuGroup, "LL Accuracy 3", A2ACoordinateMenu, self.MenuLL_DDM_Accuracy, self, MenuGroup, RootMenu, 3 ):SetTime( MenuTime ) + end if not self:IsA2A_BULLS() then - MENU_GROUP_COMMAND:New( MenuGroup, "Bullseye (BULLS)", A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "BULLS" ):SetTime( MenuTime ) + local text="Bullseye (BULLS)" + if _SETTINGS.MenuShort then + text="Bulls" + end + MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "BULLS" ):SetTime( MenuTime ) end - + if not self:IsA2A_BRAA() then - MENU_GROUP_COMMAND:New( MenuGroup, "Bearing Range Altitude Aspect (BRAA)", A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "BRAA" ):SetTime( MenuTime ) + local text="Bearing Range Altitude Aspect (BRAA)" + if _SETTINGS.MenuShort then + text="BRAA" + end + MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "BRAA" ):SetTime( MenuTime ) end - + if not self:IsA2A_MGRS() then - MENU_GROUP_COMMAND:New( MenuGroup, "Military Grid (MGRS)", A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "MGRS" ):SetTime( MenuTime ) + local text="Military Grid (MGRS)" + if _SETTINGS.MenuShort then + text="MGRS" + end + MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "MGRS" ):SetTime( MenuTime ) end if self:IsA2A_MGRS() then @@ -539,19 +621,35 @@ do -- SETTINGS MENU_GROUP_COMMAND:New( MenuGroup, "MGRS Accuracy 3", A2ACoordinateMenu, self.MenuMGRS_Accuracy, self, MenuGroup, RootMenu, 3 ):SetTime( MenuTime ) MENU_GROUP_COMMAND:New( MenuGroup, "MGRS Accuracy 4", A2ACoordinateMenu, self.MenuMGRS_Accuracy, self, MenuGroup, RootMenu, 4 ):SetTime( MenuTime ) MENU_GROUP_COMMAND:New( MenuGroup, "MGRS Accuracy 5", A2ACoordinateMenu, self.MenuMGRS_Accuracy, self, MenuGroup, RootMenu, 5 ):SetTime( MenuTime ) - end - - local MetricsMenu = MENU_GROUP:New( MenuGroup, "Measures and Weights System", SettingsMenu ):SetTime( MenuTime ) - - if self:IsMetric() then - MENU_GROUP_COMMAND:New( MenuGroup, "Imperial (Miles,Feet)", MetricsMenu, self.MenuMWSystem, self, MenuGroup, RootMenu, false ):SetTime( MenuTime ) end - + + local text="Measures and Weights System" + if _SETTINGS.MenuShort then + text="Unit System" + end + local MetricsMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime ) + + if self:IsMetric() then + local text="Imperial (Miles,Feet)" + if _SETTINGS.MenuShort then + text="Imperial" + end + MENU_GROUP_COMMAND:New( MenuGroup, text, MetricsMenu, self.MenuMWSystem, self, MenuGroup, RootMenu, false ):SetTime( MenuTime ) + end + if self:IsImperial() then - MENU_GROUP_COMMAND:New( MenuGroup, "Metric (Kilometers,Meters)", MetricsMenu, self.MenuMWSystem, self, MenuGroup, RootMenu, true ):SetTime( MenuTime ) - end - - local MessagesMenu = MENU_GROUP:New( MenuGroup, "Messages and Reports", SettingsMenu ):SetTime( MenuTime ) + local text="Metric (Kilometers,Meters)" + if _SETTINGS.MenuShort then + text="Metric" + end + MENU_GROUP_COMMAND:New( MenuGroup, text, MetricsMenu, self.MenuMWSystem, self, MenuGroup, RootMenu, true ):SetTime( MenuTime ) + end + + local text="Messages and Reports" + if _SETTINGS.MenuShort then + text="Messages & Reports" + end + local MessagesMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime ) local UpdateMessagesMenu = MENU_GROUP:New( MenuGroup, "Update Messages", MessagesMenu ):SetTime( MenuTime ) MENU_GROUP_COMMAND:New( MenuGroup, "Off", UpdateMessagesMenu, self.MenuMessageTimingsSystem, self, MenuGroup, RootMenu, MESSAGE.Type.Update, 0 ):SetTime( MenuTime ) @@ -589,10 +687,10 @@ do -- SETTINGS MENU_GROUP_COMMAND:New( MenuGroup, "1 minute", DetailedReportsMenu, self.MenuMessageTimingsSystem, self, MenuGroup, RootMenu, MESSAGE.Type.DetailedReportsMenu, 60 ):SetTime( MenuTime ) MENU_GROUP_COMMAND:New( MenuGroup, "2 minutes", DetailedReportsMenu, self.MenuMessageTimingsSystem, self, MenuGroup, RootMenu, MESSAGE.Type.DetailedReportsMenu, 120 ):SetTime( MenuTime ) MENU_GROUP_COMMAND:New( MenuGroup, "3 minutes", DetailedReportsMenu, self.MenuMessageTimingsSystem, self, MenuGroup, RootMenu, MESSAGE.Type.DetailedReportsMenu, 180 ):SetTime( MenuTime ) - + SettingsMenu:Remove( MenuTime ) - + return self end @@ -618,8 +716,6 @@ do -- SETTINGS self.ShowPlayerMenu = false end - - --- Updates the menu of the player seated in the PlayerUnit. -- @param #SETTINGS self -- @param Wrapper.Client#CLIENT PlayerUnit @@ -627,136 +723,200 @@ do -- SETTINGS function SETTINGS:SetPlayerMenu( PlayerUnit ) if _SETTINGS.ShowPlayerMenu == true then - + local PlayerGroup = PlayerUnit:GetGroup() local PlayerName = PlayerUnit:GetPlayerName() local PlayerNames = PlayerGroup:GetPlayerNames() - + local PlayerMenu = MENU_GROUP:New( PlayerGroup, 'Settings "' .. PlayerName .. '"' ) - + self.PlayerMenu = PlayerMenu - - local A2GCoordinateMenu = MENU_GROUP:New( PlayerGroup, "A2G Coordinate System", PlayerMenu ) - - if not self:IsA2G_LL_DMS() then - MENU_GROUP_COMMAND:New( PlayerGroup, "Lat/Lon Degree Min Sec (LL DMS)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DMS" ) + + self:I(string.format("Setting menu for player %s", tostring(PlayerName))) + + local submenu = MENU_GROUP:New( PlayerGroup, "LL Accuracy", PlayerMenu ) + MENU_GROUP_COMMAND:New( PlayerGroup, "LL 0 Decimals", submenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 0 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "LL 1 Decimal", submenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "LL 2 Decimals", submenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "LL 3 Decimals", submenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "LL 4 Decimals", submenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 4 ) + + local submenu = MENU_GROUP:New( PlayerGroup, "MGRS Accuracy", PlayerMenu ) + MENU_GROUP_COMMAND:New( PlayerGroup, "MRGS Accuracy 0", submenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 0 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "MRGS Accuracy 1", submenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "MRGS Accuracy 2", submenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "MRGS Accuracy 3", submenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "MRGS Accuracy 4", submenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 4 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "MRGS Accuracy 5", submenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 5 ) + + ------ + -- A2G Coordinate System + ------ + + local text="A2G Coordinate System" + if _SETTINGS.MenuShort then + text="A2G Coordinates" end - - if not self:IsA2G_LL_DDM() then - MENU_GROUP_COMMAND:New( PlayerGroup, "Lat/Lon Degree Dec Min (LL DDM)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DDM" ) + local A2GCoordinateMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu ) + + if not self:IsA2G_LL_DMS() or _SETTINGS.MenuStatic then + local text="Lat/Lon Degree Min Sec (LL DMS)" + if _SETTINGS.MenuShort then + text="A2G LL DMS" + end + MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DMS" ) end - - if self:IsA2G_LL_DDM() then - MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 1", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 2", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 3", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 ) + + if not self:IsA2G_LL_DDM() or _SETTINGS.MenuStatic then + local text="Lat/Lon Degree Dec Min (LL DDM)" + if _SETTINGS.MenuShort then + text="A2G LL DDM" + end + MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DDM" ) end - - if not self:IsA2G_BR() then - MENU_GROUP_COMMAND:New( PlayerGroup, "Bearing, Range (BR)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "BR" ) + + if not self:IsA2G_BR() or _SETTINGS.MenuStatic then + local text="Bearing, Range (BR)" + if _SETTINGS.MenuShort then + text="A2G BR" + end + MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "BR" ) end - - if not self:IsA2G_MGRS() then - MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" ) - end - - if self:IsA2G_MGRS() then - MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 1", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 2", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 3", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 4", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 4 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 5", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 5 ) + + if not self:IsA2G_MGRS() or _SETTINGS.MenuStatic then + local text="Military Grid (MGRS)" + if _SETTINGS.MenuShort then + text="A2G MGRS" + end + MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" ) end - - local A2ACoordinateMenu = MENU_GROUP:New( PlayerGroup, "A2A Coordinate System", PlayerMenu ) - - - if not self:IsA2A_LL_DMS() then - MENU_GROUP_COMMAND:New( PlayerGroup, "Lat/Lon Degree Min Sec (LL DMS)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DMS" ) + + ------ + -- A2A Coordinates Menu + ------ + + local text="A2A Coordinate System" + if _SETTINGS.MenuShort then + text="A2A Coordinates" end - - if not self:IsA2A_LL_DDM() then - MENU_GROUP_COMMAND:New( PlayerGroup, "Lat/Lon Degree Dec Min (LL DDM)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DDM" ) + local A2ACoordinateMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu ) + + + if not self:IsA2A_LL_DMS() or _SETTINGS.MenuStatic then + local text="Lat/Lon Degree Min Sec (LL DMS)" + if _SETTINGS.MenuShort then + text="A2A LL DMS" + end + MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DMS" ) end - - if self:IsA2A_LL_DDM() then - MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 1", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 2", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 3", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 ) + + if not self:IsA2A_LL_DDM() or _SETTINGS.MenuStatic then + local text="Lat/Lon Degree Dec Min (LL DDM)" + if _SETTINGS.MenuShort then + text="A2A LL DDM" + end + MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DDM" ) end - - if not self:IsA2A_BULLS() then - MENU_GROUP_COMMAND:New( PlayerGroup, "Bullseye (BULLS)", A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BULLS" ) + + if not self:IsA2A_BULLS() or _SETTINGS.MenuStatic then + local text="Bullseye (BULLS)" + if _SETTINGS.MenuShort then + text="A2A BULLS" + end + MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BULLS" ) end - - if not self:IsA2A_BRAA() then - MENU_GROUP_COMMAND:New( PlayerGroup, "Bearing Range Altitude Aspect (BRAA)", A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BRAA" ) + + if not self:IsA2A_BRAA() or _SETTINGS.MenuStatic then + local text="Bearing Range Altitude Aspect (BRAA)" + if _SETTINGS.MenuShort then + text="A2A BRAA" + end + MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BRAA" ) end - - if not self:IsA2A_MGRS() then - MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS)", A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" ) + + if not self:IsA2A_MGRS() or _SETTINGS.MenuStatic then + local text="Military Grid (MGRS)" + if _SETTINGS.MenuShort then + text="A2A MGRS" + end + MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" ) end - - if self:IsA2A_MGRS() then - MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 1", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 2", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 3", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 4", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 4 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 5", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 5 ) - end - - local MetricsMenu = MENU_GROUP:New( PlayerGroup, "Measures and Weights System", PlayerMenu ) - - if self:IsMetric() then - MENU_GROUP_COMMAND:New( PlayerGroup, "Imperial (Miles,Feet)", MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, false ) + + --- + -- Unit system + --- + + local text="Measures and Weights System" + if _SETTINGS.MenuShort then + text="Unit System" end - - if self:IsImperial() then - MENU_GROUP_COMMAND:New( PlayerGroup, "Metric (Kilometers,Meters)", MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, true ) - end - - - local MessagesMenu = MENU_GROUP:New( PlayerGroup, "Messages and Reports", PlayerMenu ) - + local MetricsMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu ) + + if self:IsMetric() or _SETTINGS.MenuStatic then + local text="Imperial (Miles,Feet)" + if _SETTINGS.MenuShort then + text="Imperial" + end + MENU_GROUP_COMMAND:New( PlayerGroup, text, MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, false ) + end + + if self:IsImperial() or _SETTINGS.MenuStatic then + local text="Metric (Kilometers,Meters)" + if _SETTINGS.MenuShort then + text="Metric" + end + MENU_GROUP_COMMAND:New( PlayerGroup, text, MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, true ) + end + + --- + -- Messages and Reports + --- + + local text="Messages and Reports" + if _SETTINGS.MenuShort then + text="Messages & Reports" + end + local MessagesMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu ) + local UpdateMessagesMenu = MENU_GROUP:New( PlayerGroup, "Update Messages", MessagesMenu ) - MENU_GROUP_COMMAND:New( PlayerGroup, "Off", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 0 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "5 seconds", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 5 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "10 seconds", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 10 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "15 seconds", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 15 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "30 seconds", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 30 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "1 minute", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 60 ) - - local InformationMessagesMenu = MENU_GROUP:New( PlayerGroup, "Information Messages", MessagesMenu ) - MENU_GROUP_COMMAND:New( PlayerGroup, "5 seconds", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 5 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "10 seconds", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 10 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "15 seconds", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 15 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "30 seconds", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 30 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "1 minute", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 60 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "2 minutes", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 120 ) - + MENU_GROUP_COMMAND:New( PlayerGroup, "Updates Off", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 0 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Updates 5 sec", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 5 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Updates 10 sec", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 10 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Updates 15 sec", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 15 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Updates 30 sec", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 30 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Updates 1 min", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 60 ) + + local InformationMessagesMenu = MENU_GROUP:New( PlayerGroup, "Info Messages", MessagesMenu ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Info 5 sec", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 5 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Info 10 sec", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 10 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Info 15 sec", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 15 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Info 30 sec", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 30 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Info 1 min", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 60 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Info 2 min", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 120 ) + local BriefingReportsMenu = MENU_GROUP:New( PlayerGroup, "Briefing Reports", MessagesMenu ) - MENU_GROUP_COMMAND:New( PlayerGroup, "15 seconds", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 15 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "30 seconds", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 30 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "1 minute", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 60 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "2 minutes", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 120 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "3 minutes", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 180 ) - + MENU_GROUP_COMMAND:New( PlayerGroup, "Brief 15 sec", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 15 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Brief 30 sec", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 30 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Brief 1 min", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 60 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Brief 2 min", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 120 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Brief 3 min", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 180 ) + local OverviewReportsMenu = MENU_GROUP:New( PlayerGroup, "Overview Reports", MessagesMenu ) - MENU_GROUP_COMMAND:New( PlayerGroup, "15 seconds", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 15 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "30 seconds", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 30 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "1 minute", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 60 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "2 minutes", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 120 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "3 minutes", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 180 ) - + MENU_GROUP_COMMAND:New( PlayerGroup, "Overview 15 sec", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 15 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Overview 30 sec", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 30 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Overview 1 min", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 60 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Overview 2 min", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 120 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Overview 3 min", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 180 ) + local DetailedReportsMenu = MENU_GROUP:New( PlayerGroup, "Detailed Reports", MessagesMenu ) - MENU_GROUP_COMMAND:New( PlayerGroup, "15 seconds", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 15 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "30 seconds", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 30 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "1 minute", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 60 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "2 minutes", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 120 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "3 minutes", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 180 ) - - end - + MENU_GROUP_COMMAND:New( PlayerGroup, "Detailed 15 sec", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 15 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Detailed 30 sec", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 30 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Detailed 1 min", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 60 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Detailed 2 min", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 120 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "Detailed 3 min", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 180 ) + + end + return self end @@ -770,7 +930,7 @@ do -- SETTINGS self.PlayerMenu:Remove() self.PlayerMenu = nil end - + return self end @@ -822,40 +982,50 @@ do -- SETTINGS BASE:E( {self, PlayerUnit:GetName(), A2GSystem} ) self.A2GSystem = A2GSystem MESSAGE:New( string.format( "Settings: A2G format set to %s for player %s.", A2GSystem, PlayerName ), 5 ):ToGroup( PlayerGroup ) - self:RemovePlayerMenu(PlayerUnit) - self:SetPlayerMenu(PlayerUnit) + if _SETTINGS.MenuStatic==false then + self:RemovePlayerMenu(PlayerUnit) + self:SetPlayerMenu(PlayerUnit) + end end - + --- @param #SETTINGS self function SETTINGS:MenuGroupA2ASystem( PlayerUnit, PlayerGroup, PlayerName, A2ASystem ) self.A2ASystem = A2ASystem MESSAGE:New( string.format( "Settings: A2A format set to %s for player %s.", A2ASystem, PlayerName ), 5 ):ToGroup( PlayerGroup ) - self:RemovePlayerMenu(PlayerUnit) - self:SetPlayerMenu(PlayerUnit) + if _SETTINGS.MenuStatic==false then + self:RemovePlayerMenu(PlayerUnit) + self:SetPlayerMenu(PlayerUnit) + end end - + --- @param #SETTINGS self function SETTINGS:MenuGroupLL_DDM_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, LL_Accuracy ) self.LL_Accuracy = LL_Accuracy - MESSAGE:New( string.format( "Settings: A2G LL format accuracy set to %d for player %s.", LL_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup ) - self:RemovePlayerMenu(PlayerUnit) - self:SetPlayerMenu(PlayerUnit) + MESSAGE:New( string.format( "Settings: LL format accuracy set to %d decimal places for player %s.", LL_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup ) + if _SETTINGS.MenuStatic==false then + self:RemovePlayerMenu(PlayerUnit) + self:SetPlayerMenu(PlayerUnit) + end end - + --- @param #SETTINGS self function SETTINGS:MenuGroupMGRS_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, MGRS_Accuracy ) self.MGRS_Accuracy = MGRS_Accuracy - MESSAGE:New( string.format( "Settings: A2G MGRS format accuracy set to %d for player %s.", MGRS_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup ) - self:RemovePlayerMenu(PlayerUnit) - self:SetPlayerMenu(PlayerUnit) + MESSAGE:New( string.format( "Settings: MGRS format accuracy set to %d for player %s.", MGRS_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup ) + if _SETTINGS.MenuStatic==false then + self:RemovePlayerMenu(PlayerUnit) + self:SetPlayerMenu(PlayerUnit) + end end --- @param #SETTINGS self function SETTINGS:MenuGroupMWSystem( PlayerUnit, PlayerGroup, PlayerName, MW ) self.Metric = MW MESSAGE:New( string.format( "Settings: Measurement format set to %s for player %s.", MW and "Metric" or "Imperial", PlayerName ), 5 ):ToGroup( PlayerGroup ) - self:RemovePlayerMenu(PlayerUnit) - self:SetPlayerMenu(PlayerUnit) + if _SETTINGS.MenuStatic==false then + self:RemovePlayerMenu(PlayerUnit) + self:SetPlayerMenu(PlayerUnit) + end end --- @param #SETTINGS self @@ -863,50 +1033,48 @@ do -- SETTINGS self:SetMessageTime( MessageType, MessageTime ) MESSAGE:New( string.format( "Settings: Default message time set for %s to %d.", MessageType, MessageTime ), 5 ):ToGroup( PlayerGroup ) end - + end - + --- Configures the era of the mission to be WWII. -- @param #SETTINGS self -- @return #SETTINGS self function SETTINGS:SetEraWWII() - + self.Era = SETTINGS.__Enum.Era.WWII - + end - + --- Configures the era of the mission to be Korea. -- @param #SETTINGS self -- @return #SETTINGS self function SETTINGS:SetEraKorea() - + self.Era = SETTINGS.__Enum.Era.Korea - + end - - + + --- Configures the era of the mission to be Cold war. -- @param #SETTINGS self -- @return #SETTINGS self function SETTINGS:SetEraCold() - + self.Era = SETTINGS.__Enum.Era.Cold - + end - + --- Configures the era of the mission to be Modern war. -- @param #SETTINGS self -- @return #SETTINGS self function SETTINGS:SetEraModern() - + self.Era = SETTINGS.__Enum.Era.Modern - + end - - - + + + end - - diff --git a/Moose Development/Moose/DCS.lua b/Moose Development/Moose/DCS.lua index df37c1c50..0c8e87a23 100644 --- a/Moose Development/Moose/DCS.lua +++ b/Moose Development/Moose/DCS.lua @@ -326,9 +326,27 @@ end -- coalition do -- Types --- @type Desc - -- @field #TypeName typeName type name - -- @field #string displayName localized display name - -- @field #table attributes object type attributes + -- @field #number speedMax0 Max speed in meters/second at zero altitude. + -- @field #number massEmpty Empty mass in kg. + -- @field #number tankerType Type of refueling system: 0=boom, 1=probe. + -- @field #number range Range in km(?). + -- @field #table box Bounding box. + -- @field #number Hmax Max height in meters. + -- @field #number Kmax ? + -- @field #number speedMax10K Max speed in meters/second at 10k altitude. + -- @field #number NyMin ? + -- @field #number NyMax ? + -- @field #number fuelMassMax Max fuel mass in kg. + -- @field #number speedMax10K Max speed in meters/second. + -- @field #number massMax Max mass of unit. + -- @field #number RCS ? + -- @field #number life Life points. + -- @field #number VyMax Max vertical velocity in m/s. + -- @field #number Kab ? + -- @field #table attributes Table of attributes. + -- @field #TypeName typeName Type Name. + -- @field #string displayName Localized display name. + -- @field #number category Unit category. --- A distance type -- @type Distance diff --git a/Moose Development/Moose/Utilities/Enums.lua b/Moose Development/Moose/Utilities/Enums.lua index 91c814937..f47e66b94 100644 --- a/Moose Development/Moose/Utilities/Enums.lua +++ b/Moose Development/Moose/Utilities/Enums.lua @@ -1,49 +1,163 @@ --- **Utilities** Enumerators. -- --- See the [Simulator Scripting Engine Documentation](https://wiki.hoggitworld.com/view/Simulator_Scripting_Engine_Documentation) on Hoggit for further explanation and examples. +-- An enumerator is a variable that holds a constant value. Enumerators are very useful because they make the code easier to read and to change in general. -- --- @module DCS +-- For example, instead of using the same value at multiple different places in your code, you should use a variable set to that value. +-- If, for whatever reason, the value needs to be changed, you only have to change the variable once and do not have to search through you code and reset +-- every value by hand. +-- +-- Another big advantage is that the LDT intellisense "knows" the enumerators. So you can use the autocompletion feature and do not have to keep all the +-- values in your head or look them up in the docs. +-- +-- DCS itself provides a lot of enumerators for various things. See [Enumerators](https://wiki.hoggitworld.com/view/Category:Enumerators) on Hoggit. +-- +-- Other Moose classe also have enumerators. For example, the AIRBASE class has enumerators for airbase names. +-- +-- @module ENUMS -- @image MOOSE.JPG +--- [DCS Enum world](https://wiki.hoggitworld.com/view/DCS_enum_world) +-- @type ENUMS +--- Because ENUMS are just better practice. +-- +-- The ENUMS class adds some handy variables, which help you to make your code better and more general. +-- +-- @field #ENUMS ENUMS = {} +--- Rules of Engagement. +-- @type ENUMS.ROE +-- @field #number WeaponFree AI will engage any enemy group it detects. Target prioritization is based based on the threat of the target. +-- @field #number OpenFireWeaponFree AI will engage any enemy group it detects, but will prioritize targets specified in the groups tasking. +-- @field #number OpenFire AI will engage only targets specified in its taskings. +-- @field #number ReturnFire AI will only engage threats that shoot first. +-- @field #number WeaponHold AI will hold fire under all circumstances. ENUMS.ROE = { - HoldFire = 1, - ReturnFire = 2, - OpenFire = 3, - WeaponFree = 4 + WeaponFree=0, + OpenFireWeaponFree=1, + OpenFire=2, + ReturnFire=3, + WeaponHold=4, } - + +--- Reaction On Threat. +-- @type ENUMS.ROT +-- @field #number NoReaction No defensive actions will take place to counter threats. +-- @field #number PassiveDefense AI will use jammers and other countermeasures in an attempt to defeat the threat. AI will not attempt a maneuver to defeat a threat. +-- @field #number EvadeFire AI will react by performing defensive maneuvers against incoming threats. AI will also use passive defense. +-- @field #number BypassAndEscape AI will attempt to avoid enemy threat zones all together. This includes attempting to fly above or around threats. +-- @field #number AllowAbortMission If a threat is deemed severe enough the AI will abort its mission and return to base. ENUMS.ROT = { - NoReaction = 1, - PassiveDefense = 2, - EvadeFire = 3, - Vertical = 4 + NoReaction=0, + PassiveDefense=1, + EvadeFire=2, + BypassAndEscape=3, + AllowAbortMission=4, } +--- Weapon types. See the [Weapon Flag](https://wiki.hoggitworld.com/view/DCS_enum_weapon_flag) enumerotor on hoggit wiki. +-- @type ENUMS.WeaponFlag ENUMS.WeaponFlag={ - -- Auto - Auto=1073741822, -- Bombs - LGB=2, - TvGB=4, - SNSGB=8, - HEBomb=16, - Penetrator=32, - NapalmBomb=64, - FAEBomb=128, - ClusterBomb=256, - Dispencer=512, - CandleBomb=1024, - ParachuteBomb=2147483648, - GuidedBomb=14, -- (LGB + TvGB + SNSGB) - AnyUnguidedBomb=2147485680, -- (HeBomb + Penetrator + NapalmBomb + FAEBomb + ClusterBomb + Dispencer + CandleBomb + ParachuteBomb) - AnyBomb=2147485694, -- (GuidedBomb + AnyUnguidedBomb) + LGB = 2, + TvGB = 4, + SNSGB = 8, + HEBomb = 16, + Penetrator = 32, + NapalmBomb = 64, + FAEBomb = 128, + ClusterBomb = 256, + Dispencer = 512, + CandleBomb = 1024, + ParachuteBomb = 2147483648, -- Rockets - LightRocket=2048, - MarkerRocket=4096, - CandleRocket=8192, - HeavyRocket=16384, - AnyRocket=30720 -- (LightRocket + MarkerRocket + CandleRocket + HeavyRocket) + LightRocket = 2048, + MarkerRocket = 4096, + CandleRocket = 8192, + HeavyRocket = 16384, + -- Air-To-Surface Missiles + AntiRadarMissile = 32768, + AntiShipMissile = 65536, + AntiTankMissile = 131072, + FireAndForgetASM = 262144, + LaserASM = 524288, + TeleASM = 1048576, + CruiseMissile = 2097152, + AntiRadarMissile2 = 1073741824, + -- Air-To-Air Missiles + SRAM = 4194304, + MRAAM = 8388608, + LRAAM = 16777216, + IR_AAM = 33554432, + SAR_AAM = 67108864, + AR_AAM = 134217728, + --- Guns + GunPod = 268435456, + BuiltInCannon = 536870912, + --- + -- Combinations + -- + -- Bombs + GuidedBomb = 14, -- (LGB + TvGB + SNSGB) + AnyUnguidedBomb = 2147485680, -- (HeBomb + Penetrator + NapalmBomb + FAEBomb + ClusterBomb + Dispencer + CandleBomb + ParachuteBomb) + AnyBomb = 2147485694, -- (GuidedBomb + AnyUnguidedBomb) + --- Rockets + AnyRocket = 30720, -- LightRocket + MarkerRocket + CandleRocket + HeavyRocket + --- Air-To-Surface Missiles + GuidedASM = 1572864, -- (LaserASM + TeleASM) + TacticalASM = 1835008, -- (GuidedASM + FireAndForgetASM) + AnyASM = 4161536, -- (AntiRadarMissile + AntiShipMissile + AntiTankMissile + FireAndForgetASM + GuidedASM + CruiseMissile) + AnyASM2 = 1077903360, -- 4161536+1073741824, + --- Air-To-Air Missiles + AnyAAM = 264241152, -- IR_AAM + SAR_AAM + AR_AAM + SRAAM + MRAAM + LRAAM + AnyAutonomousMissile = 36012032, -- IR_AAM + AntiRadarMissile + AntiShipMissile + FireAndForgetASM + CruiseMissile + AnyMissile = 268402688, -- AnyASM + AnyAAM + --- Guns + Cannons = 805306368, -- GUN_POD + BuiltInCannon + --- + -- Even More Genral + Auto = 3221225470, -- Any Weapon (AnyBomb + AnyRocket + AnyMissile + Cannons) + AutoDCS = 1073741822, -- Something if often see + AnyAG = 2956984318, -- Any Air-To-Ground Weapon + AnyAA = 264241152, -- Any Air-To-Air Weapon + AnyUnguided = 2952822768, -- Any Unguided Weapon + AnyGuided = 268402702, -- Any Guided Weapon +} + +--- Mission tasks. +-- @type ENUMS.MissionTask +-- @field #string NOTHING No special task. Group can perform the minimal tasks: Orbit, Refuelling, Follow and Aerobatics. +-- @field #string AFAC Forward Air Controller Air. Can perform the tasks: Attack Group, Attack Unit, FAC assign group, Bombing, Attack Map Object. +-- @field #string ANTISHIPSTRIKE Naval ops. Can perform the tasks: Attack Group, Attack Unit. +-- @field #string AWACS AWACS. +-- @field #string CAP Combat Air Patrol. +-- @field #string CAS Close Air Support. +-- @field #string ESCORT Escort another group. +-- @field #string FIGHTERSWEEP Fighter sweep. +-- @field #string GROUNDATTACK Ground attack. +-- @field #string INTERCEPT Intercept. +-- @field #string PINPOINTSTRIKE Pinpoint strike. +-- @field #string RECONNAISSANCE Reconnaissance mission. +-- @field #string REFUELING Refueling mission. +-- @field #string RUNWAYATTACK Attack the runway of an airdrome. +-- @field #string SEAD Suppression of Enemy Air Defenses. +-- @field #string TRANSPORT Troop transport. +ENUMS.MissionTask={ + NOTHING="Nothing", + AFAC="AFAC", + ANTISHIPSTRIKE="Antiship Strike", + AWACS="AWACS", + CAP="CAP", + CAS="CAS", + ESCORT="Escort", + FIGHTERSWEEP="Fighter Sweep", + GROUNDATTACK="Ground Attack", + INTERCEPT="Intercept", + PINPOINTSTRIKE="Pinpoint Strike", + RECONNAISSANCE="Reconnaissance", + REFUELING="Refueling", + RUNWAYATTACK="Runway Attack", + SEAD="SEAD", + TRANSPORT="Transport", } \ No newline at end of file diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index 97f17d59a..9f34f8cf6 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -312,7 +312,6 @@ function CONTROLLABLE:ClearTasks() if DCSControllable then local Controller = self:_GetController() - env.info("FF clearing tasks!") Controller:resetTask() return self end @@ -450,7 +449,6 @@ end -- @param #number lastWayPoint Last waypoint. -- return DCS#Task function CONTROLLABLE:TaskCondition( time, userFlag, userFlagValue, condition, duration, lastWayPoint ) - self:F2( { time, userFlag, userFlagValue, condition, duration, lastWayPoint } ) --[[ StopCondition = { @@ -471,7 +469,6 @@ function CONTROLLABLE:TaskCondition( time, userFlag, userFlagValue, condition, d DCSStopCondition.duration = duration DCSStopCondition.lastWayPoint = lastWayPoint - self:T3( { DCSStopCondition } ) return DCSStopCondition end @@ -481,11 +478,8 @@ end -- @param DCS#DCSStopCondition DCSStopCondition -- @return DCS#Task function CONTROLLABLE:TaskControlled( DCSTask, DCSStopCondition ) - self:F2( { DCSTask, DCSStopCondition } ) - local DCSTaskControlled - - DCSTaskControlled = { + local DCSTaskControlled = { id = 'ControlledTask', params = { task = DCSTask, @@ -493,7 +487,6 @@ function CONTROLLABLE:TaskControlled( DCSTask, DCSStopCondition ) } } - self:T3( { DCSTaskControlled } ) return DCSTaskControlled end @@ -502,22 +495,14 @@ end -- @param DCS#TaskArray DCSTasks Array of @{DCSTasking.Task#Task} -- @return DCS#Task function CONTROLLABLE:TaskCombo( DCSTasks ) - self:F2( { DCSTasks } ) - local DCSTaskCombo - - DCSTaskCombo = { + local DCSTaskCombo = { id = 'ComboTask', params = { tasks = DCSTasks } } - - for TaskID, Task in ipairs( DCSTasks ) do - self:T( Task ) - end - - self:T3( { DCSTaskCombo } ) + return DCSTaskCombo end @@ -526,11 +511,8 @@ end -- @param DCS#Command DCSCommand -- @return DCS#Task function CONTROLLABLE:TaskWrappedAction( DCSCommand, Index ) - self:F2( { DCSCommand } ) - local DCSTaskWrappedAction - - DCSTaskWrappedAction = { + local DCSTaskWrappedAction = { id = "WrappedAction", enabled = true, number = Index or 1, @@ -540,7 +522,6 @@ function CONTROLLABLE:TaskWrappedAction( DCSCommand, Index ) }, } - self:T3( { DCSTaskWrappedAction } ) return DCSTaskWrappedAction end @@ -703,7 +684,6 @@ end -- @param #number Delay (Optional) Delay in seconds before the ICLS is deactivated. -- @return #CONTROLLABLE self function CONTROLLABLE:CommandActivateICLS(Channel, UnitID, Callsign, Delay) - self:F() -- Command to activate ICLS system. local CommandActivateICLS= { @@ -731,7 +711,6 @@ end -- @param #number Delay (Optional) Delay in seconds before the beacon is deactivated. -- @return #CONTROLLABLE self function CONTROLLABLE:CommandDeactivateBeacon(Delay) - self:F() -- Command to deactivate local CommandDeactivateBeacon={id='DeactivateBeacon', params={}} @@ -750,7 +729,6 @@ end -- @param #number Delay (Optional) Delay in seconds before the ICLS is deactivated. -- @return #CONTROLLABLE self function CONTROLLABLE:CommandDeactivateICLS(Delay) - self:F() -- Command to deactivate local CommandDeactivateICLS={id='DeactivateICLS', params={}} @@ -771,7 +749,6 @@ end -- @param #number Delay (Optional) Delay in seconds before the callsign is set. Default is immediately. -- @return #CONTROLLABLE self function CONTROLLABLE:CommandSetCallsign(CallName, CallNumber, Delay) - self:F() -- Command to set the callsign. local CommandSetCallsign={id='SetCallsign', params={callname=CallName, callnumber=CallNumber or 1}} @@ -791,28 +768,56 @@ end -- @param #number Delay (Optional) Delay in seconds before the callsign is set. Default is immediately. -- @return #CONTROLLABLE self function CONTROLLABLE:CommandEPLRS(SwitchOnOff, Delay) - self:F() if SwitchOnOff==nil then SwitchOnOff=true end - -- ID - local _id=self:GetID() - -- Command to set the callsign. - local CommandEPLRS={id='EPLRS', params={value=SwitchOnOff, groupId=_id}} + local CommandEPLRS={ + id='EPLRS', + params={ + value=SwitchOnOff, + groupId=self:GetID() + } + } if Delay and Delay>0 then SCHEDULER:New(nil, self.CommandEPLRS, {self, SwitchOnOff}, Delay) else - self:T(string.format("EPLRS=%s for controllable %s (id=%s)", tostring(SwitchOnOff), tostring(self:GetName()), tostring(_id))) + self:T(string.format("EPLRS=%s for controllable %s (id=%s)", tostring(SwitchOnOff), tostring(self:GetName()), tostring(self:GetID()))) self:SetCommand(CommandEPLRS) end return self end +--- Set radio frequency. See [DCS command EPLRS](https://wiki.hoggitworld.com/view/DCS_command_setFrequency) +-- @param #CONTROLLABLE self +-- @param #number Frequency Radio frequency in MHz. +-- @param #number Modulation Radio modulation. Default `radio.modulation.AM`. +-- @param #number Delay (Optional) Delay in seconds before the frequncy is set. Default is immediately. +-- @return #CONTROLLABLE self +function CONTROLLABLE:CommandSetFrequency(Frequency, Modulation, Delay) + + local CommandSetFrequency = { + id = 'SetFrequency', + params = { + frequency = Frequency, + modulation = Modulation or radio.modulation.AM, + } + } + + if Delay and Delay>0 then + SCHEDULER:New(nil, self.CommandSetFrequency, {self, Frequency, Modulation}, Delay) + else + self:SetCommand(CommandSetFrequency) + end + + return self +end + + --- Set EPLRS data link on/off. -- @param #CONTROLLABLE self -- @param #boolean SwitchOnOff If true (or nil) switch EPLRS on. If false switch off. @@ -820,14 +825,20 @@ end -- @return #table Task wrapped action. function CONTROLLABLE:TaskEPLRS(SwitchOnOff, idx) - -- ID - local _id=self:GetID() + if SwitchOnOff==nil then + SwitchOnOff=true + end -- Command to set the callsign. - local CommandEPLRS={id='EPLRS', params={value=SwitchOnOff, groupId=_id}} + local CommandEPLRS={ + id='EPLRS', + params={ + value=SwitchOnOff, + groupId=self:GetID() + } + } return self:TaskWrappedAction(CommandEPLRS, idx or 1) - end @@ -835,16 +846,17 @@ end --- (AIR) Attack a Controllable. -- @param #CONTROLLABLE self --- @param Wrapper.Controllable#CONTROLLABLE AttackGroup The Controllable to be attacked. +-- @param Wrapper.Group#GROUP AttackGroup The Group to be attacked. -- @param #number WeaponType (optional) Bitmask of weapon types those allowed to use. If parameter is not defined that means no limits on weapon usage. -- @param DCS#AI.Task.WeaponExpend WeaponExpend (optional) Determines how much weapon will be released at each attack. If parameter is not defined the unit / controllable will choose expend on its own discretion. -- @param #number AttackQty (optional) This parameter limits maximal quantity of attack. The aicraft/controllable will not make more attack than allowed even if the target controllable not destroyed and the aicraft/controllable still have ammo. If not defined the aircraft/controllable will attack target until it will be destroyed or until the aircraft/controllable will run out of ammo. -- @param DCS#Azimuth Direction (optional) Desired ingress direction from the target to the attacking aircraft. Controllable/aircraft will make its attacks from the direction. Of course if there is no way to attack from the direction due the terrain controllable/aircraft will choose another direction. -- @param DCS#Distance Altitude (optional) Desired attack start altitude. Controllable/aircraft will make its attacks from the altitude. If the altitude is too low or too high to use weapon aircraft/controllable will choose closest altitude to the desired attack start altitude. If the desired altitude is defined controllable/aircraft will not attack from safe altitude. -- @param #boolean AttackQtyLimit (optional) The flag determines how to interpret attackQty parameter. If the flag is true then attackQty is a limit on maximal attack quantity for "AttackGroup" and "AttackUnit" tasks. If the flag is false then attackQty is a desired attack quantity for "Bombing" and "BombingRunway" tasks. +-- @param #boolean GroupAttack (Optional) If true, attack as group. -- @return DCS#Task The DCS task structure. -function CONTROLLABLE:TaskAttackGroup( AttackGroup, WeaponType, WeaponExpend, AttackQty, Direction, Altitude, AttackQtyLimit ) - self:F2( { self.ControllableName, AttackGroup, WeaponType, WeaponExpend, AttackQty, Direction, Altitude, AttackQtyLimit } ) +function CONTROLLABLE:TaskAttackGroup( AttackGroup, WeaponType, WeaponExpend, AttackQty, Direction, Altitude, AttackQtyLimit, GroupAttack ) + --self:F2( { self.ControllableName, AttackGroup, WeaponType, WeaponExpend, AttackQty, Direction, Altitude, AttackQtyLimit } ) -- AttackGroup = { -- id = 'AttackGroup', @@ -868,15 +880,15 @@ function CONTROLLABLE:TaskAttackGroup( AttackGroup, WeaponType, WeaponExpend, At weaponType = WeaponType or 1073741822, expend = WeaponExpend or "Auto", attackQtyLimit = AttackQty and true or false, - attackQty = AttackQty, + attackQty = AttackQty or 1, directionEnabled = Direction and true or false, - direction = Direction and math.rad(Direction) or nil, + direction = Direction and math.rad(Direction) or 0, altitudeEnabled = Altitude and true or false, altitude = Altitude, + groupAttack = GroupAttack and true or false, }, - }, + } - self:T3( { DCSTask } ) return DCSTask end @@ -891,17 +903,15 @@ end -- @param #number WeaponType (optional) The WeaponType. See [DCS Enumerator Weapon Type](https://wiki.hoggitworld.com/view/DCS_enum_weapon_flag) on Hoggit. -- @return DCS#Task The DCS task structure. function CONTROLLABLE:TaskAttackUnit(AttackUnit, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, WeaponType) - self:F2({self.ControllableName, AttackUnit, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, WeaponType}) - local DCSTask - DCSTask = { + local DCSTask = { id = 'AttackUnit', params = { unitId = AttackUnit:GetID(), groupAttack = GroupAttack and GroupAttack or false, expend = WeaponExpend or "Auto", directionEnabled = Direction and true or false, - direction = Direction and math.rad(Direction) or nil, + direction = Direction and math.rad(Direction) or 0, altitudeEnabled = Altitude and true or false, altitude = Altitude, attackQtyLimit = AttackQty and true or false, @@ -909,9 +919,7 @@ function CONTROLLABLE:TaskAttackUnit(AttackUnit, GroupAttack, WeaponExpend, Atta weaponType = WeaponType or 1073741822, } } - - self:T3( DCSTask ) - + return DCSTask end @@ -928,16 +936,8 @@ end -- @param #boolean Divebomb (optional) Perform dive bombing. Default false. -- @return DCS#Task The DCS task structure. function CONTROLLABLE:TaskBombing( Vec2, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, WeaponType, Divebomb ) - self:F( { self.ControllableName, Vec2, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, WeaponType, Divebomb } ) - local _attacktype=nil - if Divebomb then - _attacktype="Dive" - end - - - local DCSTask - DCSTask = { + local DCSTask = { id = 'Bombing', params = { point = Vec2, @@ -946,17 +946,16 @@ function CONTROLLABLE:TaskBombing( Vec2, GroupAttack, WeaponExpend, AttackQty, D groupAttack = GroupAttack and GroupAttack or false, expend = WeaponExpend or "Auto", attackQtyLimit = AttackQty and true or false, - attackQty = AttackQty, + attackQty = AttackQty or 1, directionEnabled = Direction and true or false, - direction = Direction and math.rad(Direction) or nil, + direction = Direction and math.rad(Direction) or 0, altitudeEnabled = Altitude and true or false, - altitude = Altitude, + altitude = Altitude or 2000, weaponType = WeaponType or 1073741822, - attackType = _attacktype, + attackType = Divebomb and "Dive" or nil, }, } - self:F( { TaskBombing=DCSTask } ) return DCSTask end @@ -971,10 +970,8 @@ end -- @param #number WeaponType (Optional) The WeaponType. Default Auto=1073741822. -- @return DCS#Task The DCS task structure. function CONTROLLABLE:TaskAttackMapObject( Vec2, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, WeaponType ) - self:F2( { self.ControllableName, Vec2, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, WeaponType } ) - local DCSTask - DCSTask = { + local DCSTask = { id = 'AttackMapObject', params = { point = Vec2, @@ -985,14 +982,13 @@ function CONTROLLABLE:TaskAttackMapObject( Vec2, GroupAttack, WeaponExpend, Atta attackQtyLimit = AttackQty and true or false, attackQty = AttackQty, directionEnabled = Direction and true or false, - direction = Direction, + direction = Direction and math.rad(Direction) or 0, altitudeEnabled = Altitude and true or false, altitude = Altitude, weaponType = WeaponType or 1073741822, }, - }, + } - self:T3( { DCSTask } ) return DCSTask end @@ -1009,7 +1005,6 @@ end -- @param #number CarpetLength (optional) default to 500 m. -- @return DCS#Task The DCS task structure. function CONTROLLABLE:TaskCarpetBombing(Vec2, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, WeaponType, CarpetLength) - self:F2( { self.ControllableName, Vec2, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, WeaponType, CarpetLength } ) -- Build Task Structure local DCSTask = { @@ -1026,7 +1021,7 @@ function CONTROLLABLE:TaskCarpetBombing(Vec2, GroupAttack, WeaponExpend, AttackQ attackQtyLimit = AttackQty and true or false, attackQty = AttackQty, directionEnabled = Direction and true or false, - direction = Direction and math.rad(Direction) or nil, + direction = Direction and math.rad(Direction) or 0, altitudeEnabled = Altitude and true or false, altitude = Altitude, } @@ -1064,9 +1059,9 @@ end --- (AIR) Move the controllable to a Vec2 Point, wait for a defined duration and embark a controllable. -- @param #CONTROLLABLE self -- @param DCS#Vec2 Vec2 The point where to wait. Needs to have x and y components. --- @param Core.Set#SET_GROUP GroupSetForEmparking Set of groups to embark. +-- @param Core.Set#SET_GROUP GroupSetForEmbarking Set of groups to embark. -- @param #number Duration (Optional) The maximum duration in seconds to wait until all groups have embarked. --- @param Core.Set#SET_GROUP (Optional) DistributionGroupSet Set of groups identifying the groups needing to board specific helicopters. +-- @param Core.Set#SET_GROUP DistributionGroupSet (Optional) Set of groups identifying the groups needing to board specific helicopters. -- @return DCS#Task The DCS task structure. function CONTROLLABLE:TaskEmbarking(Vec2, GroupSetForEmbarking, Duration, DistributionGroupSet) @@ -1107,7 +1102,6 @@ function CONTROLLABLE:TaskEmbarking(Vec2, GroupSetForEmbarking, Duration, Distri } } - self:T3( { DCSTask } ) return DCSTask end @@ -1218,7 +1212,6 @@ end -- @param #boolean GroupAttack (optional) Flag indicates that the target must be engaged by all aircrafts of the controllable. Has effect only if the task is assigned to a group and not to a single aircraft. -- @return DCS#Task The DCS task structure. function CONTROLLABLE:TaskBombingRunway(Airbase, WeaponType, WeaponExpend, AttackQty, Direction, GroupAttack) - self:F2( { self.ControllableName, Airbase, WeaponType, WeaponExpend, AttackQty, Direction, GroupAttack } ) local DCSTask = { id = 'BombingRunway', @@ -1227,8 +1220,8 @@ function CONTROLLABLE:TaskBombingRunway(Airbase, WeaponType, WeaponExpend, Attac weaponType = WeaponType or ENUMS.WeaponFlag.AnyBomb, expend = WeaponExpend or AI.Task.WeaponExpend.ALL, attackQty = AttackQty or 1, - direction = Direction and math.rad(Direction) or nil, - groupAttack = GroupAttack and GroupAttack or false, + direction = Direction and math.rad(Direction) or 0, + groupAttack = GroupAttack and true or false, }, } @@ -1241,7 +1234,10 @@ end -- @return DCS#Task The DCS task structure. function CONTROLLABLE:TaskRefueling() - local DCSTask={id='Refueling', params={}} + local DCSTask={ + id='Refueling', + params={} + } return DCSTask end @@ -1249,7 +1245,7 @@ end --- (AIR HELICOPTER) Landing at the ground. For helicopters only. -- @param #CONTROLLABLE self --- @param DCS#Vec2 Point The point where to land. +-- @param DCS#Vec2 Vec2 The point where to land. -- @param #number Duration The duration in seconds to stay on the ground. -- @return #CONTROLLABLE self function CONTROLLABLE:TaskLandAtVec2(Vec2, Duration) @@ -1262,6 +1258,7 @@ function CONTROLLABLE:TaskLandAtVec2(Vec2, Duration) duration = Duration, }, } + return DCSTask end @@ -1271,18 +1268,12 @@ end -- @param #number Duration The duration in seconds to stay on the ground. -- @return #CONTROLLABLE self function CONTROLLABLE:TaskLandAtZone( Zone, Duration, RandomPoint ) - self:F2( { self.ControllableName, Zone, Duration, RandomPoint } ) - local Point - if RandomPoint then - Point = Zone:GetRandomVec2() - else - Point = Zone:GetVec2() - end + -- Get landing point + local Point=RandomPoint and Zone:GetRandomVec2() or Zone:GetVec2() - local DCSTask = self:TaskLandAtVec2( Point, Duration ) + local DCSTask = CONTROLLABLE.TaskLandAtVec2( self, Point, Duration ) - self:T3( DCSTask ) return DCSTask end @@ -1343,7 +1334,6 @@ end -- @param DCS#AttributeNameArray TargetTypes Array of AttributeName that is contains threat categories allowed to engage. Default {"Air"}. -- @return DCS#Task The DCS task structure. function CONTROLLABLE:TaskEscort( FollowControllable, Vec3, LastWaypointIndex, EngagementDistance, TargetTypes ) - self:F2( { self.ControllableName, FollowControllable, Vec3, LastWaypointIndex, EngagementDistance, TargetTypes } ) -- Escort = { -- id = 'Escort', @@ -1368,9 +1358,8 @@ function CONTROLLABLE:TaskEscort( FollowControllable, Vec3, LastWaypointIndex, E engagementDistMax = EngagementDistance, targetTypes = TargetTypes or {"Air"}, }, - }, + } - self:T3( { DCSTask } ) return DCSTask end @@ -1385,7 +1374,6 @@ end -- @param #number WeaponType (optional) Enum for weapon type ID. This value is only required if you want the group firing to use a specific weapon, for instance using the task on a ship to force it to fire guided missiles at targets within cannon range. See http://wiki.hoggit.us/view/DCS_enum_weapon_flag -- @return DCS#Task The DCS task structure. function CONTROLLABLE:TaskFireAtPoint( Vec2, Radius, AmmoCount, WeaponType ) - self:F2( { self.ControllableName, Vec2, Radius, AmmoCount, WeaponType } ) -- FireAtPoint = { -- id = 'FireAtPoint', @@ -1397,13 +1385,12 @@ function CONTROLLABLE:TaskFireAtPoint( Vec2, Radius, AmmoCount, WeaponType ) -- } -- } - local DCSTask - DCSTask = { + local DCSTask = { id = 'FireAtPoint', params = { - point = Vec2, - zoneRadius = Radius, - expendQty = 100, -- dummy value + point = Vec2, + zoneRadius = Radius, + expendQty = 100, -- dummy value expendQtyEnabled = false, } } @@ -1436,13 +1423,16 @@ end -- The killer is player-controlled allied CAS-aircraft that is in contact with the FAC. -- If the task is assigned to the controllable lead unit will be a FAC. -- @param #CONTROLLABLE self --- @param Wrapper.Controllable#CONTROLLABLE AttackGroup Target CONTROLLABLE. --- @param #number WeaponType Bitmask of weapon types those allowed to use. If parameter is not defined that means no limits on weapon usage. --- @param DCS#AI.Task.Designation Designation (optional) Designation type. --- @param #boolean Datalink (optional) Allows to use datalink to send the target information to attack aircraft. Enabled by default. +-- @param Wrapper.Group#GROUP AttackGroup Target GROUP object. +-- @param #number WeaponType Bitmask of weapon types, which are allowed to use. +-- @param DCS#AI.Task.Designation Designation (Optional) Designation type. +-- @param #boolean Datalink (Optional) Allows to use datalink to send the target information to attack aircraft. Enabled by default. +-- @param #number Frequency Frequency used to communicate with the FAC. +-- @param #number Modulation Modulation of radio for communication. +-- @param #number CallsignName Callsign enumerator name of the FAC. +-- @param #number CallsignNumber Callsign number, e.g. Axeman-**1**. -- @return DCS#Task The DCS task structure. -function CONTROLLABLE:TaskFAC_AttackGroup( AttackGroup, WeaponType, Designation, Datalink ) - self:F2( { self.ControllableName, AttackGroup, WeaponType, Designation, Datalink } ) +function CONTROLLABLE:TaskFAC_AttackGroup( AttackGroup, WeaponType, Designation, Datalink, Frequency, Modulation, CallsignName, CallsignNumber ) local DCSTask = { id = 'FAC_AttackGroup', @@ -1451,10 +1441,13 @@ function CONTROLLABLE:TaskFAC_AttackGroup( AttackGroup, WeaponType, Designation, weaponType = WeaponType, designation = Designation, datalink = Datalink, + frequency = Frequency, + modulation = Modulation, + callname = CallsignName, + number = CallsignNumber, } } - self:T3( { DCSTask } ) return DCSTask end @@ -1467,7 +1460,6 @@ end -- @param #number Priority All enroute tasks have the priority parameter. This is a number (less value - higher priority) that determines actions related to what task will be performed first. Default 0. -- @return DCS#Task The DCS task structure. function CONTROLLABLE:EnRouteTaskEngageTargets( Distance, TargetTypes, Priority ) - self:F2( { self.ControllableName, Distance, TargetTypes, Priority } ) local DCSTask = { id = 'EngageTargets', @@ -1479,7 +1471,6 @@ function CONTROLLABLE:EnRouteTaskEngageTargets( Distance, TargetTypes, Priority } } - self:T3( { DCSTask } ) return DCSTask end @@ -1489,11 +1480,10 @@ end -- @param #CONTROLLABLE self -- @param DCS#Vec2 Vec2 2D-coordinates of the zone. -- @param DCS#Distance Radius Radius of the zone. --- @param DCS#AttributeNameArray (Optional) TargetTypes Array of target categories allowed to engage. Default {"Air"}. +-- @param DCS#AttributeNameArray TargetTypes (Optional) Array of target categories allowed to engage. Default {"Air"}. -- @param #number Priority (Optional) All en-route tasks have the priority parameter. This is a number (less value - higher priority) that determines actions related to what task will be performed first. Default 0. -- @return DCS#Task The DCS task structure. function CONTROLLABLE:EnRouteTaskEngageTargetsInZone( Vec2, Radius, TargetTypes, Priority ) - self:F2( { self.ControllableName, Vec2, Radius, TargetTypes, Priority } ) local DCSTask = { id = 'EngageTargetsInZone', @@ -1505,7 +1495,6 @@ function CONTROLLABLE:EnRouteTaskEngageTargetsInZone( Vec2, Radius, TargetTypes, } } - self:T3( { DCSTask } ) return DCSTask end @@ -1522,7 +1511,6 @@ end -- @param #boolean AttackQtyLimit (optional) The flag determines how to interpret attackQty parameter. If the flag is true then attackQty is a limit on maximal attack quantity for "AttackGroup" and "AttackUnit" tasks. If the flag is false then attackQty is a desired attack quantity for "Bombing" and "BombingRunway" tasks. -- @return DCS#Task The DCS task structure. function CONTROLLABLE:EnRouteTaskEngageGroup( AttackGroup, Priority, WeaponType, WeaponExpend, AttackQty, Direction, Altitude, AttackQtyLimit ) - self:F2( { self.ControllableName, AttackGroup, Priority, WeaponType, WeaponExpend, AttackQty, Direction, Altitude, AttackQtyLimit } ) -- EngageControllable = { -- id = 'EngageControllable ', @@ -1554,9 +1542,8 @@ function CONTROLLABLE:EnRouteTaskEngageGroup( AttackGroup, Priority, WeaponType, attackQty = AttackQty, priority = Priority or 1, }, - }, + } - self:T3( { DCSTask } ) return DCSTask end @@ -1574,7 +1561,6 @@ end -- @param #boolean ControllableAttack (optional) Flag indicates that the target must be engaged by all aircrafts of the controllable. Has effect only if the task is assigned to a controllable, not to a single aircraft. -- @return DCS#Task The DCS task structure. function CONTROLLABLE:EnRouteTaskEngageUnit( EngageUnit, Priority, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, Visible, ControllableAttack ) - self:F2( { self.ControllableName, EngageUnit, Priority, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, Visible, ControllableAttack } ) local DCSTask = { id = 'EngageUnit', @@ -1592,9 +1578,8 @@ function CONTROLLABLE:EnRouteTaskEngageUnit( EngageUnit, Priority, GroupAttack, attackQty = AttackQty, controllableAttack = ControllableAttack, }, - }, + } - self:T3( { DCSTask } ) return DCSTask end @@ -1604,11 +1589,12 @@ end -- @param #CONTROLLABLE self -- @return DCS#Task The DCS task structure. function CONTROLLABLE:EnRouteTaskAWACS( ) - self:F2( { self.ControllableName } ) - local DCSTask = {id = 'AWACS', params = {}} + local DCSTask = { + id = 'AWACS', + params = {}, + } - self:T3( { DCSTask } ) return DCSTask end @@ -1617,11 +1603,12 @@ end -- @param #CONTROLLABLE self -- @return DCS#Task The DCS task structure. function CONTROLLABLE:EnRouteTaskTanker( ) - self:F2( { self.ControllableName } ) - local DCSTask = {id = 'Tanker', params = {}} + local DCSTask = { + id = 'Tanker', + params = {}, + } - self:T3( { DCSTask } ) return DCSTask end @@ -1632,11 +1619,12 @@ end -- @param #CONTROLLABLE self -- @return DCS#Task The DCS task structure. function CONTROLLABLE:EnRouteTaskEWR( ) - self:F2( { self.ControllableName } ) - local DCSTask = {id = 'EWR', params = {}} + local DCSTask = { + id = 'EWR', + params = {}, + } - self:T3( { DCSTask } ) return DCSTask end @@ -1654,7 +1642,6 @@ end -- @param #boolean Datalink (optional) Allows to use datalink to send the target information to attack aircraft. Enabled by default. -- @return DCS#Task The DCS task structure. function CONTROLLABLE:EnRouteTaskFAC_EngageGroup( AttackGroup, Priority, WeaponType, Designation, Datalink ) - self:F2( { self.ControllableName, AttackGroup, WeaponType, Priority, Designation, Datalink } ) local DCSTask = { id = 'FAC_EngageControllable', @@ -1667,7 +1654,6 @@ function CONTROLLABLE:EnRouteTaskFAC_EngageGroup( AttackGroup, Priority, WeaponT } } - self:T3( { DCSTask } ) return DCSTask end @@ -1680,7 +1666,6 @@ end -- @param #number Priority All en-route tasks have the priority parameter. This is a number (less value - higher priority) that determines actions related to what task will be performed first. -- @return DCS#Task The DCS task structure. function CONTROLLABLE:EnRouteTaskFAC( Radius, Priority ) - self:F2( { self.ControllableName, Radius, Priority } ) -- FAC = { -- id = 'FAC', @@ -1690,15 +1675,14 @@ function CONTROLLABLE:EnRouteTaskFAC( Radius, Priority ) -- } -- } - local DCSTask - DCSTask = { id = 'FAC', + local DCSTask = { + id = 'FAC', params = { radius = Radius, priority = Priority } } - self:T3( { DCSTask } ) return DCSTask end @@ -1799,30 +1783,6 @@ function CONTROLLABLE:TaskDisembarkFromTransport(Coordinate, Radius) end ]] ---- (AIR) Move the controllable to a Vec2 Point, wait for a defined duration and embark a controllable. --- @param #CONTROLLABLE self --- @param DCS#Vec2 Point The point where to wait. --- @param #number Duration The duration in seconds to wait. --- @param #CONTROLLABLE EmbarkingControllable The controllable to be embarked. --- @return DCS#Task The DCS task structure -function CONTROLLABLE:TaskEmbarking( Point, Duration, EmbarkingControllable ) - self:F2( { self.ControllableName, Point, Duration, EmbarkingControllable.DCSControllable } ) - - local DCSTask - DCSTask = { id = 'Embarking', - params = { x = Point.x, - y = Point.y, - duration = Duration, - controllablesForEmbarking = { EmbarkingControllable.ControllableID }, - durationFlag = true, - distributionFlag = false, - distribution = {}, - } - } - - self:T3( { DCSTask } ) - return DCSTask -end --- (GROUND) Embark to a Transport landed at a location. -- Move to a defined Vec2 Point, and embark to a controllable when arrived within a defined Radius. @@ -1831,10 +1791,8 @@ end -- @param #number Radius The radius of the embarking zone around the Point. -- @return DCS#Task The DCS task structure. function CONTROLLABLE:TaskEmbarkToTransport( Point, Radius ) - self:F2( { self.ControllableName, Point, Radius } ) - local DCSTask --DCS#Task - DCSTask = { + local DCSTask = { id = 'EmbarkToTransport', params = { point = Point, @@ -1844,7 +1802,6 @@ function CONTROLLABLE:TaskEmbarkToTransport( Point, Radius ) } } - self:T3( { DCSTask } ) return DCSTask end @@ -1899,12 +1856,9 @@ end -- function CONTROLLABLE:TaskFunction( FunctionString, ... ) - local DCSTask - + -- Script local DCSScript = {} DCSScript[#DCSScript+1] = "local MissionControllable = GROUP:Find( ... ) " - --DCSScript[#DCSScript+1] = "env.info( 'TaskFunction: ' .. ( MissionControllable and MissionControllable:GetName() ) or 'No Group' )" - if arg and arg.n > 0 then local ArgumentKey = '_' .. tostring( arg ):match("table: (.*)") self:SetState( self, ArgumentKey, arg ) @@ -1914,12 +1868,10 @@ function CONTROLLABLE:TaskFunction( FunctionString, ... ) DCSScript[#DCSScript+1] = FunctionString .. "( MissionControllable )" end - DCSTask = self:TaskWrappedAction(self:CommandDoScript(table.concat( DCSScript ))) - - self:T( DCSTask ) - + -- DCS task. + local DCSTask = self:TaskWrappedAction(self:CommandDoScript(table.concat( DCSScript ))) + return DCSTask - end @@ -1929,12 +1881,12 @@ end -- @param #table TaskMission A table containing the mission task. -- @return DCS#Task function CONTROLLABLE:TaskMission( TaskMission ) - self:F2( Points ) - local DCSTask - DCSTask = { id = 'Mission', params = { TaskMission, }, } + local DCSTask = { + id = 'Mission', + params = { TaskMission, }, + } - self:T3( { DCSTask } ) return DCSTask end @@ -2995,6 +2947,51 @@ end -- Options +--- Set option. +-- @param #CONTROLLABLE self +-- @param #number OptionID ID/Type of the option. +-- @param #number OptionValue Value of the option +-- @return #CONTROLLABLE self +function CONTROLLABLE:SetOption(OptionID, OptionValue) + + local DCSControllable = self:GetDCSObject() + if DCSControllable then + local Controller = self:_GetController() + + Controller:setOption( OptionID, OptionValue ) + + return self + end + + return nil +end + +--- Set option for Rules of Engagement (ROE). +-- @param Wrapper.Controllable#CONTROLLABLE self +-- @param #number ROEvalue ROE value. See ENUMS.ROE. +-- @return Wrapper.Controllable#CONTROLLABLE self +function CONTROLLABLE:OptionROE(ROEvalue) + + local DCSControllable = self:GetDCSObject() + + if DCSControllable then + + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption(AI.Option.Air.id.ROE, ROEvalue ) + elseif self:IsGround() then + Controller:setOption(AI.Option.Ground.id.ROE, ROEvalue ) + elseif self:IsShip() then + Controller:setOption(AI.Option.Naval.id.ROE, ROEvalue ) + end + + return self + end + + return nil +end + --- Can the CONTROLLABLE hold their weapons? -- @param #CONTROLLABLE self -- @return #boolean @@ -3237,6 +3234,27 @@ function CONTROLLABLE:OptionROTNoReaction() return nil end +--- Set Reation On Threat behaviour. +-- @param #CONTROLLABLE self +-- @param #number ROTvalue ROT value. See ENUMS.ROT. +-- @return #CONTROLLABLE self +function CONTROLLABLE:OptionROT(ROTvalue) + self:F2( { self.ControllableName } ) + + local DCSControllable = self:GetDCSObject() + if DCSControllable then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, ROTvalue ) + end + + return self + end + + return nil +end + --- Can the CONTROLLABLE evade using passive defenses? -- @param #CONTROLLABLE self -- @return #boolean @@ -3515,8 +3533,76 @@ function CONTROLLABLE:OptionKeepWeaponsOnThreat() return nil end +--- Prohibit Afterburner. +-- @param #CONTROLLABLE self +-- @param #boolean Prohibit If true or nil, prohibit. If false, do not prohibit. +-- @return #CONTROLLABLE self +function CONTROLLABLE:OptionProhibitAfterburner(Prohibit) + self:F2( { self.ControllableName } ) + + if Prohibit==nil then + Prohibit=true + end + + if self:IsAir() then + self:SetOption(AI.Option.Air.id.PROHIBIT_AB, Prohibit) + end + + return self +end + +--- Defines the usage of Electronic Counter Measures by airborne forces. Disables the ability for AI to use their ECM. +-- @param #CONTROLLABLE self +-- @return #CONTROLLABLE self +function CONTROLLABLE:OptionECM_Never() + self:F2( { self.ControllableName } ) + + if self:IsAir() then + self:SetOption(AI.Option.Air.id.ECM_USING, 0) + end + + return self +end + +--- Defines the usage of Electronic Counter Measures by airborne forces. If the AI is actively being locked by an enemy radar they will enable their ECM jammer. +-- @param #CONTROLLABLE self +-- @return #CONTROLLABLE self +function CONTROLLABLE:OptionECM_OnlyLockByRadar() + self:F2( { self.ControllableName } ) + + if self:IsAir() then + self:SetOption(AI.Option.Air.id.ECM_USING, 1) + end + + return self +end +--- Defines the usage of Electronic Counter Measures by airborne forces. If the AI is being detected by a radar they will enable their ECM. +-- @param #CONTROLLABLE self +-- @return #CONTROLLABLE self +function CONTROLLABLE:OptionECM_DetectedLockByRadar() + self:F2( { self.ControllableName } ) + + if self:IsAir() then + self:SetOption(AI.Option.Air.id.ECM_USING, 2) + end + + return self +end + +--- Defines the usage of Electronic Counter Measures by airborne forces. AI will leave their ECM on all the time. +-- @param #CONTROLLABLE self +-- @return #CONTROLLABLE self +function CONTROLLABLE:OptionECM_AlwaysOn() + self:F2( { self.ControllableName } ) + + if self:IsAir() then + self:SetOption(AI.Option.Air.id.ECM_USING, 3) + end + + return self +end --- Retrieve the controllable mission and allow to place function hooks within the mission waypoint plan. -- Use the method @{Wrapper.Controllable#CONTROLLABLE:WayPointFunction} to define the hook functions for specific waypoints. diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index 484dc160b..9ac9211c2 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -440,9 +440,16 @@ function GROUP:Destroy( GenerateEvent, delay ) end ---- Returns category of the DCS Group. +--- Returns category of the DCS Group. Returns one of +-- +-- * Group.Category.AIRPLANE +-- * Group.Category.HELICOPTER +-- * Group.Category.GROUND +-- * Group.Category.SHIP +-- * Group.Category.TRAIN +-- -- @param #GROUP self --- @return DCS#Group.Category The category ID +-- @return DCS#Group.Category The category ID. function GROUP:GetCategory() self:F2( self.GroupName ) @@ -458,7 +465,7 @@ end --- Returns the category name of the #GROUP. -- @param #GROUP self --- @return #string Category name = Helicopter, Airplane, Ground Unit, Ship +-- @return #string Category name = Helicopter, Airplane, Ground Unit, Ship, Train. function GROUP:GetCategoryName() self:F2( self.GroupName ) @@ -469,6 +476,7 @@ function GROUP:GetCategoryName() [Group.Category.HELICOPTER] = "Helicopter", [Group.Category.GROUND] = "Ground Unit", [Group.Category.SHIP] = "Ship", + [Group.Category.TRAIN] = "Train", } local GroupCategory = DCSGroup:getCategory() self:T3( GroupCategory ) @@ -867,10 +875,15 @@ end --- Activates a late activated GROUP. -- @param #GROUP self +-- @param #number delay Delay in seconds, before the group is activated. -- @return #GROUP self -function GROUP:Activate() +function GROUP:Activate(delay) self:F2( { self.GroupName } ) - trigger.action.activateGroup( self:GetDCSObject() ) + if delay and delay>0 then + self:ScheduleOnce(delay, GROUP.Activate, self) + else + trigger.action.activateGroup( self:GetDCSObject() ) + end return self end diff --git a/Moose Development/Moose/Wrapper/Identifiable.lua b/Moose Development/Moose/Wrapper/Identifiable.lua index 7943fe049..5b340aec8 100644 --- a/Moose Development/Moose/Wrapper/Identifiable.lua +++ b/Moose Development/Moose/Wrapper/Identifiable.lua @@ -90,7 +90,6 @@ end --- Returns the type name of the DCS Identifiable. -- @param #IDENTIFIABLE self -- @return #string The type name of the DCS Identifiable. --- @return #nil The DCS Identifiable is not existing or alive. function IDENTIFIABLE:GetTypeName() self:F2( self.IdentifiableName ) @@ -107,9 +106,17 @@ function IDENTIFIABLE:GetTypeName() end ---- Returns category of the DCS Identifiable. +--- Returns object category of the DCS Identifiable. One of +-- +-- * Object.Category.UNIT = 1 +-- * Object.Category.WEAPON = 2 +-- * Object.Category.STATIC = 3 +-- * Object.Category.BASE = 4 +-- * Object.Category.SCENERY = 5 +-- * Object.Category.Cargo = 6 +-- -- @param #IDENTIFIABLE self --- @return DCS#Object.Category The category ID +-- @return DCS#Object.Category The category ID, i.e. a number. function IDENTIFIABLE:GetCategory() self:F2( self.ObjectName ) diff --git a/Moose Development/Moose/Wrapper/Static.lua b/Moose Development/Moose/Wrapper/Static.lua index d26aca44c..64a12a98a 100644 --- a/Moose Development/Moose/Wrapper/Static.lua +++ b/Moose Development/Moose/Wrapper/Static.lua @@ -4,7 +4,7 @@ -- -- ### Author: **FlightControl** -- --- ### Contributions: +-- ### Contributions: **funkyfranky** -- -- === -- @@ -48,6 +48,10 @@ STATIC = { } +--- Register a static object. +-- @param #STATIC self +-- @param #string StaticName Name of the static object. +-- @return #STATIC self function STATIC:Register( StaticName ) local self = BASE:Inherit( self, POSITIONABLE:New( StaticName ) ) self.StaticName = StaticName @@ -71,21 +75,19 @@ end -- @param #STATIC self -- @param #string StaticName Name of the DCS **Static** as defined within the Mission Editor. -- @param #boolean RaiseError Raise an error if not found. --- @return #STATIC -function STATIC:FindByName( StaticName, RaiseError ) +-- @return #STATIC self or *nil* +function STATIC:FindByName( StaticName ) + + -- Find static in DB. local StaticFound = _DATABASE:FindStatic( StaticName ) + -- Set static name. self.StaticName = StaticName if StaticFound then - StaticFound:F3( { StaticName } ) return StaticFound end - if RaiseError == nil or RaiseError == true then - error( "STATIC not found for: " .. StaticName ) - end - return nil end diff --git a/Moose Development/Moose/Wrapper/Unit.lua b/Moose Development/Moose/Wrapper/Unit.lua index 9be25e3f8..a7b2316b9 100644 --- a/Moose Development/Moose/Wrapper/Unit.lua +++ b/Moose Development/Moose/Wrapper/Unit.lua @@ -424,9 +424,9 @@ function UNIT:GetRange() local Desc = self:GetDesc() if Desc then - local Range = Desc.range --This is in nautical miles for some reason. But should check again! + local Range = Desc.range --This is in kilometers (not meters) for some reason. But should check again! if Range then - Range=UTILS.NMToMeters(Range) + Range=Range*1000 -- convert to meters. else Range=10000000 --10.000 km if no range end @@ -436,6 +436,64 @@ function UNIT:GetRange() return nil end +--- Check if the unit is refuelable. Also retrieves the refuelling system (boom or probe) if applicable. +-- @param #UNIT self +-- @return #boolean If true, unit is refuelable (checks for the attribute "Refuelable"). +-- @return #number Refueling system (if any): 0=boom, 1=probe. +function UNIT:IsRefuelable() + self:F2( self.UnitName ) + + local refuelable=self:HasAttribute("Refuelable") + + local system=nil + + local Desc=self:GetDesc() + if Desc and Desc.tankerType then + system=Desc.tankerType + end + + return refuelable, system +end + +--- Check if the unit is a tanker. Also retrieves the refuelling system (boom or probe) if applicable. +-- @param #UNIT self +-- @return #boolean If true, unit is refuelable (checks for the attribute "Refuelable"). +-- @return #number Refueling system (if any): 0=boom, 1=probe. +function UNIT:IsTanker() + self:F2( self.UnitName ) + + local tanker=self:HasAttribute("Tankers") + + local system=nil + + if tanker then + + local Desc=self:GetDesc() + if Desc and Desc.tankerType then + system=Desc.tankerType + end + + local typename=self:GetTypeName() + + -- Some hard coded data as this is not in the descriptors... + if typename=="IL-78M" then + system=1 --probe + elseif typename=="KC130" then + system=1 --probe + elseif typename=="KC135BDA" then + system=1 --probe + elseif typename=="KC135MPRS" then + system=1 --probe + elseif typename=="S-3B Tanker" then + system=1 --probe + end + + end + + return tanker, system +end + + --- Returns the unit's group if it exist and nil otherwise. -- @param Wrapper.Unit#UNIT self -- @return Wrapper.Group#GROUP The Group of the Unit. @@ -756,6 +814,27 @@ function UNIT:GetDamageRelative() return 1 end +--- Returns the category of the #UNIT from descriptor. Returns one of +-- +-- * Unit.Category.AIRPLANE +-- * Unit.Category.HELICOPTER +-- * Unit.Category.GROUND_UNIT +-- * Unit.Category.SHIP +-- * Unit.Category.STRUCTURE +-- +-- @param #UNIT self +-- @return #number Unit category from `getDesc().category`. +function UNIT:GetUnitCategory() + self:F3( self.UnitName ) + + local DCSUnit = self:GetDCSObject() + if DCSUnit then + return DCSUnit:getDesc().category + end + + return nil +end + --- Returns the category name of the #UNIT. -- @param #UNIT self -- @return #string Category name = Helicopter, Airplane, Ground Unit, Ship @@ -833,7 +912,9 @@ end -- * Threat level 10: Unit is AAA. -- -- --- @param #UNIT self +-- @param #UNIT self +-- @return #number Number between 0 (low threat level) and 10 (high threat level). +-- @return #string Some text. function UNIT:GetThreatLevel()