require("vrmod")
local hooks = {}
local frame = nil
local tabselect = "GUI"
local blockedhooks = {}
local ip = ipairs

surface.CreateFont("MAIN", {
    font = "Minecraft",
    size = 13,
    weight = 1000,
    antialias = true
})

local vars = {
    friendlist = {},
    me = LocalPlayer(),
    cmdfont = "MAIN",

    MenuToggle = false,

    bSend = true,

    tScreen = Vector(0, 0, 0).ToScreen,
    sw = ScrW(),
    sh = ScrH(),
    model = LocalPlayer():GetModel(),
    vieworigin = LocalPlayer():EyePos(),
    fa = LocalPlayer():EyeAngles(),
    activeWeapon = LocalPlayer():GetActiveWeapon(),
    activeWeaponClass = IsValid(LocalPlayer():GetActiveWeapon()) and LocalPlayer():GetActiveWeapon():GetClass() or "",

    CustomSpread = {},
    SpreadComps = {},
    cones = {},
    bulletImpacts = {},

    C = CurTime,
    realFrameTime = RealFrameTime,
    GetLatency = (LocalPlayer():Ping()/1000),
    nulVec = Vector(),
    Vec = Vector,

    hooksToRemove = {},
    hGetTable = hook.GetTable(),
    hAdd = hook.Add,
    hRemove = hook.Remove,

    baseyaw = 0,

    toStr = tostring,
    isValid = IsValid,
    tSimple = timer.Simple,

    math_deg = math.deg,
    math_cos = math.cos,
    math_abs = math.abs,
    math_sin = math.sin,
    math_tan = math.tan,
    math_acos = math.acos,
    math_sqrt = math.sqrt,
    math_pi = math.pi,
    math_floor = math.floor,
    math_rad = math.rad,
    math_round = math.Round,
    math_NormAngle = math.NormalizeAngle,
    math_random = math.random,
    math_rand = math.Rand,
    math_randomseed = math.randomseed,
    math_atan = math.atan,
    math_clamp = math.Clamp,

    dSimpleText = draw.SimpleText,
    dSimpleTextOutlined = draw.SimpleTextOutlined,
    dRoundedBox = draw.RoundedBox,
    dDrawText = draw.DrawText,

    sPlaySound = surface.PlaySound,
    sSetDrawColor = surface.SetDrawColor,
    sDrawRect = surface.DrawRect,
    sDrawLine = surface.DrawLine,
    sDrawText = surface.DrawText,
    sDrawCircle = surface.DrawCircle,
    sSetFont = surface.SetFont,
    sSetTextColor = surface.SetTextColor,
    sSetTextPos = surface.SetTextPos,
    sDrawOutlinedRect = surface.DrawOutlinedRect,
    sGetTextSize = surface.GetTextSize,

    rSupEngLight = render.SuppressEngineLighting,
    rMatOver = render.MaterialOverride,
    rModelLight = render.SetModelLighting,
    rColorMod = render.SetColorModulation,
    rDepthRange = render.DepthRange,
    rBlend = render.SetBlend,
    rColorMat = render.SetColorMaterial,
    rDrawBox = render.DrawBox,

    vCreate = vgui.Create,

    kDown = input.IsKeyDown,

    Cam3Ds = cam.Start3D,
    Cam3De = cam.End3D,

    tInsert = table.insert, 
    tRemove = table.remove,

    rCC = RunConsoleCommand,

    unload = true,

    bhop = true,
    bhop_as = true,
    desync = false,
    
    thirdPersonEnabled = false,
    tps = false,
    tps_fov = 80,

    cam_fov = false,
    fov = 120,

    freecam = false,

    w_fov = true,
    wfov = 130,
 
    esp = true,
    esp_boxes = true,
    esp_chams = true,

    w_chams = true,

    act = false,

    aim_fov = 10,
    aim_aimbot = true,
    aim_silent = true,
    aim_psilent = false,
    aim_autofire = false,
    aim_rapidfire = false,
    aim_wallz = false,
    aim_nospread = true,
    aim_norecoil = true,
    predtype = 'velocity',
    boneAim = 'ValveBiped.Bip01_Head1',

    antiaim = false,
    aa_mode = 'none',
}
do
    ded.SetInterpolation( true )
    ded.SetSequenceInterpolation( true )
    ded.EnableAnimFix( false )
end

local function shouldFire(b)
    local wep = vars.activeWeaponClass
    local wepactive = vars.activeWeapon
    local weps = {
        'weapon_physgun',
        "weapon_physcannon",
        "gmod_tool",
        'hands',
        'none',
        'pocket',
        'inventory',
        'weapon_physcannon',
        'weapon_vape*',
    }
    if vars.me:Alive() and wep then
        for k, v in ip( weps ) do
            if wep == v then return false end
        end
    end
    return true
end

local function IsFriend(steamID)
    for _, id in ip(vars.friendlist) do
        if id == steamID then return true end
    end
    return false
end

