Полезные сниппеты и функции

tfornik

Известный
312
227
Описание: Класс для создания и получения клавиатуры в JSON-Формате [ VK API ]
Lua:
local keyboard = { } do
    local keyboard.encode_json = encodeJson --> МЕТОД ENCODEJSON, ЕСЛИ НЕ ИСПОЛЬЗУЙТЕ MOONLOADER - cjson.encode
    keyboard.create = function(self)
        self.key = self
        self.value = {}
        self.row_select = 1
        self.buttonColors = {
            POSITIVE = "positive",
            PRIMARY = "primary",
            SECONDARY = "secondary",
            NEGATIVE = "negative"
        }
        self.action = {
            TEXT = "text",
            OPENLINK = "open_link",
            LOCATION = "location",
            VKPAY = "vkpay",
            CALLBACK = "callback",
            OPEN_APP = "open_app"
        }

        return self
    end

    keyboard.get_type = function(params, button_type)
        local button_types = {
            ["text"] = {
                ["action"] = {
                    ["type"] = "text",
                    ["label"] = params["label"] or params[1] or "",
                    ["payload"] = keyboard.encode_json({["button"] = params["payload"] or params[2] or ""})
                },
                ["color"] = params["color"]
            },
            ["open_link"] = {
                ["action"] = {
                    ["type"] = "open_link",
                    ["link"] = params["link"] or params[1] or "",
                    ["label"] = params["label"] or params[2] or "",
                    ["payload"] = keyboard.encode_json({["button"] = params["payload"] or params[3] or ""})
                }
            },
            ["location"] = {
                ["action"] = {
                    ["type"] = "location",
                    ["payload"] = keyboard.encode_json({["button"] = params["payload"] or params[1] or ""})
                }
            },
            ["vkpay"] = {
                ["action"] = {
                    ["type"] = "vkpay",
                    ["payload"] = keyboard.encode_json({["button"] = params["payload"] or params[1] or ""}),
                    ["hash"] = params["hash"] or params[2] or ""
                }
            },
            ["open_app"] = {
                ["action"] = {
                    ["type"] = "open_app",
                    ["app_id"] = params["app_id"] or params[1] or 0,
                    ["owner_id"] = params["owner_id"] or params[2] or 0,
                    ["payload"] = keyboard.encode_json({["button"] = params["payload"] or params[3] or ""}),
                    ["label"] = params["label"] or params[4] or "",
                    ["hash"] = params["hash"] or params[5] or ""
                }
            },
            ["callback"] = {
                ["action"] = {
                    ["type"] = "callback",
                    ["label"] = params["label"] or params[1] or "",
                    ["payload"] = keyboard.encode_json({["button"] = params["payload"] or params[2] or ""}),
                },
                ["color"] = params["color"]
            }
        }
        if not button_types[button_type] then
            return "Button Type is xuinya"
        end
        return button_types[button_type]
    end

    keyboard.add_button = function(self, button_type, params, button_color)
        if not self.value[self.row_select] then self.value[self.row_select] = {} end
     
        params["color"] = button_color
        self.value[self.row_select][#self.value[self.row_select] + 1] = keyboard.get_type(params, button_type)
    end

    keyboard.row = function(self)
        self.row_select = self.row_select + 1
    end

    keyboard.get_json = function(self, one_time, inline)
        local init = {}
        for row, buttons in ipairs(self.value) do
            init[row - 1] = {}
            for button_id, params in ipairs(buttons) do
                init[row - 1][button_id - 1] = params
            end
        end

        return {
            ["inline"] = inline or false,
            ["one_time"] = one_time or false,
            ["buttons"] = init
        }
    end

    setmetatable(keyboard, {
        __call = function(self)
            return self:create(self)
        end
    })
end

Пример:
Lua:
function get_keyboard()
    local markup = keyboard()
    markup:add_button(markup.action.OPENLINK, {
        "https://vk.com/tfornik",
        "Перейти по ссылке",
        "openLink"
    }, markup.buttonColors.POSITIVE)
    markup:row()
    markup:add_button(markup.action.LOCATION, {
        payload = "location"
    }, markup.buttonColors.POSITIVE)
    return markup:get_json(false, false)
end
self:add_button(button_type:string, params:table, color:string)
  • Описание: Добавляет кнопку в список
  • button_type:string -> Тип кнопки( text, open_link, location и тд )
  • params:table -> Таблица с нужными для кнопки параметрами( чек пример )
  • color:string -> Цвет кнопки( positive, secondary, negative, primary )
self:row()
  • Описание: Создать новый ряд кнопок
self:get_json(one_time:boolean, inline:boolean)
  • Описание: Возвращает клавиатуру в JSON-Формате
  • one_time:boolean -> true - Одноразовая , false - Многоразовая
  • inline:boolean -> true - прикреплена к сообщению, false - не прикреплена

В коде есть "keyboard.encode_json", укажите в данную переменную - функцию для преобразования lua таблицы в JSON

Метод self:add_button:

Важно. Параметры кнопок нужно передавать именно те, что требует VK_API ( кликабельно! )
1713016698349.png

Указывать аргументы в массиве можно как указывая название элемента( пример: { payload = "button_1", label = "gg" }, так и не указывая( пример: {"button_1", "gg"} )
 

Вложения

  • 1713016575089.png
    1713016575089.png
    79.4 KB · Просмотры: 15
Последнее редактирование:

ARMOR

kjor32 is legend
Модератор
4,843
6,061
Описание: Получает указатели на текстуры игровых иконок оружия по ID оружия

Где это можно использовать? Например в кастомных имгуи худах вместо того чтобы подгружать из папки большое количество иконок для оружия просто получать игровые иконки и рендерить их.

Код:
Lua:
local ffi = require("ffi")
ffi.cdef[[
    typedef unsigned char RwUInt8;
    typedef int RwInt32;
    typedef short RwInt16;
    typedef struct RwRaster RwRaster;
    struct RwRaster {
        struct RwRaster*            parent;
        RwUInt8*                    cpPixels;
        RwUInt8*                    palette;
        RwInt32                     width, height, depth;
        RwInt32                     stride;
        RwInt16                     nOffsetX, nOffsetY;
        RwUInt8                     cType;
        RwUInt8                     cFlags;
        RwUInt8                     privateFlags;
        RwUInt8                     cFormat;
        RwUInt8*                    originalPixels;
        RwInt32                     originalWidth;
        RwInt32                     originalHeight;
        RwInt32                     originalStride;
        void*                       texture_ptr;
    };
    typedef struct RwLLLink RwLLLink;
    struct RwLLLink
    {
        void *next;
        void *prev;
    };
    typedef struct RwLinkList RwLinkList;
    struct RwLinkList
    {
        struct RwLLLink link;
    };
    typedef struct RwObject RwObject;
    struct RwObject
    {
      char type;
      char subType;
      char flags;
      char privateFlags;
      struct RwFrame *parent;
    };
    typedef struct RwTexDictionary RwTexDictionary;
    struct RwTexDictionary
    {
        RwObject object;
        RwLinkList texturesInDict;
        RwLLLink lInInstance;
    };
    typedef struct CBaseModelInfo_vtbl CBaseModelInfo_vtbl;
    struct CBaseModelInfo_vtbl {
        void* destructor;
        void* AsAtomicModelInfoPtr;
        void* AsDamageAtomicModelInfoPtr;
        void* AsLodAtomicModelInfoPtr;
        char(__thiscall* GetModelType)(struct CBaseModelInfo*);
    };
    typedef struct CBaseModelInfo CBaseModelInfo;
    struct CBaseModelInfo {
        CBaseModelInfo_vtbl* vtbl;
        unsigned int m_dwKey;
        short m_wUsageCount;
        short m_wTxdIndex;
        char m_nAlpha;
        char m_n2dfxCount;
        short m_w2dfxIndex;
        short m_wObjectInfoIndex;
        unsigned short m_nMdlFlags;
        struct CColModel* m_pColModel;
        float m_fDrawDistance;
        struct RpClump* m_pRwObject;
    };
    typedef struct TxdDef TxdDef;
    struct TxdDef {
        RwTexDictionary *m_pRwDictionary;
        unsigned short m_wRefsCount;
        short m_wParentIndex;
        unsigned int m_hash;
    };
    typedef struct CPool CPool;
    struct CPool
    {
        TxdDef* m_pObjects;
        uint8_t* m_byteMap;
        int m_nSize;
        int top;
        char m_bOwnsAllocations;
        char bLocked;
        short _pad;
    };
    typedef struct RwTexture RwTexture;
    struct RwTexture {
        RwRaster* raster;
    };
    typedef struct CSprite2d CSprite2d;
    struct CSprite2d {
        RwTexture* m_pTexture;
    };
    typedef struct CWeaponInfo CWeaponInfo;
    struct CWeaponInfo
    {
        int m_eFireType;
        float targetRange;
        float m_fWeaponRange;
        int dwModelId1;
        int dwModelId2;
        int nSlot;
        int m_nFlags;
        int AssocGroupId;
        short ammoClip;
        short damage;
        float* fireOffset;
        int skillLevel;
        int reqStatLevelToGetThisWeaponSkilLevel;
        float m_fAccuracy;
        float moveSpeed;
        float animLoopStart;
        float animLoopEnd;
        int animLoopFire;
        int animLoop2Start;
        int animLoop2End;
        int animLoop2Fire;
        float breakoutTime;
        float speed;
        int radius;
        float lifespan;
        float spread;
        char AssocGroupId2;
        char field_6D;
        char baseCombo;
        char m_nNumCombos;
    };
]]

local CWeaponInfo__GetWeaponInfo = ffi.cast("CWeaponInfo*(__cdecl*)(uint8_t, uint8_t)", 0x743C60)
local CKeyGen__AppendStringToKey = ffi.cast("unsigned int(__cdecl*)(unsigned int, char*)", 0x53CF70)
local RwTexDictionaryFindHashNamedTexture = ffi.cast("RwTexture*(__cdecl*)(RwTexDictionary*, unsigned int)", 0x734E50)

function getWeaponIconTexture(nWeaponModelId)
    local pTexture = ffi.new("RwTexDictionary*");
    local pModelInfo = ffi.new("CBaseModelInfo*");
    local pWeaponInfo = CWeaponInfo__GetWeaponInfo(nWeaponModelId, 1);
    if (pWeaponInfo.dwModelId1 > 0) then
        pModelInfo = ffi.cast("CBaseModelInfo**", 0xA9B0C8)[pWeaponInfo.dwModelId1];
        local nTxdIndex = pModelInfo.m_wTxdIndex;
        local pTxdPool = ffi.cast("CPool**", 0xC8800C)[0];
        if ffi.cast("uint8_t", pTxdPool.m_byteMap + nTxdIndex) >= 0 then
            pTexture = pTxdPool.m_pObjects[nTxdIndex].m_pRwDictionary;
        end
        if pTexture ~= nil then
            local nAppended = CKeyGen__AppendStringToKey(pModelInfo.m_dwKey, ffi.cast("char*", "ICON"));
            local texture = RwTexDictionaryFindHashNamedTexture(pTexture, nAppended);
            if texture ~= nil then
                return texture.raster.texture_ptr
            else
            end
        end
    else
        local fistSprite = ffi.cast("CSprite2d*", 0xBAB1FC)[0];
        return fistSprite.m_pTexture.raster.texture_ptr
    end
    return nil;
end

Способ применения:
Lua:
-- В фрейме мимгуи:
local dl = imgui.GetBackgroundDrawList();
local texture = getWeaponIconTexture(getCurrentCharWeapon(PLAYER_PED))
if texture ~= nil then
    dl:AddImage(texture, imgui.ImVec2(400, 400), imgui.ImVec2(600, 600))
end

Скриншот:
1713066362986.png
 
Последнее редактирование:

UBP

Известный
328
168
Grand Theft Auto  San Andreas 2024.04.14 - 12.21.20.01.gif


Lua:
drawAnimatedLoadingIndicator(resX / 2, resY / 2, 50, 8, 0.2)
Lua:
function drawAnimatedLoadingIndicator(centerX, centerY, radius, thickness, speed)
    local ImGui = imgui
    local draw_list = ImGui.GetWindowDrawList()
    local time = ImGui.GetTime()

    -- Основные параметры
    local start_angle = -math.pi / 2
    local max_angle = 2 * math.pi
    local end_angle = start_angle + max_angle * (time * speed % 1)

    -- Цвета
    local bgColor = ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(0.2, 0.2, 0.2, 1))
    local fgColor = ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(0.4, 0.7, 0.2, 1))

    -- Рисуем фон индикатора
    draw_list:PathArcTo(ImGui.ImVec2(centerX, centerY), radius, start_angle, start_angle + max_angle, 64)
    draw_list:PathStroke(bgColor, false, thickness)

    -- Рисуем анимированный прогресс индикатора
    draw_list:PathArcTo(ImGui.ImVec2(centerX, centerY), radius, start_angle, end_angle, 64)
    draw_list:PathStroke(fgColor, false, thickness)
end


Grand Theft Auto  San Andreas 2024.04.14 - 12.31.08.02.gif







Lua:
local totalTime = 15 -- Общее время таймера в секундах
local startTime = os.time() -- Время старта таймера


local currentTime = os.time()
local elapsedTime = os.difftime(currentTime, startTime)
local remainingTime = math.max(0, totalTime - elapsedTime)
drawCircularTimer(resX / 2, resY / 2, 100, remainingTime, totalTime)
Lua:
function drawCircularTimer(x, y, radius, remainingTime, totalTime)
    local ImGui = imgui
    local draw_list = ImGui.GetWindowDrawList()

    -- Определяем параметры для визуализации таймера
    local start_angle = 3 * math.pi / 2
    local end_angle = start_angle + (2 * math.pi) * (remainingTime / totalTime)

    -- Цвета
    local timerColor = ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(0.2, 0.7, 0.3, 1)) -- Зеленый
    local backgroundColor = ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(0.2, 0.2, 0.2, 0.3)) -- Темно-серый

    -- Рисуем фон таймера
    draw_list:AddCircleFilled(ImGui.ImVec2(x, y), radius, backgroundColor, 64)

    -- Рисуем оставшееся время таймера
    if remainingTime > 0 then
        draw_list:PathArcTo(ImGui.ImVec2(x, y), radius - 1, start_angle, end_angle, 64)
        draw_list:PathStroke(timerColor, false, 2)
    end

    -- Текст с оставшимся временем
    local timeText = string.format("%.2f", remainingTime)
    local textSize = ImGui.CalcTextSize(timeText)
    draw_list:AddText(ImGui.ImVec2(x - textSize.x / 2, y - textSize.y / 2), ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(1, 1, 1, 1)), timeText)
