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

Cosmo

Известный
Друг
653
2,724
Описание:
Функции перехода от одного значения к другому за определённый промежуток времени
Например, может пригодится для создания простых анимаций в имгуи

Float:
Lua:
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

ImVec2:
Lua:
function bringVec2To(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.ImVec2(
            from.x + (count * (to.x - from.x) / 100),
            from.y + (count * (to.y - from.y) / 100)
        ), true
    end
    return (timer > duration) and to or from, false
end

ImVec4:
Lua:
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

Аргументы функции(й):
from - начальное значение
to - конечное значение
start_time - время [ os.clock() ], с которого начнётся переход
duration - Длительность перехода в секундах

Пример реализации:
Imgui-кнопка с плавными анимациями перехода от одного состояния к другому
Lua:
AnimButton = function(label, size, duration)
    if type(duration) ~= "table" then
        duration = { 1.0, 0.3 }
    end

    local cols = {
        default = imgui.ImVec4(imgui.GetStyle().Colors[imgui.Col.Button]),
        hovered = imgui.ImVec4(imgui.GetStyle().Colors[imgui.Col.ButtonHovered]),
        active  = imgui.ImVec4(imgui.GetStyle().Colors[imgui.Col.ButtonActive])
    }

    if UI_ANIMBUT == nil then
        UI_ANIMBUT = {}
    end
    if not UI_ANIMBUT[label] then
        UI_ANIMBUT[label] = {
            color = cols.default,
            clicked = { nil, nil },
            hovered = {
                cur = false,
                old = false,
                clock = nil,
            }
        }
    end
    local pool = UI_ANIMBUT[label]

    if pool["clicked"][1] and pool["clicked"][2] then
        if os.clock() - pool["clicked"][1] <= duration[2] then
            pool["color"] = bringVec4To(
                pool["color"],
                cols.active,
                pool["clicked"][1],
                duration[2]
            )
            goto no_hovered
        end

        if os.clock() - pool["clicked"][2] <= duration[2] then
            pool["color"] = bringVec4To(
                pool["color"],
                pool["hovered"]["cur"] and cols.hovered or cols.default,
                pool["clicked"][2],
                duration[2]
            )
            goto no_hovered
        end
    end

    if pool["hovered"]["clock"] ~= nil then
        if os.clock() - pool["hovered"]["clock"] <= duration[1] then
            pool["color"] = bringVec4To(
                pool["color"],
                pool["hovered"]["cur"] and cols.hovered or cols.default,
                pool["hovered"]["clock"],
                duration[1]
            )
        else
            pool["color"] = pool["hovered"]["cur"] and cols.hovered or cols.default
        end
    end

    ::no_hovered::

    imgui.PushStyleColor(imgui.Col.Button, imgui.ImVec4(pool["color"]))
    imgui.PushStyleColor(imgui.Col.ButtonHovered, imgui.ImVec4(pool["color"]))
    imgui.PushStyleColor(imgui.Col.ButtonActive, imgui.ImVec4(pool["color"]))
    local result = imgui.Button(label, size or imgui.ImVec2(0, 0))
    imgui.PopStyleColor(3)

    if result then
        pool["clicked"] = {
            os.clock(),
            os.clock() + duration[2]
        }
    end

    pool["hovered"]["cur"] = imgui.IsItemHovered()
    if pool["hovered"]["old"] ~= pool["hovered"]["cur"] then
        pool["hovered"]["old"] = pool["hovered"]["cur"]
        pool["hovered"]["clock"] = os.clock()
    end

    return result
end

but.gif
 

Вложения

  • Degrade.lua
    1.8 KB · Просмотры: 42
Последнее редактирование:

CaJlaT

07.11.2024 14:55
Модератор
2,833
2,669
Описание: ImGui кнопка с анимацией.
UPD: Добавил возможность рисовать несколько анимаций в одной кнопке, добавил анимацию при наведении на кнопку, добавил совместимость с FrameRounding (скругление) и ButtonTextAlign (расположение текста внутри кнопки)
UPD 2: Теперь размер работает как в обычной кнопке (можно не указывать размер или в размерах поставить 0 и -1)
Lua:
-- label - название кнопки
-- size - размер кнопки (необязательно)
-- speed - скорость анимаций (необязательно)
-- rounded - будет ли кнопка соблюдать FrameRounding (необязательно)
-- P.s: Скругление работает через колхоз, т.к я не нашёл нормальной функции отсечения примитива
-- P.s.s: Функция для отсечения скруглённой кнопки взята отсюда:  https://github.com/ocornut/imgui/issues/3710#issuecomment-758686240
function imgui.AnimatedButton(label, size, speed, rounded)
    local size = size or imgui.ImVec2(0, 0)
    local bool = false
    local text = label:gsub('##.+$', '')
    local ts = imgui.CalcTextSize(text)
    speed = speed and speed or 0.4
    if not AnimatedButtons then AnimatedButtons = {} end
    if not AnimatedButtons[label] then
        local color = imgui.GetStyle().Colors[imgui.Col.ButtonHovered]
        AnimatedButtons[label] = {circles = {}, hovered = false, state = false, time = os.clock(), color = imgui.ImVec4(color.x, color.y, color.z, 0.2)}
    end
    local button = AnimatedButtons[label]
    local dl = imgui.GetWindowDrawList()
    local p = imgui.GetCursorScreenPos()
    local c = imgui.GetCursorPos()
    local CalcItemSize = function(size, width, height)
        local region = imgui.GetContentRegionMax()
        if (size.x == 0) then
            size.x = width
        elseif (size.x < 0) then
            size.x = math.max(4.0, region.x - c.x + size.x);
        end
        if (size.y == 0) then
            size.y = height;
        elseif (size.y < 0) then
            size.y = math.max(4.0, region.y - c.y + size.y);
        end
        return size
    end
    size = CalcItemSize(size, ts.x+imgui.GetStyle().FramePadding.x*2, ts.y+imgui.GetStyle().FramePadding.y*2)
    local ImSaturate = function(f) return f < 0.0 and 0.0 or (f > 1.0 and 1.0 or f) end
    if #button.circles > 0 then
        local PathInvertedRect = function(a, b, col)
            local rounding = rounded and imgui.GetStyle().FrameRounding or 0
            if rounding <= 0 or not rounded then return end
            local dl = imgui.GetWindowDrawList()
            dl:PathLineTo(a)
            dl:PathArcTo(imgui.ImVec2(a.x + rounding, a.y + rounding), rounding, -3.0, -1.5)
            dl:PathFillConvex(col)

            dl:PathLineTo(imgui.ImVec2(b.x, a.y))
            dl:PathArcTo(imgui.ImVec2(b.x - rounding, a.y + rounding), rounding, -1.5, -0.205)
            dl:PathFillConvex(col)

            dl:PathLineTo(imgui.ImVec2(b.x, b.y))
            dl:PathArcTo(imgui.ImVec2(b.x - rounding, b.y - rounding), rounding, 1.5, 0.205)
            dl:PathFillConvex(col)

            dl:PathLineTo(imgui.ImVec2(a.x, b.y))
            dl:PathArcTo(imgui.ImVec2(a.x + rounding, b.y - rounding), rounding, 3.0, 1.5)
            dl:PathFillConvex(col)
        end
        for i, circle in ipairs(button.circles) do
            local time = os.clock() - circle.time
            local t = ImSaturate(time / speed)
            local color = imgui.GetStyle().Colors[imgui.Col.ButtonActive]
            local color = imgui.GetColorU32Vec4(imgui.ImVec4(color.x, color.y, color.z, (circle.reverse and (255-255*t) or (255*t))/255))
            local radius = math.max(size.x, size.y) * (circle.reverse and 1.5 or t)
            imgui.PushClipRect(p, imgui.ImVec2(p.x+size.x, p.y+size.y), true)
            dl:AddCircleFilled(circle.clickpos, radius, color, radius/2)
            PathInvertedRect(p, imgui.ImVec2(p.x+size.x, p.y+size.y), imgui.GetColorU32Vec4(imgui.GetStyle().Colors[imgui.Col.WindowBg]))
            imgui.PopClipRect()
            if t == 1 then
                if not circle.reverse then
                    circle.reverse = true
                    circle.time = os.clock()
                else
                    table.remove(button.circles, i)
                end
            end
        end
    end
    local t = ImSaturate((os.clock()-button.time) / speed)
    button.color.w = button.color.w + (button.hovered and 0.8 or -0.8)*t
    button.color.w = button.color.w < 0.2 and 0.2 or (button.color.w > 1 and 1 or button.color.w)
    color = imgui.GetStyle().Colors[imgui.Col.Button]
    color = imgui.GetColorU32Vec4(imgui.ImVec4(color.x, color.y, color.z, 0.2))
    dl:AddRectFilled(p, imgui.ImVec2(p.x+size.x, p.y+size.y), color, rounded and imgui.GetStyle().FrameRounding or 0)
    dl:AddRect(p, imgui.ImVec2(p.x+size.x, p.y+size.y), imgui.GetColorU32Vec4(button.color), rounded and imgui.GetStyle().FrameRounding or 0)
    local align = imgui.GetStyle().ButtonTextAlign
    imgui.SetCursorPos(imgui.ImVec2(c.x+(size.x-ts.x)*align.x, c.y+(size.y-ts.y)*align.y))
    imgui.Text(text)
    imgui.SetCursorPos(c)
    if imgui.InvisibleButton(label, size) then
        bool = true
        table.insert(button.circles, {animate = true, reverse = false, time = os.clock(), clickpos = imgui.ImVec2(getCursorPos())})
    end
    button.hovered = imgui.IsItemHovered()
    if button.hovered ~= button.state then
        button.state = button.hovered
        button.time = os.clock()
    end
    return bool
end
Lua:
-- label - название кнопки
-- size - размер кнопки (необязательно)
-- speed - скорость анимаций (необязательно)
-- rounded - будет ли кнопка соблюдать FrameRounding (необязательно)
-- P.s: Скругление работает через колхоз, т.к я не нашёл нормальной функции отсечения примитива
-- P.s.s: Функция для отсечения скруглённой кнопки взята отсюда:  https://github.com/ocornut/imgui/issues/3710#issuecomment-758686240
function imgui.AnimatedButton(label, size, speed, rounded)
    local size = size or imgui.ImVec2(0, 0)
    local bool = false
    local text = label:gsub('##.+$', '')
    local ts = imgui.CalcTextSize(text)
    speed = speed and speed or 0.4
    if not AnimatedButtons then AnimatedButtons = {} end
    if not AnimatedButtons[label] then
        local color = imgui.GetStyle().Colors[imgui.Col.ButtonHovered]
        AnimatedButtons[label] = {circles = {}, hovered = false, state = false, time = os.clock(), color = imgui.ImVec4(color.x, color.y, color.z, 0.2)}
    end
    local button = AnimatedButtons[label]
    local dl = imgui.GetWindowDrawList()
    local p = imgui.GetCursorScreenPos()
    local c = imgui.GetCursorPos()
    local CalcItemSize = function(size, width, height)
        local region = imgui.GetContentRegionMax()
        if (size.x == 0) then
            size.x = width
        elseif (size.x < 0) then
            size.x = math.max(4.0, region.x - c.x + size.x);
        end
        if (size.y == 0) then
            size.y = height;
        elseif (size.y < 0) then
            size.y = math.max(4.0, region.y - c.y + size.y);
        end
        return size
    end
    size = CalcItemSize(size, ts.x+imgui.GetStyle().FramePadding.x*2, ts.y+imgui.GetStyle().FramePadding.y*2)
    local ImSaturate = function(f) return f < 0.0 and 0.0 or (f > 1.0 and 1.0 or f) end
    if #button.circles > 0 then
        local PathInvertedRect = function(a, b, col)
            local rounding = rounded and imgui.GetStyle().FrameRounding or 0
            if rounding <= 0 or not rounded then return end
            local dl = imgui.GetWindowDrawList()
            dl:PathLineTo(a)
            dl:PathArcTo(imgui.ImVec2(a.x + rounding, a.y + rounding), rounding, -3.0, -1.5)
            dl:PathFillConvex(col)

            dl:PathLineTo(imgui.ImVec2(b.x, a.y))
            dl:PathArcTo(imgui.ImVec2(b.x - rounding, a.y + rounding), rounding, -1.5, -0.205)
            dl:PathFillConvex(col)

            dl:PathLineTo(imgui.ImVec2(b.x, b.y))
            dl:PathArcTo(imgui.ImVec2(b.x - rounding, b.y - rounding), rounding, 1.5, 0.205)
            dl:PathFillConvex(col)

            dl:PathLineTo(imgui.ImVec2(a.x, b.y))
            dl:PathArcTo(imgui.ImVec2(a.x + rounding, b.y - rounding), rounding, 3.0, 1.5)
            dl:PathFillConvex(col)
        end
        for i, circle in ipairs(button.circles) do
            local time = os.clock() - circle.time
            local t = ImSaturate(time / speed)
            local color = imgui.GetStyle().Colors[imgui.Col.ButtonActive]
            local color = imgui.GetColorU32(imgui.ImVec4(color.x, color.y, color.z, (circle.reverse and (255-255*t) or (255*t))/255))
            local radius = math.max(size.x, size.y) * (circle.reverse and 1.5 or t)
            imgui.PushClipRect(p, imgui.ImVec2(p.x+size.x, p.y+size.y), true)
            dl:AddCircleFilled(circle.clickpos, radius, color, radius/2)
            PathInvertedRect(p, imgui.ImVec2(p.x+size.x, p.y+size.y), imgui.GetColorU32(imgui.GetStyle().Colors[imgui.Col.WindowBg]))
            imgui.PopClipRect()
            if t == 1 then
                if not circle.reverse then
                    circle.reverse = true
                    circle.time = os.clock()
                else
                    table.remove(button.circles, i)
                end
            end
        end
    end
    local t = ImSaturate((os.clock()-button.time) / speed)
    button.color.w = button.color.w + (button.hovered and 0.8 or -0.8)*t
    button.color.w = button.color.w < 0.2 and 0.2 or (button.color.w > 1 and 1 or button.color.w)
    color = imgui.GetStyle().Colors[imgui.Col.Button]
    color = imgui.GetColorU32(imgui.ImVec4(color.x, color.y, color.z, 0.2))
    dl:AddRectFilled(p, imgui.ImVec2(p.x+size.x, p.y+size.y), color, rounded and imgui.GetStyle().FrameRounding or 0)
    dl:AddRect(p, imgui.ImVec2(p.x+size.x, p.y+size.y), imgui.GetColorU32(button.color), rounded and imgui.GetStyle().FrameRounding or 0)
    local align = imgui.GetStyle().ButtonTextAlign
    imgui.SetCursorPos(imgui.ImVec2(c.x+(size.x-ts.x)*align.x, c.y+(size.y-ts.y)*align.y))
    imgui.Text(text)
    imgui.SetCursorPos(c)
    if imgui.InvisibleButton(label, size) then
        bool = true
        table.insert(button.circles, {animate = true, reverse = false, time = os.clock(), clickpos = imgui.ImVec2(getCursorPos())})
    end
    button.hovered = imgui.IsItemHovered()
    if button.hovered ~= button.state then
        button.state = button.hovered
        button.time = os.clock()
    end
    return bool
end
Пример использования:
Lua:
imgui.PushStyleVar(imgui.StyleVar.FrameRounding, 12)
if imgui.AnimatedButton(u8'КнопОчка', imgui.ImVec2(130, 30), 1.5, true) then clicks = clicks + 1 end
imgui.PopStyleVar()
imgui.Text(u8'Нажатий: '..clicks)
if imgui.AnimatedButton(u8'КнопОчка##2', imgui.ImVec2(130, 30)) then clicks = clicks + 1 end
ezgif-1-77a08866494e.gif
 
Последнее редактирование:

|| NN - NoName ||

Известный
1,049
635
Описание: Получаем скорость с зависимостью от пинга и фпс для функции: getOffsetFromCharInWorldCoords(любого coordmaster'а)

Lua:
function getFullSpeed(speed, ping, min_ping)
    local fps = require('memory').getfloat(0xB7CB50, true)
    local result = (speed / (fps / 60))
    if ping == 1 then
        local ping = sampGetPlayerPing(select(2, sampGetPlayerIdByCharHandle(PLAYER_PED)))
        if min_ping < ping then
            result = (result / (min_ping / ping))
        end
    end
    return result
end

Lua:
local result = getFullSpeed(0.76, 1, 20) -- 0.76 - скорость; 1 - изменять скорость, из-за пинга; 20 - минимальный пинг
 
Последнее редактирование:

_razor

t.me/sssecretway | ТГК: t.me/razor_code
Всефорумный модератор
1,948
3,211
Описание: Возвращает Roll и Direction транспорта по его хендлу.
Lua:
function getCarRealMatrix(handle) -- by seven
    local entity = getCarPointer(handle)
    if entity ~= 0 then
        local carMatrix = memory.getuint32(entity + 0x14, true)
        if carMatrix ~= 0 then
            local rx = memory.getfloat(carMatrix + 0 * 4, true)
            local ry = memory.getfloat(carMatrix + 1 * 4, true)
            local rz = memory.getfloat(carMatrix + 2 * 4, true)

            local dx = memory.getfloat(carMatrix + 4 * 4, true)
            local dy = memory.getfloat(carMatrix + 5 * 4, true)
            local dz = memory.getfloat(carMatrix + 6 * 4, true)
            return rx, ry, rz, dx, dy, dz
        end
    end
end
Пример использования:
Lua:
local rx, ry, rz, dx, dy, dz = getCarRealMatrix(storeCarCharIsInNoSave(PLAYER_PED))
print(rx) -- rollX
 

kizn

\ 0 _ 0 /
Всефорумный модератор
2,408
2,090
Описание: проверка на активность курсора (не SAMP-курсора, а обычного), как в MoonLoader v0.27. Скорее всего только для Windows. Источник

Lua:
local ffi = require("ffi")
ffi.cdef[[
    typedef struct {int x; int y;} POINT;
    typedef struct {int cbSize; int flags; int hCursor; POINT ptScreenPos;} CURSORINFO, *PCURSORINFO;
    int GetCursorInfo(PCURSORINFO pci);
]]

function isCursorActive()
    local pci = ffi.new("CURSORINFO")
    pci.cbSize = ffi.sizeof("CURSORINFO")
    ffi.C.GetCursorInfo(pci)
    return (pci.flags == 1)
end

Пример использования:
Lua:
if isCursorActive() then
    print("ну у тебя курсор активен короче")
end
 

Smeruxa

Известный
1,364
723
Описание: Устанавливает дальность камеры от персонажа
Lua:
function setDistanceAngle(dist)
    local sBase = require 'memory'
    local memory = { 11989248, 11989228, 11989244, 11989224 }
    for i = 1, #memory do
        sBase.setfloat(memory[i], dist)
    end
end
Пример использования:
Lua:
setDistanceAngle(1.2)
 
  • Нравится
Реакции: CaJlaT, kyrtion и chapo

lorgon

Известный
656
271
Описание: Поворачивает двумерный вектор на заданный угол (Источник)

1628213401919.png

Lua:
function rotateVector(vec, ang) --ВАЖНО! Угол измеряется в радианах
  x = vec[1] * math.cos(ang) - vec[2] * math.sin(ang);
  y = vec[1] * math.sin(ang) + vec[2] * math.cos(ang);
  return {x, y}
end

Пример использования:
Lua:
function rotateVector(vec, ang)
  x = vec[1] * math.cos(ang) - vec[2] * math.sin(ang);
  y = vec[1] * math.sin(ang) + vec[2] * math.cos(ang);
  return {x, y}
end

vec = rotateVector({1, 2}, math.rad(90)) -- math.rad переводит градусы в радианы
print(tostring(vec[1]).." "..tostring(vec[2])) -- ( -2;1 )
 

Cosmo

Известный
Друг
653
2,724
Описание:
Кнопки для создания панели-навигации вверху вашего меню.

Function:
HeaderButton = function(bool, str_id)
    local DL = imgui.GetWindowDrawList()
    local ToU32 = imgui.ColorConvertFloat4ToU32
    local result = false
    local label = string.gsub(str_id, "##.*$", "")
    local duration = { 0.5, 0.3 }
    local cols = {
        idle = imgui.GetStyle().Colors[imgui.Col.TextDisabled],
        hovr = imgui.GetStyle().Colors[imgui.Col.Text],
        slct = imgui.GetStyle().Colors[imgui.Col.ButtonActive]
    }

    if not AI_HEADERBUT then AI_HEADERBUT = {} end
     if not AI_HEADERBUT[str_id] then
        AI_HEADERBUT[str_id] = {
            color = bool and cols.slct or cols.idle,
            clock = os.clock() + duration[1],
            h = {
                state = bool,
                alpha = bool and 1.00 or 0.00,
                clock = os.clock() + duration[2],
            }
        }
    end
    local pool = AI_HEADERBUT[str_id]

    local degrade = function(before, after, start_time, duration)
        local result = before
        local timer = os.clock() - start_time
        if timer >= 0.00 then
            local offs = {
                x = after.x - before.x,
                y = after.y - before.y,
                z = after.z - before.z,
                w = after.w - before.w
            }

            result.x = result.x + ( (offs.x / duration) * timer )
            result.y = result.y + ( (offs.y / duration) * timer )
            result.z = result.z + ( (offs.z / duration) * timer )
            result.w = result.w + ( (offs.w / duration) * timer )
        end
        return result
    end

    local pushFloatTo = function(p1, p2, clock, duration)
        local result = p1
        local timer = os.clock() - clock
        if timer >= 0.00 then
            local offs = p2 - p1
            result = result + ((offs / duration) * timer)
        end
        return result
    end

    local set_alpha = function(color, alpha)
        return imgui.ImVec4(color.x, color.y, color.z, alpha or 1.00)
    end

    imgui.BeginGroup()
        local pos = imgui.GetCursorPos()
        local p = imgui.GetCursorScreenPos()
      
        imgui.TextColored(pool.color, label)
        local s = imgui.GetItemRectSize()
        local hovered = imgui.IsItemHovered()
        local clicked = imgui.IsItemClicked()
      
        if pool.h.state ~= hovered and not bool then
            pool.h.state = hovered
            pool.h.clock = os.clock()
        end
      
        if clicked then
            pool.clock = os.clock()
            result = true
        end

        if os.clock() - pool.clock <= duration[1] then
            pool.color = degrade(
                imgui.ImVec4(pool.color),
                bool and cols.slct or (hovered and cols.hovr or cols.idle),
                pool.clock,
                duration[1]
            )
        else
            pool.color = bool and cols.slct or (hovered and cols.hovr or cols.idle)
        end

        if pool.h.clock ~= nil then
            if os.clock() - pool.h.clock <= duration[2] then
                pool.h.alpha = pushFloatTo(
                    pool.h.alpha,
                    pool.h.state and 1.00 or 0.00,
                    pool.h.clock,
                    duration[2]
                )
            else
                pool.h.alpha = pool.h.state and 1.00 or 0.00
                if not pool.h.state then
                    pool.h.clock = nil
                end
            end

            local max = s.x / 2
            local Y = p.y + s.y + 3
            local mid = p.x + max

            DL:AddLine(imgui.ImVec2(mid, Y), imgui.ImVec2(mid + (max * pool.h.alpha), Y), ToU32(set_alpha(pool.color, pool.h.alpha)), 3)
            DL:AddLine(imgui.ImVec2(mid, Y), imgui.ImVec2(mid - (max * pool.h.alpha), Y), ToU32(set_alpha(pool.color, pool.h.alpha)), 3)
        end

    imgui.EndGroup()
    return result
end

Использование:
Example:
-- Где-то вначале
local navigation = {
    current = 1,
    list = { "Home", "Settings", "Misc", "Donate", "About" }
}

-- В onFrame
for i, title in ipairs(navigation.list) do
    if HeaderButton(navigation.current == i, title) then
        navigation.current = i
    end
    if i ~= #navigation.list then
        imgui.SameLine(nil, 30)
    end
end

Пример реализации:

header.gif
 

leekyrave

Известный
419
226
Описание:
Рекурсивное деление текста, функции, которые я видел - не подходят для моих целей, поэтому я написал что-то подобное. На русском языке не проверялось

Function:
function split(text,limit,massive)
    if #text > limit then
        local w = text:sub(1,limit)
        massive[#massive + 1] = w
        if(#text:gsub(w,'') > limit) then
            split(text:gsub(w,''),limit,massive)
        else
            massive[#massive + 1] = text:gsub(w,'')
        end
        return massive
    else
        return {text}
    end

end

Использование:

Example:
local text = [[Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.]]
local result = split(text,50,{})
print(unpack(result))

Результат:

Result:
Lorem Ipsum is simply dummy text of the printing a    nd typesetting industry. Lorem Ipsum has been the     industry's standard dummy text ever since the 1500    s, when an unknown printer took a galley of type a    nd scrambled it to make a type specimen book. It h    as survived not only five centuries, but also the     leap into electronic typesetting, remaining essent    ially unchanged. It was popularised in the 1960s w    ith the release of Letraset sheets containing Lore    m Ipsum passages, and more recently with desktop p    ublishing software like Aldus PageMaker including     versions of Lorem Ipsum.
 
Последнее редактирование:
  • Нравится
Реакции: Judo!

etereon

MQ-Team
Проверенный
327
851
Описание: функция, которая позволяет сменить цвет треугольника над головой (как тут)
Lua:
local memory = require("memory")

function set_triangle_color(r, g, b)
    local bytes= "90909090909090909090909090C744240E00000000909090909090909090909090909090C744240F0000000090B300"
    memory.hex2bin(bytes, 0x60BB41, bytes:len()/2)
    memory.setint8(0x60BB52, r, false)
    memory.setint8(0x60BB69, g, false)
    memory.setint8(0x60BB6F, b, false)
end
 
Последнее редактирование:

#Northn

Pears Project — уже запущен!
Всефорумный модератор
2,654
2,535
Описание: Простой обработчик команд. В первый аргумент пихает полную строку, которую отправил пользователь, а в остальные пихает же все аргументы по очереди. Вдохновлялся рейджмп, скорее всего никто не будет юзать, но пусть будет
Lua:
local _sampRegisterChatCommand_orig = sampRegisterChatCommand

function sampRegisterChatCommand(cmd, callback)
    _sampRegisterChatCommand_orig(cmd, function(args)
        local args_list = {}
        if args:empty() then
            args = nil
        else
            args_list = split(args, '%s+', false)
            for a, b in ipairs(args_list) do
                local num = tonumber(b)
                if num then args_list[a] = num end
            end
        end
        callback(args, table.unpack(args_list))
    end)
end

-- https://www.blast.hk/threads/13380/post-231049
function split(str, delim, plain)
    local tokens, pos, plain = {}, 1, not (plain == false) --[[ delimiter is plain text by default ]]
    repeat
        local npos, epos = string.find(str, delim, pos, plain)
        table.insert(tokens, string.sub(str, pos, npos and npos - 1))
        pos = epos and epos + 1
    until not pos
    return tokens
end

function string.empty(str)
    return string.find(str, '%S') == nil
end
Пример использования:
Lua:
sampRegisterChatCommand("pay", cmd_pay)

function cmd_pay(fullText, id, sum)
    if not fullText or not tonumber(id) or not tonumber(sum) then
        sampAddChatMessage('/pay id sum', -1)
    end
    sampAddChatMessage(string.format("ID: %d; sum: %d", id, sum), -1)
end
 

horacy

Известный
102
92
Описание: взять ник по идентификатору игрока за 0.3DL
к сожалению, выше 15 символов ник не работает
Lua:
local memory = require 'memory'
local nick = 0

function test()
--name(id)
name(995)
end

function name(samp0)
samp10 = getModuleHandle('samp.dll')
samp10 = samp10 + 0x2ACA24
samp10 = readMemory(samp10, 4, false)
samp10 =  samp10 + 0x3DE
samp10 = readMemory(samp10, 4, false)
samp10 = samp10 + 0x8
samp10 = readMemory(samp10, 4, false)
samp10 = samp10 + 0x26
samp0 = samp0 * 0x4
samp10 = samp10 + samp0
samp10 = readMemory(samp10, 4, false)
if samp10 > 0 then
samp10 = samp10 + 0x14
samp11 = readMemory(samp10, 4, false)
samp11 = samp10 + 0x0

samp26 = readMemory(0x8580DC, 4, false)
samp25 = callFunction(samp26, 1, 0, samp11)
if samp25 > 0 then
str = memory.tostring(samp11, samp25, false)
nick = str
--dl.AddMessageToChat(4, "lenght: "..samp25, "", 0xFFFFFF, 0xFFFFFF) samp api 0.3 beta
--dl.AddMessageToChat(4, "address: "..samp11, "", 0xFFFFFF, 0xFFFFFF)
else
--dl.AddMessageToChat(4, "error: "..samp10, "", 0xFFFFFF, 0xFFFFFF)
end
end
end

source: https://ugbase.eu/threads/some-snippets.20983/post-128160
 

Rafinad

Известный
189
63

Исключительно для новичков

Описание: ответ на диалог по поиску текста. (Например в автошколе на АРЗ ответы появляются рандомно)
Lua:
function sendDialog(id, data, answer)
    local i = 0; local flag = false
    for str in data:gmatch("[^\n]+") do
       -- sampAddChatMessage(str, -1) -- выводить каждый пункт text`a диалога
        if str:match(answer) then
            flag = true
            break
        end
        i=i+1
    end
   
    if flag == true then
        sampSendDialogResponse(id, 1, i, "")
    end
   
    return flag
end

Lua:
local hook = require "lib.samp.events"

function hook.onShowDialog(p1, p2, p3, p4, p5, p6)
    if p3:match("Игровое меню") then
        sendDialog(p1, p6, "Донат")
    end
end
Выберет пункт "Донат".
1629942760713.png

Исключительно для новичков

Описание: переход на нижнею директорию getGameDirectory() или getRakBotPath()
Lua:
local path = getGameDirectory(); local bufer = ""; local ender = "";
function Directory()
    sampAddChatMessage("Дефолт: "..path, -1)
    while string.match(path, "\\") do
        bufer, path=string.match(path, "(%S+)\\(%S+)")
        ender=ender..bufer.."\\";
    end
    sampAddChatMessage("Изменили: "..bufer, -1)
end
1629943387871.png
 
Последнее редактирование:

MrBidloKoder

Известный
423
249
Описание: Открытие меню паузы (ESC).
Активировать меню:
Lua:
memory.setuint8(0xBA6748 + 0x33, 1)
Деактивировать меню:
Lua:
memory.setuint8(0xBA6748 + 0x32, 1)
Получить состояние меню:
Lua:
memory.getuint8(0xBA6748 + 0x5C)
Lua:
function pauseMenu(bool)
    if bool then
        memory.setuint8(0xBA6748 + 0x33, 1)
    else
        memory.setuint8(0xBA6748 + 0x32, 1)
    end
end
Пример:
Lua:
local memory = require "memory"

function main()
    pauseMenu(true) -- откроет меню паузы
end

function pauseMenu(bool)
    if bool then
        memory.setuint8(0xBA6748 + 0x33, 1)
    else
        memory.setuint8(0xBA6748 + 0x32, 1)
    end
end
 

kizn

\ 0 _ 0 /
Всефорумный модератор
2,408
2,090
Описание: эмуляция поднятия пикапа (ракботовский sendPickup телепортирует на пикап) [Для RakBot]
Lua:
function sendPickup(pickupId)
    eBs = bitStreamNew()
    bitStreamWriteDWord(eBs, pickupId)
    sendRpc(131, eBs)
    bitStreamDelete(eBs)
end

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

Lua:
sendPickup(175)
 
Последнее редактирование: