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

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Друг
8,768
11,210
Описание: функция для создания кнопки с индивидуальными настройками (mimgui)
Доступные настройки: (если что-то из списка не будет введено, то будет использоваться значение из стиля окна)
  • rounding - закругление
  • color - цвет
  • color_hovered - цвет при наведении
  • color_active - цвет при клике
  • color_text - цвет текста

Код:
Lua:
function imgui.ButtonWithSettings(text, settings, size)
    imgui.PushStyleVarFloat(imgui.StyleVar.FrameRounding, settings.rounding or imgui.GetStyle().FrameRounding)
    imgui.PushStyleColor(imgui.Col.Button, settings.color or imgui.GetStyle().Colors[imgui.Col.Button])
    imgui.PushStyleColor(imgui.Col.ButtonHovered, settings.color_hovered or imgui.GetStyle().Colors[imgui.Col.ButtonHovered])
    imgui.PushStyleColor(imgui.Col.ButtonActive, settings.color_active or imgui.GetStyle().Colors[imgui.Col.ButtonActive])
    imgui.PushStyleColor(imgui.Col.Text, settings.color_text or imgui.GetStyle().Colors[imgui.Col.Text])
    local click = imgui.Button(text, size)
    imgui.PopStyleColor(4)
    imgui.PopStyleVar()
    return click
end
Пример использования:
Lua:
imgui.ButtonWithSettings(u8'Настраиваемая кнопка 1', {rounding = 10, color = imgui.ImVec4(1, 1, 1, 1), color_text = imgui.ImVec4(1, 0, 0, 1)})
imgui.ButtonWithSettings(u8'Настраиваемая кнопка 2', {rounding = 5, color = imgui.ImVec4(1, 0.3, 0.3, 1), color_text = imgui.ImVec4(0, 0, 0, 1)}, imgui.ImVec2(200, 20))
imgui.ButtonWithSettings(u8'Настр. кнопка 3 (только закругление)', {rounding = 10}, imgui.ImVec2(230, 30))
imgui.Button(u8'Обычная кнопка')
1644702275445.png
 
Последнее редактирование:

Rice.

https://t.me/riceoff
Модератор
1,680
1,388
Описание: Получение ID текстдрава по его тексту
Lua:
function getIdTextDraw(text)
    for i = 0, 4096 do
        if sampTextdrawIsExists(i) then
            local td_text = sampTextdrawGetString(i)
            if tostring(td_text) == tostring(text) then
                return i
            end
        end
    end
    return -1
end
Lua:
function getIdTextDraw(text)
    for i = 0, 4096 do
        if sampTextdrawIsExists(i) then
            local td_text = sampTextdrawGetString(i)
            if tostring(string.lower(td_text)) == tostring(string.lower(text)) then
                return i
            end
        end
    end
    return -1
end
Пример использования:
Lua:
local id = getIdTextDraw('Text')
 
Последнее редактирование:

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Друг
8,768
11,210
Описание: возвращает версию сампа
Код:
Lua:
function getSampVersion()
    return getGameGlobal(707) <= 21 and 'r1' or 'r3'
end
Пример использования:
Lua:
function main()
    while not isSampAvailable() do wait(0) end
    sampfuncsRegisterConsoleCommand('sampver', function()
        sampfuncsLog('SAMP '..getSampVersion())
    end)
    wait(-1)
end

function getSampVersion()
    return getGameGlobal(707) <= 21 and 'r1' or 'r3'
end
1645355607932.png

источник
 

SomaGnoma

Известный
442
152
Подборка супер крутых функций для mimgui, т.к. форум не дает выложить отдельным сообщением...
Описание: Кастомный ToggleButton для mimgui.
Код:
Lua:
--[[
label      - Текст при значении переменной false (Опционально)
label_true - Текст при значении переменной true (Опционально)
bool       - Переменная, которую будет менять кнопка (Требуется)
a_speed    - Скорость анимации (Опционально)
--]]
function imgui.ToggleButton(label, label_true, bool, a_speed)
    local p  = imgui.GetCursorScreenPos()
    local dl = imgui.GetWindowDrawList()
 
    local bebrochka = false

    local label      = label or ""                          -- Текст false
    local label_true = label_true or ""                     -- Текст true
    local h          = imgui.GetTextLineHeightWithSpacing() -- Высота кнопки
    local w          = h * 1.7                              -- Ширина кнопки
    local r          = h / 2                                -- Радиус кружка
    local s          = a_speed or 0.2                       -- Скорость анимации
 
    local function ImSaturate(f)
        return f < 0.0 and 0.0 or (f > 1.0 and 1.0 or f)
    end
 
    local x_begin = bool[0] and 1.0 or 0.0
    local t_begin = bool[0] and 0.0 or 1.0
 
    if LastTime == nil then
        LastTime = {}
    end
    if LastActive == nil then
        LastActive = {}
    end
 
    if imgui.InvisibleButton(label, imgui.ImVec2(w, h)) then
        bool[0] = not bool[0]
        LastTime[label] = os.clock()
        LastActive[label] = true
        bebrochka = true
    end

    if LastActive[label] then
        local time = os.clock() - LastTime[label]
        if time <= s then
            local anim = ImSaturate(time / s)
            x_begin = bool[0] and anim or 1.0 - anim
            t_begin = bool[0] and 1.0 - anim or anim
        else
            LastActive[label] = false
        end
    end
 
    local bg_color = imgui.ImVec4(x_begin * 0.13, x_begin * 0.9, x_begin * 0.13, imgui.IsItemHovered(0) and 0.7 or 0.9) -- Цвет прямоугольника
    local t_color  = imgui.ImVec4(1, 1, 1, x_begin) -- Цвет текста при false
    local t2_color = imgui.ImVec4(1, 1, 1, t_begin) -- Цвет текста при true
 
    dl:AddRectFilled(imgui.ImVec2(p.x, p.y), imgui.ImVec2(p.x + w, p.y + h), imgui.GetColorU32Vec4(bg_color), r)
    dl:AddCircleFilled(imgui.ImVec2(p.x + r + x_begin * (w - r * 2), p.y + r), t_begin < 0.5 and x_begin * r or t_begin * r, imgui.GetColorU32Vec4(imgui.ImVec4(0.9, 0.9, 0.9, 1.0)), r + 5)
    dl:AddText(imgui.ImVec2(p.x + w + r, p.y + r - (r / 2) - (imgui.CalcTextSize(label).y / 4)), imgui.GetColorU32Vec4(t_color), label_true)
    dl:AddText(imgui.ImVec2(p.x + w + r, p.y + r - (r / 2) - (imgui.CalcTextSize(label).y / 4)), imgui.GetColorU32Vec4(t2_color), label)
    return bebrochka
end
Пример использования:
Lua:
local variable = new.bool(false)

-- Во фрейме
if imgui.ToggleButton(u8"Включить чит", u8"Выключить чит", variable) then
    sampAddChatMessage("Ты нажал на кнопку")
end
Че вышло:

ezgif.com-gif-maker (3).gif
Описание:
Круглый CheckBox, зачеркивающийся в зависимости от переменной.
Может быть использован для составления списка дел и т.д.
Код:
кот:
--[[
label - Название чекбокса | ОпциАНАЛьно
bool - Переменная, которую меняет чекbox | Требуется
a_speed - Скорость анимации | Опционально
]]