local function VARhooks(event, func)
    local hID = util.CRC(vars.math_random(10^4) + SysTime())

    vars.hAdd(event, hID, func)
    hooks[#hooks + 1] = { event = event, id = hID }

    print("Hook ajouté → ", event, "| ID:", hID)
end


local colors = {
    white = Color(255, 255, 255),
    red = Color(255, 0, 0),
    armor = Color(0, 100, 255, 255),
    background = Color(0, 0, 0, 200),
    unhover = Color(56, 56, 56),
    hover = Color(46, 46, 46),
    header = Color(50, 50, 50),
    bg = Color(65, 65, 65, 230),

    Background1 = Color(33, 33, 38),
    TopBar1 = Color(247, 23, 23)
}

-- === FONCTIONS CUSTOM ===

local function DrawText(col, x, y, str, font)
    vars.sSetFont(font)
    vars.sSetTextColor(col.r, col.g, col.b, col.a)
    vars.sSetTextPos(x, y)
    vars.sDrawText(str)
end

local function GetTextSize(font, str)
    vars.sSetFont(font)
    return vars.sGetTextSize(str)
end

local function ThemeBox(name,x,y,x1,y1,col,col2)
    DrawText(col, x + 30, y - 7, name, vars.cmdfont)
    local w,h = GetTextSize(vars.cmdfont,name)
    vars.sSetDrawColor(col2.r, col2.g, col2.b, col2.a)
    vars.sDrawLine(x,y,x+25,y)
    vars.sDrawLine(x+w+35,y,x+x1,y)
    vars.sDrawLine(x,y+y1,x+x1,y+y1)
    vars.sDrawLine(x,y+y1,x,y)
    vars.sDrawLine(x+x1,y+y1,x+x1,y)
end

local function IsOutOfFOV(ent)
    if vars.me:GetObserverMode() == 0 then
        local Disp = (ent:GetPos() - vars.me:GetShootPos()):GetNormalized()
        return Disp:Dot(vars.me:EyeAngles():Forward()) < vars.math_cos(vars.math_atan(ent:BoundingRadius() / (ent:GetPos():Distance(vars.me:GetShootPos()))) + vars.math_rad(56))
    end
end


-- === INTERFACE === --
local lastActiveTab = "GUI"

local function createTabButton(name, x, panel)
    local btn = vars.vCreate('DButton', frame)
    btn:SetText(name)
    btn:SetTextColor(colors.white)
    btn:SetSize(frame:GetWide() / 4 - 10, 19)
    btn:SetPos(x, 3)

    btn.Paint = function()
        vars.sSetDrawColor(tabselect == name and colors.hover or colors.unhover)
        vars.sDrawRect(0, 0, btn:GetWide(), btn:GetTall())
    end

    btn.DoClick = function()
        tabselect = name
        lastActiveTab = name
        hookpanel:SetVisible(panel == hookpanel)
        guipanel:SetVisible(panel == guipanel)
        friendslistpanel:SetVisible(panel == friendslistpanel)
        lastActivePanel = panel
    end
end

local function checkbox( name, tooltip, val, x, y, parent )
    local checkbox = vars.vCreate( "DCheckBoxLabel", parent )
    checkbox:SetText( name )
    checkbox:SetPos( x, y )
    checkbox:SetChecked( vars[val] )
    if isstring( tooltip ) then
        checkbox:SetTooltip( tooltip )
    end
    function checkbox:OnChange(bval)
            vars[val] = bval
    end
    function checkbox:PaintOver()
    vars.dRoundedBox( 0, 0, 0, 15, 15, Color( 0, 0, 0 ) )
        if checkbox:GetChecked() then
    vars.dRoundedBox( 0, 4, 4, 7.5, 7.5, Color( 100, 0, 0 ) )
        end
    end
end

local function combobox(name, val, x, y, choices, mappings, parent)
    local combo = vars.vCreate("DComboBox", parent)
    combo:SetPos(x, y)
    combo:SetSize(140, 20)
    combo:SetSortItems(false)
    combo:SetValue(choices[1])
    combo:SetTextColor(Color(210, 210, 210))

    for _, choice in ip(choices) do
        combo:AddChoice(choice)
    end

    function combo:OnSelect(index, mode)
        vars[val] = mappings and mappings[mode] or mode
    end

    combo.Paint = function(self, w, h)
        vars.sSetDrawColor(colors.hover)
        vars.sDrawRect(0, 0, w, h)
        vars.sDrawOutlinedRect(0, 0, w, h)
    end

    combo.DropButton.Paint = function(self, w, h)
        vars.sSetDrawColor(colors.hover)
        vars.sDrawRect(0, 0, w, h)
    end

    combo.OnMenuOpened = function(pnl)
        local menu = pnl.Menu
        if vars.isValid(menu) then
            menu.Paint = function(self, w, h)
                vars.sSetDrawColor(colors.hover)
                vars.sDrawRect(0, 0, w, h)
            end
            for _, option in ip(menu:GetCanvas():GetChildren()) do
                option:SetTextColor(Color(210, 210, 210))
            end
        end
    end
end

local function slider( name, val, min, max, x, y, w, h, parent)
    local slider = vars.vCreate( "DNumSlider", parent)
        slider:SetMin( min )
        slider:SetMax( max )
        slider:SetText( name )
        slider:SetSize(w, h)
        slider:SetPos(x, y)
        slider:SetValue( vars[val] )
        slider:SetDecimals(0)
    function slider:OnValueChanged( num )
        vars[val] = num
    end
end

local function showPanel(panel)
    hookpanel:SetVisible(panel == hookpanel)
    guipanel:SetVisible(panel == guipanel)
    friendslistpanel:SetVisible(panel == friendslistpanel)
end

-- === UI PRINCIPALE ===
local function ui()
    if vars.isValid(frame) then
        if frame:IsVisible() then
            frame:SetVisible(false)
            gui.EnableScreenClicker(false)
            gui.HideGameUI()
        else
            frame:SetVisible(true)
            frame:MakePopup()
            gui.EnableScreenClicker(true)
            updateFriends()
            -- vars.rCC("gameui_activate")
        end
        return
    end

    -- vars.rCC("gameui_activate")

    frame = vars.vCreate('DFrame')
    frame:SetSize(700, 230)
    frame:Center()
    frame:MakePopup()
    frame:ShowCloseButton(false)
    frame:SetTitle('')

    frame.Paint = function()
        vars.sSetDrawColor(colors.header)
        vars.sDrawRect(0, 0, frame:GetWide(), 25)

        vars.sSetDrawColor(colors.bg)
        vars.sDrawRect(0, 25, frame:GetWide(), frame:GetTall() - 25)
    end

    -- === PANELS ===
    hookpanel = vars.vCreate('DPanel', frame)
    hookpanel:Dock(FILL)
    hookpanel:SetVisible(false)
    hookpanel.Paint = function()
        vars.sSetDrawColor(Color(255,255,255,0))
        vars.sDrawRect(0, 0, hookpanel:GetWide(), hookpanel:GetTall())
    end

    guipanel = vars.vCreate('DPanel', frame)
    guipanel:Dock(FILL)
    guipanel:SetVisible(false)

    friendslistpanel = vars.vCreate('DPanel', frame)
    friendslistpanel:Dock(FILL)
    friendslistpanel:SetVisible(false)
    friendslistpanel.Paint = function()
        vars.sSetDrawColor(Color(255,255,255,0))
        vars.sDrawRect(0, 0, friendslistpanel:GetWide(), friendslistpanel:GetTall())
    end

    -- === TABS ===
    createTabButton('Hooks', 3, hookpanel)
    createTabButton('Friends', frame:GetWide() / 4 + 3, friendslistpanel)
    createTabButton('GUI', frame:GetWide() / 2 + 3, guipanel)

    showPanel(lastActiveTab == "Hooks" and hookpanel or lastActiveTab == "Friends" and friendslistpanel or guipanel)

    function styleListView(listview)
        listview:SetHeaderHeight(20)
        listview.Paint = function(_, w, h)
            vars.sSetDrawColor(Color(0, 0, 0, 150))
            vars.sDrawRect(0, 0, w, h)
        end

        listview.OnRowSelected = function(_, _, row)
            for _, column in ip(row.Columns) do
                column:SetTextColor(Color(255, 255, 255))
            end
        end

        listview:AddLine("Loading...", "Please wait")
        for _, line in ip(listview:GetLines()) do
            for _, column in ip(line.Columns) do
                column:SetTextColor(Color(255, 255, 255))
            end
        end
        listview:Clear()
    end

    -- === GUI PANEL ===
    guipanel.Paint = function()
        local col = colors.white

        ThemeBox("ESP", 5, 5, 150, 180, col, col)
        ThemeBox("AA", 5, 85, 150, 100, col, col)
        ThemeBox("Aimbot", 160, 5, 315, 180, col, col)
        ThemeBox("Movement", 160, 95, 125, 90, col, col)
        ThemeBox("CamCtrl", 285, 95, 145, 90, col, col)
    end
    
    -- esp stuff
    checkbox("ESP: Toggle", "esp elements", "esp", 9, 14, guipanel)
    checkbox("ESP: Boxes", "toggles boxes", "esp_boxes", 9, 30, guipanel) -- + 17
    checkbox("ESP: Chams", "chams", "esp_chams", 9,  46, guipanel)
    checkbox("ESP: Weapon Chams", "chams", "w_chams", 9,  62, guipanel)

    -- aa stuff
    checkbox("AA: Toggle", "antiaim", "antiaim", 9, 92, guipanel)
    combobox("AA Methods", "aa_mode", 9, 112, {"none", "sway", "spin", "side left", "side right", "square"}, nil, guipanel)
    
    --aimbot stuff
    checkbox("AIM: Aimbot", "fire on mousepress", "aim_aimbot", 165, 14, guipanel)
    checkbox("AIM: Silent", "defucked view", "aim_silent", 165, 30, guipanel)
    checkbox("AIM: AutoPistol", "auto fire", "aim_autopistol", 165, 46, guipanel) --  62
    local boneMappings = {
        head = "ValveBiped.Bip01_Head1",
        neck = "ValveBiped.Bip01_Neck1",
        spine = "ValveBiped.Bip01_Spine1"
    }
    
    combobox("boneAim", "boneAim", 165, 65, {"head", "neck", "spine"}, boneMappings, guipanel)        

    checkbox("AIM: No Spread", "reverse the spread", "aim_nospread", 315, 14, guipanel)
    checkbox("AIM: No Recoil", "reverse the recoil", "aim_norecoil", 315, 30, guipanel)
    slider("AimFOV", "aim_fov", 0, 90, 315, 49, 150, 10, guipanel)
    combobox("predtype", "predtype", 315, 65, {"none", "velocity", "classic", "engine", "ping"}, nil, guipanel)

    -- mouvement
    checkbox("MV: Bunnyhop", "toggle bunnyhop", "bhop", 165, 105, guipanel)
    checkbox("MV: Autostrafe", "toggle autostrafe", "bhop_as", 165, 121, guipanel)
    checkbox("MV: Desync", "Desync", "desync", 165, 137, guipanel)
    checkbox("MV: Act", "toggle act", "act", 165, 153, guipanel)
    -- cam stuff
    checkbox("CAM: Thirdperson", "thirdperson", "tps", 290, 106, guipanel)
    checkbox("CAM: Fov", "fov", "cam_fov", 290, 122, guipanel)
    checkbox("CAM: Weapon Fov", "weapon fov", "w_fov", 290, 138, guipanel)
    slider("WFov", "wfov", 90, 130, 290, 156, 150, 10, guipanel)
    slider("TFov", "tps_fov", 30, 130, 290, 170, 150, 10, guipanel)
    
    -- === MODELE 3D ===
    local coolhoob2 = vars.vCreate('DModelPanel', guipanel)
    coolhoob2:SetSize(195, 180)
    coolhoob2:SetPos(480, 5)
    coolhoob2:SetModel(vars.model)
    coolhoob2:SetAnimated(true)

    function coolhoob2:LayoutEntity()
        self:RunAnimation()
        self:SetCamPos(vars.Vec(50, 50, 50))
    end

    -- === FRIENDS LIST PANEL ===
    function styleListViewHeader(listview)
        listview:SetHeaderHeight(25)
    
        for _, column in ip(listview.Columns) do
            column.Header:SetFont(vars.cmdfont)
            column.Header:SetTextColor(Color(255, 255, 255))
            
            column.Header.Paint = function(_, w, h)
                vars.dRoundedBox(0, 0, 0, w, h, colors.header)
            end
        end
    end
    

    local friendslist = vars.vCreate('DListView', friendslistpanel)
    friendslist:Dock(FILL)
    friendslist:AddColumn('Player')
    friendslist:AddColumn('Steam ID')
    friendslist:AddColumn('Friend')
    friendslist.Paint = function(_, w, h)
        vars.sSetDrawColor(Color(0,0,0,0))
        vars.sDrawRect(0, 0, w, h)
    end

    function AddFriend(steamID)
        if not IsFriend(steamID) then
            vars.tInsert(vars.friendlist, steamID)
        end
    end

    function RemoveFriend(steamID)
        for i, id in ip(vars.friendlist) do
            if id == steamID then
                vars.tRemove(vars.friendlist, i)
                break
            end
        end
    end

    function updateFriends()
        friendslist:Clear()
        for _, ply in ip(player.GetAll()) do
            local line = friendslist:AddLine(ply:Nick(), ply:SteamID(), IsFriend(ply:SteamID()) and "Yes" or "No")
            if vars.isValid(line) then
                for _, column in ip(line.Columns) do
                    if column then
                        column:SetTextColor(Color(255, 255, 255))
                    end
                end
            end
        end
    end

    styleListViewHeader(friendslist)

    friendslist.OnRowSelected = function(_, _, line)
        local steamID = line:GetColumnText(2)
        if IsFriend(steamID) then
            RemoveFriend(steamID)
        else
            AddFriend(steamID)
        end
        updateFriends()
    end
    
    updateFriends()
    
    -- Hooks
    local refreshBlocked
    local hooklist = vars.vCreate('DListView', hookpanel)
    hooklist:Dock(LEFT)
    hooklist:SetWidth(350)
    hooklist:AddColumn('Name')
    hooklist:AddColumn('Type')
    hooklist.VBar:SetEnabled(false)
    hooklist.VBar.Paint = function(_, w, h) 
        vars.dRoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0))
    end
    hooklist.VBar.btnUp.Paint = function(_, w, h) 
        vars.dRoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0))
    end
    hooklist.VBar.btnDown.Paint = function(_, w, h) 
        vars.dRoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0))
    end
    hooklist.VBar.btnGrip.Paint = function(_, w, h) 
        vars.dRoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0))
    end

    hooklist.Paint = function(_, w, h)
        vars.sSetDrawColor(Color(255,255,255,0))
        vars.sDrawRect(0, 0, w, h)
    end
    styleListViewHeader(hooklist)


    function refreshHooks()
        hooklist:Clear()
        for htype, hooks in ip(vars.hGetTable) do
            if !istable(hooks) then continue end
            for hname, _ in ip(hooks) do
                htype = vars.toStr(htype)
                hname = vars.toStr(hname)

                hooklist:AddLine(hname, htype)
            end
        end
        for _, line in ip(hooklist.Lines) do
            function line:Paint()
                if line:IsHovered() then
                    vars.sSetDrawColor(Color(100, 100, 100))
                else
                    vars.sSetDrawColor(Color(50, 50, 50))
                end
                vars.sDrawRect(0, 0, self:GetWide(), self:GetTall())
            end
            for _, column in ip(line.Columns) do
                column:SetTextColor(Color(255, 255, 255))
                column:SetFont(vars.cmdfont)
            end
        end
    end

    function hooklist:OnRowSelected()
        for _, v in ip(hooklist:GetSelected()) do
            local hname = vars.toStr(v:GetValue(1))
            local htype = vars.toStr(v:GetValue(2))
            if !istable(blockedhooks[htype]) then blockedhooks[htype] = {} end
            blockedhooks[htype][hname] = vars.hGetTable[htype][hname]
            vars.hRemove(htype, hname)
        end
        refreshHooks()
        refreshBlocked()
    end
    refreshHooks()
    
    local blocklist = vars.vCreate('DListView', hookpanel)
    blocklist:Dock(RIGHT)
    blocklist:SetWidth(350)
    blocklist:AddColumn('Blocked Name')
    blocklist:AddColumn('Type')
    blocklist.Paint = function(_, w, h)
        vars.sSetDrawColor(Color(255,255,255,0))
        vars.sDrawRect(0, 0, w, h)
    end
    styleListViewHeader(blocklist)

    function refreshBlocked()
        blocklist:Clear()
        for htype, hooks in ip(blockedhooks) do
            if !istable(hooks) then continue end
            for hname, _ in ip(hooks) do
                htype = vars.toStr(htype)
                hname = vars.toStr(hname)
                blocklist:AddLine(hname, htype)
            end
        end
        for _, line in ip(blocklist.Lines) do
            function line:Paint()
                if line:IsHovered() then
                    vars.sSetDrawColor(Color(100, 100, 100))
                else
                    vars.sSetDrawColor(Color(50, 50, 50))
                end

                vars.sDrawRect(0, 0, self:GetWide(), self:GetTall())
            end
            for _, column in ip(line.Columns) do
                column:SetTextColor(Color(255, 255, 255))
                column:SetFont(vars.cmdfont)
            end
        end
    end
    function blocklist:OnRowSelected()
        for _, v in ip(blocklist:GetSelected()) do
            local hname = vars.toStr(v:GetValue(1))
            local htype = vars.toStr(v:GetValue(2))
            vars.hAdd(htype, hname, blockedhooks[htype][hname])
            blockedhooks[htype][hname] = nil
        end
        refreshBlocked()
        refreshHooks()
    end
    refreshHooks()
