LUA скрипт [spirt] hud: watermark, keylist, speclist

Дизайнер
Статус
Оффлайн
Регистрация
18 Авг 2017
Сообщения
1,924
Реакции[?]
2,245
Поинты[?]
146K
Товары в продаже
1
1688664865984.png
Пожалуйста, авторизуйтесь для просмотра ссылки.


в коде есть крутые виджеты, драг и анимации, советую
Код:
-- spirthud
---- enq

-- КакДатыPascalCase


--
-- #region : Definitions

-- #region - Globals

math.clamp = function (v, a, b)  if v < a then return a elseif v > b then return b else return v end  end
string.limit = function (s, l, c) local r, i = {}, 1 for w in string.gmatch(s, ".[\128-\191]*") do i, r[i] = i + 1, w if i > l then if c then r[i] = c == true and "..." or c end break end end return table.concat(r) end

-- #endregion

-- #region - Render and widgets

local Screen = EngineClient.GetScreenSize()

local Colors = {
    Text = Color.new(1, 1, 1),
    Frame = Color.new(33 / 255, 28 / 255, 66 / 255),
    Back = Color.new(15 / 255, 12 / 255, 33 / 255),
    Main = Color.new(23 / 255, 20 / 255, 41 / 255),
    FadeA = Color.new(24 / 255, 21 / 255, 48 / 255),
    FadeB = Color.new(28 / 255, 25 / 255, 61 / 255),
    Accent = Color.new(107 / 255, 89 / 255, 222 / 255),
}

do
    local ColorMt = getmetatable(Colors.Text)
    ColorMt.SetAlpha = function (self, a, s)
        return Color.new(self.r, self.g, self.b, s and self.a * a or a)
    end
end

local Images = {
    Arrows = Render.LoadImage("\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x0A\x00\x00\x00\x0A\x08\x06\x00\x00\x00\x8D\x32\xCF\xBD\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7C\x08\x64\x88\x00\x00\x00\x6D\x49\x44\x41\x54\x18\x57\x85\x90\xD1\x0D\xC0\x20\x08\x44\x61\xB2\x76\x93\xEA\x64\xB5\x9B\x74\x33\x7B\xD7\x08\xA5\x7C\xA8\x09\x21\x0F\x8F\x13\xD4\xDE\x7B\x11\x91\x4D\x55\x2B\xB2\x64\x66\x8D\x47\x71\xD1\x90\x0F\x44\xA3\x38\xB3\x0B\x87\xCB\x52\xAC\xD6\xB1\x72\x76\xE1\x70\xBE\x39\x2F\xA2\x62\x8C\x86\xE6\x8F\x83\x23\x97\x3A\x11\x17\x44\x65\x2C\xE5\xFC\x3A\xE6\x62\x66\xDB\x7A\xEA\x14\xBF\x87\xC2\x9D\xCF\x05\x77\xE7\xDF\xF7\x18\xCC\xF2\x03\x7A\x89\x55\x68\x5B\xE3\x6A\x5D\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82", Vector2.new(10, 10)),
    Logo = Render.LoadImage("\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x0C\x00\x00\x00\x0C\x08\x06\x00\x00\x00\x56\x75\x5C\xE7\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7C\x08\x64\x88\x00\x00\x00\xA9\x49\x44\x41\x54\x28\x53\x6D\x91\x0B\x11\xC2\x30\x10\x44\x39\x05\xD4\x02\x0E\x70\x40\xAB\x84\xD6\x01\x38\xC1\x41\xE3\x00\x09\x54\x02\x38\x01\x05\x61\xB7\x93\xEB\x5C\x37\xC9\xCC\xCD\x34\x7B\xFB\xEE\x93\xDA\x41\x4E\xCE\xB9\x83\xF4\x44\xDC\xCD\xEC\xAD\x79\x8B\x42\x31\xBF\xA0\x9D\x11\x5F\xC4\xA0\xD0\x06\x88\xF9\x07\xF3\xB1\x05\xAD\x80\x98\x3F\x90\x7A\xC4\x03\x71\x55\xC8\x5A\x66\x8C\xC1\x71\x58\x28\x29\x44\x60\x81\x78\x29\x95\x4E\x6E\xF6\xDD\xAA\x3C\x04\x2E\x48\x88\x33\x27\x00\x53\x30\x8F\xF8\x9E\xCB\x7D\x42\x2E\xF9\x0E\x15\x84\x42\x95\x99\x60\x7C\xA5\x08\xB1\x23\x17\xE7\x59\x2B\x7B\x57\xFD\x0F\x11\xAA\xCC\xBB\x0E\x61\x6E\x87\x6E\xB1\x72\xB3\x43\x80\x3A\x7D\x2D\xCF\xFD\x01\x8D\x5B\x59\x1A\x80\xD2\xA3\x1A\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82", Vector2.new(12, 12))
}

local Anima do
    local animators = setmetatable({}, {__mode = "k"})

    --
    Anima = {
        Pulse = 0,

        Easings = {
            pow = {
                function (x, p) return 1 - ((1 - x) ^ (p or 3)) end,
                function (x, p) return x ^ (p or 3) end,
                function (x, p) return x < 0.5 and 4 * math.pow(x, p or 3) or 1 - math.pow(-2 * x + 2, p or 3) * 0.5 end,
            }
        },

        Lerp = function (a, b, s, t)
            local c = a + (b - a) * GlobalVars.absoluteframetime * (s or 8)
            return math.abs(b - c) < (t or 0.002) and b or c
        end,

        Condition = function (id, c, s, e)
            local ctx = id[1] and id or animators[id]
            if not ctx then animators[id] = { c and 1 or 0, c }; ctx = animators[id] end

            s = s or 4
            local cur_s = s
            if type(s) == "table" then cur_s = c and s[1] or s[2] end

            ctx[1] = math.clamp(ctx[1] + ( GlobalVars.absoluteframetime * math.abs(cur_s) * (c and 1 or -1) ), 0, 1)

            return (ctx[1] % 1 == 0 or cur_s < 0) and ctx[1] or
            Anima.Easings.pow[e and (c and e[1][1] or e[2][1]) or (c and 1 or 3)](ctx[1], e and (c and e[1][2] or e[2][2]) or 3)
        end
    }
end

local Drag do
    local Current

    local InBounds = function (p, s, e)
        return (p.x >= s.x and p.x <= e.x) and (p.y >= s.y and p.y <= e.y)
    end

    local Process = function (Widget)
        local ctx = Widget.__drag
        if ctx.Locked or not Cheat.IsMenuVisible() then return end

        local Mouse, MenuPos, MenuSize = Cheat.GetMousePos(), Render.GetMenuPos(), Render.GetMenuSize()
        local Held = Cheat.IsMenuVisible() and Cheat.IsKeyDown(1)
        local Hovered = InBounds(Mouse, Widget.pos, Widget.pos + Widget.size) and not InBounds(Mouse, MenuPos, (MenuPos + MenuSize))

        --
        if Held and ctx.ready == nil then
            ctx.ready, ctx.point, ctx.init = Hovered, Widget.pos - Mouse, Vector2.new(Widget.pos.x, Widget.pos.y)
        end

        if Held and ctx.ready then
            Current = (ctx.ready and Current == nil) and Widget.id or Current
            ctx.active = Current == Widget.id
        elseif not Held then
            ctx.active = false
            ctx.ready, ctx.point, ctx.init, Current = nil, nil, nil, nil
        end

        ctx.hovered = Hovered or ctx.active
        local Wished = ctx.point and (ctx.point + Mouse) or Widget.pos

        --
        if ctx.active then
            local Finale = Wished

            --
            Widget.pos.x, Widget.pos.y = math.clamp(Finale.x, 0, Screen.x - Widget.size.x), math.clamp(Finale.y, 0, Screen.y - Widget.size.y)
            ctx.config.x:Set(Widget.pos.x)
            ctx.config.y:Set(Widget.pos.y)
        end
    end

    --
    Drag = function (Widget, Props)
        Props = Props or {}

        Widget.__drag = {
            locked = false, active = false, hovered = nil, point = Vector2.new(0, 0),
            process = Process,
            config = {
                x = Menu.SliderInt("General", Widget.id .. "-x", Widget.pos.x, 0, Screen.x),
                y = Menu.SliderInt("General", Widget.id .. "-y", Widget.pos.y, 0, Screen.y),
            }
        }

        Widget.pos.x, Widget.pos.y = Widget.__drag.config.x:Get(), Widget.__drag.config.y:Get()
        Widget.__drag.config.x:RegisterCallback(function (val) Widget.pos.x = val end)
        Widget.__drag.config.y:RegisterCallback(function (val) Widget.pos.y = val end)
        Widget.__drag.config.x:SetVisible(false)
        Widget.__drag.config.y:SetVisible(false)
    end
