mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
-- Added a scoring tailoring possibility for TASK_DISPATCHER class tasks. -- DETECTION_MANAGER has become an FSM -- TASK_A2G_DISPATCHER has become an FSM. It implements an Assign Event, that can be handled. In the Assign event handler, you can specify scoring schemes etc.
439 lines
17 KiB
Lua
439 lines
17 KiB
Lua
--- **Tasking** - The TASK_A2G models tasks for players in Air to Ground engagements.
|
|
--
|
|
-- 
|
|
--
|
|
--
|
|
-- # 1) @{Task_A2G#TASK_A2G} class, extends @{Task#TASK}
|
|
--
|
|
-- The @{#TASK_A2G} class defines Air To Ground tasks for a @{Set} of Target Units,
|
|
-- based on the tasking capabilities defined in @{Task#TASK}.
|
|
-- The TASK_A2G is implemented using a @{Statemachine#FSM_TASK}, and has the following statuses:
|
|
--
|
|
-- * **None**: Start of the process
|
|
-- * **Planned**: The A2G task is planned.
|
|
-- * **Assigned**: The A2G task is assigned to a @{Group#GROUP}.
|
|
-- * **Success**: The A2G task is successfully completed.
|
|
-- * **Failed**: The A2G task has failed. This will happen if the player exists the task early, without communicating a possible cancellation to HQ.
|
|
--
|
|
-- # 1.1) Set the scoring of achievements in an A2G attack.
|
|
--
|
|
-- Scoring or penalties can be given in the following circumstances:
|
|
--
|
|
-- * @{#TASK_A2G.SetScoreOnDestroy}(): Set a score when a target in scope of the A2G attack, has been destroyed.
|
|
-- * @{#TASK_A2G.SetScoreOnSuccess}(): Set a score when all the targets in scope of the A2G attack, have been destroyed.
|
|
-- * @{#TASK_A2G.SetPenaltyOnFailed}(): Set a penalty when the A2G attack has failed.
|
|
--
|
|
-- # 2) @{Task_A2G#TASK_SEAD} class, extends @{Task_A2G#TASK_A2G}
|
|
--
|
|
-- The @{#TASK_SEAD} class defines a SEAD task for a @{Set} of Target Units.
|
|
--
|
|
-- ===
|
|
--
|
|
-- # 3) @{Task_A2G#TASK_CAS} class, extends @{Task_A2G#TASK_A2G}
|
|
--
|
|
-- The @{#TASK_CAS} class defines a CAS task for a @{Set} of Target Units.
|
|
--
|
|
-- ===
|
|
--
|
|
-- # 4) @{Task_A2G#TASK_BAI} class, extends @{Task_A2G#TASK_A2G}
|
|
--
|
|
-- The @{#TASK_BAI} class defines a BAI task for a @{Set} of Target Units.
|
|
--
|
|
-- ====
|
|
--
|
|
-- # **API CHANGE HISTORY**
|
|
--
|
|
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
|
--
|
|
-- * **Added** parts are expressed in bold type face.
|
|
-- * _Removed_ parts are expressed in italic type face.
|
|
--
|
|
-- Hereby the change log:
|
|
--
|
|
-- 2017-03-09: Revised version.
|
|
--
|
|
-- ===
|
|
--
|
|
-- # **AUTHORS and CONTRIBUTIONS**
|
|
--
|
|
-- ### Contributions:
|
|
--
|
|
-- * **[WingThor]**: Concept, Advice & Testing.
|
|
--
|
|
-- ### Authors:
|
|
--
|
|
-- * **FlightControl**: Concept, Design & Programming.
|
|
--
|
|
-- @module Task_A2G
|
|
|
|
do -- TASK_A2G
|
|
|
|
--- The TASK_A2G class
|
|
-- @type TASK_A2G
|
|
-- @field Set#SET_UNIT TargetSetUnit
|
|
-- @extends Tasking.Task#TASK
|
|
TASK_A2G = {
|
|
ClassName = "TASK_A2G",
|
|
}
|
|
|
|
--- Instantiates a new TASK_A2G.
|
|
-- @param #TASK_A2G 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 Set#SET_UNIT UnitSetTargets
|
|
-- @param #number TargetDistance The distance to Target when the Player is considered to have "arrived" at the engagement range.
|
|
-- @param Core.Zone#ZONE_BASE TargetZone The target zone, if known.
|
|
-- If the TargetZone parameter is specified, the player will be routed to the center of the zone where all the targets are assumed to be.
|
|
-- @return #TASK_A2G self
|
|
function TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskType )
|
|
local self = BASE:Inherit( self, TASK:New( Mission, SetGroup, TaskName, TaskType ) ) -- Tasking.Task#TASK_A2G
|
|
self:F()
|
|
|
|
self.TargetSetUnit = TargetSetUnit
|
|
self.TaskType = TaskType
|
|
|
|
Mission:AddTask( self )
|
|
|
|
local Fsm = self:GetUnitProcess()
|
|
|
|
|
|
Fsm:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "RouteToRendezVous", Rejected = "Reject" } )
|
|
|
|
Fsm:AddTransition( "Assigned", "RouteToRendezVous", "RoutingToRendezVous" )
|
|
Fsm:AddProcess ( "RoutingToRendezVous", "RouteToRendezVousPoint", ACT_ROUTE_POINT:New(), { Arrived = "ArriveAtRendezVous" } )
|
|
Fsm:AddProcess ( "RoutingToRendezVous", "RouteToRendezVousZone", ACT_ROUTE_ZONE:New(), { Arrived = "ArriveAtRendezVous" } )
|
|
|
|
Fsm:AddTransition( { "Arrived", "RoutingToRendezVous" }, "ArriveAtRendezVous", "ArrivedAtRendezVous" )
|
|
|
|
Fsm:AddTransition( { "ArrivedAtRendezVous", "HoldingAtRendezVous" }, "Engage", "Engaging" )
|
|
Fsm:AddTransition( { "ArrivedAtRendezVous", "HoldingAtRendezVous" }, "HoldAtRendezVous", "HoldingAtRendezVous" )
|
|
|
|
Fsm:AddProcess ( "Engaging", "Account", ACT_ACCOUNT_DEADS:New( self.TargetSetUnit, self.TaskType ), { Accounted = "Success" } )
|
|
Fsm:AddTransition( "Engaging", "RouteToTarget", "Engaging" )
|
|
Fsm:AddProcess( "Engaging", "RouteToTargetZone", ACT_ROUTE_ZONE:New(), {} )
|
|
Fsm:AddProcess( "Engaging", "RouteToTargetPoint", ACT_ROUTE_POINT:New(), {} )
|
|
Fsm:AddTransition( "Engaging", "RouteToTargets", "Engaging" )
|
|
|
|
Fsm:AddTransition( "Accounted", "DestroyedAll", "Accounted" )
|
|
Fsm:AddTransition( "Accounted", "Success", "Success" )
|
|
Fsm:AddTransition( "Rejected", "Reject", "Aborted" )
|
|
Fsm:AddTransition( "Failed", "Fail", "Failed" )
|
|
|
|
|
|
--- Test
|
|
-- @param #FSM_PROCESS self
|
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
|
-- @param Tasking.Task_A2G#TASK_A2G Task
|
|
function Fsm:onafterRouteToRendezVous( TaskUnit, Task )
|
|
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
|
-- Determine the first Unit from the self.RendezVousSetUnit
|
|
|
|
if Task:GetRendezVousZone( TaskUnit ) then
|
|
self:__RouteToRendezVousZone( 0.1 )
|
|
else
|
|
if Task:GetRendezVousPointVec2( TaskUnit ) then
|
|
self:__RouteToRendezVousPoint( 0.1 )
|
|
else
|
|
self:__ArriveAtRendezVous( 0.1 )
|
|
end
|
|
end
|
|
end
|
|
|
|
--- Test
|
|
-- @param #FSM_PROCESS self
|
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
|
-- @param Tasking.Task#TASK_A2G Task
|
|
function Fsm:OnAfterArriveAtRendezVous( TaskUnit, Task )
|
|
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
|
-- Determine the first Unit from the self.TargetSetUnit
|
|
|
|
self:__Engage( 0.1 )
|
|
end
|
|
|
|
--- Test
|
|
-- @param #FSM_PROCESS self
|
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
|
-- @param Tasking.Task#TASK_A2G Task
|
|
function Fsm:onafterEngage( TaskUnit, Task )
|
|
self:E( { self } )
|
|
self:__Account( 0.1 )
|
|
self:__RouteToTarget(0.1 )
|
|
self:__RouteToTargets( -10 )
|
|
end
|
|
|
|
--- Test
|
|
-- @param #FSM_PROCESS self
|
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
|
-- @param Tasking.Task_A2G#TASK_A2G Task
|
|
function Fsm:onafterRouteToTarget( TaskUnit, Task )
|
|
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
|
-- Determine the first Unit from the self.TargetSetUnit
|
|
|
|
if Task:GetTargetZone( TaskUnit ) then
|
|
self:__RouteToTargetZone( 0.1 )
|
|
else
|
|
local TargetUnit = Task.TargetSetUnit:GetFirst() -- Wrapper.Unit#UNIT
|
|
if TargetUnit then
|
|
local PointVec2 = TargetUnit:GetPointVec2()
|
|
self:T( { TargetPointVec2 = PointVec2, PointVec2:GetX(), PointVec2:GetAlt(), PointVec2:GetZ() } )
|
|
Task:SetTargetPointVec2( TargetUnit:GetPointVec2(), TaskUnit )
|
|
end
|
|
self:__RouteToTargetPoint( 0.1 )
|
|
end
|
|
end
|
|
|
|
--- Test
|
|
-- @param #FSM_PROCESS self
|
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
|
-- @param Tasking.Task_A2G#TASK_A2G Task
|
|
function Fsm:onafterRouteToTargets( TaskUnit, Task )
|
|
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
|
local TargetUnit = Task.TargetSetUnit:GetFirst() -- Wrapper.Unit#UNIT
|
|
if TargetUnit then
|
|
Task:SetTargetPointVec2( TargetUnit:GetPointVec2(), TaskUnit )
|
|
end
|
|
self:__RouteToTargets( -10 )
|
|
end
|
|
|
|
return self
|
|
|
|
end
|
|
|
|
--- @param #TASK_A2G self
|
|
function TASK_A2G:GetPlannedMenuText()
|
|
return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.TargetSetUnit:GetUnitTypesText() .. " )"
|
|
end
|
|
|
|
--- @param #TASK_A2G self
|
|
-- @param Core.Point#POINT_VEC2 RendezVousPointVec2 The PointVec2 object referencing to the 2D point where the RendezVous point is located on the map.
|
|
-- @param #number RendezVousRange The RendezVousRange that defines when the player is considered to have arrived at the RendezVous point.
|
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
|
function TASK_A2G:SetRendezVousPointVec2( RendezVousPointVec2, RendezVousRange, TaskUnit )
|
|
|
|
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
|
|
|
local ActRouteRendezVous = ProcessUnit:GetProcess( "RoutingToRendezVous", "RouteToRendezVousPoint" ) -- Actions.Act_Route#ACT_ROUTE_POINT
|
|
ActRouteRendezVous:SetPointVec2( RendezVousPointVec2 )
|
|
ActRouteRendezVous:SetRange( RendezVousRange )
|
|
end
|
|
|
|
--- @param #TASK_A2G self
|
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
|
-- @return Core.Point#POINT_VEC2 The PointVec2 object referencing to the 2D point where the RendezVous point is located on the map.
|
|
-- @return #number The RendezVousRange that defines when the player is considered to have arrived at the RendezVous point.
|
|
function TASK_A2G:GetRendezVousPointVec2( TaskUnit )
|
|
|
|
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
|
|
|
local ActRouteRendezVous = ProcessUnit:GetProcess( "RoutingToRendezVous", "RouteToRendezVousPoint" ) -- Actions.Act_Route#ACT_ROUTE_POINT
|
|
return ActRouteRendezVous:GetPointVec2(), ActRouteRendezVous:GetRange()
|
|
end
|
|
|
|
|
|
|
|
--- @param #TASK_A2G self
|
|
-- @param Core.Zone#ZONE_BASE RendezVousZone The Zone object where the RendezVous is located on the map.
|
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
|
function TASK_A2G:SetRendezVousZone( RendezVousZone, TaskUnit )
|
|
|
|
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
|
|
|
local ActRouteRendezVous = ProcessUnit:GetProcess( "RoutingToRendezVous", "RouteToRendezVousZone" ) -- Actions.Act_Route#ACT_ROUTE_ZONE
|
|
ActRouteRendezVous:SetZone( RendezVousZone )
|
|
end
|
|
|
|
--- @param #TASK_A2G self
|
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
|
-- @return Core.Zone#ZONE_BASE The Zone object where the RendezVous is located on the map.
|
|
function TASK_A2G:GetRendezVousZone( TaskUnit )
|
|
|
|
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
|
|
|
local ActRouteRendezVous = ProcessUnit:GetProcess( "RoutingToRendezVous", "RouteToRendezVousZone" ) -- Actions.Act_Route#ACT_ROUTE_ZONE
|
|
return ActRouteRendezVous:GetZone()
|
|
end
|
|
|
|
--- @param #TASK_A2G self
|
|
-- @param Core.Point#POINT_VEC2 TargetPointVec2 The PointVec2 object where the Target is located on the map.
|
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
|
function TASK_A2G:SetTargetPointVec2( TargetPointVec2, TaskUnit )
|
|
|
|
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
|
|
|
local ActRouteTarget = ProcessUnit:GetProcess( "Engaging", "RouteToTargetPoint" ) -- Actions.Act_Route#ACT_ROUTE_POINT
|
|
ActRouteTarget:SetPointVec2( TargetPointVec2 )
|
|
end
|
|
|
|
|
|
--- @param #TASK_A2G self
|
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
|
-- @return Core.Point#POINT_VEC2 The PointVec2 object where the Target is located on the map.
|
|
function TASK_A2G:GetTargetPointVec2( TaskUnit )
|
|
|
|
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
|
|
|
local ActRouteTarget = ProcessUnit:GetProcess( "Engaging", "RouteToTargetPoint" ) -- Actions.Act_Route#ACT_ROUTE_POINT
|
|
return ActRouteTarget:GetPointVec2()
|
|
end
|
|
|
|
|
|
--- @param #TASK_A2G self
|
|
-- @param Core.Zone#ZONE_BASE TargetZone The Zone object where the Target is located on the map.
|
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
|
function TASK_A2G:SetTargetZone( TargetZone, TaskUnit )
|
|
|
|
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
|
|
|
local ActRouteTarget = ProcessUnit:GetProcess( "Engaging", "RouteToTargetZone" ) -- Actions.Act_Route#ACT_ROUTE_ZONE
|
|
ActRouteTarget:SetZone( TargetZone )
|
|
end
|
|
|
|
|
|
--- @param #TASK_A2G self
|
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
|
-- @return Core.Zone#ZONE_BASE The Zone object where the Target is located on the map.
|
|
function TASK_A2G:GetTargetZone( TaskUnit )
|
|
|
|
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
|
|
|
local ActRouteTarget = ProcessUnit:GetProcess( "Engaging", "RouteToTargetZone" ) -- Actions.Act_Route#ACT_ROUTE_ZONE
|
|
return ActRouteTarget:GetZone()
|
|
end
|
|
|
|
--- Set a score when a target in scope of the A2G attack, has been destroyed .
|
|
-- @param #TASK_A2G self
|
|
-- @param #string Text The text to display to the player, when the target has been destroyed.
|
|
-- @param #number Score The score in points.
|
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
|
-- @return #TASK_A2G
|
|
function TASK_A2G:SetScoreOnDestroy( Text, Score, TaskUnit )
|
|
|
|
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
|
|
|
ProcessUnit:AddScoreProcess( "Engaging", "Account", "Account", Text, Score )
|
|
|
|
return self
|
|
end
|
|
|
|
--- Set a score when all the targets in scope of the A2G attack, have been destroyed.
|
|
-- @param #TASK_A2G self
|
|
-- @param #string Text The text to display to the player, when all targets hav been destroyed.
|
|
-- @param #number Score The score in points.
|
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
|
-- @return #TASK_A2G
|
|
function TASK_A2G:SetScoreOnSuccess( Text, Score, TaskUnit )
|
|
|
|
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
|
|
|
ProcessUnit:AddScore( "Success", Text, Score )
|
|
|
|
return self
|
|
end
|
|
|
|
--- Set a penalty when the A2G attack has failed.
|
|
-- @param #TASK_A2G self
|
|
-- @param #string Text The text to display to the player, when the A2G attack has failed.
|
|
-- @param #number Penalty The penalty in points.
|
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
|
-- @return #TASK_A2G
|
|
function TASK_A2G:SetPenaltyOnFailed( Text, Penalty, TaskUnit )
|
|
|
|
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
|
|
|
ProcessUnit:AddScore( "Failed", Text, Penalty )
|
|
|
|
return self
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
do -- TASK_SEAD
|
|
|
|
--- The TASK_SEAD class
|
|
-- @type TASK_SEAD
|
|
-- @field Set#SET_UNIT TargetSetUnit
|
|
-- @extends Tasking.Task#TASK
|
|
TASK_SEAD = {
|
|
ClassName = "TASK_SEAD",
|
|
}
|
|
|
|
--- Instantiates a new TASK_SEAD.
|
|
-- @param #TASK_SEAD 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 Set#SET_UNIT UnitSetTargets
|
|
-- @param #number TargetDistance The distance to Target when the Player is considered to have "arrived" at the engagement range.
|
|
-- @param Core.Zone#ZONE_BASE TargetZone The target zone, if known.
|
|
-- If the TargetZone parameter is specified, the player will be routed to the center of the zone where all the targets are assumed to be.
|
|
-- @return #TASK_SEAD self
|
|
function TASK_SEAD:New( Mission, SetGroup, TaskName, TargetSetUnit )
|
|
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "SEAD" ) ) -- #TASK_SEAD
|
|
self:F()
|
|
|
|
return self
|
|
end
|
|
|
|
end
|
|
|
|
do -- TASK_BAI
|
|
|
|
--- The TASK_BAI class
|
|
-- @type TASK_BAI
|
|
-- @field Set#SET_UNIT TargetSetUnit
|
|
-- @extends Tasking.Task#TASK
|
|
TASK_BAI = {
|
|
ClassName = "TASK_BAI",
|
|
}
|
|
|
|
--- Instantiates a new TASK_BAI.
|
|
-- @param #TASK_BAI 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 Set#SET_UNIT UnitSetTargets
|
|
-- @param #number TargetDistance The distance to Target when the Player is considered to have "arrived" at the engagement range.
|
|
-- @param Core.Zone#ZONE_BASE TargetZone The target zone, if known.
|
|
-- If the TargetZone parameter is specified, the player will be routed to the center of the zone where all the targets are assumed to be.
|
|
-- @return #TASK_BAI self
|
|
function TASK_BAI:New( Mission, SetGroup, TaskName, TargetSetUnit )
|
|
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "BAI" ) ) -- #TASK_BAI
|
|
self:F()
|
|
|
|
return self
|
|
end
|
|
|
|
end
|
|
|
|
do -- TASK_CAS
|
|
|
|
--- The TASK_CAS class
|
|
-- @type TASK_CAS
|
|
-- @field Set#SET_UNIT TargetSetUnit
|
|
-- @extends Tasking.Task#TASK
|
|
TASK_CAS = {
|
|
ClassName = "TASK_CAS",
|
|
}
|
|
|
|
--- Instantiates a new TASK_CAS.
|
|
-- @param #TASK_CAS 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 Set#SET_UNIT UnitSetTargets
|
|
-- @param #number TargetDistance The distance to Target when the Player is considered to have "arrived" at the engagement range.
|
|
-- @param Core.Zone#ZONE_BASE TargetZone The target zone, if known.
|
|
-- If the TargetZone parameter is specified, the player will be routed to the center of the zone where all the targets are assumed to be.
|
|
-- @return #TASK_CAS self
|
|
function TASK_CAS:New( Mission, SetGroup, TaskName, TargetSetUnit )
|
|
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "CAS" ) ) -- #TASK_CAS
|
|
self:F()
|
|
|
|
return self
|
|
end
|
|
|
|
end
|