end

-- === AA STUFF === --
local pitch, yaw = 0, 0
function GetBaseYaw()
    return vars.fa.y
end

local function CalcPitch()
    local x = 0
    x = 0
    if vars.aa_mode == "none" then
        x = 0
    else 
        x = 89
    end
    return x
end

local function CalcYaw()
    local y = 0
        y = vars.baseyaw - 180
    if vars.aa_mode == "spin" then
        local s = vars.math_NormAngle( vars.C() * 750 )
        y = s
    elseif vars.aa_mode == "sway" then
        local s = vars.math_sin(vars.C() * 2346) * 75
        y = ( vars.baseyaw - 180 ) + s -- sway
    elseif vars.aa_mode == "square" then
        if not vars.yaw_offset then vars.yaw_offset = 0 end
        if not vars.last_update or (vars.C() - vars.last_update) > 0.4 then
            vars.yaw_offset = vars.yaw_offset + 90
            vars.last_update = vars.C()
        end
        y = vars.baseyaw + vars.yaw_offset
    elseif vars.aa_mode == "side left" then
        y = vars.baseyaw - 90
    elseif vars.aa_mode == "side right" then
        y = vars.baseyaw + 90
    elseif vars.aa_mode == "none" then
        y = vars.baseyaw
    end
    return y