end

local Widget do
    local WidgetMt; WidgetMt = {
        update = function (self) return 1 end,
        paint = function (self, pos, fin) end,

        __call = function (self)
            local __list, __drag = self.__list, self.__drag
            if __list then
                __list.items, __list.active = __list.collect(), 0
                for i = 1, #__list.items do
                    if __list.items[i].active then __list.active = __list.active + 1 end
                end
            end
            self.alpha = self:update()

            if self.alpha > 0 then
                if __drag then __drag.process(self) end
                if __list then WidgetMt.traverse(self) end
                self:paint(self.pos, self.pos + self.size)
            end
        end,

        enlist = function (self, collector, painter)
            self.__list = {
                items = {}, progress = setmetatable({}, { __mode = "k" }),
                longest = 0, active = 0, minwidth = self.size.x, height = 0,
                collect = collector, paint = painter,
            }
        end,
        traverse = function (self)
            local ctx, offset, latest = self.__list, 0, Vector2.new(0, 0)
            ctx.active, ctx.longest = 0, 0

            Render.BoxFilled(Vector2.new(self.pos.x, self.pos.y + 32), Vector2.new(self.pos.x + self.size.x, self.pos.y + ctx.height + 32), Colors.Main:SetAlpha(self.alpha, true))

            for i = 1, #ctx.items do
                local v = ctx.items[i]
                local id = v.name or i
                ctx.progress[id] = ctx.progress[id] or {0}
                local progress = Anima.Condition(ctx.progress[id], v.active)

                if progress > 0 then
                    latest = ctx.paint(self, v, offset, progress)

                    ctx.active, offset = ctx.active + 1, offset + (latest.y * progress)
                    ctx.longest = math.max(ctx.longest, latest.x)
                end
            end

            ctx.height = offset
            self.size.x = Anima.Lerp(self.size.x, math.max(ctx.longest, ctx.minwidth), 10, .5)
        end,

        lock = function (self, b)
            if not self.__drag then return end
            self.__drag.locked = b and true or false
        end,
    }    WidgetMt.__index = WidgetMt

    --
    Widget = function (ID, Pos, Size, Draggable)
        local self = {
            id = ID, pos = Pos, size = Size,
            alpha = 1, progress = {0}
        }

        if Draggable then
            Drag(self, type(Draggable) == "table" and Draggable or nil)
        end

        return setmetatable(self, WidgetMt)
    end
end

-- #endregion

-- #endregion
--



--
-- #region : Main

local HUD = {}
local Vars = {
    Menu.Text("Info", "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  SpirtHUD"),
    Menu.Text("Info", "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Designed by enQ"),
    Color = Menu.ColorEdit("Widgets", "Accent color", Colors.Accent),
    Watermark = Menu.Switch("Widgets", "Watermark", true),
    TimeZone = Menu.SliderInt("Widgets", "\tTime Zone", 3, -12, 12),
    Keylist = Menu.Switch("Widgets", "Keylist", false),
    Speclist = Menu.Switch("Widgets", "Speclist", false),
}

Vars.TimeZone:SetVisible(Vars.Watermark:Get())
Vars.Watermark:RegisterCallback(function (v)
    Vars.TimeZone:SetVisible(v)
end)


-- #region - Watermark

HUD.Watermark = Widget("Watermark", Vector2.new(Screen.x - 194 - 24, 24), Vector2.new(194, 32))

HUD.Watermark.GetTime = function ()
    local UnixTime = Utils.UnixTime() / 1000
    local Hours = (UnixTime / 3600 + Vars.TimeZone:Get()) % 24
    local Minutes = UnixTime / 60 % 60
    return math.floor(Hours), math.floor(Minutes)
end

HUD.Watermark.update = function (self)
    return Anima.Condition(self.progress, Vars.Watermark:Get())
end

HUD.Watermark.paint = function (self, Pos, Fin)
    Render.BoxFilled(Pos, Fin, Colors.Back, 4)
    Render.Image(Images.Logo, Vector2.new(Pos.x + 12, Pos.y + 10), Vector2.new(12, 12), Colors.Accent:SetAlpha(self.alpha, true))
    Render.Text("SpirtHack", Vector2.new(Pos.x + 32, Pos.y + 8), Colors.Text:SetAlpha(self.alpha, true), 14)
    local LogoSize = Render.CalcTextSize("SpirtHack", 14)
    LogoSize.x = LogoSize.x + 44

    Pos = Vector2.new(Pos.x + LogoSize.x, Pos.y)
    Render.BoxFilled(Vector2.new(Pos.x, Pos.y), Fin, Colors.Main:SetAlpha(self.alpha, true), 4)
    Render.Box(Vector2.new(Pos.x, Pos.y), Fin, Colors.Frame:SetAlpha(self.alpha, true), 4)

    local Latency = EngineClient.GetNetChannelInfo()
    Latency = Latency and Latency:GetLatency(0) * 1000
    local Hours, Minutes = self.GetTime()
    local Text = string.format("%s  /  %02d:%02d" .. ((Latency and Latency > 5) and "  /  %dms" or ""), Cheat.GetCheatUserName(), Hours, Minutes, Latency)

    local TextSize = Render.CalcTextSize(Text, 14)
    TextSize.x = TextSize.x + 24
    Render.Text(Text, Vector2.new(Pos.x + 12, Pos.y + 8), Colors.Text:SetAlpha(self.alpha, true), 14)

    self.size.x = Anima.Lerp(self.size.x, LogoSize.x + TextSize.x, 12, .1)
    self.pos.x = Screen.x - self.size.x - 24
end

-- #endregion

-- #region - Keylist

HUD.Keylist = Widget("Keylist", Vector2.new(Render.GetMenuPos().x + Render.GetMenuSize().x + 16, Render.GetMenuPos().y), Vector2.new(140, 32), true)

HUD.Keylist.FormatValue = function (v)
    if v == "on" or v == "off" or tonumber(v) then
        return v
    else
        return string.gsub(v, "%l", "")
    end
end

HUD.Keylist:enlist(function ()
    local Raw, Binds = Cheat.GetBinds(), {}
    local Len = #Raw
    for i = 1, Len do
        local v, n = Raw[i], Len - i + 1
        Binds[n] = {
            n = n,
            name = v:GetName(),
            value = v:GetValue(),
            active = v:IsActive(),
        }
    end
    return Binds
end, function (self, Item, Offset, Progress)
    local Pos = Vector2.new(self.pos.x, self.pos.y + Offset + 32 * Progress)
    local Size = Vector2.new(self.size.x, 32)
    local End = Pos + Size

    Render.Box(Pos - Vector2.new(0, 1), End, Colors.Frame:SetAlpha(self.alpha * Progress, true))

    local Value = self.FormatValue(Item.value)
    local LengthA = Render.CalcTextSize(Item.name, 14)
    local LengthB = Render.CalcTextSize(Value, 14)
    Render.Text(Item.name, Pos + Vector2.new(12, 8), Colors.Text:SetAlpha(self.alpha * Progress, true), 14)
    Render.Text(Value, Vector2.new(End.x - 12 - LengthB.x, Pos.y + 8), Colors.Accent:SetAlpha(self.alpha * Progress, true), 14)

    return Vector2.new(LengthA.x + LengthB.x + 40, 32)
end)

