From 793c0d988eb91fb3125de814f208411fe8ae895b Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Tue, 3 Jan 2023 10:22:10 +0100 Subject: [PATCH] Changes from dev --- Moose Development/Moose/Core/Set.lua | 644 ++++++++++++++++++-- Moose Development/Moose/Utilities/Utils.lua | 76 ++- 2 files changed, 663 insertions(+), 57 deletions(-) diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index 82a7d65a5..b973172c1 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -53,6 +53,7 @@ do -- SET_BASE -- @field #table Index Table of indices. -- @field #table List Unused table. -- @field Core.Scheduler#SCHEDULER CallScheduler + -- @field #SET_BASE.Filters Filter Filters -- @extends Core.Base#BASE --- The @{Core.Set#SET_BASE} class defines the core functions that define a collection of objects. @@ -83,6 +84,11 @@ do -- SET_BASE YieldInterval = nil, } + --- Filters + -- @type SET_BASE.Filters + -- @field #table Coalition Coalitions + -- @field #table Prefix Prefixes. + --- Creates a new SET_BASE object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names. -- @param #SET_BASE self -- @return #SET_BASE @@ -135,11 +141,12 @@ do -- SET_BASE --- Clear the Objects in the Set. -- @param #SET_BASE self + -- @param #boolean TriggerEvent If `true`, an event remove is triggered for each group that is removed from the set. -- @return #SET_BASE self - function SET_BASE:Clear() + function SET_BASE:Clear(TriggerEvent) for Name, Object in pairs( self.Set ) do - self:Remove( Name ) + self:Remove( Name, not TriggerEvent ) end return self @@ -166,7 +173,7 @@ do -- SET_BASE --- Gets a list of the Names of the Objects in the Set. -- @param #SET_BASE self - -- @return #SET_BASE self + -- @return #table Table of names. function SET_BASE:GetSetNames() -- R2.3 self:F2() @@ -181,7 +188,7 @@ do -- SET_BASE --- Returns a table of the Objects in the Set. -- @param #SET_BASE self - -- @return #SET_BASE self + -- @return #table Table of objects. function SET_BASE:GetSetObjects() -- R2.3 self:F2() @@ -197,16 +204,21 @@ do -- SET_BASE --- Removes a @{Core.Base#BASE} object from the @{Core.Set#SET_BASE} and derived classes, based on the Object Name. -- @param #SET_BASE self -- @param #string ObjectName - -- @param NoTriggerEvent (Optional) When `true`, the :Remove() method will not trigger a **Removed** event. + -- @param #boolean NoTriggerEvent (Optional) When `true`, the :Remove() method will not trigger a **Removed** event. function SET_BASE:Remove( ObjectName, NoTriggerEvent ) self:F2( { ObjectName = ObjectName } ) local TriggerEvent = true - if NoTriggerEvent then TriggerEvent = false end + if NoTriggerEvent then + TriggerEvent = false + else + TriggerEvent = true + end local Object = self.Set[ObjectName] if Object then + for Index, Key in ipairs( self.Index ) do if Key == ObjectName then table.remove( self.Index, Index ) @@ -214,6 +226,7 @@ do -- SET_BASE break end end + -- When NoTriggerEvent is true, then no Removed event will be triggered. if TriggerEvent then self:Removed( ObjectName, Object ) @@ -311,7 +324,6 @@ do -- SET_BASE -- @param #SET_BASE self -- @param Core.Set#SET_BASE SetB Set other set, called *B*. -- @return Core.Set#SET_BASE A set of objects that is included in set *A* **and** in set *B*. - function SET_BASE:GetSetIntersection(SetB) local intersection=SET_BASE:New() @@ -461,16 +473,32 @@ do -- SET_BASE -- @param #SET_BASE self -- @return #SET_BASE self function SET_BASE:FilterOnce() + + --self:Clear() for ObjectName, Object in pairs( self.Database ) do if self:IsIncludeObject( Object ) then self:Add( ObjectName, Object ) + else + self:Remove(ObjectName, true) end end return self end + + --- Clear all filters. You still need to apply :FilterOnce() + -- @param #SET_BASE self + -- @return #SET_BASE self + function SET_BASE:FilterClear() + + for key,value in pairs(self.Filter) do + self.Filter[key]={} + end + + return self + end --- Starts the filtering for the defined collection. -- @param #SET_BASE self @@ -817,7 +845,7 @@ do -- SET_BASE --- Decides whether an object is in the SET -- @param #SET_BASE self -- @param #table Object - -- @return #SET_BASE self + -- @return #boolean `true` if object is in set and `false` otherwise. function SET_BASE:IsInSet( Object ) self:F3( Object ) local outcome = false @@ -1021,9 +1049,9 @@ do -- SET_GROUP return self end - --- Gets the Set. + --- Get a *new* set that only contains alive groups. -- @param #SET_GROUP self - -- @return #table Table of objects + -- @return #SET_GROUP Set of alive groups. function SET_GROUP:GetAliveSet() self:F2() @@ -1169,11 +1197,14 @@ do -- SET_GROUP --- Builds a set of groups in zones. -- @param #SET_GROUP self -- @param #table Zones Table of Core.Zone#ZONE Zone objects, or a Core.Set#SET_ZONE + -- @param #boolean Clear If `true`, clear any previously defined filters. -- @return #SET_GROUP self - function SET_GROUP:FilterZones( Zones ) - if not self.Filter.Zones then + function SET_GROUP:FilterZones( Zones, Clear ) + + if Clear or not self.Filter.Zones then self.Filter.Zones = {} end + local zones = {} if Zones.ClassName and Zones.ClassName == "SET_ZONE" then zones = Zones.Set @@ -1183,34 +1214,12 @@ do -- SET_GROUP else zones = Zones end + for _, Zone in pairs( zones ) do local zonename = Zone:GetName() self.Filter.Zones[zonename] = Zone end - return self - end - - --- Builds a set of groups in zones. - -- @param #SET_GROUP self - -- @param #table Zones Table of Core.Zone#ZONE Zone objects, or a Core.Set#SET_ZONE - -- @return #SET_GROUP self - function SET_GROUP:FilterZones( Zones ) - if not self.Filter.Zones then - self.Filter.Zones = {} - end - local zones = {} - if Zones.ClassName and Zones.ClassName == "SET_ZONE" then - zones = Zones.Set - elseif type( Zones ) ~= "table" or (type( Zones ) == "table" and Zones.ClassName ) then - self:E("***** FilterZones needs either a table of ZONE Objects or a SET_ZONE as parameter!") - return self - else - zones = Zones - end - for _,Zone in pairs( zones ) do - local zonename = Zone:GetName() - self.Filter.Zones[zonename] = Zone - end + return self end @@ -1218,17 +1227,21 @@ do -- SET_GROUP -- Possible current coalitions are red, blue and neutral. -- @param #SET_GROUP self -- @param #string Coalitions Can take the following values: "red", "blue", "neutral". + -- @param #boolean Clear If `true`, clear any previously defined filters. -- @return #SET_GROUP self - function SET_GROUP:FilterCoalitions( Coalitions ) - if not self.Filter.Coalitions then + function SET_GROUP:FilterCoalitions( Coalitions, Clear ) + + if Clear or (not self.Filter.Coalitions) then self.Filter.Coalitions = {} end - if type( Coalitions ) ~= "table" then - Coalitions = { Coalitions } - end + + -- Ensure table. + Coalitions = UTILS.EnsureTable(Coalitions, false) + for CoalitionID, Coalition in pairs( Coalitions ) do self.Filter.Coalitions[Coalition] = Coalition end + return self end @@ -1236,17 +1249,22 @@ do -- SET_GROUP -- Possible current categories are plane, helicopter, ground, ship. -- @param #SET_GROUP self -- @param #string Categories Can take the following values: "plane", "helicopter", "ground", "ship". + -- @param #boolean Clear If `true`, clear any previously defined filters. -- @return #SET_GROUP self - function SET_GROUP:FilterCategories( Categories ) - if not self.Filter.Categories then + function SET_GROUP:FilterCategories( Categories, Clear ) + + if Clear or not self.Filter.Categories then self.Filter.Categories = {} end + if type( Categories ) ~= "table" then Categories = { Categories } end + for CategoryID, Category in pairs( Categories ) do self.Filter.Categories[Category] = Category end + return self end @@ -1899,6 +1917,41 @@ do -- SET_GROUP end end + + --- Get the closest group of the set with respect to a given reference coordinate. Optionally, only groups of given coalitions are considered in the search. + -- @param #SET_GROUP self + -- @param Core.Point#COORDINATE Coordinate Reference Coordinate from which the closest group is determined. + -- @return Wrapper.Group#GROUP The closest group (if any). + -- @return #number Distance in meters to the closest group. + function SET_GROUP:GetClosestGroup(Coordinate, Coalitions) + + local Set = self:GetSet() + + local dmin=math.huge + local gmin=nil + + for GroupID, GroupData in pairs( Set ) do -- For each GROUP in SET_GROUP + local group=GroupData --Wrapper.Group#GROUP + + if group and group:IsAlive() and (Coalitions==nil or UTILS.IsAnyInTable(Coalitions, group:GetCoalition())) then + + local coord=group:GetCoord() + + -- Distance between ref. coordinate and group coordinate. + local d=UTILS.VecDist3D(Coordinate, coord) + + if d