end

local function aacheck(cmd)
    if !vars.antiaim then return false end
    if !shouldFire() then return false end
    if cmd:KeyDown(IN_ATTACK) then return false end
    if cmd:KeyDown(IN_USE) then return false end
    if vars.me:GetMoveType() == MOVETYPE_LADDER then return false end
    if vars.me:GetMoveType() == MOVETYPE_NOCLIP then return false end
    
    return true
end

local function ANTIAIM_C(cmd)
    if aacheck(cmd) then
        vars.baseyaw = GetBaseYaw()
        pitch = CalcPitch()
        yaw = CalcYaw()
        local pyAngle = Angle(pitch,yaw,0)
        cmd:SetViewAngles(pyAngle)
    end
end

-- === AILMBOT STUFF === --
local function MovementFix(cmd, wish_yaw)
    local pitch = vars.math_NormAngle(cmd:GetViewAngles().x)
    local inverted = -1

    if (pitch > 89 or pitch < -89) then
        inverted = 1
    end

    local ang_diff = vars.math_rad(vars.math_NormAngle((cmd:GetViewAngles().y - wish_yaw) * inverted))
    local forwardmove = cmd:GetForwardMove()
    local sidemove = cmd:GetSideMove()

    local new_forwardmove = forwardmove * -vars.math_cos(ang_diff) * inverted + sidemove * vars.math_sin(ang_diff)
    local new_sidemove = forwardmove * vars.math_sin(ang_diff) * inverted + sidemove * vars.math_cos(ang_diff)

    cmd:SetForwardMove(new_forwardmove)
    cmd:SetSideMove(new_sidemove)
end

local function Silent(cmd)
	if !vars.fa then vars.fa = cmd:GetViewAngles() end
	vars.fa = vars.fa + Angle(cmd:GetMouseY() * GetConVarNumber("m_yaw"), cmd:GetMouseX() * -GetConVarNumber("m_yaw"), 0)
	vars.fa.p = vars.math_clamp(vars.fa.p, -89, 89)
    vars.fa.r = 0
    vars.fa:Normalize()
end

function vars.CustomSpread.swb( cmd, ang ) -- WORK

    local cone = vars.activeWeapon.CurCone
    if !cone then return ang end
    if vars.me:Crouching() then
        cone = cone * 0.85
    end

    vars.math_randomseed( cmd:CommandNumber() )
    return ang  - vars.me:GetViewPunchAngles() - Angle( vars.math_rand(-cone, cone), vars.math_rand(-cone, cone), 0 ) * 25
end