function imgui.TodoCheck(label, bool, a_speed)

    local p  = imgui.GetCursorScreenPos()
    local dl = imgui.GetWindowDrawList()

    local clicked = false

    local label      = label or ""                               -- Название
    local outline    = 2.0                                       -- Толщина обводки
    local r          = imgui.GetTextLineHeightWithSpacing() / 2  -- Радиус кружочка
    local s          = a_speed or 0.2                            -- Скорость анимации

    local function ImSaturate(f)
        return f < 0.0 and 0.0 or (f > 1.0 and 1.0 or f)
    end
  
    if imgui.InvisibleButton(label, imgui.ImVec2(r * 2, r * 2)) then
        bool[0] = not bool[0]
        LastTime[label] = os.clock()
        LastActive[label] = true
        clicked = true
    end

    local w = bool[0] and 1.0 or 0.0
    local bebra = 0.0
  
    if LastTime == nil then
        LastTime = {}
    end
    if LastActive == nil then
        LastActive = {}
    end
  
    if LastActive[label] then
        local time = os.clock() - LastTime[label]
        if time <= s then
            local anim = ImSaturate(time / s)
            w = bool[0] and anim or 1.0 - anim
            bebra = anim
        else
            LastActive[label] = false
        end
    end

    local c_color = bool[0] and imgui.ImVec4(1, 1, 1, 1) or (imgui.IsItemHovered(0) and imgui.ImVec4(1, 1, 1, 0.6) or imgui.ImVec4(1, 1, 1, 0.4))  -- Цвет обводки кружочка
    local cin_color = imgui.ImVec4(0.13, 0.83, 0.13, w)   -- Цвет кружочка
    local cline_color = imgui.ImVec4(1.00, 1.00, 1.00, w) -- Цвет галки
    local cbebra_color = imgui.ImVec4(1.00, 1.00, 1.00, (1 - bebra) * 0.2)

    dl:AddCircleFilled(imgui.ImVec2(p.x + r, p.y + r), r * bebra * 2, imgui.GetColorU32Vec4(cbebra_color), r + 5, outline)
    dl:AddCircleFilled(imgui.ImVec2(p.x + r, p.y + r), r * w, imgui.GetColorU32Vec4(cin_color), r + 5)
    dl:AddCircle(imgui.ImVec2(p.x + r, p.y + r), r, imgui.GetColorU32Vec4(c_color), r + 5, outline)
    dl:AddLine(imgui.ImVec2(p.x + r, p.y + w * (r + r / 2)), imgui.ImVec2(p.x, p.y + w * (r / 2)), imgui.GetColorU32Vec4(cline_color), outline)
    dl:AddLine(imgui.ImVec2(p.x + r, p.y + w * (r + r / 2)), imgui.ImVec2(p.x + w * (r + r / 2), p.y + w * (r / 2)), imgui.GetColorU32Vec4(cline_color), outline)
    dl:AddText(imgui.ImVec2(p.x + r * 2.7, p.y + r - (r / 2) - (imgui.CalcTextSize(label).y / 4)), imgui.GetColorU32Vec4(imgui.ImVec4(1 , 1, 1, 1)), label)
    dl:AddLine(imgui.ImVec2(p.x + r * 2.7, p.y + r - (r / 2) + (imgui.CalcTextSize(label).y / 4)), imgui.ImVec2(p.x + w * (imgui.CalcTextSize(label).x) + r * 2.7, p.y + r - (r / 2) + (imgui.CalcTextSize(label).y / 4)), imgui.GetColorU32Vec4(cline_color), outline)
    return clicked
end

Как юзать:
пример:
local var = new.bool(false)

-- Во фрейме

if imgui.TodoCheck(u8"Я выполнил что-то там", var) then
    sampAddChatMessage("Вау, ты нажал на чекбокс")
end

Че вышло:

ezgif.com-gif-maker (4).gif
 
Последнее редактирование:

Shishkin

Известный
488
249
Описание: анимационное солнце
Код:
Lua:
function animationsun(x, y, color, radius, speed)
    function animFloatTo(from, to, start_time, duration)
        local timer = os.clock() - start_time
        if timer >= 0.00 and timer <= duration then
            local count = timer / (duration / 100)
            return from + (count * (to - from) / 100)
        end
        return (timer > duration) and to or from
    end
    if clocksun == nil then clocksun = os.clock() end
    sun = animFloatTo(0, 25, clocksun, speed)
    if sun == 25 then clocksun = nil end
    imgui.GetWindowDrawList():AddCircleFilled(imgui.ImVec2(p.x, p.y), radius, color, 40)
    --[[imgui.GetWindowDrawList():AddLine(imgui.ImVec2( -- 3d, я ахуел
        p.x + math.cos(sun) * radius,
        p.y + math.sin(sun) * radius),
        imgui.ImVec2(
        p.x + math.cos(sun) * radius + 30,
        p.y + math.sin(sun) * radius + 30),
    color)]]
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun) * radius, y + math.sin(sun) * radius), imgui.ImVec2(x + math.cos(sun) * (radius + radius + radius / 2), y + math.sin(sun) * (radius + radius + radius / 2)), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 0.7) * radius, y + math.sin(sun + 0.7) * radius), imgui.ImVec2(x + math.cos(sun + 0.7) * (radius + radius + radius / 2), y + math.sin(sun + 0.7) * (radius + radius + radius / 2)), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 1.4) * radius, y + math.sin(sun + 1.4) * radius), imgui.ImVec2(x + math.cos(sun + 1.4) * (radius + radius + radius / 2), y + math.sin(sun + 1.4) * (radius + radius + radius / 2)), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 2.1) * radius, y + math.sin(sun + 2.1) * radius), imgui.ImVec2(x + math.cos(sun + 2.1) * (radius + radius + radius / 2), y + math.sin(sun + 2.1) * (radius + radius + radius / 2)), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 2.8) * radius, y + math.sin(sun + 2.8) * radius), imgui.ImVec2(x + math.cos(sun + 2.8) * (radius + radius + radius / 2), y + math.sin(sun + 2.8) * (radius + radius + radius / 2)), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 3.5) * radius, y + math.sin(sun + 3.5) * radius), imgui.ImVec2(x + math.cos(sun + 3.5) * (radius + radius + radius / 2), y + math.sin(sun + 3.5) * (radius + radius + radius / 2)), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 4.2) * radius, y + math.sin(sun + 4.2) * radius), imgui.ImVec2(x + math.cos(sun + 4.2) * (radius + radius + radius / 2), y + math.sin(sun + 4.2) * (radius + radius + radius / 2)), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 4.9) * radius, y + math.sin(sun + 4.9) * radius), imgui.ImVec2(x + math.cos(sun + 4.9) * (radius + radius + radius / 2), y + math.sin(sun + 4.9) * (radius + radius + radius / 2)), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 5.6) * radius, y + math.sin(sun + 5.6) * radius), imgui.ImVec2(x + math.cos(sun + 5.6) * (radius + radius + radius / 2), y + math.sin(sun + 5.6) * (radius + radius + radius / 2)), color)
end
Пример использования:
Lua:
function imgui.OnDrawFrame()
    imgui.Begin('animationsun', show_main_window, imgui.WindowFlags.NoCollapse)
    imgui.SetCursorPos(imgui.ImVec2(800, 400))
    p = imgui.GetCursorScreenPos()
    animationsun(p.x, p.y, 0xff00feff, 20, 10) -- p.x, p.y - координаты, 0xff00feff - цвет, 20 - размер, 10 - скорость.
    imgui.End()
end
Гифка:
GTA_SA_MP 2022-03-07 23-20-29.gif
 
Последнее редактирование:

Shishkin