HUD.Keylist.update = function (self)
    return Anima.Condition(self.progress, Vars.Keylist:Get() and (Cheat.IsMenuVisible() or self.__list.active > 0))
end

HUD.Keylist.paint = function (self, Pos, End)
    local CFadeA, CFadeB = Colors.FadeA:SetAlpha(self.alpha, true), Colors.FadeB:SetAlpha(self.alpha, true)
    Render.GradientBoxFilled(Pos, End, CFadeA, CFadeB, CFadeA, CFadeB)
    Render.Box(Pos, End, Colors.Frame:SetAlpha(self.alpha, true))
    Render.Text("Hotkeys", Vector2.new(Pos.x + 28, Pos.y + 8), Colors.Text:SetAlpha(self.alpha, true), 14)
    Render.Image(Images.Arrows, Vector2.new(Pos.x + 12, Pos.y + 12), Vector2.new(10, 10), Colors.Accent:SetAlpha(self.alpha, true))
end

-- #endregion

-- #region - Speclist

HUD.Speclist = Widget("Speclist", Vector2.new(Render.GetMenuPos().x + Render.GetMenuSize().x + 16, Render.GetMenuPos().y + 240), Vector2.new(140, 32), true)

HUD.Speclist:enlist(function ()
    local List = {}
    local Players = EntityList.GetPlayers()
    local Me = EntityList.GetLocalPlayer()


    if Me then
        local Target

        local Observer, ObserverMode = Me:GetProp "m_hObserverTarget", Me:GetProp "m_iObserverMode"
        if Observer and (ObserverMode == 4 or ObserverMode == 5) then
            Target = Observer
        else
            Target = Me
        end

        if type(Target) == "number" then
            Target = EntityList.GetPlayerFromHandle(Target)
        end

        --
        for i = 1, #Players do
            local Player = Players[i]
            if Player ~= Me and type(Target) == "userdata" then
                local ObTarget, ObMode = EntityList.GetPlayerFromHandle(Player:GetProp "m_hObserverTarget"), Player:GetProp "m_iObserverMode"
                local iObTarget, iTarget = ObTarget and ObTarget:EntIndex(), Target:EntIndex()

                List[#List+1] = {
                    name = Player:GetPlayerInfo().iSteamID,
                    ent = Player, nick = string.limit(Player:GetName(), 20, "..."),
                    active = ObTarget and iObTarget == iTarget and (ObMode == 4 or ObMode == 5)
                }
            end
        end
    end

    return List
end, function (self, Item, Offset, Progress)
    local Pos = Vector2.new(self.pos.x, self.pos.y + Offset + 32 * Progress)
    local Size = Vector2.new(self.size.x, 32)
    local End = Pos + Size

    Render.Box(Pos - Vector2.new(0, 1), End, Colors.Frame:SetAlpha(self.alpha * Progress, true))

    local LengthA = Render.CalcTextSize(Item.nick, 14)
    Render.Text(Item.nick, Pos + Vector2.new(12, 8), Colors.Text:SetAlpha(self.alpha * Progress, true), 14)

    return Vector2.new(LengthA.x + 16, 32)
end)

HUD.Speclist.update = function (self)
    return Anima.Condition(self.progress, Vars.Speclist:Get() and (Cheat.IsMenuVisible() or self.__list.active > 0))
end

HUD.Speclist.paint = function (self, Pos, End)
    local CFadeA, CFadeB = Colors.FadeA:SetAlpha(self.alpha, true), Colors.FadeB:SetAlpha(self.alpha, true)
    Render.GradientBoxFilled(Pos, End, CFadeA, CFadeB, CFadeA, CFadeB)
    Render.Box(Pos, End, Colors.Frame:SetAlpha(self.alpha, true))
    Render.Text(string.format("Spectators (%d)", self.__list.active), Vector2.new(Pos.x + 28, Pos.y + 8), Colors.Text:SetAlpha(self.alpha, true), 14)
    Render.Image(Images.Arrows, Vector2.new(Pos.x + 12, Pos.y + 12), Vector2.new(10, 10), Colors.Accent:SetAlpha(self.alpha, true))
end

-- #endregion

Cheat.RegisterCallback("draw", function ()
    Colors.Accent = Vars.Color:Get()

    if Vars.Watermark:Get() or HUD.Watermark.alpha > 0 then
        HUD.Watermark()
    end
    if Vars.Keylist:Get() or HUD.Keylist.alpha > 0 then
        HUD.Keylist()
    end
    if Vars.Speclist:Get() or HUD.Speclist.alpha > 0 then
        HUD.Speclist()
    end
end)

-- #endregion
--
 
Последнее редактирование:
Эксперт
Статус
Оффлайн
Регистрация
14 Ноя 2020
Сообщения
1,796
Реакции[?]
586
Поинты[?]
2K
Посмотреть вложение 252632
Пожалуйста, авторизуйтесь для просмотра ссылки.


в коде есть крутые виджеты и драг, система анимаций, советую
Код:
-- spirthud
---- enq

-- КакДатыPascalCase


--
-- #region : Definitions

-- #region - Globals

math.clamp = function (v, a, b)  if v < a then return a elseif v > b then return b else return v end  end
string.limit = function (s, l, c) local r, i = {}, 1 for w in string.gmatch(s, ".[\128-\191]*") do i, r[i] = i + 1, w if i > l then if c then r[i] = c == true and "..." or c end break end end return table.concat(r) end

-- #endregion

-- #region - Render and widgets

local Screen = EngineClient.GetScreenSize()

local Colors = {
    Text = Color.new(1, 1, 1),
    Frame = Color.new(33 / 255, 28 / 255, 66 / 255),
    Back = Color.new(15 / 255, 12 / 255, 33 / 255),
    Main = Color.new(23 / 255, 20 / 255, 41 / 255),
    FadeA = Color.new(24 / 255, 21 / 255, 48 / 255),
    FadeB = Color.new(28 / 255, 25 / 255, 61 / 255),
    Accent = Color.new(107 / 255, 89 / 255, 222 / 255),
}

do
    local ColorMt = getmetatable(Colors.Text)
    ColorMt.SetAlpha = function (self, a, s)
        return Color.new(self.r, self.g, self.b, s and self.a * a or a)
    end
end

local Images = {
    Arrows = Render.LoadImage("\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x0A\x00\x00\x00\x0A\x08\x06\x00\x00\x00\x8D\x32\xCF\xBD\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7C\x08\x64\x88\x00\x00\x00\x6D\x49\x44\x41\x54\x18\x57\x85\x90\xD1\x0D\xC0\x20\x08\x44\x61\xB2\x76\x93\xEA\x64\xB5\x9B\x74\x33\x7B\xD7\x08\xA5\x7C\xA8\x09\x21\x0F\x8F\x13\xD4\xDE\x7B\x11\x91\x4D\x55\x2B\xB2\x64\x66\x8D\x47\x71\xD1\x90\x0F\x44\xA3\x38\xB3\x0B\x87\xCB\x52\xAC\xD6\xB1\x72\x76\xE1\x70\xBE\x39\x2F\xA2\x62\x8C\x86\xE6\x8F\x83\x23\x97\x3A\x11\x17\x44\x65\x2C\xE5\xFC\x3A\xE6\x62\x66\xDB\x7A\xEA\x14\xBF\x87\xC2\x9D\xCF\x05\x77\xE7\xDF\xF7\x18\xCC\xF2\x03\x7A\x89\x55\x68\x5B\xE3\x6A\x5D\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82", Vector2.new(10, 10)),
    Logo = Render.LoadImage("\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x0C\x00\x00\x00\x0C\x08\x06\x00\x00\x00\x56\x75\x5C\xE7\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7C\x08\x64\x88\x00\x00\x00\xA9\x49\x44\x41\x54\x28\x53\x6D\x91\x0B\x11\xC2\x30\x10\x44\x39\x05\xD4\x02\x0E\x70\x40\xAB\x84\xD6\x01\x38\xC1\x41\xE3\x00\x09\x54\x02\x38\x01\x05\x61\xB7\x93\xEB\x5C\x37\xC9\xCC\xCD\x34\x7B\xFB\xEE\x93\xDA\x41\x4E\xCE\xB9\x83\xF4\x44\xDC\xCD\xEC\xAD\x79\x8B\x42\x31\xBF\xA0\x9D\x11\x5F\xC4\xA0\xD0\x06\x88\xF9\x07\xF3\xB1\x05\xAD\x80\x98\x3F\x90\x7A\xC4\x03\x71\x55\xC8\x5A\x66\x8C\xC1\x71\x58\x28\x29\x44\x60\x81\x78\x29\x95\x4E\x6E\xF6\xDD\xAA\x3C\x04\x2E\x48\x88\x33\x27\x00\x53\x30\x8F\xF8\x9E\xCB\x7D\x42\x2E\xF9\x0E\x15\x84\x42\x95\x99\x60\x7C\xA5\x08\xB1\x23\x17\xE7\x59\x2B\x7B\x57\xFD\x0F\x11\xAA\xCC\xBB\x0E\x61\x6E\x87\x6E\xB1\x72\xB3\x43\x80\x3A\x7D\x2D\xCF\xFD\x01\x8D\x5B\x59\x1A\x80\xD2\xA3\x1A\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82", Vector2.new(12, 12))
}