function vars.CustomSpread.cw(cmd, ang) -- WORK
    if not (cmd and ang) then return ang end
    if not vars.isValid(vars.me) or not vars.isValid(vars.activeWeapon) then return ang end
    if not isnumber(vars.activeWeapon.CurCone) then return ang end

    local cone = vars.activeWeapon.CurCone
    if not cone then return ang end
    vars.math_randomseed(cmd:CommandNumber())

    if vars.me:Crouching() then
        cone = cone * 0.85
    end

    if not isnumber(cone) then return ang end
    Dir = Angle(vars.math_rand(cone, -cone), vars.math_rand(cone, -cone), 0) * 25

    clumpSpread = clumpSpread or vars.activeWeapon.ClumpSpread
    if not isnumber(clumpSpread) then clumpSpread = 0 end

    Dir2 = Dir
    if clumpSpread > 0 then
        Dir2 = Dir + vars.Vec(vars.math_rand(-1, 1), vars.math_rand(-1, 1), vars.math_rand(-1, 1)) * clumpSpread
    end

    if not isangle(ang) or not isangle(Dir2) then return ang end

    return ang - vars.me:GetViewPunchAngles() + Dir2
end

function vars.CustomSpread.arccw( cmd, ang )
    return ang - vars.me:GetViewPunchAngles()
end

function vars.CustomSpread.fas2( cmd, ang )
    local cone = vars.activeWeapon.CurCone
    if !cone then return ang end
    vars.math_randomseed(vars.C())

    Dir2 = Angle(vars.math_rand(cone, -cone), vars.math_rand(cone, -cone), 0) * 25

    return ang - vars.me:GetViewPunchAngles() + Dir2
end

function vars.CustomSpread.tfa(cmd, ang) -- WORK
    if not vars or not vars.activeWeapon or not vars.isValid(vars.activeWeapon) then return ang end
    local wep = vars.activeWeapon
    if not isfunction(wep.CalculateConeRecoil) or not isfunction(wep.ComputeBulletDeviation) then return ang end

    local con, _ = wep:CalculateConeRecoil()
    if not con or not wep:CanPrimaryAttack() then return ang end

    local dYaw, dPitch = wep:ComputeBulletDeviation(1, 1, con)
    if not dYaw or not dPitch then return ang end

    local aimAng = Angle(ang)
    local right, up = aimAng:Right(), aimAng:Up()

    aimAng:RotateAroundAxis(up, -dYaw)
    aimAng:RotateAroundAxis(right, -dPitch)

    return aimAng
end

vars.SpreadComps["swb"]     = vars.CustomSpread.swb
vars.SpreadComps["cw"]      = vars.CustomSpread.cw
vars.SpreadComps["arccw"]   = vars.CustomSpread.arccw
vars.SpreadComps["fas2"]    = vars.CustomSpread.fas2
vars.SpreadComps["tfa"]     = vars.CustomSpread.tfa

GAMEMODE["EntityFireBullets"] = function( self, p, data )

    local spread = data.Spread * -1

	if vars.cones[ vars.activeWeaponClass ] == spread or spread == vars.nulVec then return end

    vars.cones[ vars.activeWeaponClass ] = spread;
end

local function Spread(cmd, ang, spread)
    if !vars.cones[ vars.activeWeaponClass ] then return ang end
    local spread = vars.cones[ vars.activeWeaponClass ]
	local dir = ded.PredictSpread( cmd, ang, spread )
	local spreadangle = ang + dir:Angle()
	spreadangle:Normalize()
	return spreadangle
end

local function NoSpread(cmd, ang)
    if not vars.activeWeaponClass or not vars.activeWeapon then return ang end

    local wep = vars.activeWeapon
    local base = string.Split(vars.activeWeaponClass, "_")[1]
    if vars.isValid(wep) and wep.IsTFAWeapon then
        base = "tfa"
    end
    if vars.SpreadComps[base] then
        ang = vars.SpreadComps[base](cmd, ang)
    elseif vars.cones[vars.activeWeaponClass] then
        local spread = vars.cones[vars.activeWeaponClass]
        return Spread(cmd, ang, spread)
    end
    return ang
end

local tr = {
	mask = MASK_SHOT,
	filter = vars.me
}

local function VisibleCheck( who, where, wall)
    local start = vars.me:EyePos()
    tr.start = start
	tr.endpos = where
	tr.mask = MASK_SHOT
    local trace = util.TraceLine( tr )
    local canhit = trace.Entity == who or trace.Fraction == 1

    return canhit

end

local function GetAngleDifference(from, to)
    return vars.math_deg(vars.math_acos(to:Forward():Dot(from:Forward())))
end

local function GetBestTarget()
    local bestTarget = nil
    local bestFov = vars.aim_fov

    for _, ply in ip(player.GetAll()) do
        if ply ~= vars.me and ply:Alive() and !ply:IsDormant() then
            local boneIndex = ply:LookupBone(vars.boneAim)
            if boneIndex then
                local bonePos = ply:GetBonePosition(boneIndex)
                if bonePos and VisibleCheck(ply, bonePos) and !IsFriend(ply:SteamID()) and !ply:HasGodMode() and !ply:InVehicle() then
                    local targetDirection = (bonePos - vars.me:GetShootPos()):Angle()
                    targetDirection:Normalize()

                    local angDiff = vars.math_abs(vars.math_NormAngle(GetAngleDifference(vars.fa, targetDirection)))

                    if angDiff < bestFov then
                        bestFov = angDiff
                        bestTarget = ply
                    end
                end
            end
        end
    end

    return bestTarget
end

local function NoRecoil(ang)
    local wep = vars.activeWeapon
    if vars.activeWeaponClass == "weapon_pistol" or string.StartsWith(vars.activeWeaponClass, "m9k_") or 
       string.StartsWith(vars.activeWeaponClass, "fas2") or string.StartsWith(vars.activeWeaponClass, "cw") or 
       string.StartsWith(vars.activeWeaponClass, "arccw") or string.StartsWith(vars.activeWeaponClass, "swb") then
        return ang
    elseif wep and wep.IsTFAWeapon then
        ang.p = ang.p - wep:GetViewPunchP()
        ang.y = ang.y - wep:GetViewPunchY()
    else
        ang = ang - vars.me:GetViewPunchAngles()
    end

    return ang
end

local function getCenterBone(ply)
    if not ply then return end
    local Bone = ply:LookupBone(vars.boneAim)
    if not Bone then return end
    local matrix = ply:GetBoneMatrix(Bone)
    if not matrix then return end
    local pos, ang = matrix:GetTranslation(), matrix:GetAngles()
    
    local min, max = ply:GetHitBoxBounds(0, 0)
    min:Rotate(ang)
    max:Rotate(ang)
    
    pos = pos + ((min + max) * 0.5)
    return pos
end

local function AUTOPISTOL_C( cmd )
    if vars.me:KeyDown( IN_ATTACK ) and vars.me:Alive() and vars.aim_autopistol and shouldFire() then
        cmd:RemoveKey( IN_ATTACK )
    end
end

