📅 2026-07-04T07:28:15.077Z
👁️ 261 katselukertaa
🔓 Julkinen


--phần 1
-- 1. Định nghĩa đầy đủ các dịch vụ hệ thống cốt lõi
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local UserInputService = game:GetService("UserInputService")
local Teams = game:GetService("Teams")
local Camera = Workspace.CurrentCamera
local LocalPlayer = Players.LocalPlayer

-- LƯU LẠI THÔNG SỐ CAMERA BAN ĐẦU CỦA GAME (Chống lỗi zoom khi OFF)
local OriginalCameraMode = LocalPlayer.CameraMode
local OriginalMaxZoom = LocalPlayer.CameraMaxZoomDistance
local OriginalMinZoom = LocalPlayer.CameraMinZoomDistance

-- 2. Khởi tạo bảng trạng thái tính năng chống xung đột toàn cục
local State = { 
    TP_Closest = false, 
    TP_4Far = false, 
    TP_Mid = false,
    Speed_Hack = false,
    Jump_Hack = false,
    Lock_Player = false, 
    Lock_NPC = false, 
    AIM = false,               
    AIM_Player = false,        
    Aim_VatCan_S2 = false,     
    ESP_1 = false,             
    ESP_2 = false,             
    ESP_3 = false,
    Unlock_Camera = false
}

-- KHỞI TẠO KHOẢNG CÁCH MẶC ĐỊNH BẰNG 0 (ĐỨNG GIỮA NGƯỜI CHƠI)
local TargetHeight, LoopDistance = 0, 0
local FOV_Aim_Radius, FOV_Player_Radius, FOV_NPC_Radius = 150, 120, 120
local Aim_Smooth = 5
local Target_Speed = 16 
local Target_Jump = 50
local Max_Zoom_Value = 10000 

local ESPDrawings, ButtonsList = {}, {}
local LockedTarget = nil
local LockedTPTarget = nil

-- Quản lý danh sách đổi người TP không trùng lặp
local TP_Queue = {}
local TP_Pointer = 0

-- 3. Khởi tạo đồ họa vòng tròn FOV bằng Drawing API
local FOVCircle = Drawing.new("Circle")
FOVCircle.Color = Color3.fromRGB(255, 255, 255); FOVCircle.Thickness = 1; FOVCircle.Filled = false; FOVCircle.Visible = false

local CirclePlayer = Drawing.new("Circle")
CirclePlayer.Color = Color3.fromRGB(255, 255, 255); CirclePlayer.Thickness = 1; CirclePlayer.Filled = false; CirclePlayer.Visible = false

local CircleNPC = Drawing.new("Circle")
CircleNPC.Color = Color3.fromRGB(0, 255, 255); CircleNPC.Thickness = 1; CircleNPC.Filled = false; CircleNPC.Visible = false
--phần 2
-- 4. Ép buộc Menu cài vào CoreGui và đặt DisplayOrder tối đa để đè lên mọi UI của game
local CoreGui = game:GetService("CoreGui")
if CoreGui:FindFirstChild("P2077KNG1_0") then CoreGui:FindFirstChild("P2077KNG1_0"):Destroy() end

local ScreenGui = Instance.new("ScreenGui")
ScreenGui.Name = "P2077KNG1_0"
ScreenGui.ResetOnSpawn = false
ScreenGui.DisplayOrder = 999999 
ScreenGui.Parent = CoreGui

local MainFrame = Instance.new("Frame", ScreenGui)
MainFrame.Name = "MainFrame"; MainFrame.Size = UDim2.new(0, 180, 0, 260); MainFrame.Position = UDim2.new(0.05, 0, 0.2, 0)
MainFrame.BackgroundColor3 = Color3.fromRGB(20, 20, 20); MainFrame.BackgroundTransparency = 0.15; MainFrame.ClipsDescendants = true
Instance.new("UICorner", MainFrame).CornerRadius = UDim.new(0, 8)