Известный
488
249
Описание: анимационная снежинка
Код:
Lua:
function animationsnowflake(x, y, color, radius, speed)
    function animFloatTo(from, to, start_time, duration)
        local timer = os.clock() - start_time
        if timer >= 0.00 and timer <= duration then
        local count = timer / (duration / 100)
        return from + (count * (to - from) / 100)
        end
        return (timer > duration) and to or from
    end
    if clocksnowflake == nil then clocksnowflake = os.clock() end
    sun = animFloatTo(0, 25, clocksnowflake, speed)
    if sun == 25 then clocksnowflake = nil end
    imgui.GetWindowDrawList():AddCircle(imgui.ImVec2(x, y), radius, color, 40)
    -- ПЕРВАЯ ЧАСТЬ
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun) * radius, y + math.sin(sun) * radius), imgui.ImVec2(x + math.cos(sun) * radius * 5, y + math.sin(sun) * radius * 5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun) * radius * 3.5, y + math.sin(sun) * radius * 3.5), imgui.ImVec2(x + math.cos(sun + -1150) * radius * 5, y + math.sin(sun + -1150) * radius * 5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun) * radius * 3.5, y + math.sin(sun) * radius * 3.5), imgui.ImVec2(x + math.cos(sun + 1150) * radius * 5, y + math.sin(sun + 1150) * radius * 5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun) * radius * 3, y + math.sin(sun) * radius * 3), imgui.ImVec2(x + math.cos(sun + -1150) * radius * 4, y + math.sin(sun + -1150) * radius * 4), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun) * radius * 3, y + math.sin(sun) * radius * 3), imgui.ImVec2(x + math.cos(sun + 1150) * radius * 4, y + math.sin(sun + 1150) * radius * 4), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun) * radius * 2, y + math.sin(sun) * radius * 2), imgui.ImVec2(x + math.cos(sun + -1150.442) * radius * 3.5,y + math.sin(sun + -1150.442) * radius * 3.5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun) * radius * 1.5, y + math.sin(sun) * radius * 1.5), imgui.ImVec2(x + math.cos(sun + -1150.442) * radius * 2.5, y + math.sin(sun + -1150.442) * radius * 2.5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun) * radius * 2, y + math.sin(sun) * radius * 2), imgui.ImVec2(x + math.cos(sun + 1150.442) * radius * 3.5, y + math.sin(sun + 1150.442) * radius * 3.5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun) * radius * 1.5, y + math.sin(sun) * radius * 1.5), imgui.ImVec2(x + math.cos(sun + 1150.442) * radius * 2.5,y + math.sin(sun + 1150.442) * radius * 2.5), color)
    -- ВТОРАЯ ЧАСТЬ
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 1.25) * radius, y + math.sin(sun + 1.25) * radius),imgui.ImVec2(x + math.cos(sun + 1.25) * radius * 5, y + math.sin(sun + 1.25) * radius * 5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 1.25) * radius * 3.5, y + math.sin(sun + 1.25) * radius * 3.5), imgui.ImVec2(x + math.cos(sun + 1.25 + -1150) * radius * 5, y + math.sin(sun + 1.25 + -1150) * radius * 5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 1.25) * radius * 3.5, y + math.sin(sun + 1.25) * radius * 3.5), imgui.ImVec2(x + math.cos(sun + 1.25 + 1150) * radius * 5, y + math.sin(sun + 1.25 + 1150) * radius * 5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 1.25) * radius * 3, y + math.sin(sun + 1.25) * radius * 3), imgui.ImVec2(x + math.cos(sun + 1.25 + -1150) * radius * 4, y + math.sin(sun + 1.25 + -1150) * radius * 4), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 1.25) * radius * 3, y + math.sin(sun + 1.25) * radius * 3), imgui.ImVec2(x + math.cos(sun + 1.25 + 1150) * radius * 4, y + math.sin(sun + 1.25 + 1150) * radius * 4), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 1.25) * radius * 2, y + math.sin(sun + 1.25) * radius * 2), imgui.ImVec2(x + math.cos(sun + 1.25 + 1150.442) * radius * 3.5, y + math.sin(sun + 1.25 + 1150.442) * radius * 3.5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 1.25) * radius * 1.5, y + math.sin(sun + 1.25) * radius * 1.5),imgui.ImVec2(x + math.cos(sun + 1.25 + 1150.442) * radius * 2.5, y + math.sin(sun + 1.25 + 1150.442) * radius * 2.5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 1.25) * radius * 2, y + math.sin(sun + 1.25) * radius * 2), imgui.ImVec2(x + math.cos(sun + 1.25 + -1150.442) * radius * 3.5, y + math.sin(sun + 1.25 + -1150.442) * radius * 3.5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 1.25) * radius * 1.5, y + math.sin(sun + 1.25) * radius * 1.5), imgui.ImVec2(x + math.cos(sun + 1.25 + -1150.442) * radius * 2.5, y + math.sin(sun + 1.25 + -1150.442) * radius * 2.5), color)
    -- ТРЕТЬЯ ЧАСТЬ
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 2.5) * radius, y + math.sin(sun + 2.5) * radius), imgui.ImVec2(x + math.cos(sun + 2.5) * radius * 5, y + math.sin(sun + 2.5) * radius * 5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 2.5) * radius * 3.5, y + math.sin(sun + 2.5) * radius * 3.5), imgui.ImVec2(x + math.cos(sun + 2.5 + -1150) * radius * 5, y + math.sin(sun + 2.5 + -1150) * radius * 5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 2.5) * radius * 3.5, y + math.sin(sun + 2.5) * radius * 3.5), imgui.ImVec2(x + math.cos(sun + 2.5 + 1150) * radius * 5, y + math.sin(sun + 2.5 + 1150) * radius * 5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 2.5) * radius * 3, y + math.sin(sun + 2.5) * radius * 3), imgui.ImVec2(x + math.cos(sun + 2.5 + -1150) * radius * 4, y + math.sin(sun + 2.5 + -1150) * radius * 4), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 2.5) * radius * 3, y + math.sin(sun + 2.5) * radius * 3), imgui.ImVec2(x + math.cos(sun + 2.5 + 1150) * radius * 4, y + math.sin(sun + 2.5 + 1150) * radius * 4), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 2.5) * radius * 2, y + math.sin(sun + 2.5) * radius * 2), imgui.ImVec2(x + math.cos(sun + 2.5 + 1150.442) * radius * 3.5, y + math.sin(sun + 2.5 + 1150.442) * radius * 3.5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 2.5) * radius * 1.5, y + math.sin(sun + 2.5) * radius * 1.5),imgui.ImVec2(x + math.cos(sun + 2.5 + 1150.442) * radius * 2.5, y + math.sin(sun + 2.5 + 1150.442) * radius * 2.5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 2.5) * radius * 2, y + math.sin(sun + 2.5) * radius * 2), imgui.ImVec2(x + math.cos(sun + 2.5 + -1150.442) * radius * 3.5, y + math.sin(sun + 2.5 + -1150.442) * radius * 3.5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 2.5) * radius * 1.5, y + math.sin(sun + 2.5) * radius * 1.5), imgui.ImVec2(x + math.cos(sun + 2.5 + -1150.442) * radius * 2.5, y + math.sin(sun + 2.5 + -1150.442) * radius * 2.5), color)
    -- ЧЕТВЕРТАЯ часть
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 3.75) * radius, y + math.sin(sun + 3.75) * radius),imgui.ImVec2(x + math.cos(sun + 3.75) * radius * 5, y + math.sin(sun + 3.75) * radius * 5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 3.75) * radius * 3.5, y + math.sin(sun + 3.75) * radius * 3.5), imgui.ImVec2(x + math.cos(sun + 3.75 + -1150) * radius * 5, y + math.sin(sun + 3.75 + -1150) * radius * 5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 3.75) * radius * 3.5, y + math.sin(sun + 3.75) * radius * 3.5), imgui.ImVec2(x + math.cos(sun + 3.75 + 1150) * radius * 5, y + math.sin(sun + 3.75 + 1150) * radius * 5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 3.75) * radius * 3, y + math.sin(sun + 3.75) * radius * 3), imgui.ImVec2(x + math.cos(sun + 3.75 + -1150) * radius * 4, y + math.sin(sun + 3.75 + -1150) * radius * 4), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 3.75) * radius * 3, y + math.sin(sun + 3.75) * radius * 3), imgui.ImVec2(x + math.cos(sun + 3.75 + 1150) * radius * 4, y + math.sin(sun + 3.75 + 1150) * radius * 4), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 3.75) * radius * 2, y + math.sin(sun + 3.75) * radius * 2), imgui.ImVec2(x + math.cos(sun + 3.75 + 1150.442) * radius * 3.5, y + math.sin(sun + 3.75 + 1150.442) * radius * 3.5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 3.75) * radius * 1.5, y + math.sin(sun + 3.75) * radius * 1.5),imgui.ImVec2(x + math.cos(sun + 3.75 + 1150.442) * radius * 2.5, y + math.sin(sun + 3.75 + 1150.442) * radius * 2.5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 3.75) * radius * 2, y + math.sin(sun + 3.75) * radius * 2), imgui.ImVec2(x + math.cos(sun + 3.75 + -1150.442) * radius * 3.5, y + math.sin(sun + 3.75 + -1150.442) * radius * 3.5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 3.75) * radius * 1.5, y + math.sin(sun + 3.75) * radius * 1.5), imgui.ImVec2(x + math.cos(sun + 3.75 + -1150.442) * radius * 2.5, y + math.sin(sun + 3.75 + -1150.442) * radius * 2.5), color)
    -- ПЯТАЯ ЧАСТЬ
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 5) * radius, y + math.sin(sun + 5) * radius),imgui.ImVec2(x + math.cos(sun + 5) * radius * 5,y + math.sin(sun + 5) * radius * 5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 5) * radius * 3.5, y + math.sin(sun + 5) * radius * 3.5), imgui.ImVec2(x + math.cos(sun + 5 + -1150) * radius * 5,y + math.sin(sun + 5 + -1150) * radius * 5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 5) * radius * 3.5, y + math.sin(sun + 5) * radius * 3.5), imgui.ImVec2(x + math.cos(sun + 5 + 1150) * radius * 5, y + math.sin(sun + 5 + 1150) * radius * 5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 5) * radius * 3, y + math.sin(sun + 5) * radius * 3), imgui.ImVec2(x + math.cos(sun + 5 + -1150) * radius * 4, y + math.sin(sun + 5 + -1150) * radius * 4), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 5) * radius * 3, y + math.sin(sun + 5) * radius * 3), imgui.ImVec2(x + math.cos(sun + 5 + 1150) * radius * 4, y + math.sin(sun + 5 + 1150) * radius * 4), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 5) * radius * 2, y + math.sin(sun + 5) * radius * 2), imgui.ImVec2(x + math.cos(sun + 5 + 1150.465) * radius * 3.5, y + math.sin(sun + 5 + 1150.465) * radius * 3.5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 5) * radius * 1.5, y + math.sin(sun + 5) * radius * 1.5),imgui.ImVec2(x + math.cos(sun + 5 + 1150.465) * radius * 2.5, y + math.sin(sun + 5 + 1150.465) * radius * 2.5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 5) * radius * 2, y + math.sin(sun + 5) * radius * 2), imgui.ImVec2(x + math.cos(sun + 5 + -1150.465) * radius * 3.5,y + math.sin(sun + 5 + -1150.465) * radius * 3.5), color)
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(x + math.cos(sun + 5) * radius * 1.5, y + math.sin(sun + 5) * radius * 1.5), imgui.ImVec2(x + math.cos(sun + 5 + -1150.465) * radius * 2.5,y + math.sin(sun + 5 + -1150.465) * radius * 2.5), color)
end
Пример использования:
Lua:
function imgui.OnDrawFrame()
    imgui.Begin('animationsnowflake', show_main_window, imgui.WindowFlags.NoCollapse)
    imgui.SetCursorPos(imgui.ImVec2(800, 400))
    p = imgui.GetCursorScreenPos()
    animationsnowflake(p.x, p.y, 0xff00feff, 10, 10) -- p.x, p.y - координаты, 0xff00feff - цвет, 10 - размер, 10 - скорость.
    imgui.End()
end
Гифка:
GTA_SA_MP 2022-03-07 23-20-29 (1) (1).gif
 
  • Грустно
  • Вау
Реакции: AdCKuY_DpO4uLa и The Spark

Cosmo

Известный
Друг
646
2,597
Описание: анимационная залупа
Код:
Lua:
function anim_hui(centre, scale, color, speed)
    local DL = imgui.GetWindowDrawList() 
    local top = imgui.ImVec2(centre.x, centre.y - (scale * 40))
    local bot = imgui.ImVec2(centre.x, centre.y + (scale * 40))
    local rEgg = imgui.ImVec2(bot.x - (scale * 20), bot.y + scale * 5)
    local lEgg = imgui.ImVec2(bot.x + (scale * 20), bot.y + scale * 5)
    local angle = math.rad((imgui.GetTime() * (speed or 1) % 1) * 360)
    local polygons = 36 * scale 

    local rotate = function(v, cos, sin) return imgui.ImVec2(v.x * cos - v.y * sin, v.x * sin + v.y * cos) end
    local calc = function(l, r) return { x = l.x - r.x, y = l.y - r.y } end
    local buf_size = DL.VtxBuffer.Size

    DL:PathClear()
    DL:PathArcTo(top, scale * 15, math.rad(180), math.rad(360), polygons / 2)
    DL:PathArcTo(bot, scale * 15, math.rad(0), math.rad(180), polygons / 2)
    DL:PathFillConvex(color)
    DL:AddCircleFilled(rEgg, scale * 20, color, polygons)
    DL:AddCircleFilled(lEgg, scale * 20, color, polygons)

    local aS, aC = math.sin(angle), math.cos(angle)
    centre = calc(rotate(centre, aS, aC), centre)
    for i = buf_size, DL.VtxBuffer.Size - 1 do
        DL.VtxBuffer.Data[i].pos = calc(rotate(DL.VtxBuffer.Data[i].pos, aS, aC), centre)
    end
end
Пример использования:
Lua:
local p = imgui.GetCursorScreenPos()
anim_hui(imgui.ImVec2(p.x + 100, p.y + 100), 1.0, 0xFFFFFFFF, 1.0)
Гифка:
rotated_zalupa.gif
 

Cosmo

Известный
Друг
646
2,597
Описание:
Функция, получающая текстуру текстдрава, например для использования в Imgui.

Важное замечание: Возвращается текстура только существующего в данный момент текстдрава (то-есть если он есть на экране)! Как не пытался, не смог сохранить текстуру в память и продолжать рендерить её посредством имгуи после того как текстрдав пропал.. Если у кого-то есть идеи, можете ими поделиться..

Lua:
local ffi = require "ffi"

ffi.cdef [[
    struct CTextDrawData {
        float          m_fLetterWidth;
        float          m_fLetterHeight;
        unsigned long  m_letterColor;
        unsigned char  unknown;
        unsigned char  m_bCenter;
        unsigned char  m_bBox;
        float          m_fBoxSizeX;
        float          m_fBoxSizeY;
        unsigned long  m_boxColor;
        unsigned char  m_nProportional;
        unsigned long  m_backgroundColor;
        unsigned char  m_nShadow;
        unsigned char  m_nOutline;
        unsigned char  m_bLeft;
        unsigned char  m_bRight;
        int            m_nStyle;
        float          m_fX;
        float          m_fY;
        unsigned char  pad_[8];
        unsigned long  field_99B;
        unsigned long  field_99F;
        unsigned long  m_nIndex;
        unsigned char  field_9A7;
        unsigned short m_nModel;
        float          m_rotation[3];
        float          m_fZoom;
        unsigned short m_aColor[2];
        unsigned char  field_9BE;
        unsigned char  field_9BF;
        unsigned char  field_9C0;
        unsigned long  field_9C1;
        unsigned long  field_9C5;
        unsigned long  field_9C9;
        unsigned long  field_9CD;
        unsigned char  field_9D1;
        unsigned long  field_9D2;
    }__attribute__ ((packed));

    struct CTextDraw {
        char m_szText[801];
        char m_szString[1602];
        struct CTextDrawData m_data;
    }__attribute__ ((packed));

    struct CTextDrawPool {
        int       m_bNotEmpty[2048 + 256];
        struct CTextDraw* m_pObject[2048 + 256];
    }__attribute__ ((packed));

    typedef unsigned char RwUInt8;
    typedef int RwInt32;
    typedef short RwInt16;

    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;
    };

    struct RwTexture {
        struct RwRaster* raster;
    };
]]

function getTextDrawTexture(textdraw_id)
    if not sampTextdrawIsExists(textdraw_id) then return false end
    local offset = { ["R1"] = 0x216058, ["R3"] = 0x26B2B8 }
    local vSAMP = getGameGlobal(707) <= 21 and "R1" or "R3"
    local textdraw_pool = ffi.cast("struct CTextDrawPool*", sampGetTextdrawPoolPtr())
    local textures_pool = ffi.cast("struct RwTexture**", sampGetBase() + offset[vSAMP])

    local pObject = textdraw_pool.m_pObject[textdraw_id]
    if pObject ~= ffi.NULL then
        local index = pObject.m_data.m_nIndex
        if index ~= 0xFFFFFFFF then
            local raster = textures_pool[index].raster
            return true, raster.texture_ptr
        end
    end
    return false
end
-- При помощи @kin4stat

Пример использования:
Lua:
imgui.OnFrame(
    function() return true end,
    function(self)
        local result, texture = getTextDrawTexture(1234)
        if result then
            imgui.Image(texture, imgui.ImVec2(250, 250))
        end
    end
)

Пример простой реализации:
Селектор скинов с предосмотром. Файл ниже.

1647131335252.png
 

Вложения

  • SkinSelector.lua
    6.4 KB · Просмотры: 47

kin4stat

mq-team
Всефорумный модератор
2,730
4,710
Как не пытался, не смог сохранить текстуру в память и продолжать рендерить её посредством имгуи после того как текстрдав пропал.. Если у кого-то есть идеи, можете ими поделиться..
Есть другая идея. Только я заебался адреса под R1 искать(kye пидор)

Описание:
Функция рендерит модель в текстуру, и возвращает ее вам.

Lua:
local ffi = require "ffi"

local MODEL_INFO_ATOMIC = 1
local MODEL_INFO_TIME = 3
local MODEL_INFO_WEAPON = 4
local MODEL_INFO_CLUMP = 5
local MODEL_INFO_VEHICLE = 6
local MODEL_INFO_PED = 7
local MODEL_INFO_LOD = 8

ffi.cdef [[
    typedef unsigned char RwUInt8;
    typedef int RwInt32;
    typedef short RwInt16;

    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;
    };

    struct RwTexture {
        struct RwRaster* raster;
    };

    struct CBaseModelInfo_vtbl {
        void* destructor;
        void* AsAtomicModelInfoPtr;
        void* AsDamageAtomicModelInfoPtr;
        void* AsLodAtomicModelInfoPtr;
        char(__thiscall* GetModelType)(struct CBaseModelInfo*);
    };

    struct CBaseModelInfo {
        struct CBaseModelInfo_vtbl* vtbl;
    };

    typedef struct RwTexture*(__thiscall* vehicle_render_t)(unsigned long, int, int, float*, float, int, int);
    typedef struct RwTexture*(__thiscall* ped_render_t)(unsigned long, int, int, float*, float);
    typedef struct RwTexture*(__thiscall* others_render_t)(unsigned long, int, int, float*, float);
]]

