New implementations

of inheritance
of private - public methods ....

This is a big improvement for many!
This commit is contained in:
FlightControl
2017-07-01 12:32:44 +02:00
parent 5d2eb2ea15
commit 8e5af4ada4
15 changed files with 441 additions and 420 deletions

View File

@@ -1,7 +1,5 @@
--- **Functional** -- The CLEANUP class keeps an area clean of crashing or colliding airplanes. It also prevents airplanes from firing within this area.
--
-- ![Banner Image](..\Presentations\CLEANUP\Dia1.JPG)
--
-- ===
--
-- ### Author: **Sven Van de Velde (FlightControl)**
@@ -11,14 +9,57 @@
--
-- @module CleanUp
--- @type CLEANUP.__
-- @extends Core.Base#BASE
--- @type CLEANUP
-- @extends Core.Base#BASE
-- @extends #CLEANUP.__
-- @field #map<#string,Wrapper.Airbase#AIRBASE> Airbases Map of Airbases.
--- # CLEANUP, extends @{Base#BASE}
--
-- ![Banner Image](..\Presentations\CLEANUP\Dia1.JPG)
--
-- The CLEANUP class keeps airbases clean, and tries to guarantee continuous airbase operations, even under combat.
-- Specific airbases need to be provided that need to be guarded. Each airbase registered, will be guarded within a zone of 8 km around the airbase.
-- Any unit that fires a missile, or shoots within the zone of an airbase, will be monitored by CLEANUP.
-- Within the 8km zone, units cannot fire any missile, which prevents the airbase runway to receive missile or bomb hits.
-- Any airborne or ground unit that is on the runway below 30 meters (default value) will be automatically removed if it is damaged.
--
-- This is not a full 100% secure implementation. It is still possible that CLEANUP cannot prevent (in-time) to keep the airbase clean.
-- The following situations may happen that will still stop the runway of an airbase:
--
-- * A damaged unit is not removed on time when above the runway, and crashes on the runway.
-- * A bomb or missile is still able to dropped on the runway.
-- * Units collide on the airbase, and could not be removed on time.
--
-- When a unit is within the airbase zone and needs to be monitored,
-- its status will be checked every 0.25 seconds! This is required to ensure that the airbase is kept clean.
-- But as a result, there is more CPU overload.
--
-- So as an advise, I suggest you use the CLEANUP class with care:
--
-- * Only monitor airbases that really need to be monitored!
-- * Try not to monitor airbases that are likely to be invaded by enemy troops.
-- For these airbases, there is little use to keep them clean, as they will be invaded anyway...
--
-- By following the above guidelines, you can add airbase cleanup with acceptable CPU overhead.
--
-- ## 1. CLEANUP Constructor
--
-- Creates the main object which is preventing the airbase to get polluted with debris on the runway, which halts the airbase.
--
-- -- Clean these Zones.
-- CleanUpAirports = CLEANUP:New( { AIRBASE.Caucasus.Tbilisi, AIRBASE.Caucasus.Kutaisi )
--
-- -- or
-- CleanUpTbilisi = CLEANUP:New( AIRBASE.Caucasus.Tbilisi )
-- CleanUpKutaisi = CLEANUP:New( AIRBASE.Caucasus.Kutaisi )
--
-- ## 2. Add or Remove airbases
--
-- The method @{#CLEANUP.AddAirbase} to add an airbase to the cleanup validation process.
-- The method @{#CLEANUP.RemoveAirbase} removes an airbase from the cleanup validation process.
--
-- @field #CLEANUP
CLEANUP = {
@@ -28,6 +69,10 @@ CLEANUP = {
Airbases = {},
}
--- @field #CLEANUP.__
CLEANUP.__ = {}
--- Creates the main object which is handling the cleaning of the debris within the given Zone Names.
-- @param #CLEANUP self
-- @param #list<#string> AirbaseNames Is a table of airbase names where the debris should be cleaned. Also a single string can be passed with one airbase name.
@@ -52,9 +97,9 @@ function CLEANUP:New( AirbaseNames )
self:AddAirbase( AirbaseName )
end
self:HandleEvent( EVENTS.Birth )
self:HandleEvent( EVENTS.Birth, self.__.OnEventBirth )
self.CleanUpScheduler = SCHEDULER:New( self, self._CleanUpScheduler, {}, 1, self.TimeInterval )
self.CleanUpScheduler = SCHEDULER:New( self, self.__.CleanUpScheduler, {}, 1, self.TimeInterval )
return self
end
@@ -81,7 +126,7 @@ end
function CLEANUP:IsInAirbase( Vec2 )
function CLEANUP.__:IsInAirbase( Vec2 )
local InAirbase = false
for AirbaseName, Airbase in pairs( self.Airbases ) do
@@ -95,23 +140,12 @@ function CLEANUP:IsInAirbase( Vec2 )
return InAirbase
end
--- Destroys a group from the simulator, but checks first if it is still existing!
-- @param #CLEANUP self
-- @param Dcs.DCSWrapper.Group#Group GroupObject The object to be destroyed.
-- @param #string CleanUpGroupName The groupname...
function CLEANUP:_DestroyGroup( GroupObject, CleanUpGroupName )
self:F( { GroupObject, CleanUpGroupName } )
if GroupObject then -- and GroupObject:isExist() then
trigger.action.deactivateGroup(GroupObject)
self:T( { "GroupObject Destroyed", GroupObject } )
end
end
--- Destroys a @{Unit} from the simulator, but checks first if it is still existing!
-- @param #CLEANUP self
-- @param Wrapper.Unit#UNIT CleanUpUnit The object to be destroyed.
function CLEANUP:_DestroyUnit( CleanUpUnit )
function CLEANUP.__:DestroyUnit( CleanUpUnit )
self:F( { CleanUpUnit } )
if CleanUpUnit then
@@ -131,13 +165,14 @@ function CLEANUP:_DestroyUnit( CleanUpUnit )
end
end
-- TODO check Dcs.DCSTypes#Weapon
--- Destroys a missile from the simulator, but checks first if it is still existing!
-- @param #CLEANUP self
-- @param Dcs.DCSTypes#Weapon MissileObject
function CLEANUP:_DestroyMissile( MissileObject )
function CLEANUP.__:DestroyMissile( MissileObject )
self:F( { MissileObject } )
if MissileObject and MissileObject:isExist() then
MissileObject:destroy()
self:T( "MissileObject Destroyed")
@@ -146,30 +181,31 @@ end
--- @param #CLEANUP self
-- @param Core.Event#EVENTDATA EventData
function CLEANUP:OnEventBirth( EventData )
function CLEANUP.__:OnEventBirth( EventData )
self:F( { EventData } )
self.CleanUpList[EventData.IniDCSUnitName] = {}
self.CleanUpList[EventData.IniDCSUnitName].CleanUpUnit = EventData.IniDCSUnit
self.CleanUpList[EventData.IniDCSUnitName].CleanUpGroup = EventData.IniDCSGroup
self.CleanUpList[EventData.IniDCSUnitName].CleanUpUnit = EventData.IniUnit
self.CleanUpList[EventData.IniDCSUnitName].CleanUpGroup = EventData.IniGroup
self.CleanUpList[EventData.IniDCSUnitName].CleanUpGroupName = EventData.IniDCSGroupName
self.CleanUpList[EventData.IniDCSUnitName].CleanUpUnitName = EventData.IniDCSUnitName
self:HandleEvent( EVENTS.EngineShutdown , self._EventAddForCleanUp )
self:HandleEvent( EVENTS.EngineStartup, self._EventAddForCleanUp )
self:HandleEvent( EVENTS.Hit, self._EventAddForCleanUp )
self:HandleEvent( EVENTS.PilotDead, self.OnEventCrash )
self:HandleEvent( EVENTS.Dead, self.OnEventCrash )
self:HandleEvent( EVENTS.Crash, self.OnEventCrash )
self:HandleEvent( EVENTS.Shot, self.OnEventShot )
self:HandleEvent( EVENTS.EngineShutdown , self.__.EventAddForCleanUp )
self:HandleEvent( EVENTS.EngineStartup, self.__.EventAddForCleanUp )
self:HandleEvent( EVENTS.Hit, self.__.EventAddForCleanUp )
self:HandleEvent( EVENTS.PilotDead, self.__.OnEventCrash )
self:HandleEvent( EVENTS.Dead, self.__.OnEventCrash )
self:HandleEvent( EVENTS.Crash, self.__.OnEventCrash )
self:HandleEvent( EVENTS.Shot, self.__.OnEventShot )
end
--- Detects if a crash event occurs.
-- Crashed units go into a CleanUpList for removal.
-- @param #CLEANUP self
-- @param Dcs.DCSTypes#Event event
function CLEANUP:OnEventCrash( Event )
-- @param Core.Event#EVENTDATA Event
function CLEANUP.__:OnEventCrash( Event )
self:F( { Event } )
--TODO: This stuff is not working due to a DCS bug. Burning units cannot be destroyed.
@@ -180,10 +216,10 @@ function CLEANUP:OnEventCrash( Event )
-- self:T("after deactivateGroup")
-- event.initiator:destroy()
if Event.IniDCSUnitName then
if Event.IniDCSUnitName and Event.IniCategory == Object.Category.UNIT then
self.CleanUpList[Event.IniDCSUnitName] = {}
self.CleanUpList[Event.IniDCSUnitName].CleanUpUnit = Event.IniDCSUnit
self.CleanUpList[Event.IniDCSUnitName].CleanUpGroup = Event.IniDCSGroup
self.CleanUpList[Event.IniDCSUnitName].CleanUpUnit = Event.IniUnit
self.CleanUpList[Event.IniDCSUnitName].CleanUpGroup = Event.IniGroup
self.CleanUpList[Event.IniDCSUnitName].CleanUpGroupName = Event.IniDCSGroupName
self.CleanUpList[Event.IniDCSUnitName].CleanUpUnitName = Event.IniDCSUnitName
end
@@ -194,79 +230,85 @@ end
-- If this occurs within one of the airbases, then the weapon used must be destroyed.
-- @param #CLEANUP self
-- @param Core.Event#EVENTDATA Event
function CLEANUP:OnEventShot( Event )
function CLEANUP.__:OnEventShot( Event )
self:F( { Event } )
-- Test if the missile was fired within one of the CLEANUP.AirbaseNames.
if self:IsInAirbase( Event.IniUnit:GetVec2() ) then
-- Okay, the missile was fired within the CLEANUP.AirbaseNames, destroy the fired weapon.
self:_DestroyMissile( Event.Weapon )
self:DestroyMissile( Event.Weapon )
end
end
--- Detects if the Unit has an S_EVENT_HIT within the given AirbaseNames. If this is the case, destroy the unit.
-- @param #CLEANUP self
-- @param Core.Event#EVENTDATA Event
function CLEANUP:OnEventHit( Event )
function CLEANUP.__:OnEventHit( Event )
self:F( { Event } )
if Event.IniUnit then
if self:IsInAirbase( Event.IniUnit:GetVec2() ) then
self:T( { "Life: ", Event.IniDCSUnitName, ' = ', Event.IniDCSUnit:getLife(), "/", Event.IniDCSUnit:getLife0() } )
if Event.IniDCSUnit:getLife() < Event.IniDCSUnit:getLife0() then
self:T( { "Life: ", Event.IniDCSUnitName, ' = ', Event.IniUnit:GetLife(), "/", Event.IniUnit:GetLife0() } )
if Event.IniUnit:GetLife() < Event.IniUnit:GetLife0() then
self:T( "CleanUp: Destroy: " .. Event.IniDCSUnitName )
CLEANUP:_DestroyUnit( Event.IniUnit )
CLEANUP.__:DestroyUnit( Event.IniUnit )
end
end
end
if Event.TgtUnit then
if self:IsInAirbase( Event.TgtUnit:GetVec2() ) then
self:T( { "Life: ", Event.TgtDCSUnitName, ' = ', Event.TgtDCSUnit:getLife(), "/", Event.TgtDCSUnit:getLife0() } )
if Event.TgtDCSUnit:getLife() < Event.TgtDCSUnit:getLife0() then
self:T( { "Life: ", Event.TgtDCSUnitName, ' = ', Event.TgtUnit:GetLife(), "/", Event.TgtUnit:GetLife0() } )
if Event.TgtUnit:GetLife() < Event.TgtUnit:GetLife0() then
self:T( "CleanUp: Destroy: " .. Event.TgtDCSUnitName )
CLEANUP:_DestroyUnit( Event.TgtUnit )
CLEANUP.__:DestroyUnit( Event.TgtUnit )
end
end
end
end
--- Add the @{DCSWrapper.Unit#Unit} to the CleanUpList for CleanUp.
function CLEANUP:_AddForCleanUp( CleanUpUnit, CleanUpUnitName )
-- @param #CLEANUP self
-- @param Wrapper.Unit#UNIT CleanUpUnit
-- @oaram #string CleanUpUnitName
function CLEANUP.__:AddForCleanUp( CleanUpUnit, CleanUpUnitName )
self:F( { CleanUpUnit, CleanUpUnitName } )
self.CleanUpList[CleanUpUnitName] = {}
self.CleanUpList[CleanUpUnitName].CleanUpUnit = CleanUpUnit
self.CleanUpList[CleanUpUnitName].CleanUpUnitName = CleanUpUnitName
self.CleanUpList[CleanUpUnitName].CleanUpGroup = Unit.getGroup(CleanUpUnit)
self.CleanUpList[CleanUpUnitName].CleanUpGroupName = Unit.getGroup(CleanUpUnit):getName()
local CleanUpGroup = CleanUpUnit:GetGroup()
self.CleanUpList[CleanUpUnitName].CleanUpGroup = CleanUpGroup
self.CleanUpList[CleanUpUnitName].CleanUpGroupName = CleanUpGroup:GetName()
self.CleanUpList[CleanUpUnitName].CleanUpTime = timer.getTime()
self.CleanUpList[CleanUpUnitName].CleanUpMoved = false
self:T( { "CleanUp: Add to CleanUpList: ", Unit.getGroup(CleanUpUnit):getName(), CleanUpUnitName } )
self:T( { "CleanUp: Add to CleanUpList: ", CleanUpGroup:GetName(), CleanUpUnitName } )
end
--- Detects if the Unit has an S_EVENT_ENGINE_SHUTDOWN or an S_EVENT_HIT within the given AirbaseNames. If this is the case, add the Group to the CLEANUP List.
-- @param #CLEANUP self
-- @param #CLEANUP.__ self
-- @param Core.Event#EVENTDATA Event
function CLEANUP:_EventAddForCleanUp( Event )
function CLEANUP.__:EventAddForCleanUp( Event )
self:F({Event})
if Event.IniDCSUnit then
if Event.IniDCSUnit and Event.IniCategory == Object.Category.UNIT then
if self.CleanUpList[Event.IniDCSUnitName] == nil then
if self:IsInAirbase( Event.IniUnit:GetVec2() ) then
self:_AddForCleanUp( Event.IniDCSUnit, Event.IniDCSUnitName )
self:AddForCleanUp( Event.IniUnit, Event.IniDCSUnitName )
end
end
end
if Event.TgtDCSUnit then
if Event.TgtDCSUnit and Event.TgtCategory == Object.Category.UNIT then
if self.CleanUpList[Event.TgtDCSUnitName] == nil then
if self:IsInAirbase( Event.TgtUnit:GetVec2() ) then
self:_AddForCleanUp( Event.TgtDCSUnit, Event.TgtDCSUnitName )
self:AddForCleanUp( Event.TgtUnit, Event.TgtDCSUnitName )
end
end
end
@@ -276,23 +318,23 @@ end
--- At the defined time interval, CleanUp the Groups within the CleanUpList.
-- @param #CLEANUP self
function CLEANUP:_CleanUpScheduler()
function CLEANUP.__:CleanUpScheduler()
local CleanUpCount = 0
for CleanUpUnitName, UnitData in pairs( self.CleanUpList ) do
for CleanUpUnitName, CleanUpListData in pairs( self.CleanUpList ) do
CleanUpCount = CleanUpCount + 1
local CleanUpUnit = UNIT:FindByName( CleanUpUnitName )
local CleanUpDCSUnit = Unit.getByName( CleanUpUnitName )
local CleanUpGroupName = UnitData.CleanUpGroupName
local CleanUpUnit = CleanUpListData.CleanUpUnit -- Wrapper.Unit#UNIT
local CleanUpGroupName = CleanUpListData.CleanUpGroupName
if CleanUpUnit then
if CleanUpUnit:IsAlive() ~= nil then
if _DATABASE:GetStatusGroup( CleanUpGroupName ) ~= "ReSpawn" then
local CleanUpCoordinate = CleanUpUnit:GetCoordinate()
if CleanUpDCSUnit and CleanUpDCSUnit:getLife() <= CleanUpDCSUnit:getLife0() * 0.95 then
self:T( { "CleanUp Scheduler", CleanUpUnitName } )
if CleanUpUnit:GetLife() <= CleanUpUnit:GetLife0() * 0.95 then
if CleanUpUnit:IsAboveRunway() then
if CleanUpUnit:InAir() then
@@ -301,11 +343,11 @@ function CLEANUP:_CleanUpScheduler()
if CleanUpUnitHeight < 30 then
self:T( { "CleanUp Scheduler", "Destroy " .. CleanUpUnitName .. " because below safe height and damaged." } )
self:_DestroyUnit( CleanUpUnit )
self:DestroyUnit( CleanUpUnit )
end
else
self:T( { "CleanUp Scheduler", "Destroy " .. CleanUpUnitName .. " because on runway and damaged." } )
self:_DestroyUnit(CleanUpUnit )
self:DestroyUnit( CleanUpUnit )
end
end
end
@@ -313,15 +355,15 @@ function CLEANUP:_CleanUpScheduler()
if CleanUpUnit then
local CleanUpUnitVelocity = CleanUpUnit:GetVelocityKMH()
if CleanUpUnitVelocity < 1 then
if UnitData.CleanUpMoved then
if UnitData.CleanUpTime + 180 <= timer.getTime() then
if CleanUpListData.CleanUpMoved then
if CleanUpListData.CleanUpTime + 180 <= timer.getTime() then
self:T( { "CleanUp Scheduler", "Destroy due to not moving anymore " .. CleanUpUnitName } )
self:_DestroyUnit( CleanUpUnit )
self:DestroyUnit( CleanUpUnit )
end
end
else
UnitData.CleanUpTime = timer.getTime()
UnitData.CleanUpMoved = true
CleanUpListData.CleanUpTime = timer.getTime()
CleanUpListData.CleanUpMoved = true
end
end