local function predictTarget(pos,trg)
    if !pos or not trg then return nulVec end
    local lvel,tvel,frm,eng = vars.me:GetAbsVelocity(), trg:GetAbsVelocity(), vars.realFrameTime(), engine.TickInterval()
    if vars.predtype == 'none' then return pos end
    if vars.predtype == 'classic' then return pos-(lvel*eng) end
    if vars.predtype == 'velocity' then return pos+((lvel-tvel)*(frm/(1/eng))) end
    if vars.predtype == 'ping'  then return pos+(lvel*eng)*(vars.GetLatency) end
    if vars.predtype == 'engine'  then return tvel == nulVec and pos or pos+tvel*eng*frm-lvel*eng end
end

local function _CAIM(cmd)
    if not (vars.aim_aimbot and shouldFire()) then return end

    ded.StartPrediction(cmd)

        vars.target = GetBestTarget()
        local direction = cmd:GetViewAngles()

        if vars.target and cmd:KeyDown(IN_ATTACK) then
            if string.StartsWith(vars.activeWeaponClass, "m9k_") then
                cmd:RemoveKey(IN_SPEED)
            end

            local pos = getCenterBone(vars.target)
            local bonePos = predictTarget(pos, vars.target)

            direction = (bonePos - vars.me:GetShootPos()):Angle()
            direction:Normalize()
        end

        if vars.aim_nospread and cmd:KeyDown(IN_ATTACK) then
            direction = NoSpread(cmd, direction)
        end

        direction = NoRecoil(direction)

        cmd:SetViewAngles(direction)

    ded.FinishPrediction(cmd)
end

-- === MOVEMENT STUFF === --
local function BHOP_C(cmd)
    if vars.bhop then
    	if cmd:KeyDown( IN_JUMP ) then
	    	if !vars.me:OnGround() then
	    		cmd:SetButtons( cmd:GetButtons() - IN_JUMP )
	    	end
            if !vars.bhop_as then return end
        	if vars.me:IsFlagSet( FL_ONGROUND ) then
        	    cmd:SetForwardMove(10000)
        	else
            	cmd:SetForwardMove(5850 / vars.me:GetVelocity():Length2D())
            	cmd:SetSideMove((cmd:CommandNumber() % 2 == 0) && -400 || 400)
        	end
		end
	end
end

local function DESYNC_C(cmd)
    vars.bSend = true
    if vars.desync and !cmd:KeyDown(IN_ATTACK) then
        ded.SetBSendPacket(vars.bSend)
        local tickrate = vars.math_floor(1 / engine.TickInterval())
        local seqshift =  tickrate - (tickrate / 2) + 2
        local bRunning = true
        if (vars.bSend) then
            if (seqshift > 0) then
                if (!vars.bRunning) then
                    ded.SetOutSequenceNr(ded.GetOutSequenceNr() + seqshift)
                    vars.bRunning = true
                else
                    ded.SetNetChokedPackets(127*1.25)
                end
            else
                vars.bRunning = false
            end
        end
    else
    	vars.bRunning = false
    end
end

-- === SPAM STUFF === --
local players=FindMetaTable("Player")
local oldcmd=players.ConCommand
players.ConCommand=function(p,cmd,...)
	if cmd=="jpeg"then return end
	return oldcmd(p,cmd,...)
end
local function SPAM_C(cmd)
    if vars.kDown(KEY_L) then
        vars.rCC("use","gmod_camera")
        if cmd:TickCount()%2==0 then
            cmd:SetButtons(bit.bor(cmd:GetButtons(),IN_ATTACK))
        end
    end
    if vars.kDown(KEY_K) then
        vars.rCC("impulse", "100" )
    end
end

local tauntActive, nextAct = false, 0

local function DANCE_C(cmd)
    if tauntActive or nextAct > vars.C() or not LocalPlayer():Alive() or not vars.act then return end
    vars.rCC("_darkrp_doanimation", "1642")
    vars.rCC("act", "dance")
    tauntActive, nextAct = true, vars.C() + 0.3
    vars.tSimple(7, function() tauntActive = false end)
end

-- === VIEW STUFF === --
local togglethird = false

local function THIRDPERSON_C(cmd)
    if !vars.tps then return end
    if vars.kDown(KEY_V) and !togglethird then
        vars.thirdPersonEnabled = !vars.thirdPersonEnabled
        togglethird = true
    elseif !vars.kDown(KEY_V) then
        togglethird = false
    end
end

local freecamAngles = Angle()
local freecamAngles2 = Angle()
local freecamPos = vars.Vec()
local freecamSpeed = 7
local keyPressed = false

local function FREECAM_C(cmd)
    if vars.kDown(KEY_F) then
        if not keyPressed then
            vars.freecam = not vars.freecam
            freecamAngles = vars.me:EyeAngles()
            freecamAngles2 = vars.me:EyeAngles()
            freecamPos = vars.me:EyePos()
            keyPressed = true
        end
    else
        keyPressed = false
    end

    if vars.freecam then
        cmd:SetSideMove(0)
        cmd:SetForwardMove(0)
        cmd:SetViewAngles(freecamAngles2)
        cmd:RemoveKey(IN_JUMP)
        cmd:RemoveKey(IN_DUCK)

        freecamAngles = freecamAngles + Angle(cmd:GetMouseY() * 0.023, cmd:GetMouseX() * -0.023, 0)
        freecamAngles.p = vars.math_clamp(freecamAngles.p, -89, 89)
        freecamAngles.y = vars.math_NormAngle(freecamAngles.y)
        freecamAngles.x = vars.math_NormAngle(freecamAngles.x)

        local curFreecamSpeed = vars.kDown(KEY_LSHIFT) and (freecamSpeed * 2) or freecamSpeed

        if vars.kDown(KEY_Z) then
            freecamPos = freecamPos + (freecamAngles:Forward() * curFreecamSpeed)
        end
        if vars.kDown(KEY_S) then
            freecamPos = freecamPos - (freecamAngles:Forward() * curFreecamSpeed)
        end
        if vars.kDown(KEY_Q) then
            freecamPos = freecamPos - (freecamAngles:Right() * curFreecamSpeed)
        end
        if vars.kDown(KEY_D) then
            freecamPos = freecamPos + (freecamAngles:Right() * curFreecamSpeed)
        end
    end
end

local function MENU_C(cmd)
    if vars.kDown(KEY_J) and not vars.MenuToggle then
        vars.MenuToggle = true
        ui()
    elseif not vars.kDown(KEY_J) then
        vars.MenuToggle = false
    end
end

local function UnloadHooks()
    for _, v in ip(hooks) do
        vars.hRemove(v.event, v.id)
    end
    print("Unloaded.")
    hooks = {}
end

local function UNLOAD_C(cmd)
    if vars.kDown(KEY_INSERT) then
        if frame:IsVisible() and vars.isValid(frame) then
            ui()
        end
        UnloadHooks()
        vars.unload = false
    end