local RwTextureDestroy = ffi.cast("int(__cdecl*)(struct RwTexture*)", 0x7F3820)
local GetModelInfo = ffi.cast("struct CBaseModelInfo*(__cdecl*)(int)", 0x403DA0)

local textures_from_render = {}

function render_ond3d_lost()
    for i = 1, #textures_from_render do
        RwTextureDestroy(textures_from_render[i])
    end
end

function render_model(model_id, params)
    if 0 > model_id or model_id >= 20000 then return nil end

    local backcolor = params["background_color"]
    local zoom = params["zoom"]
    local rot = params["rotation"]
    local rotation = ffi.new("float [3]")
    rotation[0] = rot.x
    rotation[1] = rot.y
    rotation[2] = rot.z

    local offsets = {
        ["vehicle"]   = { ["R1"] = 0x2EE4E5, ["R3"] = 0x6BC50 },
        ["ped"]       = { ["R1"] = 0x2F522D, ["R3"] = 0x6B9D0 },
        ["others"]    = { ["R1"] = 0x2BE702, ["R3"] = 0x6C240 },
        ["sampst"]    = { ["R1"] = 0x21A108, ["R3"] = 0x26E8F0 }
    }
    local vSAMP = getGameGlobal(707) <= 21 and "R1" or "R3"

    local model_info = GetModelInfo(model_id);
    if model_info ~= ffi.NULL then
        local model_type = model_info.vtbl.GetModelType(model_info);
        local sampst = ffi.cast("unsigned long*", sampGetBase() + offsets["sampst"][vSAMP])[0]

        local result = ffi.NULL
        if model_type == MODEL_INFO_VEHICLE then
            local func_addr = sampGetBase() + offsets["vehicle"][vSAMP]
            result = ffi.cast("vehicle_render_t", func_addr)(sampst, model_id, backcolor,  rotation, zoom, params["carc_1"], params["carc_2"])
        elseif model_type == MODEL_INFO_PED then
            local func_addr = sampGetBase() + offsets["ped"][vSAMP]
            result = ffi.cast("ped_render_t", func_addr)(sampst, model_id, backcolor,  rotation, zoom)
        elseif model_type == MODEL_INFO_WEAPON or model_type == MODEL_INFO_ATOMIC or model_type == MODEL_INFO_CLUMP then
            local func_addr = sampGetBase() + offsets["others"][vSAMP]
            result = ffi.cast("others_render_t", func_addr)(sampst, model_id, backcolor,  rotation, zoom)
        else
            return nil
        end
        if result ~= ffi.NULL and result.raster ~= ffi.NULL and result.raster.texture_ptr ~= ffi.NULL then
            textures_from_render[#textures_from_render + 1] = result
            return result.raster.texture_ptr
        end
        return nil
    end
end

Примечание:
Все текстуры рендерятся размером 256x256!
В событии onD3DLost в Lua нужно вызвать функцию render_ond3d_lost, а все текстуры, полученные посредством вызова функции - больше не использовать.

Lua:
-- в глобальной области
local texture = nil

-- где-то в imgui.OnFrame
if imgui.Button("Update texture") then
    texture = render_model([[args...]])
end

-- использование текстуры
if texture ~= nil then
     imgui.Image(texture, imgui.ImVec2(256, 256))
end

-- примечание выше
function onD3DDeviceLost()
    render_ond3d_lost()
    texture = nil
end

Пример использования:
Lua:
texture = nil

imgui.OnFrame(
    function() return true end,
    function(self)
        if imgui.Button("Update") then
            texture = render_model(411, {
                            ["background_color"] = 0x00000000,
                            ["zoom"] = 1,
                            ["rotation"] = { ["x"] = 0, ["y"] = 0, ["z"] = 0 },
                            ["carc_1"] = 0
                            ["carc_2"] = 1 })
        end
        if texture then
            imgui.Image(texture, imgui.ImVec2(256, 256)
        end
    end
)

function onD3DDeviceLost()
    render_ond3d_lost()
    texture = nil
end

Описание параметров функции в таблице:
background_color - цвет заливки за текстурой
zoom - коэффициент приближения объекта к камере
rotation - поворот объекта по осям. 0 для игнорирования оси
carc_1 - основной цвет транспорта
carc_2 - вторичный цвет транспорта

Пример простой реализации нагло спизженный у @Cosmo из поста выше:
 

Вложения

  • test_models.lua
    7.5 KB · Просмотры: 37
Последнее редактирование:

MoonGlance

Новичок
13
9
Описание: Показ цветовых кодов окрашенных в этот же цвет в диалоге
Lua:
        if text:find('%x+') then
            colors = {}
            for i = 1, 500 do
                colors[i] = text:match("{(%x+)}")
                if colors[i] ~= nil then
                    text = text.gsub(text, '{'..colors[i]..'}', '~'..colors[i]..'~')
                end
            end
            for v = 1, 500 do
                if colors[v] ~= nil then
                    text = text.gsub(text, '~'..colors[v]..'~', '{'..colors[v]..'}['..colors[v]..'] ')
                end
            end
        end
ORUZu5a.png
 
  • Bug
Реакции: paulohardy и chapo

imring

Ride the Lightning
Всефорумный модератор
2,355
2,516
Описание: Показ цветовых кодов окрашенных в этот же цвет в диалоге
Lua:
        if text:find('%x+') then
            colors = {}
            for i = 1, 500 do
                colors[i] = text:match("{(%x+)}")
                if colors[i] ~= nil then
                    text = text.gsub(text, '{'..colors[i]..'}', '~'..colors[i]..'~')
                end
            end
            for v = 1, 500 do
                if colors[v] ~= nil then
                    text = text.gsub(text, '~'..colors[v]..'~', '{'..colors[v]..'}['..colors[v]..'] ')
                end
            end
        end
Lua:
local text = '{121212}asd{343434}qwe'
text = text:gsub('{(%x%x%x%x%x%x)}', '{%1}[%1]')
print(text)
1647771729552.png
 
  • Нравится
Реакции: Tema05 и chapo

ruslol

Участник
17
73

Описание:

Кнопка с "ripple" эффектом. (присутствует говно-код)

Lua:
function imgui.RippleButton(text, size, duration, rounding, parent_color)
       
    local function CenterTextFor2Dims(text)
        local width = imgui.GetWindowWidth()
        local calc = imgui.CalcTextSize(text)
        local height = imgui.GetWindowHeight()
        imgui.SetCursorPosX( width / 2 - calc.x / 2 )
        imgui.SetCursorPosY(height / 2 - calc.y / 2)
        imgui.Text(text)
    end

    local function bringVec4To(from, to, start_time, duration)
        local timer = os.clock() - start_time
        if timer >= 0.00 and timer <= duration then
            local count = timer / (duration / 100)
            return imgui.ImVec4(
                from.x + (count * (to.x - from.x) / 100),
                from.y + (count * (to.y - from.y) / 100),
                from.z + (count * (to.z - from.z) / 100),
                from.w + (count * (to.w - from.w) / 100)
            ), true
        end
        return (timer > duration) and to or from, false
    end

    if UI_RIPPLEBUTTON == nil then
        UI_RIPPLEBUTTON = {}
    end
    if not UI_RIPPLEBUTTON[text] then
        UI_RIPPLEBUTTON[text] = {animation = nil, radius = 5, mouse_coor = nil, time = nil, color = nil}
    end
    local pool = UI_RIPPLEBUTTON[text]
    local radius
   
    if rounding == nil then
        rounding = 0
    end
    if parent_color == nil then
        parent_color = imgui.GetStyle().Colors[imgui.Col.WindowBg]
    end   
    if pool["color"] == nil then
        pool["color"] = imgui.ImVec4(parent_color.x, parent_color.y, parent_color.z, parent_color.w)
    end
    if size == nil then
        local text_size = imgui.CalcTextSize(text:match("(.+)##.+") or text)
        size = imgui.ImVec2(text_size.x + 20, text_size.y + 20)
    end
    if size.x > size.y then
        radius = size.x
        if duration == nil then duration = size.x / 64 end
    else
        radius = size.y
        if duration == nil then duration = size.y / 64 end
    end
    imgui.PushStyleColor(imgui.Col.ChildWindowBg, imgui.GetStyle().Colors[imgui.Col.Button])
    imgui.PushStyleVar(imgui.StyleVar.WindowPadding, imgui.ImVec2(0,0))
    imgui.PushStyleVar(imgui.StyleVar.ChildWindowRounding, rounding)
    imgui.BeginChild("##ripple effect" .. text, imgui.ImVec2(size.x, size.y), false, imgui.WindowFlags.NoScrollbar)
   
        local draw_list = imgui.GetWindowDrawList()
        if pool["animation"] and pool["radius"] <= radius * 2.8125 then
            draw_list:AddCircleFilled(pool["mouse_coor"], pool["radius"], imgui.GetColorU32(imgui.ImVec4(1, 1, 1, 0.6)), 64)
            pool["radius"] = pool["radius"] + (3 * duration)
            pool["time"] = os.clock()
        elseif pool["animation"] and pool["radius"] >= radius * 2.8125 then
            if bringVec4To(imgui.ImVec4(1, 1, 1, 0.6), imgui.ImVec4(1, 1, 1, 0), pool["time"], 1).w ~= 0 then                  
                draw_list:AddCircleFilled(pool["mouse_coor"], pool["radius"], imgui.GetColorU32(imgui.ImVec4(1, 1, 1, bringVec4To(imgui.ImVec4(1, 1, 1, 0.6), imgui.ImVec4(1, 1, 1, 0), pool["time"], 1).w)), 64)
            else
                pool["animation"] = false
            end
        elseif not pool["animation"] and pool["radius"] >= radius * 2.8125 then
            pool["animation"] = false
            pool["radius"] = 5
            pool["time"] = nil
        end
        if rounding ~= 0 then               
            draw_list:PathLineTo(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x,
                imgui.GetCursorPos().y + imgui.GetWindowPos().y)
            )
            draw_list:PathLineTo(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x,
                imgui.GetCursorPos().y + imgui.GetWindowPos().y + rounding)
            )
            draw_list:PathArcTo(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x + rounding,
                imgui.GetCursorPos().y + imgui.GetWindowPos().y + rounding), rounding, -3, -1.5, 64
            )
           
            draw_list:PathFillConvex(imgui.GetColorU32(pool["color"]))
            draw_list:PathClear()
            draw_list:PathLineTo(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x + size.x,
                imgui.GetCursorPos().y + imgui.GetWindowPos().y)
            )
            draw_list:PathLineTo(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x + size.x - rounding,
                imgui.GetCursorPos().y + imgui.GetWindowPos().y)
            )
            draw_list:PathArcTo(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x + size.x - rounding,
                imgui.GetCursorPos().y + imgui.GetWindowPos().y + rounding), rounding, -1.5, 0, 64
            )
            draw_list:PathFillConvex(imgui.GetColorU32(pool["color"]))
            draw_list:PathClear()
           
            draw_list:PathLineTo(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x,
                imgui.GetCursorPos().y + imgui.GetWindowPos().y + size.y)
            )
            draw_list:PathLineTo(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x,
                imgui.GetCursorPos().y + imgui.GetWindowPos().y + size.y - rounding)
            )
            draw_list:PathArcTo(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x + rounding,
                imgui.GetCursorPos().y + imgui.GetWindowPos().y + size.y - rounding), rounding, 3, 1.5, 64
            )
            draw_list:PathFillConvex(imgui.GetColorU32(pool["color"]))
            draw_list:PathClear()
            draw_list:PathLineTo(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x + size.x,
                imgui.GetCursorPos().y + imgui.GetWindowPos().y + size.y)
            )
            draw_list:PathLineTo(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x + size.x,
                imgui.GetCursorPos().y + imgui.GetWindowPos().y + size.y - rounding)
            )
            draw_list:PathArcTo(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x + size.x - rounding,
                imgui.GetCursorPos().y + imgui.GetWindowPos().y + size.y - rounding), rounding, 0, 1.5, 64
            )
            draw_list:PathFillConvex(imgui.GetColorU32(pool["color"]))
            draw_list:PathClear()
        end
        CenterTextFor2Dims(text:match("(.+)##.+") or text)
    imgui.EndChild()
    imgui.PopStyleColor()
    imgui.PopStyleVar(2)
   
   
    imgui.SetCursorPos(imgui.ImVec2(imgui.GetCursorPos().x, imgui.GetCursorPos().y + 10))
    if imgui.IsItemClicked() then
            pool["animation"] = true
            pool["radius"] = 5
            pool["mouse_coor"] = imgui.GetMousePos()
            return true
    end
end

Аргументы функции:

text - обязательный. Текст кнопки, русские буквы указывать с u8, как обычно.
size - необязательный. Размер кнопки, по дефолту сам вычисляет размер.
duration - необязательный. Интенсивность эффекта, по дефолту само вычисляется, но если надо сделать быстрее, поковыряйтесь со значениями от 1 до 10.
rounding - необязательный. Округление краёв кнопки. По дефолту равно 0.
parent_color - особенный. Если есть округление краёв, то указывается цвет родительского виджета, к примеру если кнопка находится в BeginChild то указывается imgui.GetStyle().Colors[imgui.Col.ChildWindowBg] (в примере покажу), и т.д. По дефолту цвет основного окна.

Пример использования:

Lua:
function imgui.OnDrawFrame()
    imgui.Begin("test")
        
        if imgui.RippleButton(u8"Нажми##2" ,imgui.ImVec2(64, 64), 1.5, 16) then sampAddChatMessage("Нажата кнопка", -1) end
        -- при нажатии ведет себя как обычная кнопка,

        --если кнопка в каком-то другом окне (BeginChild например) и у нее есть скругление, есть одно примечание
        imgui.BeginChild("child", imgui.ImVec2(150, 100))

            imgui.RippleButton(u8"Нажми##3" , nil, 1.5, 8, imgui.GetStyle().Colors[imgui.Col.ChildWindowBg])
            -- как видите после параметра скругления, в моем случае 8, идет получение цвета фона Child.
            -- также должно работать и с остальными окнами, Popup например.
        
        imgui.EndChild()

       
        imgui.RippleButton("Press##2", imgui.ImVec2(128, 32), 3, 16)
        -- у кнопки опять же есть скругление, но так как оно в основном окне Begin, цвет не обязательно указывать

        -- изменение цвета ripple кнопки точно такое же как изменение цвета обычной кнопки 
        imgui.PushStyleColor(imgui.Col.Button, imgui.ImVec4(0.64, 0.74, 0, 1))
        imgui.RippleButton("Press") -- размер также не обязательно указывать 
        imgui.PopStyleColor()

    imgui.End()
end
 

ruslol

Участник
17
73

Описание:

