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

MrCreepTon

Неизвестный
Всефорумный модератор
2,213
5,023
Описание: Клонирует table
Lua:
function clone (t)
    if type(t) ~= "table" then return t end
    local meta = getmetatable(t)
    local target = {}
    for k, v in pairs(t) do
        if type(v) == "table" then
            target[k] = clone(v)
        else
            target[k] = v
        end
    end
    setmetatable(target, meta)
    return target
end
Пример использования:
Lua:
local t = {name = 'User'}
local t2 = clone(t)
t2.name = 'TestUser'
print(t.name)
print(t2.name)
--[[
    Output:
    User
    TestUser
]]
Взято отсюда: https://gist.github.com/MihailJP/3931841
 

Cosmo

Известный
Друг
656
2,744
Описание:
Функция, которая получает выделенный текст в чате
String text = getSelectedText():
function getSelectedText()
    local input = sampGetChatInputText()
    local ptr = sampGetInputInfoPtr()
    local chat = getStructElement(ptr, 0x8, 4)
    local pos1 = readMemory(chat + 0x11E, 4, false)
    local pos2 = readMemory(chat + 0x119, 4, false)
    local count = pos2 - pos1
    return string.sub(input, count < 0 and pos2 + 1 or pos1 + 1, count < 0 and pos2 - count or pos2)
end

Пример использования:
Lua:
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(80) end
    local font = renderCreateFont('Arial', 9, 5)
    while true do
        if sampIsChatInputActive() then
            local text = getSelectedText()
            local strEl = getStructElement(sampGetInputInfoPtr(), 0x8, 4)
            local X, Y = getStructElement(strEl, 0x8, 4), getStructElement(strEl, 0xC, 4)
            renderFontDrawText(font, ('Выделеный текст: {FFFFFF}%s {FF9DFF}(%d символов)'):format(text, #text), X + 5, Y + 50, 0xFFFF9DFF)
        end
    wait(0)
    end
end
getSelectedText.gif
 

ImPasha

Software Developer & System Administrator
Друг
1,788
2,142
Описание: полезные функции для работы со строками в Lua; первая функция позволяет получить все строки, завернутые в кавычки (как двойные, так и одинарные, при этом имеется проверка на кавычки внутри кавычек + экранирование); вторая функция позволяет подменить текст по стартовой и конечной позиции, например, эти позиции можно взять из первой функции; третья функция позволяет развернуть текст в стартовой и конечной позиции.
Lua:
local slib = {}
function slib.parse(code)
  local matches, data = {}, {}
  for quote_pos, quote_type in code:gmatch("()(['\"])") do
    matches[#matches+1] = {pos = quote_pos, type = quote_type}
  end; table.sort(matches, function(v1, v2) return v1.pos < v2.pos end)
  local end_pos = 0
  for idx, val in ipairs(matches) do
    local start_pos, result, symbol = val.pos, nil, nil
    if start_pos > end_pos then end_pos = val.pos
      while symbol ~= val.type do
        result, end_pos, symbol = code:find("(\\?.)", end_pos + 1)
        assert(result, 'Unable to find closing one :((((9(')
      end
      local value = code:sub(val.pos + 1, end_pos - 1)
      data[#data+1] = {value = value, start = val.pos, ends = end_pos}
    end
  end; return data
end
function slib.replace(haystack, start_pos, end_pos, new_value)
  local temp_str = haystack:sub(end_pos + 1, #haystack)
  haystack = haystack:sub(1, start_pos - 1) .. new_value
  return haystack .. temp_str
end
function slib.reverse(haystack, start_pos, end_pos)
  local value = haystack:sub(start_pos, end_pos):reverse()
  return slib.replace(haystack, start_pos, end_pos, value)
end
Пример использования:
Lua:
local lua_code = [[
local str = "Hello world"
function test(str)
    local prefix = "HO"
    return prefix .. ' ' .. str
end
print(test(str))
]]

local data = slib.parse(lua_code)
lua_code = slib.reverse(lua_code, data[2].start + 1, data[2].ends - 1)
lua_code = slib.replace(lua_code, data[1].start + 1, data[1].ends - 1, "Goodbye world")

print(lua_code)
Дополнительно: аналог первой функции, отличие заключается в том, что он вызывает callback-функцию вместо записи данных в таблицу.
Lua:
function slib.parse(code, callback)
  local matches, data = {}, {}
  for quote_pos, quote_type in code:gmatch("()(['\"])") do
    matches[#matches+1] = {pos = quote_pos, type = quote_type}
  end; table.sort(matches, function(v1, v2) return v1.pos < v2.pos end)
  local end_pos = 0
  for idx, val in ipairs(matches) do
    local start_pos, result, symbol = val.pos, nil, nil
    if start_pos > end_pos then end_pos = val.pos
      while symbol ~= val.type do
        result, end_pos, symbol = code:find("(\\?.)", end_pos + 1)
        assert(result, 'Please, check your code; it might be incorrect')
      end
      local value = code:sub(val.pos + 1, end_pos - 1)
      callback(value, val.pos, end_pos)
    end
  end
end

-- Пример использования:
slib.parse(lua_code, function(value, start_pos, end_pos)
    print("String [" .. start_pos .. ':' .. end_pos .. "]: " .. value)
end)
 

Kolbasa241

Известный
213
57
Описание: Получает информацию по ближайшему игроку от указанного Handle игрока.
Аргументы:Возвращаемые значения:
Ped HndlPed - Хэндл игрока;
float radius - радиус поиска ближайшего игрока. (Если указать false, то поиск
будет производиться по зоне стрима.);
int minPlayerNear - максимальное кол-во игроков находящихся возле игрока
(если больше указанного, то возвращает false). (Если указать false, то кол-во игроков не будет учитываться.).
bool result - результат получения (true - успешное, false - ошибка/не нашёл подходящего.);
Ped HandlePed - Хэндл ближайшего игрока;
float Distance - дистанция полученная между указанным в аргументе игрока и ближайшего игрока.
float posX - позиция ближайшего игрока по оси X;
float posY - позиция ближайшего игрока по оси Y;
float posZ - позиция ближайшего игрока по оси Z;
int CountPlayers - кол-во игроков находящихся рядом с ближайшим игроком.
Lua:
function GetNearestPedByPed(HndlPed, radius, minPlayerNear)
    if doesCharExist(HndlPed) then -- проверяем, существует ли Handle
        local tableArr = {}
        local countPlayers = 0
        local posXpl, posYpl = getCharCoordinates(HndlPed)
        for _,player in pairs(getAllChars()) do -- перебираем все Handle игроков в зоне стрима
            if player ~= HndlPed then -- проверяем не совпадает ли Handle игрока и указанный Handle
                local playerid = select(2, sampGetPlayerIdByCharHandle(player)) -- получаем ID игрока
                if not sampIsPlayerNpc(playerid) and playerid ~= -1 then -- проверяем не NPC ли этот игрок
                    local posX, posY, posZ = getCharCoordinates(player) -- получаем координаты игрока
                    for _,player1 in pairs(getAllChars()) do -- перебираем ещё раз все Handle игроков в зоне стрима для подсчёта кол-ва игроков вокруг другого
                        local playerid = select(2, sampGetPlayerIdByCharHandle(player1)) -- получаем ID игрока
                        if not sampIsPlayerNpc(playerid) and playerid ~= -1 then -- проверяем не NPC ли этот игрок
                            local x,y,z = getCharCoordinates(player1)
                            if getDistanceBetweenCoords2d(x, y, posX, posY) < 2 then countPlayers = countPlayers + 1 end -- получаем дистанцию между координатами игрока и координатами остальных игроков
                        end
                    end
                    local distBetween2d = getDistanceBetweenCoords2d(posXpl, posYpl, posX, posY)
                    if minPlayerNear ~= false then -- если проверка на кол-во игроков включена, то..
                        if tonumber(minPlayerNear) >= countPlayers then -- если кол-во игроков вокруг ближайшего игрока меньше или равно, чем указанное, то..
                            table.insert(tableArr, {distBetween2d, player, posX, posY, posZ, countPlayers - 1}) -- записываем в таблицу данные
                        end
                    else table.insert(tableArr, {distBetween2d, player, posX, posY, posZ, countPlayers - 1}) end --  если функция выключена, то записываем данные
                    countPlayers = 0
                end
            end
        end
        if #tableArr > 0 then -- если в таблице есть данные, то...
            table.sort(tableArr, function(a, b) return (a[1] < b[1]) end) -- сортируем 1-ое значение в каждом массиве от меньшего к большому.
            if radius ~= false then -- если функция проверки на радиус включена, то..
                if tableArr[1][1] <= tonumber(radius) then  -- если дистанция меньше или равна заданному радиусу, то ..
                    return true, tableArr[1][2], tableArr[1][1], tableArr[1][3], tableArr[1][4], tableArr[1][5], tableArr[1][6] -- возвращаем значения
                end
            else return true, tableArr[1][2], tableArr[1][1], tableArr[1][3], tableArr[1][4], tableArr[1][5], tableArr[1][6] end -- иначе, возвращаем данные
        end
    end
    return false
end
Lua:
function main()
    if not isSampAvailable() then return false end
    sampRegisterChatCommand("test1", test1) -- /test1
    sampRegisterChatCommand("test2", test2) -- /test2 [id Player]
    sampRegisterChatCommand("test3", test3) -- /test3 [id Player]
    wait(-1)
end

function test1() -- ищет ближайшего игрока к вам (PLAYER_PED) в радиусе 300 метров, и у искомого игрока рядом должно быть не более 4 игроков
    local result, HandlePed, Distance, posX, posY, posZ, countPlayers = GetNearestPedByPed(PLAYER_PED, 300, 4)
    if result then
        print("Player ID - "..select(2, sampGetPlayerIdByCharHandle(HandlePed)).." Distance Between you and HandlePed - "..Distance.."\nPosition: X - "..posX.." Y - "..posY.." Z - "..posZ.."\nCount Players Near HandlePed - "..countPlayers)
    else
        print("The function returned False")
    end
end

function test2(id) -- ищет ближайшего игрока к указанному игроку по всей зоне стрима.
    local HandlePlayer = select(2, sampGetCharHandleBySampPlayerId(id))
    local result, HandlePed, Distance, posX, posY, posZ, countPlayers = GetNearestPedByPed(HandlePlayer, false, false)
    if result then
        print("Player ID - "..select(2, sampGetPlayerIdByCharHandle(HandlePed)).." Distance Between HandlePlayer and HandlePed - "..Distance.."\nPosition: X - "..posX.." Y - "..posY.." Z - "..posZ.."\nCount Players Near HandlePed - "..countPlayers)
    else
        print("The function returned False")
    end
end

function test3(id) -- ищет ближайшего игрока к указанному игроку по всей зоне стрима.
    -- можно получать и только первые 2 значения если вам не нужна остальная информация.
    local HandlePlayer = select(2, sampGetCharHandleBySampPlayerId(id))
    local result, HandlePed = GetNearestPedByPed(HandlePlayer, false, false)
    if result then
        sampAddChatMessage("Nearest Player ID - "..select(2, sampGetPlayerIdByCharHandle(HandlePed)))
    else
        print("The function returned False")
    end
end
 
Последнее редактирование:

Rei

Известный
Друг
1,616
1,674
Описание: Получает информацию по ближайшему игроку от указанного Handle игрока.
Аргументы:Возвращаемые значения:
Ped HndlPed - Хэндл игрока;
float radius - радиус поиска ближайшего игрока. (Если указать false, то поиск
будет производиться по зоне стрима.);
int minPlayerNear - максимальное кол-во игроков находящихся возле игрока
(если больше указанного, то возвращает false). (Если указать false, то кол-во игроков не будет учитываться.).
bool result - результат получения (true - успешное, false - ошибка/не нашёл подходящего.);
Ped HandlePed - Хэндл ближайшего игрока;
float Distance - дистанция полученная между указанным в аргументе игрока и ближайшего игрока.
float posX - позиция ближайшего игрока по оси X;
float posY - позиция ближайшего игрока по оси Y;
float posZ - позиция ближайшего игрока по оси Z;
int CountPlayers - кол-во игроков находящихся рядом с ближайшим игроком.
Lua:
function GetNearestPedByPed(HndlPed, radius, minPlayerNear)
    if doesCharExist(HndlPed) then -- проверяем, существует ли Handle
        local tableArr = {}
        local countPlayers = 0
        local posXpl, posYpl = getCharCoordinates(HndlPed)
        for _,player in pairs(getAllChars()) do -- перебираем все Handle игроков в зоне стрима
            if player ~= HndlPed then -- проверяем не совпадает ли Handle игрока и указанный Handle
                local playerid = select(2, sampGetPlayerIdByCharHandle(player)) -- получаем ID игрока
                if not sampIsPlayerNpc(playerid) and playerid ~= -1 then -- проверяем не NPC ли этот игрок
                    local posX, posY, posZ = getCharCoordinates(player) -- получаем координаты игрока
                    for _,player1 in pairs(getAllChars()) do -- перебираем ещё раз все Handle игроков в зоне стрима для подсчёта кол-ва игроков вокруг другого
                        local playerid = select(2, sampGetPlayerIdByCharHandle(player1)) -- получаем ID игрока
                        if not sampIsPlayerNpc(playerid) and playerid ~= -1 then -- проверяем не NPC ли этот игрок
                            local x,y,z = getCharCoordinates(player1)
                            if getDistanceBetweenCoords2d(x, y, posX, posY) < 2 then countPlayers = countPlayers + 1 end -- получаем дистанцию между координатами игрока и координатами остальных игроков
                        end
                    end
                    local distBetween2d = getDistanceBetweenCoords2d(posXpl, posYpl, posX, posY)
                    if minPlayerNear ~= false then -- если проверка на кол-во игроков включена, то..
                        if tonumber(minPlayerNear) >= countPlayers then -- если кол-во игроков вокруг ближайшего игрока меньше или равно, чем указанное, то..
                            table.insert(tableArr, {distBetween2d, player, posX, posY, posZ, countPlayers - 1}) -- записываем в таблицу данные
                        end
                    else table.insert(tableArr, {distBetween2d, player, posX, posY, posZ, countPlayers - 1}) end --  если функция выключена, то записываем данные
                    countPlayers = 0
                end
            end
        end
        if #tableArr > 0 then -- если в таблице есть данные, то...
            table.sort(tableArr, function(a, b) return (a[1] < b[1]) end) -- сортируем 1-ое значение в каждом массиве от меньшего к большому.
            if radius ~= false then -- если функция проверки на радиус включена, то..
                if tableArr[1][1] <= tonumber(radius) then  -- если дистанция меньше или равна заданному радиусу, то ..
                    return true, tableArr[1][2], tableArr[1][1], tableArr[1][3], tableArr[1][4], tableArr[1][5], tableArr[1][6] -- возвращаем значения
                end
            else return true, tableArr[1][2], tableArr[1][1], tableArr[1][3], tableArr[1][4], tableArr[1][5], tableArr[1][6] end -- иначе, возвращаем данные
        end
    end
    return false
end
Lua:
function main()
    if not isSampAvailable() then return false end
    sampRegisterChatCommand("test1", test1) -- /test1
    sampRegisterChatCommand("test2", test2) -- /test2 [id Player]
    sampRegisterChatCommand("test3", test3) -- /test3 [id Player]
    wait(-1)
end

function test1() -- ищет ближайшего игрока к вам (PLAYER_PED) в радиусе 300 метров, и у искомого игрока рядом должно быть не более 4 игроков
    local result, HandlePed, Distance, posX, posY, posZ, countPlayers = GetNearestPedByPed(PLAYER_PED, 300, 4)
    if result then
        print("Player ID - "..select(2, sampGetPlayerIdByCharHandle(HandlePed)).." Distance Between you and HandlePed - "..Distance.."\nPosition: X - "..posX.." Y - "..posY.." Z - "..posZ.."\nCount Players Near HandlePed - "..countPlayers)
    else
        print("The function returned False")
    end
end

function test3(id) -- ищет ближайшего игрока к указанному игроку по всей зоне стрима.
    -- можно получать и только первые 2 значения если вам не нужна остальная информация.
    local HandlePlayer = select(2, sampGetCharHandleBySampPlayerId(id))
    local result, HandlePed = GetNearestPedByPed(HandlePlayer, false, false)
    if result then
        sampAddChatMessage("Nearest Player ID - "..select(2, sampGetPlayerIdByCharHandle(HandlePed)))
    else
        print("The function returned False")
    end
end
ладно.
Lua:
function getNearestPedByPed(hndlPed, radius)
	minDist, closestHandle = nil, nil
	if doesCharExist(hndlPed) then -- проверяем, существует ли Handle
		local tX, tY, tZ = getCharCoordinates(hndlPed)
		for k, v in ipairs(getAllChars()) do
			if v ~= hndlPed then
				local x, y, z = getCharCoordinates(v)
				local dist = getDistanceBetweenCoords3d(x, y, z, tX, tY, tZ)
				if (not radius or dist < radius) and (not minDist or dist < minDist) then
					minDist, closestHandle = dist, v
				end
			end
		end
		return closestHandle
	end
end
 
  • Нравится
Реакции: goodflex

Kolbasa241

Известный
213
57
Описание: Получает информацию по ближайшей машине от указанного Handle игрока.
Аргументы:Возвращаемые значения:
Ped HndlPed - Хэндл игрока;
float radius - радиус поиска ближайшего игрока. (Если указать false, то поиск
будет производиться по зоне стрима.);
int minPlayerNear - максимальное кол-во игроков находящихся возле игрока
(если больше указанного, то возвращает false). (Если указать false, то кол-во игроков не будет учитываться.).
bool result - результат получения (true - успешное, false - ошибка/не нашёл подходящей.);
Vehicle Car - Хэндл ближайшей машины;
float Distance - дистанция полученная между указанным в аргументе игрока и ближайшей машины.
float posX - позиция ближайшей машины по оси X;
float posY - позиция ближайшей машины по оси Y;
float posZ - позиция ближайшей машины по оси Z;
int CountPlayers - кол-во игроков находящихся рядом с ближайшей машиной.
Lua:
function GetNearestCarByPed(HndlPed, radius, minPlayerNear)
    if doesCharExist(HndlPed) then -- проверяем, существует ли Handle
        local tableArr = {}
        local countPlayers = 0
        local posXpl, posYpl = getCharCoordinates(HndlPed)
        for _,car in pairs(getAllVehicles()) do -- перебираем все Handle машин в зоне стрима
            if getDriverOfCar(car) ~= HndlPed then -- проверяем не является ли водителем этой машины HndlPed
                local posX, posY, posZ = getCarCoordinates(car) -- получаем координаты машины
                for _,player in pairs(getAllChars()) do
                    if player ~= HndlPed then
                        local playerid = select(2, sampGetPlayerIdByCharHandle(player)) -- получаем ID игрока
                        if not sampIsPlayerNpc(playerid) and playerid ~= -1 then -- проверяем не NPC ли этот игрок
                            local x,y,z = getCharCoordinates(player)
                            if getDistanceBetweenCoords2d(x, y, posX, posY) < 3 then countPlayers = countPlayers + 1 end
                        end
                    end
                end
                local distBetween2d = getDistanceBetweenCoords2d(posXpl, posYpl, posX, posY)
                if minPlayerNear ~= false then
                    if tonumber(minPlayerNear) >= countPlayers then
                        table.insert(tableArr, {distBetween2d, car, posX, posY, posZ, countPlayers})
                    end
                else table.insert(tableArr, {distBetween2d, car, posX, posY, posZ, countPlayers}) end
                countPlayers = 0
            end
        end
        if #tableArr > 0 then -- если в таблице есть данные, то...
            table.sort(tableArr, function(a, b) return (a[1] < b[1]) end) -- сортируем 1-ое значение в каждом массиве от меньшего к большому.
            if radius ~= false then -- если функция проверки на радиус включена, то..
                if tableArr[1][1] <= tonumber(radius) then  -- если дистанция меньше или равна заданному радиусу, то ..
                    return true, tableArr[1][2], tableArr[1][1], tableArr[1][3], tableArr[1][4], tableArr[1][5], tableArr[1][6] -- возвращаем значения
                end
            else return true, tableArr[1][2], tableArr[1][1], tableArr[1][3], tableArr[1][4], tableArr[1][5], tableArr[1][6] end -- иначе, возвращаем данные
        end
    end
    return false
end
Lua:
function main()
    if not isSampAvailable() then return false end
    sampRegisterChatCommand("test1", test1) -- /test1
    sampRegisterChatCommand("test2", test2) -- /test2 [id Player]
    sampRegisterChatCommand("test3", test3) -- /test3 [id Player]
    wait(-1)
end

function test1() -- ищет ближайшую машину к вам (PLAYER_PED) в радиусе 200 метров, и у искомой машины рядом должно быть не более 6 игроков
    local result, HandleVeh, Distance, posX, posY, posZ, countPlayers = GetNearestCarByPed(PLAYER_PED, 200, 6)
    if result then
        print("Car ID - "..select(2, sampGetVehicleIdByCarHandle(HandleVeh)).." Distance Between you and HandleVeh - "..Distance.."\nPosition: X - "..posX.." Y - "..posY.." Z - "..posZ.."\nCount Players Near HandleVeh - "..countPlayers)
    else
        print("The function returned False")
    end
end

function test2(id) -- ищет ближайшую машину к указанному игроку по всей зоне стрима.
    local HandlePlayer = select(2, sampGetCharHandleBySampPlayerId(id))
    local result, HandleVeh, Distance, posX, posY, posZ, countPlayers = GetNearestCarByPed(HandlePlayer, false, false)
    if result then
        print("Car ID - "..select(2, sampGetVehicleIdByCarHandle(HandleVeh)).." Distance Between you and HandleVeh - "..Distance.."\nPosition: X - "..posX.." Y - "..posY.." Z - "..posZ.."\nCount Players Near HandleVeh - "..countPlayers)
    else
        print("The function returned False")
    end
end

function test3(id) -- ищет ближайшую машину к указанному игроку по всей зоне стрима.
    -- можно получать и только первые 2 значения если вам не нужна остальная информация.
    local HandlePlayer = select(2, sampGetCharHandleBySampPlayerId(id))
    local result, HandleVeh = GetNearestCarByPed(HandlePlayer, false, false)
    if result then
        sampAddChatMessage("Nearest Car ID - "..select(2, sampGetVehicleIdByCarHandle(HandleVeh)))
    else
        print("The function returned False")
    end
end
 

|| NN - NoName ||

Известный
1,049
635
Описание: Получаем дистанцию и хендл ближайшей к игроку машине. Если вы сидите в машине, то она не считается. Можно получить: 1) Если у машины есть водитель. 2) Без водителя. 3) Без разницы есть или нету.
Lua:
function GetCarHandle(param)
    local var_veh, var_dist = nil, nil
    for _, veh in ipairs(getAllVehicles()) do
        local mX, mY, mZ = getCarCoordinates(veh)
        local x, y, z = getCharCoordinates(PLAYER_PED)
        local dist = getDistanceBetweenCoords3d(x, y, z, mX, mY, mZ)
        if var_dist == nil or dist < var_dist then
            if veh ~= getCarCharIsUsing(PLAYER_PED) then
                if param == 1 then -- если у машины есть водитель
                    local ped = getDriverOfCar(veh)
                    if ped ~= -1 then
                        var_dist = dist
                        var_veh = veh
                    end
                elseif param == 2 then -- если у машины нету водителя
                    if ped == -1 then
                        var_dist = dist
                        var_veh = veh
                    end
                elseif param == 3 then -- если есть и если нету
                    var_dist = dist
                    var_veh = veh
                end
            end
        end
    end
    return var_veh, var_dist
end
Пример использования:
Lua:
function main()
    sampRegisterChatCommand('lol', function(param)
        local veh, dist = GetCarHandle(tonumber(param))
        if veh ~= nil then
            local _, id = sampGetVehicleIdByCarHandle(veh)
            sampAddChatMessage('Самый ближайший транспорт к вам имеет ID: '..id..'. Дистанция: '..dist, -1)
        end
    end)
    wait(-1)
end
 

kin4stat

mq-team · kin4@naebalovo.team
Всефорумный модератор
2,746
4,831
Описание: Player chams
Вызов должен производиться в EndScene или Present

Lua:
ffi.cdef[[
    typedef unsigned long DWORD;

    struct d3ddeviceVTBL {
        void *QueryInterface;
        void *AddRef;
        void *Release;
        void *TestCooperativeLevel;
        void *GetAvailableTextureMem;
        void *EvictManagedResources;
        void *GetDirect3D;
        void *GetDeviceCaps;
        void *GetDisplayMode;
        void *GetCreationParameters;
        void *SetCursorProperties;
        void *SetCursorPosition;
        void *ShowCursor;
        void *CreateAdditionalSwapChain;
        void *GetSwapChain;
        void *GetNumberOfSwapChains;
        void *Reset;
        void *Present;
        void *GetBackBuffer;
        void *GetRasterStatus;
        void *SetDialogBoxMode;
        void *SetGammaRamp;
        void *GetGammaRamp;
        void *CreateTexture;
        void *CreateVolumeTexture;
        void *CreateCubeTexture;
        void *CreateVertexBuffer;
        void *CreateIndexBuffer;
        void *CreateRenderTarget;
        void *CreateDepthStencilSurface;
        void *UpdateSurface;
        void *UpdateTexture;
        void *GetRenderTargetData;
        void *GetFrontBufferData;
        void *StretchRect;
        void *ColorFill;
        void *CreateOffscreenPlainSurface;
        void *SetRenderTarget;
        void *GetRenderTarget;
        void *SetDepthStencilSurface;
        void *GetDepthStencilSurface;
        void *BeginScene;
        void *EndScene;
        void *Clear;
        void *SetTransform;
        void *GetTransform;
        void *MultiplyTransform;
        void *SetViewport;
        void *GetViewport;
        void *SetMaterial;
        void *GetMaterial;
        void *SetLight;
        void *GetLight;
        void *LightEnable;
        void *GetLightEnable;
        void *SetClipPlane;
        void *GetClipPlane;
        void *SetRenderState;
        void *GetRenderState;
        void *CreateStateBlock;
        void *BeginStateBlock;
        void *EndStateBlock;
        void *SetClipStatus;
        void *GetClipStatus;
        void *GetTexture;
        void *SetTexture;
        void *GetTextureStageState;
        void *SetTextureStageState;
        void *GetSamplerState;
        void *SetSamplerState;
        void *ValidateDevice;
        void *SetPaletteEntries;
        void *GetPaletteEntries;
        void *SetCurrentTexturePalette;
        void *GetCurrentTexturePalette;
        void *SetScissorRect;
        void *GetScissorRect;
        void *SetSoftwareVertexProcessing;
        void *GetSoftwareVertexProcessing;
        void *SetNPatchMode;
        void *GetNPatchMode;
        void *DrawPrimitive;
        void* DrawIndexedPrimitive;
        void *DrawPrimitiveUP;
        void *DrawIndexedPrimitiveUP;
        void *ProcessVertices;
        void *CreateVertexDeclaration;
        void *SetVertexDeclaration;
        void *GetVertexDeclaration;
        void *SetFVF;
        void *GetFVF;
        void *CreateVertexShader;
        void *SetVertexShader;
        void *GetVertexShader;
        void *SetVertexShaderConstantF;
        void *GetVertexShaderConstantF;
        void *SetVertexShaderConstantI;
        void *GetVertexShaderConstantI;
        void *SetVertexShaderConstantB;
        void *GetVertexShaderConstantB;
        void *SetStreamSource;
        void *GetStreamSource;
        void *SetStreamSourceFreq;
        void *GetStreamSourceFreq;
        void *SetIndices;
        void *GetIndices;
        void *CreatePixelShader;
        void *SetPixelShader;
        void *GetPixelShader;
        void *SetPixelShaderConstantF;
        void *GetPixelShaderConstantF;
        void *SetPixelShaderConstantI;
        void *GetPixelShaderConstantI;
        void *SetPixelShaderConstantB;
        void *GetPixelShaderConstantB;
        void *DrawRectPatch;
        void *DrawTriPatch;
        void *DeletePatch;
    };

    struct d3ddevice {
        struct d3ddeviceVTBL** vtbl;
    };
]]

GetTextureStageState(pDevice, 0, 32, dwConstant)
GetTextureStageState(pDevice, 0, 26, dwARG0)
GetTextureStageState(pDevice, 0, 2,  dwARG1)
GetTextureStageState(pDevice, 0, 3,  dwARG2)
SetTextureStageState(pDevice, 0, 32, color) -- color - цвет чамсов
SetTextureStageState(pDevice, 0, 26, 6)
SetTextureStageState(pDevice, 0, 2,  6)
SetTextureStageState(pDevice, 0, 3,  6)

ffi.cast("void(__thiscall*)(void*)", 0x59F180)(ffi.cast("void*", pPed)) -- pPed - указатель на педа

SetTextureStageState(pDevice, 0, 32, dwConstant[0])
SetTextureStageState(pDevice, 0, 26, dwARG0[0])
SetTextureStageState(pDevice, 0, 2,  dwARG1[0])
SetTextureStageState(pDevice, 0, 3,  dwARG2[0])

Пример использования:
Lua:
function main()
    AddPlayerToChamsQuery(PLAYER_PED, 0xFFAABB00)
    wait(-1)
end

local ChamsQuery = {
}

function AddPlayerToChamsQuery(handle, color)
    ChamsQuery[handle] = color
end

function RemoveFromChamsQuery(handle)
    ChamsQuery.remove(handle)
end

function onD3DPresent()
    local pDevice = ffi.cast("struct d3ddevice*", 0xC97C28)
    local SetTextureStageState =  ffi.cast("long(__stdcall*)(void*, unsigned long, unsigned long, unsigned long)", pDevice.vtbl[0].SetTextureStageState)
    local GetTextureStageState =  ffi.cast("long(__stdcall*)(void*, unsigned long, unsigned long, unsigned int*)", pDevice.vtbl[0].GetTextureStageState)

    local dwConstant = ffi.new("unsigned int[1]")
    local dwARG0 = ffi.new("unsigned int[1]")
    local dwARG1 = ffi.new("unsigned int[1]")
    local dwARG2 = ffi.new("unsigned int[1]")
    for key, color in pairs(ChamsQuery) do
        local pPed = getCharPointer(key)
        if pPed ~= 0 then
            GetTextureStageState(pDevice, 0, 32, dwConstant)
            GetTextureStageState(pDevice, 0, 26, dwARG0)
            GetTextureStageState(pDevice, 0, 2,  dwARG1)
            GetTextureStageState(pDevice, 0, 3,  dwARG2)
            SetTextureStageState(pDevice, 0, 32, color)
            SetTextureStageState(pDevice, 0, 26, 6)
            SetTextureStageState(pDevice, 0, 2,  6)
            SetTextureStageState(pDevice, 0, 3,  6)
         
            ffi.cast("void(__thiscall*)(void*)", 0x59F180)(ffi.cast("void*", pPed))
         
            SetTextureStageState(pDevice, 0, 32, dwConstant[0])
            SetTextureStageState(pDevice, 0, 26, dwARG0[0])
            SetTextureStageState(pDevice, 0, 2,  dwARG1[0])
            SetTextureStageState(pDevice, 0, 3,  dwARG2[0])
        end
    end
end

1610898787486.png

P.S. в примере довольно херовая реализация "очереди", лучше переделывайте под свою
P.P.S т.к. onD3DPresent вызывается даже после сампфункса, эти чамсы будут поверх всего, чего только можно, так что лучше хукать D3D, но было лень, моя цель только показать как это реализовать, а не показать реальный пример.
 
Последнее редактирование:

sᴀxᴏɴ

саксофон
Всефорумный модератор
791
853
Описание: возвращает массив из логических дисков в системе

Lua:
local ffi = require("ffi")
local bit = require("bit")

ffi.cdef([[
  typedef unsigned long DWORD;
  DWORD GetLogicalDrives();
]])

local function getLogicalDrives()
    local bitmask = ffi.C.GetLogicalDrives()
    local drives = {}
    for i = 0, 25 do
        if bit.band(bitmask, bit.lshift(0x00000001, i)) ~= 0 then
            drives[#drives + 1] = string.char(65 + i) .. ":\\"
        end
    end
    return drives
end
 
Последнее редактирование:

Cosmo

Известный
Друг
656
2,744
Описание:
Ранее часто сталкивался с проблемой быстро и без заморочек прочитать какой либо неизвестный мне массив с информацией. Во многих ЯП функция вывода информации (в луа это print()) умеют читать массивы и выводить их в удобоваримом виде в консоль, но к сожалению данной фичи нет в Lua. Модернизированная функция print ниже умеет это делать. Спасибо @imring за то, что помог найти функцию перевода массива в строку

Lua:
local print_orig = print
function print(...)
    local args = {...}
    function table.val_to_str( v )
          if "string" == type( v ) then
            v = string.gsub( v, "\n", "\\n" )
            if string.match( string.gsub(v,"[^'\"]",""), '^"+$' ) then
                  return "'" .. v .. "'"
            end
            return '"' .. string.gsub(v,'"', '\\"' ) .. '"'
          else
            return "table" == type( v ) and table.tostring( v ) or tostring( v )
          end
    end
    function table.key_to_str( k )
          if "string" == type( k ) and string.match( k, "^[_%a][_%a%d]*$" ) then
            return k
          else
            return "[" .. table.val_to_str( k ) .. "]"
          end
    end
    function table.tostring( tbl )
        local result, done = {}, {}
        for k, v in ipairs( tbl ) do
            table.insert( result, table.val_to_str( v ) )
            done[ k ] = true
        end
        for k, v in pairs( tbl ) do
            if not done[ k ] then
                 table.insert( result, table.key_to_str( k ) .. "=" .. table.val_to_str( v ) )
            end
        end
        return "{" .. table.concat( result, "," ) .. "}"
    end
    for i, arg in ipairs(args) do
        if type(arg) == "table" then
            args[i] = table.tostring(arg)
        end
    end
    print_orig(table.unpack(args))
end

Пример использования:
Lua:
arr = {
    name = 'Cosmo',
    age = 19,
    other = {
        weight = 100,
        lenght = 189
    }
}

print(arr) -- Output: {age=19,name="Cosmo",other={lenght=189,weight=100}}
 
Последнее редактирование:

imring

Ride the Lightning
Всефорумный модератор
2,365
2,552
Описание:
Ранее часто сталкивался с проблемой быстро и без заморочек прочитать какой либо неизвестный мне массив с информацией. Во многих ЯП функция вывода информации (в луа это print()) умеют читать массивы и выводить их в удобоваримом виде в консоль, но к сожалению данной фичи нет в Lua. Модернизированная функция print ниже, хоть и корявенько, но умеет это делать. Функцию "рисования" таблицы взял с англоязычного форума.

Функция:
Lua:
local print_orig = print
function print(...)
    local args = {...}
    drawTable = function (tbl, indent)
    if not indent then indent = 0 end
        local toprint = "{\r\n"
        indent = indent + 4
        for k, v in pairs(tbl) do
            toprint = toprint .. string.rep(" ", indent)
            if type(k) == "number" then
                toprint = toprint .. "[" .. k .. "] = "
            elseif type(k) == "string" then
                toprint = toprint  .. k ..  " = "
            end
            if type(v) == "number" then
                toprint = toprint .. v .. ",\r\n"
            elseif type(v) == "string" then
                toprint = toprint .. "\"" .. v .. "\",\r\n"
            elseif type(v) == "table" then
                toprint = toprint .. drawTable(v, indent) .. ",\r\n"
            else
                toprint = toprint .. "\"" .. tostring(v) .. "\",\r\n"
            end
        end
        toprint = toprint .. string.rep(" ", indent - 4) .. "}"
           return toprint
    end
    for i, arg in ipairs(args) do
        if type(arg) == 'table' then
            args[i] = drawTable(arg)
        end
    end
    print_orig(table.unpack(args))
end

Пример использования:
Lua:
arr = {
    name = 'Cosmo',
    age = 19,
    other = {
        weight = 100,
        lenght = 189
    }
}

print(arr)
Output:
{
    age = 19,
    other = {
        lenght = 189,
        weight = 100,
    },
    name = "Cosmo",
}
 

CaJlaT

07.11.2024 14:55
Модератор
2,835
2,673
Описание: Вертикальный Меню-бар с скруглением справа и анимацией движения (скорость настраивается, но напрямую зависит от фпс)
P.s: Не бейте за говнокод, а напишите что исправить
UPD: Пофиксил моргание
Lua:
function imgui.Selector(labels, size, selected, pos, speed)
    local rBool = false
    if not speed then speed = 10 end
    if (pos.v < (selected.v * size.y)) then
        pos.v = pos.v + speed
    elseif (pos.v > (selected.v * size.y)) then
        pos.v = pos.v - speed
    end
    imgui.SetCursorPos(imgui.ImVec2(0.00, pos.v))
    local draw_list = imgui.GetWindowDrawList()
    local p = imgui.GetCursorScreenPos()
    local radius = size.y * 0.50
    draw_list:AddRectFilled(imgui.ImVec2(p.x-size.x/2, p.y), imgui.ImVec2(p.x + radius + 1 * (size.x - radius * 2.0), p.y + radius*2), imgui.GetColorU32(imgui.GetStyle().Colors[imgui.Col.ButtonActive]))
    draw_list:AddRectFilled(imgui.ImVec2(p.x-size.x/2, p.y), imgui.ImVec2(p.x + 5, p.y + size.y), imgui.GetColorU32(imgui.GetStyle().Colors[imgui.Col.Button]), 0)
    draw_list:AddCircleFilled(imgui.ImVec2(p.x + radius + 1 * (size.x - radius * 2.0), p.y + radius), radius, imgui.GetColorU32(imgui.GetColorU32(imgui.GetStyle().Colors[imgui.Col.ButtonActive])), radius/10*12)
    for i = 1, #labels do
        imgui.SetCursorPos(imgui.ImVec2(0, (i * size.y)))
        local p = imgui.GetCursorScreenPos()
        if imgui.InvisibleButton(labels[i], size) then selected.v = i rBool = true end
        if imgui.IsItemHovered() then
            draw_list:AddRectFilled(imgui.ImVec2(p.x-size.x/2, p.y), imgui.ImVec2(p.x + size.x, p.y + size.y), imgui.GetColorU32(imgui.ImVec4(0.58, 0.34, 0.46, 0.20)), radius/10*12)
        end
        imgui.SetCursorPos(imgui.ImVec2(20, (i * size.y + (size.y-imgui.CalcTextSize(labels[i]).y)/2)))
        imgui.Text(labels[i])
    end
    return rBool
end
Пример использования:
Lua:
local selected_label = imgui.ImInt(1)
local selector_pos = imgui.ImInt(0)
local menu = {
    u8'Что-то',
    u8'Пункт 2',
    u8'Кто я?',
    fa.ICON_FA_PAINT_ROLLER..u8' Ролик'
}




--OnDrawFrame()
imgui.Begin('##window', _, imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoResize + imgui.WindowFlags.NoTitleBar + imgui.WindowFlags.NoScrollbar)
    if imgui.Selector(menu, imgui.ImVec2(130, 50), selected_label, selector_pos, 10) then print('Вы переключили меню на пункт '..selected_label.v) end
    imgui.SetCursorPos(imgui.ImVec2(140, 0))
    imgui.BeginChild('main', imgui.ImVec2(400, 300), true)
        imgui.Text(menu[selected_label.v])
        if selected_label.v == 4 then
            imgui.Text(fa.ICON_FA_PAINT_ROLLER)
        end
    imgui.EndChild()
imgui.End()
ezgif-2-b9a68a1acdbc.gif
 
Последнее редактирование:

ImPasha

Software Developer & System Administrator
Друг
1,788
2,142
Описание: получает список персонажей, находящихся в транспортном средстве.
Lua:
local function store_chars_in_vehicle(vehicle_handle)
  if not doesVehicleExist(vehicle_handle) then return false end
  local stored_data = {}
  for i = -1, getMaximumNumberOfPassengers(vehicle_handle) - 1 do
    if not isCarPassengerSeatFree(vehicle_handle, i) then
      stored_data[#stored_data + 1] = {
        i+1, getCharInCarPassengerSeat(vehicle_handle, i)
      }
    else stored_data[#stored_data + 1] = {i+1, -1} end
  end
  return stored_data
end
Пример использования:
Lua:
local stored_chars = store_chars_in_vehicle(my_car)
local busy_place = 0
for i, v in ipairs(stored_chars) do
  if v[2] == -1 then
    print(("Место %s не занято никем"):format(v[1]))
  else
    print(("Место %s занято: PED %s"):format(v[1], v[2]))
    busy_place = busy_place + 1
  end
end
if busy_place == 0 then
  print("Все места в машине свободны!")
end
 

Cosmo

Известный
Друг
656
2,744
Описание:
Что-то типо подсказки как бывают в обучениях во многих играх, аля тыкни сюда, тыкни туда и т.п

imgui.TutorialHint(string str_id, string text, bool value, bool hideOnClick):
function imgui.TutorialHint(str_id, text, bool, hideOnClick)
    local p_orig = imgui.GetCursorPos()
    if hideOnClick == nil then hideOnClick = true end

    imgui.SameLine(nil, 0)
    local size = imgui.GetItemRectSize()
    local scrPos = imgui.GetCursorScreenPos()
    local DL = imgui.GetWindowDrawList()
    local center = imgui.ImVec2( scrPos.x - (size.x / 2), scrPos.y + (size.y / 2) )

    if bool[0] then
        local a = imgui.ImVec2( center.x - 8, center.y - size.y - 1 )
        local b = imgui.ImVec2( center.x + 8, center.y - size.y - 1)
        local c = imgui.ImVec2( center.x, center.y - size.y + 7 )
        DL:AddTriangleFilled(a, b, c, imgui.ColorConvertFloat4ToU32(imgui.GetStyle().Colors[imgui.Col.PopupBg]))
        imgui.SetNextWindowPos(imgui.ImVec2(center.x, center.y - size.y - 3), imgui.Cond.Always, imgui.ImVec2(0.5, 1.0))
        imgui.PushStyleColor(imgui.Col.WindowBg, imgui.GetStyle().Colors[imgui.Col.PopupBg])
        imgui.PushStyleColor(imgui.Col.Border, imgui.GetStyle().Colors[imgui.Col.PopupBg])
        imgui.Begin('##' .. str_id, _, imgui.WindowFlags.Tooltip + imgui.WindowFlags.AlwaysAutoResize + imgui.WindowFlags.NoScrollbar + imgui.WindowFlags.NoTitleBar)
            local width = imgui.GetWindowWidth()
            for line in text:gmatch('[^\r\n]+') do
                local len = imgui.CalcTextSize(line).x
                imgui.SetCursorPosX(width / 2 - ( len / 2 ))
                imgui.Text(line)
            end

            if hideOnClick and imgui.IsMouseClicked(0) then
                local wp = imgui.GetWindowPos()
                local ws = imgui.GetWindowSize()
                local m = imgui.GetMousePos()
                if m.x >= wp.x and m.y >= wp.y and m.x <= wp.x + ws.x and m.y <= wp.y + ws.y then
                    bool[0] = not bool[0]
                end
            end
        imgui.End()
        imgui.PopStyleColor(2)
    end

    imgui.SetCursorPos(p_orig)
end

Использование:
Lua:
-- в кфг
tutorial = {
    blue_button = true
}

-- где-нибудь
butTutor = imgui.new.bool(cfg.tutorial.blue_button)

-- в OnFrame
if imgui.Button('Yeah, push me, baby', imgui.ImVec2(200, 30)) then
    if butTutor[0] then
        butTutor[0] = false
        cfg.tutorial.blue_button = butTutor[0]
    end
end
imgui.TutorialHint('but_tutorial', 'This is blue button\nPush it!', butTutor, false)
-- последний параметр отвечает за то, можно ли скрыть подсказку нажатием на неё (по дефолту можно)

Как выглядит:
dem.gif


 

_razor

t.me/sssecretway | ТГК: t.me/razor_code
Всефорумный модератор
1,952
3,223
Описание: Получает высоту и ширину текущего диалога
Lua:
local memory = require("memory")

function sampGetCurrentDialogSize()
    local sampBase = getModuleHandle("samp.dll")
    if sampBase ~= nil then
        local CDialog = memory.getuint32(sampBase + 0x21A0B8)
        local CDXUTDialog = memory.getuint32(CDialog + 0x1C)
        local width = memory.read(CDXUTDialog + 0x11E, 4, true)
        local height = memory.read(CDXUTDialog + 0x122, 4, true)
        return width, height
    end
end
Пример использования:
Lua:
local w, h = sampGetCurrentDialogSize()
print(w, h)

Описание: Изменяет размеры текущего диалога
Lua:
function sampSetCurrentDialogSize(w, h)
    local sampBase = getModuleHandle("samp.dll")
    if sampBase ~= nil then
        local CDialog = memory.getuint32(sampBase + 0x21A0B8)
        local CDXUTDialog = memory.getuint32(CDialog + 0x1C)
        memory.write(CDXUTDialog + 0x11E, w, 4, true)
        memory.write(CDXUTDialog + 0x122, h, 4, true)
    end
end
Пример использования:
Lua:
sampSetCurrentDialogSize(500, 500)


1612038451777.png