Auto assignment of tasks with prioritization of an auto assign method. The default assign method is random, which is set at the command center. Each task type implements a prioritization mechanism which calculates the priotity of the task based on various methods: random, distance or priority. The distance is calculated from the task coordinate from the command center location.

Also fixed in a first try the route bug on Controllables.
This commit is contained in:
FlightControl 2019-03-10 16:41:53 +01:00
parent afc918c5e5
commit 925ce3ad63
7 changed files with 133 additions and 10 deletions

View File

@ -175,6 +175,14 @@ COMMANDCENTER = {
CommunicationMode = "80", CommunicationMode = "80",
} }
--- @type COMMANDCENTER.AutoAssignMethods
COMMANDCENTER.AutoAssignMethods = {
["Random"] = 1,
["Distance"] = 2,
["Priority"] = 3
}
--- The constructor takes an IDENTIFIABLE as the HQ command center. --- The constructor takes an IDENTIFIABLE as the HQ command center.
-- @param #COMMANDCENTER self -- @param #COMMANDCENTER self
-- @param Wrapper.Positionable#POSITIONABLE CommandCenterPositionable -- @param Wrapper.Positionable#POSITIONABLE CommandCenterPositionable
@ -192,6 +200,7 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
self:SetAutoAssignTasks( false ) self:SetAutoAssignTasks( false )
self:SetAutoAcceptTasks( true ) self:SetAutoAcceptTasks( true )
self:SetAutoAssignMethod( COMMANDCENTER.AutoAssignMethods.Random )
self:HandleEvent( EVENTS.Birth, self:HandleEvent( EVENTS.Birth,
--- @param #COMMANDCENTER self --- @param #COMMANDCENTER self
@ -462,7 +471,7 @@ function COMMANDCENTER:GetMenu( TaskGroup )
self.CommandCenterMenus[TaskGroup] = CommandCenterMenu self.CommandCenterMenus[TaskGroup] = CommandCenterMenu
if self.AutoAssignTasks == false then if self.AutoAssignTasks == false then
local AssignTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, "Assign Task", CommandCenterMenu, self.AssignRandomTask, self, TaskGroup ):SetTime(MenuTime):SetTag("AutoTask") local AssignTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, "Assign Task", CommandCenterMenu, self.AssignTask, self, TaskGroup ):SetTime(MenuTime):SetTag("AutoTask")
end end
CommandCenterMenu:Remove( MenuTime, "AutoTask" ) CommandCenterMenu:Remove( MenuTime, "AutoTask" )
@ -473,22 +482,33 @@ end
--- Assigns a random task to a TaskGroup. --- Assigns a random task to a TaskGroup.
-- @param #COMMANDCENTER self -- @param #COMMANDCENTER self
-- @return #COMMANDCENTER -- @return #COMMANDCENTER
function COMMANDCENTER:AssignRandomTask( TaskGroup ) function COMMANDCENTER:AssignTask( TaskGroup )
local Tasks = {} local Tasks = {}
local AssignPriority = 99999999
local AutoAssignMethod = self.AutoAssignMethod
for MissionID, Mission in pairs( self:GetMissions() ) do for MissionID, Mission in pairs( self:GetMissions() ) do
local Mission = Mission -- Tasking.Mission#MISSION local Mission = Mission -- Tasking.Mission#MISSION
local MissionTasks = Mission:GetGroupTasks( TaskGroup ) local MissionTasks = Mission:GetGroupTasks( TaskGroup )
for MissionTaskName, MissionTask in pairs( MissionTasks or {} ) do for MissionTaskName, MissionTask in pairs( MissionTasks or {} ) do
Tasks[#Tasks+1] = MissionTask local TaskPriority = MissionTask:GetAutoAssignPriority( self.AutoAssignMethod, self, TaskGroup )
if TaskPriority < AssignPriority then
AssignPriority = TaskPriority
Tasks = {}
end
if TaskPriority == AssignPriority then
Tasks[#Tasks+1] = MissionTask
end
end end
end end
local Task = Tasks[ math.random( 1, #Tasks ) ] -- Tasking.Task#TASK local Task = Tasks[ math.random( 1, #Tasks ) ] -- Tasking.Task#TASK
self:I( "Assigning task " .. Task:GetName() .. " using auto assign method " .. self.AutoAssignMethod .. " to " .. TaskGroup:GetName() .. " with task priority " .. AssignPriority )
if not self.AutoAcceptTasks == true then if not self.AutoAcceptTasks == true then
Task:SetAssignMethod( ACT_ASSIGN_MENU_ACCEPT:New( Task.TaskBriefing ) ) Task:SetAutoAssignMethod( ACT_ASSIGN_MENU_ACCEPT:New( Task.TaskBriefing ) )
end end
Task:AssignToGroup( TaskGroup ) Task:AssignToGroup( TaskGroup )
@ -551,6 +571,24 @@ function COMMANDCENTER:SetAutoAcceptTasks( AutoAccept )
end end
--- Define the method to be used to assign automatically a task from the available tasks in the mission.
-- There are 3 types of methods that can be applied for the moment:
--
-- 1. Random - assigns a random task in the mission to the player.
-- 2. Distance - assigns a task based on a distance evaluation from the player. The closest are to be assigned first.
-- 3. Priority - assigns a task based on the priority as defined by the mission designer, using the SetTaskPriority parameter.
--
-- The different task classes implement the logic to determine the priority of automatic task assignment to a player, depending on one of the above methods.
-- The method @{Tasking.Task#TASK.GetAutoAssignPriority} calculate the priority of the tasks to be assigned.
-- @param #COMMANDCENTER self
-- @param #COMMANDCENTER.AutoAssignMethods AutoAssignMethod A selection of an assign method from the COMMANDCENTER.AutoAssignMethods enumeration.
function COMMANDCENTER:SetAutoAssignMethod( AutoAssignMethod )
self.AutoAssignMethod = AutoAssignMethod or COMMANDCENTER.AutoAssignMethods.Random
end
--- Automatically assigns tasks to all TaskGroups. --- Automatically assigns tasks to all TaskGroups.
-- @param #COMMANDCENTER self -- @param #COMMANDCENTER self
function COMMANDCENTER:AssignTasks() function COMMANDCENTER:AssignTasks()
@ -568,7 +606,7 @@ function COMMANDCENTER:AssignTasks()
-- Only groups with planes or helicopters will receive automatic tasks. -- Only groups with planes or helicopters will receive automatic tasks.
-- TODO Workaround DCS-BUG-3 - https://github.com/FlightControl-Master/MOOSE/issues/696 -- TODO Workaround DCS-BUG-3 - https://github.com/FlightControl-Master/MOOSE/issues/696
if TaskGroup:IsAir() then if TaskGroup:IsAir() then
self:AssignRandomTask( TaskGroup ) self:AssignTask( TaskGroup )
end end
end end
end end

View File

@ -130,6 +130,15 @@ function TASKINFO:AddCoordinate( Coordinate, Order, Detail, Keep )
end end
--- Get the Coordinate.
-- @param #TASKINFO self
-- @return Core.Point#COORDINATE Coordinate
function TASKINFO:GetCoordinate()
return self:GetData( "Coordinate" )
end
--- Add Coordinates. --- Add Coordinates.
-- @param #TASKINFO self -- @param #TASKINFO self
-- @param #list<Core.Point#COORDINATE> Coordinates -- @param #list<Core.Point#COORDINATE> Coordinates

View File

@ -351,6 +351,26 @@ do -- TASK_A2A
end end
end end
--- This function is called from the @{Tasking.CommandCenter#COMMANDCENTER} to determine the method of automatic task selection.
-- @param #TASK_A2A self
-- @param #number AutoAssignMethod The method to be applied to the task.
-- @param Tasking.CommandCenter#COMMANDCENTER CommandCenter The command center.
-- @param Wrapper.Group#GROUP TaskGroup The player group.
function TASK_A2A:GetAutoAssignPriority( AutoAssignMethod, CommandCenter, TaskGroup )
if AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Random then
return math.random( 1, 9 )
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Distance then
local Coordinate = self.TaskInfo:GetData( "Coordinate" )
local Distance = TaskGroup:GetCoordinate():Get2DDistance( CommandCenter:GetPositionable():GetCoordinate() )
return math.floor( Distance )
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Priority then
return 1
end
return 0
end
end end

View File

@ -356,6 +356,26 @@ do -- TASK_A2G
end end
--- This function is called from the @{Tasking.CommandCenter#COMMANDCENTER} to determine the method of automatic task selection.
-- @param #TASK_A2G self
-- @param #number AutoAssignMethod The method to be applied to the task.
-- @param Tasking.CommandCenter#COMMANDCENTER CommandCenter The command center.
-- @param Wrapper.Group#GROUP TaskGroup The player group.
function TASK_A2G:GetAutoAssignPriority( AutoAssignMethod, CommandCenter, TaskGroup )
if AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Random then
return math.random( 1, 9 )
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Distance then
local Coordinate = self.TaskInfo:GetData( "Coordinate" )
local Distance = TaskGroup:GetCoordinate():Get2DDistance( CommandCenter:GetPositionable():GetCoordinate() )
return math.floor( Distance )
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Priority then
return 1
end
return 0
end
end end

View File

@ -1382,6 +1382,23 @@ do -- TASK_CARGO
return 0 return 0
end end
--- This function is called from the @{Tasking.CommandCenter#COMMANDCENTER} to determine the method of automatic task selection.
-- @param #TASK_CARGO self
-- @param #number AutoAssignMethod The method to be applied to the task.
-- @param Wrapper.Group#GROUP TaskGroup The player group.
function TASK_CARGO:GetAutoAssignPriority( AutoAssignMethod, TaskGroup )
if AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Random then
return math.random( 1, 9 )
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Distance then
return 0
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Priority then
return 1
end
return 0
end
end end

View File

@ -221,7 +221,6 @@ do -- TASK_CAPTURE_ZONE
-- @param #TASK_CAPTURE_ZONE self -- @param #TASK_CAPTURE_ZONE self
function TASK_CAPTURE_ZONE:UpdateTaskInfo() function TASK_CAPTURE_ZONE:UpdateTaskInfo()
local ZoneCoordinate = self.ZoneGoal:GetZone():GetCoordinate() local ZoneCoordinate = self.ZoneGoal:GetZone():GetCoordinate()
self.TaskInfo:AddCoordinate( ZoneCoordinate, 0, "SOD" ) self.TaskInfo:AddCoordinate( ZoneCoordinate, 0, "SOD" )
self.TaskInfo:AddText( "Zone Name", self.ZoneGoal:GetZoneName(), 10, "MOD" ) self.TaskInfo:AddText( "Zone Name", self.ZoneGoal:GetZoneName(), 10, "MOD" )
@ -230,8 +229,8 @@ do -- TASK_CAPTURE_ZONE
function TASK_CAPTURE_ZONE:ReportOrder( ReportGroup ) function TASK_CAPTURE_ZONE:ReportOrder( ReportGroup )
local Coordinate = self.TaskInfo:GetData( "Coordinate" )
--local Coordinate = self.TaskInfo.Coordinates.TaskInfoText local Coordinate = self.TaskInfo:GetCoordinate()
local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate ) local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate )
return Distance return Distance
@ -262,5 +261,25 @@ do -- TASK_CAPTURE_ZONE
self:__Goal( -10, PlayerUnit, PlayerName ) self:__Goal( -10, PlayerUnit, PlayerName )
end end
--- This function is called from the @{Tasking.CommandCenter#COMMANDCENTER} to determine the method of automatic task selection.
-- @param #TASK_CAPTURE_ZONE self
-- @param #number AutoAssignMethod The method to be applied to the task.
-- @param Tasking.CommandCenter#COMMANDCENTER CommandCenter The command center.
-- @param Wrapper.Group#GROUP TaskGroup The player group.
function TASK_CAPTURE_ZONE:GetAutoAssignPriority( AutoAssignMethod, CommandCenter, TaskGroup )
if AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Random then
return math.random( 1, 9 )
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Distance then
local Coordinate = self.TaskInfo:GetCoordinate()
local Distance = TaskGroup:GetCoordinate():Get2DDistance( CommandCenter:GetPositionable():GetCoordinate() )
return math.floor( Distance )
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Priority then
return 1
end
return 0
end
end end

View File

@ -2355,7 +2355,7 @@ do -- Route methods
-- Calculate the direct distance between the initial and final points. -- Calculate the direct distance between the initial and final points.
local LengthDirect=FromCoordinate:Get2DDistance(ToCoordinate) local LengthDirect=FromCoordinate:Get2DDistance(ToCoordinate)
if GotPath then if GotPath and LengthRoad then
-- Off road part of the rout: Total=OffRoad+OnRoad. -- Off road part of the rout: Total=OffRoad+OnRoad.
LengthOffRoad=LengthOnRoad-LengthRoad LengthOffRoad=LengthOnRoad-LengthRoad
@ -2378,7 +2378,7 @@ do -- Route methods
local canroad=false local canroad=false
-- Check if a valid path on road could be found. -- Check if a valid path on road could be found.
if GotPath and LengthDirect > 2000 then -- if the length of the movement is less than 1 km, drive directly. if GotPath and LengthRoad and LengthDirect > 2000 then -- if the length of the movement is less than 1 km, drive directly.
-- Check whether the road is very long compared to direct path. -- Check whether the road is very long compared to direct path.
if LongRoad and Shortcut then if LongRoad and Shortcut then