diff --git a/Moose Development/Moose/AI/AI_Patrol.lua b/Moose Development/Moose/AI/AI_Patrol.lua index 8780b3ac0..b925325a5 100644 --- a/Moose Development/Moose/AI/AI_Patrol.lua +++ b/Moose Development/Moose/AI/AI_Patrol.lua @@ -50,11 +50,14 @@ -- -- * **None** ( Group ): The process is not started yet. -- * **Patrolling** ( Group ): The AI is patrolling the Patrol Zone. --- * **Returning** ( Group ): The AI is returning to Base.. +-- * **Returning** ( Group ): The AI is returning to Base. +-- * **Stopped** ( Group ): The process is stopped. +-- * **Crashed** ( Group ): The AI has crashed or is dead. -- -- ### 1.2.2) AI_PATROL_ZONE Events -- -- * **Start** ( Group ): Start the process. +-- * **Stop** ( Group ): Stop the process. -- * **Route** ( Group ): Route the AI to a new random 3D point within the Patrol Zone. -- * **RTB** ( Group ): Route the AI to the home base. -- * **Detect** ( Group ): The AI is detecting targets. @@ -201,6 +204,51 @@ function AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltit self:SetStartState( "None" ) + self:AddTransition( "*", "Stop", "Stopped" ) + +--- OnLeave Transition Handler for State Stopped. +-- @function [parent=#AI_PATROL_ZONE] OnLeaveStopped +-- @param #AI_PATROL_ZONE self +-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM. +-- @param #string From The From State string. +-- @param #string Event The Event string. +-- @param #string To The To State string. +-- @return #boolean Return false to cancel Transition. + +--- OnEnter Transition Handler for State Stopped. +-- @function [parent=#AI_PATROL_ZONE] OnEnterStopped +-- @param #AI_PATROL_ZONE self +-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM. +-- @param #string From The From State string. +-- @param #string Event The Event string. +-- @param #string To The To State string. + +--- OnBefore Transition Handler for Event Stop. +-- @function [parent=#AI_PATROL_ZONE] OnBeforeStop +-- @param #AI_PATROL_ZONE self +-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM. +-- @param #string From The From State string. +-- @param #string Event The Event string. +-- @param #string To The To State string. +-- @return #boolean Return false to cancel Transition. + +--- OnAfter Transition Handler for Event Stop. +-- @function [parent=#AI_PATROL_ZONE] OnAfterStop +-- @param #AI_PATROL_ZONE self +-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM. +-- @param #string From The From State string. +-- @param #string Event The Event string. +-- @param #string To The To State string. + +--- Synchronous Event Trigger for Event Stop. +-- @function [parent=#AI_PATROL_ZONE] Stop +-- @param #AI_PATROL_ZONE self + +--- Asynchronous Event Trigger for Event Stop. +-- @function [parent=#AI_PATROL_ZONE] __Stop +-- @param #AI_PATROL_ZONE self +-- @param #number Delay The delay in seconds. + self:AddTransition( "None", "Start", "Patrolling" ) --- OnBefore Transition Handler for Event Start. diff --git a/Moose Development/Moose/Core/Event.lua b/Moose Development/Moose/Core/Event.lua index 42830fee0..10aa2804e 100644 --- a/Moose Development/Moose/Core/Event.lua +++ b/Moose Development/Moose/Core/Event.lua @@ -64,6 +64,13 @@ -- -- * @{Base#BASE.HandleEvent}(): Subscribe to a DCS Event. -- * @{Base#BASE.UnHandleEvent}(): Unsubscribe from a DCS Event. +-- +-- Note that for a UNIT, the event will be handled **for that UNIT only**! +-- Note that for a GROUP, the event will be handled **for all the UNITs in that GROUP only**! +-- +-- For all objects of other classes, the subscribed events will be handled for **all UNITs within the Mission**! +-- So if a UNIT within the mission has the subscribed event for that object, +-- then the object event handler will receive the event for that UNIT! -- -- ### 1.3.2 Event Handling of DCS Events -- @@ -165,7 +172,9 @@ -- -- Hereby the change log: -- --- * 2016-02-07: Did a complete revision of the Event Handing API and underlying mechanisms. +-- * 2017-03-07: Added the correct event dispatching in case the event is subscribed by a GROUP. +-- +-- * 2017-02-07: Did a complete revision of the Event Handing API and underlying mechanisms. -- -- === -- @@ -179,10 +188,6 @@ -- -- @module Event --- TODO: Need to update the EVENTDATA documentation with IniPlayerName and TgtPlayerName --- TODO: Need to update the EVENTDATA documentation with IniObjectCategory and TgtObjectCategory - - --- The EVENT structure -- @type EVENT @@ -443,8 +448,9 @@ function EVENT:Remove( EventClass, EventID ) self.Events[EventID][EventPriority][EventClass] = nil end ---- Removes an Events entry for a Unit +--- Removes an Events entry for a UNIT. -- @param #EVENT self +-- @param #string UnitName The name of the UNIT. -- @param Core.Base#BASE EventClass The self instance of the class for which the event is. -- @param Dcs.DCSWorld#world.event EventID -- @return #EVENT.Events @@ -457,6 +463,21 @@ function EVENT:RemoveForUnit( UnitName, EventClass, EventID ) Event.IniUnit[UnitName] = nil end +--- Removes an Events entry for a GROUP. +-- @param #EVENT self +-- @param #string GroupName The name of the GROUP. +-- @param Core.Base#BASE EventClass The self instance of the class for which the event is. +-- @param Dcs.DCSWorld#world.event EventID +-- @return #EVENT.Events +function EVENT:RemoveForGroup( GroupName, EventClass, EventID ) + self:F3( { EventClass, _EVENTMETA[EventID].Text } ) + + local EventClass = EventClass + local EventPriority = EventClass:GetEventPriority() + local Event = self.Events[EventID][EventPriority][EventClass] + Event.IniGroup[GroupName] = nil +end + --- Clears all event subscriptions for a @{Base#BASE} derived object. -- @param #EVENT self -- @param Core.Base#BASE EventObject @@ -505,23 +526,43 @@ function EVENT:OnEventGeneric( EventFunction, EventClass, EventID ) end ---- Set a new listener for an S_EVENT_X event +--- Set a new listener for an S_EVENT_X event for a UNIT. -- @param #EVENT self --- @param #string EventDCSUnitName --- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param #string UnitName The name of the UNIT. +-- @param #function EventFunction The function to be called when the event occurs for the GROUP. -- @param Core.Base#BASE EventClass The self instance of the class for which the event is. -- @param EventID -- @return #EVENT -function EVENT:OnEventForUnit( EventDCSUnitName, EventFunction, EventClass, EventID ) - self:F2( EventDCSUnitName ) +function EVENT:OnEventForUnit( UnitName, EventFunction, EventClass, EventID ) + self:F2( UnitName ) local Event = self:Init( EventID, EventClass ) if not Event.IniUnit then Event.IniUnit = {} end - Event.IniUnit[EventDCSUnitName] = {} - Event.IniUnit[EventDCSUnitName].EventFunction = EventFunction - Event.IniUnit[EventDCSUnitName].EventClass = EventClass + Event.IniUnit[UnitName] = {} + Event.IniUnit[UnitName].EventFunction = EventFunction + Event.IniUnit[UnitName].EventClass = EventClass + return self +end + +--- Set a new listener for an S_EVENT_X event for a GROUP. +-- @param #EVENT self +-- @param #string GroupName The name of the GROUP. +-- @param #function EventFunction The function to be called when the event occurs for the GROUP. +-- @param Core.Base#BASE EventClass The self instance of the class for which the event is. +-- @param EventID +-- @return #EVENT +function EVENT:OnEventForGroup( GroupName, EventFunction, EventClass, EventID ) + self:F2( GroupName ) + + local Event = self:Init( EventID, EventClass ) + if not Event.IniGroup then + Event.IniGroup = {} + end + Event.IniGroup[GroupName] = {} + Event.IniGroup[GroupName].EventFunction = EventFunction + Event.IniGroup[GroupName].EventClass = EventClass return self end @@ -1084,7 +1125,9 @@ function EVENT:onEvent( Event ) if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then Event.IniDCSGroupName = Event.IniDCSGroup:getName() Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) - self:E( { IniGroup = Event.IniGroup } ) + if Event.IniGroup then + Event.IniGroupName = Event.IniDCSGroupName + end end Event.IniPlayerName = Event.IniDCSUnit:getPlayerName() Event.IniCoalition = Event.IniDCSUnit:getCoalition() @@ -1125,6 +1168,10 @@ function EVENT:onEvent( Event ) Event.TgtDCSGroupName = "" if Event.TgtDCSGroup and Event.TgtDCSGroup:isExist() then Event.TgtDCSGroupName = Event.TgtDCSGroup:getName() + Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName ) + if Event.TgtGroup then + Event.TgtGroupName = Event.TgtDCSGroupName + end end Event.TgtPlayerName = Event.TgtDCSUnit:getPlayerName() Event.TgtCoalition = Event.TgtDCSUnit:getCoalition() @@ -1170,6 +1217,8 @@ function EVENT:onEvent( Event ) -- Okay, we got the event from DCS. Now loop the SORTED self.EventSorted[] table for the received Event.id, and for each EventData registered, check if a function needs to be called. for EventClass, EventData in pairs( self.Events[Event.id][EventPriority] ) do + + Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) -- If the EventData is for a UNIT, the call directly the EventClass EventFunction for that UNIT. if Event.IniDCSUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniDCSUnitName] then @@ -1177,8 +1226,7 @@ function EVENT:onEvent( Event ) -- First test if a EventFunction is Set, otherwise search for the default function if EventData.IniUnit[Event.IniDCSUnitName].EventFunction then - self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } ) - Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) + self:E( { "Calling EventFunction for UNIT ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } ) local Result, Value = xpcall( function() @@ -1193,7 +1241,6 @@ function EVENT:onEvent( Event ) -- Now call the default event function. self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } ) - Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) local Result, Value = xpcall( function() @@ -1204,38 +1251,69 @@ function EVENT:onEvent( Event ) end else - - -- If the EventData is not bound to a specific unit, then call the EventClass EventFunction. - -- Note that here the EventFunction will need to implement and determine the logic for the relevant source- or target unit, or weapon. - if Event.IniDCSUnit and not EventData.IniUnit then + + -- If the EventData is for a GROUP, the call directly the EventClass EventFunction for the UNIT in that GROUP. + if Event.IniDCSUnitName and Event.IniDCSGroupName and Event.IniGroupName and EventData.IniGroup and EventData.IniGroup[Event.IniGroupName] then + + -- First test if a EventFunction is Set, otherwise search for the default function + if EventData.IniGroup[Event.IniGroupName].EventFunction then - if EventClass == EventData.EventClass then + self:E( { "Calling EventFunction for GROUP ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } ) - -- First test if a EventFunction is Set, otherwise search for the default function - if EventData.EventFunction then + local Result, Value = xpcall( + function() + return EventData.IniGroup[Event.IniGroupName].EventFunction( EventClass, Event ) + end, ErrorHandler ) + + else + + -- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object. + local EventFunction = EventClass[ _EVENTMETA[Event.id].Event ] + if EventFunction and type( EventFunction ) == "function" then + + -- Now call the default event function. + self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for GROUP ", EventClass:GetClassNameAndID(), EventPriority } ) - -- There is an EventFunction defined, so call the EventFunction. - self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } ) - Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) - local Result, Value = xpcall( function() - return EventData.EventFunction( EventClass, Event ) + return EventFunction( EventClass, Event ) end, ErrorHandler ) - else + end + + end + + else + + -- If the EventData is not bound to a specific unit, then call the EventClass EventFunction. + -- Note that here the EventFunction will need to implement and determine the logic for the relevant source- or target unit, or weapon. + if Event.IniDCSUnit and not EventData.IniUnit then + + if EventClass == EventData.EventClass then - -- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object. - local EventFunction = EventClass[ _EVENTMETA[Event.id].Event ] - if EventFunction and type( EventFunction ) == "function" then - - -- Now call the default event function. - self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } ) - Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) + -- First test if a EventFunction is Set, otherwise search for the default function + if EventData.EventFunction then + -- There is an EventFunction defined, so call the EventFunction. + self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } ) + local Result, Value = xpcall( function() - return EventFunction( EventClass, Event ) + return EventData.EventFunction( EventClass, Event ) end, ErrorHandler ) + else + + -- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object. + local EventFunction = EventClass[ _EVENTMETA[Event.id].Event ] + if EventFunction and type( EventFunction ) == "function" then + + -- Now call the default event function. + self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } ) + + local Result, Value = xpcall( + function() + return EventFunction( EventClass, Event ) + end, ErrorHandler ) + end end end end diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index 998f7ee3e..4669911e3 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -76,6 +76,9 @@ -- -- Hereby the change log: -- +-- 2017-03-07: GROUP:**HandleEvent( Event, EventFunction )** added. +-- 2017-03-07: GROUP:**UnHandleEvent( Event )** added. +-- -- 2017-01-24: GROUP:**SetAIOnOff( AIOnOff )** added. -- -- 2017-01-24: GROUP:**SetAIOn()** added. @@ -897,4 +900,29 @@ function GROUP:OnReSpawn( ReSpawnFunction ) self.ReSpawnFunction = ReSpawnFunction end +do -- Event Handling + --- Subscribe to a DCS Event. + -- @param #GROUP self + -- @param Core.Event#EVENTS Event + -- @param #function EventFunction (optional) The function to be called when the event occurs for the GROUP. + -- @return #GROUP + function GROUP:HandleEvent( Event, EventFunction ) + + self:EventDispatcher():OnEventForGroup( self:GetName(), EventFunction, self, Event ) + + return self + end + + --- UnSubscribe to a DCS event. + -- @param #GROUP self + -- @param Core.Event#EVENTS Event + -- @return #GROUP + function GROUP:UnHandleEvent( Event ) + + self:EventDispatcher():RemoveForGroup( self:GetName(), self, Event ) + + return self + end + +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 8ebe4125c..e32e1c346 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: 20170306_1631' ) +env.info( 'Moose Generation Timestamp: 20170307_0923' ) local base = _G Include = {} @@ -4085,6 +4085,13 @@ end -- -- * @{Base#BASE.HandleEvent}(): Subscribe to a DCS Event. -- * @{Base#BASE.UnHandleEvent}(): Unsubscribe from a DCS Event. +-- +-- Note that for a UNIT, the event will be handled **for that UNIT only**! +-- Note that for a GROUP, the event will be handled **for all the UNITs in that GROUP only**! +-- +-- For all objects of other classes, the subscribed events will be handled for **all UNITs within the Mission**! +-- So if a UNIT within the mission has the subscribed event for that object, +-- then the object event handler will receive the event for that UNIT! -- -- ### 1.3.2 Event Handling of DCS Events -- @@ -4186,7 +4193,9 @@ end -- -- Hereby the change log: -- --- * 2016-02-07: Did a complete revision of the Event Handing API and underlying mechanisms. +-- * 2017-03-07: Added the correct event dispatching in case the event is subscribed by a GROUP. +-- +-- * 2017-02-07: Did a complete revision of the Event Handing API and underlying mechanisms. -- -- === -- @@ -4200,10 +4209,6 @@ end -- -- @module Event --- TODO: Need to update the EVENTDATA documentation with IniPlayerName and TgtPlayerName --- TODO: Need to update the EVENTDATA documentation with IniObjectCategory and TgtObjectCategory - - --- The EVENT structure -- @type EVENT @@ -4464,8 +4469,9 @@ function EVENT:Remove( EventClass, EventID ) self.Events[EventID][EventPriority][EventClass] = nil end ---- Removes an Events entry for a Unit +--- Removes an Events entry for a UNIT. -- @param #EVENT self +-- @param #string UnitName The name of the UNIT. -- @param Core.Base#BASE EventClass The self instance of the class for which the event is. -- @param Dcs.DCSWorld#world.event EventID -- @return #EVENT.Events @@ -4478,6 +4484,21 @@ function EVENT:RemoveForUnit( UnitName, EventClass, EventID ) Event.IniUnit[UnitName] = nil end +--- Removes an Events entry for a GROUP. +-- @param #EVENT self +-- @param #string GroupName The name of the GROUP. +-- @param Core.Base#BASE EventClass The self instance of the class for which the event is. +-- @param Dcs.DCSWorld#world.event EventID +-- @return #EVENT.Events +function EVENT:RemoveForGroup( GroupName, EventClass, EventID ) + self:F3( { EventClass, _EVENTMETA[EventID].Text } ) + + local EventClass = EventClass + local EventPriority = EventClass:GetEventPriority() + local Event = self.Events[EventID][EventPriority][EventClass] + Event.IniGroup[GroupName] = nil +end + --- Clears all event subscriptions for a @{Base#BASE} derived object. -- @param #EVENT self -- @param Core.Base#BASE EventObject @@ -4526,23 +4547,43 @@ function EVENT:OnEventGeneric( EventFunction, EventClass, EventID ) end ---- Set a new listener for an S_EVENT_X event +--- Set a new listener for an S_EVENT_X event for a UNIT. -- @param #EVENT self --- @param #string EventDCSUnitName --- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param #string UnitName The name of the UNIT. +-- @param #function EventFunction The function to be called when the event occurs for the GROUP. -- @param Core.Base#BASE EventClass The self instance of the class for which the event is. -- @param EventID -- @return #EVENT -function EVENT:OnEventForUnit( EventDCSUnitName, EventFunction, EventClass, EventID ) - self:F2( EventDCSUnitName ) +function EVENT:OnEventForUnit( UnitName, EventFunction, EventClass, EventID ) + self:F2( UnitName ) local Event = self:Init( EventID, EventClass ) if not Event.IniUnit then Event.IniUnit = {} end - Event.IniUnit[EventDCSUnitName] = {} - Event.IniUnit[EventDCSUnitName].EventFunction = EventFunction - Event.IniUnit[EventDCSUnitName].EventClass = EventClass + Event.IniUnit[UnitName] = {} + Event.IniUnit[UnitName].EventFunction = EventFunction + Event.IniUnit[UnitName].EventClass = EventClass + return self +end + +--- Set a new listener for an S_EVENT_X event for a GROUP. +-- @param #EVENT self +-- @param #string GroupName The name of the GROUP. +-- @param #function EventFunction The function to be called when the event occurs for the GROUP. +-- @param Core.Base#BASE EventClass The self instance of the class for which the event is. +-- @param EventID +-- @return #EVENT +function EVENT:OnEventForGroup( GroupName, EventFunction, EventClass, EventID ) + self:F2( GroupName ) + + local Event = self:Init( EventID, EventClass ) + if not Event.IniGroup then + Event.IniGroup = {} + end + Event.IniGroup[GroupName] = {} + Event.IniGroup[GroupName].EventFunction = EventFunction + Event.IniGroup[GroupName].EventClass = EventClass return self end @@ -5105,7 +5146,9 @@ function EVENT:onEvent( Event ) if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then Event.IniDCSGroupName = Event.IniDCSGroup:getName() Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) - self:E( { IniGroup = Event.IniGroup } ) + if Event.IniGroup then + Event.IniGroupName = Event.IniDCSGroupName + end end Event.IniPlayerName = Event.IniDCSUnit:getPlayerName() Event.IniCoalition = Event.IniDCSUnit:getCoalition() @@ -5146,6 +5189,10 @@ function EVENT:onEvent( Event ) Event.TgtDCSGroupName = "" if Event.TgtDCSGroup and Event.TgtDCSGroup:isExist() then Event.TgtDCSGroupName = Event.TgtDCSGroup:getName() + Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName ) + if Event.TgtGroup then + Event.TgtGroupName = Event.TgtDCSGroupName + end end Event.TgtPlayerName = Event.TgtDCSUnit:getPlayerName() Event.TgtCoalition = Event.TgtDCSUnit:getCoalition() @@ -5191,6 +5238,8 @@ function EVENT:onEvent( Event ) -- Okay, we got the event from DCS. Now loop the SORTED self.EventSorted[] table for the received Event.id, and for each EventData registered, check if a function needs to be called. for EventClass, EventData in pairs( self.Events[Event.id][EventPriority] ) do + + Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) -- If the EventData is for a UNIT, the call directly the EventClass EventFunction for that UNIT. if Event.IniDCSUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniDCSUnitName] then @@ -5198,8 +5247,7 @@ function EVENT:onEvent( Event ) -- First test if a EventFunction is Set, otherwise search for the default function if EventData.IniUnit[Event.IniDCSUnitName].EventFunction then - self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } ) - Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) + self:E( { "Calling EventFunction for UNIT ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } ) local Result, Value = xpcall( function() @@ -5214,7 +5262,6 @@ function EVENT:onEvent( Event ) -- Now call the default event function. self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } ) - Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) local Result, Value = xpcall( function() @@ -5225,38 +5272,69 @@ function EVENT:onEvent( Event ) end else - - -- If the EventData is not bound to a specific unit, then call the EventClass EventFunction. - -- Note that here the EventFunction will need to implement and determine the logic for the relevant source- or target unit, or weapon. - if Event.IniDCSUnit and not EventData.IniUnit then + + -- If the EventData is for a GROUP, the call directly the EventClass EventFunction for the UNIT in that GROUP. + if Event.IniDCSUnitName and Event.IniDCSGroupName and Event.IniGroupName and EventData.IniGroup and EventData.IniGroup[Event.IniGroupName] then + + -- First test if a EventFunction is Set, otherwise search for the default function + if EventData.IniGroup[Event.IniGroupName].EventFunction then - if EventClass == EventData.EventClass then + self:E( { "Calling EventFunction for GROUP ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } ) - -- First test if a EventFunction is Set, otherwise search for the default function - if EventData.EventFunction then + local Result, Value = xpcall( + function() + return EventData.IniGroup[Event.IniGroupName].EventFunction( EventClass, Event ) + end, ErrorHandler ) + + else + + -- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object. + local EventFunction = EventClass[ _EVENTMETA[Event.id].Event ] + if EventFunction and type( EventFunction ) == "function" then + + -- Now call the default event function. + self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for GROUP ", EventClass:GetClassNameAndID(), EventPriority } ) - -- There is an EventFunction defined, so call the EventFunction. - self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } ) - Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) - local Result, Value = xpcall( function() - return EventData.EventFunction( EventClass, Event ) + return EventFunction( EventClass, Event ) end, ErrorHandler ) - else + end + + end + + else + + -- If the EventData is not bound to a specific unit, then call the EventClass EventFunction. + -- Note that here the EventFunction will need to implement and determine the logic for the relevant source- or target unit, or weapon. + if Event.IniDCSUnit and not EventData.IniUnit then + + if EventClass == EventData.EventClass then - -- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object. - local EventFunction = EventClass[ _EVENTMETA[Event.id].Event ] - if EventFunction and type( EventFunction ) == "function" then - - -- Now call the default event function. - self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } ) - Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) + -- First test if a EventFunction is Set, otherwise search for the default function + if EventData.EventFunction then + -- There is an EventFunction defined, so call the EventFunction. + self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } ) + local Result, Value = xpcall( function() - return EventFunction( EventClass, Event ) + return EventData.EventFunction( EventClass, Event ) end, ErrorHandler ) + else + + -- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object. + local EventFunction = EventClass[ _EVENTMETA[Event.id].Event ] + if EventFunction and type( EventFunction ) == "function" then + + -- Now call the default event function. + self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } ) + + local Result, Value = xpcall( + function() + return EventFunction( EventClass, Event ) + end, ErrorHandler ) + end end end end @@ -15657,6 +15735,9 @@ end -- -- Hereby the change log: -- +-- 2017-03-07: GROUP:**HandleEvent( Event, EventFunction )** added. +-- 2017-03-07: GROUP:**UnHandleEvent( Event )** added. +-- -- 2017-01-24: GROUP:**SetAIOnOff( AIOnOff )** added. -- -- 2017-01-24: GROUP:**SetAIOn()** added. @@ -16478,7 +16559,32 @@ function GROUP:OnReSpawn( ReSpawnFunction ) self.ReSpawnFunction = ReSpawnFunction end +do -- Event Handling + --- Subscribe to a DCS Event. + -- @param #GROUP self + -- @param Core.Event#EVENTS Event + -- @param #function EventFunction (optional) The function to be called when the event occurs for the GROUP. + -- @return #GROUP + function GROUP:HandleEvent( Event, EventFunction ) + + self:EventDispatcher():OnEventForGroup( self:GetName(), EventFunction, self, Event ) + + return self + end + + --- UnSubscribe to a DCS event. + -- @param #GROUP self + -- @param Core.Event#EVENTS Event + -- @return #GROUP + function GROUP:UnHandleEvent( Event ) + + self:EventDispatcher():RemoveForGroup( self:GetName(), self, Event ) + + return self + end + +end --- This module contains the UNIT class. -- -- 1) @{#UNIT} class, extends @{Controllable#CONTROLLABLE} @@ -26484,11 +26590,14 @@ end -- -- * **None** ( Group ): The process is not started yet. -- * **Patrolling** ( Group ): The AI is patrolling the Patrol Zone. --- * **Returning** ( Group ): The AI is returning to Base.. +-- * **Returning** ( Group ): The AI is returning to Base. +-- * **Stopped** ( Group ): The process is stopped. +-- * **Crashed** ( Group ): The AI has crashed or is dead. -- -- ### 1.2.2) AI_PATROL_ZONE Events -- -- * **Start** ( Group ): Start the process. +-- * **Stop** ( Group ): Stop the process. -- * **Route** ( Group ): Route the AI to a new random 3D point within the Patrol Zone. -- * **RTB** ( Group ): Route the AI to the home base. -- * **Detect** ( Group ): The AI is detecting targets. @@ -26635,6 +26744,51 @@ function AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltit self:SetStartState( "None" ) + self:AddTransition( "*", "Stop", "Stopped" ) + +--- OnLeave Transition Handler for State Stopped. +-- @function [parent=#AI_PATROL_ZONE] OnLeaveStopped +-- @param #AI_PATROL_ZONE self +-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM. +-- @param #string From The From State string. +-- @param #string Event The Event string. +-- @param #string To The To State string. +-- @return #boolean Return false to cancel Transition. + +--- OnEnter Transition Handler for State Stopped. +-- @function [parent=#AI_PATROL_ZONE] OnEnterStopped +-- @param #AI_PATROL_ZONE self +-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM. +-- @param #string From The From State string. +-- @param #string Event The Event string. +-- @param #string To The To State string. + +--- OnBefore Transition Handler for Event Stop. +-- @function [parent=#AI_PATROL_ZONE] OnBeforeStop +-- @param #AI_PATROL_ZONE self +-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM. +-- @param #string From The From State string. +-- @param #string Event The Event string. +-- @param #string To The To State string. +-- @return #boolean Return false to cancel Transition. + +--- OnAfter Transition Handler for Event Stop. +-- @function [parent=#AI_PATROL_ZONE] OnAfterStop +-- @param #AI_PATROL_ZONE self +-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM. +-- @param #string From The From State string. +-- @param #string Event The Event string. +-- @param #string To The To State string. + +--- Synchronous Event Trigger for Event Stop. +-- @function [parent=#AI_PATROL_ZONE] Stop +-- @param #AI_PATROL_ZONE self + +--- Asynchronous Event Trigger for Event Stop. +-- @function [parent=#AI_PATROL_ZONE] __Stop +-- @param #AI_PATROL_ZONE self +-- @param #number Delay The delay in seconds. + self:AddTransition( "None", "Start", "Patrolling" ) --- OnBefore Transition Handler for Event Start. diff --git a/Moose Mission Setup/Moose.lua b/Moose Mission Setup/Moose.lua index 8ebe4125c..e32e1c346 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: 20170306_1631' ) +env.info( 'Moose Generation Timestamp: 20170307_0923' ) local base = _G Include = {} @@ -4085,6 +4085,13 @@ end -- -- * @{Base#BASE.HandleEvent}(): Subscribe to a DCS Event. -- * @{Base#BASE.UnHandleEvent}(): Unsubscribe from a DCS Event. +-- +-- Note that for a UNIT, the event will be handled **for that UNIT only**! +-- Note that for a GROUP, the event will be handled **for all the UNITs in that GROUP only**! +-- +-- For all objects of other classes, the subscribed events will be handled for **all UNITs within the Mission**! +-- So if a UNIT within the mission has the subscribed event for that object, +-- then the object event handler will receive the event for that UNIT! -- -- ### 1.3.2 Event Handling of DCS Events -- @@ -4186,7 +4193,9 @@ end -- -- Hereby the change log: -- --- * 2016-02-07: Did a complete revision of the Event Handing API and underlying mechanisms. +-- * 2017-03-07: Added the correct event dispatching in case the event is subscribed by a GROUP. +-- +-- * 2017-02-07: Did a complete revision of the Event Handing API and underlying mechanisms. -- -- === -- @@ -4200,10 +4209,6 @@ end -- -- @module Event --- TODO: Need to update the EVENTDATA documentation with IniPlayerName and TgtPlayerName --- TODO: Need to update the EVENTDATA documentation with IniObjectCategory and TgtObjectCategory - - --- The EVENT structure -- @type EVENT @@ -4464,8 +4469,9 @@ function EVENT:Remove( EventClass, EventID ) self.Events[EventID][EventPriority][EventClass] = nil end ---- Removes an Events entry for a Unit +--- Removes an Events entry for a UNIT. -- @param #EVENT self +-- @param #string UnitName The name of the UNIT. -- @param Core.Base#BASE EventClass The self instance of the class for which the event is. -- @param Dcs.DCSWorld#world.event EventID -- @return #EVENT.Events @@ -4478,6 +4484,21 @@ function EVENT:RemoveForUnit( UnitName, EventClass, EventID ) Event.IniUnit[UnitName] = nil end +--- Removes an Events entry for a GROUP. +-- @param #EVENT self +-- @param #string GroupName The name of the GROUP. +-- @param Core.Base#BASE EventClass The self instance of the class for which the event is. +-- @param Dcs.DCSWorld#world.event EventID +-- @return #EVENT.Events +function EVENT:RemoveForGroup( GroupName, EventClass, EventID ) + self:F3( { EventClass, _EVENTMETA[EventID].Text } ) + + local EventClass = EventClass + local EventPriority = EventClass:GetEventPriority() + local Event = self.Events[EventID][EventPriority][EventClass] + Event.IniGroup[GroupName] = nil +end + --- Clears all event subscriptions for a @{Base#BASE} derived object. -- @param #EVENT self -- @param Core.Base#BASE EventObject @@ -4526,23 +4547,43 @@ function EVENT:OnEventGeneric( EventFunction, EventClass, EventID ) end ---- Set a new listener for an S_EVENT_X event +--- Set a new listener for an S_EVENT_X event for a UNIT. -- @param #EVENT self --- @param #string EventDCSUnitName --- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param #string UnitName The name of the UNIT. +-- @param #function EventFunction The function to be called when the event occurs for the GROUP. -- @param Core.Base#BASE EventClass The self instance of the class for which the event is. -- @param EventID -- @return #EVENT -function EVENT:OnEventForUnit( EventDCSUnitName, EventFunction, EventClass, EventID ) - self:F2( EventDCSUnitName ) +function EVENT:OnEventForUnit( UnitName, EventFunction, EventClass, EventID ) + self:F2( UnitName ) local Event = self:Init( EventID, EventClass ) if not Event.IniUnit then Event.IniUnit = {} end - Event.IniUnit[EventDCSUnitName] = {} - Event.IniUnit[EventDCSUnitName].EventFunction = EventFunction - Event.IniUnit[EventDCSUnitName].EventClass = EventClass + Event.IniUnit[UnitName] = {} + Event.IniUnit[UnitName].EventFunction = EventFunction + Event.IniUnit[UnitName].EventClass = EventClass + return self +end + +--- Set a new listener for an S_EVENT_X event for a GROUP. +-- @param #EVENT self +-- @param #string GroupName The name of the GROUP. +-- @param #function EventFunction The function to be called when the event occurs for the GROUP. +-- @param Core.Base#BASE EventClass The self instance of the class for which the event is. +-- @param EventID +-- @return #EVENT +function EVENT:OnEventForGroup( GroupName, EventFunction, EventClass, EventID ) + self:F2( GroupName ) + + local Event = self:Init( EventID, EventClass ) + if not Event.IniGroup then + Event.IniGroup = {} + end + Event.IniGroup[GroupName] = {} + Event.IniGroup[GroupName].EventFunction = EventFunction + Event.IniGroup[GroupName].EventClass = EventClass return self end @@ -5105,7 +5146,9 @@ function EVENT:onEvent( Event ) if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then Event.IniDCSGroupName = Event.IniDCSGroup:getName() Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) - self:E( { IniGroup = Event.IniGroup } ) + if Event.IniGroup then + Event.IniGroupName = Event.IniDCSGroupName + end end Event.IniPlayerName = Event.IniDCSUnit:getPlayerName() Event.IniCoalition = Event.IniDCSUnit:getCoalition() @@ -5146,6 +5189,10 @@ function EVENT:onEvent( Event ) Event.TgtDCSGroupName = "" if Event.TgtDCSGroup and Event.TgtDCSGroup:isExist() then Event.TgtDCSGroupName = Event.TgtDCSGroup:getName() + Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName ) + if Event.TgtGroup then + Event.TgtGroupName = Event.TgtDCSGroupName + end end Event.TgtPlayerName = Event.TgtDCSUnit:getPlayerName() Event.TgtCoalition = Event.TgtDCSUnit:getCoalition() @@ -5191,6 +5238,8 @@ function EVENT:onEvent( Event ) -- Okay, we got the event from DCS. Now loop the SORTED self.EventSorted[] table for the received Event.id, and for each EventData registered, check if a function needs to be called. for EventClass, EventData in pairs( self.Events[Event.id][EventPriority] ) do + + Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) -- If the EventData is for a UNIT, the call directly the EventClass EventFunction for that UNIT. if Event.IniDCSUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniDCSUnitName] then @@ -5198,8 +5247,7 @@ function EVENT:onEvent( Event ) -- First test if a EventFunction is Set, otherwise search for the default function if EventData.IniUnit[Event.IniDCSUnitName].EventFunction then - self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } ) - Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) + self:E( { "Calling EventFunction for UNIT ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } ) local Result, Value = xpcall( function() @@ -5214,7 +5262,6 @@ function EVENT:onEvent( Event ) -- Now call the default event function. self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } ) - Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) local Result, Value = xpcall( function() @@ -5225,38 +5272,69 @@ function EVENT:onEvent( Event ) end else - - -- If the EventData is not bound to a specific unit, then call the EventClass EventFunction. - -- Note that here the EventFunction will need to implement and determine the logic for the relevant source- or target unit, or weapon. - if Event.IniDCSUnit and not EventData.IniUnit then + + -- If the EventData is for a GROUP, the call directly the EventClass EventFunction for the UNIT in that GROUP. + if Event.IniDCSUnitName and Event.IniDCSGroupName and Event.IniGroupName and EventData.IniGroup and EventData.IniGroup[Event.IniGroupName] then + + -- First test if a EventFunction is Set, otherwise search for the default function + if EventData.IniGroup[Event.IniGroupName].EventFunction then - if EventClass == EventData.EventClass then + self:E( { "Calling EventFunction for GROUP ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } ) - -- First test if a EventFunction is Set, otherwise search for the default function - if EventData.EventFunction then + local Result, Value = xpcall( + function() + return EventData.IniGroup[Event.IniGroupName].EventFunction( EventClass, Event ) + end, ErrorHandler ) + + else + + -- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object. + local EventFunction = EventClass[ _EVENTMETA[Event.id].Event ] + if EventFunction and type( EventFunction ) == "function" then + + -- Now call the default event function. + self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for GROUP ", EventClass:GetClassNameAndID(), EventPriority } ) - -- There is an EventFunction defined, so call the EventFunction. - self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } ) - Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) - local Result, Value = xpcall( function() - return EventData.EventFunction( EventClass, Event ) + return EventFunction( EventClass, Event ) end, ErrorHandler ) - else + end + + end + + else + + -- If the EventData is not bound to a specific unit, then call the EventClass EventFunction. + -- Note that here the EventFunction will need to implement and determine the logic for the relevant source- or target unit, or weapon. + if Event.IniDCSUnit and not EventData.IniUnit then + + if EventClass == EventData.EventClass then - -- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object. - local EventFunction = EventClass[ _EVENTMETA[Event.id].Event ] - if EventFunction and type( EventFunction ) == "function" then - - -- Now call the default event function. - self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } ) - Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) + -- First test if a EventFunction is Set, otherwise search for the default function + if EventData.EventFunction then + -- There is an EventFunction defined, so call the EventFunction. + self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } ) + local Result, Value = xpcall( function() - return EventFunction( EventClass, Event ) + return EventData.EventFunction( EventClass, Event ) end, ErrorHandler ) + else + + -- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object. + local EventFunction = EventClass[ _EVENTMETA[Event.id].Event ] + if EventFunction and type( EventFunction ) == "function" then + + -- Now call the default event function. + self:E( { "Calling " .. _EVENTMETA[Event.id].Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } ) + + local Result, Value = xpcall( + function() + return EventFunction( EventClass, Event ) + end, ErrorHandler ) + end end end end @@ -15657,6 +15735,9 @@ end -- -- Hereby the change log: -- +-- 2017-03-07: GROUP:**HandleEvent( Event, EventFunction )** added. +-- 2017-03-07: GROUP:**UnHandleEvent( Event )** added. +-- -- 2017-01-24: GROUP:**SetAIOnOff( AIOnOff )** added. -- -- 2017-01-24: GROUP:**SetAIOn()** added. @@ -16478,7 +16559,32 @@ function GROUP:OnReSpawn( ReSpawnFunction ) self.ReSpawnFunction = ReSpawnFunction end +do -- Event Handling + --- Subscribe to a DCS Event. + -- @param #GROUP self + -- @param Core.Event#EVENTS Event + -- @param #function EventFunction (optional) The function to be called when the event occurs for the GROUP. + -- @return #GROUP + function GROUP:HandleEvent( Event, EventFunction ) + + self:EventDispatcher():OnEventForGroup( self:GetName(), EventFunction, self, Event ) + + return self + end + + --- UnSubscribe to a DCS event. + -- @param #GROUP self + -- @param Core.Event#EVENTS Event + -- @return #GROUP + function GROUP:UnHandleEvent( Event ) + + self:EventDispatcher():RemoveForGroup( self:GetName(), self, Event ) + + return self + end + +end --- This module contains the UNIT class. -- -- 1) @{#UNIT} class, extends @{Controllable#CONTROLLABLE} @@ -26484,11 +26590,14 @@ end -- -- * **None** ( Group ): The process is not started yet. -- * **Patrolling** ( Group ): The AI is patrolling the Patrol Zone. --- * **Returning** ( Group ): The AI is returning to Base.. +-- * **Returning** ( Group ): The AI is returning to Base. +-- * **Stopped** ( Group ): The process is stopped. +-- * **Crashed** ( Group ): The AI has crashed or is dead. -- -- ### 1.2.2) AI_PATROL_ZONE Events -- -- * **Start** ( Group ): Start the process. +-- * **Stop** ( Group ): Stop the process. -- * **Route** ( Group ): Route the AI to a new random 3D point within the Patrol Zone. -- * **RTB** ( Group ): Route the AI to the home base. -- * **Detect** ( Group ): The AI is detecting targets. @@ -26635,6 +26744,51 @@ function AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltit self:SetStartState( "None" ) + self:AddTransition( "*", "Stop", "Stopped" ) + +--- OnLeave Transition Handler for State Stopped. +-- @function [parent=#AI_PATROL_ZONE] OnLeaveStopped +-- @param #AI_PATROL_ZONE self +-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM. +-- @param #string From The From State string. +-- @param #string Event The Event string. +-- @param #string To The To State string. +-- @return #boolean Return false to cancel Transition. + +--- OnEnter Transition Handler for State Stopped. +-- @function [parent=#AI_PATROL_ZONE] OnEnterStopped +-- @param #AI_PATROL_ZONE self +-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM. +-- @param #string From The From State string. +-- @param #string Event The Event string. +-- @param #string To The To State string. + +--- OnBefore Transition Handler for Event Stop. +-- @function [parent=#AI_PATROL_ZONE] OnBeforeStop +-- @param #AI_PATROL_ZONE self +-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM. +-- @param #string From The From State string. +-- @param #string Event The Event string. +-- @param #string To The To State string. +-- @return #boolean Return false to cancel Transition. + +--- OnAfter Transition Handler for Event Stop. +-- @function [parent=#AI_PATROL_ZONE] OnAfterStop +-- @param #AI_PATROL_ZONE self +-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM. +-- @param #string From The From State string. +-- @param #string Event The Event string. +-- @param #string To The To State string. + +--- Synchronous Event Trigger for Event Stop. +-- @function [parent=#AI_PATROL_ZONE] Stop +-- @param #AI_PATROL_ZONE self + +--- Asynchronous Event Trigger for Event Stop. +-- @function [parent=#AI_PATROL_ZONE] __Stop +-- @param #AI_PATROL_ZONE self +-- @param #number Delay The delay in seconds. + self:AddTransition( "None", "Start", "Patrolling" ) --- OnBefore Transition Handler for Event Start. diff --git a/Moose Test Missions/EVT - Event Handling/EVT-100 - OnEventShot Example/EVT-100 - OnEventShot Example.miz b/Moose Test Missions/EVT - Event Handling/EVT-100 - OnEventShot Example/EVT-100 - OnEventShot Example.miz deleted file mode 100644 index 22f687d8a..000000000 Binary files a/Moose Test Missions/EVT - Event Handling/EVT-100 - OnEventShot Example/EVT-100 - OnEventShot Example.miz and /dev/null differ diff --git a/Moose Test Missions/EVT - Event Handling/EVT-100 - OnEventShot Example/EVT-100 - OnEventShot Example.lua b/Moose Test Missions/EVT - Event Handling/EVT-100 - UNIT OnEventShot Example/EVT-100 - UNIT OnEventShot Example.lua similarity index 88% rename from Moose Test Missions/EVT - Event Handling/EVT-100 - OnEventShot Example/EVT-100 - OnEventShot Example.lua rename to Moose Test Missions/EVT - Event Handling/EVT-100 - UNIT OnEventShot Example/EVT-100 - UNIT OnEventShot Example.lua index 92b008506..1ea3b6dba 100644 --- a/Moose Test Missions/EVT - Event Handling/EVT-100 - OnEventShot Example/EVT-100 - OnEventShot Example.lua +++ b/Moose Test Missions/EVT - Event Handling/EVT-100 - UNIT OnEventShot Example/EVT-100 - UNIT OnEventShot Example.lua @@ -1,7 +1,7 @@ --- --- Name: EVT-100 - OnEventShot Example +-- Name: EVT-100 - UNIT OnEventShot Example -- Author: FlightControl --- Date Created: 7 February 2017 +-- Date Created: 7 Feb 2017 -- -- # Situation: -- diff --git a/Moose Test Missions/EVT - Event Handling/EVT-100 - UNIT OnEventShot Example/EVT-100 - UNIT OnEventShot Example.miz b/Moose Test Missions/EVT - Event Handling/EVT-100 - UNIT OnEventShot Example/EVT-100 - UNIT OnEventShot Example.miz new file mode 100644 index 000000000..2d5fc77b2 Binary files /dev/null and b/Moose Test Missions/EVT - Event Handling/EVT-100 - UNIT OnEventShot Example/EVT-100 - UNIT OnEventShot Example.miz differ diff --git a/Moose Test Missions/EVT - Event Handling/EVT-101 - OnEventHit Example/EVT-101 - OnEventHit Example.miz b/Moose Test Missions/EVT - Event Handling/EVT-101 - OnEventHit Example/EVT-101 - OnEventHit Example.miz deleted file mode 100644 index 610ced3f0..000000000 Binary files a/Moose Test Missions/EVT - Event Handling/EVT-101 - OnEventHit Example/EVT-101 - OnEventHit Example.miz and /dev/null differ diff --git a/Moose Test Missions/EVT - Event Handling/EVT-101 - OnEventHit Example/EVT-101 - OnEventHit Example.lua b/Moose Test Missions/EVT - Event Handling/EVT-101 - UNIT OnEventHit Example/EVT-101 - UNIT OnEventHit Example.lua similarity index 90% rename from Moose Test Missions/EVT - Event Handling/EVT-101 - OnEventHit Example/EVT-101 - OnEventHit Example.lua rename to Moose Test Missions/EVT - Event Handling/EVT-101 - UNIT OnEventHit Example/EVT-101 - UNIT OnEventHit Example.lua index 26c89daf5..88781fc39 100644 --- a/Moose Test Missions/EVT - Event Handling/EVT-101 - OnEventHit Example/EVT-101 - OnEventHit Example.lua +++ b/Moose Test Missions/EVT - Event Handling/EVT-101 - UNIT OnEventHit Example/EVT-101 - UNIT OnEventHit Example.lua @@ -1,7 +1,7 @@ --- --- Name: EVT-101 - OnEventHit Example +-- Name: EVT-101 - UNIT OnEventHit Example -- Author: FlightControl --- Date Created: 7 February 2017 +-- Date Created: 7 Feb 2017 -- -- # Situation: -- diff --git a/Moose Test Missions/EVT - Event Handling/EVT-101 - UNIT OnEventHit Example/EVT-101 - UNIT OnEventHit Example.miz b/Moose Test Missions/EVT - Event Handling/EVT-101 - UNIT OnEventHit Example/EVT-101 - UNIT OnEventHit Example.miz new file mode 100644 index 000000000..730bfc5b5 Binary files /dev/null and b/Moose Test Missions/EVT - Event Handling/EVT-101 - UNIT OnEventHit Example/EVT-101 - UNIT OnEventHit Example.miz differ diff --git a/Moose Test Missions/EVT - Event Handling/EVT-102 - OnEventTakeoff Example/EVT-102 - OnEventTakeoff Example.miz b/Moose Test Missions/EVT - Event Handling/EVT-102 - OnEventTakeoff Example/EVT-102 - OnEventTakeoff Example.miz deleted file mode 100644 index 6e755d888..000000000 Binary files a/Moose Test Missions/EVT - Event Handling/EVT-102 - OnEventTakeoff Example/EVT-102 - OnEventTakeoff Example.miz and /dev/null differ diff --git a/Moose Test Missions/EVT - Event Handling/EVT-102 - OnEventTakeoff Example/EVT-102 - OnEventTakeoff Example.lua b/Moose Test Missions/EVT - Event Handling/EVT-102 - UNIT OnEventTakeoff Example/EVT-102 - UNIT OnEventTakeoff Example.lua similarity index 91% rename from Moose Test Missions/EVT - Event Handling/EVT-102 - OnEventTakeoff Example/EVT-102 - OnEventTakeoff Example.lua rename to Moose Test Missions/EVT - Event Handling/EVT-102 - UNIT OnEventTakeoff Example/EVT-102 - UNIT OnEventTakeoff Example.lua index 4b36e09ec..21d8204c5 100644 --- a/Moose Test Missions/EVT - Event Handling/EVT-102 - OnEventTakeoff Example/EVT-102 - OnEventTakeoff Example.lua +++ b/Moose Test Missions/EVT - Event Handling/EVT-102 - UNIT OnEventTakeoff Example/EVT-102 - UNIT OnEventTakeoff Example.lua @@ -1,7 +1,7 @@ --- --- Name: EVT-102 - OnEventTakeoff Example +-- Name: EVT-102 - UNIT OnEventTakeoff Example -- Author: FlightControl --- Date Created: 7 February 2017 +-- Date Created: 7 Feb 2017 -- -- # Situation: -- diff --git a/Moose Test Missions/EVT - Event Handling/EVT-102 - UNIT OnEventTakeoff Example/EVT-102 - UNIT OnEventTakeoff Example.miz b/Moose Test Missions/EVT - Event Handling/EVT-102 - UNIT OnEventTakeoff Example/EVT-102 - UNIT OnEventTakeoff Example.miz new file mode 100644 index 000000000..1ab1cfd56 Binary files /dev/null and b/Moose Test Missions/EVT - Event Handling/EVT-102 - UNIT OnEventTakeoff Example/EVT-102 - UNIT OnEventTakeoff Example.miz differ diff --git a/Moose Test Missions/EVT - Event Handling/EVT-103 - OnEventLand Example/EVT-103 - OnEventLand Example.miz b/Moose Test Missions/EVT - Event Handling/EVT-103 - OnEventLand Example/EVT-103 - OnEventLand Example.miz deleted file mode 100644 index 26b14ce7d..000000000 Binary files a/Moose Test Missions/EVT - Event Handling/EVT-103 - OnEventLand Example/EVT-103 - OnEventLand Example.miz and /dev/null differ diff --git a/Moose Test Missions/EVT - Event Handling/EVT-103 - OnEventLand Example/EVT-103 - OnEventLand Example.lua b/Moose Test Missions/EVT - Event Handling/EVT-103 - UNIT OnEventLand Example/EVT-103 - UNIT OnEventLand Example.lua similarity index 94% rename from Moose Test Missions/EVT - Event Handling/EVT-103 - OnEventLand Example/EVT-103 - OnEventLand Example.lua rename to Moose Test Missions/EVT - Event Handling/EVT-103 - UNIT OnEventLand Example/EVT-103 - UNIT OnEventLand Example.lua index a3d5007a4..2aef2d94a 100644 --- a/Moose Test Missions/EVT - Event Handling/EVT-103 - OnEventLand Example/EVT-103 - OnEventLand Example.lua +++ b/Moose Test Missions/EVT - Event Handling/EVT-103 - UNIT OnEventLand Example/EVT-103 - UNIT OnEventLand Example.lua @@ -1,7 +1,7 @@ --- --- Name: EVT-103 - OnEventLand Example +-- Name: EVT-103 - UNIT OnEventLand Example -- Author: FlightControl --- Date Created: 7 February 2017 +-- Date Created: 7 Feb 2017 -- -- # Situation: -- diff --git a/Moose Test Missions/EVT - Event Handling/EVT-103 - UNIT OnEventLand Example/EVT-103 - UNIT OnEventLand Example.miz b/Moose Test Missions/EVT - Event Handling/EVT-103 - UNIT OnEventLand Example/EVT-103 - UNIT OnEventLand Example.miz new file mode 100644 index 000000000..30d9ac5fa Binary files /dev/null and b/Moose Test Missions/EVT - Event Handling/EVT-103 - UNIT OnEventLand Example/EVT-103 - UNIT OnEventLand Example.miz differ diff --git a/Moose Test Missions/EVT - Event Handling/EVT-104 - OnEventCrash Example/EVT-104 - OnEventCrash Example.miz b/Moose Test Missions/EVT - Event Handling/EVT-104 - OnEventCrash Example/EVT-104 - OnEventCrash Example.miz deleted file mode 100644 index 29eb6eb41..000000000 Binary files a/Moose Test Missions/EVT - Event Handling/EVT-104 - OnEventCrash Example/EVT-104 - OnEventCrash Example.miz and /dev/null differ diff --git a/Moose Test Missions/EVT - Event Handling/EVT-104 - OnEventCrash Example/EVT-104 - OnEventCrash Example.lua b/Moose Test Missions/EVT - Event Handling/EVT-104 - UNIT OnEventCrash Example/EVT-104 - UNIT OnEventCrash Example.lua similarity index 94% rename from Moose Test Missions/EVT - Event Handling/EVT-104 - OnEventCrash Example/EVT-104 - OnEventCrash Example.lua rename to Moose Test Missions/EVT - Event Handling/EVT-104 - UNIT OnEventCrash Example/EVT-104 - UNIT OnEventCrash Example.lua index bef1cb322..37fb02005 100644 --- a/Moose Test Missions/EVT - Event Handling/EVT-104 - OnEventCrash Example/EVT-104 - OnEventCrash Example.lua +++ b/Moose Test Missions/EVT - Event Handling/EVT-104 - UNIT OnEventCrash Example/EVT-104 - UNIT OnEventCrash Example.lua @@ -1,7 +1,7 @@ --- --- Name: EVT-104 - OnEventCrash Example +-- Name: EVT-104 - UNIT OnEventCrash Example -- Author: FlightControl --- Date Created: 7 February 2017 +-- Date Created: 7 Feb 2017 -- -- # Situation: -- diff --git a/Moose Test Missions/EVT - Event Handling/EVT-104 - UNIT OnEventCrash Example/EVT-104 - UNIT OnEventCrash Example.miz b/Moose Test Missions/EVT - Event Handling/EVT-104 - UNIT OnEventCrash Example/EVT-104 - UNIT OnEventCrash Example.miz new file mode 100644 index 000000000..18f3591de Binary files /dev/null and b/Moose Test Missions/EVT - Event Handling/EVT-104 - UNIT OnEventCrash Example/EVT-104 - UNIT OnEventCrash Example.miz differ diff --git a/Moose Test Missions/EVT - Event Handling/EVT-200 - GROUP OnEventShot Example/EVT-200 - GROUP OnEventShot Example.lua b/Moose Test Missions/EVT - Event Handling/EVT-200 - GROUP OnEventShot Example/EVT-200 - GROUP OnEventShot Example.lua new file mode 100644 index 000000000..b569b45c0 --- /dev/null +++ b/Moose Test Missions/EVT - Event Handling/EVT-200 - GROUP OnEventShot Example/EVT-200 - GROUP OnEventShot Example.lua @@ -0,0 +1,28 @@ +--- +-- Name: EVT-200 - GROUP OnEventShot Example +-- Author: FlightControl +-- Date Created: 07 Mar 2017 +-- +-- # Situation: +-- +-- Two groups of planes are flying in the air and shoot an missile to a multitude of ground targets. +-- +-- # Test cases: +-- +-- 1. Observe the planes shooting the missile. +-- 2. Observe when the planes shoots the missile, a dcs.log entry is written in the logging. +-- 3. Check the contents of the fields of the S_EVENT_SHOT entry. +-- 4. The planes of GROUP "Group Plane A", should only send a message when they shoot a missile. +-- 5. The planes of GROUP "Group Plane B", should NOT send a message when they shoot a missile. + +local PlaneGroup = GROUP:FindByName( "Group Plane A" ) + +PlaneGroup:HandleEvent( EVENTS.Shot ) + +function PlaneGroup:OnEventShot( EventData ) + + self:E( "I just fired a missile and I am part of " .. EventData.IniGroupName ) + EventData.IniUnit:MessageToAll( "I just fired a missile and I am part of " .. EventData.IniGroupName, 15, "Alert!" ) +end + + diff --git a/Moose Test Missions/EVT - Event Handling/EVT-200 - GROUP OnEventShot Example/EVT-200 - GROUP OnEventShot Example.miz b/Moose Test Missions/EVT - Event Handling/EVT-200 - GROUP OnEventShot Example/EVT-200 - GROUP OnEventShot Example.miz new file mode 100644 index 000000000..16bd5254f Binary files /dev/null and b/Moose Test Missions/EVT - Event Handling/EVT-200 - GROUP OnEventShot Example/EVT-200 - GROUP OnEventShot Example.miz differ diff --git a/docs/Documentation/AI_Patrol.html b/docs/Documentation/AI_Patrol.html index 51fe4286e..14a6a30b6 100644 --- a/docs/Documentation/AI_Patrol.html +++ b/docs/Documentation/AI_Patrol.html @@ -129,13 +129,16 @@ When the fuel treshold has been reached, the airplane will fly towards the neare

