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

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Друг
8,765
11,213
Описание: создает такое колхозное окно
1649866914833.png

Lua:
--[[
    title - заголовок
    var - переменная окна
    stateButton - текст на кнопке "свернуть/развернуть" вкладки (используй nil если кнопка не нужна)
    tabs - список вкладок
    selected - выбранная вкладка
    isOpened - статус (свернуто/развернуто)
    sizeClosed - размер панели если свернуто
    sizeOpened - размер панели если развернуто
    windowFlags - флаги окна (так же как и в imgui.Begin())
]]
function imgui.BeginWin11Menu(title, var, stateButton, tabs, selected, isOpened, sizeClosed, sizeOpened, windowFlags)
    imgui.PushStyleVarVec2(imgui.StyleVar.WindowPadding, imgui.ImVec2(0, 0))
    imgui.Begin(title, var, imgui.WindowFlags.NoTitleBar + (windowFlags or 0))

    local size = imgui.GetWindowSize()
    local pos = imgui.GetWindowPos()
    local dl = imgui.GetWindowDrawList()

    local tabSize = sizeClosed - 10

    imgui.SetCursorPos(imgui.ImVec2(size.x - tabSize - 5, 5))
    if imgui.Button('X##'..title..'::closebutton', imgui.ImVec2(tabSize, tabSize)) then if var then var[0] = false end end

    --==[ MAIN BG ]==--
    imgui.SetCursorPos(imgui.ImVec2(sizeClosed, sizeClosed))
    local p = imgui.GetCursorScreenPos()
    dl:AddRectFilled(p, imgui.ImVec2(p.x + size.x - sizeClosed, p.y + size.y - sizeClosed), imgui.GetColorU32Vec4(imgui.GetStyle().Colors[imgui.Col.ChildBg]), imgui.GetStyle().WindowRounding, 1 + 8)
   
    --==[ TITLEBAR ]==--
    imgui.SetCursorPos(imgui.ImVec2(0, 0))
    local p = imgui.GetCursorScreenPos()
    dl:AddRectFilled(p, imgui.ImVec2(p.x + (isOpened[0] and sizeOpened or sizeClosed), p.y + size.y), imgui.GetColorU32Vec4(imgui.GetStyle().Colors[imgui.Col.WindowBg]), imgui.GetStyle().WindowRounding, 1 + 4)
    imgui.SetCursorPos(imgui.ImVec2(tabSize + 10, sizeClosed / 2 - imgui.CalcTextSize(title).y / 2))
    imgui.Text(title)

    --==[ TABS BUTTONS ]==--
    imgui.SetCursorPosY(5)
    if stateButton then
        imgui.SetCursorPosX(5)
        if imgui.Button(stateButton, imgui.ImVec2(tabSize, tabSize)) then isOpened[0] = not isOpened[0] end
    else
        imgui.SetCursorPosY(5 + tabSize + 5)
    end
    for k, v in pairs(tabs) do
        imgui.SetCursorPosX(5)
        imgui.PushStyleColor(imgui.Col.Button, selected[0] == v and imgui.GetStyle().Colors[imgui.Col.ButtonActive] or imgui.GetStyle().Colors[imgui.Col.WindowBg])
        imgui.PushStyleVarVec2(imgui.StyleVar.ButtonTextAlign, imgui.ImVec2(isOpened[0] and 0.1 or 0.5, 0.5))
        if imgui.Button(isOpened[0] and k..' '..v or k, imgui.ImVec2(isOpened[0] and sizeOpened - 10 or tabSize, tabSize)) then selected[0] = v end
        if imgui.IsItemHovered() then
            imgui.BeginTooltip()
            imgui.Text(k..' '..v)
            imgui.EndTooltip()
        end
        imgui.PopStyleVar()
        imgui.PopStyleColor()
    end

    --==[ CHILD ]==--
    imgui.SetCursorPos(imgui.ImVec2(sizeClosed + 5, sizeClosed + 5))
    imgui.PushStyleVarVec2(imgui.StyleVar.WindowPadding, imgui.ImVec2(15, 15))
    imgui.BeginChild(title..'::mainchild', imgui.ImVec2(size.x - sizeClosed - 5, size.y - sizeClosed - 5), true)
end

function imgui.EndWin11Menu()
    imgui.EndChild()
    imgui.End()
    imgui.PopStyleVar(2)
end
Lua:
-- перед окном
local renderWindow = imgui.new.bool(true) -- статус окна

-- массив с некоторыми настройками окна (можно использовать вне массива)
local menu = {
    opened = imgui.new.bool(false),
    selected = {[0] = ''}, -- выбранный пункт (получать через menu.selected[0])
    tabs = { -- список вкладок, [иконка/буква] = название вкладки
        [fa.ICON_FA_CAR] = u8' Машина',
        [fa.ICON_FA_USER] = u8' Лошпед',
        [fa.ICON_FA_EYE] = u8' Глаз',
    }
}