local Anima do
    local animators = setmetatable({}, {__mode = "k"})

    --
    Anima = {
        Pulse = 0,

        Easings = {
            pow = {
                function (x, p) return 1 - ((1 - x) ^ (p or 3)) end,
                function (x, p) return x ^ (p or 3) end,
                function (x, p) return x < 0.5 and 4 * math.pow(x, p or 3) or 1 - math.pow(-2 * x + 2, p or 3) * 0.5 end,
            }
        },

        Lerp = function (a, b, s, t)
            local c = a + (b - a) * GlobalVars.absoluteframetime * (s or 8)
            return math.abs(b - c) < (t or 0.002) and b or c
        end,

        Condition = function (id, c, s, e)
            local ctx = id[1] and id or animators[id]
            if not ctx then animators[id] = { c and 1 or 0, c }; ctx = animators[id] end

            s = s or 4
            local cur_s = s
            if type(s) == "table" then cur_s = c and s[1] or s[2] end

            ctx[1] = math.clamp(ctx[1] + ( GlobalVars.absoluteframetime * math.abs(cur_s) * (c and 1 or -1) ), 0, 1)

            return (ctx[1] % 1 == 0 or cur_s < 0) and ctx[1] or
            Anima.Easings.pow[e and (c and e[1][1] or e[2][1]) or (c and 1 or 3)](ctx[1], e and (c and e[1][2] or e[2][2]) or 3)
        end
    }
end

local Drag do
    local Current

    local InBounds = function (p, s, e)
        return (p.x >= s.x and p.x <= e.x) and (p.y >= s.y and p.y <= e.y)
    end

    local Process = function (Widget)
        local ctx = Widget.__drag
        if ctx.Locked or not Cheat.IsMenuVisible() then return end

        local Mouse, MenuPos, MenuSize = Cheat.GetMousePos(), Render.GetMenuPos(), Render.GetMenuSize()
        local Held = Cheat.IsMenuVisible() and Cheat.IsKeyDown(1)
        local Hovered = InBounds(Mouse, Widget.pos, Widget.pos + Widget.size) and not InBounds(Mouse, MenuPos, (MenuPos + MenuSize))

        --
        if Held and ctx.ready == nil then
            ctx.ready, ctx.point, ctx.init = Hovered, Widget.pos - Mouse, Vector2.new(Widget.pos.x, Widget.pos.y)
        end

        if Held and ctx.ready then
            Current = (ctx.ready and Current == nil) and Widget.id or Current
            ctx.active = Current == Widget.id
        elseif not Held then
            ctx.active = false
            ctx.ready, ctx.point, ctx.init, Current = nil, nil, nil, nil
        end

        ctx.hovered = Hovered or ctx.active
        local Wished = ctx.point and (ctx.point + Mouse) or Widget.pos

        --
        if ctx.active then
            local Finale = Wished

            --
            Widget.pos.x, Widget.pos.y = math.clamp(Finale.x, 0, Screen.x - Widget.size.x), math.clamp(Finale.y, 0, Screen.y - Widget.size.y)
            ctx.config.x:Set(Widget.pos.x)
            ctx.config.y:Set(Widget.pos.y)
        end
    end

    --
    Drag = function (Widget, Props)
        Props = Props or {}

        Widget.__drag = {
            locked = false, active = false, hovered = nil, point = Vector2.new(0, 0),
            process = Process,
            config = {
                x = Menu.SliderInt("General", Widget.id .. "-x", Widget.pos.x, 0, Screen.x),
                y = Menu.SliderInt("General", Widget.id .. "-y", Widget.pos.y, 0, Screen.y),
            }
        }

        Widget.pos.x, Widget.pos.y = Widget.__drag.config.x:Get(), Widget.__drag.config.y:Get()
        Widget.__drag.config.x:RegisterCallback(function (val) Widget.pos.x = val end)
        Widget.__drag.config.y:RegisterCallback(function (val) Widget.pos.y = val end)
        Widget.__drag.config.x:SetVisible(false)
        Widget.__drag.config.y:SetVisible(false)
    end
end

local Widget do
    local WidgetMt; WidgetMt = {
        update = function (self) return 1 end,
        paint = function (self, pos, fin) end,

        __call = function (self)
            local __list, __drag = self.__list, self.__drag
            if __list then
                __list.items, __list.active = __list.collect(), 0
                for i = 1, #__list.items do
                    if __list.items[i].active then __list.active = __list.active + 1 end
                end
            end
            self.alpha = self:update()

            if self.alpha > 0 then
                if __drag then __drag.process(self) end
                if __list then WidgetMt.traverse(self) end
                self:paint(self.pos, self.pos + self.size)
            end
        end,

        enlist = function (self, collector, painter)
            self.__list = {
                items = {}, progress = setmetatable({}, { __mode = "k" }),
                longest = 0, active = 0, minwidth = self.size.x, height = 0,
                collect = collector, paint = painter,
            }
        end,
        traverse = function (self)
            local ctx, offset, latest = self.__list, 0, Vector2.new(0, 0)
            ctx.active, ctx.longest = 0, 0

            Render.BoxFilled(Vector2.new(self.pos.x, self.pos.y + 32), Vector2.new(self.pos.x + self.size.x, self.pos.y + ctx.height + 32), Colors.Main:SetAlpha(self.alpha, true))

            for i = 1, #ctx.items do
                local v = ctx.items[i]
                local id = v.name or i
                ctx.progress[id] = ctx.progress[id] or {0}
                local progress = Anima.Condition(ctx.progress[id], v.active)

                if progress > 0 then
                    latest = ctx.paint(self, v, offset, progress)

                    ctx.active, offset = ctx.active + 1, offset + (latest.y * progress)
                    ctx.longest = math.max(ctx.longest, latest.x)
                end
            end

            ctx.height = offset
            self.size.x = Anima.Lerp(self.size.x, math.max(ctx.longest, ctx.minwidth), 10, .5)
        end,

        lock = function (self, b)
            if not self.__drag then return end
            self.__drag.locked = b and true or false
        end,
    }    WidgetMt.__index = WidgetMt

    --
    Widget = function (ID, Pos, Size, Draggable)
        local self = {
            id = ID, pos = Pos, size = Size,
            alpha = 1, progress = {0}
        }

        if Draggable then
            Drag(self, type(Draggable) == "table" and Draggable or nil)
        end

        return setmetatable(self, WidgetMt)
    end
end

-- #endregion

-- #endregion
--



--
-- #region : Main

local HUD = {}
local Vars = {
    Menu.Text("Info", "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  SpirtHUD"),
    Menu.Text("Info", "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Designed by enQ"),
    Color = Menu.ColorEdit("Widgets", "Accent color", Colors.Accent),
    Watermark = Menu.Switch("Widgets", "Watermark", true),
    TimeZone = Menu.SliderInt("Widgets", "\tTime Zone", 3, -12, 12),
    Keylist = Menu.Switch("Widgets", "Keylist", false),
    Speclist = Menu.Switch("Widgets", "Speclist", false),
}

Vars.TimeZone:SetVisible(Vars.Watermark:Get())
Vars.Watermark:RegisterCallback(function (v)
    Vars.TimeZone:SetVisible(v)
end)


-- #region - Watermark

HUD.Watermark = Widget("Watermark", Vector2.new(Screen.x - 194 - 24, 24), Vector2.new(194, 32))

HUD.Watermark.GetTime = function ()
    local UnixTime = Utils.UnixTime() / 1000
    local Hours = (UnixTime / 3600 + Vars.TimeZone:Get()) % 24
    local Minutes = UnixTime / 60 % 60
    return math.floor(Hours), math.floor(Minutes)
end

HUD.Watermark.update = function (self)
    return Anima.Condition(self.progress, Vars.Watermark:Get())
end

HUD.Watermark.paint = function (self, Pos, Fin)
    Render.BoxFilled(Pos, Fin, Colors.Back, 4)
    Render.Image(Images.Logo, Vector2.new(Pos.x + 12, Pos.y + 10), Vector2.new(12, 12), Colors.Accent:SetAlpha(self.alpha, true))
    Render.Text("SpirtHack", Vector2.new(Pos.x + 32, Pos.y + 8), Colors.Text:SetAlpha(self.alpha, true), 14)
    local LogoSize = Render.CalcTextSize("SpirtHack", 14)
    LogoSize.x = LogoSize.x + 44

    Pos = Vector2.new(Pos.x + LogoSize.x, Pos.y)
    Render.BoxFilled(Vector2.new(Pos.x, Pos.y), Fin, Colors.Main:SetAlpha(self.alpha, true), 4)
    Render.Box(Vector2.new(Pos.x, Pos.y), Fin, Colors.Frame:SetAlpha(self.alpha, true), 4)

    local Latency = EngineClient.GetNetChannelInfo()
    Latency = Latency and Latency:GetLatency(0) * 1000
    local Hours, Minutes = self.GetTime()
    local Text = string.format("%s  /  %02d:%02d" .. ((Latency and Latency > 5) and "  /  %dms" or ""), Cheat.GetCheatUserName(), Hours, Minutes, Latency)

    local TextSize = Render.CalcTextSize(Text, 14)
    TextSize.x = TextSize.x + 24
    Render.Text(Text, Vector2.new(Pos.x + 12, Pos.y + 8), Colors.Text:SetAlpha(self.alpha, true), 14)

    self.size.x = Anima.Lerp(self.size.x, LogoSize.x + TextSize.x, 12, .1)
    self.pos.x = Screen.x - self.size.x - 24
end

-- #endregion

-- #region - Keylist

HUD.Keylist = Widget("Keylist", Vector2.new(Render.GetMenuPos().x + Render.GetMenuSize().x + 16, Render.GetMenuPos().y), Vector2.new(140, 32), true)

HUD.Keylist.FormatValue = function (v)
    if v == "on" or v == "off" or tonumber(v) then
        return v
    else
        return string.gsub(v, "%l", "")
    end
end

HUD.Keylist:enlist(function ()
    local Raw, Binds = Cheat.GetBinds(), {}
    local Len = #Raw
    for i = 1, Len do
        local v, n = Raw[i], Len - i + 1
        Binds[n] = {
            n = n,
            name = v:GetName(),
            value = v:GetValue(),
            active = v:IsActive(),
        }
    end
    return Binds
end, function (self, Item, Offset, Progress)
    local Pos = Vector2.new(self.pos.x, self.pos.y + Offset + 32 * Progress)
    local Size = Vector2.new(self.size.x, 32)
    local End = Pos + Size

    Render.Box(Pos - Vector2.new(0, 1), End, Colors.Frame:SetAlpha(self.alpha * Progress, true))

    local Value = self.FormatValue(Item.value)
    local LengthA = Render.CalcTextSize(Item.name, 14)
    local LengthB = Render.CalcTextSize(Value, 14)
    Render.Text(Item.name, Pos + Vector2.new(12, 8), Colors.Text:SetAlpha(self.alpha * Progress, true), 14)
    Render.Text(Value, Vector2.new(End.x - 12 - LengthB.x, Pos.y + 8), Colors.Accent:SetAlpha(self.alpha * Progress, true), 14)

    return Vector2.new(LengthA.x + LengthB.x + 40, 32)
end)

HUD.Keylist.update = function (self)
    return Anima.Condition(self.progress, Vars.Keylist:Get() and (Cheat.IsMenuVisible() or self.__list.active > 0))
end

HUD.Keylist.paint = function (self, Pos, End)
    local CFadeA, CFadeB = Colors.FadeA:SetAlpha(self.alpha, true), Colors.FadeB:SetAlpha(self.alpha, true)
    Render.GradientBoxFilled(Pos, End, CFadeA, CFadeB, CFadeA, CFadeB)
    Render.Box(Pos, End, Colors.Frame:SetAlpha(self.alpha, true))
    Render.Text("Hotkeys", Vector2.new(Pos.x + 28, Pos.y + 8), Colors.Text:SetAlpha(self.alpha, true), 14)
    Render.Image(Images.Arrows, Vector2.new(Pos.x + 12, Pos.y + 12), Vector2.new(10, 10), Colors.Accent:SetAlpha(self.alpha, true))
end

-- #endregion

-- #region - Speclist

HUD.Speclist = Widget("Speclist", Vector2.new(Render.GetMenuPos().x + Render.GetMenuSize().x + 16, Render.GetMenuPos().y + 240), Vector2.new(140, 32), true)

HUD.Speclist:enlist(function ()
    local List = {}
    local Players = EntityList.GetPlayers()
    local Me = EntityList.GetLocalPlayer()


    if Me then
        local Target

        local Observer, ObserverMode = Me:GetProp "m_hObserverTarget", Me:GetProp "m_iObserverMode"
        if Observer and (ObserverMode == 4 or ObserverMode == 5) then
            Target = Observer
        else
            Target = Me
        end

        if type(Target) == "number" then
            Target = EntityList.GetPlayerFromHandle(Target)
        end

        --
        for i = 1, #Players do
            local Player = Players[i]
            if Player ~= Me and type(Target) == "userdata" then
                local ObTarget, ObMode = EntityList.GetPlayerFromHandle(Player:GetProp "m_hObserverTarget"), Player:GetProp "m_iObserverMode"
                local iObTarget, iTarget = ObTarget and ObTarget:EntIndex(), Target:EntIndex()

                List[#List+1] = {
                    name = Player:GetPlayerInfo().iSteamID,
                    ent = Player, nick = string.limit(Player:GetName(), 20, "..."),
                    active = ObTarget and iObTarget == iTarget and (ObMode == 4 or ObMode == 5)
                }
            end
        end
    end

    return List
end, function (self, Item, Offset, Progress)
    local Pos = Vector2.new(self.pos.x, self.pos.y + Offset + 32 * Progress)
    local Size = Vector2.new(self.size.x, 32)
    local End = Pos + Size

    Render.Box(Pos - Vector2.new(0, 1), End, Colors.Frame:SetAlpha(self.alpha * Progress, true))

    local LengthA = Render.CalcTextSize(Item.nick, 14)
    Render.Text(Item.nick, Pos + Vector2.new(12, 8), Colors.Text:SetAlpha(self.alpha * Progress, true), 14)

    return Vector2.new(LengthA.x + 16, 32)
end)

