Added the new event S_EVENT_REMOVE_UNIT to trigger the removal of units (from groups also) when a :Destroy(false) or :Destroy() is called for a UNIT object.

The units are then removed from each SET that is subscribed to a set of UNIT objects or GROUP objects! Also the DATABASE is correctly managing this new removal method.
This to prevent the DATABASE getting corrupted with dead units, which were removed with :Destroy(), but which weren't cleaned from the database.
This commit is contained in:
FlightControl 2018-09-11 09:00:30 +02:00
parent 72538597ad
commit c1191e286a
7 changed files with 68 additions and 39 deletions

View File

@ -656,6 +656,22 @@ function BASE:CreateEventDead( EventTime, Initiator )
world.onEvent( Event )
end
--- Creation of a Remove Unit Event.
-- @param #BASE self
-- @param DCS#Time EventTime The time stamp of the event.
-- @param DCS#Object Initiator The initiating object of the event.
function BASE:CreateEventRemoveUnit( EventTime, Initiator )
self:F( { EventTime, Initiator } )
local Event = {
id = EVENTS.RemoveUnit,
time = EventTime,
initiator = Initiator,
}
world.onEvent( Event )
end
--- Creation of a Takeoff Event.
-- @param #BASE self
-- @param DCS#Time EventTime The time stamp of the event.

View File

@ -95,6 +95,7 @@ function DATABASE:New()
self:HandleEvent( EVENTS.Birth, self._EventOnBirth )
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
self:HandleEvent( EVENTS.RemoveUnit, self._EventOnDeadOrCrash )
self:HandleEvent( EVENTS.Hit, self.AccountHits )
self:HandleEvent( EVENTS.NewCargo )
self:HandleEvent( EVENTS.DeleteCargo )
@ -1347,18 +1348,12 @@ end
self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } )
end
self:T( "Something got destroyed" )
local Destroyed = false
-- What is the player destroying?
if self.HITS[Event.IniUnitName] then -- Was there a hit for this unit for this player before registered???
self.DESTROYS[Event.IniUnitName] = self.DESTROYS[Event.IniUnitName] or {}
self.DESTROYS[Event.IniUnitName] = true
end
end

View File

@ -181,6 +181,8 @@ world.event.S_EVENT_NEW_CARGO = world.event.S_EVENT_MAX + 1000
world.event.S_EVENT_DELETE_CARGO = world.event.S_EVENT_MAX + 1001
world.event.S_EVENT_NEW_ZONE = world.event.S_EVENT_MAX + 1002
world.event.S_EVENT_DELETE_ZONE = world.event.S_EVENT_MAX + 1003
world.event.S_EVENT_REMOVE_UNIT = world.event.S_EVENT_MAX + 1004
--- The different types of events supported by MOOSE.
-- Use this structure to subscribe to events using the @{Core.Base#BASE.HandleEvent}() method.
@ -216,6 +218,7 @@ EVENTS = {
DeleteCargo = world.event.S_EVENT_DELETE_CARGO,
NewZone = world.event.S_EVENT_NEW_ZONE,
DeleteZone = world.event.S_EVENT_DELETE_ZONE,
RemoveUnit = world.event.S_EVENT_REMOVE_UNIT,
}
--- The Event structure
@ -441,6 +444,11 @@ local _EVENTMETA = {
Event = "OnEventDeleteZone",
Text = "S_EVENT_DELETE_ZONE"
},
[EVENTS.RemoveUnit] = {
Order = -1,
Event = "OnEventRemoveUnit",
Text = "S_EVENT_REMOVE_UNIT"
},
}
@ -985,7 +993,8 @@ function EVENT:onEvent( Event )
if EventClass:IsAlive() or
Event.id == EVENTS.PlayerEnterUnit or
Event.id == EVENTS.Crash or
Event.id == EVENTS.Dead then
Event.id == EVENTS.Dead or
Event.id == EVENTS.RemoveUnit then
local UnitName = EventClass:GetName()
@ -1035,7 +1044,8 @@ function EVENT:onEvent( Event )
if EventClass:IsAlive() or
Event.id == EVENTS.PlayerEnterUnit or
Event.id == EVENTS.Crash or
Event.id == EVENTS.Dead then
Event.id == EVENTS.Dead or
Event.id == EVENTS.RemoveUnit then
-- We can get the name of the EventClass, which is now always a GROUP object.
local GroupName = EventClass:GetName()

