diff --git a/Base.lua b/Base.lua index bce903600..3101bba8a 100644 --- a/Base.lua +++ b/Base.lua @@ -52,7 +52,7 @@ function BASE:Inherit( Child, Parent ) setmetatable( Child, Parent ) Child.__index = Child end - Child.ClassName = Child.ClassName .. '.' .. Child.ClassID + --Child.ClassName = Child.ClassName .. '.' .. Child.ClassID trace.i( Child.ClassName, 'Inherited from ' .. Parent.ClassName ) return Child end @@ -103,9 +103,36 @@ trace.f( self.ClassName ) return self end + +BaseEventCodes = { + "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", + } function BASE:onEvent(event) -trace.f(self.ClassName, event ) +--trace.f(self.ClassName, event ) --env.info( 'onEvent Table self = ' .. tostring(self) ) if self then @@ -116,6 +143,7 @@ trace.f(self.ClassName, event ) --env.info( 'onEvent EventObject.Event = ' .. tostring(EventObject.Event) ) if event.id == EventObject.Event then if self == EventObject.Self then + trace.i( self.ClassName, { BaseEventCodes[event.id], event } ) EventObject.EventFunction( self, event ) end end diff --git a/CleanUp.lua b/CleanUp.lua index 460630dd8..d756b2cb7 100644 --- a/CleanUp.lua +++ b/CleanUp.lua @@ -40,8 +40,11 @@ trace.f( self.ClassName, { ZoneNames, TimeInterval } ) end self:AddEvent( world.event.S_EVENT_ENGINE_SHUTDOWN, self._EventAddForCleanUp ) - self:AddEvent( world.event.S_EVENT_HIT, self._EventAddForCleanUp ) - self:AddEvent( world.event.S_EVENT_DEAD, 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() self.CleanUpFunction = routines.scheduleFunction( self._Scheduler, { self }, timer.getTime() + 1, TimeInterval ) @@ -49,6 +52,196 @@ trace.f( self.ClassName, { ZoneNames, TimeInterval } ) return self end + +--- Destroys a group from the simulator, but checks first if it is still existing! +-- @see CLEANUP +function CLEANUP:_DestroyGroup( GroupObject, CleanUpGroupName ) +trace.f( self.ClassName ) + + if GroupObject then -- and GroupObject:isExist() then + MESSAGE:New( "Destroy " .. CleanUpGroupName, CleanUpGroupName, 10, CleanUpGroupName ):ToAll() + trigger.action.deactivateGroup(GroupObject) + trace.i(self.ClassName, "GroupObject Destroyed") + end +end + +--- Destroys a unit from the simulator, but checks first if it is still existing! +-- @see CLEANUP +function CLEANUP:_DestroyUnit( CleanUpUnitObject, CleanUpUnitName ) +trace.f( self.ClassName ) + + if CleanUpUnitObject then + MESSAGE:New( "Destroy " .. CleanUpUnitName, CleanUpUnitName, 10, CleanUpUnitName ):ToAll() + CleanUpUnitObject:destroy() + trace.i(self.ClassName, "UnitObject Destroyed") + end +end + +--- Destroys a missile from the simulator, but checks first if it is still existing! +-- @see CLEANUP +function CLEANUP:_DestroyMissile( MissileObject ) +trace.f( self.ClassName ) + + if MissileObject and MissileObject:isExist() then + MissileObject:destroy() + trace.i(self.ClassName, "MissileObject Destroyed") + end +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 CLEANUP +function CLEANUP:_EventCrash( event ) +trace.f( self.ClassName ) + + MESSAGE:New( "Crash ", "Crash", 10, "Crash" ):ToAll() + trace.i(self.ClassName,"before getGroup") + local _grp = Unit.getGroup(event.initiator)-- Identify the group that fired + trace.i(self.ClassName,"after getGroup") + _grp:destroy() + trace.i(self.ClassName,"after deactivateGroup") + event.initiator:destroy() + + + +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 CLEANUP +function CLEANUP:_EventShot( event ) +trace.f( self.ClassName ) + + 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 + --trace.i( self.ClassName, "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 ) + 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) + end + +--[[ + if _SEADmissileName == "KH-58" or _SEADmissileName == "KH-25MPU" or _SEADmissileName == "AGM-88" or _SEADmissileName == "KH-31A" or _SEADmissileName == "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(_SEADmissile) -- Identify target + local _targetMimname = Unit.getName(_targetMim) + local _targetMimgroup = Unit.getGroup(Weapon.getTarget(_SEADmissile)) + local _targetMimgroupName = _targetMimgroup:getName() + local _targetMimcont= _targetMimgroup:getController() + local _targetskill = _Database.Units[_targetMimname].Template.skill + trace.i( self.ClassName, self.SEADGroupPrefixes ) + trace.i( self.ClassName, _targetMimgroupName ) + local SEADGroupFound = false + for SEADGroupPrefixID, SEADGroupPrefix in pairs( self.SEADGroupPrefixes ) do + if string.find( _targetMimgroupName, SEADGroupPrefix, 1, true ) then + SEADGroupFound = true + trace.i( self.ClassName, 'Group Found' ) + break + end + end + if SEADGroupFound == true then + if _targetskill == "Random" then -- when skill is random, choose a skill + local Skills = { "Average", "Good", "High", "Excellent" } + _targetskill = Skills[ math.random(1,4) ] + end + trace.i( self.ClassName, _targetskill ) -- debug message for skill check + if self.TargetSkill[_targetskill] then + if (_evade > self.TargetSkill[_targetskill].Evade) then + trace.i( self.ClassName, string.format("Evading, target skill " ..string.format(_targetskill)) ) --debug message + local _targetMim = Weapon.getTarget(_SEADmissile) + local _targetMimname = Unit.getName(_targetMim) + local _targetMimgroup = Unit.getGroup(Weapon.getTarget(_SEADmissile)) + local _targetMimcont= _targetMimgroup:getController() + routines.groupRandomDistSelf(_targetMimgroup,300,'Rank',250,20) -- move randomly + local SuppressedGroups1 = {} -- unit suppressed radar off for a random time + local function SuppressionEnd1(id) + id.ctrl:setOption(AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.GREEN) + SuppressedGroups1[id.groupName] = nil + end + local id = { + groupName = _targetMimgroup, + ctrl = _targetMimcont + } + local delay1 = math.random(self.TargetSkill[_targetskill].DelayOff[1], self.TargetSkill[_targetskill].DelayOff[2]) + if SuppressedGroups1[id.groupName] == nil then + SuppressedGroups1[id.groupName] = { + SuppressionEndTime1 = timer.getTime() + delay1, + SuppressionEndN1 = SuppressionEndCounter1 --Store instance of SuppressionEnd() scheduled function + } + Controller.setOption(_targetMimcont, AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.GREEN) + timer.scheduleFunction(SuppressionEnd1, id, SuppressedGroups1[id.groupName].SuppressionEndTime1) --Schedule the SuppressionEnd() function + --trigger.action.outText( string.format("Radar Off " ..string.format(delay1)), 20) + end + + local SuppressedGroups = {} + local function SuppressionEnd(id) + id.ctrl:setOption(AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.RED) + SuppressedGroups[id.groupName] = nil + end + local id = { + groupName = _targetMimgroup, + ctrl = _targetMimcont + } + local delay = math.random(self.TargetSkill[_targetskill].DelayOn[1], self.TargetSkill[_targetskill].DelayOn[2]) + if SuppressedGroups[id.groupName] == nil then + SuppressedGroups[id.groupName] = { + SuppressionEndTime = timer.getTime() + delay, + SuppressionEndN = SuppressionEndCounter --Store instance of SuppressionEnd() scheduled function + } + timer.scheduleFunction(SuppressionEnd, id, SuppressedGroups[id.groupName].SuppressionEndTime) --Schedule the SuppressionEnd() function + --trigger.action.outText( string.format("Radar On " ..string.format(delay)), 20) + end + end + end + end + end + --]] +end + +--- Detects if the Unit has an S_EVENT_HIT within the given ZoneNames. If this is the case, destroy the unit. +function CLEANUP:_EventHitCleanUp( event ) +trace.f( self.ClassName ) + + 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 + local CleanUpGroup = Unit.getGroup(event.initiator)-- Identify the Group + local CleanUpGroupName = CleanUpGroup:getName() -- return the name of the Group + + if routines.IsUnitInZones( CleanUpUnit, self.ZoneNames ) ~= nil then + trace.i( self.ClassName, "Life: " .. CleanUpUnitName .. ' = ' .. CleanUpUnit:getLife() .. "/" .. CleanUpUnit:getLife0() ) + if CleanUpUnit:getLife() < CleanUpUnit:getLife0() then + trace.i( self.ClassName, "CleanUp: Destroy: " .. CleanUpUnitName ) + routines.scheduleFunction( CLEANUP._DestroyUnit, {self, CleanUpUnit}, 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 + trace.i( self.ClassName, "Life: " .. CleanUpTgtUnitName .. ' = ' .. CleanUpTgtUnit:getLife() .. "/" .. CleanUpTgtUnit:getLife0() ) + if CleanUpTgtUnit:getLife() < CleanUpTgtUnit:getLife0() then + trace.i( self.ClassName, "CleanUp: Destroy: " .. CleanUpTgtUnitName ) + routines.scheduleFunction( CLEANUP._DestroyUnit, {self, CleanUpTgtUnit}, timer.getTime() + 0.1) + end + end + end + +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. function CLEANUP:_EventAddForCleanUp( event ) trace.f( self.ClassName, { event } ) @@ -62,10 +255,9 @@ trace.f( self.ClassName, { event } ) local AddForCleanUp = false if routines.IsUnitInZones( CleanUpUnit, self.ZoneNames ) ~= nil then AddForCleanUp = true - env.info( "CleanUp:" .. CleanUpGroupName .. "/" .. CleanUpUnitName ) end if AddForCleanUp == true then - self.CleanUpList[CleanUpGroupName] = CleanUpUnitName + trace.i( self.ClassName, "CleanUp: Add for CleanUp: " .. CleanUpGroupName .. "/" .. CleanUpUnitName ) end end end @@ -77,14 +269,19 @@ trace.f( self.ClassName, { event } ) 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 not self.CleanUpList[CleanUpTgtGroupName] then + if not self.CleanUpList[CleanUpTgtUnitName] then local AddForCleanUp = false if routines.IsUnitInZones( CleanUpTgtUnit, self.ZoneNames ) ~= nil then AddForCleanUp = true - env.info( "CleanUp:" .. CleanUpTgtGroupName .. "/" .. CleanUpTgtUnitName ) + --env.info( "CleanUp:" .. CleanUpTgtGroupName .. "/" .. CleanUpTgtUnitName ) end if AddForCleanUp == true then - self.CleanUpList[CleanUpTgtGroupName] = CleanUpTgtUnitName + trace.i( self.ClassName, "CleanUp: Add for CleanUp: " .. CleanUpTgtGroupName .. "/" .. CleanUpTgtUnitName ) + self.CleanUpList[CleanUpTgtUnitName] = {} + self.CleanUpList[CleanUpTgtUnitName].CleanUpUnit = CleanUpTgtUnit + self.CleanUpList[CleanUpTgtUnitName].CleanUpGroup = CleanUpTgtGroup + self.CleanUpList[CleanUpTgtUnitName].CleanUpGroupName = CleanUpTgtGroupName + self.CleanUpList[CleanUpTgtUnitName].CleanUpUnitName = CleanUpTgtUnitName end end end @@ -95,39 +292,39 @@ end --- At the defined time interval, CleanUp the Groups within the CleanUpList. function CLEANUP:_Scheduler() - for GroupName, ListData in pairs( self.CleanUpList ) do - env.info( "CleanUp: GroupName = " .. GroupName .. " UnitName = " .. ListData ) - local CleanUpGroup = Group.getByName( GroupName ) - local CleanUpUnit = Unit.getByName( ListData ) - if CleanUpUnit and CleanUpGroup then - env.info( "CleanUp: Check Database" ) + for CleanUpUnitName, UnitData in pairs( self.CleanUpList ) do + --env.info( "CleanUp: GroupName = " .. GroupName .. " UnitName = " .. ListData ) + local CleanUpGroup = UnitData.CleanUpGroup + local CleanUpUnit = UnitData.CleanUpUnit + local CleanUpGroupName = UnitData.CleanUpGroupName + local CleanUpUnitName = UnitData.CleanUpUnitName + if CleanUpGroup then + trace.i( self.ClassName, "CleanUp: " .. CleanUpGroupName ) if CleanUpGroup:isExist() and CleanUpUnit:isExist() then - env.info( "CleanUp: Group Existing" ) - if _Database:GetStatusGroup( GroupName ) ~= "ReSpawn" then - env.info( "CleanUp: Database OK" ) + if _Database:GetStatusGroup( CleanUpGroupName ) ~= "ReSpawn" then local CleanUpUnitVelocity = CleanUpUnit:getVelocity() local CleanUpUnitVelocityTotal = math.abs(CleanUpUnitVelocity.x) + math.abs(CleanUpUnitVelocity.y) + math.abs(CleanUpUnitVelocity.z) if CleanUpUnitVelocityTotal < 1 then - env.info( "CleanUp: Destroy: " .. GroupName ) - trigger.action.deactivateGroup(CleanUpGroup) - ListData = nil + trace.i( self.ClassName, "CleanUp: Destroy: " .. CleanUpGroupName ) + self:_DestroyGroup(CleanUpGroup, CleanUpGroupName) + --routines.scheduleFunction( CLEANUP._DestroyGroup, {self, CleanUpGroup}, timer.getTime() + 0.1) + --trigger.action.deactivateGroup(CleanUpGroup) + UnitData = nil end else - ListData = nil + UnitData = nil end else - env.info( "CleanUp: Not Existing anymore, cleaning: " .. GroupName ) - Event = { - id = 8, - time = Time, - initiator = CleanUpUnit, - } - world.onEvent(Event) - trigger.action.deactivateGroup(CleanUpGroup) - ListData = nil + trace.i( self.ClassName, "CleanUp: Does not exist:" .. CleanUpGroupName ) + self:_DestroyUnit(CleanUpUnit, CleanUpUnitName) + --routines.scheduleFunction( CLEANUP._DestroyGroup, {self, CleanUpGroup}, timer.getTime() + 0.1) + UnitData = nil end else - ListData = nil -- Not anymore in the DCSRTE + trace.i( self.ClassName, "CleanUp: Cleaning: " .. CleanUpGroupName ) + self:_DestroyGroup(CleanUpGroup, CleanUpGroupName) + --routines.scheduleFunction( CLEANUP._DestroyGroup, {self, CleanUpGroup}, timer.getTime() + 0.1) + UnitData = nil -- Not anymore in the DCSRTE end end end diff --git a/Install.bat b/Install.bat index 61b8bdd87..864480e42 100644 --- a/Install.bat +++ b/Install.bat @@ -1,4 +1,4 @@ -copy "..\MissionScripting.lua" "..\MissionScripting_old.lua" +copy "%~dp0..\MissionScripting.lua" "%~dp0..\MissionScripting_old.lua" pause -copy "Script_DCS\MissionScripting.lua" "..\MissionScripting.lua" +copy "%~dp0MissionScripting.lua" "%~dp0..\MissionScripting.lua" pause \ No newline at end of file diff --git a/Routines.lua b/Routines.lua index 0db7e9766..2061861f4 100644 --- a/Routines.lua +++ b/Routines.lua @@ -1477,13 +1477,13 @@ trace.f("", "routines.IsUnitInZones" ) end end if TransportZoneResult then - env.info("TransportZone:"..TransportZoneResult) + trace.i( "routines", "TransportZone:" .. TransportZoneResult ) else - env.info("TransportZone:nil logic") + trace.i( "routines", "TransportZone:nil logic" ) end return TransportZoneResult else - env.info("TransportZone:nil hard") + trace.i( "routines", "TransportZone:nil hard" ) return nil end end diff --git a/Trace.lua b/Trace.lua index 5d9eb5b16..58f69fd5c 100644 --- a/Trace.lua +++ b/Trace.lua @@ -4,6 +4,7 @@ trace = {} trace.names = {} +trace.classes = {} trace.scheduledfunction = "" trace.names.all = false @@ -61,6 +62,7 @@ trace.names.FollowPlayers = false trace.names.AddPlayerFromUnit = false trace.names.FromCarrier = false trace.names.OnDeadOrCrash = false +trace.classes.CLEANUP = true trace.cache = {} trace.tracefunction = function( functionname ) @@ -80,7 +82,7 @@ end trace.f = function(object, parameters) local info = debug.getinfo( 2, "nl" ) - if trace.names.all or trace.tracefunction( info.name ) then + if trace.names.all or trace.tracefunction( info.name ) or trace.classes[object] then local objecttrace = "" if object then @@ -250,7 +252,7 @@ trace.i = function(object, variable) if info.name ~= trace.nametrace then trace.nametrace = info.name end - if trace.names.all or trace.tracefunction( trace.nametrace ) then + if trace.names.all or trace.tracefunction( trace.nametrace ) or trace.classes[ object ] then local objecttrace = "" if object then objecttrace = object