From 50aca57112a2c7c41d7a3c109727a6af6a300bb9 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Thu, 17 Nov 2022 13:22:34 +0100 Subject: [PATCH 01/11] #PLAYERTASK * Extended use of marker ops: -- Enable the function like so: -- mycontroller:EnableMarkerOps("TASK") -- Then as a player in a client slot, you can add a map marker on the F10 map. Next edit the text -- in the marker to make it identifiable, e.g -- -- TASK Name=Tanks Sochi, Text=Destroy tank group located near Sochi! -- -- Where **TASK** is the tag that tells the controller this mark is a target location (must). -- **Name=** ended by a comma **,** tells the controller the supposed menu entry name (optional). No extra spaces! End with a comma! -- **Text=** tells the controller the supposed free text task description (optional, only taken if **Name=** is present first). No extra spaces! function PLAYERTASKCONTROLLER:EnableMarkerOps(Tag) --- Moose Development/Moose/Ops/PlayerTask.lua | 50 +++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/Moose Development/Moose/Ops/PlayerTask.lua b/Moose Development/Moose/Ops/PlayerTask.lua index a36ab6e8c..c4deae952 100644 --- a/Moose Development/Moose/Ops/PlayerTask.lua +++ b/Moose Development/Moose/Ops/PlayerTask.lua @@ -1799,16 +1799,36 @@ end -- @param #PLAYERTASKCONTROLLER self -- @param #string Tag (Optional) The tagname to use to identify commands, defaults to "TASK" -- @return #PLAYERTASKCONTROLLER self +-- @usage +-- Enable the function like so: +-- mycontroller:EnableMarkerOps("TASK") +-- Then as a player in a client slot, you can add a map marker on the F10 map. Next edit the text +-- in the marker to make it identifiable, e.g +-- +-- TASK Name=Tanks Sochi, Text=Destroy tank group located near Sochi! +-- +-- Where **TASK** is the tag that tells the controller this mark is a target location (must). +-- **Name=** ended by a comma **,** tells the controller the supposed menu entry name (optional). No extra spaces! End with a comma! +-- **Text=** tells the controller the supposed free text task description (optional, only taken if **Name=** is present first). No extra spaces! function PLAYERTASKCONTROLLER:EnableMarkerOps(Tag) self:T(self.lid.."EnableMarkerOps") local tag = Tag or "TASK" - local MarkerOps = MARKEROPS_BASE:New(tag) + local MarkerOps = MARKEROPS_BASE:New(tag,{"Name","Text"},true) local function Handler(Keywords,Coord,Text) if self.verbose then local m = MESSAGE:New(string.format("Target added from marker at: %s", Coord:ToStringA2G(nil, nil, self.ShowMagnetic)),15,"INFO"):ToAll() + local m = MESSAGE:New(string.format("Text: %s", Text),15,"INFO"):ToAll() end + local menuname = string.match(Text,"Name=(.+),") + local freetext = string.match(Text,"Text=(.+)") + if menuname then + Coord.menuname = menuname + if freetext then + Coord.freetext = freetext + end + end self:AddTarget(Coord) end @@ -2114,6 +2134,12 @@ function PLAYERTASKCONTROLLER:_CheckTargetQueue() if self.TargetQueue:Count() > 0 then local object = self.TargetQueue:Pull() local target = TARGET:New(object) + if object.menuname then + target.menuname = object.menuname + if object.freetext then + target.freetext = object.freetext + end + end self:_AddTask(target) end return self @@ -2543,9 +2569,23 @@ function PLAYERTASKCONTROLLER:_AddTask(Target) local countg = enemysetg:Count() local counts = enemysets:Count() if countg > 0 then + -- observe Tags coming from MarkerOps + if Target.menuname then + enemysetg.menuname = Target.menuname + if Target.freetext then + enemysetg.freetext = Target.freetext + end + end self:AddTarget(enemysetg) end if counts > 0 then + -- observe Tags coming from MarkerOps + if Target.menuname then + enemysets.menuname = Target.menuname + if Target.freetext then + enemysets.freetext = Target.freetext + end + end self:AddTarget(enemysets) end return self @@ -2565,6 +2605,14 @@ function PLAYERTASKCONTROLLER:_AddTask(Target) local task = PLAYERTASK:New(type,Target,self.repeatonfailed,self.repeattimes,ttstype) + -- observe Tags coming from MarkerOps + if Target.menuname then + task:SetMenuName(Target.menuname) + if Target.freetext then + task:AddFreetext(Target.freetext) + end + end + task.coalition = self.Coalition if type == AUFTRAG.Type.BOMBRUNWAY then From df17a3d2a3a3d305dfd6d39aec96ba742a0aba21 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Fri, 18 Nov 2022 11:28:33 +0100 Subject: [PATCH 02/11] # TaskRecoveryTanker --- Moose Development/Moose/Wrapper/Controllable.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index f4adba71b..a21211ae4 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -1377,7 +1377,7 @@ end -- @return DCS#Task The DCS task structure. function CONTROLLABLE:TaskRecoveryTanker(CarrierGroup, Speed, Altitude, LastWptNumber) - local LastWptFlag = LastWptNumber and true or false + local LastWptFlag = type(LastWptNumber) == "number" and true or false local DCSTask = { id = "RecoveryTanker", From 4124b6d084743881e5a8ac736b102a82c08b1f57 Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 18 Nov 2022 19:56:30 +0100 Subject: [PATCH 03/11] OPS **LEGION** - Added `Captured` event **COMMANDER** - Improved behaviour when legion/warehouse is captured - Added `LegionLost` event - Added `RemoveLegion` function **CHIEF** - Improved behaviour when legion/warehouse is captured - Added `LegionLost` event - Added `RemoveLegion` function --- Moose Development/Moose/Ops/Chief.lua | 44 ++++++++++++++++++++++ Moose Development/Moose/Ops/Commander.lua | 45 +++++++++++++++++++++++ Moose Development/Moose/Ops/Legion.lua | 35 ++++++++++++++++++ 3 files changed, 124 insertions(+) diff --git a/Moose Development/Moose/Ops/Chief.lua b/Moose Development/Moose/Ops/Chief.lua index fe60fed48..4f9d6216b 100644 --- a/Moose Development/Moose/Ops/Chief.lua +++ b/Moose Development/Moose/Ops/Chief.lua @@ -413,6 +413,8 @@ function CHIEF:New(Coalition, AgentSet, Alias) self:AddTransition("*", "DefconChange", "*") -- Change defence condition. self:AddTransition("*", "StrategyChange", "*") -- Change strategy condition. + self:AddTransition("*", "LegionLost", "*") -- Out of our legions was lost to the enemy. + ------------------------ --- Pseudo Functions --- ------------------------ @@ -647,6 +649,33 @@ function CHIEF:New(Coalition, AgentSet, Alias) -- @param #string To To state. -- @param Ops.OpsZone#OPSZONE OpsZone Zone that is being attacked. + + --- Triggers the FSM event "LegionLost". + -- @function [parent=#CHIEF] LegionLost + -- @param #CHIEF self + -- @param Ops.Legion#LEGION Legion The legion that was lost. + -- @param DCS#coalition.side Coalition which captured the warehouse. + -- @param DCS#country.id Country which has captured the warehouse. + + --- Triggers the FSM event "LegionLost". + -- @function [parent=#CHIEF] __LegionLost + -- @param #CHIEF self + -- @param #number delay Delay in seconds. + -- @param Ops.Legion#LEGION Legion The legion that was lost. + -- @param DCS#coalition.side Coalition which captured the warehouse. + -- @param DCS#country.id Country which has captured the warehouse. + + --- On after "LegionLost" event. + -- @function [parent=#CHIEF] OnAfterLegionLost + -- @param #CHIEF self + -- @param #string From From state. + -- @param #string Event Event. + -- @param #string To To state. + -- @param Ops.Legion#LEGION Legion The legion that was lost. + -- @param DCS#coalition.side Coalition which captured the warehouse. + -- @param DCS#country.id Country which has captured the warehouse. + + return self end @@ -1115,6 +1144,21 @@ function CHIEF:AddLegion(Legion) return self end +--- Remove a LEGION to the chief's commander. +-- @param #CHIEF self +-- @param Ops.Legion#LEGION Legion The legion to add. +-- @return #CHIEF self +function CHIEF:RemoveLegion(Legion) + + -- Set chief of the legion. + Legion.chief=nil + + -- Add legion to the commander. + self.commander:RemoveLegion(Legion) + + return self +end + --- Add mission to mission queue of the COMMANDER. -- @param #CHIEF self diff --git a/Moose Development/Moose/Ops/Commander.lua b/Moose Development/Moose/Ops/Commander.lua index 022fc2678..2126a90de 100644 --- a/Moose Development/Moose/Ops/Commander.lua +++ b/Moose Development/Moose/Ops/Commander.lua @@ -209,6 +209,8 @@ function COMMANDER:New(Coalition, Alias) self:AddTransition("*", "TransportCancel", "*") -- COMMANDER cancels a Transport. self:AddTransition("*", "OpsOnMission", "*") -- An OPSGROUP was send on a Mission (AUFTRAG). + + self:AddTransition("*", "LegionLost", "*") -- Out of our legions was lost to the enemy. ------------------------ --- Pseudo Functions --- @@ -351,6 +353,32 @@ function COMMANDER:New(Coalition, Alias) -- @param Ops.OpsGroup#OPSGROUP OpsGroup The OPS group on mission. -- @param Ops.Auftrag#AUFTRAG Mission The mission. + + --- Triggers the FSM event "LegionLost". + -- @function [parent=#COMMANDER] LegionLost + -- @param #COMMANDER self + -- @param Ops.Legion#LEGION Legion The legion that was lost. + -- @param DCS#coalition.side Coalition which captured the warehouse. + -- @param DCS#country.id Country which has captured the warehouse. + + --- Triggers the FSM event "LegionLost". + -- @function [parent=#COMMANDER] __LegionLost + -- @param #COMMANDER self + -- @param #number delay Delay in seconds. + -- @param Ops.Legion#LEGION Legion The legion that was lost. + -- @param DCS#coalition.side Coalition which captured the warehouse. + -- @param DCS#country.id Country which has captured the warehouse. + + --- On after "LegionLost" event. + -- @function [parent=#COMMANDER] OnAfterLegionLost + -- @param #COMMANDER self + -- @param #string From From state. + -- @param #string Event Event. + -- @param #string To To state. + -- @param Ops.Legion#LEGION Legion The legion that was lost. + -- @param DCS#coalition.side Coalition which captured the warehouse. + -- @param DCS#country.id Country which has captured the warehouse. + return self end @@ -442,6 +470,23 @@ function COMMANDER:AddLegion(Legion) return self end +--- Remove a LEGION to the commander. +-- @param #COMMANDER self +-- @param Ops.Legion#LEGION Legion The legion to be removed. +-- @return #COMMANDER self +function COMMANDER:RemoveLegion(Legion) + + for i,_legion in pairs(self.legions) do + local legion=_legion --Ops.Legion#LEGION + if legion.alias==Legion.alias then + table.remove(self.legions, i) + Legion.commander=nil + end + end + + return self +end + --- Add mission to mission queue. -- @param #COMMANDER self -- @param Ops.Auftrag#AUFTRAG Mission Mission to be added. diff --git a/Moose Development/Moose/Ops/Legion.lua b/Moose Development/Moose/Ops/Legion.lua index 80fdf1e9e..76e0f641f 100644 --- a/Moose Development/Moose/Ops/Legion.lua +++ b/Moose Development/Moose/Ops/Legion.lua @@ -553,6 +553,13 @@ function LEGION:IsCohort(CohortName) return false end +--- Get name of legion. This is the alias of the warehouse. +-- @param #LEGION self +-- @return #string Name of legion. +function LEGION:GetName() + return self.alias +end + --- Get cohort of an asset. -- @param #LEGION self -- @param Functional.Warehouse#WAREHOUSE.Assetitem Asset The asset. @@ -1631,6 +1638,34 @@ function LEGION:onafterRequestSpawned(From, Event, To, Request, CargoGroupSet, T end +--- On after "Captured" event. +-- @param #LEGION self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +-- @param DCS#coalition.side Coalition which captured the warehouse. +-- @param DCS#country.id Country which has captured the warehouse. +function LEGION:onafterCaptured(From, Event, To, Coalition, Country) + + -- Call parent warehouse function. + self:GetParent(self, LEGION).onafterCaptured(self, From, Event, To, Coalition, Country) + + + if self.chief then + -- Trigger event for chief and commander. + self.chief.commander:LegionLost(self, Coalition, Country) + self.chief:LegionLost(self, Coalition, Country) + -- Remove legion from chief and commander. + self.chief:RemoveLegion(self) + elseif self.commander then + -- Trigger event. + self.commander:LegionLost(self, Coalition,Country) + -- Remove legion from commander. + self.commander:RemoveLegion(self) + end + +end + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Mission Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- From fe9a5aea2a1aef5ad6f4feba5ad0df5b43741713 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Wed, 23 Nov 2022 12:57:54 +0100 Subject: [PATCH 04/11] #AUFTRAG * Fix for orbit task not able to get a Vec2 from a Vec2... --- Moose Development/Moose/Ops/Auftrag.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index d007aa28a..d5e62aab1 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -6031,7 +6031,7 @@ function AUFTRAG:GetDCSMissionTask() --end -- Create orbit task. - local DCStask=CONTROLLABLE.TaskOrbit(nil, orbitVec2, self.orbitAltitude, self.orbitSpeed, orbitRaceTrack) + local DCStask=CONTROLLABLE.TaskOrbit(nil, COORDINATE:NewFromVec2(orbitVec2), self.orbitAltitude, self.orbitSpeed, orbitRaceTrack) -- Add DCS task. table.insert(DCStasks, DCStask) From 75bc95167f2b051227372443b418c3c21fdff6c6 Mon Sep 17 00:00:00 2001 From: Thomas <72444570+Applevangelist@users.noreply.github.com> Date: Mon, 28 Nov 2022 17:45:47 +0100 Subject: [PATCH 05/11] Update RAT.lua (#1849) Fix #1848 --- Moose Development/Moose/Functional/RAT.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Moose Development/Moose/Functional/RAT.lua b/Moose Development/Moose/Functional/RAT.lua index 0643cf01b..a54533eeb 100644 --- a/Moose Development/Moose/Functional/RAT.lua +++ b/Moose Development/Moose/Functional/RAT.lua @@ -5671,6 +5671,9 @@ function RAT:_ATCClearForLanding(airport, flight) -- Debug message. local text1=string.format("ATC %s: Flight %s cleared for landing (flag=%d).", airport, flight, flagvalue) + if string.find(flight,"#") then + flight = string.match(flight,"^(.+)#") + end local text2=string.format("ATC %s: Flight %s you are cleared for landing.", airport, flight) BASE:T( RAT.id..text1) MESSAGE:New(text2, 10):ToAllIf(RAT.ATC.messages) @@ -5713,6 +5716,9 @@ function RAT:_ATCFlightLanded(name) local text1=string.format("ATC %s: Flight %s landed. Tholding = %i:%02d, Tfinal = %i:%02d.", dest, name, Thold/60, Thold%60, Tfinal/60, Tfinal%60) local text2=string.format("ATC %s: Number of flights still on final %d.", dest, RAT.ATC.airport[dest].Nonfinal) local text3=string.format("ATC %s: Traffic report: Number of planes landed in total %d. Flights/hour = %3.2f.", dest, RAT.ATC.airport[dest].traffic, TrafficPerHour) + if string.find(name,"#") then + name = string.match(name,"^(.+)#") + end local text4=string.format("ATC %s: Flight %s landed. Welcome to %s.", dest, name, dest) BASE:T(RAT.id..text1) BASE:T(RAT.id..text2) From d674f5534326256f4915cd13a6a39011de7ded3b Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Tue, 29 Nov 2022 15:42:04 +0100 Subject: [PATCH 06/11] #PLAYERTASK * Added Silent option for PLAYERTASKCONTROLLER:AddPlayerTaskToQueue(PlayerTask,Silent) --- Moose Development/Moose/Ops/PlayerTask.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Moose Development/Moose/Ops/PlayerTask.lua b/Moose Development/Moose/Ops/PlayerTask.lua index c4deae952..2c6f3a75f 100644 --- a/Moose Development/Moose/Ops/PlayerTask.lua +++ b/Moose Development/Moose/Ops/PlayerTask.lua @@ -1409,7 +1409,7 @@ PLAYERTASKCONTROLLER.Messages = { --- PLAYERTASK class version. -- @field #string version -PLAYERTASKCONTROLLER.version="0.1.49" +PLAYERTASKCONTROLLER.version="0.1.50" --- Create and run a new TASKCONTROLLER instance. -- @param #PLAYERTASKCONTROLLER self @@ -2651,6 +2651,7 @@ end --- [User] Add a PLAYERTASK object to the list of (open) tasks -- @param #PLAYERTASKCONTROLLER self -- @param Ops.PlayerTask#PLAYERTASK PlayerTask +-- @param #boolean Silent If true, make no "has new task" announcement -- @return #PLAYERTASKCONTROLLER self -- @usage -- Example to create a PLAYERTASK of type CTLD and give Players 10 minutes to complete: @@ -2671,13 +2672,15 @@ end -- ) -- -- taskmanager:AddPlayerTaskToQueue(PlayerTask) -function PLAYERTASKCONTROLLER:AddPlayerTaskToQueue(PlayerTask) +function PLAYERTASKCONTROLLER:AddPlayerTaskToQueue(PlayerTask,Silent) self:T(self.lid.."AddPlayerTaskToQueue") if PlayerTask and PlayerTask.ClassName and PlayerTask.ClassName == "PLAYERTASK" then PlayerTask:_SetController(self) PlayerTask:SetCoalition(self.Coalition) self.TaskQueue:Push(PlayerTask) - self:__TaskAdded(10,PlayerTask) + if not Silent then + self:__TaskAdded(10,PlayerTask) + end else self:E(self.lid.."***** NO valid PAYERTASK object sent!") end From 85504fbe6241116e119e6a2ea20745633d1dfdb1 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sat, 3 Dec 2022 14:36:28 +0100 Subject: [PATCH 07/11] Small Fixes --- Moose Development/Moose/Ops/PlayerRecce.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose Development/Moose/Ops/PlayerRecce.lua b/Moose Development/Moose/Ops/PlayerRecce.lua index ef80816c8..f71b33fa8 100644 --- a/Moose Development/Moose/Ops/PlayerRecce.lua +++ b/Moose Development/Moose/Ops/PlayerRecce.lua @@ -1394,7 +1394,7 @@ end -- @param #string To -- @return #PLAYERRECCE self function PLAYERRECCE:onafterStatus(From, Event, To) - self:I({From, Event, To}) + self:T({From, Event, To}) if not self.timestamp then self.timestamp = timer.getTime() From 55383575e0247930b418252e8931b76b7b7c7d50 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Tue, 6 Dec 2022 12:48:20 +0100 Subject: [PATCH 08/11] #PLAYERTASKCONTROLLER * Make callout of MGRS coordinates slower --- Moose Development/Moose/Ops/PlayerTask.lua | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Moose Development/Moose/Ops/PlayerTask.lua b/Moose Development/Moose/Ops/PlayerTask.lua index 2c6f3a75f..0f6d95c78 100644 --- a/Moose Development/Moose/Ops/PlayerTask.lua +++ b/Moose Development/Moose/Ops/PlayerTask.lua @@ -21,7 +21,7 @@ -- === -- @module Ops.PlayerTask -- @image OPS_PlayerTask.jpg --- @date Last Update November 2022 +-- @date Last Update December 2022 do @@ -1409,7 +1409,7 @@ PLAYERTASKCONTROLLER.Messages = { --- PLAYERTASK class version. -- @field #string version -PLAYERTASKCONTROLLER.version="0.1.50" +PLAYERTASKCONTROLLER.version="0.1.51" --- Create and run a new TASKCONTROLLER instance. -- @param #PLAYERTASKCONTROLLER self @@ -2922,10 +2922,20 @@ function PLAYERTASKCONTROLLER:_ActiveTaskInfo(Group, Client, Task) if self.UseSRS then if string.find(CoordText," BR, ") then - CoordText = string.gsub(CoordText," BR, "," Bee, Arr, ") + CoordText = string.gsub(CoordText," BR, "," Bee, Arr; ") end if self.ShowMagnetic then - text=string.gsub(text,"°M|","° magnetic, ") + text=string.gsub(text,"°M|","° magnetic; ") + end + if string.find(CoordText,"MGRS") then + local Text = string.gsub(CoordText,"%d","%1;") -- "0 5 1 " + Text = string.gsub(Text," $","") -- "0 5 1" + CoordText = string.gsub(Text,"0","zero") + CoordText = string.gsub(Text,"MGRS","MGRS;") + if self.PathToGoogleKey then + CoordText = string.format("%s",CoordText) + end + --self:I(self.lid.." | ".. CoordText) end local ThreatLocaleTextTTS = self.gettext:GetEntry("THREATTEXTTTS",self.locale) local ttstext = string.format(ThreatLocaleTextTTS,self.MenuName or self.Name,ttsplayername,ttstaskname,ThreatLevelText, targets, CoordText) From 525666be7caf40fa8c73d591f56dff6ffb2c78fb Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Tue, 6 Dec 2022 18:05:41 +0100 Subject: [PATCH 09/11] #PLAYERRECCE * Smoke own position on ground, not mid-air --- Moose Development/Moose/Ops/PlayerRecce.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Moose Development/Moose/Ops/PlayerRecce.lua b/Moose Development/Moose/Ops/PlayerRecce.lua index f71b33fa8..0d0ce1166 100644 --- a/Moose Development/Moose/Ops/PlayerRecce.lua +++ b/Moose Development/Moose/Ops/PlayerRecce.lua @@ -104,7 +104,7 @@ PLAYERRECCE = { ClassName = "PLAYERRECCE", verbose = true, lid = nil, - version = "0.0.15", + version = "0.0.16", ViewZone = {}, ViewZoneVisual = {}, ViewZoneLaser = {}, @@ -958,9 +958,11 @@ function PLAYERRECCE:_SmokeTargets(client,group,playername) end if self.SmokeOwn[playername] then - local cc = client:GetCoordinate() + local cc = client:GetVec2() + -- don't smoke mid-air + local lc = COORDINATE:NewFromVec2(cc,1) local color = self.SmokeColor.ownsmoke - cc:Smoke(color) + lc:Smoke(color) end return self From cdfb47448f3612167b9e13159be9b9956eecb705 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Wed, 7 Dec 2022 18:56:08 +0100 Subject: [PATCH 10/11] #AWACS * Fix setting of CapVoices according to documentation #PLAYERRECCE * Speed up Marker Build #PLAYERTASK * Improve menu build --- Moose Development/Moose/Ops/Awacs.lua | 10 +-- Moose Development/Moose/Ops/PlayerRecce.lua | 5 +- Moose Development/Moose/Ops/PlayerTask.lua | 97 +++++++++++++-------- 3 files changed, 68 insertions(+), 44 deletions(-) diff --git a/Moose Development/Moose/Ops/Awacs.lua b/Moose Development/Moose/Ops/Awacs.lua index 12ff9b59b..f1f0551d8 100644 --- a/Moose Development/Moose/Ops/Awacs.lua +++ b/Moose Development/Moose/Ops/Awacs.lua @@ -2,9 +2,7 @@ -- -- === -- --- ## AWACS --- --- * MOOSE AI AWACS Operations using text-to-speech. +-- **AWACS** - MOOSE AI AWACS Operations using text-to-speech. -- -- === -- @@ -499,7 +497,7 @@ do -- @field #AWACS AWACS = { ClassName = "AWACS", -- #string - version = "0.2.49", -- #string + version = "0.2.50", -- #string lid = "", -- #string coalition = coalition.side.BLUE, -- #number coalitiontxt = "blue", -- #string @@ -916,7 +914,7 @@ AWACS.TaskStatus = { --@field #boolean FromAI ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- TODO-List 0.2.42 +-- TODO-List 0.2.50 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- -- DONE - WIP - Player tasking, VID @@ -3470,7 +3468,7 @@ function AWACS:_CheckInAI(FlightGroup,Group,AuftragsNr) local CAPVoice = self.CAPVoice if self.PathToGoogleKey then - CAPVoice = AWACS.CapVoices[math.floor(math.random(1,10))] + CAPVoice = self.CapVoices[math.floor(math.random(1,10))] end FlightGroup:SetSRS(self.PathToSRS,self.CAPGender,self.CAPCulture,CAPVoice,self.Port,self.PathToGoogleKey,"FLIGHT") diff --git a/Moose Development/Moose/Ops/PlayerRecce.lua b/Moose Development/Moose/Ops/PlayerRecce.lua index 0d0ce1166..746fff5e3 100644 --- a/Moose Development/Moose/Ops/PlayerRecce.lua +++ b/Moose Development/Moose/Ops/PlayerRecce.lua @@ -366,7 +366,10 @@ function PLAYERRECCE:SetReferencePoint(Coordinate,Name) if self.RPMarker then self.RPMarker:Remove() end - local text = string.format("%s RP %s\n%s\n%s\n%s",self.Name,Name,Coordinate:ToStringLLDDM(),Coordinate:ToStringLLDMS(),Coordinate:ToStringMGRS()) + local llddm = Coordinate:ToStringLLDDM() + local lldms = Coordinate:ToStringLLDMS() + local mgrs = Coordinate:ToStringMGRS() + local text = string.format("%s RP %s\n%s\n%s\n%s",self.Name,Name,llddm,lldms,mgrs) self.RPMarker = MARKER:New(Coordinate,text) self.RPMarker:ReadOnly() self.RPMarker:ToCoalition(self.Coalition) diff --git a/Moose Development/Moose/Ops/PlayerTask.lua b/Moose Development/Moose/Ops/PlayerTask.lua index 0f6d95c78..1e38829c0 100644 --- a/Moose Development/Moose/Ops/PlayerTask.lua +++ b/Moose Development/Moose/Ops/PlayerTask.lua @@ -770,7 +770,7 @@ function PLAYERTASK:onafterClientAdded(From, Event, To, Client) self:T({From, Event, To}) if Client and self.verbose then local text = string.format("Player %s joined task %03d!",Client:GetPlayerName() or "Generic",self.PlayerTaskNr) - self:I(self.lid..text) + self:T(self.lid..text) end self.timestamp = timer.getAbsTime() return self @@ -925,6 +925,7 @@ do -- @field #boolean ShowMagnetic Also show magnetic angles -- @field #boolean InfoHasCoordinate -- @field #boolean InfoHasLLDDM +-- @field #table PlayerMenuTag -- @extends Core.Fsm#FSM --- @@ -1232,6 +1233,7 @@ PLAYERTASKCONTROLLER = { PlayerFlashMenu = {}, PlayerJoinMenu = {}, PlayerInfoMenu = {}, + PlayerMenuTag = {}, noflaresmokemenu = false, TransmitOnlyWithPlayers = true, buddylasing = false, @@ -2099,7 +2101,7 @@ function PLAYERTASKCONTROLLER:_GetTasksPerType() self:T(self.lid.."_GetTasksPerType") local tasktypes = self:_GetAvailableTaskTypes() - self:T({tasktypes}) + --self:T({tasktypes}) -- Sort tasks per threat level first local datatable = self.TaskQueue:GetDataTable() @@ -3120,25 +3122,26 @@ end -- @param Core.Menu#MENU_BASE topmenu -- @param #table tasktypes -- @param #table taskpertype +-- @param #string newtag -- @return #table taskinfomenu -function PLAYERTASKCONTROLLER:_BuildTaskInfoMenu(group,client,playername,topmenu,tasktypes,taskpertype) +function PLAYERTASKCONTROLLER:_BuildTaskInfoMenu(group,client,playername,topmenu,tasktypes,taskpertype,newtag) self:T(self.lid.."_BuildTaskInfoMenu") local taskinfomenu = nil if self.taskinfomenu then local menutaskinfo = self.gettext:GetEntry("MENUTASKINFO",self.locale) - local taskinfomenu = MENU_GROUP_DELAYED:New(group,menutaskinfo,topmenu) + local taskinfomenu = MENU_GROUP_DELAYED: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) + ittypes[_tasktype] = MENU_GROUP_DELAYED:New(group,_tasktype,taskinfomenu):SetTag(newtag) local tasks = taskpertype[_tasktype] or {} local n = 0 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 = "*]" @@ -3151,7 +3154,7 @@ function PLAYERTASKCONTROLLER:_BuildTaskInfoMenu(group,client,playername,topmenu text = string.format("%s (%03d) [%d%s",name,_task.PlayerTaskNr,pilotcount,newtext) end end - local taskentry = MENU_GROUP_COMMAND_DELAYED:New(group,text,ittypes[_tasktype],self._ActiveTaskInfo,self,group,client,_task) + local taskentry = MENU_GROUP_COMMAND_DELAYED:New(group,text,ittypes[_tasktype],self._ActiveTaskInfo,self,group,client,_task):SetTag(newtag) --taskentry:SetTag(playername) itaskmenu[#itaskmenu+1] = taskentry -- keep max items limit @@ -3191,6 +3194,11 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess) local group = client:GetGroup() local unknown = self.gettext:GetEntry("UNKNOWN",self.locale) local playername = client:GetPlayerName() or unknown + + local oldtag = self.PlayerMenuTag[playername] + local newtag = playername..timer.getAbsTime() + self.PlayerMenuTag[playername] = newtag + if group and client then --- -- TOPMENU @@ -3202,6 +3210,8 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess) if self:_CheckPlayerHasTask(playername) and not fromsuccess then playerhastask = true end local topmenu = nil + --local oldmenu = nil + local rebuilddone = false self:T("Playerhastask = "..tostring(playerhastask).." Enforced = "..tostring(enforced).." Join or Abort = "..tostring(joinorabort)) @@ -3215,16 +3225,20 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess) -- 2)+3) Join or abort? if joinorabort then self.PlayerMenu[playername]:RemoveSubMenus() - self.PlayerMenu[playername]:SetTag(timer.getAbsTime()) + self.PlayerMenu[playername]:SetTag(newtag) topmenu = self.PlayerMenu[playername] elseif (not playerhastask) or enforced then -- 4) last build > 30 secs? local T0 = timer.getAbsTime() - local TDiff = T0-self.PlayerMenu[playername].MenuTag + local TDiff = T0-self.PlayerMenu[playername].PTTimeStamp self:T("TDiff = "..string.format("%.2d",TDiff)) if TDiff >= self.holdmenutime then - self.PlayerMenu[playername]:RemoveSubMenus() - self.PlayerMenu[playername]:SetTag(timer.getAbsTime()) + --self.PlayerMenu[playername]:RemoveSubMenus() + --oldmenu = self.PlayerMenu[playername] + --self.PlayerMenu[playername] = nil + self.PlayerMenu[playername] = MENU_GROUP_DELAYED:New(group,menuname,self.MenuParent) + self.PlayerMenu[playername]:SetTag(newtag) + self.PlayerMenu[playername].PTTimeStamp = timer.getAbsTime() timedbuild = true end topmenu = self.PlayerMenu[playername] @@ -3233,14 +3247,17 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess) -- 1) new player# topmenu = MENU_GROUP_DELAYED:New(group,menuname,self.MenuParent) self.PlayerMenu[playername] = topmenu - self.PlayerMenu[playername]:SetTag(timer.getAbsTime()) + self.PlayerMenu[playername]:SetTag(newtag) + self.PlayerMenu[playername].PTTimeStamp = timer.getAbsTime() + enforced = true end --- -- ACTIVE TASK MENU --- if playerhastask and enforced then - --self:T("Building Active Task Menus for "..playername) + self:T("Building Active Task Menus for "..playername) + rebuilddone = true local menuactive = self.gettext:GetEntry("MENUACTIVE",self.locale) local menuinfo = self.gettext:GetEntry("MENUINFO",self.locale) local menumark = self.gettext:GetEntry("MENUMARK",self.locale) @@ -3248,44 +3265,45 @@ 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) - local info = MENU_GROUP_COMMAND_DELAYED:New(group,menuinfo,active,self._ActiveTaskInfo,self,group,client) - local mark = MENU_GROUP_COMMAND_DELAYED:New(group,menumark,active,self._MarkTask,self,group,client) + 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) 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) - local flare = MENU_GROUP_COMMAND_DELAYED:New(group,menuflare,active,self._FlareTask,self,group,client) + 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 IsNight = client:GetCoordinate():IsNight() if IsNight then - local light = MENU_GROUP_COMMAND_DELAYED:New(group,menuflare,active,self._IlluminateTask,self,group,client) + local light = MENU_GROUP_COMMAND_DELAYED: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) + local abort = MENU_GROUP_COMMAND_DELAYED: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) + self:T("Building Active-Info Menus for "..playername) local tasktypes = self:_GetAvailableTaskTypes() local taskpertype = self:_GetTasksPerType() if self.PlayerInfoMenu[playername] then - self.PlayerInfoMenu[playername]:RemoveSubMenus() + self.PlayerInfoMenu[playername]:RemoveSubMenus(nil,oldtag) end - self.PlayerInfoMenu[playername] = self:_BuildTaskInfoMenu(group,client,playername,topmenu,tasktypes,taskpertype) + self.PlayerInfoMenu[playername] = self:_BuildTaskInfoMenu(group,client,playername,topmenu,tasktypes,taskpertype,newtag) end elseif (self.TaskQueue:Count() > 0 and enforced) or (not playerhastask and (timedbuild or joinorabort)) then - --self:T("Building Join Menus for "..playername) + self:T("Building Join Menus for "..playername) + rebuilddone = true --- -- JOIN TASK MENU --- local tasktypes = self:_GetAvailableTaskTypes() local taskpertype = self:_GetTasksPerType() local menujoin = self.gettext:GetEntry("MENUJOIN",self.locale) - local joinmenu = MENU_GROUP_DELAYED:New(group,menujoin,topmenu) + local joinmenu = MENU_GROUP_DELAYED:New(group,menujoin,topmenu):SetTag(newtag) local ttypes = {} local taskmenu = {} for _tasktype,_data in pairs(tasktypes) do - ttypes[_tasktype] = MENU_GROUP_DELAYED:New(group,_tasktype,joinmenu) + ttypes[_tasktype] = MENU_GROUP_DELAYED:New(group,_tasktype,joinmenu):SetTag(newtag) local tasks = taskpertype[_tasktype] or {} local n = 0 for _,_task in pairs(tasks) do @@ -3305,7 +3323,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) + local taskentry = MENU_GROUP_COMMAND_DELAYED:New(group,text,ttypes[_tasktype],self._JoinTask,self,group,client,_task):SetTag(newtag) --taskentry:SetTag(playername) taskmenu[#taskmenu+1] = taskentry n = n + 1 @@ -3315,25 +3333,30 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess) end end if self.taskinfomenu then - --self:T("Building Join-Info Menus for "..playername) + self:T("Building Join-Info Menus for "..playername) if self.PlayerInfoMenu[playername] then - self.PlayerInfoMenu[playername]:RemoveSubMenus() + self.PlayerInfoMenu[playername]:RemoveSubMenus(nil,oldtag) end - self.PlayerInfoMenu[playername] = self:_BuildTaskInfoMenu(group,client,playername,topmenu,tasktypes,taskpertype) + self.PlayerInfoMenu[playername] = self:_BuildTaskInfoMenu(group,client,playername,topmenu,tasktypes,taskpertype,newtag) end - elseif self.TaskQueue:Count() == 0 then - -- no tasks (yet) + end + if self.AllowFlash 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) + 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,topmenu) + local joinmenu = MENU_GROUP_DELAYED:New(group,menunotasks,self.PlayerMenu[playername]):SetTag(newtag) + rebuilddone = true end --- -- REFRESH MENU --- - if self.AllowFlash then - local flashtext = self.gettext:GetEntry("FLASHMENU",self.locale) - local flashmenu = MENU_GROUP_COMMAND_DELAYED:New(group,flashtext,self.PlayerMenu[playername],self._SwitchFlashing,self,group,client) + if rebuilddone then + self.PlayerMenu[playername]:RemoveSubMenus(nil,oldtag) + self.PlayerMenu[playername]:Refresh() end - self.PlayerMenu[playername]:Set() end end end From 8eef039312519c87cbd92d3f79a7ac2f335dbc41 Mon Sep 17 00:00:00 2001 From: phr0gz Date: Thu, 8 Dec 2022 13:15:07 +0100 Subject: [PATCH 11/11] New CAP auftrag (#1850) Add Ability to CAP escort Ground group or helo with a new auftrag: AUFTRAG:NewCAPGROUP --- Moose Development/Moose/Ops/Auftrag.lua | 56 +++++++++++++++++++++ Moose Development/Moose/Ops/FlightGroup.lua | 2 +- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index d5e62aab1..fa2d49679 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -1312,6 +1312,62 @@ function AUFTRAG:NewCAP(ZoneCAP, Altitude, Speed, Coordinate, Heading, Leg, Targ return mission end +--- **[AIRPANE]** Create a CAP on group mission. +-- @param #AUFTRAG self +-- @param Wrapper.Group#GROUP group. +-- @param #number Altitude Orbit altitude in feet. Default is 6,000 ft. +-- @param #number Speed Orbit speed in knots. Default 250 KIAS. +-- @param #number Leg Length of race-track in NM. Default 14 NM. +-- @param #number RelHeading Relative heading [0, 360) of race-track pattern in degrees wrt heading of the carrier. Default is heading of the carrier. +-- @param #number OffsetDist Relative distance of the first race-track point wrt to the carrier. Default 6 NM. +-- @param #number OffsetAngle Relative angle of the first race-track point wrt. to the carrier. Default 180 (behind the boat). +-- @param #number UpdateDistance Threshold distance in NM before orbit pattern is updated. Default 5 NM. +-- @param #table TargetTypes (Optional) Table of target types. Default `{"Helicopters", "Ground Units", "Light armed ships"}`. +-- @param #number EngageRange Max range in nautical miles that the escort group(s) will engage enemies. Default 32 NM (60 km). +-- @return #AUFTRAG self +function AUFTRAG:NewCAPGROUP(Grp, Altitude, Speed, RelHeading, Leg, OffsetDist, OffsetAngle, UpdateDistance, TargetTypes, EngageRange) + + -- Ensure given TargetTypes parameter is a table. + if TargetTypes then + if type(TargetTypes)~="table" then + TargetTypes={TargetTypes} + end + end + -- Six NM astern. + local OffsetVec2={r=OffsetDist or 6, phi=OffsetAngle or 180} + + -- Default leg. + Leg=Leg or 14 + + local Heading=nil + if RelHeading then + Heading=-math.abs(RelHeading) + end + + -- Create orbit mission. + local mission=AUFTRAG:NewORBIT_GROUP(Grp, Altitude, Speed, Leg, Heading, OffsetVec2, UpdateDistance) + -- Mission type CAP. + mission.type=AUFTRAG.Type.CAP + mission:_SetLogID() + + -- DCS task parameters: + local engage = EngageRange or 32 + local zoneCAPGroup = ZONE_GROUP:New("CAPGroup", Grp, UTILS.NMToMeters(engage)) + mission.engageZone=zoneCAPGroup + mission.engageTargetTypes=TargetTypes or {"Air"} + + -- Mission options: + mission.missionTask=ENUMS.MissionTask.CAP + mission.optionROE=ENUMS.ROE.OpenFire + mission.optionROT=ENUMS.ROT.EvadeFire + + mission.categories={AUFTRAG.Category.AIRCRAFT} + + mission.DCStask=mission:GetDCSMissionTask() + + return mission +end + --- **[AIR]** Create a CAS mission. -- @param #AUFTRAG self -- @param Core.Zone#ZONE_RADIUS ZoneCAS Circular CAS zone. Detected targets in this zone will be engaged. diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index 3d43ee67f..3087195f6 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -908,7 +908,7 @@ function FLIGHTGROUP:Status() if mission and mission.updateDCSTask then -- Orbit missions might need updates. - if (mission:GetType()==AUFTRAG.Type.ORBIT or mission:GetType()==AUFTRAG.Type.RECOVERYTANKER) and mission.orbitVec2 then + if (mission:GetType()==AUFTRAG.Type.ORBIT or mission:GetType()==AUFTRAG.Type.RECOVERYTANKER or mission:GetType()==AUFTRAG.Type.CAP) and mission.orbitVec2 then -- Get 2D vector of orbit target. local vec2=mission:GetTargetVec2()