Merge branch 'develop' into FF/Ops

This commit is contained in:
Frank 2022-07-31 01:13:53 +02:00
commit 200631e57e

View File

@ -67,7 +67,7 @@ PLAYERTASK = {
--- PLAYERTASK class version. --- PLAYERTASK class version.
-- @field #string version -- @field #string version
PLAYERTASK.version="0.0.6" PLAYERTASK.version="0.0.7"
--- Generic task condition. --- Generic task condition.
-- @type PLAYERTASK.Condition -- @type PLAYERTASK.Condition
@ -151,7 +151,7 @@ function PLAYERTASK:_SetController(Controller)
return self return self
end end
--- [User] Check is task is done --- [User] Check if task is done
-- @param #PLAYERTASK self -- @param #PLAYERTASK self
-- @return #boolean done -- @return #boolean done
function PLAYERTASK:IsDone() function PLAYERTASK:IsDone()
@ -164,6 +164,24 @@ function PLAYERTASK:IsDone()
return IsDone return IsDone
end end
--- [User] Get clients assigned list as table
-- @param #PLAYERTASK self
-- @return #table clients
function PLAYERTASK:GetClients()
self:I(self.lid.."GetClients?")
local clientlist = self.Clients:GetIDStackSorted() or {}
return clientlist
end
--- [User] Check if a player name is assigned to this task
-- @param #PLAYERTASK self
-- @param #string Name
-- @return #boolean HasName
function PLAYERTASK:HasPlayerName(Name)
self:I(self.lid.."HasPlayerName?")
return self.Clients:HasUniqueID(Name)
end
--- [User] Add a client to this task --- [User] Add a client to this task
-- @param #PLAYERTASK self -- @param #PLAYERTASK self
-- @param Wrapper.Client#CLIENT Client -- @param Wrapper.Client#CLIENT Client
@ -187,6 +205,9 @@ function PLAYERTASK:RemoveClient(Client)
local name = Client:GetPlayerName() local name = Client:GetPlayerName()
if self.Clients:HasUniqueID(name) then if self.Clients:HasUniqueID(name) then
self.Clients:PullByID(name) self.Clients:PullByID(name)
if self.verbose then
self.Clients:Flush()
end
self:__ClientRemoved(-2,Client) self:__ClientRemoved(-2,Client)
if self.Clients:Count() == 0 then if self.Clients:Count() == 0 then
self:__Failed(-1) self:__Failed(-1)
@ -555,6 +576,7 @@ end
-- @field #string Name -- @field #string Name
-- @field #string Type -- @field #string Type
-- @field #boolean UseGroupNames -- @field #boolean UseGroupNames
-- @field #table PlayerMenu
-- --
@ -567,6 +589,7 @@ PLAYERTASKCONTROLLER = {
TargetQueue = nil, TargetQueue = nil,
ClientSet = nil, ClientSet = nil,
UseGroupNames = true, UseGroupNames = true,
PlayerMenu = {},
} }
--- ---
@ -579,7 +602,7 @@ PLAYERTASKCONTROLLER.Type = {
--- PLAYERTASK class version. --- PLAYERTASK class version.
-- @field #string version -- @field #string version
PLAYERTASKCONTROLLER.version="0.0.4" PLAYERTASKCONTROLLER.version="0.0.7"
--- Constructor --- Constructor
-- @param #PLAYERTASKCONTROLLER self -- @param #PLAYERTASKCONTROLLER self
@ -602,6 +625,7 @@ function PLAYERTASKCONTROLLER:New(Name, Coalition, Type, ClientFilter)
self.TargetQueue = FIFO:New() -- Utilities.FiFo#FIFO self.TargetQueue = FIFO:New() -- Utilities.FiFo#FIFO
self.TaskQueue = FIFO:New() -- Utilities.FiFo#FIFO self.TaskQueue = FIFO:New() -- Utilities.FiFo#FIFO
self.TasksPerPlayer = FIFO:New() -- Utilities.FiFo#FIFO self.TasksPerPlayer = FIFO:New() -- Utilities.FiFo#FIFO
self.PlayerMenu = {} -- #table
self.repeatonfailed = true self.repeatonfailed = true
self.repeattimes = 5 self.repeattimes = 5
@ -620,6 +644,7 @@ function PLAYERTASKCONTROLLER:New(Name, Coalition, Type, ClientFilter)
self:AddTransition("Stopped", "Start", "Running") self:AddTransition("Stopped", "Start", "Running")
self:AddTransition("*", "Status", "*") self:AddTransition("*", "Status", "*")
self:AddTransition("*", "TaskAdded", "*")
self:AddTransition("*", "TaskDone", "*") self:AddTransition("*", "TaskDone", "*")
self:AddTransition("*", "TaskCancelled", "*") self:AddTransition("*", "TaskCancelled", "*")
self:AddTransition("*", "TaskSuccess", "*") self:AddTransition("*", "TaskSuccess", "*")
@ -630,11 +655,47 @@ function PLAYERTASKCONTROLLER:New(Name, Coalition, Type, ClientFilter)
self:__Start(-1) self:__Start(-1)
self:__Status(-2) self:__Status(-2)
-- Player leaves
self:HandleEvent(EVENTS.PlayerLeaveUnit, self._EventHandler)
self:HandleEvent(EVENTS.Ejection, self._EventHandler)
self:HandleEvent(EVENTS.Crash, self._EventHandler)
self:HandleEvent(EVENTS.PilotDead, self._EventHandler)
self:I(self.lid.."Started.") self:I(self.lid.."Started.")
return self return self
end end
--- [internal] Event handling
-- @param #PLAYERTASKCONTROLLER self
-- @param Core.Event#EVENTDATA EventData
-- @return #PLAYERTASKCONTROLLER self
function PLAYERTASKCONTROLLER:_EventHandler(EventData)
self:I(self.lid.."_EventHandler: "..EventData.id)
if EventData.id == EVENTS.PlayerLeaveUnit or EventData.id == EVENTS.Ejection or EventData.id == EVENTS.Crash or EventData.id == EVENTS.PilotDead then
if EventData.IniPlayerName then
self:I(self.lid.."Event for player: "..EventData.IniPlayerName)
if self.PlayerMenu[EventData.IniPlayerName] then
self.PlayerMenu[EventData.IniPlayerName]:Remove()
self.PlayerMenu[EventData.IniPlayerName] = nil
end
local text = ""
if self.TasksPerPlayer:HasUniqueID(EventData.IniPlayerName) then
local task = self.TasksPerPlayer:PullByID(EventData.IniPlayerName) -- Ops.PlayerTask#PLAYERTASK
local Client = _DATABASE:FindClient( EventData.IniPlayerName )
if Client then
task:RemoveClient(Client)
text = "Task aborted!"
end
else
text = "No active task!"
end
self:I(self.lid..text)
end
end
return self
end
function PLAYERTASKCONTROLLER:_DummyMenu(group) function PLAYERTASKCONTROLLER:_DummyMenu(group)
self:I(self.lid.."_DummyMenu") self:I(self.lid.."_DummyMenu")
return self return self
@ -718,7 +779,7 @@ function PLAYERTASKCONTROLLER:_CheckTaskQueue()
self:I("Looking at Task: "..data.PlayerTaskNr.." Type: "..data.Type.." State: "..data:GetState()) self:I("Looking at Task: "..data.PlayerTaskNr.." Type: "..data.Type.." State: "..data:GetState())
if data:GetState() == "Done" or data:GetState() == "Stopped" then if data:GetState() == "Done" or data:GetState() == "Stopped" then
local task = self.TaskQueue:ReadByID(_id) -- Ops.PlayerTask#PLAYERTASK local task = self.TaskQueue:ReadByID(_id) -- Ops.PlayerTask#PLAYERTASK
-- TODO: Remove clients from the task -- DEBUG: Remove clients from the task
local clientsattask = task.Clients:GetIDStackSorted() local clientsattask = task.Clients:GetIDStackSorted()
for _,_id in pairs(clientsattask) do for _,_id in pairs(clientsattask) do
self:I("*****Removing player " .. _id) self:I("*****Removing player " .. _id)
@ -814,6 +875,7 @@ function PLAYERTASKCONTROLLER:_AddTask(Target)
local task = PLAYERTASK:New(type,Target,self.repeatonfailed,self.repeattimes) local task = PLAYERTASK:New(type,Target,self.repeatonfailed,self.repeattimes)
task:_SetController(self) task:_SetController(self)
self.TaskQueue:Push(task) self.TaskQueue:Push(task)
self:__TaskAdded(-1,task)
return self return self
end end
@ -841,7 +903,10 @@ function PLAYERTASKCONTROLLER:_JoinTask(Group, Client, Task)
self:I(self.lid..text) self:I(self.lid..text)
local m=MESSAGE:New(text,"10","Info"):ToAll() local m=MESSAGE:New(text,"10","Info"):ToAll()
self.TasksPerPlayer:Push(Task,playername) self.TasksPerPlayer:Push(Task,playername)
Task.TaskMenu:Remove() -- clear menu
if self.PlayerMenu[playername] then
self.PlayerMenu[playername]:RemoveSubMenus()
end
end end
return self return self
end end
@ -864,8 +929,15 @@ function PLAYERTASKCONTROLLER:_ActiveTaskInfo(Group, Client)
local CoordText = Coordinate:ToStringA2G(Client) local CoordText = Coordinate:ToStringA2G(Client)
local ThreatLevel = task.Target:GetThreatLevelMax() local ThreatLevel = task.Target:GetThreatLevelMax()
local targets = task.Target:CountTargets() or 0 local targets = task.Target:CountTargets() or 0
local clientlist = task:GetClients()
local ThreatGraph = "[" .. string.rep( "", ThreatLevel ) .. string.rep( "", 10 - ThreatLevel ) .. "]: "..ThreatLevel local ThreatGraph = "[" .. string.rep( "", ThreatLevel ) .. string.rep( "", 10 - ThreatLevel ) .. "]: "..ThreatLevel
text = string.format("%s\nThreat: %s\nTargets left: %d\nCoord: %s", taskname, ThreatGraph, targets, CoordText) text = string.format("%s\nThreat: %s\nTargets left: %d\nCoord: %s", taskname, ThreatGraph, targets, CoordText)
local clienttxt = "\nPilot(s): "
for _,_name in pairs(clientlist) do
clienttxt = clienttxt .. _name .. ", "
end
clienttxt=string.gsub(clienttxt,", $",".")
text = text .. clienttxt
else else
text = "No active task!" text = "No active task!"
end end
@ -963,16 +1035,24 @@ function PLAYERTASKCONTROLLER:_BuildMenus()
if _client then if _client then
local client = _client -- Wrapper.Client#CLIENT local client = _client -- Wrapper.Client#CLIENT
local group = client:GetGroup() local group = client:GetGroup()
if group then local playername = client:GetPlayerName() or "Unknown"
if group and client then
local topmenu = MENU_GROUP:New(group,self.Name.." Tasking "..self.Type,nil) local topmenu = MENU_GROUP:New(group,self.Name.." Tasking "..self.Type,nil)
local active = MENU_GROUP:New(group,"Active Task",topmenu) local active = MENU_GROUP:New(group,"Active Task",topmenu)
local info = MENU_GROUP_COMMAND:New(group,"Info",active,self._ActiveTaskInfo,self,group,client) local info = MENU_GROUP_COMMAND:New(group,"Info",active,self._ActiveTaskInfo,self,group,client)
local mark = MENU_GROUP_COMMAND:New(group,"Mark on map",active,self._MarkTask,self,group,client) local mark = MENU_GROUP_COMMAND:New(group,"Mark on map",active,self._MarkTask,self,group,client)
local smoke = MENU_GROUP_COMMAND:New(group,"Smoke",active,self._SmokeTask,self,group,client) if self.Type ~= PLAYERTASKCONTROLLER.Type.A2A then
local flare = MENU_GROUP_COMMAND:New(group,"Flare",active,self._FlareTask,self,group,client) -- no smoking/flaring here if A2A
local smoke = MENU_GROUP_COMMAND:New(group,"Smoke",active,self._SmokeTask,self,group,client)
local flare = MENU_GROUP_COMMAND:New(group,"Flare",active,self._FlareTask,self,group,client)
end
local abort = MENU_GROUP_COMMAND:New(group,"Abort",active,self._AbortTask,self,group,client) local abort = MENU_GROUP_COMMAND:New(group,"Abort",active,self._AbortTask,self,group,client)
local join = MENU_GROUP:New(group,"Join Task",topmenu) if self.PlayerMenu[playername] then
self.PlayerMenu[playername]:RemoveSubMenus()
else
self.PlayerMenu[playername] = MENU_GROUP:New(group,"Join Task",topmenu)
end
local tasktypes = self:_GetAvailableTaskTypes() local tasktypes = self:_GetAvailableTaskTypes()
local taskpertype = self:_GetTasksPerType() local taskpertype = self:_GetTasksPerType()
@ -980,9 +1060,10 @@ function PLAYERTASKCONTROLLER:_BuildMenus()
local ttypes = {} local ttypes = {}
local taskmenu = {} local taskmenu = {}
for _tasktype,_data in pairs(tasktypes) do for _tasktype,_data in pairs(tasktypes) do
ttypes[_tasktype] = MENU_GROUP:New(group,_tasktype,join) ttypes[_tasktype] = MENU_GROUP:New(group,_tasktype,self.PlayerMenu[playername])
local tasks = taskpertype[_tasktype] or {} local tasks = taskpertype[_tasktype] or {}
for _,_task in pairs(tasks) do for _,_task in pairs(tasks) do
_task = _task -- Ops.PlayerTask#PLAYERTASK
local text = string.format("TaskNo %03d",_task.PlayerTaskNr) local text = string.format("TaskNo %03d",_task.PlayerTaskNr)
if self.UseGroupNames then if self.UseGroupNames then
local name = _task.Target:GetName() local name = _task.Target:GetName()
@ -990,13 +1071,14 @@ function PLAYERTASKCONTROLLER:_BuildMenus()
text = string.format("%s (%03d)",name,_task.PlayerTaskNr) text = string.format("%s (%03d)",name,_task.PlayerTaskNr)
end end
end end
local taskentry = MENU_GROUP_COMMAND:New(group,text,ttypes[_tasktype],self._JoinTask,self,group,client,_task) if _task:GetState() == "Planned" or (not _task:HasPlayerName(playername)) then
taskentry:SetTag(client:GetPlayerName()) local taskentry = MENU_GROUP_COMMAND:New(group,text,ttypes[_tasktype],self._JoinTask,self,group,client,_task)
taskmenu[#taskmenu+1] = taskentry taskentry:SetTag(playername)
_task.TaskMenu = taskentry taskmenu[#taskmenu+1] = taskentry
end
end end
end end
join:Refresh() self.PlayerMenu[playername]:Refresh()
end end
end end
end end
@ -1101,6 +1183,21 @@ function PLAYERTASKCONTROLLER:onafterTaskRepeatOnFailed(From, Event, To, Task)
return self return self
end end
--- [Internal] On after task added
-- @param #PLAYERTASKCONTROLLER self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @param Ops.PlayerTask#PLAYERTASK Task
-- @return #PLAYERTASKCONTROLLER self
function PLAYERTASKCONTROLLER:onafterTaskAdded(From, Event, To, Task)
self:I({From, Event, To})
self:I(self.lid.."TaskAdded")
local taskname = string.format("%s has a new Task %s", self.Name, tostring(Task.Type))
local m = MESSAGE:New(taskname,15,"Tasking"):ToCoalition(self.Coalition)
return self
end
--- [Internal] On after Stop call --- [Internal] On after Stop call
-- @param #PLAYERTASKCONTROLLER self -- @param #PLAYERTASKCONTROLLER self
-- @param #string From -- @param #string From
@ -1110,6 +1207,11 @@ end
function PLAYERTASKCONTROLLER:onafterStop(From, Event, To) function PLAYERTASKCONTROLLER:onafterStop(From, Event, To)
self:I({From, Event, To}) self:I({From, Event, To})
self:I(self.lid.."Stopped.") self:I(self.lid.."Stopped.")
-- Player leaves
self:UnHandleEvent(EVENTS.PlayerLeaveUnit)
self:UnHandleEvent(EVENTS.Ejection)
self:UnHandleEvent(EVENTS.Crash)
self:UnHandleEvent(EVENTS.PilotDead)
return self return self
end end