end

local function _C(cmd)
    if vars.me:IsTyping() or !vars.isValid(vars.me) then return end
    Silent(cmd)

    local psa = vars.aim_silent or vars.antiaim

    if psa and shouldFire() then
        cmd:SetViewAngles(vars.fa)
    end

    local wish_yaw = vars.fa.y

    vars.activeWeaponClass = vars.isValid(vars.me:GetActiveWeapon()) and vars.me:GetActiveWeapon():GetClass() or ""
    vars.activeWeapon = vars.me:GetActiveWeapon()
    vars.model = vars.me:GetModel()

    local createmove_functions = {
        SPAM_C, ANTIAIM_C, AUTOPISTOL_C,
        BHOP_C, THIRDPERSON_C, DESYNC_C,
        FREECAM_C, DANCE_C, MENU_C, UNLOAD_C
    }

    for _, func in ip(createmove_functions) do
        func(cmd)
    end

    if psa and shouldFire() then
        MovementFix(cmd, wish_yaw)
    else
        vars.fa = cmd:GetViewAngles()
    end
end

vieworigin = vars.me:EyePos()
local function getView(fangs, origin, angles, fov)
    local view = {
        origin = origin,
        angles = fangs,
        fov = vars.cam_fov and vars.fov or fov,
        drawviewer = false
    }

    if vars.thirdPersonEnabled then
        local rightOffset = 35
        view.origin = origin - (fangs:Forward() * vars.tps_fov) + (fangs:Right() * rightOffset)
        view.drawviewer = true
    end

    if vars.freecam then
        view.origin = freecamPos
        view.angles = freecamAngles
        view.drawviewer = true
    end

    return view
end

local function _CV(ply, origin, angles, fov, znear, zfar)
    local fangs = vars.fa or angles
    local view = getView(fangs, origin, angles, fov)
    vieworigin = origin
    return view
end

local function _CVMV(wep, vm, oldPos, oldAng, pos, ang, ...)
    if vars.antiaim then
        pos = vieworigin
        ang = vars.fa
        return pos, ang
    end
end

local function GetEntityColor(v)
    if v == vars.target then return Color(255, 165, 0) end
    return (vars.isValid(v) and v:IsPlayer() and IsFriend(v:SteamID())) and Color(0, 255, 0) or Color(255, 0, 0)
end

local IsDrawingGlow = false
local fov = false
local chamsMaterial = Material("models/debug/debugwhite")

local function _PDVM(vm)
    if vars.w_chams then
        vars.rSupEngLight(true)
    
        if IsDrawingGlow then
            vars.rMatOver(chamsMaterial)

            local lightColors = {
                {0.2, 0.2, 0.5}, {0.3, 0.1, 0.6}, {0.1, 0.3, 0.7},
                {0.2, 0.4, 0.8}, {0.4, 0.2, 0.6}, {0.1, 0.5, 0.6}
            }

            for i, color in ip(lightColors) do
                vars.rModelLight(i - 1, unpack(color))
            end
        else
            vars.rColorMod(1, 1, 1)
            vars.rBlend(1)
        end
    end

    if vars.w_fov then
        if !fov then
            vars.Cam3Ds(nil, nil, vars.wfov)
            vars.rDepthRange( 0.2, 0 )
            fov = true
            vm:DrawModel()
            fov = false
            vars.Cam3De()
        else
            return
        end
        return true
    else
        return false
    end
end

local function _PODVM()
	if vars.w_chams then
		vars.rColorMod(1, 1, 1)
		vars.rMatOver(None)
		vars.rBlend(1)
		vars.rSupEngLight(false)
		if IsDrawingGlow then return end

		IsDrawingGlow = true
		vars.me:GetViewModel():DrawModel()
		IsDrawingGlow = false
	end
end

local function camignorez(bool)
    vars.rDepthRange( 0,bool and 0.8 or 1 )
end

local function chamz(v)
    if not vars.isValid(v) or v == vars.me or not v:Alive() or v:IsDormant() or vars.me:GetPos():Distance(v:GetPos()) > 10000 then return end
    if not vars.me:InVehicle() and not vars.antiaim and IsOutOfFOV(v) then return end

    local teamColor = team.GetColor(v:Team())
    local r, g, b = teamColor.r / 255, teamColor.g / 255, teamColor.b / 255

    local lightColors = {
        {r * 0.2 + 0.05, g * 0.1 + 0.05, b * 0.3 + 0.2}, -- BOX_FRONT 
        {r * 0.4, g * 0.3 - 0.05, b * 0.2 + 0.1},       -- BOX_BACK 
        {r * 0.7, g * 0.6 - 0.05, b * 0.2 - 0.1},      -- BOX_RIGHT
        {r * 0.8, g * 0.5, b * 0.3 - 0.2},            -- BOX_LEFT
        {r * 0.9, g * 0.8, b * 0.3 - 0.1},            -- BOX_TOP
        {r * 0.4, g * 0.3, b * 0.5 + 0.2}             -- BOX_BOTTOM
    }

    local GodAndNoclip = {
        {0.01, 0.01, 0.02}, {0.10, 0.00, 0.20}, {0.25, 0.00, 0.40}, 
        {0.50, 0.00, 0.20}, {0.70, 0.00, 0.10}, {0.30, 0.00, 0.35} 
    }

    local isGod = v:HasGodMode()
    local isNoclipped = v:GetMoveType() == MOVETYPE_NOCLIP
    local colorTable = (isGod or isNoclipped) and GodAndNoclip or lightColors

    vars.rSupEngLight(true)
    camignorez(true)

    vars.rMatOver(chamsMaterial)
    if IsGod and isNoclipped then
        vars.rBlend(0.3)
    end
    for i, color in ip(colorTable) do
        vars.rModelLight(i - 1, unpack(color))
    end
    v:DrawModel()

    vars.rMatOver()
    vars.rColorMod(1, 1, 1)
    vars.rSupEngLight(false)
    camignorez(false)
end

local function _PDE()
    for k,v in ip(player.GetAll()) do
        if (vars.isValid(v) and v:Alive() and v ~= vars.me) then
            if vars.esp_chams then chamz(v) end
        end
    end
end

local lerpData = {}

local function GetHealthColor(health)
    local t = health / 100
    return Color(255 * (1 - t), 255 * t, 0, 255)
end

