diff --git a/Moose Development/Moose/AI/AI_Cargo.lua b/Moose Development/Moose/AI/AI_Cargo.lua index 2da2566e7..1d358b735 100644 --- a/Moose Development/Moose/AI/AI_Cargo.lua +++ b/Moose Development/Moose/AI/AI_Cargo.lua @@ -178,7 +178,7 @@ function AI_CARGO:onbeforeLoad( Carrier, From, Event, To, PickupZone ) local Boarding = false - local LoadInterval = 10 + local LoadInterval = 2 local LoadDelay = 0 local Carrier_List = {} local Carrier_Weight = {} diff --git a/Moose Development/Moose/Cargo/CargoGroup.lua b/Moose Development/Moose/Cargo/CargoGroup.lua index aa0917810..7c3a2530c 100644 --- a/Moose Development/Moose/Cargo/CargoGroup.lua +++ b/Moose Development/Moose/Cargo/CargoGroup.lua @@ -258,7 +258,6 @@ do -- CARGO_GROUP --- @param #CARGO_GROUP self -- @param Core.Event#EVENTDATA EventData function CARGO_GROUP:OnEventCargoDead( EventData ) - self:I( EventData ) local Destroyed = false @@ -424,7 +423,7 @@ do -- CARGO_GROUP ToVec=ToPointVec2 end Cargo:__UnBoard( Timer, ToVec, NearRadius ) - Timer = Timer + 3 + Timer = Timer + 1 end end, { NearRadius } ) diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index 262cbed56..45a0f4091 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -636,7 +636,7 @@ function SET_BASE:Flush( MasterObject ) for ObjectName, Object in pairs( self.Set ) do ObjectNames = ObjectNames .. ObjectName .. ", " end - self:I( { MasterObject = MasterObject and MasterObject:GetClassNameAndID(), "Objects in Set:", ObjectNames } ) + self:F( { MasterObject = MasterObject and MasterObject:GetClassNameAndID(), "Objects in Set:", ObjectNames } ) return ObjectNames end @@ -672,6 +672,7 @@ end -- * @{#SET_GROUP.FilterCategories}: Builds the SET_GROUP with the groups belonging to the category(ies). -- * @{#SET_GROUP.FilterCountries}: Builds the SET_GROUP with the gruops belonging to the country(ies). -- * @{#SET_GROUP.FilterPrefixes}: Builds the SET_GROUP with the groups starting with the same prefix string(s). +-- * @{#SET_GROUP.FilterActive}: Builds the SET_GROUP with the groups that are only active. Groups that are inactive (late activation) won't be included in the set! -- -- For the Category Filter, extra methods have been added: -- @@ -685,6 +686,7 @@ end -- Once the filter criteria have been set for the SET_GROUP, you can start filtering using: -- -- * @{#SET_GROUP.FilterStart}: Starts the filtering of the groups within the SET_GROUP and add or remove GROUP objects **dynamically**. +-- * @{#SET_GROUP.FilterOnce}: Filters of the groups **once**. -- -- Planned filter criteria within development are (so these are not yet available): -- @@ -783,7 +785,9 @@ SET_GROUP = { function SET_GROUP:New() -- Inherits from BASE - local self = BASE:Inherit( self, SET_BASE:New( _DATABASE.GROUPS ) ) + local self = BASE:Inherit( self, SET_BASE:New( _DATABASE.GROUPS ) ) -- #SET_GROUP + + self:FilterActive( false ) return self end @@ -1012,6 +1016,32 @@ function SET_GROUP:FilterPrefixes( Prefixes ) return self end +--- Builds a set of groups that are only active. +-- Only the groups that are active will be included within the set. +-- @param #SET_GROUP self +-- @param #boolean Active (optional) Include only active groups to the set. +-- Include inactive groups if you provide false. +-- @return #SET_GROUP self +-- @usage +-- +-- -- Include only active groups to the set. +-- GroupSet = SET_GROUP:New():FilterActive():FilterStart() +-- +-- -- Include only active groups to the set of the blue coalition, and filter one time. +-- GroupSet = SET_GROUP:New():FilterActive():FilterCoalition( "blue" ):FilterOnce() +-- +-- -- Include only active groups to the set of the blue coalition, and filter one time. +-- -- Later, reset to include back inactive groups to the set. +-- GroupSet = SET_GROUP:New():FilterActive():FilterCoalition( "blue" ):FilterOnce() +-- ... logic ... +-- GroupSet = SET_GROUP:New():FilterActive( false ):FilterCoalition( "blue" ):FilterOnce() +-- +function SET_GROUP:FilterActive( Active ) + Active = Active or not ( Active == false ) + self.Filter.Active = Active + return self +end + --- Starts the filtering. -- @param #SET_GROUP self @@ -1377,58 +1407,67 @@ end --- -- @param #SET_GROUP self --- @param Wrapper.Group#GROUP MooseGroup +-- @param Wrapper.Group#GROUP MGroup The group that is checked for inclusion. -- @return #SET_GROUP self -function SET_GROUP:IsIncludeObject( MooseGroup ) - self:F2( MooseGroup ) - local MooseGroupInclude = true +function SET_GROUP:IsIncludeObject( MGroup ) + self:F2( MGroup ) + local MGroupInclude = true + if self.Filter.Active ~= nil then + local MGroupActive = false + self:F( { Active = self.Filter.Active } ) + if self.Filter.Active == false or ( self.Filter.Active == true and MGroup:IsActive() == true ) then + MGroupActive = true + end + MGroupInclude = MGroupInclude and MGroupActive + end + if self.Filter.Coalitions then - local MooseGroupCoalition = false + local MGroupCoalition = false for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do - self:T3( { "Coalition:", MooseGroup:GetCoalition(), self.FilterMeta.Coalitions[CoalitionName], CoalitionName } ) - if self.FilterMeta.Coalitions[CoalitionName] and self.FilterMeta.Coalitions[CoalitionName] == MooseGroup:GetCoalition() then - MooseGroupCoalition = true + self:T3( { "Coalition:", MGroup:GetCoalition(), self.FilterMeta.Coalitions[CoalitionName], CoalitionName } ) + if self.FilterMeta.Coalitions[CoalitionName] and self.FilterMeta.Coalitions[CoalitionName] == MGroup:GetCoalition() then + MGroupCoalition = true end end - MooseGroupInclude = MooseGroupInclude and MooseGroupCoalition + MGroupInclude = MGroupInclude and MGroupCoalition end if self.Filter.Categories then - local MooseGroupCategory = false + local MGroupCategory = false for CategoryID, CategoryName in pairs( self.Filter.Categories ) do - self:T3( { "Category:", MooseGroup:GetCategory(), self.FilterMeta.Categories[CategoryName], CategoryName } ) - if self.FilterMeta.Categories[CategoryName] and self.FilterMeta.Categories[CategoryName] == MooseGroup:GetCategory() then - MooseGroupCategory = true + self:T3( { "Category:", MGroup:GetCategory(), self.FilterMeta.Categories[CategoryName], CategoryName } ) + if self.FilterMeta.Categories[CategoryName] and self.FilterMeta.Categories[CategoryName] == MGroup:GetCategory() then + MGroupCategory = true end end - MooseGroupInclude = MooseGroupInclude and MooseGroupCategory + MGroupInclude = MGroupInclude and MGroupCategory end if self.Filter.Countries then - local MooseGroupCountry = false + local MGroupCountry = false for CountryID, CountryName in pairs( self.Filter.Countries ) do - self:T3( { "Country:", MooseGroup:GetCountry(), CountryName } ) - if country.id[CountryName] == MooseGroup:GetCountry() then - MooseGroupCountry = true + self:T3( { "Country:", MGroup:GetCountry(), CountryName } ) + if country.id[CountryName] == MGroup:GetCountry() then + MGroupCountry = true end end - MooseGroupInclude = MooseGroupInclude and MooseGroupCountry + MGroupInclude = MGroupInclude and MGroupCountry end if self.Filter.GroupPrefixes then - local MooseGroupPrefix = false + local MGroupPrefix = false for GroupPrefixId, GroupPrefix in pairs( self.Filter.GroupPrefixes ) do - self:T3( { "Prefix:", string.find( MooseGroup:GetName(), GroupPrefix, 1 ), GroupPrefix } ) - if string.find( MooseGroup:GetName(), GroupPrefix:gsub ("-", "%%-"), 1 ) then - MooseGroupPrefix = true + self:T3( { "Prefix:", string.find( MGroup:GetName(), GroupPrefix, 1 ), GroupPrefix } ) + if string.find( MGroup:GetName(), GroupPrefix:gsub ("-", "%%-"), 1 ) then + MGroupPrefix = true end end - MooseGroupInclude = MooseGroupInclude and MooseGroupPrefix + MGroupInclude = MGroupInclude and MGroupPrefix end - self:T2( MooseGroupInclude ) - return MooseGroupInclude + self:T2( MGroupInclude ) + return MGroupInclude end @@ -1463,18 +1502,18 @@ do -- SET_UNIT -- * Unit types -- * Starting with certain prefix strings. -- - -- ## SET_UNIT constructor + -- ## 1) SET_UNIT constructor -- -- Create a new SET_UNIT object with the @{#SET_UNIT.New} method: -- -- * @{#SET_UNIT.New}: Creates a new SET_UNIT object. -- - -- ## Add or Remove UNIT(s) from SET_UNIT + -- ## 2) Add or Remove UNIT(s) from SET_UNIT -- -- UNITs can be added and removed using the @{Core.Set#SET_UNIT.AddUnitsByName} and @{Core.Set#SET_UNIT.RemoveUnitsByName} respectively. -- These methods take a single UNIT name or an array of UNIT names to be added or removed from SET_UNIT. -- - -- ## SET_UNIT filter criteria + -- ## 3) SET_UNIT filter criteria -- -- You can set filter criteria to define the set of units within the SET_UNIT. -- Filter criteria are defined by: @@ -1484,24 +1523,26 @@ do -- SET_UNIT -- * @{#SET_UNIT.FilterTypes}: Builds the SET_UNIT with the units belonging to the unit type(s). -- * @{#SET_UNIT.FilterCountries}: Builds the SET_UNIT with the units belonging to the country(ies). -- * @{#SET_UNIT.FilterPrefixes}: Builds the SET_UNIT with the units starting with the same prefix string(s). + -- * @{#SET_UNIT.FilterActive}: Builds the SET_UNIT with the units that are only active. Units that are inactive (late activation) won't be included in the set! -- -- Once the filter criteria have been set for the SET_UNIT, you can start filtering using: -- - -- * @{#SET_UNIT.FilterStart}: Starts the filtering of the units within the SET_UNIT. + -- * @{#SET_UNIT.FilterStart}: Starts the filtering of the units **dynamically**. + -- * @{#SET_UNIT.FilterOnce}: Filters of the units **once**. -- -- Planned filter criteria within development are (so these are not yet available): -- -- * @{#SET_UNIT.FilterZones}: Builds the SET_UNIT with the units within a @{Core.Zone#ZONE}. -- - -- ## SET_UNIT iterators + -- ## 4) SET_UNIT iterators -- -- Once the filters have been defined and the SET_UNIT has been built, you can iterate the SET_UNIT with the available iterator methods. -- The iterator methods will walk the SET_UNIT set, and call for each element within the set a function that you provide. -- The following iterator methods are currently available within the SET_UNIT: -- -- * @{#SET_UNIT.ForEachUnit}: Calls a function for each alive unit it finds within the SET_UNIT. - -- * @{#SET_GROUP.ForEachGroupCompletelyInZone}: Iterate the SET_GROUP and call an iterator function for each **alive** GROUP presence completely in a @{Zone}, providing the GROUP and optional parameters to the called function. - -- * @{#SET_GROUP.ForEachGroupNotInZone}: Iterate the SET_GROUP and call an iterator function for each **alive** GROUP presence not in a @{Zone}, providing the GROUP and optional parameters to the called function. + -- * @{#SET_UNIT.ForEachUnitInZone}: Iterate the SET_UNIT and call an iterator function for each **alive** UNIT object presence completely in a @{Zone}, providing the UNIT object and optional parameters to the called function. + -- * @{#SET_UNIT.ForEachUnitNotInZone}: Iterate the SET_UNIT and call an iterator function for each **alive** UNIT object presence not in a @{Zone}, providing the UNIT object and optional parameters to the called function. -- -- Planned iterators methods in development are (so these are not yet available): -- @@ -1509,27 +1550,17 @@ do -- SET_UNIT -- * @{#SET_UNIT.ForEachUnitCompletelyInZone}: Iterate and call an iterator function for each **alive** UNIT presence completely in a @{Zone}, providing the UNIT and optional parameters to the called function. -- * @{#SET_UNIT.ForEachUnitNotInZone}: Iterate and call an iterator function for each **alive** UNIT presence not in a @{Zone}, providing the UNIT and optional parameters to the called function. -- - -- ## SET_UNIT atomic methods + -- ## 5) SET_UNIT atomic methods -- -- Various methods exist for a SET_UNIT to perform actions or calculations and retrieve results from the SET_UNIT: -- -- * @{#SET_UNIT.GetTypeNames}(): Retrieve the type names of the @{Wrapper.Unit}s in the SET, delimited by a comma. -- - -- ## SET_UNIT iterators - -- - -- Once the filters have been defined and the SET_UNIT has been built, you can iterate the SET_UNIT with the available iterator methods. - -- The iterator methods will walk the SET_UNIT set, and call for each element within the set a function that you provide. - -- The following iterator methods are currently available within the SET_UNIT: - -- - -- * @{#SET_UNIT.ForEachUnit}: Calls a function for each alive group it finds within the SET_UNIT. - -- * @{#SET_UNIT.ForEachUnitInZone}: Iterate the SET_UNIT and call an iterator function for each **alive** UNIT object presence completely in a @{Zone}, providing the UNIT object and optional parameters to the called function. - -- * @{#SET_UNIT.ForEachUnitNotInZone}: Iterate the SET_UNIT and call an iterator function for each **alive** UNIT object presence not in a @{Zone}, providing the UNIT object and optional parameters to the called function. - -- - -- ## SET_UNIT trigger events on the UNIT objects. + -- ## 6) SET_UNIT trigger events on the UNIT objects. -- -- The SET is derived from the FSM class, which provides extra capabilities to track the contents of the UNIT objects in the SET_UNIT. -- - -- ### When a UNIT object crashes or is dead, the SET_UNIT will trigger a **Dead** event. + -- ### 6.1) When a UNIT object crashes or is dead, the SET_UNIT will trigger a **Dead** event. -- -- You can handle the event using the OnBefore and OnAfter event handlers. -- The event handlers need to have the paramters From, Event, To, GroupObject. @@ -1611,7 +1642,9 @@ do -- SET_UNIT function SET_UNIT:New() -- Inherits from BASE - local self = BASE:Inherit( self, SET_BASE:New( _DATABASE.UNITS ) ) -- Core.Set#SET_UNIT + local self = BASE:Inherit( self, SET_BASE:New( _DATABASE.UNITS ) ) -- #SET_UNIT + + self:FilterActive( false ) return self end @@ -1769,6 +1802,32 @@ do -- SET_UNIT return self end + --- Builds a set of units that are only active. + -- Only the units that are active will be included within the set. + -- @param #SET_UNIT self + -- @param #boolean Active (optional) Include only active units to the set. + -- Include inactive units if you provide false. + -- @return #SET_UNIT self + -- @usage + -- + -- -- Include only active units to the set. + -- UnitSet = SET_UNIT:New():FilterActive():FilterStart() + -- + -- -- Include only active units to the set of the blue coalition, and filter one time. + -- UnitSet = SET_UNIT:New():FilterActive():FilterCoalition( "blue" ):FilterOnce() + -- + -- -- Include only active units to the set of the blue coalition, and filter one time. + -- -- Later, reset to include back inactive units to the set. + -- UnitSet = SET_UNIT:New():FilterActive():FilterCoalition( "blue" ):FilterOnce() + -- ... logic ... + -- UnitSet = SET_UNIT:New():FilterActive( false ):FilterCoalition( "blue" ):FilterOnce() + -- + function SET_UNIT:FilterActive( Active ) + Active = Active or not ( Active == false ) + self.Filter.Active = Active + return self + end + --- Builds a set of units having a radar of give types. -- All the units having a radar of a given type will be included within the set. -- @param #SET_UNIT self @@ -2343,6 +2402,14 @@ do -- SET_UNIT self:F2( MUnit ) local MUnitInclude = true + if self.Filter.Active ~= nil then + local MUnitActive = false + if self.Filter.Active == false or ( self.Filter.Active == true and MUnit:IsActive() == true ) then + MUnitActive = true + end + MUnitInclude = MUnitInclude and MUnitActive + end + if self.Filter.Coalitions then local MUnitCoalition = false for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do @@ -3155,18 +3222,18 @@ end -- * Client types -- * Starting with certain prefix strings. -- --- ## SET_CLIENT constructor +-- ## 1) SET_CLIENT constructor -- -- Create a new SET_CLIENT object with the @{#SET_CLIENT.New} method: -- -- * @{#SET_CLIENT.New}: Creates a new SET_CLIENT object. -- --- ## Add or Remove CLIENT(s) from SET_CLIENT +-- ## 2) Add or Remove CLIENT(s) from SET_CLIENT -- -- CLIENTs can be added and removed using the @{Core.Set#SET_CLIENT.AddClientsByName} and @{Core.Set#SET_CLIENT.RemoveClientsByName} respectively. -- These methods take a single CLIENT name or an array of CLIENT names to be added or removed from SET_CLIENT. -- --- ## SET_CLIENT filter criteria +-- ## 3) SET_CLIENT filter criteria -- -- You can set filter criteria to define the set of clients within the SET_CLIENT. -- Filter criteria are defined by: @@ -3176,16 +3243,18 @@ end -- * @{#SET_CLIENT.FilterTypes}: Builds the SET_CLIENT with the clients belonging to the client type(s). -- * @{#SET_CLIENT.FilterCountries}: Builds the SET_CLIENT with the clients belonging to the country(ies). -- * @{#SET_CLIENT.FilterPrefixes}: Builds the SET_CLIENT with the clients starting with the same prefix string(s). +-- * @{#SET_CLIENT.FilterActive}: Builds the SET_CLIENT with the units that are only active. Units that are inactive (late activation) won't be included in the set! -- -- Once the filter criteria have been set for the SET_CLIENT, you can start filtering using: -- --- * @{#SET_CLIENT.FilterStart}: Starts the filtering of the clients within the SET_CLIENT. +-- * @{#SET_CLIENT.FilterStart}: Starts the filtering of the clients **dynamically**. +-- * @{#SET_CLIENT.FilterOnce}: Filters the clients **once**. -- -- Planned filter criteria within development are (so these are not yet available): -- -- * @{#SET_CLIENT.FilterZones}: Builds the SET_CLIENT with the clients within a @{Core.Zone#ZONE}. -- --- ## SET_CLIENT iterators +-- ## 4) SET_CLIENT iterators -- -- Once the filters have been defined and the SET_CLIENT has been built, you can iterate the SET_CLIENT with the available iterator methods. -- The iterator methods will walk the SET_CLIENT set, and call for each element within the set a function that you provide. @@ -3230,7 +3299,9 @@ SET_CLIENT = { -- DBObject = SET_CLIENT:New() function SET_CLIENT:New() -- Inherits from BASE - local self = BASE:Inherit( self, SET_BASE:New( _DATABASE.CLIENTS ) ) + local self = BASE:Inherit( self, SET_BASE:New( _DATABASE.CLIENTS ) ) -- #SET_CLIENT + + self:FilterActive( false ) return self end @@ -3372,6 +3443,31 @@ function SET_CLIENT:FilterPrefixes( Prefixes ) return self end +--- Builds a set of clients that are only active. +-- Only the clients that are active will be included within the set. +-- @param #SET_CLIENT self +-- @param #boolean Active (optional) Include only active clients to the set. +-- Include inactive clients if you provide false. +-- @return #SET_CLIENT self +-- @usage +-- +-- -- Include only active clients to the set. +-- ClientSet = SET_CLIENT:New():FilterActive():FilterStart() +-- +-- -- Include only active clients to the set of the blue coalition, and filter one time. +-- ClientSet = SET_CLIENT:New():FilterActive():FilterCoalition( "blue" ):FilterOnce() +-- +-- -- Include only active clients to the set of the blue coalition, and filter one time. +-- -- Later, reset to include back inactive clients to the set. +-- ClientSet = SET_CLIENT:New():FilterActive():FilterCoalition( "blue" ):FilterOnce() +-- ... logic ... +-- ClientSet = SET_CLIENT:New():FilterActive( false ):FilterCoalition( "blue" ):FilterOnce() +-- +function SET_CLIENT:FilterActive( Active ) + Active = Active or not ( Active == false ) + self.Filter.Active = Active + return self +end @@ -3482,6 +3578,14 @@ function SET_CLIENT:IsIncludeObject( MClient ) if MClient then local MClientName = MClient.UnitName + if self.Filter.Active ~= nil then + local MClientActive = false + if self.Filter.Active == false or ( self.Filter.Active == true and MClient:IsActive() == true ) then + MClientActive = true + end + MClientInclude = MClientInclude and MClientActive + end + if self.Filter.Coalitions then local MClientCoalition = false for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do diff --git a/Moose Development/Moose/Core/Settings.lua b/Moose Development/Moose/Core/Settings.lua index 819690607..20935af35 100644 --- a/Moose Development/Moose/Core/Settings.lua +++ b/Moose Development/Moose/Core/Settings.lua @@ -364,7 +364,6 @@ do -- SETTINGS -- @param #SETTINGS self -- @return #boolean true if BRA function SETTINGS:IsA2A_BRAA() - self:E( { BRA = ( self.A2ASystem and self.A2ASystem == "BRAA" ) or ( not self.A2ASystem and _SETTINGS:IsA2A_BRAA() ) } ) return ( self.A2ASystem and self.A2ASystem == "BRAA" ) or ( not self.A2ASystem and _SETTINGS:IsA2A_BRAA() ) end diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index 44ca57d5f..470de56b4 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -205,18 +205,18 @@ function GROUP:GetPositionVec3() -- Overridden from POSITIONABLE:GetPositionVec3 return nil end ---- Returns if the Group is alive. +--- Returns if the group is alive. -- The Group must: -- -- * Exist at run-time. -- * Has at least one unit. -- --- When the first @{Wrapper.Unit} of the Group is active, it will return true. --- If the first @{Wrapper.Unit} of the Group is inactive, it will return false. +-- When the first @{Wrapper.Unit} of the group is active, it will return true. +-- If the first @{Wrapper.Unit} of the group is inactive, it will return false. -- -- @param #GROUP self --- @return #boolean true if the Group is alive and active. --- @return #boolean false if the Group is alive but inactive. +-- @return #boolean true if the group is alive and active. +-- @return #boolean false if the group is alive but inactive. -- @return #nil if the group does not exist anymore. function GROUP:IsAlive() self:F2( self.GroupName ) @@ -237,6 +237,26 @@ function GROUP:IsAlive() return nil end +--- Returns if the group is activated. +-- @param #GROUP self +-- @return #boolean true if group is activated. +-- @return #nil The group is not existing or alive. +function GROUP:IsActive() + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSObject() -- DCS#Group + + if DCSGroup then + + local GroupIsActive = DCSGroup:getUnit(1):isActive() + return GroupIsActive + end + + return nil +end + + + --- Destroys the DCS Group and all of its DCS Units. -- Note that this destroy method also can raise a destroy event at run-time. -- So all event listeners will catch the destroy event of this group for each unit in the group.