end
Grand Theft Auto  San Andreas 2024.04.14 - 12.40.11.03.gif


Lua:
local volumeLevel = imgui.new.float(0.5)
drawVerticalVolumeSlider(resX / 2, resY / 2, 30, 200, volumeLevel)
Lua:
function drawVerticalVolumeSlider(x, y, width, height, volumeLevel)
    local ImGui = imgui
    local draw_list = ImGui.GetWindowDrawList()

    -- Определяем параметры
    local sliderBgColor = ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(0.2, 0.25, 0.3, 1))
    local sliderFilledColor = ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(0.2, 0.7, 0.3, 1))
    local borderColor = ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(1, 1, 1, 0.5))

    -- Рисуем фон слайдера
    draw_list:AddRectFilled(ImGui.ImVec2(x, y), ImGui.ImVec2(x + width, y + height), sliderBgColor, 4)
    draw_list:AddRect(ImGui.ImVec2(x, y), ImGui.ImVec2(x + width, y + height), borderColor, 4)
    ImGui.SetCursorPos(ImGui.ImVec2(x, y))
    ImGui.InvisibleButton("slider", ImGui.ImVec2(width, height))

    -- Если элемент активен (нажатие и удерживание кнопки мыши), обновляем уровень громкости
    if ImGui.IsItemActive() then
        local mousePos = ImGui.GetMousePos()
        volumeLevel[0] = math.max(0, math.min(1, (mousePos.y - y) / height))
        volumeLevel[0] = 1.0 - volumeLevel[0]  -- Инвертируем значение, так как координаты идут сверху вниз
    end

    -- Рассчитываем высоту заполнения в зависимости от уровня громкости
    local fillHeight = height * volumeLevel[0]
    local fillYStart = y + height - fillHeight

    -- Рисуем заполнение слайдера
    draw_list:AddRectFilled(ImGui.ImVec2(x, fillYStart), ImGui.ImVec2(x + width, y + height), sliderFilledColor, 4)