View File

@ -1023,6 +1023,7 @@ function SET_GROUP:FilterStart()
self:HandleEvent( EVENTS.Birth, self._EventOnBirth )
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
self:HandleEvent( EVENTS.RemoveUnit, self._EventOnDeadOrCrash )
end
@ -1804,8 +1805,9 @@ do -- SET_UNIT
if _DATABASE then
self:_FilterStart()
self:HandleEvent( EVENTS.Birth, self._EventOnBirth )
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrashOr )
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
self:HandleEvent( EVENTS.RemoveUnit, self._EventOnDeadOrCrash )
end
return self

View File

@ -261,13 +261,15 @@ function GROUP:Destroy( GenerateEvent )
local DCSGroup = self:GetDCSObject()
if DCSGroup then
if GenerateEvent and GenerateEvent == true then
for Index, UnitData in pairs( DCSGroup:getUnits() ) do
for Index, UnitData in pairs( DCSGroup:getUnits() ) do
if GenerateEvent and GenerateEvent == true then
if self:IsAir() then
self:CreateEventCrash( timer.getTime(), UnitData )
else
self:CreateEventDead( timer.getTime(), UnitData )
end
else
self:CreateEventRemove( timer.getTime(), UnitData )
end
end
USERFLAG:New( self:GetName() ):Set( 100 )

View File

@ -69,6 +69,38 @@ function POSITIONABLE:New( PositionableName )
return self
end
--- Destroys the POSITIONABLE.
-- @param #POSITIONABLE self
-- @param #boolean GenerateEvent (Optional) true if you want to generate a crash or dead event for the unit.
-- @return #nil The DCS Unit is not existing or alive.
function POSITIONABLE:Destroy( GenerateEvent )
self:F2( self.ObjectName )
local DCSObject = self:GetDCSObject()
if DCSObject then
local UnitGroup = self:GetGroup()
local UnitGroupName = UnitGroup:GetName()
self:F( { UnitGroupName = UnitGroupName } )
if GenerateEvent and GenerateEvent == true then
if self:IsAir() then
self:CreateEventCrash( timer.getTime(), DCSObject )
else
self:CreateEventDead( timer.getTime(), DCSObject )
end
else
self:CreateEventRemoveUnit( timer.getTime(), DCSObject )
end
USERFLAG:New( UnitGroupName ):Set( 100 )
DCSObject:destroy()
end
return nil
end
--- Returns the @{DCS#Position3} position vectors indicating the point and direction vectors in 3D of the POSITIONABLE within the mission.
-- @param Wrapper.Positionable#POSITIONABLE self
-- @return DCS#Position The 3D position vectors of the POSITIONABLE.

View File

@ -157,35 +157,7 @@ function UNIT:GetDCSObject()
return nil
end
--- Destroys the UNIT.
-- @param #UNIT self
-- @param #boolean GenerateEvent (Optional) true if you want to generate a crash or dead event for the unit.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:Destroy( GenerateEvent )
self:F2( self.ObjectName )
local DCSObject = self:GetDCSObject()
if DCSObject then
local UnitGroup = self:GetGroup()
local UnitGroupName = UnitGroup:GetName()
self:F( { UnitGroupName = UnitGroupName } )
if GenerateEvent and GenerateEvent == true then
if self:IsAir() then
self:CreateEventCrash( timer.getTime(), DCSObject )
else
self:CreateEventDead( timer.getTime(), DCSObject )
end
end
USERFLAG:New( UnitGroupName ):Set( 100 )
DCSObject:destroy()
end
return nil
end
--- Respawn the @{Wrapper.Unit} using a (tweaked) template of the parent Group.