-- окно
local newFrame = imgui.OnFrame(
    function() return renderWindow[0] end,
    function(player)
        local resX, resY = getScreenResolution()
        local sizeX, sizeY = 300, 300
        imgui.SetNextWindowPos(imgui.ImVec2(resX / 2, resY / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(sizeX, sizeY), imgui.Cond.FirstUseEver)
        imgui.BeginWin11Menu('Win11 menu example', renderWindow, false, menu.tabs, menu.selected, menu.opened, 40, 100)

        if menu.selected[0] == u8' Машина' then
            imgui.Checkbox('checkbox', placeholder_bool)
        elseif menu.selected[0] == u8' Лошпед' then
            -- code
        elseif menu.selected[0] == u8' Глаз' then
            -- code
        end

        imgui.EndWin11Menu()
    end
)

Описание: функция для простого взаимодействия с JSON
Lua:
function json(jsonFilePath)
    local class = {}
    function class:Save(t)
        file = io.open(jsonFilePath, "w")
        file:write(encodeJson(t or {}))
        file:close()
    end

    function class:Load(defaultTable)
        if not doesFileExist(jsonFilePath) then class:Save(defaultTable or {}) end
        local file = io.open(jsonFilePath, "r+")
        local jsonInString = file:read("*a")
        file:close()
        return decodeJson(jsonInString) or {}
    end

    return class
end
Lua:
--[[
    json(файл):
        Save(таблица) - сохранить таблицу в файл
        Load(DefaultTable) -- загрузить таблицу из файла, (если файла нет, то создает файл и записывает в него DefaultTable)
]]

local defaultTable = {'Это первый элемент в твоем массиве'}
local jsonFile = getWorkingDirectory()..'\\config\\myJsonConfig.json'
local list = json(jsonFile):Load(defaultTable)

function main()
    while not isSampAvailable() do wait(0) end
    sampRegisterChatCommand('table.add', function(arg)
        table.insert(list, arg)
        json(jsonFile):Save(list)
    end)
    sampRegisterChatCommand('table.print', function()
        for k, v in ipairs(list) do
            print(k, v)
        end
    end)
    wait(-1)
end
 
Последнее редактирование:

sizeoftrickster

…And Megadeth For All?
Проверенный
121
435
Описание: аналог sampAddChatMessage, только без зависимости от SAMPFUNCS и возможность использовать на версии SA:MP 0.3.7 (R1, R2, R3, R4). Требует FFI и Memory.
Lua:
function AddMessage( szText, ulColor ) 
    local ffi    = require('ffi')
    local memory = require('memory')
    local function getSAMPHandle()
        local samp = nil
        if ( not samp ) then
            samp = getModuleHandle( 'samp.dll' )
            if ( samp == 0 ) then
                return 0
            end
        end
        return samp
    end
    local function getSAMPVersion()
        local sampVersionCode = {
            [1] = 'notLoaded',    [2] = 'unknown',
            [3] = '0.3.7-R1',   [4] = '0.3.7-R2',
            [5] = '0.3.7-R3',   [6] = '0.3.7-R4'
        }
        local sampVersion = sampVersionCode[2]
        if ( sampVersion ~= sampVersionCode[2] ) then
            return sampVersion
        end
        local samp = getSAMPHandle()
        local EntryPoint = memory.getuint32( ( samp + memory.getint32( samp + 0x3C ) ) + 0x28 )
        if ( EntryPoint == 0x31DF13 ) then
            sampVersion = sampVersionCode[3]
        elseif ( EntryPoint == 0x3195DD ) then
            sampVersion = sampVersionCode[4]
        elseif ( EntryPoint == 0xCC4D0 ) then
            sampVersion = sampVersionCode[5]
        elseif ( EntryPoint == 0xCBCB0 ) then
            sampVersion = sampVersionCode[6]
        end
        return sampVersion
    end

    local handle     = getSAMPHandle()
    if ( handle == 0 or handle == nil ) then
        return false
    end
    local version    = getSAMPVersion()
    if ( version == 'unknown' or version == 'notLoaded' ) then
        return false
    end
    local samp = {
        ['pChat']  = {
            ['0.3.7-R1'] = memory.getint32( handle + 0x21A0E4, true ),
            ['0.3.7-R2'] = memory.getint32( handle + 0x21A0EC, true ),
            ['0.3.7-R3'] = memory.getint32( handle + 0x26E8C8, true ),
            ['0.3.7-R4'] = memory.getint32( handle + 0x26E9F8, true )
        },
        ['Offset'] = {
            ['0.3.7-R1'] = handle + 0x645A0,
            ['0.3.7-R2'] = handle + 0x64670,
            ['0.3.7-R3'] = handle + 0x679F0,
            ['0.3.7-R4'] = handle + 0x68130
        }
    }
    local args = {
        ['pChat']   = ffi.cast( 'void*', samp['pChat'][version] ),
        ['szText']  = ffi.cast( 'const char*', tostring(szText) ),
        ['ulColor'] = tonumber( ulColor )
    }
    return ffi.cast( 'void(__thiscall*)(void*, unsigned long, const char*)', samp['Offset'][version] )( args['pChat'], args['ulColor'], args['szText'] )
end
Пример использования:
Lua:
require('moonloader')
local wm = require( 'windows.message' )

function main()
    addEventHandler( 'onWindowMessage', function( uMsg, wParam, lParam )
        if ( uMsg == wm.WM_KEYDOWN or uMsg == wm.WM_SYSKEYDOWN ) then
            if ( wParam == VK_X ) then
                AddMessage( 'Привет!', -1 )
            end
        end
    end )
    wait(-1)
end
 

Rice.

https://t.me/riceoff
Модератор
1,681
1,388
Описание: Получение заглавных букв в строчке
Lua:
function getCapitalLetter(text, mode)
    local num = 0
    local a = {}
    local b = tostring(text)

    if mode == 1 then
        string_world = 'ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ'
    elseif mode == 2 then
        string_world = 'QWERTYUIOPASDFGHJKLZXCVBNM'
    elseif mode == 3 then
        string_world = 'ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮQWERTYUIOPASDFGHJKLZXCVBNM'
    end

    for i = 1, #b do -- Разбиваем строчку на кажлый символ
        a[#a + 1] = b:sub(i, i)
    end

    for k, v in pairs(a) do -- Сверяем каждый символ со строчкой
        if string.find(string_world, v, nil, true) then
            num = num + 1
        end
    end

    return num
end
Аргументы:
АргументТипОписание
textstringТекст, в котором будут искаться заглавные буквы
modenumberРежим, в котором будет проверяться строчка (1 - только русские буквы, 2 - только английские буквы, 3 - русские и английские буквы
Пример использования:
Lua:
local samp = require('samp.events')

function samp.onServerMessage(color, text)
    if getCapitalLetter(text, 1) > 10 then
        return{color, text .. ' {FF0000}| Возможен капс (число заглавных букв: ' .. getCapitalLetter(text, 1) .. ')'}
    end
end
FtZHQHbP.jpg
 

|| NN - NoName ||

Известный
1,049
628
Описание: Получение заглавных букв в строчке
Lua:
function getCapitalLetter(text, mode)
    local num = 0
    local a = {}
    local b = tostring(text)

    if mode == 1 then
        string_world = 'ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ'
    elseif mode == 2 then
        string_world = 'QWERTYUIOPASDFGHJKLZXCVBNM'
    elseif mode == 3 then
        string_world = 'ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮQWERTYUIOPASDFGHJKLZXCVBNM'
    end

    for i = 1, #b do -- Разбиваем строчку на кажлый символ
        a[#a + 1] = b:sub(i, i)
    end

    for k, v in pairs(a) do -- Сверяем каждый символ со строчкой
        if string.find(string_world, v, nil, true) then
            num = num + 1
        end
    end

    return num
end
Аргументы:
АргументТипОписание
textstringТекст, в котором будут искаться заглавные буквы
modenumberРежим, в котором будет проверяться строчка (1 - только русские буквы, 2 - только английские буквы, 3 - русские и английские буквы
Пример использования:
Lua:
local samp = require('samp.events')

function samp.onServerMessage(color, text)
    if getCapitalLetter(text, 1) > 10 then
        return{color, text .. ' {FF0000}| Возможен капс (число заглавных букв: ' .. getCapitalLetter(text, 1) .. ')'}
    end
end
FtZHQHbP.jpg

???
 

Cosmo

Известный
Друг
646
2,596
Получение заглавных букв в строчке
Lua:
function getCapitalLetersCount(text, mode)
    mode = mode or 3
    local count = 0
    local reg = "[A-ZА-ЯЁ]"
    
    if mode == 1 then
        reg = "[A-Z]"
    elseif mode == 2 then
        reg = "[А-ЯЁ]"
    end
    
    for l in string.gmatch(text, reg) do
        count = count + 1
    end
    return count
end
 

Parazitas

Известный
19
8
Описание: Изменяет цвет HP бара у игроков над головами
Lua:
function setHealthColor(hpHigh, hpLow)
     local samp = getModuleHandle("samp.dll")
     memory.setuint32(samp + 0x68B0C, hpHigh, true) -- полная полоска хп
     memory.setuint32(samp + 0x68B33, hpLow, true) -- задний фон
end
Пример использования:
Lua:
setHealthColor(0xFFFFFFFF, 0xFF000000)
Посмотреть вложение 92143


Lua:
function setArmourColor(armourHigh, armourLow)
     local samp = getModuleHandle("samp.dll")
     memory.setuint32(samp + 0x68DD5, armourHigh, true) -- full armour bar
     memory.setuint32(samp + 0x68E00, armourLow, true) -- the background
end
Пример использования:
Lua:
setArmourColor(0xFFFFFFFF, 0xFF000000)
 

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Друг
8,765
11,213
Функция для сохранения/чтения из JSON
Lua:
function json(filePath)
    local filePath = getWorkingDirectory()..'\\config\\'..(filePath:find('(.+).json') and filePath or filePath..'.json')
    local class = {}
    if not doesDirectoryExist(getWorkingDirectory()..'\\config') then
        createDirectory(getWorkingDirectory()..'\\config')
    end
    
    function class:Save(tbl)
        if tbl then
            local F = io.open(filePath, 'w')
            F:write(encodeJson(tbl) or {})
            F:close()
            return true, 'ok'
        end
        return false, 'table = nil'
    end

    function class:Load(defaultTable)
        if not doesFileExist(filePath) then
            class:Save(defaultTable or {})
        end
        local F = io.open(filePath, 'r+')
        local TABLE = decodeJson(F:read() or {})
        F:close()
        for def_k, def_v in next, defaultTable do
            if TABLE[def_k] == nil then
                TABLE[def_k] = def_v
            end
        end
        return TABLE
    end

    return class
end
Примеры вызова функций:
Загрузка/создание файла:
--[[
    table var = json(filePath):Load(defaultTable)
    var - переменная в которую будет записана таблица
    filePath - название файла (например: "myConfig.json")
    defaultTable - таблица, которая будет создана по умолчанию
        (так же если в загружаемом конфиге нет ключа из стандартной таблицы, то он будет создан)
]]

--Пример:

local settings = json('myFirstConfig.json'):Load({
    ['type_string'] = 'hello world',
    ['type_int'] = 550,
    ['type_bool'] = true
})

-- теперь загруженные данные мы можем получать так:
print(settings['type_string']) -- будет выведено: "hello world" (так же вместо таблица['ключ'] можно таблица.ключ, например: settings.type_string)

Сохранение:
--[[
    bool status, string code = json(string filePath):Save(table tableToSave)
        - status - статус сохранения (true - сохранено, false - ошибка)
        - code - на это поебать, тут всегда либо nil, либо "table = nil" (зависит от статуса сохранения)
        - filePath - название файла (например: "myConfig.json")
        - tableToSave - таблица которая будет сохранена
]]
-- Пример:
local status, code = json('myFirstConfig.json'):Save(settings)
sampAddChatMessage(status and 'Настройки сохранены!' or 'Настройки не были сохранены: '..code, -1)
Lua:
function json(filePath)
    local filePath = getWorkingDirectory()..'\\config\\'..(filePath:find('(.+).json') and filePath or filePath..'.json')
    local class = {}
    if not doesDirectoryExist(getWorkingDirectory()..'\\config') then
        createDirectory(getWorkingDirectory()..'\\config')
    end
    
    function class:Save(tbl)
        if tbl then
            local F = io.open(filePath, 'w')
            F:write(encodeJson(tbl) or {})
            F:close()
            return true, 'ok'
        end
        return false, 'table = nil'
    end

    function class:Load(defaultTable)
        if not doesFileExist(filePath) then
            class:Save(defaultTable or {})
        end
        local F = io.open(filePath, 'r+')
        local TABLE = decodeJson(F:read() or {})
        F:close()
        for def_k, def_v in next, defaultTable do
            if TABLE[def_k] == nil then
                TABLE[def_k] = def_v
            end
        end
        return TABLE
    end

    return class
end

require('jCfg')

local settings = json('cfg123.json'):Load({
    ['text'] = 'hello world',
    ['number'] = 550,
    ['state'] = true
})

function main()
    while not isSampAvailable() do wait(0) end
    sampRegisterChatCommand('json.print', function()
        for k, v in next, settings do
            sampAddChatMessage(k..' = '..tostring(v), -1)
        end
    end)
    sampRegisterChatCommand('json.append', function(arg)
        if arg:match('(.+) = (.+)') then
            local k, v = arg:match('(.+) = (.+)')
            settings[k] = v
            json('cfg123.json'):Save(settings)
            sampAddChatMessage('ok!', -1)
        else
            sampAddChatMessage('incorrect arg', -1)
        end
    end)
    wait(-1)
end
 

SADFI2259X

Участник
92
75
Change samp started text
Lua:
function loaded_msg()
memory.fill(sampGetBase() + 463840, 0, 1, true)
memory.fill(sampGetChatInfoPtr() + 306, 0x0, 25200)
memory.write(sampGetChatInfoPtr() + 306, 25562, 4, 0x0)
memory.write(sampGetChatInfoPtr() + 0x63DA, 1, 1)
sampAddChatMessage('SAMP 0.3.7 R1 {ffffff}Started', -1)
end

chnage player skin model by id
Lua:
function ChangerSkinNewEdition(skinid)
    requestModel(skinid)
    loadAllModelsNow()
    setPlayerModel(PLAYER_HANDLE, skinid)
end
 
Последнее редактирование:

ruslol

Участник
17
73

Описание:

Улучшенный слайдер в стиле Material Design.

Material Design Slider:
function imgui.MaterialSlider(id, width, max_value, value, color, bg_color)
    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
    if UI_MATERIALSLIDER == nil then UI_MATERIALSLIDER = {} end
    if not UI_MATERIALSLIDER[id] then UI_MATERIALSLIDER[id] = {height = width / 12, curr_width = 0, clicked = nil, c_pos_y = nil, c_pos_y_old = nil, c_pos_x = imgui.GetCursorPos().x + imgui.GetWindowPos().x, text = nil, hovered = {nil, nil}} end
    local pool = UI_MATERIALSLIDER[id]
    if max_value ~= nil and value ~= nil and pool["clicked"] == nil then
        pool["curr_width"] = width * (value / (max_value + 1))
        pool["text"] = tostring(value)
    end
    if pool["c_pos_y"] == nil then pool["c_pos_y"] = imgui.GetCursorPos().y + (pool["height"] / 2) end
    if pool["c_pos_y_old"] == nil then pool["c_pos_y_old"] = pool["c_pos_y"] end
    imgui.SetCursorPosY(pool["c_pos_y"])
    imgui.PushStyleVar(imgui.StyleVar.ChildWindowRounding, pool["height"])
    imgui.PushStyleColor(imgui.Col.ChildWindowBg, imgui.ImVec4(0, 0, 0, 0))
    local draw_list = imgui.GetWindowDrawList()
    draw_list:AddRectFilled(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x, imgui.GetCursorPos().y + imgui.GetWindowPos().y - imgui.GetScrollY()), imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x + width, imgui.GetCursorPos().y + imgui.GetWindowPos().y + pool["height"] - imgui.GetScrollY()), imgui.GetColorU32(bg_color or imgui.GetStyle().Colors[imgui.Col.TextDisabled]), pool["height"] / 2)
    imgui.BeginChild("##" .. id, imgui.ImVec2(width, pool["height"]))
    if pool["curr_width"] < pool["height"] / 2 then
        draw_list:PathArcTo(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x + (pool["height"] / 2), imgui.GetCursorPos().y + imgui.GetWindowPos().y + (pool["height"] / 2) - imgui.GetScrollY()), pool["height"] / 2, math.acos(-(((pool["height"] / 2) - pool["curr_width"]) / (pool["height"] / 2))), math.acos(((pool["height"] / 2) - pool["curr_width"]) / (pool["height"] / 2)) + 3.141)
        draw_list:PathFillConvex(imgui.GetColorU32(color or imgui.GetStyle().Colors[imgui.Col.ButtonActive]))
        draw_list:PathClear()
    else
        draw_list:AddRectFilled(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x, imgui.GetCursorPos().y + imgui.GetWindowPos().y - imgui.GetScrollY()), imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x + pool["curr_width"], imgui.GetCursorPos().y + imgui.GetWindowPos().y + pool["height"] - imgui.GetScrollY()), imgui.GetColorU32(color or imgui.GetStyle().Colors[imgui.Col.ButtonActive]), pool["height"] / 2)
    end
    imgui.EndChild()
    imgui.PopStyleColor()
    imgui.PopStyleVar()
    if imgui.IsItemClicked() then pool["clicked"] = true end
    if imgui.IsItemHovered() then
        if pool["hovered"][1] == nil then pool["hovered"][1] = os.clock() end
        pool["hovered"][2] = nil
    else
        if pool["hovered"][2] == nil then pool["hovered"][2] = os.clock() end
        pool["hovered"][1] = nil
    end
    if pool["hovered"][1] ~= nil then
        pool["height"] = bringFloatTo(pool["height"], width / 8, pool["hovered"][1], 0.3)
        pool["c_pos_y"] = bringFloatTo(pool["c_pos_y"], pool["c_pos_y_old"] - ((((width/8) - (width/16)) / 2) * 0.5), pool["hovered"][1], 0.3)
    elseif pool["hovered"][2] ~= nil then
        pool["height"] = bringFloatTo(pool["height"], width / 12, pool["hovered"][2], 0.3)
        pool["c_pos_y"] = bringFloatTo(pool["c_pos_y"], pool["c_pos_y_old"], pool["hovered"][2], 0.3)
    end
    if imgui.IsMouseDown(0) and pool["clicked"] then
        if imgui.GetMousePos().x - pool["c_pos_x"] > width then pool["curr_width"] = width
        elseif imgui.GetMousePos().x - pool["c_pos_x"] < 0 then pool["curr_width"] = 0
        else pool["curr_width"] = imgui.GetMousePos().x - pool["c_pos_x"] end
        if max_value ~= nil and max_value > 1 then
            local nearest = nil
            local min_dist = nil
            for i = 0, max_value do
                if nearest == nil then nearest = i end
                if min_dist == nil then min_dist = math.abs((i * (width / max_value)) - pool["curr_width"]) end
                if math.abs((i * (width / max_value)) - pool["curr_width"]) < min_dist then
                    min_dist = math.abs((i * (width / max_value)) - pool["curr_width"])
                    nearest = i
                end
            end
            pool["curr_width"] = nearest * (width / max_value)
            pool["text"] = tostring(nearest)
        end
    elseif not imgui.IsMouseDown(0) and pool["clicked"] then pool["clicked"] = false end
    return pool["text"] or pool["curr_width"]
