diff --git a/Documentation/Escort.html b/Documentation/Escort.html
index 5a5ed26f5..3afd42ee6 100644
--- a/Documentation/Escort.html
+++ b/Documentation/Escort.html
@@ -76,17 +76,19 @@ Ships and Ground troops will have a more limited set, but they can provide suppo
1. Navigation ...: Escort group navigation functions:
- - "Hold Position and Stay Low": Stops the escort group and they will hover 30 meters above the ground at the position they stopped.
- - "Join-Up and Hold Position NearBy": The escort group will stop nearby you, and then the group will hover.
- - "Join-Up and Follow at 100": The escort group fill follow you at about 100 meters, and they will follow you.
- - "Join-Up and Follow at 200": The escort group fill follow you at about 200 meters, and they will follow you.
- - "Join-Up and Follow at 400": The escort group fill follow you at about 400 meters, and they will follow you.
- - "Join-Up and Follow at 800": The escort group fill follow you at about 800 meters, and they will follow you.
+ - "Join-Up and Follow at x meters": The escort group fill follow you at about x meters, and they will follow you.
- "Flare": Provides menu commands to let the escort group shoot a flare in the air in a color.
- "Smoke": Provides menu commands to let the escort group smoke the air in a color. Note that smoking is only available for ground and naval troops.
-2. Report targets ...: Report targets will make the escort group to report any target that it identifies within a 8km range. Any detected target can be attacked using the 4. Attack nearby targets function. (see below).
+2. Hold position ...: Escort group navigation functions:
+
+
+ - "At current location": Stops the escort group and they will hover 30 meters above the ground at the position they stopped.
+ - "At client location": Stops the escort group and they will hover 30 meters above the ground at the position they stopped.
+
+
+3. Report targets ...: Report targets will make the escort group to report any target that it identifies within a 8km range. Any detected target can be attacked using the 4. Attack nearby targets function. (see below).
- "Report now": Will report the current detected targets.
@@ -94,21 +96,21 @@ Ships and Ground troops will have a more limited set, but they can provide suppo
- "Report targets off": Will stop detecting targets.
-3. Scan targets ...: Menu items to pop-up the escort group for target scanning. After scanning, the escort group will resume with the mission or defined task.
+4. Scan targets ...: Menu items to pop-up the escort group for target scanning. After scanning, the escort group will resume with the mission or defined task.
- "Scan targets 30 seconds": Scan 30 seconds for targets.
- "Scan targets 60 seconds": Scan 60 seconds for targets.
-4. Attack targets ...: This menu item will list all detected targets within a 15km range. Depending on the level of detection (known/unknown) and visuality, the targets type will also be listed.
+5. Attack targets ...: This menu item will list all detected targets within a 15km range. Depending on the level of detection (known/unknown) and visuality, the targets type will also be listed.
-5. Request assistance from ...: This menu item will list all detected targets within a 15km range, as with the menu item Attack Targets.
+
6. Request assistance from ...: This menu item will list all detected targets within a 15km range, as with the menu item Attack Targets.
This menu item allows to request attack support from other escorts supporting the current client group.
eg. the function allows a player to request support from the Ship escort to attack a target identified by the Plane escort with its Tomahawk missiles.
eg. the function allows a player to request support from other Planes escorting to bomb the unit with illumination missiles or bombs, so that the main plane escort can attack the area.
-6. ROE ...: Defines the Rules of Engagement of the escort group when in flight.
+7. ROE ...: Defines the Rules of Engagement of the escort group when in flight.
- "Hold Fire": The escort group will hold fire.
@@ -117,7 +119,7 @@ eg. the function allows a player to request support from other Planes escorting
- "Weapon Free": The escort group will engage with any target.
-7. Evasion ...: Will define the evasion techniques that the escort group will perform during flight or combat.
+8. Evasion ...: Will define the evasion techniques that the escort group will perform during flight or combat.
- "Fight until death": The escort group will have no reaction to threats.
@@ -126,27 +128,41 @@ eg. the function allows a player to request support from other Planes escorting
- "Go below radar and evade fire": The escort group will perform evasive vertical manoeuvres.
-8. Resume Mission ...: Escort groups can have their own mission. This menu item will allow the escort group to resume their Mission from a given waypoint.
+
9. Resume Mission ...: Escort groups can have their own mission. This menu item will allow the escort group to resume their Mission from a given waypoint.
Note that this is really fantastic, as you now have the dynamic of taking control of the escort groups, and allowing them to resume their path or mission.
-9. Abort Current Task: Cancel the current task and rejoin formation.
+10. Abort Current Task: Cancel the current task and rejoin formation.
ESCORT object construction methods.
Create a new SPAWN object with the ESCORT.New method:
ESCORT.New: Creates a new ESCORT object from a Group#GROUP for a Client#CLIENT, with an optional briefing text.
ESCORT object initialization methods.
- None.
+ The following menus can be setup:
+ ESCORT.MenuFollowAt: Creates a menu to make the escort follow the client.
+ ESCORT.MenuHoldAtEscortPosition: Creates a menu to hold the escort at its current position.
+ ESCORT.MenuHoldAtLeaderPosition: Creates a menu to hold the escort at the client position.
+ ESCORT.MenuScanForTargets: Creates a menu so that the escort scans targets.
+ ESCORT.MenuFlare: Creates a menu to disperse flares.
+ ESCORT.MenuSmoke: Creates a menu to disparse smoke.
+ ESCORT.MenuReportTargets: Creates a menu so that the escort reports targets.
+ ESCORT.MenuReportPosition: Creates a menu so that the escort reports its current position from bullseye.
+ ESCORT.MenuAssistedAttack: Creates a menu structure so that the escort can resume from a waypoint.
-
Global(s)
@@ -168,12 +184,222 @@ Note that this is really fantastic, as you now have the dynamic of taking contro
ESCORT.EscortGroup |
+ |
+
+
+ | ESCORT.EscortMenuAttackNearbyTargets |
+
+
+ |
+
+
+ | ESCORT.EscortMenuEvasion |
+
+
+ |
+
+
+ | ESCORT.EscortMenuEvasionEvadeFire |
+
+
+ |
+
+
+ | ESCORT.EscortMenuEvasionNoReaction |
+
+
+ |
+
+
+ | ESCORT.EscortMenuEvasionPassiveDefense |
+
+
+ |
+
+
+ | ESCORT.EscortMenuFlare |
+
+
+ |
+
+
+ | ESCORT.EscortMenuFlareGreen |
+
+
+ |
+
+
+ | ESCORT.EscortMenuFlareRed |
+
+
+ |
+
+
+ | ESCORT.EscortMenuFlareWhite |
+
+
+ |
+
+
+ | ESCORT.EscortMenuFlareYellow |
+
+
+ |
+
+
+ | ESCORT.EscortMenuHold |
+
+
+ |
+
+
+ | ESCORT.EscortMenuHoldAtLeaderPosition |
+
+
+ |
+
+
+ | ESCORT.EscortMenuHoldPosition |
+
+
+ |
+
+
+ | ESCORT.EscortMenuJoinUpAndFollow |
+
+
+ |
+
+
+ | ESCORT.EscortMenuOptionEvasionVertical |
+
+
+ |
+
+
+ | ESCORT.EscortMenuROE |
+
+
+ |
+
+
+ | ESCORT.EscortMenuROEHoldFire |
+
+
+ |
+
+
+ | ESCORT.EscortMenuROEOpenFire |
+
+
+ |
+
+
+ | ESCORT.EscortMenuROEReturnFire |
+
+
+ |
+
+
+ | ESCORT.EscortMenuROEWeaponFree |
+
+
+ |
+
+
+ | ESCORT.EscortMenuReportNavigation |
+
+
+ |
+
+
+ | ESCORT.EscortMenuReportNearbyTargets |
+
+
+ |
+
+
+ | ESCORT.EscortMenuReportNearbyTargetsNow |
+
+
+ |
+
+
+ | ESCORT.EscortMenuReportNearbyTargetsOff |
+
+
+ |
+
+
+ | ESCORT.EscortMenuReportNearbyTargetsOn |
+
+
|
| ESCORT.EscortMenuResumeMission |
+ |
+
+
+ | ESCORT.EscortMenuScan |
+
+
+ |
+
+
+ | ESCORT.EscortMenuScanForTargets |
+
+
+ |
+
+
+ | ESCORT.EscortMenuSmoke |
+
+
+ |
+
+
+ | ESCORT.EscortMenuSmokeBlue |
+
+
+ |
+
+
+ | ESCORT.EscortMenuSmokeGreen |
+
+
+ |
+
+
+ | ESCORT.EscortMenuSmokeOrange |
+
+
+ |
+
+
+ | ESCORT.EscortMenuSmokeRed |
+
+
+ |
+
+
+ | ESCORT.EscortMenuSmokeWhite |
+
+
+ |
+
+
+ | ESCORT.EscortMenuTargetAssistance |
+
+
+ |
+
+
+ | ESCORT.EscortMode |
+
+ The mode the escort is in.
|
@@ -192,6 +418,84 @@ Note that this is really fantastic, as you now have the dynamic of taking contro
| ESCORT:JoinUpAndFollow(EscortGroup, EscortClient, Distance) |
JoinsUp and Follows a CLIENT.
+ |
+
+
+ | ESCORT.MODE |
+
+
+ |
+
+
+ | ESCORT:MenuAssistedAttack() |
+
+ Defines a menu slot to let the escort attack its detected targets using assisted attack from another escort joined also with the client.
+ |
+
+
+ | ESCORT:MenuEvasion(MenuTextFormat) |
+
+ Defines a menu to let the escort set its evasion when under threat.
+ |
+
+
+ | ESCORT:MenuFlare(MenuTextFormat) |
+
+ Defines a menu slot to let the escort disperse a flare in a certain color.
+ |
+
+
+ | ESCORT:MenuFollowAt(Distance) |
+
+ Defines a menu slot to let the escort Join and Follow you at a certain distance.
+ |
+
+
+ | ESCORT:MenuHoldAtEscortPosition(Height, Seconds, MenuTextFormat) |
+
+ Defines a menu slot to let the escort hold at their current position and stay low with a specified height during a specified time in seconds.
+ |
+
+
+ | ESCORT:MenuHoldAtLeaderPosition(Height, Seconds, MenuTextFormat) |
+
+ Defines a menu slot to let the escort hold at the client position and stay low with a specified height during a specified time in seconds.
+ |
+
+
+ | ESCORT:MenuROE(MenuTextFormat) |
+
+ Defines a menu to let the escort set its rules of engagement.
+ |
+
+
+ | ESCORT:MenuReportTargets(Seconds) |
+
+ Defines a menu slot to let the escort report their current detected targets with a specified time interval in seconds.
+ |
+
+
+ | ESCORT:MenuResumeMission() |
+
+ Defines a menu to let the escort resume its mission from a waypoint on its route.
+ |
+
+
+ | ESCORT:MenuScanForTargets(Height, Seconds, MenuTextFormat) |
+
+ Defines a menu slot to let the escort scan for targets at a certain height for a certain time in seconds.
+ |
+
+
+ | ESCORT:MenuSmoke(MenuTextFormat) |
+
+ Defines a menu slot to let the escort disperse a smoke in a certain color.
+ |
+
+
+ | ESCORT:Menus() |
+
+ Defines the default menus
|
@@ -270,12 +574,6 @@ Note that this is really fantastic, as you now have the dynamic of taking contro
| ESCORT._HoldPosition(MenuParam) |
- |
-
-
- | ESCORT._HoldPositionNearBy(MenuParam) |
-
-
|
@@ -330,6 +628,22 @@ Note that this is really fantastic, as you now have the dynamic of taking contro
| ESCORT._SwitchReportNearbyTargets(MenuParam) |
+ |
+
+
+
+
+
@@ -375,6 +689,27 @@ Note that this is really fantastic, as you now have the dynamic of taking contro
+
+
+
+-
+
+
+_Resume(EscortGroup)
+
+
+-
+
+
+
+
Parameter
+
+ -
+
+
EscortGroup :
+
+
+
@@ -426,6 +761,368 @@ Note that this is really fantastic, as you now have the dynamic of taking contro
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
Attack Targets
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
Reaction to Threats
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+ESCORT.EscortMenuJoinUpAndFollow
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
Rules of Engagement
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
Report Targets
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
@@ -440,6 +1137,150 @@ Note that this is really fantastic, as you now have the dynamic of taking contro
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+-
+
+
+
+
+
Request assistance from other escorts.
+ This is very useful to let f.e. an escorting ship attack a target detected by an escorting plane...
+
+
+
+
+-
+
+ #ESCORT.MODE
+
+ESCORT.EscortMode
+
+
+-
+
+
The mode the escort is in.
+
@@ -499,6 +1340,389 @@ Note that this is really fantastic, as you now have the dynamic of taking contro
+
+
+
+-
+
+
+
+ESCORT.MODE
+
+
+-
+
+
+
+
+
+
+-
+
+
+
+-
+
+
Defines a menu slot to let the escort attack its detected targets using assisted attack from another escort joined also with the client.
+
+
+This menu will appear under Request assistance from.
+Note that this method needs to be preceded with the method MenuReportTargets.
+
+ Return value
+
+#ESCORT:
+
+
+
+
+
+-
+
+
+
+-
+
+
Defines a menu to let the escort set its evasion when under threat.
+
+
+All rules of engagement will appear under the menu Evasion.
+
+ Parameter
+
+ -
+
+
MenuTextFormat :
+
+
+
+ Return value
+
+#ESCORT:
+
+
+
+
+
+-
+
+
+
+-
+
+
Defines a menu slot to let the escort disperse a flare in a certain color.
+
+
+This menu will appear under Navigation.
+The flare will be fired from the first unit in the group.
+
+ Parameter
+
+ Return value
+
+#ESCORT:
+
+
+
+
+
+-
+
+
+
+-
+
+
Defines a menu slot to let the escort Join and Follow you at a certain distance.
+
+
+This menu will appear under Navigation.
+
+ Parameter
+
+ Return value
+
+#ESCORT:
+
+
+
+
+
+-
+
+
+
+-
+
+
Defines a menu slot to let the escort hold at their current position and stay low with a specified height during a specified time in seconds.
+
+
+This menu will appear under Hold position.
+
+ Parameters
+
+ -
+
+
DCSTypes#Distance Height :
+Optional parameter that sets the height in meters to let the escort orbit at the current location. The default value is 30 meters.
+
+
+ -
+
+
DCSTypes#Time Seconds :
+Optional parameter that lets the escort orbit at the current position for a specified time. (not implemented yet). The default value is 0 seconds, meaning, that the escort will orbit forever until a sequent command is given.
+
+
+ -
+
+
#string MenuTextFormat :
+Optional parameter that shows the menu option text. The text string is formatted, and should contain two %d tokens in the string. The first for the Height, the second for the Time (if given). If no text is given, the default text will be displayed.
+
+
+
+ Return value
+
+#ESCORT:
+TODO: Implement Seconds parameter. Challenge is to first develop the "continue from last activity" function.
+
+
+
+
+-
+
+
+
+-
+
+
Defines a menu slot to let the escort hold at the client position and stay low with a specified height during a specified time in seconds.
+
+
+This menu will appear under Navigation.
+
+ Parameters
+
+ -
+
+
DCSTypes#Distance Height :
+Optional parameter that sets the height in meters to let the escort orbit at the current location. The default value is 30 meters.
+
+
+ -
+
+
DCSTypes#Time Seconds :
+Optional parameter that lets the escort orbit at the current position for a specified time. (not implemented yet). The default value is 0 seconds, meaning, that the escort will orbit forever until a sequent command is given.
+
+
+ -
+
+
#string MenuTextFormat :
+Optional parameter that shows the menu option text. The text string is formatted, and should contain one or two %d tokens in the string. The first for the Height, the second for the Time (if given). If no text is given, the default text will be displayed.
+
+
+
+ Return value
+
+#ESCORT:
+TODO: Implement Seconds parameter. Challenge is to first develop the "continue from last activity" function.
+
+
+
+
+-
+
+
+
+-
+
+
Defines a menu to let the escort set its rules of engagement.
+
+
+All rules of engagement will appear under the menu ROE.
+
+ Parameter
+
+ -
+
+
MenuTextFormat :
+
+
+
+ Return value
+
+#ESCORT:
+
+
+
+
+
+-
+
+
+
+-
+
+
Defines a menu slot to let the escort report their current detected targets with a specified time interval in seconds.
+
+
+This menu will appear under Report targets.
+Note that if a report targets menu is not specified, no targets will be detected by the escort, and the attack and assisted attack menus will not be displayed.
+
+ Parameter
+
+ Return value
+
+#ESCORT:
+
+
+
+
+
+-
+
+
+
+-
+
+
Defines a menu to let the escort resume its mission from a waypoint on its route.
+
+
+All rules of engagement will appear under the menu Resume mission from.
+
+ Return value
+
+#ESCORT:
+
+
+
+
+
+-
+
+
+
+-
+
+
Defines a menu slot to let the escort scan for targets at a certain height for a certain time in seconds.
+
+
+This menu will appear under Scan targets.
+
+ Parameters
+
+ -
+
+
DCSTypes#Distance Height :
+Optional parameter that sets the height in meters to let the escort orbit at the current location. The default value is 30 meters.
+
+
+ -
+
+
DCSTypes#Time Seconds :
+Optional parameter that lets the escort orbit at the current position for a specified time. (not implemented yet). The default value is 0 seconds, meaning, that the escort will orbit forever until a sequent command is given.
+
+
+ -
+
+
#string MenuTextFormat :
+Optional parameter that shows the menu option text. The text string is formatted, and should contain one or two %d tokens in the string. The first for the Height, the second for the Time (if given). If no text is given, the default text will be displayed.
+
+
+
+ Return value
+
+#ESCORT:
+
+
+
+
+
+-
+
+
+
+-
+
+
Defines a menu slot to let the escort disperse a smoke in a certain color.
+
+
+This menu will appear under Navigation.
+Note that smoke menu options will only be displayed for ships and ground units. Not for air units.
+The smoke will be fired from the first unit in the group.
+
+ Parameter
+
+ Return value
+
+#ESCORT:
+
+
+
+
+
+-
+
+
+
+-
+
+
Defines the default menus
+
+ Return value
+
+#ESCORT:
+
+
@@ -741,27 +1965,6 @@ self
- Parameter
-
-
-
-
--
-
-
-ESCORT._HoldPositionNearBy(MenuParam)
-
-
--
-
-
-
Parameter
-
@@ -951,6 +2154,40 @@ self
+
+
+
+
+
+ESCORT.Mode class
+
+ Field(s)
+
+-
+
+ #number
+
+ESCORT.MODE.FOLLOW
+
+
+-
+
+
+
+
+
+
+-
+
+ #number
+
+ESCORT.MODE.MISSION
+
+
+-
+
+
+
diff --git a/Moose/Escort.lua b/Moose/Escort.lua
index dd195b277..2e654db49 100644
--- a/Moose/Escort.lua
+++ b/Moose/Escort.lua
@@ -1,71 +1,83 @@
--- Taking the lead of AI escorting your flight.
-- The ESCORT class allows you to interact with escorting AI on your flight and take the lead.
-- Each escorting group can be commanded with a whole set of radio commands (radio menu in your flight, and then F10).
---
+--
-- The radio commands will vary according the category of the group. The richest set of commands are with Helicopters and AirPlanes.
-- Ships and Ground troops will have a more limited set, but they can provide support through the bombing of targets designated by the other escorts.
---
+--
-- Find a summary below of the current available commands:
---
+--
-- **1. Navigation ...:** Escort group navigation functions:
---
--- * **"Hold Position and Stay Low":** Stops the escort group and they will hover 30 meters above the ground at the position they stopped.
--- * **"Join-Up and Hold Position NearBy":** The escort group will stop nearby you, and then the group will hover.
--- * **"Join-Up and Follow at 100":** The escort group fill follow you at about 100 meters, and they will follow you.
--- * **"Join-Up and Follow at 200":** The escort group fill follow you at about 200 meters, and they will follow you.
--- * **"Join-Up and Follow at 400":** The escort group fill follow you at about 400 meters, and they will follow you.
--- * **"Join-Up and Follow at 800":** The escort group fill follow you at about 800 meters, and they will follow you.
+--
+-- * **"Join-Up and Follow at x meters":** The escort group fill follow you at about x meters, and they will follow you.
-- * **"Flare":** Provides menu commands to let the escort group shoot a flare in the air in a color.
-- * **"Smoke":** Provides menu commands to let the escort group smoke the air in a color. Note that smoking is only available for ground and naval troops.
---
--- **2. Report targets ...:** Report targets will make the escort group to report any target that it identifies within a 8km range. Any detected target can be attacked using the 4. Attack nearby targets function. (see below).
---
+--
+-- **2. Hold position ...:** Escort group navigation functions:
+--
+-- * **"At current location":** Stops the escort group and they will hover 30 meters above the ground at the position they stopped.
+-- * **"At client location":** Stops the escort group and they will hover 30 meters above the ground at the position they stopped.
+--
+-- **3. Report targets ...:** Report targets will make the escort group to report any target that it identifies within a 8km range. Any detected target can be attacked using the 4. Attack nearby targets function. (see below).
+--
-- * **"Report now":** Will report the current detected targets.
-- * **"Report targets on":** Will make the escort group to report detected targets and will fill the "Attack nearby targets" menu list.
-- * **"Report targets off":** Will stop detecting targets.
---
--- **3. Scan targets ...:** Menu items to pop-up the escort group for target scanning. After scanning, the escort group will resume with the mission or defined task.
---
+--
+-- **4. Scan targets ...:** Menu items to pop-up the escort group for target scanning. After scanning, the escort group will resume with the mission or defined task.
+--
-- * **"Scan targets 30 seconds":** Scan 30 seconds for targets.
-- * **"Scan targets 60 seconds":** Scan 60 seconds for targets.
---
--- **4. Attack targets ...:** This menu item will list all detected targets within a 15km range. Depending on the level of detection (known/unknown) and visuality, the targets type will also be listed.
---
--- **5. Request assistance from ...:** This menu item will list all detected targets within a 15km range, as with the menu item **Attack Targets**.
+--
+-- **5. Attack targets ...:** This menu item will list all detected targets within a 15km range. Depending on the level of detection (known/unknown) and visuality, the targets type will also be listed.
+--
+-- **6. Request assistance from ...:** This menu item will list all detected targets within a 15km range, as with the menu item **Attack Targets**.
-- This menu item allows to request attack support from other escorts supporting the current client group.
-- eg. the function allows a player to request support from the Ship escort to attack a target identified by the Plane escort with its Tomahawk missiles.
-- eg. the function allows a player to request support from other Planes escorting to bomb the unit with illumination missiles or bombs, so that the main plane escort can attack the area.
---
--- **6. ROE ...:** Defines the Rules of Engagement of the escort group when in flight.
---
+--
+-- **7. ROE ...:** Defines the Rules of Engagement of the escort group when in flight.
+--
-- * **"Hold Fire":** The escort group will hold fire.
-- * **"Return Fire":** The escort group will return fire.
-- * **"Open Fire":** The escort group will open fire on designated targets.
-- * **"Weapon Free":** The escort group will engage with any target.
---
--- **7. Evasion ...:** Will define the evasion techniques that the escort group will perform during flight or combat.
---
+--
+-- **8. Evasion ...:** Will define the evasion techniques that the escort group will perform during flight or combat.
+--
-- * **"Fight until death":** The escort group will have no reaction to threats.
-- * **"Use flares, chaff and jammers":** The escort group will use passive defense using flares and jammers. No evasive manoeuvres are executed.
-- * **"Evade enemy fire":** The rescort group will evade enemy fire before firing.
-- * **"Go below radar and evade fire":** The escort group will perform evasive vertical manoeuvres.
---
--- **8. Resume Mission ...:** Escort groups can have their own mission. This menu item will allow the escort group to resume their Mission from a given waypoint.
+--
+-- **9. Resume Mission ...:** Escort groups can have their own mission. This menu item will allow the escort group to resume their Mission from a given waypoint.
-- Note that this is really fantastic, as you now have the dynamic of taking control of the escort groups, and allowing them to resume their path or mission.
---
--- **9. Abort Current Task:** Cancel the current task and rejoin formation.
---
+--
+-- **10. Abort Current Task:** Cancel the current task and rejoin formation.
+--
-- 1. ESCORT object construction methods.
-- --------------------------------------
-- Create a new SPAWN object with the @{#ESCORT.New} method:
---
+--
-- * @{#ESCORT.New}: Creates a new ESCORT object from a @{Group#GROUP} for a @{Client#CLIENT}, with an optional briefing text.
---
+--
-- 2. ESCORT object initialization methods.
-- ----------------------------------------
--- None.
---
---
+-- The following menus can be setup:
+--
+-- * @{#ESCORT.MenuFollowAt}: Creates a menu to make the escort follow the client.
+-- * @{#ESCORT.MenuHoldAtEscortPosition}: Creates a menu to hold the escort at its current position.
+-- * @{#ESCORT.MenuHoldAtLeaderPosition}: Creates a menu to hold the escort at the client position.
+-- * @{#ESCORT.MenuScanForTargets}: Creates a menu so that the escort scans targets.
+-- * @{#ESCORT.MenuFlare}: Creates a menu to disperse flares.
+-- * @{#ESCORT.MenuSmoke}: Creates a menu to disparse smoke.
+-- * @{#ESCORT.MenuReportTargets}: Creates a menu so that the escort reports targets.
+-- * @{#ESCORT.MenuReportPosition}: Creates a menu so that the escort reports its current position from bullseye.
+-- * @{#ESCORT.MenuAssistedAttack: Creates a menu so that the escort supportes assisted attack from other escorts with the client.
+-- * @{#ESCORT.MenuROE: Creates a menu structure to set the rules of engagement of the escort.
+-- * @{#ESCORT.MenuEvasion: Creates a menu structure to set the evasion techniques when the escort is under threat.
+-- * @{#ESCORT.MenuResumeMission}: Creates a menu structure so that the escort can resume from a waypoint.
+--
-- @module Escort
-- @author FlightControl
@@ -82,6 +94,7 @@ Include.File( "Zone" )
-- @field Client#CLIENT EscortClient
-- @field Group#GROUP EscortGroup
-- @field #string EscortName
+-- @field #ESCORT.MODE EscortMode The mode the escort is in.
-- @field #number FollowScheduler The id of the _FollowScheduler function.
-- @field #boolean ReportTargets If true, nearby targets are reported.
-- @Field DCSTypes#AI.Option.Air.val.ROE OptionROE Which ROE is set to the EscortGroup.
@@ -92,6 +105,11 @@ ESCORT = {
EscortName = nil, -- The Escort Name
EscortClient = nil,
EscortGroup = nil,
+ EscortMode = nil,
+ MODE = {
+ FOLLOW = 1,
+ MISSION = 2,
+ },
Targets = {}, -- The identified targets
FollowScheduler = nil,
ReportTargets = true,
@@ -100,6 +118,11 @@ ESCORT = {
TaskPoints = {}
}
+--- ESCORT.Mode class
+-- @type ESCORT.MODE
+-- @field #number FOLLOW
+-- @field #number MISSION
+
--- MENUPARAM type
-- @type MENUPARAM
-- @field #ESCORT ParamSelf
@@ -115,127 +138,465 @@ ESCORT = {
-- @return #ESCORT self
function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing )
local self = BASE:Inherit( self, BASE:New() )
- self:F( { EscortClient, EscortGroup, EscortName } )
-
+ self:F( { EscortClient, EscortGroup, EscortName } )
+
self.EscortClient = EscortClient -- Client#CLIENT
self.EscortGroup = EscortGroup -- Group#GROUP
self.EscortName = EscortName
self.EscortBriefing = EscortBriefing
-
+
self:T( EscortGroup:GetClassNameAndID() )
-
+
-- Set EscortGroup known at EscortClient.
if not self.EscortClient._EscortGroups then
- self.EscortClient._EscortGroups = {}
+ self.EscortClient._EscortGroups = {}
end
if not self.EscortClient._EscortGroups[EscortGroup:GetName()] then
- self.EscortClient._EscortGroups[EscortGroup:GetName()] = {}
- self.EscortClient._EscortGroups[EscortGroup:GetName()].EscortGroup = self.EscortGroup
- self.EscortClient._EscortGroups[EscortGroup:GetName()].EscortName = self.EscortName
- self.EscortClient._EscortGroups[EscortGroup:GetName()].Targets = {}
-
+ self.EscortClient._EscortGroups[EscortGroup:GetName()] = {}
+ self.EscortClient._EscortGroups[EscortGroup:GetName()].EscortGroup = self.EscortGroup
+ self.EscortClient._EscortGroups[EscortGroup:GetName()].EscortName = self.EscortName
+ self.EscortClient._EscortGroups[EscortGroup:GetName()].Targets = {}
+ self.EscortMode = ESCORT.MODE.FOLLOW
end
-
-
+
+
self.EscortMenu = MENU_CLIENT:New( self.EscortClient, self.EscortName )
-
- self.EscortMenuReportNavigation = MENU_CLIENT:New( self.EscortClient, "Navigation", self.EscortMenu )
- if EscortGroup:IsHelicopter() or EscortGroup:IsAirPlane() then
- -- Escort Navigation
- self.EscortMenuHoldPosition = MENU_CLIENT_COMMAND:New( self.EscortClient, "Hold Position and Stay Low", self.EscortMenuReportNavigation, ESCORT._HoldPosition, { ParamSelf = self } )
- self.EscortMenuJoinUpAndHoldPosition = MENU_CLIENT_COMMAND:New( self.EscortClient, "Join-Up and Hold Position NearBy", self.EscortMenuReportNavigation, ESCORT._HoldPositionNearBy, { ParamSelf = self } )
- self.EscortMenuJoinUpAndFollow50Meters = MENU_CLIENT_COMMAND:New( self.EscortClient, "Join-Up and Follow at 100", self.EscortMenuReportNavigation, ESCORT._JoinUpAndFollow, { ParamSelf = self, ParamDistance = 100 } )
- self.EscortMenuJoinUpAndFollow100Meters = MENU_CLIENT_COMMAND:New( self.EscortClient, "Join-Up and Follow at 200", self.EscortMenuReportNavigation, ESCORT._JoinUpAndFollow, { ParamSelf = self, ParamDistance = 200 } )
- self.EscortMenuJoinUpAndFollow150Meters = MENU_CLIENT_COMMAND:New( self.EscortClient, "Join-Up and Follow at 400", self.EscortMenuReportNavigation, ESCORT._JoinUpAndFollow, { ParamSelf = self, ParamDistance = 400 } )
- self.EscortMenuJoinUpAndFollow200Meters = MENU_CLIENT_COMMAND:New( self.EscortClient, "Join-Up and Follow at 800", self.EscortMenuReportNavigation, ESCORT._JoinUpAndFollow, { ParamSelf = self, ParamDistance = 800 } )
- end
- self.EscortMenuFlare = MENU_CLIENT:New( self.EscortClient, "Flare", self.EscortMenuReportNavigation, ESCORT._Flare, { ParamSelf = self } )
- self.EscortMenuFlareGreen = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release green flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.Green, ParamMessage = "Released a green flare!" } )
- self.EscortMenuFlareRed = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release red flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.Red, ParamMessage = "Released a red flare!" } )
- self.EscortMenuFlareWhite = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release white flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.White, ParamMessage = "Released a white flare!" } )
- self.EscortMenuFlareYellow = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release yellow flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.Yellow, ParamMessage = "Released a yellow flare!" } )
- if EscortGroup:IsGround() or EscortGroup:IsShip() then
- self.EscortMenuSmoke = MENU_CLIENT:New( self.EscortClient, "Smoke", self.EscortMenuReportNavigation, ESCORT._Smoke, { ParamSelf = self } )
- self.EscortMenuSmokeGreen = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release green smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.Green, ParamMessage = "Releasing green smoke!" } )
- self.EscortMenuSmokeRed = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release red smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.Red, ParamMessage = "Releasing red smoke!" } )
- self.EscortMenuSmokeWhite = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release white smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.White, ParamMessage = "Releasing white smoke!" } )
- self.EscortMenuSmokeOrange = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release orange smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.Orange, ParamMessage = "Releasing orange smoke!" } )
- self.EscortMenuSmokeBlue = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release blue smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.Blue, ParamMessage = "Releasing blue smoke!" } )
+ self.EscortGroup:WayPointInitialize(1)
+
+ self.EscortGroup:OptionROTVertical()
+ self.EscortGroup:OptionROEOpenFire()
+
+ EscortGroup:MessageToClient( EscortGroup:GetCategoryName() .. " '" .. EscortName .. "' (" .. EscortGroup:GetCallsign() .. ") reporting! " ..
+ "We're escorting your flight. " ..
+ "Use the Radio Menu and F10 and use the options under + " .. EscortName .. "\n",
+ 60, EscortClient
+ )
+
+ return self
+end
+
+
+--- Defines the default menus
+-- @param #ESCORT self
+-- @return #ESCORT
+function ESCORT:Menus()
+ self:F()
+
+ self:MenuFollowAt( 100 )
+ self:MenuFollowAt( 200 )
+ self:MenuFollowAt( 300 )
+ self:MenuFollowAt( 400 )
+
+ self:MenuScanForTargets( 100, 60 )
+
+ self:MenuHoldAtEscortPosition( 30 )
+ self:MenuHoldAtLeaderPosition( 30 )
+
+ self:MenuFlare()
+ self:MenuSmoke()
+
+ self:MenuReportTargets( 60 )
+ self:MenuAssistedAttack()
+ self:MenuROE()
+ self:MenuEvasion()
+ self:MenuResumeMission()
+
+ return self
+end
+
+
+
+--- Defines a menu slot to let the escort Join and Follow you at a certain distance.
+-- This menu will appear under **Navigation**.
+-- @param #ESCORT self
+-- @param DCSTypes#Distance Distance The distance in meters that the escort needs to follow the client.
+-- @return #ESCORT
+function ESCORT:MenuFollowAt( Distance )
+ self:F(Distance)
+
+ if self.EscortGroup:IsAir() then
+ if not self.EscortMenuReportNavigation then
+ self.EscortMenuReportNavigation = MENU_CLIENT:New( self.EscortClient, "Navigation", self.EscortMenu )
+ end
+
+ if not self.EscortMenuJoinUpAndFollow then
+ self.EscortMenuJoinUpAndFollow = {}
+ end
+
+ self.EscortMenuJoinUpAndFollow[#self.EscortMenuJoinUpAndFollow+1] = MENU_CLIENT_COMMAND:New( self.EscortClient, "Join-Up and Follow at " .. Distance, self.EscortMenuReportNavigation, ESCORT._JoinUpAndFollow, { ParamSelf = self, ParamDistance = Distance } )
+
+ self.EscortMode = ESCORT.MODE.FOLLOW
end
-
- if EscortGroup:IsHelicopter() or EscortGroup:IsAirPlane() or EscortGroup:IsGround() or EscortGroup:IsShip() then
- -- Report Targets
+
+ return self
+end
+
+--- Defines a menu slot to let the escort hold at their current position and stay low with a specified height during a specified time in seconds.
+-- This menu will appear under **Hold position**.
+-- @param #ESCORT self
+-- @param DCSTypes#Distance Height Optional parameter that sets the height in meters to let the escort orbit at the current location. The default value is 30 meters.
+-- @param DCSTypes#Time Seconds Optional parameter that lets the escort orbit at the current position for a specified time. (not implemented yet). The default value is 0 seconds, meaning, that the escort will orbit forever until a sequent command is given.
+-- @param #string MenuTextFormat Optional parameter that shows the menu option text. The text string is formatted, and should contain two %d tokens in the string. The first for the Height, the second for the Time (if given). If no text is given, the default text will be displayed.
+-- @return #ESCORT
+-- TODO: Implement Seconds parameter. Challenge is to first develop the "continue from last activity" function.
+function ESCORT:MenuHoldAtEscortPosition( Height, Seconds, MenuTextFormat )
+ self:F( { Height, Seconds, MenuTextFormat } )
+
+ if self.EscortGroup:IsAir() then
+
+ if not self.EscortMenuHold then
+ self.EscortMenuHold = MENU_CLIENT:New( self.EscortClient, "Hold position", self.EscortMenu )
+ end
+
+ if not Height then
+ Height = 30
+ end
+
+ if not Seconds then
+ Seconds = 0
+ end
+
+ local MenuText = ""
+ if not MenuTextFormat then
+ if Seconds == 0 then
+ MenuText = string.format( "Hold at %d meter", Height )
+ else
+ MenuText = string.format( "Hold at %d meter for %d seconds", Height, Seconds )
+ end
+ else
+ if Seconds == 0 then
+ MenuText = string.format( MenuTextFormat, Height )
+ else
+ MenuText = string.format( MenuTextFormat, Height, Seconds )
+ end
+ end
+
+ if not self.EscortMenuHoldPosition then
+ self.EscortMenuHoldPosition = {}
+ end
+
+ self.EscortMenuHoldPosition[#self.EscortMenuHoldPosition+1] = MENU_CLIENT_COMMAND
+ :New(
+ self.EscortClient,
+ MenuText,
+ self.EscortMenuHold,
+ ESCORT._HoldPosition,
+ { ParamSelf = self,
+ ParamOrbitGroup = self.EscortGroup,
+ ParamHeight = Height,
+ ParamSeconds = Seconds
+ }
+ )
+ end
+
+ return self
+end
+
+
+--- Defines a menu slot to let the escort hold at the client position and stay low with a specified height during a specified time in seconds.
+-- This menu will appear under **Navigation**.
+-- @param #ESCORT self
+-- @param DCSTypes#Distance Height Optional parameter that sets the height in meters to let the escort orbit at the current location. The default value is 30 meters.
+-- @param DCSTypes#Time Seconds Optional parameter that lets the escort orbit at the current position for a specified time. (not implemented yet). The default value is 0 seconds, meaning, that the escort will orbit forever until a sequent command is given.
+-- @param #string MenuTextFormat Optional parameter that shows the menu option text. The text string is formatted, and should contain one or two %d tokens in the string. The first for the Height, the second for the Time (if given). If no text is given, the default text will be displayed.
+-- @return #ESCORT
+-- TODO: Implement Seconds parameter. Challenge is to first develop the "continue from last activity" function.
+function ESCORT:MenuHoldAtLeaderPosition( Height, Seconds, MenuTextFormat )
+ self:F( { Height, Seconds, MenuTextFormat } )
+
+ if self.EscortGroup:IsAir() then
+
+ if not self.EscortMenuHold then
+ self.EscortMenuHold = MENU_CLIENT:New( self.EscortClient, "Hold position", self.EscortMenu )
+ end
+
+ if not Height then
+ Height = 30
+ end
+
+ if not Seconds then
+ Seconds = 0
+ end
+
+ local MenuText = ""
+ if not MenuTextFormat then
+ if Seconds == 0 then
+ MenuText = string.format( "Rejoin and hold at %d meter", Height )
+ else
+ MenuText = string.format( "Rejoin and hold at %d meter for %d seconds", Height, Seconds )
+ end
+ else
+ if Seconds == 0 then
+ MenuText = string.format( MenuTextFormat, Height )
+ else
+ MenuText = string.format( MenuTextFormat, Height, Seconds )
+ end
+ end
+
+ if not self.EscortMenuHoldAtLeaderPosition then
+ self.EscortMenuHoldAtLeaderPosition = {}
+ end
+
+ self.EscortMenuHoldAtLeaderPosition[#self.EscortMenuHoldAtLeaderPosition+1] = MENU_CLIENT_COMMAND
+ :New(
+ self.EscortClient,
+ MenuText,
+ self.EscortMenuHold,
+ ESCORT._HoldPosition,
+ { ParamSelf = self,
+ ParamOrbitGroup = self.EscortClient,
+ ParamHeight = Height,
+ ParamSeconds = Seconds
+ }
+ )
+ end
+
+ return self
+end
+
+--- Defines a menu slot to let the escort scan for targets at a certain height for a certain time in seconds.
+-- This menu will appear under **Scan targets**.
+-- @param #ESCORT self
+-- @param DCSTypes#Distance Height Optional parameter that sets the height in meters to let the escort orbit at the current location. The default value is 30 meters.
+-- @param DCSTypes#Time Seconds Optional parameter that lets the escort orbit at the current position for a specified time. (not implemented yet). The default value is 0 seconds, meaning, that the escort will orbit forever until a sequent command is given.
+-- @param #string MenuTextFormat Optional parameter that shows the menu option text. The text string is formatted, and should contain one or two %d tokens in the string. The first for the Height, the second for the Time (if given). If no text is given, the default text will be displayed.
+-- @return #ESCORT
+function ESCORT:MenuScanForTargets( Height, Seconds, MenuTextFormat )
+ self:F( { Height, Seconds, MenuTextFormat } )
+
+ if self.EscortGroup:IsAir() then
+ if not self.EscortMenuScan then
+ self.EscortMenuScan = MENU_CLIENT:New( self.EscortClient, "Scan for targets", self.EscortMenu )
+ end
+
+ if not Height then
+ Height = 100
+ end
+
+ if not Seconds then
+ Seconds = 30
+ end
+
+ local MenuText = ""
+ if not MenuTextFormat then
+ if Seconds == 0 then
+ MenuText = string.format( "At %d meter", Height )
+ else
+ MenuText = string.format( "At %d meter for %d seconds", Height, Seconds )
+ end
+ else
+ if Seconds == 0 then
+ MenuText = string.format( MenuTextFormat, Height )
+ else
+ MenuText = string.format( MenuTextFormat, Height, Seconds )
+ end
+ end
+
+ if not self.EscortMenuScanForTargets then
+ self.EscortMenuScanForTargets = {}
+ end
+
+ self.EscortMenuScanForTargets[#self.EscortMenuScanForTargets+1] = MENU_CLIENT_COMMAND
+ :New(
+ self.EscortClient,
+ MenuText,
+ self.EscortMenuScan,
+ ESCORT._ScanTargets,
+ { ParamSelf = self,
+ ParamScanDuration = 30
+ }
+ )
+ end
+
+ return self
+end
+
+
+
+--- Defines a menu slot to let the escort disperse a flare in a certain color.
+-- This menu will appear under **Navigation**.
+-- The flare will be fired from the first unit in the group.
+-- @param #ESCORT self
+-- @param #string MenuTextFormat Optional parameter that shows the menu option text. If no text is given, the default text will be displayed.
+-- @return #ESCORT
+function ESCORT:MenuFlare( MenuTextFormat )
+ self:F()
+
+ if not self.EscortMenuReportNavigation then
+ self.EscortMenuReportNavigation = MENU_CLIENT:New( self.EscortClient, "Navigation", self.EscortMenu )
+ end
+
+ local MenuText = ""
+ if not MenuTextFormat then
+ MenuText = "Flare"
+ else
+ MenuText = MenuTextFormat
+ end
+
+ if not self.EscortMenuFlare then
+ self.EscortMenuFlare = MENU_CLIENT:New( self.EscortClient, MenuText, self.EscortMenuReportNavigation, ESCORT._Flare, { ParamSelf = self } )
+ self.EscortMenuFlareGreen = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release green flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.Green, ParamMessage = "Released a green flare!" } )
+ self.EscortMenuFlareRed = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release red flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.Red, ParamMessage = "Released a red flare!" } )
+ self.EscortMenuFlareWhite = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release white flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.White, ParamMessage = "Released a white flare!" } )
+ self.EscortMenuFlareYellow = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release yellow flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.Yellow, ParamMessage = "Released a yellow flare!" } )
+ end
+
+ return self
+end
+
+--- Defines a menu slot to let the escort disperse a smoke in a certain color.
+-- This menu will appear under **Navigation**.
+-- Note that smoke menu options will only be displayed for ships and ground units. Not for air units.
+-- The smoke will be fired from the first unit in the group.
+-- @param #ESCORT self
+-- @param #string MenuTextFormat Optional parameter that shows the menu option text. If no text is given, the default text will be displayed.
+-- @return #ESCORT
+function ESCORT:MenuSmoke( MenuTextFormat )
+ self:F()
+
+ if not self.EscortGroup:IsAir() then
+ if not self.EscortMenuReportNavigation then
+ self.EscortMenuReportNavigation = MENU_CLIENT:New( self.EscortClient, "Navigation", self.EscortMenu )
+ end
+
+ local MenuText = ""
+ if not MenuTextFormat then
+ MenuText = "Smoke"
+ else
+ MenuText = MenuTextFormat
+ end
+
+ if not self.EscortMenuSmoke then
+ self.EscortMenuSmoke = MENU_CLIENT:New( self.EscortClient, "Smoke", self.EscortMenuReportNavigation, ESCORT._Smoke, { ParamSelf = self } )
+ self.EscortMenuSmokeGreen = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release green smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.Green, ParamMessage = "Releasing green smoke!" } )
+ self.EscortMenuSmokeRed = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release red smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.Red, ParamMessage = "Releasing red smoke!" } )
+ self.EscortMenuSmokeWhite = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release white smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.White, ParamMessage = "Releasing white smoke!" } )
+ self.EscortMenuSmokeOrange = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release orange smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.Orange, ParamMessage = "Releasing orange smoke!" } )
+ self.EscortMenuSmokeBlue = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release blue smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.Blue, ParamMessage = "Releasing blue smoke!" } )
+ end
+ end
+
+ return self
+end
+
+--- Defines a menu slot to let the escort report their current detected targets with a specified time interval in seconds.
+-- This menu will appear under **Report targets**.
+-- Note that if a report targets menu is not specified, no targets will be detected by the escort, and the attack and assisted attack menus will not be displayed.
+-- @param #ESCORT self
+-- @param DCSTypes#Time Seconds Optional parameter that lets the escort report their current detected targets after specified time interval in seconds. The default time is 30 seconds.
+-- @return #ESCORT
+function ESCORT:MenuReportTargets( Seconds )
+ self:F( { Seconds } )
+
+ if not self.EscortMenuReportNearbyTargets then
self.EscortMenuReportNearbyTargets = MENU_CLIENT:New( self.EscortClient, "Report targets", self.EscortMenu )
- self.EscortMenuReportNearbyTargetsNow = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets now!", self.EscortMenuReportNearbyTargets, ESCORT._ReportNearbyTargetsNow, { ParamSelf = self } )
- self.EscortMenuReportNearbyTargetsOn = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets on", self.EscortMenuReportNearbyTargets, ESCORT._SwitchReportNearbyTargets, { ParamSelf = self, ParamReportTargets = true } )
- self.EscortMenuReportNearbyTargetsOff = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets off", self.EscortMenuReportNearbyTargets, ESCORT._SwitchReportNearbyTargets, { ParamSelf = self, ParamReportTargets = false, } )
end
- if EscortGroup:IsHelicopter() then
- -- Scanning Targets
- self.EscortMenuScanForTargets = MENU_CLIENT:New( self.EscortClient, "Scan targets", self.EscortMenu )
- self.EscortMenuReportNearbyTargetsOn = MENU_CLIENT_COMMAND:New( self.EscortClient, "Scan targets 30 seconds", self.EscortMenuScanForTargets, ESCORT._ScanTargets, { ParamSelf = self, ParamScanDuration = 30 } )
- self.EscortMenuReportNearbyTargetsOn = MENU_CLIENT_COMMAND:New( self.EscortClient, "Scan targets 60 seconds", self.EscortMenuScanForTargets, ESCORT._ScanTargets, { ParamSelf = self, ParamScanDuration = 60 } )
+ if not Seconds then
+ Seconds = 30
end
-
+
+ -- Report Targets
+ self.EscortMenuReportNearbyTargetsNow = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets now!", self.EscortMenuReportNearbyTargets, ESCORT._ReportNearbyTargetsNow, { ParamSelf = self } )
+ self.EscortMenuReportNearbyTargetsOn = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets on", self.EscortMenuReportNearbyTargets, ESCORT._SwitchReportNearbyTargets, { ParamSelf = self, ParamReportTargets = true } )
+ self.EscortMenuReportNearbyTargetsOff = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets off", self.EscortMenuReportNearbyTargets, ESCORT._SwitchReportNearbyTargets, { ParamSelf = self, ParamReportTargets = false, } )
+
-- Attack Targets
self.EscortMenuAttackNearbyTargets = MENU_CLIENT:New( self.EscortClient, "Attack targets", self.EscortMenu )
- -- Request assistance from other escorts.
+
+ self.ReportTargetsScheduler = routines.scheduleFunction( self._ReportTargetsScheduler, { self }, timer.getTime() + 1, Seconds )
+
+ return self
+end
+
+--- Defines a menu slot to let the escort attack its detected targets using assisted attack from another escort joined also with the client.
+-- This menu will appear under **Request assistance from**.
+-- Note that this method needs to be preceded with the method MenuReportTargets.
+-- @param #ESCORT self
+-- @return #ESCORT
+function ESCORT:MenuAssistedAttack()
+ self:F()
+
+ -- Request assistance from other escorts.
-- This is very useful to let f.e. an escorting ship attack a target detected by an escorting plane...
self.EscortMenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, "Request assistance from", self.EscortMenu )
-
- -- Rules of Engagement
- self.EscortMenuROE = MENU_CLIENT:New( self.EscortClient, "ROE", self.EscortMenu )
- if EscortGroup:OptionROEHoldFirePossible() then
- self.EscortMenuROEHoldFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Hold Fire", self.EscortMenuROE, ESCORT._ROE, { ParamSelf = self, ParamFunction = EscortGroup:OptionROEHoldFire(), ParamMessage = "Holding weapons!" } )
- end
- if EscortGroup:OptionROEReturnFirePossible() then
- self.EscortMenuROEReturnFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Return Fire", self.EscortMenuROE, ESCORT._ROE, { ParamSelf = self, ParamFunction = EscortGroup:OptionROEReturnFire(), ParamMessage = "Returning fire!" } )
- end
- if EscortGroup:OptionROEOpenFirePossible() then
- self.EscortMenuROEOpenFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Open Fire", self.EscortMenuROE, ESCORT._ROE, { ParamSelf = self, ParamFunction = EscortGroup:OptionROEOpenFire(), ParamMessage = "Opening fire on designated targets!!" } )
- end
- if EscortGroup:OptionROEWeaponFreePossible() then
- self.EscortMenuROEWeaponFree = MENU_CLIENT_COMMAND:New( self.EscortClient, "Weapon Free", self.EscortMenuROE, ESCORT._ROE, { ParamSelf = self, ParamFunction = EscortGroup:OptionROEWeaponFree(), ParamMessage = "Opening fire on targets of opportunity!" } )
+ return self
+end
+
+--- Defines a menu to let the escort set its rules of engagement.
+-- All rules of engagement will appear under the menu **ROE**.
+-- @param #ESCORT self
+-- @return #ESCORT
+function ESCORT:MenuROE( MenuTextFormat )
+ self:F( MenuTextFormat )
+
+ if not self.EscortMenuROE then
+ -- Rules of Engagement
+ self.EscortMenuROE = MENU_CLIENT:New( self.EscortClient, "ROE", self.EscortMenu )
+ if self.EscortGroup:OptionROEHoldFirePossible() then
+ self.EscortMenuROEHoldFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Hold Fire", self.EscortMenuROE, ESCORT._ROE, { ParamSelf = self, ParamFunction = self.EscortGroup:OptionROEHoldFire(), ParamMessage = "Holding weapons!" } )
+ end
+ if self.EscortGroup:OptionROEReturnFirePossible() then
+ self.EscortMenuROEReturnFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Return Fire", self.EscortMenuROE, ESCORT._ROE, { ParamSelf = self, ParamFunction = self.EscortGroup:OptionROEReturnFire(), ParamMessage = "Returning fire!" } )
+ end
+ if self.EscortGroup:OptionROEOpenFirePossible() then
+ self.EscortMenuROEOpenFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Open Fire", self.EscortMenuROE, ESCORT._ROE, { ParamSelf = self, ParamFunction = self.EscortGroup:OptionROEOpenFire(), ParamMessage = "Opening fire on designated targets!!" } )
+ end
+ if self.EscortGroup:OptionROEWeaponFreePossible() then
+ self.EscortMenuROEWeaponFree = MENU_CLIENT_COMMAND:New( self.EscortClient, "Weapon Free", self.EscortMenuROE, ESCORT._ROE, { ParamSelf = self, ParamFunction = self.EscortGroup:OptionROEWeaponFree(), ParamMessage = "Opening fire on targets of opportunity!" } )
+ end
end
- -- Reaction to Threats
- self.EscortMenuEvasion = MENU_CLIENT:New( self.EscortClient, "Evasion", self.EscortMenu )
- if EscortGroup:OptionROTNoReactionPossible() then
- self.EscortMenuEvasionNoReaction = MENU_CLIENT_COMMAND:New( self.EscortClient, "Fight until death", self.EscortMenuEvasion, ESCORT._ROT, { ParamSelf = self, ParamFunction = EscortGroup:OptionROTNoReaction(), ParamMessage = "Fighting until death!" } )
- end
- if EscortGroup:OptionROTPassiveDefensePossible() then
- self.EscortMenuEvasionPassiveDefense = MENU_CLIENT_COMMAND:New( self.EscortClient, "Use flares, chaff and jammers", self.EscortMenuEvasion, ESCORT._ROT, { ParamSelf = self, ParamFunction = EscortGroup:OptionROTPassiveDefense(), ParamMessage = "Defending using jammers, chaff and flares!" } )
- end
- if EscortGroup:OptionROTEvadeFirePossible() then
- self.EscortMenuEvasionEvadeFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Evade enemy fire", self.EscortMenuEvasion, ESCORT._ROT, { ParamSelf = self, ParamFunction = EscortGroup:OptionROTEvadeFire(), ParamMessage = "Evading on enemy fire!" } )
- end
- if EscortGroup:OptionROTVerticalPossible() then
- self.EscortMenuOptionEvasionVertical = MENU_CLIENT_COMMAND:New( self.EscortClient, "Go below radar and evade fire", self.EscortMenuEvasion, ESCORT._ROT, { ParamSelf = self, ParamFunction = EscortGroup:OptionROTVertical(), ParamMessage = "Evading on enemy fire with vertical manoeuvres!" } )
- end
-
- -- Mission Resume Menu Root
- self.EscortMenuResumeMission = MENU_CLIENT:New( self.EscortClient, "Resume the escort mission", self.EscortMenu )
+ return self
+end
- -- Initialize the EscortGroup
-
- self.EscortGroup:WayPointInitialize(1)
-
- self.EscortGroup:OptionROTVertical()
- self.EscortGroup:OptionROEOpenFire()
-
-
- self.ReportTargetsScheduler = routines.scheduleFunction( self._ReportTargetsScheduler, { self }, timer.getTime() + 1, 30 )
-
- EscortGroup:MessageToClient( EscortGroup:GetCategoryName() .. " '" .. EscortName .. "' (" .. EscortGroup:GetCallsign() .. ") reporting! " ..
- "We're escorting your flight. " ..
- "Use the Radio Menu and F10 and use the options under + " .. EscortName .. "\n",
- 60, EscortClient
- )
+
+--- Defines a menu to let the escort set its evasion when under threat.
+-- All rules of engagement will appear under the menu **Evasion**.
+-- @param #ESCORT self
+-- @return #ESCORT
+function ESCORT:MenuEvasion( MenuTextFormat )
+ self:F( MenuTextFormat )
+
+ if self.EscortGroup:IsAir() then
+ if not self.EscortMenuEvasion then
+ -- Reaction to Threats
+ self.EscortMenuEvasion = MENU_CLIENT:New( self.EscortClient, "Evasion", self.EscortMenu )
+ if self.EscortGroup:OptionROTNoReactionPossible() then
+ self.EscortMenuEvasionNoReaction = MENU_CLIENT_COMMAND:New( self.EscortClient, "Fight until death", self.EscortMenuEvasion, ESCORT._ROT, { ParamSelf = self, ParamFunction = self.EscortGroup:OptionROTNoReaction(), ParamMessage = "Fighting until death!" } )
+ end
+ if self.EscortGroup:OptionROTPassiveDefensePossible() then
+ self.EscortMenuEvasionPassiveDefense = MENU_CLIENT_COMMAND:New( self.EscortClient, "Use flares, chaff and jammers", self.EscortMenuEvasion, ESCORT._ROT, { ParamSelf = self, ParamFunction = self.EscortGroup:OptionROTPassiveDefense(), ParamMessage = "Defending using jammers, chaff and flares!" } )
+ end
+ if self.EscortGroup:OptionROTEvadeFirePossible() then
+ self.EscortMenuEvasionEvadeFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Evade enemy fire", self.EscortMenuEvasion, ESCORT._ROT, { ParamSelf = self, ParamFunction = self.EscortGroup:OptionROTEvadeFire(), ParamMessage = "Evading on enemy fire!" } )
+ end
+ if self.EscortGroup:OptionROTVerticalPossible() then
+ self.EscortMenuOptionEvasionVertical = MENU_CLIENT_COMMAND:New( self.EscortClient, "Go below radar and evade fire", self.EscortMenuEvasion, ESCORT._ROT, { ParamSelf = self, ParamFunction = self.EscortGroup:OptionROTVertical(), ParamMessage = "Evading on enemy fire with vertical manoeuvres!" } )
+ end
+ end
+ end
+
+ return self
+end
+
+--- Defines a menu to let the escort resume its mission from a waypoint on its route.
+-- All rules of engagement will appear under the menu **Resume mission from**.
+-- @param #ESCORT self
+-- @return #ESCORT
+function ESCORT:MenuResumeMission()
+ self:F()
+
+ if not self.EscortMenuResumeMission then
+ -- Mission Resume Menu Root
+ self.EscortMenuResumeMission = MENU_CLIENT:New( self.EscortClient, "Resume mission from", self.EscortMenu )
+ end
+
+ return self
end
@@ -245,48 +606,41 @@ function ESCORT._HoldPosition( MenuParam )
local self = MenuParam.ParamSelf
local EscortGroup = self.EscortGroup
local EscortClient = self.EscortClient
-
- routines.removeFunction( self.FollowScheduler )
- EscortGroup:SetTask( EscortGroup:TaskHoldPosition( 300 ) )
- EscortGroup:MessageToClient( "Holding Position.", 10, EscortClient )
-end
-
---- @param #MENUPARAM MenuParam
-function ESCORT._HoldPositionNearBy( MenuParam )
-
- local self = MenuParam.ParamSelf
- local EscortGroup = self.EscortGroup
- local EscortClient = self.EscortClient
-
- --MenuParam.ParamSelf.EscortGroup:TaskOrbitCircleAtVec2( MenuParam.ParamSelf.EscortClient:GetPointVec2(), 300, 30, 0 )
+ local OrbitGroup = MenuParam.ParamOrbitGroup -- Group#GROUP
+ local OrbitUnit = OrbitGroup:GetUnit(1) -- Unit#UNIT
+ local OrbitHeight = MenuParam.ParamHeight
+ local OrbitSeconds = MenuParam.ParamSeconds -- Not implemented yet
routines.removeFunction( self.FollowScheduler )
-
+
local PointFrom = {}
- local GroupPoint = EscortGroup:GetPointVec2()
+ local GroupPoint = EscortGroup:GetUnit(1):GetPositionVec3()
PointFrom = {}
PointFrom.x = GroupPoint.x
- PointFrom.y = GroupPoint.y
+ PointFrom.y = GroupPoint.z
PointFrom.speed = 250
PointFrom.type = AI.Task.WaypointType.TURNING_POINT
- PointFrom.alt = EscortClient:GetAltitude()
+ PointFrom.alt = GroupPoint.y
PointFrom.alt_type = AI.Task.AltitudeType.BARO
- local ClientPoint = MenuParam.ParamSelf.EscortClient:GetPointVec2()
+ local OrbitPoint = OrbitUnit:GetPointVec2()
local PointTo = {}
- PointTo.x = ClientPoint.x
- PointTo.y = ClientPoint.y
+ PointTo.x = OrbitPoint.x
+ PointTo.y = OrbitPoint.y
PointTo.speed = 250
PointTo.type = AI.Task.WaypointType.TURNING_POINT
- PointTo.alt = EscortClient:GetAltitude()
+ PointTo.alt = OrbitHeight
PointTo.alt_type = AI.Task.AltitudeType.BARO
- PointTo.task = EscortGroup:TaskOrbitCircleAtVec2( EscortClient:GetPointVec2(), 300, 30, 0 )
-
+ PointTo.task = EscortGroup:TaskOrbitCircleAtVec2( OrbitPoint, OrbitHeight, 0 )
+
local Points = { PointFrom, PointTo }
-
+
+ EscortGroup:OptionROEHoldFire()
+ EscortGroup:OptionROTPassiveDefense()
+
EscortGroup:SetTask( EscortGroup:TaskRoute( Points ) )
- EscortGroup:MessageToClient( "Rejoining to your location. Please hold at your location.", 10, EscortClient )
+ EscortGroup:MessageToClient( "Orbiting at location.", 10, EscortClient )
end
--- @param #MENUPARAM MenuParam
@@ -295,10 +649,10 @@ function ESCORT._JoinUpAndFollow( MenuParam )
local self = MenuParam.ParamSelf
local EscortGroup = self.EscortGroup
local EscortClient = self.EscortClient
-
- local Distance = MenuParam.ParamDistance
-
- self:JoinUpAndFollow( EscortGroup, EscortClient, Distance )
+
+ self.Distance = MenuParam.ParamDistance
+
+ self:JoinUpAndFollow( EscortGroup, EscortClient, self.Distance )
end
--- JoinsUp and Follows a CLIENT.
@@ -312,10 +666,12 @@ function ESCORT:JoinUpAndFollow( EscortGroup, EscortClient, Distance )
if self.FollowScheduler then
routines.removeFunction( self.FollowScheduler )
end
-
+
EscortGroup:OptionROEHoldFire()
EscortGroup:OptionROTPassiveDefense()
-
+
+ self.EscortMode = ESCORT.MODE.FOLLOW
+
self.CT1 = 0
self.GT1 = 0
self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + 1, .5 )
@@ -328,7 +684,7 @@ function ESCORT._Flare( MenuParam )
local self = MenuParam.ParamSelf
local EscortGroup = self.EscortGroup
local EscortClient = self.EscortClient
-
+
local Color = MenuParam.ParamColor
local Message = MenuParam.ParamMessage
@@ -345,7 +701,7 @@ function ESCORT._Smoke( MenuParam )
local Color = MenuParam.ParamColor
local Message = MenuParam.ParamMessage
-
+
EscortGroup:GetUnit(1):Smoke( Color )
EscortGroup:MessageToClient( Message, 10, EscortClient )
end
@@ -359,7 +715,7 @@ function ESCORT._ReportNearbyTargetsNow( MenuParam )
local EscortClient = self.EscortClient
self:_ReportTargetsScheduler()
-
+
end
function ESCORT._SwitchReportNearbyTargets( MenuParam )
@@ -367,9 +723,9 @@ function ESCORT._SwitchReportNearbyTargets( MenuParam )
local self = MenuParam.ParamSelf
local EscortGroup = self.EscortGroup
local EscortClient = self.EscortClient
-
+
self.ReportTargets = MenuParam.ParamReportTargets
-
+
if self.ReportTargets then
if not self.ReportTargetsScheduler then
self.ReportTargetsScheduler = routines.scheduleFunction( self._ReportTargetsScheduler, { self }, timer.getTime() + 1, 30 )
@@ -386,45 +742,56 @@ function ESCORT._ScanTargets( MenuParam )
local self = MenuParam.ParamSelf
local EscortGroup = self.EscortGroup
local EscortClient = self.EscortClient
-
+
local ScanDuration = MenuParam.ParamScanDuration
if self.FollowScheduler then
routines.removeFunction( self.FollowScheduler )
end
-
+
self:T( { "FollowScheduler after removefunction: ", self.FollowScheduler } )
-
+
if EscortGroup:IsHelicopter() then
routines.scheduleFunction( EscortGroup.PushTask,
- { EscortGroup,
- EscortGroup:TaskControlled(
- EscortGroup:TaskOrbitCircle( 200, 20 ),
- EscortGroup:TaskCondition( nil, nil, nil, nil, ScanDuration, nil )
- )
- },
- timer.getTime() + 1
- )
+ { EscortGroup,
+ EscortGroup:TaskControlled(
+ EscortGroup:TaskOrbitCircle( 200, 20 ),
+ EscortGroup:TaskCondition( nil, nil, nil, nil, ScanDuration, nil )
+ )
+ },
+ timer.getTime() + 1
+ )
elseif EscortGroup:IsAirPlane() then
routines.scheduleFunction( EscortGroup.PushTask,
- { EscortGroup,
- EscortGroup:TaskControlled(
- EscortGroup:TaskOrbitCircle( 1000, 500 ),
- EscortGroup:TaskCondition( nil, nil, nil, nil, ScanDuration, nil )
- )
- },
- timer.getTime() + 1
- )
- end
-
+ { EscortGroup,
+ EscortGroup:TaskControlled(
+ EscortGroup:TaskOrbitCircle( 1000, 500 ),
+ EscortGroup:TaskCondition( nil, nil, nil, nil, ScanDuration, nil )
+ )
+ },
+ timer.getTime() + 1
+ )
+ end
+
EscortGroup:MessageToClient( "Scanning targets for " .. ScanDuration .. " seconds.", ScanDuration, EscortClient )
- if self.FollowScheduler then
+ if self.EscortMode == ESCORT.MODE.FOLLOW then
self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + ScanDuration, 1 )
end
end
+function _Resume( EscortGroup )
+ env.info( '_Resume' )
+
+ local Escort = EscortGroup.Escort -- #ESCORT
+ env.info( "EscortMode = " .. Escort.EscortMode )
+ if Escort.EscortMode == ESCORT.MODE.FOLLOW then
+ Escort:JoinUpAndFollow( EscortGroup, Escort.EscortClient, Escort.Distance )
+ end
+
+end
+
--- @param #MENUPARAM MenuParam
function ESCORT._AttackTarget( MenuParam )
@@ -436,40 +803,37 @@ function ESCORT._AttackTarget( MenuParam )
if self.FollowScheduler then
routines.removeFunction( self.FollowScheduler )
end
-
+
self:T( AttackUnit )
-
+
if EscortGroup:IsAir() then
EscortGroup:OptionROEOpenFire()
- EscortGroup:OptionROTVertical()
- routines.scheduleFunction(
- EscortGroup.PushTask,
- { EscortGroup,
+ EscortGroup:OptionROTPassiveDefense()
+ EscortGroup.Escort = self -- Need to do this trick to get the reference for the escort in the _Resume function.
+ routines.scheduleFunction(
+ EscortGroup.PushTask,
+ { EscortGroup,
EscortGroup:TaskCombo(
{ EscortGroup:TaskAttackUnit( AttackUnit ),
- EscortGroup:TaskOrbitCircle( 500, 350 )
+ EscortGroup:TaskFunction( 1, 2, "_Resume", {"''"} )
}
)
}, timer.getTime() + 10
)
else
- routines.scheduleFunction(
- EscortGroup.PushTask,
- { EscortGroup,
+ routines.scheduleFunction(
+ EscortGroup.PushTask,
+ { EscortGroup,
EscortGroup:TaskCombo(
{ EscortGroup:TaskFireAtPoint( AttackUnit:GetPointVec2(), 50 )
}
)
- }, timer.getTime() + 10
+ }, timer.getTime() + 10
)
- end
+ end
EscortGroup:MessageToClient( "Engaging Designated Unit!", 10, EscortClient )
- if self.FollowScheduler then
- self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + ScanDuration, 1 )
- end
-
end
--- @param #MENUPARAM MenuParam
@@ -484,34 +848,34 @@ function ESCORT._AssistTarget( MenuParam )
if self.FollowScheduler then
routines.removeFunction( self.FollowScheduler )
end
-
-
+
+
self:T( AttackUnit )
-
+
if EscortGroupAttack:IsAir() then
EscortGroupAttack:OptionROEOpenFire()
EscortGroupAttack:OptionROTVertical()
- routines.scheduleFunction(
- EscortGroupAttack.PushTask,
- { EscortGroupAttack,
+ routines.scheduleFunction(
+ EscortGroupAttack.PushTask,
+ { EscortGroupAttack,
EscortGroupAttack:TaskCombo(
{ EscortGroupAttack:TaskAttackUnit( AttackUnit ),
EscortGroupAttack:TaskOrbitCircle( 500, 350 )
}
)
- }, timer.getTime() + 10
+ }, timer.getTime() + 10
)
else
- routines.scheduleFunction(
- EscortGroupAttack.PushTask,
- { EscortGroupAttack,
+ routines.scheduleFunction(
+ EscortGroupAttack.PushTask,
+ { EscortGroupAttack,
EscortGroupAttack:TaskCombo(
{ EscortGroupAttack:TaskFireAtPoint( AttackUnit:GetPointVec2(), 50 )
}
)
- }, timer.getTime() + 10
+ }, timer.getTime() + 10
)
- end
+ end
EscortGroupAttack:MessageToClient( "Assisting with the destroying the enemy unit!", 10, EscortClient )
end
@@ -522,10 +886,10 @@ function ESCORT._ROE( MenuParam )
local self = MenuParam.ParamSelf
local EscortGroup = self.EscortGroup
local EscortClient = self.EscortClient
-
+
local EscortROEFunction = MenuParam.ParamFunction
local EscortROEMessage = MenuParam.ParamMessage
-
+
pcall( function() EscortROEFunction() end )
EscortGroup:MessageToClient( EscortROEMessage, 10, EscortClient )
end
@@ -550,21 +914,21 @@ function ESCORT._ResumeMission( MenuParam )
local self = MenuParam.ParamSelf
local EscortGroup = self.EscortGroup
local EscortClient = self.EscortClient
-
+
local WayPoint = MenuParam.ParamWayPoint
-
+
routines.removeFunction( self.FollowScheduler )
self.FollowScheduler = nil
local WayPoints = EscortGroup:GetTaskRoute()
self:T( WayPoint, WayPoints )
-
+
for WayPointIgnore = 1, WayPoint do
table.remove( WayPoints, 1 )
end
-
+
routines.scheduleFunction( EscortGroup.SetTask, {EscortGroup, EscortGroup:TaskRoute( WayPoints ) }, timer.getTime() + 1 )
-
+
EscortGroup:MessageToClient( "Resuming mission from waypoint " .. WayPoint .. ".", 10, EscortClient )
end
@@ -575,9 +939,9 @@ function ESCORT:RegisterRoute()
self:F()
local EscortGroup = self.EscortGroup -- Group#GROUP
-
+
local TaskPoints = EscortGroup:GetTaskRoute()
-
+
self:T( TaskPoints )
return TaskPoints
@@ -588,7 +952,7 @@ function ESCORT:_FollowScheduler( FollowDistance )
self:F( { FollowDistance })
if self.EscortGroup:IsAlive() and self.EscortClient:IsAlive() then
-
+
local ClientUnit = self.EscortClient:GetClientGroupUnit()
local GroupUnit = self.EscortGroup:GetUnit( 1 )
@@ -604,70 +968,70 @@ function ESCORT:_FollowScheduler( FollowDistance )
local CV2 = ClientUnit:GetPositionVec3()
self.CT1 = CT2
self.CV1 = CV2
-
+
local CD = ( ( CV2.x - CV1.x )^2 + ( CV2.y - CV1.y )^2 + ( CV2.z - CV1.z )^2 ) ^ 0.5
local CT = CT2 - CT1
-
+
local CS = ( 3600 / CT ) * ( CD / 1000 )
-
+
self:T2( { "Client:", CS, CD, CT, CV2, CV1, CT2, CT1 } )
-
+
local GT1 = self.GT1
local GT2 = timer.getTime()
local GV1 = self.GV1
local GV2 = GroupUnit:GetPositionVec3()
self.GT1 = GT2
self.GV1 = GV2
-
+
local GD = ( ( GV2.x - GV1.x )^2 + ( GV2.y - GV1.y )^2 + ( GV2.z - GV1.z )^2 ) ^ 0.5
local GT = GT2 - GT1
-
+
local GS = ( 3600 / GT ) * ( GD / 1000 )
-
+
self:T2( { "Group:", GS, GD, GT, GV2, GV1, GT2, GT1 } )
-
+
-- Calculate the group direction vector
local GV = { x = GV2.x - CV2.x, y = GV2.y - CV2.y, z = GV2.z - CV2.z }
-
+
-- Calculate GH2, GH2 with the same height as CV2.
local GH2 = { x = GV2.x, y = CV2.y, z = GV2.z }
-
+
-- Calculate the angle of GV to the orthonormal plane
local alpha = math.atan2( GV.z, GV.x )
-
+
-- Now we calculate the intersecting vector between the circle around CV2 with radius FollowDistance and GH2.
-- From the GeoGebra model: CVI = (x(CV2) + FollowDistance cos(alpha), y(GH2) + FollowDistance sin(alpha), z(CV2))
- local CVI = { x = CV2.x + FollowDistance * math.cos(alpha),
- y = GH2.y,
- z = CV2.z + FollowDistance * math.sin(alpha),
- }
-
+ local CVI = { x = CV2.x + FollowDistance * math.cos(alpha),
+ y = GH2.y,
+ z = CV2.z + FollowDistance * math.sin(alpha),
+ }
+
-- Calculate the direction vector DV of the escort group. We use CVI as the base and CV2 as the direction.
local DV = { x = CV2.x - CVI.x, y = CV2.y - CVI.y, z = CV2.z - CVI.z }
-
+
-- We now calculate the unary direction vector DVu, so that we can multiply DVu with the speed, which is expressed in meters / s.
-- We need to calculate this vector to predict the point the escort group needs to fly to according its speed.
-- The distance of the destination point should be far enough not to have the aircraft starting to swipe left to right...
local DVu = { x = DV.x / FollowDistance, y = DV.y / FollowDistance, z = DV.z / FollowDistance }
-
+
-- Now we can calculate the group destination vector GDV.
local GDV = { x = DVu.x * CS * 8 + CVI.x, y = CVI.y, z = DVu.z * CS * 8 + CVI.z }
self:T2( { "CV2:", CV2 } )
self:T2( { "CVI:", CVI } )
self:T2( { "GDV:", GDV } )
-
+
-- Measure distance between client and group
local CatchUpDistance = ( ( GDV.x - GV2.x )^2 + ( GDV.y - GV2.y )^2 + ( GDV.z - GV2.z )^2 ) ^ 0.5
-
- -- The calculation of the Speed would simulate that the group would take 30 seconds to overcome
+
+ -- The calculation of the Speed would simulate that the group would take 30 seconds to overcome
-- the requested Distance).
local Time = 10
- local CatchUpSpeed = ( CatchUpDistance - ( CS * 8.4 ) ) / Time
-
+ local CatchUpSpeed = ( CatchUpDistance - ( CS * 8.4 ) ) / Time
+
local Speed = CS + CatchUpSpeed
- if Speed < 0 then
+ if Speed < 0 then
Speed = 0
- end
+ end
self:T( { "Client Speed, Escort Speed, Speed, FlyDistance, Time:", CS, GS, Speed, Distance, Time } )
@@ -684,90 +1048,93 @@ end
--- Report Targets Scheduler.
-- @param #ESCORT self
function ESCORT:_ReportTargetsScheduler()
- self:F( self.EscortGroup:GetName() )
+ self:F( self.EscortGroup:GetName() )
if self.EscortGroup:IsAlive() and self.EscortClient:IsAlive() then
local EscortGroupName = self.EscortGroup:GetName()
local EscortTargets = self.EscortGroup:GetDetectedTargets()
-
+
local ClientEscortTargets = self.EscortClient._EscortGroups[EscortGroupName].Targets
-
+
local EscortTargetMessages = ""
for EscortTargetID, EscortTarget in pairs( EscortTargets ) do
local EscortObject = EscortTarget.object
self:T( EscortObject )
if EscortObject and EscortObject:isExist() and EscortObject.id_ < 50000000 then
-
- local EscortTargetUnit = UNIT:New( EscortObject )
- local EscortTargetUnitName = EscortTargetUnit:GetName()
-
-
-
--- local EscortTargetIsDetected,
--- EscortTargetIsVisible,
--- EscortTargetLastTime,
--- EscortTargetKnowType,
--- EscortTargetKnowDistance,
--- EscortTargetLastPos,
--- EscortTargetLastVelocity
--- = self.EscortGroup:IsTargetDetected( EscortObject )
---
--- self:T( { EscortTargetIsDetected,
--- EscortTargetIsVisible,
--- EscortTargetLastTime,
--- EscortTargetKnowType,
--- EscortTargetKnowDistance,
--- EscortTargetLastPos,
--- EscortTargetLastVelocity } )
-
- local EscortTargetUnitPositionVec3 = EscortTargetUnit:GetPositionVec3()
- local EscortPositionVec3 = self.EscortGroup:GetPositionVec3()
- local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 +
- ( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 +
- ( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2
- ) ^ 0.5 / 1000
+ local EscortTargetUnit = UNIT:New( EscortObject )
+ local EscortTargetUnitName = EscortTargetUnit:GetName()
- self:T( { self.EscortGroup:GetName(), EscortTargetUnit:GetName(), Distance, EscortTarget } )
- if Distance <= 15 then
- if not ClientEscortTargets[EscortTargetUnitName] then
- ClientEscortTargets[EscortTargetUnitName] = {}
- end
- ClientEscortTargets[EscortTargetUnitName].AttackUnit = EscortTargetUnit
- ClientEscortTargets[EscortTargetUnitName].visible = EscortTarget.visible
- ClientEscortTargets[EscortTargetUnitName].type = EscortTarget.type
- ClientEscortTargets[EscortTargetUnitName].distance = EscortTarget.distance
- else
- if ClientEscortTargets[EscortTargetUnitName] then
- ClientEscortTargets[EscortTargetUnitName] = nil
- end
+ -- local EscortTargetIsDetected,
+ -- EscortTargetIsVisible,
+ -- EscortTargetLastTime,
+ -- EscortTargetKnowType,
+ -- EscortTargetKnowDistance,
+ -- EscortTargetLastPos,
+ -- EscortTargetLastVelocity
+ -- = self.EscortGroup:IsTargetDetected( EscortObject )
+ --
+ -- self:T( { EscortTargetIsDetected,
+ -- EscortTargetIsVisible,
+ -- EscortTargetLastTime,
+ -- EscortTargetKnowType,
+ -- EscortTargetKnowDistance,
+ -- EscortTargetLastPos,
+ -- EscortTargetLastVelocity } )
+
+
+ local EscortTargetUnitPositionVec3 = EscortTargetUnit:GetPositionVec3()
+ local EscortPositionVec3 = self.EscortGroup:GetPositionVec3()
+ local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 +
+ ( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 +
+ ( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2
+ ) ^ 0.5 / 1000
+
+ self:T( { self.EscortGroup:GetName(), EscortTargetUnit:GetName(), Distance, EscortTarget } )
+
+ if Distance <= 15 then
+
+ if not ClientEscortTargets[EscortTargetUnitName] then
+ ClientEscortTargets[EscortTargetUnitName] = {}
end
+ ClientEscortTargets[EscortTargetUnitName].AttackUnit = EscortTargetUnit
+ ClientEscortTargets[EscortTargetUnitName].visible = EscortTarget.visible
+ ClientEscortTargets[EscortTargetUnitName].type = EscortTarget.type
+ ClientEscortTargets[EscortTargetUnitName].distance = EscortTarget.distance
+ else
+ if ClientEscortTargets[EscortTargetUnitName] then
+ ClientEscortTargets[EscortTargetUnitName] = nil
+ end
+ end
end
end
-
+
self:T( { "Sorting Targets Table:", ClientEscortTargets } )
table.sort( ClientEscortTargets, function( a, b ) return a.Distance < b.Distance end )
self:T( { "Sorted Targets Table:", ClientEscortTargets } )
-- Remove the sub menus of the Attack menu of the Escort for the EscortGroup.
self.EscortMenuAttackNearbyTargets:RemoveSubMenus()
- self.EscortMenuTargetAssistance:RemoveSubMenus()
-
+
+ if self.EscortMenuTargetAssistance then
+ self.EscortMenuTargetAssistance:RemoveSubMenus()
+ end
+
--for MenuIndex = 1, #self.EscortMenuAttackTargets do
-- self:T( { "Remove Menu:", self.EscortMenuAttackTargets[MenuIndex] } )
-- self.EscortMenuAttackTargets[MenuIndex] = self.EscortMenuAttackTargets[MenuIndex]:Remove()
--end
-
+
if ClientEscortTargets then
for ClientEscortTargetUnitName, ClientEscortTargetData in pairs( ClientEscortTargets ) do
-
+
for ClientEscortGroupName, EscortGroupData in pairs( self.EscortClient._EscortGroups ) do
-
+
if ClientEscortTargetData and ClientEscortTargetData.AttackUnit:IsAlive() then
-
+
local EscortTargetMessage = ""
local EscortTargetCategoryName = ClientEscortTargetData.AttackUnit:GetCategoryName()
local EscortTargetCategoryType = ClientEscortTargetData.AttackUnit:GetTypeName()
@@ -776,54 +1143,56 @@ function ESCORT:_ReportTargetsScheduler()
else
EscortTargetMessage = EscortTargetMessage .. "Unknown target at "
end
-
+
local EscortTargetUnitPositionVec3 = ClientEscortTargetData.AttackUnit:GetPositionVec3()
local EscortPositionVec3 = self.EscortGroup:GetPositionVec3()
- local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 +
- ( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 +
- ( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2
- ) ^ 0.5 / 1000
-
+ local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 +
+ ( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 +
+ ( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2
+ ) ^ 0.5 / 1000
+
self:T( { self.EscortGroup:GetName(), ClientEscortTargetData.AttackUnit:GetName(), Distance, ClientEscortTargetData.AttackUnit } )
if ClientEscortTargetData.visible == false then
EscortTargetMessage = EscortTargetMessage .. string.format( "%.2f", Distance ) .. " estimated km"
else
EscortTargetMessage = EscortTargetMessage .. string.format( "%.2f", Distance ) .. " km"
end
-
+
if ClientEscortTargetData.visible then
EscortTargetMessage = EscortTargetMessage .. ", visual"
end
-
+
if ClientEscortGroupName == EscortGroupName then
-
+
MENU_CLIENT_COMMAND:New( self.EscortClient,
- EscortTargetMessage,
- self.EscortMenuAttackNearbyTargets,
- ESCORT._AttackTarget,
- { ParamSelf = self,
- ParamUnit = ClientEscortTargetData.AttackUnit
- }
- )
- EscortTargetMessages = EscortTargetMessages .. "\n - " .. EscortTargetMessage
+ EscortTargetMessage,
+ self.EscortMenuAttackNearbyTargets,
+ ESCORT._AttackTarget,
+ { ParamSelf = self,
+ ParamUnit = ClientEscortTargetData.AttackUnit
+ }
+ )
+ EscortTargetMessages = EscortTargetMessages .. "\n - " .. EscortTargetMessage
else
- local MenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, EscortGroupData.EscortName, self.EscortMenuTargetAssistance )
- MENU_CLIENT_COMMAND:New( self.EscortClient,
- EscortTargetMessage,
- MenuTargetAssistance,
- ESCORT._AssistTarget,
- { ParamSelf = self,
- ParamEscortGroup = EscortGroupData.EscortGroup,
- ParamUnit = ClientEscortTargetData.AttackUnit
- }
- )
+ if self.EscortMenuTargetAssistance then
+ local MenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, EscortGroupData.EscortName, self.EscortMenuTargetAssistance )
+ MENU_CLIENT_COMMAND:New( self.EscortClient,
+ EscortTargetMessage,
+ MenuTargetAssistance,
+ ESCORT._AssistTarget,
+ { ParamSelf = self,
+ ParamEscortGroup = EscortGroupData.EscortGroup,
+ ParamUnit = ClientEscortTargetData.AttackUnit
+ }
+ )
+ end
end
else
ClientEscortTargetData = nil
end
end
end
-
+
if EscortTargetMessages ~= "" and self.ReportTargets == true then
self.EscortGroup:MessageToClient( "Detected targets within 15 km range:" .. EscortTargetMessages:gsub("\n$",""), 20, self.EscortClient )
else
@@ -831,22 +1200,24 @@ function ESCORT:_ReportTargetsScheduler()
end
end
- self.EscortMenuResumeMission:RemoveSubMenus()
-
--- if self.EscortMenuResumeWayPoints then
--- for MenuIndex = 1, #self.EscortMenuResumeWayPoints do
--- self:T( { "Remove Menu:", self.EscortMenuResumeWayPoints[MenuIndex] } )
--- self.EscortMenuResumeWayPoints[MenuIndex] = self.EscortMenuResumeWayPoints[MenuIndex]:Remove()
--- end
--- end
+ if self.EscortMenuResumeMission then
+ self.EscortMenuResumeMission:RemoveSubMenus()
- local TaskPoints = self:RegisterRoute()
- for WayPointID, WayPoint in pairs( TaskPoints ) do
- local EscortPositionVec3 = self.EscortGroup:GetPositionVec3()
- local Distance = ( ( WayPoint.x - EscortPositionVec3.x )^2 +
- ( WayPoint.y - EscortPositionVec3.z )^2
- ) ^ 0.5 / 1000
- MENU_CLIENT_COMMAND:New( self.EscortClient, "Waypoint " .. WayPointID .. " at " .. string.format( "%.2f", Distance ).. "km", self.EscortMenuResumeMission, ESCORT._ResumeMission, { ParamSelf = self, ParamWayPoint = WayPointID } )
+ -- if self.EscortMenuResumeWayPoints then
+ -- for MenuIndex = 1, #self.EscortMenuResumeWayPoints do
+ -- self:T( { "Remove Menu:", self.EscortMenuResumeWayPoints[MenuIndex] } )
+ -- self.EscortMenuResumeWayPoints[MenuIndex] = self.EscortMenuResumeWayPoints[MenuIndex]:Remove()
+ -- end
+ -- end
+
+ local TaskPoints = self:RegisterRoute()
+ for WayPointID, WayPoint in pairs( TaskPoints ) do
+ local EscortPositionVec3 = self.EscortGroup:GetPositionVec3()
+ local Distance = ( ( WayPoint.x - EscortPositionVec3.x )^2 +
+ ( WayPoint.y - EscortPositionVec3.z )^2
+ ) ^ 0.5 / 1000
+ MENU_CLIENT_COMMAND:New( self.EscortClient, "Waypoint " .. WayPointID .. " at " .. string.format( "%.2f", Distance ).. "km", self.EscortMenuResumeMission, ESCORT._ResumeMission, { ParamSelf = self, ParamWayPoint = WayPointID } )
+ end
end
else
diff --git a/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua b/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua
index e53577029..6e5e36e0b 100644
--- a/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua
+++ b/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua
@@ -8,18 +8,44 @@ Include.File( "Escort" )
do
local function EventAliveHelicopter( Client )
local EscortGroupHeli1 = SpawnEscortHeli:ReSpawn(1)
- local EscortHeli1 = ESCORT:New( Client, EscortGroupHeli1, "Escort Alpha" )
+ local EscortHeli1 = ESCORT
+ :New( Client, EscortGroupHeli1, "Escort Helicopter" )
+ :MenuFollowAt( 100 )
+ :MenuFollowAt( 200 )
+ :MenuHoldAtEscortPosition( 20, 10, "Hold at %d meters for %d seconds" )
+ :MenuHoldAtLeaderPosition( 120 )
+ :MenuFlare( "Disperse Flares" )
+ :MenuSmoke()
+ :MenuReportTargets( 60, 20 )
+ :MenuResumeMission()
+ :MenuAssistedAttack()
end
local function EventAlivePlane( Client )
local EscortGroupPlane2 = SpawnEscortPlane:ReSpawn(1)
- local EscortPlane2 = ESCORT:New( Client, EscortGroupPlane2, "Escort Test Plane" )
+ local EscortPlane2 = ESCORT
+ :New( Client, EscortGroupPlane2, "Escort Test Plane" )
+ :MenuFollowAt( 100 )
+ :MenuFollowAt( 200 )
+ :MenuHoldAtEscortPosition( 20, 10, "Hold at %d meters for %d seconds" )
+ :MenuHoldAtLeaderPosition( 120 )
+ :MenuFlare( "Disperse Flares" )
+ :MenuSmoke()
+ :MenuReportTargets( 60, 20 )
+ :MenuResumeMission()
+ :MenuAssistedAttack()
+ :MenuROE()
+ :MenuEvasion()
local EscortGroupGround2 = SpawnEscortGround:ReSpawn(1)
- local EscortGround2 = ESCORT:New( Client, EscortGroupGround2, "Test Ground" )
+ local EscortGround2 = ESCORT
+ :New( Client, EscortGroupGround2, "Test Ground" )
+ :Menus()
local EscortGroupShip2 = SpawnEscortShip:ReSpawn(1)
- local EscortShip2 = ESCORT:New( Client, EscortGroupShip2, "Test Ship" )
+ local EscortShip2 = ESCORT
+ :New( Client, EscortGroupShip2, "Test Ship" )
+ :Menus()
end
SpawnEscortHeli = SPAWN:New( "Escort Helicopter" )
diff --git a/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz b/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz
index c0f47f112..2b8e5b658 100644
Binary files a/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz and b/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz differ
diff --git a/Tools and Installation/DCS World - MOOSE - Development - Part 2 - Using Eclipse and MOOSE.pptx b/Tools and Installation/DCS World - MOOSE - Development - Part 2 - Using Eclipse and MOOSE - Copy.pptx
similarity index 100%
rename from Tools and Installation/DCS World - MOOSE - Development - Part 2 - Using Eclipse and MOOSE.pptx
rename to Tools and Installation/DCS World - MOOSE - Development - Part 2 - Using Eclipse and MOOSE - Copy.pptx
diff --git a/Tools and Installation/DCS World - MOOSE - Escorting - Part 2 - APIs.pptx b/Tools and Installation/DCS World - MOOSE - Escorting - Part 2 - APIs.pptx
new file mode 100644
index 000000000..ccedaa222
Binary files /dev/null and b/Tools and Installation/DCS World - MOOSE - Escorting - Part 2 - APIs.pptx differ