end


1713088125373.png

1713088138525.png



Lua:
local chargeLevel = 0.75 -- 75% заряда
drawBatteryIndicator(resX / 2, resY / 2, 100, 50, chargeLevel)


Lua:
function drawBatteryIndicator(x, y, width, height, chargeLevel)
    local ImGui = imgui
    local draw_list = ImGui.GetWindowDrawList()

    -- Определяем цвета в зависимости от уровня заряда
    local chargeColor
    if chargeLevel > 0.5 then
        chargeColor = ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(0.2, 0.8, 0.2, 1)) -- Зелёный
    elseif chargeLevel > 0.2 then
        chargeColor = ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(0.8, 0.8, 0.2, 1)) -- Жёлтый
    else
        chargeColor = ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(0.8, 0.2, 0.2, 1)) -- Красный
    end

    -- Рисуем контур батареи
    draw_list:AddRect(ImGui.ImVec2(x, y), ImGui.ImVec2(x + width, y + height), ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(1, 1, 1, 1)), 1.0, 0, 2)
    -- Рисуем "наконечник" батареи
    draw_list:AddRectFilled(ImGui.ImVec2(x + width, y + height * 0.3), ImGui.ImVec2(x + width + width * 0.05, y + height * 0.7), ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(1, 1, 1, 1)))
    -- Рисуем уровень заряда
    draw_list:AddRectFilled(ImGui.ImVec2(x + 2, y + 2), ImGui.ImVec2(x + 2 + (width - 4) * chargeLevel, y + height - 2), chargeColor)

    -- Опционально: добавляем текст с процентом заряда
    local text = string.format("%.0f%%", chargeLevel * 100)
    draw_list:AddText(ImGui.ImVec2(x + width / 2 - 10, y + height / 2 - 8), ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(1, 1, 1, 1)), text)
end


Grand Theft Auto  San Andreas 2024.04.14 - 12.51.27.04.gif


Lua:
local activityData = {
    { day = "Пн", value = 30 },
    { day = "Вт", value = 60 },
    { day = "Ср", value = 45 },
    { day = "Чт", value = 80 },
    { day = "Пт", value = 55 },
    { day = "Сб", value = 70 },
    { day = "Вс", value = 20 }
}
drawActivityGraph(resX / 2, resY / 2, 300, 100, activityData)


Lua:
function drawActivityGraph(x, y, width, height, activityData)
    local ImGui = imgui
    local draw_list = ImGui.GetWindowDrawList()

    -- Определяем цвета
    local bgColor = ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(0.2, 0.25, 0.3, 1))
    local barColor = ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(0.2, 0.7, 0.3, 1))
    local highlightColor = ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(0.4, 0.9, 0.4, 1))

    -- Рисуем фон графика
    draw_list:AddRectFilled(ImGui.ImVec2(x, y), ImGui.ImVec2(x + width, y + height), bgColor, 4)

    local barWidth = width / #activityData
    for i, activity in ipairs(activityData) do
        local barHeight = (height * activity.value) / 100
        local barX = x + (i - 1) * barWidth
        local barY = y + height - barHeight

        -- Проверяем, находится ли курсор над столбцом
        local isHovered = ImGui.IsMouseHoveringRect(ImGui.ImVec2(barX, barY), ImGui.ImVec2(barX + barWidth, y + height))
        local color = isHovered and highlightColor or barColor

        -- Рисуем столбец гистограммы
        draw_list:AddRectFilled(ImGui.ImVec2(barX, barY), ImGui.ImVec2(barX + barWidth, y + height), color, 2)

        -- Если курсор над столбцом, отображаем подсказку с значением
        if isHovered then
            ImGui.BeginTooltip()
            ImGui.Text(string.format("%s: %.2f%%", activity.day, activity.value))
            ImGui.EndTooltip()
        end
    end
