mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
New Event Dispatching based on priorities
-- First _DATABASE -- then SETS -- then the rest -- changed AIRBASEPOLICE
This commit is contained in:
parent
33af2b4f95
commit
ab345f5ad2
@ -1,4 +1,4 @@
|
|||||||
rem This script will pull the latest changes from the remote repository, and update the submodules accordingly.
|
rem This script will pull the latest changes from the remote repository, and update the submodules accordingly.
|
||||||
|
|
||||||
git pull
|
C:\Program Files (x86)\Git\bin\git pull
|
||||||
git submodule update --init
|
C:\Program Files (x86)\Git\bin\git submodule update --init
|
||||||
|
|||||||
@ -55,6 +55,8 @@ DATABASE = {
|
|||||||
CLIENTS = {},
|
CLIENTS = {},
|
||||||
AIRBASES = {},
|
AIRBASES = {},
|
||||||
NavPoints = {},
|
NavPoints = {},
|
||||||
|
EventPriority = 1, -- Used to sort the DCS event order processing (complicated). Database has highest priority.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
local _DATABASECoalition =
|
local _DATABASECoalition =
|
||||||
@ -228,6 +230,7 @@ end
|
|||||||
function DATABASE:AddGroup( GroupName )
|
function DATABASE:AddGroup( GroupName )
|
||||||
|
|
||||||
if not self.GROUPS[GroupName] then
|
if not self.GROUPS[GroupName] then
|
||||||
|
self:E( { "Add GROUP:", GroupName } )
|
||||||
self.GROUPS[GroupName] = GROUP:Register( GroupName )
|
self.GROUPS[GroupName] = GROUP:Register( GroupName )
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -569,6 +572,8 @@ function DATABASE:_EventOnPlayerEnterUnit( Event )
|
|||||||
self:F2( { Event } )
|
self:F2( { Event } )
|
||||||
|
|
||||||
if Event.IniUnit then
|
if Event.IniUnit then
|
||||||
|
self:AddUnit( Event.IniDCSUnitName )
|
||||||
|
self:AddGroup( Event.IniDCSGroupName )
|
||||||
local PlayerName = Event.IniUnit:GetPlayerName()
|
local PlayerName = Event.IniUnit:GetPlayerName()
|
||||||
if not self.PLAYERS[PlayerName] then
|
if not self.PLAYERS[PlayerName] then
|
||||||
self:AddPlayer( Event.IniUnitName, PlayerName )
|
self:AddPlayer( Event.IniUnitName, PlayerName )
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
EVENT = {
|
EVENT = {
|
||||||
ClassName = "EVENT",
|
ClassName = "EVENT",
|
||||||
ClassID = 0,
|
ClassID = 0,
|
||||||
|
SortedEvents = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
local _EVENTCODES = {
|
local _EVENTCODES = {
|
||||||
@ -50,6 +51,33 @@ local _EVENTCODES = {
|
|||||||
"S_EVENT_MAX",
|
"S_EVENT_MAX",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local _EVENTORDER = {
|
||||||
|
[world.event.S_EVENT_SHOT] = 1,
|
||||||
|
[world.event.S_EVENT_HIT] = 1,
|
||||||
|
[world.event.S_EVENT_TAKEOFF] = 1,
|
||||||
|
[world.event.S_EVENT_LAND] = 1,
|
||||||
|
[world.event.S_EVENT_CRASH] = -1,
|
||||||
|
[world.event.S_EVENT_EJECTION] = -1,
|
||||||
|
[world.event.S_EVENT_REFUELING] = 1,
|
||||||
|
[world.event.S_EVENT_DEAD] = -1,
|
||||||
|
[world.event.S_EVENT_PILOT_DEAD] = -1,
|
||||||
|
[world.event.S_EVENT_BASE_CAPTURED] = 1,
|
||||||
|
[world.event.S_EVENT_MISSION_START] = 1,
|
||||||
|
[world.event.S_EVENT_MISSION_END] = -1,
|
||||||
|
[world.event.S_EVENT_TOOK_CONTROL] = 1,
|
||||||
|
[world.event.S_EVENT_REFUELING_STOP] = 1,
|
||||||
|
[world.event.S_EVENT_BIRTH] = 1,
|
||||||
|
[world.event.S_EVENT_HUMAN_FAILURE] = 1,
|
||||||
|
[world.event.S_EVENT_ENGINE_STARTUP] = 1,
|
||||||
|
[world.event.S_EVENT_ENGINE_SHUTDOWN] = 1,
|
||||||
|
[world.event.S_EVENT_PLAYER_ENTER_UNIT] = 1,
|
||||||
|
[world.event.S_EVENT_PLAYER_LEAVE_UNIT] = -1,
|
||||||
|
[world.event.S_EVENT_PLAYER_COMMENT] = 1,
|
||||||
|
[world.event.S_EVENT_SHOOTING_START] = 1,
|
||||||
|
[world.event.S_EVENT_SHOOTING_END] = 1,
|
||||||
|
[world.event.S_EVENT_MAX] = 1,
|
||||||
|
}
|
||||||
|
|
||||||
--- The Event structure
|
--- The Event structure
|
||||||
-- @type EVENTDATA
|
-- @type EVENTDATA
|
||||||
-- @field id
|
-- @field id
|
||||||
@ -102,7 +130,7 @@ function EVENT:Init( EventID, EventClass )
|
|||||||
if not self.Events[EventID] then
|
if not self.Events[EventID] then
|
||||||
-- Create a WEAK table to ensure that the garbage collector is cleaning the event links when the object usage is cleaned.
|
-- Create a WEAK table to ensure that the garbage collector is cleaning the event links when the object usage is cleaned.
|
||||||
self.Events[EventID] = setmetatable( {}, { __mode = "k" } )
|
self.Events[EventID] = setmetatable( {}, { __mode = "k" } )
|
||||||
|
self.SortedEvents[EventID] = setmetatable( {}, { __mode = "k" } )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self.Events[EventID][EventClass] then
|
if not self.Events[EventID][EventClass] then
|
||||||
@ -121,6 +149,12 @@ function EVENT:Remove( EventClass, EventID )
|
|||||||
|
|
||||||
local EventClass = EventClass
|
local EventClass = EventClass
|
||||||
self.Events[EventID][EventClass] = nil
|
self.Events[EventID][EventClass] = nil
|
||||||
|
|
||||||
|
self.SortedEvents[EventID] = nil
|
||||||
|
self.SortedEvents[EventID] = {}
|
||||||
|
for EventClass, Event in pairs(self.Events[EventID]) do table.insert( self.SortedEvents[EventID], Event) end
|
||||||
|
table.sort( self.SortedEvents[EventID], function( Event1, Event2 ) return Event1.EventTime < Event2.EventTime end )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Clears all event subscriptions for a @{Core.Base#BASE} derived object.
|
--- Clears all event subscriptions for a @{Core.Base#BASE} derived object.
|
||||||
@ -132,6 +166,7 @@ function EVENT:RemoveAll( EventObject )
|
|||||||
local EventClass = EventObject:GetClassNameAndID()
|
local EventClass = EventObject:GetClassNameAndID()
|
||||||
for EventID, EventData in pairs( self.Events ) do
|
for EventID, EventData in pairs( self.Events ) do
|
||||||
self.Events[EventID][EventClass] = nil
|
self.Events[EventID][EventClass] = nil
|
||||||
|
self.SortedEvents[EventID] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -165,6 +200,13 @@ function EVENT:OnEventGeneric( EventFunction, EventClass, EventID )
|
|||||||
local Event = self:Init( EventID, EventClass )
|
local Event = self:Init( EventID, EventClass )
|
||||||
Event.EventFunction = EventFunction
|
Event.EventFunction = EventFunction
|
||||||
Event.EventClass = EventClass
|
Event.EventClass = EventClass
|
||||||
|
Event.EventTime = EventClass.EventPriority and EventClass.EventPriority or 10
|
||||||
|
|
||||||
|
self.SortedEvents[EventID] = nil
|
||||||
|
self.SortedEvents[EventID] = {}
|
||||||
|
for EventClass, Event in pairs(self.Events[EventID]) do table.insert( self.SortedEvents[EventID], Event) end
|
||||||
|
table.sort( self.SortedEvents[EventID], function( Event1, Event2 ) return Event1.EventTime < Event2.EventTime end )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -741,6 +783,8 @@ function EVENT:onEvent( Event )
|
|||||||
Event.IniDCSGroupName = ""
|
Event.IniDCSGroupName = ""
|
||||||
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
|
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
|
||||||
Event.IniDCSGroupName = Event.IniDCSGroup:getName()
|
Event.IniDCSGroupName = Event.IniDCSGroup:getName()
|
||||||
|
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||||
|
self:E( { IniGroup = Event.IniGroup } )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if Event.target then
|
if Event.target then
|
||||||
@ -763,11 +807,27 @@ function EVENT:onEvent( Event )
|
|||||||
end
|
end
|
||||||
self:E( { _EVENTCODES[Event.id], Event, Event.IniDCSUnitName, Event.TgtDCSUnitName } )
|
self:E( { _EVENTCODES[Event.id], Event, Event.IniDCSUnitName, Event.TgtDCSUnitName } )
|
||||||
|
|
||||||
-- Okay, we got the event from DCS. Now loop the self.Events[] table for the received Event.id, and for each EventData registered, check if a function needs to be called.
|
local function pairsByEventSorted( EventSorted, Order )
|
||||||
for EventClass, EventData in pairs( self.Events[Event.id] ) do
|
local i = Order == -1 and #EventSorted or 0
|
||||||
|
local iter = function()
|
||||||
|
i = i + Order
|
||||||
|
if EventSorted[i] == nil then
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
return EventSorted[i].EventClass, EventSorted[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return iter
|
||||||
|
end
|
||||||
|
|
||||||
|
self:E( { Order = _EVENTORDER[Event.id] } )
|
||||||
|
|
||||||
|
-- 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 pairsByEventSorted( self.SortedEvents[Event.id], _EVENTORDER[Event.id] ) do
|
||||||
-- If the EventData is for a UNIT, the call directly the EventClass EventFunction for that UNIT.
|
-- 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
|
if Event.IniDCSUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniDCSUnitName] then
|
||||||
self:T( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName } )
|
self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventData.EventTime } )
|
||||||
|
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||||
local Result, Value = xpcall( function() return EventData.IniUnit[Event.IniDCSUnitName].EventFunction( EventData.IniUnit[Event.IniDCSUnitName].EventClass, Event ) end, ErrorHandler )
|
local Result, Value = xpcall( function() return EventData.IniUnit[Event.IniDCSUnitName].EventFunction( EventData.IniUnit[Event.IniDCSUnitName].EventClass, Event ) end, ErrorHandler )
|
||||||
--EventData.IniUnit[Event.IniDCSUnitName].EventFunction( EventData.IniUnit[Event.IniDCSUnitName].EventClass, Event )
|
--EventData.IniUnit[Event.IniDCSUnitName].EventFunction( EventData.IniUnit[Event.IniDCSUnitName].EventClass, Event )
|
||||||
else
|
else
|
||||||
@ -775,7 +835,8 @@ function EVENT:onEvent( Event )
|
|||||||
-- Note that here the EventFunction will need to implement and determine the logic for the relevant source- or target unit, or weapon.
|
-- 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 Event.IniDCSUnit and not EventData.IniUnit then
|
||||||
if EventClass == EventData.EventClass then
|
if EventClass == EventData.EventClass then
|
||||||
self:T( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID() } )
|
self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventData.EventTime } )
|
||||||
|
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||||
local Result, Value = xpcall( function() return EventData.EventFunction( EventData.EventClass, Event ) end, ErrorHandler )
|
local Result, Value = xpcall( function() return EventData.EventFunction( EventData.EventClass, Event ) end, ErrorHandler )
|
||||||
--EventData.EventFunction( EventData.EventClass, Event )
|
--EventData.EventFunction( EventData.EventClass, Event )
|
||||||
end
|
end
|
||||||
|
|||||||
@ -240,6 +240,7 @@ SET_BASE = {
|
|||||||
Filter = {},
|
Filter = {},
|
||||||
Set = {},
|
Set = {},
|
||||||
List = {},
|
List = {},
|
||||||
|
EventPriority = 2, -- Used to sort the DCS event order processing (complicated)
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Creates a new SET_BASE object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.
|
--- Creates a new SET_BASE object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.
|
||||||
|
|||||||
@ -182,7 +182,7 @@ function AIRBASEPOLICE_BASE:_AirbaseMonitor()
|
|||||||
Client:SetState( self, "Warnings", SpeedingWarnings + 1 )
|
Client:SetState( self, "Warnings", SpeedingWarnings + 1 )
|
||||||
else
|
else
|
||||||
MESSAGE:New( "Player " .. Client:GetPlayerName() .. " has been removed from the airbase, due to a speeding violation ...", 10, "Airbase Police" ):ToAll()
|
MESSAGE:New( "Player " .. Client:GetPlayerName() .. " has been removed from the airbase, due to a speeding violation ...", 10, "Airbase Police" ):ToAll()
|
||||||
Client:GetGroup():Destroy()
|
Client:Destroy()
|
||||||
Client:SetState( self, "Speeding", false )
|
Client:SetState( self, "Speeding", false )
|
||||||
Client:SetState( self, "Warnings", 0 )
|
Client:SetState( self, "Warnings", 0 )
|
||||||
end
|
end
|
||||||
|
|||||||
@ -81,7 +81,8 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
|||||||
local PlayerUnit = EventData.IniUnit
|
local PlayerUnit = EventData.IniUnit
|
||||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||||
local Mission = Mission -- Tasking.Mission#MISSION
|
local Mission = Mission -- Tasking.Mission#MISSION
|
||||||
Mission:JoinUnit( PlayerUnit )
|
local PlayerGroup = EventData.IniGroup -- The GROUP object should be filled!
|
||||||
|
Mission:JoinUnit( PlayerUnit, PlayerGroup )
|
||||||
Mission:ReportDetails()
|
Mission:ReportDetails()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -100,7 +101,8 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
|||||||
local PlayerUnit = EventData.IniUnit
|
local PlayerUnit = EventData.IniUnit
|
||||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||||
local Mission = Mission -- Tasking.Mission#MISSION
|
local Mission = Mission -- Tasking.Mission#MISSION
|
||||||
Mission:JoinUnit( PlayerUnit )
|
local PlayerGroup = EventData.IniGroup -- The GROUP object should be filled!
|
||||||
|
Mission:JoinUnit( PlayerUnit, PlayerGroup )
|
||||||
Mission:ReportDetails()
|
Mission:ReportDetails()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -115,6 +117,7 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
|||||||
function( self, EventData )
|
function( self, EventData )
|
||||||
local PlayerUnit = EventData.IniUnit
|
local PlayerUnit = EventData.IniUnit
|
||||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||||
|
local Mission = Mission -- Tasking.Mission#MISSION
|
||||||
Mission:AbortUnit( PlayerUnit )
|
Mission:AbortUnit( PlayerUnit )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -103,15 +103,16 @@ end
|
|||||||
-- If the Unit is part of a Task in the Mission, true is returned.
|
-- If the Unit is part of a Task in the Mission, true is returned.
|
||||||
-- @param #MISSION self
|
-- @param #MISSION self
|
||||||
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player joining the Mission.
|
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player joining the Mission.
|
||||||
|
-- @param Wrapper.Group#GROUP PlayerGroup The GROUP of the player joining the Mission.
|
||||||
-- @return #boolean true if Unit is part of a Task in the Mission.
|
-- @return #boolean true if Unit is part of a Task in the Mission.
|
||||||
function MISSION:JoinUnit( PlayerUnit )
|
function MISSION:JoinUnit( PlayerUnit, PlayerGroup )
|
||||||
self:F( { PlayerUnit = PlayerUnit } )
|
self:F( { PlayerUnit = PlayerUnit, PlayerGroup = PlayerGroup } )
|
||||||
|
|
||||||
local PlayerUnitAdded = false
|
local PlayerUnitAdded = false
|
||||||
|
|
||||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||||
local Task = Task -- Tasking.Task#TASK
|
local Task = Task -- Tasking.Task#TASK
|
||||||
if Task:JoinUnit( PlayerUnit ) then
|
if Task:JoinUnit( PlayerUnit, PlayerGroup ) then
|
||||||
PlayerUnitAdded = true
|
PlayerUnitAdded = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -234,14 +234,14 @@ end
|
|||||||
-- If the Unit is part of the Task, true is returned.
|
-- If the Unit is part of the Task, true is returned.
|
||||||
-- @param #TASK self
|
-- @param #TASK self
|
||||||
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player joining the Mission.
|
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player joining the Mission.
|
||||||
|
-- @param Wrapper.Group#GROUP PlayerGroup The GROUP of the player joining the Mission.
|
||||||
-- @return #boolean true if Unit is part of the Task.
|
-- @return #boolean true if Unit is part of the Task.
|
||||||
function TASK:JoinUnit( PlayerUnit )
|
function TASK:JoinUnit( PlayerUnit, PlayerGroup )
|
||||||
self:F( { PlayerUnit = PlayerUnit } )
|
self:F( { PlayerUnit = PlayerUnit, PlayerGroup = PlayerGroup } )
|
||||||
|
|
||||||
local PlayerUnitAdded = false
|
local PlayerUnitAdded = false
|
||||||
|
|
||||||
local PlayerGroups = self:GetGroups()
|
local PlayerGroups = self:GetGroups()
|
||||||
local PlayerGroup = PlayerUnit:GetGroup()
|
|
||||||
|
|
||||||
-- Is the PlayerGroup part of the PlayerGroups?
|
-- Is the PlayerGroup part of the PlayerGroups?
|
||||||
if PlayerGroups:IsIncludeObject( PlayerGroup ) then
|
if PlayerGroups:IsIncludeObject( PlayerGroup ) then
|
||||||
@ -394,7 +394,6 @@ end
|
|||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
function TASK:HasGroup( FindGroup )
|
function TASK:HasGroup( FindGroup )
|
||||||
|
|
||||||
self:GetGroups():FilterOnce() -- Ensure that the filter is updated.
|
|
||||||
return self:GetGroups():IsIncludeObject( FindGroup )
|
return self:GetGroups():IsIncludeObject( FindGroup )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
env.info( '*** MOOSE STATIC INCLUDE START *** ' )
|
env.info( '*** MOOSE STATIC INCLUDE START *** ' )
|
||||||
env.info( 'Moose Generation Timestamp: 20170124_1109' )
|
env.info( 'Moose Generation Timestamp: 20170203_2208' )
|
||||||
local base = _G
|
local base = _G
|
||||||
|
|
||||||
Include = {}
|
Include = {}
|
||||||
@ -4211,6 +4211,7 @@ end
|
|||||||
EVENT = {
|
EVENT = {
|
||||||
ClassName = "EVENT",
|
ClassName = "EVENT",
|
||||||
ClassID = 0,
|
ClassID = 0,
|
||||||
|
SortedEvents = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
local _EVENTCODES = {
|
local _EVENTCODES = {
|
||||||
@ -4240,6 +4241,33 @@ local _EVENTCODES = {
|
|||||||
"S_EVENT_MAX",
|
"S_EVENT_MAX",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local _EVENTORDER = {
|
||||||
|
[world.event.S_EVENT_SHOT] = 1,
|
||||||
|
[world.event.S_EVENT_HIT] = 1,
|
||||||
|
[world.event.S_EVENT_TAKEOFF] = 1,
|
||||||
|
[world.event.S_EVENT_LAND] = 1,
|
||||||
|
[world.event.S_EVENT_CRASH] = -1,
|
||||||
|
[world.event.S_EVENT_EJECTION] = -1,
|
||||||
|
[world.event.S_EVENT_REFUELING] = 1,
|
||||||
|
[world.event.S_EVENT_DEAD] = -1,
|
||||||
|
[world.event.S_EVENT_PILOT_DEAD] = -1,
|
||||||
|
[world.event.S_EVENT_BASE_CAPTURED] = 1,
|
||||||
|
[world.event.S_EVENT_MISSION_START] = 1,
|
||||||
|
[world.event.S_EVENT_MISSION_END] = -1,
|
||||||
|
[world.event.S_EVENT_TOOK_CONTROL] = 1,
|
||||||
|
[world.event.S_EVENT_REFUELING_STOP] = 1,
|
||||||
|
[world.event.S_EVENT_BIRTH] = 1,
|
||||||
|
[world.event.S_EVENT_HUMAN_FAILURE] = 1,
|
||||||
|
[world.event.S_EVENT_ENGINE_STARTUP] = 1,
|
||||||
|
[world.event.S_EVENT_ENGINE_SHUTDOWN] = 1,
|
||||||
|
[world.event.S_EVENT_PLAYER_ENTER_UNIT] = 1,
|
||||||
|
[world.event.S_EVENT_PLAYER_LEAVE_UNIT] = -1,
|
||||||
|
[world.event.S_EVENT_PLAYER_COMMENT] = 1,
|
||||||
|
[world.event.S_EVENT_SHOOTING_START] = 1,
|
||||||
|
[world.event.S_EVENT_SHOOTING_END] = 1,
|
||||||
|
[world.event.S_EVENT_MAX] = 1,
|
||||||
|
}
|
||||||
|
|
||||||
--- The Event structure
|
--- The Event structure
|
||||||
-- @type EVENTDATA
|
-- @type EVENTDATA
|
||||||
-- @field id
|
-- @field id
|
||||||
@ -4292,7 +4320,7 @@ function EVENT:Init( EventID, EventClass )
|
|||||||
if not self.Events[EventID] then
|
if not self.Events[EventID] then
|
||||||
-- Create a WEAK table to ensure that the garbage collector is cleaning the event links when the object usage is cleaned.
|
-- Create a WEAK table to ensure that the garbage collector is cleaning the event links when the object usage is cleaned.
|
||||||
self.Events[EventID] = setmetatable( {}, { __mode = "k" } )
|
self.Events[EventID] = setmetatable( {}, { __mode = "k" } )
|
||||||
|
self.SortedEvents[EventID] = setmetatable( {}, { __mode = "k" } )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self.Events[EventID][EventClass] then
|
if not self.Events[EventID][EventClass] then
|
||||||
@ -4311,6 +4339,12 @@ function EVENT:Remove( EventClass, EventID )
|
|||||||
|
|
||||||
local EventClass = EventClass
|
local EventClass = EventClass
|
||||||
self.Events[EventID][EventClass] = nil
|
self.Events[EventID][EventClass] = nil
|
||||||
|
|
||||||
|
self.SortedEvents[EventID] = nil
|
||||||
|
self.SortedEvents[EventID] = {}
|
||||||
|
for EventClass, Event in pairs(self.Events[EventID]) do table.insert( self.SortedEvents[EventID], Event) end
|
||||||
|
table.sort( self.SortedEvents[EventID], function( Event1, Event2 ) return Event1.EventTime < Event2.EventTime end )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Clears all event subscriptions for a @{Core.Base#BASE} derived object.
|
--- Clears all event subscriptions for a @{Core.Base#BASE} derived object.
|
||||||
@ -4322,6 +4356,7 @@ function EVENT:RemoveAll( EventObject )
|
|||||||
local EventClass = EventObject:GetClassNameAndID()
|
local EventClass = EventObject:GetClassNameAndID()
|
||||||
for EventID, EventData in pairs( self.Events ) do
|
for EventID, EventData in pairs( self.Events ) do
|
||||||
self.Events[EventID][EventClass] = nil
|
self.Events[EventID][EventClass] = nil
|
||||||
|
self.SortedEvents[EventID] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -4355,6 +4390,13 @@ function EVENT:OnEventGeneric( EventFunction, EventClass, EventID )
|
|||||||
local Event = self:Init( EventID, EventClass )
|
local Event = self:Init( EventID, EventClass )
|
||||||
Event.EventFunction = EventFunction
|
Event.EventFunction = EventFunction
|
||||||
Event.EventClass = EventClass
|
Event.EventClass = EventClass
|
||||||
|
Event.EventTime = EventClass.EventPriority and EventClass.EventPriority or 10
|
||||||
|
|
||||||
|
self.SortedEvents[EventID] = nil
|
||||||
|
self.SortedEvents[EventID] = {}
|
||||||
|
for EventClass, Event in pairs(self.Events[EventID]) do table.insert( self.SortedEvents[EventID], Event) end
|
||||||
|
table.sort( self.SortedEvents[EventID], function( Event1, Event2 ) return Event1.EventTime < Event2.EventTime end )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -4931,6 +4973,8 @@ function EVENT:onEvent( Event )
|
|||||||
Event.IniDCSGroupName = ""
|
Event.IniDCSGroupName = ""
|
||||||
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
|
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
|
||||||
Event.IniDCSGroupName = Event.IniDCSGroup:getName()
|
Event.IniDCSGroupName = Event.IniDCSGroup:getName()
|
||||||
|
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||||
|
self:E( { IniGroup = Event.IniGroup } )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if Event.target then
|
if Event.target then
|
||||||
@ -4953,11 +4997,27 @@ function EVENT:onEvent( Event )
|
|||||||
end
|
end
|
||||||
self:E( { _EVENTCODES[Event.id], Event, Event.IniDCSUnitName, Event.TgtDCSUnitName } )
|
self:E( { _EVENTCODES[Event.id], Event, Event.IniDCSUnitName, Event.TgtDCSUnitName } )
|
||||||
|
|
||||||
-- Okay, we got the event from DCS. Now loop the self.Events[] table for the received Event.id, and for each EventData registered, check if a function needs to be called.
|
local function pairsByEventSorted( EventSorted, Order )
|
||||||
for EventClass, EventData in pairs( self.Events[Event.id] ) do
|
local i = Order == -1 and #EventSorted or 0
|
||||||
|
local iter = function()
|
||||||
|
i = i + Order
|
||||||
|
if EventSorted[i] == nil then
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
return EventSorted[i].EventClass, EventSorted[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return iter
|
||||||
|
end
|
||||||
|
|
||||||
|
self:E( { Order = _EVENTORDER[Event.id] } )
|
||||||
|
|
||||||
|
-- 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 pairsByEventSorted( self.SortedEvents[Event.id], _EVENTORDER[Event.id] ) do
|
||||||
-- If the EventData is for a UNIT, the call directly the EventClass EventFunction for that UNIT.
|
-- 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
|
if Event.IniDCSUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniDCSUnitName] then
|
||||||
self:T( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName } )
|
self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventData.EventTime } )
|
||||||
|
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||||
local Result, Value = xpcall( function() return EventData.IniUnit[Event.IniDCSUnitName].EventFunction( EventData.IniUnit[Event.IniDCSUnitName].EventClass, Event ) end, ErrorHandler )
|
local Result, Value = xpcall( function() return EventData.IniUnit[Event.IniDCSUnitName].EventFunction( EventData.IniUnit[Event.IniDCSUnitName].EventClass, Event ) end, ErrorHandler )
|
||||||
--EventData.IniUnit[Event.IniDCSUnitName].EventFunction( EventData.IniUnit[Event.IniDCSUnitName].EventClass, Event )
|
--EventData.IniUnit[Event.IniDCSUnitName].EventFunction( EventData.IniUnit[Event.IniDCSUnitName].EventClass, Event )
|
||||||
else
|
else
|
||||||
@ -4965,7 +5025,8 @@ function EVENT:onEvent( Event )
|
|||||||
-- Note that here the EventFunction will need to implement and determine the logic for the relevant source- or target unit, or weapon.
|
-- 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 Event.IniDCSUnit and not EventData.IniUnit then
|
||||||
if EventClass == EventData.EventClass then
|
if EventClass == EventData.EventClass then
|
||||||
self:T( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID() } )
|
self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventData.EventTime } )
|
||||||
|
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||||
local Result, Value = xpcall( function() return EventData.EventFunction( EventData.EventClass, Event ) end, ErrorHandler )
|
local Result, Value = xpcall( function() return EventData.EventFunction( EventData.EventClass, Event ) end, ErrorHandler )
|
||||||
--EventData.EventFunction( EventData.EventClass, Event )
|
--EventData.EventFunction( EventData.EventClass, Event )
|
||||||
end
|
end
|
||||||
@ -5765,7 +5826,7 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self:F( { MenuGroup:GetName(), MenuText, ParentMenu.MenuPath } )
|
--self:F( { MenuGroup:GetName(), MenuText, ParentMenu.MenuPath } )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -5844,7 +5905,7 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self:F( { MenuGroup:GetName(), MenuText, ParentMenu.MenuPath } )
|
--self:F( { MenuGroup:GetName(), MenuText, ParentMenu.MenuPath } )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -6321,16 +6382,20 @@ end
|
|||||||
|
|
||||||
--- Returns a random location within the zone.
|
--- Returns a random location within the zone.
|
||||||
-- @param #ZONE_RADIUS self
|
-- @param #ZONE_RADIUS self
|
||||||
|
-- @param #number inner minimal distance from the center of the zone
|
||||||
|
-- @param #number outer minimal distance from the outer edge of the zone
|
||||||
-- @return Dcs.DCSTypes#Vec2 The random location within the zone.
|
-- @return Dcs.DCSTypes#Vec2 The random location within the zone.
|
||||||
function ZONE_RADIUS:GetRandomVec2()
|
function ZONE_RADIUS:GetRandomVec2(inner, outer)
|
||||||
self:F( self.ZoneName )
|
self:F( self.ZoneName, inner, outer )
|
||||||
|
|
||||||
local Point = {}
|
local Point = {}
|
||||||
local Vec2 = self:GetVec2()
|
local Vec2 = self:GetVec2()
|
||||||
|
local _inner = inner or 0
|
||||||
|
local _outer = outer or self:GetRadius()
|
||||||
|
|
||||||
local angle = math.random() * math.pi*2;
|
local angle = math.random() * math.pi * 2;
|
||||||
Point.x = Vec2.x + math.cos( angle ) * math.random() * self:GetRadius();
|
Point.x = Vec2.x + math.cos( angle ) * math.random(_inner, _outer);
|
||||||
Point.y = Vec2.y + math.sin( angle ) * math.random() * self:GetRadius();
|
Point.y = Vec2.y + math.sin( angle ) * math.random(_inner, _outer);
|
||||||
|
|
||||||
self:T( { Point } )
|
self:T( { Point } )
|
||||||
|
|
||||||
@ -6757,6 +6822,8 @@ DATABASE = {
|
|||||||
CLIENTS = {},
|
CLIENTS = {},
|
||||||
AIRBASES = {},
|
AIRBASES = {},
|
||||||
NavPoints = {},
|
NavPoints = {},
|
||||||
|
EventPriority = 1, -- Used to sort the DCS event order processing (complicated). Database has highest priority.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
local _DATABASECoalition =
|
local _DATABASECoalition =
|
||||||
@ -6930,6 +6997,7 @@ end
|
|||||||
function DATABASE:AddGroup( GroupName )
|
function DATABASE:AddGroup( GroupName )
|
||||||
|
|
||||||
if not self.GROUPS[GroupName] then
|
if not self.GROUPS[GroupName] then
|
||||||
|
self:E( { "Add GROUP:", GroupName } )
|
||||||
self.GROUPS[GroupName] = GROUP:Register( GroupName )
|
self.GROUPS[GroupName] = GROUP:Register( GroupName )
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -7271,6 +7339,8 @@ function DATABASE:_EventOnPlayerEnterUnit( Event )
|
|||||||
self:F2( { Event } )
|
self:F2( { Event } )
|
||||||
|
|
||||||
if Event.IniUnit then
|
if Event.IniUnit then
|
||||||
|
self:AddUnit( Event.IniDCSUnitName )
|
||||||
|
self:AddGroup( Event.IniDCSGroupName )
|
||||||
local PlayerName = Event.IniUnit:GetPlayerName()
|
local PlayerName = Event.IniUnit:GetPlayerName()
|
||||||
if not self.PLAYERS[PlayerName] then
|
if not self.PLAYERS[PlayerName] then
|
||||||
self:AddPlayer( Event.IniUnitName, PlayerName )
|
self:AddPlayer( Event.IniUnitName, PlayerName )
|
||||||
@ -7721,6 +7791,7 @@ SET_BASE = {
|
|||||||
Filter = {},
|
Filter = {},
|
||||||
Set = {},
|
Set = {},
|
||||||
List = {},
|
List = {},
|
||||||
|
EventPriority = 2, -- Used to sort the DCS event order processing (complicated)
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Creates a new SET_BASE object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.
|
--- Creates a new SET_BASE object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.
|
||||||
@ -22398,7 +22469,7 @@ function AIRBASEPOLICE_BASE:_AirbaseMonitor()
|
|||||||
Client:SetState( self, "Warnings", SpeedingWarnings + 1 )
|
Client:SetState( self, "Warnings", SpeedingWarnings + 1 )
|
||||||
else
|
else
|
||||||
MESSAGE:New( "Player " .. Client:GetPlayerName() .. " has been removed from the airbase, due to a speeding violation ...", 10, "Airbase Police" ):ToAll()
|
MESSAGE:New( "Player " .. Client:GetPlayerName() .. " has been removed from the airbase, due to a speeding violation ...", 10, "Airbase Police" ):ToAll()
|
||||||
Client:GetGroup():Destroy()
|
Client:Destroy()
|
||||||
Client:SetState( self, "Speeding", false )
|
Client:SetState( self, "Speeding", false )
|
||||||
Client:SetState( self, "Warnings", 0 )
|
Client:SetState( self, "Warnings", 0 )
|
||||||
end
|
end
|
||||||
@ -24867,13 +24938,14 @@ AI_PATROL_ZONE = {
|
|||||||
-- @param Dcs.DCSTypes#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
|
-- @param Dcs.DCSTypes#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
|
||||||
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h.
|
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h.
|
||||||
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
|
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
|
||||||
|
-- @param Dcs.DCSTypes#AltitudeType PatrolAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to RADIO
|
||||||
-- @return #AI_PATROL_ZONE self
|
-- @return #AI_PATROL_ZONE self
|
||||||
-- @usage
|
-- @usage
|
||||||
-- -- Define a new AI_PATROL_ZONE Object. This PatrolArea will patrol an AIControllable within PatrolZone between 3000 and 6000 meters, with a variying speed between 600 and 900 km/h.
|
-- -- Define a new AI_PATROL_ZONE Object. This PatrolArea will patrol an AIControllable within PatrolZone between 3000 and 6000 meters, with a variying speed between 600 and 900 km/h.
|
||||||
-- PatrolZone = ZONE:New( 'PatrolZone' )
|
-- PatrolZone = ZONE:New( 'PatrolZone' )
|
||||||
-- PatrolSpawn = SPAWN:New( 'Patrol Group' )
|
-- PatrolSpawn = SPAWN:New( 'Patrol Group' )
|
||||||
-- PatrolArea = AI_PATROL_ZONE:New( PatrolZone, 3000, 6000, 600, 900 )
|
-- PatrolArea = AI_PATROL_ZONE:New( PatrolZone, 3000, 6000, 600, 900 )
|
||||||
function AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed )
|
function AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
|
||||||
|
|
||||||
-- Inherits from BASE
|
-- Inherits from BASE
|
||||||
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New() ) -- #AI_PATROL_ZONE
|
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New() ) -- #AI_PATROL_ZONE
|
||||||
@ -24885,6 +24957,9 @@ function AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltit
|
|||||||
self.PatrolMinSpeed = PatrolMinSpeed
|
self.PatrolMinSpeed = PatrolMinSpeed
|
||||||
self.PatrolMaxSpeed = PatrolMaxSpeed
|
self.PatrolMaxSpeed = PatrolMaxSpeed
|
||||||
|
|
||||||
|
-- defafult PatrolAltType to "RADIO" if not specified
|
||||||
|
self.PatrolAltType = PatrolAltType or "RADIO"
|
||||||
|
|
||||||
self:SetDetectionOn()
|
self:SetDetectionOn()
|
||||||
|
|
||||||
self.CheckStatus = true
|
self.CheckStatus = true
|
||||||
@ -25390,7 +25465,7 @@ function AI_PATROL_ZONE:onafterRoute( Controllable, From, Event, To )
|
|||||||
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
||||||
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
|
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
|
||||||
local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
|
local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
|
||||||
POINT_VEC3.RoutePointAltType.BARO,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TakeOffParking,
|
POINT_VEC3.RoutePointType.TakeOffParking,
|
||||||
POINT_VEC3.RoutePointAction.FromParkingArea,
|
POINT_VEC3.RoutePointAction.FromParkingArea,
|
||||||
ToPatrolZoneSpeed,
|
ToPatrolZoneSpeed,
|
||||||
@ -25405,7 +25480,7 @@ function AI_PATROL_ZONE:onafterRoute( Controllable, From, Event, To )
|
|||||||
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
||||||
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
|
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
|
||||||
local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
|
local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
|
||||||
POINT_VEC3.RoutePointAltType.BARO,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
ToPatrolZoneSpeed,
|
ToPatrolZoneSpeed,
|
||||||
@ -25431,7 +25506,7 @@ function AI_PATROL_ZONE:onafterRoute( Controllable, From, Event, To )
|
|||||||
|
|
||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local ToTargetRoutePoint = ToTargetPointVec3:RoutePointAir(
|
local ToTargetRoutePoint = ToTargetPointVec3:RoutePointAir(
|
||||||
POINT_VEC3.RoutePointAltType.BARO,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
ToTargetSpeed,
|
ToTargetSpeed,
|
||||||
@ -25519,7 +25594,7 @@ function AI_PATROL_ZONE:onafterRTB()
|
|||||||
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
||||||
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
|
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
|
||||||
local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
|
local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
|
||||||
POINT_VEC3.RoutePointAltType.BARO,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
ToPatrolZoneSpeed,
|
ToPatrolZoneSpeed,
|
||||||
@ -25709,12 +25784,13 @@ AI_CAS_ZONE = {
|
|||||||
-- @param Dcs.DCSTypes#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
|
-- @param Dcs.DCSTypes#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
|
||||||
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h.
|
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h.
|
||||||
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
|
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
|
||||||
|
-- @param Dcs.DCSTypes#AltitudeType PatrolAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to RADIO
|
||||||
-- @param Core.Zone#ZONE EngageZone
|
-- @param Core.Zone#ZONE EngageZone
|
||||||
-- @return #AI_CAS_ZONE self
|
-- @return #AI_CAS_ZONE self
|
||||||
function AI_CAS_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, EngageZone )
|
function AI_CAS_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, EngageZone, PatrolAltType )
|
||||||
|
|
||||||
-- Inherits from BASE
|
-- Inherits from BASE
|
||||||
local self = BASE:Inherit( self, AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed ) ) -- #AI_CAS_ZONE
|
local self = BASE:Inherit( self, AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType ) ) -- #AI_CAS_ZONE
|
||||||
|
|
||||||
self.EngageZone = EngageZone
|
self.EngageZone = EngageZone
|
||||||
self.Accomplished = false
|
self.Accomplished = false
|
||||||
@ -25953,7 +26029,7 @@ function AI_CAS_ZONE:onafterEngage( Controllable, From, Event, To )
|
|||||||
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
||||||
local ToEngageZoneSpeed = self.PatrolMaxSpeed
|
local ToEngageZoneSpeed = self.PatrolMaxSpeed
|
||||||
local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
|
local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
|
||||||
POINT_VEC3.RoutePointAltType.BARO,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
ToEngageZoneSpeed,
|
ToEngageZoneSpeed,
|
||||||
@ -25979,7 +26055,7 @@ function AI_CAS_ZONE:onafterEngage( Controllable, From, Event, To )
|
|||||||
|
|
||||||
-- Create a route point of type air.
|
-- Create a route point of type air.
|
||||||
local ToEngageZoneRoutePoint = ToEngageZonePointVec3:RoutePointAir(
|
local ToEngageZoneRoutePoint = ToEngageZonePointVec3:RoutePointAir(
|
||||||
POINT_VEC3.RoutePointAltType.BARO,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
ToEngageZoneSpeed,
|
ToEngageZoneSpeed,
|
||||||
@ -26006,7 +26082,7 @@ function AI_CAS_ZONE:onafterEngage( Controllable, From, Event, To )
|
|||||||
|
|
||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local ToTargetRoutePoint = ToTargetPointVec3:RoutePointAir(
|
local ToTargetRoutePoint = ToTargetPointVec3:RoutePointAir(
|
||||||
POINT_VEC3.RoutePointAltType.BARO,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
ToTargetSpeed,
|
ToTargetSpeed,
|
||||||
@ -26220,11 +26296,12 @@ AI_CAP_ZONE = {
|
|||||||
-- @param Dcs.DCSTypes#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
|
-- @param Dcs.DCSTypes#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
|
||||||
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h.
|
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h.
|
||||||
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
|
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
|
||||||
|
-- @param Dcs.DCSTypes#AltitudeType PatrolAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to RADIO
|
||||||
-- @return #AI_CAP_ZONE self
|
-- @return #AI_CAP_ZONE self
|
||||||
function AI_CAP_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed )
|
function AI_CAP_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
|
||||||
|
|
||||||
-- Inherits from BASE
|
-- Inherits from BASE
|
||||||
local self = BASE:Inherit( self, AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed ) ) -- #AI_CAP_ZONE
|
local self = BASE:Inherit( self, AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType ) ) -- #AI_CAP_ZONE
|
||||||
|
|
||||||
self.Accomplished = false
|
self.Accomplished = false
|
||||||
self.Engaging = false
|
self.Engaging = false
|
||||||
@ -26501,7 +26578,7 @@ function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
|
|||||||
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
||||||
local ToEngageZoneSpeed = self.PatrolMaxSpeed
|
local ToEngageZoneSpeed = self.PatrolMaxSpeed
|
||||||
local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
|
local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
|
||||||
POINT_VEC3.RoutePointAltType.BARO,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
ToEngageZoneSpeed,
|
ToEngageZoneSpeed,
|
||||||
@ -26525,7 +26602,7 @@ function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
|
|||||||
|
|
||||||
--- Create a route point of type air.
|
--- Create a route point of type air.
|
||||||
local ToPatrolRoutePoint = ToTargetPointVec3:RoutePointAir(
|
local ToPatrolRoutePoint = ToTargetPointVec3:RoutePointAir(
|
||||||
POINT_VEC3.RoutePointAltType.BARO,
|
self.PatrolAltType,
|
||||||
POINT_VEC3.RoutePointType.TurningPoint,
|
POINT_VEC3.RoutePointType.TurningPoint,
|
||||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||||
ToTargetSpeed,
|
ToTargetSpeed,
|
||||||
@ -28739,7 +28816,8 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
|||||||
local PlayerUnit = EventData.IniUnit
|
local PlayerUnit = EventData.IniUnit
|
||||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||||
local Mission = Mission -- Tasking.Mission#MISSION
|
local Mission = Mission -- Tasking.Mission#MISSION
|
||||||
Mission:JoinUnit( PlayerUnit )
|
local PlayerGroup = EventData.IniGroup -- The GROUP object should be filled!
|
||||||
|
Mission:JoinUnit( PlayerUnit, PlayerGroup )
|
||||||
Mission:ReportDetails()
|
Mission:ReportDetails()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -28758,7 +28836,8 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
|||||||
local PlayerUnit = EventData.IniUnit
|
local PlayerUnit = EventData.IniUnit
|
||||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||||
local Mission = Mission -- Tasking.Mission#MISSION
|
local Mission = Mission -- Tasking.Mission#MISSION
|
||||||
Mission:JoinUnit( PlayerUnit )
|
local PlayerGroup = EventData.IniGroup -- The GROUP object should be filled!
|
||||||
|
Mission:JoinUnit( PlayerUnit, PlayerGroup )
|
||||||
Mission:ReportDetails()
|
Mission:ReportDetails()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -28773,6 +28852,7 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
|||||||
function( self, EventData )
|
function( self, EventData )
|
||||||
local PlayerUnit = EventData.IniUnit
|
local PlayerUnit = EventData.IniUnit
|
||||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||||
|
local Mission = Mission -- Tasking.Mission#MISSION
|
||||||
Mission:AbortUnit( PlayerUnit )
|
Mission:AbortUnit( PlayerUnit )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -29040,15 +29120,16 @@ end
|
|||||||
-- If the Unit is part of a Task in the Mission, true is returned.
|
-- If the Unit is part of a Task in the Mission, true is returned.
|
||||||
-- @param #MISSION self
|
-- @param #MISSION self
|
||||||
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player joining the Mission.
|
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player joining the Mission.
|
||||||
|
-- @param Wrapper.Group#GROUP PlayerGroup The GROUP of the player joining the Mission.
|
||||||
-- @return #boolean true if Unit is part of a Task in the Mission.
|
-- @return #boolean true if Unit is part of a Task in the Mission.
|
||||||
function MISSION:JoinUnit( PlayerUnit )
|
function MISSION:JoinUnit( PlayerUnit, PlayerGroup )
|
||||||
self:F( { PlayerUnit = PlayerUnit } )
|
self:F( { PlayerUnit = PlayerUnit, PlayerGroup = PlayerGroup } )
|
||||||
|
|
||||||
local PlayerUnitAdded = false
|
local PlayerUnitAdded = false
|
||||||
|
|
||||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||||
local Task = Task -- Tasking.Task#TASK
|
local Task = Task -- Tasking.Task#TASK
|
||||||
if Task:JoinUnit( PlayerUnit ) then
|
if Task:JoinUnit( PlayerUnit, PlayerGroup ) then
|
||||||
PlayerUnitAdded = true
|
PlayerUnitAdded = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -30125,14 +30206,14 @@ end
|
|||||||
-- If the Unit is part of the Task, true is returned.
|
-- If the Unit is part of the Task, true is returned.
|
||||||
-- @param #TASK self
|
-- @param #TASK self
|
||||||
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player joining the Mission.
|
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player joining the Mission.
|
||||||
|
-- @param Wrapper.Group#GROUP PlayerGroup The GROUP of the player joining the Mission.
|
||||||
-- @return #boolean true if Unit is part of the Task.
|
-- @return #boolean true if Unit is part of the Task.
|
||||||
function TASK:JoinUnit( PlayerUnit )
|
function TASK:JoinUnit( PlayerUnit, PlayerGroup )
|
||||||
self:F( { PlayerUnit = PlayerUnit } )
|
self:F( { PlayerUnit = PlayerUnit, PlayerGroup = PlayerGroup } )
|
||||||
|
|
||||||
local PlayerUnitAdded = false
|
local PlayerUnitAdded = false
|
||||||
|
|
||||||
local PlayerGroups = self:GetGroups()
|
local PlayerGroups = self:GetGroups()
|
||||||
local PlayerGroup = PlayerUnit:GetGroup()
|
|
||||||
|
|
||||||
-- Is the PlayerGroup part of the PlayerGroups?
|
-- Is the PlayerGroup part of the PlayerGroups?
|
||||||
if PlayerGroups:IsIncludeObject( PlayerGroup ) then
|
if PlayerGroups:IsIncludeObject( PlayerGroup ) then
|
||||||
@ -30285,7 +30366,6 @@ end
|
|||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
function TASK:HasGroup( FindGroup )
|
function TASK:HasGroup( FindGroup )
|
||||||
|
|
||||||
self:GetGroups():FilterOnce() -- Ensure that the filter is updated.
|
|
||||||
return self:GetGroups():IsIncludeObject( FindGroup )
|
return self:GetGroups():IsIncludeObject( FindGroup )
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -30911,7 +30991,7 @@ end
|
|||||||
|
|
||||||
|
|
||||||
end -- Reporting
|
end -- Reporting
|
||||||
-- This module contains the DETECTION_MANAGER class and derived classes.
|
--- This module contains the DETECTION_MANAGER class and derived classes.
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
env.info( '*** MOOSE STATIC INCLUDE START *** ' )
|
env.info( '*** MOOSE STATIC INCLUDE START *** ' )
|
||||||
env.info( 'Moose Generation Timestamp: "20170202_2257"' )
|
env.info( 'Moose Generation Timestamp: 20170203_2208' )
|
||||||
local base = _G
|
local base = _G
|
||||||
|
|
||||||
Include = {}
|
Include = {}
|
||||||
@ -4211,6 +4211,7 @@ end
|
|||||||
EVENT = {
|
EVENT = {
|
||||||
ClassName = "EVENT",
|
ClassName = "EVENT",
|
||||||
ClassID = 0,
|
ClassID = 0,
|
||||||
|
SortedEvents = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
local _EVENTCODES = {
|
local _EVENTCODES = {
|
||||||
@ -4240,6 +4241,33 @@ local _EVENTCODES = {
|
|||||||
"S_EVENT_MAX",
|
"S_EVENT_MAX",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local _EVENTORDER = {
|
||||||
|
[world.event.S_EVENT_SHOT] = 1,
|
||||||
|
[world.event.S_EVENT_HIT] = 1,
|
||||||
|
[world.event.S_EVENT_TAKEOFF] = 1,
|
||||||
|
[world.event.S_EVENT_LAND] = 1,
|
||||||
|
[world.event.S_EVENT_CRASH] = -1,
|
||||||
|
[world.event.S_EVENT_EJECTION] = -1,
|
||||||
|
[world.event.S_EVENT_REFUELING] = 1,
|
||||||
|
[world.event.S_EVENT_DEAD] = -1,
|
||||||
|
[world.event.S_EVENT_PILOT_DEAD] = -1,
|
||||||
|
[world.event.S_EVENT_BASE_CAPTURED] = 1,
|
||||||
|
[world.event.S_EVENT_MISSION_START] = 1,
|
||||||
|
[world.event.S_EVENT_MISSION_END] = -1,
|
||||||
|
[world.event.S_EVENT_TOOK_CONTROL] = 1,
|
||||||
|
[world.event.S_EVENT_REFUELING_STOP] = 1,
|
||||||
|
[world.event.S_EVENT_BIRTH] = 1,
|
||||||
|
[world.event.S_EVENT_HUMAN_FAILURE] = 1,
|
||||||
|
[world.event.S_EVENT_ENGINE_STARTUP] = 1,
|
||||||
|
[world.event.S_EVENT_ENGINE_SHUTDOWN] = 1,
|
||||||
|
[world.event.S_EVENT_PLAYER_ENTER_UNIT] = 1,
|
||||||
|
[world.event.S_EVENT_PLAYER_LEAVE_UNIT] = -1,
|
||||||
|
[world.event.S_EVENT_PLAYER_COMMENT] = 1,
|
||||||
|
[world.event.S_EVENT_SHOOTING_START] = 1,
|
||||||
|
[world.event.S_EVENT_SHOOTING_END] = 1,
|
||||||
|
[world.event.S_EVENT_MAX] = 1,
|
||||||
|
}
|
||||||
|
|
||||||
--- The Event structure
|
--- The Event structure
|
||||||
-- @type EVENTDATA
|
-- @type EVENTDATA
|
||||||
-- @field id
|
-- @field id
|
||||||
@ -4292,7 +4320,7 @@ function EVENT:Init( EventID, EventClass )
|
|||||||
if not self.Events[EventID] then
|
if not self.Events[EventID] then
|
||||||
-- Create a WEAK table to ensure that the garbage collector is cleaning the event links when the object usage is cleaned.
|
-- Create a WEAK table to ensure that the garbage collector is cleaning the event links when the object usage is cleaned.
|
||||||
self.Events[EventID] = setmetatable( {}, { __mode = "k" } )
|
self.Events[EventID] = setmetatable( {}, { __mode = "k" } )
|
||||||
|
self.SortedEvents[EventID] = setmetatable( {}, { __mode = "k" } )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self.Events[EventID][EventClass] then
|
if not self.Events[EventID][EventClass] then
|
||||||
@ -4311,6 +4339,12 @@ function EVENT:Remove( EventClass, EventID )
|
|||||||
|
|
||||||
local EventClass = EventClass
|
local EventClass = EventClass
|
||||||
self.Events[EventID][EventClass] = nil
|
self.Events[EventID][EventClass] = nil
|
||||||
|
|
||||||
|
self.SortedEvents[EventID] = nil
|
||||||
|
self.SortedEvents[EventID] = {}
|
||||||
|
for EventClass, Event in pairs(self.Events[EventID]) do table.insert( self.SortedEvents[EventID], Event) end
|
||||||
|
table.sort( self.SortedEvents[EventID], function( Event1, Event2 ) return Event1.EventTime < Event2.EventTime end )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Clears all event subscriptions for a @{Core.Base#BASE} derived object.
|
--- Clears all event subscriptions for a @{Core.Base#BASE} derived object.
|
||||||
@ -4322,6 +4356,7 @@ function EVENT:RemoveAll( EventObject )
|
|||||||
local EventClass = EventObject:GetClassNameAndID()
|
local EventClass = EventObject:GetClassNameAndID()
|
||||||
for EventID, EventData in pairs( self.Events ) do
|
for EventID, EventData in pairs( self.Events ) do
|
||||||
self.Events[EventID][EventClass] = nil
|
self.Events[EventID][EventClass] = nil
|
||||||
|
self.SortedEvents[EventID] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -4355,6 +4390,13 @@ function EVENT:OnEventGeneric( EventFunction, EventClass, EventID )
|
|||||||
local Event = self:Init( EventID, EventClass )
|
local Event = self:Init( EventID, EventClass )
|
||||||
Event.EventFunction = EventFunction
|
Event.EventFunction = EventFunction
|
||||||
Event.EventClass = EventClass
|
Event.EventClass = EventClass
|
||||||
|
Event.EventTime = EventClass.EventPriority and EventClass.EventPriority or 10
|
||||||
|
|
||||||
|
self.SortedEvents[EventID] = nil
|
||||||
|
self.SortedEvents[EventID] = {}
|
||||||
|
for EventClass, Event in pairs(self.Events[EventID]) do table.insert( self.SortedEvents[EventID], Event) end
|
||||||
|
table.sort( self.SortedEvents[EventID], function( Event1, Event2 ) return Event1.EventTime < Event2.EventTime end )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -4931,6 +4973,8 @@ function EVENT:onEvent( Event )
|
|||||||
Event.IniDCSGroupName = ""
|
Event.IniDCSGroupName = ""
|
||||||
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
|
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
|
||||||
Event.IniDCSGroupName = Event.IniDCSGroup:getName()
|
Event.IniDCSGroupName = Event.IniDCSGroup:getName()
|
||||||
|
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||||
|
self:E( { IniGroup = Event.IniGroup } )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if Event.target then
|
if Event.target then
|
||||||
@ -4953,11 +4997,27 @@ function EVENT:onEvent( Event )
|
|||||||
end
|
end
|
||||||
self:E( { _EVENTCODES[Event.id], Event, Event.IniDCSUnitName, Event.TgtDCSUnitName } )
|
self:E( { _EVENTCODES[Event.id], Event, Event.IniDCSUnitName, Event.TgtDCSUnitName } )
|
||||||
|
|
||||||
-- Okay, we got the event from DCS. Now loop the self.Events[] table for the received Event.id, and for each EventData registered, check if a function needs to be called.
|
local function pairsByEventSorted( EventSorted, Order )
|
||||||
for EventClass, EventData in pairs( self.Events[Event.id] ) do
|
local i = Order == -1 and #EventSorted or 0
|
||||||
|
local iter = function()
|
||||||
|
i = i + Order
|
||||||
|
if EventSorted[i] == nil then
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
return EventSorted[i].EventClass, EventSorted[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return iter
|
||||||
|
end
|
||||||
|
|
||||||
|
self:E( { Order = _EVENTORDER[Event.id] } )
|
||||||
|
|
||||||
|
-- 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 pairsByEventSorted( self.SortedEvents[Event.id], _EVENTORDER[Event.id] ) do
|
||||||
-- If the EventData is for a UNIT, the call directly the EventClass EventFunction for that UNIT.
|
-- 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
|
if Event.IniDCSUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniDCSUnitName] then
|
||||||
self:T( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName } )
|
self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventData.EventTime } )
|
||||||
|
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||||
local Result, Value = xpcall( function() return EventData.IniUnit[Event.IniDCSUnitName].EventFunction( EventData.IniUnit[Event.IniDCSUnitName].EventClass, Event ) end, ErrorHandler )
|
local Result, Value = xpcall( function() return EventData.IniUnit[Event.IniDCSUnitName].EventFunction( EventData.IniUnit[Event.IniDCSUnitName].EventClass, Event ) end, ErrorHandler )
|
||||||
--EventData.IniUnit[Event.IniDCSUnitName].EventFunction( EventData.IniUnit[Event.IniDCSUnitName].EventClass, Event )
|
--EventData.IniUnit[Event.IniDCSUnitName].EventFunction( EventData.IniUnit[Event.IniDCSUnitName].EventClass, Event )
|
||||||
else
|
else
|
||||||
@ -4965,7 +5025,8 @@ function EVENT:onEvent( Event )
|
|||||||
-- Note that here the EventFunction will need to implement and determine the logic for the relevant source- or target unit, or weapon.
|
-- 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 Event.IniDCSUnit and not EventData.IniUnit then
|
||||||
if EventClass == EventData.EventClass then
|
if EventClass == EventData.EventClass then
|
||||||
self:T( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID() } )
|
self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventData.EventTime } )
|
||||||
|
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||||
local Result, Value = xpcall( function() return EventData.EventFunction( EventData.EventClass, Event ) end, ErrorHandler )
|
local Result, Value = xpcall( function() return EventData.EventFunction( EventData.EventClass, Event ) end, ErrorHandler )
|
||||||
--EventData.EventFunction( EventData.EventClass, Event )
|
--EventData.EventFunction( EventData.EventClass, Event )
|
||||||
end
|
end
|
||||||
@ -6761,6 +6822,8 @@ DATABASE = {
|
|||||||
CLIENTS = {},
|
CLIENTS = {},
|
||||||
AIRBASES = {},
|
AIRBASES = {},
|
||||||
NavPoints = {},
|
NavPoints = {},
|
||||||
|
EventPriority = 1, -- Used to sort the DCS event order processing (complicated). Database has highest priority.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
local _DATABASECoalition =
|
local _DATABASECoalition =
|
||||||
@ -6934,6 +6997,7 @@ end
|
|||||||
function DATABASE:AddGroup( GroupName )
|
function DATABASE:AddGroup( GroupName )
|
||||||
|
|
||||||
if not self.GROUPS[GroupName] then
|
if not self.GROUPS[GroupName] then
|
||||||
|
self:E( { "Add GROUP:", GroupName } )
|
||||||
self.GROUPS[GroupName] = GROUP:Register( GroupName )
|
self.GROUPS[GroupName] = GROUP:Register( GroupName )
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -7275,6 +7339,8 @@ function DATABASE:_EventOnPlayerEnterUnit( Event )
|
|||||||
self:F2( { Event } )
|
self:F2( { Event } )
|
||||||
|
|
||||||
if Event.IniUnit then
|
if Event.IniUnit then
|
||||||
|
self:AddUnit( Event.IniDCSUnitName )
|
||||||
|
self:AddGroup( Event.IniDCSGroupName )
|
||||||
local PlayerName = Event.IniUnit:GetPlayerName()
|
local PlayerName = Event.IniUnit:GetPlayerName()
|
||||||
if not self.PLAYERS[PlayerName] then
|
if not self.PLAYERS[PlayerName] then
|
||||||
self:AddPlayer( Event.IniUnitName, PlayerName )
|
self:AddPlayer( Event.IniUnitName, PlayerName )
|
||||||
@ -7725,6 +7791,7 @@ SET_BASE = {
|
|||||||
Filter = {},
|
Filter = {},
|
||||||
Set = {},
|
Set = {},
|
||||||
List = {},
|
List = {},
|
||||||
|
EventPriority = 2, -- Used to sort the DCS event order processing (complicated)
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Creates a new SET_BASE object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.
|
--- Creates a new SET_BASE object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.
|
||||||
@ -22402,7 +22469,7 @@ function AIRBASEPOLICE_BASE:_AirbaseMonitor()
|
|||||||
Client:SetState( self, "Warnings", SpeedingWarnings + 1 )
|
Client:SetState( self, "Warnings", SpeedingWarnings + 1 )
|
||||||
else
|
else
|
||||||
MESSAGE:New( "Player " .. Client:GetPlayerName() .. " has been removed from the airbase, due to a speeding violation ...", 10, "Airbase Police" ):ToAll()
|
MESSAGE:New( "Player " .. Client:GetPlayerName() .. " has been removed from the airbase, due to a speeding violation ...", 10, "Airbase Police" ):ToAll()
|
||||||
Client:GetGroup():Destroy()
|
Client:Destroy()
|
||||||
Client:SetState( self, "Speeding", false )
|
Client:SetState( self, "Speeding", false )
|
||||||
Client:SetState( self, "Warnings", 0 )
|
Client:SetState( self, "Warnings", 0 )
|
||||||
end
|
end
|
||||||
@ -28749,7 +28816,8 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
|||||||
local PlayerUnit = EventData.IniUnit
|
local PlayerUnit = EventData.IniUnit
|
||||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||||
local Mission = Mission -- Tasking.Mission#MISSION
|
local Mission = Mission -- Tasking.Mission#MISSION
|
||||||
Mission:JoinUnit( PlayerUnit )
|
local PlayerGroup = EventData.IniGroup -- The GROUP object should be filled!
|
||||||
|
Mission:JoinUnit( PlayerUnit, PlayerGroup )
|
||||||
Mission:ReportDetails()
|
Mission:ReportDetails()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -28768,7 +28836,8 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
|||||||
local PlayerUnit = EventData.IniUnit
|
local PlayerUnit = EventData.IniUnit
|
||||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||||
local Mission = Mission -- Tasking.Mission#MISSION
|
local Mission = Mission -- Tasking.Mission#MISSION
|
||||||
Mission:JoinUnit( PlayerUnit )
|
local PlayerGroup = EventData.IniGroup -- The GROUP object should be filled!
|
||||||
|
Mission:JoinUnit( PlayerUnit, PlayerGroup )
|
||||||
Mission:ReportDetails()
|
Mission:ReportDetails()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -28783,6 +28852,7 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
|||||||
function( self, EventData )
|
function( self, EventData )
|
||||||
local PlayerUnit = EventData.IniUnit
|
local PlayerUnit = EventData.IniUnit
|
||||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||||
|
local Mission = Mission -- Tasking.Mission#MISSION
|
||||||
Mission:AbortUnit( PlayerUnit )
|
Mission:AbortUnit( PlayerUnit )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -29050,15 +29120,16 @@ end
|
|||||||
-- If the Unit is part of a Task in the Mission, true is returned.
|
-- If the Unit is part of a Task in the Mission, true is returned.
|
||||||
-- @param #MISSION self
|
-- @param #MISSION self
|
||||||
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player joining the Mission.
|
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player joining the Mission.
|
||||||
|
-- @param Wrapper.Group#GROUP PlayerGroup The GROUP of the player joining the Mission.
|
||||||
-- @return #boolean true if Unit is part of a Task in the Mission.
|
-- @return #boolean true if Unit is part of a Task in the Mission.
|
||||||
function MISSION:JoinUnit( PlayerUnit )
|
function MISSION:JoinUnit( PlayerUnit, PlayerGroup )
|
||||||
self:F( { PlayerUnit = PlayerUnit } )
|
self:F( { PlayerUnit = PlayerUnit, PlayerGroup = PlayerGroup } )
|
||||||
|
|
||||||
local PlayerUnitAdded = false
|
local PlayerUnitAdded = false
|
||||||
|
|
||||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||||
local Task = Task -- Tasking.Task#TASK
|
local Task = Task -- Tasking.Task#TASK
|
||||||
if Task:JoinUnit( PlayerUnit ) then
|
if Task:JoinUnit( PlayerUnit, PlayerGroup ) then
|
||||||
PlayerUnitAdded = true
|
PlayerUnitAdded = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -30135,14 +30206,14 @@ end
|
|||||||
-- If the Unit is part of the Task, true is returned.
|
-- If the Unit is part of the Task, true is returned.
|
||||||
-- @param #TASK self
|
-- @param #TASK self
|
||||||
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player joining the Mission.
|
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player joining the Mission.
|
||||||
|
-- @param Wrapper.Group#GROUP PlayerGroup The GROUP of the player joining the Mission.
|
||||||
-- @return #boolean true if Unit is part of the Task.
|
-- @return #boolean true if Unit is part of the Task.
|
||||||
function TASK:JoinUnit( PlayerUnit )
|
function TASK:JoinUnit( PlayerUnit, PlayerGroup )
|
||||||
self:F( { PlayerUnit = PlayerUnit } )
|
self:F( { PlayerUnit = PlayerUnit, PlayerGroup = PlayerGroup } )
|
||||||
|
|
||||||
local PlayerUnitAdded = false
|
local PlayerUnitAdded = false
|
||||||
|
|
||||||
local PlayerGroups = self:GetGroups()
|
local PlayerGroups = self:GetGroups()
|
||||||
local PlayerGroup = PlayerUnit:GetGroup()
|
|
||||||
|
|
||||||
-- Is the PlayerGroup part of the PlayerGroups?
|
-- Is the PlayerGroup part of the PlayerGroups?
|
||||||
if PlayerGroups:IsIncludeObject( PlayerGroup ) then
|
if PlayerGroups:IsIncludeObject( PlayerGroup ) then
|
||||||
@ -30295,7 +30366,6 @@ end
|
|||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
function TASK:HasGroup( FindGroup )
|
function TASK:HasGroup( FindGroup )
|
||||||
|
|
||||||
self:GetGroups():FilterOnce() -- Ensure that the filter is updated.
|
|
||||||
return self:GetGroups():IsIncludeObject( FindGroup )
|
return self:GetGroups():IsIncludeObject( FindGroup )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user