diff --git a/Moose Development/Moose/Base.lua b/Moose Development/Moose/Base.lua index e2196c8ba..3586673d1 100644 --- a/Moose Development/Moose/Base.lua +++ b/Moose Development/Moose/Base.lua @@ -487,7 +487,10 @@ function BASE:E( Arguments ) end local LineCurrent = DebugInfoCurrent.currentline - local LineFrom = DebugInfoFrom.currentline + local LineFrom = -1 + if DebugInfoFrom then + LineFrom = DebugInfoFrom.currentline + end env.info( string.format( "%6d(%6d)/%1s:%20s%05d.%s(%s)" , LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) end diff --git a/Moose Development/Moose/Database.lua b/Moose Development/Moose/Database.lua index 1814af91f..66febcae9 100644 --- a/Moose Development/Moose/Database.lua +++ b/Moose Development/Moose/Database.lua @@ -1,64 +1,34 @@ ---- Manage sets of units and groups. +--- Manage the mission database. -- --- @{#Database} class +-- @{#DATABASE} class -- ================== --- Mission designers can use the DATABASE class to build sets of units belonging to certain: +-- Mission designers can use the DATABASE class to refer to: -- --- * Coalitions --- * Categories --- * Countries --- * Unit types --- * Starting with certain prefix strings. +-- * UNITS +-- * GROUPS +-- * players +-- * alive players +-- * CLIENTS +-- * alive CLIENTS -- --- This list will grow over time. Planned developments are to include filters and iterators. --- Additional filters will be added around @{Zone#ZONEs}, Radiuses, Active players, ... --- More iterators will be implemented in the near future ... --- --- Administers the Initial Sets of the Mission Templates as defined within the Mission Editor. --- --- DATABASE construction methods: --- ================================= --- Create a new DATABASE object with the @{#DATABASE.New} method: --- --- * @{#DATABASE.New}: Creates a new DATABASE object. --- --- --- DATABASE filter criteria: --- ========================= --- You can set filter criteria to define the set of units within the database. --- Filter criteria are defined by: --- --- * @{#DATABASE.FilterCoalitions}: Builds the DATABASE with the units belonging to the coalition(s). --- * @{#DATABASE.FilterCategories}: Builds the DATABASE with the units belonging to the category(ies). --- * @{#DATABASE.FilterTypes}: Builds the DATABASE with the units belonging to the unit type(s). --- * @{#DATABASE.FilterCountries}: Builds the DATABASE with the units belonging to the country(ies). --- * @{#DATABASE.FilterUnitPrefixes}: Builds the DATABASE with the units starting with the same prefix string(s). --- --- Once the filter criteria have been set for the DATABASE, you can start filtering using: --- --- * @{#DATABASE.FilterStart}: Starts the filtering of the units within the database. --- --- Planned filter criteria within development are (so these are not yet available): --- --- * @{#DATABASE.FilterGroupPrefixes}: Builds the DATABASE with the groups of the units starting with the same prefix string(s). --- * @{#DATABASE.FilterZones}: Builds the DATABASE with the units within a @{Zone#ZONE}. +-- On top, for internal MOOSE administration purposes, the DATBASE administers the Unit and Gruop templates as defined within the Mission Editor. -- +-- Moose will automatically create one instance of the DATABASE class into the **global** object _DATABASE. +-- Moose refers to _DATABASE within the framework extensively, but you can also refer to the _DATABASE object within your missions if required. -- -- DATABASE iterators: -- =================== --- Once the filters have been defined and the DATABASE has been built, you can iterate the database with the available iterator methods. +-- You can iterate the database with the available iterator methods. -- The iterator methods will walk the DATABASE set, and call for each element within the set a function that you provide. -- The following iterator methods are currently available within the DATABASE: -- --- * @{#DATABASE.ForEachAliveUnit}: Calls a function for each alive unit it finds within the DATABASE. +-- * @{#DATABASE.ForEachUnit}: Calls a function for each @{UNIT} it finds within the DATABASE. +-- * @{#DATABASE.ForEachGroup}: Calls a function for each @{GROUP} it finds within the DATABASE. +-- * @{#DATABASE.ForEachPlayer}: Calls a function for each player it finds within the DATABASE. +-- * @{#DATABASE.ForEachPlayerAlive}: Calls a function for each alive player it finds within the DATABASE. +-- * @{#DATABASE.ForEachClient}: Calls a function for each @{CLIENT} it finds within the DATABASE. +-- * @{#DATABASE.ForEachClientAlive}: Calls a function for each alive @{CLIENT} it finds within the DATABASE. -- --- Planned iterators methods in development are (so these are not yet available): --- --- * @{#DATABASE.ForEachUnit}: Calls a function for each unit contained within the DATABASE. --- * @{#DATABASE.ForEachGroup}: Calls a function for each group contained within the DATABASE. --- * @{#DATABASE.ForEachUnitInZone}: Calls a function for each unit within a certain zone contained within the DATABASE. --- --- ==== -- @module Database -- @author FlightControl @@ -70,6 +40,7 @@ Include.File( "Unit" ) Include.File( "Event" ) Include.File( "Client" ) + --- DATABASE class -- @type DATABASE -- @extends Base#BASE @@ -85,34 +56,11 @@ DATABASE = { DCSGroups = {}, UNITS = {}, GROUPS = {}, - NavPoints = {}, - Statics = {}, - Players = {}, - PlayersAlive = {}, + PLAYERS = {}, + PLAYERSALIVE = {}, CLIENTS = {}, - ClientsAlive = {}, - Filter = { - Coalitions = nil, - Categories = nil, - Types = nil, - Countries = nil, - UnitPrefixes = nil, - GroupPrefixes = 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, - }, - }, + CLIENTSALIVE = {}, + NavPoints = {}, } local _DATABASECoalition = @@ -147,12 +95,13 @@ function DATABASE:New() _EVENTDISPATCHER:OnCrash( self._EventOnDeadOrCrash, self ) - -- Add database with registered clients and already alive players - -- Follow alive players and clients _EVENTDISPATCHER:OnPlayerEnterUnit( self._EventOnPlayerEnterUnit, self ) _EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventOnPlayerLeaveUnit, self ) + self:_RegisterTemplates() + self:_RegisterDatabase() + self:_RegisterPlayers() return self end @@ -167,6 +116,7 @@ function DATABASE:FindUnit( UnitName ) return UnitFound end + --- Adds a Unit based on the Unit Name in the DATABASE. -- @param #DATABASE self function DATABASE:AddUnit( DCSUnit, DCSUnitName ) @@ -175,6 +125,7 @@ function DATABASE:AddUnit( DCSUnit, DCSUnitName ) self.UNITS[DCSUnitName] = UNIT:Register( DCSUnitName ) end + --- Deletes a Unit from the DATABASE based on the Unit Name. -- @param #DATABASE self function DATABASE:DeleteUnit( DCSUnitName ) @@ -182,6 +133,7 @@ function DATABASE:DeleteUnit( DCSUnitName ) self.DCSUnits[DCSUnitName] = nil end + --- Finds a CLIENT based on the ClientName. -- @param #DATABASE self -- @param #string ClientName @@ -192,6 +144,7 @@ function DATABASE:FindClient( ClientName ) return ClientFound end + --- Adds a CLIENT based on the ClientName in the DATABASE. -- @param #DATABASE self function DATABASE:AddClient( ClientName ) @@ -200,6 +153,7 @@ function DATABASE:AddClient( ClientName ) self:E( self.CLIENTS[ClientName]:GetClassNameAndID() ) end + --- Finds a GROUP based on the GroupName. -- @param #DATABASE self -- @param #string GroupName @@ -210,6 +164,7 @@ function DATABASE:FindGroup( GroupName ) return GroupFound end + --- Adds a GROUP based on the GroupName in the DATABASE. -- @param #DATABASE self function DATABASE:AddGroup( DCSGroup, GroupName ) @@ -218,6 +173,30 @@ function DATABASE:AddGroup( DCSGroup, GroupName ) self.GROUPS[GroupName] = GROUP:Register( GroupName ) end +--- Adds a player based on the Player Name in the DATABASE. +-- @param #DATABASE self +function DATABASE:AddPlayer( UnitName, PlayerName ) + + if PlayerName then + self:E( { "Add player for unit:", UnitName, PlayerName } ) + self.PLAYERS[PlayerName] = PlayerName + self.PLAYERSALIVE[PlayerName] = PlayerName + self.CLIENTSALIVE[PlayerName] = self:FindClient( UnitName ) + end +end + +--- Deletes a player from the DATABASE based on the Player Name. +-- @param #DATABASE self +function DATABASE:DeletePlayer( PlayerName ) + + if PlayerName then + self:E( { "Clean player:", PlayerName } ) + self.PLAYERSALIVE[PlayerName] = nil + self.CLIENTSALIVE[PlayerName] = nil + end +end + + --- Instantiate new Groups within the DCSRTE. -- This method expects EXACTLY the same structure as a structure within the ME, and needs 2 additional fields defined: -- SpawnCountryID, SpawnCategoryID @@ -226,9 +205,9 @@ end -- @param #table SpawnTemplate -- @return #DATABASE self function DATABASE:Spawn( SpawnTemplate ) - self:F( SpawnTemplate.name ) + self:F2( SpawnTemplate.name ) - self:T( { SpawnTemplate.SpawnCountryID, SpawnTemplate.SpawnCategoryID } ) + self:T2( { SpawnTemplate.SpawnCountryID, SpawnTemplate.SpawnCategoryID } ) -- Copy the spawn variables of the template in temporary storage, nullify, and restore the spawn variables. local SpawnCoalitionID = SpawnTemplate.SpawnCoalitionID @@ -240,7 +219,7 @@ function DATABASE:Spawn( SpawnTemplate ) SpawnTemplate.SpawnCountryID = nil SpawnTemplate.SpawnCategoryID = nil - self:_RegisterGroup( SpawnTemplate ) + self:_RegisterTemplate( SpawnTemplate ) coalition.addGroup( SpawnCountryID, SpawnCategoryID, SpawnTemplate ) -- Restore @@ -253,18 +232,16 @@ function DATABASE:Spawn( SpawnTemplate ) return SpawnGroup end - --- Set a status to a Group within the Database, this to check crossing events for example. function DATABASE:SetStatusGroup( GroupName, Status ) - self:F( Status ) + self:F2( Status ) self.Templates.Groups[GroupName].Status = Status end - --- Get a status to a Group within the Database, this to check crossing events for example. function DATABASE:GetStatusGroup( GroupName ) - self:F( Status ) + self:F2( Status ) if self.Templates.Groups[GroupName] then return self.Templates.Groups[GroupName].Status @@ -273,11 +250,12 @@ function DATABASE:GetStatusGroup( GroupName ) end end + --- Private method that registers new Group Templates within the DATABASE Object. -- @param #DATABASE self -- @param #table GroupTemplate -- @return #DATABASE self -function DATABASE:_RegisterGroup( GroupTemplate ) +function DATABASE:_RegisterTemplate( GroupTemplate ) local GroupTemplateName = env.getValueDictByKey(GroupTemplate.name) @@ -297,7 +275,7 @@ function DATABASE:_RegisterGroup( GroupTemplate ) self.Templates.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units self.Templates.Groups[GroupTemplateName].Units = GroupTemplate.units - self:T( { "Group", self.Templates.Groups[GroupTemplateName].GroupName, self.Templates.Groups[GroupTemplateName].UnitCount } ) + self:T2( { "Group", self.Templates.Groups[GroupTemplateName].GroupName, self.Templates.Groups[GroupTemplateName].UnitCount } ) for unit_num, UnitTemplate in pairs( GroupTemplate.units ) do @@ -317,6 +295,7 @@ function DATABASE:_RegisterGroup( GroupTemplate ) end end + --- Private method that registers all alive players in the mission. -- @param #DATABASE self -- @return #DATABASE self @@ -328,9 +307,10 @@ function DATABASE:_RegisterPlayers() self:T3( { "UnitData:", UnitData } ) if UnitData and UnitData:isExist() then local UnitName = UnitData:getName() - if not self.PlayersAlive[UnitName] then - self:E( { "Add player for unit:", UnitName, UnitData:getPlayerName() } ) - self.PlayersAlive[UnitName] = UnitData:getPlayerName() + local PlayerName = UnitData:getPlayerName() + if not self.PLAYERS[PlayerName] then + self:E( { "Add player for unit:", UnitName, PlayerName } ) + self:AddPlayer( UnitName, PlayerName ) end end end @@ -339,6 +319,7 @@ function DATABASE:_RegisterPlayers() return self end + --- Private method that registers all datapoints within in the mission. -- @param #DATABASE self -- @return #DATABASE self @@ -381,22 +362,21 @@ end -- @param #DATABASE self -- @param Event#EVENTDATA Event function DATABASE:_EventOnBirth( Event ) - self:F( { Event } ) + self:F2( { Event } ) if Event.IniDCSUnit then - if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then - self:AddUnit( Event.IniDCSUnit, Event.IniDCSUnitName ) - self:AddGroup( Event.IniDCSGroup, Event.IniDCSGroupName ) - self:_EventOnPlayerEnterUnit( Event ) - end + self:AddUnit( Event.IniDCSUnit, Event.IniDCSUnitName ) + self:AddGroup( Event.IniDCSGroup, Event.IniDCSGroupName ) + self:_EventOnPlayerEnterUnit( Event ) end end + --- Handles the OnDead or OnCrash event for alive units set. -- @param #DATABASE self -- @param Event#EVENTDATA Event function DATABASE:_EventOnDeadOrCrash( Event ) - self:F( { Event } ) + self:F2( { Event } ) if Event.IniDCSUnit then if self.DCSUnits[Event.IniDCSUnitName] then @@ -406,48 +386,44 @@ function DATABASE:_EventOnDeadOrCrash( Event ) end end + --- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied). -- @param #DATABASE self -- @param Event#EVENTDATA Event function DATABASE:_EventOnPlayerEnterUnit( Event ) - self:F( { Event } ) + self:F2( { Event } ) if Event.IniDCSUnit then - if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then - if not self.PlayersAlive[Event.IniDCSUnitName] then - self:E( { "Add player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) - self.PlayersAlive[Event.IniDCSUnitName] = Event.IniDCSUnit:getPlayerName() - self.ClientsAlive[Event.IniDCSUnitName] = self.CLIENTS[ Event.IniDCSUnitName ] - end + local PlayerName = Event.IniDCSUnit:getPlayerName() + if not self.PLAYERSALIVE[PlayerName] then + self:AddPlayer( Event.IniDCSUnitName, PlayerName ) end end end + --- Handles the OnPlayerLeaveUnit event to clean the active players table. -- @param #DATABASE self -- @param Event#EVENTDATA Event function DATABASE:_EventOnPlayerLeaveUnit( Event ) - self:F( { Event } ) + self:F2( { Event } ) if Event.IniDCSUnit then - if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then - if self.PlayersAlive[Event.IniDCSUnitName] then - self:E( { "Cleaning player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) - self.PlayersAlive[Event.IniDCSUnitName] = nil - self.ClientsAlive[Event.IniDCSUnitName] = nil - end + local PlayerName = Event.IniDCSUnit:getPlayerName() + if self.PLAYERSALIVE[PlayerName] then + self:DeletePlayer( PlayerName ) end end end --- Iterators ---- Interate the DATABASE and call an interator function for the given set, providing the Object for each element within the set and optional parameters. +--- Iterate the DATABASE and call an iterator function for the given set, providing the Object for each element within the set and optional parameters. -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called when there is an alive player in the database. -- @return #DATABASE self function DATABASE:ForEach( IteratorFunction, arg, Set ) - self:F( arg ) + self:F2( arg ) local function CoRoutine() local Count = 0 @@ -467,7 +443,7 @@ function DATABASE:ForEach( IteratorFunction, arg, Set ) local function Schedule() local status, res = coroutine.resume( co ) - self:T( { status, res } ) + self:T2( { status, res } ) if status == false then error( res ) @@ -485,46 +461,96 @@ function DATABASE:ForEach( IteratorFunction, arg, Set ) end ---- Interate the DATABASE and call an interator function for each **alive** unit, providing the Unit and optional parameters. +--- Iterate the DATABASE and call an iterator function for each **alive** unit, providing the DCSUnit and optional parameters. -- @param #DATABASE self --- @param #function IteratorFunction The function that will be called when there is an alive unit in the database. The function needs to accept a UNIT parameter. +-- @param #function IteratorFunction The function that will be called when there is an alive unit in the database. The function needs to accept a DCSUnit parameter. -- @return #DATABASE self function DATABASE:ForEachDCSUnit( IteratorFunction, ... ) - self:F( arg ) + self:F2( arg ) self:ForEach( IteratorFunction, arg, self.DCSUnits ) return self end ---- Interate the DATABASE and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. + +--- Iterate the DATABASE and call an iterator function for each **alive** UNIT, providing the UNIT and optional parameters. -- @param #DATABASE self --- @param #function IteratorFunction The function that will be called when there is an alive player in the database. The function needs to accept a UNIT parameter. +-- @param #function IteratorFunction The function that will be called when there is an alive UNIT in the database. The function needs to accept a UNIT parameter. +-- @return #DATABASE self +function DATABASE:ForEachUnit( IteratorFunction, ... ) + self:F2( arg ) + + self:ForEach( IteratorFunction, arg, self.UNITS ) + + return self +end + +--- Iterate the DATABASE and call an iterator function for each **alive** GROUP, providing the GROUP and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an alive GROUP in the database. The function needs to accept a GROUP parameter. +-- @return #DATABASE self +function DATABASE:ForEachGroup( IteratorFunction, ... ) + self:F2( arg ) + + self:ForEach( IteratorFunction, arg, self.GROUPS ) + + return self +end + + +--- Iterate the DATABASE and call an iterator function for each player, providing the player name and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an player in the database. The function needs to accept the player name. -- @return #DATABASE self function DATABASE:ForEachPlayer( IteratorFunction, ... ) - self:F( arg ) + self:F2( arg ) - self:ForEach( IteratorFunction, arg, self.PlayersAlive ) + self:ForEach( IteratorFunction, arg, self.PLAYERS ) return self end ---- Interate the DATABASE and call an interator function for each client, providing the Client to the function and optional parameters. +--- Iterate the DATABASE and call an iterator function for each **alive** player, providing the Unit of the player and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an alive player in the database. The function needs to accept a UNIT parameter. +-- @return #DATABASE self +function DATABASE:ForEachPlayerAlive( IteratorFunction, ... ) + self:F2( arg ) + + self:ForEach( IteratorFunction, arg, self.PLAYERSALIVE ) + + return self +end + +--- Iterate the DATABASE and call an iterator function for each CLIENT, providing the CLIENT to the function and optional parameters. -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called when there is an alive player in the database. The function needs to accept a CLIENT parameter. -- @return #DATABASE self function DATABASE:ForEachClient( IteratorFunction, ... ) - self:F( arg ) + self:F2( arg ) self:ForEach( IteratorFunction, arg, self.CLIENTS ) return self end +--- Iterate the DATABASE and call an iterator function for each **ALIVE** CLIENT, providing the CLIENT to the function and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an alive CLIENT in the database. The function needs to accept a CLIENT parameter. +-- @return #DATABASE self +function DATABASE:ForEachClientAlive( IteratorFunction, ... ) + self:F2( arg ) + + self:ForEach( IteratorFunction, arg, self.CLIENTSALIVE ) -function DATABASE:ScanEnvironment() - self:F() + return self +end + + +function DATABASE:_RegisterTemplates() + self:F2() self.Navpoints = {} self.UNITS = {} @@ -574,7 +600,7 @@ function DATABASE:ScanEnvironment() for group_num, GroupTemplate in pairs(obj_type_data.group) do if GroupTemplate and GroupTemplate.units and type(GroupTemplate.units) == 'table' then --making sure again- this is a valid group - self:_RegisterGroup( GroupTemplate ) + self:_RegisterTemplate( GroupTemplate ) end --if GroupTemplate and GroupTemplate.units then end --for group_num, GroupTemplate in pairs(obj_type_data.group) do end --if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then @@ -586,120 +612,9 @@ function DATABASE:ScanEnvironment() end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then end --for coa_name, coa_data in pairs(mission.coalition) do - self:_RegisterDatabase() - self:_RegisterPlayers() - return self end ---- --- @param #DATABASE self --- @param DCSUnit#Unit DCSUnit --- @return #DATABASE self -function DATABASE:_IsIncludeDCSUnit( DCSUnit ) - self:F( DCSUnit ) - local DCSUnitInclude = true - - if self.Filter.Coalitions then - local DCSUnitCoalition = false - for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do - self:T( { "Coalition:", DCSUnit:getCoalition(), self.FilterMeta.Coalitions[CoalitionName], CoalitionName } ) - if self.FilterMeta.Coalitions[CoalitionName] and self.FilterMeta.Coalitions[CoalitionName] == DCSUnit:getCoalition() then - DCSUnitCoalition = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitCoalition - end - - if self.Filter.Categories then - local DCSUnitCategory = false - for CategoryID, CategoryName in pairs( self.Filter.Categories ) do - self:T( { "Category:", DCSUnit:getDesc().category, self.FilterMeta.Categories[CategoryName], CategoryName } ) - if self.FilterMeta.Categories[CategoryName] and self.FilterMeta.Categories[CategoryName] == DCSUnit:getDesc().category then - DCSUnitCategory = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitCategory - end - - if self.Filter.Types then - local DCSUnitType = false - for TypeID, TypeName in pairs( self.Filter.Types ) do - self:T( { "Type:", DCSUnit:getTypeName(), TypeName } ) - if TypeName == DCSUnit:getTypeName() then - DCSUnitType = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitType - end - - if self.Filter.Countries then - local DCSUnitCountry = false - for CountryID, CountryName in pairs( self.Filter.Countries ) do - self:T( { "Country:", DCSUnit:getCountry(), CountryName } ) - if country.id[CountryName] == DCSUnit:getCountry() then - DCSUnitCountry = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitCountry - end - - if self.Filter.UnitPrefixes then - local DCSUnitPrefix = false - for UnitPrefixId, UnitPrefix in pairs( self.Filter.UnitPrefixes ) do - self:T( { "Unit Prefix:", string.find( DCSUnit:getName(), UnitPrefix, 1 ), UnitPrefix } ) - if string.find( DCSUnit:getName(), UnitPrefix, 1 ) then - DCSUnitPrefix = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitPrefix - end - - self:T( DCSUnitInclude ) - return DCSUnitInclude -end - ---- --- @param #DATABASE self --- @param DCSUnit#Unit DCSUnit --- @return #DATABASE self -function DATABASE:_IsAliveDCSUnit( DCSUnit ) - self:F( DCSUnit ) - local DCSUnitAlive = false - if DCSUnit and DCSUnit:isExist() and DCSUnit:isActive() then - if self.DCSUnits[DCSUnit:getName()] then - DCSUnitAlive = true - end - end - self:T( DCSUnitAlive ) - return DCSUnitAlive -end - ---- --- @param #DATABASE self --- @param DCSGroup#Group DCSGroup --- @return #DATABASE self -function DATABASE:_IsAliveDCSGroup( DCSGroup ) - self:F( DCSGroup ) - local DCSGroupAlive = false - if DCSGroup and DCSGroup:isExist() then - if self.DCSGroups[DCSGroup:getName()] then - DCSGroupAlive = true - end - end - self:T( DCSGroupAlive ) - return DCSGroupAlive -end - - ---- Traces the current database contents in the log ... (for debug reasons). --- @param #DATABASE self --- @return #DATABASE self -function DATABASE:TraceDatabase() - self:F() - - self:T( { "DCSUnits:", self.DCSUnits } ) -end diff --git a/Moose Development/Moose/Event.lua b/Moose Development/Moose/Event.lua index f7c2a0649..75cfca6ff 100644 --- a/Moose Development/Moose/Event.lua +++ b/Moose Development/Moose/Event.lua @@ -64,7 +64,7 @@ local _EVENTCODES = { function EVENT:New() local self = BASE:Inherit( self, BASE:New() ) - self:F() + self:F2() self.EventHandler = world.addEventHandler( self ) return self end @@ -154,7 +154,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnBirthForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnBirthForUnit ) @@ -167,7 +167,7 @@ end -- @param Base#BASE EventSelf -- @return #EVENT function EVENT:OnBirth( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_BIRTH ) @@ -181,7 +181,7 @@ end -- @param Base#BASE EventSelf -- @return #EVENT function EVENT:OnBirthForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_BIRTH ) @@ -195,7 +195,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnCrashForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnCrashForUnit ) @@ -208,7 +208,7 @@ end -- @param Base#BASE EventSelf -- @return #EVENT function EVENT:OnCrash( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_CRASH ) @@ -222,7 +222,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnCrashForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_CRASH ) @@ -236,7 +236,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnDeadForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnDeadForUnit ) @@ -249,7 +249,7 @@ end -- @param Base#BASE EventSelf -- @return #EVENT function EVENT:OnDead( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_DEAD ) @@ -264,7 +264,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnDeadForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_DEAD ) @@ -278,7 +278,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnPilotDeadForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_PILOT_DEAD ) @@ -292,7 +292,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnLandForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnLandForUnit ) @@ -306,7 +306,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnLandForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_LAND ) @@ -320,7 +320,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnTakeOffForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnTakeOffForUnit ) @@ -334,7 +334,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnTakeOffForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_TAKEOFF ) @@ -348,7 +348,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnEngineShutDownForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnEngineShutDownForUnit ) @@ -362,7 +362,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnEngineShutDownForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_ENGINE_SHUTDOWN ) @@ -376,7 +376,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnEngineStartUpForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_ENGINE_STARTUP ) @@ -389,7 +389,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnShot( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_SHOT ) @@ -403,7 +403,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnShotForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_SHOT ) @@ -416,7 +416,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnHit( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_HIT ) @@ -430,7 +430,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnHitForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_HIT ) @@ -443,7 +443,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnPlayerEnterUnit( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_PLAYER_ENTER_UNIT ) @@ -456,7 +456,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnPlayerLeaveUnit( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_PLAYER_LEAVE_UNIT ) @@ -466,7 +466,7 @@ end function EVENT:onEvent( Event ) - self:F( { _EVENTCODES[Event.id], Event } ) + self:F2( { _EVENTCODES[Event.id], Event } ) if self and self.Events and self.Events[Event.id] then if Event.initiator and Event.initiator:getCategory() == Object.Category.UNIT then diff --git a/Moose Development/Moose/Group.lua b/Moose Development/Moose/Group.lua index 89cf288b8..27e972843 100644 --- a/Moose Development/Moose/Group.lua +++ b/Moose Development/Moose/Group.lua @@ -198,6 +198,23 @@ function GROUP:GetCoalition() return nil end +--- Returns the country of the DCS Group. +-- @param #GROUP self +-- @return DCScountry#country.id The country identifier. +-- @return #nil The DCS Group is not existing or alive. +function GROUP:GetCountry() + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local GroupCountry = DCSGroup:getUnit(1):getCountry() + self:T3( GroupCountry ) + return GroupCountry + end + + return nil +end + --- Returns the name of the DCS Group. -- @param #GROUP self -- @return #string The DCS Group name. diff --git a/Moose Development/Moose/GroupSet.lua b/Moose Development/Moose/GroupSet.lua new file mode 100644 index 000000000..fb3f45fc5 --- /dev/null +++ b/Moose Development/Moose/GroupSet.lua @@ -0,0 +1,327 @@ +--- Create and manage a set of groups. +-- +-- @{#GROUPSET} class +-- ================== +-- Mission designers can use the GROUPSET class to build sets of groups belonging to certain: +-- +-- * Coalitions +-- * Categories +-- * Countries +-- * Starting with certain prefix strings. +-- +-- GROUPSET construction methods: +-- ================================= +-- Create a new GROUPSET object with the @{#GROUPSET.New} method: +-- +-- * @{#GROUPSET.New}: Creates a new GROUPSET object. +-- +-- +-- GROUPSET filter criteria: +-- ========================= +-- You can set filter criteria to define the set of groups within the GROUPSET. +-- Filter criteria are defined by: +-- +-- * @{#GROUPSET.FilterCoalitions}: Builds the GROUPSET with the groups belonging to the coalition(s). +-- * @{#GROUPSET.FilterCategories}: Builds the GROUPSET with the groups belonging to the category(ies). +-- * @{#GROUPSET.FilterTypes}: Builds the GROUPSET with the groups belonging to the unit type(s). +-- * @{#GROUPSET.FilterPrefixes}: Builds the GROUPSET with the groups starting with the same prefix string(s). +-- +-- Once the filter criteria have been set for the GROUPSET, you can start filtering using: +-- +-- * @{#GROUPSET.FilterStart}: Starts the filtering of the groups within the GROUPSET. +-- +-- Planned filter criteria within development are (so these are not yet available): +-- +-- * @{#GROUPSET.FilterZones}: Builds the GROUPSET with the groups within a @{Zone#ZONE}. +-- +-- +-- GROUPSET iterators: +-- =================== +-- Once the filters have been defined and the GROUPSET has been built, you can iterate the GROUPSET with the available iterator methods. +-- The iterator methods will walk the GROUPSET set, and call for each element within the set a function that you provide. +-- The following iterator methods are currently available within the GROUPSET: +-- +-- * @{#GROUPSET.ForEachGroup}: Calls a function for each alive unit it finds within the GROUPSET. +-- +-- Planned iterators methods in development are (so these are not yet available): +-- +-- * @{#GROUPSET.ForEachUnitInGroup}: Calls a function for each group contained within the GROUPSET. +-- * @{#GROUPSET.ForEachUnitInZone}: Calls a function for each unit within a certain zone contained within the GROUPSET. +-- +-- @module GroupSet +-- @author FlightControl + +Include.File( "Routines" ) +Include.File( "Base" ) +Include.File( "Group" ) +Include.File( "Set" ) + + +--- GROUPSET class +-- @type GROUPSET +-- @extends Set#SET +GROUPSET = { + ClassName = "GROUPSET", + Units = {}, + Filter = { + Coalitions = nil, + Categories = nil, + Countries = nil, + GroupPrefixes = nil, + }, + FilterMeta = { + Coalitions = { + red = coalition.side.RED, + blue = coalition.side.BLUE, + neutral = coalition.side.NEUTRAL, + }, + Categories = { + plane = Group.Category.AIRPLANE, + helicopter = Group.Category.HELICOPTER, + ground = Group.Category.GROUND_UNIT, + ship = Group.Category.SHIP, + structure = Group.Category.STRUCTURE, + }, + }, +} + + +--- Creates a new GROUPSET object, building a set of groups belonging to a coalitions, categories, countries, types or with defined prefix names. +-- @param #GROUPSET self +-- @return #GROUPSET +-- @usage +-- -- Define a new GROUPSET Object. This DBObject will contain a reference to all alive GROUPS. +-- DBObject = GROUPSET:New() +function GROUPSET:New() + + -- Inherits from BASE + local self = BASE:Inherit( self, SET:New( _DATABASE.GROUPS ) ) + + return self +end + + +--- Finds a Unit based on the Unit Name. +-- @param #GROUPSET self +-- @param #string GroupName +-- @return Group#GROUP The found Unit. +function GROUPSET:FindUnit( GroupName ) + + local GroupFound = self.Set[GroupName] + return GroupFound +end + + + +--- Builds a set of groups of coalitions. +-- Possible current coalitions are red, blue and neutral. +-- @param #GROUPSET self +-- @param #string Coalitions Can take the following values: "red", "blue", "neutral". +-- @return #GROUPSET self +function GROUPSET: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 groups out of categories. +-- Possible current categories are plane, helicopter, ground, ship. +-- @param #GROUPSET self +-- @param #string Categories Can take the following values: "plane", "helicopter", "ground", "ship". +-- @return #GROUPSET self +function GROUPSET: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 groups of defined countries. +-- Possible current countries are those known within DCS world. +-- @param #GROUPSET self +-- @param #string Countries Can take those country strings known within DCS world. +-- @return #GROUPSET self +function GROUPSET: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 groups of defined unit prefixes. +-- All the groups starting with the given prefixes will be included within the set. +-- @param #GROUPSET self +-- @param #string Prefixes The prefix of which the group name starts with. +-- @return #GROUPSET self +function GROUPSET:FilterPrefixes( Prefixes ) + if not self.Filter.GroupPrefixes then + self.Filter.GroupPrefixes = {} + end + if type( Prefixes ) ~= "table" then + Prefixes = { Prefixes } + end + for PrefixID, Prefix in pairs( Prefixes ) do + self.Filter.GroupPrefixes[Prefix] = Prefix + end + return self +end + + +--- Starts the filtering. +-- @param #GROUPSET self +-- @return #GROUPSET self +function GROUPSET: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 #GROUPSET self +-- @param Event#EVENTDATA Event +-- @return #string The name of the GROUP +-- @return #table The GROUP +function GROUPSET:AddInDatabase( Event ) + self:F3( { Event } ) + + if not self.Database[Event.IniDCSGroupName] then + self.Database[Event.IniDCSGroupName] = GROUP:Register( Event.IniDCSGroupName ) + self:T3( self.Database[Event.IniDCSGroupName] ) + end + + return Event.IniDCSGroupName, self.Database[Event.IniDCSGroupName] +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 #GROUPSET self +-- @param Event#EVENTDATA Event +-- @return #string The name of the GROUP +-- @return #table The GROUP +function GROUPSET:FindInDatabase( Event ) + self:F3( { Event } ) + + return Event.IniDCSGroupName, self.Database[Event.IniDCSGroupName] +end + +--- Interate the GROUPSET and call an interator function for each **alive** GROUP, providing the GROUP and optional parameters. +-- @param #GROUPSET self +-- @param #function IteratorFunction The function that will be called when there is an alive GROUP in the GROUPSET. The function needs to accept a GROUP parameter. +-- @return #GROUPSET self +function GROUPSET:ForEachUnit( IteratorFunction, ... ) + self:F2( arg ) + + self:ForEach( IteratorFunction, arg, self.Set ) + + return self +end + + +----- Interate the GROUPSET and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. +---- @param #GROUPSET self +---- @param #function IteratorFunction The function that will be called when there is an alive player in the GROUPSET. The function needs to accept a GROUP parameter. +---- @return #GROUPSET self +--function GROUPSET:ForEachPlayer( IteratorFunction, ... ) +-- self:F2( arg ) +-- +-- self:ForEach( IteratorFunction, arg, self.PlayersAlive ) +-- +-- return self +--end +-- +-- +----- Interate the GROUPSET and call an interator function for each client, providing the Client to the function and optional parameters. +---- @param #GROUPSET self +---- @param #function IteratorFunction The function that will be called when there is an alive player in the GROUPSET. The function needs to accept a CLIENT parameter. +---- @return #GROUPSET self +--function GROUPSET:ForEachClient( IteratorFunction, ... ) +-- self:F2( arg ) +-- +-- self:ForEach( IteratorFunction, arg, self.Clients ) +-- +-- return self +--end + + +--- +-- @param #GROUPSET self +-- @param Group#GROUP MooseGroup +-- @return #GROUPSET self +function GROUPSET:IsIncludeObject( MooseGroup ) + self:F2( MooseGroup ) + local MooseGroupInclude = true + + if self.Filter.Coalitions then + local MooseGroupCoalition = 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 + end + end + MooseGroupInclude = MooseGroupInclude and MooseGroupCoalition + end + + if self.Filter.Categories then + local MooseGroupCategory = 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 + end + end + MooseGroupInclude = MooseGroupInclude and MooseGroupCategory + end + + if self.Filter.Countries then + local MooseGroupCountry = 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 + end + end + MooseGroupInclude = MooseGroupInclude and MooseGroupCountry + end + + if self.Filter.GroupPrefixes then + local MooseGroupPrefix = 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, 1 ) then + MooseGroupPrefix = true + end + end + MooseGroupInclude = MooseGroupInclude and MooseGroupPrefix + end + + self:T2( MooseGroupInclude ) + return MooseGroupInclude +end + + diff --git a/Moose Development/Moose/Moose.lua b/Moose Development/Moose/Moose.lua index b9df585ce..123f51481 100644 --- a/Moose Development/Moose/Moose.lua +++ b/Moose Development/Moose/Moose.lua @@ -11,5 +11,5 @@ Include.File( "Event" ) _EVENTDISPATCHER = EVENT:New() -- #EVENT --- Declare the main database object, which is used internally by the MOOSE classes. -_DATABASE = DATABASE:New():ScanEnvironment() -- Database#DATABASE +_DATABASE = DATABASE:New() -- Database#DATABASE diff --git a/Moose Development/Moose/Set.lua b/Moose Development/Moose/Set.lua index 063ec2fe0..feff204a4 100644 --- a/Moose Development/Moose/Set.lua +++ b/Moose Development/Moose/Set.lua @@ -75,371 +75,109 @@ Include.File( "Client" ) -- @extends Base#BASE SET = { ClassName = "SET", - Templates = { - Units = {}, - Groups = {}, - ClientsByName = {}, - ClientsByID = {}, - }, - DCSUnits = {}, - DCSUnitsAlive = {}, - DCSGroups = {}, - DCSGroupsAlive = {}, - Units = {}, - UnitsAlive = {}, - Groups = {}, - GroupsAlive = {}, - NavPoints = {}, - Statics = {}, - Players = {}, - PlayersAlive = {}, - Clients = {}, - ClientsAlive = {}, - Filter = { - Coalitions = nil, - Categories = nil, - Types = nil, - Countries = nil, - UnitPrefixes = nil, - GroupPrefixes = 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, - }, - }, + Set = {}, + Database = {}, } -local _DATABASECoalition = - { - [1] = "Red", - [2] = "Blue", - } - -local _DATABASECategory = - { - [Unit.Category.AIRPLANE] = "Plane", - [Unit.Category.HELICOPTER] = "Helicopter", - [Unit.Category.GROUND_UNIT] = "Vehicle", - [Unit.Category.SHIP] = "Ship", - [Unit.Category.STRUCTURE] = "Structure", - } - - --- Creates a new SET object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names. -- @param #SET self -- @return #SET -- @usage -- -- Define a new SET Object. This DBObject will contain a reference to all Group and Unit Templates defined within the ME and the DCSRTE. -- DBObject = SET:New() -function SET:New() +function SET:New( Database ) -- Inherits from BASE local self = BASE:Inherit( self, BASE:New() ) + self.Database = Database + + return self +end + +--- Finds an Object based on the Object Name. +-- @param #SET self +-- @param #string ObjectName +-- @return #table The Object found. +function SET:_Find( ObjectName ) + + local ObjectFound = self.Set[ObjectName] + return ObjectFound +end + +--- Adds a Object based on the Object Name. +-- @param #SET self +-- @param #string ObjectName +-- @param #table Object +-- @return #table The added Object. +function SET:_Add( ObjectName, Object ) + + self.Set[ObjectName] = Object +end + +--- Starts the filtering for the defined collection. +-- @param #SET self +-- @return #SET self +function SET:_FilterStart() + + for ObjectName, Object in pairs( self.Database ) do + + if self:IsIncludeObject( Object ) then + self:E( { "Adding Object:", ObjectName } ) + self:_Add( ObjectName, Object ) + end + end + _EVENTDISPATCHER:OnBirth( self._EventOnBirth, self ) _EVENTDISPATCHER:OnDead( self._EventOnDeadOrCrash, self ) _EVENTDISPATCHER:OnCrash( self._EventOnDeadOrCrash, self ) - - -- Add SET with registered clients and already alive players - -- Follow alive players and clients - _EVENTDISPATCHER:OnPlayerEnterUnit( self._EventOnPlayerEnterUnit, self ) - _EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventOnPlayerLeaveUnit, self ) +-- _EVENTDISPATCHER:OnPlayerEnterUnit( self._EventOnPlayerEnterUnit, self ) +-- _EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventOnPlayerLeaveUnit, self ) return self end ---- Finds a Unit based on the Unit Name. --- @param #SET self --- @param #string UnitName --- @return Unit#UNIT The found Unit. -function SET:FindUnit( UnitName ) - - local UnitFound = self.Units[UnitName] - return UnitFound -end - ---- Finds a Unit based on the Unit Name. --- @param #SET self --- @param Unit#UNIT UnitToAdd --- @return Unit#UNIT The added Unit. -function SET:AddUnit( UnitToAdd ) - - self.Units[UnitToAdd.UnitName] = UnitToAdd - return self.Units[UnitToAdd.UnitName] -end - ---- Builds a set of units of coalitons. --- Possible current coalitions are red, blue and neutral. --- @param #SET self --- @param #string Coalitions Can take the following values: "red", "blue", "neutral". --- @return #SET self -function SET: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 #SET self --- @param #string Categories Can take the following values: "plane", "helicopter", "ground", "ship". --- @return #SET self -function SET: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 #SET self --- @param #string Types Can take those type strings known within DCS world. --- @return #SET self -function SET: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 #SET self --- @param #string Countries Can take those country strings known within DCS world. --- @return #SET self -function SET: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 #SET self --- @param #string Prefixes The prefix of which the unit name starts with. --- @return #SET self -function SET:FilterUnitPrefixes( 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 - ---- Builds a set of units of defined group prefixes. --- All the units starting with the given group prefixes will be included within the set. --- @param #SET self --- @param #string Prefixes The prefix of which the group name where the unit belongs to starts with. --- @return #SET self -function SET:FilterGroupPrefixes( Prefixes ) - if not self.Filter.GroupPrefixes then - self.Filter.GroupPrefixes = {} - end - if type( Prefixes ) ~= "table" then - Prefixes = { Prefixes } - end - for PrefixID, Prefix in pairs( Prefixes ) do - self.Filter.GroupPrefixes[Prefix] = Prefix - end - return self -end - ---- Starts the filtering. --- @param #SET self --- @return #SET self -function SET:FilterStart() - - if _DATABASE then - -- OK, we have a _DATABASE - -- Now use the different filters to build the set. - -- We first take ALL of the Units of the _DATABASE. - - self:E( { "Adding Set Datapoints with filters" } ) - for DCSUnitName, DCSUnit in pairs( _DATABASE.DCSUnits ) do - - if self:_IsIncludeDCSUnit( DCSUnit ) then - - self:E( { "Adding Unit:", DCSUnitName } ) - self.DCSUnits[DCSUnitName] = _DATABASE.DCSUnits[DCSUnitName] - self.Units[DCSUnitName] = _DATABASE:FindUnit( DCSUnitName ) - - if _DATABASE.DCSUnitsAlive[DCSUnitName] then - self.DCSUnitsAlive[DCSUnitName] = _DATABASE.DCSUnitsAlive[DCSUnitName] - self.UnitsAlive[DCSUnitName] = _DATABASE.UnitsAlive[DCSUnitName] - end - - end - end - - for DCSGroupName, DCSGroup in pairs( _DATABASE.DCSGroups ) do - - --if self:_IsIncludeDCSGroup( DCSGroup ) then - self:E( { "Adding Group:", DCSGroupName } ) - self.DCSGroups[DCSGroupName] = _DATABASE.DCSGroups[DCSGroupName] - self.Groups[DCSGroupName] = _DATABASE:FindGroups( DCSGroupName ) - --end - - if _DATABASE.DCSGroupsAlive[DCSGroupName] then - self.DCSGroupsAlive[DCSGroupName] = _DATABASE.DCSGroupsAlive[DCSGroupName] - self.GroupsAlive[DCSGroupName] = _DATABASE.GroupsAlive[DCSGroupName] - end - end - - for DCSUnitName, Client in pairs( _DATABASE.CLIENTS ) do - self:E( { "Adding Client for Unit:", DCSUnitName } ) - self.Clients[DCSUnitName] = _DATABASE.Clients[DCSUnitName] - end - - else - self:E( "There is a structural error in MOOSE. No _DATABASE has been defined! Cannot build this custom SET." ) - end - - return self -end - - - ---- Private method that registers all alive players in the mission. --- @param #SET self --- @return #SET self -function SET:_RegisterPlayers() - - local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) } - for CoalitionId, CoalitionData in pairs( CoalitionsData ) do - for UnitId, UnitData in pairs( CoalitionData ) do - self:T3( { "UnitData:", UnitData } ) - if UnitData and UnitData:isExist() then - local UnitName = UnitData:getName() - if not self.PlayersAlive[UnitName] then - self:E( { "Add player for unit:", UnitName, UnitData:getPlayerName() } ) - self.PlayersAlive[UnitName] = UnitData:getPlayerName() - end - end - end - end - - return self -end - ---- Private method that registers all datapoints within in the mission. --- @param #SET self --- @return #SET self -function SET:_RegisterDatabase() - - local CoalitionsData = { AlivePlayersRed = coalition.getGroups( coalition.side.RED ), AlivePlayersBlue = coalition.getGroups( coalition.side.BLUE ) } - for CoalitionId, CoalitionData in pairs( CoalitionsData ) do - for DCSGroupId, DCSGroup in pairs( CoalitionData ) do - - if DCSGroup:isExist() then - local DCSGroupName = DCSGroup:getName() - - self:E( { "Register Group:", DCSGroup, DCSGroupName } ) - self.DCSGroups[DCSGroupName] = DCSGroup - self.Groups[DCSGroupName] = GROUP:New( DCSGroup ) - - if self:_IsAliveDCSGroup(DCSGroup) then - self:E( { "Register Alive Group:", DCSGroup, DCSGroupName } ) - self.DCSGroupsAlive[DCSGroupName] = DCSGroup - self.GroupsAlive[DCSGroupName] = self.Groups[DCSGroupName] - end - - for DCSUnitId, DCSUnit in pairs( DCSGroup:getUnits() ) do - - local DCSUnitName = DCSUnit:getName() - self:E( { "Register Unit:", DCSUnit, DCSUnitName } ) - - self.DCSUnits[DCSUnitName] = DCSUnit - self:AddUnit( UNIT:Find( DCSUnit ) ) - --self.Units[DCSUnitName] = UNIT:Register( DCSUnit ) - - if self:_IsAliveDCSUnit(DCSUnit) then - self:E( { "Register Alive Unit:", DCSUnit, DCSUnitName } ) - self.DCSUnitsAlive[DCSUnitName] = DCSUnit - self.UnitsAlive[DCSUnitName] = self.Units[DCSUnitName] - end - end - else - self:E( "Group does not exist: " .. DCSGroup ) - end - - for ClientName, ClientTemplate in pairs( self.Templates.ClientsByName ) do - self.Clients[ClientName] = CLIENT:Find( ClientName ) - end - end - end - - return self -end - +----- Private method that registers all alive players in the mission. +---- @param #SET self +---- @return #SET self +--function SET:_RegisterPlayers() +-- +-- local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) } +-- for CoalitionId, CoalitionData in pairs( CoalitionsData ) do +-- for UnitId, UnitData in pairs( CoalitionData ) do +-- self:T3( { "UnitData:", UnitData } ) +-- if UnitData and UnitData:isExist() then +-- local UnitName = UnitData:getName() +-- if not self.PlayersAlive[UnitName] then +-- self:E( { "Add player for unit:", UnitName, UnitData:getPlayerName() } ) +-- self.PlayersAlive[UnitName] = UnitData:getPlayerName() +-- end +-- end +-- end +-- end +-- +-- return self +--end --- Events ---- Handles the OnBirth event for the alive units set. +--- Handles the OnBirth event for the Set. -- @param #SET self -- @param Event#EVENTDATA Event function SET:_EventOnBirth( Event ) - self:F( { Event } ) + self:F3( { Event } ) if Event.IniDCSUnit then - if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then - self.DCSUnits[Event.IniDCSUnitName] = Event.IniDCSUnit - self.DCSUnitsAlive[Event.IniDCSUnitName] = Event.IniDCSUnit - self:AddUnit( UNIT:Register( Event.IniDCSUnit ) ) - --self.Units[Event.IniDCSUnitName] = UNIT:Register( Event.IniDCSUnit ) - - --if not self.DCSGroups[Event.IniDCSGroupName] then - -- self.DCSGroups[Event.IniDCSGroupName] = Event.IniDCSGroupName - -- self.DCSGroupsAlive[Event.IniDCSGroupName] = Event.IniDCSGroupName - -- self.Groups[Event.IniDCSGroupName] = GROUP:New( Event.IniDCSGroup ) - --end - self:_EventOnPlayerEnterUnit( Event ) + local ObjectName, Object = self:AddInDatabase( Event ) + self:T3( ObjectName, Object ) + if self:IsIncludeObject( Object ) then + self:_Add( ObjectName, Object ) + --self:_EventOnPlayerEnterUnit( Event ) end end end @@ -448,49 +186,49 @@ end -- @param #SET self -- @param Event#EVENTDATA Event function SET:_EventOnDeadOrCrash( Event ) - self:F( { Event } ) + self:F3( { Event } ) if Event.IniDCSUnit then - if self.DCSUnitsAlive[Event.IniDCSUnitName] then - self.DCSUnits[Event.IniDCSUnitName] = nil - self.DCSUnitsAlive[Event.IniDCSUnitName] = nil + local ObjectName, Object = self:FindInDatabase( Event ) + if ObjectName and Object then + self:_Delete( ObjectName ) end end end ---- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied). --- @param #SET self --- @param Event#EVENTDATA Event -function SET:_EventOnPlayerEnterUnit( Event ) - self:F( { Event } ) - - if Event.IniDCSUnit then - if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then - if not self.PlayersAlive[Event.IniDCSUnitName] then - self:E( { "Add player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) - self.PlayersAlive[Event.IniDCSUnitName] = Event.IniDCSUnit:getPlayerName() - self.ClientsAlive[Event.IniDCSUnitName] = _DATABASE.Clients[ Event.IniDCSUnitName ] - end - end - end -end - ---- Handles the OnPlayerLeaveUnit event to clean the active players table. --- @param #SET self --- @param Event#EVENTDATA Event -function SET:_EventOnPlayerLeaveUnit( Event ) - self:F( { Event } ) - - if Event.IniDCSUnit then - if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then - if self.PlayersAlive[Event.IniDCSUnitName] then - self:E( { "Cleaning player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) - self.PlayersAlive[Event.IniDCSUnitName] = nil - self.ClientsAlive[Event.IniDCSUnitName] = nil - end - end - end -end +----- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied). +---- @param #SET self +---- @param Event#EVENTDATA Event +--function SET:_EventOnPlayerEnterUnit( Event ) +-- self:F3( { Event } ) +-- +-- if Event.IniDCSUnit then +-- if self:IsIncludeObject( Event.IniDCSUnit ) then +-- if not self.PlayersAlive[Event.IniDCSUnitName] then +-- self:E( { "Add player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) +-- self.PlayersAlive[Event.IniDCSUnitName] = Event.IniDCSUnit:getPlayerName() +-- self.ClientsAlive[Event.IniDCSUnitName] = _DATABASE.Clients[ Event.IniDCSUnitName ] +-- end +-- end +-- end +--end +-- +----- Handles the OnPlayerLeaveUnit event to clean the active players table. +---- @param #SET self +---- @param Event#EVENTDATA Event +--function SET:_EventOnPlayerLeaveUnit( Event ) +-- self:F3( { Event } ) +-- +-- if Event.IniDCSUnit then +-- if self:IsIncludeObject( Event.IniDCSUnit ) then +-- if self.PlayersAlive[Event.IniDCSUnitName] then +-- self:E( { "Cleaning player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) +-- self.PlayersAlive[Event.IniDCSUnitName] = nil +-- self.ClientsAlive[Event.IniDCSUnitName] = nil +-- end +-- end +-- end +--end --- Iterators @@ -499,7 +237,7 @@ end -- @param #function IteratorFunction The function that will be called when there is an alive player in the SET. -- @return #SET self function SET:ForEach( IteratorFunction, arg, Set ) - self:F( arg ) + self:F3( arg ) local function CoRoutine() local Count = 0 @@ -519,7 +257,7 @@ function SET:ForEach( IteratorFunction, arg, Set ) local function Schedule() local status, res = coroutine.resume( co ) - self:T( { status, res } ) + self:T3( { status, res } ) if status == false then error( res ) @@ -537,222 +275,67 @@ function SET:ForEach( IteratorFunction, arg, Set ) end ---- Interate the SET and call an interator function for each **alive** unit, providing the Unit and optional parameters. +----- Interate the SET and call an interator function for each **alive** unit, providing the Unit and optional parameters. +---- @param #SET self +---- @param #function IteratorFunction The function that will be called when there is an alive unit in the SET. The function needs to accept a UNIT parameter. +---- @return #SET self +--function SET:ForEachDCSUnitAlive( IteratorFunction, ... ) +-- self:F3( arg ) +-- +-- self:ForEach( IteratorFunction, arg, self.DCSUnitsAlive ) +-- +-- return self +--end +-- +----- Interate the SET and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. +---- @param #SET self +---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET. The function needs to accept a UNIT parameter. +---- @return #SET self +--function SET:ForEachPlayer( IteratorFunction, ... ) +-- self:F3( arg ) +-- +-- self:ForEach( IteratorFunction, arg, self.PlayersAlive ) +-- +-- return self +--end +-- +-- +----- Interate the SET and call an interator function for each client, providing the Client to the function and optional parameters. +---- @param #SET self +---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET. The function needs to accept a CLIENT parameter. +---- @return #SET self +--function SET:ForEachClient( IteratorFunction, ... ) +-- self:F3( arg ) +-- +-- self:ForEach( IteratorFunction, arg, self.Clients ) +-- +-- return self +--end + + +--- Decides whether to include the Object -- @param #SET self --- @param #function IteratorFunction The function that will be called when there is an alive unit in the SET. The function needs to accept a UNIT parameter. +-- @param #table Object -- @return #SET self -function SET:ForEachDCSUnitAlive( IteratorFunction, ... ) - self:F( arg ) +function SET:IsIncludeObject( Object ) + self:F3( Object ) - self:ForEach( IteratorFunction, arg, self.DCSUnitsAlive ) - - return self + return true end ---- Interate the SET and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. +--- Flushes the current SET contents in the log ... (for debug reasons). -- @param #SET self --- @param #function IteratorFunction The function that will be called when there is an alive player in the SET. The function needs to accept a UNIT parameter. --- @return #SET self -function SET:ForEachPlayer( IteratorFunction, ... ) - self:F( arg ) +-- @return #string A string with the names of the objects. +function SET:Flush() + self:F3() + + local ObjectNames = "" + for ObjectName, Object in pairs( self.Set ) do + ObjectNames = ObjectNames .. ObjectName .. ", " + end + self:T( { "Objects in Set:", ObjectNames } ) - self:ForEach( IteratorFunction, arg, self.PlayersAlive ) - - return self -end - - ---- Interate the SET and call an interator function for each client, providing the Client to the function and optional parameters. --- @param #SET self --- @param #function IteratorFunction The function that will be called when there is an alive player in the SET. The function needs to accept a CLIENT parameter. --- @return #SET self -function SET:ForEachClient( IteratorFunction, ... ) - self:F( arg ) - - self:ForEach( IteratorFunction, arg, self.Clients ) - - return self -end - - -function SET:ScanEnvironment() - self:F() - - self.Navpoints = {} - self.Units = {} - --Build routines.db.units and self.Navpoints - for coa_name, coa_data in pairs(env.mission.coalition) do - - if (coa_name == 'red' or coa_name == 'blue') and type(coa_data) == 'table' then - --self.Units[coa_name] = {} - - ---------------------------------------------- - -- build nav points DB - self.Navpoints[coa_name] = {} - if coa_data.nav_points then --navpoints - for nav_ind, nav_data in pairs(coa_data.nav_points) do - - if type(nav_data) == 'table' then - self.Navpoints[coa_name][nav_ind] = routines.utils.deepCopy(nav_data) - - self.Navpoints[coa_name][nav_ind]['name'] = nav_data.callsignStr -- name is a little bit more self-explanatory. - self.Navpoints[coa_name][nav_ind]['point'] = {} -- point is used by SSE, support it. - self.Navpoints[coa_name][nav_ind]['point']['x'] = nav_data.x - self.Navpoints[coa_name][nav_ind]['point']['y'] = 0 - self.Navpoints[coa_name][nav_ind]['point']['z'] = nav_data.y - end - end - end - ------------------------------------------------- - if coa_data.country then --there is a country table - for cntry_id, cntry_data in pairs(coa_data.country) do - - local countryName = string.lower(cntry_data.name) - --self.Units[coa_name][countryName] = {} - --self.Units[coa_name][countryName]["countryId"] = cntry_data.id - - if type(cntry_data) == 'table' then --just making sure - - for obj_type_name, obj_type_data in pairs(cntry_data) do - - if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then --should be an unncessary check - - local category = obj_type_name - - if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then --there's a group! - - --self.Units[coa_name][countryName][category] = {} - - for group_num, GroupTemplate in pairs(obj_type_data.group) do - - if GroupTemplate and GroupTemplate.units and type(GroupTemplate.units) == 'table' then --making sure again- this is a valid group - self:_RegisterGroup( GroupTemplate ) - end --if GroupTemplate and GroupTemplate.units then - end --for group_num, GroupTemplate in pairs(obj_type_data.group) do - end --if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then - end --if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then - end --for obj_type_name, obj_type_data in pairs(cntry_data) do - end --if type(cntry_data) == 'table' then - end --for cntry_id, cntry_data in pairs(coa_data.country) do - end --if coa_data.country then --there is a country table - end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then - end --for coa_name, coa_data in pairs(mission.coalition) do - - self:_RegisterDatabase() - self:_RegisterPlayers() - - return self -end - - ---- --- @param #SET self --- @param DCSUnit#Unit DCSUnit --- @return #SET self -function SET:_IsIncludeDCSUnit( DCSUnit ) - self:F( DCSUnit ) - local DCSUnitInclude = true - - if self.Filter.Coalitions then - local DCSUnitCoalition = false - for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do - self:T( { "Coalition:", DCSUnit:getCoalition(), self.FilterMeta.Coalitions[CoalitionName], CoalitionName } ) - if self.FilterMeta.Coalitions[CoalitionName] and self.FilterMeta.Coalitions[CoalitionName] == DCSUnit:getCoalition() then - DCSUnitCoalition = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitCoalition - end - - if self.Filter.Categories then - local DCSUnitCategory = false - for CategoryID, CategoryName in pairs( self.Filter.Categories ) do - self:T( { "Category:", DCSUnit:getDesc().category, self.FilterMeta.Categories[CategoryName], CategoryName } ) - if self.FilterMeta.Categories[CategoryName] and self.FilterMeta.Categories[CategoryName] == DCSUnit:getDesc().category then - DCSUnitCategory = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitCategory - end - - if self.Filter.Types then - local DCSUnitType = false - for TypeID, TypeName in pairs( self.Filter.Types ) do - self:T( { "Type:", DCSUnit:getTypeName(), TypeName } ) - if TypeName == DCSUnit:getTypeName() then - DCSUnitType = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitType - end - - if self.Filter.Countries then - local DCSUnitCountry = false - for CountryID, CountryName in pairs( self.Filter.Countries ) do - self:T( { "Country:", DCSUnit:getCountry(), CountryName } ) - if country.id[CountryName] == DCSUnit:getCountry() then - DCSUnitCountry = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitCountry - end - - if self.Filter.UnitPrefixes then - local DCSUnitPrefix = false - for UnitPrefixId, UnitPrefix in pairs( self.Filter.UnitPrefixes ) do - self:T( { "Unit Prefix:", string.find( DCSUnit:getName(), UnitPrefix, 1 ), UnitPrefix } ) - if string.find( DCSUnit:getName(), UnitPrefix, 1 ) then - DCSUnitPrefix = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitPrefix - end - - self:T( DCSUnitInclude ) - return DCSUnitInclude -end - ---- --- @param #SET self --- @param DCSUnit#Unit DCSUnit --- @return #SET self -function SET:_IsAliveDCSUnit( DCSUnit ) - self:F( DCSUnit ) - local DCSUnitAlive = false - if DCSUnit and DCSUnit:isExist() and DCSUnit:isActive() then - if self.DCSUnits[DCSUnit:getName()] then - DCSUnitAlive = true - end - end - self:T( DCSUnitAlive ) - return DCSUnitAlive -end - ---- --- @param #SET self --- @param DCSGroup#Group DCSGroup --- @return #SET self -function SET:_IsAliveDCSGroup( DCSGroup ) - self:F( DCSGroup ) - local DCSGroupAlive = false - if DCSGroup and DCSGroup:isExist() then - if self.DCSGroups[DCSGroup:getName()] then - DCSGroupAlive = true - end - end - self:T( DCSGroupAlive ) - return DCSGroupAlive -end - - ---- Traces the current SET contents in the log ... (for debug reasons). --- @param #SET self --- @return #SET self -function SET:TraceDatabase() - self:F() - - self:T( { "DCSUnits:", self.DCSUnits } ) - self:T( { "DCSUnitsAlive:", self.DCSUnitsAlive } ) + return ObjectNames end diff --git a/Moose Development/Moose/UnitSet.lua b/Moose Development/Moose/UnitSet.lua new file mode 100644 index 000000000..5bd542727 --- /dev/null +++ b/Moose Development/Moose/UnitSet.lua @@ -0,0 +1,363 @@ +--- 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 + + diff --git a/Moose Mission Setup/Moose Mission Update/l10n/DEFAULT/Moose.lua b/Moose Mission Setup/Moose Mission Update/l10n/DEFAULT/Moose.lua index 8f1d04ce8..6339b2e01 100644 --- a/Moose Mission Setup/Moose Mission Update/l10n/DEFAULT/Moose.lua +++ b/Moose Mission Setup/Moose Mission Update/l10n/DEFAULT/Moose.lua @@ -1,5 +1,5 @@ env.info( '*** MOOSE STATIC INCLUDE START *** ' ) -env.info( 'Moose Generation Timestamp: 20160526_1413' ) +env.info( 'Moose Generation Timestamp: 20160527_1334' ) local base = _G env.info("Loading MOOSE " .. base.timer.getAbsTime() ) @@ -3037,7 +3037,10 @@ function BASE:E( Arguments ) end local LineCurrent = DebugInfoCurrent.currentline - local LineFrom = DebugInfoFrom.currentline + local LineFrom = -1 + if DebugInfoFrom then + LineFrom = DebugInfoFrom.currentline + end env.info( string.format( "%6d(%6d)/%1s:%20s%05d.%s(%s)" , LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) end @@ -3252,7 +3255,7 @@ local _EVENTCODES = { function EVENT:New() local self = BASE:Inherit( self, BASE:New() ) - self:F() + self:F2() self.EventHandler = world.addEventHandler( self ) return self end @@ -3342,7 +3345,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnBirthForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnBirthForUnit ) @@ -3355,7 +3358,7 @@ end -- @param Base#BASE EventSelf -- @return #EVENT function EVENT:OnBirth( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_BIRTH ) @@ -3369,7 +3372,7 @@ end -- @param Base#BASE EventSelf -- @return #EVENT function EVENT:OnBirthForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_BIRTH ) @@ -3383,7 +3386,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnCrashForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnCrashForUnit ) @@ -3396,7 +3399,7 @@ end -- @param Base#BASE EventSelf -- @return #EVENT function EVENT:OnCrash( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_CRASH ) @@ -3410,7 +3413,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnCrashForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_CRASH ) @@ -3424,7 +3427,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnDeadForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnDeadForUnit ) @@ -3437,7 +3440,7 @@ end -- @param Base#BASE EventSelf -- @return #EVENT function EVENT:OnDead( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_DEAD ) @@ -3452,7 +3455,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnDeadForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_DEAD ) @@ -3466,7 +3469,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnPilotDeadForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_PILOT_DEAD ) @@ -3480,7 +3483,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnLandForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnLandForUnit ) @@ -3494,7 +3497,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnLandForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_LAND ) @@ -3508,7 +3511,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnTakeOffForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnTakeOffForUnit ) @@ -3522,7 +3525,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnTakeOffForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_TAKEOFF ) @@ -3536,7 +3539,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnEngineShutDownForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnEngineShutDownForUnit ) @@ -3550,7 +3553,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnEngineShutDownForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_ENGINE_SHUTDOWN ) @@ -3564,7 +3567,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnEngineStartUpForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_ENGINE_STARTUP ) @@ -3577,7 +3580,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnShot( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_SHOT ) @@ -3591,7 +3594,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnShotForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_SHOT ) @@ -3604,7 +3607,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnHit( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_HIT ) @@ -3618,7 +3621,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnHitForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_HIT ) @@ -3631,7 +3634,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnPlayerEnterUnit( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_PLAYER_ENTER_UNIT ) @@ -3644,7 +3647,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnPlayerLeaveUnit( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_PLAYER_LEAVE_UNIT ) @@ -3654,7 +3657,7 @@ end function EVENT:onEvent( Event ) - self:F( { _EVENTCODES[Event.id], Event } ) + self:F2( { _EVENTCODES[Event.id], Event } ) if self and self.Events and self.Events[Event.id] then if Event.initiator and Event.initiator:getCategory() == Object.Category.UNIT then @@ -4268,6 +4271,23 @@ function GROUP:GetCoalition() return nil end +--- Returns the country of the DCS Group. +-- @param #GROUP self +-- @return DCScountry#country.id The country identifier. +-- @return #nil The DCS Group is not existing or alive. +function GROUP:GetCountry() + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local GroupCountry = DCSGroup:getUnit(1):getCountry() + self:T3( GroupCountry ) + return GroupCountry + end + + return nil +end + --- Returns the name of the DCS Group. -- @param #GROUP self -- @return #string The DCS Group name. @@ -7277,67 +7297,37 @@ function CLIENT:Message( Message, MessageDuration, MessageId, MessageCategory, M end end end ---- Manage sets of units and groups. +--- Manage the mission database. -- --- @{#Database} class +-- @{#DATABASE} class -- ================== --- Mission designers can use the DATABASE class to build sets of units belonging to certain: +-- Mission designers can use the DATABASE class to refer to: -- --- * Coalitions --- * Categories --- * Countries --- * Unit types --- * Starting with certain prefix strings. +-- * UNITS +-- * GROUPS +-- * players +-- * alive players +-- * CLIENTS +-- * alive CLIENTS -- --- This list will grow over time. Planned developments are to include filters and iterators. --- Additional filters will be added around @{Zone#ZONEs}, Radiuses, Active players, ... --- More iterators will be implemented in the near future ... --- --- Administers the Initial Sets of the Mission Templates as defined within the Mission Editor. --- --- DATABASE construction methods: --- ================================= --- Create a new DATABASE object with the @{#DATABASE.New} method: --- --- * @{#DATABASE.New}: Creates a new DATABASE object. --- --- --- DATABASE filter criteria: --- ========================= --- You can set filter criteria to define the set of units within the database. --- Filter criteria are defined by: --- --- * @{#DATABASE.FilterCoalitions}: Builds the DATABASE with the units belonging to the coalition(s). --- * @{#DATABASE.FilterCategories}: Builds the DATABASE with the units belonging to the category(ies). --- * @{#DATABASE.FilterTypes}: Builds the DATABASE with the units belonging to the unit type(s). --- * @{#DATABASE.FilterCountries}: Builds the DATABASE with the units belonging to the country(ies). --- * @{#DATABASE.FilterUnitPrefixes}: Builds the DATABASE with the units starting with the same prefix string(s). --- --- Once the filter criteria have been set for the DATABASE, you can start filtering using: --- --- * @{#DATABASE.FilterStart}: Starts the filtering of the units within the database. --- --- Planned filter criteria within development are (so these are not yet available): --- --- * @{#DATABASE.FilterGroupPrefixes}: Builds the DATABASE with the groups of the units starting with the same prefix string(s). --- * @{#DATABASE.FilterZones}: Builds the DATABASE with the units within a @{Zone#ZONE}. +-- On top, for internal MOOSE administration purposes, the DATBASE administers the Unit and Gruop templates as defined within the Mission Editor. -- +-- Moose will automatically create one instance of the DATABASE class into the **global** object _DATABASE. +-- Moose refers to _DATABASE within the framework extensively, but you can also refer to the _DATABASE object within your missions if required. -- -- DATABASE iterators: -- =================== --- Once the filters have been defined and the DATABASE has been built, you can iterate the database with the available iterator methods. +-- You can iterate the database with the available iterator methods. -- The iterator methods will walk the DATABASE set, and call for each element within the set a function that you provide. -- The following iterator methods are currently available within the DATABASE: -- --- * @{#DATABASE.ForEachAliveUnit}: Calls a function for each alive unit it finds within the DATABASE. +-- * @{#DATABASE.ForEachUnit}: Calls a function for each @{UNIT} it finds within the DATABASE. +-- * @{#DATABASE.ForEachGroup}: Calls a function for each @{GROUP} it finds within the DATABASE. +-- * @{#DATABASE.ForEachPlayer}: Calls a function for each player it finds within the DATABASE. +-- * @{#DATABASE.ForEachPlayerAlive}: Calls a function for each alive player it finds within the DATABASE. +-- * @{#DATABASE.ForEachClient}: Calls a function for each @{CLIENT} it finds within the DATABASE. +-- * @{#DATABASE.ForEachClientAlive}: Calls a function for each alive @{CLIENT} it finds within the DATABASE. -- --- Planned iterators methods in development are (so these are not yet available): --- --- * @{#DATABASE.ForEachUnit}: Calls a function for each unit contained within the DATABASE. --- * @{#DATABASE.ForEachGroup}: Calls a function for each group contained within the DATABASE. --- * @{#DATABASE.ForEachUnitInZone}: Calls a function for each unit within a certain zone contained within the DATABASE. --- --- ==== -- @module Database -- @author FlightControl @@ -7349,6 +7339,7 @@ Include.File( "Unit" ) Include.File( "Event" ) Include.File( "Client" ) + --- DATABASE class -- @type DATABASE -- @extends Base#BASE @@ -7364,34 +7355,11 @@ DATABASE = { DCSGroups = {}, UNITS = {}, GROUPS = {}, - NavPoints = {}, - Statics = {}, - Players = {}, - PlayersAlive = {}, + PLAYERS = {}, + PLAYERSALIVE = {}, CLIENTS = {}, - ClientsAlive = {}, - Filter = { - Coalitions = nil, - Categories = nil, - Types = nil, - Countries = nil, - UnitPrefixes = nil, - GroupPrefixes = 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, - }, - }, + CLIENTSALIVE = {}, + NavPoints = {}, } local _DATABASECoalition = @@ -7426,12 +7394,13 @@ function DATABASE:New() _EVENTDISPATCHER:OnCrash( self._EventOnDeadOrCrash, self ) - -- Add database with registered clients and already alive players - -- Follow alive players and clients _EVENTDISPATCHER:OnPlayerEnterUnit( self._EventOnPlayerEnterUnit, self ) _EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventOnPlayerLeaveUnit, self ) + self:_RegisterTemplates() + self:_RegisterDatabase() + self:_RegisterPlayers() return self end @@ -7446,6 +7415,7 @@ function DATABASE:FindUnit( UnitName ) return UnitFound end + --- Adds a Unit based on the Unit Name in the DATABASE. -- @param #DATABASE self function DATABASE:AddUnit( DCSUnit, DCSUnitName ) @@ -7454,6 +7424,7 @@ function DATABASE:AddUnit( DCSUnit, DCSUnitName ) self.UNITS[DCSUnitName] = UNIT:Register( DCSUnitName ) end + --- Deletes a Unit from the DATABASE based on the Unit Name. -- @param #DATABASE self function DATABASE:DeleteUnit( DCSUnitName ) @@ -7461,6 +7432,7 @@ function DATABASE:DeleteUnit( DCSUnitName ) self.DCSUnits[DCSUnitName] = nil end + --- Finds a CLIENT based on the ClientName. -- @param #DATABASE self -- @param #string ClientName @@ -7471,6 +7443,7 @@ function DATABASE:FindClient( ClientName ) return ClientFound end + --- Adds a CLIENT based on the ClientName in the DATABASE. -- @param #DATABASE self function DATABASE:AddClient( ClientName ) @@ -7479,6 +7452,7 @@ function DATABASE:AddClient( ClientName ) self:E( self.CLIENTS[ClientName]:GetClassNameAndID() ) end + --- Finds a GROUP based on the GroupName. -- @param #DATABASE self -- @param #string GroupName @@ -7489,6 +7463,7 @@ function DATABASE:FindGroup( GroupName ) return GroupFound end + --- Adds a GROUP based on the GroupName in the DATABASE. -- @param #DATABASE self function DATABASE:AddGroup( DCSGroup, GroupName ) @@ -7497,6 +7472,30 @@ function DATABASE:AddGroup( DCSGroup, GroupName ) self.GROUPS[GroupName] = GROUP:Register( GroupName ) end +--- Adds a player based on the Player Name in the DATABASE. +-- @param #DATABASE self +function DATABASE:AddPlayer( UnitName, PlayerName ) + + if PlayerName then + self:E( { "Add player for unit:", UnitName, PlayerName } ) + self.PLAYERS[PlayerName] = PlayerName + self.PLAYERSALIVE[PlayerName] = PlayerName + self.CLIENTSALIVE[PlayerName] = self:FindClient( UnitName ) + end +end + +--- Deletes a player from the DATABASE based on the Player Name. +-- @param #DATABASE self +function DATABASE:DeletePlayer( PlayerName ) + + if PlayerName then + self:E( { "Clean player:", PlayerName } ) + self.PLAYERSALIVE[PlayerName] = nil + self.CLIENTSALIVE[PlayerName] = nil + end +end + + --- Instantiate new Groups within the DCSRTE. -- This method expects EXACTLY the same structure as a structure within the ME, and needs 2 additional fields defined: -- SpawnCountryID, SpawnCategoryID @@ -7505,9 +7504,9 @@ end -- @param #table SpawnTemplate -- @return #DATABASE self function DATABASE:Spawn( SpawnTemplate ) - self:F( SpawnTemplate.name ) + self:F2( SpawnTemplate.name ) - self:T( { SpawnTemplate.SpawnCountryID, SpawnTemplate.SpawnCategoryID } ) + self:T2( { SpawnTemplate.SpawnCountryID, SpawnTemplate.SpawnCategoryID } ) -- Copy the spawn variables of the template in temporary storage, nullify, and restore the spawn variables. local SpawnCoalitionID = SpawnTemplate.SpawnCoalitionID @@ -7519,7 +7518,7 @@ function DATABASE:Spawn( SpawnTemplate ) SpawnTemplate.SpawnCountryID = nil SpawnTemplate.SpawnCategoryID = nil - self:_RegisterGroup( SpawnTemplate ) + self:_RegisterTemplate( SpawnTemplate ) coalition.addGroup( SpawnCountryID, SpawnCategoryID, SpawnTemplate ) -- Restore @@ -7532,18 +7531,16 @@ function DATABASE:Spawn( SpawnTemplate ) return SpawnGroup end - --- Set a status to a Group within the Database, this to check crossing events for example. function DATABASE:SetStatusGroup( GroupName, Status ) - self:F( Status ) + self:F2( Status ) self.Templates.Groups[GroupName].Status = Status end - --- Get a status to a Group within the Database, this to check crossing events for example. function DATABASE:GetStatusGroup( GroupName ) - self:F( Status ) + self:F2( Status ) if self.Templates.Groups[GroupName] then return self.Templates.Groups[GroupName].Status @@ -7552,11 +7549,12 @@ function DATABASE:GetStatusGroup( GroupName ) end end + --- Private method that registers new Group Templates within the DATABASE Object. -- @param #DATABASE self -- @param #table GroupTemplate -- @return #DATABASE self -function DATABASE:_RegisterGroup( GroupTemplate ) +function DATABASE:_RegisterTemplate( GroupTemplate ) local GroupTemplateName = env.getValueDictByKey(GroupTemplate.name) @@ -7576,7 +7574,7 @@ function DATABASE:_RegisterGroup( GroupTemplate ) self.Templates.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units self.Templates.Groups[GroupTemplateName].Units = GroupTemplate.units - self:T( { "Group", self.Templates.Groups[GroupTemplateName].GroupName, self.Templates.Groups[GroupTemplateName].UnitCount } ) + self:T2( { "Group", self.Templates.Groups[GroupTemplateName].GroupName, self.Templates.Groups[GroupTemplateName].UnitCount } ) for unit_num, UnitTemplate in pairs( GroupTemplate.units ) do @@ -7596,6 +7594,7 @@ function DATABASE:_RegisterGroup( GroupTemplate ) end end + --- Private method that registers all alive players in the mission. -- @param #DATABASE self -- @return #DATABASE self @@ -7607,9 +7606,10 @@ function DATABASE:_RegisterPlayers() self:T3( { "UnitData:", UnitData } ) if UnitData and UnitData:isExist() then local UnitName = UnitData:getName() - if not self.PlayersAlive[UnitName] then - self:E( { "Add player for unit:", UnitName, UnitData:getPlayerName() } ) - self.PlayersAlive[UnitName] = UnitData:getPlayerName() + local PlayerName = UnitData:getPlayerName() + if not self.PLAYERS[PlayerName] then + self:E( { "Add player for unit:", UnitName, PlayerName } ) + self:AddPlayer( UnitName, PlayerName ) end end end @@ -7618,6 +7618,7 @@ function DATABASE:_RegisterPlayers() return self end + --- Private method that registers all datapoints within in the mission. -- @param #DATABASE self -- @return #DATABASE self @@ -7660,22 +7661,21 @@ end -- @param #DATABASE self -- @param Event#EVENTDATA Event function DATABASE:_EventOnBirth( Event ) - self:F( { Event } ) + self:F2( { Event } ) if Event.IniDCSUnit then - if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then - self:AddUnit( Event.IniDCSUnit, Event.IniDCSUnitName ) - self:AddGroup( Event.IniDCSGroup, Event.IniDCSGroupName ) - self:_EventOnPlayerEnterUnit( Event ) - end + self:AddUnit( Event.IniDCSUnit, Event.IniDCSUnitName ) + self:AddGroup( Event.IniDCSGroup, Event.IniDCSGroupName ) + self:_EventOnPlayerEnterUnit( Event ) end end + --- Handles the OnDead or OnCrash event for alive units set. -- @param #DATABASE self -- @param Event#EVENTDATA Event function DATABASE:_EventOnDeadOrCrash( Event ) - self:F( { Event } ) + self:F2( { Event } ) if Event.IniDCSUnit then if self.DCSUnits[Event.IniDCSUnitName] then @@ -7685,48 +7685,44 @@ function DATABASE:_EventOnDeadOrCrash( Event ) end end + --- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied). -- @param #DATABASE self -- @param Event#EVENTDATA Event function DATABASE:_EventOnPlayerEnterUnit( Event ) - self:F( { Event } ) + self:F2( { Event } ) if Event.IniDCSUnit then - if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then - if not self.PlayersAlive[Event.IniDCSUnitName] then - self:E( { "Add player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) - self.PlayersAlive[Event.IniDCSUnitName] = Event.IniDCSUnit:getPlayerName() - self.ClientsAlive[Event.IniDCSUnitName] = self.CLIENTS[ Event.IniDCSUnitName ] - end + local PlayerName = Event.IniDCSUnit:getPlayerName() + if not self.PLAYERSALIVE[PlayerName] then + self:AddPlayer( Event.IniDCSUnitName, PlayerName ) end end end + --- Handles the OnPlayerLeaveUnit event to clean the active players table. -- @param #DATABASE self -- @param Event#EVENTDATA Event function DATABASE:_EventOnPlayerLeaveUnit( Event ) - self:F( { Event } ) + self:F2( { Event } ) if Event.IniDCSUnit then - if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then - if self.PlayersAlive[Event.IniDCSUnitName] then - self:E( { "Cleaning player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) - self.PlayersAlive[Event.IniDCSUnitName] = nil - self.ClientsAlive[Event.IniDCSUnitName] = nil - end + local PlayerName = Event.IniDCSUnit:getPlayerName() + if self.PLAYERSALIVE[PlayerName] then + self:DeletePlayer( PlayerName ) end end end --- Iterators ---- Interate the DATABASE and call an interator function for the given set, providing the Object for each element within the set and optional parameters. +--- Iterate the DATABASE and call an iterator function for the given set, providing the Object for each element within the set and optional parameters. -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called when there is an alive player in the database. -- @return #DATABASE self function DATABASE:ForEach( IteratorFunction, arg, Set ) - self:F( arg ) + self:F2( arg ) local function CoRoutine() local Count = 0 @@ -7746,7 +7742,7 @@ function DATABASE:ForEach( IteratorFunction, arg, Set ) local function Schedule() local status, res = coroutine.resume( co ) - self:T( { status, res } ) + self:T2( { status, res } ) if status == false then error( res ) @@ -7764,46 +7760,96 @@ function DATABASE:ForEach( IteratorFunction, arg, Set ) end ---- Interate the DATABASE and call an interator function for each **alive** unit, providing the Unit and optional parameters. +--- Iterate the DATABASE and call an iterator function for each **alive** unit, providing the DCSUnit and optional parameters. -- @param #DATABASE self --- @param #function IteratorFunction The function that will be called when there is an alive unit in the database. The function needs to accept a UNIT parameter. +-- @param #function IteratorFunction The function that will be called when there is an alive unit in the database. The function needs to accept a DCSUnit parameter. -- @return #DATABASE self function DATABASE:ForEachDCSUnit( IteratorFunction, ... ) - self:F( arg ) + self:F2( arg ) self:ForEach( IteratorFunction, arg, self.DCSUnits ) return self end ---- Interate the DATABASE and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. + +--- Iterate the DATABASE and call an iterator function for each **alive** UNIT, providing the UNIT and optional parameters. -- @param #DATABASE self --- @param #function IteratorFunction The function that will be called when there is an alive player in the database. The function needs to accept a UNIT parameter. +-- @param #function IteratorFunction The function that will be called when there is an alive UNIT in the database. The function needs to accept a UNIT parameter. +-- @return #DATABASE self +function DATABASE:ForEachUnit( IteratorFunction, ... ) + self:F2( arg ) + + self:ForEach( IteratorFunction, arg, self.UNITS ) + + return self +end + +--- Iterate the DATABASE and call an iterator function for each **alive** GROUP, providing the GROUP and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an alive GROUP in the database. The function needs to accept a GROUP parameter. +-- @return #DATABASE self +function DATABASE:ForEachGroup( IteratorFunction, ... ) + self:F2( arg ) + + self:ForEach( IteratorFunction, arg, self.GROUPS ) + + return self +end + + +--- Iterate the DATABASE and call an iterator function for each player, providing the player name and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an player in the database. The function needs to accept the player name. -- @return #DATABASE self function DATABASE:ForEachPlayer( IteratorFunction, ... ) - self:F( arg ) + self:F2( arg ) - self:ForEach( IteratorFunction, arg, self.PlayersAlive ) + self:ForEach( IteratorFunction, arg, self.PLAYERS ) return self end ---- Interate the DATABASE and call an interator function for each client, providing the Client to the function and optional parameters. +--- Iterate the DATABASE and call an iterator function for each **alive** player, providing the Unit of the player and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an alive player in the database. The function needs to accept a UNIT parameter. +-- @return #DATABASE self +function DATABASE:ForEachPlayerAlive( IteratorFunction, ... ) + self:F2( arg ) + + self:ForEach( IteratorFunction, arg, self.PLAYERSALIVE ) + + return self +end + +--- Iterate the DATABASE and call an iterator function for each CLIENT, providing the CLIENT to the function and optional parameters. -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called when there is an alive player in the database. The function needs to accept a CLIENT parameter. -- @return #DATABASE self function DATABASE:ForEachClient( IteratorFunction, ... ) - self:F( arg ) + self:F2( arg ) self:ForEach( IteratorFunction, arg, self.CLIENTS ) return self end +--- Iterate the DATABASE and call an iterator function for each **ALIVE** CLIENT, providing the CLIENT to the function and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an alive CLIENT in the database. The function needs to accept a CLIENT parameter. +-- @return #DATABASE self +function DATABASE:ForEachClientAlive( IteratorFunction, ... ) + self:F2( arg ) + + self:ForEach( IteratorFunction, arg, self.CLIENTSALIVE ) -function DATABASE:ScanEnvironment() - self:F() + return self +end + + +function DATABASE:_RegisterTemplates() + self:F2() self.Navpoints = {} self.UNITS = {} @@ -7853,7 +7899,7 @@ function DATABASE:ScanEnvironment() for group_num, GroupTemplate in pairs(obj_type_data.group) do if GroupTemplate and GroupTemplate.units and type(GroupTemplate.units) == 'table' then --making sure again- this is a valid group - self:_RegisterGroup( GroupTemplate ) + self:_RegisterTemplate( GroupTemplate ) end --if GroupTemplate and GroupTemplate.units then end --for group_num, GroupTemplate in pairs(obj_type_data.group) do end --if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then @@ -7865,121 +7911,10 @@ function DATABASE:ScanEnvironment() end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then end --for coa_name, coa_data in pairs(mission.coalition) do - self:_RegisterDatabase() - self:_RegisterPlayers() - return self end ---- --- @param #DATABASE self --- @param DCSUnit#Unit DCSUnit --- @return #DATABASE self -function DATABASE:_IsIncludeDCSUnit( DCSUnit ) - self:F( DCSUnit ) - local DCSUnitInclude = true - - if self.Filter.Coalitions then - local DCSUnitCoalition = false - for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do - self:T( { "Coalition:", DCSUnit:getCoalition(), self.FilterMeta.Coalitions[CoalitionName], CoalitionName } ) - if self.FilterMeta.Coalitions[CoalitionName] and self.FilterMeta.Coalitions[CoalitionName] == DCSUnit:getCoalition() then - DCSUnitCoalition = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitCoalition - end - - if self.Filter.Categories then - local DCSUnitCategory = false - for CategoryID, CategoryName in pairs( self.Filter.Categories ) do - self:T( { "Category:", DCSUnit:getDesc().category, self.FilterMeta.Categories[CategoryName], CategoryName } ) - if self.FilterMeta.Categories[CategoryName] and self.FilterMeta.Categories[CategoryName] == DCSUnit:getDesc().category then - DCSUnitCategory = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitCategory - end - - if self.Filter.Types then - local DCSUnitType = false - for TypeID, TypeName in pairs( self.Filter.Types ) do - self:T( { "Type:", DCSUnit:getTypeName(), TypeName } ) - if TypeName == DCSUnit:getTypeName() then - DCSUnitType = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitType - end - - if self.Filter.Countries then - local DCSUnitCountry = false - for CountryID, CountryName in pairs( self.Filter.Countries ) do - self:T( { "Country:", DCSUnit:getCountry(), CountryName } ) - if country.id[CountryName] == DCSUnit:getCountry() then - DCSUnitCountry = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitCountry - end - - if self.Filter.UnitPrefixes then - local DCSUnitPrefix = false - for UnitPrefixId, UnitPrefix in pairs( self.Filter.UnitPrefixes ) do - self:T( { "Unit Prefix:", string.find( DCSUnit:getName(), UnitPrefix, 1 ), UnitPrefix } ) - if string.find( DCSUnit:getName(), UnitPrefix, 1 ) then - DCSUnitPrefix = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitPrefix - end - - self:T( DCSUnitInclude ) - return DCSUnitInclude -end - ---- --- @param #DATABASE self --- @param DCSUnit#Unit DCSUnit --- @return #DATABASE self -function DATABASE:_IsAliveDCSUnit( DCSUnit ) - self:F( DCSUnit ) - local DCSUnitAlive = false - if DCSUnit and DCSUnit:isExist() and DCSUnit:isActive() then - if self.DCSUnits[DCSUnit:getName()] then - DCSUnitAlive = true - end - end - self:T( DCSUnitAlive ) - return DCSUnitAlive -end - ---- --- @param #DATABASE self --- @param DCSGroup#Group DCSGroup --- @return #DATABASE self -function DATABASE:_IsAliveDCSGroup( DCSGroup ) - self:F( DCSGroup ) - local DCSGroupAlive = false - if DCSGroup and DCSGroup:isExist() then - if self.DCSGroups[DCSGroup:getName()] then - DCSGroupAlive = true - end - end - self:T( DCSGroupAlive ) - return DCSGroupAlive -end - - ---- Traces the current database contents in the log ... (for debug reasons). --- @param #DATABASE self --- @return #DATABASE self -function DATABASE:TraceDatabase() - self:F() - - self:T( { "DCSUnits:", self.DCSUnits } ) -end --- The main include file for the MOOSE system. @@ -7995,7 +7930,7 @@ Include.File( "Event" ) _EVENTDISPATCHER = EVENT:New() -- #EVENT --- Declare the main database object, which is used internally by the MOOSE classes. -_DATABASE = DATABASE:New():ScanEnvironment() -- Database#DATABASE +_DATABASE = DATABASE:New() -- Database#DATABASE --- Scoring system for MOOSE. -- This scoring class calculates the hits and kills that players make within a simulation session. diff --git a/Moose Mission Setup/Moose.lua b/Moose Mission Setup/Moose.lua index 8f1d04ce8..6339b2e01 100644 --- a/Moose Mission Setup/Moose.lua +++ b/Moose Mission Setup/Moose.lua @@ -1,5 +1,5 @@ env.info( '*** MOOSE STATIC INCLUDE START *** ' ) -env.info( 'Moose Generation Timestamp: 20160526_1413' ) +env.info( 'Moose Generation Timestamp: 20160527_1334' ) local base = _G env.info("Loading MOOSE " .. base.timer.getAbsTime() ) @@ -3037,7 +3037,10 @@ function BASE:E( Arguments ) end local LineCurrent = DebugInfoCurrent.currentline - local LineFrom = DebugInfoFrom.currentline + local LineFrom = -1 + if DebugInfoFrom then + LineFrom = DebugInfoFrom.currentline + end env.info( string.format( "%6d(%6d)/%1s:%20s%05d.%s(%s)" , LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) end @@ -3252,7 +3255,7 @@ local _EVENTCODES = { function EVENT:New() local self = BASE:Inherit( self, BASE:New() ) - self:F() + self:F2() self.EventHandler = world.addEventHandler( self ) return self end @@ -3342,7 +3345,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnBirthForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnBirthForUnit ) @@ -3355,7 +3358,7 @@ end -- @param Base#BASE EventSelf -- @return #EVENT function EVENT:OnBirth( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_BIRTH ) @@ -3369,7 +3372,7 @@ end -- @param Base#BASE EventSelf -- @return #EVENT function EVENT:OnBirthForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_BIRTH ) @@ -3383,7 +3386,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnCrashForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnCrashForUnit ) @@ -3396,7 +3399,7 @@ end -- @param Base#BASE EventSelf -- @return #EVENT function EVENT:OnCrash( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_CRASH ) @@ -3410,7 +3413,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnCrashForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_CRASH ) @@ -3424,7 +3427,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnDeadForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnDeadForUnit ) @@ -3437,7 +3440,7 @@ end -- @param Base#BASE EventSelf -- @return #EVENT function EVENT:OnDead( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_DEAD ) @@ -3452,7 +3455,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnDeadForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_DEAD ) @@ -3466,7 +3469,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnPilotDeadForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_PILOT_DEAD ) @@ -3480,7 +3483,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnLandForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnLandForUnit ) @@ -3494,7 +3497,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnLandForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_LAND ) @@ -3508,7 +3511,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnTakeOffForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnTakeOffForUnit ) @@ -3522,7 +3525,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnTakeOffForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_TAKEOFF ) @@ -3536,7 +3539,7 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnEngineShutDownForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate.name ) + self:F2( EventTemplate.name ) self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnEngineShutDownForUnit ) @@ -3550,7 +3553,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnEngineShutDownForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_ENGINE_SHUTDOWN ) @@ -3564,7 +3567,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnEngineStartUpForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_ENGINE_STARTUP ) @@ -3577,7 +3580,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnShot( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_SHOT ) @@ -3591,7 +3594,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnShotForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_SHOT ) @@ -3604,7 +3607,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnHit( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_HIT ) @@ -3618,7 +3621,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnHitForUnit( EventDCSUnitName, EventFunction, EventSelf ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_HIT ) @@ -3631,7 +3634,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnPlayerEnterUnit( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_PLAYER_ENTER_UNIT ) @@ -3644,7 +3647,7 @@ end -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnPlayerLeaveUnit( EventFunction, EventSelf ) - self:F() + self:F2() self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_PLAYER_LEAVE_UNIT ) @@ -3654,7 +3657,7 @@ end function EVENT:onEvent( Event ) - self:F( { _EVENTCODES[Event.id], Event } ) + self:F2( { _EVENTCODES[Event.id], Event } ) if self and self.Events and self.Events[Event.id] then if Event.initiator and Event.initiator:getCategory() == Object.Category.UNIT then @@ -4268,6 +4271,23 @@ function GROUP:GetCoalition() return nil end +--- Returns the country of the DCS Group. +-- @param #GROUP self +-- @return DCScountry#country.id The country identifier. +-- @return #nil The DCS Group is not existing or alive. +function GROUP:GetCountry() + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local GroupCountry = DCSGroup:getUnit(1):getCountry() + self:T3( GroupCountry ) + return GroupCountry + end + + return nil +end + --- Returns the name of the DCS Group. -- @param #GROUP self -- @return #string The DCS Group name. @@ -7277,67 +7297,37 @@ function CLIENT:Message( Message, MessageDuration, MessageId, MessageCategory, M end end end ---- Manage sets of units and groups. +--- Manage the mission database. -- --- @{#Database} class +-- @{#DATABASE} class -- ================== --- Mission designers can use the DATABASE class to build sets of units belonging to certain: +-- Mission designers can use the DATABASE class to refer to: -- --- * Coalitions --- * Categories --- * Countries --- * Unit types --- * Starting with certain prefix strings. +-- * UNITS +-- * GROUPS +-- * players +-- * alive players +-- * CLIENTS +-- * alive CLIENTS -- --- This list will grow over time. Planned developments are to include filters and iterators. --- Additional filters will be added around @{Zone#ZONEs}, Radiuses, Active players, ... --- More iterators will be implemented in the near future ... --- --- Administers the Initial Sets of the Mission Templates as defined within the Mission Editor. --- --- DATABASE construction methods: --- ================================= --- Create a new DATABASE object with the @{#DATABASE.New} method: --- --- * @{#DATABASE.New}: Creates a new DATABASE object. --- --- --- DATABASE filter criteria: --- ========================= --- You can set filter criteria to define the set of units within the database. --- Filter criteria are defined by: --- --- * @{#DATABASE.FilterCoalitions}: Builds the DATABASE with the units belonging to the coalition(s). --- * @{#DATABASE.FilterCategories}: Builds the DATABASE with the units belonging to the category(ies). --- * @{#DATABASE.FilterTypes}: Builds the DATABASE with the units belonging to the unit type(s). --- * @{#DATABASE.FilterCountries}: Builds the DATABASE with the units belonging to the country(ies). --- * @{#DATABASE.FilterUnitPrefixes}: Builds the DATABASE with the units starting with the same prefix string(s). --- --- Once the filter criteria have been set for the DATABASE, you can start filtering using: --- --- * @{#DATABASE.FilterStart}: Starts the filtering of the units within the database. --- --- Planned filter criteria within development are (so these are not yet available): --- --- * @{#DATABASE.FilterGroupPrefixes}: Builds the DATABASE with the groups of the units starting with the same prefix string(s). --- * @{#DATABASE.FilterZones}: Builds the DATABASE with the units within a @{Zone#ZONE}. +-- On top, for internal MOOSE administration purposes, the DATBASE administers the Unit and Gruop templates as defined within the Mission Editor. -- +-- Moose will automatically create one instance of the DATABASE class into the **global** object _DATABASE. +-- Moose refers to _DATABASE within the framework extensively, but you can also refer to the _DATABASE object within your missions if required. -- -- DATABASE iterators: -- =================== --- Once the filters have been defined and the DATABASE has been built, you can iterate the database with the available iterator methods. +-- You can iterate the database with the available iterator methods. -- The iterator methods will walk the DATABASE set, and call for each element within the set a function that you provide. -- The following iterator methods are currently available within the DATABASE: -- --- * @{#DATABASE.ForEachAliveUnit}: Calls a function for each alive unit it finds within the DATABASE. +-- * @{#DATABASE.ForEachUnit}: Calls a function for each @{UNIT} it finds within the DATABASE. +-- * @{#DATABASE.ForEachGroup}: Calls a function for each @{GROUP} it finds within the DATABASE. +-- * @{#DATABASE.ForEachPlayer}: Calls a function for each player it finds within the DATABASE. +-- * @{#DATABASE.ForEachPlayerAlive}: Calls a function for each alive player it finds within the DATABASE. +-- * @{#DATABASE.ForEachClient}: Calls a function for each @{CLIENT} it finds within the DATABASE. +-- * @{#DATABASE.ForEachClientAlive}: Calls a function for each alive @{CLIENT} it finds within the DATABASE. -- --- Planned iterators methods in development are (so these are not yet available): --- --- * @{#DATABASE.ForEachUnit}: Calls a function for each unit contained within the DATABASE. --- * @{#DATABASE.ForEachGroup}: Calls a function for each group contained within the DATABASE. --- * @{#DATABASE.ForEachUnitInZone}: Calls a function for each unit within a certain zone contained within the DATABASE. --- --- ==== -- @module Database -- @author FlightControl @@ -7349,6 +7339,7 @@ Include.File( "Unit" ) Include.File( "Event" ) Include.File( "Client" ) + --- DATABASE class -- @type DATABASE -- @extends Base#BASE @@ -7364,34 +7355,11 @@ DATABASE = { DCSGroups = {}, UNITS = {}, GROUPS = {}, - NavPoints = {}, - Statics = {}, - Players = {}, - PlayersAlive = {}, + PLAYERS = {}, + PLAYERSALIVE = {}, CLIENTS = {}, - ClientsAlive = {}, - Filter = { - Coalitions = nil, - Categories = nil, - Types = nil, - Countries = nil, - UnitPrefixes = nil, - GroupPrefixes = 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, - }, - }, + CLIENTSALIVE = {}, + NavPoints = {}, } local _DATABASECoalition = @@ -7426,12 +7394,13 @@ function DATABASE:New() _EVENTDISPATCHER:OnCrash( self._EventOnDeadOrCrash, self ) - -- Add database with registered clients and already alive players - -- Follow alive players and clients _EVENTDISPATCHER:OnPlayerEnterUnit( self._EventOnPlayerEnterUnit, self ) _EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventOnPlayerLeaveUnit, self ) + self:_RegisterTemplates() + self:_RegisterDatabase() + self:_RegisterPlayers() return self end @@ -7446,6 +7415,7 @@ function DATABASE:FindUnit( UnitName ) return UnitFound end + --- Adds a Unit based on the Unit Name in the DATABASE. -- @param #DATABASE self function DATABASE:AddUnit( DCSUnit, DCSUnitName ) @@ -7454,6 +7424,7 @@ function DATABASE:AddUnit( DCSUnit, DCSUnitName ) self.UNITS[DCSUnitName] = UNIT:Register( DCSUnitName ) end + --- Deletes a Unit from the DATABASE based on the Unit Name. -- @param #DATABASE self function DATABASE:DeleteUnit( DCSUnitName ) @@ -7461,6 +7432,7 @@ function DATABASE:DeleteUnit( DCSUnitName ) self.DCSUnits[DCSUnitName] = nil end + --- Finds a CLIENT based on the ClientName. -- @param #DATABASE self -- @param #string ClientName @@ -7471,6 +7443,7 @@ function DATABASE:FindClient( ClientName ) return ClientFound end + --- Adds a CLIENT based on the ClientName in the DATABASE. -- @param #DATABASE self function DATABASE:AddClient( ClientName ) @@ -7479,6 +7452,7 @@ function DATABASE:AddClient( ClientName ) self:E( self.CLIENTS[ClientName]:GetClassNameAndID() ) end + --- Finds a GROUP based on the GroupName. -- @param #DATABASE self -- @param #string GroupName @@ -7489,6 +7463,7 @@ function DATABASE:FindGroup( GroupName ) return GroupFound end + --- Adds a GROUP based on the GroupName in the DATABASE. -- @param #DATABASE self function DATABASE:AddGroup( DCSGroup, GroupName ) @@ -7497,6 +7472,30 @@ function DATABASE:AddGroup( DCSGroup, GroupName ) self.GROUPS[GroupName] = GROUP:Register( GroupName ) end +--- Adds a player based on the Player Name in the DATABASE. +-- @param #DATABASE self +function DATABASE:AddPlayer( UnitName, PlayerName ) + + if PlayerName then + self:E( { "Add player for unit:", UnitName, PlayerName } ) + self.PLAYERS[PlayerName] = PlayerName + self.PLAYERSALIVE[PlayerName] = PlayerName + self.CLIENTSALIVE[PlayerName] = self:FindClient( UnitName ) + end +end + +--- Deletes a player from the DATABASE based on the Player Name. +-- @param #DATABASE self +function DATABASE:DeletePlayer( PlayerName ) + + if PlayerName then + self:E( { "Clean player:", PlayerName } ) + self.PLAYERSALIVE[PlayerName] = nil + self.CLIENTSALIVE[PlayerName] = nil + end +end + + --- Instantiate new Groups within the DCSRTE. -- This method expects EXACTLY the same structure as a structure within the ME, and needs 2 additional fields defined: -- SpawnCountryID, SpawnCategoryID @@ -7505,9 +7504,9 @@ end -- @param #table SpawnTemplate -- @return #DATABASE self function DATABASE:Spawn( SpawnTemplate ) - self:F( SpawnTemplate.name ) + self:F2( SpawnTemplate.name ) - self:T( { SpawnTemplate.SpawnCountryID, SpawnTemplate.SpawnCategoryID } ) + self:T2( { SpawnTemplate.SpawnCountryID, SpawnTemplate.SpawnCategoryID } ) -- Copy the spawn variables of the template in temporary storage, nullify, and restore the spawn variables. local SpawnCoalitionID = SpawnTemplate.SpawnCoalitionID @@ -7519,7 +7518,7 @@ function DATABASE:Spawn( SpawnTemplate ) SpawnTemplate.SpawnCountryID = nil SpawnTemplate.SpawnCategoryID = nil - self:_RegisterGroup( SpawnTemplate ) + self:_RegisterTemplate( SpawnTemplate ) coalition.addGroup( SpawnCountryID, SpawnCategoryID, SpawnTemplate ) -- Restore @@ -7532,18 +7531,16 @@ function DATABASE:Spawn( SpawnTemplate ) return SpawnGroup end - --- Set a status to a Group within the Database, this to check crossing events for example. function DATABASE:SetStatusGroup( GroupName, Status ) - self:F( Status ) + self:F2( Status ) self.Templates.Groups[GroupName].Status = Status end - --- Get a status to a Group within the Database, this to check crossing events for example. function DATABASE:GetStatusGroup( GroupName ) - self:F( Status ) + self:F2( Status ) if self.Templates.Groups[GroupName] then return self.Templates.Groups[GroupName].Status @@ -7552,11 +7549,12 @@ function DATABASE:GetStatusGroup( GroupName ) end end + --- Private method that registers new Group Templates within the DATABASE Object. -- @param #DATABASE self -- @param #table GroupTemplate -- @return #DATABASE self -function DATABASE:_RegisterGroup( GroupTemplate ) +function DATABASE:_RegisterTemplate( GroupTemplate ) local GroupTemplateName = env.getValueDictByKey(GroupTemplate.name) @@ -7576,7 +7574,7 @@ function DATABASE:_RegisterGroup( GroupTemplate ) self.Templates.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units self.Templates.Groups[GroupTemplateName].Units = GroupTemplate.units - self:T( { "Group", self.Templates.Groups[GroupTemplateName].GroupName, self.Templates.Groups[GroupTemplateName].UnitCount } ) + self:T2( { "Group", self.Templates.Groups[GroupTemplateName].GroupName, self.Templates.Groups[GroupTemplateName].UnitCount } ) for unit_num, UnitTemplate in pairs( GroupTemplate.units ) do @@ -7596,6 +7594,7 @@ function DATABASE:_RegisterGroup( GroupTemplate ) end end + --- Private method that registers all alive players in the mission. -- @param #DATABASE self -- @return #DATABASE self @@ -7607,9 +7606,10 @@ function DATABASE:_RegisterPlayers() self:T3( { "UnitData:", UnitData } ) if UnitData and UnitData:isExist() then local UnitName = UnitData:getName() - if not self.PlayersAlive[UnitName] then - self:E( { "Add player for unit:", UnitName, UnitData:getPlayerName() } ) - self.PlayersAlive[UnitName] = UnitData:getPlayerName() + local PlayerName = UnitData:getPlayerName() + if not self.PLAYERS[PlayerName] then + self:E( { "Add player for unit:", UnitName, PlayerName } ) + self:AddPlayer( UnitName, PlayerName ) end end end @@ -7618,6 +7618,7 @@ function DATABASE:_RegisterPlayers() return self end + --- Private method that registers all datapoints within in the mission. -- @param #DATABASE self -- @return #DATABASE self @@ -7660,22 +7661,21 @@ end -- @param #DATABASE self -- @param Event#EVENTDATA Event function DATABASE:_EventOnBirth( Event ) - self:F( { Event } ) + self:F2( { Event } ) if Event.IniDCSUnit then - if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then - self:AddUnit( Event.IniDCSUnit, Event.IniDCSUnitName ) - self:AddGroup( Event.IniDCSGroup, Event.IniDCSGroupName ) - self:_EventOnPlayerEnterUnit( Event ) - end + self:AddUnit( Event.IniDCSUnit, Event.IniDCSUnitName ) + self:AddGroup( Event.IniDCSGroup, Event.IniDCSGroupName ) + self:_EventOnPlayerEnterUnit( Event ) end end + --- Handles the OnDead or OnCrash event for alive units set. -- @param #DATABASE self -- @param Event#EVENTDATA Event function DATABASE:_EventOnDeadOrCrash( Event ) - self:F( { Event } ) + self:F2( { Event } ) if Event.IniDCSUnit then if self.DCSUnits[Event.IniDCSUnitName] then @@ -7685,48 +7685,44 @@ function DATABASE:_EventOnDeadOrCrash( Event ) end end + --- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied). -- @param #DATABASE self -- @param Event#EVENTDATA Event function DATABASE:_EventOnPlayerEnterUnit( Event ) - self:F( { Event } ) + self:F2( { Event } ) if Event.IniDCSUnit then - if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then - if not self.PlayersAlive[Event.IniDCSUnitName] then - self:E( { "Add player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) - self.PlayersAlive[Event.IniDCSUnitName] = Event.IniDCSUnit:getPlayerName() - self.ClientsAlive[Event.IniDCSUnitName] = self.CLIENTS[ Event.IniDCSUnitName ] - end + local PlayerName = Event.IniDCSUnit:getPlayerName() + if not self.PLAYERSALIVE[PlayerName] then + self:AddPlayer( Event.IniDCSUnitName, PlayerName ) end end end + --- Handles the OnPlayerLeaveUnit event to clean the active players table. -- @param #DATABASE self -- @param Event#EVENTDATA Event function DATABASE:_EventOnPlayerLeaveUnit( Event ) - self:F( { Event } ) + self:F2( { Event } ) if Event.IniDCSUnit then - if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then - if self.PlayersAlive[Event.IniDCSUnitName] then - self:E( { "Cleaning player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) - self.PlayersAlive[Event.IniDCSUnitName] = nil - self.ClientsAlive[Event.IniDCSUnitName] = nil - end + local PlayerName = Event.IniDCSUnit:getPlayerName() + if self.PLAYERSALIVE[PlayerName] then + self:DeletePlayer( PlayerName ) end end end --- Iterators ---- Interate the DATABASE and call an interator function for the given set, providing the Object for each element within the set and optional parameters. +--- Iterate the DATABASE and call an iterator function for the given set, providing the Object for each element within the set and optional parameters. -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called when there is an alive player in the database. -- @return #DATABASE self function DATABASE:ForEach( IteratorFunction, arg, Set ) - self:F( arg ) + self:F2( arg ) local function CoRoutine() local Count = 0 @@ -7746,7 +7742,7 @@ function DATABASE:ForEach( IteratorFunction, arg, Set ) local function Schedule() local status, res = coroutine.resume( co ) - self:T( { status, res } ) + self:T2( { status, res } ) if status == false then error( res ) @@ -7764,46 +7760,96 @@ function DATABASE:ForEach( IteratorFunction, arg, Set ) end ---- Interate the DATABASE and call an interator function for each **alive** unit, providing the Unit and optional parameters. +--- Iterate the DATABASE and call an iterator function for each **alive** unit, providing the DCSUnit and optional parameters. -- @param #DATABASE self --- @param #function IteratorFunction The function that will be called when there is an alive unit in the database. The function needs to accept a UNIT parameter. +-- @param #function IteratorFunction The function that will be called when there is an alive unit in the database. The function needs to accept a DCSUnit parameter. -- @return #DATABASE self function DATABASE:ForEachDCSUnit( IteratorFunction, ... ) - self:F( arg ) + self:F2( arg ) self:ForEach( IteratorFunction, arg, self.DCSUnits ) return self end ---- Interate the DATABASE and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. + +--- Iterate the DATABASE and call an iterator function for each **alive** UNIT, providing the UNIT and optional parameters. -- @param #DATABASE self --- @param #function IteratorFunction The function that will be called when there is an alive player in the database. The function needs to accept a UNIT parameter. +-- @param #function IteratorFunction The function that will be called when there is an alive UNIT in the database. The function needs to accept a UNIT parameter. +-- @return #DATABASE self +function DATABASE:ForEachUnit( IteratorFunction, ... ) + self:F2( arg ) + + self:ForEach( IteratorFunction, arg, self.UNITS ) + + return self +end + +--- Iterate the DATABASE and call an iterator function for each **alive** GROUP, providing the GROUP and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an alive GROUP in the database. The function needs to accept a GROUP parameter. +-- @return #DATABASE self +function DATABASE:ForEachGroup( IteratorFunction, ... ) + self:F2( arg ) + + self:ForEach( IteratorFunction, arg, self.GROUPS ) + + return self +end + + +--- Iterate the DATABASE and call an iterator function for each player, providing the player name and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an player in the database. The function needs to accept the player name. -- @return #DATABASE self function DATABASE:ForEachPlayer( IteratorFunction, ... ) - self:F( arg ) + self:F2( arg ) - self:ForEach( IteratorFunction, arg, self.PlayersAlive ) + self:ForEach( IteratorFunction, arg, self.PLAYERS ) return self end ---- Interate the DATABASE and call an interator function for each client, providing the Client to the function and optional parameters. +--- Iterate the DATABASE and call an iterator function for each **alive** player, providing the Unit of the player and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an alive player in the database. The function needs to accept a UNIT parameter. +-- @return #DATABASE self +function DATABASE:ForEachPlayerAlive( IteratorFunction, ... ) + self:F2( arg ) + + self:ForEach( IteratorFunction, arg, self.PLAYERSALIVE ) + + return self +end + +--- Iterate the DATABASE and call an iterator function for each CLIENT, providing the CLIENT to the function and optional parameters. -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called when there is an alive player in the database. The function needs to accept a CLIENT parameter. -- @return #DATABASE self function DATABASE:ForEachClient( IteratorFunction, ... ) - self:F( arg ) + self:F2( arg ) self:ForEach( IteratorFunction, arg, self.CLIENTS ) return self end +--- Iterate the DATABASE and call an iterator function for each **ALIVE** CLIENT, providing the CLIENT to the function and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an alive CLIENT in the database. The function needs to accept a CLIENT parameter. +-- @return #DATABASE self +function DATABASE:ForEachClientAlive( IteratorFunction, ... ) + self:F2( arg ) + + self:ForEach( IteratorFunction, arg, self.CLIENTSALIVE ) -function DATABASE:ScanEnvironment() - self:F() + return self +end + + +function DATABASE:_RegisterTemplates() + self:F2() self.Navpoints = {} self.UNITS = {} @@ -7853,7 +7899,7 @@ function DATABASE:ScanEnvironment() for group_num, GroupTemplate in pairs(obj_type_data.group) do if GroupTemplate and GroupTemplate.units and type(GroupTemplate.units) == 'table' then --making sure again- this is a valid group - self:_RegisterGroup( GroupTemplate ) + self:_RegisterTemplate( GroupTemplate ) end --if GroupTemplate and GroupTemplate.units then end --for group_num, GroupTemplate in pairs(obj_type_data.group) do end --if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then @@ -7865,121 +7911,10 @@ function DATABASE:ScanEnvironment() end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then end --for coa_name, coa_data in pairs(mission.coalition) do - self:_RegisterDatabase() - self:_RegisterPlayers() - return self end ---- --- @param #DATABASE self --- @param DCSUnit#Unit DCSUnit --- @return #DATABASE self -function DATABASE:_IsIncludeDCSUnit( DCSUnit ) - self:F( DCSUnit ) - local DCSUnitInclude = true - - if self.Filter.Coalitions then - local DCSUnitCoalition = false - for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do - self:T( { "Coalition:", DCSUnit:getCoalition(), self.FilterMeta.Coalitions[CoalitionName], CoalitionName } ) - if self.FilterMeta.Coalitions[CoalitionName] and self.FilterMeta.Coalitions[CoalitionName] == DCSUnit:getCoalition() then - DCSUnitCoalition = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitCoalition - end - - if self.Filter.Categories then - local DCSUnitCategory = false - for CategoryID, CategoryName in pairs( self.Filter.Categories ) do - self:T( { "Category:", DCSUnit:getDesc().category, self.FilterMeta.Categories[CategoryName], CategoryName } ) - if self.FilterMeta.Categories[CategoryName] and self.FilterMeta.Categories[CategoryName] == DCSUnit:getDesc().category then - DCSUnitCategory = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitCategory - end - - if self.Filter.Types then - local DCSUnitType = false - for TypeID, TypeName in pairs( self.Filter.Types ) do - self:T( { "Type:", DCSUnit:getTypeName(), TypeName } ) - if TypeName == DCSUnit:getTypeName() then - DCSUnitType = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitType - end - - if self.Filter.Countries then - local DCSUnitCountry = false - for CountryID, CountryName in pairs( self.Filter.Countries ) do - self:T( { "Country:", DCSUnit:getCountry(), CountryName } ) - if country.id[CountryName] == DCSUnit:getCountry() then - DCSUnitCountry = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitCountry - end - - if self.Filter.UnitPrefixes then - local DCSUnitPrefix = false - for UnitPrefixId, UnitPrefix in pairs( self.Filter.UnitPrefixes ) do - self:T( { "Unit Prefix:", string.find( DCSUnit:getName(), UnitPrefix, 1 ), UnitPrefix } ) - if string.find( DCSUnit:getName(), UnitPrefix, 1 ) then - DCSUnitPrefix = true - end - end - DCSUnitInclude = DCSUnitInclude and DCSUnitPrefix - end - - self:T( DCSUnitInclude ) - return DCSUnitInclude -end - ---- --- @param #DATABASE self --- @param DCSUnit#Unit DCSUnit --- @return #DATABASE self -function DATABASE:_IsAliveDCSUnit( DCSUnit ) - self:F( DCSUnit ) - local DCSUnitAlive = false - if DCSUnit and DCSUnit:isExist() and DCSUnit:isActive() then - if self.DCSUnits[DCSUnit:getName()] then - DCSUnitAlive = true - end - end - self:T( DCSUnitAlive ) - return DCSUnitAlive -end - ---- --- @param #DATABASE self --- @param DCSGroup#Group DCSGroup --- @return #DATABASE self -function DATABASE:_IsAliveDCSGroup( DCSGroup ) - self:F( DCSGroup ) - local DCSGroupAlive = false - if DCSGroup and DCSGroup:isExist() then - if self.DCSGroups[DCSGroup:getName()] then - DCSGroupAlive = true - end - end - self:T( DCSGroupAlive ) - return DCSGroupAlive -end - - ---- Traces the current database contents in the log ... (for debug reasons). --- @param #DATABASE self --- @return #DATABASE self -function DATABASE:TraceDatabase() - self:F() - - self:T( { "DCSUnits:", self.DCSUnits } ) -end --- The main include file for the MOOSE system. @@ -7995,7 +7930,7 @@ Include.File( "Event" ) _EVENTDISPATCHER = EVENT:New() -- #EVENT --- Declare the main database object, which is used internally by the MOOSE classes. -_DATABASE = DATABASE:New():ScanEnvironment() -- Database#DATABASE +_DATABASE = DATABASE:New() -- Database#DATABASE --- Scoring system for MOOSE. -- This scoring class calculates the hits and kills that players make within a simulation session. diff --git a/Moose Test Missions/Moose_Test_CLEANUP/Moose_Test_CLEANUP.miz b/Moose Test Missions/Moose_Test_CLEANUP/Moose_Test_CLEANUP.miz index 928c05242..5b3946c14 100644 Binary files a/Moose Test Missions/Moose_Test_CLEANUP/Moose_Test_CLEANUP.miz and b/Moose Test Missions/Moose_Test_CLEANUP/Moose_Test_CLEANUP.miz differ diff --git a/Moose Test Missions/Moose_Test_DATABASE/Moose_Test_DATABASE.lua b/Moose Test Missions/Moose_Test_DATABASE/Moose_Test_DATABASE.lua index 88f76d82a..d299d3501 100644 --- a/Moose Test Missions/Moose_Test_DATABASE/Moose_Test_DATABASE.lua +++ b/Moose Test Missions/Moose_Test_DATABASE/Moose_Test_DATABASE.lua @@ -1,39 +1,52 @@ -Include.File( 'Database' ) + +Include.File( 'UnitSet' ) +Include.File( 'GroupSet' ) Include.File( 'Spawn' ) -DBBluePlanes = DATABASE:New() +DBBluePlanes = UNITSET:New() :FilterCoalitions( "blue" ) :FilterCategories( "plane" ) :FilterStart() -DBRedVehicles = DATABASE:New() +DBRedVehicles = UNITSET:New() :FilterCoalitions( "red" ) :FilterCategories( "ground" ) :FilterStart() -DBShips = DATABASE:New() +DBShips = UNITSET:New() :FilterCategories( "ship" ) :FilterStart() -DBBelgium = DATABASE:New() +DBBelgium = UNITSET:New() :FilterCategories( "helicopter" ) :FilterCountries( "BELGIUM" ) :FilterStart() -DBNorthKorea = DATABASE:New() +DBNorthKorea = UNITSET:New() :FilterCountries( "NORTH_KOREA" ) :FilterStart() -DBKA50Vinson = DATABASE:New() +DBKA50Vinson = UNITSET:New() :FilterTypes( { "Ka-50", "VINSON" } ) :FilterStart() + +DBBluePlanesGroup = GROUPSET:New() + :FilterCoalitions( "blue" ) + :FilterCategories( "plane" ) + :FilterStart() + +DBNorthKoreaGroup = GROUPSET:New() + :FilterCountries( "NORTH_KOREA" ) + :FilterStart() -DBBluePlanes:TraceDatabase() -DBRedVehicles:TraceDatabase() -DBShips:TraceDatabase() -DBBelgium:TraceDatabase() -DBNorthKorea:TraceDatabase() -DBKA50Vinson:TraceDatabase() +DBBluePlanes:Flush() +DBRedVehicles:Flush() +DBShips:Flush() +DBBelgium:Flush() +DBNorthKorea:Flush() +DBKA50Vinson:Flush() +DBBluePlanesGroup:Flush() +DBNorthKoreaGroup:Flush() SpawnUS_Plane = SPAWN:New( 'Database Spawn Test USA Plane') @@ -54,21 +67,42 @@ GroupRU_Ship = SpawnRU_Ship:Spawn() SpawnUS_AttackVehicle = SPAWN:New( 'Database Spawn Test USA Attack Vehicle' ) SpawnRU_AttackVehicle = SPAWN:New( 'Database Spawn Test RUSSIA Attack Vehicle' ) -for i = 1, 10 do +for i = 1, 2 do GroupRU_AttackVehicle = SpawnRU_AttackVehicle:SpawnInZone( ZONE:New("Spawn Zone RU"), true) GroupUS_AttackVehicle = SpawnUS_AttackVehicle:SpawnInZone( ZONE:New("Spawn Zone US"), true) end --DBBlue:TraceDatabase() -routines.scheduleFunction( DBBluePlanes.TraceDatabase, { DBBluePlanes }, 1 ) -routines.scheduleFunction( DBRedVehicles.TraceDatabase, { DBRedVehicles }, 1 ) -routines.scheduleFunction( DBShips.TraceDatabase, { DBShips }, 1 ) -routines.scheduleFunction( DBBelgium.TraceDatabase, { DBBelgium }, 1 ) -routines.scheduleFunction( DBNorthKorea.TraceDatabase, { DBNorthKorea }, 1 ) -routines.scheduleFunction( DBKA50Vinson.TraceDatabase, { DBKA50Vinson }, 1 ) +SCHEDULER:New( DBBluePlanes, DBBluePlanes.Flush, { }, 1 ) +SCHEDULER:New( DBRedVehicles, DBRedVehicles.Flush, { }, 1 ) +SCHEDULER:New( DBShips, DBShips.Flush, { }, 1 ) +SCHEDULER:New( DBBelgium, DBBelgium.Flush, { }, 1 ) +SCHEDULER:New( DBNorthKorea, DBNorthKorea.Flush, { }, 1 ) +SCHEDULER:New( DBKA50Vinson, DBKA50Vinson.Flush, { }, 1 ) + +SCHEDULER:New( DBBluePlanesGroup, DBBluePlanesGroup.Flush, { }, 1 ) +SCHEDULER:New( DBNorthKoreaGroup, DBNorthKoreaGroup.Flush, { }, 1 ) DBRedVehicles - :ForEachAliveUnit( function( DCSUnit ) - DBRedVehicles:T( DCSUnit:getName() ) + :ForEachUnit( function( MooseUnit ) + DBRedVehicles:T( MooseUnit:GetName() ) end ) + +local function FlushPlayers() + + _DATABASE:E( "FlushPlayers" ) + _DATABASE + :ForEachPlayerAlive( function( Player ) + _DATABASE:E( Player ) + MESSAGE:New( Player, "Test", 5, "Player Test" ):ToAll() + return true + end ) + return true +end + +_DATABASE:E( "Schedule" ) +local PlayerShow = SCHEDULER:New( nil, FlushPlayers, {}, 1, 10 ) + + + diff --git a/Moose Test Missions/Moose_Test_DATABASE/Moose_Test_DATABASE.miz b/Moose Test Missions/Moose_Test_DATABASE/Moose_Test_DATABASE.miz index 0bdbd3f05..bc67a6daa 100644 Binary files a/Moose Test Missions/Moose_Test_DATABASE/Moose_Test_DATABASE.miz and b/Moose Test Missions/Moose_Test_DATABASE/Moose_Test_DATABASE.miz differ diff --git a/Moose Test Missions/Moose_Test_DESTROY/MOOSE_Test_DESTROY.miz b/Moose Test Missions/Moose_Test_DESTROY/MOOSE_Test_DESTROY.miz index 670f8d468..741f65acd 100644 Binary files a/Moose Test Missions/Moose_Test_DESTROY/MOOSE_Test_DESTROY.miz and b/Moose Test Missions/Moose_Test_DESTROY/MOOSE_Test_DESTROY.miz differ diff --git a/Moose Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz b/Moose Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz index 912b3d1cf..e8c0176c4 100644 Binary files a/Moose Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz and b/Moose Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz differ diff --git a/Moose Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.miz b/Moose Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.miz index 69faae2df..3c78aff79 100644 Binary files a/Moose Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.miz and b/Moose Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.miz differ diff --git a/Moose Test Missions/Moose_Test_SEAD/MOOSE_Test_SEAD.miz b/Moose Test Missions/Moose_Test_SEAD/MOOSE_Test_SEAD.miz index dbe71769b..b7f520bf6 100644 Binary files a/Moose Test Missions/Moose_Test_SEAD/MOOSE_Test_SEAD.miz and b/Moose Test Missions/Moose_Test_SEAD/MOOSE_Test_SEAD.miz differ diff --git a/Moose Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.miz b/Moose Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.miz index 3a6bcd9e6..efb125ade 100644 Binary files a/Moose Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.miz and b/Moose Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.miz differ diff --git a/Moose Test Missions/Moose_Test_SPAWN_Repeat/MOOSE_Test_SPAWN_Repeat.miz b/Moose Test Missions/Moose_Test_SPAWN_Repeat/MOOSE_Test_SPAWN_Repeat.miz index 63198ee5a..91112db60 100644 Binary files a/Moose Test Missions/Moose_Test_SPAWN_Repeat/MOOSE_Test_SPAWN_Repeat.miz and b/Moose Test Missions/Moose_Test_SPAWN_Repeat/MOOSE_Test_SPAWN_Repeat.miz differ diff --git a/Moose Test Missions/Moose_Test_TASK_Pickup_and_Deploy/MOOSE_Test_TASK_Pickup_and_Deploy.miz b/Moose Test Missions/Moose_Test_TASK_Pickup_and_Deploy/MOOSE_Test_TASK_Pickup_and_Deploy.miz index c909c341b..3b8e93543 100644 Binary files a/Moose Test Missions/Moose_Test_TASK_Pickup_and_Deploy/MOOSE_Test_TASK_Pickup_and_Deploy.miz and b/Moose Test Missions/Moose_Test_TASK_Pickup_and_Deploy/MOOSE_Test_TASK_Pickup_and_Deploy.miz differ diff --git a/Moose Test Missions/Moose_Test_WRAPPER/Moose_Test_WRAPPER.miz b/Moose Test Missions/Moose_Test_WRAPPER/Moose_Test_WRAPPER.miz index d2fa72778..36e69ef22 100644 Binary files a/Moose Test Missions/Moose_Test_WRAPPER/Moose_Test_WRAPPER.miz and b/Moose Test Missions/Moose_Test_WRAPPER/Moose_Test_WRAPPER.miz differ diff --git a/Moose Training/Documentation/Base.html b/Moose Training/Documentation/Base.html index f7177aa41..c35a7adac 100644 --- a/Moose Training/Documentation/Base.html +++ b/Moose Training/Documentation/Base.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • @@ -253,7 +255,7 @@ These tracing levels were defined to avoid bulks of tracing to be generated by l BASE:New() - +

    The base constructor.

    @@ -769,7 +771,29 @@ is the Child class from which the Parent class needs to be retrieved.

    +

    The base constructor.

    + +

    This is the top top class of all classed defined within the MOOSE. +Any new class needs to be derived from this class for proper inheritance.

    + +

    Return value

    + +

    #BASE: +The new instance of the BASE class.

    + +

    Usage:

    +
    function TASK:New()
    +
    +    local self = BASE:Inherit( self, BASE:New() )
    +
    +    -- assign Task default values during construction
    +    self.TaskBriefing = "Task: No Task."
    +    self.Time = timer.getTime()
    +    self.ExecuteStage = _TransportExecuteStage.NONE
    +
    +    return self
    +end
    diff --git a/Moose Training/Documentation/CARGO.html b/Moose Training/Documentation/CARGO.html index fdacc75e3..f7ca9c91e 100644 --- a/Moose Training/Documentation/CARGO.html +++ b/Moose Training/Documentation/CARGO.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/CleanUp.html b/Moose Training/Documentation/CleanUp.html index 1b0702bb3..c22bc448d 100644 --- a/Moose Training/Documentation/CleanUp.html +++ b/Moose Training/Documentation/CleanUp.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/Client.html b/Moose Training/Documentation/Client.html index 67e324e6f..7ad2cd35e 100644 --- a/Moose Training/Documentation/Client.html +++ b/Moose Training/Documentation/Client.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • @@ -309,13 +311,19 @@ If the DCS Unit object does not exist or is nil, the CLIENT methods will return CLIENT:ShowBriefing() -

    Show the briefing of the MISSION to the CLIENT.

    +

    Show the briefing of a CLIENT.

    CLIENT:ShowCargo()

    Shows the Cargo#CARGO contained within the CLIENT to the player as a message.

    + + + + CLIENT:ShowMissionBriefing(MissionBriefing) + +

    Show the mission briefing of a MISSION to the CLIENT.

    @@ -992,7 +1000,7 @@ Name of the Group as defined within the Mission Editor. The Group must have a Un
    -

    Show the briefing of the MISSION to the CLIENT.

    +

    Show the briefing of a CLIENT.

    Return value

    @@ -1020,6 +1028,32 @@ self

    + +CLIENT:ShowMissionBriefing(MissionBriefing) + +
    +
    + +

    Show the mission briefing of a MISSION to the CLIENT.

    + +

    Parameter

    +
      +
    • + +

      #string MissionBriefing :

      + +
    • +
    +

    Return value

    + +

    #CLIENT: +self

    + +
    +
    +
    +
    + CLIENT.SwitchMessages(PrmTable) diff --git a/Moose Training/Documentation/DCSAirbase.html b/Moose Training/Documentation/DCSAirbase.html index 907c576e5..c5ad209a8 100644 --- a/Moose Training/Documentation/DCSAirbase.html +++ b/Moose Training/Documentation/DCSAirbase.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/DCSCoalitionObject.html b/Moose Training/Documentation/DCSCoalitionObject.html index ee0e7b8dc..d7a968f25 100644 --- a/Moose Training/Documentation/DCSCoalitionObject.html +++ b/Moose Training/Documentation/DCSCoalitionObject.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/DCSCommand.html b/Moose Training/Documentation/DCSCommand.html index 4c9762082..5f433a2f3 100644 --- a/Moose Training/Documentation/DCSCommand.html +++ b/Moose Training/Documentation/DCSCommand.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/DCSController.html b/Moose Training/Documentation/DCSController.html index c4e7c7428..228983cdf 100644 --- a/Moose Training/Documentation/DCSController.html +++ b/Moose Training/Documentation/DCSController.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/DCSGroup.html b/Moose Training/Documentation/DCSGroup.html index a7a84c8d1..d5df1b04a 100644 --- a/Moose Training/Documentation/DCSGroup.html +++ b/Moose Training/Documentation/DCSGroup.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/DCSObject.html b/Moose Training/Documentation/DCSObject.html index 44157433f..d536b3e22 100644 --- a/Moose Training/Documentation/DCSObject.html +++ b/Moose Training/Documentation/DCSObject.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/DCSTask.html b/Moose Training/Documentation/DCSTask.html index 93585f188..adf8812c1 100644 --- a/Moose Training/Documentation/DCSTask.html +++ b/Moose Training/Documentation/DCSTask.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/DCSTypes.html b/Moose Training/Documentation/DCSTypes.html index 2cf9f22b0..56ccd79ff 100644 --- a/Moose Training/Documentation/DCSTypes.html +++ b/Moose Training/Documentation/DCSTypes.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/DCSUnit.html b/Moose Training/Documentation/DCSUnit.html index e09265c44..e40060e37 100644 --- a/Moose Training/Documentation/DCSUnit.html +++ b/Moose Training/Documentation/DCSUnit.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/DCSWorld.html b/Moose Training/Documentation/DCSWorld.html index e91ba3f3f..13b3fe634 100644 --- a/Moose Training/Documentation/DCSWorld.html +++ b/Moose Training/Documentation/DCSWorld.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/DCStimer.html b/Moose Training/Documentation/DCStimer.html index b4af45ac2..b05ff053c 100644 --- a/Moose Training/Documentation/DCStimer.html +++ b/Moose Training/Documentation/DCStimer.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/DEPLOYTASK.html b/Moose Training/Documentation/DEPLOYTASK.html index b57bf41c4..53467e608 100644 --- a/Moose Training/Documentation/DEPLOYTASK.html +++ b/Moose Training/Documentation/DEPLOYTASK.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/DESTROYBASETASK.html b/Moose Training/Documentation/DESTROYBASETASK.html index 263a03453..aa3bef726 100644 --- a/Moose Training/Documentation/DESTROYBASETASK.html +++ b/Moose Training/Documentation/DESTROYBASETASK.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/DESTROYGROUPSTASK.html b/Moose Training/Documentation/DESTROYGROUPSTASK.html index 2235e0590..baa779ad1 100644 --- a/Moose Training/Documentation/DESTROYGROUPSTASK.html +++ b/Moose Training/Documentation/DESTROYGROUPSTASK.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/DESTROYRADARSTASK.html b/Moose Training/Documentation/DESTROYRADARSTASK.html index f246dfc10..cab844e6f 100644 --- a/Moose Training/Documentation/DESTROYRADARSTASK.html +++ b/Moose Training/Documentation/DESTROYRADARSTASK.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/DESTROYUNITTYPESTASK.html b/Moose Training/Documentation/DESTROYUNITTYPESTASK.html index 62898b2ee..f5ce3a192 100644 --- a/Moose Training/Documentation/DESTROYUNITTYPESTASK.html +++ b/Moose Training/Documentation/DESTROYUNITTYPESTASK.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/Database.html b/Moose Training/Documentation/Database.html index baef7069e..211aacd2c 100644 --- a/Moose Training/Documentation/Database.html +++ b/Moose Training/Documentation/Database.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • @@ -68,80 +70,42 @@

    Module Database

    -

    Manage sets of units and groups.

    +

    Manage the mission database.

    -

    #Database class

    -

    Mission designers can use the DATABASE class to build sets of units belonging to certain:

    +

    #DATABASE class

    +

    Mission designers can use the DATABASE class to refer to:

      -
    • Coalitions
    • -
    • Categories
    • -
    • Countries
    • -
    • Unit types
    • -
    • Starting with certain prefix strings.
    • +
    • UNITS
    • +
    • GROUPS
    • +
    • players
    • +
    • alive players
    • +
    • CLIENTS
    • +
    • alive CLIENTS
    -

    This list will grow over time. Planned developments are to include filters and iterators. -Additional filters will be added around Zone#ZONEs, Radiuses, Active players, ... -More iterators will be implemented in the near future ...

    - -

    Administers the Initial Sets of the Mission Templates as defined within the Mission Editor.

    - -

    DATABASE construction methods:

    -

    Create a new DATABASE object with the DATABASE.New method:

    - - - - -

    DATABASE filter criteria:

    -

    You can set filter criteria to define the set of units within the database. -Filter criteria are defined by:

    - - - -

    Once the filter criteria have been set for the DATABASE, you can start filtering using:

    - - - -

    Planned filter criteria within development are (so these are not yet available):

    - - +

    On top, for internal MOOSE administration purposes, the DATBASE administers the Unit and Gruop templates as defined within the Mission Editor.

    +

    Moose will automatically create one instance of the DATABASE class into the global object _DATABASE. +Moose refers to _DATABASE within the framework extensively, but you can also refer to the _DATABASE object within your missions if required.

    DATABASE iterators:

    -

    Once the filters have been defined and the DATABASE has been built, you can iterate the database with the available iterator methods. +

    You can iterate the database with the available iterator methods. The iterator methods will walk the DATABASE set, and call for each element within the set a function that you provide. The following iterator methods are currently available within the DATABASE:

    -

    Planned iterators methods in development are (so these are not yet available):

    - - - -
    -

    Global(s)

    @@ -163,6 +127,12 @@ The following iterator methods are currently available within the DATABASE:

    + + + + @@ -178,13 +148,13 @@ The following iterator methods are currently available within the DATABASE:

    - + - + @@ -199,24 +169,18 @@ The following iterator methods are currently available within the DATABASE:

    + + + + - - - - - - - - @@ -240,25 +204,49 @@ The following iterator methods are currently available within the DATABASE:

    + + + + + + + + + + + + + + + + @@ -286,19 +274,13 @@ The following iterator methods are currently available within the DATABASE:

    - + - - - - - + @@ -313,24 +295,12 @@ The following iterator methods are currently available within the DATABASE:

    - - - - - - - - @@ -361,24 +331,6 @@ The following iterator methods are currently available within the DATABASE:

    - - - - - - - - - - - - @@ -388,15 +340,21 @@ The following iterator methods are currently available within the DATABASE:

    - + + + + + - +
    DATABASE:AddGroup(DCSGroup, GroupName)

    Adds a GROUP based on the GroupName in the DATABASE.

    +
    DATABASE:AddPlayer(UnitName, PlayerName) +

    Adds a player based on the Player Name in the DATABASE.

    DATABASE.ClassNameDATABASE.CLIENTSALIVE
    DATABASE.ClientsAliveDATABASE.ClassName DATABASE.DCSUnits +
    DATABASE:DeletePlayer(PlayerName) +

    Deletes a player from the DATABASE based on the Player Name.

    DATABASE:DeleteUnit(DCSUnitName)

    Deletes a Unit from the DATABASE based on the Unit Name.

    -
    DATABASE.Filter - -
    DATABASE.FilterMeta -
    DATABASE:ForEach(IteratorFunction, arg, Set) -

    Interate the DATABASE and call an interator function for the given set, providing the Object for each element within the set and optional parameters.

    +

    Iterate the DATABASE and call an iterator function for the given set, providing the Object for each element within the set and optional parameters.

    DATABASE:ForEachClient(IteratorFunction, ...) -

    Interate the DATABASE and call an interator function for each client, providing the Client to the function and optional parameters.

    +

    Iterate the DATABASE and call an iterator function for each CLIENT, providing the CLIENT to the function and optional parameters.

    +
    DATABASE:ForEachClientAlive(IteratorFunction, ...) +

    Iterate the DATABASE and call an iterator function for each ALIVE CLIENT, providing the CLIENT to the function and optional parameters.

    DATABASE:ForEachDCSUnit(IteratorFunction, ...) -

    Interate the DATABASE and call an interator function for each alive unit, providing the Unit and optional parameters.

    +

    Iterate the DATABASE and call an iterator function for each alive unit, providing the DCSUnit and optional parameters.

    +
    DATABASE:ForEachGroup(IteratorFunction, ...) +

    Iterate the DATABASE and call an iterator function for each alive GROUP, providing the GROUP and optional parameters.

    DATABASE:ForEachPlayer(IteratorFunction, ...) -

    Interate the DATABASE and call an interator function for each alive player, providing the Unit of the player and optional parameters.

    +

    Iterate the DATABASE and call an iterator function for each player, providing the player name and optional parameters.

    +
    DATABASE:ForEachPlayerAlive(IteratorFunction, ...) +

    Iterate the DATABASE and call an iterator function for each alive player, providing the Unit of the player and optional parameters.

    +
    DATABASE:ForEachUnit(IteratorFunction, ...) +

    Iterate the DATABASE and call an iterator function for each alive UNIT, providing the UNIT and optional parameters.

    DATABASE.PlayersDATABASE.PLAYERS
    DATABASE.PlayersAlive - -
    DATABASE:ScanEnvironment()DATABASE.PLAYERSALIVE DATABASE:Spawn(SpawnTemplate)

    Instantiate new Groups within the DCSRTE.

    -
    DATABASE.Statics -
    DATABASE.Templates -
    DATABASE:TraceDatabase() -

    Traces the current database contents in the log ...

    DATABASE:_EventOnPlayerLeaveUnit(Event)

    Handles the OnPlayerLeaveUnit event to clean the active players table.

    -
    DATABASE:_IsAliveDCSGroup(DCSGroup) - -
    DATABASE:_IsAliveDCSUnit(DCSUnit) - -
    DATABASE:_IsIncludeDCSUnit(DCSUnit) -
    DATABASE:_RegisterGroup(GroupTemplate)DATABASE:_RegisterPlayers() +

    Private method that registers all alive players in the mission.

    +
    DATABASE:_RegisterTemplate(GroupTemplate)

    Private method that registers new Group Templates within the DATABASE Object.

    DATABASE:_RegisterPlayers()DATABASE:_RegisterTemplates() -

    Private method that registers all alive players in the mission.

    +
    @@ -473,6 +431,32 @@ The following iterator methods are currently available within the DATABASE:

    + +DATABASE:AddPlayer(UnitName, PlayerName) + +
    +
    + +

    Adds a player based on the Player Name in the DATABASE.

    + +

    Parameters

    +
      +
    • + +

      UnitName :

      + +
    • +
    • + +

      PlayerName :

      + +
    • +
    +
    +
    +
    +
    + DATABASE:AddUnit(DCSUnit, DCSUnitName) @@ -513,9 +497,9 @@ The following iterator methods are currently available within the DATABASE:

    - #string - -DATABASE.ClassName + + +DATABASE.CLIENTSALIVE
    @@ -527,9 +511,9 @@ The following iterator methods are currently available within the DATABASE:

    - - -DATABASE.ClientsAlive + #string + +DATABASE.ClassName
    @@ -564,6 +548,27 @@ The following iterator methods are currently available within the DATABASE:

    +
    +
    +
    +
    + + +DATABASE:DeletePlayer(PlayerName) + +
    +
    + +

    Deletes a player from the DATABASE based on the Player Name.

    + +

    Parameter

    +
      +
    • + +

      PlayerName :

      + +
    • +
    @@ -585,34 +590,6 @@ The following iterator methods are currently available within the DATABASE:

    -
    -
    -
    -
    - - - -DATABASE.Filter - -
    -
    - - - -
    -
    -
    -
    - - - -DATABASE.FilterMeta - -
    -
    - - -
    @@ -702,7 +679,7 @@ The found Unit.

    -

    Interate the DATABASE and call an interator function for the given set, providing the Object for each element within the set and optional parameters.

    +

    Iterate the DATABASE and call an iterator function for the given set, providing the Object for each element within the set and optional parameters.

    Parameters

      @@ -739,7 +716,7 @@ self

    -

    Interate the DATABASE and call an interator function for each client, providing the Client to the function and optional parameters.

    +

    Iterate the DATABASE and call an iterator function for each CLIENT, providing the CLIENT to the function and optional parameters.

    Parameters

      @@ -765,20 +742,84 @@ self

      - -DATABASE:ForEachDCSUnit(IteratorFunction, ...) + +DATABASE:ForEachClientAlive(IteratorFunction, ...)
      -

      Interate the DATABASE and call an interator function for each alive unit, providing the Unit and optional parameters.

      +

      Iterate the DATABASE and call an iterator function for each ALIVE CLIENT, providing the CLIENT to the function and optional parameters.

      Parameters

      • #function IteratorFunction : -The function that will be called when there is an alive unit in the database. The function needs to accept a UNIT parameter.

        +The function that will be called when there is an alive CLIENT in the database. The function needs to accept a CLIENT parameter.

        + +
      • +
      • + +

        ... :

        + +
      • +
      +

      Return value

      + +

      #DATABASE: +self

      + +
      +
      +
      +
      + + +DATABASE:ForEachDCSUnit(IteratorFunction, ...) + +
      +
      + +

      Iterate the DATABASE and call an iterator function for each alive unit, providing the DCSUnit and optional parameters.

      + +

      Parameters

      +
        +
      • + +

        #function IteratorFunction : +The function that will be called when there is an alive unit in the database. The function needs to accept a DCSUnit parameter.

        + +
      • +
      • + +

        ... :

        + +
      • +
      +

      Return value

      + +

      #DATABASE: +self

      + +
      +
      +
      +
      + + +DATABASE:ForEachGroup(IteratorFunction, ...) + +
      +
      + +

      Iterate the DATABASE and call an iterator function for each alive GROUP, providing the GROUP and optional parameters.

      + +

      Parameters

      +
        +
      • + +

        #function IteratorFunction : +The function that will be called when there is an alive GROUP in the database. The function needs to accept a GROUP parameter.

      • @@ -803,7 +844,39 @@ self

        -

        Interate the DATABASE and call an interator function for each alive player, providing the Unit of the player and optional parameters.

        +

        Iterate the DATABASE and call an iterator function for each player, providing the player name and optional parameters.

        + +

        Parameters

        +
          +
        • + +

          #function IteratorFunction : +The function that will be called when there is an player in the database. The function needs to accept the player name.

          + +
        • +
        • + +

          ... :

          + +
        • +
        +

        Return value

        + +

        #DATABASE: +self

        + +
        +
      +
      +
      + + +DATABASE:ForEachPlayerAlive(IteratorFunction, ...) + +
      +
      + +

      Iterate the DATABASE and call an iterator function for each alive player, providing the Unit of the player and optional parameters.

      Parameters

        @@ -824,6 +897,38 @@ The function that will be called when there is an alive player in the database.

        #DATABASE: self

        +
      +
      +
      +
      + + +DATABASE:ForEachUnit(IteratorFunction, ...) + +
      +
      + +

      Iterate the DATABASE and call an iterator function for each alive UNIT, providing the UNIT and optional parameters.

      + +

      Parameters

      +
        +
      • + +

        #function IteratorFunction : +The function that will be called when there is an alive UNIT in the database. The function needs to accept a UNIT parameter.

        + +
      • +
      • + +

        ... :

        + +
      • +
      +

      Return value

      + +

      #DATABASE: +self

      +
      @@ -901,8 +1006,8 @@ DBObject = DATABASE:New()
      - -DATABASE.Players + +DATABASE.PLAYERS
      @@ -915,21 +1020,8 @@ DBObject = DATABASE:New()
      - -DATABASE.PlayersAlive - -
      -
      - - - -
      -
      -
      -
      - - -DATABASE:ScanEnvironment() + +DATABASE.PLAYERSALIVE
      @@ -993,20 +1085,6 @@ This method is used by the SPAWN class.

      #DATABASE: self

      -
      -
      -
      -
      - - - -DATABASE.Statics - -
      -
      - - -
      @@ -1021,27 +1099,6 @@ self

      -
    -
    -
    -
    - - -DATABASE:TraceDatabase() - -
    -
    - -

    Traces the current database contents in the log ...

    - - -

    (for debug reasons).

    - -

    Return value

    - -

    #DATABASE: -self

    -
    @@ -1145,84 +1202,6 @@ self

    - -DATABASE:_IsAliveDCSGroup(DCSGroup) - -
    -
    - - - -

    Parameter

    - -

    Return value

    - -

    #DATABASE: -self

    - -
    -
    -
    -
    - - -DATABASE:_IsAliveDCSUnit(DCSUnit) - -
    -
    - - - -

    Parameter

    - -

    Return value

    - -

    #DATABASE: -self

    - -
    -
    -
    -
    - - -DATABASE:_IsIncludeDCSUnit(DCSUnit) - -
    -
    - - - -

    Parameter

    - -

    Return value

    - -

    #DATABASE: -self

    - -
    -
    -
    -
    - DATABASE:_RegisterDatabase() @@ -1241,32 +1220,6 @@ self

    - -DATABASE:_RegisterGroup(GroupTemplate) - -
    -
    - -

    Private method that registers new Group Templates within the DATABASE Object.

    - -

    Parameter

    -
      -
    • - -

      #table GroupTemplate :

      - -
    • -
    -

    Return value

    - -

    #DATABASE: -self

    - -
    -
    -
    -
    - DATABASE:_RegisterPlayers() @@ -1280,6 +1233,45 @@ self

    #DATABASE: self

    +
    + +
    +
    + + +DATABASE:_RegisterTemplate(GroupTemplate) + +
    +
    + +

    Private method that registers new Group Templates within the DATABASE Object.

    + +

    Parameter

    + +

    Return value

    + +

    #DATABASE: +self

    + +
    +
    +
    +
    + + +DATABASE:_RegisterTemplates() + +
    +
    + + +
    diff --git a/Moose Training/Documentation/Escort.html b/Moose Training/Documentation/Escort.html index 6da80cd1e..040d46ca3 100644 --- a/Moose Training/Documentation/Escort.html +++ b/Moose Training/Documentation/Escort.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • @@ -1859,6 +1861,9 @@ self

    + +

    self.ReportTargetsScheduler = routines.scheduleFunction( self._ReportTargetsScheduler, { self }, timer.getTime() + 1, Seconds )

    +
    diff --git a/Moose Training/Documentation/Event.html b/Moose Training/Documentation/Event.html index 153c8cb07..1591464a5 100644 --- a/Moose Training/Documentation/Event.html +++ b/Moose Training/Documentation/Event.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/GOHOMETASK.html b/Moose Training/Documentation/GOHOMETASK.html index 3a3adccd4..be69f3990 100644 --- a/Moose Training/Documentation/GOHOMETASK.html +++ b/Moose Training/Documentation/GOHOMETASK.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/Group.html b/Moose Training/Documentation/Group.html index cfbc60f20..4e957bb03 100644 --- a/Moose Training/Documentation/Group.html +++ b/Moose Training/Documentation/Group.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • @@ -212,6 +214,12 @@ If the DCS Group object does not exist or is nil, the GROUP methods will return GROUP:GetCoalition()

    Returns the coalition of the DCS Group.

    + + + + GROUP:GetCountry() + +

    Returns the country of the DCS Group.

    @@ -1068,6 +1076,34 @@ The coalition side of the DCS Group.

    + +GROUP:GetCountry() + +
    +
    + +

    Returns the country of the DCS Group.

    + +

    Return values

    +
      +
    1. + +

      DCScountry#country.id: +The country identifier.

      + +
    2. +
    3. + +

      #nil: +The DCS Group is not existing or alive.

      + +
    4. +
    +
    +
    +
    +
    + GROUP:GetDCSGroup() diff --git a/Moose Training/Documentation/GroupSet.html b/Moose Training/Documentation/GroupSet.html new file mode 100644 index 000000000..140e7e19a --- /dev/null +++ b/Moose Training/Documentation/GroupSet.html @@ -0,0 +1,644 @@ + + + + + + +
    +
    + +
    +
    +
    +
    + +
    +

    Module GroupSet

    + +

    Create and manage a set of groups.

    + + + +

    #GROUPSET class

    +

    Mission designers can use the GROUPSET class to build sets of groups belonging to certain:

    + +
      +
    • Coalitions
    • +
    • Categories
    • +
    • Countries
    • +
    • Starting with certain prefix strings.
    • +
    + +

    GROUPSET construction methods:

    +

    Create a new GROUPSET object with the GROUPSET.New method:

    + + + + +

    GROUPSET filter criteria:

    +

    You can set filter criteria to define the set of groups within the GROUPSET. +Filter criteria are defined by:

    + + + +

    Once the filter criteria have been set for the GROUPSET, you can start filtering using:

    + + + +

    Planned filter criteria within development are (so these are not yet available):

    + + + + +

    GROUPSET iterators:

    +

    Once the filters have been defined and the GROUPSET has been built, you can iterate the GROUPSET with the available iterator methods. +The iterator methods will walk the GROUPSET set, and call for each element within the set a function that you provide. +The following iterator methods are currently available within the GROUPSET:

    + + + +

    Planned iterators methods in development are (so these are not yet available):

    + + + + +

    Global(s)

    + + + + + +
    GROUPSET + +
    +

    Type GROUPSET

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    GROUPSET:AddInDatabase(Event) +

    Handles the Database to check on an event (birth) that the Object was added in the Database.

    +
    GROUPSET.ClassName + +
    GROUPSET.Filter + +
    GROUPSET:FilterCategories(Categories) +

    Builds a set of groups out of categories.

    +
    GROUPSET:FilterCoalitions(Coalitions) +

    Builds a set of groups of coalitions.

    +
    GROUPSET:FilterCountries(Countries) +

    Builds a set of groups of defined countries.

    +
    GROUPSET.FilterMeta + +
    GROUPSET:FilterPrefixes(Prefixes) +

    Builds a set of groups of defined unit prefixes.

    +
    GROUPSET:FilterStart() +

    Starts the filtering.

    +
    GROUPSET:FindInDatabase(Event) +

    Handles the Database to check on any event that Object exists in the Database.

    +
    GROUPSET:FindUnit(GroupName) +

    Finds a Unit based on the Unit Name.

    +
    GROUPSET:ForEachUnit(IteratorFunction, ...) +

    Interate the GROUPSET and call an interator function for each alive GROUP, providing the GROUP and optional parameters.

    +
    GROUPSET:IsIncludeObject(MooseGroup) + +
    GROUPSET:New() +

    Creates a new GROUPSET object, building a set of groups belonging to a coalitions, categories, countries, types or with defined prefix names.

    +
    GROUPSET.Units + +
    + +

    Global(s)

    +
    +
    + + #GROUPSET + +GROUPSET + +
    +
    + + + +
    +
    +

    Type GroupSet

    + +

    Type GROUPSET

    + +

    GROUPSET class

    + +

    Field(s)

    +
    +
    + + +GROUPSET:AddInDatabase(Event) + +
    +
    + +

    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!

    + +

    Parameter

    + +

    Return values

    +
      +
    1. + +

      #string: +The name of the GROUP

      + +
    2. +
    3. + +

      #table: +The GROUP

      + +
    4. +
    +
    +
    +
    +
    + + #string + +GROUPSET.ClassName + +
    +
    + + + +
    +
    +
    +
    + + + +GROUPSET.Filter + +
    +
    + + + +
    +
    +
    +
    + + +GROUPSET:FilterCategories(Categories) + +
    +
    + +

    Builds a set of groups out of categories.

    + + +

    Possible current categories are plane, helicopter, ground, ship.

    + +

    Parameter

    +
      +
    • + +

      #string Categories : +Can take the following values: "plane", "helicopter", "ground", "ship".

      + +
    • +
    +

    Return value

    + +

    #GROUPSET: +self

    + +
    +
    +
    +
    + + +GROUPSET:FilterCoalitions(Coalitions) + +
    +
    + +

    Builds a set of groups of coalitions.

    + + +

    Possible current coalitions are red, blue and neutral.

    + +

    Parameter

    +
      +
    • + +

      #string Coalitions : +Can take the following values: "red", "blue", "neutral".

      + +
    • +
    +

    Return value

    + +

    #GROUPSET: +self

    + +
    +
    +
    +
    + + +GROUPSET:FilterCountries(Countries) + +
    +
    + +

    Builds a set of groups of defined countries.

    + + +

    Possible current countries are those known within DCS world.

    + +

    Parameter

    +
      +
    • + +

      #string Countries : +Can take those country strings known within DCS world.

      + +
    • +
    +

    Return value

    + +

    #GROUPSET: +self

    + +
    +
    +
    +
    + + + +GROUPSET.FilterMeta + +
    +
    + + + +
    +
    +
    +
    + + +GROUPSET:FilterPrefixes(Prefixes) + +
    +
    + +

    Builds a set of groups of defined unit prefixes.

    + + +

    All the groups starting with the given prefixes will be included within the set.

    + +

    Parameter

    +
      +
    • + +

      #string Prefixes : +The prefix of which the group name starts with.

      + +
    • +
    +

    Return value

    + +

    #GROUPSET: +self

    + +
    +
    +
    +
    + + +GROUPSET:FilterStart() + +
    +
    + +

    Starts the filtering.

    + +

    Return value

    + +

    #GROUPSET: +self

    + +
    +
    +
    +
    + + +GROUPSET:FindInDatabase(Event) + +
    +
    + +

    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!

    + +

    Parameter

    + +

    Return values

    +
      +
    1. + +

      #string: +The name of the GROUP

      + +
    2. +
    3. + +

      #table: +The GROUP

      + +
    4. +
    +
    +
    +
    +
    + + +GROUPSET:FindUnit(GroupName) + +
    +
    + +

    Finds a Unit based on the Unit Name.

    + +

    Parameter

    +
      +
    • + +

      #string GroupName :

      + +
    • +
    +

    Return value

    + +

    Group#GROUP: +The found Unit.

    + +
    +
    +
    +
    + + +GROUPSET:ForEachUnit(IteratorFunction, ...) + +
    +
    + +

    Interate the GROUPSET and call an interator function for each alive GROUP, providing the GROUP and optional parameters.

    + +

    Parameters

    +
      +
    • + +

      #function IteratorFunction : +The function that will be called when there is an alive GROUP in the GROUPSET. The function needs to accept a GROUP parameter.

      + +
    • +
    • + +

      ... :

      + +
    • +
    +

    Return value

    + +

    #GROUPSET: +self

    + +
    +
    +
    +
    + + +GROUPSET:IsIncludeObject(MooseGroup) + +
    +
    + + + +

    Parameter

    + +

    Return value

    + +

    #GROUPSET: +self

    + +
    +
    +
    +
    + + +GROUPSET:New() + +
    +
    + +

    Creates a new GROUPSET object, building a set of groups belonging to a coalitions, categories, countries, types or with defined prefix names.

    + +

    Return value

    + +

    #GROUPSET:

    + + +

    Usage:

    +
    -- Define a new GROUPSET Object. This DBObject will contain a reference to all alive GROUPS.
    +DBObject = GROUPSET:New()
    + +
    +
    +
    +
    + + + +GROUPSET.Units + +
    +
    + + + +
    +
    + +
    + +
    + + diff --git a/Moose Training/Documentation/MISSION.html b/Moose Training/Documentation/MISSION.html index 0e909bbc5..785f9854a 100644 --- a/Moose Training/Documentation/MISSION.html +++ b/Moose Training/Documentation/MISSION.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • @@ -66,7 +68,7 @@
    -

    Module MISSION

    +

    Module Mission

    A MISSION is the main owner of a Mission orchestration within MOOSE .

    @@ -86,12 +88,6 @@ A CLIENT needs to be registered within the MISSIONSCHEDULER - - - - TaskComplete - - @@ -101,8 +97,8 @@ A CLIENT needs to be registered within the Type MISSION - +

    Type MISSION

    +
    + + + + @@ -466,24 +468,6 @@ A CLIENT needs to be registered within the -
    - - #boolean - -TaskComplete - -
    -
    - - - - -

    For each Client, check for each Task the state and evolve the mission. - This flag will indicate if the Task of the Client is Complete.

    -
    @@ -511,8 +495,13 @@ A CLIENT needs to be registered within the Type MISSION -

    Field(s)

    +

    Type Mission

    + +

    Type MISSION

    + +

    The MISSION class

    + +

    Field(s)

    @@ -550,10 +539,10 @@ Client is the CLIENT object. The object must have been

    Usage:

    Add a number of Client objects to the Mission.
    -	Mission:AddClient( CLIENT:New( 'US UH-1H*HOT-Deploy Troops 1', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
    -	Mission:AddClient( CLIENT:New( 'US UH-1H*RAMP-Deploy Troops 3', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
    -	Mission:AddClient( CLIENT:New( 'US UH-1H*HOT-Deploy Troops 2', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
    -	Mission:AddClient( CLIENT:New( 'US UH-1H*RAMP-Deploy Troops 4', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
    + Mission:AddClient( CLIENT:FindByName( 'US UH-1H*HOT-Deploy Troops 1', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() ) + Mission:AddClient( CLIENT:FindByName( 'US UH-1H*RAMP-Deploy Troops 3', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() ) + Mission:AddClient( CLIENT:FindByName( 'US UH-1H*HOT-Deploy Troops 2', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() ) + Mission:AddClient( CLIENT:FindByName( 'US UH-1H*RAMP-Deploy Troops 4', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
    @@ -885,6 +874,20 @@ env.info( "Task 2 Completion = " .. Tasks[2]:GetGoalPercentage() .. "%" ) + +
    +
    +
    + + #string + +MISSION.MissionBriefing + +
    +
    + + +
    @@ -1197,7 +1200,7 @@ local Mission = MISSIONSCHEDULER.AddMission( 'Rescue secret agent', 'Tactical',
    - + #MISSION.Clients MISSION._Clients @@ -1237,6 +1240,8 @@ local Mission = MISSIONSCHEDULER.AddMission( 'Rescue secret agent', 'Tactical',
    +

    Type MISSION.Clients

    +

    Type MISSIONSCHEDULER

    The MISSIONSCHEDULER is an OBJECT and is the main scheduler of ALL active MISSIONs registered within this scheduler.

    @@ -1339,7 +1344,7 @@ MissionFind = MISSIONSCHEDULER:FindMission( 'Russia Transport Troops SA-6' )
    - + #MISSIONSCHEDULER.MISSIONS MISSIONSCHEDULER.Missions @@ -1491,6 +1496,9 @@ MISSIONSCHEDULER:RemoveMission( 'Russia Transport Troops SA-6' ) + +

    MISSIONSCHEDULER.SchedulerId = routines.scheduleFunction( MISSIONSCHEDULER.Scheduler, { }, 0, 2 )

    +
    @@ -1628,6 +1636,8 @@ MISSIONSCHEDULER:RemoveMission( 'Russia Transport Troops SA-6' )
    +

    Type MISSIONSCHEDULER.MISSIONS

    + diff --git a/Moose Training/Documentation/MOVEMENT.html b/Moose Training/Documentation/MOVEMENT.html index 5d35d954c..ef93fb7c1 100644 --- a/Moose Training/Documentation/MOVEMENT.html +++ b/Moose Training/Documentation/MOVEMENT.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/Menu.html b/Moose Training/Documentation/Menu.html index 286cd3f1f..7086e16b5 100644 --- a/Moose Training/Documentation/Menu.html +++ b/Moose Training/Documentation/Menu.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/Message.html b/Moose Training/Documentation/Message.html index e7fb13b06..5b3fd432f 100644 --- a/Moose Training/Documentation/Message.html +++ b/Moose Training/Documentation/Message.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/MissileTrainer.html b/Moose Training/Documentation/MissileTrainer.html index 8e21f7b5b..10678955f 100644 --- a/Moose Training/Documentation/MissileTrainer.html +++ b/Moose Training/Documentation/MissileTrainer.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/NOTASK.html b/Moose Training/Documentation/NOTASK.html index 8aeb474b4..66d88c1ba 100644 --- a/Moose Training/Documentation/NOTASK.html +++ b/Moose Training/Documentation/NOTASK.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/PICKUPTASK.html b/Moose Training/Documentation/PICKUPTASK.html index 079600693..50e1e220d 100644 --- a/Moose Training/Documentation/PICKUPTASK.html +++ b/Moose Training/Documentation/PICKUPTASK.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/ROUTETASK.html b/Moose Training/Documentation/ROUTETASK.html index b53f143b3..efd64169e 100644 --- a/Moose Training/Documentation/ROUTETASK.html +++ b/Moose Training/Documentation/ROUTETASK.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/STAGE.html b/Moose Training/Documentation/STAGE.html index c45a68326..a4476cf94 100644 --- a/Moose Training/Documentation/STAGE.html +++ b/Moose Training/Documentation/STAGE.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • @@ -274,6 +276,16 @@ + +
    MISSION.AddClient(CLIENT, self, Client) @@ -197,6 +193,12 @@ A CLIENT needs to be registered within the MISSION:Meta() +
    MISSION.MissionBriefing +
    STAGE.WaitTime +
    + +

    Type STAGEBRIEF

    + + + +
    STAGEBRIEF.StageBriefingTime +
    @@ -809,6 +821,23 @@

    Type STAGEARRIVE

    +

    Type STAGEBRIEF

    +

    Field(s)

    +
    +
    + + + +STAGEBRIEF.StageBriefingTime + +
    +
    + + + +
    +
    +

    Type STAGELANDING

    Type STAGEROUTE

    diff --git a/Moose Training/Documentation/Scheduler.html b/Moose Training/Documentation/Scheduler.html index 0b09abf54..59557d5cf 100644 --- a/Moose Training/Documentation/Scheduler.html +++ b/Moose Training/Documentation/Scheduler.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • @@ -91,8 +93,6 @@ - -

    Global(s)

    @@ -120,12 +120,6 @@ - - - - @@ -138,6 +132,12 @@ + + + +
    SCHEDULER.Repeat -
    SCHEDULER:Scheduler() -
    SCHEDULER:Stop()

    Stops the scheduler.

    +
    SCHEDULER:_Scheduler() +
    @@ -253,19 +253,6 @@ self

    - -
    -
    -
    - - -SCHEDULER:Scheduler() - -
    -
    - - -
    @@ -302,6 +289,19 @@ self

    #SCHEDULER: self

    + +
    +
    +
    + + +SCHEDULER:_Scheduler() + +
    +
    + + +
    diff --git a/Moose Training/Documentation/Scoring.html b/Moose Training/Documentation/Scoring.html index bcecc4626..199f2d13d 100644 --- a/Moose Training/Documentation/Scoring.html +++ b/Moose Training/Documentation/Scoring.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/Sead.html b/Moose Training/Documentation/Sead.html index e8bf12d86..68a532b60 100644 --- a/Moose Training/Documentation/Sead.html +++ b/Moose Training/Documentation/Sead.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • diff --git a/Moose Training/Documentation/Set.html b/Moose Training/Documentation/Set.html index e43329a31..5d11030b7 100644 --- a/Moose Training/Documentation/Set.html +++ b/Moose Training/Documentation/Set.html @@ -42,11 +42,12 @@
  • Event
  • GOHOMETASK
  • Group
  • -
  • MISSION
  • +
  • GroupSet
  • MOVEMENT
  • Menu
  • Message
  • MissileTrainer
  • +
  • Mission
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • @@ -59,6 +60,7 @@
  • StaticObject
  • TASK
  • Unit
  • +
  • UnitSet
  • Zone
  • env
  • land
  • @@ -154,111 +156,21 @@ The following iterator methods are currently available within the SET:

    Type SET

    - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -268,99 +180,33 @@ The following iterator methods are currently available within the SET:

    - + - - - - - - - - - - - - - - - - - - - - - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - @@ -370,45 +216,15 @@ The following iterator methods are currently available within the SET:

    - + - + - - - - - - - - - - - - - - - - - - - -
    SET:AddUnit(UnitToAdd) -

    Finds a Unit based on the Unit Name.

    -
    SET.ClassName
    SET.ClientsSET.Database
    SET.ClientsAliveSET:Flush() - -
    SET.DCSGroups - -
    SET.DCSGroupsAlive - -
    SET.DCSUnits - -
    SET.DCSUnitsAlive - -
    SET.Filter - -
    SET:FilterCategories(Categories) -

    Builds a set of units out of categories.

    -
    SET:FilterCoalitions(Coalitions) -

    Builds a set of units of coalitons.

    -
    SET:FilterCountries(Countries) -

    Builds a set of units of defined countries.

    -
    SET:FilterGroupPrefixes(Prefixes) -

    Builds a set of units of defined group prefixes.

    -
    SET.FilterMeta - -
    SET:FilterStart() -

    Starts the filtering.

    -
    SET:FilterTypes(Types) -

    Builds a set of units of defined unit types.

    -
    SET:FilterUnitPrefixes(Prefixes) -

    Builds a set of units of defined unit prefixes.

    -
    SET:FindUnit(UnitName) -

    Finds a Unit based on the Unit Name.

    +

    Flushes the current SET contents in the log ...

    SET:ForEachClient(IteratorFunction, ...)SET:IsIncludeObject(Object) -

    Interate the SET and call an interator function for each client, providing the Client to the function and optional parameters.

    +

    Decides whether to include the Object

    SET:ForEachDCSUnitAlive(IteratorFunction, ...) -

    Interate the SET and call an interator function for each alive unit, providing the Unit and optional parameters.

    -
    SET:ForEachPlayer(IteratorFunction, ...) -

    Interate the SET and call an interator function for each alive player, providing the Unit of the player and optional parameters.

    -
    SET.Groups - -
    SET.GroupsAlive - -
    SET.NavPoints - -
    SET:New()SET:New(Database)

    Creates a new SET object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.

    SET.PlayersSET.Set
    SET.PlayersAliveSET:_Add(ObjectName, Object) - -
    SET:ScanEnvironment() - -
    SET.Statics - -
    SET.Templates - -
    SET:TraceDatabase() -

    Traces the current SET contents in the log ...

    -
    SET.Units - -
    SET.UnitsAlive - +

    Adds a Object based on the Object Name.

    SET:_EventOnBirth(Event) -

    Handles the OnBirth event for the alive units set.

    +

    Handles the OnBirth event for the Set.

    SET:_EventOnPlayerEnterUnit(Event)SET:_FilterStart() -

    Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied).

    +

    Starts the filtering for the defined collection.

    SET:_EventOnPlayerLeaveUnit(Event)SET:_Find(ObjectName) -

    Handles the OnPlayerLeaveUnit event to clean the active players table.

    -
    SET:_IsAliveDCSGroup(DCSGroup) - -
    SET:_IsAliveDCSUnit(DCSUnit) - -
    SET:_IsIncludeDCSUnit(DCSUnit) - -
    SET:_RegisterDatabase() -

    Private method that registers all datapoints within in the mission.

    -
    SET:_RegisterPlayers() -

    Private method that registers all alive players in the mission.

    +

    Finds an Object based on the Object Name.

    @@ -438,32 +254,6 @@ The following iterator methods are currently available within the SET:

    - -SET:AddUnit(UnitToAdd) - -
    -
    - -

    Finds a Unit based on the Unit Name.

    - -

    Parameter

    - -

    Return value

    - -

    Unit#UNIT: -The added Unit.

    - -
    -
    -
    -
    - #string SET.ClassName @@ -479,8 +269,8 @@ The added Unit.

    - -SET.Clients + +SET.Database
    @@ -492,322 +282,21 @@ The added Unit.

    - - -SET.ClientsAlive + +SET:Flush()
    - - -
    -
    -
    -
    - - - -SET.DCSGroups - -
    -
    - - - -
    -
    -
    -
    - - - -SET.DCSGroupsAlive - -
    -
    - - - -
    -
    -
    -
    - - - -SET.DCSUnits - -
    -
    - - - -
    -
    -
    -
    - - - -SET.DCSUnitsAlive - -
    -
    - - - -
    -
    -
    -
    - - - -SET.Filter - -
    -
    - - - -
    -
    -
    -
    - - -SET:FilterCategories(Categories) - -
    -
    - -

    Builds a set of units out of categories.

    +

    Flushes the current SET contents in the log ...

    -

    Possible current categories are plane, helicopter, ground, ship.

    - -

    Parameter

    -
      -
    • - -

      #string Categories : -Can take the following values: "plane", "helicopter", "ground", "ship".

      - -
    • -
    -

    Return value

    - -

    #SET: -self

    - -
    -
    -
    -
    - - -SET:FilterCoalitions(Coalitions) - -
    -
    - -

    Builds a set of units of coalitons.

    - - -

    Possible current coalitions are red, blue and neutral.

    - -

    Parameter

    -
      -
    • - -

      #string Coalitions : -Can take the following values: "red", "blue", "neutral".

      - -
    • -
    -

    Return value

    - -

    #SET: -self

    - -
    -
    -
    -
    - - -SET:FilterCountries(Countries) - -
    -
    - -

    Builds a set of units of defined countries.

    - - -

    Possible current countries are those known within DCS world.

    - -

    Parameter

    -
      -
    • - -

      #string Countries : -Can take those country strings known within DCS world.

      - -
    • -
    -

    Return value

    - -

    #SET: -self

    - -
    -
    -
    -
    - - -SET:FilterGroupPrefixes(Prefixes) - -
    -
    - -

    Builds a set of units of defined group prefixes.

    - - -

    All the units starting with the given group prefixes will be included within the set.

    - -

    Parameter

    -
      -
    • - -

      #string Prefixes : -The prefix of which the group name where the unit belongs to starts with.

      - -
    • -
    -

    Return value

    - -

    #SET: -self

    - -
    -
    -
    -
    - - - -SET.FilterMeta - -
    -
    - - - -
    -
    -
    -
    - - -SET:FilterStart() - -
    -
    - -

    Starts the filtering.

    +

    (for debug reasons).

    Return value

    -

    #SET: -self

    - -
    -
    -
    -
    - - -SET:FilterTypes(Types) - -
    -
    - -

    Builds a set of units of defined unit types.

    - - -

    Possible current types are those types known within DCS world.

    - -

    Parameter

    -
      -
    • - -

      #string Types : -Can take those type strings known within DCS world.

      - -
    • -
    -

    Return value

    - -

    #SET: -self

    - -
    -
    -
    -
    - - -SET:FilterUnitPrefixes(Prefixes) - -
    -
    - -

    Builds a set of units of defined unit prefixes.

    - - -

    All the units starting with the given prefixes will be included within the set.

    - -

    Parameter

    -
      -
    • - -

      #string Prefixes : -The prefix of which the unit name starts with.

      - -
    • -
    -

    Return value

    - -

    #SET: -self

    - -
    -
    -
    -
    - - -SET:FindUnit(UnitName) - -
    -
    - -

    Finds a Unit based on the Unit Name.

    - -

    Parameter

    -
      -
    • - -

      #string UnitName :

      - -
    • -
    -

    Return value

    - -

    Unit#UNIT: -The found Unit.

    +

    #string: +A string with the names of the objects.

    @@ -851,25 +340,19 @@ self

    - -SET:ForEachClient(IteratorFunction, ...) + +SET:IsIncludeObject(Object)
    -

    Interate the SET and call an interator function for each client, providing the Client to the function and optional parameters.

    +

    Decides whether to include the Object

    -

    Parameters

    +

    Parameter

    • -

      #function IteratorFunction : -The function that will be called when there is an alive player in the SET. The function needs to accept a CLIENT parameter.

      - -
    • -
    • - -

      ... :

      +

      #table Object :

    @@ -878,125 +361,27 @@ The function that will be called when there is an alive player in the SET. The f

    #SET: self

    -
    -
    -
    -
    - - -SET:ForEachDCSUnitAlive(IteratorFunction, ...) - -
    -
    - -

    Interate the SET and call an interator function for each alive unit, providing the Unit and optional parameters.

    - -

    Parameters

    -
      -
    • - -

      #function IteratorFunction : -The function that will be called when there is an alive unit in the SET. The function needs to accept a UNIT parameter.

      - -
    • -
    • - -

      ... :

      - -
    • -
    -

    Return value

    - -

    #SET: -self

    - -
    -
    -
    -
    - - -SET:ForEachPlayer(IteratorFunction, ...) - -
    -
    - -

    Interate the SET and call an interator function for each alive player, providing the Unit of the player and optional parameters.

    - -

    Parameters

    -
      -
    • - -

      #function IteratorFunction : -The function that will be called when there is an alive player in the SET. The function needs to accept a UNIT parameter.

      - -
    • -
    • - -

      ... :

      - -
    • -
    -

    Return value

    - -

    #SET: -self

    - -
    -
    -
    -
    - - - -SET.Groups - -
    -
    - - - -
    -
    -
    -
    - - - -SET.GroupsAlive - -
    -
    - - - -
    -
    -
    -
    - - - -SET.NavPoints - -
    -
    - - -
    -SET:New() +SET:New(Database)

    Creates a new SET object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.

    +

    Parameter

    +
      +
    • + +

      Database :

      + +
    • +

    Return value

    #SET:

    @@ -1012,8 +397,8 @@ DBObject = SET:New()
    - -SET.Players + +SET.Set
    @@ -1025,104 +410,31 @@ DBObject = SET:New()
    - - -SET.PlayersAlive + +SET:_Add(ObjectName, Object)
    +

    Adds a Object based on the Object Name.

    +

    Parameters

    +
      +
    • + +

      #string ObjectName :

      -
    -
    -
    -
    - - -SET:ScanEnvironment() - -
    -
    - - - -
    -
    -
    -
    - - - -SET.Statics - -
    -
    - - - -
    -
    -
    -
    - - - -SET.Templates - -
    -
    - - - -
    -
    -
    -
    - - -SET:TraceDatabase() - -
    -
    - -

    Traces the current SET contents in the log ...

    - - -

    (for debug reasons).

    + +
  • + +

    #table Object :

    +
  • +

    Return value

    -

    #SET: -self

    - -
    -
    -
    -
    - - - -SET.Units - -
    -
    - - - -
    -
    -
    -
    - - - -SET.UnitsAlive - -
    -
    - - +

    #table: +The added Object.

    @@ -1135,7 +447,7 @@ self

    -

    Handles the OnBirth event for the alive units set.

    +

    Handles the OnBirth event for the Set.

    Parameter