end


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


Аргумент​

Тип данных​

Статус​

Описание​

idstringОбязательныйУникальный id виджета. У каждого виджета свой id.
widthfloatОбязательныйШирина виджета.
max_valuefloatНеобязательныйМаксимальное значение слайдера. К примеру, указав 4,
виджет распределит свою ширину на 4 части так, чтобы
каждая часть возвращала значения от 1 до 4 соответственно.
Если ничего не указать то макс. значение будет равно ширине.
(чекайте примеры если нихуя не понятно)
valuefloatНеобязательныйЗначение по умолчанию. Если max_value чему-то равно,
к примеру 4, и мы хотим чтобы по умолчанию слайдер был
выкручен к примеру до 3, то указываем в параметр value значение 3.
colorImVec4НеобязательныйЦвет слайдера. По умолчанию равен цвету ButtonActive.
bg_colorImVec4НеобязательныйЦвет заднего фона слайдера. По умолчанию равен цвету TextDisabled.


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


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

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

    imgui.Begin("test", mws, imgui.WindowFlags.NoMove)
        -- обязателен флаг imgui.WindowFlags.NoMove для окна, чтобы оно не убегало

        imgui.SetCursorPos(imgui.ImVec2(20, 28))
        text = imgui.MaterialSlider("1", 156)
        -- мы присваиваем переменной text значение, которое вернет imgui.MaterialSlider,
        -- тоесть строку с текущим значением слайдера.
        -- как видите остальные параметры я даже не ввёл, так как они необязательны

        imgui.SetCursorPos(imgui.ImVec2(200, 34))

        imgui.Text(text)


        imgui.SetCursorPos(imgui.ImVec2(20, 78))
        text2 = imgui.MaterialSlider("2", 128, 4, nil, nil, imgui.ImVec4(42/255, 121/255, 254/255, 0.36))
        -- тут мы хотим чтобы максимальное значение было равно 4

        imgui.SetCursorPos(imgui.ImVec2(172, 82))

        imgui.Text(text2)


        imgui.SetCursorPos(imgui.ImVec2(20, 128))
        text3 = imgui.MaterialSlider("3", 156, 10, 4, imgui.ImVec4(1, 246/255, 137/255, 1), imgui.ImVec4(1, 246/255, 137/255, 0.36))
        -- тут у нас мало того что максимальное значение равно 10,
        -- так и еще значение по умолчанию равно 4
        
        imgui.SetCursorPos(imgui.ImVec2(200, 134))

        imgui.Text(text3)

    imgui.End()
