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

ШPEK

Известный
1,474
525
Описание: получает moveSpeed
Lua:
function getVelocity(x, y, z, x1, y1, z1, speed)
    local x2, y2, z2 = x1 - x, y1 - y, z1 - z
    local dist = math.sqrt(math.pow(x1 - x, 2.0) + math.pow(y1 - y, 2.0) + math.pow(z1 - z, 2.0))
    return x2 / dist * speed, y2 / dist * speed, z2 / dist * speed
end
Пример использования:
Lua:
print(getVelocity(1, 1, 1, 1, 100,1, 1) -- 0, 1, 0
 
  • Нравится
Реакции: mzxer, coldest и Rei

Musaigen

abobusnik
Проверенный
1,607
1,365
Описание: Рисует вертикальный разделитель (imgui.Separator)
P.S: По идее можно использовать и imgui.GetWindowHeight() вместо imgui.GetContentRegionMax().y, но я хз.
P.S.S: Также можно отнять от imgui.GetContentRegionMax().y какое-то значение, тогда получится отступ от конца как в обычном imgui.Separator()
Lua:
function imgui.VerticalSeparator()
    local p = imgui.GetCursorScreenPos()
    imgui.GetWindowDrawList():AddLine(imgui.ImVec2(p.x, p.y), imgui.ImVec2(p.x, p.y + imgui.GetContentRegionMax().y), imgui.GetColorU32(imgui.GetStyle().Colors[imgui.Col.Separator]))
end
Пример использования:
Lua:
function imgui.OnDrawFrame()
    imgui.VerticalSeparator()
    imgui.SameLine()
    imgui.BeginChild('in-child separator', imgui.ImVec2(100, 100), true)
    imgui.SetCursorPosX(imgui.GetCursorPos().x + 10)
    imgui.VerticalSeparator()
    imgui.EndChild()
end
sa-mp-019.png
 

Petr_Sergeevich

Известный
Проверенный
707
297
Описание: установка координат курсора на экране в нужное место (многие спрашивали, как это сделать, почему бы и нет)
Lua:
local ffi = require 'ffi'
ffi.cdef("bool SetCursorPos(int X, int Y);")

Пример использования:
Установит координаты по середине экрана
Чтобы наблюдать изменение местоположения курсора, установите sampSetCursorMode(3)
Lua:
local sW, sH = getScreenResolution()
ffi.C.SetCursorPos(sW/2, sH/2)
 

ШPEK

Известный
1,474
525
Описание: Получает массив с id всех 3D текстов
Lua:
function sampGetAllTextlabels()
    local tdts = {}
    pTt = sampGetTextlabelPoolPtr() + 59392
    for i = 0, 2047 do
        if readMemory(pTt + i * 4, 4) ~= 0 then
            table.insert(tdts, i)
        end
    end
    return tdts
end
Описание: Получает массив с
id всех TextDraw
Lua:
function sampGetAllTextDraws()
    local tds = {}
    pTd = sampGetTextdrawPoolPtr() + 9216
    for i = 0, 2303 do
        if readMemory(pTd+i*4, 4) ~= 0 then
            table.insert(tds, i)
        end
    end
    return tds
end
Описание: Получает массив с хэндлами всех пикапов
Lua:
function getAllPickups()
    local pu = {}
    pPu = sampGetPickupPoolPtr() + 16388
    for i = 0, 4095 do
        local id = readMemory(pPu + 4 * i, 4)
        if id ~= -1 then
            table.insert(pu, sampGetPickupHandleBySampId(i))
        end
    end
    return pu
end
 
  • Нравится
Реакции: Eugene Crabs

AnWu

https://t.me/anwublog
Всефорумный модератор
4,770
5,377
Описание: Получает массив с id всех 3D текстов
Lua:
function sampGetAllTextlabels()
local tdts = {}
pTt = sampGetTextlabelPoolPtr() + 59392
for i = 0, 2047 do
if readMemory(pTt + i * 4, 4) ~= 0 then
table.insert(tdts, i)
end
end
return tdts
end
Описание: Получает массив с
id всех TextDraw
Lua:
function sampGetAllTextDraws()
local tds = {}
pTd = sampGetTextdrawPoolPtr() + 9216
for i = 0, 2303 do
if readMemory(pTd+i*4, 4) ~= 0 then
table.insert(tds, i)
end
end
return tds
end
Описание: Получает массив с хэндлами всех пикапов
Lua:
function getAllPickups()
local pu = {}
pPu = sampGetPickupPoolPtr() + 16388
for i = 0, 4095 do
local id = readMemory(pPu + 4 * i, 4)
if id ~= -1 then
table.insert(pu, sampGetPickupHandleBySampId(i))
end
end
return pu
end
Что с табуляцией? Не на ЧМ пишешь ну.
Lua:
bool result = sampTextdrawIsExists(int id)
bool result = sampIs3dTextDefined(int 3dText)
bool result = doesPickupExist(Pickup pickup)
Что не так с этими функциями? Почему используешь чтение памяти?
 
  • Ха-ха
Реакции: Vintik

madrasso

Потрачен
883
325
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Описание: отправка в чат нескольких сообщений с определенной задержкой(да да, пинаться не надо).

Lua:
function sampSendChatArray(delay, ...)
    lua_thread.create(function()
        for i, v in ipairs({...}) do
            sampSendChat(v)
            wait(delay)
        end
    end)
end

Пример использования:
Lua:
sampSendChatArray(1200, 'Привет, это мое первое сообщение', 'а это мое второе сообщение!') -- где 1200 - это задержка(указывается первым аргументом).
 

ImPasha

Software Developer & System Administrator
Друг
1,788
2,141
Описание: Получение списка пользователей в зоне стрима с определенным цветом
Lua:
function sampGetAllPlayersByPlayerColor(color)
    local players = getAllChars()
    local tempTable = {}
    for k, v in ipairs(players) do
        if doesCharExist(v) then
            local noError, id = sampGetPlayerIdByCharHandle(v)
            if noError and sampGetPlayerColor(id) == tonumber(color) then
                local pName = sampGetPlayerNickname(id)
                if pName == nil then pName = "Player_Name" end
                table.insert(tempTable, {v, id, pName})
            end
        end
    end
    return tempTable
end
Пример использования:
Lua:
local table = sampGetAllPlayersByPlayerColor(4294967295) -- ЗДЕСЬ ПОМЕНЯТЬ ЦВЕТ!
if next(table) == nil then print('Нет игроков с таким цветом в зоне стрима!')
else
    for k, v in pairs(table) do
        print(v[1]) -- char handle
        print(v[2]) -- player id
        print(v[3]) -- player nick
    end
end
 

ШPEK

Известный
1,474
525
Описание: Добавляет новое убийство в KillList, цвет NickName вводятся в формате ARGB
Lua:
function addKillLineToKillList(killer, died, killercolor, diedcolor, weapon)
    if isSampAvailable() then
        local ffi = require("ffi")
        local chKiller = ffi.new("char[?]", #killer + 1)
        ffi.copy(chKiller, killer, #killer)
        local chDied = ffi.new("char[?]", #died + 1)
        ffi.copy(chDied, died, #died)
        func = ffi.cast("char* (__thiscall*)(unsigned long, char*, char*, unsigned long, unsigned long, char)", sampGetBase() + 0x66A10)
        func(sampGetKillInfoPtr(), chKiller, chDied, killercolor, diedcolor, weapon)
    end
end
Пример использования:
Lua:
function main()
    while not isSampLoaded() do wait(100) end
    sampRegisterChatCommand("add", function(param) addKillLineToKillList(param:match("(.+)%s"), param:match("%s(.+)"), 0xFFFF0000, 0xFFFF0000, 1) end)
    wait(-1)
end
 

ImPasha

Software Developer & System Administrator
Друг
1,788
2,141
Описание: Практичная загрузка библиотек с использованием менеджера зависимостей FYP
Lua:
local libs = {
    {'moonloader'}, -- просто библиотека: без присваивания и подгрузки
    {'samp.events', 'sampev'}, -- библиотека с присваиванием, но без подгрузки
    {'inspect', 'inspect', 'inspect'}, -- библиотека с присваиванием и подгрузкой
    {'dkjson', 'json', 'dkjson@2.4-1'},
    {'lume', 'lume', 'fyp:lume'},
    {'pl.Set', nil, 'steved/penlight@1.5.4-1'} -- библиотека без присваивания, но с подгрузкой
}
local libsForLoad = {}
for k, v in pairs(libs) do
    if v[3] ~= nil then table.insert(libsForLoad, v[3]) end
end
require ('libstd.deps')(libsForLoad)
for k, v in pairs(libs) do
    if not v[1] then error('Не удалось произвести загрузку библиотек, так как таблица заполнена неверно.') end
    if v[2] then noError, _G[v[2]] = pcall(require, v[1])
    else noError = pcall(require, v[1]) end
    assert(noError, "Не удалось загрузить библиотеку "..v[1]..". Установите её и попробуйте ещё раз.")
end
Пример использования: Загрузка SAMP.LUA и присвоение его к переменной sampev.
Lua:
local libs = {
    {'moonloader'},
    {'samp.events', 'sampev', 'fyp:samp-lua'} -- библиотека, переменная, LuaRocks
}
local libsForLoad = {}
for k, v in pairs(libs) do
    if v[3] ~= nil then table.insert(libsForLoad, v[3]) end
end
require ('libstd.deps')(libsForLoad)
for k, v in pairs(libs) do
    if not v[1] then error('Не удалось произвести загрузку библиотек, так как таблица заполнена неверно.') end
    if v[2] then noError, _G[v[2]] = pcall(require, v[1])
    else noError = pcall(require, v[1]) end
    assert(noError, "Не удалось загрузить библиотеку "..v[1]..". Установите её и попробуйте ещё раз.")
end

function sampev.onServerMessage(color, text) -- sampev будет работать, т.к. мы присвоили samp.events к этой переменной
    -- ваш код
end
Warning! Код протестирован и работает нормально, но поведение МЗ может оказаться нестабильным и всё поломать. В целом, код можно использовать даже без МЗ - это просто очень удобно и можно быстренько загрузить все нужные библиотеки, не забивая при этом код assert'ами.
 

Akionka

akionka.lua
Проверенный
742
502
Описание: Lua из коробки не умеет нативными методами s:upper & s:lower работать с non-ASCII символами, данные функции умеют. QRLK уже выкладывал подобную функцию, но лично у меня она работает несколько криво. Функция взята с какого-то форума.
Lua:
function stringToLower(s)
  for i = 192, 223 do
    s = s:gsub(_G.string.char(i), _G.string.char(i + 32))
  end
  s = s:gsub(_G.string.char(168), _G.string.char(184))
  return s:lower()
end
Lua:
function stringToUpper(s)
  for i = 224, 255 do
    s = s:gsub(_G.string.char(i), _G.string.char(i - 32))
  end
  s = s:gsub(_G.string.char(184), _G.string.char(168))
  return s:upper()
end
Пример использования:
Lua:
print(stringToLower('КУПЛЮ ХАНТЛИ')) -- output: куплю хантли
-- Если файл в кодировке UTF-8 или любой другой не ANSI/Win1251/CP1251, то необходимо строку сначала преобразовать в CP1251.
local encoding = require 'encoding'
encoding.default = 'cp1251'
local u8 = encoding.UTF8

function main()
  print(stringToLower(u8:decode('КУПЛЮ ХАНТЛИ')))
end
 
  • Нравится
Реакции: 1NS, xColorized и inf

#Northn

Pears Project — уже запущен!
Всефорумный модератор
2,653
2,535
Описание: Центрирование текста в imgui.Columns(count) imgui.SetColumnWidth(start, _end)
Lua:
function imgui.CenterColumnText(text)
    imgui.SetCursorPosX((imgui.GetColumnOffset() + (imgui.GetColumnWidth() / 2)) - imgui.CalcTextSize(text).x / 2)
    imgui.Text(text)
end
Пример использования:
Lua:
imgui.Columns(6)
imgui.SetColumnWidth(-1, 77); imgui.CenterColumnText(u8'Рация'); imgui.NextColumn()
imgui.SetColumnWidth(-1, 175); imgui.CenterColumnText(u8'Ник'); imgui.NextColumn()
imgui.SetColumnWidth(-1, 65); imgui.CenterColumnText(u8'Уровень'); imgui.NextColumn()
if list.fbi == true then
    imgui.SetColumnWidth(-1, 113);
else
    imgui.SetColumnWidth(-1, 50);
end
imgui.CenterColumnText(u8'Ранг')
imgui.NextColumn()
imgui.SetColumnWidth(-1, 81); imgui.CenterColumnText(u8'Расстояние'); imgui.NextColumn()
imgui.SetColumnWidth(-1, 100); imgui.CenterColumnText(u8'AFK'); imgui.NextColumn()

35242
 
Последнее редактирование:

DolgorukovGTA

Известный
Проверенный
652
345
Описание: Функция перевода чисел и цифр из арабских в римские. Вернет nil, если введенноё значение не принадлежит полуинтервалу (0; 4999].
Lua:
function fromArabicToRoman(data)

    if data > 0 and data <= 4999 then
        local romanNumbersArray = {
            [4] = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"}, -- разряд единиц
            [3] = {"X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"}, -- разряд десятков
            [2] = {"C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"}, -- разряд сотен
            [1] = {"M", "MM", "MMM", "MMMM"} -- разряд тысяч
        }
        local operationArray = {
            [1] = math.floor(data / 1000),
            [2] = math.floor(data / 100) % 10,
            [3] = math.floor(data / 10) % 10,
            [4] = math.floor(data  % 10)
        }
    
        local digitNumbersArray = {}
        for i = 1, 4 do
            if operationArray[i] ~= 0 then
                digitNumbersArray[i] = romanNumbersArray[i][operationArray[i]]
            end
        end

        local romanNumber = ""

        for _, v in pairs(digitNumbersArray) do
            romanNumber = romanNumber..v
        end

        return romanNumber
    end
        return nil
end
Пример использования:
Lua:
print(fromArabicToRoman(4588)) -- MMMMDLXXXVIII
print(fromArabicToRoman(2313)) -- MMCCCXIII
print(fromArabicToRoman(8)) -- VIII
Если каким-то чудом обнаружили несоответствие введенному числу, то, пожалуйста, отпишитесь мне в личные сообщения на форуме.
 
Последнее редактирование:

ШPEK

Известный
1,474
525
Описание: меняет статус прорисовки чата
Lua:
function changeChatRender(status) 
 local memory = require("memory") 
 memory.setuint8(sampGetBase() + 0x71480, status and 0x74 or 0xEB, true) 
end
Пример использования:
Lua:
function main() 
 while not isSampAvailable() do wait(100) end 
 sampRegisterChatCommand("enof", function()  
  changeChatRender(true) 
 end) 
 wait(-1) 
end
 

astynk

Известный
Проверенный
742
532
Описание: рисует текст, раскрашенный градиентом.
Lua:
function renderGradientText(font, text, posX, posY, startingColor, endingColor)
    local startingColorComponents = { startingColor:match('(..)(..)(..)') }
    local endingColorComponents = { endingColor:match('(..)(..)(..)') }
    for i = 1, 3 do
        startingColorComponents[i] = tonumber(startingColorComponents[i], 16)
        endingColorComponents[i] = tonumber(endingColorComponents[i], 16)
    end
    local length = text:len()
    local gradient = ''
    local function shift(comp, i)
        return startingColorComponents[comp] + (endingColorComponents[comp] - startingColorComponents[comp]) * ((i - 1) / (length - 1))
    end
    for i = 1, length do
        local R = shift(1, i)
        local G = shift(2, i)
        local B = shift(3, i)
        gradient = gradient .. string.format('{%0.2x%0.2x%0.2x}%s', R, G, B, text:sub(i, i))
    end
    renderFontDrawText(font, gradient, posX, posY, -1)
end
Пример использования:
Lua:
while true do
    wait(1)
    renderGradientText(font, 'This is a gradient text.', 300, 300, '007FFF', 'FF00FF')
end
 

ШPEK

Известный
1,474
525
Описание: включает редактирование обьекта
Lua:
function editObjectBySampId(id, playerobj)
    if isSampAvailable() then
        local ffi = require("ffi")
        ffi.cast("void (__thiscall*)(unsigned long, short int, unsigned long)", sampGetBase() + 0x6DE40)(readMemory(sampGetBase() + 0x21A0C4, 4), id, playerobj and 1 or 0)
    end
end
Пример использования:
Lua:
function main()
    while not isSampAvailable() do wait(100) end 
    sampRegisterChatCommand("editobject", function(param)  editObjectBySampId(tonumber(param), false)
    end)
    wait(-1)
end