Улучшенное поле ввода в стиле Material Design.
Lua:
function imgui.BetterInput(name, hint_text, buffer, color, text_color, width)

    ----==| Локальные фунцкии, использованные в этой функции. |==----

    local function bringVec4To(from, to, start_time, duration)
        local timer = os.clock() - start_time
        if timer >= 0.00 and timer <= duration then
            local count = timer / (duration / 100)
            return imgui.ImVec4(
                from.x + (count * (to.x - from.x) / 100),
                from.y + (count * (to.y - from.y) / 100),
                from.z + (count * (to.z - from.z) / 100),
                from.w + (count * (to.w - from.w) / 100)
            ), true
        end
        return (timer > duration) and to or from, false
    end

    local function bringFloatTo(from, to, start_time, duration)
        local timer = os.clock() - start_time
        if timer >= 0.00 and timer <= duration then
            local count = timer / (duration / 100)
            return from + (count * (to - from) / 100), true
        end
        return (timer > duration) and to or from, false
    end


    ----==| Изменение местоположения Imgui курсора, чтобы подсказка при анимации отображалась корректно. |==----

    imgui.SetCursorPosY(imgui.GetCursorPos().y + (imgui.CalcTextSize(hint_text).y * 0.7))


    ----==| Создание шаблона, для корректной работы нескольких таких виджетов. |==----

    if UI_BETTERINPUT == nil then
        UI_BETTERINPUT = {}
    end
    if not UI_BETTERINPUT[name] then
        UI_BETTERINPUT[name] = {buffer = buffer or imgui.ImBuffer(256), width = nil,
        hint = {
            pos = nil,
            old_pos = nil,
            scale = nil
        },
        color = imgui.GetStyle().Colors[imgui.Col.TextDisabled],
        old_color = imgui.GetStyle().Colors[imgui.Col.TextDisabled],
        active = {false, nil}, inactive = {true, nil}
    }
    end

    local pool = UI_BETTERINPUT[name] -- локальный список переменных для одного виджета


    ----==| Проверка и присваивание значений нужных переменных и аргументов. |==----
    
    if color == nil then
        color = imgui.GetStyle().Colors[imgui.Col.ButtonActive]
    end

    if width == nil then
        pool["width"] = imgui.CalcTextSize(hint_text).x + 50
        if pool["width"] < 150 then
            pool["width"] = 150
        end
    else
        pool["width"] = width
    end

    if pool["hint"]["scale"] == nil then
        pool["hint"]["scale"] = 1.0
    end

    if pool["hint"]["pos"] == nil then
        pool["hint"]["pos"] = imgui.ImVec2(imgui.GetCursorPos().x, imgui.GetCursorPos().y)
    end

    if pool["hint"]["old_pos"] == nil then
        pool["hint"]["old_pos"] = imgui.GetCursorPos().y
    end


    ----==| Изменение стилей под параметры виджета. |==----

    imgui.PushStyleColor(imgui.Col.FrameBg, imgui.ImVec4(1, 1, 1, 0))
    imgui.PushStyleColor(imgui.Col.Text, text_color or imgui.ImVec4(1, 1, 1, 1))
    imgui.PushStyleColor(imgui.Col.TextSelectedBg, color)
    imgui.PushStyleVar(imgui.StyleVar.FramePadding, imgui.ImVec2(0, imgui.GetStyle().FramePadding.y))
    imgui.PushItemWidth(pool["width"])


    ----==| Получение Imgui Draw List текущего окна. |==----

    local draw_list = imgui.GetWindowDrawList()


    ----==| Добавление декоративной линии под виджет. |==----

    draw_list:AddLine(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x,
    imgui.GetCursorPos().y + imgui.GetWindowPos().y + (2 * imgui.GetStyle().FramePadding.y) + imgui.CalcTextSize(hint_text).y),
    imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x + pool["width"],
    imgui.GetCursorPos().y + imgui.GetWindowPos().y + (2 * imgui.GetStyle().FramePadding.y) + imgui.CalcTextSize(hint_text).y),
    imgui.GetColorU32(pool["color"]), 2.0)


    ----==| Само поле ввода. |==----

    imgui.InputText("##" .. name, pool["buffer"])


    ----==| Переключатель состояний виджета. |==----

    if not imgui.IsItemActive() then
        if pool["inactive"][2] == nil then pool["inactive"][2] = os.clock() end
        pool["inactive"][1] = true
        pool["active"][1] = false
        pool["active"][2] = nil

    elseif imgui.IsItemActive() or imgui.IsItemClicked() then
        pool["inactive"][1] = false
        pool["inactive"][2] = nil
        if pool["active"][2] == nil then pool["active"][2] = os.clock() end
        pool["active"][1] = true
    end
    
    ----==| Изменение цвета; размера и позиции подсказки по состоянию. |==----

    if pool["inactive"][1] and #pool["buffer"].v == 0 then
        pool["color"] = bringVec4To(pool["color"], pool["old_color"], pool["inactive"][2], 0.75)
        pool["hint"]["scale"] = bringFloatTo(pool["hint"]["scale"], 1.0, pool["inactive"][2], 0.25)
        pool["hint"]["pos"].y = bringFloatTo(pool["hint"]["pos"].y, pool["hint"]["old_pos"], pool["inactive"][2], 0.25)
        
    elseif pool["inactive"][1] and #pool["buffer"].v > 0 then
        pool["color"] = bringVec4To(pool["color"], pool["old_color"], pool["inactive"][2], 0.75)
        pool["hint"]["scale"] = bringFloatTo(pool["hint"]["scale"], 0.7, pool["inactive"][2], 0.25)
        pool["hint"]["pos"].y = bringFloatTo(pool["hint"]["pos"].y, pool["hint"]["old_pos"] - (imgui.GetFontSize() * 0.7) - 2,
        pool["inactive"][2], 0.25)

    elseif pool["active"][1] and #pool["buffer"].v == 0 then
        pool["color"] = bringVec4To(pool["color"], color, pool["active"][2], 0.75)
        pool["hint"]["scale"] = bringFloatTo(pool["hint"]["scale"], 0.7, pool["active"][2], 0.25)
        pool["hint"]["pos"].y = bringFloatTo(pool["hint"]["pos"].y, pool["hint"]["old_pos"] - (imgui.GetFontSize() * 0.7) - 2,
        pool["active"][2], 0.25)

    elseif pool["active"][1] and #pool["buffer"].v > 0 then
        pool["color"] = bringVec4To(pool["color"], color, pool["active"][2], 0.75)
        pool["hint"]["scale"] = bringFloatTo(pool["hint"]["scale"], 0.7, pool["active"][2], 0.25)
        pool["hint"]["pos"].y = bringFloatTo(pool["hint"]["pos"].y, pool["hint"]["old_pos"] - (imgui.GetFontSize() * 0.7) - 2,
        pool["active"][2], 0.25)
    end   
    imgui.SetWindowFontScale(pool["hint"]["scale"])
    
    
    ----==| Сама подсказка с анимацией. |==----

    draw_list:AddText(imgui.ImVec2(pool["hint"]["pos"].x + imgui.GetWindowPos().x + imgui.GetStyle().FramePadding.x,
    pool["hint"]["pos"].y + imgui.GetWindowPos().y + imgui.GetStyle().FramePadding.y),
    imgui.GetColorU32(pool["color"]),
    hint_text)


    ----==| Возвращение стилей в свой первоначальный вид. |==----

    imgui.SetWindowFontScale(1.0)
    imgui.PopItemWidth()
    imgui.PopStyleColor(3)
    imgui.PopStyleVar()
end

Аргументы функции:

Аргумент

Тип данных

Статус

Описание

name
stringОбязательный*Уникальное имя виджета (оно нигде не показывается). У разных виджетов должно быть разное уникальное имя.
hint_text
stringОбязательный*Текст подсказки.
bufferImBufferНеобязательныйImgui буфер текста. Если не указать свой буфер, то функция создаст свой локальный, с которым не получится взаимодейстовать.
colorImVec4НеобязательныйЦвет активных подсказки и линии снизу. По дефолту равен цвету ButtonActive.
text_colorImVec4НеобязательныйЦвет текста ввода. По дефолту равен цвету Text.
widthfloatНеобязательныйШирина виджета. По дефолту зависит от ширины текста подсказки.

Пример использования:

Lua:
function imgui.OnDrawFrame()

    local X, Y = getScreenResolution()
    imgui.SetNextWindowSize(imgui.ImVec2(512, 384), imgui.Cond.Always)
    imgui.SetNextWindowPos(imgui.ImVec2(X / 2, Y / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))

    imgui.Begin("test")
      
        imgui.SetCursorPosX(106)
        imgui.BetterInput("1", u8"Подсказка с анимацией.", nil, nil, nil, 300)


        imgui.SetCursorPosX(106)
        imgui.SetCursorPosY(100)
        imgui.BetterInput("2", u8("Работа с буфером текста."), test_buffer, nil, nil, 300)
        
        imgui.SetCursorPosX(56)
        imgui.Text(u8"Текст отобразится тут: " .. test_buffer.v)


        imgui.SetCursorPosY(200)
        imgui.BeginChild("child", imgui.ImVec2(496, 100))

            imgui.SetCursorPosY(25)
            imgui.SetCursorPosX(50)
            imgui.BetterInput("3", u8 "Кастомные цвета.",
                nil, imgui.ImVec4(187/255, 0, 1, 1), imgui.ImVec4(0, 0, 0, 1)
            )

        imgui.EndChild()    
    imgui.End()
end
 
Последнее редактирование:

ruslol

Участник
17
73

Описание:

Ввод графического ключа.