end

 

#Northn

Police Helper «Reborn» — уже ШЕСТЬ лет!
Всефорумный модератор
2,634
2,482

Описание:

Улучшенный слайдер в стиле Material Design.

Material Design Slider:
function imgui.MaterialSlider(id, width, max_value, value, color, bg_color)
    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
    if UI_MATERIALSLIDER == nil then UI_MATERIALSLIDER = {} end
    if not UI_MATERIALSLIDER[id] then UI_MATERIALSLIDER[id] = {height = width / 12, curr_width = 0, clicked = nil, c_pos_y = nil, c_pos_y_old = nil, c_pos_x = imgui.GetCursorPos().x + imgui.GetWindowPos().x, text = nil, hovered = {nil, nil}} end
    local pool = UI_MATERIALSLIDER[id]
    if max_value ~= nil and value ~= nil and pool["clicked"] == nil then
        pool["curr_width"] = width * (value / (max_value + 1))
        pool["text"] = tostring(value)
    end
    if pool["c_pos_y"] == nil then pool["c_pos_y"] = imgui.GetCursorPos().y + (pool["height"] / 2) end
    if pool["c_pos_y_old"] == nil then pool["c_pos_y_old"] = pool["c_pos_y"] end
    imgui.SetCursorPosY(pool["c_pos_y"])
    imgui.PushStyleVar(imgui.StyleVar.ChildWindowRounding, pool["height"])
    imgui.PushStyleColor(imgui.Col.ChildWindowBg, imgui.ImVec4(0, 0, 0, 0))
    local draw_list = imgui.GetWindowDrawList()
    draw_list:AddRectFilled(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x, imgui.GetCursorPos().y + imgui.GetWindowPos().y - imgui.GetScrollY()), imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x + width, imgui.GetCursorPos().y + imgui.GetWindowPos().y + pool["height"] - imgui.GetScrollY()), imgui.GetColorU32(bg_color or imgui.GetStyle().Colors[imgui.Col.TextDisabled]), pool["height"] / 2)
    imgui.BeginChild("##" .. id, imgui.ImVec2(width, pool["height"]))
    if pool["curr_width"] < pool["height"] / 2 then
        draw_list:PathArcTo(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x + (pool["height"] / 2), imgui.GetCursorPos().y + imgui.GetWindowPos().y + (pool["height"] / 2) - imgui.GetScrollY()), pool["height"] / 2, math.acos(-(((pool["height"] / 2) - pool["curr_width"]) / (pool["height"] / 2))), math.acos(((pool["height"] / 2) - pool["curr_width"]) / (pool["height"] / 2)) + 3.141)
        draw_list:PathFillConvex(imgui.GetColorU32(color or imgui.GetStyle().Colors[imgui.Col.ButtonActive]))
        draw_list:PathClear()
    else
        draw_list:AddRectFilled(imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x, imgui.GetCursorPos().y + imgui.GetWindowPos().y - imgui.GetScrollY()), imgui.ImVec2(imgui.GetCursorPos().x + imgui.GetWindowPos().x + pool["curr_width"], imgui.GetCursorPos().y + imgui.GetWindowPos().y + pool["height"] - imgui.GetScrollY()), imgui.GetColorU32(color or imgui.GetStyle().Colors[imgui.Col.ButtonActive]), pool["height"] / 2)
    end
    imgui.EndChild()
    imgui.PopStyleColor()
    imgui.PopStyleVar()
    if imgui.IsItemClicked() then pool["clicked"] = true end
    if imgui.IsItemHovered() then
        if pool["hovered"][1] == nil then pool["hovered"][1] = os.clock() end
        pool["hovered"][2] = nil
    else
        if pool["hovered"][2] == nil then pool["hovered"][2] = os.clock() end
        pool["hovered"][1] = nil
    end
    if pool["hovered"][1] ~= nil then
        pool["height"] = bringFloatTo(pool["height"], width / 8, pool["hovered"][1], 0.3)
        pool["c_pos_y"] = bringFloatTo(pool["c_pos_y"], pool["c_pos_y_old"] - ((((width/8) - (width/16)) / 2) * 0.5), pool["hovered"][1], 0.3)
    elseif pool["hovered"][2] ~= nil then
        pool["height"] = bringFloatTo(pool["height"], width / 12, pool["hovered"][2], 0.3)
        pool["c_pos_y"] = bringFloatTo(pool["c_pos_y"], pool["c_pos_y_old"], pool["hovered"][2], 0.3)
    end
    if imgui.IsMouseDown(0) and pool["clicked"] then
        if imgui.GetMousePos().x - pool["c_pos_x"] > width then pool["curr_width"] = width
        elseif imgui.GetMousePos().x - pool["c_pos_x"] < 0 then pool["curr_width"] = 0
        else pool["curr_width"] = imgui.GetMousePos().x - pool["c_pos_x"] end
        if max_value ~= nil and max_value > 1 then
            local nearest = nil
            local min_dist = nil
            for i = 0, max_value do
                if nearest == nil then nearest = i end
                if min_dist == nil then min_dist = math.abs((i * (width / max_value)) - pool["curr_width"]) end
                if math.abs((i * (width / max_value)) - pool["curr_width"]) < min_dist then
                    min_dist = math.abs((i * (width / max_value)) - pool["curr_width"])
                    nearest = i
                end
            end
            pool["curr_width"] = nearest * (width / max_value)
            pool["text"] = tostring(nearest)
        end
    elseif not imgui.IsMouseDown(0) and pool["clicked"] then pool["clicked"] = false end
    return pool["text"] or pool["curr_width"]
