FlightControl 645d074a7d GROUPSET and UNITSET are working now !!
- GROUPSET and UNITSET inherit SET
- DATABASE optimized
- Tracing levels tuned.
2016-05-27 11:32:49 +02:00

364 lines
11 KiB
Lua

--- Create and manage a set of units.
--
-- @{#UNITSET} class
-- ==================
-- Mission designers can use the UNITSET class to build sets of units belonging to certain:
--
-- * Coalitions
-- * Categories
-- * Countries
-- * Unit types
-- * Starting with certain prefix strings.
--
-- UNITSET construction methods:
-- =================================
-- Create a new UNITSET object with the @{#UNITSET.New} method:
--
-- * @{#UNITSET.New}: Creates a new UNITSET object.
--
--
-- UNITSET filter criteria:
-- =========================
-- You can set filter criteria to define the set of units within the UNITSET.
-- Filter criteria are defined by:
--
-- * @{#UNITSET.FilterCoalitions}: Builds the UNITSET with the units belonging to the coalition(s).
-- * @{#UNITSET.FilterCategories}: Builds the UNITSET with the units belonging to the category(ies).
-- * @{#UNITSET.FilterTypes}: Builds the UNITSET with the units belonging to the unit type(s).
-- * @{#UNITSET.FilterCountries}: Builds the UNITSET with the units belonging to the country(ies).
-- * @{#UNITSET.FilterPrefixes}: Builds the UNITSET with the units starting with the same prefix string(s).
--
-- Once the filter criteria have been set for the UNITSET, you can start filtering using:
--
-- * @{#UNITSET.FilterStart}: Starts the filtering of the units within the UNITSET.
--
-- Planned filter criteria within development are (so these are not yet available):
--
-- * @{#UNITSET.FilterZones}: Builds the UNITSET with the units within a @{Zone#ZONE}.
--
--
-- UNITSET iterators:
-- ===================
-- Once the filters have been defined and the UNITSET has been built, you can iterate the UNITSET with the available iterator methods.
-- The iterator methods will walk the UNITSET set, and call for each element within the set a function that you provide.
-- The following iterator methods are currently available within the UNITSET:
--
-- * @{#UNITSET.ForEachUnit}: Calls a function for each alive unit it finds within the UNITSET.
--
-- Planned iterators methods in development are (so these are not yet available):
--
-- * @{#UNITSET.ForEachUnitInGroup}: Calls a function for each group contained within the UNITSET.
-- * @{#UNITSET.ForEachUnitInZone}: Calls a function for each unit within a certain zone contained within the UNITSET.
--
-- @module UnitSet
-- @author FlightControl
Include.File( "Routines" )
Include.File( "Base" )
Include.File( "Unit" )
Include.File( "Set" )
--- UNITSET class
-- @type UNITSET
-- @extends Set#SET
UNITSET = {
ClassName = "UNITSET",
Units = {},
Filter = {
Coalitions = nil,
Categories = nil,
Types = nil,
Countries = nil,
UnitPrefixes = nil,
},
FilterMeta = {
Coalitions = {
red = coalition.side.RED,
blue = coalition.side.BLUE,
neutral = coalition.side.NEUTRAL,
},
Categories = {
plane = Unit.Category.AIRPLANE,
helicopter = Unit.Category.HELICOPTER,
ground = Unit.Category.GROUND_UNIT,
ship = Unit.Category.SHIP,
structure = Unit.Category.STRUCTURE,
},
},
}
--- Creates a new UNITSET object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.
-- @param #UNITSET self
-- @return #UNITSET
-- @usage
-- -- Define a new UNITSET Object. This DBObject will contain a reference to all alive Units.
-- DBObject = UNITSET:New()
function UNITSET:New()
-- Inherits from BASE
local self = BASE:Inherit( self, SET:New( _DATABASE.UNITS ) )
return self
end
--- Finds a Unit based on the Unit Name.
-- @param #UNITSET self
-- @param #string UnitName
-- @return Unit#UNIT The found Unit.
function UNITSET:FindUnit( UnitName )
local UnitFound = self.Set[UnitName]
return UnitFound
end
--- Builds a set of units of coalitions.
-- Possible current coalitions are red, blue and neutral.
-- @param #UNITSET self
-- @param #string Coalitions Can take the following values: "red", "blue", "neutral".
-- @return #UNITSET self
function UNITSET:FilterCoalitions( Coalitions )
if not self.Filter.Coalitions then
self.Filter.Coalitions = {}
end
if type( Coalitions ) ~= "table" then
Coalitions = { Coalitions }
end
for CoalitionID, Coalition in pairs( Coalitions ) do
self.Filter.Coalitions[Coalition] = Coalition
end
return self
end
--- Builds a set of units out of categories.
-- Possible current categories are plane, helicopter, ground, ship.
-- @param #UNITSET self
-- @param #string Categories Can take the following values: "plane", "helicopter", "ground", "ship".
-- @return #UNITSET self
function UNITSET:FilterCategories( Categories )
if 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
--- Builds a set of units of defined unit types.
-- Possible current types are those types known within DCS world.
-- @param #UNITSET self
-- @param #string Types Can take those type strings known within DCS world.
-- @return #UNITSET self
function UNITSET:FilterTypes( Types )
if not self.Filter.Types then
self.Filter.Types = {}
end
if type( Types ) ~= "table" then
Types = { Types }
end
for TypeID, Type in pairs( Types ) do
self.Filter.Types[Type] = Type
end
return self
end
--- Builds a set of units of defined countries.
-- Possible current countries are those known within DCS world.
-- @param #UNITSET self
-- @param #string Countries Can take those country strings known within DCS world.
-- @return #UNITSET self
function UNITSET:FilterCountries( Countries )
if not self.Filter.Countries then
self.Filter.Countries = {}
end
if type( Countries ) ~= "table" then
Countries = { Countries }
end
for CountryID, Country in pairs( Countries ) do
self.Filter.Countries[Country] = Country
end
return self
end
--- Builds a set of units of defined unit prefixes.
-- All the units starting with the given prefixes will be included within the set.
-- @param #UNITSET self
-- @param #string Prefixes The prefix of which the unit name starts with.
-- @return #UNITSET self
function UNITSET:FilterPrefixes( Prefixes )
if not self.Filter.UnitPrefixes then
self.Filter.UnitPrefixes = {}
end
if type( Prefixes ) ~= "table" then
Prefixes = { Prefixes }
end
for PrefixID, Prefix in pairs( Prefixes ) do
self.Filter.UnitPrefixes[Prefix] = Prefix
end
return self
end
--- Starts the filtering.
-- @param #UNITSET self
-- @return #UNITSET self
function UNITSET:FilterStart()
if _DATABASE then
self:_FilterStart()
end
return self
end
--- Handles the Database to check on an event (birth) that the Object was added in the Database.
-- This is required, because sometimes the _DATABASE birth event gets called later than the SET birth event!
-- @param #UNITSET self
-- @param Event#EVENTDATA Event
-- @return #string The name of the UNIT
-- @return #table The UNIT
function UNITSET:AddInDatabase( Event )
self:F3( { Event } )
if not self.Database[Event.IniDCSUnitName] then
self.Database[Event.IniDCSUnitName] = UNIT:Register( Event.IniDCSUnitName )
self:T3( self.Database[Event.IniDCSUnitName] )
end
return Event.IniDCSUnitName, self.Database[Event.IniDCSUnitName]
end
--- Handles the Database to check on any event that Object exists in the Database.
-- This is required, because sometimes the _DATABASE event gets called later than the SET event or vise versa!
-- @param #UNITSET self
-- @param Event#EVENTDATA Event
-- @return #string The name of the UNIT
-- @return #table The UNIT
function UNITSET:FindInDatabase( Event )
self:F3( { Event } )
return Event.IniDCSUnitName, self.Database[Event.IniDCSUnitName]
end
--- Interate the UNITSET and call an interator function for each **alive** UNIT, providing the UNIT and optional parameters.
-- @param #UNITSET self
-- @param #function IteratorFunction The function that will be called when there is an alive UNIT in the UNITSET. The function needs to accept a UNIT parameter.
-- @return #UNITSET self
function UNITSET:ForEachUnit( IteratorFunction, ... )
self:F2( arg )
self:ForEach( IteratorFunction, arg, self.Set )
return self
end
----- Interate the UNITSET and call an interator function for each **alive** player, providing the Unit of the player and optional parameters.
---- @param #UNITSET self
---- @param #function IteratorFunction The function that will be called when there is an alive player in the UNITSET. The function needs to accept a UNIT parameter.
---- @return #UNITSET self
--function UNITSET:ForEachPlayer( IteratorFunction, ... )
-- self:F2( arg )
--
-- self:ForEach( IteratorFunction, arg, self.PlayersAlive )
--
-- return self
--end
--
--
----- Interate the UNITSET and call an interator function for each client, providing the Client to the function and optional parameters.
---- @param #UNITSET self
---- @param #function IteratorFunction The function that will be called when there is an alive player in the UNITSET. The function needs to accept a CLIENT parameter.
---- @return #UNITSET self
--function UNITSET:ForEachClient( IteratorFunction, ... )
-- self:F2( arg )
--
-- self:ForEach( IteratorFunction, arg, self.Clients )
--
-- return self
--end
---
-- @param #UNITSET self
-- @param Unit#UNIT MUnit
-- @return #UNITSET self
function UNITSET:IsIncludeObject( MUnit )
self:F2( MUnit )
local MUnitInclude = true
if self.Filter.Coalitions then
local MUnitCoalition = false
for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do
self:T3( { "Coalition:", MUnit:GetCoalition(), self.FilterMeta.Coalitions[CoalitionName], CoalitionName } )
if self.FilterMeta.Coalitions[CoalitionName] and self.FilterMeta.Coalitions[CoalitionName] == MUnit:GetCoalition() then
MUnitCoalition = true
end
end
MUnitInclude = MUnitInclude and MUnitCoalition
end
if self.Filter.Categories then
local MUnitCategory = false
for CategoryID, CategoryName in pairs( self.Filter.Categories ) do
self:T3( { "Category:", MUnit:GetDesc().category, self.FilterMeta.Categories[CategoryName], CategoryName } )
if self.FilterMeta.Categories[CategoryName] and self.FilterMeta.Categories[CategoryName] == MUnit:GetDesc().category then
MUnitCategory = true
end
end
MUnitInclude = MUnitInclude and MUnitCategory
end
if self.Filter.Types then
local MUnitType = false
for TypeID, TypeName in pairs( self.Filter.Types ) do
self:T3( { "Type:", MUnit:GetTypeName(), TypeName } )
if TypeName == MUnit:GetTypeName() then
MUnitType = true
end
end
MUnitInclude = MUnitInclude and MUnitType
end
if self.Filter.Countries then
local MUnitCountry = false
for CountryID, CountryName in pairs( self.Filter.Countries ) do
self:T3( { "Country:", MUnit:GetCountry(), CountryName } )
if country.id[CountryName] == MUnit:GetCountry() then
MUnitCountry = true
end
end
MUnitInclude = MUnitInclude and MUnitCountry
end
if self.Filter.UnitPrefixes then
local MUnitPrefix = false
for UnitPrefixId, UnitPrefix in pairs( self.Filter.UnitPrefixes ) do
self:T3( { "Prefix:", string.find( MUnit:GetName(), UnitPrefix, 1 ), UnitPrefix } )
if string.find( MUnit:GetName(), UnitPrefix, 1 ) then
MUnitPrefix = true
end
end
MUnitInclude = MUnitInclude and MUnitPrefix
end
self:T2( MUnitInclude )
return MUnitInclude
end