From b2193cc038c40d943c4cfaaedececc368ea879c0 Mon Sep 17 00:00:00 2001 From: admin Date: Tue, 24 Feb 2026 12:13:34 +0000 Subject: [PATCH] Update main.lua --- main.lua | 170 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 119 insertions(+), 51 deletions(-) diff --git a/main.lua b/main.lua index 5a420ca..8c68134 100644 --- a/main.lua +++ b/main.lua @@ -105,6 +105,7 @@ local DEFAULT_SETTINGS = { espTextSize = 15, espRefreshMs = 150, espMaxDistance = 1500, + espInactiveDetection = false, teleportViewKey = "V", teleportPointKey = "Equals", @@ -236,6 +237,7 @@ local function loadSettings() settings.espTextSize = math.floor(clampNumber(parsed.espTextSize, 10, 22, settings.espTextSize) + 0.5) settings.espRefreshMs = math.floor(clampNumber(parsed.espRefreshMs, 33, 500, settings.espRefreshMs) + 0.5) settings.espMaxDistance = math.floor(clampNumber(parsed.espMaxDistance, 50, 10000, settings.espMaxDistance) + 0.5) + settings.espInactiveDetection = readBoolean(parsed.espInactiveDetection, settings.espInactiveDetection) settings.teleportViewKey = normaliseKeyName(parsed.teleportViewKey, settings.teleportViewKey) settings.teleportPointKey = normaliseKeyName(parsed.teleportPointKey, settings.teleportPointKey) @@ -1737,6 +1739,36 @@ end local espEntries = {} local espAccumulator = 0 local espWasEnabledLastTick = false +local espActivityStates = {} + +local ESP_INACTIVE_TIMEOUT_SECONDS = 60 +local ESP_INACTIVE_POSITION_EPSILON = 0.35 + +local function clearEspActivityState(player) + espActivityStates[player] = nil +end + +local function isEspPlayerInactive(player, rootPart, nowTime) + local state = espActivityStates[player] + local position = rootPart.Position + + if not state then + espActivityStates[player] = { + lastPosition = position, + lastMovedAt = nowTime + } + return false + end + + if (position - state.lastPosition).Magnitude > ESP_INACTIVE_POSITION_EPSILON then + state.lastPosition = position + state.lastMovedAt = nowTime + return false + end + + state.lastPosition = position + return (nowTime - state.lastMovedAt) >= ESP_INACTIVE_TIMEOUT_SECONDS +end local function hideEspEntry(entry) if not entry then @@ -1787,6 +1819,7 @@ local function destroyEspEntry(player) end espEntries[player] = nil + clearEspActivityState(player) end local function getEspEntry(player) @@ -1849,6 +1882,7 @@ local function updateEsp() if espWasEnabledLastTick then hideAllEspEntries() end + espActivityStates = {} espWasEnabledLastTick = false return end @@ -1873,6 +1907,8 @@ local function updateEsp() local maxDistance = settings.espMaxDistance local textSize = settings.espTextSize local useDistanceIndicator = showTracers and settings.espDistanceIndicator + local nowTime = os.clock() + local inactivePlayers = settings.espInactiveDetection and {} or nil local nearestDistance = nil local furthestDistance = nil @@ -1885,15 +1921,25 @@ local function updateEsp() local rootPart = character and character:FindFirstChild("HumanoidRootPart") if humanoid and humanoid.Health > 0 and rootPart then - local distance = (rootPart.Position - cameraPosition).Magnitude - if distance <= maxDistance then - if not nearestDistance or distance < nearestDistance then - nearestDistance = distance - end - if not furthestDistance or distance > furthestDistance then - furthestDistance = distance + local isInactive = false + if inactivePlayers then + isInactive = isEspPlayerInactive(player, rootPart, nowTime) + inactivePlayers[player] = isInactive + end + + if not isInactive then + local distance = (rootPart.Position - cameraPosition).Magnitude + if distance <= maxDistance then + if not nearestDistance or distance < nearestDistance then + nearestDistance = distance + end + if not furthestDistance or distance > furthestDistance then + furthestDistance = distance + end end end + elseif inactivePlayers then + clearEspActivityState(player) end end end @@ -1911,67 +1957,80 @@ local function updateEsp() local rootPart = character and character:FindFirstChild("HumanoidRootPart") if humanoid and humanoid.Health > 0 and head and rootPart then - local distance = (rootPart.Position - cameraPosition).Magnitude - if distance <= maxDistance then - local rootPosition, rootOnScreen = Camera:WorldToViewportPoint(rootPart.Position) - local headPosition, headOnScreen = Camera:WorldToViewportPoint(head.Position + Vector3.new(0, 0.5, 0)) + local isInactive = false + if inactivePlayers then + if inactivePlayers[player] == nil then + inactivePlayers[player] = isEspPlayerInactive(player, rootPart, nowTime) + end + isInactive = inactivePlayers[player] + end - if rootOnScreen and headOnScreen and rootPosition.Z > 0 and headPosition.Z > 0 then - if showText then - local roundedDistance = math.floor(distance + 0.5) + if isInactive then + hideEspEntry(entry) + else + local distance = (rootPart.Position - cameraPosition).Magnitude + if distance <= maxDistance then + local rootPosition, rootOnScreen = Camera:WorldToViewportPoint(rootPart.Position) + local headPosition, headOnScreen = Camera:WorldToViewportPoint(head.Position + Vector3.new(0, 0.5, 0)) - if settings.espShowName and settings.espShowDistance then - entry.text.Text = player.Name .. " [" .. roundedDistance .. "m]" - elseif settings.espShowName then - entry.text.Text = player.Name - else - entry.text.Text = roundedDistance .. "m" - end + if rootOnScreen and headOnScreen and rootPosition.Z > 0 and headPosition.Z > 0 then + if showText then + local roundedDistance = math.floor(distance + 0.5) - entry.text.Size = textSize - entry.text.Position = Vector2.new(headPosition.X, headPosition.Y - 18) - entry.text.Visible = true - else - entry.text.Visible = false - end - - if showTracers then - entry.line.From = tracerOrigin - entry.line.To = Vector2.new(headPosition.X, headPosition.Y) - - if useDistanceIndicator then - if nearestDistance and furthestDistance and furthestDistance > nearestDistance then - local ratio = math.clamp((distance - nearestDistance) / (furthestDistance - nearestDistance), 0, 1) - entry.line.Color = Color3.new(1, ratio, ratio) + if settings.espShowName and settings.espShowDistance then + entry.text.Text = player.Name .. " [" .. roundedDistance .. "m]" + elseif settings.espShowName then + entry.text.Text = player.Name else - entry.line.Color = Color3.fromRGB(255, 64, 64) + entry.text.Text = roundedDistance .. "m" end + + entry.text.Size = textSize + entry.text.Position = Vector2.new(headPosition.X, headPosition.Y - 18) + entry.text.Visible = true else - entry.line.Color = Color3.fromRGB(255, 255, 255) + entry.text.Visible = false end - entry.line.Visible = true - else - entry.line.Visible = false - end + if showTracers then + entry.line.From = tracerOrigin + entry.line.To = Vector2.new(headPosition.X, headPosition.Y) - if showBox then - local height = math.max(math.abs(rootPosition.Y - headPosition.Y) * 2.2, 16) - local width = math.max(height * 0.62, 10) + if useDistanceIndicator then + if nearestDistance and furthestDistance and furthestDistance > nearestDistance then + local ratio = math.clamp((distance - nearestDistance) / (furthestDistance - nearestDistance), 0, 1) + entry.line.Color = Color3.new(1, ratio, ratio) + else + entry.line.Color = Color3.fromRGB(255, 64, 64) + end + else + entry.line.Color = Color3.fromRGB(255, 255, 255) + end - entry.box.Size = Vector2.new(width, height) - entry.box.Position = Vector2.new(rootPosition.X - width * 0.5, rootPosition.Y - height * 0.9) - entry.box.Visible = true + entry.line.Visible = true + else + entry.line.Visible = false + end + + if showBox then + local height = math.max(math.abs(rootPosition.Y - headPosition.Y) * 2.2, 16) + local width = math.max(height * 0.62, 10) + + entry.box.Size = Vector2.new(width, height) + entry.box.Position = Vector2.new(rootPosition.X - width * 0.5, rootPosition.Y - height * 0.9) + entry.box.Visible = true + else + entry.box.Visible = false + end else - entry.box.Visible = false + hideEspEntry(entry) end else hideEspEntry(entry) end - else - hideEspEntry(entry) end else + clearEspActivityState(player) hideEspEntry(entry) end end @@ -2200,6 +2259,14 @@ end, function(value) saveSettings() end, 50, 10000) +addToggleRow(PlayersPage, "Inactive player detection", function() + return settings.espInactiveDetection +end, function(state) + settings.espInactiveDetection = state + espActivityStates = {} + saveSettings() +end) + if not hasDrawing then addActionRow(PlayersPage, "Drawing API", "Unavailable", function() end) @@ -2331,6 +2398,7 @@ addActionRow(ConfigPage, "Reset", "Defaults", function() espAccumulator = 0 espWasEnabledLastTick = false + espActivityStates = {} selectedTeleportPointIndex = 1 selectedTeleportPlayerIndex = 1 selectedTeleportPlayerUserId = nil