From ba44e39344f4a472893864bb95f564579dc1b819 Mon Sep 17 00:00:00 2001 From: FlightControl Date: Wed, 20 Apr 2016 11:10:26 +0200 Subject: [PATCH 1/5] First version of new event handling ready. only for spawning, now we need to make this for the rest of the AddEvent handlers :-) --- Dcs/DCSworld.lua | 35 +++ Moose/Base.lua | 20 +- Moose/Event.lua | 282 ++++++++++++++++++ Moose/Spawn.lua | 42 ++- .../Moose_Test_SPAWN/MOOSE_Test_SPAWN.miz | Bin 45968 -> 46836 bytes .../MOOSE_Test_SPAWN_Repeat.miz | Bin 101907 -> 103416 bytes 6 files changed, 364 insertions(+), 15 deletions(-) create mode 100644 Dcs/DCSworld.lua create mode 100644 Moose/Event.lua diff --git a/Dcs/DCSworld.lua b/Dcs/DCSworld.lua new file mode 100644 index 000000000..5bcb203d2 --- /dev/null +++ b/Dcs/DCSworld.lua @@ -0,0 +1,35 @@ +------------------------------------------------------------------------------- +-- @module DCSWorld + +--- @type world +-- @field #world.event event + + +--- @type world.event +-- @field S_EVENT_INVALID +-- @field S_EVENT_SHOT +-- @field S_EVENT_HIT +-- @field S_EVENT_TAKEOFF +-- @field S_EVENT_LAND +-- @field S_EVENT_CRASH +-- @field S_EVENT_EJECTION +-- @field S_EVENT_REFUELING +-- @field S_EVENT_DEAD +-- @field S_EVENT_PILOT_DEAD +-- @field S_EVENT_BASE_CAPTURED +-- @field S_EVENT_MISSION_START +-- @field S_EVENT_MISSION_END +-- @field S_EVENT_TOOK_CONTROL +-- @field S_EVENT_REFUELING_STOP +-- @field S_EVENT_BIRTH +-- @field S_EVENT_HUMAN_FAILURE +-- @field S_EVENT_ENGINE_STARTUP +-- @field S_EVENT_ENGINE_SHUTDOWN +-- @field S_EVENT_PLAYER_ENTER_UNIT +-- @field S_EVENT_PLAYER_LEAVE_UNIT +-- @field S_EVENT_PLAYER_COMMENT +-- @field S_EVENT_SHOOTING_START +-- @field S_EVENT_SHOOTING_END +-- @field S_EVENT_MAX + +world = {} --#world \ No newline at end of file diff --git a/Moose/Base.lua b/Moose/Base.lua index f806d0c2e..d5b7d43b6 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -46,6 +46,8 @@ FORMATION = { Cone = "Cone" } + + --- The base constructor. This is the top top class of all classed defined within the MOOSE. -- Any new class needs to be derived from this class for proper inheritance. -- @param #BASE self @@ -140,6 +142,18 @@ function BASE:AddEvent( Event, EventFunction ) return self end +--- Returns the event dispatcher +-- @param #BASE self +-- @return Event#EVENT +function BASE:Event() + + return _EventDispatcher +end + + + + + --- Enable the event listeners for the class. -- @param #BASE self -- @return #BASE @@ -253,8 +267,8 @@ end -- @param #BASE self -- @param DCSTypes#Event event function BASE:onEvent(event) + --self:F( { BaseEventCodes[event.id], event } ) - --env.info( 'onEvent Table self = ' .. tostring(self) ) if self then for EventID, EventObject in pairs( self.Events ) do if EventObject.EventEnabled then @@ -269,8 +283,8 @@ function BASE:onEvent(event) if event.target and event.target:isExist() then event.TgtUnitName = event.target:getName() end - self:T( { BaseEventCodes[event.id], event } ) - EventObject.EventFunction( self, event ) + --self:T( { BaseEventCodes[event.id], event } ) + --EventObject.EventFunction( self, event ) end end end diff --git a/Moose/Event.lua b/Moose/Event.lua new file mode 100644 index 000000000..6346dbf4f --- /dev/null +++ b/Moose/Event.lua @@ -0,0 +1,282 @@ +--- The EVENT class models an efficient event handling process between other classes and its units, weapons. +-- @module Event +-- @author FlightControl + +Include.File( "Routines" ) +Include.File( "Base" ) + +--- The EVENT structure +-- @type EVENT +-- @field #EVENT.Events Events +EVENT = { + ClassName = "EVENT", + ClassID = 0, +} + +local EVENTCODES = { + "S_EVENT_SHOT", + "S_EVENT_HIT", + "S_EVENT_TAKEOFF", + "S_EVENT_LAND", + "S_EVENT_CRASH", + "S_EVENT_EJECTION", + "S_EVENT_REFUELING", + "S_EVENT_DEAD", + "S_EVENT_PILOT_DEAD", + "S_EVENT_BASE_CAPTURED", + "S_EVENT_MISSION_START", + "S_EVENT_MISSION_END", + "S_EVENT_TOOK_CONTROL", + "S_EVENT_REFUELING_STOP", + "S_EVENT_BIRTH", + "S_EVENT_HUMAN_FAILURE", + "S_EVENT_ENGINE_STARTUP", + "S_EVENT_ENGINE_SHUTDOWN", + "S_EVENT_PLAYER_ENTER_UNIT", + "S_EVENT_PLAYER_LEAVE_UNIT", + "S_EVENT_PLAYER_COMMENT", + "S_EVENT_SHOOTING_START", + "S_EVENT_SHOOTING_END", + "S_EVENT_MAX", +} + + +--- The Events structure +-- @type EVENT.Events +-- @field #number IniUnit + +function EVENT:New() + local self = BASE:Inherit( self, BASE:New() ) + self:F() + self.EventHandler = world.addEventHandler( self ) + return self +end + + +--- Initializes the Events structure for the event +-- @param #EVENT self +-- @param DCSWorld#world.event EventID +-- @param #string EventClass +-- @return #EVENT.Events +function EVENT:Init( EventID, EventClass ) + self:F( EventID, EventClass ) + if not self.Events[EventID] then + self.Events[EventID] = {} + end + if not self.Events[EventID][EventClass] then + self.Events[EventID][EventClass] = {} + end + if not self.Events[EventID][EventClass].IniUnit then + self.Events[EventID][EventClass].IniUnit = {} + end + return self.Events[EventID][EventClass] +end + + +--- Create an OnDead event handler for a group +-- @param #EVENT self +-- @param #table EventTemplate +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param EventSelf The self instance of the class for which the event is. +-- @param #function OnEventFunction +-- @return #EVENT +function EVENT:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, OnEventFunction ) + self:F( EventTemplate ) + + for EventUnitID, EventUnit in pairs( EventTemplate.units ) do + OnEventFunction( self, EventUnit.name, EventFunction, EventSelf ) + end + return self +end + + +--- Set a new listener for an S_EVENT_X event +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @param EventID +-- @return #EVENT +function EVENT:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, EventID ) + self:F( EventDCSUnitName ) + + local Event = self:Init( EventID, EventSelf:GetClassNameAndID() ) + Event.IniUnit[EventDCSUnitName] = {} + Event.IniUnit[EventDCSUnitName].EventFunction = EventFunction + Event.IniUnit[EventDCSUnitName].EventSelf = EventSelf + return self +end + + +--- Create an OnBirth event handler for a group +-- @param #EVENT self +-- @param Group#GROUP EventGroup +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnBirthForTemplate( EventTemplate, EventFunction, EventSelf ) + self:F( { EventTemplate } ) + + return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnBirth ) +end + +--- Set a new listener for an S_EVENT_BIRTH event. +-- @param #EVENT self +-- @param #string EventDCSUnitName The id of the unit for the event to be handled. +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf +-- @return #EVENT +function EVENT:OnBirth( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_BIRTH ) +end + +--- Create an OnCrash event handler for a group +-- @param #EVENT self +-- @param Group#GROUP EventGroup +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnCrashForTemplate( EventTemplate, EventFunction, EventSelf ) + self:F( EventTemplate ) + + return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnCrash ) +end + +--- Set a new listener for an S_EVENT_CRASH event. +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnCrash( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_CRASH ) +end + +--- Create an OnDead event handler for a group +-- @param #EVENT self +-- @param Group#GROUP EventGroup +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnDeadForTemplate( EventTemplate, EventFunction, EventSelf ) + self:F( EventTemplate ) + + return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnDead ) +end + +--- Set a new listener for an S_EVENT_DEAD event. +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnDead( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_DEAD ) +end + +--- Create an OnDead event handler for a group +-- @param #EVENT self +-- @param #table EventTemplate +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnLandForTemplate( EventTemplate, EventFunction, EventSelf ) + self:F( EventTemplate ) + + return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnLand ) +end + +--- Set a new listener for an S_EVENT_LAND event. +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnLand( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_LAND ) +end + +--- Create an OnDead event handler for a group +-- @param #EVENT self +-- @param #table EventTemplate +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnTakeOffForTemplate( EventTemplate, EventFunction, EventSelf ) + self:F( EventTemplate ) + + return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnTakeOff ) +end + +--- Set a new listener for an S_EVENT_LAND event. +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnTakeOff( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_TAKEOFF ) +end + +--- Create an OnDead event handler for a group +-- @param #EVENT self +-- @param #table EventTemplate +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnEngineShutDownForTemplate( EventTemplate, EventFunction, EventSelf ) + self:F( EventTemplate ) + + return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnEngineShutDown ) +end + +--- Set a new listener for an S_EVENT_LAND event. +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnEngineShutDown( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_ENGINE_SHUTDOWN ) +end + + + +function EVENT:onEvent( Event ) + self:F( { EVENTCODES[Event.id], Event } ) + + if self and self.Events and self.Events[Event.id] then + local IniDCSUnit = Event.initiator + if IniDCSUnit and IniDCSUnit:getCategory() == Object.Category.UNIT then + Event.IniUnitName = IniDCSUnit:getName() + end + local TgtDCSUnit = Event.target + if TgtDCSUnit and TgtDCSUnit:isExist() and TgtDCSUnit:getCategory() == Object.Category.UNIT then + Event.TgtUnitName = TgtDCSUnit:getName() + end + for ClassName, EventData in pairs( self.Events[Event.id] ) do + if Event.IniUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniUnitName] then + self:T( { "Calling event function for class ", ClassName, " unit ", Event.IniUnitName } ) + EventData.IniUnit[Event.IniUnitName].EventFunction( EventData.IniUnit[Event.IniUnitName].EventSelf, Event ) + end + end + end +end + + + +--- Declare the event dispatcher based on the EVENT class +_EventDispatcher = EVENT:New() -- #EVENT + diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index be3462ccf..f61f351ad 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -75,6 +75,7 @@ Include.File( "Base" ) Include.File( "Database" ) Include.File( "Group" ) Include.File( "Zone" ) +Include.File( "Event" ) --- SPAWN Class -- @type SPAWN @@ -122,9 +123,9 @@ function SPAWN:New( SpawnTemplatePrefix ) error( "SPAWN:New: There is no group declared in the mission editor with SpawnTemplatePrefix = '" .. SpawnTemplatePrefix .. "'" ) end - self:AddEvent( world.event.S_EVENT_BIRTH, self._OnBirth ) - self:AddEvent( world.event.S_EVENT_DEAD, self._OnDeadOrCrash ) - self:AddEvent( world.event.S_EVENT_CRASH, self._OnDeadOrCrash ) + --self:AddEvent( world.event.S_EVENT_BIRTH, self._OnBirth ) + --self:AddEvent( world.event.S_EVENT_DEAD, self._OnDeadOrCrash ) + --self:AddEvent( world.event.S_EVENT_CRASH, self._OnDeadOrCrash ) self:EnableEvents() @@ -165,11 +166,11 @@ function SPAWN:NewWithAlias( SpawnTemplatePrefix, SpawnAliasPrefix ) error( "SPAWN:New: There is no group declared in the mission editor with SpawnTemplatePrefix = '" .. SpawnTemplatePrefix .. "'" ) end - self:AddEvent( world.event.S_EVENT_BIRTH, self._OnBirth ) - self:AddEvent( world.event.S_EVENT_DEAD, self._OnDeadOrCrash ) - self:AddEvent( world.event.S_EVENT_CRASH, self._OnDeadOrCrash ) + --self:AddEvent( world.event.S_EVENT_BIRTH, self._OnBirth ) + --self:AddEvent( world.event.S_EVENT_DEAD, self._OnDeadOrCrash ) + --self:AddEvent( world.event.S_EVENT_CRASH, self._OnDeadOrCrash ) - self:EnableEvents() + --self:EnableEvents() return self end @@ -282,16 +283,16 @@ end -- -- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically. -- SpawnRU_SU34 = SPAWN:New( 'TF1 RU Su-34 Krymsk@AI - Attack Ships' ):Schedule( 2, 3, 1800, 0.4 ):SpawnUncontrolled():RandomizeRoute( 1, 1, 3000 ):RepeatOnEngineShutDown() function SPAWN:Repeat() - self:F( { self.SpawnTemplatePrefix } ) + self:F( { self.SpawnTemplatePrefix, self.SpawnIndex } ) self.SpawnRepeat = true self.RepeatOnEngineShutDown = false self.RepeatOnLanding = true - self:AddEvent( world.event.S_EVENT_LAND, self._OnLand ) - self:AddEvent( world.event.S_EVENT_TAKEOFF, self._OnTakeOff ) - self:AddEvent( world.event.S_EVENT_ENGINE_SHUTDOWN, self._OnEngineShutDown ) - self:EnableEvents() + --self:AddEvent( world.event.S_EVENT_LAND, self._OnLand ) + --self:AddEvent( world.event.S_EVENT_TAKEOFF, self._OnTakeOff ) + --self:AddEvent( world.event.S_EVENT_ENGINE_SHUTDOWN, self._OnEngineShutDown ) + --self:EnableEvents() return self end @@ -386,6 +387,9 @@ function SPAWN:Array( SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY ) self.SpawnGroups[SpawnGroupID].Visible = true self.SpawnGroups[SpawnGroupID].Group = _Database:Spawn( self.SpawnGroups[SpawnGroupID].SpawnTemplate ) + self:Event():OnBirthForGroup( self.SpawnGroups[SpawnGroupID].Group, self._OnBirth, self ) + self:Event():OnCrashForGroup( self.SpawnGroups[SpawnGroupID].Group, self._OnBirth, self ) + self:Event():OnDeadForGroup ( self.SpawnGroups[SpawnGroupID].Group, self._OnBirth, self ) SpawnX = SpawnXIndex * SpawnDeltaX SpawnY = SpawnYIndex * SpawnDeltaY @@ -443,6 +447,20 @@ function SPAWN:SpawnWithIndex( SpawnIndex ) self.SpawnGroups[self.SpawnIndex].Group:Activate() else self:T( self.SpawnGroups[self.SpawnIndex].SpawnTemplate ) + _EventDispatcher:OnBirthForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnBirth, self ) + _EventDispatcher:OnCrashForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnDeadOrCrash, self ) + _EventDispatcher:OnDeadForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnDeadOrCrash, self ) + + if self.SpawnRepeat then + _EventDispatcher:OnTakeOffForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnTakeOff, self ) + end + if self.RepeatOnLanding then + _EventDispatcher:OnLandForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnLand, self ) + end + if self.RepeatOnEngineShutDown then + _EventDispatcher:OnEngineShutDownForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnEngineShutDown, self ) + end + self.SpawnGroups[self.SpawnIndex].Group = _Database:Spawn( self.SpawnGroups[self.SpawnIndex].SpawnTemplate ) -- If there is a SpawnFunction hook defined, call it. diff --git a/Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.miz b/Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.miz index 361cf596fceb5faab54985690e428d1d731f2e6d..4a1b110f25028c6eb1c3f2a05b25574751a4098e 100644 GIT binary patch delta 33650 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 gUH+#)VD@to(zyNT7&_mBagMQNpEST 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°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 delta 99425 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%0AC+tN}=jP(E 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 WLVa8b5D4kx6$=3Z*+u-z+W!Kj$=|{N From 66c7ebf7867a106ec8f27e02c32ae081062b22e6 Mon Sep 17 00:00:00 2001 From: FlightControl Date: Wed, 20 Apr 2016 21:59:37 +0200 Subject: [PATCH 2/5] Further optimization of the Event Dispatcher. Also fixed a problem with DESTROYGROUPTASK --- Moose/CleanUp.lua | 131 ++++++------ Moose/Database.lua | 10 +- Moose/DestroyBaseTask.lua | 43 ++-- Moose/DestroyGroupsTask.lua | 39 ++-- Moose/DestroyRadarsTask.lua | 4 +- Moose/DestroyUnitTypesTask.lua | 2 +- Moose/Event.lua | 194 +++++++++++++++--- Moose/Movement.lua | 42 ++-- Moose/Sead.lua | 18 +- Moose/Spawn.lua | 35 ++-- Moose/Task.lua | 43 ++-- .../Moose_Test_DESTROY/MOOSE_Test_DESTROY.miz | Bin 0 -> 29167 bytes .../Moose_Test_DESTROY/Moose_Test_DESTROY.lua | 41 ++++ .../Moose_Test_SEAD/MOOSE_Test_SEAD.miz | Bin 0 -> 20851 bytes .../Moose_Test_SEAD/Moose_Test_SEAD.lua | 11 + 15 files changed, 396 insertions(+), 217 deletions(-) create mode 100644 Test Missions/Moose_Test_DESTROY/MOOSE_Test_DESTROY.miz create mode 100644 Test Missions/Moose_Test_DESTROY/Moose_Test_DESTROY.lua create mode 100644 Test Missions/Moose_Test_SEAD/MOOSE_Test_SEAD.miz create mode 100644 Test Missions/Moose_Test_SEAD/Moose_Test_SEAD.lua diff --git a/Moose/CleanUp.lua b/Moose/CleanUp.lua index 4c05fadc6..ac28d7738 100644 --- a/Moose/CleanUp.lua +++ b/Moose/CleanUp.lua @@ -40,15 +40,8 @@ function CLEANUP:New( ZoneNames, TimeInterval ) local self = BASE:Inherit( self, self.TimeInterval = TimeInterval end - self:AddEvent( world.event.S_EVENT_ENGINE_SHUTDOWN, self._EventAddForCleanUp ) - self:AddEvent( world.event.S_EVENT_ENGINE_STARTUP, self._EventAddForCleanUp ) - self:AddEvent( world.event.S_EVENT_HIT, self._EventAddForCleanUp ) -- , self._EventHitCleanUp ) - self:AddEvent( world.event.S_EVENT_CRASH, self._EventCrash ) -- , self._EventHitCleanUp ) - --self:AddEvent( world.event.S_EVENT_DEAD, self._EventCrash ) - self:AddEvent( world.event.S_EVENT_SHOT, self._EventShot ) + _EventDispatcher:OnBirth( self._OnEventBirth, self ) - self:EnableEvents() - self.CleanUpScheduler = routines.scheduleFunction( self._CleanUpScheduler, { self }, timer.getTime() + 1, TimeInterval ) return self @@ -111,6 +104,33 @@ function CLEANUP:_DestroyMissile( MissileObject ) end end +function CLEANUP:_OnEventBirth( Event ) + self:F( { Event } ) + + self.CleanUpList[Event.IniDCSUnitName] = {} + self.CleanUpList[Event.IniDCSUnitName].CleanUpUnit = Event.IniDCSUnit + self.CleanUpList[Event.IniDCSUnitName].CleanUpGroup = Event.IniDCSGroup + self.CleanUpList[Event.IniDCSUnitName].CleanUpGroupName = Event.IniDCSGroupName + self.CleanUpList[Event.IniDCSUnitName].CleanUpUnitName = Event.IniDCSUnitName + + _EventDispatcher:OnEngineShutDownForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) + _EventDispatcher:OnEngineStartUpForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) + _EventDispatcher:OnHitForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) + _EventDispatcher:OnCrashForUnit( Event.IniDCSUnitName, self._EventCrash, self ) + _EventDispatcher:OnShotForUnit( Event.IniDCSUnitName, self._EventShot, self ) + + --self:AddEvent( world.event.S_EVENT_ENGINE_SHUTDOWN, self._EventAddForCleanUp ) + --self:AddEvent( world.event.S_EVENT_ENGINE_STARTUP, self._EventAddForCleanUp ) +-- self:AddEvent( world.event.S_EVENT_HIT, self._EventAddForCleanUp ) -- , self._EventHitCleanUp ) +-- self:AddEvent( world.event.S_EVENT_CRASH, self._EventCrash ) -- , self._EventHitCleanUp ) +-- --self:AddEvent( world.event.S_EVENT_DEAD, self._EventCrash ) +-- self:AddEvent( world.event.S_EVENT_SHOT, self._EventShot ) +-- +-- self:EnableEvents() + + +end + --- Detects if a crash event occurs. -- Crashed units go into a CleanUpList for removal. -- @param #CLEANUP self @@ -126,44 +146,27 @@ function CLEANUP:_EventCrash( event ) -- self:T("after deactivateGroup") -- event.initiator:destroy() - local CleanUpUnit = event.initiator -- the Unit - local CleanUpUnitName = CleanUpUnit:getName() -- return the name of the Unit - local CleanUpGroup = Unit.getGroup(CleanUpUnit)-- Identify the Group - local CleanUpGroupName = "" - if CleanUpGroup and CleanUpGroup:isExist() then - CleanUpGroupName = CleanUpGroup:getName() -- return the name of the Group - end - - self.CleanUpList[CleanUpUnitName] = {} - self.CleanUpList[CleanUpUnitName].CleanUpUnit = CleanUpUnit - self.CleanUpList[CleanUpUnitName].CleanUpGroup = CleanUpGroup - self.CleanUpList[CleanUpUnitName].CleanUpGroupName = CleanUpGroupName - self.CleanUpList[CleanUpUnitName].CleanUpUnitName = CleanUpUnitName + self.CleanUpList[Event.IniDCSUnitName] = {} + self.CleanUpList[Event.IniDCSUnitName].CleanUpUnit = Event.IniDCSUnit + self.CleanUpList[Event.IniDCSUnitName].CleanUpGroup = Event.IniDCSGroup + self.CleanUpList[Event.IniDCSUnitName].CleanUpGroupName = Event.IniDCSGroupName + self.CleanUpList[Event.IniDCSUnitName].CleanUpUnitName = Event.IniDCSUnitName end --- Detects if a unit shoots a missile. -- If this occurs within one of the zones, then the weapon used must be destroyed. -- @param #CLEANUP self -- @param DCSTypes#Event event -function CLEANUP:_EventShot( event ) - self:F( { event } ) +function CLEANUP:_EventShot( Event ) + self:F( { Event } ) - local _grp = Unit.getGroup(event.initiator)-- Identify the group that fired - local _groupname = _grp:getName() -- return the name of the group - local _unittable = {event.initiator:getName()} -- return the name of the units in the group - local _SEADmissile = event.weapon -- Identify the weapon fired - --local _SEADmissileName = _SEADmissile:getTypeName() -- return weapon type - --trigger.action.outText( string.format("Alerte, depart missile " ..string.format(_SEADmissileName)), 20) --debug message - -- Start of the 2nd loop - --self:T( "Missile Launched = " .. _SEADmissileName ) - -- Test if the missile was fired within one of the CLEANUP.ZoneNames. local CurrentLandingZoneID = 0 - CurrentLandingZoneID = routines.IsUnitInZones( event.initiator, self.ZoneNames ) + CurrentLandingZoneID = routines.IsUnitInZones( Event.IniDCSUnit, self.ZoneNames ) if ( CurrentLandingZoneID ) then -- Okay, the missile was fired within the CLEANUP.ZoneNames, destroy the fired weapon. --_SEADmissile:destroy() - routines.scheduleFunction( CLEANUP._DestroyMissile, {self, _SEADmissile}, timer.getTime() + 0.1) + routines.scheduleFunction( CLEANUP._DestroyMissile, { self, Event.Weapon }, timer.getTime() + 0.1) end end @@ -171,38 +174,28 @@ end --- Detects if the Unit has an S_EVENT_HIT within the given ZoneNames. If this is the case, destroy the unit. -- @param #CLEANUP self -- @param DCSTypes#Event event -function CLEANUP:_EventHitCleanUp( event ) - self:F( { event } ) +function CLEANUP:_EventHitCleanUp( Event ) + self:F( { Event } ) - local CleanUpUnit = event.initiator -- the Unit - if CleanUpUnit and CleanUpUnit:isExist() and Object.getCategory(CleanUpUnit) == Object.Category.UNIT then - local CleanUpUnitName = event.initiator:getName() -- return the name of the Unit - - if routines.IsUnitInZones( CleanUpUnit, self.ZoneNames ) ~= nil then - self:T( "Life: " .. CleanUpUnitName .. ' = ' .. CleanUpUnit:getLife() .. "/" .. CleanUpUnit:getLife0() ) - if CleanUpUnit:getLife() < CleanUpUnit:getLife0() then - self:T( "CleanUp: Destroy: " .. CleanUpUnitName ) - routines.scheduleFunction( CLEANUP._DestroyUnit, {self, CleanUpUnit}, timer.getTime() + 0.1) + if Event.IniDCSUnit then + if routines.IsUnitInZones( Event.IniDCSUnit, self.ZoneNames ) ~= nil then + self:T( { "Life: ", Event.IniDCSUnitName, ' = ', Event.IniDCSUnit:getLife(), "/", Event.IniDCSUnit:getLife0() } ) + if Event.IniDCSUnit:getLife() < Event.IniDCSUnit:getLife0() then + self:T( "CleanUp: Destroy: " .. Event.IniDCSUnitName ) + routines.scheduleFunction( CLEANUP._DestroyUnit, { self, Event.IniDCSUnit }, timer.getTime() + 0.1) end end end - local CleanUpTgtUnit = event.target -- the target Unit - if CleanUpTgtUnit and CleanUpTgtUnit:isExist() and Object.getCategory(CleanUpTgtUnit) == Object.Category.UNIT then - local CleanUpTgtUnitName = event.target:getName() -- return the name of the target Unit - local CleanUpTgtGroup = Unit.getGroup(event.target)-- Identify the target Group - local CleanUpTgtGroupName = CleanUpTgtGroup:getName() -- return the name of the target Group - - - if routines.IsUnitInZones( CleanUpTgtUnit, self.ZoneNames ) ~= nil then - self:T( "Life: " .. CleanUpTgtUnitName .. ' = ' .. CleanUpTgtUnit:getLife() .. "/" .. CleanUpTgtUnit:getLife0() ) - if CleanUpTgtUnit:getLife() < CleanUpTgtUnit:getLife0() then - self:T( "CleanUp: Destroy: " .. CleanUpTgtUnitName ) - routines.scheduleFunction( CLEANUP._DestroyUnit, {self, CleanUpTgtUnit}, timer.getTime() + 0.1) + if Event.TgtDCSUnit then + if routines.IsUnitInZones( Event.TgtDCSUnit, self.ZoneNames ) ~= nil then + self:T( { "Life: ", Event.TgtDCSUnitName, ' = ', Event.TgtDCSUnit:getLife(), "/", Event.TgtDCSUnit:getLife0() } ) + if Event.TgtDCSUnit:getLife() < Event.TgtDCSUnit:getLife0() then + self:T( "CleanUp: Destroy: " .. Event.TgtDCSUnitName ) + routines.scheduleFunction( CLEANUP._DestroyUnit, { self, Event.TgtDCSUnit }, timer.getTime() + 0.1 ) end end end - end --- Add the @{DCSUnit#Unit} to the CleanUpList for CleanUp. @@ -224,24 +217,20 @@ end --- Detects if the Unit has an S_EVENT_ENGINE_SHUTDOWN or an S_EVENT_HIT within the given ZoneNames. If this is the case, add the Group to the CLEANUP List. -- @param #CLEANUP self -- @param DCSTypes#Event event -function CLEANUP:_EventAddForCleanUp( event ) +function CLEANUP:_EventAddForCleanUp( Event ) - local CleanUpUnit = event.initiator -- the Unit - if CleanUpUnit and Object.getCategory(CleanUpUnit) == Object.Category.UNIT then - local CleanUpUnitName = CleanUpUnit:getName() -- return the name of the Unit - if self.CleanUpList[CleanUpUnitName] == nil then - if routines.IsUnitInZones( CleanUpUnit, self.ZoneNames ) ~= nil then - self:_AddForCleanUp( CleanUpUnit, CleanUpUnitName ) + if Event.IniDCSUnit then + if self.CleanUpList[Event.IniDCSUnitName] == nil then + if routines.IsUnitInZones( Event.IniDCSUnit, self.ZoneNames ) ~= nil then + self:_AddForCleanUp( Event.IniDCSUnit, Event.IniDCSUnitName ) end end end - local CleanUpTgtUnit = event.target -- the target Unit - if CleanUpTgtUnit and Object.getCategory(CleanUpTgtUnit) == Object.Category.UNIT then - local CleanUpTgtUnitName = CleanUpTgtUnit:getName() -- return the name of the target Unit - if self.CleanUpList[CleanUpTgtUnitName] == nil then - if routines.IsUnitInZones( CleanUpTgtUnit, self.ZoneNames ) ~= nil then - self:_AddForCleanUp( CleanUpTgtUnit, CleanUpTgtUnitName ) + if Event.TgtDCSUnit then + if self.CleanUpList[Event.TgtDCSUnitName] == nil then + if routines.IsUnitInZones( Event.TgtDCSUnit, self.ZoneNames ) ~= nil then + self:_AddForCleanUp( Event.TgtDCSUnit, Event.TgtDCSUnitName ) end end end diff --git a/Moose/Database.lua b/Moose/Database.lua index eef7fb002..a05b31fea 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -7,6 +7,7 @@ Include.File( "Routines" ) Include.File( "Base" ) Include.File( "Menu" ) Include.File( "Group" ) +Include.File( "Event" ) --- The DATABASE class -- @type DATABASE @@ -110,13 +111,10 @@ function DATABASE:New() end --for coa_name, coa_data in pairs(mission.coalition) do --self:AddEvent( world.event.S_EVENT_BIRTH, self.OnBirth ) - self:AddEvent( world.event.S_EVENT_DEAD, self.OnDeadOrCrash ) - self:AddEvent( world.event.S_EVENT_CRASH, self.OnDeadOrCrash ) + _EventDispatcher:OnDead( self.OnDeadOrCrash, self ) + _EventDispatcher:OnCrash( self.OnDeadOrCrash, self ) + _EventDispatcher:OnHit( self.OnHit, self ) - self:AddEvent( world.event.S_EVENT_HIT, self.OnHit) - - self:EnableEvents() - self.SchedulerId = routines.scheduleFunction( DATABASE._FollowPlayers, { self }, 0, 5 ) self:ScoreMenu() diff --git a/Moose/DestroyBaseTask.lua b/Moose/DestroyBaseTask.lua index 6d73b0036..3cef73cd5 100644 --- a/Moose/DestroyBaseTask.lua +++ b/Moose/DestroyBaseTask.lua @@ -16,10 +16,11 @@ DESTROYBASETASK = { } --- Creates a new DESTROYBASETASK. --- @param string DestroyGroupType Text describing the group to be destroyed. f.e. "Radar Installations", "Ships", "Vehicles", "Command Centers". --- @param string DestroyUnitType Text describing the unit types to be destroyed. f.e. "SA-6", "Row Boats", "Tanks", "Tents". --- @param table{string,...} DestroyGroupPrefixes Table of Prefixes of the Groups to be destroyed before task is completed. --- @param ?number DestroyPercentage defines the %-tage that needs to be destroyed to achieve mission success. eg. If in the Group there are 10 units, then a value of 75 would require 8 units to be destroyed from the Group to complete the @{TASK}. +-- @param #DESTROYBASETASK self +-- @param #string DestroyGroupType Text describing the group to be destroyed. f.e. "Radar Installations", "Ships", "Vehicles", "Command Centers". +-- @param #string DestroyUnitType Text describing the unit types to be destroyed. f.e. "SA-6", "Row Boats", "Tanks", "Tents". +-- @param #list<#string> DestroyGroupPrefixes Table of Prefixes of the Groups to be destroyed before task is completed. +-- @param #number DestroyPercentage defines the %-tage that needs to be destroyed to achieve mission success. eg. If in the Group there are 10 units, then a value of 75 would require 8 units to be destroyed from the Group to complete the @{TASK}. -- @return DESTROYBASETASK function DESTROYBASETASK:New( DestroyGroupType, DestroyUnitType, DestroyGroupPrefixes, DestroyPercentage ) local self = BASE:Inherit( self, TASK:New() ) @@ -30,34 +31,31 @@ function DESTROYBASETASK:New( DestroyGroupType, DestroyUnitType, DestroyGroupPre self.DestroyGroupPrefixes = DestroyGroupPrefixes self.DestroyGroupType = DestroyGroupType self.DestroyUnitType = DestroyUnitType + if DestroyPercentage then + self.DestroyPercentage = DestroyPercentage + end self.TaskBriefing = "Task: Destroy " .. DestroyGroupType .. "." self.Stages = { STAGEBRIEF:New(), STAGESTART:New(), STAGEGROUPSDESTROYED:New(), STAGEDONE:New() } self.SetStage( self, 1 ) - --self.AddEvent( self, world.event.S_EVENT_DEAD, self.EventDead ) - - --env.info( 'New Table self = ' .. tostring(self) ) - --env.info( 'New Table self = ' .. tostring(self) ) - return self end --- Handle the S_EVENT_DEAD events to validate the destruction of units for the task monitoring. --- @param event Event structure of DCS world. -function DESTROYBASETASK:EventDead( event ) - self:F( { 'EventDead', event } ) +-- @param #DESTROYBASETASK self +-- @param Event#EVENTDATA Event structure of MOOSE. +function DESTROYBASETASK:EventDead( Event ) + self:F( { Event } ) - if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then - local DestroyUnit = event.initiator - local DestroyUnitName = DestroyUnit:getName() - local DestroyGroup = Unit.getGroup( DestroyUnit ) - local DestroyGroupName = "" - if DestroyGroup and DestroyGroup:isExist() then - local DestroyGroupName = DestroyGroup:getName() - end + if Event.IniDCSUnit then + local DestroyUnit = Event.IniDCSUnit + local DestroyUnitName = Event.IniDCSUnitName + local DestroyGroup = Event.IniDCSGroup + local DestroyGroupName = Event.IniDCSGroupName + + --TODO: I need to fix here if 2 groups in the mission have a similar name with GroupPrefix equal, then i should differentiate for which group the goal was reached! + --I may need to test if for the goalverb that group goal was reached or something. Need to think about it a bit more ... local UnitsDestroyed = 0 - self:T( DestroyGroupName ) - self:T( DestroyUnitName ) for DestroyGroupPrefixID, DestroyGroupPrefix in pairs( self.DestroyGroupPrefixes ) do self:T( DestroyGroupPrefix ) if string.find( DestroyGroupName, DestroyGroupPrefix, 1, true ) then @@ -70,6 +68,7 @@ function DESTROYBASETASK:EventDead( event ) self:T( { UnitsDestroyed } ) self:IncreaseGoalCount( UnitsDestroyed, self.GoalVerb ) end + end --- Validate task completeness of DESTROYBASETASK. diff --git a/Moose/DestroyGroupsTask.lua b/Moose/DestroyGroupsTask.lua index 44ab501ff..81c3fbca0 100644 --- a/Moose/DestroyGroupsTask.lua +++ b/Moose/DestroyGroupsTask.lua @@ -11,10 +11,11 @@ DESTROYGROUPSTASK = { } --- Creates a new DESTROYGROUPSTASK. --- @param string DestroyGroupType String describing the group to be destroyed. --- @param string DestroyUnitType String describing the unit to be destroyed. --- @param table{string,...} DestroyGroupNames Table of string containing the name of the groups to be destroyed before task is completed. --- @param ?number DestroyPercentage defines the %-tage that needs to be destroyed to achieve mission success. eg. If in the Group there are 10 units, then a value of 75 would require 8 units to be destroyed from the Group to complete the @{TASK}. +-- @param #DESTROYGROUPSTASK self +-- @param #string DestroyGroupType String describing the group to be destroyed. +-- @param #string DestroyUnitType String describing the unit to be destroyed. +-- @param #list<#string> DestroyGroupNames Table of string containing the name of the groups to be destroyed before task is completed. +-- @param #number DestroyPercentage defines the %-tage that needs to be destroyed to achieve mission success. eg. If in the Group there are 10 units, then a value of 75 would require 8 units to be destroyed from the Group to complete the @{TASK}. ---@return DESTROYGROUPSTASK function DESTROYGROUPSTASK:New( DestroyGroupType, DestroyUnitType, DestroyGroupNames, DestroyPercentage ) local self = BASE:Inherit( self, DESTROYBASETASK:New( DestroyGroupType, DestroyUnitType, DestroyGroupNames, DestroyPercentage ) ) @@ -23,34 +24,34 @@ function DESTROYGROUPSTASK:New( DestroyGroupType, DestroyUnitType, DestroyGroupN self.Name = 'Destroy Groups' self.GoalVerb = "Destroy " .. DestroyGroupType - self:AddEvent( world.event.S_EVENT_DEAD, self.EventDead ) - self:AddEvent( world.event.S_EVENT_CRASH, self.EventDead ) - --Child.AddEvent( Child, world.event.S_EVENT_PILOT_DEAD, Child.EventDead ) + _EventDispatcher:OnDead( self.EventDead , self ) + _EventDispatcher:OnCrash( self.EventDead , self ) return self end --- Report Goal Progress. --- @param Group DestroyGroup Group structure describing the group to be evaluated. --- @param Unit DestroyUnit Unit structure describing the Unit to be evaluated. +-- @param #DESTROYGROUPSTASK self +-- @param DCSGroup#Group DestroyGroup Group structure describing the group to be evaluated. +-- @param DCSUnit#Unit DestroyUnit Unit structure describing the Unit to be evaluated. +-- @return #number The DestroyCount reflecting the amount of units destroyed within the group. function DESTROYGROUPSTASK:ReportGoalProgress( DestroyGroup, DestroyUnit ) - self:F( { DestroyGroup, DestroyUnit } ) - self:T( DestroyGroup:getSize() ) + self:F( { DestroyGroup, DestroyUnit, self.DestroyPercentage } ) + + local DestroyGroupSize = DestroyGroup:getSize() - 1 -- When a DEAD event occurs, the getSize is still one larger than the destroyed unit. + local DestroyGroupInitialSize = DestroyGroup:getInitialSize() + self:T( { DestroyGroupSize, DestroyGroupInitialSize - ( DestroyGroupInitialSize * self.DestroyPercentage / 100 ) } ) local DestroyCount = 0 if DestroyGroup then - if ( ( DestroyGroup:getInitialSize() * self.DestroyPercentage ) / 100 ) - DestroyGroup:getSize() <= 0 then + if DestroyGroupSize <= DestroyGroupInitialSize - ( DestroyGroupInitialSize * self.DestroyPercentage / 100 ) then DestroyCount = 1 ---[[ else - if DestroyGroup:getSize() == 1 then - if DestroyUnit and DestroyUnit:getLife() <= 1.0 then - DestroyCount = 1 - end - end - ]] end + end else DestroyCount = 1 end + self:T( DestroyCount ) + return DestroyCount end diff --git a/Moose/DestroyRadarsTask.lua b/Moose/DestroyRadarsTask.lua index be28006d8..9c799d586 100644 --- a/Moose/DestroyRadarsTask.lua +++ b/Moose/DestroyRadarsTask.lua @@ -18,8 +18,8 @@ function DESTROYRADARSTASK:New( DestroyGroupNames ) self:F() self.Name = 'Destroy Radars' - - self:AddEvent( world.event.S_EVENT_DEAD, self.EventDead ) + + _EventDispatcher:OnDead( self.EventDead , self ) return self end diff --git a/Moose/DestroyUnitTypesTask.lua b/Moose/DestroyUnitTypesTask.lua index 17e5af1bf..27426ed15 100644 --- a/Moose/DestroyUnitTypesTask.lua +++ b/Moose/DestroyUnitTypesTask.lua @@ -29,7 +29,7 @@ function DESTROYUNITTYPESTASK:New( DestroyGroupType, DestroyUnitType, DestroyGro self.Name = 'Destroy Unit Types' self.GoalVerb = "Destroy " .. DestroyGroupType - self:AddEvent( world.event.S_EVENT_DEAD, self.EventDead ) + _EventDispatcher:OnDead( self.EventDead , self ) return self end diff --git a/Moose/Event.lua b/Moose/Event.lua index 6346dbf4f..6ad91e3cf 100644 --- a/Moose/Event.lua +++ b/Moose/Event.lua @@ -40,6 +40,23 @@ local EVENTCODES = { "S_EVENT_MAX", } +--- The Event structure +-- @type EVENTDATA +-- @field id +-- @field initiator +-- @field target +-- @field weapon +-- @field IniDCSUnit +-- @field IniDCSUnitName +-- @field IniDCSGroup +-- @field IniDCSGroupName +-- @field TgtDCSUnit +-- @field TgtDCSUnitName +-- @field TgtDCSGroup +-- @field TgtDCSGroupName +-- @field Weapon +-- @field WeaponName +-- @field WeaponTgtDCSUnit --- The Events structure -- @type EVENT.Events @@ -59,7 +76,7 @@ end -- @param #string EventClass -- @return #EVENT.Events function EVENT:Init( EventID, EventClass ) - self:F( EventID, EventClass ) + self:F( { EventID, EventClass } ) if not self.Events[EventID] then self.Events[EventID] = {} end @@ -89,6 +106,21 @@ function EVENT:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, OnEv return self end +--- Set a new listener for an S_EVENT_X event independent from a unit or a weapon. +-- @param #EVENT self +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @param EventID +-- @return #EVENT +function EVENT:OnEventGeneric( EventFunction, EventSelf, EventID ) + self:F( { EventID } ) + + local Event = self:Init( EventID, EventSelf:GetClassNameAndID() ) + Event.EventFunction = EventFunction + Event.EventSelf = EventSelf + return self +end + --- Set a new listener for an S_EVENT_X event -- @param #EVENT self @@ -117,7 +149,18 @@ end function EVENT:OnBirthForTemplate( EventTemplate, EventFunction, EventSelf ) self:F( { EventTemplate } ) - return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnBirth ) + return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnBirthForUnit ) +end + +--- Set a new listener for an S_EVENT_BIRTH event, and registers the unit born. +-- @param #EVENT self +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf +-- @return #EVENT +function EVENT:OnBirth( EventFunction, EventSelf ) + self:F() + + return self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_BIRTH ) end --- Set a new listener for an S_EVENT_BIRTH event. @@ -126,7 +169,7 @@ end -- @param #function EventFunction The function to be called when the event occurs for the unit. -- @param Base#BASE EventSelf -- @return #EVENT -function EVENT:OnBirth( EventDCSUnitName, EventFunction, EventSelf ) +function EVENT:OnBirthForUnit( EventDCSUnitName, EventFunction, EventSelf ) self:F( EventDCSUnitName ) return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_BIRTH ) @@ -141,7 +184,18 @@ end function EVENT:OnCrashForTemplate( EventTemplate, EventFunction, EventSelf ) self:F( EventTemplate ) - return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnCrash ) + return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnCrashForUnit ) +end + +--- Set a new listener for an S_EVENT_CRASH event. +-- @param #EVENT self +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf +-- @return #EVENT +function EVENT:OnCrash( EventFunction, EventSelf ) + self:F() + + return self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_CRASH ) end --- Set a new listener for an S_EVENT_CRASH event. @@ -150,7 +204,7 @@ end -- @param #function EventFunction The function to be called when the event occurs for the unit. -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT -function EVENT:OnCrash( EventDCSUnitName, EventFunction, EventSelf ) +function EVENT:OnCrashForUnit( EventDCSUnitName, EventFunction, EventSelf ) self:F( EventDCSUnitName ) return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_CRASH ) @@ -165,16 +219,28 @@ end function EVENT:OnDeadForTemplate( EventTemplate, EventFunction, EventSelf ) self:F( EventTemplate ) - return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnDead ) + return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnDeadForUnit ) end +--- Set a new listener for an S_EVENT_DEAD event. +-- @param #EVENT self +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf +-- @return #EVENT +function EVENT:OnDead( EventFunction, EventSelf ) + self:F() + + return self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_DEAD ) +end + + --- Set a new listener for an S_EVENT_DEAD event. -- @param #EVENT self -- @param #string EventDCSUnitName -- @param #function EventFunction The function to be called when the event occurs for the unit. -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT -function EVENT:OnDead( EventDCSUnitName, EventFunction, EventSelf ) +function EVENT:OnDeadForUnit( EventDCSUnitName, EventFunction, EventSelf ) self:F( EventDCSUnitName ) return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_DEAD ) @@ -189,7 +255,7 @@ end function EVENT:OnLandForTemplate( EventTemplate, EventFunction, EventSelf ) self:F( EventTemplate ) - return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnLand ) + return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnLandForUnit ) end --- Set a new listener for an S_EVENT_LAND event. @@ -198,7 +264,7 @@ end -- @param #function EventFunction The function to be called when the event occurs for the unit. -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT -function EVENT:OnLand( EventDCSUnitName, EventFunction, EventSelf ) +function EVENT:OnLandForUnit( EventDCSUnitName, EventFunction, EventSelf ) self:F( EventDCSUnitName ) return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_LAND ) @@ -213,16 +279,16 @@ end function EVENT:OnTakeOffForTemplate( EventTemplate, EventFunction, EventSelf ) self:F( EventTemplate ) - return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnTakeOff ) + return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnTakeOffForUnit ) end ---- Set a new listener for an S_EVENT_LAND event. +--- Set a new listener for an S_EVENT_TAKEOFF event. -- @param #EVENT self -- @param #string EventDCSUnitName -- @param #function EventFunction The function to be called when the event occurs for the unit. -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT -function EVENT:OnTakeOff( EventDCSUnitName, EventFunction, EventSelf ) +function EVENT:OnTakeOffForUnit( EventDCSUnitName, EventFunction, EventSelf ) self:F( EventDCSUnitName ) return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_TAKEOFF ) @@ -237,39 +303,119 @@ end function EVENT:OnEngineShutDownForTemplate( EventTemplate, EventFunction, EventSelf ) self:F( EventTemplate ) - return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnEngineShutDown ) + return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnEngineShutDownForUnit ) end ---- Set a new listener for an S_EVENT_LAND event. +--- Set a new listener for an S_EVENT_ENGINE_SHUTDOWN event. -- @param #EVENT self -- @param #string EventDCSUnitName -- @param #function EventFunction The function to be called when the event occurs for the unit. -- @param Base#BASE EventSelf The self instance of the class for which the event is. -- @return #EVENT -function EVENT:OnEngineShutDown( EventDCSUnitName, EventFunction, EventSelf ) +function EVENT:OnEngineShutDownForUnit( EventDCSUnitName, EventFunction, EventSelf ) self:F( EventDCSUnitName ) return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_ENGINE_SHUTDOWN ) end +--- Set a new listener for an S_EVENT_ENGINE_STARTUP event. +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnEngineStartUpForUnit( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_ENGINE_STARTUP ) +end + +--- Set a new listener for an S_EVENT_SHOT event. +-- @param #EVENT self +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnShot( EventFunction, EventSelf ) + self:F() + + return self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_SHOT ) +end + +--- Set a new listener for an S_EVENT_SHOT 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 Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnShotForUnit( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_SHOT ) +end + +--- Set a new listener for an S_EVENT_HIT event. +-- @param #EVENT self +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnHit( EventFunction, EventSelf ) + self:F() + + return self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_HIT ) +end + +--- Set a new listener for an S_EVENT_HIT event. +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnHitForUnit( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_HIT ) +end + function EVENT:onEvent( Event ) self:F( { EVENTCODES[Event.id], Event } ) if self and self.Events and self.Events[Event.id] then - local IniDCSUnit = Event.initiator - if IniDCSUnit and IniDCSUnit:getCategory() == Object.Category.UNIT then - Event.IniUnitName = IniDCSUnit:getName() + if Event.initiator and Event.initiator:getCategory() == Object.Category.UNIT then + Event.IniDCSUnit = Event.initiator + Event.IniDCSGroup = Event.IniDCSUnit:getGroup() + Event.IniDCSUnitName = Event.IniDCSUnit:getName() + Event.IniDCSGroupName = "" + if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then + Event.IniDCSGroupName = Event.IniDCSGroup:getName() + end end - local TgtDCSUnit = Event.target - if TgtDCSUnit and TgtDCSUnit:isExist() and TgtDCSUnit:getCategory() == Object.Category.UNIT then - Event.TgtUnitName = TgtDCSUnit:getName() + if Event.target then + if Event.target and Event.target:getCategory() == Object.Category.UNIT then + Event.TgtDCSUnit = Event.target + Event.TgtDCSGroup = Event.TgtDCSUnit:getGroup() + Event.TgtDCSUnitName = Event.TgtDCSUnit:getName() + Event.TgtDCSGroupName = "" + if Event.TgtDCSGroup and Event.TgtDCSGroup:isExist() then + Event.TgtDCSGroupName = Event.TgtDCSGroup:getName() + end + end + end + if Event.weapon then + Event.Weapon = Event.weapon + Event.WeaponName = Event.Weapon:getTypeName() + Event.WeaponTgtDCSUnit = Event.Weapon:getTarget() end for ClassName, EventData in pairs( self.Events[Event.id] ) do - if Event.IniUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniUnitName] then - self:T( { "Calling event function for class ", ClassName, " unit ", Event.IniUnitName } ) - EventData.IniUnit[Event.IniUnitName].EventFunction( EventData.IniUnit[Event.IniUnitName].EventSelf, Event ) + if Event.IniDCSUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniDCSUnitName] then + self:T( { "Calling event function for class ", ClassName, " unit ", Event.IniDCSUnitName } ) + EventData.IniUnit[Event.IniDCSUnitName].EventFunction( EventData.IniUnit[Event.IniDCSUnitName].EventSelf, Event ) + else + if Event.IniDCSUnit and not EventData.IniUnit then + self:T( { "Calling event function for class ", ClassName } ) + EventData.EventFunction( EventData.EventSelf, Event ) + end end end end diff --git a/Moose/Movement.lua b/Moose/Movement.lua index 727b4f36e..8f809a20d 100644 --- a/Moose/Movement.lua +++ b/Moose/Movement.lua @@ -35,11 +35,11 @@ function MOVEMENT:New( MovePrefixes, MoveMaximum ) self.AliveUnits = 0 -- Contains the counter how many units are currently alive self.MoveUnits = {} -- Reflects if the Moving for this MovePrefixes is going to be scheduled or not. - self:AddEvent( world.event.S_EVENT_BIRTH, self.OnBirth ) - self:AddEvent( world.event.S_EVENT_DEAD, self.OnDeadOrCrash ) - self:AddEvent( world.event.S_EVENT_CRASH, self.OnDeadOrCrash ) + _EventDispatcher:OnBirth( self.OnBirth, self ) - self:EnableEvents() +-- self:AddEvent( world.event.S_EVENT_BIRTH, self.OnBirth ) +-- +-- self:EnableEvents() self:ScheduleStart() @@ -61,43 +61,39 @@ end --- Captures the birth events when new Units were spawned. -- @todo This method should become obsolete. The new @{DATABASE} class will handle the collection administration. -function MOVEMENT:OnBirth( event ) - self:F( { event } ) +function MOVEMENT:OnBirth( Event ) + self:F( { Event } ) if timer.getTime0() < timer.getAbsTime() then -- dont need to add units spawned in at the start of the mission if mist is loaded in init line - if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then - local MovementUnit = event.initiator - local MovementUnitName = MovementUnit:getName() - self:T( "Birth object : " .. MovementUnitName ) - local MovementGroup = MovementUnit:getGroup() - if MovementGroup and MovementGroup:isExist() then - local MovementGroupName = MovementGroup:getName() + if Event.IniDCSUnit then + self:T( "Birth object : " .. Event.IniDCSUnitName ) + if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then for MovePrefixID, MovePrefix in pairs( self.MovePrefixes ) do - if string.find( MovementUnitName, MovePrefix, 1, true ) then + if string.find( Event.IniDCSUnitName, MovePrefix, 1, true ) then self.AliveUnits = self.AliveUnits + 1 - self.MoveUnits[MovementUnitName] = MovementGroupName + self.MoveUnits[Event.IniDCSUnitName] = Event.IniDCSGroupName self:T( self.AliveUnits ) end end end end + _EventDispatcher:OnCrashForUnit( Event.IniDCSUnitName, self.OnDeadOrCrash, self ) + _EventDispatcher:OnDeadForUnit( Event.IniDCSUnitName, self.OnDeadOrCrash, self ) end end --- Captures the Dead or Crash events when Units crash or are destroyed. -- @todo This method should become obsolete. The new @{DATABASE} class will handle the collection administration. -function MOVEMENT:OnDeadOrCrash( event ) - self:F( { event } ) +function MOVEMENT:OnDeadOrCrash( Event ) + self:F( { Event } ) - if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then - local MovementUnit = event.initiator - local MovementUnitName = MovementUnit:getName() - self:T( "Dead object : " .. MovementUnitName ) + if Event.IniDCSUnit then + self:T( "Dead object : " .. Event.IniDCSUnitName ) for MovePrefixID, MovePrefix in pairs( self.MovePrefixes ) do - if string.find( MovementUnitName, MovePrefix, 1, true ) then + if string.find( Event.IniDCSUnitName, MovePrefix, 1, true ) then self.AliveUnits = self.AliveUnits - 1 - self.MoveUnits[MovementUnitName] = nil + self.MoveUnits[Event.IniDCSUnitName] = nil self:T( self.AliveUnits ) end end diff --git a/Moose/Sead.lua b/Moose/Sead.lua index 78d8f0d37..2bbfd31b8 100644 --- a/Moose/Sead.lua +++ b/Moose/Sead.lua @@ -4,6 +4,7 @@ -- @author (co) Flightcontrol (Modified and enriched with functionality) Include.File( "Routines" ) +Include.File( "Event" ) Include.File( "Base" ) Include.File( "Mission" ) Include.File( "Client" ) @@ -42,27 +43,26 @@ function SEAD:New( SEADGroupPrefixes ) else self.SEADGroupNames[SEADGroupPrefixes] = SEADGroupPrefixes end - self:AddEvent( world.event.S_EVENT_SHOT, self.EventShot ) - self:EnableEvents() + _EventDispatcher:OnShot( self.EventShot, self ) return self end --- Detects if an SA site was shot with an anti radiation missile. In this case, take evasive actions based on the skill level set within the ME. -- @see SEAD -function SEAD:EventShot( event ) - self:F( { event } ) +function SEAD:EventShot( Event ) + self:F( { Event } ) - local SEADUnit = event.initiator - local SEADUnitName = SEADUnit:getName() - local SEADWeapon = event.weapon -- Identify the weapon fired - local SEADWeaponName = SEADWeapon:getTypeName() -- return weapon type + local SEADUnit = Event.IniDCSUnit + local SEADUnitName = Event.IniDCSUnitName + local SEADWeapon = Event.Weapon -- Identify the weapon fired + local SEADWeaponName = Event.WeaponName -- return weapon type --trigger.action.outText( string.format("Alerte, depart missile " ..string.format(SEADWeaponName)), 20) --debug message -- Start of the 2nd loop self:T( "Missile Launched = " .. SEADWeaponName ) if SEADWeaponName == "KH-58" or SEADWeaponName == "KH-25MPU" or SEADWeaponName == "AGM-88" or SEADWeaponName == "KH-31A" or SEADWeaponName == "KH-31P" then -- Check if the missile is a SEAD local _evade = math.random (1,100) -- random number for chance of evading action - local _targetMim = Weapon.getTarget(SEADWeapon) -- Identify target + local _targetMim = Event.WeaponTgtDCSUnit -- Identify target local _targetMimname = Unit.getName(_targetMim) local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon)) local _targetMimgroupName = _targetMimgroup:getName() diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index f61f351ad..f6659d7e1 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -122,12 +122,6 @@ function SPAWN:New( SpawnTemplatePrefix ) else error( "SPAWN:New: There is no group declared in the mission editor with SpawnTemplatePrefix = '" .. SpawnTemplatePrefix .. "'" ) end - - --self:AddEvent( world.event.S_EVENT_BIRTH, self._OnBirth ) - --self:AddEvent( world.event.S_EVENT_DEAD, self._OnDeadOrCrash ) - --self:AddEvent( world.event.S_EVENT_CRASH, self._OnDeadOrCrash ) - - self:EnableEvents() return self end @@ -166,12 +160,6 @@ function SPAWN:NewWithAlias( SpawnTemplatePrefix, SpawnAliasPrefix ) error( "SPAWN:New: There is no group declared in the mission editor with SpawnTemplatePrefix = '" .. SpawnTemplatePrefix .. "'" ) end - --self:AddEvent( world.event.S_EVENT_BIRTH, self._OnBirth ) - --self:AddEvent( world.event.S_EVENT_DEAD, self._OnDeadOrCrash ) - --self:AddEvent( world.event.S_EVENT_CRASH, self._OnDeadOrCrash ) - - --self:EnableEvents() - return self end @@ -289,11 +277,6 @@ function SPAWN:Repeat() self.RepeatOnEngineShutDown = false self.RepeatOnLanding = true - --self:AddEvent( world.event.S_EVENT_LAND, self._OnLand ) - --self:AddEvent( world.event.S_EVENT_TAKEOFF, self._OnTakeOff ) - --self:AddEvent( world.event.S_EVENT_ENGINE_SHUTDOWN, self._OnEngineShutDown ) - --self:EnableEvents() - return self end @@ -386,10 +369,22 @@ function SPAWN:Array( SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY ) self.SpawnGroups[SpawnGroupID].SpawnTemplate.visible = true self.SpawnGroups[SpawnGroupID].Visible = true + + _EventDispatcher:OnBirthForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnBirth, self ) + _EventDispatcher:OnCrashForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnDeadOrCrash, self ) + _EventDispatcher:OnDeadForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnDeadOrCrash, self ) + + if self.SpawnRepeat then + _EventDispatcher:OnTakeOffForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnTakeOff, self ) + end + if self.RepeatOnLanding then + _EventDispatcher:OnLandForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnLand, self ) + end + if self.RepeatOnEngineShutDown then + _EventDispatcher:OnEngineShutDownForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnEngineShutDown, self ) + end + self.SpawnGroups[SpawnGroupID].Group = _Database:Spawn( self.SpawnGroups[SpawnGroupID].SpawnTemplate ) - self:Event():OnBirthForGroup( self.SpawnGroups[SpawnGroupID].Group, self._OnBirth, self ) - self:Event():OnCrashForGroup( self.SpawnGroups[SpawnGroupID].Group, self._OnBirth, self ) - self:Event():OnDeadForGroup ( self.SpawnGroups[SpawnGroupID].Group, self._OnBirth, self ) SpawnX = SpawnXIndex * SpawnDeltaX SpawnY = SpawnYIndex * SpawnDeltaY diff --git a/Moose/Task.lua b/Moose/Task.lua index 3481963a2..68cd199e1 100644 --- a/Moose/Task.lua +++ b/Moose/Task.lua @@ -91,7 +91,7 @@ end --- Get progress of a TASK. -- @return string GoalsText function TASK:GetGoalProgress() - self:F() + self:F2() local GoalsText = "" for GoalVerb, GoalVerbData in pairs( self.GoalTasks ) do @@ -115,7 +115,7 @@ end -- @param MISSION Mission Group structure describing the Mission. -- @param CLIENT Client Group structure describing the Client. function TASK:ShowGoalProgress( Mission, Client ) - self:F() + self:F2() local GoalsText = "" for GoalVerb, GoalVerbData in pairs( self.GoalTasks ) do @@ -137,14 +137,14 @@ end --- Sets a TASK to status Done. function TASK:Done() - self:F() + self:F2() self.TaskDone = true end --- Returns if a TASK is done. -- @return bool function TASK:IsDone() - self:F( self.TaskDone ) + self:F2( self.TaskDone ) return self.TaskDone end @@ -157,12 +157,12 @@ end --- Returns if a TASk has failed. -- @return bool function TASK:IsFailed() - self:F( self.TaskFailed ) + self:F2( self.TaskFailed ) return self.TaskFailed end function TASK:Reset( Mission, Client ) - self:F() + self:F2() self.ExecuteStage = _TransportExecuteStage.NONE end @@ -173,13 +173,15 @@ function TASK:GetGoals() end --- Returns if a TASK has Goal(s). --- @param ?string GoalVerb is the name of the Goal of the TASK. +-- @param #TASK self +-- @param #string GoalVerb is the name of the Goal of the TASK. -- @return bool function TASK:Goal( GoalVerb ) - self:F() + self:F2( { GoalVerb } ) if not GoalVerb then GoalVerb = self.GoalVerb end + self:T2( {self.GoalTasks[GoalVerb] } ) if self.GoalTasks[GoalVerb] and self.GoalTasks[GoalVerb].GoalTotal > 0 then return true else @@ -191,7 +193,7 @@ end -- @param number GoalTotal is the number of times the GoalVerb needs to be achieved. -- @param ?string GoalVerb is the name of the Goal of the TASK. If the GoalVerb is not given, then the default TASK Goals will be used. function TASK:SetGoalTotal( GoalTotal, GoalVerb ) - self:F( { GoalTotal, GoalVerb } ) + self:F2( { GoalTotal, GoalVerb } ) if not GoalVerb then GoalVerb = self.GoalVerb @@ -206,7 +208,7 @@ end --- Gets the total of Goals to be achieved within the TASK of the GoalVerb. -- @param ?string GoalVerb is the name of the Goal of the TASK. If the GoalVerb is not given, then the default TASK Goals will be used. function TASK:GetGoalTotal( GoalVerb ) - self:F() + self:F2( { GoalVerb } ) if not GoalVerb then GoalVerb = self.GoalVerb end @@ -222,7 +224,7 @@ end -- @param ?string GoalVerb is the name of the Goal of the TASK. If the GoalVerb is not given, then the default TASK Goals will be used. -- @return TASK function TASK:SetGoalCount( GoalCount, GoalVerb ) - self:F() + self:F2() if not GoalVerb then GoalVerb = self.GoalVerb end @@ -237,7 +239,7 @@ end -- @param ?string GoalVerb is the name of the Goal of the TASK. If the GoalVerb is not given, then the default TASK Goals will be used. -- @return TASK function TASK:IncreaseGoalCount( GoalCountIncrease, GoalVerb ) - self:F() + self:F2( { GoalCountIncrease, GoalVerb } ) if not GoalVerb then GoalVerb = self.GoalVerb end @@ -251,7 +253,7 @@ end -- @param ?string GoalVerb is the name of the Goal of the TASK. If the GoalVerb is not given, then the default TASK Goals will be used. -- @return TASK function TASK:GetGoalCount( GoalVerb ) - self:F() + self:F2() if not GoalVerb then GoalVerb = self.GoalVerb end @@ -266,7 +268,7 @@ end -- @param ?string GoalVerb is the name of the Goal of the TASK. If the GoalVerb is not given, then the default TASK Goals will be used. -- @return TASK function TASK:GetGoalPercentage( GoalVerb ) - self:F() + self:F2() if not GoalVerb then GoalVerb = self.GoalVerb end @@ -279,15 +281,16 @@ end --- Returns if all the Goals of the TASK were achieved. -- @return bool -function TASK:IsGoalReached( ) +function TASK:IsGoalReached() + self:F2() local GoalReached = true for GoalVerb, Goals in pairs( self.GoalTasks ) do - self:T( { "GoalVerb", GoalVerb } ) + self:T2( { "GoalVerb", GoalVerb } ) if self:Goal( GoalVerb ) then local GoalToDo = self:GetGoalTotal( GoalVerb ) - self:GetGoalCount( GoalVerb ) - self:T( "GoalToDo = " .. GoalToDo ) + self:T2( "GoalToDo = " .. GoalToDo ) if GoalToDo <= 0 then else GoalReached = false @@ -298,7 +301,7 @@ function TASK:IsGoalReached( ) end end - self:T( GoalReached ) + self:T( { GoalReached, self.GoalTasks } ) return GoalReached end @@ -307,7 +310,7 @@ end -- @param string GoalTask is a text describing the Goal of the TASK to be achieved. -- @param number GoalIncrease is a number by which the Goal achievement is increasing. function TASK:AddGoalCompletion( GoalVerb, GoalTask, GoalIncrease ) - self:F( { GoalVerb, GoalTask, GoalIncrease } ) + self:F2( { GoalVerb, GoalTask, GoalIncrease } ) if self:Goal( GoalVerb ) then self.GoalTasks[GoalVerb].Goals[#self.GoalTasks[GoalVerb].Goals+1] = GoalTask @@ -320,7 +323,7 @@ end -- @param ?string GoalVerb is the name of the Goal of the TASK. If the GoalVerb is not given, then the default TASK Goals will be used. -- @return string Goals function TASK:GetGoalCompletion( GoalVerb ) - self:F( { GoalVerb } ) + self:F2( { GoalVerb } ) if self:Goal( GoalVerb ) then local Goals = "" diff --git a/Test Missions/Moose_Test_DESTROY/MOOSE_Test_DESTROY.miz b/Test Missions/Moose_Test_DESTROY/MOOSE_Test_DESTROY.miz new file mode 100644 index 0000000000000000000000000000000000000000..af1132ad39a04542af7ebde70d78516cc7dca145 GIT binary patch literal 29167 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 Date: Sat, 23 Apr 2016 08:17:57 +0200 Subject: [PATCH 3/5] Event functions replacement stable now ... (I think)... --- Embedded/Moose_Create_Embedded.bat | 1 + Embedded/Moose_Embedded.lua | 3447 +++++++++++------ Moose/CleanUp.lua | 19 +- Moose/Database.lua | 1488 ++++--- Moose/Event.lua | 137 +- Moose/Sead.lua | 2 +- Moose/Spawn.lua | 2 +- .../Moose_Test_CLEANUP/Moose_Test_CLEANUP.lua | 10 + .../Moose_Test_CLEANUP/Moose_Test_CLEANUP.miz | Bin 0 -> 99751 bytes 9 files changed, 3031 insertions(+), 2075 deletions(-) create mode 100644 Test Missions/Moose_Test_CLEANUP/Moose_Test_CLEANUP.lua create mode 100644 Test Missions/Moose_Test_CLEANUP/Moose_Test_CLEANUP.miz diff --git a/Embedded/Moose_Create_Embedded.bat b/Embedded/Moose_Create_Embedded.bat index 7211a207d..7dfa51470 100644 --- a/Embedded/Moose_Create_Embedded.bat +++ b/Embedded/Moose_Create_Embedded.bat @@ -2,6 +2,7 @@ rem Generate Moose_Embedded.lua copy /b ..\Moose\Routines.lua ^ + ..\Moose\Base.lua ^ + + ..\Moose\Event.lua ^ + ..\Moose\Menu.lua ^ + ..\Moose\Group.lua ^ + ..\Moose\Unit.lua ^ diff --git a/Embedded/Moose_Embedded.lua b/Embedded/Moose_Embedded.lua index 5f2fa13cb..7ab06e4d4 100644 --- a/Embedded/Moose_Embedded.lua +++ b/Embedded/Moose_Embedded.lua @@ -2624,6 +2624,8 @@ FORMATION = { Cone = "Cone" } + + --- The base constructor. This is the top top class of all classed defined within the MOOSE. -- Any new class needs to be derived from this class for proper inheritance. -- @param #BASE self @@ -2718,6 +2720,18 @@ function BASE:AddEvent( Event, EventFunction ) return self end +--- Returns the event dispatcher +-- @param #BASE self +-- @return Event#EVENT +function BASE:Event() + + return _EventDispatcher +end + + + + + --- Enable the event listeners for the class. -- @param #BASE self -- @return #BASE @@ -2831,8 +2845,8 @@ end -- @param #BASE self -- @param DCSTypes#Event event function BASE:onEvent(event) + --self:F( { BaseEventCodes[event.id], event } ) - --env.info( 'onEvent Table self = ' .. tostring(self) ) if self then for EventID, EventObject in pairs( self.Events ) do if EventObject.EventEnabled then @@ -2847,8 +2861,8 @@ function BASE:onEvent(event) if event.target and event.target:isExist() then event.TgtUnitName = event.target:getName() end - self:T( { BaseEventCodes[event.id], event } ) - EventObject.EventFunction( self, event ) + --self:T( { BaseEventCodes[event.id], event } ) + --EventObject.EventFunction( self, event ) end end end @@ -2909,7 +2923,7 @@ function BASE:F( Arguments ) if DebugInfoFrom then LineFrom = DebugInfoFrom.currentline end - env.info( string.format( "%6d\(%6d\)/%1s:%20s%05d.%s\(%s\)" , LineCurrent, LineFrom, "F", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) + env.info( string.format( "%6d(%6d)/%1s:%20s%05d.%s(%s)" , LineCurrent, LineFrom, "F", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) end end end @@ -2957,7 +2971,7 @@ function BASE:T( Arguments ) if DebugInfoFrom then LineFrom = DebugInfoFrom.currentline end - env.info( string.format( "%6d\(%6d\)/%1s:%20s%05d.%s" , LineCurrent, LineFrom, "T", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) ) + env.info( string.format( "%6d(%6d)/%1s:%20s%05d.%s" , LineCurrent, LineFrom, "T", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) ) end end end @@ -3000,11 +3014,500 @@ function BASE:E( Arguments ) local LineCurrent = DebugInfoCurrent.currentline local LineFrom = DebugInfoFrom.currentline - env.info( string.format( "%6d\(%6d\)/%1s:%20s%05d.%s\(%s\)" , LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) + env.info( string.format( "%6d(%6d)/%1s:%20s%05d.%s(%s)" , LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) end +--- The EVENT class models an efficient event handling process between other classes and its units, weapons. +-- @module Event +-- @author FlightControl + +Include.File( "Routines" ) +Include.File( "Base" ) + +--- The EVENT structure +-- @type EVENT +-- @field #EVENT.Events Events +EVENT = { + ClassName = "EVENT", + ClassID = 0, +} + +local _EVENTCODES = { + "S_EVENT_SHOT", + "S_EVENT_HIT", + "S_EVENT_TAKEOFF", + "S_EVENT_LAND", + "S_EVENT_CRASH", + "S_EVENT_EJECTION", + "S_EVENT_REFUELING", + "S_EVENT_DEAD", + "S_EVENT_PILOT_DEAD", + "S_EVENT_BASE_CAPTURED", + "S_EVENT_MISSION_START", + "S_EVENT_MISSION_END", + "S_EVENT_TOOK_CONTROL", + "S_EVENT_REFUELING_STOP", + "S_EVENT_BIRTH", + "S_EVENT_HUMAN_FAILURE", + "S_EVENT_ENGINE_STARTUP", + "S_EVENT_ENGINE_SHUTDOWN", + "S_EVENT_PLAYER_ENTER_UNIT", + "S_EVENT_PLAYER_LEAVE_UNIT", + "S_EVENT_PLAYER_COMMENT", + "S_EVENT_SHOOTING_START", + "S_EVENT_SHOOTING_END", + "S_EVENT_MAX", +} + +--- The Event structure +-- @type EVENTDATA +-- @field id +-- @field initiator +-- @field target +-- @field weapon +-- @field IniDCSUnit +-- @field IniDCSUnitName +-- @field IniDCSGroup +-- @field IniDCSGroupName +-- @field TgtDCSUnit +-- @field TgtDCSUnitName +-- @field TgtDCSGroup +-- @field TgtDCSGroupName +-- @field Weapon +-- @field WeaponName +-- @field WeaponTgtDCSUnit + +--- The Events structure +-- @type EVENT.Events +-- @field #number IniUnit + +function EVENT:New() + local self = BASE:Inherit( self, BASE:New() ) + self:F() + self.EventHandler = world.addEventHandler( self ) + return self +end + +function EVENT:EventText( EventID ) + + local EventText = _EVENTCODES[EventID] + + return EventText +end + + +--- Initializes the Events structure for the event +-- @param #EVENT self +-- @param DCSWorld#world.event EventID +-- @param #string EventClass +-- @return #EVENT.Events +function EVENT:Init( EventID, EventClass ) + self:F3( { _EVENTCODES[EventID], EventClass } ) + if not self.Events[EventID] then + self.Events[EventID] = {} + end + if not self.Events[EventID][EventClass] then + self.Events[EventID][EventClass] = {} + end + return self.Events[EventID][EventClass] +end + + +--- Create an OnDead event handler for a group +-- @param #EVENT self +-- @param #table EventTemplate +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param EventSelf The self instance of the class for which the event is. +-- @param #function OnEventFunction +-- @return #EVENT +function EVENT:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, OnEventFunction ) + self:F2( EventTemplate.name ) + + for EventUnitID, EventUnit in pairs( EventTemplate.units ) do + OnEventFunction( self, EventUnit.name, EventFunction, EventSelf ) + end + return self +end + +--- Set a new listener for an S_EVENT_X event independent from a unit or a weapon. +-- @param #EVENT self +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @param EventID +-- @return #EVENT +function EVENT:OnEventGeneric( EventFunction, EventSelf, EventID ) + self:F2( { EventID } ) + + local Event = self:Init( EventID, EventSelf:GetClassNameAndID() ) + Event.EventFunction = EventFunction + Event.EventSelf = EventSelf + return self +end + + +--- Set a new listener for an S_EVENT_X event +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @param EventID +-- @return #EVENT +function EVENT:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, EventID ) + self:F2( EventDCSUnitName ) + + local Event = self:Init( EventID, EventSelf:GetClassNameAndID() ) + if not Event.IniUnit then + Event.IniUnit = {} + end + Event.IniUnit[EventDCSUnitName] = {} + Event.IniUnit[EventDCSUnitName].EventFunction = EventFunction + Event.IniUnit[EventDCSUnitName].EventSelf = EventSelf + return self +end + + +--- Create an OnBirth event handler for a group +-- @param #EVENT self +-- @param Group#GROUP EventGroup +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnBirthForTemplate( EventTemplate, EventFunction, EventSelf ) + self:F( EventTemplate.name ) + + self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnBirthForUnit ) + + return self +end + +--- Set a new listener for an S_EVENT_BIRTH event, and registers the unit born. +-- @param #EVENT self +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf +-- @return #EVENT +function EVENT:OnBirth( EventFunction, EventSelf ) + self:F() + + self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_BIRTH ) + + return self +end + +--- Set a new listener for an S_EVENT_BIRTH event. +-- @param #EVENT self +-- @param #string EventDCSUnitName The id of the unit for the event to be handled. +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf +-- @return #EVENT +function EVENT:OnBirthForUnit( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_BIRTH ) + + return self +end + +--- Create an OnCrash event handler for a group +-- @param #EVENT self +-- @param Group#GROUP EventGroup +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnCrashForTemplate( EventTemplate, EventFunction, EventSelf ) + self:F( EventTemplate.name ) + + self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnCrashForUnit ) + + return self +end + +--- Set a new listener for an S_EVENT_CRASH event. +-- @param #EVENT self +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf +-- @return #EVENT +function EVENT:OnCrash( EventFunction, EventSelf ) + self:F() + + self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_CRASH ) + + return self +end + +--- Set a new listener for an S_EVENT_CRASH event. +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnCrashForUnit( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_CRASH ) + + return self +end + +--- Create an OnDead event handler for a group +-- @param #EVENT self +-- @param Group#GROUP EventGroup +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnDeadForTemplate( EventTemplate, EventFunction, EventSelf ) + self:F( EventTemplate.name ) + + self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnDeadForUnit ) + + return self +end + +--- Set a new listener for an S_EVENT_DEAD event. +-- @param #EVENT self +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf +-- @return #EVENT +function EVENT:OnDead( EventFunction, EventSelf ) + self:F() + + self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_DEAD ) + + return self +end + + +--- Set a new listener for an S_EVENT_DEAD event. +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnDeadForUnit( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_DEAD ) + + return self +end + +--- Set a new listener for an S_EVENT_PILOT_DEAD event. +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnPilotDeadForUnit( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_PILOT_DEAD ) + + return self +end + +--- Create an OnDead event handler for a group +-- @param #EVENT self +-- @param #table EventTemplate +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnLandForTemplate( EventTemplate, EventFunction, EventSelf ) + self:F( EventTemplate.name ) + + self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnLandForUnit ) + + return self +end + +--- Set a new listener for an S_EVENT_LAND event. +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnLandForUnit( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_LAND ) + + return self +end + +--- Create an OnDead event handler for a group +-- @param #EVENT self +-- @param #table EventTemplate +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnTakeOffForTemplate( EventTemplate, EventFunction, EventSelf ) + self:F( EventTemplate.name ) + + self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnTakeOffForUnit ) + + return self +end + +--- Set a new listener for an S_EVENT_TAKEOFF event. +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnTakeOffForUnit( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_TAKEOFF ) + + return self +end + +--- Create an OnDead event handler for a group +-- @param #EVENT self +-- @param #table EventTemplate +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnEngineShutDownForTemplate( EventTemplate, EventFunction, EventSelf ) + self:F( EventTemplate.name ) + + self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnEngineShutDownForUnit ) + + return self +end + +--- Set a new listener for an S_EVENT_ENGINE_SHUTDOWN event. +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnEngineShutDownForUnit( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_ENGINE_SHUTDOWN ) + + return self +end + +--- Set a new listener for an S_EVENT_ENGINE_STARTUP event. +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnEngineStartUpForUnit( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_ENGINE_STARTUP ) + + return self +end + +--- Set a new listener for an S_EVENT_SHOT event. +-- @param #EVENT self +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnShot( EventFunction, EventSelf ) + self:F() + + self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_SHOT ) + + return self +end + +--- Set a new listener for an S_EVENT_SHOT 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 Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnShotForUnit( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_SHOT ) + + return self +end + +--- Set a new listener for an S_EVENT_HIT event. +-- @param #EVENT self +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnHit( EventFunction, EventSelf ) + self:F() + + self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_HIT ) + + return self +end + +--- Set a new listener for an S_EVENT_HIT event. +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnHitForUnit( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_HIT ) + + return self +end + + + +function EVENT:onEvent( Event ) + self:F( { _EVENTCODES[Event.id], Event } ) + + if self and self.Events and self.Events[Event.id] then + if Event.initiator and Event.initiator:getCategory() == Object.Category.UNIT then + Event.IniDCSUnit = Event.initiator + Event.IniDCSGroup = Event.IniDCSUnit:getGroup() + Event.IniDCSUnitName = Event.IniDCSUnit:getName() + Event.IniDCSGroupName = "" + if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then + Event.IniDCSGroupName = Event.IniDCSGroup:getName() + end + end + if Event.target then + if Event.target and Event.target:getCategory() == Object.Category.UNIT then + Event.TgtDCSUnit = Event.target + Event.TgtDCSGroup = Event.TgtDCSUnit:getGroup() + Event.TgtDCSUnitName = Event.TgtDCSUnit:getName() + Event.TgtDCSGroupName = "" + if Event.TgtDCSGroup and Event.TgtDCSGroup:isExist() then + Event.TgtDCSGroupName = Event.TgtDCSGroup:getName() + end + end + end + if Event.weapon then + Event.Weapon = Event.weapon + Event.WeaponName = Event.Weapon:getTypeName() + --Event.WeaponTgtDCSUnit = Event.Weapon:getTarget() + end + for ClassName, EventData in pairs( self.Events[Event.id] ) do + if Event.IniDCSUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniDCSUnitName] then + self:T2( { "Calling event function for class ", ClassName, " unit ", Event.IniDCSUnitName } ) + EventData.IniUnit[Event.IniDCSUnitName].EventFunction( EventData.IniUnit[Event.IniDCSUnitName].EventSelf, Event ) + else + if Event.IniDCSUnit and not EventData.IniUnit then + self:T2( { "Calling event function for class ", ClassName } ) + EventData.EventFunction( EventData.EventSelf, Event ) + end + end + end + end +end + + + +--- Declare the event dispatcher based on the EVENT class +_EventDispatcher = EVENT:New() -- #EVENT + --- Encapsulation of DCS World Menu system in a set of MENU classes. -- @module Menu @@ -4993,36 +5496,37 @@ Include.File( "Routines" ) Include.File( "Base" ) Include.File( "Menu" ) Include.File( "Group" ) +Include.File( "Event" ) --- The DATABASE class -- @type DATABASE -- @extends Base#BASE DATABASE = { - ClassName = "DATABASE", - Units = {}, - Groups = {}, - NavPoints = {}, - Statics = {}, - Players = {}, - ActivePlayers = {}, - ClientsByName = {}, - ClientsByID = {}, + ClassName = "DATABASE", + Units = {}, + Groups = {}, + NavPoints = {}, + Statics = {}, + Players = {}, + ActivePlayers = {}, + ClientsByName = {}, + ClientsByID = {}, } -DATABASECoalition = -{ - [1] = "Red", - [2] = "Blue", -} +local _DATABASECoalition = + { + [1] = "Red", + [2] = "Blue", + } -DATABASECategory = -{ - [Unit.Category.AIRPLANE] = "Plane", - [Unit.Category.HELICOPTER] = "Helicopter", - [Unit.Category.GROUND_UNIT] = "Vehicle", - [Unit.Category.SHIP] = "Ship", - [Unit.Category.STRUCTURE] = "Structure", -} +local _DATABASECategory = + { + [Unit.Category.AIRPLANE] = "Plane", + [Unit.Category.HELICOPTER] = "Helicopter", + [Unit.Category.GROUND_UNIT] = "Vehicle", + [Unit.Category.SHIP] = "Ship", + [Unit.Category.STRUCTURE] = "Structure", + } --- Creates a new DATABASE Object to administer the Groups defined and alive within the DCSRTE. @@ -5032,83 +5536,79 @@ DATABASECategory = -- DBObject = DATABASE:New() function DATABASE:New() - -- Inherits from BASE - local self = BASE:Inherit( self, BASE:New() ) - - self.Navpoints = {} - self.Units = {} - --Build routines.db.units and self.Navpoints - for coa_name, coa_data in pairs(env.mission.coalition) do + -- Inherits from BASE + local self = BASE:Inherit( self, BASE:New() ) - if (coa_name == 'red' or coa_name == 'blue') and type(coa_data) == 'table' then - self.Units[coa_name] = {} - - ---------------------------------------------- - -- build nav points DB - self.Navpoints[coa_name] = {} - if coa_data.nav_points then --navpoints - for nav_ind, nav_data in pairs(coa_data.nav_points) do - - if type(nav_data) == 'table' then - self.Navpoints[coa_name][nav_ind] = routines.utils.deepCopy(nav_data) + self.Navpoints = {} + self.Units = {} + --Build routines.db.units and self.Navpoints + for coa_name, coa_data in pairs(env.mission.coalition) do - self.Navpoints[coa_name][nav_ind]['name'] = nav_data.callsignStr -- name is a little bit more self-explanatory. - self.Navpoints[coa_name][nav_ind]['point'] = {} -- point is used by SSE, support it. - self.Navpoints[coa_name][nav_ind]['point']['x'] = nav_data.x - self.Navpoints[coa_name][nav_ind]['point']['y'] = 0 - self.Navpoints[coa_name][nav_ind]['point']['z'] = nav_data.y - end - end - end - ------------------------------------------------- - if coa_data.country then --there is a country table - for cntry_id, cntry_data in pairs(coa_data.country) do - - local countryName = string.lower(cntry_data.name) - self.Units[coa_name][countryName] = {} - self.Units[coa_name][countryName]["countryId"] = cntry_data.id + if (coa_name == 'red' or coa_name == 'blue') and type(coa_data) == 'table' then + self.Units[coa_name] = {} - if type(cntry_data) == 'table' then --just making sure - - for obj_type_name, obj_type_data in pairs(cntry_data) do - - if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then --should be an unncessary check - - local category = obj_type_name - - if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then --there's a group! - - self.Units[coa_name][countryName][category] = {} - - for group_num, GroupTemplate in pairs(obj_type_data.group) do - - if GroupTemplate and GroupTemplate.units and type(GroupTemplate.units) == 'table' then --making sure again- this is a valid group - self:_RegisterGroup( GroupTemplate ) - end --if GroupTemplate and GroupTemplate.units then - end --for group_num, GroupTemplate in pairs(obj_type_data.group) do - end --if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then - end --if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then - end --for obj_type_name, obj_type_data in pairs(cntry_data) do - end --if type(cntry_data) == 'table' then - end --for cntry_id, cntry_data in pairs(coa_data.country) do - end --if coa_data.country then --there is a country table - end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then - end --for coa_name, coa_data in pairs(mission.coalition) do + ---------------------------------------------- + -- build nav points DB + self.Navpoints[coa_name] = {} + if coa_data.nav_points then --navpoints + for nav_ind, nav_data in pairs(coa_data.nav_points) do - --self:AddEvent( world.event.S_EVENT_BIRTH, self.OnBirth ) - self:AddEvent( world.event.S_EVENT_DEAD, self.OnDeadOrCrash ) - self:AddEvent( world.event.S_EVENT_CRASH, self.OnDeadOrCrash ) - - self:AddEvent( world.event.S_EVENT_HIT, self.OnHit) + if type(nav_data) == 'table' then + self.Navpoints[coa_name][nav_ind] = routines.utils.deepCopy(nav_data) - self:EnableEvents() + self.Navpoints[coa_name][nav_ind]['name'] = nav_data.callsignStr -- name is a little bit more self-explanatory. + self.Navpoints[coa_name][nav_ind]['point'] = {} -- point is used by SSE, support it. + self.Navpoints[coa_name][nav_ind]['point']['x'] = nav_data.x + self.Navpoints[coa_name][nav_ind]['point']['y'] = 0 + self.Navpoints[coa_name][nav_ind]['point']['z'] = nav_data.y + end + end + end + ------------------------------------------------- + if coa_data.country then --there is a country table + for cntry_id, cntry_data in pairs(coa_data.country) do - self.SchedulerId = routines.scheduleFunction( DATABASE._FollowPlayers, { self }, 0, 5 ) - - self:ScoreMenu() - - - return self + local countryName = string.lower(cntry_data.name) + self.Units[coa_name][countryName] = {} + self.Units[coa_name][countryName]["countryId"] = cntry_data.id + + if type(cntry_data) == 'table' then --just making sure + + for obj_type_name, obj_type_data in pairs(cntry_data) do + + if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then --should be an unncessary check + + local category = obj_type_name + + if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then --there's a group! + + self.Units[coa_name][countryName][category] = {} + + for group_num, GroupTemplate in pairs(obj_type_data.group) do + + if GroupTemplate and GroupTemplate.units and type(GroupTemplate.units) == 'table' then --making sure again- this is a valid group + self:_RegisterGroup( GroupTemplate ) + end --if GroupTemplate and GroupTemplate.units then + end --for group_num, GroupTemplate in pairs(obj_type_data.group) do + end --if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then + end --if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then + end --for obj_type_name, obj_type_data in pairs(cntry_data) do + end --if type(cntry_data) == 'table' then + end --for cntry_id, cntry_data in pairs(coa_data.country) do + end --if coa_data.country then --there is a country table + end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then + end --for coa_name, coa_data in pairs(mission.coalition) do + + --self:AddEvent( world.event.S_EVENT_BIRTH, self.OnBirth ) + _EventDispatcher:OnDead( self._EventOnDeadOrCrash, self ) + _EventDispatcher:OnCrash( self._EventOnDeadOrCrash, self ) + _EventDispatcher:OnHit( self._EventOnHit, self ) + + self.SchedulerId = routines.scheduleFunction( DATABASE._FollowPlayers, { self }, 0, 5 ) + + self:ScoreMenu() + + return self end @@ -5118,49 +5618,49 @@ end -- This method is used by the SPAWN class. function DATABASE:Spawn( SpawnTemplate ) - self:T( { SpawnTemplate.SpawnCountryID, SpawnTemplate.SpawnCategoryID, SpawnTemplate.name } ) - - -- Copy the spawn variables of the template in temporary storage, nullify, and restore the spawn variables. - local SpawnCoalitionID = SpawnTemplate.SpawnCoalitionID - local SpawnCountryID = SpawnTemplate.SpawnCountryID - local SpawnCategoryID = SpawnTemplate.SpawnCategoryID - - -- Nullify - SpawnTemplate.SpawnCoalitionID = nil - SpawnTemplate.SpawnCountryID = nil - SpawnTemplate.SpawnCategoryID = nil - - self:_RegisterGroup( SpawnTemplate ) - coalition.addGroup( SpawnCountryID, SpawnCategoryID, SpawnTemplate ) + self:T( { SpawnTemplate.SpawnCountryID, SpawnTemplate.SpawnCategoryID, SpawnTemplate.name } ) - -- Restore - SpawnTemplate.SpawnCoalitionID = SpawnCoalitionID - SpawnTemplate.SpawnCountryID = SpawnCountryID - SpawnTemplate.SpawnCategoryID = SpawnCategoryID + -- Copy the spawn variables of the template in temporary storage, nullify, and restore the spawn variables. + local SpawnCoalitionID = SpawnTemplate.SpawnCoalitionID + local SpawnCountryID = SpawnTemplate.SpawnCountryID + local SpawnCategoryID = SpawnTemplate.SpawnCategoryID - - local SpawnGroup = GROUP:New( Group.getByName( SpawnTemplate.name ) ) - return SpawnGroup + -- Nullify + SpawnTemplate.SpawnCoalitionID = nil + SpawnTemplate.SpawnCountryID = nil + SpawnTemplate.SpawnCategoryID = nil + + self:_RegisterGroup( SpawnTemplate ) + coalition.addGroup( SpawnCountryID, SpawnCategoryID, SpawnTemplate ) + + -- Restore + SpawnTemplate.SpawnCoalitionID = SpawnCoalitionID + SpawnTemplate.SpawnCountryID = SpawnCountryID + SpawnTemplate.SpawnCategoryID = SpawnCategoryID + + + local SpawnGroup = GROUP:New( Group.getByName( SpawnTemplate.name ) ) + return SpawnGroup end --- Set a status to a Group within the Database, this to check crossing events for example. function DATABASE:SetStatusGroup( GroupName, Status ) - self:F( Status ) + self:F( Status ) - self.Groups[GroupName].Status = Status + self.Groups[GroupName].Status = Status end --- Get a status to a Group within the Database, this to check crossing events for example. function DATABASE:GetStatusGroup( GroupName ) - self:F( Status ) + self:F( Status ) - if self.Groups[GroupName] then - return self.Groups[GroupName].Status - else - return "" - end + if self.Groups[GroupName] then + return self.Groups[GroupName].Status + else + return "" + end end @@ -5171,35 +5671,35 @@ end --- Registers new Group Templates within the DATABASE Object. function DATABASE:_RegisterGroup( GroupTemplate ) - local GroupTemplateName = env.getValueDictByKey(GroupTemplate.name) + local GroupTemplateName = env.getValueDictByKey(GroupTemplate.name) - if not self.Groups[GroupTemplateName] then - self.Groups[GroupTemplateName] = {} - self.Groups[GroupTemplateName].Status = nil - end - self.Groups[GroupTemplateName].GroupName = GroupTemplateName - self.Groups[GroupTemplateName].Template = GroupTemplate - self.Groups[GroupTemplateName].groupId = GroupTemplate.groupId - self.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units - self.Groups[GroupTemplateName].Units = GroupTemplate.units - - self:T( { "Group", self.Groups[GroupTemplateName].GroupName, self.Groups[GroupTemplateName].UnitCount } ) - - for unit_num, UnitTemplate in pairs(GroupTemplate.units) do - - local UnitTemplateName = env.getValueDictByKey(UnitTemplate.name) - self.Units[UnitTemplateName] = {} - self.Units[UnitTemplateName].UnitName = UnitTemplateName - self.Units[UnitTemplateName].Template = UnitTemplate - self.Units[UnitTemplateName].GroupName = GroupTemplateName - self.Units[UnitTemplateName].GroupTemplate = GroupTemplate - self.Units[UnitTemplateName].GroupId = GroupTemplate.groupId - if UnitTemplate.skill and (UnitTemplate.skill == "Client" or UnitTemplate.skill == "Player") then - self.ClientsByName[UnitTemplateName] = UnitTemplate - self.ClientsByID[UnitTemplate.unitId] = UnitTemplate - end - self:T( { "Unit", self.Units[UnitTemplateName].UnitName } ) - end + if not self.Groups[GroupTemplateName] then + self.Groups[GroupTemplateName] = {} + self.Groups[GroupTemplateName].Status = nil + end + self.Groups[GroupTemplateName].GroupName = GroupTemplateName + self.Groups[GroupTemplateName].Template = GroupTemplate + self.Groups[GroupTemplateName].groupId = GroupTemplate.groupId + self.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units + self.Groups[GroupTemplateName].Units = GroupTemplate.units + + self:T( { "Group", self.Groups[GroupTemplateName].GroupName, self.Groups[GroupTemplateName].UnitCount } ) + + for unit_num, UnitTemplate in pairs(GroupTemplate.units) do + + local UnitTemplateName = env.getValueDictByKey(UnitTemplate.name) + self.Units[UnitTemplateName] = {} + self.Units[UnitTemplateName].UnitName = UnitTemplateName + self.Units[UnitTemplateName].Template = UnitTemplate + self.Units[UnitTemplateName].GroupName = GroupTemplateName + self.Units[UnitTemplateName].GroupTemplate = GroupTemplate + self.Units[UnitTemplateName].GroupId = GroupTemplate.groupId + if UnitTemplate.skill and (UnitTemplate.skill == "Client" or UnitTemplate.skill == "Player") then + self.ClientsByName[UnitTemplateName] = UnitTemplate + self.ClientsByID[UnitTemplate.unitId] = UnitTemplate + end + self:T( { "Unit", self.Units[UnitTemplateName].UnitName } ) + end end @@ -5208,96 +5708,94 @@ end --- Track DCSRTE DEAD or CRASH events for the internal scoring. -function DATABASE:OnDeadOrCrash( event ) - self:F( { event } ) +-- @param #DATABASE self +-- @param Event#EVENTDATA Event +function DATABASE:_EventOnDeadOrCrash( Event ) + self:F( { Event } ) - local TargetUnit = nil - local TargetGroup = nil - local TargetUnitName = "" - local TargetGroupName = "" - local TargetPlayerName = "" - local TargetCoalition = nil - local TargetCategory = nil - local TargetType = nil - local TargetUnitCoalition = nil - local TargetUnitCategory = nil - local TargetUnitType = nil + local TargetUnit = nil + local TargetGroup = nil + local TargetUnitName = "" + local TargetGroupName = "" + local TargetPlayerName = "" + local TargetCoalition = nil + local TargetCategory = nil + local TargetType = nil + local TargetUnitCoalition = nil + local TargetUnitCategory = nil + local TargetUnitType = nil - if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then - - TargetUnit = event.initiator - TargetGroup = Unit.getGroup( TargetUnit ) - TargetUnitDesc = TargetUnit:getDesc() - - TargetUnitName = TargetUnit:getName() - if TargetGroup and TargetGroup:isExist() then - TargetGroupName = TargetGroup:getName() - end - TargetPlayerName = TargetUnit:getPlayerName() + if Event.IniDCSUnit then - TargetCoalition = TargetUnit:getCoalition() - --TargetCategory = TargetUnit:getCategory() - TargetCategory = TargetUnitDesc.category -- Workaround - TargetType = TargetUnit:getTypeName() + TargetUnit = Event.IniDCSUnit + TargetUnitName = Event.IniDCSUnitName + TargetGroup = Event.IniDCSGroup + TargetGroupName = Event.IniDCSGroupName + TargetPlayerName = TargetUnit:getPlayerName() - TargetUnitCoalition = DATABASECoalition[TargetCoalition] - TargetUnitCategory = DATABASECategory[TargetCategory] - TargetUnitType = TargetType + TargetCoalition = TargetUnit:getCoalition() + --TargetCategory = TargetUnit:getCategory() + TargetCategory = TargetUnit:getDesc().category -- Workaround + TargetType = TargetUnit:getTypeName() - self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } ) - end + TargetUnitCoalition = _DATABASECoalition[TargetCoalition] + TargetUnitCategory = _DATABASECategory[T1argetCategory] + TargetUnitType = TargetType - for PlayerName, PlayerData in pairs( self.Players ) do - if PlayerData then -- This should normally not happen, but i'll test it anyway. - self:T( "Something got killed" ) + self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } ) + end - -- Some variables - local InitUnitName = PlayerData.UnitName - local InitUnitType = PlayerData.UnitType - local InitCoalition = PlayerData.UnitCoalition - local InitCategory = PlayerData.UnitCategory - local InitUnitCoalition = DATABASECoalition[InitCoalition] - local InitUnitCategory = DATABASECategory[InitCategory] - - self:T( { InitUnitName, InitUnitType, InitUnitCoalition, InitCoalition, InitUnitCategory, InitCategory } ) + for PlayerName, PlayerData in pairs( self.Players ) do + if PlayerData then -- This should normally not happen, but i'll test it anyway. + self:T( "Something got killed" ) - -- What is he hitting? - if TargetCategory then - if PlayerData and PlayerData.Hit and PlayerData.Hit[TargetCategory] and PlayerData.Hit[TargetCategory][TargetUnitName] then -- Was there a hit for this unit for this player before registered??? - if not PlayerData.Kill[TargetCategory] then - PlayerData.Kill[TargetCategory] = {} - end - if not PlayerData.Kill[TargetCategory][TargetType] then - PlayerData.Kill[TargetCategory][TargetType] = {} - PlayerData.Kill[TargetCategory][TargetType].Score = 0 - PlayerData.Kill[TargetCategory][TargetType].ScoreKill = 0 - PlayerData.Kill[TargetCategory][TargetType].Penalty = 0 - PlayerData.Kill[TargetCategory][TargetType].PenaltyKill = 0 - end + -- Some variables + local InitUnitName = PlayerData.UnitName + local InitUnitType = PlayerData.UnitType + local InitCoalition = PlayerData.UnitCoalition + local InitCategory = PlayerData.UnitCategory + local InitUnitCoalition = _DATABASECoalition[InitCoalition] + local InitUnitCategory = _DATABASECategory[InitCategory] - if InitCoalition == TargetCoalition then - PlayerData.Penalty = PlayerData.Penalty + 25 - PlayerData.Kill[TargetCategory][TargetType].Penalty = PlayerData.Kill[TargetCategory][TargetType].Penalty + 25 - PlayerData.Kill[TargetCategory][TargetType].PenaltyKill = PlayerData.Kill[TargetCategory][TargetType].PenaltyKill + 1 - MESSAGE:New( "Player '" .. PlayerName .. "' killed a friendly " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. - PlayerData.Kill[TargetCategory][TargetType].PenaltyKill .. " times. Penalty: -" .. PlayerData.Kill[TargetCategory][TargetType].Penalty .. - ". Score Total:" .. PlayerData.Score - PlayerData.Penalty, - "", 5, "/PENALTY" .. PlayerName .. "/" .. InitUnitName ):ToAll() - self:ScoreAdd( PlayerName, "KILL_PENALTY", 1, -125, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) - else - PlayerData.Score = PlayerData.Score + 10 - PlayerData.Kill[TargetCategory][TargetType].Score = PlayerData.Kill[TargetCategory][TargetType].Score + 10 - PlayerData.Kill[TargetCategory][TargetType].ScoreKill = PlayerData.Kill[TargetCategory][TargetType].ScoreKill + 1 - MESSAGE:New( "Player '" .. PlayerName .. "' killed an enemy " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. - PlayerData.Kill[TargetCategory][TargetType].ScoreKill .. " times. Score: " .. PlayerData.Kill[TargetCategory][TargetType].Score .. - ". Score Total:" .. PlayerData.Score - PlayerData.Penalty, - "", 5, "/SCORE" .. PlayerName .. "/" .. InitUnitName ):ToAll() - self:ScoreAdd( PlayerName, "KILL_SCORE", 1, 10, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) - end - end - end - end - end + self:T( { InitUnitName, InitUnitType, InitUnitCoalition, InitCoalition, InitUnitCategory, InitCategory } ) + + -- What is he hitting? + if TargetCategory then + if PlayerData and PlayerData.Hit and PlayerData.Hit[TargetCategory] and PlayerData.Hit[TargetCategory][TargetUnitName] then -- Was there a hit for this unit for this player before registered??? + if not PlayerData.Kill[TargetCategory] then + PlayerData.Kill[TargetCategory] = {} + end + if not PlayerData.Kill[TargetCategory][TargetType] then + PlayerData.Kill[TargetCategory][TargetType] = {} + PlayerData.Kill[TargetCategory][TargetType].Score = 0 + PlayerData.Kill[TargetCategory][TargetType].ScoreKill = 0 + PlayerData.Kill[TargetCategory][TargetType].Penalty = 0 + PlayerData.Kill[TargetCategory][TargetType].PenaltyKill = 0 + end + + if InitCoalition == TargetCoalition then + PlayerData.Penalty = PlayerData.Penalty + 25 + PlayerData.Kill[TargetCategory][TargetType].Penalty = PlayerData.Kill[TargetCategory][TargetType].Penalty + 25 + PlayerData.Kill[TargetCategory][TargetType].PenaltyKill = PlayerData.Kill[TargetCategory][TargetType].PenaltyKill + 1 + MESSAGE:New( "Player '" .. PlayerName .. "' killed a friendly " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. + PlayerData.Kill[TargetCategory][TargetType].PenaltyKill .. " times. Penalty: -" .. PlayerData.Kill[TargetCategory][TargetType].Penalty .. + ". Score Total:" .. PlayerData.Score - PlayerData.Penalty, + "", 5, "/PENALTY" .. PlayerName .. "/" .. InitUnitName ):ToAll() + self:ScoreAdd( PlayerName, "KILL_PENALTY", 1, -125, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) + else + PlayerData.Score = PlayerData.Score + 10 + PlayerData.Kill[TargetCategory][TargetType].Score = PlayerData.Kill[TargetCategory][TargetType].Score + 10 + PlayerData.Kill[TargetCategory][TargetType].ScoreKill = PlayerData.Kill[TargetCategory][TargetType].ScoreKill + 1 + MESSAGE:New( "Player '" .. PlayerName .. "' killed an enemy " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. + PlayerData.Kill[TargetCategory][TargetType].ScoreKill .. " times. Score: " .. PlayerData.Kill[TargetCategory][TargetType].Score .. + ". Score Total:" .. PlayerData.Score - PlayerData.Penalty, + "", 5, "/SCORE" .. PlayerName .. "/" .. InitUnitName ):ToAll() + self:ScoreAdd( PlayerName, "KILL_SCORE", 1, 10, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) + end + end + end + end + end end @@ -5307,20 +5805,20 @@ end --- Follows new players entering Clients within the DCSRTE. function DATABASE:_FollowPlayers() - self:F3( "_FollowPlayers" ) + self:F3( "_FollowPlayers" ) - local ClientUnit = 0 - local CoalitionsData = { AlivePlayersRed = coalition.getPlayers(coalition.side.RED), AlivePlayersBlue = coalition.getPlayers(coalition.side.BLUE) } - local unitId - local unitData - local AlivePlayerUnits = {} - - for CoalitionId, CoalitionData in pairs( CoalitionsData ) do - self:T3( { "_FollowPlayers", CoalitionData } ) - for UnitId, UnitData in pairs( CoalitionData ) do - self:_AddPlayerFromUnit( UnitData ) - end - end + local ClientUnit = 0 + local CoalitionsData = { AlivePlayersRed = coalition.getPlayers(coalition.side.RED), AlivePlayersBlue = coalition.getPlayers(coalition.side.BLUE) } + local unitId + local unitData + local AlivePlayerUnits = {} + + for CoalitionId, CoalitionData in pairs( CoalitionsData ) do + self:T3( { "_FollowPlayers", CoalitionData } ) + for UnitId, UnitData in pairs( CoalitionData ) do + self:_AddPlayerFromUnit( UnitData ) + end + end end @@ -5330,102 +5828,102 @@ end --- Add a new player entering a Unit. function DATABASE:_AddPlayerFromUnit( UnitData ) - self:F( UnitData ) + self:F( UnitData ) - if UnitData:isExist() then - local UnitName = UnitData:getName() - local PlayerName = UnitData:getPlayerName() - local UnitDesc = UnitData:getDesc() - local UnitCategory = UnitDesc.category - local UnitCoalition = UnitData:getCoalition() - local UnitTypeName = UnitData:getTypeName() + if UnitData:isExist() then + local UnitName = UnitData:getName() + local PlayerName = UnitData:getPlayerName() + local UnitDesc = UnitData:getDesc() + local UnitCategory = UnitDesc.category + local UnitCoalition = UnitData:getCoalition() + local UnitTypeName = UnitData:getTypeName() - self:T( { PlayerName, UnitName, UnitCategory, UnitCoalition, UnitTypeName } ) + self:T( { PlayerName, UnitName, UnitCategory, UnitCoalition, UnitTypeName } ) - if self.Players[PlayerName] == nil then -- I believe this is the place where a Player gets a life in a mission when he enters a unit ... - self.Players[PlayerName] = {} - self.Players[PlayerName].Hit = {} - self.Players[PlayerName].Kill = {} - self.Players[PlayerName].Mission = {} - - -- for CategoryID, CategoryName in pairs( DATABASECategory ) do - -- self.Players[PlayerName].Hit[CategoryID] = {} - -- self.Players[PlayerName].Kill[CategoryID] = {} - -- end - self.Players[PlayerName].HitPlayers = {} - self.Players[PlayerName].HitUnits = {} + if self.Players[PlayerName] == nil then -- I believe this is the place where a Player gets a life in a mission when he enters a unit ... + self.Players[PlayerName] = {} + self.Players[PlayerName].Hit = {} + self.Players[PlayerName].Kill = {} + self.Players[PlayerName].Mission = {} + + -- for CategoryID, CategoryName in pairs( DATABASECategory ) do + -- self.Players[PlayerName].Hit[CategoryID] = {} + -- self.Players[PlayerName].Kill[CategoryID] = {} + -- end + self.Players[PlayerName].HitPlayers = {} + self.Players[PlayerName].HitUnits = {} self.Players[PlayerName].Score = 0 - self.Players[PlayerName].Penalty = 0 - self.Players[PlayerName].PenaltyCoalition = 0 - self.Players[PlayerName].PenaltyWarning = 0 - end + self.Players[PlayerName].Penalty = 0 + self.Players[PlayerName].PenaltyCoalition = 0 + self.Players[PlayerName].PenaltyWarning = 0 + end - if not self.Players[PlayerName].UnitCoalition then - self.Players[PlayerName].UnitCoalition = UnitCoalition - else - if self.Players[PlayerName].UnitCoalition ~= UnitCoalition then - self.Players[PlayerName].Penalty = self.Players[PlayerName].Penalty + 50 - self.Players[PlayerName].PenaltyCoalition = self.Players[PlayerName].PenaltyCoalition + 1 - MESSAGE:New( "Player '" .. PlayerName .. "' changed coalition from " .. DATABASECoalition[self.Players[PlayerName].UnitCoalition] .. " to " .. DATABASECoalition[UnitCoalition] .. - "(changed " .. self.Players[PlayerName].PenaltyCoalition .. " times the coalition). 50 Penalty points added.", - "", - 2, - "/PENALTYCOALITION" .. PlayerName - ):ToAll() - self:ScoreAdd( PlayerName, "COALITION_PENALTY", 1, -50, self.Players[PlayerName].UnitName, DATABASECoalition[self.Players[PlayerName].UnitCoalition], DATABASECategory[self.Players[PlayerName].UnitCategory], self.Players[PlayerName].UnitType, - UnitName, DATABASECoalition[UnitCoalition], DATABASECategory[UnitCategory], UnitData:getTypeName() ) - end - end - self.Players[PlayerName].UnitName = UnitName - self.Players[PlayerName].UnitCoalition = UnitCoalition - self.Players[PlayerName].UnitCategory = UnitCategory - self.Players[PlayerName].UnitType = UnitTypeName + if not self.Players[PlayerName].UnitCoalition then + self.Players[PlayerName].UnitCoalition = UnitCoalition + else + if self.Players[PlayerName].UnitCoalition ~= UnitCoalition then + self.Players[PlayerName].Penalty = self.Players[PlayerName].Penalty + 50 + self.Players[PlayerName].PenaltyCoalition = self.Players[PlayerName].PenaltyCoalition + 1 + MESSAGE:New( "Player '" .. PlayerName .. "' changed coalition from " .. _DATABASECoalition[self.Players[PlayerName].UnitCoalition] .. " to " .. _DATABASECoalition[UnitCoalition] .. + "(changed " .. self.Players[PlayerName].PenaltyCoalition .. " times the coalition). 50 Penalty points added.", + "", + 2, + "/PENALTYCOALITION" .. PlayerName + ):ToAll() + self:ScoreAdd( PlayerName, "COALITION_PENALTY", 1, -50, self.Players[PlayerName].UnitName, _DATABASECoalition[self.Players[PlayerName].UnitCoalition], _DATABASECategory[self.Players[PlayerName].UnitCategory], self.Players[PlayerName].UnitType, + UnitName, _DATABASECoalition[UnitCoalition], _DATABASECategory[UnitCategory], UnitData:getTypeName() ) + end + end + self.Players[PlayerName].UnitName = UnitName + self.Players[PlayerName].UnitCoalition = UnitCoalition + self.Players[PlayerName].UnitCategory = UnitCategory + self.Players[PlayerName].UnitType = UnitTypeName if self.Players[PlayerName].Penalty > 100 then if self.Players[PlayerName].PenaltyWarning < 1 then - MESSAGE:New( "Player '" .. PlayerName .. "': WARNING! If you continue to commit FRATRICIDE and have a PENALTY score higher than 150, you will be COURT MARTIALED and DISMISSED from this mission! \nYour total penalty is: " .. self.Players[PlayerName].Penalty, - "", - 30, - "/PENALTYCOALITION" .. PlayerName - ):ToAll() + MESSAGE:New( "Player '" .. PlayerName .. "': WARNING! If you continue to commit FRATRICIDE and have a PENALTY score higher than 150, you will be COURT MARTIALED and DISMISSED from this mission! \nYour total penalty is: " .. self.Players[PlayerName].Penalty, + "", + 30, + "/PENALTYCOALITION" .. PlayerName + ):ToAll() self.Players[PlayerName].PenaltyWarning = self.Players[PlayerName].PenaltyWarning + 1 end end - + if self.Players[PlayerName].Penalty > 150 then ClientGroup = GROUP:NewFromDCSUnit( UnitData ) ClientGroup:Destroy() - MESSAGE:New( "Player '" .. PlayerName .. "' committed FRATRICIDE, he will be COURT MARTIALED and is DISMISSED from this mission!", - "", - 10, - "/PENALTYCOALITION" .. PlayerName - ):ToAll() + MESSAGE:New( "Player '" .. PlayerName .. "' committed FRATRICIDE, he will be COURT MARTIALED and is DISMISSED from this mission!", + "", + 10, + "/PENALTYCOALITION" .. PlayerName + ):ToAll() end - - end + + end end --- Registers Scores the players completing a Mission Task. function DATABASE:_AddMissionTaskScore( PlayerUnit, MissionName, Score ) - self:F( { PlayerUnit, MissionName, Score } ) + self:F( { PlayerUnit, MissionName, Score } ) - local PlayerName = PlayerUnit:getPlayerName() - - if not self.Players[PlayerName].Mission[MissionName] then - self.Players[PlayerName].Mission[MissionName] = {} - self.Players[PlayerName].Mission[MissionName].ScoreTask = 0 - self.Players[PlayerName].Mission[MissionName].ScoreMission = 0 - end - - self:T( PlayerName ) - self:T( self.Players[PlayerName].Mission[MissionName] ) + local PlayerName = PlayerUnit:getPlayerName() - self.Players[PlayerName].Score = self.Players[PlayerName].Score + Score - self.Players[PlayerName].Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score + if not self.Players[PlayerName].Mission[MissionName] then + self.Players[PlayerName].Mission[MissionName] = {} + self.Players[PlayerName].Mission[MissionName].ScoreTask = 0 + self.Players[PlayerName].Mission[MissionName].ScoreMission = 0 + end - MESSAGE:New( "Player '" .. PlayerName .. "' has finished another Task in Mission '" .. MissionName .. "'. " .. - Score .. " Score points added.", + self:T( PlayerName ) + self:T( self.Players[PlayerName].Mission[MissionName] ) + + self.Players[PlayerName].Score = self.Players[PlayerName].Score + Score + self.Players[PlayerName].Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score + + MESSAGE:New( "Player '" .. PlayerName .. "' has finished another Task in Mission '" .. MissionName .. "'. " .. + Score .. " Score points added.", "", 20, "/SCORETASK" .. PlayerName ):ToAll() _Database:ScoreAdd( PlayerName, "TASK_" .. MissionName:gsub( ' ', '_' ), 1, Score, PlayerUnit:getName() ) @@ -5434,19 +5932,19 @@ end --- Registers Mission Scores for possible multiple players that contributed in the Mission. function DATABASE:_AddMissionScore( MissionName, Score ) - self:F( { PlayerUnit, MissionName, Score } ) + self:F( { PlayerUnit, MissionName, Score } ) - for PlayerName, PlayerData in pairs( self.Players ) do - - if PlayerData.Mission[MissionName] then - PlayerData.Score = PlayerData.Score + Score - PlayerData.Mission[MissionName].ScoreMission = PlayerData.Mission[MissionName].ScoreMission + Score - MESSAGE:New( "Player '" .. PlayerName .. "' has finished Mission '" .. MissionName .. "'. " .. - Score .. " Score points added.", - "", 20, "/SCOREMISSION" .. PlayerName ):ToAll() - _Database:ScoreAdd( PlayerName, "MISSION_" .. MissionName:gsub( ' ', '_' ), 1, Score ) - end - end + for PlayerName, PlayerData in pairs( self.Players ) do + + if PlayerData.Mission[MissionName] then + PlayerData.Score = PlayerData.Score + Score + PlayerData.Mission[MissionName].ScoreMission = PlayerData.Mission[MissionName].ScoreMission + Score + MESSAGE:New( "Player '" .. PlayerName .. "' has finished Mission '" .. MissionName .. "'. " .. + Score .. " Score points added.", + "", 20, "/SCOREMISSION" .. PlayerName ):ToAll() + _Database:ScoreAdd( PlayerName, "MISSION_" .. MissionName:gsub( ' ', '_' ), 1, Score ) + end + end end @@ -5454,373 +5952,367 @@ end -- @section Events -function DATABASE:OnHit( event ) - self:F( { event } ) +--- Handles the OnHit event for the scoring. +-- @param #DATABASE self +-- @param Event#EVENTDATA Event +function DATABASE:_EventOnHit( Event ) + self:F( { Event } ) - local InitUnit = nil - local InitUnitName = "" - local InitGroupName = "" - local InitPlayerName = "dummy" + local InitUnit = nil + local InitUnitName = "" + local InitGroup = nil + local InitGroupName = "" + local InitPlayerName = "dummy" - local InitCoalition = nil - local InitCategory = nil - local InitType = nil - local InitUnitCoalition = nil - local InitUnitCategory = nil - local InitUnitType = nil + local InitCoalition = nil + local InitCategory = nil + local InitType = nil + local InitUnitCoalition = nil + local InitUnitCategory = nil + local InitUnitType = nil - local TargetUnit = nil - local TargetUnitName = "" - local TargetGroupName = "" - local TargetPlayerName = "" + local TargetUnit = nil + local TargetUnitName = "" + local TargetGroup = nil + local TargetGroupName = "" + local TargetPlayerName = "" - local TargetCoalition = nil - local TargetCategory = nil - local TargetType = nil - local TargetUnitCoalition = nil - local TargetUnitCategory = nil - local TargetUnitType = nil + local TargetCoalition = nil + local TargetCategory = nil + local TargetType = nil + local TargetUnitCoalition = nil + local TargetUnitCategory = nil + local TargetUnitType = nil - if event.initiator and event.initiator:getName() then - - if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then - - InitUnit = event.initiator - InitGroup = Unit.getGroup( InitUnit ) - InitUnitDesc = InitUnit:getDesc() - - InitUnitName = InitUnit:getName() - if InitGroup and InitGroup:isExist() then - InitGroupName = InitGroup:getName() - end - InitPlayerName = InitUnit:getPlayerName() - - InitCoalition = InitUnit:getCoalition() - --InitCategory = InitUnit:getCategory() - InitCategory = InitUnitDesc.category -- Workaround - InitType = InitUnit:getTypeName() + if Event.IniDCSUnit then - InitUnitCoalition = DATABASECoalition[InitCoalition] - InitUnitCategory = DATABASECategory[InitCategory] - InitUnitType = InitType - - self:T( { InitUnitName, InitGroupName, InitPlayerName, InitCoalition, InitCategory, InitType , InitUnitCoalition, InitUnitCategory, InitUnitType } ) - self:T( { InitUnitDesc } ) - end + InitUnit = Event.IniDCSUnit + InitUnitName = Event.IniDCSUnitName + InitGroup = Event.IniDCSGroup + InitGroupName = Event.IniDCSGroupName + InitPlayerName = InitUnit:getPlayerName() - - if event.target and Object.getCategory(event.target) == Object.Category.UNIT then - - TargetUnit = event.target - TargetGroup = Unit.getGroup( TargetUnit ) - TargetUnitDesc = TargetUnit:getDesc() - - TargetUnitName = TargetUnit:getName() - if TargetGroup and TargetGroup:isExist() then - TargetGroupName = TargetGroup:getName() - end - TargetPlayerName = TargetUnit:getPlayerName() + InitCoalition = InitUnit:getCoalition() + --TODO: Workaround Client DCS Bug + --InitCategory = InitUnit:getCategory() + InitCategory = InitUnit:getDesc().category + InitType = InitUnit:getTypeName() - TargetCoalition = TargetUnit:getCoalition() - --TargetCategory = TargetUnit:getCategory() - TargetCategory = TargetUnitDesc.category -- Workaround - TargetType = TargetUnit:getTypeName() + InitUnitCoalition = _DATABASECoalition[InitCoalition] + InitUnitCategory = _DATABASECategory[InitCategory] + InitUnitType = InitType - TargetUnitCoalition = DATABASECoalition[TargetCoalition] - TargetUnitCategory = DATABASECategory[TargetCategory] - TargetUnitType = TargetType - - self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType, TargetUnitCoalition, TargetUnitCategory, TargetUnitType } ) - self:T( { TargetUnitDesc } ) - end - - if InitPlayerName ~= nil then -- It is a player that is hitting something - self:_AddPlayerFromUnit( InitUnit ) - if self.Players[InitPlayerName] then -- This should normally not happen, but i'll test it anyway. - if TargetPlayerName ~= nil then -- It is a player hitting another player ... - self:_AddPlayerFromUnit( TargetUnit ) - self.Players[InitPlayerName].HitPlayers = self.Players[InitPlayerName].HitPlayers + 1 - end - - self:T( "Hitting Something" ) - -- What is he hitting? - if TargetCategory then - if not self.Players[InitPlayerName].Hit[TargetCategory] then - self.Players[InitPlayerName].Hit[TargetCategory] = {} - end - if not self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName] then - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName] = {} - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score = 0 - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty = 0 - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit = 0 - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit = 0 - end - local Score = 0 - if InitCoalition == TargetCoalition then - self.Players[InitPlayerName].Penalty = self.Players[InitPlayerName].Penalty + 10 - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty + 10 - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit + 1 - MESSAGE:New( "Player '" .. InitPlayerName .. "' hit a friendly " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit .. " times. Penalty: -" .. self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty .. - ". Score Total:" .. self.Players[InitPlayerName].Score - self.Players[InitPlayerName].Penalty, - "", - 2, - "/PENALTY" .. InitPlayerName .. "/" .. InitUnitName - ):ToAll() - self:ScoreAdd( InitPlayerName, "HIT_PENALTY", 1, -25, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) - else - self.Players[InitPlayerName].Score = self.Players[InitPlayerName].Score + 10 - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score + 1 - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit + 1 - MESSAGE:New( "Player '" .. InitPlayerName .. "' hit a target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit .. " times. Score: " .. self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score .. - ". Score Total:" .. self.Players[InitPlayerName].Score - self.Players[InitPlayerName].Penalty, - "", - 2, - "/SCORE" .. InitPlayerName .. "/" .. InitUnitName - ):ToAll() - self:ScoreAdd( InitPlayerName, "HIT_SCORE", 1, 1, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) - end - end - end - elseif InitPlayerName == nil then -- It is an AI hitting a player??? - - end - end + self:T( { InitUnitName, InitGroupName, InitPlayerName, InitCoalition, InitCategory, InitType , InitUnitCoalition, InitUnitCategory, InitUnitType } ) + end + + + if Event.TgtDCSUnit then + + TargetUnit = Event.TgtDCSUnit + TargetUnitName = Event.TgtDCSUnitName + TargetGroup = Event.TgtDCSGroup + TargetGroupName = Event.TgtDCSGroupName + TargetPlayerName = TargetUnit:getPlayerName() + + TargetCoalition = TargetUnit:getCoalition() + --TODO: Workaround Client DCS Bug + --TargetCategory = TargetUnit:getCategory() + TargetCategory = TargetUnit:getDesc().category + TargetType = TargetUnit:getTypeName() + + TargetUnitCoalition = _DATABASECoalition[TargetCoalition] + TargetUnitCategory = _DATABASECategory[TargetCategory] + TargetUnitType = TargetType + + self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType, TargetUnitCoalition, TargetUnitCategory, TargetUnitType } ) + end + + if InitPlayerName ~= nil then -- It is a player that is hitting something + self:_AddPlayerFromUnit( InitUnit ) + if self.Players[InitPlayerName] then -- This should normally not happen, but i'll test it anyway. + if TargetPlayerName ~= nil then -- It is a player hitting another player ... + self:_AddPlayerFromUnit( TargetUnit ) + self.Players[InitPlayerName].HitPlayers = self.Players[InitPlayerName].HitPlayers + 1 + end + + self:T( "Hitting Something" ) + -- What is he hitting? + if TargetCategory then + if not self.Players[InitPlayerName].Hit[TargetCategory] then + self.Players[InitPlayerName].Hit[TargetCategory] = {} + end + if not self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName] then + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName] = {} + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score = 0 + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty = 0 + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit = 0 + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit = 0 + end + local Score = 0 + if InitCoalition == TargetCoalition then + self.Players[InitPlayerName].Penalty = self.Players[InitPlayerName].Penalty + 10 + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty + 10 + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit + 1 + MESSAGE:New( "Player '" .. InitPlayerName .. "' hit a friendly " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit .. " times. Penalty: -" .. self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty .. + ". Score Total:" .. self.Players[InitPlayerName].Score - self.Players[InitPlayerName].Penalty, + "", + 2, + "/PENALTY" .. InitPlayerName .. "/" .. InitUnitName + ):ToAll() + self:ScoreAdd( InitPlayerName, "HIT_PENALTY", 1, -25, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) + else + self.Players[InitPlayerName].Score = self.Players[InitPlayerName].Score + 10 + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score + 1 + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit + 1 + MESSAGE:New( "Player '" .. InitPlayerName .. "' hit a target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit .. " times. Score: " .. self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score .. + ". Score Total:" .. self.Players[InitPlayerName].Score - self.Players[InitPlayerName].Penalty, + "", + 2, + "/SCORE" .. InitPlayerName .. "/" .. InitUnitName + ):ToAll() + self:ScoreAdd( InitPlayerName, "HIT_SCORE", 1, 1, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) + end + end + end + elseif InitPlayerName == nil then -- It is an AI hitting a player??? + + end end function DATABASE:ReportScoreAll() -env.info( "Hello World " ) + env.info( "Hello World " ) - local ScoreMessage = "" - local PlayerMessage = "" - - self:T( "Score Report" ) + local ScoreMessage = "" + local PlayerMessage = "" - for PlayerName, PlayerData in pairs( self.Players ) do - if PlayerData then -- This should normally not happen, but i'll test it anyway. - self:T( "Score Player: " .. PlayerName ) + self:T( "Score Report" ) - -- Some variables - local InitUnitCoalition = DATABASECoalition[PlayerData.UnitCoalition] - local InitUnitCategory = DATABASECategory[PlayerData.UnitCategory] - local InitUnitType = PlayerData.UnitType - local InitUnitName = PlayerData.UnitName - - local PlayerScore = 0 - local PlayerPenalty = 0 - - ScoreMessage = ":\n" - - local ScoreMessageHits = "" + for PlayerName, PlayerData in pairs( self.Players ) do + if PlayerData then -- This should normally not happen, but i'll test it anyway. + self:T( "Score Player: " .. PlayerName ) - for CategoryID, CategoryName in pairs( DATABASECategory ) do - self:T( CategoryName ) - if PlayerData.Hit[CategoryID] then - local Score = 0 - local ScoreHit = 0 - local Penalty = 0 - local PenaltyHit = 0 - self:T( "Hit scores exist for player " .. PlayerName ) - for UnitName, UnitData in pairs( PlayerData.Hit[CategoryID] ) do - Score = Score + UnitData.Score - ScoreHit = ScoreHit + UnitData.ScoreHit - Penalty = Penalty + UnitData.Penalty - PenaltyHit = UnitData.PenaltyHit - end - local ScoreMessageHit = string.format( "%s:%d ", CategoryName, Score - Penalty ) - self:T( ScoreMessageHit ) - ScoreMessageHits = ScoreMessageHits .. ScoreMessageHit - PlayerScore = PlayerScore + Score - PlayerPenalty = PlayerPenalty + Penalty - else - --ScoreMessageHits = ScoreMessageHits .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 ) - end - end - if ScoreMessageHits ~= "" then - ScoreMessage = ScoreMessage .. " Hits: " .. ScoreMessageHits .. "\n" - end - - local ScoreMessageKills = "" - for CategoryID, CategoryName in pairs( DATABASECategory ) do - self:T( "Kill scores exist for player " .. PlayerName ) - if PlayerData.Kill[CategoryID] then - local Score = 0 - local ScoreKill = 0 - local Penalty = 0 - local PenaltyKill = 0 - - for UnitName, UnitData in pairs( PlayerData.Kill[CategoryID] ) do - Score = Score + UnitData.Score - ScoreKill = ScoreKill + UnitData.ScoreKill - Penalty = Penalty + UnitData.Penalty - PenaltyKill = PenaltyKill + UnitData.PenaltyKill - end - - local ScoreMessageKill = string.format( " %s:%d ", CategoryName, Score - Penalty ) - self:T( ScoreMessageKill ) - ScoreMessageKills = ScoreMessageKills .. ScoreMessageKill + -- Some variables + local InitUnitCoalition = _DATABASECoalition[PlayerData.UnitCoalition] + local InitUnitCategory = _DATABASECategory[PlayerData.UnitCategory] + local InitUnitType = PlayerData.UnitType + local InitUnitName = PlayerData.UnitName - PlayerScore = PlayerScore + Score - PlayerPenalty = PlayerPenalty + Penalty - else - --ScoreMessageKills = ScoreMessageKills .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 ) - end - end - if ScoreMessageKills ~= "" then - ScoreMessage = ScoreMessage .. " Kills: " .. ScoreMessageKills .. "\n" - end - - local ScoreMessageCoalitionChangePenalties = "" - if PlayerData.PenaltyCoalition ~= 0 then - ScoreMessageCoalitionChangePenalties = ScoreMessageCoalitionChangePenalties .. string.format( " -%d (%d changed)", PlayerData.Penalty, PlayerData.PenaltyCoalition ) - PlayerPenalty = PlayerPenalty + PlayerData.Penalty - end - if ScoreMessageCoalitionChangePenalties ~= "" then - ScoreMessage = ScoreMessage .. " Coalition Penalties: " .. ScoreMessageCoalitionChangePenalties .. "\n" - end + local PlayerScore = 0 + local PlayerPenalty = 0 - local ScoreMessageMission = "" - local ScoreMission = 0 - local ScoreTask = 0 - for MissionName, MissionData in pairs( PlayerData.Mission ) do - ScoreMission = ScoreMission + MissionData.ScoreMission - ScoreTask = ScoreTask + MissionData.ScoreTask - ScoreMessageMission = ScoreMessageMission .. "'" .. MissionName .. "'; " - end - PlayerScore = PlayerScore + ScoreMission + ScoreTask + ScoreMessage = ":\n" - if ScoreMessageMission ~= "" then - ScoreMessage = ScoreMessage .. " Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ")\n" - end - - PlayerMessage = PlayerMessage .. string.format( "Player '%s' Score:%d (%d Score -%d Penalties)%s", PlayerName, PlayerScore - PlayerPenalty, PlayerScore, PlayerPenalty, ScoreMessage ) - end - end - MESSAGE:New( PlayerMessage, "Player Scores", 30, "AllPlayerScores"):ToAll() + local ScoreMessageHits = "" + + for CategoryID, CategoryName in pairs( _DATABASECategory ) do + self:T( CategoryName ) + if PlayerData.Hit[CategoryID] then + local Score = 0 + local ScoreHit = 0 + local Penalty = 0 + local PenaltyHit = 0 + self:T( "Hit scores exist for player " .. PlayerName ) + for UnitName, UnitData in pairs( PlayerData.Hit[CategoryID] ) do + Score = Score + UnitData.Score + ScoreHit = ScoreHit + UnitData.ScoreHit + Penalty = Penalty + UnitData.Penalty + PenaltyHit = UnitData.PenaltyHit + end + local ScoreMessageHit = string.format( "%s:%d ", CategoryName, Score - Penalty ) + self:T( ScoreMessageHit ) + ScoreMessageHits = ScoreMessageHits .. ScoreMessageHit + PlayerScore = PlayerScore + Score + PlayerPenalty = PlayerPenalty + Penalty + else + --ScoreMessageHits = ScoreMessageHits .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 ) + end + end + if ScoreMessageHits ~= "" then + ScoreMessage = ScoreMessage .. " Hits: " .. ScoreMessageHits .. "\n" + end + + local ScoreMessageKills = "" + for CategoryID, CategoryName in pairs( _DATABASECategory ) do + self:T( "Kill scores exist for player " .. PlayerName ) + if PlayerData.Kill[CategoryID] then + local Score = 0 + local ScoreKill = 0 + local Penalty = 0 + local PenaltyKill = 0 + + for UnitName, UnitData in pairs( PlayerData.Kill[CategoryID] ) do + Score = Score + UnitData.Score + ScoreKill = ScoreKill + UnitData.ScoreKill + Penalty = Penalty + UnitData.Penalty + PenaltyKill = PenaltyKill + UnitData.PenaltyKill + end + + local ScoreMessageKill = string.format( " %s:%d ", CategoryName, Score - Penalty ) + self:T( ScoreMessageKill ) + ScoreMessageKills = ScoreMessageKills .. ScoreMessageKill + + PlayerScore = PlayerScore + Score + PlayerPenalty = PlayerPenalty + Penalty + else + --ScoreMessageKills = ScoreMessageKills .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 ) + end + end + if ScoreMessageKills ~= "" then + ScoreMessage = ScoreMessage .. " Kills: " .. ScoreMessageKills .. "\n" + end + + local ScoreMessageCoalitionChangePenalties = "" + if PlayerData.PenaltyCoalition ~= 0 then + ScoreMessageCoalitionChangePenalties = ScoreMessageCoalitionChangePenalties .. string.format( " -%d (%d changed)", PlayerData.Penalty, PlayerData.PenaltyCoalition ) + PlayerPenalty = PlayerPenalty + PlayerData.Penalty + end + if ScoreMessageCoalitionChangePenalties ~= "" then + ScoreMessage = ScoreMessage .. " Coalition Penalties: " .. ScoreMessageCoalitionChangePenalties .. "\n" + end + + local ScoreMessageMission = "" + local ScoreMission = 0 + local ScoreTask = 0 + for MissionName, MissionData in pairs( PlayerData.Mission ) do + ScoreMission = ScoreMission + MissionData.ScoreMission + ScoreTask = ScoreTask + MissionData.ScoreTask + ScoreMessageMission = ScoreMessageMission .. "'" .. MissionName .. "'; " + end + PlayerScore = PlayerScore + ScoreMission + ScoreTask + + if ScoreMessageMission ~= "" then + ScoreMessage = ScoreMessage .. " Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ")\n" + end + + PlayerMessage = PlayerMessage .. string.format( "Player '%s' Score:%d (%d Score -%d Penalties)%s", PlayerName, PlayerScore - PlayerPenalty, PlayerScore, PlayerPenalty, ScoreMessage ) + end + end + MESSAGE:New( PlayerMessage, "Player Scores", 30, "AllPlayerScores"):ToAll() end function DATABASE:ReportScorePlayer() -env.info( "Hello World " ) + env.info( "Hello World " ) - local ScoreMessage = "" - local PlayerMessage = "" - - self:T( "Score Report" ) + local ScoreMessage = "" + local PlayerMessage = "" - for PlayerName, PlayerData in pairs( self.Players ) do - if PlayerData then -- This should normally not happen, but i'll test it anyway. - self:T( "Score Player: " .. PlayerName ) + self:T( "Score Report" ) - -- Some variables - local InitUnitCoalition = DATABASECoalition[PlayerData.UnitCoalition] - local InitUnitCategory = DATABASECategory[PlayerData.UnitCategory] - local InitUnitType = PlayerData.UnitType - local InitUnitName = PlayerData.UnitName - - local PlayerScore = 0 - local PlayerPenalty = 0 - - ScoreMessage = "" - - local ScoreMessageHits = "" + for PlayerName, PlayerData in pairs( self.Players ) do + if PlayerData then -- This should normally not happen, but i'll test it anyway. + self:T( "Score Player: " .. PlayerName ) - for CategoryID, CategoryName in pairs( DATABASECategory ) do - self:T( CategoryName ) - if PlayerData.Hit[CategoryID] then - local Score = 0 - local ScoreHit = 0 - local Penalty = 0 - local PenaltyHit = 0 - self:T( "Hit scores exist for player " .. PlayerName ) - for UnitName, UnitData in pairs( PlayerData.Hit[CategoryID] ) do - Score = Score + UnitData.Score - ScoreHit = ScoreHit + UnitData.ScoreHit - Penalty = Penalty + UnitData.Penalty - PenaltyHit = UnitData.PenaltyHit - end - local ScoreMessageHit = string.format( "\n %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreHit, PenaltyHit ) - self:T( ScoreMessageHit ) - ScoreMessageHits = ScoreMessageHits .. ScoreMessageHit - PlayerScore = PlayerScore + Score - PlayerPenalty = PlayerPenalty + Penalty - else - --ScoreMessageHits = ScoreMessageHits .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 ) - end - end - if ScoreMessageHits ~= "" then - ScoreMessage = ScoreMessage .. "\n Hits: " .. ScoreMessageHits .. " " - end - - local ScoreMessageKills = "" - for CategoryID, CategoryName in pairs( DATABASECategory ) do - self:T( "Kill scores exist for player " .. PlayerName ) - if PlayerData.Kill[CategoryID] then - local Score = 0 - local ScoreKill = 0 - local Penalty = 0 - local PenaltyKill = 0 - - for UnitName, UnitData in pairs( PlayerData.Kill[CategoryID] ) do - Score = Score + UnitData.Score - ScoreKill = ScoreKill + UnitData.ScoreKill - Penalty = Penalty + UnitData.Penalty - PenaltyKill = PenaltyKill + UnitData.PenaltyKill - end - - local ScoreMessageKill = string.format( "\n %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreKill, PenaltyKill ) - self:T( ScoreMessageKill ) - ScoreMessageKills = ScoreMessageKills .. ScoreMessageKill + -- Some variables + local InitUnitCoalition = _DATABASECoalition[PlayerData.UnitCoalition] + local InitUnitCategory = _DATABASECategory[PlayerData.UnitCategory] + local InitUnitType = PlayerData.UnitType + local InitUnitName = PlayerData.UnitName - PlayerScore = PlayerScore + Score - PlayerPenalty = PlayerPenalty + Penalty - else - --ScoreMessageKills = ScoreMessageKills .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 ) - end - end - if ScoreMessageKills ~= "" then - ScoreMessage = ScoreMessage .. "\n Kills: " .. ScoreMessageKills .. " " - end - - local ScoreMessageCoalitionChangePenalties = "" - if PlayerData.PenaltyCoalition ~= 0 then - ScoreMessageCoalitionChangePenalties = ScoreMessageCoalitionChangePenalties .. string.format( " -%d (%d changed)", PlayerData.Penalty, PlayerData.PenaltyCoalition ) - PlayerPenalty = PlayerPenalty + PlayerData.Penalty - end - if ScoreMessageCoalitionChangePenalties ~= "" then - ScoreMessage = ScoreMessage .. "\n Coalition: " .. ScoreMessageCoalitionChangePenalties .. " " - end + local PlayerScore = 0 + local PlayerPenalty = 0 - local ScoreMessageMission = "" - local ScoreMission = 0 - local ScoreTask = 0 - for MissionName, MissionData in pairs( PlayerData.Mission ) do - ScoreMission = ScoreMission + MissionData.ScoreMission - ScoreTask = ScoreTask + MissionData.ScoreTask - ScoreMessageMission = ScoreMessageMission .. "'" .. MissionName .. "'; " - end - PlayerScore = PlayerScore + ScoreMission + ScoreTask + ScoreMessage = "" - if ScoreMessageMission ~= "" then - ScoreMessage = ScoreMessage .. "\n Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ") " - end - - PlayerMessage = PlayerMessage .. string.format( "Player '%s' Score = %d ( %d Score, -%d Penalties ):%s", PlayerName, PlayerScore - PlayerPenalty, PlayerScore, PlayerPenalty, ScoreMessage ) - end - end - MESSAGE:New( PlayerMessage, "Player Scores", 30, "AllPlayerScores"):ToAll() + local ScoreMessageHits = "" + + for CategoryID, CategoryName in pairs( _DATABASECategory ) do + self:T( CategoryName ) + if PlayerData.Hit[CategoryID] then + local Score = 0 + local ScoreHit = 0 + local Penalty = 0 + local PenaltyHit = 0 + self:T( "Hit scores exist for player " .. PlayerName ) + for UnitName, UnitData in pairs( PlayerData.Hit[CategoryID] ) do + Score = Score + UnitData.Score + ScoreHit = ScoreHit + UnitData.ScoreHit + Penalty = Penalty + UnitData.Penalty + PenaltyHit = UnitData.PenaltyHit + end + local ScoreMessageHit = string.format( "\n %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreHit, PenaltyHit ) + self:T( ScoreMessageHit ) + ScoreMessageHits = ScoreMessageHits .. ScoreMessageHit + PlayerScore = PlayerScore + Score + PlayerPenalty = PlayerPenalty + Penalty + else + --ScoreMessageHits = ScoreMessageHits .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 ) + end + end + if ScoreMessageHits ~= "" then + ScoreMessage = ScoreMessage .. "\n Hits: " .. ScoreMessageHits .. " " + end + + local ScoreMessageKills = "" + for CategoryID, CategoryName in pairs( _DATABASECategory ) do + self:T( "Kill scores exist for player " .. PlayerName ) + if PlayerData.Kill[CategoryID] then + local Score = 0 + local ScoreKill = 0 + local Penalty = 0 + local PenaltyKill = 0 + + for UnitName, UnitData in pairs( PlayerData.Kill[CategoryID] ) do + Score = Score + UnitData.Score + ScoreKill = ScoreKill + UnitData.ScoreKill + Penalty = Penalty + UnitData.Penalty + PenaltyKill = PenaltyKill + UnitData.PenaltyKill + end + + local ScoreMessageKill = string.format( "\n %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreKill, PenaltyKill ) + self:T( ScoreMessageKill ) + ScoreMessageKills = ScoreMessageKills .. ScoreMessageKill + + PlayerScore = PlayerScore + Score + PlayerPenalty = PlayerPenalty + Penalty + else + --ScoreMessageKills = ScoreMessageKills .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 ) + end + end + if ScoreMessageKills ~= "" then + ScoreMessage = ScoreMessage .. "\n Kills: " .. ScoreMessageKills .. " " + end + + local ScoreMessageCoalitionChangePenalties = "" + if PlayerData.PenaltyCoalition ~= 0 then + ScoreMessageCoalitionChangePenalties = ScoreMessageCoalitionChangePenalties .. string.format( " -%d (%d changed)", PlayerData.Penalty, PlayerData.PenaltyCoalition ) + PlayerPenalty = PlayerPenalty + PlayerData.Penalty + end + if ScoreMessageCoalitionChangePenalties ~= "" then + ScoreMessage = ScoreMessage .. "\n Coalition: " .. ScoreMessageCoalitionChangePenalties .. " " + end + + local ScoreMessageMission = "" + local ScoreMission = 0 + local ScoreTask = 0 + for MissionName, MissionData in pairs( PlayerData.Mission ) do + ScoreMission = ScoreMission + MissionData.ScoreMission + ScoreTask = ScoreTask + MissionData.ScoreTask + ScoreMessageMission = ScoreMessageMission .. "'" .. MissionName .. "'; " + end + PlayerScore = PlayerScore + ScoreMission + ScoreTask + + if ScoreMessageMission ~= "" then + ScoreMessage = ScoreMessage .. "\n Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ") " + end + + PlayerMessage = PlayerMessage .. string.format( "Player '%s' Score = %d ( %d Score, -%d Penalties ):%s", PlayerName, PlayerScore - PlayerPenalty, PlayerScore, PlayerPenalty, ScoreMessage ) + end + end + MESSAGE:New( PlayerMessage, "Player Scores", 30, "AllPlayerScores"):ToAll() end function DATABASE:ScoreMenu() - local ReportScore = SUBMENU:New( 'Scoring' ) - local ReportAllScores = COMMANDMENU:New( 'Score All Active Players', ReportScore, DATABASE.ReportScoreAll, self ) - local ReportPlayerScores = COMMANDMENU:New('Your Current Score', ReportScore, DATABASE.ReportScorePlayer, self ) + local ReportScore = SUBMENU:New( 'Scoring' ) + local ReportAllScores = COMMANDMENU:New( 'Score All Active Players', ReportScore, DATABASE.ReportScoreAll, self ) + local ReportPlayerScores = COMMANDMENU:New('Your Current Score', ReportScore, DATABASE.ReportScorePlayer, self ) end @@ -5829,102 +6321,116 @@ end -- File Logic for tracking the scores function DATABASE:SecondsToClock(sSeconds) -local nSeconds = sSeconds - if nSeconds == 0 then - --return nil; - return "00:00:00"; - else - nHours = string.format("%02.f", math.floor(nSeconds/3600)); - nMins = string.format("%02.f", math.floor(nSeconds/60 - (nHours*60))); - nSecs = string.format("%02.f", math.floor(nSeconds - nHours*3600 - nMins *60)); - return nHours..":"..nMins..":"..nSecs - end + local nSeconds = sSeconds + if nSeconds == 0 then + --return nil; + return "00:00:00"; + else + nHours = string.format("%02.f", math.floor(nSeconds/3600)); + nMins = string.format("%02.f", math.floor(nSeconds/60 - (nHours*60))); + nSecs = string.format("%02.f", math.floor(nSeconds - nHours*3600 - nMins *60)); + return nHours..":"..nMins..":"..nSecs + end end function DATABASE:ScoreOpen() - if lfs then - local fdir = lfs.writedir() .. [[Logs\]] .. "Player_Scores_" .. os.date( "%Y-%m-%d_%H-%M-%S" ) .. ".csv" - self.StatFile, self.err = io.open(fdir,"w+") - if not self.StatFile then - error( "Error: Cannot open 'Player Scores.csv' file in " .. lfs.writedir() ) - end - self.StatFile:write( '"RunID";"Time";"PlayerName";"ScoreType";"PlayerUnitCoaltion";"PlayerUnitCategory";"PlayerUnitType";"PlayerUnitName";"TargetUnitCoalition";"TargetUnitCategory";"TargetUnitType";"TargetUnitName";"Times";"Score"\n' ) - - self.RunID = os.date("%y-%m-%d_%H-%M-%S") - end + if lfs then + local fdir = lfs.writedir() .. [[Logs\]] .. "Player_Scores_" .. os.date( "%Y-%m-%d_%H-%M-%S" ) .. ".csv" + self.StatFile, self.err = io.open(fdir,"w+") + if not self.StatFile then + error( "Error: Cannot open 'Player Scores.csv' file in " .. lfs.writedir() ) + end + self.StatFile:write( '"RunID","Time","PlayerName","ScoreType","PlayerUnitCoaltion","PlayerUnitCategory","PlayerUnitType","PlayerUnitName","TargetUnitCoalition","TargetUnitCategory","TargetUnitType","TargetUnitName","Times","Score"\n' ) + + self.RunID = os.date("%y-%m-%d_%H-%M-%S") + end end function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, PlayerUnitName, PlayerUnitCoalition, PlayerUnitCategory, PlayerUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) - --write statistic information to file - local ScoreTime = self:SecondsToClock(timer.getTime()) - PlayerName = PlayerName:gsub( '"', '_' ) + --write statistic information to file + local ScoreTime = self:SecondsToClock(timer.getTime()) + PlayerName = PlayerName:gsub( '"', '_' ) - if PlayerUnitName and PlayerUnitName ~= '' then - local PlayerUnit = Unit.getByName( PlayerUnitName ) - - if PlayerUnit then - if not PlayerUnitCategory then - --PlayerUnitCategory = DATABASECategory[PlayerUnit:getCategory()] - PlayerUnitCategory = DATABASECategory[PlayerUnit:getDesc().category] - end - - if not PlayerUnitCoalition then - PlayerUnitCoalition = DATABASECoalition[PlayerUnit:getCoalition()] - end - - if not PlayerUnitType then - PlayerUnitType = PlayerUnit:getTypeName() - end - else - PlayerUnitName = '' - PlayerUnitCategory = '' - PlayerUnitCoalition = '' - PlayerUnitType = '' - end - else - PlayerUnitName = '' - PlayerUnitCategory = '' - PlayerUnitCoalition = '' - PlayerUnitType = '' - end - - if not TargetUnitCoalition then - TargetUnitCoalition = '' - end - - if not TargetUnitCategory then - TargetUnitCategory = '' - end - - if not TargetUnitType then - TargetUnitType = '' - end - - if not TargetUnitName then - TargetUnitName = '' - end + if PlayerUnitName and PlayerUnitName ~= '' then + local PlayerUnit = Unit.getByName( PlayerUnitName ) - if lfs then - self.StatFile:write( '"' .. self.RunID .. '";' .. ScoreTime .. ';"' .. PlayerName .. '";"' .. ScoreType .. '";"' .. - PlayerUnitCoalition .. '";"' .. PlayerUnitCategory .. '";"' .. PlayerUnitType .. '";"' .. PlayerUnitName .. '";"' .. - TargetUnitCoalition .. '";"' .. TargetUnitCategory .. '";"' .. TargetUnitType .. '";"' .. TargetUnitName .. '";' .. - ScoreTimes .. ';' .. ScoreAmount ) - self.StatFile:write( "\n" ) - end + if PlayerUnit then + if not PlayerUnitCategory then + --PlayerUnitCategory = DATABASECategory[PlayerUnit:getCategory()] + PlayerUnitCategory = _DATABASECategory[PlayerUnit:getDesc().category] + end + + if not PlayerUnitCoalition then + PlayerUnitCoalition = _DATABASECoalition[PlayerUnit:getCoalition()] + end + + if not PlayerUnitType then + PlayerUnitType = PlayerUnit:getTypeName() + end + else + PlayerUnitName = '' + PlayerUnitCategory = '' + PlayerUnitCoalition = '' + PlayerUnitType = '' + end + else + PlayerUnitName = '' + PlayerUnitCategory = '' + PlayerUnitCoalition = '' + PlayerUnitType = '' + end + + if not TargetUnitCoalition then + TargetUnitCoalition = '' + end + + if not TargetUnitCategory then + TargetUnitCategory = '' + end + + if not TargetUnitType then + TargetUnitType = '' + end + + if not TargetUnitName then + TargetUnitName = '' + end + + if lfs then + self.StatFile:write( + '"' .. self.RunID .. '"' .. ',' .. + '' .. ScoreTime .. '' .. ',' .. + '"' .. PlayerName .. '"' .. ',' .. + '"' .. ScoreType .. '"' .. ',' .. + '"' .. PlayerUnitCoalition .. '"' .. ',' .. + '"' .. PlayerUnitCategory .. '"' .. ',' .. + '"' .. PlayerUnitType .. '"' .. ',' .. + '"' .. PlayerUnitName .. '"' .. ',' .. + '"' .. TargetUnitCoalition .. '"' .. ',' .. + '"' .. TargetUnitCategory .. '"' .. ',' .. + '"' .. TargetUnitType .. '"' .. ',' .. + '"' .. TargetUnitName .. '"' .. ',' .. + '' .. ScoreTimes .. '' .. ',' .. + '' .. ScoreAmount + ) + + self.StatFile:write( "\n" ) + end end - + function LogClose() - if lfs then - self.StatFile:close() - end + if lfs then + self.StatFile:close() + end end _Database = DATABASE:New() -- Database#DATABASE _Database:ScoreOpen() + --- CARGO Classes -- @module CARGO @@ -8579,7 +9085,7 @@ end --- Get progress of a TASK. -- @return string GoalsText function TASK:GetGoalProgress() - self:F() + self:F2() local GoalsText = "" for GoalVerb, GoalVerbData in pairs( self.GoalTasks ) do @@ -8603,7 +9109,7 @@ end -- @param MISSION Mission Group structure describing the Mission. -- @param CLIENT Client Group structure describing the Client. function TASK:ShowGoalProgress( Mission, Client ) - self:F() + self:F2() local GoalsText = "" for GoalVerb, GoalVerbData in pairs( self.GoalTasks ) do @@ -8625,14 +9131,14 @@ end --- Sets a TASK to status Done. function TASK:Done() - self:F() + self:F2() self.TaskDone = true end --- Returns if a TASK is done. -- @return bool function TASK:IsDone() - self:F( self.TaskDone ) + self:F2( self.TaskDone ) return self.TaskDone end @@ -8645,12 +9151,12 @@ end --- Returns if a TASk has failed. -- @return bool function TASK:IsFailed() - self:F( self.TaskFailed ) + self:F2( self.TaskFailed ) return self.TaskFailed end function TASK:Reset( Mission, Client ) - self:F() + self:F2() self.ExecuteStage = _TransportExecuteStage.NONE end @@ -8661,13 +9167,15 @@ function TASK:GetGoals() end --- Returns if a TASK has Goal(s). --- @param ?string GoalVerb is the name of the Goal of the TASK. +-- @param #TASK self +-- @param #string GoalVerb is the name of the Goal of the TASK. -- @return bool function TASK:Goal( GoalVerb ) - self:F() + self:F2( { GoalVerb } ) if not GoalVerb then GoalVerb = self.GoalVerb end + self:T2( {self.GoalTasks[GoalVerb] } ) if self.GoalTasks[GoalVerb] and self.GoalTasks[GoalVerb].GoalTotal > 0 then return true else @@ -8679,7 +9187,7 @@ end -- @param number GoalTotal is the number of times the GoalVerb needs to be achieved. -- @param ?string GoalVerb is the name of the Goal of the TASK. If the GoalVerb is not given, then the default TASK Goals will be used. function TASK:SetGoalTotal( GoalTotal, GoalVerb ) - self:F( { GoalTotal, GoalVerb } ) + self:F2( { GoalTotal, GoalVerb } ) if not GoalVerb then GoalVerb = self.GoalVerb @@ -8694,7 +9202,7 @@ end --- Gets the total of Goals to be achieved within the TASK of the GoalVerb. -- @param ?string GoalVerb is the name of the Goal of the TASK. If the GoalVerb is not given, then the default TASK Goals will be used. function TASK:GetGoalTotal( GoalVerb ) - self:F() + self:F2( { GoalVerb } ) if not GoalVerb then GoalVerb = self.GoalVerb end @@ -8710,7 +9218,7 @@ end -- @param ?string GoalVerb is the name of the Goal of the TASK. If the GoalVerb is not given, then the default TASK Goals will be used. -- @return TASK function TASK:SetGoalCount( GoalCount, GoalVerb ) - self:F() + self:F2() if not GoalVerb then GoalVerb = self.GoalVerb end @@ -8725,7 +9233,7 @@ end -- @param ?string GoalVerb is the name of the Goal of the TASK. If the GoalVerb is not given, then the default TASK Goals will be used. -- @return TASK function TASK:IncreaseGoalCount( GoalCountIncrease, GoalVerb ) - self:F() + self:F2( { GoalCountIncrease, GoalVerb } ) if not GoalVerb then GoalVerb = self.GoalVerb end @@ -8739,7 +9247,7 @@ end -- @param ?string GoalVerb is the name of the Goal of the TASK. If the GoalVerb is not given, then the default TASK Goals will be used. -- @return TASK function TASK:GetGoalCount( GoalVerb ) - self:F() + self:F2() if not GoalVerb then GoalVerb = self.GoalVerb end @@ -8754,7 +9262,7 @@ end -- @param ?string GoalVerb is the name of the Goal of the TASK. If the GoalVerb is not given, then the default TASK Goals will be used. -- @return TASK function TASK:GetGoalPercentage( GoalVerb ) - self:F() + self:F2() if not GoalVerb then GoalVerb = self.GoalVerb end @@ -8767,15 +9275,16 @@ end --- Returns if all the Goals of the TASK were achieved. -- @return bool -function TASK:IsGoalReached( ) +function TASK:IsGoalReached() + self:F2() local GoalReached = true for GoalVerb, Goals in pairs( self.GoalTasks ) do - self:T( { "GoalVerb", GoalVerb } ) + self:T2( { "GoalVerb", GoalVerb } ) if self:Goal( GoalVerb ) then local GoalToDo = self:GetGoalTotal( GoalVerb ) - self:GetGoalCount( GoalVerb ) - self:T( "GoalToDo = " .. GoalToDo ) + self:T2( "GoalToDo = " .. GoalToDo ) if GoalToDo <= 0 then else GoalReached = false @@ -8786,7 +9295,7 @@ function TASK:IsGoalReached( ) end end - self:T( GoalReached ) + self:T( { GoalReached, self.GoalTasks } ) return GoalReached end @@ -8795,7 +9304,7 @@ end -- @param string GoalTask is a text describing the Goal of the TASK to be achieved. -- @param number GoalIncrease is a number by which the Goal achievement is increasing. function TASK:AddGoalCompletion( GoalVerb, GoalTask, GoalIncrease ) - self:F( { GoalVerb, GoalTask, GoalIncrease } ) + self:F2( { GoalVerb, GoalTask, GoalIncrease } ) if self:Goal( GoalVerb ) then self.GoalTasks[GoalVerb].Goals[#self.GoalTasks[GoalVerb].Goals+1] = GoalTask @@ -8808,7 +9317,7 @@ end -- @param ?string GoalVerb is the name of the Goal of the TASK. If the GoalVerb is not given, then the default TASK Goals will be used. -- @return string Goals function TASK:GetGoalCompletion( GoalVerb ) - self:F( { GoalVerb } ) + self:F2( { GoalVerb } ) if self:Goal( GoalVerb ) then local Goals = "" @@ -9001,10 +9510,11 @@ DESTROYBASETASK = { } --- Creates a new DESTROYBASETASK. --- @param string DestroyGroupType Text describing the group to be destroyed. f.e. "Radar Installations", "Ships", "Vehicles", "Command Centers". --- @param string DestroyUnitType Text describing the unit types to be destroyed. f.e. "SA-6", "Row Boats", "Tanks", "Tents". --- @param table{string,...} DestroyGroupPrefixes Table of Prefixes of the Groups to be destroyed before task is completed. --- @param ?number DestroyPercentage defines the %-tage that needs to be destroyed to achieve mission success. eg. If in the Group there are 10 units, then a value of 75 would require 8 units to be destroyed from the Group to complete the @{TASK}. +-- @param #DESTROYBASETASK self +-- @param #string DestroyGroupType Text describing the group to be destroyed. f.e. "Radar Installations", "Ships", "Vehicles", "Command Centers". +-- @param #string DestroyUnitType Text describing the unit types to be destroyed. f.e. "SA-6", "Row Boats", "Tanks", "Tents". +-- @param #list<#string> DestroyGroupPrefixes Table of Prefixes of the Groups to be destroyed before task is completed. +-- @param #number DestroyPercentage defines the %-tage that needs to be destroyed to achieve mission success. eg. If in the Group there are 10 units, then a value of 75 would require 8 units to be destroyed from the Group to complete the @{TASK}. -- @return DESTROYBASETASK function DESTROYBASETASK:New( DestroyGroupType, DestroyUnitType, DestroyGroupPrefixes, DestroyPercentage ) local self = BASE:Inherit( self, TASK:New() ) @@ -9015,34 +9525,31 @@ function DESTROYBASETASK:New( DestroyGroupType, DestroyUnitType, DestroyGroupPre self.DestroyGroupPrefixes = DestroyGroupPrefixes self.DestroyGroupType = DestroyGroupType self.DestroyUnitType = DestroyUnitType + if DestroyPercentage then + self.DestroyPercentage = DestroyPercentage + end self.TaskBriefing = "Task: Destroy " .. DestroyGroupType .. "." self.Stages = { STAGEBRIEF:New(), STAGESTART:New(), STAGEGROUPSDESTROYED:New(), STAGEDONE:New() } self.SetStage( self, 1 ) - --self.AddEvent( self, world.event.S_EVENT_DEAD, self.EventDead ) - - --env.info( 'New Table self = ' .. tostring(self) ) - --env.info( 'New Table self = ' .. tostring(self) ) - return self end --- Handle the S_EVENT_DEAD events to validate the destruction of units for the task monitoring. --- @param event Event structure of DCS world. -function DESTROYBASETASK:EventDead( event ) - self:F( { 'EventDead', event } ) +-- @param #DESTROYBASETASK self +-- @param Event#EVENTDATA Event structure of MOOSE. +function DESTROYBASETASK:EventDead( Event ) + self:F( { Event } ) - if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then - local DestroyUnit = event.initiator - local DestroyUnitName = DestroyUnit:getName() - local DestroyGroup = Unit.getGroup( DestroyUnit ) - local DestroyGroupName = "" - if DestroyGroup and DestroyGroup:isExist() then - local DestroyGroupName = DestroyGroup:getName() - end + if Event.IniDCSUnit then + local DestroyUnit = Event.IniDCSUnit + local DestroyUnitName = Event.IniDCSUnitName + local DestroyGroup = Event.IniDCSGroup + local DestroyGroupName = Event.IniDCSGroupName + + --TODO: I need to fix here if 2 groups in the mission have a similar name with GroupPrefix equal, then i should differentiate for which group the goal was reached! + --I may need to test if for the goalverb that group goal was reached or something. Need to think about it a bit more ... local UnitsDestroyed = 0 - self:T( DestroyGroupName ) - self:T( DestroyUnitName ) for DestroyGroupPrefixID, DestroyGroupPrefix in pairs( self.DestroyGroupPrefixes ) do self:T( DestroyGroupPrefix ) if string.find( DestroyGroupName, DestroyGroupPrefix, 1, true ) then @@ -9055,6 +9562,7 @@ function DESTROYBASETASK:EventDead( event ) self:T( { UnitsDestroyed } ) self:IncreaseGoalCount( UnitsDestroyed, self.GoalVerb ) end + end --- Validate task completeness of DESTROYBASETASK. @@ -9078,10 +9586,11 @@ DESTROYGROUPSTASK = { } --- Creates a new DESTROYGROUPSTASK. --- @param string DestroyGroupType String describing the group to be destroyed. --- @param string DestroyUnitType String describing the unit to be destroyed. --- @param table{string,...} DestroyGroupNames Table of string containing the name of the groups to be destroyed before task is completed. --- @param ?number DestroyPercentage defines the %-tage that needs to be destroyed to achieve mission success. eg. If in the Group there are 10 units, then a value of 75 would require 8 units to be destroyed from the Group to complete the @{TASK}. +-- @param #DESTROYGROUPSTASK self +-- @param #string DestroyGroupType String describing the group to be destroyed. +-- @param #string DestroyUnitType String describing the unit to be destroyed. +-- @param #list<#string> DestroyGroupNames Table of string containing the name of the groups to be destroyed before task is completed. +-- @param #number DestroyPercentage defines the %-tage that needs to be destroyed to achieve mission success. eg. If in the Group there are 10 units, then a value of 75 would require 8 units to be destroyed from the Group to complete the @{TASK}. ---@return DESTROYGROUPSTASK function DESTROYGROUPSTASK:New( DestroyGroupType, DestroyUnitType, DestroyGroupNames, DestroyPercentage ) local self = BASE:Inherit( self, DESTROYBASETASK:New( DestroyGroupType, DestroyUnitType, DestroyGroupNames, DestroyPercentage ) ) @@ -9090,35 +9599,35 @@ function DESTROYGROUPSTASK:New( DestroyGroupType, DestroyUnitType, DestroyGroupN self.Name = 'Destroy Groups' self.GoalVerb = "Destroy " .. DestroyGroupType - self:AddEvent( world.event.S_EVENT_DEAD, self.EventDead ) - self:AddEvent( world.event.S_EVENT_CRASH, self.EventDead ) - --Child.AddEvent( Child, world.event.S_EVENT_PILOT_DEAD, Child.EventDead ) + _EventDispatcher:OnDead( self.EventDead , self ) + _EventDispatcher:OnCrash( self.EventDead , self ) return self end --- Report Goal Progress. --- @param Group DestroyGroup Group structure describing the group to be evaluated. --- @param Unit DestroyUnit Unit structure describing the Unit to be evaluated. +-- @param #DESTROYGROUPSTASK self +-- @param DCSGroup#Group DestroyGroup Group structure describing the group to be evaluated. +-- @param DCSUnit#Unit DestroyUnit Unit structure describing the Unit to be evaluated. +-- @return #number The DestroyCount reflecting the amount of units destroyed within the group. function DESTROYGROUPSTASK:ReportGoalProgress( DestroyGroup, DestroyUnit ) - self:F( { DestroyGroup, DestroyUnit } ) - self:T( DestroyGroup:getSize() ) + self:F( { DestroyGroup, DestroyUnit, self.DestroyPercentage } ) + + local DestroyGroupSize = DestroyGroup:getSize() - 1 -- When a DEAD event occurs, the getSize is still one larger than the destroyed unit. + local DestroyGroupInitialSize = DestroyGroup:getInitialSize() + self:T( { DestroyGroupSize, DestroyGroupInitialSize - ( DestroyGroupInitialSize * self.DestroyPercentage / 100 ) } ) local DestroyCount = 0 if DestroyGroup then - if ( ( DestroyGroup:getInitialSize() * self.DestroyPercentage ) / 100 ) - DestroyGroup:getSize() <= 0 then + if DestroyGroupSize <= DestroyGroupInitialSize - ( DestroyGroupInitialSize * self.DestroyPercentage / 100 ) then DestroyCount = 1 ---[[ else - if DestroyGroup:getSize() == 1 then - if DestroyUnit and DestroyUnit:getLife() <= 1.0 then - DestroyCount = 1 - end - end - ]] end + end else DestroyCount = 1 end + self:T( DestroyCount ) + return DestroyCount end --- Task class to destroy radar installations. @@ -9141,8 +9650,8 @@ function DESTROYRADARSTASK:New( DestroyGroupNames ) self:F() self.Name = 'Destroy Radars' - - self:AddEvent( world.event.S_EVENT_DEAD, self.EventDead ) + + _EventDispatcher:OnDead( self.EventDead , self ) return self end @@ -9193,7 +9702,7 @@ function DESTROYUNITTYPESTASK:New( DestroyGroupType, DestroyUnitType, DestroyGro self.Name = 'Destroy Unit Types' self.GoalVerb = "Destroy " .. DestroyGroupType - self:AddEvent( world.event.S_EVENT_DEAD, self.EventDead ) + _EventDispatcher:OnDead( self.EventDead , self ) return self end @@ -10271,6 +10780,7 @@ Include.File( "Task" ) --- The CLEANUP class. -- @type CLEANUP +-- @extends Base#BASE CLEANUP = { ClassName = "CLEANUP", ZoneNames = {}, @@ -10301,15 +10811,8 @@ function CLEANUP:New( ZoneNames, TimeInterval ) local self = BASE:Inherit( self, self.TimeInterval = TimeInterval end - self:AddEvent( world.event.S_EVENT_ENGINE_SHUTDOWN, self._EventAddForCleanUp ) - self:AddEvent( world.event.S_EVENT_ENGINE_STARTUP, self._EventAddForCleanUp ) - self:AddEvent( world.event.S_EVENT_HIT, self._EventAddForCleanUp ) -- , self._EventHitCleanUp ) - self:AddEvent( world.event.S_EVENT_CRASH, self._EventCrash ) -- , self._EventHitCleanUp ) - --self:AddEvent( world.event.S_EVENT_DEAD, self._EventCrash ) - self:AddEvent( world.event.S_EVENT_SHOT, self._EventShot ) + _EventDispatcher:OnBirth( self._OnEventBirth, self ) - self:EnableEvents() - self.CleanUpScheduler = routines.scheduleFunction( self._CleanUpScheduler, { self }, timer.getTime() + 1, TimeInterval ) return self @@ -10345,9 +10848,8 @@ function CLEANUP:_DestroyUnit( CleanUpUnit, CleanUpUnitName ) local CleanUpGroupUnits = CleanUpGroup:getUnits() if #CleanUpGroupUnits == 1 then local CleanUpGroupName = CleanUpGroup:getName() - local Event = {["initiator"]=CleanUpUnit,["id"]=8} - world.onEvent( Event ) - trigger.action.deactivateGroup( CleanUpGroup ) + --self:CreateEventCrash( timer.getTime(), CleanUpUnit ) + CleanUpGroup:destroy() self:T( { "Destroyed Group:", CleanUpGroupName } ) else CleanUpUnit:destroy() @@ -10372,13 +10874,43 @@ function CLEANUP:_DestroyMissile( MissileObject ) end end +function CLEANUP:_OnEventBirth( Event ) + self:F( { Event } ) + + self.CleanUpList[Event.IniDCSUnitName] = {} + self.CleanUpList[Event.IniDCSUnitName].CleanUpUnit = Event.IniDCSUnit + self.CleanUpList[Event.IniDCSUnitName].CleanUpGroup = Event.IniDCSGroup + self.CleanUpList[Event.IniDCSUnitName].CleanUpGroupName = Event.IniDCSGroupName + self.CleanUpList[Event.IniDCSUnitName].CleanUpUnitName = Event.IniDCSUnitName + + _EventDispatcher:OnEngineShutDownForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) + _EventDispatcher:OnEngineStartUpForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) + _EventDispatcher:OnHitForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) + _EventDispatcher:OnPilotDeadForUnit( Event.IniDCSUnitName, self._EventCrash, self ) + _EventDispatcher:OnDeadForUnit( Event.IniDCSUnitName, self._EventCrash, self ) + _EventDispatcher:OnCrashForUnit( Event.IniDCSUnitName, self._EventCrash, self ) + _EventDispatcher:OnShotForUnit( Event.IniDCSUnitName, self._EventShot, self ) + + --self:AddEvent( world.event.S_EVENT_ENGINE_SHUTDOWN, self._EventAddForCleanUp ) + --self:AddEvent( world.event.S_EVENT_ENGINE_STARTUP, self._EventAddForCleanUp ) +-- self:AddEvent( world.event.S_EVENT_HIT, self._EventAddForCleanUp ) -- , self._EventHitCleanUp ) +-- self:AddEvent( world.event.S_EVENT_CRASH, self._EventCrash ) -- , self._EventHitCleanUp ) +-- --self:AddEvent( world.event.S_EVENT_DEAD, self._EventCrash ) +-- self:AddEvent( world.event.S_EVENT_SHOT, self._EventShot ) +-- +-- self:EnableEvents() + + +end + --- Detects if a crash event occurs. -- Crashed units go into a CleanUpList for removal. -- @param #CLEANUP self -- @param DCSTypes#Event event -function CLEANUP:_EventCrash( event ) - self:F( { event } ) +function CLEANUP:_EventCrash( Event ) + self:F( { Event } ) + --TODO: This stuff is not working due to a DCS bug. Burning units cannot be destroyed. --MESSAGE:New( "Crash ", "Crash", 10, "Crash" ):ToAll() -- self:T("before getGroup") -- local _grp = Unit.getGroup(event.initiator)-- Identify the group that fired @@ -10387,44 +10919,28 @@ function CLEANUP:_EventCrash( event ) -- self:T("after deactivateGroup") -- event.initiator:destroy() - local CleanUpUnit = event.initiator -- the Unit - local CleanUpUnitName = CleanUpUnit:getName() -- return the name of the Unit - local CleanUpGroup = Unit.getGroup(CleanUpUnit)-- Identify the Group - local CleanUpGroupName = "" - if CleanUpGroup and CleanUpGroup:isExist() then - CleanUpGroupName = CleanUpGroup:getName() -- return the name of the Group - end - - self.CleanUpList[CleanUpUnitName] = {} - self.CleanUpList[CleanUpUnitName].CleanUpUnit = CleanUpUnit - self.CleanUpList[CleanUpUnitName].CleanUpGroup = CleanUpGroup - self.CleanUpList[CleanUpUnitName].CleanUpGroupName = CleanUpGroupName - self.CleanUpList[CleanUpUnitName].CleanUpUnitName = CleanUpUnitName + self.CleanUpList[Event.IniDCSUnitName] = {} + self.CleanUpList[Event.IniDCSUnitName].CleanUpUnit = Event.IniDCSUnit + self.CleanUpList[Event.IniDCSUnitName].CleanUpGroup = Event.IniDCSGroup + self.CleanUpList[Event.IniDCSUnitName].CleanUpGroupName = Event.IniDCSGroupName + self.CleanUpList[Event.IniDCSUnitName].CleanUpUnitName = Event.IniDCSUnitName + end --- Detects if a unit shoots a missile. -- If this occurs within one of the zones, then the weapon used must be destroyed. -- @param #CLEANUP self -- @param DCSTypes#Event event -function CLEANUP:_EventShot( event ) - self:F( { event } ) +function CLEANUP:_EventShot( Event ) + self:F( { Event } ) - local _grp = Unit.getGroup(event.initiator)-- Identify the group that fired - local _groupname = _grp:getName() -- return the name of the group - local _unittable = {event.initiator:getName()} -- return the name of the units in the group - local _SEADmissile = event.weapon -- Identify the weapon fired - --local _SEADmissileName = _SEADmissile:getTypeName() -- return weapon type - --trigger.action.outText( string.format("Alerte, depart missile " ..string.format(_SEADmissileName)), 20) --debug message - -- Start of the 2nd loop - --self:T( "Missile Launched = " .. _SEADmissileName ) - -- Test if the missile was fired within one of the CLEANUP.ZoneNames. local CurrentLandingZoneID = 0 - CurrentLandingZoneID = routines.IsUnitInZones( event.initiator, self.ZoneNames ) + CurrentLandingZoneID = routines.IsUnitInZones( Event.IniDCSUnit, self.ZoneNames ) if ( CurrentLandingZoneID ) then -- Okay, the missile was fired within the CLEANUP.ZoneNames, destroy the fired weapon. --_SEADmissile:destroy() - routines.scheduleFunction( CLEANUP._DestroyMissile, {self, _SEADmissile}, timer.getTime() + 0.1) + routines.scheduleFunction( CLEANUP._DestroyMissile, { self, Event.Weapon }, timer.getTime() + 0.1) end end @@ -10432,38 +10948,28 @@ end --- Detects if the Unit has an S_EVENT_HIT within the given ZoneNames. If this is the case, destroy the unit. -- @param #CLEANUP self -- @param DCSTypes#Event event -function CLEANUP:_EventHitCleanUp( event ) - self:F( { event } ) +function CLEANUP:_EventHitCleanUp( Event ) + self:F( { Event } ) - local CleanUpUnit = event.initiator -- the Unit - if CleanUpUnit and CleanUpUnit:isExist() and Object.getCategory(CleanUpUnit) == Object.Category.UNIT then - local CleanUpUnitName = event.initiator:getName() -- return the name of the Unit - - if routines.IsUnitInZones( CleanUpUnit, self.ZoneNames ) ~= nil then - self:T( "Life: " .. CleanUpUnitName .. ' = ' .. CleanUpUnit:getLife() .. "/" .. CleanUpUnit:getLife0() ) - if CleanUpUnit:getLife() < CleanUpUnit:getLife0() then - self:T( "CleanUp: Destroy: " .. CleanUpUnitName ) - routines.scheduleFunction( CLEANUP._DestroyUnit, {self, CleanUpUnit}, timer.getTime() + 0.1) + if Event.IniDCSUnit then + if routines.IsUnitInZones( Event.IniDCSUnit, self.ZoneNames ) ~= nil then + self:T( { "Life: ", Event.IniDCSUnitName, ' = ', Event.IniDCSUnit:getLife(), "/", Event.IniDCSUnit:getLife0() } ) + if Event.IniDCSUnit:getLife() < Event.IniDCSUnit:getLife0() then + self:T( "CleanUp: Destroy: " .. Event.IniDCSUnitName ) + routines.scheduleFunction( CLEANUP._DestroyUnit, { self, Event.IniDCSUnit }, timer.getTime() + 0.1) end end end - local CleanUpTgtUnit = event.target -- the target Unit - if CleanUpTgtUnit and CleanUpTgtUnit:isExist() and Object.getCategory(CleanUpTgtUnit) == Object.Category.UNIT then - local CleanUpTgtUnitName = event.target:getName() -- return the name of the target Unit - local CleanUpTgtGroup = Unit.getGroup(event.target)-- Identify the target Group - local CleanUpTgtGroupName = CleanUpTgtGroup:getName() -- return the name of the target Group - - - if routines.IsUnitInZones( CleanUpTgtUnit, self.ZoneNames ) ~= nil then - self:T( "Life: " .. CleanUpTgtUnitName .. ' = ' .. CleanUpTgtUnit:getLife() .. "/" .. CleanUpTgtUnit:getLife0() ) - if CleanUpTgtUnit:getLife() < CleanUpTgtUnit:getLife0() then - self:T( "CleanUp: Destroy: " .. CleanUpTgtUnitName ) - routines.scheduleFunction( CLEANUP._DestroyUnit, {self, CleanUpTgtUnit}, timer.getTime() + 0.1) + if Event.TgtDCSUnit then + if routines.IsUnitInZones( Event.TgtDCSUnit, self.ZoneNames ) ~= nil then + self:T( { "Life: ", Event.TgtDCSUnitName, ' = ', Event.TgtDCSUnit:getLife(), "/", Event.TgtDCSUnit:getLife0() } ) + if Event.TgtDCSUnit:getLife() < Event.TgtDCSUnit:getLife0() then + self:T( "CleanUp: Destroy: " .. Event.TgtDCSUnitName ) + routines.scheduleFunction( CLEANUP._DestroyUnit, { self, Event.TgtDCSUnit }, timer.getTime() + 0.1 ) end end end - end --- Add the @{DCSUnit#Unit} to the CleanUpList for CleanUp. @@ -10485,24 +10991,20 @@ end --- Detects if the Unit has an S_EVENT_ENGINE_SHUTDOWN or an S_EVENT_HIT within the given ZoneNames. If this is the case, add the Group to the CLEANUP List. -- @param #CLEANUP self -- @param DCSTypes#Event event -function CLEANUP:_EventAddForCleanUp( event ) +function CLEANUP:_EventAddForCleanUp( Event ) - local CleanUpUnit = event.initiator -- the Unit - if CleanUpUnit and Object.getCategory(CleanUpUnit) == Object.Category.UNIT then - local CleanUpUnitName = CleanUpUnit:getName() -- return the name of the Unit - if self.CleanUpList[CleanUpUnitName] == nil then - if routines.IsUnitInZones( CleanUpUnit, self.ZoneNames ) ~= nil then - self:_AddForCleanUp( CleanUpUnit, CleanUpUnitName ) + if Event.IniDCSUnit then + if self.CleanUpList[Event.IniDCSUnitName] == nil then + if routines.IsUnitInZones( Event.IniDCSUnit, self.ZoneNames ) ~= nil then + self:_AddForCleanUp( Event.IniDCSUnit, Event.IniDCSUnitName ) end end end - local CleanUpTgtUnit = event.target -- the target Unit - if CleanUpTgtUnit and Object.getCategory(CleanUpTgtUnit) == Object.Category.UNIT then - local CleanUpTgtUnitName = CleanUpTgtUnit:getName() -- return the name of the target Unit - if self.CleanUpList[CleanUpTgtUnitName] == nil then - if routines.IsUnitInZones( CleanUpTgtUnit, self.ZoneNames ) ~= nil then - self:_AddForCleanUp( CleanUpTgtUnit, CleanUpTgtUnitName ) + if Event.TgtDCSUnit then + if self.CleanUpList[Event.TgtDCSUnitName] == nil then + if routines.IsUnitInZones( Event.TgtDCSUnit, self.ZoneNames ) ~= nil then + self:_AddForCleanUp( Event.TgtDCSUnit, Event.TgtDCSUnitName ) end end end @@ -10520,9 +11022,11 @@ local CleanUpSurfaceTypeText = { --- At the defined time interval, CleanUp the Groups within the CleanUpList. -- @param #CLEANUP self function CLEANUP:_CleanUpScheduler() - self:F( "CleanUp Scheduler" ) + self:F( { "CleanUp Scheduler" } ) + local CleanUpCount = 0 for CleanUpUnitName, UnitData in pairs( self.CleanUpList ) do + CleanUpCount = CleanUpCount + 1 self:T( { CleanUpUnitName, UnitData } ) local CleanUpUnit = Unit.getByName(UnitData.CleanUpUnitName) @@ -10584,6 +11088,7 @@ function CLEANUP:_CleanUpScheduler() self.CleanUpList[CleanUpUnitName] = nil -- Not anymore in the DCSRTE end end + self:T(CleanUpCount) end --- Dynamic spawning of groups (and units). @@ -10663,6 +11168,7 @@ Include.File( "Base" ) Include.File( "Database" ) Include.File( "Group" ) Include.File( "Zone" ) +Include.File( "Event" ) --- SPAWN Class -- @type SPAWN @@ -10709,12 +11215,6 @@ function SPAWN:New( SpawnTemplatePrefix ) else error( "SPAWN:New: There is no group declared in the mission editor with SpawnTemplatePrefix = '" .. SpawnTemplatePrefix .. "'" ) end - - self:AddEvent( world.event.S_EVENT_BIRTH, self._OnBirth ) - self:AddEvent( world.event.S_EVENT_DEAD, self._OnDeadOrCrash ) - self:AddEvent( world.event.S_EVENT_CRASH, self._OnDeadOrCrash ) - - self:EnableEvents() return self end @@ -10753,12 +11253,6 @@ function SPAWN:NewWithAlias( SpawnTemplatePrefix, SpawnAliasPrefix ) error( "SPAWN:New: There is no group declared in the mission editor with SpawnTemplatePrefix = '" .. SpawnTemplatePrefix .. "'" ) end - self:AddEvent( world.event.S_EVENT_BIRTH, self._OnBirth ) - self:AddEvent( world.event.S_EVENT_DEAD, self._OnDeadOrCrash ) - self:AddEvent( world.event.S_EVENT_CRASH, self._OnDeadOrCrash ) - - self:EnableEvents() - return self end @@ -10870,17 +11364,12 @@ end -- -- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically. -- SpawnRU_SU34 = SPAWN:New( 'TF1 RU Su-34 Krymsk@AI - Attack Ships' ):Schedule( 2, 3, 1800, 0.4 ):SpawnUncontrolled():RandomizeRoute( 1, 1, 3000 ):RepeatOnEngineShutDown() function SPAWN:Repeat() - self:F( { self.SpawnTemplatePrefix } ) + self:F( { self.SpawnTemplatePrefix, self.SpawnIndex } ) self.SpawnRepeat = true self.RepeatOnEngineShutDown = false self.RepeatOnLanding = true - self:AddEvent( world.event.S_EVENT_LAND, self._OnLand ) - self:AddEvent( world.event.S_EVENT_TAKEOFF, self._OnTakeOff ) - self:AddEvent( world.event.S_EVENT_ENGINE_SHUTDOWN, self._OnEngineShutDown ) - self:EnableEvents() - return self end @@ -10973,6 +11462,21 @@ function SPAWN:Array( SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY ) self.SpawnGroups[SpawnGroupID].SpawnTemplate.visible = true self.SpawnGroups[SpawnGroupID].Visible = true + + _EventDispatcher:OnBirthForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnBirth, self ) + _EventDispatcher:OnCrashForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnDeadOrCrash, self ) + _EventDispatcher:OnDeadForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnDeadOrCrash, self ) + + if self.SpawnRepeat then + _EventDispatcher:OnTakeOffForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnTakeOff, self ) + end + if self.RepeatOnLanding then + _EventDispatcher:OnLandForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnLand, self ) + end + if self.RepeatOnEngineShutDown then + _EventDispatcher:OnEngineShutDownForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnEngineShutDown, self ) + end + self.SpawnGroups[SpawnGroupID].Group = _Database:Spawn( self.SpawnGroups[SpawnGroupID].SpawnTemplate ) SpawnX = SpawnXIndex * SpawnDeltaX @@ -11031,6 +11535,20 @@ function SPAWN:SpawnWithIndex( SpawnIndex ) self.SpawnGroups[self.SpawnIndex].Group:Activate() else self:T( self.SpawnGroups[self.SpawnIndex].SpawnTemplate ) + _EventDispatcher:OnBirthForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnBirth, self ) + _EventDispatcher:OnCrashForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnDeadOrCrash, self ) + _EventDispatcher:OnDeadForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnDeadOrCrash, self ) + + if self.SpawnRepeat then + _EventDispatcher:OnTakeOffForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnTakeOff, self ) + end + if self.RepeatOnLanding then + _EventDispatcher:OnLandForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnLand, self ) + end + if self.RepeatOnEngineShutDown then + _EventDispatcher:OnEngineShutDownForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnEngineShutDown, self ) + end + self.SpawnGroups[self.SpawnIndex].Group = _Database:Spawn( self.SpawnGroups[self.SpawnIndex].SpawnTemplate ) -- If there is a SpawnFunction hook defined, call it. @@ -11046,7 +11564,7 @@ function SPAWN:SpawnWithIndex( SpawnIndex ) self.SpawnGroups[self.SpawnIndex].Spawned = true return self.SpawnGroups[self.SpawnIndex].Group else - self:E( { self.SpawnTemplatePrefix, "No more Groups to Spawn:", SpawnIndex, self.SpawnMaxGroups } ) + --self:E( { self.SpawnTemplatePrefix, "No more Groups to Spawn:", SpawnIndex, self.SpawnMaxGroups } ) end return nil @@ -11885,11 +12403,11 @@ function MOVEMENT:New( MovePrefixes, MoveMaximum ) self.AliveUnits = 0 -- Contains the counter how many units are currently alive self.MoveUnits = {} -- Reflects if the Moving for this MovePrefixes is going to be scheduled or not. - self:AddEvent( world.event.S_EVENT_BIRTH, self.OnBirth ) - self:AddEvent( world.event.S_EVENT_DEAD, self.OnDeadOrCrash ) - self:AddEvent( world.event.S_EVENT_CRASH, self.OnDeadOrCrash ) + _EventDispatcher:OnBirth( self.OnBirth, self ) - self:EnableEvents() +-- self:AddEvent( world.event.S_EVENT_BIRTH, self.OnBirth ) +-- +-- self:EnableEvents() self:ScheduleStart() @@ -11911,43 +12429,39 @@ end --- Captures the birth events when new Units were spawned. -- @todo This method should become obsolete. The new @{DATABASE} class will handle the collection administration. -function MOVEMENT:OnBirth( event ) - self:F( { event } ) +function MOVEMENT:OnBirth( Event ) + self:F( { Event } ) if timer.getTime0() < timer.getAbsTime() then -- dont need to add units spawned in at the start of the mission if mist is loaded in init line - if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then - local MovementUnit = event.initiator - local MovementUnitName = MovementUnit:getName() - self:T( "Birth object : " .. MovementUnitName ) - local MovementGroup = MovementUnit:getGroup() - if MovementGroup and MovementGroup:isExist() then - local MovementGroupName = MovementGroup:getName() + if Event.IniDCSUnit then + self:T( "Birth object : " .. Event.IniDCSUnitName ) + if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then for MovePrefixID, MovePrefix in pairs( self.MovePrefixes ) do - if string.find( MovementUnitName, MovePrefix, 1, true ) then + if string.find( Event.IniDCSUnitName, MovePrefix, 1, true ) then self.AliveUnits = self.AliveUnits + 1 - self.MoveUnits[MovementUnitName] = MovementGroupName + self.MoveUnits[Event.IniDCSUnitName] = Event.IniDCSGroupName self:T( self.AliveUnits ) end end end end + _EventDispatcher:OnCrashForUnit( Event.IniDCSUnitName, self.OnDeadOrCrash, self ) + _EventDispatcher:OnDeadForUnit( Event.IniDCSUnitName, self.OnDeadOrCrash, self ) end end --- Captures the Dead or Crash events when Units crash or are destroyed. -- @todo This method should become obsolete. The new @{DATABASE} class will handle the collection administration. -function MOVEMENT:OnDeadOrCrash( event ) - self:F( { event } ) +function MOVEMENT:OnDeadOrCrash( Event ) + self:F( { Event } ) - if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then - local MovementUnit = event.initiator - local MovementUnitName = MovementUnit:getName() - self:T( "Dead object : " .. MovementUnitName ) + if Event.IniDCSUnit then + self:T( "Dead object : " .. Event.IniDCSUnitName ) for MovePrefixID, MovePrefix in pairs( self.MovePrefixes ) do - if string.find( MovementUnitName, MovePrefix, 1, true ) then + if string.find( Event.IniDCSUnitName, MovePrefix, 1, true ) then self.AliveUnits = self.AliveUnits - 1 - self.MoveUnits[MovementUnitName] = nil + self.MoveUnits[Event.IniDCSUnitName] = nil self:T( self.AliveUnits ) end end @@ -11986,6 +12500,7 @@ end -- @author (co) Flightcontrol (Modified and enriched with functionality) Include.File( "Routines" ) +Include.File( "Event" ) Include.File( "Base" ) Include.File( "Mission" ) Include.File( "Client" ) @@ -12024,27 +12539,26 @@ function SEAD:New( SEADGroupPrefixes ) else self.SEADGroupNames[SEADGroupPrefixes] = SEADGroupPrefixes end - self:AddEvent( world.event.S_EVENT_SHOT, self.EventShot ) - self:EnableEvents() + _EventDispatcher:OnShot( self.EventShot, self ) return self end --- Detects if an SA site was shot with an anti radiation missile. In this case, take evasive actions based on the skill level set within the ME. -- @see SEAD -function SEAD:EventShot( event ) - self:F( { event } ) +function SEAD:EventShot( Event ) + self:F( { Event } ) - local SEADUnit = event.initiator - local SEADUnitName = SEADUnit:getName() - local SEADWeapon = event.weapon -- Identify the weapon fired - local SEADWeaponName = SEADWeapon:getTypeName() -- return weapon type + local SEADUnit = Event.IniDCSUnit + local SEADUnitName = Event.IniDCSUnitName + local SEADWeapon = Event.Weapon -- Identify the weapon fired + local SEADWeaponName = Event.WeaponName -- return weapon type --trigger.action.outText( string.format("Alerte, depart missile " ..string.format(SEADWeaponName)), 20) --debug message -- Start of the 2nd loop self:T( "Missile Launched = " .. SEADWeaponName ) if SEADWeaponName == "KH-58" or SEADWeaponName == "KH-25MPU" or SEADWeaponName == "AGM-88" or SEADWeaponName == "KH-31A" or SEADWeaponName == "KH-31P" then -- Check if the missile is a SEAD local _evade = math.random (1,100) -- random number for chance of evading action - local _targetMim = Weapon.getTarget(SEADWeapon) -- Identify target + local _targetMim = Event.Weapon:getTarget() -- Identify target local _targetMimname = Unit.getName(_targetMim) local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon)) local _targetMimgroupName = _targetMimgroup:getName() @@ -12120,71 +12634,83 @@ end --- Taking the lead of AI escorting your flight. -- The ESCORT class allows you to interact with escorting AI on your flight and take the lead. -- Each escorting group can be commanded with a whole set of radio commands (radio menu in your flight, and then F10). --- +-- -- The radio commands will vary according the category of the group. The richest set of commands are with Helicopters and AirPlanes. -- Ships and Ground troops will have a more limited set, but they can provide support through the bombing of targets designated by the other escorts. --- +-- -- Find a summary below of the current available commands: --- +-- -- **1. Navigation ...:** Escort group navigation functions: --- --- * **"Hold Position and Stay Low":** Stops the escort group and they will hover 30 meters above the ground at the position they stopped. --- * **"Join-Up and Hold Position NearBy":** The escort group will stop nearby you, and then the group will hover. --- * **"Join-Up and Follow at 100":** The escort group fill follow you at about 100 meters, and they will follow you. --- * **"Join-Up and Follow at 200":** The escort group fill follow you at about 200 meters, and they will follow you. --- * **"Join-Up and Follow at 400":** The escort group fill follow you at about 400 meters, and they will follow you. --- * **"Join-Up and Follow at 800":** The escort group fill follow you at about 800 meters, and they will follow you. +-- +-- * **"Join-Up and Follow at x meters":** The escort group fill follow you at about x meters, and they will follow you. -- * **"Flare":** Provides menu commands to let the escort group shoot a flare in the air in a color. -- * **"Smoke":** Provides menu commands to let the escort group smoke the air in a color. Note that smoking is only available for ground and naval troops. --- --- **2. Report targets ...:** Report targets will make the escort group to report any target that it identifies within a 8km range. Any detected target can be attacked using the 4. Attack nearby targets function. (see below). --- +-- +-- **2. Hold position ...:** Escort group navigation functions: +-- +-- * **"At current location":** Stops the escort group and they will hover 30 meters above the ground at the position they stopped. +-- * **"At client location":** Stops the escort group and they will hover 30 meters above the ground at the position they stopped. +-- +-- **3. Report targets ...:** Report targets will make the escort group to report any target that it identifies within a 8km range. Any detected target can be attacked using the 4. Attack nearby targets function. (see below). +-- -- * **"Report now":** Will report the current detected targets. -- * **"Report targets on":** Will make the escort group to report detected targets and will fill the "Attack nearby targets" menu list. -- * **"Report targets off":** Will stop detecting targets. --- --- **3. Scan targets ...:** Menu items to pop-up the escort group for target scanning. After scanning, the escort group will resume with the mission or defined task. --- +-- +-- **4. Scan targets ...:** Menu items to pop-up the escort group for target scanning. After scanning, the escort group will resume with the mission or defined task. +-- -- * **"Scan targets 30 seconds":** Scan 30 seconds for targets. -- * **"Scan targets 60 seconds":** Scan 60 seconds for targets. --- --- **4. Attack targets ...:** This menu item will list all detected targets within a 15km range. Depending on the level of detection (known/unknown) and visuality, the targets type will also be listed. --- --- **5. Request assistance from ...:** This menu item will list all detected targets within a 15km range, as with the menu item **Attack Targets**. +-- +-- **5. Attack targets ...:** This menu item will list all detected targets within a 15km range. Depending on the level of detection (known/unknown) and visuality, the targets type will also be listed. +-- +-- **6. Request assistance from ...:** This menu item will list all detected targets within a 15km range, as with the menu item **Attack Targets**. -- This menu item allows to request attack support from other escorts supporting the current client group. -- eg. the function allows a player to request support from the Ship escort to attack a target identified by the Plane escort with its Tomahawk missiles. -- eg. the function allows a player to request support from other Planes escorting to bomb the unit with illumination missiles or bombs, so that the main plane escort can attack the area. --- --- **6. ROE ...:** Defines the Rules of Engagement of the escort group when in flight. --- +-- +-- **7. ROE ...:** Defines the Rules of Engagement of the escort group when in flight. +-- -- * **"Hold Fire":** The escort group will hold fire. -- * **"Return Fire":** The escort group will return fire. -- * **"Open Fire":** The escort group will open fire on designated targets. -- * **"Weapon Free":** The escort group will engage with any target. --- --- **7. Evasion ...:** Will define the evasion techniques that the escort group will perform during flight or combat. --- +-- +-- **8. Evasion ...:** Will define the evasion techniques that the escort group will perform during flight or combat. +-- -- * **"Fight until death":** The escort group will have no reaction to threats. -- * **"Use flares, chaff and jammers":** The escort group will use passive defense using flares and jammers. No evasive manoeuvres are executed. -- * **"Evade enemy fire":** The rescort group will evade enemy fire before firing. -- * **"Go below radar and evade fire":** The escort group will perform evasive vertical manoeuvres. --- --- **8. Resume Mission ...:** Escort groups can have their own mission. This menu item will allow the escort group to resume their Mission from a given waypoint. +-- +-- **9. Resume Mission ...:** Escort groups can have their own mission. This menu item will allow the escort group to resume their Mission from a given waypoint. -- Note that this is really fantastic, as you now have the dynamic of taking control of the escort groups, and allowing them to resume their path or mission. --- --- **9. Abort Current Task:** Cancel the current task and rejoin formation. --- +-- +-- **10. Abort Current Task:** Cancel the current task and rejoin formation. +-- -- 1. ESCORT object construction methods. -- -------------------------------------- -- Create a new SPAWN object with the @{#ESCORT.New} method: --- +-- -- * @{#ESCORT.New}: Creates a new ESCORT object from a @{Group#GROUP} for a @{Client#CLIENT}, with an optional briefing text. --- +-- -- 2. ESCORT object initialization methods. -- ---------------------------------------- --- None. --- --- +-- The following menus can be setup: +-- +-- * @{#ESCORT.MenuFollowAt}: Creates a menu to make the escort follow the client. +-- * @{#ESCORT.MenuHoldAtEscortPosition}: Creates a menu to hold the escort at its current position. +-- * @{#ESCORT.MenuHoldAtLeaderPosition}: Creates a menu to hold the escort at the client position. +-- * @{#ESCORT.MenuScanForTargets}: Creates a menu so that the escort scans targets. +-- * @{#ESCORT.MenuFlare}: Creates a menu to disperse flares. +-- * @{#ESCORT.MenuSmoke}: Creates a menu to disparse smoke. +-- * @{#ESCORT.MenuReportTargets}: Creates a menu so that the escort reports targets. +-- * @{#ESCORT.MenuReportPosition}: Creates a menu so that the escort reports its current position from bullseye. +-- * @{#ESCORT.MenuAssistedAttack: Creates a menu so that the escort supportes assisted attack from other escorts with the client. +-- * @{#ESCORT.MenuROE: Creates a menu structure to set the rules of engagement of the escort. +-- * @{#ESCORT.MenuEvasion: Creates a menu structure to set the evasion techniques when the escort is under threat. +-- * @{#ESCORT.MenuResumeMission}: Creates a menu structure so that the escort can resume from a waypoint. +-- -- @module Escort -- @author FlightControl @@ -12201,6 +12727,7 @@ Include.File( "Zone" ) -- @field Client#CLIENT EscortClient -- @field Group#GROUP EscortGroup -- @field #string EscortName +-- @field #ESCORT.MODE EscortMode The mode the escort is in. -- @field #number FollowScheduler The id of the _FollowScheduler function. -- @field #boolean ReportTargets If true, nearby targets are reported. -- @Field DCSTypes#AI.Option.Air.val.ROE OptionROE Which ROE is set to the EscortGroup. @@ -12211,6 +12738,11 @@ ESCORT = { EscortName = nil, -- The Escort Name EscortClient = nil, EscortGroup = nil, + EscortMode = nil, + MODE = { + FOLLOW = 1, + MISSION = 2, + }, Targets = {}, -- The identified targets FollowScheduler = nil, ReportTargets = true, @@ -12219,6 +12751,11 @@ ESCORT = { TaskPoints = {} } +--- ESCORT.Mode class +-- @type ESCORT.MODE +-- @field #number FOLLOW +-- @field #number MISSION + --- MENUPARAM type -- @type MENUPARAM -- @field #ESCORT ParamSelf @@ -12234,127 +12771,465 @@ ESCORT = { -- @return #ESCORT self function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing ) local self = BASE:Inherit( self, BASE:New() ) - self:F( { EscortClient, EscortGroup, EscortName } ) - + self:F( { EscortClient, EscortGroup, EscortName } ) + self.EscortClient = EscortClient -- Client#CLIENT self.EscortGroup = EscortGroup -- Group#GROUP self.EscortName = EscortName self.EscortBriefing = EscortBriefing - + self:T( EscortGroup:GetClassNameAndID() ) - + -- Set EscortGroup known at EscortClient. if not self.EscortClient._EscortGroups then - self.EscortClient._EscortGroups = {} + self.EscortClient._EscortGroups = {} end if not self.EscortClient._EscortGroups[EscortGroup:GetName()] then - self.EscortClient._EscortGroups[EscortGroup:GetName()] = {} - self.EscortClient._EscortGroups[EscortGroup:GetName()].EscortGroup = self.EscortGroup - self.EscortClient._EscortGroups[EscortGroup:GetName()].EscortName = self.EscortName - self.EscortClient._EscortGroups[EscortGroup:GetName()].Targets = {} - + self.EscortClient._EscortGroups[EscortGroup:GetName()] = {} + self.EscortClient._EscortGroups[EscortGroup:GetName()].EscortGroup = self.EscortGroup + self.EscortClient._EscortGroups[EscortGroup:GetName()].EscortName = self.EscortName + self.EscortClient._EscortGroups[EscortGroup:GetName()].Targets = {} + self.EscortMode = ESCORT.MODE.FOLLOW end - - + + self.EscortMenu = MENU_CLIENT:New( self.EscortClient, self.EscortName ) - - self.EscortMenuReportNavigation = MENU_CLIENT:New( self.EscortClient, "Navigation", self.EscortMenu ) - if EscortGroup:IsHelicopter() or EscortGroup:IsAirPlane() then - -- Escort Navigation - self.EscortMenuHoldPosition = MENU_CLIENT_COMMAND:New( self.EscortClient, "Hold Position and Stay Low", self.EscortMenuReportNavigation, ESCORT._HoldPosition, { ParamSelf = self } ) - self.EscortMenuJoinUpAndHoldPosition = MENU_CLIENT_COMMAND:New( self.EscortClient, "Join-Up and Hold Position NearBy", self.EscortMenuReportNavigation, ESCORT._HoldPositionNearBy, { ParamSelf = self } ) - self.EscortMenuJoinUpAndFollow50Meters = MENU_CLIENT_COMMAND:New( self.EscortClient, "Join-Up and Follow at 100", self.EscortMenuReportNavigation, ESCORT._JoinUpAndFollow, { ParamSelf = self, ParamDistance = 100 } ) - self.EscortMenuJoinUpAndFollow100Meters = MENU_CLIENT_COMMAND:New( self.EscortClient, "Join-Up and Follow at 200", self.EscortMenuReportNavigation, ESCORT._JoinUpAndFollow, { ParamSelf = self, ParamDistance = 200 } ) - self.EscortMenuJoinUpAndFollow150Meters = MENU_CLIENT_COMMAND:New( self.EscortClient, "Join-Up and Follow at 400", self.EscortMenuReportNavigation, ESCORT._JoinUpAndFollow, { ParamSelf = self, ParamDistance = 400 } ) - self.EscortMenuJoinUpAndFollow200Meters = MENU_CLIENT_COMMAND:New( self.EscortClient, "Join-Up and Follow at 800", self.EscortMenuReportNavigation, ESCORT._JoinUpAndFollow, { ParamSelf = self, ParamDistance = 800 } ) - end - self.EscortMenuFlare = MENU_CLIENT:New( self.EscortClient, "Flare", self.EscortMenuReportNavigation, ESCORT._Flare, { ParamSelf = self } ) - self.EscortMenuFlareGreen = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release green flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.Green, ParamMessage = "Released a green flare!" } ) - self.EscortMenuFlareRed = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release red flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.Red, ParamMessage = "Released a red flare!" } ) - self.EscortMenuFlareWhite = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release white flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.White, ParamMessage = "Released a white flare!" } ) - self.EscortMenuFlareYellow = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release yellow flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.Yellow, ParamMessage = "Released a yellow flare!" } ) - if EscortGroup:IsGround() or EscortGroup:IsShip() then - self.EscortMenuSmoke = MENU_CLIENT:New( self.EscortClient, "Smoke", self.EscortMenuReportNavigation, ESCORT._Smoke, { ParamSelf = self } ) - self.EscortMenuSmokeGreen = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release green smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.Green, ParamMessage = "Releasing green smoke!" } ) - self.EscortMenuSmokeRed = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release red smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.Red, ParamMessage = "Releasing red smoke!" } ) - self.EscortMenuSmokeWhite = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release white smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.White, ParamMessage = "Releasing white smoke!" } ) - self.EscortMenuSmokeOrange = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release orange smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.Orange, ParamMessage = "Releasing orange smoke!" } ) - self.EscortMenuSmokeBlue = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release blue smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.Blue, ParamMessage = "Releasing blue smoke!" } ) + self.EscortGroup:WayPointInitialize(1) + + self.EscortGroup:OptionROTVertical() + self.EscortGroup:OptionROEOpenFire() + + EscortGroup:MessageToClient( EscortGroup:GetCategoryName() .. " '" .. EscortName .. "' (" .. EscortGroup:GetCallsign() .. ") reporting! " .. + "We're escorting your flight. " .. + "Use the Radio Menu and F10 and use the options under + " .. EscortName .. "\n", + 60, EscortClient + ) + + return self +end + + +--- Defines the default menus +-- @param #ESCORT self +-- @return #ESCORT +function ESCORT:Menus() + self:F() + + self:MenuFollowAt( 100 ) + self:MenuFollowAt( 200 ) + self:MenuFollowAt( 300 ) + self:MenuFollowAt( 400 ) + + self:MenuScanForTargets( 100, 60 ) + + self:MenuHoldAtEscortPosition( 30 ) + self:MenuHoldAtLeaderPosition( 30 ) + + self:MenuFlare() + self:MenuSmoke() + + self:MenuReportTargets( 60 ) + self:MenuAssistedAttack() + self:MenuROE() + self:MenuEvasion() + self:MenuResumeMission() + + return self +end + + + +--- Defines a menu slot to let the escort Join and Follow you at a certain distance. +-- This menu will appear under **Navigation**. +-- @param #ESCORT self +-- @param DCSTypes#Distance Distance The distance in meters that the escort needs to follow the client. +-- @return #ESCORT +function ESCORT:MenuFollowAt( Distance ) + self:F(Distance) + + if self.EscortGroup:IsAir() then + if not self.EscortMenuReportNavigation then + self.EscortMenuReportNavigation = MENU_CLIENT:New( self.EscortClient, "Navigation", self.EscortMenu ) + end + + if not self.EscortMenuJoinUpAndFollow then + self.EscortMenuJoinUpAndFollow = {} + end + + self.EscortMenuJoinUpAndFollow[#self.EscortMenuJoinUpAndFollow+1] = MENU_CLIENT_COMMAND:New( self.EscortClient, "Join-Up and Follow at " .. Distance, self.EscortMenuReportNavigation, ESCORT._JoinUpAndFollow, { ParamSelf = self, ParamDistance = Distance } ) + + self.EscortMode = ESCORT.MODE.FOLLOW end - - if EscortGroup:IsHelicopter() or EscortGroup:IsAirPlane() or EscortGroup:IsGround() or EscortGroup:IsShip() then - -- Report Targets + + return self +end + +--- Defines a menu slot to let the escort hold at their current position and stay low with a specified height during a specified time in seconds. +-- This menu will appear under **Hold position**. +-- @param #ESCORT self +-- @param DCSTypes#Distance Height Optional parameter that sets the height in meters to let the escort orbit at the current location. The default value is 30 meters. +-- @param DCSTypes#Time Seconds Optional parameter that lets the escort orbit at the current position for a specified time. (not implemented yet). The default value is 0 seconds, meaning, that the escort will orbit forever until a sequent command is given. +-- @param #string MenuTextFormat Optional parameter that shows the menu option text. The text string is formatted, and should contain two %d tokens in the string. The first for the Height, the second for the Time (if given). If no text is given, the default text will be displayed. +-- @return #ESCORT +-- TODO: Implement Seconds parameter. Challenge is to first develop the "continue from last activity" function. +function ESCORT:MenuHoldAtEscortPosition( Height, Seconds, MenuTextFormat ) + self:F( { Height, Seconds, MenuTextFormat } ) + + if self.EscortGroup:IsAir() then + + if not self.EscortMenuHold then + self.EscortMenuHold = MENU_CLIENT:New( self.EscortClient, "Hold position", self.EscortMenu ) + end + + if not Height then + Height = 30 + end + + if not Seconds then + Seconds = 0 + end + + local MenuText = "" + if not MenuTextFormat then + if Seconds == 0 then + MenuText = string.format( "Hold at %d meter", Height ) + else + MenuText = string.format( "Hold at %d meter for %d seconds", Height, Seconds ) + end + else + if Seconds == 0 then + MenuText = string.format( MenuTextFormat, Height ) + else + MenuText = string.format( MenuTextFormat, Height, Seconds ) + end + end + + if not self.EscortMenuHoldPosition then + self.EscortMenuHoldPosition = {} + end + + self.EscortMenuHoldPosition[#self.EscortMenuHoldPosition+1] = MENU_CLIENT_COMMAND + :New( + self.EscortClient, + MenuText, + self.EscortMenuHold, + ESCORT._HoldPosition, + { ParamSelf = self, + ParamOrbitGroup = self.EscortGroup, + ParamHeight = Height, + ParamSeconds = Seconds + } + ) + end + + return self +end + + +--- Defines a menu slot to let the escort hold at the client position and stay low with a specified height during a specified time in seconds. +-- This menu will appear under **Navigation**. +-- @param #ESCORT self +-- @param DCSTypes#Distance Height Optional parameter that sets the height in meters to let the escort orbit at the current location. The default value is 30 meters. +-- @param DCSTypes#Time Seconds Optional parameter that lets the escort orbit at the current position for a specified time. (not implemented yet). The default value is 0 seconds, meaning, that the escort will orbit forever until a sequent command is given. +-- @param #string MenuTextFormat Optional parameter that shows the menu option text. The text string is formatted, and should contain one or two %d tokens in the string. The first for the Height, the second for the Time (if given). If no text is given, the default text will be displayed. +-- @return #ESCORT +-- TODO: Implement Seconds parameter. Challenge is to first develop the "continue from last activity" function. +function ESCORT:MenuHoldAtLeaderPosition( Height, Seconds, MenuTextFormat ) + self:F( { Height, Seconds, MenuTextFormat } ) + + if self.EscortGroup:IsAir() then + + if not self.EscortMenuHold then + self.EscortMenuHold = MENU_CLIENT:New( self.EscortClient, "Hold position", self.EscortMenu ) + end + + if not Height then + Height = 30 + end + + if not Seconds then + Seconds = 0 + end + + local MenuText = "" + if not MenuTextFormat then + if Seconds == 0 then + MenuText = string.format( "Rejoin and hold at %d meter", Height ) + else + MenuText = string.format( "Rejoin and hold at %d meter for %d seconds", Height, Seconds ) + end + else + if Seconds == 0 then + MenuText = string.format( MenuTextFormat, Height ) + else + MenuText = string.format( MenuTextFormat, Height, Seconds ) + end + end + + if not self.EscortMenuHoldAtLeaderPosition then + self.EscortMenuHoldAtLeaderPosition = {} + end + + self.EscortMenuHoldAtLeaderPosition[#self.EscortMenuHoldAtLeaderPosition+1] = MENU_CLIENT_COMMAND + :New( + self.EscortClient, + MenuText, + self.EscortMenuHold, + ESCORT._HoldPosition, + { ParamSelf = self, + ParamOrbitGroup = self.EscortClient, + ParamHeight = Height, + ParamSeconds = Seconds + } + ) + end + + return self +end + +--- Defines a menu slot to let the escort scan for targets at a certain height for a certain time in seconds. +-- This menu will appear under **Scan targets**. +-- @param #ESCORT self +-- @param DCSTypes#Distance Height Optional parameter that sets the height in meters to let the escort orbit at the current location. The default value is 30 meters. +-- @param DCSTypes#Time Seconds Optional parameter that lets the escort orbit at the current position for a specified time. (not implemented yet). The default value is 0 seconds, meaning, that the escort will orbit forever until a sequent command is given. +-- @param #string MenuTextFormat Optional parameter that shows the menu option text. The text string is formatted, and should contain one or two %d tokens in the string. The first for the Height, the second for the Time (if given). If no text is given, the default text will be displayed. +-- @return #ESCORT +function ESCORT:MenuScanForTargets( Height, Seconds, MenuTextFormat ) + self:F( { Height, Seconds, MenuTextFormat } ) + + if self.EscortGroup:IsAir() then + if not self.EscortMenuScan then + self.EscortMenuScan = MENU_CLIENT:New( self.EscortClient, "Scan for targets", self.EscortMenu ) + end + + if not Height then + Height = 100 + end + + if not Seconds then + Seconds = 30 + end + + local MenuText = "" + if not MenuTextFormat then + if Seconds == 0 then + MenuText = string.format( "At %d meter", Height ) + else + MenuText = string.format( "At %d meter for %d seconds", Height, Seconds ) + end + else + if Seconds == 0 then + MenuText = string.format( MenuTextFormat, Height ) + else + MenuText = string.format( MenuTextFormat, Height, Seconds ) + end + end + + if not self.EscortMenuScanForTargets then + self.EscortMenuScanForTargets = {} + end + + self.EscortMenuScanForTargets[#self.EscortMenuScanForTargets+1] = MENU_CLIENT_COMMAND + :New( + self.EscortClient, + MenuText, + self.EscortMenuScan, + ESCORT._ScanTargets, + { ParamSelf = self, + ParamScanDuration = 30 + } + ) + end + + return self +end + + + +--- Defines a menu slot to let the escort disperse a flare in a certain color. +-- This menu will appear under **Navigation**. +-- The flare will be fired from the first unit in the group. +-- @param #ESCORT self +-- @param #string MenuTextFormat Optional parameter that shows the menu option text. If no text is given, the default text will be displayed. +-- @return #ESCORT +function ESCORT:MenuFlare( MenuTextFormat ) + self:F() + + if not self.EscortMenuReportNavigation then + self.EscortMenuReportNavigation = MENU_CLIENT:New( self.EscortClient, "Navigation", self.EscortMenu ) + end + + local MenuText = "" + if not MenuTextFormat then + MenuText = "Flare" + else + MenuText = MenuTextFormat + end + + if not self.EscortMenuFlare then + self.EscortMenuFlare = MENU_CLIENT:New( self.EscortClient, MenuText, self.EscortMenuReportNavigation, ESCORT._Flare, { ParamSelf = self } ) + self.EscortMenuFlareGreen = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release green flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.Green, ParamMessage = "Released a green flare!" } ) + self.EscortMenuFlareRed = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release red flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.Red, ParamMessage = "Released a red flare!" } ) + self.EscortMenuFlareWhite = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release white flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.White, ParamMessage = "Released a white flare!" } ) + self.EscortMenuFlareYellow = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release yellow flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.Yellow, ParamMessage = "Released a yellow flare!" } ) + end + + return self +end + +--- Defines a menu slot to let the escort disperse a smoke in a certain color. +-- This menu will appear under **Navigation**. +-- Note that smoke menu options will only be displayed for ships and ground units. Not for air units. +-- The smoke will be fired from the first unit in the group. +-- @param #ESCORT self +-- @param #string MenuTextFormat Optional parameter that shows the menu option text. If no text is given, the default text will be displayed. +-- @return #ESCORT +function ESCORT:MenuSmoke( MenuTextFormat ) + self:F() + + if not self.EscortGroup:IsAir() then + if not self.EscortMenuReportNavigation then + self.EscortMenuReportNavigation = MENU_CLIENT:New( self.EscortClient, "Navigation", self.EscortMenu ) + end + + local MenuText = "" + if not MenuTextFormat then + MenuText = "Smoke" + else + MenuText = MenuTextFormat + end + + if not self.EscortMenuSmoke then + self.EscortMenuSmoke = MENU_CLIENT:New( self.EscortClient, "Smoke", self.EscortMenuReportNavigation, ESCORT._Smoke, { ParamSelf = self } ) + self.EscortMenuSmokeGreen = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release green smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.Green, ParamMessage = "Releasing green smoke!" } ) + self.EscortMenuSmokeRed = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release red smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.Red, ParamMessage = "Releasing red smoke!" } ) + self.EscortMenuSmokeWhite = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release white smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.White, ParamMessage = "Releasing white smoke!" } ) + self.EscortMenuSmokeOrange = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release orange smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.Orange, ParamMessage = "Releasing orange smoke!" } ) + self.EscortMenuSmokeBlue = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release blue smoke", self.EscortMenuSmoke, ESCORT._Smoke, { ParamSelf = self, ParamColor = UNIT.SmokeColor.Blue, ParamMessage = "Releasing blue smoke!" } ) + end + end + + return self +end + +--- Defines a menu slot to let the escort report their current detected targets with a specified time interval in seconds. +-- This menu will appear under **Report targets**. +-- Note that if a report targets menu is not specified, no targets will be detected by the escort, and the attack and assisted attack menus will not be displayed. +-- @param #ESCORT self +-- @param DCSTypes#Time Seconds Optional parameter that lets the escort report their current detected targets after specified time interval in seconds. The default time is 30 seconds. +-- @return #ESCORT +function ESCORT:MenuReportTargets( Seconds ) + self:F( { Seconds } ) + + if not self.EscortMenuReportNearbyTargets then self.EscortMenuReportNearbyTargets = MENU_CLIENT:New( self.EscortClient, "Report targets", self.EscortMenu ) - self.EscortMenuReportNearbyTargetsNow = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets now!", self.EscortMenuReportNearbyTargets, ESCORT._ReportNearbyTargetsNow, { ParamSelf = self } ) - self.EscortMenuReportNearbyTargetsOn = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets on", self.EscortMenuReportNearbyTargets, ESCORT._SwitchReportNearbyTargets, { ParamSelf = self, ParamReportTargets = true } ) - self.EscortMenuReportNearbyTargetsOff = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets off", self.EscortMenuReportNearbyTargets, ESCORT._SwitchReportNearbyTargets, { ParamSelf = self, ParamReportTargets = false, } ) end - if EscortGroup:IsHelicopter() then - -- Scanning Targets - self.EscortMenuScanForTargets = MENU_CLIENT:New( self.EscortClient, "Scan targets", self.EscortMenu ) - self.EscortMenuReportNearbyTargetsOn = MENU_CLIENT_COMMAND:New( self.EscortClient, "Scan targets 30 seconds", self.EscortMenuScanForTargets, ESCORT._ScanTargets, { ParamSelf = self, ParamScanDuration = 30 } ) - self.EscortMenuReportNearbyTargetsOn = MENU_CLIENT_COMMAND:New( self.EscortClient, "Scan targets 60 seconds", self.EscortMenuScanForTargets, ESCORT._ScanTargets, { ParamSelf = self, ParamScanDuration = 60 } ) + if not Seconds then + Seconds = 30 end - + + -- Report Targets + self.EscortMenuReportNearbyTargetsNow = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets now!", self.EscortMenuReportNearbyTargets, ESCORT._ReportNearbyTargetsNow, { ParamSelf = self } ) + self.EscortMenuReportNearbyTargetsOn = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets on", self.EscortMenuReportNearbyTargets, ESCORT._SwitchReportNearbyTargets, { ParamSelf = self, ParamReportTargets = true } ) + self.EscortMenuReportNearbyTargetsOff = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets off", self.EscortMenuReportNearbyTargets, ESCORT._SwitchReportNearbyTargets, { ParamSelf = self, ParamReportTargets = false, } ) + -- Attack Targets self.EscortMenuAttackNearbyTargets = MENU_CLIENT:New( self.EscortClient, "Attack targets", self.EscortMenu ) - -- Request assistance from other escorts. + + self.ReportTargetsScheduler = routines.scheduleFunction( self._ReportTargetsScheduler, { self }, timer.getTime() + 1, Seconds ) + + return self +end + +--- Defines a menu slot to let the escort attack its detected targets using assisted attack from another escort joined also with the client. +-- This menu will appear under **Request assistance from**. +-- Note that this method needs to be preceded with the method MenuReportTargets. +-- @param #ESCORT self +-- @return #ESCORT +function ESCORT:MenuAssistedAttack() + self:F() + + -- Request assistance from other escorts. -- This is very useful to let f.e. an escorting ship attack a target detected by an escorting plane... self.EscortMenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, "Request assistance from", self.EscortMenu ) - - -- Rules of Engagement - self.EscortMenuROE = MENU_CLIENT:New( self.EscortClient, "ROE", self.EscortMenu ) - if EscortGroup:OptionROEHoldFirePossible() then - self.EscortMenuROEHoldFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Hold Fire", self.EscortMenuROE, ESCORT._ROE, { ParamSelf = self, ParamFunction = EscortGroup:OptionROEHoldFire(), ParamMessage = "Holding weapons!" } ) - end - if EscortGroup:OptionROEReturnFirePossible() then - self.EscortMenuROEReturnFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Return Fire", self.EscortMenuROE, ESCORT._ROE, { ParamSelf = self, ParamFunction = EscortGroup:OptionROEReturnFire(), ParamMessage = "Returning fire!" } ) - end - if EscortGroup:OptionROEOpenFirePossible() then - self.EscortMenuROEOpenFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Open Fire", self.EscortMenuROE, ESCORT._ROE, { ParamSelf = self, ParamFunction = EscortGroup:OptionROEOpenFire(), ParamMessage = "Opening fire on designated targets!!" } ) - end - if EscortGroup:OptionROEWeaponFreePossible() then - self.EscortMenuROEWeaponFree = MENU_CLIENT_COMMAND:New( self.EscortClient, "Weapon Free", self.EscortMenuROE, ESCORT._ROE, { ParamSelf = self, ParamFunction = EscortGroup:OptionROEWeaponFree(), ParamMessage = "Opening fire on targets of opportunity!" } ) + return self +end + +--- Defines a menu to let the escort set its rules of engagement. +-- All rules of engagement will appear under the menu **ROE**. +-- @param #ESCORT self +-- @return #ESCORT +function ESCORT:MenuROE( MenuTextFormat ) + self:F( MenuTextFormat ) + + if not self.EscortMenuROE then + -- Rules of Engagement + self.EscortMenuROE = MENU_CLIENT:New( self.EscortClient, "ROE", self.EscortMenu ) + if self.EscortGroup:OptionROEHoldFirePossible() then + self.EscortMenuROEHoldFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Hold Fire", self.EscortMenuROE, ESCORT._ROE, { ParamSelf = self, ParamFunction = self.EscortGroup:OptionROEHoldFire(), ParamMessage = "Holding weapons!" } ) + end + if self.EscortGroup:OptionROEReturnFirePossible() then + self.EscortMenuROEReturnFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Return Fire", self.EscortMenuROE, ESCORT._ROE, { ParamSelf = self, ParamFunction = self.EscortGroup:OptionROEReturnFire(), ParamMessage = "Returning fire!" } ) + end + if self.EscortGroup:OptionROEOpenFirePossible() then + self.EscortMenuROEOpenFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Open Fire", self.EscortMenuROE, ESCORT._ROE, { ParamSelf = self, ParamFunction = self.EscortGroup:OptionROEOpenFire(), ParamMessage = "Opening fire on designated targets!!" } ) + end + if self.EscortGroup:OptionROEWeaponFreePossible() then + self.EscortMenuROEWeaponFree = MENU_CLIENT_COMMAND:New( self.EscortClient, "Weapon Free", self.EscortMenuROE, ESCORT._ROE, { ParamSelf = self, ParamFunction = self.EscortGroup:OptionROEWeaponFree(), ParamMessage = "Opening fire on targets of opportunity!" } ) + end end - -- Reaction to Threats - self.EscortMenuEvasion = MENU_CLIENT:New( self.EscortClient, "Evasion", self.EscortMenu ) - if EscortGroup:OptionROTNoReactionPossible() then - self.EscortMenuEvasionNoReaction = MENU_CLIENT_COMMAND:New( self.EscortClient, "Fight until death", self.EscortMenuEvasion, ESCORT._ROT, { ParamSelf = self, ParamFunction = EscortGroup:OptionROTNoReaction(), ParamMessage = "Fighting until death!" } ) - end - if EscortGroup:OptionROTPassiveDefensePossible() then - self.EscortMenuEvasionPassiveDefense = MENU_CLIENT_COMMAND:New( self.EscortClient, "Use flares, chaff and jammers", self.EscortMenuEvasion, ESCORT._ROT, { ParamSelf = self, ParamFunction = EscortGroup:OptionROTPassiveDefense(), ParamMessage = "Defending using jammers, chaff and flares!" } ) - end - if EscortGroup:OptionROTEvadeFirePossible() then - self.EscortMenuEvasionEvadeFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Evade enemy fire", self.EscortMenuEvasion, ESCORT._ROT, { ParamSelf = self, ParamFunction = EscortGroup:OptionROTEvadeFire(), ParamMessage = "Evading on enemy fire!" } ) - end - if EscortGroup:OptionROTVerticalPossible() then - self.EscortMenuOptionEvasionVertical = MENU_CLIENT_COMMAND:New( self.EscortClient, "Go below radar and evade fire", self.EscortMenuEvasion, ESCORT._ROT, { ParamSelf = self, ParamFunction = EscortGroup:OptionROTVertical(), ParamMessage = "Evading on enemy fire with vertical manoeuvres!" } ) - end - - -- Mission Resume Menu Root - self.EscortMenuResumeMission = MENU_CLIENT:New( self.EscortClient, "Resume the escort mission", self.EscortMenu ) + return self +end - -- Initialize the EscortGroup - - self.EscortGroup:WayPointInitialize(1) - - self.EscortGroup:OptionROTVertical() - self.EscortGroup:OptionROEOpenFire() - - - self.ReportTargetsScheduler = routines.scheduleFunction( self._ReportTargetsScheduler, { self }, timer.getTime() + 1, 30 ) - - EscortGroup:MessageToClient( EscortGroup:GetCategoryName() .. " '" .. EscortName .. "' (" .. EscortGroup:GetCallsign() .. ") reporting! " .. - "We're escorting your flight. " .. - "Use the Radio Menu and F10 and use the options under + " .. EscortName .. "\n", - 60, EscortClient - ) + +--- Defines a menu to let the escort set its evasion when under threat. +-- All rules of engagement will appear under the menu **Evasion**. +-- @param #ESCORT self +-- @return #ESCORT +function ESCORT:MenuEvasion( MenuTextFormat ) + self:F( MenuTextFormat ) + + if self.EscortGroup:IsAir() then + if not self.EscortMenuEvasion then + -- Reaction to Threats + self.EscortMenuEvasion = MENU_CLIENT:New( self.EscortClient, "Evasion", self.EscortMenu ) + if self.EscortGroup:OptionROTNoReactionPossible() then + self.EscortMenuEvasionNoReaction = MENU_CLIENT_COMMAND:New( self.EscortClient, "Fight until death", self.EscortMenuEvasion, ESCORT._ROT, { ParamSelf = self, ParamFunction = self.EscortGroup:OptionROTNoReaction(), ParamMessage = "Fighting until death!" } ) + end + if self.EscortGroup:OptionROTPassiveDefensePossible() then + self.EscortMenuEvasionPassiveDefense = MENU_CLIENT_COMMAND:New( self.EscortClient, "Use flares, chaff and jammers", self.EscortMenuEvasion, ESCORT._ROT, { ParamSelf = self, ParamFunction = self.EscortGroup:OptionROTPassiveDefense(), ParamMessage = "Defending using jammers, chaff and flares!" } ) + end + if self.EscortGroup:OptionROTEvadeFirePossible() then + self.EscortMenuEvasionEvadeFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Evade enemy fire", self.EscortMenuEvasion, ESCORT._ROT, { ParamSelf = self, ParamFunction = self.EscortGroup:OptionROTEvadeFire(), ParamMessage = "Evading on enemy fire!" } ) + end + if self.EscortGroup:OptionROTVerticalPossible() then + self.EscortMenuOptionEvasionVertical = MENU_CLIENT_COMMAND:New( self.EscortClient, "Go below radar and evade fire", self.EscortMenuEvasion, ESCORT._ROT, { ParamSelf = self, ParamFunction = self.EscortGroup:OptionROTVertical(), ParamMessage = "Evading on enemy fire with vertical manoeuvres!" } ) + end + end + end + + return self +end + +--- Defines a menu to let the escort resume its mission from a waypoint on its route. +-- All rules of engagement will appear under the menu **Resume mission from**. +-- @param #ESCORT self +-- @return #ESCORT +function ESCORT:MenuResumeMission() + self:F() + + if not self.EscortMenuResumeMission then + -- Mission Resume Menu Root + self.EscortMenuResumeMission = MENU_CLIENT:New( self.EscortClient, "Resume mission from", self.EscortMenu ) + end + + return self end @@ -12364,48 +13239,41 @@ function ESCORT._HoldPosition( MenuParam ) local self = MenuParam.ParamSelf local EscortGroup = self.EscortGroup local EscortClient = self.EscortClient - - routines.removeFunction( self.FollowScheduler ) - EscortGroup:SetTask( EscortGroup:TaskHoldPosition( 300 ) ) - EscortGroup:MessageToClient( "Holding Position.", 10, EscortClient ) -end - ---- @param #MENUPARAM MenuParam -function ESCORT._HoldPositionNearBy( MenuParam ) - - local self = MenuParam.ParamSelf - local EscortGroup = self.EscortGroup - local EscortClient = self.EscortClient - - --MenuParam.ParamSelf.EscortGroup:TaskOrbitCircleAtVec2( MenuParam.ParamSelf.EscortClient:GetPointVec2(), 300, 30, 0 ) + local OrbitGroup = MenuParam.ParamOrbitGroup -- Group#GROUP + local OrbitUnit = OrbitGroup:GetUnit(1) -- Unit#UNIT + local OrbitHeight = MenuParam.ParamHeight + local OrbitSeconds = MenuParam.ParamSeconds -- Not implemented yet routines.removeFunction( self.FollowScheduler ) - + local PointFrom = {} - local GroupPoint = EscortGroup:GetPointVec2() + local GroupPoint = EscortGroup:GetUnit(1):GetPositionVec3() PointFrom = {} PointFrom.x = GroupPoint.x - PointFrom.y = GroupPoint.y + PointFrom.y = GroupPoint.z PointFrom.speed = 250 PointFrom.type = AI.Task.WaypointType.TURNING_POINT - PointFrom.alt = EscortClient:GetAltitude() + PointFrom.alt = GroupPoint.y PointFrom.alt_type = AI.Task.AltitudeType.BARO - local ClientPoint = MenuParam.ParamSelf.EscortClient:GetPointVec2() + local OrbitPoint = OrbitUnit:GetPointVec2() local PointTo = {} - PointTo.x = ClientPoint.x - PointTo.y = ClientPoint.y + PointTo.x = OrbitPoint.x + PointTo.y = OrbitPoint.y PointTo.speed = 250 PointTo.type = AI.Task.WaypointType.TURNING_POINT - PointTo.alt = EscortClient:GetAltitude() + PointTo.alt = OrbitHeight PointTo.alt_type = AI.Task.AltitudeType.BARO - PointTo.task = EscortGroup:TaskOrbitCircleAtVec2( EscortClient:GetPointVec2(), 300, 30, 0 ) - + PointTo.task = EscortGroup:TaskOrbitCircleAtVec2( OrbitPoint, OrbitHeight, 0 ) + local Points = { PointFrom, PointTo } - + + EscortGroup:OptionROEHoldFire() + EscortGroup:OptionROTPassiveDefense() + EscortGroup:SetTask( EscortGroup:TaskRoute( Points ) ) - EscortGroup:MessageToClient( "Rejoining to your location. Please hold at your location.", 10, EscortClient ) + EscortGroup:MessageToClient( "Orbiting at location.", 10, EscortClient ) end --- @param #MENUPARAM MenuParam @@ -12414,10 +13282,10 @@ function ESCORT._JoinUpAndFollow( MenuParam ) local self = MenuParam.ParamSelf local EscortGroup = self.EscortGroup local EscortClient = self.EscortClient - - local Distance = MenuParam.ParamDistance - - self:JoinUpAndFollow( EscortGroup, EscortClient, Distance ) + + self.Distance = MenuParam.ParamDistance + + self:JoinUpAndFollow( EscortGroup, EscortClient, self.Distance ) end --- JoinsUp and Follows a CLIENT. @@ -12431,10 +13299,12 @@ function ESCORT:JoinUpAndFollow( EscortGroup, EscortClient, Distance ) if self.FollowScheduler then routines.removeFunction( self.FollowScheduler ) end - + EscortGroup:OptionROEHoldFire() EscortGroup:OptionROTPassiveDefense() - + + self.EscortMode = ESCORT.MODE.FOLLOW + self.CT1 = 0 self.GT1 = 0 self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + 1, .5 ) @@ -12447,7 +13317,7 @@ function ESCORT._Flare( MenuParam ) local self = MenuParam.ParamSelf local EscortGroup = self.EscortGroup local EscortClient = self.EscortClient - + local Color = MenuParam.ParamColor local Message = MenuParam.ParamMessage @@ -12464,7 +13334,7 @@ function ESCORT._Smoke( MenuParam ) local Color = MenuParam.ParamColor local Message = MenuParam.ParamMessage - + EscortGroup:GetUnit(1):Smoke( Color ) EscortGroup:MessageToClient( Message, 10, EscortClient ) end @@ -12478,7 +13348,7 @@ function ESCORT._ReportNearbyTargetsNow( MenuParam ) local EscortClient = self.EscortClient self:_ReportTargetsScheduler() - + end function ESCORT._SwitchReportNearbyTargets( MenuParam ) @@ -12486,9 +13356,9 @@ function ESCORT._SwitchReportNearbyTargets( MenuParam ) local self = MenuParam.ParamSelf local EscortGroup = self.EscortGroup local EscortClient = self.EscortClient - + self.ReportTargets = MenuParam.ParamReportTargets - + if self.ReportTargets then if not self.ReportTargetsScheduler then self.ReportTargetsScheduler = routines.scheduleFunction( self._ReportTargetsScheduler, { self }, timer.getTime() + 1, 30 ) @@ -12505,45 +13375,56 @@ function ESCORT._ScanTargets( MenuParam ) local self = MenuParam.ParamSelf local EscortGroup = self.EscortGroup local EscortClient = self.EscortClient - + local ScanDuration = MenuParam.ParamScanDuration if self.FollowScheduler then routines.removeFunction( self.FollowScheduler ) end - + self:T( { "FollowScheduler after removefunction: ", self.FollowScheduler } ) - + if EscortGroup:IsHelicopter() then routines.scheduleFunction( EscortGroup.PushTask, - { EscortGroup, - EscortGroup:TaskControlled( - EscortGroup:TaskOrbitCircle( 200, 20 ), - EscortGroup:TaskCondition( nil, nil, nil, nil, ScanDuration, nil ) - ) - }, - timer.getTime() + 1 - ) + { EscortGroup, + EscortGroup:TaskControlled( + EscortGroup:TaskOrbitCircle( 200, 20 ), + EscortGroup:TaskCondition( nil, nil, nil, nil, ScanDuration, nil ) + ) + }, + timer.getTime() + 1 + ) elseif EscortGroup:IsAirPlane() then routines.scheduleFunction( EscortGroup.PushTask, - { EscortGroup, - EscortGroup:TaskControlled( - EscortGroup:TaskOrbitCircle( 1000, 500 ), - EscortGroup:TaskCondition( nil, nil, nil, nil, ScanDuration, nil ) - ) - }, - timer.getTime() + 1 - ) - end - + { EscortGroup, + EscortGroup:TaskControlled( + EscortGroup:TaskOrbitCircle( 1000, 500 ), + EscortGroup:TaskCondition( nil, nil, nil, nil, ScanDuration, nil ) + ) + }, + timer.getTime() + 1 + ) + end + EscortGroup:MessageToClient( "Scanning targets for " .. ScanDuration .. " seconds.", ScanDuration, EscortClient ) - if self.FollowScheduler then + if self.EscortMode == ESCORT.MODE.FOLLOW then self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + ScanDuration, 1 ) end end +function _Resume( EscortGroup ) + env.info( '_Resume' ) + + local Escort = EscortGroup.Escort -- #ESCORT + env.info( "EscortMode = " .. Escort.EscortMode ) + if Escort.EscortMode == ESCORT.MODE.FOLLOW then + Escort:JoinUpAndFollow( EscortGroup, Escort.EscortClient, Escort.Distance ) + end + +end + --- @param #MENUPARAM MenuParam function ESCORT._AttackTarget( MenuParam ) @@ -12555,40 +13436,37 @@ function ESCORT._AttackTarget( MenuParam ) if self.FollowScheduler then routines.removeFunction( self.FollowScheduler ) end - + self:T( AttackUnit ) - + if EscortGroup:IsAir() then EscortGroup:OptionROEOpenFire() - EscortGroup:OptionROTVertical() - routines.scheduleFunction( - EscortGroup.PushTask, - { EscortGroup, + EscortGroup:OptionROTPassiveDefense() + EscortGroup.Escort = self -- Need to do this trick to get the reference for the escort in the _Resume function. + routines.scheduleFunction( + EscortGroup.PushTask, + { EscortGroup, EscortGroup:TaskCombo( { EscortGroup:TaskAttackUnit( AttackUnit ), - EscortGroup:TaskOrbitCircle( 500, 350 ) + EscortGroup:TaskFunction( 1, 2, "_Resume", {"''"} ) } ) }, timer.getTime() + 10 ) else - routines.scheduleFunction( - EscortGroup.PushTask, - { EscortGroup, + routines.scheduleFunction( + EscortGroup.PushTask, + { EscortGroup, EscortGroup:TaskCombo( { EscortGroup:TaskFireAtPoint( AttackUnit:GetPointVec2(), 50 ) } ) - }, timer.getTime() + 10 + }, timer.getTime() + 10 ) - end + end EscortGroup:MessageToClient( "Engaging Designated Unit!", 10, EscortClient ) - if self.FollowScheduler then - self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + ScanDuration, 1 ) - end - end --- @param #MENUPARAM MenuParam @@ -12603,34 +13481,34 @@ function ESCORT._AssistTarget( MenuParam ) if self.FollowScheduler then routines.removeFunction( self.FollowScheduler ) end - - + + self:T( AttackUnit ) - + if EscortGroupAttack:IsAir() then EscortGroupAttack:OptionROEOpenFire() EscortGroupAttack:OptionROTVertical() - routines.scheduleFunction( - EscortGroupAttack.PushTask, - { EscortGroupAttack, + routines.scheduleFunction( + EscortGroupAttack.PushTask, + { EscortGroupAttack, EscortGroupAttack:TaskCombo( { EscortGroupAttack:TaskAttackUnit( AttackUnit ), EscortGroupAttack:TaskOrbitCircle( 500, 350 ) } ) - }, timer.getTime() + 10 + }, timer.getTime() + 10 ) else - routines.scheduleFunction( - EscortGroupAttack.PushTask, - { EscortGroupAttack, + routines.scheduleFunction( + EscortGroupAttack.PushTask, + { EscortGroupAttack, EscortGroupAttack:TaskCombo( { EscortGroupAttack:TaskFireAtPoint( AttackUnit:GetPointVec2(), 50 ) } ) - }, timer.getTime() + 10 + }, timer.getTime() + 10 ) - end + end EscortGroupAttack:MessageToClient( "Assisting with the destroying the enemy unit!", 10, EscortClient ) end @@ -12641,10 +13519,10 @@ function ESCORT._ROE( MenuParam ) local self = MenuParam.ParamSelf local EscortGroup = self.EscortGroup local EscortClient = self.EscortClient - + local EscortROEFunction = MenuParam.ParamFunction local EscortROEMessage = MenuParam.ParamMessage - + pcall( function() EscortROEFunction() end ) EscortGroup:MessageToClient( EscortROEMessage, 10, EscortClient ) end @@ -12669,21 +13547,21 @@ function ESCORT._ResumeMission( MenuParam ) local self = MenuParam.ParamSelf local EscortGroup = self.EscortGroup local EscortClient = self.EscortClient - + local WayPoint = MenuParam.ParamWayPoint - + routines.removeFunction( self.FollowScheduler ) self.FollowScheduler = nil local WayPoints = EscortGroup:GetTaskRoute() self:T( WayPoint, WayPoints ) - + for WayPointIgnore = 1, WayPoint do table.remove( WayPoints, 1 ) end - + routines.scheduleFunction( EscortGroup.SetTask, {EscortGroup, EscortGroup:TaskRoute( WayPoints ) }, timer.getTime() + 1 ) - + EscortGroup:MessageToClient( "Resuming mission from waypoint " .. WayPoint .. ".", 10, EscortClient ) end @@ -12694,9 +13572,9 @@ function ESCORT:RegisterRoute() self:F() local EscortGroup = self.EscortGroup -- Group#GROUP - + local TaskPoints = EscortGroup:GetTaskRoute() - + self:T( TaskPoints ) return TaskPoints @@ -12707,7 +13585,7 @@ function ESCORT:_FollowScheduler( FollowDistance ) self:F( { FollowDistance }) if self.EscortGroup:IsAlive() and self.EscortClient:IsAlive() then - + local ClientUnit = self.EscortClient:GetClientGroupUnit() local GroupUnit = self.EscortGroup:GetUnit( 1 ) @@ -12723,70 +13601,70 @@ function ESCORT:_FollowScheduler( FollowDistance ) local CV2 = ClientUnit:GetPositionVec3() self.CT1 = CT2 self.CV1 = CV2 - + local CD = ( ( CV2.x - CV1.x )^2 + ( CV2.y - CV1.y )^2 + ( CV2.z - CV1.z )^2 ) ^ 0.5 local CT = CT2 - CT1 - + local CS = ( 3600 / CT ) * ( CD / 1000 ) - + self:T2( { "Client:", CS, CD, CT, CV2, CV1, CT2, CT1 } ) - + local GT1 = self.GT1 local GT2 = timer.getTime() local GV1 = self.GV1 local GV2 = GroupUnit:GetPositionVec3() self.GT1 = GT2 self.GV1 = GV2 - + local GD = ( ( GV2.x - GV1.x )^2 + ( GV2.y - GV1.y )^2 + ( GV2.z - GV1.z )^2 ) ^ 0.5 local GT = GT2 - GT1 - + local GS = ( 3600 / GT ) * ( GD / 1000 ) - + self:T2( { "Group:", GS, GD, GT, GV2, GV1, GT2, GT1 } ) - + -- Calculate the group direction vector local GV = { x = GV2.x - CV2.x, y = GV2.y - CV2.y, z = GV2.z - CV2.z } - + -- Calculate GH2, GH2 with the same height as CV2. local GH2 = { x = GV2.x, y = CV2.y, z = GV2.z } - + -- Calculate the angle of GV to the orthonormal plane local alpha = math.atan2( GV.z, GV.x ) - + -- Now we calculate the intersecting vector between the circle around CV2 with radius FollowDistance and GH2. -- From the GeoGebra model: CVI = (x(CV2) + FollowDistance cos(alpha), y(GH2) + FollowDistance sin(alpha), z(CV2)) - local CVI = { x = CV2.x + FollowDistance * math.cos(alpha), - y = GH2.y, - z = CV2.z + FollowDistance * math.sin(alpha), - } - + local CVI = { x = CV2.x + FollowDistance * math.cos(alpha), + y = GH2.y, + z = CV2.z + FollowDistance * math.sin(alpha), + } + -- Calculate the direction vector DV of the escort group. We use CVI as the base and CV2 as the direction. local DV = { x = CV2.x - CVI.x, y = CV2.y - CVI.y, z = CV2.z - CVI.z } - + -- We now calculate the unary direction vector DVu, so that we can multiply DVu with the speed, which is expressed in meters / s. -- We need to calculate this vector to predict the point the escort group needs to fly to according its speed. -- The distance of the destination point should be far enough not to have the aircraft starting to swipe left to right... local DVu = { x = DV.x / FollowDistance, y = DV.y / FollowDistance, z = DV.z / FollowDistance } - + -- Now we can calculate the group destination vector GDV. local GDV = { x = DVu.x * CS * 8 + CVI.x, y = CVI.y, z = DVu.z * CS * 8 + CVI.z } self:T2( { "CV2:", CV2 } ) self:T2( { "CVI:", CVI } ) self:T2( { "GDV:", GDV } ) - + -- Measure distance between client and group local CatchUpDistance = ( ( GDV.x - GV2.x )^2 + ( GDV.y - GV2.y )^2 + ( GDV.z - GV2.z )^2 ) ^ 0.5 - - -- The calculation of the Speed would simulate that the group would take 30 seconds to overcome + + -- The calculation of the Speed would simulate that the group would take 30 seconds to overcome -- the requested Distance). local Time = 10 - local CatchUpSpeed = ( CatchUpDistance - ( CS * 8.4 ) ) / Time - + local CatchUpSpeed = ( CatchUpDistance - ( CS * 8.4 ) ) / Time + local Speed = CS + CatchUpSpeed - if Speed < 0 then + if Speed < 0 then Speed = 0 - end + end self:T( { "Client Speed, Escort Speed, Speed, FlyDistance, Time:", CS, GS, Speed, Distance, Time } ) @@ -12803,90 +13681,93 @@ end --- Report Targets Scheduler. -- @param #ESCORT self function ESCORT:_ReportTargetsScheduler() - self:F( self.EscortGroup:GetName() ) + self:F( self.EscortGroup:GetName() ) if self.EscortGroup:IsAlive() and self.EscortClient:IsAlive() then local EscortGroupName = self.EscortGroup:GetName() local EscortTargets = self.EscortGroup:GetDetectedTargets() - + local ClientEscortTargets = self.EscortClient._EscortGroups[EscortGroupName].Targets - + local EscortTargetMessages = "" for EscortTargetID, EscortTarget in pairs( EscortTargets ) do local EscortObject = EscortTarget.object self:T( EscortObject ) if EscortObject and EscortObject:isExist() and EscortObject.id_ < 50000000 then - - local EscortTargetUnit = UNIT:New( EscortObject ) - local EscortTargetUnitName = EscortTargetUnit:GetName() - - - --- local EscortTargetIsDetected, --- EscortTargetIsVisible, --- EscortTargetLastTime, --- EscortTargetKnowType, --- EscortTargetKnowDistance, --- EscortTargetLastPos, --- EscortTargetLastVelocity --- = self.EscortGroup:IsTargetDetected( EscortObject ) --- --- self:T( { EscortTargetIsDetected, --- EscortTargetIsVisible, --- EscortTargetLastTime, --- EscortTargetKnowType, --- EscortTargetKnowDistance, --- EscortTargetLastPos, --- EscortTargetLastVelocity } ) - - local EscortTargetUnitPositionVec3 = EscortTargetUnit:GetPositionVec3() - local EscortPositionVec3 = self.EscortGroup:GetPositionVec3() - local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 + - ( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 + - ( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2 - ) ^ 0.5 / 1000 + local EscortTargetUnit = UNIT:New( EscortObject ) + local EscortTargetUnitName = EscortTargetUnit:GetName() - self:T( { self.EscortGroup:GetName(), EscortTargetUnit:GetName(), Distance, EscortTarget } ) - if Distance <= 15 then - if not ClientEscortTargets[EscortTargetUnitName] then - ClientEscortTargets[EscortTargetUnitName] = {} - end - ClientEscortTargets[EscortTargetUnitName].AttackUnit = EscortTargetUnit - ClientEscortTargets[EscortTargetUnitName].visible = EscortTarget.visible - ClientEscortTargets[EscortTargetUnitName].type = EscortTarget.type - ClientEscortTargets[EscortTargetUnitName].distance = EscortTarget.distance - else - if ClientEscortTargets[EscortTargetUnitName] then - ClientEscortTargets[EscortTargetUnitName] = nil - end + -- local EscortTargetIsDetected, + -- EscortTargetIsVisible, + -- EscortTargetLastTime, + -- EscortTargetKnowType, + -- EscortTargetKnowDistance, + -- EscortTargetLastPos, + -- EscortTargetLastVelocity + -- = self.EscortGroup:IsTargetDetected( EscortObject ) + -- + -- self:T( { EscortTargetIsDetected, + -- EscortTargetIsVisible, + -- EscortTargetLastTime, + -- EscortTargetKnowType, + -- EscortTargetKnowDistance, + -- EscortTargetLastPos, + -- EscortTargetLastVelocity } ) + + + local EscortTargetUnitPositionVec3 = EscortTargetUnit:GetPositionVec3() + local EscortPositionVec3 = self.EscortGroup:GetPositionVec3() + local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 + + ( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 + + ( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2 + ) ^ 0.5 / 1000 + + self:T( { self.EscortGroup:GetName(), EscortTargetUnit:GetName(), Distance, EscortTarget } ) + + if Distance <= 15 then + + if not ClientEscortTargets[EscortTargetUnitName] then + ClientEscortTargets[EscortTargetUnitName] = {} end + ClientEscortTargets[EscortTargetUnitName].AttackUnit = EscortTargetUnit + ClientEscortTargets[EscortTargetUnitName].visible = EscortTarget.visible + ClientEscortTargets[EscortTargetUnitName].type = EscortTarget.type + ClientEscortTargets[EscortTargetUnitName].distance = EscortTarget.distance + else + if ClientEscortTargets[EscortTargetUnitName] then + ClientEscortTargets[EscortTargetUnitName] = nil + end + end end end - + self:T( { "Sorting Targets Table:", ClientEscortTargets } ) table.sort( ClientEscortTargets, function( a, b ) return a.Distance < b.Distance end ) self:T( { "Sorted Targets Table:", ClientEscortTargets } ) -- Remove the sub menus of the Attack menu of the Escort for the EscortGroup. self.EscortMenuAttackNearbyTargets:RemoveSubMenus() - self.EscortMenuTargetAssistance:RemoveSubMenus() - + + if self.EscortMenuTargetAssistance then + self.EscortMenuTargetAssistance:RemoveSubMenus() + end + --for MenuIndex = 1, #self.EscortMenuAttackTargets do -- self:T( { "Remove Menu:", self.EscortMenuAttackTargets[MenuIndex] } ) -- self.EscortMenuAttackTargets[MenuIndex] = self.EscortMenuAttackTargets[MenuIndex]:Remove() --end - + if ClientEscortTargets then for ClientEscortTargetUnitName, ClientEscortTargetData in pairs( ClientEscortTargets ) do - + for ClientEscortGroupName, EscortGroupData in pairs( self.EscortClient._EscortGroups ) do - + if ClientEscortTargetData and ClientEscortTargetData.AttackUnit:IsAlive() then - + local EscortTargetMessage = "" local EscortTargetCategoryName = ClientEscortTargetData.AttackUnit:GetCategoryName() local EscortTargetCategoryType = ClientEscortTargetData.AttackUnit:GetTypeName() @@ -12895,54 +13776,56 @@ function ESCORT:_ReportTargetsScheduler() else EscortTargetMessage = EscortTargetMessage .. "Unknown target at " end - + local EscortTargetUnitPositionVec3 = ClientEscortTargetData.AttackUnit:GetPositionVec3() local EscortPositionVec3 = self.EscortGroup:GetPositionVec3() - local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 + - ( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 + - ( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2 - ) ^ 0.5 / 1000 - + local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 + + ( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 + + ( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2 + ) ^ 0.5 / 1000 + self:T( { self.EscortGroup:GetName(), ClientEscortTargetData.AttackUnit:GetName(), Distance, ClientEscortTargetData.AttackUnit } ) if ClientEscortTargetData.visible == false then EscortTargetMessage = EscortTargetMessage .. string.format( "%.2f", Distance ) .. " estimated km" else EscortTargetMessage = EscortTargetMessage .. string.format( "%.2f", Distance ) .. " km" end - + if ClientEscortTargetData.visible then EscortTargetMessage = EscortTargetMessage .. ", visual" end - + if ClientEscortGroupName == EscortGroupName then - + MENU_CLIENT_COMMAND:New( self.EscortClient, - EscortTargetMessage, - self.EscortMenuAttackNearbyTargets, - ESCORT._AttackTarget, - { ParamSelf = self, - ParamUnit = ClientEscortTargetData.AttackUnit - } - ) - EscortTargetMessages = EscortTargetMessages .. "\n - " .. EscortTargetMessage + EscortTargetMessage, + self.EscortMenuAttackNearbyTargets, + ESCORT._AttackTarget, + { ParamSelf = self, + ParamUnit = ClientEscortTargetData.AttackUnit + } + ) + EscortTargetMessages = EscortTargetMessages .. "\n - " .. EscortTargetMessage else - local MenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, EscortGroupData.EscortName, self.EscortMenuTargetAssistance ) - MENU_CLIENT_COMMAND:New( self.EscortClient, - EscortTargetMessage, - MenuTargetAssistance, - ESCORT._AssistTarget, - { ParamSelf = self, - ParamEscortGroup = EscortGroupData.EscortGroup, - ParamUnit = ClientEscortTargetData.AttackUnit - } - ) + if self.EscortMenuTargetAssistance then + local MenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, EscortGroupData.EscortName, self.EscortMenuTargetAssistance ) + MENU_CLIENT_COMMAND:New( self.EscortClient, + EscortTargetMessage, + MenuTargetAssistance, + ESCORT._AssistTarget, + { ParamSelf = self, + ParamEscortGroup = EscortGroupData.EscortGroup, + ParamUnit = ClientEscortTargetData.AttackUnit + } + ) + end end else ClientEscortTargetData = nil end end end - + if EscortTargetMessages ~= "" and self.ReportTargets == true then self.EscortGroup:MessageToClient( "Detected targets within 15 km range:" .. EscortTargetMessages:gsub("\n$",""), 20, self.EscortClient ) else @@ -12950,22 +13833,24 @@ function ESCORT:_ReportTargetsScheduler() end end - self.EscortMenuResumeMission:RemoveSubMenus() - --- if self.EscortMenuResumeWayPoints then --- for MenuIndex = 1, #self.EscortMenuResumeWayPoints do --- self:T( { "Remove Menu:", self.EscortMenuResumeWayPoints[MenuIndex] } ) --- self.EscortMenuResumeWayPoints[MenuIndex] = self.EscortMenuResumeWayPoints[MenuIndex]:Remove() --- end --- end + if self.EscortMenuResumeMission then + self.EscortMenuResumeMission:RemoveSubMenus() - local TaskPoints = self:RegisterRoute() - for WayPointID, WayPoint in pairs( TaskPoints ) do - local EscortPositionVec3 = self.EscortGroup:GetPositionVec3() - local Distance = ( ( WayPoint.x - EscortPositionVec3.x )^2 + - ( WayPoint.y - EscortPositionVec3.z )^2 - ) ^ 0.5 / 1000 - MENU_CLIENT_COMMAND:New( self.EscortClient, "Waypoint " .. WayPointID .. " at " .. string.format( "%.2f", Distance ).. "km", self.EscortMenuResumeMission, ESCORT._ResumeMission, { ParamSelf = self, ParamWayPoint = WayPointID } ) + -- if self.EscortMenuResumeWayPoints then + -- for MenuIndex = 1, #self.EscortMenuResumeWayPoints do + -- self:T( { "Remove Menu:", self.EscortMenuResumeWayPoints[MenuIndex] } ) + -- self.EscortMenuResumeWayPoints[MenuIndex] = self.EscortMenuResumeWayPoints[MenuIndex]:Remove() + -- end + -- end + + local TaskPoints = self:RegisterRoute() + for WayPointID, WayPoint in pairs( TaskPoints ) do + local EscortPositionVec3 = self.EscortGroup:GetPositionVec3() + local Distance = ( ( WayPoint.x - EscortPositionVec3.x )^2 + + ( WayPoint.y - EscortPositionVec3.z )^2 + ) ^ 0.5 / 1000 + MENU_CLIENT_COMMAND:New( self.EscortClient, "Waypoint " .. WayPointID .. " at " .. string.format( "%.2f", Distance ).. "km", self.EscortMenuResumeMission, ESCORT._ResumeMission, { ParamSelf = self, ParamWayPoint = WayPointID } ) + end end else diff --git a/Moose/CleanUp.lua b/Moose/CleanUp.lua index ac28d7738..236f63e14 100644 --- a/Moose/CleanUp.lua +++ b/Moose/CleanUp.lua @@ -10,6 +10,7 @@ Include.File( "Task" ) --- The CLEANUP class. -- @type CLEANUP +-- @extends Base#BASE CLEANUP = { ClassName = "CLEANUP", ZoneNames = {}, @@ -77,9 +78,8 @@ function CLEANUP:_DestroyUnit( CleanUpUnit, CleanUpUnitName ) local CleanUpGroupUnits = CleanUpGroup:getUnits() if #CleanUpGroupUnits == 1 then local CleanUpGroupName = CleanUpGroup:getName() - local Event = {["initiator"]=CleanUpUnit,["id"]=8} - world.onEvent( Event ) - trigger.action.deactivateGroup( CleanUpGroup ) + --self:CreateEventCrash( timer.getTime(), CleanUpUnit ) + CleanUpGroup:destroy() self:T( { "Destroyed Group:", CleanUpGroupName } ) else CleanUpUnit:destroy() @@ -116,6 +116,8 @@ function CLEANUP:_OnEventBirth( Event ) _EventDispatcher:OnEngineShutDownForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) _EventDispatcher:OnEngineStartUpForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) _EventDispatcher:OnHitForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) + _EventDispatcher:OnPilotDeadForUnit( Event.IniDCSUnitName, self._EventCrash, self ) + _EventDispatcher:OnDeadForUnit( Event.IniDCSUnitName, self._EventCrash, self ) _EventDispatcher:OnCrashForUnit( Event.IniDCSUnitName, self._EventCrash, self ) _EventDispatcher:OnShotForUnit( Event.IniDCSUnitName, self._EventShot, self ) @@ -135,9 +137,10 @@ end -- Crashed units go into a CleanUpList for removal. -- @param #CLEANUP self -- @param DCSTypes#Event event -function CLEANUP:_EventCrash( event ) - self:F( { event } ) +function CLEANUP:_EventCrash( Event ) + self:F( { Event } ) + --TODO: This stuff is not working due to a DCS bug. Burning units cannot be destroyed. --MESSAGE:New( "Crash ", "Crash", 10, "Crash" ):ToAll() -- self:T("before getGroup") -- local _grp = Unit.getGroup(event.initiator)-- Identify the group that fired @@ -151,6 +154,7 @@ function CLEANUP:_EventCrash( event ) self.CleanUpList[Event.IniDCSUnitName].CleanUpGroup = Event.IniDCSGroup self.CleanUpList[Event.IniDCSUnitName].CleanUpGroupName = Event.IniDCSGroupName self.CleanUpList[Event.IniDCSUnitName].CleanUpUnitName = Event.IniDCSUnitName + end --- Detects if a unit shoots a missile. @@ -248,9 +252,11 @@ local CleanUpSurfaceTypeText = { --- At the defined time interval, CleanUp the Groups within the CleanUpList. -- @param #CLEANUP self function CLEANUP:_CleanUpScheduler() - self:F( "CleanUp Scheduler" ) + self:F( { "CleanUp Scheduler" } ) + local CleanUpCount = 0 for CleanUpUnitName, UnitData in pairs( self.CleanUpList ) do + CleanUpCount = CleanUpCount + 1 self:T( { CleanUpUnitName, UnitData } ) local CleanUpUnit = Unit.getByName(UnitData.CleanUpUnitName) @@ -312,5 +318,6 @@ function CLEANUP:_CleanUpScheduler() self.CleanUpList[CleanUpUnitName] = nil -- Not anymore in the DCSRTE end end + self:T(CleanUpCount) end diff --git a/Moose/Database.lua b/Moose/Database.lua index a05b31fea..58d2a5011 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -13,31 +13,31 @@ Include.File( "Event" ) -- @type DATABASE -- @extends Base#BASE DATABASE = { - ClassName = "DATABASE", - Units = {}, - Groups = {}, - NavPoints = {}, - Statics = {}, - Players = {}, - ActivePlayers = {}, - ClientsByName = {}, - ClientsByID = {}, + ClassName = "DATABASE", + Units = {}, + Groups = {}, + NavPoints = {}, + Statics = {}, + Players = {}, + ActivePlayers = {}, + ClientsByName = {}, + ClientsByID = {}, } -DATABASECoalition = -{ - [1] = "Red", - [2] = "Blue", -} +local _DATABASECoalition = + { + [1] = "Red", + [2] = "Blue", + } -DATABASECategory = -{ - [Unit.Category.AIRPLANE] = "Plane", - [Unit.Category.HELICOPTER] = "Helicopter", - [Unit.Category.GROUND_UNIT] = "Vehicle", - [Unit.Category.SHIP] = "Ship", - [Unit.Category.STRUCTURE] = "Structure", -} +local _DATABASECategory = + { + [Unit.Category.AIRPLANE] = "Plane", + [Unit.Category.HELICOPTER] = "Helicopter", + [Unit.Category.GROUND_UNIT] = "Vehicle", + [Unit.Category.SHIP] = "Ship", + [Unit.Category.STRUCTURE] = "Structure", + } --- Creates a new DATABASE Object to administer the Groups defined and alive within the DCSRTE. @@ -47,80 +47,79 @@ DATABASECategory = -- DBObject = DATABASE:New() function DATABASE:New() - -- Inherits from BASE - local self = BASE:Inherit( self, BASE:New() ) - - self.Navpoints = {} - self.Units = {} - --Build routines.db.units and self.Navpoints - for coa_name, coa_data in pairs(env.mission.coalition) do + -- Inherits from BASE + local self = BASE:Inherit( self, BASE:New() ) - if (coa_name == 'red' or coa_name == 'blue') and type(coa_data) == 'table' then - self.Units[coa_name] = {} - - ---------------------------------------------- - -- build nav points DB - self.Navpoints[coa_name] = {} - if coa_data.nav_points then --navpoints - for nav_ind, nav_data in pairs(coa_data.nav_points) do - - if type(nav_data) == 'table' then - self.Navpoints[coa_name][nav_ind] = routines.utils.deepCopy(nav_data) + self.Navpoints = {} + self.Units = {} + --Build routines.db.units and self.Navpoints + for coa_name, coa_data in pairs(env.mission.coalition) do - self.Navpoints[coa_name][nav_ind]['name'] = nav_data.callsignStr -- name is a little bit more self-explanatory. - self.Navpoints[coa_name][nav_ind]['point'] = {} -- point is used by SSE, support it. - self.Navpoints[coa_name][nav_ind]['point']['x'] = nav_data.x - self.Navpoints[coa_name][nav_ind]['point']['y'] = 0 - self.Navpoints[coa_name][nav_ind]['point']['z'] = nav_data.y - end - end - end - ------------------------------------------------- - if coa_data.country then --there is a country table - for cntry_id, cntry_data in pairs(coa_data.country) do - - local countryName = string.lower(cntry_data.name) - self.Units[coa_name][countryName] = {} - self.Units[coa_name][countryName]["countryId"] = cntry_data.id + if (coa_name == 'red' or coa_name == 'blue') and type(coa_data) == 'table' then + self.Units[coa_name] = {} - if type(cntry_data) == 'table' then --just making sure - - for obj_type_name, obj_type_data in pairs(cntry_data) do - - if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then --should be an unncessary check - - local category = obj_type_name - - if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then --there's a group! - - self.Units[coa_name][countryName][category] = {} - - for group_num, GroupTemplate in pairs(obj_type_data.group) do - - if GroupTemplate and GroupTemplate.units and type(GroupTemplate.units) == 'table' then --making sure again- this is a valid group - self:_RegisterGroup( GroupTemplate ) - end --if GroupTemplate and GroupTemplate.units then - end --for group_num, GroupTemplate in pairs(obj_type_data.group) do - end --if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then - end --if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then - end --for obj_type_name, obj_type_data in pairs(cntry_data) do - end --if type(cntry_data) == 'table' then - end --for cntry_id, cntry_data in pairs(coa_data.country) do - end --if coa_data.country then --there is a country table - end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then - end --for coa_name, coa_data in pairs(mission.coalition) do + ---------------------------------------------- + -- build nav points DB + self.Navpoints[coa_name] = {} + if coa_data.nav_points then --navpoints + for nav_ind, nav_data in pairs(coa_data.nav_points) do - --self:AddEvent( world.event.S_EVENT_BIRTH, self.OnBirth ) - _EventDispatcher:OnDead( self.OnDeadOrCrash, self ) - _EventDispatcher:OnCrash( self.OnDeadOrCrash, self ) - _EventDispatcher:OnHit( self.OnHit, self ) - - self.SchedulerId = routines.scheduleFunction( DATABASE._FollowPlayers, { self }, 0, 5 ) - - self:ScoreMenu() - - - return self + if type(nav_data) == 'table' then + self.Navpoints[coa_name][nav_ind] = routines.utils.deepCopy(nav_data) + + self.Navpoints[coa_name][nav_ind]['name'] = nav_data.callsignStr -- name is a little bit more self-explanatory. + self.Navpoints[coa_name][nav_ind]['point'] = {} -- point is used by SSE, support it. + self.Navpoints[coa_name][nav_ind]['point']['x'] = nav_data.x + self.Navpoints[coa_name][nav_ind]['point']['y'] = 0 + self.Navpoints[coa_name][nav_ind]['point']['z'] = nav_data.y + end + end + end + ------------------------------------------------- + if coa_data.country then --there is a country table + for cntry_id, cntry_data in pairs(coa_data.country) do + + local countryName = string.lower(cntry_data.name) + self.Units[coa_name][countryName] = {} + self.Units[coa_name][countryName]["countryId"] = cntry_data.id + + if type(cntry_data) == 'table' then --just making sure + + for obj_type_name, obj_type_data in pairs(cntry_data) do + + if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then --should be an unncessary check + + local category = obj_type_name + + if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then --there's a group! + + self.Units[coa_name][countryName][category] = {} + + for group_num, GroupTemplate in pairs(obj_type_data.group) do + + if GroupTemplate and GroupTemplate.units and type(GroupTemplate.units) == 'table' then --making sure again- this is a valid group + self:_RegisterGroup( GroupTemplate ) + end --if GroupTemplate and GroupTemplate.units then + end --for group_num, GroupTemplate in pairs(obj_type_data.group) do + end --if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then + end --if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then + end --for obj_type_name, obj_type_data in pairs(cntry_data) do + end --if type(cntry_data) == 'table' then + end --for cntry_id, cntry_data in pairs(coa_data.country) do + end --if coa_data.country then --there is a country table + end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then + end --for coa_name, coa_data in pairs(mission.coalition) do + + --self:AddEvent( world.event.S_EVENT_BIRTH, self.OnBirth ) + _EventDispatcher:OnDead( self._EventOnDeadOrCrash, self ) + _EventDispatcher:OnCrash( self._EventOnDeadOrCrash, self ) + _EventDispatcher:OnHit( self._EventOnHit, self ) + + self.SchedulerId = routines.scheduleFunction( DATABASE._FollowPlayers, { self }, 0, 5 ) + + self:ScoreMenu() + + return self end @@ -130,49 +129,49 @@ end -- This method is used by the SPAWN class. function DATABASE:Spawn( SpawnTemplate ) - self:T( { SpawnTemplate.SpawnCountryID, SpawnTemplate.SpawnCategoryID, SpawnTemplate.name } ) - - -- Copy the spawn variables of the template in temporary storage, nullify, and restore the spawn variables. - local SpawnCoalitionID = SpawnTemplate.SpawnCoalitionID - local SpawnCountryID = SpawnTemplate.SpawnCountryID - local SpawnCategoryID = SpawnTemplate.SpawnCategoryID - - -- Nullify - SpawnTemplate.SpawnCoalitionID = nil - SpawnTemplate.SpawnCountryID = nil - SpawnTemplate.SpawnCategoryID = nil - - self:_RegisterGroup( SpawnTemplate ) - coalition.addGroup( SpawnCountryID, SpawnCategoryID, SpawnTemplate ) + self:T( { SpawnTemplate.SpawnCountryID, SpawnTemplate.SpawnCategoryID, SpawnTemplate.name } ) - -- Restore - SpawnTemplate.SpawnCoalitionID = SpawnCoalitionID - SpawnTemplate.SpawnCountryID = SpawnCountryID - SpawnTemplate.SpawnCategoryID = SpawnCategoryID + -- Copy the spawn variables of the template in temporary storage, nullify, and restore the spawn variables. + local SpawnCoalitionID = SpawnTemplate.SpawnCoalitionID + local SpawnCountryID = SpawnTemplate.SpawnCountryID + local SpawnCategoryID = SpawnTemplate.SpawnCategoryID - - local SpawnGroup = GROUP:New( Group.getByName( SpawnTemplate.name ) ) - return SpawnGroup + -- Nullify + SpawnTemplate.SpawnCoalitionID = nil + SpawnTemplate.SpawnCountryID = nil + SpawnTemplate.SpawnCategoryID = nil + + self:_RegisterGroup( SpawnTemplate ) + coalition.addGroup( SpawnCountryID, SpawnCategoryID, SpawnTemplate ) + + -- Restore + SpawnTemplate.SpawnCoalitionID = SpawnCoalitionID + SpawnTemplate.SpawnCountryID = SpawnCountryID + SpawnTemplate.SpawnCategoryID = SpawnCategoryID + + + local SpawnGroup = GROUP:New( Group.getByName( SpawnTemplate.name ) ) + return SpawnGroup end --- Set a status to a Group within the Database, this to check crossing events for example. function DATABASE:SetStatusGroup( GroupName, Status ) - self:F( Status ) + self:F( Status ) - self.Groups[GroupName].Status = Status + self.Groups[GroupName].Status = Status end --- Get a status to a Group within the Database, this to check crossing events for example. function DATABASE:GetStatusGroup( GroupName ) - self:F( Status ) + self:F( Status ) - if self.Groups[GroupName] then - return self.Groups[GroupName].Status - else - return "" - end + if self.Groups[GroupName] then + return self.Groups[GroupName].Status + else + return "" + end end @@ -183,35 +182,35 @@ end --- Registers new Group Templates within the DATABASE Object. function DATABASE:_RegisterGroup( GroupTemplate ) - local GroupTemplateName = env.getValueDictByKey(GroupTemplate.name) + local GroupTemplateName = env.getValueDictByKey(GroupTemplate.name) - if not self.Groups[GroupTemplateName] then - self.Groups[GroupTemplateName] = {} - self.Groups[GroupTemplateName].Status = nil - end - self.Groups[GroupTemplateName].GroupName = GroupTemplateName - self.Groups[GroupTemplateName].Template = GroupTemplate - self.Groups[GroupTemplateName].groupId = GroupTemplate.groupId - self.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units - self.Groups[GroupTemplateName].Units = GroupTemplate.units - - self:T( { "Group", self.Groups[GroupTemplateName].GroupName, self.Groups[GroupTemplateName].UnitCount } ) - - for unit_num, UnitTemplate in pairs(GroupTemplate.units) do - - local UnitTemplateName = env.getValueDictByKey(UnitTemplate.name) - self.Units[UnitTemplateName] = {} - self.Units[UnitTemplateName].UnitName = UnitTemplateName - self.Units[UnitTemplateName].Template = UnitTemplate - self.Units[UnitTemplateName].GroupName = GroupTemplateName - self.Units[UnitTemplateName].GroupTemplate = GroupTemplate - self.Units[UnitTemplateName].GroupId = GroupTemplate.groupId - if UnitTemplate.skill and (UnitTemplate.skill == "Client" or UnitTemplate.skill == "Player") then - self.ClientsByName[UnitTemplateName] = UnitTemplate - self.ClientsByID[UnitTemplate.unitId] = UnitTemplate - end - self:T( { "Unit", self.Units[UnitTemplateName].UnitName } ) - end + if not self.Groups[GroupTemplateName] then + self.Groups[GroupTemplateName] = {} + self.Groups[GroupTemplateName].Status = nil + end + self.Groups[GroupTemplateName].GroupName = GroupTemplateName + self.Groups[GroupTemplateName].Template = GroupTemplate + self.Groups[GroupTemplateName].groupId = GroupTemplate.groupId + self.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units + self.Groups[GroupTemplateName].Units = GroupTemplate.units + + self:T( { "Group", self.Groups[GroupTemplateName].GroupName, self.Groups[GroupTemplateName].UnitCount } ) + + for unit_num, UnitTemplate in pairs(GroupTemplate.units) do + + local UnitTemplateName = env.getValueDictByKey(UnitTemplate.name) + self.Units[UnitTemplateName] = {} + self.Units[UnitTemplateName].UnitName = UnitTemplateName + self.Units[UnitTemplateName].Template = UnitTemplate + self.Units[UnitTemplateName].GroupName = GroupTemplateName + self.Units[UnitTemplateName].GroupTemplate = GroupTemplate + self.Units[UnitTemplateName].GroupId = GroupTemplate.groupId + if UnitTemplate.skill and (UnitTemplate.skill == "Client" or UnitTemplate.skill == "Player") then + self.ClientsByName[UnitTemplateName] = UnitTemplate + self.ClientsByID[UnitTemplate.unitId] = UnitTemplate + end + self:T( { "Unit", self.Units[UnitTemplateName].UnitName } ) + end end @@ -220,96 +219,94 @@ end --- Track DCSRTE DEAD or CRASH events for the internal scoring. -function DATABASE:OnDeadOrCrash( event ) - self:F( { event } ) +-- @param #DATABASE self +-- @param Event#EVENTDATA Event +function DATABASE:_EventOnDeadOrCrash( Event ) + self:F( { Event } ) - local TargetUnit = nil - local TargetGroup = nil - local TargetUnitName = "" - local TargetGroupName = "" - local TargetPlayerName = "" - local TargetCoalition = nil - local TargetCategory = nil - local TargetType = nil - local TargetUnitCoalition = nil - local TargetUnitCategory = nil - local TargetUnitType = nil + local TargetUnit = nil + local TargetGroup = nil + local TargetUnitName = "" + local TargetGroupName = "" + local TargetPlayerName = "" + local TargetCoalition = nil + local TargetCategory = nil + local TargetType = nil + local TargetUnitCoalition = nil + local TargetUnitCategory = nil + local TargetUnitType = nil - if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then - - TargetUnit = event.initiator - TargetGroup = Unit.getGroup( TargetUnit ) - TargetUnitDesc = TargetUnit:getDesc() - - TargetUnitName = TargetUnit:getName() - if TargetGroup and TargetGroup:isExist() then - TargetGroupName = TargetGroup:getName() - end - TargetPlayerName = TargetUnit:getPlayerName() + if Event.IniDCSUnit then - TargetCoalition = TargetUnit:getCoalition() - --TargetCategory = TargetUnit:getCategory() - TargetCategory = TargetUnitDesc.category -- Workaround - TargetType = TargetUnit:getTypeName() + TargetUnit = Event.IniDCSUnit + TargetUnitName = Event.IniDCSUnitName + TargetGroup = Event.IniDCSGroup + TargetGroupName = Event.IniDCSGroupName + TargetPlayerName = TargetUnit:getPlayerName() - TargetUnitCoalition = DATABASECoalition[TargetCoalition] - TargetUnitCategory = DATABASECategory[TargetCategory] - TargetUnitType = TargetType + TargetCoalition = TargetUnit:getCoalition() + --TargetCategory = TargetUnit:getCategory() + TargetCategory = TargetUnit:getDesc().category -- Workaround + TargetType = TargetUnit:getTypeName() - self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } ) - end + TargetUnitCoalition = _DATABASECoalition[TargetCoalition] + TargetUnitCategory = _DATABASECategory[T1argetCategory] + TargetUnitType = TargetType - for PlayerName, PlayerData in pairs( self.Players ) do - if PlayerData then -- This should normally not happen, but i'll test it anyway. - self:T( "Something got killed" ) + self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } ) + end - -- Some variables - local InitUnitName = PlayerData.UnitName - local InitUnitType = PlayerData.UnitType - local InitCoalition = PlayerData.UnitCoalition - local InitCategory = PlayerData.UnitCategory - local InitUnitCoalition = DATABASECoalition[InitCoalition] - local InitUnitCategory = DATABASECategory[InitCategory] - - self:T( { InitUnitName, InitUnitType, InitUnitCoalition, InitCoalition, InitUnitCategory, InitCategory } ) + for PlayerName, PlayerData in pairs( self.Players ) do + if PlayerData then -- This should normally not happen, but i'll test it anyway. + self:T( "Something got killed" ) - -- What is he hitting? - if TargetCategory then - if PlayerData and PlayerData.Hit and PlayerData.Hit[TargetCategory] and PlayerData.Hit[TargetCategory][TargetUnitName] then -- Was there a hit for this unit for this player before registered??? - if not PlayerData.Kill[TargetCategory] then - PlayerData.Kill[TargetCategory] = {} - end - if not PlayerData.Kill[TargetCategory][TargetType] then - PlayerData.Kill[TargetCategory][TargetType] = {} - PlayerData.Kill[TargetCategory][TargetType].Score = 0 - PlayerData.Kill[TargetCategory][TargetType].ScoreKill = 0 - PlayerData.Kill[TargetCategory][TargetType].Penalty = 0 - PlayerData.Kill[TargetCategory][TargetType].PenaltyKill = 0 - end + -- Some variables + local InitUnitName = PlayerData.UnitName + local InitUnitType = PlayerData.UnitType + local InitCoalition = PlayerData.UnitCoalition + local InitCategory = PlayerData.UnitCategory + local InitUnitCoalition = _DATABASECoalition[InitCoalition] + local InitUnitCategory = _DATABASECategory[InitCategory] - if InitCoalition == TargetCoalition then - PlayerData.Penalty = PlayerData.Penalty + 25 - PlayerData.Kill[TargetCategory][TargetType].Penalty = PlayerData.Kill[TargetCategory][TargetType].Penalty + 25 - PlayerData.Kill[TargetCategory][TargetType].PenaltyKill = PlayerData.Kill[TargetCategory][TargetType].PenaltyKill + 1 - MESSAGE:New( "Player '" .. PlayerName .. "' killed a friendly " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. - PlayerData.Kill[TargetCategory][TargetType].PenaltyKill .. " times. Penalty: -" .. PlayerData.Kill[TargetCategory][TargetType].Penalty .. - ". Score Total:" .. PlayerData.Score - PlayerData.Penalty, - "", 5, "/PENALTY" .. PlayerName .. "/" .. InitUnitName ):ToAll() - self:ScoreAdd( PlayerName, "KILL_PENALTY", 1, -125, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) - else - PlayerData.Score = PlayerData.Score + 10 - PlayerData.Kill[TargetCategory][TargetType].Score = PlayerData.Kill[TargetCategory][TargetType].Score + 10 - PlayerData.Kill[TargetCategory][TargetType].ScoreKill = PlayerData.Kill[TargetCategory][TargetType].ScoreKill + 1 - MESSAGE:New( "Player '" .. PlayerName .. "' killed an enemy " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. - PlayerData.Kill[TargetCategory][TargetType].ScoreKill .. " times. Score: " .. PlayerData.Kill[TargetCategory][TargetType].Score .. - ". Score Total:" .. PlayerData.Score - PlayerData.Penalty, - "", 5, "/SCORE" .. PlayerName .. "/" .. InitUnitName ):ToAll() - self:ScoreAdd( PlayerName, "KILL_SCORE", 1, 10, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) - end - end - end - end - end + self:T( { InitUnitName, InitUnitType, InitUnitCoalition, InitCoalition, InitUnitCategory, InitCategory } ) + + -- What is he hitting? + if TargetCategory then + if PlayerData and PlayerData.Hit and PlayerData.Hit[TargetCategory] and PlayerData.Hit[TargetCategory][TargetUnitName] then -- Was there a hit for this unit for this player before registered??? + if not PlayerData.Kill[TargetCategory] then + PlayerData.Kill[TargetCategory] = {} + end + if not PlayerData.Kill[TargetCategory][TargetType] then + PlayerData.Kill[TargetCategory][TargetType] = {} + PlayerData.Kill[TargetCategory][TargetType].Score = 0 + PlayerData.Kill[TargetCategory][TargetType].ScoreKill = 0 + PlayerData.Kill[TargetCategory][TargetType].Penalty = 0 + PlayerData.Kill[TargetCategory][TargetType].PenaltyKill = 0 + end + + if InitCoalition == TargetCoalition then + PlayerData.Penalty = PlayerData.Penalty + 25 + PlayerData.Kill[TargetCategory][TargetType].Penalty = PlayerData.Kill[TargetCategory][TargetType].Penalty + 25 + PlayerData.Kill[TargetCategory][TargetType].PenaltyKill = PlayerData.Kill[TargetCategory][TargetType].PenaltyKill + 1 + MESSAGE:New( "Player '" .. PlayerName .. "' killed a friendly " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. + PlayerData.Kill[TargetCategory][TargetType].PenaltyKill .. " times. Penalty: -" .. PlayerData.Kill[TargetCategory][TargetType].Penalty .. + ". Score Total:" .. PlayerData.Score - PlayerData.Penalty, + "", 5, "/PENALTY" .. PlayerName .. "/" .. InitUnitName ):ToAll() + self:ScoreAdd( PlayerName, "KILL_PENALTY", 1, -125, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) + else + PlayerData.Score = PlayerData.Score + 10 + PlayerData.Kill[TargetCategory][TargetType].Score = PlayerData.Kill[TargetCategory][TargetType].Score + 10 + PlayerData.Kill[TargetCategory][TargetType].ScoreKill = PlayerData.Kill[TargetCategory][TargetType].ScoreKill + 1 + MESSAGE:New( "Player '" .. PlayerName .. "' killed an enemy " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. + PlayerData.Kill[TargetCategory][TargetType].ScoreKill .. " times. Score: " .. PlayerData.Kill[TargetCategory][TargetType].Score .. + ". Score Total:" .. PlayerData.Score - PlayerData.Penalty, + "", 5, "/SCORE" .. PlayerName .. "/" .. InitUnitName ):ToAll() + self:ScoreAdd( PlayerName, "KILL_SCORE", 1, 10, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) + end + end + end + end + end end @@ -319,20 +316,20 @@ end --- Follows new players entering Clients within the DCSRTE. function DATABASE:_FollowPlayers() - self:F3( "_FollowPlayers" ) + self:F3( "_FollowPlayers" ) - local ClientUnit = 0 - local CoalitionsData = { AlivePlayersRed = coalition.getPlayers(coalition.side.RED), AlivePlayersBlue = coalition.getPlayers(coalition.side.BLUE) } - local unitId - local unitData - local AlivePlayerUnits = {} - - for CoalitionId, CoalitionData in pairs( CoalitionsData ) do - self:T3( { "_FollowPlayers", CoalitionData } ) - for UnitId, UnitData in pairs( CoalitionData ) do - self:_AddPlayerFromUnit( UnitData ) - end - end + local ClientUnit = 0 + local CoalitionsData = { AlivePlayersRed = coalition.getPlayers(coalition.side.RED), AlivePlayersBlue = coalition.getPlayers(coalition.side.BLUE) } + local unitId + local unitData + local AlivePlayerUnits = {} + + for CoalitionId, CoalitionData in pairs( CoalitionsData ) do + self:T3( { "_FollowPlayers", CoalitionData } ) + for UnitId, UnitData in pairs( CoalitionData ) do + self:_AddPlayerFromUnit( UnitData ) + end + end end @@ -342,102 +339,102 @@ end --- Add a new player entering a Unit. function DATABASE:_AddPlayerFromUnit( UnitData ) - self:F( UnitData ) + self:F( UnitData ) - if UnitData:isExist() then - local UnitName = UnitData:getName() - local PlayerName = UnitData:getPlayerName() - local UnitDesc = UnitData:getDesc() - local UnitCategory = UnitDesc.category - local UnitCoalition = UnitData:getCoalition() - local UnitTypeName = UnitData:getTypeName() + if UnitData:isExist() then + local UnitName = UnitData:getName() + local PlayerName = UnitData:getPlayerName() + local UnitDesc = UnitData:getDesc() + local UnitCategory = UnitDesc.category + local UnitCoalition = UnitData:getCoalition() + local UnitTypeName = UnitData:getTypeName() - self:T( { PlayerName, UnitName, UnitCategory, UnitCoalition, UnitTypeName } ) + self:T( { PlayerName, UnitName, UnitCategory, UnitCoalition, UnitTypeName } ) - if self.Players[PlayerName] == nil then -- I believe this is the place where a Player gets a life in a mission when he enters a unit ... - self.Players[PlayerName] = {} - self.Players[PlayerName].Hit = {} - self.Players[PlayerName].Kill = {} - self.Players[PlayerName].Mission = {} - - -- for CategoryID, CategoryName in pairs( DATABASECategory ) do - -- self.Players[PlayerName].Hit[CategoryID] = {} - -- self.Players[PlayerName].Kill[CategoryID] = {} - -- end - self.Players[PlayerName].HitPlayers = {} - self.Players[PlayerName].HitUnits = {} + if self.Players[PlayerName] == nil then -- I believe this is the place where a Player gets a life in a mission when he enters a unit ... + self.Players[PlayerName] = {} + self.Players[PlayerName].Hit = {} + self.Players[PlayerName].Kill = {} + self.Players[PlayerName].Mission = {} + + -- for CategoryID, CategoryName in pairs( DATABASECategory ) do + -- self.Players[PlayerName].Hit[CategoryID] = {} + -- self.Players[PlayerName].Kill[CategoryID] = {} + -- end + self.Players[PlayerName].HitPlayers = {} + self.Players[PlayerName].HitUnits = {} self.Players[PlayerName].Score = 0 - self.Players[PlayerName].Penalty = 0 - self.Players[PlayerName].PenaltyCoalition = 0 - self.Players[PlayerName].PenaltyWarning = 0 - end + self.Players[PlayerName].Penalty = 0 + self.Players[PlayerName].PenaltyCoalition = 0 + self.Players[PlayerName].PenaltyWarning = 0 + end - if not self.Players[PlayerName].UnitCoalition then - self.Players[PlayerName].UnitCoalition = UnitCoalition - else - if self.Players[PlayerName].UnitCoalition ~= UnitCoalition then - self.Players[PlayerName].Penalty = self.Players[PlayerName].Penalty + 50 - self.Players[PlayerName].PenaltyCoalition = self.Players[PlayerName].PenaltyCoalition + 1 - MESSAGE:New( "Player '" .. PlayerName .. "' changed coalition from " .. DATABASECoalition[self.Players[PlayerName].UnitCoalition] .. " to " .. DATABASECoalition[UnitCoalition] .. - "(changed " .. self.Players[PlayerName].PenaltyCoalition .. " times the coalition). 50 Penalty points added.", - "", - 2, - "/PENALTYCOALITION" .. PlayerName - ):ToAll() - self:ScoreAdd( PlayerName, "COALITION_PENALTY", 1, -50, self.Players[PlayerName].UnitName, DATABASECoalition[self.Players[PlayerName].UnitCoalition], DATABASECategory[self.Players[PlayerName].UnitCategory], self.Players[PlayerName].UnitType, - UnitName, DATABASECoalition[UnitCoalition], DATABASECategory[UnitCategory], UnitData:getTypeName() ) - end - end - self.Players[PlayerName].UnitName = UnitName - self.Players[PlayerName].UnitCoalition = UnitCoalition - self.Players[PlayerName].UnitCategory = UnitCategory - self.Players[PlayerName].UnitType = UnitTypeName + if not self.Players[PlayerName].UnitCoalition then + self.Players[PlayerName].UnitCoalition = UnitCoalition + else + if self.Players[PlayerName].UnitCoalition ~= UnitCoalition then + self.Players[PlayerName].Penalty = self.Players[PlayerName].Penalty + 50 + self.Players[PlayerName].PenaltyCoalition = self.Players[PlayerName].PenaltyCoalition + 1 + MESSAGE:New( "Player '" .. PlayerName .. "' changed coalition from " .. _DATABASECoalition[self.Players[PlayerName].UnitCoalition] .. " to " .. _DATABASECoalition[UnitCoalition] .. + "(changed " .. self.Players[PlayerName].PenaltyCoalition .. " times the coalition). 50 Penalty points added.", + "", + 2, + "/PENALTYCOALITION" .. PlayerName + ):ToAll() + self:ScoreAdd( PlayerName, "COALITION_PENALTY", 1, -50, self.Players[PlayerName].UnitName, _DATABASECoalition[self.Players[PlayerName].UnitCoalition], _DATABASECategory[self.Players[PlayerName].UnitCategory], self.Players[PlayerName].UnitType, + UnitName, _DATABASECoalition[UnitCoalition], _DATABASECategory[UnitCategory], UnitData:getTypeName() ) + end + end + self.Players[PlayerName].UnitName = UnitName + self.Players[PlayerName].UnitCoalition = UnitCoalition + self.Players[PlayerName].UnitCategory = UnitCategory + self.Players[PlayerName].UnitType = UnitTypeName if self.Players[PlayerName].Penalty > 100 then if self.Players[PlayerName].PenaltyWarning < 1 then - MESSAGE:New( "Player '" .. PlayerName .. "': WARNING! If you continue to commit FRATRICIDE and have a PENALTY score higher than 150, you will be COURT MARTIALED and DISMISSED from this mission! \nYour total penalty is: " .. self.Players[PlayerName].Penalty, - "", - 30, - "/PENALTYCOALITION" .. PlayerName - ):ToAll() + MESSAGE:New( "Player '" .. PlayerName .. "': WARNING! If you continue to commit FRATRICIDE and have a PENALTY score higher than 150, you will be COURT MARTIALED and DISMISSED from this mission! \nYour total penalty is: " .. self.Players[PlayerName].Penalty, + "", + 30, + "/PENALTYCOALITION" .. PlayerName + ):ToAll() self.Players[PlayerName].PenaltyWarning = self.Players[PlayerName].PenaltyWarning + 1 end end - + if self.Players[PlayerName].Penalty > 150 then ClientGroup = GROUP:NewFromDCSUnit( UnitData ) ClientGroup:Destroy() - MESSAGE:New( "Player '" .. PlayerName .. "' committed FRATRICIDE, he will be COURT MARTIALED and is DISMISSED from this mission!", - "", - 10, - "/PENALTYCOALITION" .. PlayerName - ):ToAll() + MESSAGE:New( "Player '" .. PlayerName .. "' committed FRATRICIDE, he will be COURT MARTIALED and is DISMISSED from this mission!", + "", + 10, + "/PENALTYCOALITION" .. PlayerName + ):ToAll() end - - end + + end end --- Registers Scores the players completing a Mission Task. function DATABASE:_AddMissionTaskScore( PlayerUnit, MissionName, Score ) - self:F( { PlayerUnit, MissionName, Score } ) + self:F( { PlayerUnit, MissionName, Score } ) - local PlayerName = PlayerUnit:getPlayerName() - - if not self.Players[PlayerName].Mission[MissionName] then - self.Players[PlayerName].Mission[MissionName] = {} - self.Players[PlayerName].Mission[MissionName].ScoreTask = 0 - self.Players[PlayerName].Mission[MissionName].ScoreMission = 0 - end - - self:T( PlayerName ) - self:T( self.Players[PlayerName].Mission[MissionName] ) + local PlayerName = PlayerUnit:getPlayerName() - self.Players[PlayerName].Score = self.Players[PlayerName].Score + Score - self.Players[PlayerName].Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score + if not self.Players[PlayerName].Mission[MissionName] then + self.Players[PlayerName].Mission[MissionName] = {} + self.Players[PlayerName].Mission[MissionName].ScoreTask = 0 + self.Players[PlayerName].Mission[MissionName].ScoreMission = 0 + end - MESSAGE:New( "Player '" .. PlayerName .. "' has finished another Task in Mission '" .. MissionName .. "'. " .. - Score .. " Score points added.", + self:T( PlayerName ) + self:T( self.Players[PlayerName].Mission[MissionName] ) + + self.Players[PlayerName].Score = self.Players[PlayerName].Score + Score + self.Players[PlayerName].Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score + + MESSAGE:New( "Player '" .. PlayerName .. "' has finished another Task in Mission '" .. MissionName .. "'. " .. + Score .. " Score points added.", "", 20, "/SCORETASK" .. PlayerName ):ToAll() _Database:ScoreAdd( PlayerName, "TASK_" .. MissionName:gsub( ' ', '_' ), 1, Score, PlayerUnit:getName() ) @@ -446,19 +443,19 @@ end --- Registers Mission Scores for possible multiple players that contributed in the Mission. function DATABASE:_AddMissionScore( MissionName, Score ) - self:F( { PlayerUnit, MissionName, Score } ) + self:F( { PlayerUnit, MissionName, Score } ) - for PlayerName, PlayerData in pairs( self.Players ) do - - if PlayerData.Mission[MissionName] then - PlayerData.Score = PlayerData.Score + Score - PlayerData.Mission[MissionName].ScoreMission = PlayerData.Mission[MissionName].ScoreMission + Score - MESSAGE:New( "Player '" .. PlayerName .. "' has finished Mission '" .. MissionName .. "'. " .. - Score .. " Score points added.", - "", 20, "/SCOREMISSION" .. PlayerName ):ToAll() - _Database:ScoreAdd( PlayerName, "MISSION_" .. MissionName:gsub( ' ', '_' ), 1, Score ) - end - end + for PlayerName, PlayerData in pairs( self.Players ) do + + if PlayerData.Mission[MissionName] then + PlayerData.Score = PlayerData.Score + Score + PlayerData.Mission[MissionName].ScoreMission = PlayerData.Mission[MissionName].ScoreMission + Score + MESSAGE:New( "Player '" .. PlayerName .. "' has finished Mission '" .. MissionName .. "'. " .. + Score .. " Score points added.", + "", 20, "/SCOREMISSION" .. PlayerName ):ToAll() + _Database:ScoreAdd( PlayerName, "MISSION_" .. MissionName:gsub( ' ', '_' ), 1, Score ) + end + end end @@ -466,373 +463,367 @@ end -- @section Events -function DATABASE:OnHit( event ) - self:F( { event } ) +--- Handles the OnHit event for the scoring. +-- @param #DATABASE self +-- @param Event#EVENTDATA Event +function DATABASE:_EventOnHit( Event ) + self:F( { Event } ) - local InitUnit = nil - local InitUnitName = "" - local InitGroupName = "" - local InitPlayerName = "dummy" + local InitUnit = nil + local InitUnitName = "" + local InitGroup = nil + local InitGroupName = "" + local InitPlayerName = "dummy" - local InitCoalition = nil - local InitCategory = nil - local InitType = nil - local InitUnitCoalition = nil - local InitUnitCategory = nil - local InitUnitType = nil + local InitCoalition = nil + local InitCategory = nil + local InitType = nil + local InitUnitCoalition = nil + local InitUnitCategory = nil + local InitUnitType = nil - local TargetUnit = nil - local TargetUnitName = "" - local TargetGroupName = "" - local TargetPlayerName = "" + local TargetUnit = nil + local TargetUnitName = "" + local TargetGroup = nil + local TargetGroupName = "" + local TargetPlayerName = "" - local TargetCoalition = nil - local TargetCategory = nil - local TargetType = nil - local TargetUnitCoalition = nil - local TargetUnitCategory = nil - local TargetUnitType = nil + local TargetCoalition = nil + local TargetCategory = nil + local TargetType = nil + local TargetUnitCoalition = nil + local TargetUnitCategory = nil + local TargetUnitType = nil - if event.initiator and event.initiator:getName() then - - if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then - - InitUnit = event.initiator - InitGroup = Unit.getGroup( InitUnit ) - InitUnitDesc = InitUnit:getDesc() - - InitUnitName = InitUnit:getName() - if InitGroup and InitGroup:isExist() then - InitGroupName = InitGroup:getName() - end - InitPlayerName = InitUnit:getPlayerName() - - InitCoalition = InitUnit:getCoalition() - --InitCategory = InitUnit:getCategory() - InitCategory = InitUnitDesc.category -- Workaround - InitType = InitUnit:getTypeName() + if Event.IniDCSUnit then - InitUnitCoalition = DATABASECoalition[InitCoalition] - InitUnitCategory = DATABASECategory[InitCategory] - InitUnitType = InitType - - self:T( { InitUnitName, InitGroupName, InitPlayerName, InitCoalition, InitCategory, InitType , InitUnitCoalition, InitUnitCategory, InitUnitType } ) - self:T( { InitUnitDesc } ) - end + InitUnit = Event.IniDCSUnit + InitUnitName = Event.IniDCSUnitName + InitGroup = Event.IniDCSGroup + InitGroupName = Event.IniDCSGroupName + InitPlayerName = InitUnit:getPlayerName() - - if event.target and Object.getCategory(event.target) == Object.Category.UNIT then - - TargetUnit = event.target - TargetGroup = Unit.getGroup( TargetUnit ) - TargetUnitDesc = TargetUnit:getDesc() - - TargetUnitName = TargetUnit:getName() - if TargetGroup and TargetGroup:isExist() then - TargetGroupName = TargetGroup:getName() - end - TargetPlayerName = TargetUnit:getPlayerName() + InitCoalition = InitUnit:getCoalition() + --TODO: Workaround Client DCS Bug + --InitCategory = InitUnit:getCategory() + InitCategory = InitUnit:getDesc().category + InitType = InitUnit:getTypeName() - TargetCoalition = TargetUnit:getCoalition() - --TargetCategory = TargetUnit:getCategory() - TargetCategory = TargetUnitDesc.category -- Workaround - TargetType = TargetUnit:getTypeName() + InitUnitCoalition = _DATABASECoalition[InitCoalition] + InitUnitCategory = _DATABASECategory[InitCategory] + InitUnitType = InitType - TargetUnitCoalition = DATABASECoalition[TargetCoalition] - TargetUnitCategory = DATABASECategory[TargetCategory] - TargetUnitType = TargetType - - self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType, TargetUnitCoalition, TargetUnitCategory, TargetUnitType } ) - self:T( { TargetUnitDesc } ) - end - - if InitPlayerName ~= nil then -- It is a player that is hitting something - self:_AddPlayerFromUnit( InitUnit ) - if self.Players[InitPlayerName] then -- This should normally not happen, but i'll test it anyway. - if TargetPlayerName ~= nil then -- It is a player hitting another player ... - self:_AddPlayerFromUnit( TargetUnit ) - self.Players[InitPlayerName].HitPlayers = self.Players[InitPlayerName].HitPlayers + 1 - end - - self:T( "Hitting Something" ) - -- What is he hitting? - if TargetCategory then - if not self.Players[InitPlayerName].Hit[TargetCategory] then - self.Players[InitPlayerName].Hit[TargetCategory] = {} - end - if not self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName] then - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName] = {} - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score = 0 - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty = 0 - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit = 0 - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit = 0 - end - local Score = 0 - if InitCoalition == TargetCoalition then - self.Players[InitPlayerName].Penalty = self.Players[InitPlayerName].Penalty + 10 - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty + 10 - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit + 1 - MESSAGE:New( "Player '" .. InitPlayerName .. "' hit a friendly " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit .. " times. Penalty: -" .. self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty .. - ". Score Total:" .. self.Players[InitPlayerName].Score - self.Players[InitPlayerName].Penalty, - "", - 2, - "/PENALTY" .. InitPlayerName .. "/" .. InitUnitName - ):ToAll() - self:ScoreAdd( InitPlayerName, "HIT_PENALTY", 1, -25, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) - else - self.Players[InitPlayerName].Score = self.Players[InitPlayerName].Score + 10 - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score + 1 - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit + 1 - MESSAGE:New( "Player '" .. InitPlayerName .. "' hit a target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. - self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit .. " times. Score: " .. self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score .. - ". Score Total:" .. self.Players[InitPlayerName].Score - self.Players[InitPlayerName].Penalty, - "", - 2, - "/SCORE" .. InitPlayerName .. "/" .. InitUnitName - ):ToAll() - self:ScoreAdd( InitPlayerName, "HIT_SCORE", 1, 1, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) - end - end - end - elseif InitPlayerName == nil then -- It is an AI hitting a player??? - - end - end + self:T( { InitUnitName, InitGroupName, InitPlayerName, InitCoalition, InitCategory, InitType , InitUnitCoalition, InitUnitCategory, InitUnitType } ) + end + + + if Event.TgtDCSUnit then + + TargetUnit = Event.TgtDCSUnit + TargetUnitName = Event.TgtDCSUnitName + TargetGroup = Event.TgtDCSGroup + TargetGroupName = Event.TgtDCSGroupName + TargetPlayerName = TargetUnit:getPlayerName() + + TargetCoalition = TargetUnit:getCoalition() + --TODO: Workaround Client DCS Bug + --TargetCategory = TargetUnit:getCategory() + TargetCategory = TargetUnit:getDesc().category + TargetType = TargetUnit:getTypeName() + + TargetUnitCoalition = _DATABASECoalition[TargetCoalition] + TargetUnitCategory = _DATABASECategory[TargetCategory] + TargetUnitType = TargetType + + self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType, TargetUnitCoalition, TargetUnitCategory, TargetUnitType } ) + end + + if InitPlayerName ~= nil then -- It is a player that is hitting something + self:_AddPlayerFromUnit( InitUnit ) + if self.Players[InitPlayerName] then -- This should normally not happen, but i'll test it anyway. + if TargetPlayerName ~= nil then -- It is a player hitting another player ... + self:_AddPlayerFromUnit( TargetUnit ) + self.Players[InitPlayerName].HitPlayers = self.Players[InitPlayerName].HitPlayers + 1 + end + + self:T( "Hitting Something" ) + -- What is he hitting? + if TargetCategory then + if not self.Players[InitPlayerName].Hit[TargetCategory] then + self.Players[InitPlayerName].Hit[TargetCategory] = {} + end + if not self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName] then + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName] = {} + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score = 0 + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty = 0 + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit = 0 + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit = 0 + end + local Score = 0 + if InitCoalition == TargetCoalition then + self.Players[InitPlayerName].Penalty = self.Players[InitPlayerName].Penalty + 10 + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty + 10 + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit + 1 + MESSAGE:New( "Player '" .. InitPlayerName .. "' hit a friendly " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit .. " times. Penalty: -" .. self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty .. + ". Score Total:" .. self.Players[InitPlayerName].Score - self.Players[InitPlayerName].Penalty, + "", + 2, + "/PENALTY" .. InitPlayerName .. "/" .. InitUnitName + ):ToAll() + self:ScoreAdd( InitPlayerName, "HIT_PENALTY", 1, -25, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) + else + self.Players[InitPlayerName].Score = self.Players[InitPlayerName].Score + 10 + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score + 1 + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit + 1 + MESSAGE:New( "Player '" .. InitPlayerName .. "' hit a target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. + self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].ScoreHit .. " times. Score: " .. self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Score .. + ". Score Total:" .. self.Players[InitPlayerName].Score - self.Players[InitPlayerName].Penalty, + "", + 2, + "/SCORE" .. InitPlayerName .. "/" .. InitUnitName + ):ToAll() + self:ScoreAdd( InitPlayerName, "HIT_SCORE", 1, 1, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) + end + end + end + elseif InitPlayerName == nil then -- It is an AI hitting a player??? + + end end function DATABASE:ReportScoreAll() -env.info( "Hello World " ) + env.info( "Hello World " ) - local ScoreMessage = "" - local PlayerMessage = "" - - self:T( "Score Report" ) + local ScoreMessage = "" + local PlayerMessage = "" - for PlayerName, PlayerData in pairs( self.Players ) do - if PlayerData then -- This should normally not happen, but i'll test it anyway. - self:T( "Score Player: " .. PlayerName ) + self:T( "Score Report" ) - -- Some variables - local InitUnitCoalition = DATABASECoalition[PlayerData.UnitCoalition] - local InitUnitCategory = DATABASECategory[PlayerData.UnitCategory] - local InitUnitType = PlayerData.UnitType - local InitUnitName = PlayerData.UnitName - - local PlayerScore = 0 - local PlayerPenalty = 0 - - ScoreMessage = ":\n" - - local ScoreMessageHits = "" + for PlayerName, PlayerData in pairs( self.Players ) do + if PlayerData then -- This should normally not happen, but i'll test it anyway. + self:T( "Score Player: " .. PlayerName ) - for CategoryID, CategoryName in pairs( DATABASECategory ) do - self:T( CategoryName ) - if PlayerData.Hit[CategoryID] then - local Score = 0 - local ScoreHit = 0 - local Penalty = 0 - local PenaltyHit = 0 - self:T( "Hit scores exist for player " .. PlayerName ) - for UnitName, UnitData in pairs( PlayerData.Hit[CategoryID] ) do - Score = Score + UnitData.Score - ScoreHit = ScoreHit + UnitData.ScoreHit - Penalty = Penalty + UnitData.Penalty - PenaltyHit = UnitData.PenaltyHit - end - local ScoreMessageHit = string.format( "%s:%d ", CategoryName, Score - Penalty ) - self:T( ScoreMessageHit ) - ScoreMessageHits = ScoreMessageHits .. ScoreMessageHit - PlayerScore = PlayerScore + Score - PlayerPenalty = PlayerPenalty + Penalty - else - --ScoreMessageHits = ScoreMessageHits .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 ) - end - end - if ScoreMessageHits ~= "" then - ScoreMessage = ScoreMessage .. " Hits: " .. ScoreMessageHits .. "\n" - end - - local ScoreMessageKills = "" - for CategoryID, CategoryName in pairs( DATABASECategory ) do - self:T( "Kill scores exist for player " .. PlayerName ) - if PlayerData.Kill[CategoryID] then - local Score = 0 - local ScoreKill = 0 - local Penalty = 0 - local PenaltyKill = 0 - - for UnitName, UnitData in pairs( PlayerData.Kill[CategoryID] ) do - Score = Score + UnitData.Score - ScoreKill = ScoreKill + UnitData.ScoreKill - Penalty = Penalty + UnitData.Penalty - PenaltyKill = PenaltyKill + UnitData.PenaltyKill - end - - local ScoreMessageKill = string.format( " %s:%d ", CategoryName, Score - Penalty ) - self:T( ScoreMessageKill ) - ScoreMessageKills = ScoreMessageKills .. ScoreMessageKill + -- Some variables + local InitUnitCoalition = _DATABASECoalition[PlayerData.UnitCoalition] + local InitUnitCategory = _DATABASECategory[PlayerData.UnitCategory] + local InitUnitType = PlayerData.UnitType + local InitUnitName = PlayerData.UnitName - PlayerScore = PlayerScore + Score - PlayerPenalty = PlayerPenalty + Penalty - else - --ScoreMessageKills = ScoreMessageKills .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 ) - end - end - if ScoreMessageKills ~= "" then - ScoreMessage = ScoreMessage .. " Kills: " .. ScoreMessageKills .. "\n" - end - - local ScoreMessageCoalitionChangePenalties = "" - if PlayerData.PenaltyCoalition ~= 0 then - ScoreMessageCoalitionChangePenalties = ScoreMessageCoalitionChangePenalties .. string.format( " -%d (%d changed)", PlayerData.Penalty, PlayerData.PenaltyCoalition ) - PlayerPenalty = PlayerPenalty + PlayerData.Penalty - end - if ScoreMessageCoalitionChangePenalties ~= "" then - ScoreMessage = ScoreMessage .. " Coalition Penalties: " .. ScoreMessageCoalitionChangePenalties .. "\n" - end + local PlayerScore = 0 + local PlayerPenalty = 0 - local ScoreMessageMission = "" - local ScoreMission = 0 - local ScoreTask = 0 - for MissionName, MissionData in pairs( PlayerData.Mission ) do - ScoreMission = ScoreMission + MissionData.ScoreMission - ScoreTask = ScoreTask + MissionData.ScoreTask - ScoreMessageMission = ScoreMessageMission .. "'" .. MissionName .. "'; " - end - PlayerScore = PlayerScore + ScoreMission + ScoreTask + ScoreMessage = ":\n" - if ScoreMessageMission ~= "" then - ScoreMessage = ScoreMessage .. " Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ")\n" - end - - PlayerMessage = PlayerMessage .. string.format( "Player '%s' Score:%d (%d Score -%d Penalties)%s", PlayerName, PlayerScore - PlayerPenalty, PlayerScore, PlayerPenalty, ScoreMessage ) - end - end - MESSAGE:New( PlayerMessage, "Player Scores", 30, "AllPlayerScores"):ToAll() + local ScoreMessageHits = "" + + for CategoryID, CategoryName in pairs( _DATABASECategory ) do + self:T( CategoryName ) + if PlayerData.Hit[CategoryID] then + local Score = 0 + local ScoreHit = 0 + local Penalty = 0 + local PenaltyHit = 0 + self:T( "Hit scores exist for player " .. PlayerName ) + for UnitName, UnitData in pairs( PlayerData.Hit[CategoryID] ) do + Score = Score + UnitData.Score + ScoreHit = ScoreHit + UnitData.ScoreHit + Penalty = Penalty + UnitData.Penalty + PenaltyHit = UnitData.PenaltyHit + end + local ScoreMessageHit = string.format( "%s:%d ", CategoryName, Score - Penalty ) + self:T( ScoreMessageHit ) + ScoreMessageHits = ScoreMessageHits .. ScoreMessageHit + PlayerScore = PlayerScore + Score + PlayerPenalty = PlayerPenalty + Penalty + else + --ScoreMessageHits = ScoreMessageHits .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 ) + end + end + if ScoreMessageHits ~= "" then + ScoreMessage = ScoreMessage .. " Hits: " .. ScoreMessageHits .. "\n" + end + + local ScoreMessageKills = "" + for CategoryID, CategoryName in pairs( _DATABASECategory ) do + self:T( "Kill scores exist for player " .. PlayerName ) + if PlayerData.Kill[CategoryID] then + local Score = 0 + local ScoreKill = 0 + local Penalty = 0 + local PenaltyKill = 0 + + for UnitName, UnitData in pairs( PlayerData.Kill[CategoryID] ) do + Score = Score + UnitData.Score + ScoreKill = ScoreKill + UnitData.ScoreKill + Penalty = Penalty + UnitData.Penalty + PenaltyKill = PenaltyKill + UnitData.PenaltyKill + end + + local ScoreMessageKill = string.format( " %s:%d ", CategoryName, Score - Penalty ) + self:T( ScoreMessageKill ) + ScoreMessageKills = ScoreMessageKills .. ScoreMessageKill + + PlayerScore = PlayerScore + Score + PlayerPenalty = PlayerPenalty + Penalty + else + --ScoreMessageKills = ScoreMessageKills .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 ) + end + end + if ScoreMessageKills ~= "" then + ScoreMessage = ScoreMessage .. " Kills: " .. ScoreMessageKills .. "\n" + end + + local ScoreMessageCoalitionChangePenalties = "" + if PlayerData.PenaltyCoalition ~= 0 then + ScoreMessageCoalitionChangePenalties = ScoreMessageCoalitionChangePenalties .. string.format( " -%d (%d changed)", PlayerData.Penalty, PlayerData.PenaltyCoalition ) + PlayerPenalty = PlayerPenalty + PlayerData.Penalty + end + if ScoreMessageCoalitionChangePenalties ~= "" then + ScoreMessage = ScoreMessage .. " Coalition Penalties: " .. ScoreMessageCoalitionChangePenalties .. "\n" + end + + local ScoreMessageMission = "" + local ScoreMission = 0 + local ScoreTask = 0 + for MissionName, MissionData in pairs( PlayerData.Mission ) do + ScoreMission = ScoreMission + MissionData.ScoreMission + ScoreTask = ScoreTask + MissionData.ScoreTask + ScoreMessageMission = ScoreMessageMission .. "'" .. MissionName .. "'; " + end + PlayerScore = PlayerScore + ScoreMission + ScoreTask + + if ScoreMessageMission ~= "" then + ScoreMessage = ScoreMessage .. " Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ")\n" + end + + PlayerMessage = PlayerMessage .. string.format( "Player '%s' Score:%d (%d Score -%d Penalties)%s", PlayerName, PlayerScore - PlayerPenalty, PlayerScore, PlayerPenalty, ScoreMessage ) + end + end + MESSAGE:New( PlayerMessage, "Player Scores", 30, "AllPlayerScores"):ToAll() end function DATABASE:ReportScorePlayer() -env.info( "Hello World " ) + env.info( "Hello World " ) - local ScoreMessage = "" - local PlayerMessage = "" - - self:T( "Score Report" ) + local ScoreMessage = "" + local PlayerMessage = "" - for PlayerName, PlayerData in pairs( self.Players ) do - if PlayerData then -- This should normally not happen, but i'll test it anyway. - self:T( "Score Player: " .. PlayerName ) + self:T( "Score Report" ) - -- Some variables - local InitUnitCoalition = DATABASECoalition[PlayerData.UnitCoalition] - local InitUnitCategory = DATABASECategory[PlayerData.UnitCategory] - local InitUnitType = PlayerData.UnitType - local InitUnitName = PlayerData.UnitName - - local PlayerScore = 0 - local PlayerPenalty = 0 - - ScoreMessage = "" - - local ScoreMessageHits = "" + for PlayerName, PlayerData in pairs( self.Players ) do + if PlayerData then -- This should normally not happen, but i'll test it anyway. + self:T( "Score Player: " .. PlayerName ) - for CategoryID, CategoryName in pairs( DATABASECategory ) do - self:T( CategoryName ) - if PlayerData.Hit[CategoryID] then - local Score = 0 - local ScoreHit = 0 - local Penalty = 0 - local PenaltyHit = 0 - self:T( "Hit scores exist for player " .. PlayerName ) - for UnitName, UnitData in pairs( PlayerData.Hit[CategoryID] ) do - Score = Score + UnitData.Score - ScoreHit = ScoreHit + UnitData.ScoreHit - Penalty = Penalty + UnitData.Penalty - PenaltyHit = UnitData.PenaltyHit - end - local ScoreMessageHit = string.format( "\n %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreHit, PenaltyHit ) - self:T( ScoreMessageHit ) - ScoreMessageHits = ScoreMessageHits .. ScoreMessageHit - PlayerScore = PlayerScore + Score - PlayerPenalty = PlayerPenalty + Penalty - else - --ScoreMessageHits = ScoreMessageHits .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 ) - end - end - if ScoreMessageHits ~= "" then - ScoreMessage = ScoreMessage .. "\n Hits: " .. ScoreMessageHits .. " " - end - - local ScoreMessageKills = "" - for CategoryID, CategoryName in pairs( DATABASECategory ) do - self:T( "Kill scores exist for player " .. PlayerName ) - if PlayerData.Kill[CategoryID] then - local Score = 0 - local ScoreKill = 0 - local Penalty = 0 - local PenaltyKill = 0 - - for UnitName, UnitData in pairs( PlayerData.Kill[CategoryID] ) do - Score = Score + UnitData.Score - ScoreKill = ScoreKill + UnitData.ScoreKill - Penalty = Penalty + UnitData.Penalty - PenaltyKill = PenaltyKill + UnitData.PenaltyKill - end - - local ScoreMessageKill = string.format( "\n %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreKill, PenaltyKill ) - self:T( ScoreMessageKill ) - ScoreMessageKills = ScoreMessageKills .. ScoreMessageKill + -- Some variables + local InitUnitCoalition = _DATABASECoalition[PlayerData.UnitCoalition] + local InitUnitCategory = _DATABASECategory[PlayerData.UnitCategory] + local InitUnitType = PlayerData.UnitType + local InitUnitName = PlayerData.UnitName - PlayerScore = PlayerScore + Score - PlayerPenalty = PlayerPenalty + Penalty - else - --ScoreMessageKills = ScoreMessageKills .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 ) - end - end - if ScoreMessageKills ~= "" then - ScoreMessage = ScoreMessage .. "\n Kills: " .. ScoreMessageKills .. " " - end - - local ScoreMessageCoalitionChangePenalties = "" - if PlayerData.PenaltyCoalition ~= 0 then - ScoreMessageCoalitionChangePenalties = ScoreMessageCoalitionChangePenalties .. string.format( " -%d (%d changed)", PlayerData.Penalty, PlayerData.PenaltyCoalition ) - PlayerPenalty = PlayerPenalty + PlayerData.Penalty - end - if ScoreMessageCoalitionChangePenalties ~= "" then - ScoreMessage = ScoreMessage .. "\n Coalition: " .. ScoreMessageCoalitionChangePenalties .. " " - end + local PlayerScore = 0 + local PlayerPenalty = 0 - local ScoreMessageMission = "" - local ScoreMission = 0 - local ScoreTask = 0 - for MissionName, MissionData in pairs( PlayerData.Mission ) do - ScoreMission = ScoreMission + MissionData.ScoreMission - ScoreTask = ScoreTask + MissionData.ScoreTask - ScoreMessageMission = ScoreMessageMission .. "'" .. MissionName .. "'; " - end - PlayerScore = PlayerScore + ScoreMission + ScoreTask + ScoreMessage = "" - if ScoreMessageMission ~= "" then - ScoreMessage = ScoreMessage .. "\n Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ") " - end - - PlayerMessage = PlayerMessage .. string.format( "Player '%s' Score = %d ( %d Score, -%d Penalties ):%s", PlayerName, PlayerScore - PlayerPenalty, PlayerScore, PlayerPenalty, ScoreMessage ) - end - end - MESSAGE:New( PlayerMessage, "Player Scores", 30, "AllPlayerScores"):ToAll() + local ScoreMessageHits = "" + + for CategoryID, CategoryName in pairs( _DATABASECategory ) do + self:T( CategoryName ) + if PlayerData.Hit[CategoryID] then + local Score = 0 + local ScoreHit = 0 + local Penalty = 0 + local PenaltyHit = 0 + self:T( "Hit scores exist for player " .. PlayerName ) + for UnitName, UnitData in pairs( PlayerData.Hit[CategoryID] ) do + Score = Score + UnitData.Score + ScoreHit = ScoreHit + UnitData.ScoreHit + Penalty = Penalty + UnitData.Penalty + PenaltyHit = UnitData.PenaltyHit + end + local ScoreMessageHit = string.format( "\n %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreHit, PenaltyHit ) + self:T( ScoreMessageHit ) + ScoreMessageHits = ScoreMessageHits .. ScoreMessageHit + PlayerScore = PlayerScore + Score + PlayerPenalty = PlayerPenalty + Penalty + else + --ScoreMessageHits = ScoreMessageHits .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 ) + end + end + if ScoreMessageHits ~= "" then + ScoreMessage = ScoreMessage .. "\n Hits: " .. ScoreMessageHits .. " " + end + + local ScoreMessageKills = "" + for CategoryID, CategoryName in pairs( _DATABASECategory ) do + self:T( "Kill scores exist for player " .. PlayerName ) + if PlayerData.Kill[CategoryID] then + local Score = 0 + local ScoreKill = 0 + local Penalty = 0 + local PenaltyKill = 0 + + for UnitName, UnitData in pairs( PlayerData.Kill[CategoryID] ) do + Score = Score + UnitData.Score + ScoreKill = ScoreKill + UnitData.ScoreKill + Penalty = Penalty + UnitData.Penalty + PenaltyKill = PenaltyKill + UnitData.PenaltyKill + end + + local ScoreMessageKill = string.format( "\n %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreKill, PenaltyKill ) + self:T( ScoreMessageKill ) + ScoreMessageKills = ScoreMessageKills .. ScoreMessageKill + + PlayerScore = PlayerScore + Score + PlayerPenalty = PlayerPenalty + Penalty + else + --ScoreMessageKills = ScoreMessageKills .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 ) + end + end + if ScoreMessageKills ~= "" then + ScoreMessage = ScoreMessage .. "\n Kills: " .. ScoreMessageKills .. " " + end + + local ScoreMessageCoalitionChangePenalties = "" + if PlayerData.PenaltyCoalition ~= 0 then + ScoreMessageCoalitionChangePenalties = ScoreMessageCoalitionChangePenalties .. string.format( " -%d (%d changed)", PlayerData.Penalty, PlayerData.PenaltyCoalition ) + PlayerPenalty = PlayerPenalty + PlayerData.Penalty + end + if ScoreMessageCoalitionChangePenalties ~= "" then + ScoreMessage = ScoreMessage .. "\n Coalition: " .. ScoreMessageCoalitionChangePenalties .. " " + end + + local ScoreMessageMission = "" + local ScoreMission = 0 + local ScoreTask = 0 + for MissionName, MissionData in pairs( PlayerData.Mission ) do + ScoreMission = ScoreMission + MissionData.ScoreMission + ScoreTask = ScoreTask + MissionData.ScoreTask + ScoreMessageMission = ScoreMessageMission .. "'" .. MissionName .. "'; " + end + PlayerScore = PlayerScore + ScoreMission + ScoreTask + + if ScoreMessageMission ~= "" then + ScoreMessage = ScoreMessage .. "\n Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ") " + end + + PlayerMessage = PlayerMessage .. string.format( "Player '%s' Score = %d ( %d Score, -%d Penalties ):%s", PlayerName, PlayerScore - PlayerPenalty, PlayerScore, PlayerPenalty, ScoreMessage ) + end + end + MESSAGE:New( PlayerMessage, "Player Scores", 30, "AllPlayerScores"):ToAll() end function DATABASE:ScoreMenu() - local ReportScore = SUBMENU:New( 'Scoring' ) - local ReportAllScores = COMMANDMENU:New( 'Score All Active Players', ReportScore, DATABASE.ReportScoreAll, self ) - local ReportPlayerScores = COMMANDMENU:New('Your Current Score', ReportScore, DATABASE.ReportScorePlayer, self ) + local ReportScore = SUBMENU:New( 'Scoring' ) + local ReportAllScores = COMMANDMENU:New( 'Score All Active Players', ReportScore, DATABASE.ReportScoreAll, self ) + local ReportPlayerScores = COMMANDMENU:New('Your Current Score', ReportScore, DATABASE.ReportScorePlayer, self ) end @@ -841,112 +832,113 @@ end -- File Logic for tracking the scores function DATABASE:SecondsToClock(sSeconds) -local nSeconds = sSeconds - if nSeconds == 0 then - --return nil; - return "00:00:00"; - else - nHours = string.format("%02.f", math.floor(nSeconds/3600)); - nMins = string.format("%02.f", math.floor(nSeconds/60 - (nHours*60))); - nSecs = string.format("%02.f", math.floor(nSeconds - nHours*3600 - nMins *60)); - return nHours..":"..nMins..":"..nSecs - end + local nSeconds = sSeconds + if nSeconds == 0 then + --return nil; + return "00:00:00"; + else + nHours = string.format("%02.f", math.floor(nSeconds/3600)); + nMins = string.format("%02.f", math.floor(nSeconds/60 - (nHours*60))); + nSecs = string.format("%02.f", math.floor(nSeconds - nHours*3600 - nMins *60)); + return nHours..":"..nMins..":"..nSecs + end end function DATABASE:ScoreOpen() - if lfs then - local fdir = lfs.writedir() .. [[Logs\]] .. "Player_Scores_" .. os.date( "%Y-%m-%d_%H-%M-%S" ) .. ".csv" - self.StatFile, self.err = io.open(fdir,"w+") - if not self.StatFile then - error( "Error: Cannot open 'Player Scores.csv' file in " .. lfs.writedir() ) - end - self.StatFile:write( '"RunID","Time","PlayerName","ScoreType","PlayerUnitCoaltion","PlayerUnitCategory","PlayerUnitType","PlayerUnitName","TargetUnitCoalition","TargetUnitCategory","TargetUnitType","TargetUnitName","Times","Score"\n' ) - - self.RunID = os.date("%y-%m-%d_%H-%M-%S") - end + if lfs then + local fdir = lfs.writedir() .. [[Logs\]] .. "Player_Scores_" .. os.date( "%Y-%m-%d_%H-%M-%S" ) .. ".csv" + self.StatFile, self.err = io.open(fdir,"w+") + if not self.StatFile then + error( "Error: Cannot open 'Player Scores.csv' file in " .. lfs.writedir() ) + end + self.StatFile:write( '"RunID","Time","PlayerName","ScoreType","PlayerUnitCoaltion","PlayerUnitCategory","PlayerUnitType","PlayerUnitName","TargetUnitCoalition","TargetUnitCategory","TargetUnitType","TargetUnitName","Times","Score"\n' ) + + self.RunID = os.date("%y-%m-%d_%H-%M-%S") + end end function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, PlayerUnitName, PlayerUnitCoalition, PlayerUnitCategory, PlayerUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) - --write statistic information to file - local ScoreTime = self:SecondsToClock(timer.getTime()) - PlayerName = PlayerName:gsub( '"', '_' ) + --write statistic information to file + local ScoreTime = self:SecondsToClock(timer.getTime()) + PlayerName = PlayerName:gsub( '"', '_' ) - if PlayerUnitName and PlayerUnitName ~= '' then - local PlayerUnit = Unit.getByName( PlayerUnitName ) - - if PlayerUnit then - if not PlayerUnitCategory then - --PlayerUnitCategory = DATABASECategory[PlayerUnit:getCategory()] - PlayerUnitCategory = DATABASECategory[PlayerUnit:getDesc().category] - end - - if not PlayerUnitCoalition then - PlayerUnitCoalition = DATABASECoalition[PlayerUnit:getCoalition()] - end - - if not PlayerUnitType then - PlayerUnitType = PlayerUnit:getTypeName() - end - else - PlayerUnitName = '' - PlayerUnitCategory = '' - PlayerUnitCoalition = '' - PlayerUnitType = '' - end - else - PlayerUnitName = '' - PlayerUnitCategory = '' - PlayerUnitCoalition = '' - PlayerUnitType = '' - end - - if not TargetUnitCoalition then - TargetUnitCoalition = '' - end - - if not TargetUnitCategory then - TargetUnitCategory = '' - end - - if not TargetUnitType then - TargetUnitType = '' - end - - if not TargetUnitName then - TargetUnitName = '' - end + if PlayerUnitName and PlayerUnitName ~= '' then + local PlayerUnit = Unit.getByName( PlayerUnitName ) - if lfs then - self.StatFile:write( - '"' .. self.RunID .. '"' .. ',' .. - '' .. ScoreTime .. '' .. ',' .. - '"' .. PlayerName .. '"' .. ',' .. - '"' .. ScoreType .. '"' .. ',' .. - '"' .. PlayerUnitCoalition .. '"' .. ',' .. - '"' .. PlayerUnitCategory .. '"' .. ',' .. - '"' .. PlayerUnitType .. '"' .. ',' .. - '"' .. PlayerUnitName .. '"' .. ',' .. - '"' .. TargetUnitCoalition .. '"' .. ',' .. - '"' .. TargetUnitCategory .. '"' .. ',' .. - '"' .. TargetUnitType .. '"' .. ',' .. - '"' .. TargetUnitName .. '"' .. ',' .. - '' .. ScoreTimes .. '' .. ',' .. - '' .. ScoreAmount - ) - - self.StatFile:write( "\n" ) - end + if PlayerUnit then + if not PlayerUnitCategory then + --PlayerUnitCategory = DATABASECategory[PlayerUnit:getCategory()] + PlayerUnitCategory = _DATABASECategory[PlayerUnit:getDesc().category] + end + + if not PlayerUnitCoalition then + PlayerUnitCoalition = _DATABASECoalition[PlayerUnit:getCoalition()] + end + + if not PlayerUnitType then + PlayerUnitType = PlayerUnit:getTypeName() + end + else + PlayerUnitName = '' + PlayerUnitCategory = '' + PlayerUnitCoalition = '' + PlayerUnitType = '' + end + else + PlayerUnitName = '' + PlayerUnitCategory = '' + PlayerUnitCoalition = '' + PlayerUnitType = '' + end + + if not TargetUnitCoalition then + TargetUnitCoalition = '' + end + + if not TargetUnitCategory then + TargetUnitCategory = '' + end + + if not TargetUnitType then + TargetUnitType = '' + end + + if not TargetUnitName then + TargetUnitName = '' + end + + if lfs then + self.StatFile:write( + '"' .. self.RunID .. '"' .. ',' .. + '' .. ScoreTime .. '' .. ',' .. + '"' .. PlayerName .. '"' .. ',' .. + '"' .. ScoreType .. '"' .. ',' .. + '"' .. PlayerUnitCoalition .. '"' .. ',' .. + '"' .. PlayerUnitCategory .. '"' .. ',' .. + '"' .. PlayerUnitType .. '"' .. ',' .. + '"' .. PlayerUnitName .. '"' .. ',' .. + '"' .. TargetUnitCoalition .. '"' .. ',' .. + '"' .. TargetUnitCategory .. '"' .. ',' .. + '"' .. TargetUnitType .. '"' .. ',' .. + '"' .. TargetUnitName .. '"' .. ',' .. + '' .. ScoreTimes .. '' .. ',' .. + '' .. ScoreAmount + ) + + self.StatFile:write( "\n" ) + end end - + function LogClose() - if lfs then - self.StatFile:close() - end + if lfs then + self.StatFile:close() + end end _Database = DATABASE:New() -- Database#DATABASE _Database:ScoreOpen() + diff --git a/Moose/Event.lua b/Moose/Event.lua index 6ad91e3cf..a3501b44c 100644 --- a/Moose/Event.lua +++ b/Moose/Event.lua @@ -13,7 +13,7 @@ EVENT = { ClassID = 0, } -local EVENTCODES = { +local _EVENTCODES = { "S_EVENT_SHOT", "S_EVENT_HIT", "S_EVENT_TAKEOFF", @@ -69,6 +69,13 @@ function EVENT:New() return self end +function EVENT:EventText( EventID ) + + local EventText = _EVENTCODES[EventID] + + return EventText +end + --- Initializes the Events structure for the event -- @param #EVENT self @@ -76,16 +83,13 @@ end -- @param #string EventClass -- @return #EVENT.Events function EVENT:Init( EventID, EventClass ) - self:F( { EventID, EventClass } ) + self:F3( { _EVENTCODES[EventID], EventClass } ) if not self.Events[EventID] then self.Events[EventID] = {} end if not self.Events[EventID][EventClass] then self.Events[EventID][EventClass] = {} end - if not self.Events[EventID][EventClass].IniUnit then - self.Events[EventID][EventClass].IniUnit = {} - end return self.Events[EventID][EventClass] end @@ -98,7 +102,7 @@ end -- @param #function OnEventFunction -- @return #EVENT function EVENT:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, OnEventFunction ) - self:F( EventTemplate ) + self:F2( EventTemplate.name ) for EventUnitID, EventUnit in pairs( EventTemplate.units ) do OnEventFunction( self, EventUnit.name, EventFunction, EventSelf ) @@ -113,7 +117,7 @@ end -- @param EventID -- @return #EVENT function EVENT:OnEventGeneric( EventFunction, EventSelf, EventID ) - self:F( { EventID } ) + self:F2( { EventID } ) local Event = self:Init( EventID, EventSelf:GetClassNameAndID() ) Event.EventFunction = EventFunction @@ -130,9 +134,12 @@ end -- @param EventID -- @return #EVENT function EVENT:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, EventID ) - self:F( EventDCSUnitName ) + self:F2( EventDCSUnitName ) local Event = self:Init( EventID, EventSelf:GetClassNameAndID() ) + if not Event.IniUnit then + Event.IniUnit = {} + end Event.IniUnit[EventDCSUnitName] = {} Event.IniUnit[EventDCSUnitName].EventFunction = EventFunction Event.IniUnit[EventDCSUnitName].EventSelf = EventSelf @@ -147,9 +154,11 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnBirthForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( { EventTemplate } ) + self:F( EventTemplate.name ) - return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnBirthForUnit ) + self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnBirthForUnit ) + + return self end --- Set a new listener for an S_EVENT_BIRTH event, and registers the unit born. @@ -160,7 +169,9 @@ end function EVENT:OnBirth( EventFunction, EventSelf ) self:F() - return self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_BIRTH ) + self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_BIRTH ) + + return self end --- Set a new listener for an S_EVENT_BIRTH event. @@ -172,7 +183,9 @@ end function EVENT:OnBirthForUnit( EventDCSUnitName, EventFunction, EventSelf ) self:F( EventDCSUnitName ) - return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_BIRTH ) + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_BIRTH ) + + return self end --- Create an OnCrash event handler for a group @@ -182,9 +195,11 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnCrashForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate ) + self:F( EventTemplate.name ) - return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnCrashForUnit ) + self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnCrashForUnit ) + + return self end --- Set a new listener for an S_EVENT_CRASH event. @@ -195,7 +210,9 @@ end function EVENT:OnCrash( EventFunction, EventSelf ) self:F() - return self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_CRASH ) + self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_CRASH ) + + return self end --- Set a new listener for an S_EVENT_CRASH event. @@ -206,8 +223,10 @@ end -- @return #EVENT function EVENT:OnCrashForUnit( EventDCSUnitName, EventFunction, EventSelf ) self:F( EventDCSUnitName ) + + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_CRASH ) - return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_CRASH ) + return self end --- Create an OnDead event handler for a group @@ -217,9 +236,11 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnDeadForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate ) + self:F( EventTemplate.name ) + + self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnDeadForUnit ) - return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnDeadForUnit ) + return self end --- Set a new listener for an S_EVENT_DEAD event. @@ -230,7 +251,9 @@ end function EVENT:OnDead( EventFunction, EventSelf ) self:F() - return self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_DEAD ) + self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_DEAD ) + + return self end @@ -243,7 +266,23 @@ end function EVENT:OnDeadForUnit( EventDCSUnitName, EventFunction, EventSelf ) self:F( EventDCSUnitName ) - return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_DEAD ) + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_DEAD ) + + return self +end + +--- Set a new listener for an S_EVENT_PILOT_DEAD event. +-- @param #EVENT self +-- @param #string EventDCSUnitName +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnPilotDeadForUnit( EventDCSUnitName, EventFunction, EventSelf ) + self:F( EventDCSUnitName ) + + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_PILOT_DEAD ) + + return self end --- Create an OnDead event handler for a group @@ -253,9 +292,11 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnLandForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate ) + self:F( EventTemplate.name ) - return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnLandForUnit ) + self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnLandForUnit ) + + return self end --- Set a new listener for an S_EVENT_LAND event. @@ -267,7 +308,9 @@ end function EVENT:OnLandForUnit( EventDCSUnitName, EventFunction, EventSelf ) self:F( EventDCSUnitName ) - return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_LAND ) + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_LAND ) + + return self end --- Create an OnDead event handler for a group @@ -277,9 +320,11 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnTakeOffForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate ) + self:F( EventTemplate.name ) - return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnTakeOffForUnit ) + self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnTakeOffForUnit ) + + return self end --- Set a new listener for an S_EVENT_TAKEOFF event. @@ -291,7 +336,9 @@ end function EVENT:OnTakeOffForUnit( EventDCSUnitName, EventFunction, EventSelf ) self:F( EventDCSUnitName ) - return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_TAKEOFF ) + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_TAKEOFF ) + + return self end --- Create an OnDead event handler for a group @@ -301,9 +348,11 @@ end -- @param EventSelf The self instance of the class for which the event is. -- @return #EVENT function EVENT:OnEngineShutDownForTemplate( EventTemplate, EventFunction, EventSelf ) - self:F( EventTemplate ) + self:F( EventTemplate.name ) - return self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnEngineShutDownForUnit ) + self:OnEventForTemplate( EventTemplate, EventFunction, EventSelf, self.OnEngineShutDownForUnit ) + + return self end --- Set a new listener for an S_EVENT_ENGINE_SHUTDOWN event. @@ -315,7 +364,9 @@ end function EVENT:OnEngineShutDownForUnit( EventDCSUnitName, EventFunction, EventSelf ) self:F( EventDCSUnitName ) - return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_ENGINE_SHUTDOWN ) + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_ENGINE_SHUTDOWN ) + + return self end --- Set a new listener for an S_EVENT_ENGINE_STARTUP event. @@ -327,7 +378,9 @@ end function EVENT:OnEngineStartUpForUnit( EventDCSUnitName, EventFunction, EventSelf ) self:F( EventDCSUnitName ) - return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_ENGINE_STARTUP ) + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_ENGINE_STARTUP ) + + return self end --- Set a new listener for an S_EVENT_SHOT event. @@ -338,7 +391,9 @@ end function EVENT:OnShot( EventFunction, EventSelf ) self:F() - return self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_SHOT ) + self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_SHOT ) + + return self end --- Set a new listener for an S_EVENT_SHOT event for a unit. @@ -350,7 +405,9 @@ end function EVENT:OnShotForUnit( EventDCSUnitName, EventFunction, EventSelf ) self:F( EventDCSUnitName ) - return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_SHOT ) + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_SHOT ) + + return self end --- Set a new listener for an S_EVENT_HIT event. @@ -361,7 +418,9 @@ end function EVENT:OnHit( EventFunction, EventSelf ) self:F() - return self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_HIT ) + self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_HIT ) + + return self end --- Set a new listener for an S_EVENT_HIT event. @@ -373,13 +432,15 @@ end function EVENT:OnHitForUnit( EventDCSUnitName, EventFunction, EventSelf ) self:F( EventDCSUnitName ) - return self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_HIT ) + self:OnEventForUnit( EventDCSUnitName, EventFunction, EventSelf, world.event.S_EVENT_HIT ) + + return self end function EVENT:onEvent( Event ) - self:F( { EVENTCODES[Event.id], Event } ) + self:F( { _EVENTCODES[Event.id], Event } ) if self and self.Events and self.Events[Event.id] then if Event.initiator and Event.initiator:getCategory() == Object.Category.UNIT then @@ -405,15 +466,15 @@ function EVENT:onEvent( Event ) if Event.weapon then Event.Weapon = Event.weapon Event.WeaponName = Event.Weapon:getTypeName() - Event.WeaponTgtDCSUnit = Event.Weapon:getTarget() + --Event.WeaponTgtDCSUnit = Event.Weapon:getTarget() end for ClassName, EventData in pairs( self.Events[Event.id] ) do if Event.IniDCSUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniDCSUnitName] then - self:T( { "Calling event function for class ", ClassName, " unit ", Event.IniDCSUnitName } ) + self:T2( { "Calling event function for class ", ClassName, " unit ", Event.IniDCSUnitName } ) EventData.IniUnit[Event.IniDCSUnitName].EventFunction( EventData.IniUnit[Event.IniDCSUnitName].EventSelf, Event ) else if Event.IniDCSUnit and not EventData.IniUnit then - self:T( { "Calling event function for class ", ClassName } ) + self:T2( { "Calling event function for class ", ClassName } ) EventData.EventFunction( EventData.EventSelf, Event ) end end diff --git a/Moose/Sead.lua b/Moose/Sead.lua index 2bbfd31b8..8c1ddbc6b 100644 --- a/Moose/Sead.lua +++ b/Moose/Sead.lua @@ -62,7 +62,7 @@ function SEAD:EventShot( Event ) self:T( "Missile Launched = " .. SEADWeaponName ) if SEADWeaponName == "KH-58" or SEADWeaponName == "KH-25MPU" or SEADWeaponName == "AGM-88" or SEADWeaponName == "KH-31A" or SEADWeaponName == "KH-31P" then -- Check if the missile is a SEAD local _evade = math.random (1,100) -- random number for chance of evading action - local _targetMim = Event.WeaponTgtDCSUnit -- Identify target + local _targetMim = Event.Weapon:getTarget() -- Identify target local _targetMimname = Unit.getName(_targetMim) local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon)) local _targetMimgroupName = _targetMimgroup:getName() diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index f6659d7e1..9ad27e90e 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -471,7 +471,7 @@ function SPAWN:SpawnWithIndex( SpawnIndex ) self.SpawnGroups[self.SpawnIndex].Spawned = true return self.SpawnGroups[self.SpawnIndex].Group else - self:E( { self.SpawnTemplatePrefix, "No more Groups to Spawn:", SpawnIndex, self.SpawnMaxGroups } ) + --self:E( { self.SpawnTemplatePrefix, "No more Groups to Spawn:", SpawnIndex, self.SpawnMaxGroups } ) end return nil diff --git a/Test Missions/Moose_Test_CLEANUP/Moose_Test_CLEANUP.lua b/Test Missions/Moose_Test_CLEANUP/Moose_Test_CLEANUP.lua new file mode 100644 index 000000000..1066f424a --- /dev/null +++ b/Test Missions/Moose_Test_CLEANUP/Moose_Test_CLEANUP.lua @@ -0,0 +1,10 @@ +Include.File( 'Cleanup' ) +Include.File( 'Spawn' ) +Include.File( 'Event') + +Clean = CLEANUP:New( 'CLEAN_BATUMI', 180 ) + +SpawnRU = SPAWN:New( 'RU Attack Heli Batumi'):Limit( 2, 20 ):SpawnScheduled( 2, 0.2 ) + +SpawnUS = SPAWN:New( 'US Attack Heli Batumi'):Limit( 2, 20 ):SpawnScheduled( 2, 0.2 ) + diff --git a/Test Missions/Moose_Test_CLEANUP/Moose_Test_CLEANUP.miz b/Test Missions/Moose_Test_CLEANUP/Moose_Test_CLEANUP.miz new file mode 100644 index 0000000000000000000000000000000000000000..2627bceb207f01f015f504e0c685d50e43a5c25d GIT binary patch literal 99751 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

~W~aO9RcYxc_Pl*3vx0b9;#b^I6}wwOg^8 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 literal 0 HcmV?d00001 From ab4f4e75d18e9bc40ede4a4ffb7594c78471d6d1 Mon Sep 17 00:00:00 2001 From: FlightControl Date: Sat, 23 Apr 2016 13:26:33 +0200 Subject: [PATCH 4/5] Trying a workaround for a new DCS crash when ReSpawning Now i destroy the group first before respawning... --- Embedded/Moose_Embedded.lua | 14 +++++++------- Moose/Spawn.lua | 14 +++++++------- .../Moose_Test_SPAWN/MOOSE_Test_SPAWN.lua | 2 +- .../Moose_Test_SPAWN/MOOSE_Test_SPAWN.miz | Bin 46836 -> 48756 bytes 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Embedded/Moose_Embedded.lua b/Embedded/Moose_Embedded.lua index 7ab06e4d4..30ea0c6dd 100644 --- a/Embedded/Moose_Embedded.lua +++ b/Embedded/Moose_Embedded.lua @@ -11511,13 +11511,13 @@ function SPAWN:ReSpawn( SpawnIndex ) end -- TODO: This logic makes DCS crash and i don't know why (yet). --- local SpawnGroup = self:GetGroupFromIndex( SpawnIndex ) --- if SpawnGroup then --- local SpawnDCSGroup = SpawnGroup:GetDCSGroup() --- if SpawnDCSGroup then --- SpawnGroup:Destroy() --- end --- end + local SpawnGroup = self:GetGroupFromIndex( SpawnIndex ) + if SpawnGroup then + local SpawnDCSGroup = SpawnGroup:GetDCSGroup() + if SpawnDCSGroup then + SpawnGroup:Destroy() + end + end return self:SpawnWithIndex( SpawnIndex ) end diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index 9ad27e90e..c82e88ec8 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -418,13 +418,13 @@ function SPAWN:ReSpawn( SpawnIndex ) end -- TODO: This logic makes DCS crash and i don't know why (yet). --- local SpawnGroup = self:GetGroupFromIndex( SpawnIndex ) --- if SpawnGroup then --- local SpawnDCSGroup = SpawnGroup:GetDCSGroup() --- if SpawnDCSGroup then --- SpawnGroup:Destroy() --- end --- end + local SpawnGroup = self:GetGroupFromIndex( SpawnIndex ) + if SpawnGroup then + local SpawnDCSGroup = SpawnGroup:GetDCSGroup() + if SpawnDCSGroup then + SpawnGroup:Destroy() + end + end return self:SpawnWithIndex( SpawnIndex ) end diff --git a/Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.lua b/Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.lua index 6b2c96c5e..5b832af72 100644 --- a/Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.lua +++ b/Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.lua @@ -77,7 +77,7 @@ Spawn_Vehicle_Limited_Scheduled_RandomizeRoute = SPAWN:New( "Spawn Vehicle Limit -- Tests the CleanUp functionality. -- Limited spawning of groups, scheduled every 10 seconds, who are engaging into combat. Some helicopters may crash land on the ground. -- Observe when helicopters land but are not dead and are out of the danger zone, that they get removed after a while (+/- 180 seconds) and ReSpawn. -Spawn_Helicopter_Scheduled_CleanUp = SPAWN:New( "Spawn Helicopter Scheduled CleanUp" ):Limit( 3, 100 ):RandomizeRoute( 1, 1, 1000 ):CleanUp( 180 ):SpawnScheduled( 10, 0 ) +Spawn_Helicopter_Scheduled_CleanUp = SPAWN:New( "Spawn Helicopter Scheduled CleanUp" ):Limit( 3, 100 ):RandomizeRoute( 1, 1, 1000 ):CleanUp( 60 ):SpawnScheduled( 10, 0 ) Spawn_Vehicle_Scheduled_CleanUp = SPAWN:New( "Spawn Vehicle Scheduled CleanUp" ):Limit( 3, 100 ):RandomizeRoute( 1, 1, 1000 ):SpawnScheduled( 10, 0 ) -- Maykop diff --git a/Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.miz b/Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.miz index 4a1b110f25028c6eb1c3f2a05b25574751a4098e..56f294d0aa437e124c7771c96a5dee9f47280227 100644 GIT binary patch delta 31242 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 From 620844b7e08eaa9f706020d8ca2f1cd5e79d70c0 Mon Sep 17 00:00:00 2001 From: FlightControl Date: Sun, 24 Apr 2016 06:24:21 +0200 Subject: [PATCH 5/5] Release of new EVENT class The logic of the EVENT class has finished. Releasing it. --- Embedded/Moose_Embedded.lua | 66 +++++++++++++++++----------------- Moose/Base.lua | 2 +- Moose/CleanUp.lua | 16 ++++----- Moose/Database.lua | 6 ++-- Moose/DestroyGroupsTask.lua | 4 +-- Moose/DestroyRadarsTask.lua | 2 +- Moose/DestroyUnitTypesTask.lua | 2 +- Moose/Event.lua | 2 +- Moose/Movement.lua | 6 ++-- Moose/Sead.lua | 2 +- Moose/Spawn.lua | 24 ++++++------- 11 files changed, 66 insertions(+), 66 deletions(-) diff --git a/Embedded/Moose_Embedded.lua b/Embedded/Moose_Embedded.lua index 30ea0c6dd..d53726370 100644 --- a/Embedded/Moose_Embedded.lua +++ b/Embedded/Moose_Embedded.lua @@ -2725,7 +2725,7 @@ end -- @return Event#EVENT function BASE:Event() - return _EventDispatcher + return _EVENTDISPATCHER end @@ -3506,7 +3506,7 @@ end --- Declare the event dispatcher based on the EVENT class -_EventDispatcher = EVENT:New() -- #EVENT +_EVENTDISPATCHER = EVENT:New() -- #EVENT --- Encapsulation of DCS World Menu system in a set of MENU classes. -- @module Menu @@ -5600,9 +5600,9 @@ function DATABASE:New() end --for coa_name, coa_data in pairs(mission.coalition) do --self:AddEvent( world.event.S_EVENT_BIRTH, self.OnBirth ) - _EventDispatcher:OnDead( self._EventOnDeadOrCrash, self ) - _EventDispatcher:OnCrash( self._EventOnDeadOrCrash, self ) - _EventDispatcher:OnHit( self._EventOnHit, self ) + _EVENTDISPATCHER:OnDead( self._EventOnDeadOrCrash, self ) + _EVENTDISPATCHER:OnCrash( self._EventOnDeadOrCrash, self ) + _EVENTDISPATCHER:OnHit( self._EventOnHit, self ) self.SchedulerId = routines.scheduleFunction( DATABASE._FollowPlayers, { self }, 0, 5 ) @@ -9599,8 +9599,8 @@ function DESTROYGROUPSTASK:New( DestroyGroupType, DestroyUnitType, DestroyGroupN self.Name = 'Destroy Groups' self.GoalVerb = "Destroy " .. DestroyGroupType - _EventDispatcher:OnDead( self.EventDead , self ) - _EventDispatcher:OnCrash( self.EventDead , self ) + _EVENTDISPATCHER:OnDead( self.EventDead , self ) + _EVENTDISPATCHER:OnCrash( self.EventDead , self ) return self end @@ -9651,7 +9651,7 @@ function DESTROYRADARSTASK:New( DestroyGroupNames ) self.Name = 'Destroy Radars' - _EventDispatcher:OnDead( self.EventDead , self ) + _EVENTDISPATCHER:OnDead( self.EventDead , self ) return self end @@ -9702,7 +9702,7 @@ function DESTROYUNITTYPESTASK:New( DestroyGroupType, DestroyUnitType, DestroyGro self.Name = 'Destroy Unit Types' self.GoalVerb = "Destroy " .. DestroyGroupType - _EventDispatcher:OnDead( self.EventDead , self ) + _EVENTDISPATCHER:OnDead( self.EventDead , self ) return self end @@ -10811,7 +10811,7 @@ function CLEANUP:New( ZoneNames, TimeInterval ) local self = BASE:Inherit( self, self.TimeInterval = TimeInterval end - _EventDispatcher:OnBirth( self._OnEventBirth, self ) + _EVENTDISPATCHER:OnBirth( self._OnEventBirth, self ) self.CleanUpScheduler = routines.scheduleFunction( self._CleanUpScheduler, { self }, timer.getTime() + 1, TimeInterval ) @@ -10883,13 +10883,13 @@ function CLEANUP:_OnEventBirth( Event ) self.CleanUpList[Event.IniDCSUnitName].CleanUpGroupName = Event.IniDCSGroupName self.CleanUpList[Event.IniDCSUnitName].CleanUpUnitName = Event.IniDCSUnitName - _EventDispatcher:OnEngineShutDownForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) - _EventDispatcher:OnEngineStartUpForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) - _EventDispatcher:OnHitForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) - _EventDispatcher:OnPilotDeadForUnit( Event.IniDCSUnitName, self._EventCrash, self ) - _EventDispatcher:OnDeadForUnit( Event.IniDCSUnitName, self._EventCrash, self ) - _EventDispatcher:OnCrashForUnit( Event.IniDCSUnitName, self._EventCrash, self ) - _EventDispatcher:OnShotForUnit( Event.IniDCSUnitName, self._EventShot, self ) + _EVENTDISPATCHER:OnEngineShutDownForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) + _EVENTDISPATCHER:OnEngineStartUpForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) + _EVENTDISPATCHER:OnHitForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) + _EVENTDISPATCHER:OnPilotDeadForUnit( Event.IniDCSUnitName, self._EventCrash, self ) + _EVENTDISPATCHER:OnDeadForUnit( Event.IniDCSUnitName, self._EventCrash, self ) + _EVENTDISPATCHER:OnCrashForUnit( Event.IniDCSUnitName, self._EventCrash, self ) + _EVENTDISPATCHER:OnShotForUnit( Event.IniDCSUnitName, self._EventShot, self ) --self:AddEvent( world.event.S_EVENT_ENGINE_SHUTDOWN, self._EventAddForCleanUp ) --self:AddEvent( world.event.S_EVENT_ENGINE_STARTUP, self._EventAddForCleanUp ) @@ -11463,18 +11463,18 @@ function SPAWN:Array( SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY ) self.SpawnGroups[SpawnGroupID].Visible = true - _EventDispatcher:OnBirthForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnBirth, self ) - _EventDispatcher:OnCrashForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnDeadOrCrash, self ) - _EventDispatcher:OnDeadForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnDeadOrCrash, self ) + _EVENTDISPATCHER:OnBirthForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnBirth, self ) + _EVENTDISPATCHER:OnCrashForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnDeadOrCrash, self ) + _EVENTDISPATCHER:OnDeadForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnDeadOrCrash, self ) if self.SpawnRepeat then - _EventDispatcher:OnTakeOffForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnTakeOff, self ) + _EVENTDISPATCHER:OnTakeOffForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnTakeOff, self ) end if self.RepeatOnLanding then - _EventDispatcher:OnLandForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnLand, self ) + _EVENTDISPATCHER:OnLandForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnLand, self ) end if self.RepeatOnEngineShutDown then - _EventDispatcher:OnEngineShutDownForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnEngineShutDown, self ) + _EVENTDISPATCHER:OnEngineShutDownForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnEngineShutDown, self ) end self.SpawnGroups[SpawnGroupID].Group = _Database:Spawn( self.SpawnGroups[SpawnGroupID].SpawnTemplate ) @@ -11535,18 +11535,18 @@ function SPAWN:SpawnWithIndex( SpawnIndex ) self.SpawnGroups[self.SpawnIndex].Group:Activate() else self:T( self.SpawnGroups[self.SpawnIndex].SpawnTemplate ) - _EventDispatcher:OnBirthForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnBirth, self ) - _EventDispatcher:OnCrashForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnDeadOrCrash, self ) - _EventDispatcher:OnDeadForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnDeadOrCrash, self ) + _EVENTDISPATCHER:OnBirthForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnBirth, self ) + _EVENTDISPATCHER:OnCrashForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnDeadOrCrash, self ) + _EVENTDISPATCHER:OnDeadForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnDeadOrCrash, self ) if self.SpawnRepeat then - _EventDispatcher:OnTakeOffForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnTakeOff, self ) + _EVENTDISPATCHER:OnTakeOffForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnTakeOff, self ) end if self.RepeatOnLanding then - _EventDispatcher:OnLandForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnLand, self ) + _EVENTDISPATCHER:OnLandForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnLand, self ) end if self.RepeatOnEngineShutDown then - _EventDispatcher:OnEngineShutDownForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnEngineShutDown, self ) + _EVENTDISPATCHER:OnEngineShutDownForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnEngineShutDown, self ) end self.SpawnGroups[self.SpawnIndex].Group = _Database:Spawn( self.SpawnGroups[self.SpawnIndex].SpawnTemplate ) @@ -12403,7 +12403,7 @@ function MOVEMENT:New( MovePrefixes, MoveMaximum ) self.AliveUnits = 0 -- Contains the counter how many units are currently alive self.MoveUnits = {} -- Reflects if the Moving for this MovePrefixes is going to be scheduled or not. - _EventDispatcher:OnBirth( self.OnBirth, self ) + _EVENTDISPATCHER:OnBirth( self.OnBirth, self ) -- self:AddEvent( world.event.S_EVENT_BIRTH, self.OnBirth ) -- @@ -12445,8 +12445,8 @@ function MOVEMENT:OnBirth( Event ) end end end - _EventDispatcher:OnCrashForUnit( Event.IniDCSUnitName, self.OnDeadOrCrash, self ) - _EventDispatcher:OnDeadForUnit( Event.IniDCSUnitName, self.OnDeadOrCrash, self ) + _EVENTDISPATCHER:OnCrashForUnit( Event.IniDCSUnitName, self.OnDeadOrCrash, self ) + _EVENTDISPATCHER:OnDeadForUnit( Event.IniDCSUnitName, self.OnDeadOrCrash, self ) end end @@ -12539,7 +12539,7 @@ function SEAD:New( SEADGroupPrefixes ) else self.SEADGroupNames[SEADGroupPrefixes] = SEADGroupPrefixes end - _EventDispatcher:OnShot( self.EventShot, self ) + _EVENTDISPATCHER:OnShot( self.EventShot, self ) return self end diff --git a/Moose/Base.lua b/Moose/Base.lua index d5b7d43b6..fe6affc98 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -147,7 +147,7 @@ end -- @return Event#EVENT function BASE:Event() - return _EventDispatcher + return _EVENTDISPATCHER end diff --git a/Moose/CleanUp.lua b/Moose/CleanUp.lua index 236f63e14..1e0c902c5 100644 --- a/Moose/CleanUp.lua +++ b/Moose/CleanUp.lua @@ -41,7 +41,7 @@ function CLEANUP:New( ZoneNames, TimeInterval ) local self = BASE:Inherit( self, self.TimeInterval = TimeInterval end - _EventDispatcher:OnBirth( self._OnEventBirth, self ) + _EVENTDISPATCHER:OnBirth( self._OnEventBirth, self ) self.CleanUpScheduler = routines.scheduleFunction( self._CleanUpScheduler, { self }, timer.getTime() + 1, TimeInterval ) @@ -113,13 +113,13 @@ function CLEANUP:_OnEventBirth( Event ) self.CleanUpList[Event.IniDCSUnitName].CleanUpGroupName = Event.IniDCSGroupName self.CleanUpList[Event.IniDCSUnitName].CleanUpUnitName = Event.IniDCSUnitName - _EventDispatcher:OnEngineShutDownForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) - _EventDispatcher:OnEngineStartUpForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) - _EventDispatcher:OnHitForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) - _EventDispatcher:OnPilotDeadForUnit( Event.IniDCSUnitName, self._EventCrash, self ) - _EventDispatcher:OnDeadForUnit( Event.IniDCSUnitName, self._EventCrash, self ) - _EventDispatcher:OnCrashForUnit( Event.IniDCSUnitName, self._EventCrash, self ) - _EventDispatcher:OnShotForUnit( Event.IniDCSUnitName, self._EventShot, self ) + _EVENTDISPATCHER:OnEngineShutDownForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) + _EVENTDISPATCHER:OnEngineStartUpForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) + _EVENTDISPATCHER:OnHitForUnit( Event.IniDCSUnitName, self._EventAddForCleanUp, self ) + _EVENTDISPATCHER:OnPilotDeadForUnit( Event.IniDCSUnitName, self._EventCrash, self ) + _EVENTDISPATCHER:OnDeadForUnit( Event.IniDCSUnitName, self._EventCrash, self ) + _EVENTDISPATCHER:OnCrashForUnit( Event.IniDCSUnitName, self._EventCrash, self ) + _EVENTDISPATCHER:OnShotForUnit( Event.IniDCSUnitName, self._EventShot, self ) --self:AddEvent( world.event.S_EVENT_ENGINE_SHUTDOWN, self._EventAddForCleanUp ) --self:AddEvent( world.event.S_EVENT_ENGINE_STARTUP, self._EventAddForCleanUp ) diff --git a/Moose/Database.lua b/Moose/Database.lua index 58d2a5011..02fcb30d6 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -111,9 +111,9 @@ function DATABASE:New() end --for coa_name, coa_data in pairs(mission.coalition) do --self:AddEvent( world.event.S_EVENT_BIRTH, self.OnBirth ) - _EventDispatcher:OnDead( self._EventOnDeadOrCrash, self ) - _EventDispatcher:OnCrash( self._EventOnDeadOrCrash, self ) - _EventDispatcher:OnHit( self._EventOnHit, self ) + _EVENTDISPATCHER:OnDead( self._EventOnDeadOrCrash, self ) + _EVENTDISPATCHER:OnCrash( self._EventOnDeadOrCrash, self ) + _EVENTDISPATCHER:OnHit( self._EventOnHit, self ) self.SchedulerId = routines.scheduleFunction( DATABASE._FollowPlayers, { self }, 0, 5 ) diff --git a/Moose/DestroyGroupsTask.lua b/Moose/DestroyGroupsTask.lua index 81c3fbca0..38cd98fb6 100644 --- a/Moose/DestroyGroupsTask.lua +++ b/Moose/DestroyGroupsTask.lua @@ -24,8 +24,8 @@ function DESTROYGROUPSTASK:New( DestroyGroupType, DestroyUnitType, DestroyGroupN self.Name = 'Destroy Groups' self.GoalVerb = "Destroy " .. DestroyGroupType - _EventDispatcher:OnDead( self.EventDead , self ) - _EventDispatcher:OnCrash( self.EventDead , self ) + _EVENTDISPATCHER:OnDead( self.EventDead , self ) + _EVENTDISPATCHER:OnCrash( self.EventDead , self ) return self end diff --git a/Moose/DestroyRadarsTask.lua b/Moose/DestroyRadarsTask.lua index 9c799d586..347ad4181 100644 --- a/Moose/DestroyRadarsTask.lua +++ b/Moose/DestroyRadarsTask.lua @@ -19,7 +19,7 @@ function DESTROYRADARSTASK:New( DestroyGroupNames ) self.Name = 'Destroy Radars' - _EventDispatcher:OnDead( self.EventDead , self ) + _EVENTDISPATCHER:OnDead( self.EventDead , self ) return self end diff --git a/Moose/DestroyUnitTypesTask.lua b/Moose/DestroyUnitTypesTask.lua index 27426ed15..a4001ccd4 100644 --- a/Moose/DestroyUnitTypesTask.lua +++ b/Moose/DestroyUnitTypesTask.lua @@ -29,7 +29,7 @@ function DESTROYUNITTYPESTASK:New( DestroyGroupType, DestroyUnitType, DestroyGro self.Name = 'Destroy Unit Types' self.GoalVerb = "Destroy " .. DestroyGroupType - _EventDispatcher:OnDead( self.EventDead , self ) + _EVENTDISPATCHER:OnDead( self.EventDead , self ) return self end diff --git a/Moose/Event.lua b/Moose/Event.lua index a3501b44c..a51ec4a88 100644 --- a/Moose/Event.lua +++ b/Moose/Event.lua @@ -485,5 +485,5 @@ end --- Declare the event dispatcher based on the EVENT class -_EventDispatcher = EVENT:New() -- #EVENT +_EVENTDISPATCHER = EVENT:New() -- #EVENT diff --git a/Moose/Movement.lua b/Moose/Movement.lua index 8f809a20d..e90caa260 100644 --- a/Moose/Movement.lua +++ b/Moose/Movement.lua @@ -35,7 +35,7 @@ function MOVEMENT:New( MovePrefixes, MoveMaximum ) self.AliveUnits = 0 -- Contains the counter how many units are currently alive self.MoveUnits = {} -- Reflects if the Moving for this MovePrefixes is going to be scheduled or not. - _EventDispatcher:OnBirth( self.OnBirth, self ) + _EVENTDISPATCHER:OnBirth( self.OnBirth, self ) -- self:AddEvent( world.event.S_EVENT_BIRTH, self.OnBirth ) -- @@ -77,8 +77,8 @@ function MOVEMENT:OnBirth( Event ) end end end - _EventDispatcher:OnCrashForUnit( Event.IniDCSUnitName, self.OnDeadOrCrash, self ) - _EventDispatcher:OnDeadForUnit( Event.IniDCSUnitName, self.OnDeadOrCrash, self ) + _EVENTDISPATCHER:OnCrashForUnit( Event.IniDCSUnitName, self.OnDeadOrCrash, self ) + _EVENTDISPATCHER:OnDeadForUnit( Event.IniDCSUnitName, self.OnDeadOrCrash, self ) end end diff --git a/Moose/Sead.lua b/Moose/Sead.lua index 8c1ddbc6b..f30459de2 100644 --- a/Moose/Sead.lua +++ b/Moose/Sead.lua @@ -43,7 +43,7 @@ function SEAD:New( SEADGroupPrefixes ) else self.SEADGroupNames[SEADGroupPrefixes] = SEADGroupPrefixes end - _EventDispatcher:OnShot( self.EventShot, self ) + _EVENTDISPATCHER:OnShot( self.EventShot, self ) return self end diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index c82e88ec8..ad8575e9a 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -370,18 +370,18 @@ function SPAWN:Array( SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY ) self.SpawnGroups[SpawnGroupID].Visible = true - _EventDispatcher:OnBirthForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnBirth, self ) - _EventDispatcher:OnCrashForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnDeadOrCrash, self ) - _EventDispatcher:OnDeadForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnDeadOrCrash, self ) + _EVENTDISPATCHER:OnBirthForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnBirth, self ) + _EVENTDISPATCHER:OnCrashForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnDeadOrCrash, self ) + _EVENTDISPATCHER:OnDeadForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnDeadOrCrash, self ) if self.SpawnRepeat then - _EventDispatcher:OnTakeOffForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnTakeOff, self ) + _EVENTDISPATCHER:OnTakeOffForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnTakeOff, self ) end if self.RepeatOnLanding then - _EventDispatcher:OnLandForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnLand, self ) + _EVENTDISPATCHER:OnLandForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnLand, self ) end if self.RepeatOnEngineShutDown then - _EventDispatcher:OnEngineShutDownForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnEngineShutDown, self ) + _EVENTDISPATCHER:OnEngineShutDownForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnEngineShutDown, self ) end self.SpawnGroups[SpawnGroupID].Group = _Database:Spawn( self.SpawnGroups[SpawnGroupID].SpawnTemplate ) @@ -442,18 +442,18 @@ function SPAWN:SpawnWithIndex( SpawnIndex ) self.SpawnGroups[self.SpawnIndex].Group:Activate() else self:T( self.SpawnGroups[self.SpawnIndex].SpawnTemplate ) - _EventDispatcher:OnBirthForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnBirth, self ) - _EventDispatcher:OnCrashForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnDeadOrCrash, self ) - _EventDispatcher:OnDeadForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnDeadOrCrash, self ) + _EVENTDISPATCHER:OnBirthForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnBirth, self ) + _EVENTDISPATCHER:OnCrashForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnDeadOrCrash, self ) + _EVENTDISPATCHER:OnDeadForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnDeadOrCrash, self ) if self.SpawnRepeat then - _EventDispatcher:OnTakeOffForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnTakeOff, self ) + _EVENTDISPATCHER:OnTakeOffForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnTakeOff, self ) end if self.RepeatOnLanding then - _EventDispatcher:OnLandForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnLand, self ) + _EVENTDISPATCHER:OnLandForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnLand, self ) end if self.RepeatOnEngineShutDown then - _EventDispatcher:OnEngineShutDownForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnEngineShutDown, self ) + _EVENTDISPATCHER:OnEngineShutDownForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnEngineShutDown, self ) end self.SpawnGroups[self.SpawnIndex].Group = _Database:Spawn( self.SpawnGroups[self.SpawnIndex].SpawnTemplate )