end
 

g305noobo

Известный
205
168
Описание:
- get_current_function_name() возвращает название текущей функции, в которой вызвали
- get_caller_function_name() возвращает функцию, откуда вызвали функцию, в которой вызвана get_caller_function_name() 🤔

Код:
Lua:
function get_current_function_name()
    local info = debug.getinfo(2, "n")
    if info then return info.name or "unknown" end
    return "main"
end

function get_caller_function_name()
    local info = debug.getinfo(3, "n")
    if info then return info.name or "unknown" end
    return "main"
end

Способы применения:
Эти функции полезны в объёмных скриптах, чтобы вывод был более приятным и информативным

- get_current_function_name():
Lua:
function a()
    print("Сейчас я нахожусь в функции ", get_current_function_name())
    -- выведет "Сейчас я нахожусь в функции a"
end
- get_caller_function_name():
Lua:
function b()
    print("Меня вызвали из функции ", get_caller_function_name())
    -- выведет "Меня вызвали из функции caller"
end

function caller()
    b()
end
 

UBP

Известный
328
168
Описание:
- get_current_function_name() возвращает название текущей функции, в которой вызвали
- get_caller_function_name() возвращает функцию, откуда вызвали функцию, в которой вызвана get_caller_function_name() 🤔

Код:
Lua:
function get_current_function_name()
    local info = debug.getinfo(2, "n")
    if info then return info.name or "unknown" end
    return "main"
end

function get_caller_function_name()
    local info = debug.getinfo(3, "n")
    if info then return info.name or "unknown" end
    return "main"
end

Способы применения:
Эти функции полезны в объёмных скриптах, чтобы вывод был более приятным и информативным

- get_current_function_name():
Lua:
function a()
    print("Сейчас я нахожусь в функции ", get_current_function_name())
    -- выведет "Сейчас я нахожусь в функции a"
end
- get_caller_function_name():
Lua:
function b()
    print("Меня вызвали из функции ", get_caller_function_name())
    -- выведет "Меня вызвали из функции caller"
end

function caller()
    b()
end
nahui eto nado?
1713200574111.png


Lua:
drawAnimatedGradientProgressBar(resX / 2, resY / 2, 300, 15, 0.4)