end


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


Аргумент​

Тип данных​

Статус​

Описание​

idstringОбязательныйУникальный id виджета. У каждого виджета свой id.
widthfloatОбязательныйШирина виджета.
max_valuefloatНеобязательныйМаксимальное значение слайдера. К примеру, указав 4,
виджет распределит свою ширину на 4 части так, чтобы
каждая часть возвращала значения от 1 до 4 соответственно.
Если ничего не указать то макс. значение будет равно ширине.
(чекайте примеры если нихуя не понятно)
valuefloatНеобязательныйЗначение по умолчанию. Если max_value чему-то равно,
к примеру 4, и мы хотим чтобы по умолчанию слайдер был
выкручен к примеру до 3, то указываем в параметр value значение 3.
colorImVec4НеобязательныйЦвет слайдера. По умолчанию равен цвету ButtonActive.
bg_colorImVec4НеобязательныйЦвет заднего фона слайдера. По умолчанию равен цвету TextDisabled.


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


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

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

    imgui.Begin("test", mws, imgui.WindowFlags.NoMove)
        -- обязателен флаг imgui.WindowFlags.NoMove для окна, чтобы оно не убегало

        imgui.SetCursorPos(imgui.ImVec2(20, 28))
        text = imgui.MaterialSlider("1", 156)
        -- мы присваиваем переменной text значение, которое вернет imgui.MaterialSlider,
        -- тоесть строку с текущим значением слайдера.
        -- как видите остальные параметры я даже не ввёл, так как они необязательны

        imgui.SetCursorPos(imgui.ImVec2(200, 34))

        imgui.Text(text)


        imgui.SetCursorPos(imgui.ImVec2(20, 78))
        text2 = imgui.MaterialSlider("2", 128, 4, nil, nil, imgui.ImVec4(42/255, 121/255, 254/255, 0.36))
        -- тут мы хотим чтобы максимальное значение было равно 4

        imgui.SetCursorPos(imgui.ImVec2(172, 82))

        imgui.Text(text2)


        imgui.SetCursorPos(imgui.ImVec2(20, 128))
        text3 = imgui.MaterialSlider("3", 156, 10, 4, imgui.ImVec4(1, 246/255, 137/255, 1), imgui.ImVec4(1, 246/255, 137/255, 0.36))
        -- тут у нас мало того что максимальное значение равно 10,
        -- так и еще значение по умолчанию равно 4
       
        imgui.SetCursorPos(imgui.ImVec2(200, 134))

        imgui.Text(text3)

    imgui.End()
