--This watermark is used to delete the file if its cached, remove it to make the file persist after vape updates. local entitylib = { isAlive = false, character = {}, List = {}, Connections = {}, PlayerConnections = {}, EntityThreads = {}, Running = false, Events = setmetatable({}, { __index = function(self, ind) self[ind] = { Connections = {}, Connect = function(rself, func) table.insert(rself.Connections, func) return { Disconnect = function() local rind = table.find(rself.Connections, func) if rind then table.remove(rself.Connections, rind) end end } end, Fire = function(rself, ...) for _, v in rself.Connections do task.spawn(v, ...) end end, Destroy = function(rself) table.clear(rself.Connections) table.clear(rself) end } return self[ind] end }) } local cloneref = cloneref or function(obj) return obj end local playersService = cloneref(game:GetService('Players')) local inputService = cloneref(game:GetService('UserInputService')) local lplr = playersService.LocalPlayer local gameCamera = workspace.CurrentCamera local function getMousePosition() if inputService.TouchEnabled then return gameCamera.ViewportSize / 2 end return inputService.GetMouseLocation(inputService) end local function loopClean(tbl) for i, v in tbl do if type(v) == 'table' then loopClean(v) end tbl[i] = nil end end local function waitForChildOfType(obj, name, timeout, prop) local checktick = tick() + timeout local returned repeat returned = prop and obj[name] or obj:FindFirstChildOfClass(name) if returned or checktick < tick() then break end task.wait() until false return returned end entitylib.targetCheck = function(ent) if ent.TeamCheck then return ent:TeamCheck() end if ent.NPC then return true end if not lplr.Team then return true end if not ent.Player.Team then return true end if ent.Player.Team ~= lplr.Team then return true end return #ent.Player.Team:GetPlayers() == #playersService:GetPlayers() end entitylib.getUpdateConnections = function(ent) local hum = ent.Humanoid return { hum:GetPropertyChangedSignal('Health'), hum:GetPropertyChangedSignal('MaxHealth') } end entitylib.isVulnerable = function(ent) return ent.Health > 0 and not ent.Character.FindFirstChildWhichIsA(ent.Character, 'ForceField') end entitylib.getEntityColor = function(ent) ent = ent.Player return ent and tostring(ent.TeamColor) ~= 'White' and ent.TeamColor.Color or nil end entitylib.IgnoreObject = RaycastParams.new() entitylib.IgnoreObject.RespectCanCollide = true entitylib.Wallcheck = function(origin, position, ignoreobject) if typeof(ignoreobject) ~= 'Instance' then local ignorelist = {gameCamera, lplr.Character} for _, v in entitylib.List do if v.Targetable then table.insert(ignorelist, v.Character) end end if typeof(ignoreobject) == 'table' then for _, v in ignoreobject do table.insert(ignorelist, v) end end ignoreobject = entitylib.IgnoreObject ignoreobject.FilterDescendantsInstances = ignorelist end return workspace.Raycast(workspace, origin, (position - origin), ignoreobject) end entitylib.EntityMouse = function(entitysettings) if entitylib.isAlive then local mouseLocation, sortingTable = entitysettings.MouseOrigin or getMousePosition(), {} for _, v in entitylib.List do if not entitysettings.Players and v.Player then continue end if not entitysettings.NPCs and v.NPC then continue end if not v.Targetable then continue end local position, vis = gameCamera.WorldToViewportPoint(gameCamera, v[entitysettings.Part].Position) if not vis then continue end local mag = (mouseLocation - Vector2.new(position.x, position.y)).Magnitude if mag > entitysettings.Range then continue end if entitylib.isVulnerable(v) then table.insert(sortingTable, { Entity = v, Magnitude = v.Target and -1 or mag }) end end table.sort(sortingTable, entitysettings.Sort or function(a, b) return a.Magnitude < b.Magnitude end) for _, v in sortingTable do if entitysettings.Wallcheck then if entitylib.Wallcheck(entitysettings.Origin, v.Entity[entitysettings.Part].Position, entitysettings.Wallcheck) then continue end end table.clear(entitysettings) table.clear(sortingTable) return v.Entity end table.clear(sortingTable) end table.clear(entitysettings) end entitylib.EntityPosition = function(entitysettings) if entitylib.isAlive then local localPosition, sortingTable = entitysettings.Origin or entitylib.character.HumanoidRootPart.Position, {} for _, v in entitylib.List do if not entitysettings.Players and v.Player then continue end if not entitysettings.NPCs and v.NPC then continue end if not v.Targetable then continue end local mag = (v[entitysettings.Part].Position - localPosition).Magnitude if mag > entitysettings.Range then continue end if entitylib.isVulnerable(v) then table.insert(sortingTable, { Entity = v, Magnitude = v.Target and -1 or mag }) end end table.sort(sortingTable, entitysettings.Sort or function(a, b) return a.Magnitude < b.Magnitude end) for _, v in sortingTable do if entitysettings.Wallcheck then if entitylib.Wallcheck(localPosition, v.Entity[entitysettings.Part].Position, entitysettings.Wallcheck) then continue end end table.clear(entitysettings) table.clear(sortingTable) return v.Entity end table.clear(sortingTable) end table.clear(entitysettings) end entitylib.AllPosition = function(entitysettings) local returned = {} if entitylib.isAlive then local localPosition, sortingTable = entitysettings.Origin or entitylib.character.HumanoidRootPart.Position, {} for _, v in entitylib.List do if not entitysettings.Players and v.Player then continue end if not entitysettings.NPCs and v.NPC then continue end if not v.Targetable then continue end local mag = (v[entitysettings.Part].Position - localPosition).Magnitude if mag > entitysettings.Range then continue end if entitylib.isVulnerable(v) then table.insert(sortingTable, {Entity = v, Magnitude = v.Target and -1 or mag}) end end table.sort(sortingTable, entitysettings.Sort or function(a, b) return a.Magnitude < b.Magnitude end) for _, v in sortingTable do if entitysettings.Wallcheck then if entitylib.Wallcheck(localPosition, v.Entity[entitysettings.Part].Position, entitysettings.Wallcheck) then continue end end table.insert(returned, v.Entity) if #returned >= (entitysettings.Limit or math.huge) then break end end table.clear(sortingTable) end table.clear(entitysettings) return returned end entitylib.getEntity = function(char) for i, v in entitylib.List do if v.Player == char or v.Character == char then return v, i end end end entitylib.addEntity = function(char, plr, teamfunc) if not char then return end entitylib.EntityThreads[char] = task.spawn(function() local hum = waitForChildOfType(char, 'Humanoid', 10) local humrootpart = hum and waitForChildOfType(hum, 'RootPart', workspace.StreamingEnabled and 9e9 or 10, true) local head = char:WaitForChild('Head', 10) or humrootpart if hum and humrootpart then local entity = { Connections = {}, Character = char, Health = hum.Health, Head = head, Humanoid = hum, HumanoidRootPart = humrootpart, HipHeight = hum.HipHeight + (humrootpart.Size.Y / 2) + (hum.RigType == Enum.HumanoidRigType.R6 and 2 or 0), MaxHealth = hum.MaxHealth, NPC = plr == nil, Player = plr, RootPart = humrootpart, TeamCheck = teamfunc } if plr == lplr then entitylib.character = entity entitylib.isAlive = true entitylib.Events.LocalAdded:Fire(entity) else entity.Targetable = entitylib.targetCheck(entity) for _, v in entitylib.getUpdateConnections(entity) do table.insert(entity.Connections, v:Connect(function() entity.Health = hum.Health entity.MaxHealth = hum.MaxHealth entitylib.Events.EntityUpdated:Fire(entity) end)) end table.insert(entitylib.List, entity) entitylib.Events.EntityAdded:Fire(entity) end --[[table.insert(entity.Connections, char.ChildRemoved:Connect(function(part) if (part == humrootpart or part == hum or part == head) then local found = char:FindFirstChild(part.Name) if found then if part == humrootpart then entity.HumanoidRootPart = found entity.RootPart = found humrootpart = found return elseif part == head then entity.Head = found head = found return end end entitylib.removeEntity(char, plr == lplr) end end))]] end entitylib.EntityThreads[char] = nil end) end entitylib.removeEntity = function(char, localcheck) if localcheck then if entitylib.isAlive then entitylib.isAlive = false for _, v in entitylib.character.Connections do v:Disconnect() end table.clear(entitylib.character.Connections) entitylib.Events.LocalRemoved:Fire(entitylib.character) --table.clear(entitylib.character) end return end if char then if entitylib.EntityThreads[char] then task.cancel(entitylib.EntityThreads[char]) entitylib.EntityThreads[char] = nil end local entity, ind = entitylib.getEntity(char) if ind then for _, v in entity.Connections do v:Disconnect() end table.clear(entity.Connections) table.remove(entitylib.List, ind) entitylib.Events.EntityRemoved:Fire(entity) end end end entitylib.refreshEntity = function(char, plr) entitylib.removeEntity(char) entitylib.addEntity(char, plr) end entitylib.addPlayer = function(plr) if plr.Character then entitylib.refreshEntity(plr.Character, plr) end entitylib.PlayerConnections[plr] = { plr.CharacterAdded:Connect(function(char) entitylib.refreshEntity(char, plr) end), plr.CharacterRemoving:Connect(function(char) entitylib.removeEntity(char, plr == lplr) end), plr:GetPropertyChangedSignal('Team'):Connect(function() for _, v in entitylib.List do if v.Targetable ~= entitylib.targetCheck(v) then entitylib.refreshEntity(v.Character, v.Player) end end if plr == lplr then entitylib.start() else entitylib.refreshEntity(plr.Character, plr) end end) } end entitylib.removePlayer = function(plr) if entitylib.PlayerConnections[plr] then for _, v in entitylib.PlayerConnections[plr] do v:Disconnect() end table.clear(entitylib.PlayerConnections[plr]) entitylib.PlayerConnections[plr] = nil end entitylib.removeEntity(plr) end entitylib.start = function() if entitylib.Running then entitylib.stop() end table.insert(entitylib.Connections, playersService.PlayerAdded:Connect(function(v) entitylib.addPlayer(v) end)) table.insert(entitylib.Connections, playersService.PlayerRemoving:Connect(function(v) entitylib.removePlayer(v) end)) for _, v in playersService:GetPlayers() do entitylib.addPlayer(v) end table.insert(entitylib.Connections, workspace:GetPropertyChangedSignal('CurrentCamera'):Connect(function() gameCamera = workspace.CurrentCamera or workspace:FindFirstChildWhichIsA('Camera') end)) entitylib.Running = true end entitylib.stop = function() for _, v in entitylib.Connections do v:Disconnect() end for _, v in entitylib.PlayerConnections do for _, v2 in v do v2:Disconnect() end table.clear(v) end entitylib.removeEntity(nil, true) local cloned = table.clone(entitylib.List) for _, v in cloned do entitylib.removeEntity(v.Character) end for _, v in entitylib.EntityThreads do task.cancel(v) end table.clear(entitylib.PlayerConnections) table.clear(entitylib.EntityThreads) table.clear(entitylib.Connections) table.clear(cloned) entitylib.Running = false end entitylib.kill = function() if entitylib.Running then entitylib.stop() end for _, v in entitylib.Events do v:Destroy() end entitylib.IgnoreObject:Destroy() loopClean(entitylib) end entitylib.refresh = function() local cloned = table.clone(entitylib.List) for _, v in cloned do entitylib.refreshEntity(v.Character, v.Player) end table.clear(cloned) end entitylib.start() return entitylib