Lua:
function drawAnimatedGradientProgressBar(x, y, width, height, progress)
    local ImGui = imgui
    local draw_list = ImGui.GetWindowDrawList()

    -- Определение цветов для градиента
    local startColor = ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(0.4, 0.9, 0.4, 1)) -- Зеленый
    local endColor = ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(0.9, 0.4, 0.4, 1)) -- Красный

    -- Рисуем фон прогресс-бара
    draw_list:AddRectFilled(ImGui.ImVec2(x, y), ImGui.ImVec2(x + width, y + height), ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(0.2, 0.2, 0.2, 1)), 4)

    -- Рисуем градиентную заливку в зависимости от прогресса
    local filledWidth = width * progress
    draw_list:AddRectFilledMultiColor(
        ImGui.ImVec2(x, y),
        ImGui.ImVec2(x + filledWidth, y + height),
        startColor, endColor, endColor, startColor
    )

    -- Добавляем анимацию мерцания на переднем крае прогресс-бара
    local flickerWidth = 5 -- ширина мерцания
    local flickerX = x + filledWidth - flickerWidth / 2
    local time = os.clock()
    local flickerAlpha = 0.5 + 0.5 * math.sin(time * 10) -- анимация мерцания
    local flickerColor = ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(1, 1, 1, flickerAlpha))

    if progress > 0 and progress < 1 then
        draw_list:AddRectFilled(ImGui.ImVec2(flickerX, y), ImGui.ImVec2(flickerX + flickerWidth, y + height), flickerColor)
    end

    -- Текст с процентом заполнения
    local text = string.format("%.0f%%", progress * 100)
    local text_size = ImGui.CalcTextSize(text)
    draw_list:AddText(ImGui.ImVec2(x + (width - text_size.x) / 2, y + (height - text_size.y) / 2), ImGui.ColorConvertFloat4ToU32(ImGui.ImVec4(1, 1, 1, 1)), text)
end

1713201517812.png

только английские буквы
Lua:
function displayActiveOptionsWithColors(selectedIndices, options)
    if DisplayActiveOptions == false then return end
    imgui.BeginChild('ActiveOptionsColors', imgui.ImVec2(300, 500), true)
    for key, index in pairs(selectedIndices) do
        local optionValue = options[key][index]
        if optionValue ~= 'Off' then
            local text = (key)
            local textSize = imgui.CalcTextSize(text)
            local cursorPos = imgui.GetCursorScreenPos()
            local drawList = imgui.GetWindowDrawList()

            -- Добавляем текст поверх прямоугольника
            if enableTextGradient then
                -- Создаем переливающийся текст
                imgui.PushFont(Font[19])
                displayRainbowText(text, 0.5, 255, 0)
                imgui.PopFont()
            else
                -- Обычный белый текст
                drawList:AddText(cursorPos, imgui.ColorConvertFloat4ToU32(imgui.ImVec4(1, 1, 1, 1)), text)
            end
            
            -- Сдвигаем курсор вниз для следующего элемента
            imgui.SetCursorPosY(imgui.GetCursorPosY() + textSize.y + 9)
        end
    end
    
    imgui.EndChild()
end
или более простой пример
Lua:
displayRainbowText(u8('Print'), 0.5, 255, 0)

Lua:
-- Функция для отображения переливающегося текста
function displayRainbowText(text, speed, alpha, offset)
    local drawList = imgui.GetWindowDrawList()
    local cursorPos = imgui.GetCursorScreenPos()
    
    for i = 1, #text do
        local char = text:sub(i, i)
        local charSize = imgui.CalcTextSize(char)
        
        -- Получаем цвет для текущей буквы
        local r, g, b = rainbow(speed, alpha, offset + i * 0.1) -- Смещаем цвет для каждой буквы
        local color = join_argb(alpha, r, g, b)
        
        -- Рисуем букву
        drawList:AddText(cursorPos, color, char)
        -- Сдвигаем позицию курсора для следующей буквы
        cursorPos.x = cursorPos.x + charSize.x
    end
end
function join_argb(a, r, g, b)
    local argb = b
    argb = bit.bor(argb, bit.lshift(g, 8))
    argb = bit.bor(argb, bit.lshift(r, 16))
    argb = bit.bor(argb, bit.lshift(a, 24))
    return argb
end

function rainbow(speed, alpha, offset) -- by rraggerr
    local clock = os.clock() + offset
    local r = math.floor(math.sin(clock * speed) * 127 + 128)
    local g = math.floor(math.sin(clock * speed + 2) * 127 + 128)
    local b = math.floor(math.sin(clock * speed + 4) * 127 + 128)
    return r,g,b,alpha
end