Графический ключ:
function imgui.GraphicKey(name, size, color, line_color)

    if UI_GRAPHICKEY == nil then
        UI_GRAPHICKEY = {}
    end
    if not UI_GRAPHICKEY[name] then
        UI_GRAPHICKEY[name] = {
            clicked = nil,
            line_list = {},
            code_list = ""
    }
    end

    local pool = UI_GRAPHICKEY[name]
    local old_cursor = imgui.ImVec2(imgui.GetCursorPos().x,
        imgui.GetCursorPos().y
    )
    local draw_list = imgui.GetWindowDrawList()

    local function DotBox(i)
        local dot_box_cursor = imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x + (size / 2),
        imgui.GetCursorPos().y + imgui.GetWindowPos().y + (size / 2))

        imgui.BeginChild("##" .. name .. i, imgui.ImVec2(size, size))

        imgui.EndChild()

        draw_list:AddCircleFilled(dot_box_cursor, (size / 2) * 0.4,
            imgui.GetColorU32(color or imgui.GetStyle().Colors[imgui.Col.Button]), 64
        )

        if imgui.IsItemClicked() and pool["clicked"] == nil then
            pool["clicked"] = i
            table.insert(pool["line_list"], dot_box_cursor)
            pool["code_list"] = pool["code_list"] .. i
        end
        if imgui.IsItemHovered() and imgui.IsMouseDown(0) and pool["clicked"] ~= i and pool["clicked"] ~= nil then
            for j = 1, #pool["line_list"] do
                if pool["line_list"][j].x == dot_box_cursor.x and pool["line_list"][j].y == dot_box_cursor.y then
                    return nil
                end
            end
            table.insert(pool["line_list"], dot_box_cursor)
            pool["code_list"] = pool["code_list"] .. i
        end
    end
    imgui.PushStyleColor(imgui.Col.ChildWindowBg, imgui.ImVec4(1, 1, 1, 0))
        for i = 1, 9 do
            imgui.SetCursorPos(imgui.ImVec2(old_cursor.x + (size * ((2 + (i % -3)) * 1.5)),
            old_cursor.y + (size * math.floor((i / 3) - 0.2) * 1.5)
        ))
            DotBox(i)
        end

        if imgui.IsMouseDown(0) and pool["clicked"] ~= nil then
            for i = 1, #pool["line_list"] do

                if i ~= #pool["line_list"] then
                    draw_list:AddLine(
                        pool["line_list"][i],
                        pool["line_list"][i + 1],
                        imgui.GetColorU32(line_color or imgui.GetStyle().Colors[imgui.Col.Separator]),
                        size / 8
                    )
                    draw_list:AddCircle(
                        pool["line_list"][i],
                        size / 2,
                        imgui.GetColorU32(line_color or imgui.GetStyle().Colors[imgui.Col.Separator]),
                        nil, size / 8
                    )
                else
                    draw_list:AddLine(
                        pool["line_list"][i],
                        imgui.ImVec2(imgui.GetMousePos().x, imgui.GetMousePos().y),
                        imgui.GetColorU32(line_color or imgui.GetStyle().Colors[imgui.Col.Separator]),
                        size / 8
                    )
                    draw_list:AddCircle(
                        pool["line_list"][i],
                        size / 2,
                        imgui.GetColorU32(line_color or imgui.GetStyle().Colors[imgui.Col.Separator]),
                        nil, size / 8
                    )
                end
            end
        elseif not imgui.IsMouseDown(0) then
            pool["clicked"] = nil
            pool["line_list"] = {}
            pool["code_list"] = ""
        end
    imgui.PopStyleColor(1)
    return pool["code_list"]
end

Аргументы функции:


Аргумент

Тип данных

Статус

Описание

namestringОбязательный*Уникальное имя виджета.
У разных виджетов разное имя.
sizefloatОбязательный*Полу радиус обведенных кружков.
Все остальные размеры элементов виджета опираются на этот размер.
colorImVec4НеобязательныйЦвет маленьких кружков.
По дефолту равно цвету Button.
line_colorImVec4НеобязательныйЦвет линии и обведенных кружков.
По дефолту равно цвету Separator.


Пример использования:


Пример использования:
function imgui.OnDrawFrame()

    local X, Y = getScreenResolution()
    imgui.SetNextWindowSize(imgui.ImVec2(512, 384), imgui.Cond.Always)
    imgui.SetNextWindowPos(imgui.ImVec2(X / 2, Y / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))


    imgui.Begin("test", mws, imgui.WindowFlags.NoMove)
    -- Обязателен флаг NoMove для окна,
    -- иначе окно будет убегать и виджет не будет работать.


    if text ~= "2589" then
        -- Тут мы хотим чтобы пароль был "2589",
        -- пока он не такой то мы показываем виджеты ниже.

        imgui.Text(u8"Введите графический пароль:")

        text = imgui.GraphicKey("1", 32, imgui.ImVec4(1, 1, 1, 1), imgui.ImVec4(191/255, 215/255, 234/255, 1))
        -- Виджет будет возвращать строку с паролем, если же пароль пока пуст,
        -- то виджет вернет пустую строку "".

        imgui.Text(text)
    else
        -- Как только пароль становится "2589",
        -- виджет выше больше не показываются, так как не входят в условие,
        -- а появляется новый виджет с текстом ниже.
        imgui.Text(u8"Пароль верный")
    end

    imgui.End()
end

UPD: че вы ржете? 😅
 
Последнее редактирование:

lorgon

Известный
657
267
Описание: Ищет кратчайший путь от точки до точки по таблице (графу) / Алгоритм Дейкстры / Dijkstra's algorithm (АВТОР)
Lua:
function dijkstra(starting_vertex, destination_vertex, edges)
    local function create_dijkstra(starting_vertex)
       local shortest_paths = {[starting_vertex] = {full_distance = 0}}
       local vertex, distance, heap_size, heap = starting_vertex, 0, 0, {}
       return
          function (adjacent_vertex, edge_length)
             if adjacent_vertex then
                local new_distance = distance + edge_length
                local adjacent_vertex_info = shortest_paths[adjacent_vertex]
                local pos
                if adjacent_vertex_info then
                   if new_distance < adjacent_vertex_info.full_distance then
                      adjacent_vertex_info.full_distance = new_distance
                      adjacent_vertex_info.previous_vertex = vertex
                      pos = adjacent_vertex_info.index
                   else
                      return
                   end
                else
                   adjacent_vertex_info = {full_distance = new_distance, previous_vertex = vertex, index = 0}
                   shortest_paths[adjacent_vertex] = adjacent_vertex_info
                   heap_size = heap_size + 1
                   pos = heap_size
                end
                while pos > 1 do
                   local parent_pos = (pos - pos % 2) / 2
                   local parent = heap[parent_pos]
                   local parent_info = shortest_paths[parent]
                   if new_distance < parent_info.full_distance then
                      heap[pos] = parent
                      parent_info.index = pos
                      pos = parent_pos
                   else
                      break
                   end
                end
                heap[pos] = adjacent_vertex
                adjacent_vertex_info.index = pos
             elseif heap_size > 0 then
                vertex = heap[1]
                local parent = heap[heap_size]
                heap[heap_size] = nil
                heap_size = heap_size - 1
                if heap_size > 0 then
                   local pos = 1
                   local last_node_pos = heap_size / 2
                   local parent_info = shortest_paths[parent]
                   local parent_distance = parent_info.full_distance
                   while pos <= last_node_pos do
                      local child_pos = pos + pos
                      local child = heap[child_pos]
                      local child_info = shortest_paths[child]
                      local child_distance = child_info.full_distance
                      if child_pos < heap_size then
                         local child_pos2 = child_pos + 1
                         local child2 = heap[child_pos2]
                         local child2_info = shortest_paths[child2]
                         local child2_distance = child2_info.full_distance
                         if child2_distance < child_distance then
                            child_pos = child_pos2
                            child = child2
                            child_info = child2_info
                            child_distance = child2_distance
                         end
                      end
                      if child_distance < parent_distance then
                         heap[pos] = child
                         child_info.index = pos
                         pos = child_pos
                      else
                         break
                      end
                   end
                   heap[pos] = parent
                   parent_info.index = pos
                end
                local vertex_info = shortest_paths[vertex]
                vertex_info.index = nil
                distance = vertex_info.full_distance
                return vertex
             end
          end,
          shortest_paths
    end
    local vertex, dijkstra, shortest_paths = starting_vertex, create_dijkstra(starting_vertex)
    while vertex and vertex ~= destination_vertex do
       for adjacent_vertex, edge_length in pairs(edges[vertex]) do
          dijkstra(adjacent_vertex, edge_length)
       end
       vertex = dijkstra()
    end
    if vertex then
        local path = {}
        local full_distance = shortest_paths[vertex].full_distance
        table.insert(path, vertex)
        while vertex do
          vertex = shortest_paths[vertex].previous_vertex
          if vertex then
             table.insert(path, vertex)
          end
        end
        local res = {}
        for i = #path, 1, -1 do table.insert(res, path[i]) end
        return true, {
            full_distance = full_distance,
            path = res,
        }
    else
       return false, {}
    end
end
-- возвращает Bool result, Table tab


Значение возвращаемой таблицы:

NUMBERfull_distanceДистанция от начальной до конечной точки
TABLEpathТаблица точек пути, от начальной до конечной.

Пример использования:

Lua:
local edges = {
   [34] = {[35] = 1,[37] = 1,},
   [35] = {[34] = 1,[36] = 1,[46] = 1,},
   [36] = {[35] = 1,[37] = 1,},
   [37] = {[34] = 1,[36] = 1,},
   [38] = {[46] = 1,},
   [46] = {[35] = 1,[38] = 1,},
}
local res, tab = dijkstra(34, 38, edges)
if res then
    print('dist: '..tab.full_distance)
    for i = 1, #tab.path do
        print(tab.path[i])
    end
end
--[[ Result:
  - dist: 3
  - 34
  - 35
  - 46
  - 38
]]
1649203418647.png
 
Последнее редактирование: