From 155b06edc822ae894f66a2c50f45709677f476de Mon Sep 17 00:00:00 2001 From: Applevangelist <72444570+Applevangelist@users.noreply.github.com> Date: Thu, 28 Jan 2021 10:04:00 +0100 Subject: [PATCH 01/15] Update Task_A2G_Dispatcher.lua Added injection of Task Name into DetectedItem; useful when using also Designate with same Detection Object to ensure menu entries are harmonized. --- Moose Development/Moose/Tasking/Task_A2G_Dispatcher.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Moose Development/Moose/Tasking/Task_A2G_Dispatcher.lua b/Moose Development/Moose/Tasking/Task_A2G_Dispatcher.lua index 448d7f545..05bf2d11f 100644 --- a/Moose Development/Moose/Tasking/Task_A2G_Dispatcher.lua +++ b/Moose Development/Moose/Tasking/Task_A2G_Dispatcher.lua @@ -753,6 +753,7 @@ do -- TASK_A2G_DISPATCHER local TargetSetUnit = self:EvaluateSEAD( DetectedItem ) -- Returns a SetUnit if there are targets to be SEADed... if TargetSetUnit then Task = TASK_A2G_SEAD:New( Mission, self.SetGroup, string.format( "SEAD.%03d", DetectedItemID ), TargetSetUnit ) + DetectedItem.DesignateMenuName = string.format( "SEAD.%03d", DetectedItemID ) --inject a name for DESIGNATE, if using same DETECTION object Task:SetDetection( Detection, DetectedItem ) end @@ -761,6 +762,7 @@ do -- TASK_A2G_DISPATCHER local TargetSetUnit = self:EvaluateCAS( DetectedItem ) -- Returns a SetUnit if there are targets to be CASed... if TargetSetUnit then Task = TASK_A2G_CAS:New( Mission, self.SetGroup, string.format( "CAS.%03d", DetectedItemID ), TargetSetUnit ) + DetectedItem.DesignateMenuName = string.format( "CAS.%03d", DetectedItemID ) --inject a name for DESIGNATE, if using same DETECTION object Task:SetDetection( Detection, DetectedItem ) end @@ -769,6 +771,7 @@ do -- TASK_A2G_DISPATCHER local TargetSetUnit = self:EvaluateBAI( DetectedItem, self.Mission:GetCommandCenter():GetPositionable():GetCoalition() ) -- Returns a SetUnit if there are targets to be BAIed... if TargetSetUnit then Task = TASK_A2G_BAI:New( Mission, self.SetGroup, string.format( "BAI.%03d", DetectedItemID ), TargetSetUnit ) + DetectedItem.DesignateMenuName = string.format( "BAI.%03d", DetectedItemID ) --inject a name for DESIGNATE, if using same DETECTION object Task:SetDetection( Detection, DetectedItem ) end end From c71c6c5178043a481ec9c69baed4f5677b9c05fc Mon Sep 17 00:00:00 2001 From: Applevangelist <72444570+Applevangelist@users.noreply.github.com> Date: Thu, 28 Jan 2021 10:10:39 +0100 Subject: [PATCH 02/15] Update Designate.lua Use of added injection of Task Name into DetectedItem; useful when using also Designate with same Detection Object to ensure menu entries are harmonized. --- Moose Development/Moose/Functional/Designate.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Moose Development/Moose/Functional/Designate.lua b/Moose Development/Moose/Functional/Designate.lua index a11aa21b8..72aaf9959 100644 --- a/Moose Development/Moose/Functional/Designate.lua +++ b/Moose Development/Moose/Functional/Designate.lua @@ -1001,7 +1001,13 @@ do -- DESIGNATE local ID = self.Detection:GetDetectedItemID( DetectedItem ) local MenuText = ID --.. ", " .. Coord:ToStringA2G( AttackGroup ) - MenuText = string.format( "(%3s) %s", Designating, MenuText ) + -- Use injected MenuName from TaskA2GDispatcher if using same Detection Object + if DetectedItem.DesignateMenuName then + MenuText = string.format( "(%3s) %s", Designating, DetectedItem.DesignateMenuName ) + else + MenuText = string.format( "(%3s) %s", Designating, MenuText ) + end + local DetectedMenu = MENU_GROUP_DELAYED:New( AttackGroup, MenuText, MenuDesignate ):SetTime( MenuTime ):SetTag( self.DesignateName ) -- Build the Lasing menu. From 261d1cbeba6192579268e210280079bd00c1c9ce Mon Sep 17 00:00:00 2001 From: rollnthndr Date: Fri, 29 Jan 2021 18:15:20 -0700 Subject: [PATCH 03/15] Added a note pointing out that callsigns need to be chosen depending on the type of unit that this task is being assigned to. --- Moose Development/Moose/Wrapper/Controllable.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index 595b0e473..4c527e997 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -1467,6 +1467,7 @@ end --- (AIR + GROUND) The task makes the controllable/unit a FAC and orders the FAC to control the target (enemy ground controllable) destruction. -- 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. +-- It's important to note that depending on the type of unit that is being assigned the task (AIR or GROUND), you must choose the correct type of callsign enumerator. For airborne controllables use CALLSIGN.Aircraft and for ground based use CALLSIGN.JTAC enumerators. -- @param #CONTROLLABLE self -- @param Wrapper.Group#GROUP AttackGroup Target GROUP object. -- @param #number WeaponType Bitmask of weapon types, which are allowed to use. @@ -1474,7 +1475,7 @@ end -- @param #boolean Datalink (Optional) Allows to use datalink to send the target information to attack aircraft. Enabled by default. -- @param #number Frequency Frequency in MHz used to communicate with the FAC. Default 133 MHz. -- @param #number Modulation Modulation of radio for communication. Default 0=AM. --- @param #number CallsignName Callsign enumerator name of the FAC. +-- @param #number CallsignName Callsign enumerator name of the FAC. (CALLSIGN.Aircraft.{name} for airborne controllables, CALLSIGN.JTACS.{name} for ground units) -- @param #number CallsignNumber Callsign number, e.g. Axeman-**1**. -- @return DCS#Task The DCS task structure. function CONTROLLABLE:TaskFAC_AttackGroup( AttackGroup, WeaponType, Designation, Datalink, Frequency, Modulation, CallsignName, CallsignNumber ) From 50d2e42cc30bac2e3687ea1138507aba09bcee72 Mon Sep 17 00:00:00 2001 From: rollnthndr Date: Fri, 29 Jan 2021 18:31:19 -0700 Subject: [PATCH 04/15] Added VSCode settings folder and workspace file to the ignore list. --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index 5e42c0c93..96ee72d9a 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,13 @@ local.properties .buildpath +##################### +## Visual Studio Code +##################### +*.code-workspace +.vscode/ + + ################# ## Visual Studio ################# From 1daa2857b2283dfd52237d6896b628197417bc14 Mon Sep 17 00:00:00 2001 From: Applevangelist <72444570+Applevangelist@users.noreply.github.com> Date: Wed, 10 Feb 2021 13:19:53 +0100 Subject: [PATCH 05/15] Update Auftrag.lua Corrected docu in NewTanker, 1 is actually boom, and 0 probe --- Moose Development/Moose/Ops/Auftrag.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index 7a952cba8..f285e461d 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -688,7 +688,7 @@ end -- @param #number Speed Orbit speed in knots. Default 350 kts. -- @param #number Heading Heading of race-track pattern in degrees. Default 270 (East to West). -- @param #number Leg Length of race-track in NM. Default 10 NM. --- @param #number RefuelSystem Refueling system (0=boom, 1=probe). This info is *only* for AIRWINGs so they launch the right tanker type. +-- @param #number RefuelSystem Refueling system (1=boom, 0=probe). This info is *only* for AIRWINGs so they launch the right tanker type. -- @return #AUFTRAG self function AUFTRAG:NewTANKER(Coordinate, Altitude, Speed, Heading, Leg, RefuelSystem) From e8bfab515c87e673edca0c402f75c6107e324637 Mon Sep 17 00:00:00 2001 From: Applevangelist <72444570+Applevangelist@users.noreply.github.com> Date: Tue, 16 Feb 2021 16:13:10 +0100 Subject: [PATCH 06/15] Integrate option for Shorad in Mantis Also, correct some documentation errors --- Moose Development/Moose/Functional/Mantis.lua | 55 ++++++++++++++++--- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/Moose Development/Moose/Functional/Mantis.lua b/Moose Development/Moose/Functional/Mantis.lua index a06b5ccc2..17e6b9524 100644 --- a/Moose Development/Moose/Functional/Mantis.lua +++ b/Moose Development/Moose/Functional/Mantis.lua @@ -24,14 +24,14 @@ ------------------------------------------------------------------------- --- **MANTIS** class, extends @{#Core.Base#BASE} --- @type MANTIS #MANTIS +-- @type MANTIS -- @field #string Classname -- @field #string name Name of this Mantis --- @field #string SAM_Templates_Prefix Prefix to build the #GROUP_SET for SAM sites --- @field @{#Core.Set#GROUP_SET} SAM_Group The SAM #GROUP_SET --- @field #string EWR_Templates_Prefix Prefix to build the #GROUP_SET for EWR group --- @field @{#Core.Set#GROUP_SET} EWR_Group The EWR #GROUP_SET --- @field @{#Core.Set#GROUP_SET} Adv_EWR_Group The EWR #GROUP_SET used for advanced mode +-- @field #string SAM_Templates_Prefix Prefix to build the #SET_GROUP for SAM sites +-- @field @{#Core.Set#SET_GROUP} SAM_Group The SAM #SET_GROUP +-- @field #string EWR_Templates_Prefix Prefix to build the #SET_GROUP for EWR group +-- @field @{#Core.Set#SET_GROUP} EWR_Group The EWR #SET_GROUP +-- @field @{#Core.Set#SET_GROUP} Adv_EWR_Group The EWR #SET_GROUP used for advanced mode -- @field #string HQ_Template_CC The ME name of the HQ object -- @field @{#Wrapper.Group#GROUP} HQ_CC The #GROUP object of the HQ -- @field #table SAM_Table Table of SAM sites @@ -51,6 +51,9 @@ -- @field #number adv_state Advanced mode state tracker -- @field #boolean advAwacs Boolean switch to use Awacs as a separate detection stream -- @field #number awacsrange Detection range of an optional Awacs unit +-- @field @{#Functional.Shorad#SHORAD} Shorad SHORAD Object, if available +-- @field #boolean ShoradLink If true, #MANTIS has #SHORAD enabled +-- @field #number ShoradTime Timer in seconds, how long #SHORAD will be active after a detection inside of the defense range -- @extends @{#Core.Base#BASE} @@ -163,7 +166,10 @@ MANTIS = { AWACS_Prefix = "", advAwacs = false, verbose = false, - awacsrange = 250000 + awacsrange = 250000, + Shorad = nil, + ShoradLink = false, + ShoradTime = 600, } ----------------------------------------------------------------------- @@ -230,6 +236,9 @@ do self.Adv_EWR_Group = nil self.AWACS_Prefix = awacs or nil self.awacsrange = 250000 --TODO: 250km, User Function to change + self.Shorad = nil + self.ShoradLink = false + self.ShoradTime = 600 if type(awacs) == "string" then self.advAwacs = true else @@ -709,6 +718,27 @@ do return self end + --- Function to link up #MANTIS with a #SHORAD installation + -- @param #MANTIS self + -- @param Functional.Shorad#SHORAD Shorad The #SHORAD object + -- @param #number Shoradtime Number of seconds #SHORAD stays active post wake-up + function MANTIS:AddShorad(Shorad,Shoradtime) + local Shorad = Shorad or nil + local ShoradTime = Shoradtime or 600 + local ShoradLink = true + if Shorad:IsInstanceOf("SHORAD") then + self.ShoradLink = ShoradLink + self.Shorad = Shorad --#SHORAD + self.ShoradTime = Shoradtime -- #number + end + end + + --- Function to unlink #MANTIS from a #SHORAD installation + -- @param #MANTIS self + function MANTIS:RemoveShorad() + self.ShoradLink = false + end + ----------------------------------------------------------------------- -- MANTIS main functions ----------------------------------------------------------------------- @@ -743,8 +773,15 @@ do if samgroup:IsAlive() then -- switch off SAM samgroup:OptionAlarmStateRed() - --samgroup:OptionROEWeaponFree() - --samgroup:SetAIOn() + -- link in to SHORAD if available + -- TODO Test integration + if self.ShoradLink then + local Shorad = self.Shorad + local radius = self.checkradius + local ontime = self.ShoradTime + Shorad:WakeUpShorad(name, radius, ontime) + end + -- debug output local text = string.format("SAM %s switched to alarm state RED!", name) local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug) if self.verbose then env.info(self.lid..text) end From c0e58e9c929d6b623e471237a6df858574e8c930 Mon Sep 17 00:00:00 2001 From: Applevangelist <72444570+Applevangelist@users.noreply.github.com> Date: Tue, 16 Feb 2021 16:14:53 +0100 Subject: [PATCH 07/15] Update Sead.lua Handle new shortened weapon names in DCS, make handling more graceful --- Moose Development/Moose/Functional/Sead.lua | 63 ++++++++++++++++++--- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/Moose Development/Moose/Functional/Sead.lua b/Moose Development/Moose/Functional/Sead.lua index f7e591897..2c5abb451 100644 --- a/Moose Development/Moose/Functional/Sead.lua +++ b/Moose Development/Moose/Functional/Sead.lua @@ -17,7 +17,7 @@ -- -- ### Authors: **FlightControl**, **applevangelist** -- --- Last Update: Dec 2020 +-- Last Update: Feb 2021 -- -- === -- @@ -51,9 +51,44 @@ SEAD = { EngagementRange = 75 -- default 75% engagement range Feature Request #1355 } + -- TODO Complete list? + --- Missile enumerators + -- @field Harms + SEAD.Harms = { + --[[ + ["X58"] = "weapons.missiles.X_58", --Kh-58X anti-radiation missiles fired + ["Kh25"] = "weapons.missiles.Kh25MP_PRGS1VP", --Kh-25MP anti-radiation missiles fired + ["X25"] = "weapons.missiles.X_25MP", --Kh-25MPU anti-radiation missiles fired + ["X28"] = "weapons.missiles.X_28", --Kh-28 anti-radiation missiles fired + ["X31"] = "weapons.missiles.X_31P", --Kh-31P anti-radiation missiles fired + ["AGM45A"] = "weapons.missiles.AGM_45A", --AGM-45A anti-radiation missiles fired + ["AGM45"] = "weapons.missiles.AGM_45", --AGM-45B anti-radiation missiles fired + ["AGM88"] = "weapons.missiles.AGM_88", --AGM-88C anti-radiation missiles fired + ["AGM122"] = "weapons.missiles.AGM_122", --AGM-122 Sidearm anti-radiation missiles fired + ["LD10"] = "weapons.missiles.LD-10", --LD-10 anti-radiation missiles fired + ["ALARM"] = "weapons.missiles.ALARM", --ALARM anti-radiation missiles fired + ["AGM84E"] = "weapons.missiles.AGM_84E", --AGM84 anti-radiation missiles fired + ["AGM84A"] = "weapons.missiles.AGM_84A", --AGM84 anti-radiation missiles fired + ["AGM84H"] = "weapons.missiles.AGM_84H", --AGM84 anti-radiation missiles fired + --]] + ["AGM_88"] = "AGM_88", + ["AGM_45"] = "AGM_45", + ["AGM_122"] = "AGM_122", + ["AGM_84"] = "AGM_84", + ["AGM_45"] = "AGM_45", + ["ALARN"] = "ALARM", + ["LD-10"] = "LD-10", + ["X_58"] = "X_58", + ["X_28"] = "X_28", + ["X_25"] = "X_25", + ["X_31"] = "X_31", + ["Kh25"] = "Kh25", + } + --- Creates the main object which is handling defensive actions for SA sites or moving SA vehicles. -- When an anti radiation missile is fired (KH-58, KH-31P, KH-31A, KH-25MPU, HARM missiles), the SA will shut down their radars and will take evasive actions... -- Chances are big that the missile will miss. +-- @param #SEAD self -- @param table{string,...}|string SEADGroupPrefixes which is a table of Prefixes of the SA Groups in the DCS mission editor on which evasive actions need to be taken. -- @return SEAD -- @usage @@ -74,7 +109,7 @@ function SEAD:New( SEADGroupPrefixes ) end self:HandleEvent( EVENTS.Shot ) - self:I("*** SEAD - Started Version 0.2.2") + self:I("*** SEAD - Started Version 0.2.5") return self end @@ -112,7 +147,20 @@ function SEAD:SetEngagementRange(range) return self end ---- Detects if an SA site was shot with an anti radiation missile. In this case, take evasive actions based on the skill level set within the ME. + --- Check if a known HARM was fired + -- @param #SEAD self + -- @param #string WeaponName + -- @return #boolean Returns true for a match + function SEAD:_CheckHarms(WeaponName) + self:F( { WeaponName } ) + local hit = false + for _,_name in pairs (SEAD.Harms) do + if string.find(WeaponName,_name,1) then hit = true end + end + return hit + end + +--- Detects if an SAM site was shot with an anti radiation missile. In this case, take evasive actions based on the skill level set within the ME. -- @see SEAD -- @param #SEAD -- @param Core.Event#EVENTDATA EventData @@ -127,7 +175,7 @@ function SEAD:OnEventShot( EventData ) self:T( "*** SEAD - Missile Launched = " .. SEADWeaponName) self:T({ SEADWeapon }) - --check for SEAD missiles + --[[check for SEAD missiles if SEADWeaponName == "weapons.missiles.X_58" --Kh-58U anti-radiation missiles fired or SEADWeaponName == "weapons.missiles.Kh25MP_PRGS1VP" --Kh-25MP anti-radiation missiles fired @@ -155,12 +203,13 @@ function SEAD:OnEventShot( EventData ) SEADWeaponName == "weapons.missiles.AGM_84A" --AGM84 anti-radiation missiles fired or SEADWeaponName == "weapons.missiles.AGM_84H" --AGM84 anti-radiation missiles fired - then - + --]] + if self:_CheckHarms(SEADWeaponName) then + local _evade = math.random (1,100) -- random number for chance of evading action local _targetMim = EventData.Weapon:getTarget() -- Identify target local _targetMimname = Unit.getName(_targetMim) -- Unit name - local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon)) --targeted grouo + local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon)) --targeted group local _targetMimgroupName = _targetMimgroup:getName() -- group name local _targetskill = _DATABASE.Templates.Units[_targetMimname].Template.skill self:T( self.SEADGroupPrefixes ) From 154cc9fbebb6ef12eb352f6113d30cabcfe1a9aa Mon Sep 17 00:00:00 2001 From: Applevangelist <72444570+Applevangelist@users.noreply.github.com> Date: Tue, 16 Feb 2021 16:25:22 +0100 Subject: [PATCH 08/15] Shorad.lua - Initial release :) --- Moose Development/Moose/Functional/Shorad.lua | 457 ++++++++++++++++++ 1 file changed, 457 insertions(+) create mode 100644 Moose Development/Moose/Functional/Shorad.lua diff --git a/Moose Development/Moose/Functional/Shorad.lua b/Moose Development/Moose/Functional/Shorad.lua new file mode 100644 index 000000000..098bf70c9 --- /dev/null +++ b/Moose Development/Moose/Functional/Shorad.lua @@ -0,0 +1,457 @@ +--- **Functional** -- Short Range Air Defense System +-- +-- === +-- +-- **SHORAD** - Short Range Air Defense System +-- Controls a network of short range AAA groups. Uses events to detect a missile attack +-- +-- === +-- +-- ## Missions: +-- +-- ### [SHORAD - Short Range Air Defense](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/tbd) +-- +-- === +-- +-- ### Author : **applevangelist ** +-- +-- @module Functional.Shorad +-- @image Functional.Mantis.jpg +-- +-- Date: Feb 2021 + +------------------------------------------------------------------------- +--- **SHORAD** class, extends @{#Core.Base#BASE} +-- @type SHORAD +-- @field #string ClassName +-- @field #string name Name of this Shorad +-- @field #boolean debug Set the debug state +-- @field #string Prefixes String to be used to build the @{#Core.Set#SET_GROUP} +-- @field #number Radius Shorad defense radius in meters +-- @field @{#Core.Set#SET_GROUP} Groupset The set of Shorad groups +-- @field @{#Core.Set#SET_GROUP} Samset The set of SAM groups to defend +-- @field #string Coalition The coalition of this Shorad +-- @field #number ActiveTimer How long a Shorad stays active after wake-up in seconds +-- @field #table ActiveGroups Table for the timer function +-- @field #string lid The log ID for the dcs.log +-- @field #boolean DefendHarms Default true, intercept incoming HARMS +-- @field #boolean DefendMavs Default true, intercept incoming AG-Missiles +-- @field #number DefenseLowProb Default 70, minimum detection limit +-- @field #number DefenseHighProb Default 90, maximim detection limit +-- @extends Core.Base#BASE + +--- *The worst thing that can happen to a good cause is, not to be skillfully attacked, but to be ineptly defended.* - Frédéric Bastiat +-- +-- Simple Class for a more intelligent Short Range Air Defense System +-- +-- #SHORAD +-- Moose derived missile intercepting short range defense system +-- Protects a network of SAM sites. Uses events to switch on the defense groups closest to the enemy +-- Integrate with @{Functional.Mantis#MANTIS} to complete the defensive system setup. +-- +-- ## Usage +-- +-- Set up a #SET_GROUP for the SAM sites to be protected: +-- +-- `local SamSet = SET_GROUP:New():FilterPrefixes("Red SAM"):FilterCoalitions("red"):FilterStart()` +-- +-- By default, SHORAD will defense against both HARMs and AG-Missiles with short to medium range. The default defense probability is 70-90%. +-- When a missile is detected, SHORAD will activate defense groups in the given radius around the target for 10 minutes. It will *not* react to friendly fire. +-- +-- ### Start a new SHORAD system, parameters are: +-- +-- * Name: Name of this SHORAD. +-- * ShoradPrefix: Filter for the Shorad #SET_GROUP. +-- * Samset: The #SET_GROUP of SAM sites to defend. +-- * Radius: Defense radius in meters. +-- * ActiveTimer: Determines how many seconds the systems stay on red alert after wake-up call. +-- * Coalition: Coalition, i.e. "blue", "red", or "neutral".* +-- +-- `myshorad = SHORAD:New("RedShorad", "Red SHORAD", SamSet, 25000, 600, "red")` +-- +-- ## Customize options +-- +-- * SHORAD:SwitchDebug(debug) +-- * SHORAD:SwitchHARMDefense(onoff) +-- * SHORAD:SwitchAGMDefense(onoff) +-- * SHORAD:SetDefenseLimits(low,high) +-- * SHORAD:SetActiveTimer(seconds) +-- * SHORAD:SetDefenseRadius(meters) +-- * SHORAD:SetActiveTimer(seconds) +-- * SHORAD:SetDefenseRadius(meters) +-- +-- @field #SHORAD +SHORAD = { + ClassName = "SHORAD", + name = "MyShorad", + debug = false, + Prefixes = "", + Radius = 20000, + Groupset = nil, + Samset = nil, + Coalition = nil, + ActiveTimer = 600, --stay on 10 mins + ActiveGroups = {}, + lid = "", + DefendHarms = true, + DefendMavs = true, + DefenseLowProb = 70, + DefenseHighProb = 90, +} + +----------------------------------------------------------------------- +-- SHORAD System +----------------------------------------------------------------------- + +do + -- TODO Complete list? + --- Missile enumerators + -- @field Harms + SHORAD.Harms = { + --[[ + ["X58"] = "weapons.missiles.X_58", --Kh-58X anti-radiation missiles fired + ["Kh25"] = "weapons.missiles.Kh25MP_PRGS1VP", --Kh-25MP anti-radiation missiles fired + ["X25"] = "weapons.missiles.X_25MP", --Kh-25MPU anti-radiation missiles fired + ["X28"] = "weapons.missiles.X_28", --Kh-28 anti-radiation missiles fired + ["X31"] = "weapons.missiles.X_31P", --Kh-31P anti-radiation missiles fired + ["AGM45A"] = "weapons.missiles.AGM_45A", --AGM-45A anti-radiation missiles fired + ["AGM45"] = "weapons.missiles.AGM_45", --AGM-45B anti-radiation missiles fired + ["AGM88"] = "weapons.missiles.AGM_88", --AGM-88C anti-radiation missiles fired + ["AGM122"] = "weapons.missiles.AGM_122", --AGM-122 Sidearm anti-radiation missiles fired + ["LD10"] = "weapons.missiles.LD-10", --LD-10 anti-radiation missiles fired + ["ALARM"] = "weapons.missiles.ALARM", --ALARM anti-radiation missiles fired + ["AGM84E"] = "weapons.missiles.AGM_84E", --AGM84 anti-radiation missiles fired + ["AGM84A"] = "weapons.missiles.AGM_84A", --AGM84 anti-radiation missiles fired + ["AGM84H"] = "weapons.missiles.AGM_84H", --AGM84 anti-radiation missiles fired + --]] + ["AGM_88"] = "AGM_88", + ["AGM_45"] = "AGM_45", + ["AGM_122"] = "AGM_122", + ["AGM_84"] = "AGM_84", + ["AGM_45"] = "AGM_45", + ["ALARN"] = "ALARM", + ["LD-10"] = "LD-10", + ["X_58"] = "X_58", + ["X_28"] = "X_28", + ["X_25"] = "X_25", + ["X_31"] = "X_31", + ["Kh25"] = "Kh25", + } + + --- TODO complete list? + -- @field Mavs + SHORAD.Mavs = { + ["AGM"] = "AGM", + ["C-701"] = "C-701", + ["Kh25"] = "Kh25", + ["Kh29"] = "Kh29", + ["Kh31"] = "Kh31", + ["Kh66"] = "Kh66", + } + + --- Instantiates a new SHORAD object + -- @param #SHORAD self + -- @param #string Name Name of this SHORAD + -- @param #string ShoradPrefix Filter for the Shorad #SET_GROUP + -- @param Core.Set#SET_GROUP Samset The #SET_GROUP of SAM sites to defend + -- @param #number Radius Defense radius in meters, used to switch on groups + -- @param #number ActiveTimer Determines how many seconds the systems stay on red alert after wake-up call + -- @param #string Coalition Coalition, i.e. "blue", "red", or "neutral" + function SHORAD:New(Name, ShoradPrefix, Samset, Radius, ActiveTimer, Coalition) + local self = BASE:Inherit( self, BASE:New() ) + self:F({Name, ShoradPrefix, Samset, Radius, ActiveTimer, Coalition}) + + local GroupSet = SET_GROUP:New():FilterPrefixes(ShoradPrefix):FilterCoalitions(Coalition):FilterCategoryGround():FilterStart() + + self.name = Name or "MyShorad" + self.Prefixes = ShoradPrefix or "SAM SHORAD" + self.Radius = Radius or 20000 + self.Coalition = Coalition or "blue" + self.Samset = Samset or GroupSet + self.ActiveTimer = ActiveTimer or 600 + self.ActiveGroups = {} + self.Groupset = GroupSet + self:HandleEvent( EVENTS.Shot ) + self.DefendHarms = true + self.DefendMavs = true + self.DefenseLowProb = 70 -- probability to detect a missile shot, low margin + self.DefenseHighProb = 90 -- probability to detect a missile shot, high margin + self:I("*** SHORAD - Started Version 0.0.1") + -- Set the string id for output to DCS.log file. + self.lid=string.format("SHORAD %s | ", self.name) + self:_InitState() + return self + end + + --- Initially set all groups to alarm state GREEN + -- @param #SHORAD self + function SHORAD:_InitState() + local table = {} + local set = self.Groupset + self:T({set = set}) + local aliveset = set:GetAliveSet() --#table + for _,_group in pairs (aliveset) do + _group:OptionAlarmStateGreen() --Wrapper.Group#GROUP + end + -- gather entropy + for i=1,10 do + math.random() + end + end + + --- Switch debug state + -- @param #SHORAD self + -- @param #boolean debug Switch debug on (true) or off (false) + function SHORAD:SwitchDebug(debug) + self:F( { debug } ) + local onoff = debug or false + if debug then + self.debug = true + --tracing + BASE:TraceOn() + BASE:TraceClass("SHORAD") + else + self.debug = false + BASE:TraceOff() + end + end + + --- Switch defense for HARMs + -- @param #SHORAD self + -- @param #boolean onoff + function SHORAD:SwitchHARMDefense(onoff) + self:F( { onoff } ) + local onoff = onoff or true + self.DefendHarms = onoff + end + + --- Switch defense for AGMs + -- @param #SHORAD self + -- @param #boolean onoff + function SHORAD:SwitchAGMDefense(onoff) + self:F( { onoff } ) + local onoff = onoff or true + self.DefendMavs = onoff + end + + --- Set defense probability limits + -- @param #SHORAD self + -- @param #number low Minimum detection limit, integer 1-100 + -- @param #number high Maximum detection limit integer 1-100 + function SHORAD:SetDefenseLimits(low,high) + self:F( { low, high } ) + local low = low or 70 + local high = high or 90 + if (low < 0) or (low > 100) or (low > high) then + low = 70 + end + if (high < 0) or (high > 100) or (high < low ) then + high = 90 + end + self.DefenseLowProb = low + self.DefenseHighProb = high + end + + --- Set the number of seconds a SHORAD site will stay active + -- @param #SHORAD self + -- @param #number seconds Number of seconds systems stay active + function SHORAD:SetActiveTimer(seconds) + local timer = seconds or 600 + if timer < 0 then + timer = 600 + end + self.ActiveTimer = timer + end + + --- Set the number of meters for the SHORAD defense zone + -- @param #SHORAD self + -- @param #number meters Radius of the defense search zone in meters. #SHORADs in this range around a targeted group will go active + function SHORAD:SetDefenseRadius(meters) + local radius = meters or 20000 + if radius < 0 then + radius = 20000 + end + self.Radius = radius + end + + --- Check if a HARM was fired + -- @param #SHORAD self + -- @param #string WeaponName + -- @return #boolean Returns true for a match + function SHORAD:_CheckHarms(WeaponName) + self:F( { WeaponName } ) + local hit = false + if self.DefendHarms then + for _,_name in pairs (SHORAD.Harms) do + if string.find(WeaponName,_name,1) then hit = true end + end + end + return hit + end + + --- Check if a Maverick was fired + -- @param #SHORAD self + -- @param #string WeaponName + -- @return #boolean Returns true for a match + function SHORAD:_CheckMavs(WeaponName) + self:F( { WeaponName } ) + local hit = false + if self.DefendMavs then + for _,_name in pairs (SHORAD.Mavs) do + if string.find(WeaponName,_name,1) then hit = true end + end + end + return hit + end + + --- Check the coalition of the attacker + -- @param #SHORAD self + -- @param #string Coalition name + -- @return #boolean Returns false for a match + function SHORAD:_CheckCoalition(Coalition) + local owncoalition = self.Coalition + local othercoalition = "" + if Coalition == 0 then + othercoalition = "neutral" + elseif Coalition == 1 then + othercoalition = "red" + else + othercoalition = "blue" + end + self:T({owncoalition = owncoalition, othercoalition = othercoalition}) + if owncoalition ~= othercoalition then + return true + else + return false + end + end + + --- Check if the missile is aimed at a SHORAD + -- @param #SHORAD self + -- @param #string TargetGroupName Name of the target group + -- @return #boolean Returns true for a match, else false + function SHORAD:_CheckShotAtShorad(TargetGroupName) + local tgtgrp = TargetGroupName + local shorad = self.Groupset + local shoradset = shorad:GetAliveSet() --#table + local returnname = false + for _,_groups in pairs (shoradset) do + local groupname = _groups:GetName() + if string.find(groupname, tgtgrp, 1) then + returnname = true + end + end + return returnname + end + + --- Check if the missile is aimed at a SAM site + -- @param #SHORAD self + -- @param #string TargetGroupName Name of the target group + -- @return #boolean Returns true for a match, else false + function SHORAD:_CheckShotAtSams(TargetGroupName) + local tgtgrp = TargetGroupName + local shorad = self.Samset + local shoradset = shorad:GetAliveSet() --#table + local returnname = false + for _,_groups in pairs (shoradset) do + local groupname = _groups:GetName() + if string.find(groupname, tgtgrp, 1) then + returnname = true + end + end + return returnname + end + + --- Calculate if the missile shot is detected + -- @param #SHORAD self + -- @return #boolean Returns true for a detection, else false + function SHORAD:_ShotIsDetected() + local IsDetected = false + local DetectionProb = math.random(self.DefenseLowProb, self.DefenseHighProb) -- reference value + local ActualDetection = math.random(1,100) -- value for this shot + if ActualDetection <= DetectionProb then + IsDetected = true + end + return IsDetected + end + + --- Wake up #SHORADs in a zone with diameter Radius for ActiveTimer seconds + -- @param #SHORAD self + -- @param #string TargetGroup Name of the target group used to build the #ZONE + -- @param #number Radius Radius of the #ZONE + -- @param #number ActiveTimer Number of seconds to stay active + function SHORAD:WakeUpShorad(TargetGroup, Radius, ActiveTimer) + self:F({TargetGroup, Radius, ActiveTimer}) + local targetgroup = GROUP:FindByName(TargetGroup) + local targetzone = ZONE_GROUP:New("Shorad",targetgroup,Radius) -- create a defense zone to check + local groupset = self.Groupset --Core.Set#SET_GROUP + local shoradset = groupset:GetAliveSet() --#table + -- local function to switch off shorad again + local function SleepShorad(group) + local groupname = group:GetName() + self.ActiveGroups[groupname] = nil + group:OptionAlarmStateGreen() + local text = string.format("Sleeping SHORAD %s", group:GetName()) + self:T(text) + local m = MESSAGE:New(text,10,"SHORAD"):ToAllIf(self.debug) + end + -- go through set and find the one(s) to activate + for _,_group in pairs (shoradset) do + if _group:IsAnyInZone(targetzone) then + local text = string.format("Waking up SHORAD %s", _group:GetName()) + self:T(text) + local m = MESSAGE:New(text,10,"SHORAD"):ToAllIf(self.debug) + _group:OptionAlarmStateRed() + local groupname = _group:GetName() + if self.ActiveGroups[groupname] == nil then -- no timer yet for this group + self.ActiveGroups[groupname] = { Timing = ActiveTimer } + local endtime = timer.getTime() + (ActiveTimer * math.random(75,100) / 100 ) -- randomize wakeup a bit + timer.scheduleFunction(SleepShorad, _group, endtime) + end + end + end + end + + --- Main function - work on the EventData + -- @param #SHORAD self + function SHORAD:OnEventShot( EventData ) + self:F( { EventData } ) + + --local ShootingUnit = EventData.IniDCSUnit + --local ShootingUnitName = EventData.IniDCSUnitName + local ShootingWeapon = EventData.Weapon -- Identify the weapon fired + local ShootingWeaponName = EventData.WeaponName -- return weapon type + -- get detection probability + local IsDetected = self:_ShotIsDetected() + -- convert to text + local DetectedText = "false" + if IsDetected then + DetectedText = "true" + end + local text = string.format("%s Missile Launched = %s | Detected probability state is %s", self.lid, ShootingWeaponName, DetectedText) + self:T( text ) + local m = MESSAGE:New(text,15,"Info"):ToAllIf(self.debug) + -- get firing coalition + local weaponcoalition = EventData.IniGroup:GetCoalition() + if (self:_CheckHarms(ShootingWeaponName) or self:_CheckMavs(ShootingWeaponName)) and self:_CheckCoalition(weaponcoalition) and IsDetected then + -- get target data + local targetdata = EventData.Weapon:getTarget() -- Identify target + local targetunitname = Unit.getName(targetdata) -- Unit name + local targetgroup = Unit.getGroup(Weapon.getTarget(ShootingWeapon)) --targeted group + local targetgroupname = targetgroup:getName() -- group name + -- check if we or a SAM site are the target + --local TargetGroup = EventData.TgtGroup -- Wrapper.Group#GROUP + local shotatus = self:_CheckShotAtShorad(targetgroupname) --#boolean + local shotatsams = self:_CheckShotAtSams(targetgroupname) --#boolean + -- if being shot at, find closest SHORADs to activate + if shotatsams or shotatus then + self:T({shotatsams=shotatsams,shotatus=shotatus}) + self:WakeUpShorad(targetgroupname, self.Radius, self.ActiveTimer) + end + end + end +-- +end +----------------------------------------------------------------------- +-- SHORAD end +----------------------------------------------------------------------- From d4c8d5d91b7835c08eca384d5224b7aa0868261d Mon Sep 17 00:00:00 2001 From: Applevangelist <72444570+Applevangelist@users.noreply.github.com> Date: Tue, 16 Feb 2021 16:26:25 +0100 Subject: [PATCH 09/15] Include Shorad.lua --- Moose Development/Moose/Modules.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/Moose Development/Moose/Modules.lua b/Moose Development/Moose/Modules.lua index c26eb8c33..62d483052 100644 --- a/Moose Development/Moose/Modules.lua +++ b/Moose Development/Moose/Modules.lua @@ -68,6 +68,7 @@ __Moose.Include( 'Scripts/Moose/Functional/PseudoATC.lua' ) __Moose.Include( 'Scripts/Moose/Functional/Warehouse.lua' ) __Moose.Include( 'Scripts/Moose/Functional/Fox.lua' ) __Moose.Include( 'Scripts/Moose/Functional/Mantis.lua' ) +__Moose.Include( 'Scripts/Moose/Functional/Shorad.lua' ) __Moose.Include( 'Scripts/Moose/Ops/Airboss.lua' ) __Moose.Include( 'Scripts/Moose/Ops/RecoveryTanker.lua' ) From 688c57d91d1c703c2506f29df033fac3ff2714c6 Mon Sep 17 00:00:00 2001 From: Applevangelist <72444570+Applevangelist@users.noreply.github.com> Date: Tue, 16 Feb 2021 16:29:13 +0100 Subject: [PATCH 10/15] Update Moose.files --- Moose Setup/Moose.files | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Moose Setup/Moose.files b/Moose Setup/Moose.files index b5a4d5031..3e43da98e 100644 --- a/Moose Setup/Moose.files +++ b/Moose Setup/Moose.files @@ -67,7 +67,8 @@ Functional/Artillery.lua Functional/Suppression.lua Functional/PseudoATC.lua Functional/Warehouse.lua -Functional/Fox.lua +Functional/Mantis.lua +Functional/Shorad.lua Ops/Airboss.lua Ops/RecoveryTanker.lua From 798c5b292a102c65a55185ba7e1a823ee03d3d7a Mon Sep 17 00:00:00 2001 From: Applevangelist <72444570+Applevangelist@users.noreply.github.com> Date: Tue, 16 Feb 2021 16:30:46 +0100 Subject: [PATCH 11/15] Update Moose.files --- Moose Setup/Moose.files | 1 + 1 file changed, 1 insertion(+) diff --git a/Moose Setup/Moose.files b/Moose Setup/Moose.files index 3e43da98e..f64bb2ff3 100644 --- a/Moose Setup/Moose.files +++ b/Moose Setup/Moose.files @@ -67,6 +67,7 @@ Functional/Artillery.lua Functional/Suppression.lua Functional/PseudoATC.lua Functional/Warehouse.lua +Functional/Fox.lua Functional/Mantis.lua Functional/Shorad.lua From 9491b18ff40b7c64ac03a508e5f6164c4824e56a Mon Sep 17 00:00:00 2001 From: Applevangelist <72444570+Applevangelist@users.noreply.github.com> Date: Wed, 17 Feb 2021 09:13:35 +0100 Subject: [PATCH 12/15] Update Shorad.lua Own picture and quote, cleanup docs, link missions, less overhead by avoiding checks on friendly fire. --- Moose Development/Moose/Functional/Shorad.lua | 79 ++++++++++--------- 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/Moose Development/Moose/Functional/Shorad.lua b/Moose Development/Moose/Functional/Shorad.lua index 098bf70c9..7ed638f43 100644 --- a/Moose Development/Moose/Functional/Shorad.lua +++ b/Moose Development/Moose/Functional/Shorad.lua @@ -3,33 +3,33 @@ -- === -- -- **SHORAD** - Short Range Air Defense System --- Controls a network of short range AAA groups. Uses events to detect a missile attack +-- Controls a network of short range air/missile defense groups. -- -- === -- -- ## Missions: -- --- ### [SHORAD - Short Range Air Defense](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/tbd) +-- ### [SHORAD - Short Range Air Defense](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/SRD%20-%20SHORAD%20Defense) -- -- === -- -- ### Author : **applevangelist ** -- -- @module Functional.Shorad --- @image Functional.Mantis.jpg +-- @image Functional.Shorad.jpg -- -- Date: Feb 2021 ------------------------------------------------------------------------- ---- **SHORAD** class, extends @{#Core.Base#BASE} +--- **SHORAD** class, extends Core.Base#BASE -- @type SHORAD -- @field #string ClassName -- @field #string name Name of this Shorad -- @field #boolean debug Set the debug state -- @field #string Prefixes String to be used to build the @{#Core.Set#SET_GROUP} -- @field #number Radius Shorad defense radius in meters --- @field @{#Core.Set#SET_GROUP} Groupset The set of Shorad groups --- @field @{#Core.Set#SET_GROUP} Samset The set of SAM groups to defend +-- @field Core.Set#SET_GROUP Groupset The set of Shorad groups +-- @field Core.Set#SET_GROUP Samset The set of SAM groups to defend -- @field #string Coalition The coalition of this Shorad -- @field #number ActiveTimer How long a Shorad stays active after wake-up in seconds -- @field #table ActiveGroups Table for the timer function @@ -40,14 +40,14 @@ -- @field #number DefenseHighProb Default 90, maximim detection limit -- @extends Core.Base#BASE ---- *The worst thing that can happen to a good cause is, not to be skillfully attacked, but to be ineptly defended.* - Frédéric Bastiat +--- *Good friends are worth defending.* Mr Tushman, Wonder (the Movie) -- -- Simple Class for a more intelligent Short Range Air Defense System -- -- #SHORAD --- Moose derived missile intercepting short range defense system --- Protects a network of SAM sites. Uses events to switch on the defense groups closest to the enemy --- Integrate with @{Functional.Mantis#MANTIS} to complete the defensive system setup. +-- Moose derived missile intercepting short range defense system. +-- Protects a network of SAM sites. Uses events to switch on the defense groups closest to the enemy. +-- Easily integrated with @{Functional.Mantis#MANTIS} to complete the defensive system setup. -- -- ## Usage -- @@ -77,8 +77,6 @@ -- * SHORAD:SetDefenseLimits(low,high) -- * SHORAD:SetActiveTimer(seconds) -- * SHORAD:SetDefenseRadius(meters) --- * SHORAD:SetActiveTimer(seconds) --- * SHORAD:SetDefenseRadius(meters) -- -- @field #SHORAD SHORAD = { @@ -176,7 +174,7 @@ do self.DefendMavs = true self.DefenseLowProb = 70 -- probability to detect a missile shot, low margin self.DefenseHighProb = 90 -- probability to detect a missile shot, high margin - self:I("*** SHORAD - Started Version 0.0.1") + self:I("*** SHORAD - Started Version 0.0.2") -- Set the string id for output to DCS.log file. self.lid=string.format("SHORAD %s | ", self.name) self:_InitState() @@ -289,7 +287,7 @@ do return hit end - --- Check if a Maverick was fired + --- Check if an AGM was fired -- @param #SHORAD self -- @param #string WeaponName -- @return #boolean Returns true for a match @@ -380,6 +378,7 @@ do -- @param #string TargetGroup Name of the target group used to build the #ZONE -- @param #number Radius Radius of the #ZONE -- @param #number ActiveTimer Number of seconds to stay active + -- @usage Use this function to integrate with other systems. function SHORAD:WakeUpShorad(TargetGroup, Radius, ActiveTimer) self:F({TargetGroup, Radius, ActiveTimer}) local targetgroup = GROUP:FindByName(TargetGroup) @@ -414,6 +413,7 @@ do --- Main function - work on the EventData -- @param #SHORAD self + -- @param Core.Event#EVENTDATA EventData The event details table data set function SHORAD:OnEventShot( EventData ) self:F( { EventData } ) @@ -421,32 +421,35 @@ do --local ShootingUnitName = EventData.IniDCSUnitName local ShootingWeapon = EventData.Weapon -- Identify the weapon fired local ShootingWeaponName = EventData.WeaponName -- return weapon type - -- get detection probability - local IsDetected = self:_ShotIsDetected() - -- convert to text - local DetectedText = "false" - if IsDetected then - DetectedText = "true" - end - local text = string.format("%s Missile Launched = %s | Detected probability state is %s", self.lid, ShootingWeaponName, DetectedText) - self:T( text ) - local m = MESSAGE:New(text,15,"Info"):ToAllIf(self.debug) -- get firing coalition local weaponcoalition = EventData.IniGroup:GetCoalition() - if (self:_CheckHarms(ShootingWeaponName) or self:_CheckMavs(ShootingWeaponName)) and self:_CheckCoalition(weaponcoalition) and IsDetected then - -- get target data - local targetdata = EventData.Weapon:getTarget() -- Identify target - local targetunitname = Unit.getName(targetdata) -- Unit name - local targetgroup = Unit.getGroup(Weapon.getTarget(ShootingWeapon)) --targeted group - local targetgroupname = targetgroup:getName() -- group name - -- check if we or a SAM site are the target - --local TargetGroup = EventData.TgtGroup -- Wrapper.Group#GROUP - local shotatus = self:_CheckShotAtShorad(targetgroupname) --#boolean - local shotatsams = self:_CheckShotAtSams(targetgroupname) --#boolean - -- if being shot at, find closest SHORADs to activate - if shotatsams or shotatus then - self:T({shotatsams=shotatsams,shotatus=shotatus}) - self:WakeUpShorad(targetgroupname, self.Radius, self.ActiveTimer) + -- get detection probability + if self:_CheckCoalition(weaponcoalition) then --avoid overhead on friendly fire + local IsDetected = self:_ShotIsDetected() + -- convert to text + local DetectedText = "false" + if IsDetected then + DetectedText = "true" + end + local text = string.format("%s Missile Launched = %s | Detected probability state is %s", self.lid, ShootingWeaponName, DetectedText) + self:T( text ) + local m = MESSAGE:New(text,15,"Info"):ToAllIf(self.debug) + -- + if (self:_CheckHarms(ShootingWeaponName) or self:_CheckMavs(ShootingWeaponName)) and IsDetected then + -- get target data + local targetdata = EventData.Weapon:getTarget() -- Identify target + local targetunitname = Unit.getName(targetdata) -- Unit name + local targetgroup = Unit.getGroup(Weapon.getTarget(ShootingWeapon)) --targeted group + local targetgroupname = targetgroup:getName() -- group name + -- check if we or a SAM site are the target + --local TargetGroup = EventData.TgtGroup -- Wrapper.Group#GROUP + local shotatus = self:_CheckShotAtShorad(targetgroupname) --#boolean + local shotatsams = self:_CheckShotAtSams(targetgroupname) --#boolean + -- if being shot at, find closest SHORADs to activate + if shotatsams or shotatus then + self:T({shotatsams=shotatsams,shotatus=shotatus}) + self:WakeUpShorad(targetgroupname, self.Radius, self.ActiveTimer) + end end end end From 37c061bcbdbafca629526d2b61252a4e2d435a2a Mon Sep 17 00:00:00 2001 From: Applevangelist <72444570+Applevangelist@users.noreply.github.com> Date: Wed, 17 Feb 2021 09:14:56 +0100 Subject: [PATCH 13/15] Update Mantis.lua Nicefy doc output, Shorad link doc --- Moose Development/Moose/Functional/Mantis.lua | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Moose Development/Moose/Functional/Mantis.lua b/Moose Development/Moose/Functional/Mantis.lua index 17e6b9524..bc043506b 100644 --- a/Moose Development/Moose/Functional/Mantis.lua +++ b/Moose Development/Moose/Functional/Mantis.lua @@ -23,21 +23,21 @@ -- Date: Jan 2021 ------------------------------------------------------------------------- ---- **MANTIS** class, extends @{#Core.Base#BASE} +--- **MANTIS** class, extends #Core.Base#BASE -- @type MANTIS -- @field #string Classname -- @field #string name Name of this Mantis -- @field #string SAM_Templates_Prefix Prefix to build the #SET_GROUP for SAM sites --- @field @{#Core.Set#SET_GROUP} SAM_Group The SAM #SET_GROUP +-- @field Core.Set#SET_GROUP SAM_Group The SAM #SET_GROUP -- @field #string EWR_Templates_Prefix Prefix to build the #SET_GROUP for EWR group --- @field @{#Core.Set#SET_GROUP} EWR_Group The EWR #SET_GROUP --- @field @{#Core.Set#SET_GROUP} Adv_EWR_Group The EWR #SET_GROUP used for advanced mode +-- @field Core.Set#SET_GROUP EWR_Group The EWR #SET_GROUP +-- @field #Core.Set#SET_GROUP Adv_EWR_Group The EWR #SET_GROUP used for advanced mode -- @field #string HQ_Template_CC The ME name of the HQ object --- @field @{#Wrapper.Group#GROUP} HQ_CC The #GROUP object of the HQ +-- @field Wrapper.Group#GROUP HQ_CC The #GROUP object of the HQ -- @field #table SAM_Table Table of SAM sites -- @field #string lid Prefix for logging --- @field @{#Functional.Detection#DETECTION_AREAS} Detection The #DETECTION_AREAS object for EWR --- @field @{#Functional.Detection#DETECTION_AREAS} AWACS_Detection The #DETECTION_AREAS object for AWACS +-- @field Functional.Detection#DETECTION_AREAS Detection The #DETECTION_AREAS object for EWR +-- @field Functional.Detection#DETECTION_AREAS AWACS_Detection The #DETECTION_AREAS object for AWACS -- @field #boolean debug Switch on extra messages -- @field #boolean verbose Switch on extra logging -- @field #number checkradius Radius of the SAM sites @@ -51,10 +51,10 @@ -- @field #number adv_state Advanced mode state tracker -- @field #boolean advAwacs Boolean switch to use Awacs as a separate detection stream -- @field #number awacsrange Detection range of an optional Awacs unit --- @field @{#Functional.Shorad#SHORAD} Shorad SHORAD Object, if available +-- @field Functional.Shorad#SHORAD Shorad SHORAD Object, if available -- @field #boolean ShoradLink If true, #MANTIS has #SHORAD enabled -- @field #number ShoradTime Timer in seconds, how long #SHORAD will be active after a detection inside of the defense range --- @extends @{#Core.Base#BASE} +-- @extends Core.Base#BASE --- *The worst thing that can happen to a good cause is, not to be skillfully attacked, but to be ineptly defended.* - Frédéric Bastiat @@ -382,7 +382,7 @@ do --- Function to set the HQ object for further use -- @param #MANTIS self - -- @param Wrapper.GROUP#GROUP The HQ #GROUP object to be set as HQ + -- @param Wrapper.GROUP#GROUP group The #GROUP object to be set as HQ function MANTIS:SetCommandCenter(group) local group = group or nil if group ~= nil then @@ -774,7 +774,7 @@ do -- switch off SAM samgroup:OptionAlarmStateRed() -- link in to SHORAD if available - -- TODO Test integration + -- TODO Test integration fully if self.ShoradLink then local Shorad = self.Shorad local radius = self.checkradius From fb66d74ab7ef491b589f6cd449a3e3802b425fbe Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 17 Feb 2021 10:26:13 +0100 Subject: [PATCH 14/15] ENUMS - ENUMS: Added Phonetic and ISOLang by A101Wayz - Fixed CALLSIGN.JTAC.Warrior (was CALLSIGN.JTAC.Warrier) --- Moose Development/Moose/Utilities/Enums.lua | 51 ++++++++++++++++++++- Moose Development/Moose/Utilities/Utils.lua | 2 +- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/Moose Development/Moose/Utilities/Enums.lua b/Moose Development/Moose/Utilities/Enums.lua index 84712dc7a..757b67ea1 100644 --- a/Moose Development/Moose/Utilities/Enums.lua +++ b/Moose Development/Moose/Utilities/Enums.lua @@ -310,4 +310,53 @@ ENUMS.Morse.N7="- - * * *" ENUMS.Morse.N8="- - - * *" ENUMS.Morse.N9="- - - - *" ENUMS.Morse.N0="- - - - -" -ENUMS.Morse[" "]=" " \ No newline at end of file +ENUMS.Morse[" "]=" " + +--- ISO (639-1) 2-letter Language Codes. See the [Wikipedia](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). +-- +-- @type ENUMS.ISOLang +ENUMS.ISOLang = +{ + Arabic = 'AR', + Chinese = 'ZH', + English = 'EN', + French = 'FR', + German = 'DE', + Russian = 'RU', + Spanish = 'ES', + Japanese = 'JA', + Italian = 'IT', +} + +--- Phonetic Alphabet (NATO). See the [Wikipedia](https://en.wikipedia.org/wiki/NATO_phonetic_alphabet). +-- +-- @type ENUMS.Phonetic +ENUMS.Phonetic = +{ + A = 'Alpha', + B = 'Bravo', + C = 'Charlie', + D = 'Delta', + E = 'Echo', + F = 'Foxtrot', + G = 'Golf', + H = 'Hotel', + I = 'India', + J = 'Juliett', + K = 'Kilo', + L = 'Lima', + M = 'Mike', + N = 'November', + O = 'Oscar', + P = 'Papa', + Q = 'Quebec', + R = 'Romeo', + S = 'Sierra', + T = 'Tango', + U = 'Uniform', + V = 'Victor', + W = 'Whiskey', + X = 'Xray', + Y = 'Yankee', + Z = 'Zulu', +} \ No newline at end of file diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index ff42f0a47..fc2acdd9d 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -97,7 +97,7 @@ CALLSIGN={ JTAC={ Axeman=1, Darknight=2, - Warrier=3, + Warrior=3, Pointer=4, Eyeball=5, Moonbeam=6, From 6791e4d4ba6ca52bc43ce6fcb9d3187d53f3f75f Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 17 Feb 2021 13:11:18 +0100 Subject: [PATCH 15/15] Update Set.lua - Improved docs for `:FilterPrefixes()` --- Moose Development/Moose/Core/Set.lua | 66 ++++++++++++++-------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index 87bcf9e4a..c8cb5dd05 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -880,8 +880,8 @@ do -- SET_GROUP -- -- * @{#SET_GROUP.FilterCoalitions}: Builds the SET_GROUP with the groups belonging to the coalition(s). -- * @{#SET_GROUP.FilterCategories}: Builds the SET_GROUP with the groups belonging to the category(ies). - -- * @{#SET_GROUP.FilterCountries}: Builds the SET_GROUP with the gruops belonging to the country(ies). - -- * @{#SET_GROUP.FilterPrefixes}: Builds the SET_GROUP with the groups starting with the same prefix string(s). + -- * @{#SET_GROUP.FilterCountries}: Builds the SET_GROUP with the groups belonging to the country(ies). + -- * @{#SET_GROUP.FilterPrefixes}: Builds the SET_GROUP with the groups *containing* the given string in the group name. **Attention!** Bad naming convention, as this not really filtering *prefixes*. -- * @{#SET_GROUP.FilterActive}: Builds the SET_GROUP with the groups that are only active. Groups that are inactive (late activation) won't be included in the set! -- -- For the Category Filter, extra methods have been added: @@ -1241,10 +1241,10 @@ do -- SET_GROUP end - --- Builds a set of groups of defined GROUP prefixes. - -- All the groups starting with the given prefixes will be included within the set. + --- Builds a set of groups that contain the given string in their group name. + -- **Attention!** Bad naming convention as this **does not** filter only **prefixes** but all groups that **contain** the string. -- @param #SET_GROUP self - -- @param #string Prefixes The prefix of which the group name starts with. + -- @param #string Prefixes The string pattern(s) that needs to be contained in the group name. Can also be passed as a `#table` of strings. -- @return #SET_GROUP self function SET_GROUP:FilterPrefixes( Prefixes ) if not self.Filter.GroupPrefixes then @@ -1843,7 +1843,7 @@ do -- SET_UNIT -- * @{#SET_UNIT.FilterCategories}: Builds the SET_UNIT with the units belonging to the category(ies). -- * @{#SET_UNIT.FilterTypes}: Builds the SET_UNIT with the units belonging to the unit type(s). -- * @{#SET_UNIT.FilterCountries}: Builds the SET_UNIT with the units belonging to the country(ies). - -- * @{#SET_UNIT.FilterPrefixes}: Builds the SET_UNIT with the units starting with the same prefix string(s). + -- * @{#SET_UNIT.FilterPrefixes}: Builds the SET_UNIT with the units sharing the same string(s) in their name. **ATTENTION!** Bad naming convention as this *does not* only filter *prefixes*. -- * @{#SET_UNIT.FilterActive}: Builds the SET_UNIT with the units that are only active. Units that are inactive (late activation) won't be included in the set! -- -- Once the filter criteria have been set for the SET_UNIT, you can start filtering using: @@ -2105,10 +2105,10 @@ do -- SET_UNIT end - --- Builds a set of units of defined unit prefixes. - -- All the units starting with the given prefixes will be included within the set. + --- Builds a set of UNITs that contain a given string in their unit name. + -- **Attention!** Bad naming convention as this **does not** filter only **prefixes** but all units that **contain** the string. -- @param #SET_UNIT self - -- @param #string Prefixes The prefix of which the unit name starts with. + -- @param #string Prefixes The string pattern(s) that needs to be contained in the unit name. Can also be passed as a `#table` of strings. -- @return #SET_UNIT self function SET_UNIT:FilterPrefixes( Prefixes ) if not self.Filter.UnitPrefixes then @@ -2963,7 +2963,7 @@ do -- SET_STATIC -- * @{#SET_STATIC.FilterCategories}: Builds the SET_STATIC with the units belonging to the category(ies). -- * @{#SET_STATIC.FilterTypes}: Builds the SET_STATIC with the units belonging to the unit type(s). -- * @{#SET_STATIC.FilterCountries}: Builds the SET_STATIC with the units belonging to the country(ies). - -- * @{#SET_STATIC.FilterPrefixes}: Builds the SET_STATIC with the units starting with the same prefix string(s). + -- * @{#SET_STATIC.FilterPrefixes}: Builds the SET_STATIC with the units containing the same string(s) in their name. **ATTENTION** bad naming convention as this *does not** only filter *prefixes*. -- -- Once the filter criteria have been set for the SET_STATIC, you can start filtering using: -- @@ -3176,10 +3176,10 @@ do -- SET_STATIC end - --- Builds a set of units of defined unit prefixes. - -- All the units starting with the given prefixes will be included within the set. + --- Builds a set of STATICs that contain the given string in their name. + -- **Attention!** Bad naming convention as this **does not** filter only **prefixes** but all statics that **contain** the string. -- @param #SET_STATIC self - -- @param #string Prefixes The prefix of which the unit name starts with. + -- @param #string Prefixes The string pattern(s) that need to be contained in the static name. Can also be passed as a `#table` of strings. -- @return #SET_STATIC self function SET_STATIC:FilterPrefixes( Prefixes ) if not self.Filter.StaticPrefixes then @@ -3675,7 +3675,7 @@ do -- SET_CLIENT -- * @{#SET_CLIENT.FilterCategories}: Builds the SET_CLIENT with the clients belonging to the category(ies). -- * @{#SET_CLIENT.FilterTypes}: Builds the SET_CLIENT with the clients belonging to the client type(s). -- * @{#SET_CLIENT.FilterCountries}: Builds the SET_CLIENT with the clients belonging to the country(ies). - -- * @{#SET_CLIENT.FilterPrefixes}: Builds the SET_CLIENT with the clients starting with the same prefix string(s). + -- * @{#SET_CLIENT.FilterPrefixes}: Builds the SET_CLIENT with the clients containing the same string(s) in their unit/pilot name. **ATTENTION!** Bad naming convention as this *does not* only filter *prefixes*. -- * @{#SET_CLIENT.FilterActive}: Builds the SET_CLIENT with the units that are only active. Units that are inactive (late activation) won't be included in the set! -- -- Once the filter criteria have been set for the SET_CLIENT, you can start filtering using: @@ -3858,10 +3858,10 @@ do -- SET_CLIENT end - --- Builds a set of clients of defined client prefixes. - -- All the clients starting with the given prefixes will be included within the set. + --- Builds a set of CLIENTs that contain the given string in their unit/pilot name. + -- **Attention!** Bad naming convention as this **does not** filter only **prefixes** but all clients that **contain** the string. -- @param #SET_CLIENT self - -- @param #string Prefixes The prefix of which the client name starts with. + -- @param #string Prefixes The string pattern(s) that needs to be contained in the unit/pilot name. Can also be passed as a `#table` of strings. -- @return #SET_CLIENT self function SET_CLIENT:FilterPrefixes( Prefixes ) if not self.Filter.ClientPrefixes then @@ -4114,7 +4114,7 @@ do -- SET_PLAYER -- * @{#SET_PLAYER.FilterCategories}: Builds the SET_PLAYER with the clients belonging to the category(ies). -- * @{#SET_PLAYER.FilterTypes}: Builds the SET_PLAYER with the clients belonging to the client type(s). -- * @{#SET_PLAYER.FilterCountries}: Builds the SET_PLAYER with the clients belonging to the country(ies). - -- * @{#SET_PLAYER.FilterPrefixes}: Builds the SET_PLAYER with the clients starting with the same prefix string(s). + -- * @{#SET_PLAYER.FilterPrefixes}: Builds the SET_PLAYER with the clients sharing the same string(s) in their unit/pilot name. **ATTENTION** Bad naming convention as this *does not* only filter prefixes. -- -- Once the filter criteria have been set for the SET_PLAYER, you can start filtering using: -- @@ -4293,10 +4293,10 @@ do -- SET_PLAYER end - --- Builds a set of clients of defined client prefixes. - -- All the clients starting with the given prefixes will be included within the set. + --- Builds a set of PLAYERs that contain the given string in their unit/pilot name. + -- **Attention!** Bad naming convention as this **does not** filter only **prefixes** but all player clients that **contain** the string. -- @param #SET_PLAYER self - -- @param #string Prefixes The prefix of which the client name starts with. + -- @param #string Prefixes The string pattern(s) that needs to be contained in the unit/pilot name. Can also be passed as a `#table` of strings. -- @return #SET_PLAYER self function SET_PLAYER:FilterPrefixes( Prefixes ) if not self.Filter.ClientPrefixes then @@ -4874,7 +4874,7 @@ do -- SET_CARGO -- Filter criteria are defined by: -- -- * @{#SET_CARGO.FilterCoalitions}: Builds the SET_CARGO with the cargos belonging to the coalition(s). - -- * @{#SET_CARGO.FilterPrefixes}: Builds the SET_CARGO with the cargos containing the prefix string(s). + -- * @{#SET_CARGO.FilterPrefixes}: Builds the SET_CARGO with the cargos containing the same string(s). **ATTENTION** Bad naming convention as this *does not* only filter *prefixes*. -- * @{#SET_CARGO.FilterTypes}: Builds the SET_CARGO with the cargos belonging to the cargo type(s). -- * @{#SET_CARGO.FilterCountries}: Builds the SET_CARGO with the cargos belonging to the country(ies). -- @@ -5036,10 +5036,10 @@ do -- SET_CARGO end - --- (R2.1) Builds a set of cargos of defined cargo prefixes. - -- All the cargos starting with the given prefixes will be included within the set. + --- Builds a set of CARGOs that contain a given string in their name. + -- **Attention!** Bad naming convention as this **does not** filter only **prefixes** but all cargos that **contain** the string. -- @param #SET_CARGO self - -- @param #string Prefixes The prefix of which the cargo name starts with. + -- @param #string Prefixes The string pattern(s) that need to be in the cargo name. Can also be passed as a `#table` of strings. -- @return #SET_CARGO self function SET_CARGO:FilterPrefixes( Prefixes ) --R2.1 if not self.Filter.CargoPrefixes then @@ -5315,7 +5315,7 @@ do -- SET_ZONE -- You can set filter criteria to build the collection of zones in SET_ZONE. -- Filter criteria are defined by: -- - -- * @{#SET_ZONE.FilterPrefixes}: Builds the SET_ZONE with the zones having a certain text pattern of prefix. + -- * @{#SET_ZONE.FilterPrefixes}: Builds the SET_ZONE with the zones having a certain text pattern in their name. **ATTENTION!** Bad naming convention as this *does not* only filter *prefixes*. -- -- Once the filter criteria have been set for the SET_ZONE, you can start filtering using: -- @@ -5450,10 +5450,10 @@ do -- SET_ZONE - --- Builds a set of zones of defined zone prefixes. - -- All the zones starting with the given prefixes will be included within the set. + --- Builds a set of ZONEs that contain the given string in their name. + -- **ATTENTION!** Bad naming convention as this **does not** filter only **prefixes** but all zones that **contain** the string. -- @param #SET_ZONE self - -- @param #string Prefixes The prefix of which the zone name starts with. + -- @param #string Prefixes The string pattern(s) that need to be contained in the zone name. Can also be passed as a `#table` of strings. -- @return #SET_ZONE self function SET_ZONE:FilterPrefixes( Prefixes ) if not self.Filter.Prefixes then @@ -5652,7 +5652,7 @@ do -- SET_ZONE_GOAL -- You can set filter criteria to build the collection of zones in SET_ZONE_GOAL. -- Filter criteria are defined by: -- - -- * @{#SET_ZONE_GOAL.FilterPrefixes}: Builds the SET_ZONE_GOAL with the zones having a certain text pattern of prefix. + -- * @{#SET_ZONE_GOAL.FilterPrefixes}: Builds the SET_ZONE_GOAL with the zones having a certain text pattern in their name. **ATTENTION!** Bad naming convention as this *does not* only filter *prefixes*. -- -- Once the filter criteria have been set for the SET_ZONE_GOAL, you can start filtering using: -- @@ -5768,10 +5768,10 @@ do -- SET_ZONE_GOAL - --- Builds a set of zones of defined zone prefixes. - -- All the zones starting with the given prefixes will be included within the set. + --- Builds a set of ZONE_GOALs that contain the given string in their name. + -- **ATTENTION!** Bad naming convention as this **does not** filter only **prefixes** but all zones that **contain** the string. -- @param #SET_ZONE_GOAL self - -- @param #string Prefixes The prefix of which the zone name starts with. + -- @param #string Prefixes The string pattern(s) that needs to be contained in the zone name. Can also be passed as a `#table` of strings. -- @return #SET_ZONE_GOAL self function SET_ZONE_GOAL:FilterPrefixes( Prefixes ) if not self.Filter.Prefixes then