#MARKEROPS

* Added option to enforce case sensitive matches on Tagname

#PLAYERTASKCONTROLLER
* Text tweaking
* Fixed "mark on map" not showing subtitles
* Revamped menu build to have less rebuilds
* Added option to show additional info menu for tasks before joining
This commit is contained in:
Applevangelist 2022-09-02 13:10:46 +02:00
parent fa0d076a09
commit 361ca2cece
2 changed files with 152 additions and 39 deletions

View File

@ -11,6 +11,7 @@
-- ### Author: **Applevangelist**
--
-- Date: 5 May 2021
-- Last Update: Sep 2022
--
-- ===
---
@ -27,6 +28,7 @@
-- @field #string Tag Tag to identify commands.
-- @field #table Keywords Table of keywords to recognize.
-- @field #string version Version of #MARKEROPS_BASE.
-- @field #boolean Casesensitive Enforce case when identifying the Tag, i.e. tag ~= Tag
-- @extends Core.Fsm#FSM
--- *Fiat lux.* -- Latin proverb.
@ -42,16 +44,18 @@ MARKEROPS_BASE = {
ClassName = "MARKEROPS",
Tag = "mytag",
Keywords = {},
version = "0.0.1",
version = "0.1.0",
debug = false,
Casesensitive = true,
}
--- Function to instantiate a new #MARKEROPS_BASE object.
-- @param #MARKEROPS_BASE self
-- @param #string Tagname Name to identify us from the event text.
-- @param #table Keywords Table of keywords recognized from the event text.
-- @param #boolean Casesensitive (Optional) Switch case sensitive identification of Tagname. Defaults to true.
-- @return #MARKEROPS_BASE self
function MARKEROPS_BASE:New(Tagname,Keywords)
function MARKEROPS_BASE:New(Tagname,Keywords,Casesensitive)
-- Inherit FSM
local self=BASE:Inherit(self, FSM:New()) -- #MARKEROPS_BASE
@ -61,6 +65,11 @@ function MARKEROPS_BASE:New(Tagname,Keywords)
self.Tag = Tagname or "mytag"-- #string
self.Keywords = Keywords or {} -- #table - might want to use lua regex here, too
self.debug = false
self.Casesensitive = true
if Casesensitive and Casesensitive == false then
self.Casesensitive = false
end
-----------------------
--- FSM Transitions ---
@ -178,9 +187,16 @@ end
-- @return #boolean
function MARKEROPS_BASE:_MatchTag(Eventtext)
local matches = false
local type = string.lower(self.Tag) -- #string
if string.find(string.lower(Eventtext),type) then
matches = true --event text contains tag
if not self.Casesensitive then
local type = string.lower(self.Tag) -- #string
if string.find(string.lower(Eventtext),type) then
matches = true --event text contains tag
end
else
local type = self.Tag -- #string
if string.find(Eventtext,type) then
matches = true --event text contains tag
end
end
return matches
end

View File

