This commit is contained in:
Sven Van de Velde 2016-04-17 11:44:04 +02:00
parent 90827d5c35
commit a8f51751f1

View File

@ -2909,7 +2909,7 @@ function BASE:F( Arguments )
if DebugInfoFrom then
LineFrom = DebugInfoFrom.currentline
end
env.info( string.format( "%6d\(%6d\)/%1s:%20s%05d.%s\(%s\)" , LineCurrent, LineFrom, "F", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
env.info( string.format( "%6d(%6d)/%1s:%20s%05d.%s(%s)" , LineCurrent, LineFrom, "F", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
end
end
end
@ -2957,7 +2957,7 @@ function BASE:T( Arguments )
if DebugInfoFrom then
LineFrom = DebugInfoFrom.currentline
end
env.info( string.format( "%6d\(%6d\)/%1s:%20s%05d.%s" , LineCurrent, LineFrom, "T", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) )
env.info( string.format( "%6d(%6d)/%1s:%20s%05d.%s" , LineCurrent, LineFrom, "T", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) )
end
end
end
@ -3000,7 +3000,7 @@ function BASE:E( Arguments )
local LineCurrent = DebugInfoCurrent.currentline
local LineFrom = DebugInfoFrom.currentline
env.info( string.format( "%6d\(%6d\)/%1s:%20s%05d.%s\(%s\)" , LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
env.info( string.format( "%6d(%6d)/%1s:%20s%05d.%s(%s)" , LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
end
@ -5849,7 +5849,7 @@ function DATABASE:ScoreOpen()
if not self.StatFile then
error( "Error: Cannot open 'Player Scores.csv' file in " .. lfs.writedir() )
end
self.StatFile:write( '"RunID";"Time";"PlayerName";"ScoreType";"PlayerUnitCoaltion";"PlayerUnitCategory";"PlayerUnitType";"PlayerUnitName";"TargetUnitCoalition";"TargetUnitCategory";"TargetUnitType";"TargetUnitName";"Times";"Score"\n' )
self.StatFile:write( '"RunID","Time","PlayerName","ScoreType","PlayerUnitCoaltion","PlayerUnitCategory","PlayerUnitType","PlayerUnitName","TargetUnitCoalition","TargetUnitCategory","TargetUnitType","TargetUnitName","Times","Score"\n' )
self.RunID = os.date("%y-%m-%d_%H-%M-%S")
end
@ -5907,10 +5907,23 @@ function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, Play
end
if lfs then
self.StatFile:write( '"' .. self.RunID .. '";' .. ScoreTime .. ';"' .. PlayerName .. '";"' .. ScoreType .. '";"' ..
PlayerUnitCoalition .. '";"' .. PlayerUnitCategory .. '";"' .. PlayerUnitType .. '";"' .. PlayerUnitName .. '";"' ..
TargetUnitCoalition .. '";"' .. TargetUnitCategory .. '";"' .. TargetUnitType .. '";"' .. TargetUnitName .. '";' ..
ScoreTimes .. ';' .. ScoreAmount )
self.StatFile:write(
'"' .. self.RunID .. '"' .. ',' ..
'' .. ScoreTime .. '' .. ',' ..
'"' .. PlayerName .. '"' .. ',' ..
'"' .. ScoreType .. '"' .. ',' ..
'"' .. PlayerUnitCoalition .. '"' .. ',' ..
'"' .. PlayerUnitCategory .. '"' .. ',' ..
'"' .. PlayerUnitType .. '"' .. ',' ..
'"' .. PlayerUnitName .. '"' .. ',' ..
'"' .. TargetUnitCoalition .. '"' .. ',' ..
'"' .. TargetUnitCategory .. '"' .. ',' ..
'"' .. TargetUnitType .. '"' .. ',' ..
'"' .. TargetUnitName .. '"' .. ',' ..
'' .. ScoreTimes .. '' .. ',' ..
'' .. ScoreAmount
)
self.StatFile:write( "\n" )
end
end
@ -12128,51 +12141,51 @@ end
--
-- **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. 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.
-- * **"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.
-- --------------------------------------
@ -12182,8 +12195,20 @@ end
--
-- 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
@ -12201,6 +12226,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.
@ -12211,6 +12237,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,
@ -12219,6 +12250,11 @@ ESCORT = {
TaskPoints = {}
}
--- ESCORT.Mode class
-- @type ESCORT.MODE
-- @field #number FOLLOW
-- @field #number MISSION
--- MENUPARAM type
-- @type MENUPARAM
-- @field #ESCORT ParamSelf
@ -12253,29 +12289,318 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing )
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 } )
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
self.EscortMenuFlare = MENU_CLIENT:New( self.EscortClient, "Flare", self.EscortMenuReportNavigation, ESCORT._Flare, { ParamSelf = self } )
--- 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
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
if EscortGroup:IsGround() or EscortGroup:IsShip() then
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!" } )
@ -12283,78 +12608,127 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing )
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
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 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 )
end
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, } )
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 } )
end
-- Attack Targets
self.EscortMenuAttackNearbyTargets = MENU_CLIENT:New( self.EscortClient, "Attack targets", self.EscortMenu )
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 )
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 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!" } )
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 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!" } )
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 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!!" } )
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
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!" } )
end
return self
end
--- 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 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!" } )
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 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!" } )
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
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
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 the escort mission", self.EscortMenu )
self.EscortMenuResumeMission = MENU_CLIENT:New( self.EscortClient, "Resume mission from", self.EscortMenu )
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
)
return self
end
@ -12365,47 +12739,40 @@ function ESCORT._HoldPosition( MenuParam )
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
@ -12415,9 +12782,9 @@ function ESCORT._JoinUpAndFollow( MenuParam )
local EscortGroup = self.EscortGroup
local EscortClient = self.EscortClient
local Distance = MenuParam.ParamDistance
self.Distance = MenuParam.ParamDistance
self:JoinUpAndFollow( EscortGroup, EscortClient, Distance )
self:JoinUpAndFollow( EscortGroup, EscortClient, self.Distance )
end
--- JoinsUp and Follows a CLIENT.
@ -12435,6 +12802,8 @@ function ESCORT:JoinUpAndFollow( EscortGroup, EscortClient, Distance )
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 )
@ -12538,12 +12907,23 @@ function ESCORT._ScanTargets( MenuParam )
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 )
@ -12560,13 +12940,14 @@ function ESCORT._AttackTarget( MenuParam )
if EscortGroup:IsAir() then
EscortGroup:OptionROEOpenFire()
EscortGroup:OptionROTVertical()
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
@ -12585,10 +12966,6 @@ function ESCORT._AttackTarget( MenuParam )
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
@ -12872,7 +13249,10 @@ function ESCORT:_ReportTargetsScheduler()
-- Remove the sub menus of the Attack menu of the Escort for the EscortGroup.
self.EscortMenuAttackNearbyTargets:RemoveSubMenus()
if self.EscortMenuTargetAssistance then
self.EscortMenuTargetAssistance:RemoveSubMenus()
end
--for MenuIndex = 1, #self.EscortMenuAttackTargets do
-- self:T( { "Remove Menu:", self.EscortMenuAttackTargets[MenuIndex] } )
@ -12926,6 +13306,7 @@ function ESCORT:_ReportTargetsScheduler()
)
EscortTargetMessages = EscortTargetMessages .. "\n - " .. EscortTargetMessage
else
if self.EscortMenuTargetAssistance then
local MenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, EscortGroupData.EscortName, self.EscortMenuTargetAssistance )
MENU_CLIENT_COMMAND:New( self.EscortClient,
EscortTargetMessage,
@ -12937,6 +13318,7 @@ function ESCORT:_ReportTargetsScheduler()
}
)
end
end
else
ClientEscortTargetData = nil
end
@ -12950,6 +13332,7 @@ function ESCORT:_ReportTargetsScheduler()
end
end
if self.EscortMenuResumeMission then
self.EscortMenuResumeMission:RemoveSubMenus()
-- if self.EscortMenuResumeWayPoints then
@ -12967,6 +13350,7 @@ function ESCORT:_ReportTargetsScheduler()
) ^ 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
routines.removeFunction( self.ReportTargetsScheduler )