--Variable Assigning
local plyr = LocalPlayer()
local friends = {}
local lookingat = nil
local lookingatsid = nil
local ticks = 0
local hopped = 0
local minf = 13
local maxf = 18
local multiplier = 2.2
local maxdist = 3500

for i = minf, maxf do
    surface.CreateFont("Adolf_"..tostring(i), {size = i})
end
local adolf_material = CreateMaterial("adolf_material", "UnlitGeneric", {
    ["$basetexture"] = "models/debug/debugwhite",
    ["$ignorez"] = 1,
})


--Functions
local function update_la()
    local lookingat = plyr:GetEyeTrace().Entity
    if lookingat:IsPlayer() and !lookingat:IsBot() then
        lookingatsid = lookingat:SteamID64()
    else 
        lookingatsid = nil
    end
end

hook.Add("Think", "update_looking_at", function()
    ticks = ticks + 1
    if ticks >= 100 then
        update_la()
        ticks = 0
    end
end)
hook.Add("Think", "bhop", function()
    if bhop then
        if input.IsKeyDown(KEY_SPACE) and plyr:GetMoveType() != MOVETYPE_NOCLIP and plyr:GetVelocity():Length() > 1 then
            if plyr:IsOnGround() then
                RunConsoleCommand("+jump")
                hopped = 1
            else
                RunConsoleCommand("-jump")
                hopped = 0
            end
        elseif bhop and plyr:IsOnGround() then
            RunConsoleCommand("-jump")
            hopped = 0
        end
    end
end)
hook.Add("Think", "map_xray", function()
    local mapmats = Entity(0):GetMaterials()
    for k, v in pairs(mapmats) do
        local mat = Material(v)
        if map_xray then
            mat:SetFloat("$alpha", 0.75)
        else
            mat:SetFloat("$alpha", 1)
        end
    end
end)
hook.Add("Think", "flashlight_spam", function()
    if flashlight_spam then
        if input.IsKeyDown(KEY_F) and plyr:GetVelocity():Length() > 1 then
            plyr:ConCommand("impulse 100")
        end
    end
end)
hook.Add("Think", "fullbright", function()
    local dynlightf = DynamicLight(plyr:EntIndex())
    if fullbright then
        dynlightf.pos = plyr:GetShootPos()
        dynlightf.r = 255
        dynlightf.g = 255
        dynlightf.b = 255
        dynlightf.brightness = 1
        dynlightf.Decay = 0
        dynlightf.Size = 5000
        dynlightf.DieTime = CurTime() + 1
    end
end)
hook.Add("Think", "adv_flashlight", function()
    local dynlighta = DynamicLight(plyr:EntIndex())
    if adv_flashlight then
        dynlighta.pos = plyr:GetEyeTrace().HitPos
        dynlighta.r = 255
        dynlighta.g = 255
        dynlighta.b = 255
        dynlighta.brightness = 1
        dynlighta.Decay = 0
        dynlighta.Size = 1000
        dynlighta.DieTime = CurTime() + 1
    end
end)