@ -20,7 +20,7 @@
-- ===
-- @module Ops.PlayerTask
-- @image OPS_PlayerTask.jpg
-- @date Last Update August 2022
-- @date Last Update September 2022
do
@ -264,10 +264,12 @@ end
--- [User] Get clients assigned list as table
-- @param #PLAYERTASK self
-- @return #table clients
-- @return #number clientcount
function PLAYERTASK:GetClients()
self:T(self.lid.."GetClients")
local clientlist = self.Clients:GetIDStackSorted() or {}
return clientlist
local count = self.Clients:Count()
return clientlist, count
end
--- [User] Count clients
@ -704,6 +706,7 @@ do
-- @field #boolean precisionbombing
-- @field Ops.FlightGroup#FLIGHTGROUP LasingDrone
-- @field Core.MarkerOps_BASE#MARKEROPS_BASE MarkerOps
-- @field #boolean askinfomenu
-- @extends Core.Fsm#FSM
---
@ -839,7 +842,7 @@ do
-- INTERCEPTTS = "intercept",
-- BOMBRUNWAYTTS = "bomb runway",
-- HAVEACTIVETASK = "You already have one active task! Complete it first!",
-- PILOTJOINEDTASK = "%s, %s joined task %03d",
-- PILOTJOINEDTASK = "%s, %s. You have been assigned %s task %03d",
-- TASKNAME = "%s Task ID %03d",
-- TASKNAMETTS = "%s Task ID %03d",
-- THREATHIGH = "high",
@ -850,7 +853,7 @@ do
-- MARKTASK = "%s, %s, copy, task %03d location marked on map!",
-- SMOKETASK = "%s, %s, copy, task %03d location smoked!",
-- FLARETASK = "%s, %s, copy, task %03d location illuminated!",
-- ABORTTASK = "%s, all stations, %s aborted task %03d!",
-- ABORTTASK = "%s, all stations, %s has aborted %s task %03d!",
-- UNKNOWN = "Unknown",
-- MENUTASKING = " Tasking ",
-- MENUACTIVE = "Active Task",
@ -860,6 +863,7 @@ do
-- MENUFLARE = "Flare",
-- MENUABORT = "Abort",
-- MENUJOIN = "Join Task",
-- MENUTASKINFO = Task Info",
-- MENUTASKNO = "TaskNo",
-- MENUNOTASKS = "Currently no tasks available.",
-- TASKCANCELLED = "Task #%03d %s is cancelled!",
@ -875,6 +879,7 @@ do
-- PILOTSTTS = ". Pilot(s): ",
-- YES = "Yes",
-- NO = "No",
-- NONE = "None",
-- POINTEROVERTARGET = "%s, %s, pointer in reach for task %03d, lasing!",
-- POINTERTARGETREPORT = "\nPointer in reach: %s\nLasing: %s",
-- POINTERTARGETLASINGTTS = ". Pointer in reach and lasing.",
@ -984,6 +989,7 @@ PLAYERTASKCONTROLLER = {
gettext = nil,
locale = "en",
precisionbombing = false,
taskinfomenu = false,
}
---
@ -1031,7 +1037,8 @@ PLAYERTASKCONTROLLER.Messages = {
INTERCEPTTS = "intercept",
BOMBRUNWAYTTS = "bomb runway",
HAVEACTIVETASK = "You already have one active task! Complete it first!",
PILOTJOINEDTASK = "%s, %s joined task %03d",
--PILOTJOINEDTASK = "%s, %s joined task %03d",
PILOTJOINEDTASK = "%s, %s. You have been assigned %s task %03d",
TASKNAME = "%s Task ID %03d",
TASKNAMETTS = "%s Task ID %03d",
THREATHIGH = "high",
@ -1042,7 +1049,7 @@ PLAYERTASKCONTROLLER.Messages = {
MARKTASK = "%s, %s, copy, task %03d location marked on map!",
SMOKETASK = "%s, %s, copy, task %03d location smoked!",
FLARETASK = "%s, %s, copy, task %03d location illuminated!",
ABORTTASK = "%s, all stations, %s aborted task %03d!",
ABORTTASK = "%s, all stations, %s has aborted %s task %03d!",
UNKNOWN = "Unknown",
MENUTASKING = " Tasking ",
MENUACTIVE = "Active Task",
@ -1052,6 +1059,7 @@ PLAYERTASKCONTROLLER.Messages = {
MENUFLARE = "Flare",
MENUABORT = "Abort",
MENUJOIN = "Join Task",
MENUTASKINFO = "Task Info",
MENUTASKNO = "TaskNo",
MENUNOTASKS = "Currently no tasks available.",
TASKCANCELLED = "Task #%03d %s is cancelled!",
@ -1060,13 +1068,14 @@ PLAYERTASKCONTROLLER.Messages = {
TASKSUCCESSTTS = "%s, task %03d %s completed successfully!",
TASKFAILED = "Task #%03d %s was a failure!",
TASKFAILEDTTS = "%s, task %03d %s was a failure!",
TASKFAILEDREPLAN = "Task #%03d %s was a failure! Replanning!",
TASKFAILEDREPLANTTS = "%s, task %03d %s was a failure! Replanning!",
TASKADDED = "%s has a new task %s available!",
TASKFAILEDREPLAN = "Task #%03d %s available for reassignment!",
TASKFAILEDREPLANTTS = "%s, task %03d %s vailable for reassignment!",
TASKADDED = "%s has a new %s task available!",
PILOTS = "\nPilot(s): ",
PILOTSTTS = ". Pilot(s): ",
YES = "Yes",
NO = "No",
NONE = "None",
POINTEROVERTARGET = "%s, %s, pointer in reach for task %03d, lasing!",
POINTERTARGETREPORT = "\nPointer in reach: %s\nLasing: %s",
POINTERTARGETLASINGTTS = ". Pointer in reach and lasing.",
@ -1086,7 +1095,8 @@ PLAYERTASKCONTROLLER.Messages = {
INTERCEPTTS = "Abfangen",
BOMBRUNWAYTTS = "Startbahn Bombardieren",
HAVEACTIVETASK = "Du hast einen aktiven Auftrag! Beende ihn zuerst!",
PILOTJOINEDTASK = "%s, %s hat Auftrag %03d angenommen",
--PILOTJOINEDTASK = "%s, %s. You have been assigned %s task %03d",
PILOTJOINEDTASK = "%s, %s hat Auftrag %s %03d angenommen",
TASKNAME = "%s Auftrag ID %03d",
TASKNAMETTS = "%s Auftrag ID %03d",
THREATHIGH = "hoch",
@ -1097,7 +1107,7 @@ PLAYERTASKCONTROLLER.Messages = {
MARKTASK = "%s, %s, verstanden, Zielposition %03d auf der Karte markiert!",
SMOKETASK = "%s, %s, verstanden, Zielposition %03d mit Rauch markiert!",
FLARETASK = "%s, %s, verstanden, Zielposition %03d beleuchtet!",
ABORTTASK = "%s, an alle, %s hat Auftrag %03d abgebrochen!",
ABORTTASK = "%s, an alle, %s hat Auftrag %s %03d abgebrochen!",
UNKNOWN = "Unbekannt",
MENUTASKING = " Aufträge ",
MENUACTIVE = "Aktiver Auftrag",
@ -1107,6 +1117,7 @@ PLAYERTASKCONTROLLER.Messages = {
MENUFLARE = "Leuchtgranate",
MENUABORT = "Abbrechen",
MENUJOIN = "Auftrag annehmen",
MENUTASKINFO = "Auftrag Briefing",
MENUTASKNO = "AuftragsNr",
MENUNOTASKS = "Momentan keine Aufträge verfügbar.",
TASKCANCELLED = "Auftrag #%03d %s wurde beendet!",
@ -1122,6 +1133,7 @@ PLAYERTASKCONTROLLER.Messages = {
PILOTSTTS = ". Pilot(en): ",
YES = "Ja",
NO = "Nein",
NONE = "Keine",
POINTEROVERTARGET = "%s, %s, Marker im Zielbereich für %03d, Laser an!",
POINTERTARGETREPORT = "\nMarker im Zielbereich: %s\nLaser an: %s",
POINTERTARGETLASINGTTS = ". Marker im Zielbereich, Laser is an.",
@ -1130,7 +1142,7 @@ PLAYERTASKCONTROLLER.Messages = {
--- PLAYERTASK class version.
-- @field #string version
PLAYERTASKCONTROLLER.version="0.1.27"
PLAYERTASKCONTROLLER.version="0.1.29"
--- Constructor
-- @param #PLAYERTASKCONTROLLER self
@ -1164,6 +1176,8 @@ function PLAYERTASKCONTROLLER:New(Name, Coalition, Type, ClientFilter)
self.TasksPerPlayer = FIFO:New() -- Utilities.FiFo#FIFO
self.PrecisionTasks = FIFO:New() -- Utilities.FiFo#FIFO
self.PlayerMenu = {} -- #table
self.lasttaskcount = 0
self.taskinfomenu = false
self.MenuName = nil
@ -1407,6 +1421,22 @@ function PLAYERTASKCONTROLLER:DisablePrecisionBombing(FlightGroup,LaserCode)
return self
end
--- [User] Enable extra menu to show task detail information before joining
-- @param #PLAYERTASKCONTROLLER self
-- @return #PLAYERTASKCONTROLLER self
function PLAYERTASKCONTROLLER:EnableTaskInfoMenu()
self:T(self.lid.."EnableTaskInfoMenu")
self.taskinfomenu = true
end
--- [User] Disable extra menu to show task detail information before joining
-- @param #PLAYERTASKCONTROLLER self
-- @return #PLAYERTASKCONTROLLER self
function PLAYERTASKCONTROLLER:DisableTaskInfoMenu()
self:T(self.lid.."DisableTaskInfoMenu")
self.taskinfomenu = false
end
--- [Internal] Event handling
-- @param #PLAYERTASKCONTROLLER self
-- @param Core.Event#EVENTDATA EventData
@ -2080,7 +2110,8 @@ function PLAYERTASKCONTROLLER:_JoinTask(Group, Client, Task)
end
Task:AddClient(Client)
local joined = self.gettext:GetEntry("PILOTJOINEDTASK",self.locale)
local text = string.format(joined, self.MenuName or self.Name, ttsplayername, Task.PlayerTaskNr)
-- PILOTJOINEDTASK = "%s, %s. You have been assigned %s task %03d",
local text = string.format(joined,ttsplayername, self.MenuName or self.Name, Task.TTSType, Task.PlayerTaskNr)
self:T(self.lid..text)
if not self.NoScreenOutput then
local m=MESSAGE:New(text,"10","Tasking"):ToAll()
@ -2090,7 +2121,7 @@ function PLAYERTASKCONTROLLER:_JoinTask(Group, Client, Task)
end
self.TasksPerPlayer:Push(Task,playername)
-- clear menu
self:_BuildMenus(Client)
self:_BuildMenus(Client,true)
end
if Task.Type == AUFTRAG.Type.PRECISIONBOMBING then
if not self.PrecisionTasks:HasUniqueID(Task.PlayerTaskNr) then
@ -2104,14 +2135,15 @@ end
-- @param #PLAYERTASKCONTROLLER self
-- @param Wrapper.Group#GROUP Group
-- @param Wrapper.Client#CLIENT Client
-- @param Ops.PlayerTask#PLAYERTASK Task
-- @return #PLAYERTASKCONTROLLER self
function PLAYERTASKCONTROLLER:_ActiveTaskInfo(Group, Client)
function PLAYERTASKCONTROLLER:_ActiveTaskInfo(Group, Client, Task)
self:T(self.lid.."_ActiveTaskInfo")
local playername, ttsplayername = self:_GetPlayerName(Client)
local text = ""
if self.TasksPerPlayer:HasUniqueID(playername) then
if self.TasksPerPlayer:HasUniqueID(playername) or Task then
-- TODO: Show multiple?
local task = self.TasksPerPlayer:ReadByID(playername) -- Ops.PlayerTask#PLAYERTASK
local task = Task or self.TasksPerPlayer:ReadByID(playername) -- Ops.PlayerTask#PLAYERTASK
local tname = self.gettext:GetEntry("TASKNAME",self.locale)
local ttsname = self.gettext:GetEntry("TASKNAMETTS",self.locale)
local taskname = string.format(tname,task.Type,task.PlayerTaskNr)
@ -2134,7 +2166,7 @@ function PLAYERTASKCONTROLLER:_ActiveTaskInfo(Group, Client)
ThreatLevelText = self.gettext:GetEntry("THREATLOW",self.locale)
end
local targets = task.Target:CountTargets() or 0
local clientlist = task:GetClients()
local clientlist, clientcount = task:GetClients()
local ThreatGraph = "[" .. string.rep( "", ThreatLevel ) .. string.rep( "", 10 - ThreatLevel ) .. "]: "..ThreatLevel
local ThreatLocaleText = self.gettext:GetEntry("THREATTEXT",self.locale)
text = string.format(ThreatLocaleText, taskname, ThreatGraph, targets, CoordText)
@ -2150,14 +2182,19 @@ function PLAYERTASKCONTROLLER:_ActiveTaskInfo(Group, Client)
end
end
local clienttxt = self.gettext:GetEntry("PILOTS",self.locale)
for _,_name in pairs(clientlist) do
if string.find(_name,"|") then
-- personalized flight name in player naming
_name = string.match(_name,"| ([%a]+)")
if clientcount > 0 then
for _,_name in pairs(clientlist) do
if string.find(_name,"|") then
-- personalized flight name in player naming
_name = string.match(_name,"| ([%a]+)")
end
clienttxt = clienttxt .. _name .. ", "
end
clienttxt = clienttxt .. _name .. ", "
clienttxt=string.gsub(clienttxt,", $",".")
else
local keine = self.gettext:GetEntry("NONE",self.locale)
clienttxt = clienttxt .. keine
end
clienttxt=string.gsub(clienttxt,", $",".")
text = text .. clienttxt
if self.UseSRS then
if string.find(CoordText," BR, ") then
@ -2194,7 +2231,7 @@ function PLAYERTASKCONTROLLER:_MarkTask(Group, Client)
local text = ""
if self.TasksPerPlayer:HasUniqueID(playername) then
local task = self.TasksPerPlayer:ReadByID(playername) -- Ops.PlayerTask#PLAYERTASK
local text = string.format("Task ID #%03d | Type: %s | Threat: %d",task.PlayerTaskNr,task.Type,task.Target:GetThreatLevelMax())
text = string.format("Task ID #%03d | Type: %s | Threat: %d",task.PlayerTaskNr,task.Type,task.Target:GetThreatLevelMax())
task:MarkTargetOnF10Map(text)
local textmark = self.gettext:GetEntry("MARKTASK",self.locale)
--text = string.format("%s, copy pilot %s, task %03d location marked on map!", self.MenuName or self.Name, playername, task.PlayerTaskNr)
@ -2281,7 +2318,8 @@ function PLAYERTASKCONTROLLER:_AbortTask(Group, Client)
local task = self.TasksPerPlayer:PullByID(playername) -- Ops.PlayerTask#PLAYERTASK
task:ClientAbort(Client)
local textmark = self.gettext:GetEntry("ABORTTASK",self.locale)
text = string.format(textmark, ttsplayername, self.MenuName or self.Name, task.PlayerTaskNr)
-- ABORTTASK = "%s, to all stations, %s has aborted %s task %03d!",
text = string.format(textmark, self.MenuName or self.Name, ttsplayername, task.TTSType, task.PlayerTaskNr)
self:T(self.lid..text)
--local m=MESSAGE:New(text,"10","Tasking"):ToAll()
if self.UseSRS then
@ -2293,19 +2331,21 @@ function PLAYERTASKCONTROLLER:_AbortTask(Group, Client)
if not self.NoScreenOutput then
local m=MESSAGE:New(text,15,"Tasking"):ToGroup(Group)
end
self:_BuildMenus(Client)
self:_BuildMenus(Client,true)
return self
end
--- [Internal] Build client menus
-- @param #PLAYERTASKCONTROLLER self
-- @param Wrapper.Client#CLIENT Client (optional) build for this client name only
-- @param #boolen enforced
-- @return #PLAYERTASKCONTROLLER self
function PLAYERTASKCONTROLLER:_BuildMenus(Client)
function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced)
self:T(self.lid.."_BuildMenus")
local clients = self.ClientSet:GetAliveSet()
if Client then
clients = {Client}
enforced = true
end
for _,_client in pairs(clients) do
if _client then
@ -2314,23 +2354,37 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client)
local unknown = self.gettext:GetEntry("UNKNOWN",self.locale)
local playername = client:GetPlayerName() or unknown
if group and client then
---
-- Conditions for menu rebuild
-- 1) Player has no menu
-- 2) Player has no running task
-- 3) enforced
---
-- TOPMENU
---
local taskings = self.gettext:GetEntry("MENUTASKING",self.locale)
local menuname = self.MenuName or self.Name..taskings..self.Type
local topmenu = MENU_GROUP:New(group,menuname,nil)
local playerhastask = false
if self:_CheckPlayerHasTask(playername) then playerhastask = true end
local topmenu = nil
self:T("Playerhastask = "..tostring(playerhastask).." Enforced = "..tostring(enforced))
if self.PlayerMenu[playername] then
self.PlayerMenu[playername]:RemoveSubMenus()
if enforced or not playerhastask then
self.PlayerMenu[playername]:RemoveSubMenus()
end
topmenu = self.PlayerMenu[playername]
else
topmenu = MENU_GROUP:New(group,menuname,nil)
self.PlayerMenu[playername] = topmenu
end
---
-- ACTIVE TASK MENU
---
if self:_CheckPlayerHasTask(playername) then
if playerhastask and enforced then
local menuactive = self.gettext:GetEntry("MENUACTIVE",self.locale)
local menuinfo = self.gettext:GetEntry("MENUINFO",self.locale)
@ -2348,17 +2402,21 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client)
local flare = MENU_GROUP_COMMAND:New(group,menuflare,active,self._FlareTask,self,group,client)
end
local abort = MENU_GROUP_COMMAND:New(group,menuabort,active,self._AbortTask,self,group,client)
elseif self.TaskQueue:Count() > 0 then
elseif (self.TaskQueue:Count() > 0 and enforced) or (not playerhastask) then
---
-- JOIN TASK MENU
---
local tasktypes = self:_GetAvailableTaskTypes()
local taskpertype = self:_GetTasksPerType()
local menujoin = self.gettext:GetEntry("MENUJOIN",self.locale)
local menutaskinfo = self.gettext:GetEntry("MENUTASKINFO",self.locale)
local joinmenu = MENU_GROUP:New(group,menujoin,topmenu)
local ttypes = {}
local taskmenu = {}
local ittypes = {}
local itaskmenu = {}
for _tasktype,_data in pairs(tasktypes) do
ttypes[_tasktype] = MENU_GROUP:New(group,_tasktype,joinmenu)
local tasks = taskpertype[_tasktype] or {}
@ -2386,7 +2444,38 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client)
--end
end
end
else
if self.taskinfomenu then
local taskinfomenu = MENU_GROUP:New(group,menutaskinfo,topmenu)
for _tasktype,_data in pairs(tasktypes) do
ittypes[_tasktype] = MENU_GROUP:New(group,_tasktype,taskinfomenu)
local tasks = taskpertype[_tasktype] or {}
for _,_task in pairs(tasks) do
_task = _task -- Ops.PlayerTask#PLAYERTASK
local pilotcount = _task:CountClients()
local newtext = "]"
local tnow = timer.getTime()
-- marker for new tasks
if tnow - _task.timestamp < 60 then
newtext = "*]"
end
local menutaskno = self.gettext:GetEntry("MENUTASKNO",self.locale)
local text = string.format("%s %03d [%d%s",menutaskno,_task.PlayerTaskNr,pilotcount,newtext)
if self.UseGroupNames then
local name = _task.Target:GetName()
if name ~= "Unknown" then
text = string.format("%s (%03d) [%d%s",name,_task.PlayerTaskNr,pilotcount,newtext)
end
end
--if _task:GetState() == "Planned" or (not _task:HasPlayerName(playername)) then
local taskentry = MENU_GROUP_COMMAND:New(group,text,ittypes[_tasktype],self._ActiveTaskInfo,self,group,client,_task)
taskentry:SetTag(playername)
itaskmenu[#itaskmenu+1] = taskentry
--end
end
end
end
elseif self.TaskQueue:Count() == 0 then
-- no tasks (yet)
local menunotasks = self.gettext:GetEntry("MENUNOTASKS",self.locale)
local joinmenu = MENU_GROUP:New(group,menunotasks,topmenu)
@ -2638,15 +2727,23 @@ end
-- @return #PLAYERTASKCONTROLLER self
function PLAYERTASKCONTROLLER:onafterStatus(From, Event, To)
self:I({From, Event, To})
self:_CheckTargetQueue()
self:_CheckTaskQueue()
self:_CheckPrecisionTasks()
self:_BuildMenus()
local targetcount = self.TargetQueue:Count()
local taskcount = self.TaskQueue:Count()
local playercount = self.ClientSet:CountAlive()
local assignedtasks = self.TasksPerPlayer:Count()
local enforcedmenu = false
if taskcount ~= self.lasttaskcount then
self.lasttaskcount = taskcount
enforcedmenu = true
end
self:_BuildMenus(nil,enforcedmenu)
if self.verbose then
local text = string.format("New Targets: %02d | Active Tasks: %02d | Active Players: %02d | Assigned Tasks: %02d",targetcount,taskcount,playercount,assignedtasks)