local ScrollFrame = Instance.new("ScrollingFrame", MainFrame)
ScrollFrame.Name = "ScrollFrame"; ScrollFrame.Size = UDim2.new(1, 0, 1, -35); ScrollFrame.Position = UDim2.new(0, 0, 0, 35)
ScrollFrame.BackgroundTransparency = 1; ScrollFrame.ScrollBarThickness = 3; ScrollFrame.ScrollBarImageColor3 = Color3.fromRGB(120, 120, 120)
ScrollFrame.AutomaticCanvasSize = Enum.AutomaticSize.Y; ScrollFrame.CanvasSize = UDim2.new(0, 0, 0, 0)

local ListLayout = Instance.new("UIListLayout", ScrollFrame)
ListLayout.SortOrder = Enum.SortOrder.LayoutOrder; ListLayout.Padding = UDim.new(0, 5)

local ListPadding = Instance.new("UIPadding", ScrollFrame)
ListPadding.PaddingTop = UDim.new(0, 5); ListPadding.PaddingLeft = UDim.new(0, 8); ListPadding.PaddingRight = UDim.new(0, 8)

local MenuTitle = Instance.new("TextLabel", MainFrame)
MenuTitle.Size = UDim2.new(0, 130, 0, 30); MenuTitle.Position = UDim2.new(0, 10, 0, 2)
MenuTitle.Text = "P2077KNG 1.0"; MenuTitle.TextColor3 = Color3.fromRGB(255, 0, 0); MenuTitle.Font = Enum.Font.SourceSansBold; MenuTitle.TextSize = 11; MenuTitle.BackgroundTransparency = 1

local MinimizeBtn = Instance.new("TextButton", MainFrame)
MinimizeBtn.Size = UDim2.new(0, 25, 0, 25); MinimizeBtn.Position = UDim2.new(1, -30, 0, 2); MinimizeBtn.BackgroundTransparency = 1
MinimizeBtn.Text = "[-]"; MinimizeBtn.TextColor3 = Color3.fromRGB(255, 50, 50); MinimizeBtn.Font = Enum.Font.SourceSansBold; MinimizeBtn.TextSize = 14

local MaximizeBtn = Instance.new("TextButton", ScreenGui)
MaximizeBtn.Size = UDim2.new(0, 40, 0, 40); MaximizeBtn.Position = MainFrame.Position; MaximizeBtn.BackgroundColor3 = Color3.fromRGB(30, 30, 30)
MaximizeBtn.Text = "[+]"; MaximizeBtn.TextColor3 = Color3.fromRGB(50, 255, 50); MaximizeBtn.Font = Enum.Font.SourceSansBold; MaximizeBtn.TextSize = 16; MaximizeBtn.Visible = false
Instance.new("UICorner", MaximizeBtn).CornerRadius = UDim.new(0, 20)

MinimizeBtn.MouseButton1Click:Connect(function() MaximizeBtn.Position = MainFrame.Position; MainFrame.Visible = false; MaximizeBtn.Visible = true end)
MaximizeBtn.MouseButton1Click:Connect(function() MainFrame.Position = MaximizeBtn.Position; MaximizeBtn.Visible = false; MainFrame.Visible = true end)
--phần 3
local function SetMenuDragLogic()
    local dragging, dragStart, startPos; local holdTimer = 0
    MenuTitle.InputBegan:Connect(function(input)
        if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then
            holdTimer = tick()
            task.delay(1.0, function()
                if holdTimer ~= 0 and (tick() - holdTimer >= 1.0) then
                    dragging = true; dragStart = input.Position; startPos = MainFrame.Position
                    MenuTitle.Text = "ĐANG DI CHUYỂN..."; MenuTitle.TextColor3 = Color3.fromRGB(255, 255, 0)
                end
            end)
        end
    end)
    UserInputService.InputChanged:Connect(function(input)
        if dragging and (input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseMovement) then
            local delta = input.Position - dragStart
            MainFrame.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
        end
    end)
    UserInputService.InputEnded:Connect(function(input)
        if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then
            dragging = false; holdTimer = 0; 
            -- ĐÃ SỬA LỖI: Cố định tên menu P2077KNG 1.0 và màu đỏ chữ khi thả ra
            MenuTitle.Text = "P2077KNG 1.0"; MenuTitle.TextColor3 = Color3.fromRGB(255, 0, 0)
        end
    end)