end

Это не Material Design
 
  • Вау
Реакции: ruslol

shrug228

Активный
212
75
Описание: позволяет узнать, находится ли персонаж на пассажирском сидении.
Lua:
function isCharOnCarPassengerSeat(veh, ped)
    for i = 1, 3 do
        if getCharInCarPassengerSeat(veh, i) == ped then
            return true
        end
    end
    return false
end
Пример использования: не придумал, но тут вряд ли и есть смысл)

Описание: Получение заглавных букв в строчке
Lua:
function getCapitalLetter(text, mode)
    local num = 0
    local a = {}
    local b = tostring(text)

    if mode == 1 then
        string_world = 'ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ'
    elseif mode == 2 then
        string_world = 'QWERTYUIOPASDFGHJKLZXCVBNM'
    elseif mode == 3 then
        string_world = 'ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮQWERTYUIOPASDFGHJKLZXCVBNM'
    end

    for i = 1, #b do -- Разбиваем строчку на кажлый символ
        a[#a + 1] = b:sub(i, i)
    end

    for k, v in pairs(a) do -- Сверяем каждый символ со строчкой
        if string.find(string_world, v, nil, true) then
            num = num + 1
        end
    end

    return num
end
Аргументы:
АргументТипОписание
textstringТекст, в котором будут искаться заглавные буквы
modenumberРежим, в котором будет проверяться строчка (1 - только русские буквы, 2 - только английские буквы, 3 - русские и английские буквы
Пример использования:
Lua:
local samp = require('samp.events')

function samp.onServerMessage(color, text)
    if getCapitalLetter(text, 1) > 10 then
        return{color, text .. ' {FF0000}| Возможен капс (число заглавных букв: ' .. getCapitalLetter(text, 1) .. ')'}
    end
end
FtZHQHbP.jpg
Для проверки на загловность букв разве не лучше делать вот так?
Lua:
if symbol == symbol:upper() then
    -- code
end
 
Последнее редактирование:
  • Bug
  • Вау
Реакции: The Spark и RoflHaHaWF

Cosmo

Известный
Друг
646
2,596
Описание: позволяет узнать, находится ли персонаж на пассажирском сидении.
А если это какой-нибудь автобус или мотоцикл где не 3 места? Ищи, в муне есть функция получения колличества мест в т/с


Для проверки на загловность букв разве не лучше делать вот так?
string.upper/lower не поддерживает кириллицу (русские символы)
 
  • Нравится
Реакции: PanSeek и imring

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Друг
8,765
11,213
Описание: небольшая функция для серверов аризоны (писал для своего скрипта, мб кому-нибудь пригодится)
Функции:
  • находится ли игрок на сервере аризоны
  • играет ли игрок с лаунчера
  • получение всех лаунчерных машин
  • получение всех лаунчерных скинов
Lua:
function Arizona()
    local c = {}
    
    function c:IsArizona(callback)
        if not doesDirectoryExist( getWorkingDirectory()..'\\resource' ) then createDirectory( getWorkingDirectory()..'\\resource' ) end
        local ip, port = sampGetCurrentServerAddress()
        local file = getWorkingDirectory()..'\\resource\\ARIZONA_SERVERS.json'
        local url = 'https://arizona-ping.react.group/desktop/ping/Arizona/ping.json'
        local dlstatus = require('moonloader').download_status
        downloadUrlToFile(url, file, function (id, status, p1, p2) 
            if status == dlstatus.STATUSEX_ENDDOWNLOAD then
                local F = {}
                for line in io.lines(file) do
                    table.insert(F, line)
                end
                local data = decodeJson(table.concat(F, '\n'))
                if data['query'] then
                    for k, v in ipairs(data['query']) do
                        if ip == data['query'][k]['ip'] and port == data['query'][k]['port'] then
                            --return true, data['query'][k]['name'], data['query'][k]['number']
                            callback(true, data['query'][k]['name'], data['query'][k]['number'])
                            return
                        end
                    end
                end
                callback(false, sampGetCurrentServerName(), -1)
            end
        end)
    end

    function c:IsLauncher()
        return doesFileExist(getGameDirectory()..'\\_CoreGame.asi')
    end

    function c:GetSkins()
        local result = {}
        local count = 0
        if c:IsLauncher() and doesFileExist(getGameDirectory()..'\\SAMP\\SAMP.ide') then
            local start = -1
            local lineIndex = 0
            for line in io.lines(getGameDirectory()..'\\SAMP\\SAMP.ide') do
                lineIndex = lineIndex + 1
                if line == 'ped' then
                    start = lineIndex + 1
                end
                if lineIndex > start then
                    local line = line:gsub(' ', '')
                    if line:find('(%d+),(.+),.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+') then
                        count = count + 1
                        local id, model = line:match('(%d+),(.+),.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+')
                        result[tonumber(id)] = model
                    end
                end
            end
        end
        return result, count
    end

    function c:GetVehicles()
        local result = {}
        local count = 0
        if c:IsLauncher() and doesFileExist(getGameDirectory()..'\\arizona\\vehicles.ide') then
            for line in io.lines(getGameDirectory()..'\\arizona\\vehicles.ide') do
                if line:find('(%d+),(.+),.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+') then
                    count = count + 1
                    local id, model = line:match('(%d+),(.+),.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+')
                    if tonumber(id) > 611 then
                        result[tonumber(id)] = model:gsub(' ', '')
                    end
                end
            end
        end
        return result, count
    end

    return c
end
Получение машин:
--ФУНКЦИИ ДЛЯ ПОЛУЧЕНИЯ МАШИН/СКИНОВ НЕЛЬЗЯ ВЫЗЫВАТЬ В БЕСК. ЦИКЛЕ
local vehs, vehsCount = Arizona():GetVehicles()
if vehsCount > 0 then
    for id, model in pairs(vehs) do
        print('ID: ', id, 'ModelName:', model)
    end
else
    print('Ошибка, машины не найдены :(')
end
Получение скинов:
--ФУНКЦИИ ДЛЯ ПОЛУЧЕНИЯ МАШИН/СКИНОВ НЕЛЬЗЯ ВЫЗЫВАТЬ В БЕСК. ЦИКЛЕ
local skins, skinsCount = Arizona():GetSkins()
if skinsCount > 0 then
    for id, model in pairs(skins) do
        print('ID: ', id, 'ModelName:', model)
    end
else
    print('Ошибка, скины не найдены :(')
end
Определение лаунчера::
local status = Arizona():IsLauncher()
if status then
    -- игрок на лаунчере
else
    -- игрок не на лаунчере
end
Находится ли игрок на аризоне:
-- для начала создаем функцию, которая будет вызвана после проверки на сервер
function checkServer(result, name_OPTIONAL, number_OPTIONAL) -- после проверки функция вызывается с 3 параметрами: на аризоне ли игрок (например: true), название сервера (например: Brainburg), номер сервера (например: 5)
    if result then
        sampAddChatMessage('Скрипт загружен! (Вы играете на ARZ #'..number_OPTIONAL..', '..name_OPTIONAL..')', -1)
    else
        sampAddChatMessage('Скрипт работает только на Arizona Role Play!', -1)
        thisScript():unload()
    end
end

-- для проверки вызываем функцию и в качестве аргумента вписываем нашу функцию
Arizona():IsArizona(checkServer)
1652631902783.png

Lua:
function Arizona()
    local c = {}
    
    function c:IsArizona(callback)
        if not doesDirectoryExist( getWorkingDirectory()..'\\resource' ) then createDirectory( getWorkingDirectory()..'\\resource' ) end
        local ip, port = sampGetCurrentServerAddress()
        local file = getWorkingDirectory()..'\\resource\\ARIZONA_SERVERS.json'
        local url = 'https://arizona-ping.react.group/desktop/ping/Arizona/ping.json'
        local dlstatus = require('moonloader').download_status
        downloadUrlToFile(url, file, function (id, status, p1, p2) 
            if status == dlstatus.STATUSEX_ENDDOWNLOAD then
                local F = {}
                for line in io.lines(file) do
                    table.insert(F, line)
                end
                local data = decodeJson(table.concat(F, '\n'))
                if data['query'] then
                    for k, v in ipairs(data['query']) do
                        if ip == data['query'][k]['ip'] and port == data['query'][k]['port'] then
                            --return true, data['query'][k]['name'], data['query'][k]['number']
                            callback(true, data['query'][k]['name'], data['query'][k]['number'])
                            return
                        end
                    end
                end
                callback(false, sampGetCurrentServerName(), -1)
            end
        end)
    end

    function c:IsLauncher()
        return doesFileExist(getGameDirectory()..'\\_CoreGame.asi')
    end

    function c:GetSkins()
        local result = {}
        local count = 0
        if c:IsLauncher() and doesFileExist(getGameDirectory()..'\\SAMP\\SAMP.ide') then
            local start = -1
            local lineIndex = 0
            for line in io.lines(getGameDirectory()..'\\SAMP\\SAMP.ide') do
                lineIndex = lineIndex + 1
                if line == 'ped' then
                    start = lineIndex + 1
                end
                if lineIndex > start then
                    local line = line:gsub(' ', '')
                    if line:find('(%d+),(.+),.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+') then
                        count = count + 1
                        local id, model = line:match('(%d+),(.+),.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+')
                        result[tonumber(id)] = model
                    end
                end
            end
        end
        return result, count
    end

    function c:GetVehicles()
        local result = {}
        local count = 0
        if c:IsLauncher() and doesFileExist(getGameDirectory()..'\\arizona\\vehicles.ide') then
            for line in io.lines(getGameDirectory()..'\\arizona\\vehicles.ide') do
                if line:find('(%d+),(.+),.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+') then
                    count = count + 1
                    local id, model = line:match('(%d+),(.+),.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+,.+')
                    if tonumber(id) > 611 then
                        result[tonumber(id)] = model:gsub(' ', '')
                    end
                end
            end
        end
        return result, count
    end

    return c
end



local imgui = require 'mimgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local renderWindow = imgui.new.bool(true)

local vehs, vehsCount = Arizona():GetVehicles()
local skins, skinsCount = Arizona():GetSkins()

local Frame = imgui.OnFrame(
    function() return renderWindow[0] end,
    function(player)
        local resX, resY = getScreenResolution()
        local sizeX, sizeY = 300, 300
        imgui.SetNextWindowPos(imgui.ImVec2(resX / 2, resY / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(sizeX, sizeY), imgui.Cond.FirstUseEver)
        imgui.Begin('Arizona', renderWindow)
      
        imgui.Text(u8'Лаунчер:')
        imgui.SameLine()
        imgui.TextColored(Arizona():IsLauncher() and imgui.ImVec4(0.45, 1, 0.44, 1) or imgui.ImVec4(1, 0.44, 0.44, 1), Arizona():IsLauncher() and u8'да' or u8'нет')

        if imgui.CollapsingHeader(u8'Машины из лаунчера (всего: '..tostring(vehsCount)..')') then
            imgui.Columns(2)
            imgui.Text('ID')
            imgui.NextColumn()
            imgui.Text('MODEL')
            imgui.Columns(1)
            imgui.Separator()
            for k, v in pairs(vehs) do
                imgui.Columns(2)
                imgui.Text(tostring(k))
                imgui.NextColumn()
                imgui.Text(v)
                imgui.Columns(1)
                imgui.Separator()
            end
        end

        if imgui.CollapsingHeader(u8'Скины из лаунчера (всего: '..tostring(skinsCount)..')') then
            imgui.Columns(2)
            imgui.Text('ID')
            imgui.NextColumn()
            imgui.Text('MODEL')
            imgui.Columns(1)
            imgui.Separator()
            for k, v in pairs(skins) do
                imgui.Columns(2)
                imgui.Text(tostring(k))
                imgui.NextColumn()
                imgui.Text(v)
                imgui.Columns(1)
                imgui.Separator()
            end
        end

        imgui.End()
    end
)

function checkServer(result, name_OPTIONAL, number_OPTIONAL)
    if result then
        sampAddChatMessage('Скрипт загружен! (Вы играете на ARZ #'..number_OPTIONAL..', '..name_OPTIONAL..')', -1)
    else
        sampAddChatMessage('Скрипт работает только на Arizona Role Play!', -1)
        thisScript():unload()
    end
end

function main()
    while not isSampAvailable() do wait(0) end
    Arizona():IsArizona(checkServer)
    sampRegisterChatCommand('mimgui', function()
        renderWindow[0] = not renderWindow[0]
    end)
    wait(-1)
end
 

PanSeek

t.me/dailypanseek
Всефорумный модератор
899
1,745
Баянисто, но я здесь не видел такого.
Описание: Меняет "формат" скриншота.
Получить формат скриншота:
local mem = require 'memory'
local samp = getModuleHandle('samp.dll')
function getTypeScreenshot()
    return mem.getint8(samp + 0x710CA)
end
Изменить формат скриншота:
local mem = require 'memory'
local samp = getModuleHandle('samp.dll')
function setTypeScreenshot(int)
    mem.setint8(samp + 0x710CA, int, true)
end
Получить формат скриншота:
local mem = require 'memory'
local samp = getModuleHandle('samp.dll')
function getTypeScreenshot()
    return mem.getint8(samp + 0x74FBA)
end
Изменить формат скриншота:
local mem = require 'memory'
local samp = getModuleHandle('samp.dll')
function setTypeScreenshot(int)
    mem.setint8(samp + 0x74FBA, int, true)
end
Подробнее про "форматы".
Пример использования: Можно, например, при загрузке скрипта изменить "формат" сохранения скриншотов на JPG, файл скриншота будет весить меньше.
Также можно прикрутить массив из названий формата, чтобы указывать, например, в команде, в каком формате хочешь сохранить скриншот.
Lua:
local mem = require 'memory'
local samp = 0x0

function main()
    while not isSampAvailable() do wait(40) end
    samp = getModuleHandle('samp.dll')
    setTypeScreenshot(1)
    wait(-1)
end

function onScriptTerminate(script, bQuitGame) -- при выгрузке скрипта меняем на дефолт значение
    if script == thisScript() then
        setTypeScreenshot(3)
    end
end

function setTypeScreenshot(int)
    mem.setint8(samp + 0x710CA --[[ R3: 0x74FBA ]], int, true)
end
 

mzxer

Активный
81
119
Описание: возвращает версию сампа
Код:
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
Посмотреть вложение 137176
источник
Описание: возвращает версию сампа
Lua:
local ffi = require("ffi")

function get_samp_version()
    if samp_base == nil or samp_base == 0 then
        samp_base = getModuleHandle("samp.dll")
    end

    if samp_base ~= 0 then
        local e_lfanew = ffi.cast("long*", samp_base + 60)[0]
        local nt_header = samp_base + e_lfanew
        local entry_point_addr = ffi.cast("unsigned int*", nt_header + 40)[0]
        if entry_point_addr == 0x31DF13 then
            return "r1"
        elseif entry_point_addr == 0xCC4D0 then
            return "r3"
        end
    end

    return "unknown"
end

Пример использования:
Lua:
local ffi = require("ffi")

function get_samp_version()
    if samp_base == nil or samp_base == 0 then
        samp_base = getModuleHandle("samp.dll")
    end
   
    if samp_base ~= 0 then
        local e_lfanew = ffi.cast("long*", samp_base + 60)[0]
        local nt_header = samp_base + e_lfanew
        local entry_point_addr = ffi.cast("unsigned int*", nt_header + 40)[0]
        if entry_point_addr == 0x31DF13 then
            return "r1"
        elseif entry_point_addr == 0xCC4D0 then
            return "r3"
        end
    end
   
    return "unknown"
end

function addChatMessage(color, message)
    local samp_version = get_samp_version()
 
    if samp_version ~= "unknown" then
        local CChat__AddMessage = ffi.cast(
            "void(__thiscall*)(void* pChat, unsigned int color, const char* text)",
            (samp_version == "r1") and (samp_base + 0x64450) or (samp_base + 0x679F0)
        )
     
        -- CChat* this
        local pChat = ffi.new("void*")
        pChat = ffi.cast(
            "void**",
            (samp_version == "r1") and (samp_base + 0x21A0E4) or (samp_base + 0x26E8C8)
        )[0]

        if pChat ~= 0 then
            return CChat__AddMessage(pChat, color, message)
        end
    end
end

function main()
    wait(500)

    -- msg color must be in RGBA fmt
    addChatMessage(-1, "Hello, BlastHack!")
    addChatMessage(0xFF000000, "{00FF00}hello {00FFFF}world")
end

ещё пример
Баянисто, но я здесь не видел такого.
Описание: Меняет "формат" скриншота.
Получить формат скриншота:
local mem = require 'memory'
local samp = getModuleHandle('samp.dll')
function getTypeScreenshot()
    return mem.getint8(samp + 0x710CA)
end
Изменить формат скриншота:
local mem = require 'memory'
local samp = getModuleHandle('samp.dll')
function setTypeScreenshot(int)
    mem.setint8(samp + 0x710CA, int, true)
end
Получить формат скриншота:
local mem = require 'memory'
local samp = getModuleHandle('samp.dll')
function getTypeScreenshot()
    return mem.getint8(samp + 0x74FBA)
end
Изменить формат скриншота:
local mem = require 'memory'
local samp = getModuleHandle('samp.dll')
function setTypeScreenshot(int)
    mem.setint8(samp + 0x74FBA, int, true)
end
Подробнее про "форматы".
Пример использования: Можно, например, при загрузке скрипта изменить "формат" сохранения скриншотов на JPG, файл скриншота будет весить меньше.
Также можно прикрутить массив из названий формата, чтобы указывать, например, в команде, в каком формате хочешь сохранить скриншот.
Lua:
local mem = require 'memory'
local samp = 0x0

function main()
    while not isSampAvailable() do wait(40) end
    samp = getModuleHandle('samp.dll')
    setTypeScreenshot(1)
    wait(-1)
end

function onScriptTerminate(script, bQuitGame) -- при выгрузке скрипта меняем на дефолт значение
    if script == thisScript() then
        setTypeScreenshot(3)
    end
end

function setTypeScreenshot(int)
    mem.setint8(samp + 0x710CA --[[ R3: 0x74FBA ]], int, true)
end
Lua:
local mem = require 'memory'
local samp = getModuleHandle('samp.dll')

function getTypeScreenshot()
    return mem.getint8(samp + ((get_samp_version() == "r1") and 0x710CA or 0x74FBA))
end

function setTypeScreenshot(int)
    mem.setint8(samp + ((get_samp_version() == "r1") and 0x710CA or 0x74FBA), int, true)
end
 
Последнее редактирование: