From 6773ac784193209d4e9154a4b8ef9d30eb34d3f6 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Tue, 30 May 2023 12:06:03 +0200 Subject: [PATCH] #PLAYERTASK * Added FSM event "Progress" that will be triggered if the targetcount goes down for a task, but is not yet zero. This will bubble up to PLAYERTASKCONTROLLER #PLAYERTASKCONTROLLER * Added FSM event"TaskProgess" (see above). The event function will recveive the PLAYERTASK and the current target count * Changed the menu build strategy to ensure a lot less menu rebuilds. Menus are now only build if * A new player joins (for the joining single player) * On joining a task (for the joining single player) * When aborting a task (for the aborting single player) * On Task succes (for all players) * Removal of time based builds: The status loop will now only enforce the menu build if the task count in the queue is smaller than the menu item limit. This effectively enforces a time-based order of tasks, and newer, even higher prio task will not bubble into the task list of pilots automatically. --- Moose Development/Moose/Ops/PlayerTask.lua | 96 ++++++++++++++++------ 1 file changed, 70 insertions(+), 26 deletions(-) diff --git a/Moose Development/Moose/Ops/PlayerTask.lua b/Moose Development/Moose/Ops/PlayerTask.lua index b5ee9e527..34471b41f 100644 --- a/Moose Development/Moose/Ops/PlayerTask.lua +++ b/Moose Development/Moose/Ops/PlayerTask.lua @@ -58,6 +58,7 @@ do -- @field #table NextTaskFailure -- @field #string FinalState -- @field #string TypeName +-- @field #number PreviousCount -- @extends Core.Fsm#FSM @@ -92,11 +93,12 @@ PLAYERTASK = { NextTaskSuccess = {}, NextTaskFailure = {}, FinalState = "none", + PreviousCount = 0, } --- PLAYERTASK class version. -- @field #string version -PLAYERTASK.version="0.1.14" +PLAYERTASK.version="0.1.16" --- Generic task condition. -- @type PLAYERTASK.Condition @@ -151,6 +153,8 @@ function PLAYERTASK:New(Type, Target, Repeat, Times, TTSType) return self end + self.PreviousCount = self.Target:CountTargets() + self:T(self.lid.."Created.") -- FMS start state is PLANNED. @@ -162,6 +166,7 @@ function PLAYERTASK:New(Type, Target, Repeat, Times, TTSType) self:AddTransition("*", "ClientAdded", "*") -- Client has been added to the task self:AddTransition("*", "ClientRemoved", "*") -- Client has been removed from the task self:AddTransition("*", "Executing", "Executing") -- First client is executing the Task. + self:AddTransition("*", "Progress", "*") -- Task target count reduced - progress self:AddTransition("*", "Done", "Done") -- All clients have reported that Task is done. self:AddTransition("*", "Cancel", "Done") -- Command to cancel the Task. self:AddTransition("*", "Success", "Done") @@ -710,6 +715,16 @@ function PLAYERTASK:onafterStatus(From, Event, To) status = "Success" end + if status ~= "Failed" and status ~= "Success" then + -- Partial Success? + local targetcount = self.Target:CountTargets() + if targetcount < self.PreviousCount then + -- Progress + self:__Progress(-2,targetcount) + self.PreviousCount = targetcount + end + end + if self.verbose then self:I(self.lid.."Target dead: "..tostring(targetdead).." | Clients alive: " .. tostring(clientsalive)) end @@ -723,6 +738,21 @@ function PLAYERTASK:onafterStatus(From, Event, To) end +--- [Internal] On after progress call +-- @param #PLAYERTASK self +-- @param #string From +-- @param #string Event +-- @param #string To +-- @param #number TargetCount +-- @return #PLAYERTASK self +function PLAYERTASK:onafterProgress(From, Event, To, TargetCount) + self:T({From, Event, To}) + if self.TaskController then + self.TaskController:__TaskProgress(-1,self,TargetCount ) + end + return self +end + --- [Internal] On after planned call -- @param #PLAYERTASK self -- @param #string From @@ -1549,6 +1579,7 @@ function PLAYERTASKCONTROLLER:New(Name, Coalition, Type, ClientFilter) self:AddTransition("*", "TaskCancelled", "*") self:AddTransition("*", "TaskSuccess", "*") self:AddTransition("*", "TaskFailed", "*") + self:AddTransition("*", "TaskProgress", "*") self:AddTransition("*", "TaskTargetSmoked", "*") self:AddTransition("*", "TaskTargetFlared", "*") self:AddTransition("*", "TaskTargetIlluminated", "*") @@ -1615,6 +1646,15 @@ function PLAYERTASKCONTROLLER:New(Name, Coalition, Type, ClientFilter) -- @param #string Event Event. -- @param #string To To state. -- @param Ops.PlayerTask#PLAYERTASK Task + + --- On After "TaskProgress" event. Task target count has been reduced. + -- @function [parent=#PLAYERTASKCONTROLLER] OnAfterTaskProgress + -- @param #PLAYERTASKCONTROLLER self + -- @param #string From From state. + -- @param #string Event Event. + -- @param #string To To state. + -- @param Ops.PlayerTask#PLAYERTASK Task The current Task. + -- @param #number TargetCount Targets left over --- On After "TaskRepeatOnFailed" event. Task has failed and will be repeated. -- @function [parent=#PLAYERTASKCONTROLLER] OnAfterTaskRepeatOnFailed @@ -3303,13 +3343,13 @@ function PLAYERTASKCONTROLLER:_BuildTaskInfoMenu(group,client,playername,topmenu local taskinfomenu = nil if self.taskinfomenu then local menutaskinfo = self.gettext:GetEntry("MENUTASKINFO",self.locale) - local taskinfomenu = MENU_GROUP_DELAYED:New(group,menutaskinfo,topmenu):SetTag(newtag) + local taskinfomenu = MENU_GROUP:New(group,menutaskinfo,topmenu):SetTag(newtag) local ittypes = {} local itaskmenu = {} local tnow = timer.getTime() for _tasktype,_data in pairs(tasktypes) do - ittypes[_tasktype] = MENU_GROUP_DELAYED:New(group,_tasktype,taskinfomenu):SetTag(newtag) + ittypes[_tasktype] = MENU_GROUP:New(group,_tasktype,taskinfomenu):SetTag(newtag) local tasks = taskpertype[_tasktype] or {} local n = 0 for _,_task in pairs(tasks) do @@ -3335,7 +3375,7 @@ function PLAYERTASKCONTROLLER:_BuildTaskInfoMenu(group,client,playername,topmenu --self:T(self.lid.."Menu text = "..text) end end - local taskentry = MENU_GROUP_COMMAND_DELAYED:New(group,text,ittypes[_tasktype],self._ActiveTaskInfo,self,group,client,_task):SetTag(newtag) + local taskentry = MENU_GROUP_COMMAND:New(group,text,ittypes[_tasktype],self._ActiveTaskInfo,self,group,client,_task):SetTag(newtag) --taskentry:SetTag(playername) itaskmenu[#itaskmenu+1] = taskentry -- keep max items limit @@ -3409,6 +3449,7 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess) -- 2)+3) Join or abort? if joinorabort then self.PlayerMenu[playername]:RemoveSubMenus() + self.PlayerMenu[playername] = MENU_GROUP:New(group,menuname,self.MenuParent) self.PlayerMenu[playername]:SetTag(newtag) topmenu = self.PlayerMenu[playername] elseif (not playerhastask) or enforced then @@ -3420,17 +3461,18 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess) --self.PlayerMenu[playername]:RemoveSubMenus() --oldmenu = self.PlayerMenu[playername] --self.PlayerMenu[playername] = nil - self.PlayerMenu[playername]:RemoveSubMenus() - self.PlayerMenu[playername] = MENU_GROUP_DELAYED:New(group,menuname,self.MenuParent) - self.PlayerMenu[playername]:SetTag(newtag) - self.PlayerMenu[playername].PTTimeStamp = timer.getAbsTime() - timedbuild = true + + --self.PlayerMenu[playername]:RemoveSubMenus() + --self.PlayerMenu[playername] = MENU_GROUP:New(group,menuname,self.MenuParent) + --self.PlayerMenu[playername]:SetTag(newtag) + --self.PlayerMenu[playername].PTTimeStamp = timer.getAbsTime() + --timedbuild = true end topmenu = self.PlayerMenu[playername] end else -- 1) new player# - topmenu = MENU_GROUP_DELAYED:New(group,menuname,self.MenuParent) + topmenu = MENU_GROUP:New(group,menuname,self.MenuParent) self.PlayerMenu[playername] = topmenu self.PlayerMenu[playername]:SetTag(newtag) self.PlayerMenu[playername].PTTimeStamp = timer.getAbsTime() @@ -3450,21 +3492,21 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess) local menuflare = self.gettext:GetEntry("MENUFLARE",self.locale) local menuabort = self.gettext:GetEntry("MENUABORT",self.locale) - local active = MENU_GROUP_DELAYED:New(group,menuactive,topmenu):SetTag(newtag) - local info = MENU_GROUP_COMMAND_DELAYED:New(group,menuinfo,active,self._ActiveTaskInfo,self,group,client):SetTag(newtag) - local mark = MENU_GROUP_COMMAND_DELAYED:New(group,menumark,active,self._MarkTask,self,group,client):SetTag(newtag) + local active = MENU_GROUP:New(group,menuactive,topmenu):SetTag(newtag) + local info = MENU_GROUP_COMMAND:New(group,menuinfo,active,self._ActiveTaskInfo,self,group,client):SetTag(newtag) + local mark = MENU_GROUP_COMMAND:New(group,menumark,active,self._MarkTask,self,group,client):SetTag(newtag) if self.Type ~= PLAYERTASKCONTROLLER.Type.A2A then if self.noflaresmokemenu ~= true then -- no smoking/flaring here if A2A or designer has set noflaresmokemenu to true - local smoke = MENU_GROUP_COMMAND_DELAYED:New(group,menusmoke,active,self._SmokeTask,self,group,client):SetTag(newtag) - local flare = MENU_GROUP_COMMAND_DELAYED:New(group,menuflare,active,self._FlareTask,self,group,client):SetTag(newtag) + local smoke = MENU_GROUP_COMMAND:New(group,menusmoke,active,self._SmokeTask,self,group,client):SetTag(newtag) + local flare = MENU_GROUP_COMMAND:New(group,menuflare,active,self._FlareTask,self,group,client):SetTag(newtag) local IsNight = client:GetCoordinate():IsNight() if IsNight then - local light = MENU_GROUP_COMMAND_DELAYED:New(group,menuflare,active,self._IlluminateTask,self,group,client):SetTag(newtag) + local light = MENU_GROUP_COMMAND:New(group,menuflare,active,self._IlluminateTask,self,group,client):SetTag(newtag) end end end - local abort = MENU_GROUP_COMMAND_DELAYED:New(group,menuabort,active,self._AbortTask,self,group,client):SetTag(newtag) + local abort = MENU_GROUP_COMMAND:New(group,menuabort,active,self._AbortTask,self,group,client):SetTag(newtag) if self.activehasinfomenu and self.taskinfomenu then self:T("Building Active-Info Menus for "..playername) if self.PlayerInfoMenu[playername] then @@ -3484,13 +3526,13 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess) self.PlayerJoinMenu[playername]:RemoveSubMenus(nil,oldtag) end - local joinmenu = MENU_GROUP_DELAYED:New(group,menujoin,topmenu):SetTag(newtag) + local joinmenu = MENU_GROUP:New(group,menujoin,topmenu):SetTag(newtag) self.PlayerJoinMenu[playername] = joinmenu local ttypes = {} local taskmenu = {} for _tasktype,_data in pairs(tasktypes) do - ttypes[_tasktype] = MENU_GROUP_DELAYED:New(group,_tasktype,joinmenu):SetTag(newtag) + ttypes[_tasktype] = MENU_GROUP:New(group,_tasktype,joinmenu):SetTag(newtag) local tasks = taskpertype[_tasktype] or {} local n = 0 for _,_task in pairs(tasks) do @@ -3510,7 +3552,7 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess) text = string.format("%s (%03d) [%d%s",name,_task.PlayerTaskNr,pilotcount,newtext) end end - local taskentry = MENU_GROUP_COMMAND_DELAYED:New(group,text,ttypes[_tasktype],self._JoinTask,self,group,client,_task):SetTag(newtag) + local taskentry = MENU_GROUP_COMMAND:New(group,text,ttypes[_tasktype],self._JoinTask,self,group,client,_task):SetTag(newtag) --taskentry:SetTag(playername) taskmenu[#taskmenu+1] = taskentry n = n + 1 @@ -3527,22 +3569,22 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess) self.PlayerInfoMenu[playername] = self:_BuildTaskInfoMenu(group,client,playername,topmenu,tasktypes,taskpertype,newtag) end end - if self.AllowFlash then + if self.AllowFlash and topmenu ~= nil then local flashtext = self.gettext:GetEntry("FLASHMENU",self.locale) - local flashmenu = MENU_GROUP_COMMAND_DELAYED:New(group,flashtext,topmenu,self._SwitchFlashing,self,group,client):SetTag(newtag) + local flashmenu = MENU_GROUP_COMMAND:New(group,flashtext,topmenu,self._SwitchFlashing,self,group,client):SetTag(newtag) end if self.TaskQueue:Count() == 0 then self:T("No open tasks info") local menunotasks = self.gettext:GetEntry("MENUNOTASKS",self.locale) - local joinmenu = MENU_GROUP_DELAYED:New(group,menunotasks,self.PlayerMenu[playername]):SetTag(newtag) + local joinmenu = MENU_GROUP:New(group,menunotasks,self.PlayerMenu[playername]):SetTag(newtag) rebuilddone = true end --- -- REFRESH MENU --- if rebuilddone then - self.PlayerMenu[playername]:RemoveSubMenus(nil,oldtag) - self.PlayerMenu[playername]:Set() + --self.PlayerMenu[playername]:RemoveSubMenus(nil,oldtag) + --self.PlayerMenu[playername]:Set() self.PlayerMenu[playername]:Refresh() end end @@ -3874,7 +3916,9 @@ function PLAYERTASKCONTROLLER:onafterStatus(From, Event, To) if taskcount ~= self.lasttaskcount then self.lasttaskcount = taskcount - enforcedmenu = true + if taskcount < self.menuitemlimit then + enforcedmenu = true + end end self:_BuildMenus(nil,enforcedmenu)