end
SetMenuDragLogic()

local function SetMaximizeDrag(targetObj)
    local dragging, dragStart, startPos; local holdTimer = 0
    targetObj.InputBegan:Connect(function(input)
        if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then
            holdTimer = tick()
            task.delay(1.0, function() if holdTimer ~= 0 and (tick() - holdTimer >= 1.0) then dragging = true; dragStart = input.Position; startPos = targetObj.Position end end)
        end
    end)
    UserInputService.InputChanged:Connect(function(input)
        if dragging and (input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseMovement) then
            local delta = input.Position - dragStart; targetObj.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
        end
    end)
    targetObj.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then dragging = false; holdTimer = 0 end end)
end
SetMaximizeDrag(MaximizeBtn)

local currentOrder = 1
local function AddMenuButton(name, displayName, circleGraphic)
    local btn = Instance.new("TextButton", ScrollFrame)
    btn.Size = UDim2.new(1, 0, 0, 24); btn.LayoutOrder = currentOrder; currentOrder = currentOrder + 1
    btn.BackgroundColor3 = Color3.fromRGB(35, 35, 35); btn.Text = displayName .. (name == "RESET" and "" or ": OFF")
    btn.TextColor3 = Color3.new(1, 1, 1); btn.Font = Enum.Font.SourceSansBold; btn.TextSize = 10
    Instance.new("UICorner", btn).CornerRadius = UDim.new(0, 4)
    
    if name ~= "RESET" then ButtonsList[name] = { Instance = btn, DisplayName = displayName } end
    btn.MouseButton1Click:Connect(function()
        if name == "RESET" then
            State.ESP_1 = false; State.ESP_2 = false; State.ESP_3 = false
            if ButtonsList["ESP_1"] then ButtonsList["ESP_1"].Instance.Text = "ESP BOX CỐ ĐỊNH (S2): OFF"; ButtonsList["ESP_1"].Instance.BackgroundColor3 = Color3.fromRGB(35, 35, 35) end
            if ButtonsList["ESP_2"] then ButtonsList["ESP_2"].Instance.Text = "ESP DYNAMIC CO GIÃN (S2): OFF"; ButtonsList["ESP_2"].Instance.BackgroundColor3 = Color3.fromRGB(35, 35, 35) end
            if ButtonsList["ESP_3"] then ButtonsList["ESP_3"].Instance.Text = "ESP PLAYER GỐC (S1): OFF"; ButtonsList["ESP_3"].Instance.BackgroundColor3 = Color3.fromRGB(35, 35, 35) end
            
            for pName, drawGroup in pairs(ESPDrawings) do 
                if drawGroup then 
                    pcall(function() drawGroup.Box:Remove(); drawGroup.Line:Remove(); drawGroup.Text:Remove() end) 
                end 
            end
            table.clear(ESPDrawings)
        else
            State[name] = not State[name]
            btn.Text = displayName .. (State[name] and ": ON" or ": OFF")
            btn.BackgroundColor3 = State[name] and Color3.fromRGB(0, 80, 0) or Color3.fromRGB(35, 35, 35)
            if circleGraphic then circleGraphic.Visible = State[name] end
            if name == "AIM" or name == "AIM_Player" or name == "Aim_VatCan_S2" then FOVCircle.Visible = (State.AIM or State.AIM_Player or State.Aim_VatCan_S2) end
            if name == "Jump_Hack" and not State[name] then pcall(function() if LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("Humanoid") then LocalPlayer.Character.Humanoid.JumpPower = 50; LocalPlayer.Character.Humanoid.UseJumpPower = true end end) end
            
            if name == "Unlock_Camera" and not State[name] then
                pcall(function()
                    LocalPlayer.CameraMode = OriginalCameraMode
                    LocalPlayer.CameraMaxZoomDistance = OriginalMaxZoom
                    LocalPlayer.CameraMinZoomDistance = OriginalMinZoom
                end)
            end
        end
    end)
end