local function boxcorners(v)
    if not vars.isValid(v) or not v:IsPlayer() then return end

    local data = lerpData[v] or { health = v:Health(), armor = v:Armor() }
    lerpData[v] = data

    local min, max = v:GetCollisionBounds()
    local pos, pos2 = v:GetPos(), v:GetPos() + vars.Vec(0, 0, max.z)
    pos, pos2 = vars.tScreen(pos), vars.tScreen(pos2)

    local h, w = pos.y - pos2.y, (pos.y - pos2.y) / 2
    local x, y = pos.x - w / 2, pos.y - h

    vars.sSetDrawColor(Color(0, 0, 0))
    vars.sDrawOutlinedRect(x - 1, y - 1, w + 2, h + 2)

    vars.sSetDrawColor(GetEntityColor(v))
    vars.sDrawOutlinedRect(x, y, w, h)

    local health = vars.math_clamp(v:Health(), 0, 100)
    data.health = Lerp(FrameTime() * 10, data.health, health)
    
    local healthColor = GetHealthColor(health)
    local healthBarHeight = h * (data.health / 100)

    vars.sSetDrawColor(Color(0, 0, 0))
    vars.sDrawRect(x - 6, y - 1, 4, h + 2)

    vars.sSetDrawColor(healthColor)
    vars.sDrawRect(x - 5, y + h - healthBarHeight, 2, healthBarHeight)

    local armor = vars.math_clamp(v:Armor(), 0, 100)
    data.armor = Lerp(FrameTime() * 10, data.armor, armor)
    
    local armorBarHeight = h * (data.armor / 100)

    vars.sSetDrawColor(Color(0, 0, 0))
    vars.sDrawRect(x + w + 2, y - 1, 4, h + 2)

    vars.sSetDrawColor(Color(0, 150, 255))
    vars.sDrawRect(x + w + 3, y + h - armorBarHeight, 2, armorBarHeight)
end

local function txtesp(v)
    local pos = vars.tScreen((v:GetPos() + vars.Vec(0, 0, 75)))
    
    local pName = v:Nick()
    if v:IsAdmin() then
        pName = pName .. " [STAFF]"
    end

    vars.dSimpleTextOutlined(pName, vars.cmdfont, pos.x, pos.y, GetEntityColor(v), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 1, Color(30, 30, 30, 255))
end

local function xhair()
    local X, Y = vars.sw * 0.5, vars.sh * 0.5

    if vars.thirdPersonEnabled then
        local trace = util.TraceLine({
            start = vars.me:EyePos(),
            endpos = vars.me:EyePos() + vars.fa:Forward() * 10000,
            filter = vars.me
        })

        if trace.Hit then
            local screenPos = vars.tScreen(trace.HitPos)
            X, Y = screenPos.x or X, screenPos.y or Y
        end
    end

    local size, thickness = 3.5, 2
    vars.sSetDrawColor(255, 0, 0, 255)
    vars.sDrawRect(X - size - thickness, Y - thickness * 0.5, size, thickness)
    vars.sDrawRect(X + thickness, Y - thickness * 0.5, size, thickness)
    vars.sDrawRect(X - thickness * 0.5, Y - size - thickness, thickness, size)
    vars.sDrawRect(X - thickness * 0.5, Y + thickness, thickness, size)
end

local function watermark()
	---- WATERMARK ----
    vars.sSetDrawColor(colors.Background1)
    vars.sDrawRect(10, 10, 200, 94)
    vars.sSetDrawColor(colors.TopBar1)
    vars.sDrawRect(10, 10, 200, 3)
    vars.dDrawText( "Client fps: "..  vars.math_round( 1 / FrameTime()), vars.cmdfont, 25, 20, Color( 255, 255, 255, 255 ) )
    vars.dDrawText( "Server Tick: "..  vars.math_round( 1/engine.TickInterval()) .. "" , vars.cmdfont, 25, 33, Color( 255, 255, 255, 255 ) )
    vars.dDrawText( "Date: "..  os.date( "%d/%m/%Y" ) .. "" , vars.cmdfont, 25, 46, Color( 255, 255, 255, 255 ) )
    vars.dDrawText( "Version: "..  "2.0" .. "" , vars.cmdfont, 25, 58, Color( 255, 255, 255, 255 ) )

    local choke_seconds = ded.GetAvgChoke(0) / 100

    vars.dDrawText( "Desync: ".. string.format("%.3f sec", choke_seconds) , vars.cmdfont, 25, 78, Color( 255, 255, 255, 255 ) )
    ------------------
end

local function _HP()
    if vars.unload then
        for k,v in ip(player.GetAll()) do
            if not vars.isValid(v) or v == vars.me or not v:Alive() or v:IsDormant() then continue end
            if vars.me:GetPos():Distance(v:GetPos()) > 10000 then continue end
            if not vars.me:InVehicle() and not vars.antiaim and IsOutOfFOV(v) then continue end

            if vars.esp_boxes then boxcorners(v) end
            if vars.esp then txtesp(v) end
        end
        if vars.aim_aimbot and !vars.thirdPersonEnabled then
            local X1 = vars.math_tan( vars.math_rad( vars.aim_fov ) / 1.25 )
            local X2 = vars.math_tan( vars.math_rad( vars.me:GetFOV() / 2 ) )
            local r = X1 / X2
            local pxR = r * ( vars.sw / 2 )
            vars.sDrawCircle(vars.sw / 2, vars.sh / 2, pxR, colors.red)
            if vars.target and shouldFire() then
                local bonePos = getCenterBone(vars.target)
                if not bonePos then return end
                local pos = vars.tScreen(bonePos)
                vars.sSetDrawColor( colors.red )
                vars.sDrawLine( pos.x, pos.y, vars.sw / 2, vars.sh / 2 )
            end
        end
        xhair()
        watermark()
     end
end

local function _OI(data)
    vars.bulletImpacts[#vars.bulletImpacts + 1] = {
        shootTime = vars.C(),
        pos = data.m_vOrigin,
        alpha = 255
    }
end

local function _PDOR()
    local currentTime = vars.C()

    for i = #vars.bulletImpacts, 1, -1 do
        local impact = vars.bulletImpacts[i]
        local timeLeft = 0.5 - (currentTime - impact.shootTime)

        if timeLeft <= 0 then
            vars.tRemove(vars.bulletImpacts, i)
        else
            local fadeFactor = timeLeft * 2
            local size = 4 * fadeFactor
            local color = Color(255 * fadeFactor, 0, 255 * (1 - fadeFactor), 255 * fadeFactor)

            vars.Cam3Ds()
                vars.rColorMat()
                vars.rDrawBox(impact.pos, angle_zero, vars.Vec(-size, -size, -size), vars.Vec(size, size, size), color)
            vars.Cam3De()
        end
    end
end

VARhooks("CreateMove", _C)
VARhooks("PostCreateMove", _CAIM)
VARhooks("CalcView", _CV)
VARhooks("CalcViewModelView", _CVMV)
VARhooks("PreDrawViewModel", _PDVM)
VARhooks("PostDrawViewModel", _PODVM)
VARhooks('PreDrawEffects', _PDE)
VARhooks('HUDPaint', _HP)
VARhooks("OnImpact", _OI)
VARhooks("PostDrawOpaqueRenderables", _PDOR)
