-- New modules for CSAR tasking.

This commit is contained in:
FlightControl_Master 2018-03-31 07:35:18 +02:00
parent 1401bb29aa
commit a94e744028
6 changed files with 892 additions and 3 deletions

View File

@ -726,10 +726,9 @@ do -- TASK_CARGO
end
--- @param #TASK_CARGO self
-- @param @list<Core.Zone#ZONE> DeployZones
-- @param Wrapper.Unit#UNIT TaskUnit
-- @param #list<Core.Zone#ZONE> DeployZones
-- @return #TASK_CARGO
function TASK_CARGO:SetDeployZones( DeployZones, TaskUnit )
function TASK_CARGO:SetDeployZones( DeployZones )
for DeployZoneID, DeployZone in pairs( DeployZones ) do
self.DeployZones[DeployZone:GetName()] = DeployZone

View File

@ -0,0 +1,187 @@
--- **Tasking** -- Models tasks for players to execute CSAR @{Cargo} downed pilots.
--
-- ![Banner Image](..\Presentations\TASK_CARGO\Dia1.JPG)
--
-- ===
do -- TASK_CARGO_CSAR
--- The TASK_CARGO_CSAR class
-- @type TASK_CARGO_CSAR
-- @extends Tasking.Task_Cargo#TASK_CARGO
TASK_CARGO_CSAR = {
ClassName = "TASK_CARGO_CSAR",
}
--- Instantiates a new TASK_CARGO_CSAR.
-- @param #TASK_CARGO_CSAR self
-- @param Tasking.Mission#MISSION Mission
-- @param Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned.
-- @param #string TaskName The name of the Task.
-- @param Core.Set#SET_CARGO SetCargo The scope of the cargo to be transported.
-- @param #string TaskBriefing The Cargo Task briefing.
-- @return #TASK_CARGO_CSAR self
function TASK_CARGO_CSAR:New( Mission, SetGroup, TaskName, SetCargo, TaskBriefing )
local self = BASE:Inherit( self, TASK_CARGO:New( Mission, SetGroup, TaskName, SetCargo, "Transport", TaskBriefing ) ) -- #TASK_CARGO_CSAR
self:F()
Mission:AddTask( self )
-- Events
self:AddTransition( "*", "CargoPickedUp", "*" )
self:AddTransition( "*", "CargoDeployed", "*" )
self:F( { CargoDeployed = self.CargoDeployed ~= nil and "true" or "false" } )
--- OnBefore Transition Handler for Event CargoPickedUp.
-- @function [parent=#TASK_CARGO_CSAR] OnBeforeCargoPickedUp
-- @param #TASK_CARGO_CSAR self
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that PickedUp the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
-- @return #boolean Return false to cancel Transition.
--- OnAfter Transition Handler for Event CargoPickedUp.
-- @function [parent=#TASK_CARGO_CSAR] OnAfterCargoPickedUp
-- @param #TASK_CARGO_CSAR self
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that PickedUp the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
--- Synchronous Event Trigger for Event CargoPickedUp.
-- @function [parent=#TASK_CARGO_CSAR] CargoPickedUp
-- @param #TASK_CARGO_CSAR self
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that PickedUp the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
--- Asynchronous Event Trigger for Event CargoPickedUp.
-- @function [parent=#TASK_CARGO_CSAR] __CargoPickedUp
-- @param #TASK_CARGO_CSAR self
-- @param #number Delay The delay in seconds.
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that PickedUp the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
--- OnBefore Transition Handler for Event CargoDeployed.
-- @function [parent=#TASK_CARGO_CSAR] OnBeforeCargoDeployed
-- @param #TASK_CARGO_CSAR self
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that Deployed the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
-- @param Core.Zone#ZONE DeployZone The zone where the Cargo got Deployed or UnBoarded.
-- @return #boolean Return false to cancel Transition.
--- OnAfter Transition Handler for Event CargoDeployed.
-- @function [parent=#TASK_CARGO_CSAR] OnAfterCargoDeployed
-- @param #TASK_CARGO_CSAR self
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that Deployed the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
-- @param Core.Zone#ZONE DeployZone The zone where the Cargo got Deployed or UnBoarded.
--- Synchronous Event Trigger for Event CargoDeployed.
-- @function [parent=#TASK_CARGO_CSAR] CargoDeployed
-- @param #TASK_CARGO_CSAR self
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that Deployed the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
-- @param Core.Zone#ZONE DeployZone The zone where the Cargo got Deployed or UnBoarded.
--- Asynchronous Event Trigger for Event CargoDeployed.
-- @function [parent=#TASK_CARGO_CSAR] __CargoDeployed
-- @param #TASK_CARGO_CSAR self
-- @param #number Delay The delay in seconds.
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that Deployed the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
-- @param Core.Zone#ZONE DeployZone The zone where the Cargo got Deployed or UnBoarded.
local Fsm = self:GetUnitProcess()
local CargoReport = REPORT:New( "Rescue a downed pilot from the following position:")
SetCargo:ForEachCargo(
--- @param Core.Cargo#CARGO Cargo
function( Cargo )
local CargoType = Cargo:GetType()
local CargoName = Cargo:GetName()
local CargoCoordinate = Cargo:GetCoordinate()
CargoReport:Add( string.format( '- "%s" (%s) at %s', CargoName, CargoType, CargoCoordinate:ToStringMGRS() ) )
end
)
self:SetBriefing(
TaskBriefing or
CargoReport:Text()
)
return self
end
function TASK_CARGO_CSAR:ReportOrder( ReportGroup )
return 0
end
---
-- @param #TASK_CARGO_CSAR self
-- @return #boolean
function TASK_CARGO_CSAR:IsAllCargoTransported()
local CargoSet = self:GetCargoSet()
local Set = CargoSet:GetSet()
local DeployZones = self:GetDeployZones()
local CargoDeployed = true
-- Loop the CargoSet (so evaluate each Cargo in the SET_CARGO ).
for CargoID, CargoData in pairs( Set ) do
local Cargo = CargoData -- Core.Cargo#CARGO
self:F( { Cargo = Cargo:GetName(), CargoDeployed = Cargo:IsDeployed() } )
if Cargo:IsDeployed() then
-- -- Loop the DeployZones set for the TASK_CARGO_CSAR.
-- for DeployZoneID, DeployZone in pairs( DeployZones ) do
--
-- -- If all cargo is in one of the deploy zones, then all is good.
-- self:T( { Cargo.CargoObject } )
-- if Cargo:IsInZone( DeployZone ) == false then
-- CargoDeployed = false
-- end
-- end
else
CargoDeployed = false
end
end
self:F( { CargoDeployed = CargoDeployed } )
return CargoDeployed
end
--- @param #TASK_CARGO_CSAR self
function TASK_CARGO_CSAR:onafterGoal( TaskUnit, From, Event, To )
local CargoSet = self.CargoSet
if self:IsAllCargoTransported() then
self:Success()
end
self:__Goal( -10 )
end
end

View File

@ -0,0 +1,362 @@
--- **Tasking** - Creates and manages player TASK_CARGO tasks.
--
-- ===
--
-- ### Author: **FlightControl**
--
-- ### Contributions:
--
-- ===
--
-- @module Task_Cargo_Dispatcher
do -- TASK_CARGO_DISPATCHER
--- TASK_CARGO_DISPATCHER class.
-- @type TASK_CARGO_DISPATCHER
-- @extends Tasking.Task_Manager#TASK_MANAGER
-- @field TASK_CARGO_DISPATCHER.CSAR CSAR
--- @type TASK_CARGO_DISPATCHER.CSAR
-- @field Wrapper.Unit#UNIT PilotUnit
-- @field Tasking.Task#TASK Task
--- # TASK_CARGO_DISPATCHER class, extends @{Task_Manager#TASK_MANAGER}
--
-- ![Banner Image](..\Presentations\TASK_CARGO_DISPATCHER\Dia1.JPG)
--
-- The @{#TASK_CARGO_DISPATCHER} class implements the dynamic dispatching of cargo tasks.
--
-- ![Banner Image](..\Presentations\TASK_CARGO_DISPATCHER\Dia3.JPG)
--
-- The EWR will detect units, will group them, and will dispatch @{Task}s to groups. Depending on the type of target detected, different tasks will be dispatched.
-- Find a summary below describing for which situation a task type is created:
--
-- ![Banner Image](..\Presentations\TASK_CARGO_DISPATCHER\Dia9.JPG)
--
-- * **CSAR Task**: Is created when a fiendly pilot has ejected from a plane, and needs to be rescued (sometimes behind enemy lines).
--
-- ## 1. TASK\_A2A\_DISPATCHER constructor:
--
-- The @{#TASK_CARGO_DISPATCHER.New}() method creates a new TASK\_A2A\_DISPATCHER instance.
--
-- ### 1.1. Define or set the **Mission**:
--
-- Tasking is executed to accomplish missions. Therefore, a MISSION object needs to be given as the first parameter.
--
-- local HQ = GROUP:FindByName( "HQ", "Bravo" )
-- local CommandCenter = COMMANDCENTER:New( HQ, "Lima" )
-- local Mission = MISSION:New( CommandCenter, "A2A Mission", "High", "Watch the air enemy units being detected.", coalition.side.RED )
--
-- Missions are governed by COMMANDCENTERS, so, ensure you have a COMMANDCENTER object installed and setup within your mission.
-- Create the MISSION object, and hook it under the command center.
--
-- ### 1.2. Build a set of the groups seated by human players:
--
-- ![Banner Image](..\Presentations\TASK_CARGO_DISPATCHER\Dia6.JPG)
--
-- A set or collection of the groups wherein human players can be seated, these can be clients or units that can be joined as a slot or jumping into.
--
-- local AttackGroups = SET_GROUP:New():FilterCoalitions( "red" ):FilterPrefixes( "Defender" ):FilterStart()
--
-- The set is built using the SET_GROUP class. Apply any filter criteria to identify the correct groups for your mission.
-- Only these slots or units will be able to execute the mission and will receive tasks for this mission, once available.
--
-- ### 1.3. Define the **EWR network**:
--
-- As part of the TASK\_A2A\_DISPATCHER constructor, an EWR network must be given as the third parameter.
-- An EWR network, or, Early Warning Radar network, is used to early detect potential airborne targets and to understand the position of patrolling targets of the enemy.
--
-- ![Banner Image](..\Presentations\TASK_CARGO_DISPATCHER\Dia5.JPG)
--
-- Typically EWR networks are setup using 55G6 EWR, 1L13 EWR, Hawk sr and Patriot str ground based radar units.
-- These radars have different ranges and 55G6 EWR and 1L13 EWR radars are Eastern Bloc units (eg Russia, Ukraine, Georgia) while the Hawk and Patriot radars are Western (eg US).
-- Additionally, ANY other radar capable unit can be part of the EWR network! Also AWACS airborne units, planes, helicopters can help to detect targets, as long as they have radar.
-- The position of these units is very important as they need to provide enough coverage
-- to pick up enemy aircraft as they approach so that CAP and GCI flights can be tasked to intercept them.
--
-- ![Banner Image](..\Presentations\TASK_CARGO_DISPATCHER\Dia7.JPG)
--
-- Additionally in a hot war situation where the border is no longer respected the placement of radars has a big effect on how fast the war escalates.
-- For example if they are a long way forward and can detect enemy planes on the ground and taking off
-- they will start to vector CAP and GCI flights to attack them straight away which will immediately draw a response from the other coalition.
-- Having the radars further back will mean a slower escalation because fewer targets will be detected and
-- therefore less CAP and GCI flights will spawn and this will tend to make just the border area active rather than a melee over the whole map.
-- It all depends on what the desired effect is.
--
-- EWR networks are **dynamically constructed**, that is, they form part of the @{Functional#DETECTION_BASE} object that is given as the input parameter of the TASK\_A2A\_DISPATCHER class.
-- By defining in a **smart way the names or name prefixes of the groups** with EWR capable units, these groups will be **automatically added or deleted** from the EWR network,
-- increasing or decreasing the radar coverage of the Early Warning System.
--
-- See the following example to setup an EWR network containing EWR stations and AWACS.
--
-- local EWRSet = SET_GROUP:New():FilterPrefixes( "EWR" ):FilterCoalitions("red"):FilterStart()
--
-- local EWRDetection = DETECTION_AREAS:New( EWRSet, 6000 )
-- EWRDetection:SetFriendliesRange( 10000 )
-- EWRDetection:SetRefreshTimeInterval(30)
--
-- -- Setup the A2A dispatcher, and initialize it.
-- A2ADispatcher = TASK_CARGO_DISPATCHER:New( Mission, AttackGroups, EWRDetection )
--
-- The above example creates a SET_GROUP instance, and stores this in the variable (object) **EWRSet**.
-- **EWRSet** is then being configured to filter all active groups with a group name starting with **EWR** to be included in the Set.
-- **EWRSet** is then being ordered to start the dynamic filtering. Note that any destroy or new spawn of a group with the above names will be removed or added to the Set.
-- Then a new **EWRDetection** object is created from the class DETECTION_AREAS. A grouping radius of 6000 is choosen, which is 6km.
-- The **EWRDetection** object is then passed to the @{#TASK_CARGO_DISPATCHER.New}() method to indicate the EWR network configuration and setup the A2A tasking and detection mechanism.
--
-- ### 2. Define the detected **target grouping radius**:
--
-- ![Banner Image](..\Presentations\TASK_CARGO_DISPATCHER\Dia8.JPG)
--
-- The target grouping radius is a property of the Detection object, that was passed to the AI\_A2A\_DISPATCHER object, but can be changed.
-- The grouping radius should not be too small, but also depends on the types of planes and the era of the simulation.
-- Fast planes like in the 80s, need a larger radius than WWII planes.
-- Typically I suggest to use 30000 for new generation planes and 10000 for older era aircraft.
--
-- Note that detected targets are constantly re-grouped, that is, when certain detected aircraft are moving further than the group radius, then these aircraft will become a separate
-- group being detected. This may result in additional GCI being started by the dispatcher! So don't make this value too small!
--
-- ## 3. Set the **Engage radius**:
--
-- Define the radius to engage any target by airborne friendlies, which are executing cap or returning from an intercept mission.
--
-- ![Banner Image](..\Presentations\TASK_CARGO_DISPATCHER\Dia11.JPG)
--
-- So, if there is a target area detected and reported,
-- then any friendlies that are airborne near this target area,
-- will be commanded to (re-)engage that target when available (if no other tasks were commanded).
-- For example, if 100000 is given as a value, then any friendly that is airborne within 100km from the detected target,
-- will be considered to receive the command to engage that target area.
-- You need to evaluate the value of this parameter carefully.
-- If too small, more intercept missions may be triggered upon detected target areas.
-- If too large, any airborne cap may not be able to reach the detected target area in time, because it is too far.
--
-- ## 4. Set **Scoring** and **Messages**:
--
-- The TASK\_A2A\_DISPATCHER is a state machine. It triggers the event Assign when a new player joins a @{Task} dispatched by the TASK\_A2A\_DISPATCHER.
-- An _event handler_ can be defined to catch the **Assign** event, and add **additional processing** to set _scoring_ and to _define messages_,
-- when the player reaches certain achievements in the task.
--
-- The prototype to handle the **Assign** event needs to be developed as follows:
--
-- TaskDispatcher = TASK_CARGO_DISPATCHER:New( ... )
--
-- --- @param #TaskDispatcher self
-- -- @param #string From Contains the name of the state from where the Event was triggered.
-- -- @param #string Event Contains the name of the event that was triggered. In this case Assign.
-- -- @param #string To Contains the name of the state that will be transitioned to.
-- -- @param Tasking.Task_A2A#TASK_A2A Task The Task object, which is any derived object from TASK_A2A.
-- -- @param Wrapper.Unit#UNIT TaskUnit The Unit or Client that contains the Player.
-- -- @param #string PlayerName The name of the Player that joined the TaskUnit.
-- function TaskDispatcher:OnAfterAssign( From, Event, To, Task, TaskUnit, PlayerName )
-- Task:SetScoreOnProgress( PlayerName, 20, TaskUnit )
-- Task:SetScoreOnSuccess( PlayerName, 200, TaskUnit )
-- Task:SetScoreOnFail( PlayerName, -100, TaskUnit )
-- end
--
-- The **OnAfterAssign** method (function) is added to the TaskDispatcher object.
-- This method will be called when a new player joins a unit in the set of groups in scope of the dispatcher.
-- So, this method will be called only **ONCE** when a player joins a unit in scope of the task.
--
-- The TASK class implements various methods to additional **set scoring** for player achievements:
--
-- * @{Tasking.Task#TASK.SetScoreOnProgress}() will add additional scores when a player achieves **Progress** while executing the task.
-- Examples of **task progress** can be destroying units, arriving at zones etc.
--
-- * @{Tasking.Task#TASK.SetScoreOnSuccess}() will add additional scores when the task goes into **Success** state.
-- This means the **task has been successfully completed**.
--
-- * @{Tasking.Task#TASK.SetScoreOnSuccess}() will add additional (negative) scores when the task goes into **Failed** state.
-- This means the **task has not been successfully completed**, and the scores must be given with a negative value!
--
-- @field #TASK_CARGO_DISPATCHER
TASK_CARGO_DISPATCHER = {
ClassName = "TASK_CARGO_DISPATCHER",
Mission = nil,
Tasks = {},
CSAR = {},
}
--- TASK_CARGO_DISPATCHER constructor.
-- @param #TASK_CARGO_DISPATCHER self
-- @param Tasking.Mission#MISSION Mission The mission for which the task dispatching is done.
-- @param Set#SET_GROUP SetGroup The set of groups that can join the tasks within the mission.
-- @return #TASK_CARGO_DISPATCHER self
function TASK_CARGO_DISPATCHER:New( Mission, SetGroup )
-- Inherits from DETECTION_MANAGER
local self = BASE:Inherit( self, TASK_MANAGER:New( SetGroup ) ) -- #TASK_CARGO_DISPATCHER
self.Mission = Mission
self:AddTransition( "Started", "Assign", "Started" )
--- OnAfter Transition Handler for Event Assign.
-- @function [parent=#TASK_CARGO_DISPATCHER] OnAfterAssign
-- @param #TASK_CARGO_DISPATCHER self
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @param Tasking.Task_A2A#TASK_A2A Task
-- @param Wrapper.Unit#UNIT TaskUnit
-- @param #string PlayerName
self:SetCSARRadius()
self:__Start( 5 )
-- For CSAR missions, we process the event when a pilot ejects.
self:HandleEvent( EVENTS.Ejection )
return self
end
--- Handle the event when a pilot ejects.
-- @param #TASK_CARGO_DISPATCHER self
-- @param Core.Event#EVENTDATA EventData
function TASK_CARGO_DISPATCHER:OnEventEjection( EventData )
self:E( { EventData = EventData } )
local PilotUnit = EventData.IniUnit
local CSARName = EventData.IniUnitName
self.CSAR[CSARName] = {}
self.CSAR[CSARName].PilotUnit = PilotUnit
self.CSAR[CSARName].Task = nil
return self
end
--- Define the radius to when a CSAR task will be generated for any downed pilot within range of the nearest CSAR airbase.
-- @param #TASK_CARGO_DISPATCHER self
-- @param #number CSARRadius (Optional, Default = 50000) The radius in meters to decide whether a CSAR needs to be created.
-- @return #TASK_CARGO_DISPATCHER
-- @usage
--
-- -- Set 20km as the radius to CSAR any downed pilot within range of the nearest CSAR airbase.
-- TaskA2ADispatcher:SetEngageRadius( 20000 )
--
-- -- Set 50km as the radius to to CSAR any downed pilot within range of the nearest CSAR airbase.
-- TaskA2ADispatcher:SetEngageRadius() -- 50000 is the default value.
--
function TASK_CARGO_DISPATCHER:SetCSARRadius( CSARRadius )
self.Detection:SetFriendliesRange( CSARRadius or 50000 )
return self
end
--- Define one deploy zone for the CSAR tasks.
-- @param #TASK_CARGO_DISPATCHER self
-- @param DeployZone A deploy zone.
-- @return #TASK_CARGO_DISPATCHER
function TASK_CARGO_DISPATCHER:SetCSARDeployZone( CSARDeployZone )
self.CSARDeployZones = { CSARDeployZone }
return self
end
--- Define the deploy zones for the CSAR tasks.
-- @param #TASK_CARGO_DISPATCHER self
-- @param DeployZones A list of the deploy zones.
-- @return #TASK_CARGO_DISPATCHER
function TASK_CARGO_DISPATCHER:SetCSARDeployZones( CSARDeployZones )
self.CSARDeployZones = CSARDeployZones
return self
end
--- Evaluates of a CSAR task needs to be started.
-- @param #TASK_CARGO_DISPATCHER self
-- @return Set#SET_CARGO The SetCargo to be rescued.
-- @return #nil If there is no CSAR task required.
function TASK_CARGO_DISPATCHER:EvaluateCSAR( CSARUnit )
local CSARCargo = CARGO_UNIT:New( CSARUnit, "Pilot", CSARUnit:GetName(), 80, 1500, 10 )
local SetCargo = SET_CARGO:New()
SetCargo:AddCargosByName( CSARUnit:GetName() )
SetCargo:Flush(self)
return SetCargo
end
--- Assigns tasks to the @{Set#SET_GROUP}.
-- @param #TASK_CARGO_DISPATCHER self
-- @return #boolean Return true if you want the task assigning to continue... false will cancel the loop.
function TASK_CARGO_DISPATCHER:ManageTasks()
self:F()
local AreaMsg = {}
local TaskMsg = {}
local ChangeMsg = {}
local Mission = self.Mission
if Mission:IsIDLE() or Mission:IsENGAGED() then
local TaskReport = REPORT:New()
-- Checking the task queue for the dispatcher, and removing any obsolete task!
for TaskIndex, TaskData in pairs( self.Tasks ) do
local Task = TaskData -- Tasking.Task#TASK
if Task:IsStatePlanned() then
-- Here we need to check if the pilot is still existing.
-- local DetectedItem = Detection:GetDetectedItemByIndex( TaskIndex )
-- if not DetectedItem then
-- local TaskText = Task:GetName()
-- for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
-- Mission:GetCommandCenter():MessageToGroup( string.format( "Obsolete A2A task %s for %s removed.", TaskText, Mission:GetShortText() ), TaskGroup )
-- end
-- Task = self:RemoveTask( TaskIndex )
-- end
end
end
-- Now that all obsolete tasks are removed, loop through the CSAR pilots.
for CSARID, CSARData in pairs( self.CSAR ) do
if CSARData.Task then
else
-- New CSAR Task
local SetCargo = self:EvaluateCSAR( CSARData.PilotUnit )
local CSARTask = TASK_CARGO_CSAR:New( Mission, self.SetGroup, "Rescue Pilot", SetCargo )
CSARTask:SetDeployZones( { self.CSARDeployZones } )
Mission:AddTask( CSARTask )
TaskReport:Add( CSARTask:GetName() )
end
end
-- TODO set menus using the HQ coordinator
Mission:GetCommandCenter():SetMenu()
local TaskText = TaskReport:Text(", ")
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
if ( not Mission:IsGroupAssigned(TaskGroup) ) and TaskText ~= "" then
Mission:GetCommandCenter():MessageToGroup( string.format( "%s has tasks %s. Subscribe to a task using the radio menu.", Mission:GetShortText(), TaskText ), TaskGroup )
end
end
end
return true
end
end

View File

@ -0,0 +1,187 @@
--- **Tasking** -- The TASK_CARGO models tasks for players to transport @{Cargo}.
--
-- ![Banner Image](..\Presentations\TASK_CARGO\Dia1.JPG)
--
-- ===
do -- TASK_CARGO_TRANSPORT
--- The TASK_CARGO_TRANSPORT class
-- @type TASK_CARGO_TRANSPORT
-- @extends Tasking.Task_Cargo#TASK_CARGO
TASK_CARGO_TRANSPORT = {
ClassName = "TASK_CARGO_TRANSPORT",
}
--- Instantiates a new TASK_CARGO_TRANSPORT.
-- @param #TASK_CARGO_TRANSPORT self
-- @param Tasking.Mission#MISSION Mission
-- @param Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned.
-- @param #string TaskName The name of the Task.
-- @param Core.Set#SET_CARGO SetCargo The scope of the cargo to be transported.
-- @param #string TaskBriefing The Cargo Task briefing.
-- @return #TASK_CARGO_TRANSPORT self
function TASK_CARGO_TRANSPORT:New( Mission, SetGroup, TaskName, SetCargo, TaskBriefing )
local self = BASE:Inherit( self, TASK_CARGO:New( Mission, SetGroup, TaskName, SetCargo, "Transport", TaskBriefing ) ) -- #TASK_CARGO_TRANSPORT
self:F()
Mission:AddTask( self )
-- Events
self:AddTransition( "*", "CargoPickedUp", "*" )
self:AddTransition( "*", "CargoDeployed", "*" )
self:F( { CargoDeployed = self.CargoDeployed ~= nil and "true" or "false" } )
--- OnBefore Transition Handler for Event CargoPickedUp.
-- @function [parent=#TASK_CARGO_TRANSPORT] OnBeforeCargoPickedUp
-- @param #TASK_CARGO_TRANSPORT self
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that PickedUp the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
-- @return #boolean Return false to cancel Transition.
--- OnAfter Transition Handler for Event CargoPickedUp.
-- @function [parent=#TASK_CARGO_TRANSPORT] OnAfterCargoPickedUp
-- @param #TASK_CARGO_TRANSPORT self
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that PickedUp the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
--- Synchronous Event Trigger for Event CargoPickedUp.
-- @function [parent=#TASK_CARGO_TRANSPORT] CargoPickedUp
-- @param #TASK_CARGO_TRANSPORT self
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that PickedUp the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
--- Asynchronous Event Trigger for Event CargoPickedUp.
-- @function [parent=#TASK_CARGO_TRANSPORT] __CargoPickedUp
-- @param #TASK_CARGO_TRANSPORT self
-- @param #number Delay The delay in seconds.
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that PickedUp the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
--- OnBefore Transition Handler for Event CargoDeployed.
-- @function [parent=#TASK_CARGO_TRANSPORT] OnBeforeCargoDeployed
-- @param #TASK_CARGO_TRANSPORT self
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that Deployed the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
-- @param Core.Zone#ZONE DeployZone The zone where the Cargo got Deployed or UnBoarded.
-- @return #boolean Return false to cancel Transition.
--- OnAfter Transition Handler for Event CargoDeployed.
-- @function [parent=#TASK_CARGO_TRANSPORT] OnAfterCargoDeployed
-- @param #TASK_CARGO_TRANSPORT self
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that Deployed the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
-- @param Core.Zone#ZONE DeployZone The zone where the Cargo got Deployed or UnBoarded.
--- Synchronous Event Trigger for Event CargoDeployed.
-- @function [parent=#TASK_CARGO_TRANSPORT] CargoDeployed
-- @param #TASK_CARGO_TRANSPORT self
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that Deployed the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
-- @param Core.Zone#ZONE DeployZone The zone where the Cargo got Deployed or UnBoarded.
--- Asynchronous Event Trigger for Event CargoDeployed.
-- @function [parent=#TASK_CARGO_TRANSPORT] __CargoDeployed
-- @param #TASK_CARGO_TRANSPORT self
-- @param #number Delay The delay in seconds.
-- @param Wrapper.Unit#UNIT TaskUnit The Unit (Client) that Deployed the cargo. You can use this to retrieve the PlayerName etc.
-- @param Core.Cargo#CARGO Cargo The Cargo that got PickedUp by the TaskUnit. You can use this to check Cargo Status.
-- @param Core.Zone#ZONE DeployZone The zone where the Cargo got Deployed or UnBoarded.
local Fsm = self:GetUnitProcess()
local CargoReport = REPORT:New( "Transport Cargo. The following cargo needs to be transported including initial positions:")
SetCargo:ForEachCargo(
--- @param Core.Cargo#CARGO Cargo
function( Cargo )
local CargoType = Cargo:GetType()
local CargoName = Cargo:GetName()
local CargoCoordinate = Cargo:GetCoordinate()
CargoReport:Add( string.format( '- "%s" (%s) at %s', CargoName, CargoType, CargoCoordinate:ToStringMGRS() ) )
end
)
self:SetBriefing(
TaskBriefing or
CargoReport:Text()
)
return self
end
function TASK_CARGO_TRANSPORT:ReportOrder( ReportGroup )
return 0
end
---
-- @param #TASK_CARGO_TRANSPORT self
-- @return #boolean
function TASK_CARGO_TRANSPORT:IsAllCargoTransported()
local CargoSet = self:GetCargoSet()
local Set = CargoSet:GetSet()
local DeployZones = self:GetDeployZones()
local CargoDeployed = true
-- Loop the CargoSet (so evaluate each Cargo in the SET_CARGO ).
for CargoID, CargoData in pairs( Set ) do
local Cargo = CargoData -- Core.Cargo#CARGO
self:F( { Cargo = Cargo:GetName(), CargoDeployed = Cargo:IsDeployed() } )
if Cargo:IsDeployed() then
-- -- Loop the DeployZones set for the TASK_CARGO_TRANSPORT.
-- for DeployZoneID, DeployZone in pairs( DeployZones ) do
--
-- -- If all cargo is in one of the deploy zones, then all is good.
-- self:T( { Cargo.CargoObject } )
-- if Cargo:IsInZone( DeployZone ) == false then
-- CargoDeployed = false
-- end
-- end
else
CargoDeployed = false
end
end
self:F( { CargoDeployed = CargoDeployed } )
return CargoDeployed
end
--- @param #TASK_CARGO_TRANSPORT self
function TASK_CARGO_TRANSPORT:onafterGoal( TaskUnit, From, Event, To )
local CargoSet = self.CargoSet
if self:IsAllCargoTransported() then
self:Success()
end
self:__Goal( -10 )
end
end

View File

@ -0,0 +1,150 @@
--- This module contains the TASK_MANAGER class and derived classes.
--
-- ===
--
-- 1) @{Task_Manager#TASK_MANAGER} class, extends @{Fsm#FSM}
-- ===
-- The @{Task_Manager#TASK_MANAGER} class defines the core functions to report tasks to groups.
-- Reportings can be done in several manners, and it is up to the derived classes if TASK_MANAGER to model the reporting behaviour.
--
-- 1.1) TASK_MANAGER constructor:
-- -----------------------------------
-- * @{Task_Manager#TASK_MANAGER.New}(): Create a new TASK_MANAGER instance.
--
-- 1.2) TASK_MANAGER reporting:
-- ---------------------------------
-- Derived TASK_MANAGER classes will manage tasks using the method @{Task_Manager#TASK_MANAGER.ManageTasks}(). This method implements polymorphic behaviour.
--
-- The time interval in seconds of the task management can be changed using the methods @{Task_Manager#TASK_MANAGER.SetRefreshTimeInterval}().
-- To control how long a reporting message is displayed, use @{Task_Manager#TASK_MANAGER.SetReportDisplayTime}().
-- Derived classes need to implement the method @{Task_Manager#TASK_MANAGER.GetReportDisplayTime}() to use the correct display time for displayed messages during a report.
--
-- Task management can be started and stopped using the methods @{Task_Manager#TASK_MANAGER.StartTasks}() and @{Task_Manager#TASK_MANAGER.StopTasks}() respectively.
-- If an ad-hoc report is requested, use the method @{Task_Manager#TASK_MANAGER#ManageTasks}().
--
-- The default task management interval is every 60 seconds.
--
-- ===
--
-- ### Contributions: Mechanist, Prof_Hilactic, FlightControl - Concept & Testing
-- ### Author: FlightControl - Framework Design & Programming
--
-- @module Task_Manager
do -- TASK_MANAGER
--- TASK_MANAGER class.
-- @type TASK_MANAGER
-- @field Set#SET_GROUP SetGroup The set of group objects containing players for which tasks are managed.
-- @extends Core.Fsm#FSM
TASK_MANAGER = {
ClassName = "TASK_MANAGER",
SetGroup = nil,
}
--- TASK\_MANAGER constructor.
-- @param #TASK_MANAGER self
-- @param Set#SET_GROUP SetGroup The set of group objects containing players for which tasks are managed.
-- @return #TASK_MANAGER self
function TASK_MANAGER:New( SetGroup )
-- Inherits from BASE
local self = BASE:Inherit( self, FSM:New() ) -- #TASK_MANAGER
self.SetGroup = SetGroup
self:SetStartState( "Stopped" )
self:AddTransition( "Stopped", "StartTasks", "Started" )
--- StartTasks Handler OnBefore for TASK_MANAGER
-- @function [parent=#TASK_MANAGER] OnBeforeStartTasks
-- @param #TASK_MANAGER self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #boolean
--- StartTasks Handler OnAfter for TASK_MANAGER
-- @function [parent=#TASK_MANAGER] OnAfterStartTasks
-- @param #TASK_MANAGER self
-- @param #string From
-- @param #string Event
-- @param #string To
--- StartTasks Trigger for TASK_MANAGER
-- @function [parent=#TASK_MANAGER] StartTasks
-- @param #TASK_MANAGER self
--- StartTasks Asynchronous Trigger for TASK_MANAGER
-- @function [parent=#TASK_MANAGER] __StartTasks
-- @param #TASK_MANAGER self
-- @param #number Delay
self:AddTransition( "Started", "StopTasks", "Stopped" )
--- StopTasks Handler OnBefore for TASK_MANAGER
-- @function [parent=#TASK_MANAGER] OnBeforeStopTasks
-- @param #TASK_MANAGER self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #boolean
--- StopTasks Handler OnAfter for TASK_MANAGER
-- @function [parent=#TASK_MANAGER] OnAfterStopTasks
-- @param #TASK_MANAGER self
-- @param #string From
-- @param #string Event
-- @param #string To
--- StopTasks Trigger for TASK_MANAGER
-- @function [parent=#TASK_MANAGER] StopTasks
-- @param #TASK_MANAGER self
--- StopTasks Asynchronous Trigger for TASK_MANAGER
-- @function [parent=#TASK_MANAGER] __StopTasks
-- @param #TASK_MANAGER self
-- @param #number Delay
self:AddTransition( "Started", "Manage", "Started" )
self:SetRefreshTimeInterval( 30 )
return self
end
function TASK_MANAGER:onafterStartTasks( From, Event, To )
self:Report()
end
function TASK_MANAGER:onafterManage( From, Event, To )
self:__Manage( -self._RefreshTimeInterval )
self:ManageTasks()
end
--- Set the refresh time interval in seconds when a new task management action needs to be done.
-- @param #TASK_MANAGER self
-- @param #number RefreshTimeInterval The refresh time interval in seconds when a new task management action needs to be done.
-- @return #TASK_MANAGER self
function TASK_MANAGER:SetRefreshTimeInterval( RefreshTimeInterval )
self:F2()
self._RefreshTimeInterval = RefreshTimeInterval
end
--- Manages the tasks for the @{Set#SET_GROUP}.
-- @param #TASK_MANAGER self
-- @return #TASK_MANAGER self
function TASK_MANAGER:ManageTasks()
self:E()
end
end

View File

@ -76,12 +76,16 @@ Tasking/CommandCenter.lua
Tasking/Mission.lua
Tasking/Task.lua
Tasking/TaskInfo.lua
Tasking/Task_Manager.lua
Tasking/DetectionManager.lua
Tasking/Task_A2G_Dispatcher.lua
Tasking/Task_A2G.lua
Tasking/Task_A2A_Dispatcher.lua
Tasking/Task_A2A.lua
Tasking/Task_Cargo.lua
Tasking/Task_Cargo_Transport.lua
Tasking/Task_Cargo_CSAR.lua
Tasking/Task_Cargo_Dispatcher.lua
Tasking/TaskZoneCapture.lua
Moose.lua