local SliderUpdateFunctions = {}
local function CreateSlider(titleText, minVal, maxVal, defaultVal, callback, uniqueKey)
    local sliderFrame = Instance.new("Frame", ScrollFrame)
    sliderFrame.Size = UDim2.new(1, 0, 0, 28); sliderFrame.BackgroundTransparency = 1; sliderFrame.LayoutOrder = currentOrder; currentOrder = currentOrder + 1
    local label = Instance.new("TextLabel", sliderFrame)
    label.Size = UDim2.new(1, 0, 0, 11); label.Text = titleText .. ": " .. tostring(defaultVal); label.TextColor3 = Color3.new(1, 1, 1); label.Font = Enum.Font.SourceSansBold; label.TextSize = 9; label.BackgroundTransparency = 1
    local bar = Instance.new("Frame", sliderFrame)
    bar.Size = UDim2.new(1, 0, 0, 3); bar.Position = UDim2.new(0, 0, 0, 14); bar.BackgroundColor3 = Color3.fromRGB(60, 60, 60)
    local pin = Instance.new("TextButton", bar)
    pin.Size = UDim2.new(0, 8, 0, 8); pin.Position = UDim2.new((defaultVal - minVal) / (maxVal - minVal), -4, 0, -3); pin.BackgroundColor3 = Color3.fromRGB(200, 200, 200); pin.Text = ""
    Instance.new("UICorner", pin).CornerRadius = UDim.new(0, 4)
    local dragging = false
    pin.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true end end)
    local function UpdateSliderVisual(value)
        local clampedVal = math.clamp(value, minVal, maxVal)
        pin.Position = UDim2.new((clampedVal - minVal) / (maxVal - minVal), -4, 0, -3)
        label.Text = titleText .. ": " .. tostring(clampedVal)
    end
    if uniqueKey then SliderUpdateFunctions[uniqueKey] = UpdateSliderVisual end
    UserInputService.InputChanged:Connect(function(input)
        if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
            local relativeX = math.clamp((input.Position.X - bar.AbsolutePosition.X) / bar.AbsoluteSize.X, 0, 1)
            pin.Position = UDim2.new(relativeX, -4, 0, -3)
            local currentVal = math.floor(minVal + (relativeX * (maxVal - minVal)))
            label.Text = titleText .. ": " .. tostring(currentVal); callback(currentVal)
        end
    end)
    UserInputService.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = false end end)
end

AddMenuButton("TP_Closest", "TP SÁT SAU LƯNG")
AddMenuButton("TP_4Far", "TP HACK") 
AddMenuButton("TP_Mid", "TP MID (S1)")

-- NÚT ĐỔI NGƯỜI SIÊU TỐC KHÔNG TRÙNG LẶP CHO TP HACK
local SwitchTPBtn = Instance.new("TextButton", ScrollFrame)
SwitchTPBtn.Size = UDim2.new(1, 0, 0, 24); SwitchTPBtn.LayoutOrder = currentOrder; currentOrder = currentOrder + 1
SwitchTPBtn.BackgroundColor3 = Color3.fromRGB(80, 40, 0); SwitchTPBtn.Text = "⏭️ ĐỔI NGƯỜI TP"; SwitchTPBtn.TextColor3 = Color3.new(1, 1, 1); SwitchTPBtn.Font = Enum.Font.SourceSansBold; SwitchTPBtn.TextSize = 10
Instance.new("UICorner", SwitchTPBtn).CornerRadius = UDim.new(0, 4)
SwitchTPBtn.MouseButton1Click:Connect(function() 
    if State.TP_4Far then
        if #TP_Queue == 0 or TP_Pointer >= #TP_Queue then
            TP_Queue = {}
            for _, p in pairs(Players:GetPlayers()) do
                if p ~= LocalPlayer and p.Character and p.Character:FindFirstChild("HumanoidRootPart") and p.Character:FindFirstChild("Humanoid") and p.Character.Humanoid.Health > 0 then
                    table.insert(TP_Queue, p)
                end
            end
            for i = #TP_Queue, 2, -1 do
                local j = math.random(1, i)
                TP_Queue[i], TP_Queue[j] = TP_Queue[j], TP_Queue[i]
            end
            TP_Pointer = 0
        end
        
        if #TP_Queue > 0 then
            TP_Pointer = TP_Pointer + 1
            LockedTPTarget = TP_Queue[TP_Pointer]
        end
    elseif State.TP_Closest or State.TP_Mid then
        LockedTPTarget = nil
    end 
end)

AddMenuButton("AIM_Player", "AIM XUYÊN VẬT CẢN (S1)")
AddMenuButton("Aim_VatCan_S2", "AIM CHẶN VẬT CẢN (S2)") 
AddMenuButton("AIM", "AIM ASSIST MƯỢT (S2)")

AddMenuButton("Speed_Hack", "CHẠY NHANH (SPEED)")
CreateSlider("TỐC ĐỘ RUN", 16, 500, Target_Speed, function(v) Target_Speed = v end, "SpeedSlider")

AddMenuButton("Jump_Hack", "NHẢY CAO (JP)")
CreateSlider("ĐỘ CAO JUMP", 50, 1000, Target_Jump, function(v) Target_Jump = v end, "JumpSlider")

local txtSpeedInput = Instance.new("TextBox", ScrollFrame)
txtSpeedInput.Size = UDim2.new(1, 0, 0, 20); txtSpeedInput.LayoutOrder = currentOrder; currentOrder = currentOrder + 1
txtSpeedInput.BackgroundColor3 = Color3.fromRGB(40, 40, 40); txtSpeedInput.Text = "Nhập số tốc độ..."; txtSpeedInput.TextColor3 = Color3.new(1, 1, 0); txtSpeedInput.Font = Enum.Font.SourceSansBold; txtSpeedInput.TextSize = 9
txtSpeedInput.FocusLost:Connect(function() local num = tonumber(txtSpeedInput.Text); if num then Target_Speed = math.clamp(num, 16, 500); if SliderUpdateFunctions["SpeedSlider"] then SliderUpdateFunctions["SpeedSlider"](Target_Speed) end end end)

AddMenuButton("Lock_Player", "LOCK PLAYER", CirclePlayer)
AddMenuButton("Lock_NPC", "LOCK NPC", CircleNPC)
AddMenuButton("ESP_3", "ESP PLAYER GỐC (S1)")
AddMenuButton("ESP_1", "ESP BOX CỐ ĐỊNH (S2)")
AddMenuButton("ESP_2", "ESP DYNAMIC CO GIÃN (S2)")
AddMenuButton("RESET", "CLEAR 3 ESP (GIỮ MOD)")

AddMenuButton("Unlock_Camera", "MỞ KHÓA CAMERA (1ST)")

local txtZoom = Instance.new("TextBox", ScrollFrame)
txtZoom.Size = UDim2.new(1, 0, 0, 20); txtZoom.LayoutOrder = currentOrder; currentOrder = currentOrder + 1
txtZoom.BackgroundColor3 = Color3.fromRGB(50, 50, 50); txtZoom.Text = "Giới hạn Zoom (Số)"; txtZoom.TextColor3 = Color3.fromRGB(255, 255, 255)
txtZoom.Font = Enum.Font.SourceSansBold; txtZoom.TextSize = 9
txtZoom.FocusLost:Connect(function() 
    local num = tonumber(txtZoom.Text)
    if num then Max_Zoom_Value = num; txtZoom.Text = "GIỚI HẠN ZOOM: " .. tostring(num) else txtZoom.Text = "Vui lòng nhập số!" end 
end)

local txtHeight = Instance.new("TextBox", ScrollFrame)
txtHeight.Size = UDim2.new(1, 0, 0, 20); txtHeight.LayoutOrder = currentOrder; currentOrder = currentOrder + 1
txtHeight.BackgroundColor3 = Color3.fromRGB(50, 50, 50); txtHeight.Text = "Chiều cao Y"; txtHeight.TextColor3 = Color3.new(0, 1, 0); txtHeight.Font = Enum.Font.SourceSansBold; txtHeight.TextSize = 9
txtHeight.FocusLost:Connect(function() local num = tonumber(txtHeight.Text); if num then TargetHeight = num end end)

local txtDist = Instance.new("TextBox", ScrollFrame)
txtDist.Size = UDim2.new(1, 0, 0, 20); txtDist.LayoutOrder = currentOrder; currentOrder = currentOrder + 1
txtDist.BackgroundColor3 = Color3.fromRGB(50, 50, 50); txtDist.Text = "Khoảng cách (Gốc: 0)"; txtDist.TextColor3 = Color3.new(1, 0.6, 0); txtDist.Font = Enum.Font.SourceSansBold; txtDist.TextSize = 9
txtDist.FocusLost:Connect(function() local num = tonumber(txtDist.Text); if num then LoopDistance = num; txtDist.Text = "KHOẢNG CÁCH: " .. tostring(num) end end)

CreateSlider("CỠ FOV AIM", 10, 500, FOV_Aim_Radius, function(v) FOV_Aim_Radius = v end)
CreateSlider("ĐỘ GHIM AIM (SMOOTH)", 1, 30, Aim_Smooth, function(v) Aim_Smooth = v end)
CreateSlider("CỠ FOV LOCK PLAYER", 10, 500, FOV_Player_Radius, function(v) FOV_Player_Radius = v end)
CreateSlider("CỠ FOV LOCK NPC", 10, 500, FOV_NPC_Radius, function(v) FOV_NPC_Radius = v end)
--phần 4
-- 5. Hàm lọc tọa độ mục tiêu nâng cấp thuật toán kiểm tra vật cản
local function GetClosestPlayerInFOV(checkWall)
    local screenCenter = Vector2.new(Camera.ViewportSize.X / 2, Camera.ViewportSize.Y / 2)
    local closest, shortestFOVDist = nil, FOV_Aim_Radius
    for _, p in pairs(Players:GetPlayers()) do
        if p ~= LocalPlayer and p.Character and p.Character:FindFirstChild("HumanoidRootPart") and p.Character:FindFirstChild("Humanoid") and p.Character.Humanoid.Health > 0 then
            local root = p.Character.HumanoidRootPart
            local screenPos, onScreen = Camera:WorldToViewportPoint(root.Position)
            if onScreen then
                local fovDistance = (Vector2.new(screenPos.X, screenPos.Y) - screenCenter).Magnitude
                if fovDistance < shortestFOVDist then
                    if checkWall then
                        local raycastParams = RaycastParams.new()
                        raycastParams.FilterType = Enum.RaycastFilterType.Exclude
                        raycastParams.FilterDescendantsInstances = {LocalPlayer.Character, p.Character}
                        raycastParams.RespectCanCollide = true
                        
                        local origin = Camera.CFrame.Position
                        local direction = root.Position - origin
                        local rayResult = Workspace:Raycast(origin, direction, raycastParams)
                        
                        if not rayResult then closest = p; shortestFOVDist = fovDistance end
                    else closest = p; shortestFOVDist = fovDistance end
                end
            end
        end
    end
    return closest
end

local function GetActualClosestPlayer()
    local closest, shortestDist = nil, math.huge
    for _, p in pairs(Players:GetPlayers()) do
        if p ~= LocalPlayer and p.Character and p.Character:FindFirstChild("HumanoidRootPart") and p.Character:FindFirstChild("Humanoid") and p.Character.Humanoid.Health > 0 then
            local dist = (Camera.CFrame.Position - p.Character.HumanoidRootPart.Position).Magnitude
            if dist < shortestDist then closest = p; shortestDist = dist end
        end
    end
    return closest
end

local function GetESPColor(p)
    if p.Team then return p.TeamColor.Color end
    return Color3.fromRGB(255, 255, 255)
end

Players.PlayerRemoving:Connect(function(player)
    if ESPDrawings[player.Name] then
        local drawGroup = ESPDrawings[player.Name]
        pcall(function() drawGroup.Box:Remove(); drawGroup.Line:Remove(); drawGroup.Text:Remove() end)
        ESPDrawings[player.Name] = nil
    end
    if LockedTarget == player then LockedTarget = nil end
    if LockedTPTarget == player then LockedTPTarget = nil end
    
    -- Xoá khỏi hàng đợi đổi người để tránh load lỗi
    for i, v in ipairs(TP_Queue) do
        if v == player then table.remove(TP_Queue, i) break end
    end
end)

