/* * Author: Needles * https://steamcommunity.com/profiles/76561198026257137/ */ ::Debug.Print("*** ENT_TRACKER"); ::EntTracker <- {}; ::EntTracker.trackedEntTable <- {}; function EntTracker::AddClassname(classname) { if (classname in ::EntTracker.trackedEntTable) return; ::EntTracker.trackedEntTable[classname] <- {}; } function EntTracker::RemoveClassname(classname) { if (!(classname in ::EntTracker.trackedEntTable)) return; ::EntTracker.trackedEntTable.rawdelete(classname); } /* * When the OnRemove function is called, the entity will already have been destroyed and is now invalid. * We need to keep a copy of important entity data so that event listeners can see it after the entity becomes invalid. */ function EntTracker::SyncTrackedEnt(ent, trackedEntData) { trackedEntData.handle = ent; trackedEntData.classname = ent.GetClassname(); trackedEntData.start = ent.GetOrigin(); trackedEntData.origin = ent.GetOrigin(); trackedEntData.angles = ent.GetAbsAngles(); trackedEntData.owner = ent.GetOwner(); trackedEntData.team = ent.GetTeam(); } function EntTracker::AddTrackedEnt(classname, ent) { if (!(classname in ::EntTracker.trackedEntTable)) return; if (ent in ::EntTracker.trackedEntTable[classname]) return; local trackedEntData = { handle = null, classname = null, start = null, origin = null, angles = null, owner = null, team = null, }; ::EntTracker.SyncTrackedEnt(ent, trackedEntData); ::EntTracker.trackedEntTable[classname][ent] <- trackedEntData; } function EntTracker::RemoveTrackedEnt(classname, ent) { if (!(classname in ::EntTracker.trackedEntTable)) return; if (!(ent in ::EntTracker.trackedEntTable[classname])) return; ::EntTracker.trackedEntTable[classname].rawdelete(ent); } function EntTracker::Tick() { foreach(classname, entTable in ::EntTracker.trackedEntTable) { ::EntTracker.UpdateAllEntTrackers(classname); } } function EntTracker::FindTrackedEntityData(entity) { if (!(entity in ::EntTracker.trackedEntTable[entity.GetClassname()])) return null; return ::EntTracker.trackedEntTable[entity.GetClassname()][entity]; } function EntTracker::UpdateAllEntTrackers(classname) { local toAdd = []; local toRemove = []; local existingEntList = ::Utils.FindAllByClassname(classname); local existingEntLookupTable = {}; /* * If any of the existing entities are not being tracked, then add them to the tracker. * If a tracked entity doesn't exist anymore, then remove it from the tracker. */ foreach (ent in existingEntList) { existingEntLookupTable[ent] <- null; if (ent in ::EntTracker.trackedEntTable[classname]) { if (ent && ent.IsValid()) { local trackedEntData = ::EntTracker.trackedEntTable[classname][ent]; ::EntTracker.SyncTrackedEnt(ent, trackedEntData); } } else { toAdd.append(ent); } } foreach (ent, _ in ::EntTracker.trackedEntTable[classname]) { if (!(ent in existingEntLookupTable)) toRemove.append(ent); } foreach (ent in toRemove) { ::EntTracker.OnRemove(::EntTracker.trackedEntTable[classname][ent]); ::EntTracker.RemoveTrackedEnt(classname, ent); } foreach (ent in toAdd) { ::EntTracker.AddTrackedEnt(classname, ent); ::EntTracker.OnAdd(::EntTracker.trackedEntTable[classname][ent]); } } function EntTracker::OnAdd(trackedEntData) { ::Debug.Print("*** ENT_TRACKER - OnAdd"); __DumpScope(0, trackedEntData); ::Events.GetGlobalEvent(EVENT.ENT_TRACKER_SPAWN).FireListeners(trackedEntData); ::Handler.HandleEvent(EVENT.ENT_TRACKER_SPAWN, trackedEntData); } function EntTracker::OnRemove(trackedEntData) { ::Debug.Print("*** ENT_TRACKER - OnRemove"); __DumpScope(0, trackedEntData); ::Events.GetGlobalEvent(EVENT.ENT_TRACKER_KILL).FireListeners(trackedEntData); ::Handler.HandleEvent(EVENT.ENT_TRACKER_KILL, trackedEntData); } ::Events.GetGlobalEvent(EVENT.TICK).AddListener(function(params) { ::EntTracker.Tick(); });