1.2.2) AIPATROLZONE Events

+

Note that for a UNIT, the event will be handled for that UNIT only! +Note that for a GROUP, the event will be handled for all the UNITs in that GROUP only!

+ +

For all objects of other classes, the subscribed events will be handled for all UNITs within the Mission! +So if a UNIT within the mission has the subscribed event for that object, +then the object event handler will receive the event for that UNIT!

+

1.3.2 Event Handling of DCS Events

Once the class is subscribed to the event, an Event Handling method on the object or class needs to be written that will be called @@ -252,7 +259,8 @@ YYYY-MM-DD: CLASS:NewFunction( Params ) added

Hereby the change log:


@@ -427,6 +435,12 @@ YYYY-MM-DD: CLASS:NewFunction( Params ) added

EVENT:OnEngineStartUpRemove(EventClass)

Stop listening to SEVENTENGINE_STARTUP event.

+ + + + EVENT:OnEventForGroup(GroupName, EventFunction, EventClass, EventID) + +

Set a new listener for an SEVENTX event for a GROUP.

@@ -436,9 +450,9 @@ YYYY-MM-DD: CLASS:NewFunction( Params ) added

- EVENT:OnEventForUnit(EventDCSUnitName, EventFunction, EventClass, EventID) + EVENT:OnEventForUnit(UnitName, EventFunction, EventClass, EventID) -

Set a new listener for an SEVENTX event

+

Set a new listener for an SEVENTX event for a UNIT.

@@ -574,9 +588,15 @@ YYYY-MM-DD: CLASS:NewFunction( Params ) added

- EVENT:RemoveForUnit(EventClass, EventID, UnitName) + EVENT:RemoveForGroup(GroupName, EventClass, EventID) -

Removes an Events entry for a Unit

+

Removes an Events entry for a GROUP.

+ + + + EVENT:RemoveForUnit(UnitName, EventClass, EventID) + +

Removes an Events entry for a UNIT.

@@ -1704,6 +1724,50 @@ The self instance of the class for which the event is.

#EVENT:

+ + +
+
+ + +EVENT:OnEventForGroup(GroupName, EventFunction, EventClass, EventID) + +
+
+ +

Set a new listener for an SEVENTX event for a GROUP.

+ +

Parameters

+ +

Return value

+ +

#EVENT:

+ +
@@ -1753,24 +1817,25 @@ The instance of the class for which the event is.

-EVENT:OnEventForUnit(EventDCSUnitName, EventFunction, EventClass, EventID) +EVENT:OnEventForUnit(UnitName, EventFunction, EventClass, EventID)
-

Set a new listener for an SEVENTX event

+

Set a new listener for an SEVENTX event for a UNIT.

Parameters

+
+
+
+ + +GROUP:UnHandleEvent(Event) + +
+
+ +

UnSubscribe to a DCS event.

+ +

Parameter

+ +

Return value

+ +

#GROUP:

+ +
diff --git a/docs/Documentation/Spawn.html b/docs/Documentation/Spawn.html index ecc39c847..5b520310c 100644 --- a/docs/Documentation/Spawn.html +++ b/docs/Documentation/Spawn.html @@ -1759,6 +1759,9 @@ The group that was spawned. You can use this group for further actions.

+ +

Don't repeat the group from Take-Off till Landing and back Take-Off by ReSpawning.

+
@@ -2233,7 +2236,7 @@ when nothing was spawned.

- #number + SPAWN.SpawnMaxGroups @@ -2250,7 +2253,7 @@ when nothing was spawned.

- #number + SPAWN.SpawnMaxUnitsAlive