-- LUỒNG XỬ LÝ DỊCH CHUYỂN HACK VỚI HỖ TRỢ KHOẢNG CÁCH KHÔNG (0) BIẾN DẠNG C_FRAME
RunService.Heartbeat:Connect(function()
    local myChar = LocalPlayer.Character
    if not myChar or not myChar:FindFirstChild("HumanoidRootPart") then return end
    local rootPart = myChar.HumanoidRootPart
    
    local isTPEnabled = (State.TP_Closest or State.TP_4Far or State.TP_Mid)
    if not isTPEnabled then LockedTPTarget = nil; return end
    
    if not LockedTPTarget or not LockedTPTarget.Character or not LockedTPTarget.Character:FindFirstChild("Humanoid") or LockedTPTarget.Character.Humanoid.Health <= 0 then 
        LockedTPTarget = GetActualClosestPlayer() 
    end
    
    if LockedTPTarget and LockedTPTarget.Character and LockedTPTarget.Character:FindFirstChild("HumanoidRootPart") then
        local targetRoot = LockedTPTarget.Character.HumanoidRootPart
        local distOffset = LoopDistance or 0
        
        -- Tính toán vị trí dịch chuyển chính xác dựa vào số khoảng cách nhập vào (Hoạt động cho số 0)
        local basePosition = targetRoot.Position + Vector3.new(0, TargetHeight, 0)
        if distOffset ~= 0 then
            basePosition = basePosition + (targetRoot.CFrame.LookVector * distOffset)
        end
        
        if State.TP_Closest then
            rootPart.CFrame = CFrame.new(basePosition, targetRoot.Position)
        elseif State.TP_4Far then 
            rootPart.CFrame = CFrame.new(basePosition, targetRoot.Position)
        elseif State.TP_Mid then
            rootPart.CFrame = CFrame.new(basePosition, targetRoot.Position)
        end
    end
end)

RunService.RenderStepped:Connect(function()
    local myChar = LocalPlayer.Character
    if not myChar or not myChar:FindFirstChild("HumanoidRootPart") or not myChar:FindFirstChild("Humanoid") then return end
    local rootPart = myChar.HumanoidRootPart
    local humanoid = myChar.Humanoid
    local screenCenter = Vector2.new(Camera.ViewportSize.X / 2, Camera.ViewportSize.Y / 2)

    if State.Unlock_Camera then
        pcall(function()
            LocalPlayer.CameraMode = Enum.CameraMode.Classic
            LocalPlayer.CameraMaxZoomDistance = Max_Zoom_Value
            if LocalPlayer.CameraMinZoomDistance > 5 then LocalPlayer.CameraMinZoomDistance = 5 end
        end)
    end

    local anyAim = (State.AIM or State.AIM_Player or State.Aim_VatCan_S2)
    if anyAim then FOVCircle.Position = screenCenter; FOVCircle.Radius = FOV_Aim_Radius; FOVCircle.Visible = true else FOVCircle.Visible = false end
    if State.Lock_Player then CirclePlayer.Position = screenCenter; CirclePlayer.Radius = FOV_Player_Radius; CirclePlayer.Visible = true else CirclePlayer.Visible = false end
    if State.Lock_NPC then CircleNPC.Position = screenCenter; CircleNPC.Radius = FOV_NPC_Radius; CircleNPC.Visible = true else CircleNPC.Visible = false end

    if State.Speed_Hack then humanoid.WalkSpeed = Target_Speed end
    if State.Jump_Hack then humanoid.UseJumpPower = true; humanoid.JumpPower = Target_Jump end

    if anyAim then
        local needCheckWall = State.Aim_VatCan_S2 
        LockedTarget = GetClosestPlayerInFOV(needCheckWall)
        if LockedTarget and LockedTarget.Character and LockedTarget.Character:FindFirstChild("HumanoidRootPart") then
            local targetPos = LockedTarget.Character.HumanoidRootPart.Position
            Camera.CFrame = Camera.CFrame:Lerp(CFrame.new(Camera.CFrame.Position, targetPos), 1 / math.clamp(Aim_Smooth, 1, 30))
        end
    else LockedTarget = nil end

    for _, p in pairs(Players:GetPlayers()) do
        if p ~= LocalPlayer and p.Character and p.Character:FindFirstChild("HumanoidRootPart") then
            local showESP = (State.ESP_1 or State.ESP_2 or State.ESP_3)
            if showESP then
                if not ESPDrawings[p.Name] then
                    ESPDrawings[p.Name] = { Box = Drawing.new("Square"), Line = Drawing.new("Line"), Text = Drawing.new("Text") }
                    ESPDrawings[p.Name].Box.Filled = false; ESPDrawings[p.Name].Text.Center = true; ESPDrawings[p.Name].Text.Outline = true
                end
                local d = ESPDrawings[p.Name]
                local pos, onScreen = Camera:WorldToViewportPoint(p.Character.HumanoidRootPart.Position)
                if onScreen then
                    local distance = math.floor((rootPart.Position - p.Character.HumanoidRootPart.Position).Magnitude)
                    local pLevel = p:FindFirstChild("Data") and p.Data:FindFirstChild("Level") and p.Data.Level.Value or "?"
                    d.Box.Color = Color3.fromRGB(255, 255, 255); d.Text.Color = GetESPColor(p); d.Line.Color = Color3.fromRGB(0, 255, 0)
                    local boxW, boxH, textSize = 30, 50, 11
                    if State.ESP_1 then boxW, boxH, textSize = 30, 40, 12
                    elseif State.ESP_2 then 
                        local scaleFactor = 1 / (pos.Z * 0.015)
                        boxW = math.clamp(30 * scaleFactor, 6, 70); boxH = math.clamp(40 * scaleFactor, 9, 95); textSize = math.clamp(12 * scaleFactor, 6, 14)
                    elseif State.ESP_3 then boxW, boxH, textSize = 30, 50, 11 end
                    d.Box.Size = Vector2.new(boxW, boxH); d.Box.Position = Vector2.new(pos.X - (boxW / 2), pos.Y - (boxH / 2)); d.Box.Visible = true
                    d.Line.From = Vector2.new(Camera.ViewportSize.X / 2, 0); d.Line.To = Vector2.new(pos.X, pos.Y - (boxH / 2)); d.Line.Visible = true
                    d.Text.Size = textSize; d.Text.Position = Vector2.new(pos.X, pos.Y + (boxH / 2) + 3)
                    d.Text.Text = string.format("%s\n[Lv.%s - %sm]", p.Name, tostring(pLevel), distance); d.Text.Visible = true
                else d.Box.Visible = false; d.Line.Visible = false; d.Text.Visible = false end
            elseif ESPDrawings[p.Name] then
                ESPDrawings[p.Name].Box.Visible = false; ESPDrawings[p.Name].Line.Visible = false; ESPDrawings[p.Name].Text.Visible = false
            end
        end
    end
end)

local gmt = getrawmetatable(game); local oldIndex = gmt.__index; setreadonly(gmt, false)
gmt.__index = newcclosure(function(self, targetIndex)
    if (State.AIM_Player or State.Aim_VatCan_S2) and tostring(self) == "Mouse" and (targetIndex == "Hit" or targetIndex == "Target") then
        local needCheckWall = State.Aim_VatCan_S2
        local closestEnemy = GetClosestPlayerInFOV(needCheckWall)
        if closestEnemy and closestEnemy.Character and closestEnemy.Character:FindFirstChild("HumanoidRootPart") then
            if targetIndex == "Hit" then return closestEnemy.Character.HumanoidRootPart.CFrame
            elseif targetIndex == "Target" then return closestEnemy.Character.HumanoidRootPart end
        end
    end
    return oldIndex(self, targetIndex)
end)
setreadonly(gmt, true)