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

Орк

Известный
340
299
Описание: Скриншот экрана, который сохраняется в буфер обмена, типа Print Screen. Не знаю зачем, но пусть будет.
Пример использования:
Lua:
screenshotToClipboard()
Код:
Lua:
local ffi = require("ffi")

ffi.cdef[[
    typedef void* HANDLE;
    typedef void* HDC;
    typedef void* HBITMAP;
    typedef const char* LPCSTR;
    typedef unsigned int UINT;
    typedef int BOOL;
    typedef unsigned long DWORD;

    HDC GetDC(void* hWnd);
    int ReleaseDC(void* hWnd, HDC hDC);
    int GetSystemMetrics(int nIndex);
    HDC CreateCompatibleDC(HDC hdc);
    HBITMAP CreateCompatibleBitmap(HDC hdc, int cx, int cy);
    HBITMAP SelectObject(HDC hdc, HBITMAP h);
    BOOL BitBlt(HDC hdcDest, int xDest, int yDest, int w, int h, HDC hdcSrc, int xSrc, int ySrc, DWORD rop);
    BOOL DeleteDC(HDC hdc);
    BOOL DeleteObject(HBITMAP hObject);

    BOOL OpenClipboard(void* hWndNewOwner);
    BOOL EmptyClipboard();
    BOOL CloseClipboard();
    HANDLE SetClipboardData(UINT uFormat, HANDLE hMem);

    enum { SM_CXSCREEN = 0, SM_CYSCREEN = 1 };
    enum { SRCCOPY = 0x00CC0020 };
    enum { CF_BITMAP = 2 };
]]

local user32 = ffi.load("user32")
local gdi32 = ffi.load("gdi32")

function screenshotToClipboard()
    local width = user32.GetSystemMetrics(0)
    local height = user32.GetSystemMetrics(1)

    local hdcScreen = user32.GetDC(nil)
    local hdcMem = gdi32.CreateCompatibleDC(hdcScreen)
    local hBitmap = gdi32.CreateCompatibleBitmap(hdcScreen, width, height)

    if hBitmap == nil then
        print("Не удалось создать совместимый битмап.")
        user32.ReleaseDC(nil, hdcScreen)
        return
    end

    gdi32.SelectObject(hdcMem, hBitmap)
    gdi32.BitBlt(hdcMem, 0, 0, width, height, hdcScreen, 0, 0, ffi.C.SRCCOPY)

    if user32.OpenClipboard(nil) ~= 0 then
        user32.EmptyClipboard()
        user32.SetClipboardData(ffi.C.CF_BITMAP, hBitmap)
        user32.CloseClipboard()
        print("Скриншот скопирован в буфер обмена.")
    else
        print("Не удалось открыть буфер обмена.")
    end

    gdi32.DeleteDC(hdcMem)
    user32.ReleaseDC(nil, hdcScreen)
    gdi32.DeleteObject(hBitmap)
end
Lua:
local ffi = require("ffi")

ffi.cdef[[
    typedef void* HANDLE;
    typedef void* HDC;
    typedef void* HBITMAP;
    typedef const char* LPCSTR;
    typedef unsigned int UINT;
    typedef int BOOL;
    typedef unsigned long DWORD;

    HDC GetDC(void* hWnd);
    int GetSystemMetrics(int nIndex);
    HDC CreateCompatibleDC(HDC hdc);
    HBITMAP CreateCompatibleBitmap(HDC hdc, int cx, int cy);
    HBITMAP SelectObject(HDC hdc, HBITMAP h);
    BOOL BitBlt(HDC hdcDest, int xDest, int yDest, int w, int h, HDC hdcSrc, int xSrc, int ySrc, DWORD rop);
    BOOL DeleteDC(HDC hdc);
    BOOL DeleteObject(HBITMAP hObject);

    BOOL OpenClipboard(void* hWndNewOwner);
    BOOL EmptyClipboard();
    BOOL CloseClipboard();
    HANDLE SetClipboardData(UINT uFormat, HANDLE hMem);

    HANDLE GlobalAlloc(UINT uFlags, size_t dwBytes);
    HANDLE GlobalLock(HANDLE hMem);
    BOOL GlobalUnlock(HANDLE hMem);
    BOOL IsClipboardFormatAvailable(UINT format);
   
    BOOL OpenClipboard(void*);
    BOOL CloseClipboard();
    enum { SM_CXSCREEN = 0, SM_CYSCREEN = 1 };
    enum { SRCCOPY = 0x00CC0020 };
    enum { CF_BITMAP = 2 };
]]

local user32 = ffi.load("user32")
local gdi32 = ffi.load("gdi32")
local kernel32 = ffi.load("kernel32")

function screenshotToClipboard()
    local width = user32.GetSystemMetrics(0)
    local height = user32.GetSystemMetrics(1)

    local hdcScreen = user32.GetDC(nil)
    local hdcMem = gdi32.CreateCompatibleDC(hdcScreen)
    local hBitmap = gdi32.CreateCompatibleBitmap(hdcScreen, width, height)
    gdi32.SelectObject(hdcMem, hBitmap)
    gdi32.BitBlt(hdcMem, 0, 0, width, height, hdcScreen, 0, 0, ffi.C.SRCCOPY)

    if user32.OpenClipboard(nil) ~= 0 then
        user32.EmptyClipboard()
        user32.SetClipboardData(ffi.C.CF_BITMAP, hBitmap)
        user32.CloseClipboard()
        print("Скриншот скопирован в буфер обмена.")
    else
        print("Не удалось открыть буфер обмена.")
    end

    -- очистка
    gdi32.DeleteDC(hdcMem)
    -- hBitmap не удаляем, т.к. он теперь в буфере обмена
end
 
Последнее редактирование:

Tectrex

Известный
139
164
Описание: Скриншот экрана, который сохраняется в буфер обмена, типа Print Screen. Не знаю зачем, но пусть будет.
Пример использования:
Lua:
screenshotToClipboard()
Код:
Lua:
local ffi = require("ffi")

ffi.cdef[[
    typedef void* HANDLE;
    typedef void* HDC;
    typedef void* HBITMAP;
    typedef const char* LPCSTR;
    typedef unsigned int UINT;
    typedef int BOOL;
    typedef unsigned long DWORD;

    HDC GetDC(void* hWnd);
    int GetSystemMetrics(int nIndex);
    HDC CreateCompatibleDC(HDC hdc);
    HBITMAP CreateCompatibleBitmap(HDC hdc, int cx, int cy);
    HBITMAP SelectObject(HDC hdc, HBITMAP h);
    BOOL BitBlt(HDC hdcDest, int xDest, int yDest, int w, int h, HDC hdcSrc, int xSrc, int ySrc, DWORD rop);
    BOOL DeleteDC(HDC hdc);
    BOOL DeleteObject(HBITMAP hObject);

    BOOL OpenClipboard(void* hWndNewOwner);
    BOOL EmptyClipboard();
    BOOL CloseClipboard();
    HANDLE SetClipboardData(UINT uFormat, HANDLE hMem);

    HANDLE GlobalAlloc(UINT uFlags, size_t dwBytes);
    HANDLE GlobalLock(HANDLE hMem);
    BOOL GlobalUnlock(HANDLE hMem);
    BOOL IsClipboardFormatAvailable(UINT format);
   
    BOOL OpenClipboard(void*);
    BOOL CloseClipboard();
    enum { SM_CXSCREEN = 0, SM_CYSCREEN = 1 };
    enum { SRCCOPY = 0x00CC0020 };
    enum { CF_BITMAP = 2 };
]]

local user32 = ffi.load("user32")
local gdi32 = ffi.load("gdi32")
local kernel32 = ffi.load("kernel32")

function screenshotToClipboard()
    local width = user32.GetSystemMetrics(0)
    local height = user32.GetSystemMetrics(1)

    local hdcScreen = user32.GetDC(nil)
    local hdcMem = gdi32.CreateCompatibleDC(hdcScreen)
    local hBitmap = gdi32.CreateCompatibleBitmap(hdcScreen, width, height)
    gdi32.SelectObject(hdcMem, hBitmap)
    gdi32.BitBlt(hdcMem, 0, 0, width, height, hdcScreen, 0, 0, ffi.C.SRCCOPY)

    if user32.OpenClipboard(nil) ~= 0 then
        user32.EmptyClipboard()
        user32.SetClipboardData(ffi.C.CF_BITMAP, hBitmap)
        user32.CloseClipboard()
        print("Скриншот скопирован в буфер обмена.")
    else
        print("Не удалось открыть буфер обмена.")
    end

    -- очистка
    gdi32.DeleteDC(hdcMem)
    -- hBitmap не удаляем, т.к. он теперь в буфере обмена
end
я не догнал, а ReleaseDC не надо вызывать шоль?
 
  • Нравится
Реакции: Орк

chapo

tg/inst: @moujeek
Всефорумный модератор
9,127
12,231
Описание: небольшой пародия на iota из Go
Код:
Lua:
local iota = setmetatable({ value = -1 }, {
    __call = function(self, newValue)
        self.value = newValue or self.value + 1;
        return self.value;
    end
});
Пример использования:
Lua:
local iota = setmetatable({ value = -1 }, {
    __call = function(self, newValue)
        self.value = newValue or self.value + 1;
        return self.value;
    end
});