HUD.Speclist.update = function (self)
    return Anima.Condition(self.progress, Vars.Speclist:Get() and (Cheat.IsMenuVisible() or self.__list.active > 0))
end

HUD.Speclist.paint = function (self, Pos, End)
    local CFadeA, CFadeB = Colors.FadeA:SetAlpha(self.alpha, true), Colors.FadeB:SetAlpha(self.alpha, true)
    Render.GradientBoxFilled(Pos, End, CFadeA, CFadeB, CFadeA, CFadeB)
    Render.Box(Pos, End, Colors.Frame:SetAlpha(self.alpha, true))
    Render.Text(string.format("Spectators (%d)", self.__list.active), Vector2.new(Pos.x + 28, Pos.y + 8), Colors.Text:SetAlpha(self.alpha, true), 14)
    Render.Image(Images.Arrows, Vector2.new(Pos.x + 12, Pos.y + 12), Vector2.new(10, 10), Colors.Accent:SetAlpha(self.alpha, true))
end

-- #endregion

Cheat.RegisterCallback("draw", function ()
    Colors.Accent = Vars.Color:Get()

    if Vars.Watermark:Get() or HUD.Watermark.alpha > 0 then
        HUD.Watermark()
    end
    if Vars.Keylist:Get() or HUD.Keylist.alpha > 0 then
        HUD.Keylist()
    end
    if Vars.Speclist:Get() or HUD.Speclist.alpha > 0 then
        HUD.Speclist()
    end
end)

-- #endregion
--
прив на нл сделай
Color.new(16 / 255, 37 / 255, 100 / 255) 🥰
ргб фикс :imp:
 
Эксперт
Статус
Оффлайн
Регистрация
13 Сен 2020
Сообщения
1,415
Реакции[?]
713
Поинты[?]
10K
Посмотреть вложение 252632
Пожалуйста, авторизуйтесь для просмотра ссылки.


в коде есть крутые виджеты, драг и анимации, советую
Код:
-- spirthud
---- enq

-- КакДатыPascalCase


--
-- #region : Definitions

-- #region - Globals

math.clamp = function (v, a, b)  if v < a then return a elseif v > b then return b else return v end  end
string.limit = function (s, l, c) local r, i = {}, 1 for w in string.gmatch(s, ".[\128-\191]*") do i, r[i] = i + 1, w if i > l then if c then r[i] = c == true and "..." or c end break end end return table.concat(r) end

-- #endregion

-- #region - Render and widgets

local Screen = EngineClient.GetScreenSize()

local Colors = {
    Text = Color.new(1, 1, 1),
    Frame = Color.new(33 / 255, 28 / 255, 66 / 255),
    Back = Color.new(15 / 255, 12 / 255, 33 / 255),
    Main = Color.new(23 / 255, 20 / 255, 41 / 255),
    FadeA = Color.new(24 / 255, 21 / 255, 48 / 255),
    FadeB = Color.new(28 / 255, 25 / 255, 61 / 255),
    Accent = Color.new(107 / 255, 89 / 255, 222 / 255),
}

do
    local ColorMt = getmetatable(Colors.Text)
    ColorMt.SetAlpha = function (self, a, s)
        return Color.new(self.r, self.g, self.b, s and self.a * a or a)
    end
end

local Images = {
    Arrows = Render.LoadImage("\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x0A\x00\x00\x00\x0A\x08\x06\x00\x00\x00\x8D\x32\xCF\xBD\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7C\x08\x64\x88\x00\x00\x00\x6D\x49\x44\x41\x54\x18\x57\x85\x90\xD1\x0D\xC0\x20\x08\x44\x61\xB2\x76\x93\xEA\x64\xB5\x9B\x74\x33\x7B\xD7\x08\xA5\x7C\xA8\x09\x21\x0F\x8F\x13\xD4\xDE\x7B\x11\x91\x4D\x55\x2B\xB2\x64\x66\x8D\x47\x71\xD1\x90\x0F\x44\xA3\x38\xB3\x0B\x87\xCB\x52\xAC\xD6\xB1\x72\x76\xE1\x70\xBE\x39\x2F\xA2\x62\x8C\x86\xE6\x8F\x83\x23\x97\x3A\x11\x17\x44\x65\x2C\xE5\xFC\x3A\xE6\x62\x66\xDB\x7A\xEA\x14\xBF\x87\xC2\x9D\xCF\x05\x77\xE7\xDF\xF7\x18\xCC\xF2\x03\x7A\x89\x55\x68\x5B\xE3\x6A\x5D\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82", Vector2.new(10, 10)),
    Logo = Render.LoadImage("\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x0C\x00\x00\x00\x0C\x08\x06\x00\x00\x00\x56\x75\x5C\xE7\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7C\x08\x64\x88\x00\x00\x00\xA9\x49\x44\x41\x54\x28\x53\x6D\x91\x0B\x11\xC2\x30\x10\x44\x39\x05\xD4\x02\x0E\x70\x40\xAB\x84\xD6\x01\x38\xC1\x41\xE3\x00\x09\x54\x02\x38\x01\x05\x61\xB7\x93\xEB\x5C\x37\xC9\xCC\xCD\x34\x7B\xFB\xEE\x93\xDA\x41\x4E\xCE\xB9\x83\xF4\x44\xDC\xCD\xEC\xAD\x79\x8B\x42\x31\xBF\xA0\x9D\x11\x5F\xC4\xA0\xD0\x06\x88\xF9\x07\xF3\xB1\x05\xAD\x80\x98\x3F\x90\x7A\xC4\x03\x71\x55\xC8\x5A\x66\x8C\xC1\x71\x58\x28\x29\x44\x60\x81\x78\x29\x95\x4E\x6E\xF6\xDD\xAA\x3C\x04\x2E\x48\x88\x33\x27\x00\x53\x30\x8F\xF8\x9E\xCB\x7D\x42\x2E\xF9\x0E\x15\x84\x42\x95\x99\x60\x7C\xA5\x08\xB1\x23\x17\xE7\x59\x2B\x7B\x57\xFD\x0F\x11\xAA\xCC\xBB\x0E\x61\x6E\x87\x6E\xB1\x72\xB3\x43\x80\x3A\x7D\x2D\xCF\xFD\x01\x8D\x5B\x59\x1A\x80\xD2\xA3\x1A\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82", Vector2.new(12, 12))
}

local Anima do
    local animators = setmetatable({}, {__mode = "k"})

    --
    Anima = {
        Pulse = 0,

        Easings = {
            pow = {
                function (x, p) return 1 - ((1 - x) ^ (p or 3)) end,
                function (x, p) return x ^ (p or 3) end,
                function (x, p) return x < 0.5 and 4 * math.pow(x, p or 3) or 1 - math.pow(-2 * x + 2, p or 3) * 0.5 end,
            }
        },

        Lerp = function (a, b, s, t)
            local c = a + (b - a) * GlobalVars.absoluteframetime * (s or 8)
            return math.abs(b - c) < (t or 0.002) and b or c
        end,

        Condition = function (id, c, s, e)
            local ctx = id[1] and id or animators[id]
            if not ctx then animators[id] = { c and 1 or 0, c }; ctx = animators[id] end

            s = s or 4
            local cur_s = s
            if type(s) == "table" then cur_s = c and s[1] or s[2] end

            ctx[1] = math.clamp(ctx[1] + ( GlobalVars.absoluteframetime * math.abs(cur_s) * (c and 1 or -1) ), 0, 1)

            return (ctx[1] % 1 == 0 or cur_s < 0) and ctx[1] or
            Anima.Easings.pow[e and (c and e[1][1] or e[2][1]) or (c and 1 or 3)](ctx[1], e and (c and e[1][2] or e[2][2]) or 3)
        end
    }
end

local Drag do
    local Current

    local InBounds = function (p, s, e)
        return (p.x >= s.x and p.x <= e.x) and (p.y >= s.y and p.y <= e.y)
    end

    local Process = function (Widget)
        local ctx = Widget.__drag
        if ctx.Locked or not Cheat.IsMenuVisible() then return end

        local Mouse, MenuPos, MenuSize = Cheat.GetMousePos(), Render.GetMenuPos(), Render.GetMenuSize()
        local Held = Cheat.IsMenuVisible() and Cheat.IsKeyDown(1)
        local Hovered = InBounds(Mouse, Widget.pos, Widget.pos + Widget.size) and not InBounds(Mouse, MenuPos, (MenuPos + MenuSize))

        --
        if Held and ctx.ready == nil then
            ctx.ready, ctx.point, ctx.init = Hovered, Widget.pos - Mouse, Vector2.new(Widget.pos.x, Widget.pos.y)
        end

        if Held and ctx.ready then
            Current = (ctx.ready and Current == nil) and Widget.id or Current
            ctx.active = Current == Widget.id
        elseif not Held then
            ctx.active = false
            ctx.ready, ctx.point, ctx.init, Current = nil, nil, nil, nil
        end

        ctx.hovered = Hovered or ctx.active
        local Wished = ctx.point and (ctx.point + Mouse) or Widget.pos

        --
        if ctx.active then
            local Finale = Wished

            --
            Widget.pos.x, Widget.pos.y = math.clamp(Finale.x, 0, Screen.x - Widget.size.x), math.clamp(Finale.y, 0, Screen.y - Widget.size.y)
            ctx.config.x:Set(Widget.pos.x)
            ctx.config.y:Set(Widget.pos.y)
        end
    end

    --
    Drag = function (Widget, Props)
        Props = Props or {}

        Widget.__drag = {
            locked = false, active = false, hovered = nil, point = Vector2.new(0, 0),
            process = Process,
            config = {
                x = Menu.SliderInt("General", Widget.id .. "-x", Widget.pos.x, 0, Screen.x),
                y = Menu.SliderInt("General", Widget.id .. "-y", Widget.pos.y, 0, Screen.y),
            }
        }

        Widget.pos.x, Widget.pos.y = Widget.__drag.config.x:Get(), Widget.__drag.config.y:Get()
        Widget.__drag.config.x:RegisterCallback(function (val) Widget.pos.x = val end)
        Widget.__drag.config.y:RegisterCallback(function (val) Widget.pos.y = val end)
        Widget.__drag.config.x:SetVisible(false)
        Widget.__drag.config.y:SetVisible(false)
    end
end

local Widget do
    local WidgetMt; WidgetMt = {
        update = function (self) return 1 end,
        paint = function (self, pos, fin) end,

        __call = function (self)
            local __list, __drag = self.__list, self.__drag
            if __list then
                __list.items, __list.active = __list.collect(), 0
                for i = 1, #__list.items do
                    if __list.items[i].active then __list.active = __list.active + 1 end
                end
            end
            self.alpha = self:update()

            if self.alpha > 0 then
                if __drag then __drag.process(self) end
                if __list then WidgetMt.traverse(self) end
                self:paint(self.pos, self.pos + self.size)
            end
        end,

        enlist = function (self, collector, painter)
            self.__list = {
                items = {}, progress = setmetatable({}, { __mode = "k" }),
                longest = 0, active = 0, minwidth = self.size.x, height = 0,
                collect = collector, paint = painter,
            }
        end,
        traverse = function (self)
            local ctx, offset, latest = self.__list, 0, Vector2.new(0, 0)
            ctx.active, ctx.longest = 0, 0

            Render.BoxFilled(Vector2.new(self.pos.x, self.pos.y + 32), Vector2.new(self.pos.x + self.size.x, self.pos.y + ctx.height + 32), Colors.Main:SetAlpha(self.alpha, true))

            for i = 1, #ctx.items do
                local v = ctx.items[i]
                local id = v.name or i
                ctx.progress[id] = ctx.progress[id] or {0}
                local progress = Anima.Condition(ctx.progress[id], v.active)

                if progress > 0 then
                    latest = ctx.paint(self, v, offset, progress)

                    ctx.active, offset = ctx.active + 1, offset + (latest.y * progress)
                    ctx.longest = math.max(ctx.longest, latest.x)
                end
            end

            ctx.height = offset
            self.size.x = Anima.Lerp(self.size.x, math.max(ctx.longest, ctx.minwidth), 10, .5)
        end,

        lock = function (self, b)
            if not self.__drag then return end
            self.__drag.locked = b and true or false
        end,
    }    WidgetMt.__index = WidgetMt

    --
    Widget = function (ID, Pos, Size, Draggable)
        local self = {
            id = ID, pos = Pos, size = Size,
            alpha = 1, progress = {0}
        }

        if Draggable then
            Drag(self, type(Draggable) == "table" and Draggable or nil)
        end

        return setmetatable(self, WidgetMt)
    end
end

-- #endregion

-- #endregion
--



--
-- #region : Main

local HUD = {}
local Vars = {
    Menu.Text("Info", "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  SpirtHUD"),
    Menu.Text("Info", "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Designed by enQ"),
    Color = Menu.ColorEdit("Widgets", "Accent color", Colors.Accent),
    Watermark = Menu.Switch("Widgets", "Watermark", true),
    TimeZone = Menu.SliderInt("Widgets", "\tTime Zone", 3, -12, 12),
    Keylist = Menu.Switch("Widgets", "Keylist", false),
    Speclist = Menu.Switch("Widgets", "Speclist", false),
}

Vars.TimeZone:SetVisible(Vars.Watermark:Get())
Vars.Watermark:RegisterCallback(function (v)
    Vars.TimeZone:SetVisible(v)
end)


-- #region - Watermark

HUD.Watermark = Widget("Watermark", Vector2.new(Screen.x - 194 - 24, 24), Vector2.new(194, 32))

HUD.Watermark.GetTime = function ()
    local UnixTime = Utils.UnixTime() / 1000
    local Hours = (UnixTime / 3600 + Vars.TimeZone:Get()) % 24
    local Minutes = UnixTime / 60 % 60
    return math.floor(Hours), math.floor(Minutes)
end

HUD.Watermark.update = function (self)
    return Anima.Condition(self.progress, Vars.Watermark:Get())
end

HUD.Watermark.paint = function (self, Pos, Fin)
    Render.BoxFilled(Pos, Fin, Colors.Back, 4)
    Render.Image(Images.Logo, Vector2.new(Pos.x + 12, Pos.y + 10), Vector2.new(12, 12), Colors.Accent:SetAlpha(self.alpha, true))
    Render.Text("SpirtHack", Vector2.new(Pos.x + 32, Pos.y + 8), Colors.Text:SetAlpha(self.alpha, true), 14)
    local LogoSize = Render.CalcTextSize("SpirtHack", 14)
    LogoSize.x = LogoSize.x + 44

    Pos = Vector2.new(Pos.x + LogoSize.x, Pos.y)
    Render.BoxFilled(Vector2.new(Pos.x, Pos.y), Fin, Colors.Main:SetAlpha(self.alpha, true), 4)
    Render.Box(Vector2.new(Pos.x, Pos.y), Fin, Colors.Frame:SetAlpha(self.alpha, true), 4)

    local Latency = EngineClient.GetNetChannelInfo()
    Latency = Latency and Latency:GetLatency(0) * 1000
    local Hours, Minutes = self.GetTime()
    local Text = string.format("%s  /  %02d:%02d" .. ((Latency and Latency > 5) and "  /  %dms" or ""), Cheat.GetCheatUserName(), Hours, Minutes, Latency)

    local TextSize = Render.CalcTextSize(Text, 14)
    TextSize.x = TextSize.x + 24
    Render.Text(Text, Vector2.new(Pos.x + 12, Pos.y + 8), Colors.Text:SetAlpha(self.alpha, true), 14)

    self.size.x = Anima.Lerp(self.size.x, LogoSize.x + TextSize.x, 12, .1)
    self.pos.x = Screen.x - self.size.x - 24
end

-- #endregion

-- #region - Keylist

HUD.Keylist = Widget("Keylist", Vector2.new(Render.GetMenuPos().x + Render.GetMenuSize().x + 16, Render.GetMenuPos().y), Vector2.new(140, 32), true)

HUD.Keylist.FormatValue = function (v)
    if v == "on" or v == "off" or tonumber(v) then
        return v
    else
        return string.gsub(v, "%l", "")
    end
end

HUD.Keylist:enlist(function ()
    local Raw, Binds = Cheat.GetBinds(), {}
    local Len = #Raw
    for i = 1, Len do
        local v, n = Raw[i], Len - i + 1
        Binds[n] = {
            n = n,
            name = v:GetName(),
            value = v:GetValue(),
            active = v:IsActive(),
        }
    end
    return Binds
end, function (self, Item, Offset, Progress)
    local Pos = Vector2.new(self.pos.x, self.pos.y + Offset + 32 * Progress)
    local Size = Vector2.new(self.size.x, 32)
    local End = Pos + Size

    Render.Box(Pos - Vector2.new(0, 1), End, Colors.Frame:SetAlpha(self.alpha * Progress, true))

    local Value = self.FormatValue(Item.value)
    local LengthA = Render.CalcTextSize(Item.name, 14)
    local LengthB = Render.CalcTextSize(Value, 14)
    Render.Text(Item.name, Pos + Vector2.new(12, 8), Colors.Text:SetAlpha(self.alpha * Progress, true), 14)
    Render.Text(Value, Vector2.new(End.x - 12 - LengthB.x, Pos.y + 8), Colors.Accent:SetAlpha(self.alpha * Progress, true), 14)

    return Vector2.new(LengthA.x + LengthB.x + 40, 32)
end)

HUD.Keylist.update = function (self)
    return Anima.Condition(self.progress, Vars.Keylist:Get() and (Cheat.IsMenuVisible() or self.__list.active > 0))
end

HUD.Keylist.paint = function (self, Pos, End)
    local CFadeA, CFadeB = Colors.FadeA:SetAlpha(self.alpha, true), Colors.FadeB:SetAlpha(self.alpha, true)
    Render.GradientBoxFilled(Pos, End, CFadeA, CFadeB, CFadeA, CFadeB)
    Render.Box(Pos, End, Colors.Frame:SetAlpha(self.alpha, true))
    Render.Text("Hotkeys", Vector2.new(Pos.x + 28, Pos.y + 8), Colors.Text:SetAlpha(self.alpha, true), 14)
    Render.Image(Images.Arrows, Vector2.new(Pos.x + 12, Pos.y + 12), Vector2.new(10, 10), Colors.Accent:SetAlpha(self.alpha, true))
end

-- #endregion

-- #region - Speclist

HUD.Speclist = Widget("Speclist", Vector2.new(Render.GetMenuPos().x + Render.GetMenuSize().x + 16, Render.GetMenuPos().y + 240), Vector2.new(140, 32), true)

HUD.Speclist:enlist(function ()
    local List = {}
    local Players = EntityList.GetPlayers()
    local Me = EntityList.GetLocalPlayer()


    if Me then
        local Target

        local Observer, ObserverMode = Me:GetProp "m_hObserverTarget", Me:GetProp "m_iObserverMode"
        if Observer and (ObserverMode == 4 or ObserverMode == 5) then
            Target = Observer
        else
            Target = Me
        end

        if type(Target) == "number" then
            Target = EntityList.GetPlayerFromHandle(Target)
        end

        --
        for i = 1, #Players do
            local Player = Players[i]
            if Player ~= Me and type(Target) == "userdata" then
                local ObTarget, ObMode = EntityList.GetPlayerFromHandle(Player:GetProp "m_hObserverTarget"), Player:GetProp "m_iObserverMode"
                local iObTarget, iTarget = ObTarget and ObTarget:EntIndex(), Target:EntIndex()

                List[#List+1] = {
                    name = Player:GetPlayerInfo().iSteamID,
                    ent = Player, nick = string.limit(Player:GetName(), 20, "..."),
                    active = ObTarget and iObTarget == iTarget and (ObMode == 4 or ObMode == 5)
                }
            end
        end
    end

    return List
end, function (self, Item, Offset, Progress)
    local Pos = Vector2.new(self.pos.x, self.pos.y + Offset + 32 * Progress)
    local Size = Vector2.new(self.size.x, 32)
    local End = Pos + Size

    Render.Box(Pos - Vector2.new(0, 1), End, Colors.Frame:SetAlpha(self.alpha * Progress, true))

    local LengthA = Render.CalcTextSize(Item.nick, 14)
    Render.Text(Item.nick, Pos + Vector2.new(12, 8), Colors.Text:SetAlpha(self.alpha * Progress, true), 14)

    return Vector2.new(LengthA.x + 16, 32)
end)

HUD.Speclist.update = function (self)
    return Anima.Condition(self.progress, Vars.Speclist:Get() and (Cheat.IsMenuVisible() or self.__list.active > 0))
end

HUD.Speclist.paint = function (self, Pos, End)
    local CFadeA, CFadeB = Colors.FadeA:SetAlpha(self.alpha, true), Colors.FadeB:SetAlpha(self.alpha, true)
    Render.GradientBoxFilled(Pos, End, CFadeA, CFadeB, CFadeA, CFadeB)
    Render.Box(Pos, End, Colors.Frame:SetAlpha(self.alpha, true))
    Render.Text(string.format("Spectators (%d)", self.__list.active), Vector2.new(Pos.x + 28, Pos.y + 8), Colors.Text:SetAlpha(self.alpha, true), 14)
    Render.Image(Images.Arrows, Vector2.new(Pos.x + 12, Pos.y + 12), Vector2.new(10, 10), Colors.Accent:SetAlpha(self.alpha, true))
end

-- #endregion

Cheat.RegisterCallback("draw", function ()
    Colors.Accent = Vars.Color:Get()

    if Vars.Watermark:Get() or HUD.Watermark.alpha > 0 then
        HUD.Watermark()
    end
    if Vars.Keylist:Get() or HUD.Keylist.alpha > 0 then
        HUD.Keylist()
    end
    if Vars.Speclist:Get() or HUD.Speclist.alpha > 0 then
        HUD.Speclist()
    end
end)

-- #endregion
--
погодите.. это реально??
 
primordial
Пользователь
Статус
Оффлайн
Регистрация
4 Сен 2020
Сообщения
361
Реакции[?]
128
Поинты[?]
42K
В целом, неплохо, но
Почему на вотермарке есть закругление, а на кейбиндах и спектлисте нет?
Почему в вотермарке 2 прямоугольника на фоне, а в кейбиндах и в спектлисте градиент на фоне?
 
Эксперт
Статус
Оффлайн
Регистрация
13 Сен 2020
Сообщения
1,415
Реакции[?]
713
Поинты[?]
10K
В целом, неплохо, но
Почему на вотермарке есть закругление, а на кейбиндах и спектлисте нет?
Почему в вотермарке 2 прямоугольника на фоне, а в кейбиндах и в спектлисте градиент на фоне?
потому что у него роль дизайнер
 
Дизайнер
Статус
Оффлайн
Регистрация
18 Авг 2017
Сообщения
1,924
Реакции[?]
2,245
Поинты[?]
146K
Товары в продаже
1
В целом, неплохо, но
Почему на вотермарке есть закругление, а на кейбиндах и спектлисте нет?
Почему в вотермарке 2 прямоугольника на фоне, а в кейбиндах и в спектлисте градиент на фоне?
за основу кейбинда и спеклиста был взять стиль чайлдов, а за основу ватермарка, грубо говоря, стиль целого меню
 
primordial
Пользователь
Статус
Оффлайн
Регистрация
4 Сен 2020
Сообщения
361
Реакции[?]
128
Поинты[?]
42K
за основу кейбинда и спеклиста был взять стиль чайлдов, а за основу ватермарка, грубо говоря, стиль целого меню
Почему не взял единый стил? Либо стиль с чаилдов либо со всего меню
 
Сверху Снизу