hook.Add("HUDPaint", "esp_3dbox", function()
    if esp_3dbox then
        for k, v in pairs(player.GetAll()) do
            if v != plyr and v:Alive() then
                local dist = plyr:GetPos():Distance(v:GetPos())
                local coloring3d = friends[v:SteamID64()] and Color(0, 200, 255) or Color(255, 200, 0)
                if !friends[v:SteamID64()] and dist < maxdist then
                    cam.Start3D(EyePos(), EyeAngles())
                    render.DrawWireframeBox(v:GetPos(), Angle(0, 0, 0), Vector(-16, -16, 0), Vector(16, 16, 72), coloringfr, true)
                    cam.End3D()
                elseif friends[v:SteamID64()] then
                    cam.Start3D(EyePos(), EyeAngles())
                    render.DrawWireframeBox(v:GetPos(), Angle(0, 0, 0), Vector(-16, -16, 0), Vector(16, 16, 72), coloringfr, true)
                    cam.End3D()
                end
            end
        end
    end
end)
hook.Add("HUDPaint", "esp_chams", function()
    if esp_chams then
        for k, v in pairs(player.GetAll()) do
            if v != plyr and v:Alive() then
                local dist = plyr:GetPos():Distance(v:GetPos())
                if friends[v:SteamID64()] then render.SetColorModulation(0, 0.78, 1) else render.SetColorModulation(1, 0.78, 0) end
                if !friends[v:SteamID64()] and dist < maxdist then
                    cam.Start3D(EyePos(), EyeAngles())
                    render.MaterialOverride(adolf_material)
                    v:DrawModel()
                    cam.End3D()
                elseif friends[v:SteamID64()] then
                    cam.Start3D(EyePos(), EyeAngles())
                    render.MaterialOverride(adolf_material)
                    v:DrawModel()
                    cam.End3D()
                end
            end
        end
    end
end)
hook.Add("HUDPaint", "esp_names", function()
    if esp_names then
        for k, v in pairs(player.GetAll()) do
            if v != plyr and v:Alive() then
                local dist = plyr:GetPos():Distance(v:GetPos())
                local coloringnm = friends[v:SteamID64()] and Color(0, 200, 255) or Color(255, 200, 0)
                local plyrpos = (v:GetPos() + Vector(0, 0, 45)):ToScreen()
                local fontsize = math.Clamp(minf+(maxf % math.floor(math.Clamp(math.log(dist) * multiplier, minf, maxf))) + 1, minf, maxf)
                local font = "Adolf_"..tostring(fontsize)
                if !friends[v:SteamID64()] and dist < maxdist then draw.SimpleTextOutlined(v:Name(), font, plyrpos.x, plyrpos.y + 10, coloringnm, 1, 1, 1, Color(0, 0, 0, 255))
                elseif friends[v:SteamID64()] then draw.SimpleTextOutlined(v:Name(), font, plyrpos.x, plyrpos.y + 10, coloringnm, 1, 1, 1, Color(0, 0, 0, 255))
                end
            end
        end
    end
end)
hook.Add("HUDPaint", "esp_hp", function()
    if esp_hp then
        for k, v in pairs(player.GetAll()) do
            if v != plyr and v:Alive() then
                local dist = plyr:GetPos():Distance(v:GetPos())
                local coloringhp = friends[v:SteamID64()] and Color(0, 200, 255) or Color(255, 200, 0)
                local plyrpos = (v:GetPos() + Vector(0, 0, 45)):ToScreen()
                local fontsize = math.Clamp(minf+(maxf % math.floor(math.Clamp(math.log(dist) * multiplier, minf, maxf))) + 1, minf, maxf)
                local font = "Adolf_"..tostring(fontsize)
                if !friends[v:SteamID64()] and dist < maxdist then draw.SimpleTextOutlined(tostring(v:Health()).." HP", font, plyrpos.x, plyrpos.y + 22, coloringhp, 1, 1, 1, Color(0, 0, 0, 255))
                elseif friends[v:SteamID64()] then draw.SimpleTextOutlined(tostring(v:Health()).." HP", font, plyrpos.x, plyrpos.y + 22, coloringhp, 1, 1, 1, Color(0, 0, 0, 255))
                end
            end
        end
    end
end)
hook.Add("HUDPaint", "esp_rank", function()
    if esp_rank then
        for k, v in pairs(player.GetAll()) do
            if v != plyr and v:Alive() then
                local dist = plyr:GetPos():Distance(v:GetPos())
                local coloringrn = friends[v:SteamID64()] and Color(0, 200, 255) or Color(255, 200, 0)
                local plyrpos = (v:GetPos() + Vector(0, 0, 45)):ToScreen()
                local fontsize = math.Clamp(minf+(maxf % math.floor(math.Clamp(math.log(dist) * multiplier, minf, maxf))) + 1, minf, maxf)
                local font = "Adolf_"..tostring(fontsize)
                if !friends[v:SteamID64()] and dist < maxdist then draw.SimpleTextOutlined(v:GetNWString("usergroup"), font, plyrpos.x, plyrpos.y + 34, coloringrn, 1, 1, 1, Color(0, 0, 0, 255))
                elseif friends[v:SteamID64()] then draw.SimpleTextOutlined(v:GetNWString("usergroup"), font, plyrpos.x, plyrpos.y + 34, coloringrn, 1, 1, 1, Color(0, 0, 0, 255))
                end
            end
        end
    end
end)
hook.Add("HUDPaint", "esp_distance", function()
    if esp_distance then
        for k, v in pairs(player.GetAll()) do
            if v != plyr and v:Alive() then
                local dist = plyr:GetPos():Distance(v:GetPos())
                local dist2metric = math.Round(dist/52.5210084034,2)
                local coloringrn = friends[v:SteamID64()] and Color(0, 200, 255) or Color(255, 200, 0)
                local plyrpos = (v:GetPos() + Vector(0, 0, 45)):ToScreen()
                local fontsize = math.Clamp(minf+(maxf % math.floor(math.Clamp(math.log(dist) * multiplier, minf, maxf))) + 1, minf, maxf)
                local font = "Adolf_"..tostring(fontsize)
                if !friends[v:SteamID64()] and dist < maxdist then draw.SimpleTextOutlined(dist2metric.."m", font, plyrpos.x, plyrpos.y + 44, coloringrn, 1, 1, 1, Color(0, 0, 0, 255))
                elseif friends[v:SteamID64()] then draw.SimpleTextOutlined(dist2metric.."m", font, plyrpos.x, plyrpos.y + 44, coloringrn, 1, 1, 1, Color(0, 0, 0, 255))
                end
            end
        end
    end
end)

--Command adding
concommand.Add("adolf_friend_sys", function() 
    update_la()
    if lookingatsid ~= nil then
        friends[lookingatsid] = (friends[lookingatsid] == nil and true or nil)
    end
end)
concommand.Add("adolf_esp_3dbox_toggle", function() esp_3dbox = !esp_3dbox end)
concommand.Add("adolf_esp_chams_toggle", function() esp_chams = !esp_chams end)
concommand.Add("adolf_esp_names_toggle", function() esp_names = !esp_names end)
concommand.Add("adolf_esp_hp_toggle", function() esp_hp = !esp_hp end)
concommand.Add("adolf_esp_rank_toggle", function() esp_rank = !esp_rank end)
concommand.Add("adolf_esp_distance_toggle", function() esp_distance = !esp_distance end)
concommand.Add("adolf_bhop_toggle", function() bhop = !bhop end)
concommand.Add("adolf_map_xray_toggle", function() map_xray = !map_xray end)
concommand.Add("adolf_flashlight_spam_toggle", function() flashlight_spam = !flashlight_spam end)
concommand.Add("adolf_fullbright_toggle", function() fullbright = !fullbright end)
concommand.Add("adolf_adv_flashlight_toggle", function() adv_flashlight = !adv_flashlight end)

--[[
Code

Lua Highlighting specific players

adolf_highlight_player <player name> <looking at>
if adolf_esp_higlight then
If !playername then
Local player2highlight = p:geteyetrace():player():steamid()
Else
Local player2highlight = player():steam()
End
Table highlight add player2highlight
End
coloringhg = stuff
​
]]