Packet = {
    Connect = iota(),
    ConnectResponse = iota(),
    BotConnect = iota(),
    BotDisconnect = iota()
};

print(Packet.Connect, Packet.ConnectResponse, Packet.BotConnect, Packet.BotDisconnect);
1745317523431.png
 

Орк

Известный
340
299
Описание: *Изменяет цвет текста в EditBox диалога*
Lua:
function editDialogEditBoxTextColor(color)
    local pDialog = memory.read(getModuleHandle("samp.dll") + 0x21A0B8, 4, true)
    local pEditBox = memory.read(pDialog + 0x24, 4, true)
    memory.write(pEditBox + 0x127, color, true)
end
Пример использования:
Lua:
function main()   
     editDialogEditBoxTextColor(0xFF00FF00) -- argb color (Green)
end
За столько времени никто не сказал, что он забыл memory.write(pEditBox + 0x127, color, uint size, true) поставить.
А я голову ломал, почему в диалогах не меняется цвет, даже по-другому сделал.
Lua:
--    ['R1'] = 0x21A0B8 , ['R2'] = 0x21A0C0, 
--    ['R3-1'] = 0x26E898, ['R4'] = 0x26E9C8, 
--    ['R4-2'] = 0x26E9C8, ['R5'] = 0x26EB50, ['DL-R1'] = 0x2AC9E0}
function SetDialogInputColors(color)
    local p = memory.getint32(memory.getint32(getModuleHandle('samp.dll') + 0x26E898) + 0x24)
    if p == 0 then return end
    memory.setuint32(p + 0x127, color) -- Цвет текста
    memory.setuint32(p + 0x133, color) -- символа | на конце
end
Возможно нужно запускать в беск. цикле
1745340369426.png
 
  • Нравится
  • Эм
Реакции: Tema05 и VanoKLR

Орк

Известный
340
299
Описание: Меняет имя скришота, сделанного на фотоаппарат. Не захотел создавать отдельную тему, покажу просто, как это реализуется, в примере сохранится по пути "\GTA San Andreas User Files\Gallery\03 мая 2025\photo - 001.jpg"
1746226368627.png

Адреса спизжены отсюда
Пример использования:
Lua:
local memory = require 'memory'
local encoding = require 'encoding'
encoding.default = 'CP1251'
local u8 = encoding.UTF8

function main()
    while memory.getuint8(0xC8D4C0) ~= 9 do wait(1000) end

    -- Получаем путь к Gallery
    local userFilesPath = getFolderPath(5) .. "\\GTA San Andreas User Files"
    local galleryBasePath = userFilesPath .. "\\Gallery"

    -- Получаем текущую дату
    local t = os.date("*t")
    local months = {"января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"}
    local dateStr = u8:decode(string.format("%02d %s %04d", t.day, months[t.month], t.year ))

    -- Путь: Gallery\YYYY-MM-DD
    local fullFolderPath = string.format("%s\\%s", galleryBasePath, dateStr)

    -- Создаём папку, если её нет
    if not doesDirectoryExist(galleryBasePath) then
        createDirectory(galleryBasePath)
    end
    if not doesDirectoryExist(fullFolderPath) then
        createDirectory(fullFolderPath)
    end

    -- Устанавливаем шаблон для имени фото
    local relativePath = string.format("Gallery\\%s\\photo - %%03d.jpg", dateStr)
 
    local str_ptr = memory.strptr(relativePath .. "\0")

    memory.fill(0x872644, 0, 260)
    memory.copy(0x872644, str_ptr, #relativePath + 1)
 
    wait(-1)
end
Код:
Lua:
local photo_pattern = "Gallery\\photo - %03d.jpg"
local str_ptr = memory.strptr(photo_pattern .. "\0")

memory.fill(0x872644, 0, 260)
memory.copy(0x872644, str_ptr, #photo_pattern + 1)
 
Последнее редактирование:
  • Нравится
Реакции: вайега52

Tectrex

Известный
139
164
Описание: Меняет имя скришота, сделанного на фотоаппарат. Не захотел создавать отдельную тему, покажу просто, как это реализуется, в примере сохранится по пути "\GTA San Andreas User Files\Gallery\03 мая 2025\photo - 001.jpg"
Посмотреть вложение 269189
Адреса спизжены отсюда
Пример использования:
Lua:
local memory = require 'memory'
local encoding = require 'encoding'
encoding.default = 'CP1251'
local u8 = encoding.UTF8

function main()
    while memory.getuint8(0xC8D4C0) ~= 9 do wait(1000) end

    -- Получаем путь к Gallery
    local userFilesPath = getFolderPath(5) .. "\\GTA San Andreas User Files"
    local galleryBasePath = userFilesPath .. "\\Gallery"

    -- Получаем текущую дату
    local t = os.date("*t")
    local months = {"января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"}
    local dateStr = u8:decode(string.format("%02d %s %04d", t.day, months[t.month], t.year ))

    -- Путь: Gallery\YYYY-MM-DD
    local fullFolderPath = string.format("%s\\%s", galleryBasePath, dateStr)

    -- Создаём папку, если её нет
    if not doesDirectoryExist(galleryBasePath) then
        createDirectory(galleryBasePath)
    end
    if not doesDirectoryExist(fullFolderPath) then
        createDirectory(fullFolderPath)
    end

    -- Устанавливаем шаблон для имени фото
    local relativePath = string.format("Gallery\\%s\\photo - %%03d.jpg", dateStr)
 
    local str_ptr = memory.strptr(relativePath .. "\0")

    memory.fill(0x872644, 0, 260)
    memory.copy(0x872644, str_ptr, #relativePath + 1)
 
    wait(-1)
end
Код:
Lua:
local photo_pattern = "Gallery\\photo - %03d.jpg"
local str_ptr = memory.strptr(photo_pattern .. "\0")

memory.fill(0x872644, 0, 260)
memory.copy(0x872644, str_ptr, #photo_pattern + 1)
Ты уверен, что там всегда будет путь в формате %UserProfile%\Documents или %UserDir%\GTA San Andreas User Files? А что если у чела стоит не стандартная винда, а какая-нибудь линуксовая сборка или виртуалка?
 

kin4stat

mq-team · kin4@naebalovo.team
Всефорумный модератор
2,750
4,857
Ты уверен, что там всегда будет путь в формате %UserProfile%\Documents или %UserDir%\GTA San Andreas User Files? А что если у чела стоит не стандартная винда, а какая-нибудь линуксовая сборка или виртуалка?
откуда ты вообще это взял
 
  • Нравится
Реакции: kyrtion и Winstаl

kyrtion

Известный
1,188
438
Ты уверен, что там всегда будет путь в формате %UserProfile%\Documents или %UserDir%\GTA San Andreas User Files? А что если у чела стоит не стандартная винда, а какая-нибудь линуксовая сборка или виртуалка?
Вообще-то пускают в линукс игру через Wine из-за того что написана в ОС Windows. В Linux сомневаюсь что запустится без вайна
Могу сказать что игра для Windows и тогда будет использовать скрипт Lua под Windows (или Wine с Linux) в GTA:SA
Если ты можешь доказать обратной, то расскажи как ты сумел запустить GTA:SA без Wine

UPD: Wine создает готовые стандартные Windows папки вроде Документы, Изображение и тд, если ты об этом не слышал
 
  • Нравится
Реакции: Tectrex и Орк

cord

Хватит спать на мне
Проверенный
576
597
Описание: Отключает возвращение камеры при движении в тс, оставляя ее в исходном положении.
Пример использования:
Lua:
function main()
    repeat wait(100) until isSampLoaded()
    local bool = false
    sampRegisterChatCommand("patch", function()
        bool = not bool
        patch(bool)
        sampAddChatMessage("patched", -1)
    end)
    wait(-1)
end
Код:
Lua:
local memory = require("memory")
function patch(bool)
    if bool then
        memory.setuint16(0x5258EC, 0x9090, true)
        memory.setuint16(0x525A31, 0x9090, true)
        memory.setuint32(0x525A33, 0x90909090, true)
    else
        memory.setuint16(0x5258EC, 0x0674, true)
        memory.setuint16(0x525A31, 0x1274, true)
        memory.setuint32(0x525A33, 0xD9442410, true)
    end
end
 

dmitry.karle

Известный
363
100
Сливаю свои штуки дуки для фрейма в мимгуи

Описание: Кастомные тултипы, можно использовать вместо imgui.Hint() если кому надо. Выглядят хайпово как по мне для mimgui (использую moonmonet)
Пример использования:
Lua:
if imgui.Button('button1') then
    sampAddChatMessage('button1', -1)
end
if imgui.IsItemHovered() then
    AnimatedTooltip('Кнопка1', fa.EXCLAMATION) --можно и без иконки
end


if imgui.Button('button2') then
    sampAddChatMessage('button2', -1)
end
if imgui.IsItemHovered() then
    CustomTooltip('кнопка2', fa.CIRCLE_EXCLAMATION) --можно и без иконки
end
1748047708344.png


Код с анимацией пульсации:
Lua:
function AnimatedTooltip(text, icon, speed) --анимационный тултип
    local time = os.clock() * (speed or 2.0)
    local alpha = 0.7 + math.sin(time) * 0.3  -- Пульсация прозрачности
    local bgColor = imgui.ImVec4(0.1 + math.sin(time * 0.5) * 0.05, 0.1 + math.cos(time * 0.7) * 0.05, 0.15, alpha + 0.3) -- Градиентный фон с легкой анимацией
    local textColor = imgui.ImVec4(1.0, 1.0, 1.0, alpha) -- Цвет текста и иконки с анимацией
    imgui.PushStyleVarVec2(imgui.StyleVar.WindowPadding, imgui.ImVec2(12, 10))
    imgui.PushStyleVarFloat(imgui.StyleVar.WindowRounding, 8.0)
    imgui.PushStyleVarFloat(imgui.StyleVar.WindowBorderSize, 1.5)
    imgui.BeginTooltip()
    if icon then
        imgui.TextColored(textColor, icon .. "  ")
        imgui.SameLine()
    end
    imgui.TextColored(textColor, u8(text))
    imgui.EndTooltip()
    imgui.PopStyleColor(1)
    imgui.PopStyleVar(3)
end

Код со статичным тултипом:
Lua:
function CustomTooltip(text, icon) --обычный тултип
    imgui.PushStyleVarVec2(imgui.StyleVar.WindowPadding, imgui.ImVec2(12, 10))
    imgui.PushStyleVarFloat(imgui.StyleVar.WindowRounding, 8.0)
    imgui.PushStyleVarFloat(imgui.StyleVar.WindowBorderSize, 1.5)
    imgui.BeginTooltip()
    if icon then
        imgui.TextColored(imgui.GetStyle().Colors[imgui.Col.ButtonActive], icon .. "  ")  -- Иконка
        imgui.SameLine()
    end
    imgui.Text(u8(text))
    imgui.EndTooltip()
    imgui.PopStyleVar(3)
end

Описание: Кастомные радиуботтоны, если кому надо. Выглядят хайпово как по мне для mimgui (использую moonmonet)
Пример использования:
Lua:
if imgui.RadioButtonBool(u8"##1", s.type == "t1", frame.to_vec4(frame.palette.accent1.color_600), frame.to_vec4(frame.palette.accent1.color_600)) then
    s.type = "t1"
end; imgui.SameLine()
if imgui.RadioButtonBool(u8"##2", s.type == "t2", frame.to_vec4(frame.palette.accent1.color_600), frame.to_vec4(frame.palette.accent1.color_600)) then
    s.type = "t2"
end


if imgui.AnimatedRadioButtonBool(u8"##1", s.type == "t1", frame.to_vec4(frame.palette.accent1.color_600), frame.to_vec4(frame.palette.accent1.color_600)) then
    s.type = "t1"
end; imgui.SameLine()
if imgui.AnimatedRadioButtonBool(u8"##2", s.type == "t2", frame.to_vec4(frame.palette.accent1.color_600), frame.to_vec4(frame.palette.accent1.color_600)) then
    s.type = "t2"
end;
1748048232131.png


Код с анимацией пульсации:
Lua:
function imgui.AnimatedRadioButtonBool(label, state, active_color, inactive_color)
    local draw_list = imgui.GetWindowDrawList()
    local cursor_pos = imgui.GetCursorScreenPos()
    local button_size = imgui.ImVec2(23, 23)
    local original_pos = imgui.GetCursorPos()
    local style = imgui.GetStyle()
  
    local display_text = label:gsub('##.*$', '')
    local text_size = imgui.CalcTextSize(u8(display_text))
  
    local button_id = '##radio_'..label
    local pressed = imgui.InvisibleButton(button_id, button_size)
  
    -- центр круга
    local center = imgui.ImVec2(cursor_pos.x + button_size.x / 2,cursor_pos.y + button_size.y / 2)
  
    -- Параметры анимации
    local time = imgui.GetTime()
    local anim_speed = 10.0
    local pulse = 0.2 * math.sin(time * anim_speed) + 0.8
  
    -- Цвета для состояний
    local outer_color = state and active_color or inactive_color
    local inner_color = imgui.ImVec4(outer_color.x,outer_color.y,outer_color.z,outer_color.w * 0.7 * (state and pulse or 1.0))
  
    -- внешний круг с анимацией
    draw_list:AddCircleFilled(center,button_size.x / 2, imgui.GetColorU32Vec4(imgui.ImVec4(outer_color.x,outer_color.y,outer_color.z,outer_color.w * 0.3)), 32)
  
    -- внутренний круг
    draw_list:AddCircleFilled(center,button_size.x / 2.5, imgui.GetColorU32Vec4(inner_color), 32)
  
    -- Эффект выделения при наведении
    if imgui.IsItemHovered() then
        draw_list:AddCircle(center,button_size.x / 2 + 1, imgui.GetColorU32Vec4(imgui.ImVec4(1, 1, 1, 0.3)), 32, 1.5)
    end
  
    -- Обводка для активного
    if state then
        draw_list:AddCircle(center,button_size.x / 2 + 1, imgui.GetColorU32Vec4(imgui.ImVec4(1, 1, 1, 0.8)), 32, 1.5)
    end
  
    -- Текст метки
    imgui.SetCursorPos(imgui.ImVec2(original_pos.x + button_size.x + style.ItemSpacing.x, original_pos.y + (button_size.y - text_size.y) / 2
    ))
    imgui.Text(label)
    return pressed
end


Статичный радиобуттон:
Lua:
function imgui.RadioButtonBool(label, state, color)
    local style = imgui.GetStyle()
    local size = imgui.ImVec2(23, 23)
    local pos = imgui.GetCursorScreenPos()
    local center = imgui.ImVec2(pos.x + size.x / 2, pos.y + size.y / 2)
    local radius = size.x / 2
    local innerRadius = size.x / 2.7
    local draw_list = imgui.GetWindowDrawList()
    local original_cursor_pos = imgui.GetCursorPos()
    local button = imgui.InvisibleButton(label .. "##RadioColor", size)
    draw_list:AddCircleFilled( center,  radius,  imgui.GetColorU32Vec4(imgui.ImVec4(color.x, color.y, color.z, 0.5)),  32) -- Внешний круг (фон)
    draw_list:AddCircleFilled(center,  innerRadius,  imgui.GetColorU32Vec4(imgui.ImVec4(color.x, color.y, color.z, color.w)),  32) -- Внутренний круг
    if state then -- Обводка в зависимости от состояния
        draw_list:AddCircle(center,  radius + 1,  imgui.GetColorU32Vec4(imgui.ImVec4(1, 1, 1, 1)),  32,  2) -- Яркая обводка для активного состояния
        draw_list:AddCircle(center,  radius + 3,  imgui.GetColorU32Vec4(imgui.ImVec4(1, 1, 1, 0.3)),  32,  1) -- Свечение
    end
    imgui.SetCursorPos(imgui.ImVec2(original_cursor_pos.x + size.x + style.ItemSpacing.x, original_cursor_pos.y + (size.y - imgui.GetTextLineHeight()) / 2))
    imgui.Text(label)
    imgui.SetCursorPos(imgui.ImVec2(original_cursor_pos.x, original_cursor_pos.y + size.y + style.ItemSpacing.y))
    return button
end

Описание: Кастомные радиобуттон с анимацией при наведении и со свечящей обводкой (знаю что сливали их), но даю свою версию, кому надо. Можно использовать для стилей mimgui. Выглядят хайпово как по мне для mimgui (использую moonmonet)
Пример использования:
Lua:
--стили moonmonet в моём случае
local f = {
    list = {
        4281859840,
        4278206719,
    }
}

--во фрейме
for k, v in ipairs(f.list) do
    if RadioColor(tostring(k), ваш кфг (s.t.m) == k, imgui.ColorConvertU32ToFloat4(v)) then
        ваш кфг (s.t.m) = k
    end
end
1748048628690.png


Код цветных радиобуттон:
Lua:
function RadioColor(label, state, color)
    local size = imgui.ImVec2(28, 28)
    local center = imgui.ImVec2(imgui.GetCursorScreenPos().x + size.x / 2, imgui.GetCursorScreenPos().y + size.y / 2)
    local radius = size.x / 2
    local innerRadius = size.x / 2.7
    local button = imgui.InvisibleButton(label .. "##RadioColor", size)
    imgui.GetWindowDrawList():AddCircleFilled(center, radius, imgui.GetColorU32Vec4(imgui.ImVec4(color.z, color.y, color.x, 0.5)), 100) -- Внешний круг (фон)
    imgui.GetWindowDrawList():AddCircleFilled(center, innerRadius, imgui.GetColorU32Vec4(imgui.ImVec4(color.z, color.y, color.x, color.w)), 100) -- Внутренний круг (основной цвет)
    if state then
        imgui.GetWindowDrawList():AddCircle(center, radius + 1, imgui.GetColorU32Vec4(imgui.ImVec4(1, 1, 1, 1)), 100, 2) -- Белая обводка
        imgui.GetWindowDrawList():AddCircle(center, radius + 3, imgui.GetColorU32Vec4(imgui.ImVec4(1, 1, 1, 0.3)), 100, 1) -- Эффект "свечения" (опционально)
    else
        imgui.GetWindowDrawList():AddCircle(center, radius, imgui.GetColorU32Vec4(imgui.ImVec4(0.5, 0.5, 0.5, 0.3)), 100, 1) -- Сероватая обводка для неактивного состояния
    end
    if imgui.IsItemHovered() then
        imgui.GetWindowDrawList():AddCircle(center, radius + 2, imgui.GetColorU32Vec4(imgui.ImVec4(1, 1, 1, 0.5)), 100, 1) -- Эффект при наведении (даже для неактивного состояния)
    end
    return button
end

Описание: Кастомная менюшка с плавными анимациями, если кому надо. mimgui (использую moonmonet)
Пример использования:
Lua:
softMenuItem = 0
softMenu = {
    'No bike fall',
    'ClickWarp',
}

--во фрейме
for i=1, #softMenu do
    if imgui.softMenu(u8(softMenu[i]), imgui.ImVec2(180, 25), softMenuItem == i) then
        softMenuItem = i
    end
end

if softMenuItem == 1 then; imgui.SetCursorPos(imgui.ImVec2(10, 10))
    imgui.CenterColoredText(imgui.GetStyle().Colors[imgui.Col.ButtonActive], 'text1')
end
if softMenuItem == 2 then; imgui.SetCursorPos(imgui.ImVec2(10, 10))
    imgui.CenterColoredText(imgui.GetStyle().Colors[imgui.Col.ButtonActive], 'text2')
end
1748049320302.png


Код:
Lua:
function imgui.softMenu(text, size, is_selected, rounding, element_id)
    local SELECTION_BAR_WIDTH = 3
    local HOVER_ANIM_SPEED = 0.2
    local SELECTED_BG_ALPHA = 0.40
    function lerp(a, b, t) -- функция для плавного перехода
        return a + (b - a) * math.min(math.max(t, 0), 1)
    end
    if not imgui.softMenu_State then
        imgui.softMenu_State = {animations = {}, last_time = imgui.GetTime()}
    end
    local state = imgui.softMenu_State
    imgui.BeginGroup()
    local button_pressed = imgui.InvisibleButton(text, size)
    local is_hovered = imgui.IsItemHovered()
    local item_min = imgui.GetItemRectMin()
    local item_max = imgui.GetItemRectMax()
    element_id = element_id or text
    if not state.animations[element_id] then
        state.animations[element_id] = {alpha = 0, last_update = state.last_time}
    end
    local anim = state.animations[element_id]
    local current_time = imgui.GetTime()
    local delta_time = current_time - anim.last_update
    anim.last_update = current_time
    state.last_time = current_time
    if is_hovered then
        anim.alpha = lerp(anim.alpha, 1.0, delta_time * 10 * HOVER_ANIM_SPEED)
    else
        anim.alpha = lerp(anim.alpha, 0.0, delta_time * 10 * HOVER_ANIM_SPEED)
        if anim.alpha < 0.01 then
            anim.alpha = 0
        end
    end
    local draw_list = imgui.GetWindowDrawList()
    local col_text = imgui.GetStyle().Colors[imgui.Col.Text]
    local col_active = imgui.GetStyle().Colors[imgui.Col.ButtonActive]
    local col_hover = imgui.GetStyle().Colors[imgui.Col.ButtonHovered]
    rounding = rounding or 4.0 -- Настройка закругления
    if is_selected then  -- Полоска выделения и фон для выбранного элемента
        local bar_pos = imgui.ImVec2(item_min.x, item_min.y)
        local bar_size = imgui.ImVec2(SELECTION_BAR_WIDTH, item_max.y - item_min.y)
        draw_list:AddRectFilled(bar_pos, imgui.ImVec2(bar_pos.x + bar_size.x, bar_pos.y + bar_size.y), imgui.GetColorU32Vec4(col_active), rounding, imgui.DrawCornerFlags.Left)
        local selected_bg_color = imgui.ImVec4(col_active.x, col_active.y, col_active.z, col_active.w * SELECTED_BG_ALPHA) -- Фон выбранного элемента
        draw_list:AddRectFilled(imgui.ImVec2(item_min.x + SELECTION_BAR_WIDTH, item_min.y), item_max, imgui.GetColorU32Vec4(selected_bg_color), rounding, imgui.DrawCornerFlags.Right)
    end
    if anim.alpha > 0.20 then -- Фон при наведении
        local bg_color = imgui.ImVec4(col_hover.x, col_hover.y, col_hover.z, col_hover.w * anim.alpha * 0.3)
        draw_list:AddRectFilled(imgui.ImVec2(item_min.x + SELECTION_BAR_WIDTH, item_min.y), item_max, imgui.GetColorU32Vec4(bg_color), rounding, imgui.DrawCornerFlags.Right)
    end
    local text_size = imgui.CalcTextSize(text) -- Текст
    local text_pos = imgui.ImVec2(item_min.x + SELECTION_BAR_WIDTH + 5 + (size.x - text_size.x - SELECTION_BAR_WIDTH - 5) * 0.5, item_min.y + (size.y - text_size.y) * 0.5)
    local text_color = imgui.ImVec4(col_text.x, col_text.y, col_text.z, is_selected and col_text.w or col_text.w * 0.9) -- Цвет текста
    draw_list:AddText(text_pos, imgui.GetColorU32Vec4(text_color), text)
    imgui.EndGroup()
    return button_pressed
end

Описание: Кастомный спиннер с приятной анимацией + анимацией точек "Загрузка..." , для mimgui (использую moonmonet)
Пример использования:
Lua:
--во фрейме
imgui.Spinner(u8' Поиск/загрузка', 10, 2, imgui.ColorConvertFloat4ToU32(imgui.GetStyle().Colors[imgui.Col.ButtonHovered]))
imgui.Spinner(u8' Загрузка', 9, 2, imgui.ColorConvertFloat4ToU32(imgui.GetStyle().Colors[imgui.Col.ButtonHovered]))
1748072314033.png


Код:
Lua:
function imgui.Spinner(label, radius, thickness, color, speed)
    speed = speed or 1.0
    local segments = 12
    local trail_length = 0.6
    local style = imgui.GetStyle()
    local pos = imgui.GetCursorScreenPos()
    local size = imgui.ImVec2(radius * 2, (radius + style.FramePadding.y) * 2)
    imgui.BeginGroup()
    local draw_list = imgui.GetWindowDrawList()
    local center = imgui.ImVec2(pos.x + radius, pos.y + radius + style.FramePadding.y)
    local current_time = imgui.GetTime() * speed
    local col_vec4 = type(color) == "number" and imgui.ColorConvertU32ToFloat4(color) or imgui.ImVec4(color.Value.x, color.Value.y, color.Value.z, color.Value.w)
    local text_color = imgui.ImVec4(1.0, 1.0, 1.0, 1.0)  -- Белый цвет
    local spin_angle = current_time * 6.28318 -- Анимация спиннера
    for i = 0, segments - 1 do
        local angle = spin_angle + (i / segments) * 6.28318
        local opacity = 0.3 + 0.7 * (1.0 - ((segments - i) % segments) / segments)
        local point = imgui.ImVec2(center.x + math.cos(angle) * radius, center.y + math.sin(angle) * radius)
        draw_list:AddCircleFilled(point, thickness, imgui.GetColorU32Vec4(imgui.ImVec4(col_vec4.x, col_vec4.y, col_vec4.z, col_vec4.w * opacity)), 8)
    end
    local dot_animation = math.floor(current_time * 2) % 4 -- Анимация текста "Загрузка..."
    local loading_text = label .. string.rep(".", dot_animation)
    imgui.SameLine()
    local text_height = imgui.GetTextLineHeight()
    local text_pos = imgui.ImVec2(pos.x + radius * 2 + style.ItemSpacing.x, pos.y + (radius * 2 - text_height) / 2)
    draw_list:AddText(text_pos, imgui.GetColorU32Vec4(text_color), loading_text) --text
    imgui.EndGroup()
    local text_width = imgui.CalcTextSize(label .. "...").x
    return imgui.ImVec2(radius * 2 + style.ItemSpacing.x + text_width, radius * 2)
end
 
Последнее редактирование:

вайега52

Eblang головного мозга
Модератор
2,892
2,872
Описание: Рендер чата как отдельной текстуры в ImGUI (не обязательно ImGUI, т.к. получается IDirect3DTexture9, который можно рендерить, как тебе нужно)
Пример использования:
Lua:
local imgui = require("mimgui")
imgui.OnFrame(
  function() return true end,
  function(player)
    local sizeX, sizeY = getScreenResolution()
    imgui.SetNextWindowPos(imgui.ImVec2(sizeX / 2, sizeY / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(500, 500), imgui.Cond.FirstUseEver)
    imgui.Begin("Main Window", renderWindow)
    local texture = getChatTexture()
    imgui.Image(texture, imgui.ImVec2(sizeX / 2, sizeY / 2))
    imgui.End()
  end
)
Код:
Lua:
local ffi = require("ffi")

function getChatTexture()
    -- Вроде как для всех версий сампа один оффсет
    return ffi.cast("void**", sampGetChatInfoPtr() + 0x63BA)[0]
end
1749850143673.png