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

Pakulichev

Software Developer & System Administrator
Друг
1,789
2,133
Описание: обычный sampRegisterChatCommand, но с возможностью регистрации сразу нескольких команд на один обработчик. И то же самое для удаления.
Lua:
local originalSampRegisterChatCommand = sampRegisterChatCommand
local originalSampUnregisterChatCommand = sampUnregisterChatCommand
function sampRegisterChatCommand(commands, callback)
  if type(commands) == "table" then
    local all_registered = true
    for i, v in ipairs(commands) do
      local temp = originalSampRegisterChatCommand(v, callback)
      all_registered = all_registered and temp
    end
    return all_registered
  else
    return originalSampRegisterChatCommand(commands, callback)
  end
end
function sampUnregisterChatCommand(commands)
  if type(commands) == "table" then
    local all_unregistered = true
    for i, v in ipairs(commands) do
      local temp = originalSampUnregisterChatCommand(v)
      all_unregistered = all_unregistered and temp
    end
    return all_unregistered
  else
    return originalSampUnregisterChatCommand(commands)
  end
end
Пример использования:
Lua:
sampRegisterChatCommand({"command", "cmd", "cm", "comm"}, function()
  sampAddChatMessage("Hello world, how are you?", -1)
end)
 

Cosmo

Известный
Друг
646
2,597
Описание:
Простой чайлд, но c заголовком на его обводке (Быдлокод)
Lua:
function imgui.BeginTitleChild(str_id, size, color, offset)
    color = color or imgui.GetStyle().Colors[imgui.Col.Border]
    offset = offset or 30
    local DL = imgui.GetWindowDrawList()
    local posS = imgui.GetCursorScreenPos()
    local rounding = imgui.GetStyle().ChildRounding
    local title = str_id:gsub('##.+$', '')
    local sizeT = imgui.CalcTextSize(title)
    local padd = imgui.GetStyle().WindowPadding
    local bgColor = imgui.ColorConvertFloat4ToU32(imgui.GetStyle().Colors[imgui.Col.WindowBg])

    imgui.PushStyleColor(imgui.Col.ChildBg, imgui.ImVec4(0, 0, 0, 0))
    imgui.PushStyleColor(imgui.Col.Border, imgui.ImVec4(0, 0, 0, 0))
    imgui.BeginChild(str_id, size, true)
    imgui.Spacing()
    imgui.PopStyleColor(2)

    size.x = size.x == -1.0 and imgui.GetWindowWidth() or size.x
    size.y = size.y == -1.0 and imgui.GetWindowHeight() or size.y
    DL:AddRect(posS, imgui.ImVec2(posS.x + size.x, posS.y + size.y), imgui.ColorConvertFloat4ToU32(color), rounding, _, 1)
    DL:AddLine(imgui.ImVec2(posS.x + offset - 3, posS.y), imgui.ImVec2(posS.x + offset + sizeT.x + 3, posS.y), bgColor, 3)
    DL:AddText(imgui.ImVec2(posS.x + offset, posS.y - (sizeT.y / 2)), imgui.ColorConvertFloat4ToU32(color), title)
end

Пример использования:
Lua:
[CODE]local sw, sh = getScreenResolution()
local test_frame = imgui.OnFrame(
    function() return true end,
    function(self)    
        imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(700, 500), imgui.Cond.FirstUseEver)
        imgui.Begin(u8'New Child Demo', menu, imgui.WindowFlags.NoCollapse)

        imgui.BeginTitleChild(u8'Первое окно', imgui.ImVec2(200, 300))
        imgui.EndChild()

        imgui.SameLine()
 
        -- Свой цвет
        imgui.BeginTitleChild(u8'Второе окно', imgui.ImVec2(-1, 300), imgui.ImVec4(0.3, 0.3, 1, 1))
        imgui.EndChild()

        imgui.Spacing()
     
        -- Свой цвет + смещение заголовка на 60 пикселей вправо
        imgui.BeginTitleChild(u8'Третье окно', imgui.ImVec2(-1, -1), imgui.ImVec4(0.3, 1, 0.3, 1), 60)
        imgui.EndChild()

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

Smeruxa

Известный
1,297
682
Описание: Убирает лимит с выстрелов из гидры и выстрела световой пушкой какой-то черт его.
Lua:
function hydraSkill()
    local memory = require 'memory'
    local adress = {'0x6E351B', '0x6D4634', '0x6D462E', '0x6E363A', '0x6E36FB'}
    for k,v in ipairs(adress) do
        memory.setfloat(v, 0)
    end
end
Пример использования:
Lua:
function main()
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand('hydraskill', function()
        hydraSkill()
    end)
    wait(-1)
end

function hydraSkill()
    local memory = require 'memory'
    local adress = {'0x6E351B', '0x6D4634', '0x6D462E', '0x6E363A', '0x6E36FB'}
    for k,v in ipairs(adress) do
        memory.setfloat(v, 0)
    end
end
космо в беседе выложил адреса а я спиздил
 
Последнее редактирование:

imring

Ride the Lightning
Всефорумный модератор
2,355
2,516
Описание: Убирает лимит с выстрелов из гидры и выстрела световой пушкой какой-то черт его.
Lua:
function hydraSkill()
    local memory = require 'memory'
    local adress = {'0x6E351B', '0x6D4634', '0x6D462E', '0x6E363A', '0x6E36FB'}
    for k,v in ipairs(adress) do
        memory.setfloat(v, 0)
    end
end
Пример использования:
Lua:
function main()
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand('hydraskill', function()
        hydraSkill()
    end)
    wait(-1)
end

function hydraSkill()
    local memory = require 'memory'
    local adress = {'0x6E351B', '0x6D4634', '0x6D462E', '0x6E363A', '0x6E36FB'}
    for k,v in ipairs(adress) do
        memory.setfloat(v, 0)
    end
end
космо в беседе выложил адреса а я спиздил
почему адреса - строки?
 
  • Нравится
Реакции: Vintik

Vintik

Мечтатель
Проверенный
1,469
917
почему адреса - строки?
Непонятно. Снизу рабочий по идее.
Lua:
local memory = require 'memory'

function main()
  while not isSampAvailable() do wait(0) end
  sampRegisterChatCommand('hydraskill', function()
    hydraSkill()
  end)
  wait(-1)
end

function hydraSkill()
  local adress = { 0x6E351B, 0x6D4634, 0x6D462E, 0x6E363A, 0x6E36FB }
  for _, adr in ipairs(adress) do
    memory.setfloat(adr, 0)
  end
end
 

Adrian G.

Известный
Проверенный
521
453
Описание: sampSetChatInputText, но вводящий текст последовательно и с указанной задержкой. Кто-то просил скрипт с таким в разделе "Помощь", я подумал почему нет.
Код:
Дёшево, но сердито:
function sampSetChatInputTextWithDelay(text, delay)
    local array = {}
    for i in text:gmatch('[^%z]') do
        wait(delay)
        table.insert(array, i)
        sampSetChatInputText(table.concat(array))
    end
end

Пример использования:
Lua:
local vk = require 'vkeys'

function main()
    if not isSampLoaded() then return end
        while not isSampAvailable() do wait(100) end

    while true do wait(0)
        if isKeyJustPressed(vk.VK_P) then
            sampSetChatInputEnabled(true)
            sampSetChatInputTextWithDelay('Текст вводится последовательно с указанной задержкой.', 5)
        end
    end   
end
укпук.gif

вкр6.gif
 

Vintik

Мечтатель
Проверенный
1,469
917
Код:
Дёшево, но сердито:
function sampSetChatInputTextWithDelay(text, delay)
    local array = {}
    for i in text:gmatch('[^%z]') do
        wait(delay)
        table.insert(array, i)
        sampSetChatInputText(table.concat(array))
    end
end
Неплохо, но всё же.

Lua:
function sampSetChatInputTextWithDelay(text, delay)
  for i = 1, text:len() do
    wait(delay)
    sampSetChatInputText(text:sub(1, i))
  end
end
 

CaJlaT

Овощ
Модератор
2,805
2,606
Описание: Ищет ближайший серверный объект по id модели
Lua:
function GetNearestObject(modelid)
    local objects = {}
    local x, y, z = getCharCoordinates(playerPed)
    for i, obj in ipairs(getAllObjects()) do
        if getObjectModel(obj) == modelid then
            local result, ox, oy, oz = getObjectCoordinates(obj)
            table.insert(objects, {getDistanceBetweenCoords3d(ox, oy, oz, x, y, z), ox, oy, oz})
        end
    end
    if #objects <= 0 then return false end
    table.sort(objects, function(a, b) return a[1] < b[1] end)
    return true, unpack(objects[1])
end
Пример использования:
Lua:
local result, distance, x, y, z = GetNearestObject(660)
sampAddChatMessage(string.format('Ближайшее дерево находится на расстоянии %.2f метров от вас', distance), -1)
 
Последнее редактирование:

invilso.

Известный
249
89
Описание:
Ранее часто сталкивался с проблемой быстро и без заморочек прочитать какой либо неизвестный мне массив с информацией. Во многих ЯП функция вывода информации (в луа это 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}}

Можно ещё так, мне кажется это более удобным.
Lua:
function dump(o)
   if type(o) == 'table' then
      local s = '{ '
      for k,v in pairs(o) do
         if type(k) ~= 'number' then k = '"'..k..'"' end
         s = s .. '['..k..'] = ' .. dump(v) .. ','
      end
      return s .. '} '
   else
      return tostring(o)
   end
end
Lua:
local people = {
   {
      name = "Fred",
      address = "16 Long Street",
      phone = "123456"
   },

   {
      name = "Wilma",
      address = "16 Long Street",
      phone = "123456"
   },

   {
      name = "Barney",
      address = "17 Long Street",
      phone = "123457"
   },
   {
       1,
       2,
       3,
       4,
       5,
   }

}
function dump(o)
   if type(o) == 'table' then
      local s = '{ '
      for k,v in pairs(o) do
         if type(k) ~= 'number' then k = '"'..k..'"' end
         s = s .. '['..k..'] = ' .. dump(v) .. ','
      end
      return s .. '} '
   else
      return tostring(o)
   end
end

print(dump(people))
--{ [1] = { ["address"] = 16 Long Street,["phone"] = 123456,["name"] = Fred,} ,[2] = { ["address"] = 16 Long Street,["phone"] = 123456,["name"] = Wilma,} ,[3] = { ["address"] = 17 Long Street,["phone"] = 123457,["name"] = Barney,} ,[4] = { [1] = 1,[2] = 2,[3] = 3,[4] = 4,[5] = 5,} ,}
 

#Northn

Police Helper «Reborn» — уже ШЕСТЬ лет!
Всефорумный модератор
2,634
2,483
Можно ещё так, мне кажется это более удобным.
Lua:
function dump(o)
   if type(o) == 'table' then
      local s = '{ '
      for k,v in pairs(o) do
         if type(k) ~= 'number' then k = '"'..k..'"' end
         s = s .. '['..k..'] = ' .. dump(v) .. ','
      end
      return s .. '} '
   else
      return tostring(o)
   end
end
Lua:
local people = {
   {
      name = "Fred",
      address = "16 Long Street",
      phone = "123456"
   },

   {
      name = "Wilma",
      address = "16 Long Street",
      phone = "123456"
   },

   {
      name = "Barney",
      address = "17 Long Street",
      phone = "123457"
   },
   {
       1,
       2,
       3,
       4,
       5,
   }

}
function dump(o)
   if type(o) == 'table' then
      local s = '{ '
      for k,v in pairs(o) do
         if type(k) ~= 'number' then k = '"'..k..'"' end
         s = s .. '['..k..'] = ' .. dump(v) .. ','
      end
      return s .. '} '
   else
      return tostring(o)
   end
end

print(dump(people))
--{ [1] = { ["address"] = 16 Long Street,["phone"] = 123456,["name"] = Fred,} ,[2] = { ["address"] = 16 Long Street,["phone"] = 123456,["name"] = Wilma,} ,[3] = { ["address"] = 17 Long Street,["phone"] = 123457,["name"] = Barney,} ,[4] = { [1] = 1,[2] = 2,[3] = 3,[4] = 4,[5] = 5,} ,}
encodeJson(t)
Вот и всё..
 

meowprd

Тот самый Котовский
Проверенный
1,280
712
Описание: Находит ближайший пикап по его модели
Lua:
function getNearestPickup(modelid)
    local pickups = {}
    local x, y, z = getCharCoordinates(playerPed)
    for i, v in ipairs(getAllPickups()) do
        local id = sampGetPickupSampIdByHandle(v)
        if getPickupModel(id) == modelid then
            local px, py, pz = getPickupCoordinates(v)
            table.insert(pickups, {getDistanceBetweenCoords3d(px, py, pz, x, y, z), px, py, pz})
        end
    end
    table.sort(pickups, function(a, b) return a[1] < b[1] end)
    return unpack(pickups[1])
end


function getAllPickups() -- https://www.blast.hk/threads/13380/page-8#post-361600
    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


function getPickupModel(id) -- https://www.blast.hk/threads/13380/page-15#post-604316
    PICKUP_POOL = sampGetPickupPoolPtr()
    return ffi.cast("int *", (id * 20 + 61444) + PICKUP_POOL)[0]
end
Пример использования:
Lua:
local ffi = require('ffi')

local distance, x, y, z = getNearestPickup(1274)
 

Vintik

Мечтатель
Проверенный
1,469
917
Описание: Простая реализация CoordMaster с использованием рекурсии.
CoordMaster:
function CoordMaster(px, py, pz, step, time)
  local x, y, z = getCharCoordinates(PLAYER_PED)
  local d = getDistanceBetweenCoords3d(px, py, pz, x, y, z)
  if d <= step then
    setCharCoordinates(PLAYER_PED, px, py, pz)
    freezeCharPosition(PLAYER_PED, false)
  else
    local dx, dy, dz = px - x, py - y, pz - z
    x = x + step / d * dx
    y = y + step / d * dy
    z = z + step / d * dz
    freezeCharPosition(PLAYER_PED, true)
    setCharCoordinates(PLAYER_PED, x, y, z)
    wait(time)
    CoordMaster(px, py, pz, step, time)
  end
end
Пример использования:
Пример вызова функции:
function main()
  while not isSampAvailable() do wait(0) end
  sampRegisterChatCommand('teleport', lua_thread.create(teleport)) -- новый поток потому, что используются задержки (wait)
  wait(-1)
end

function teleport()
  local result, x, y, z = getTargetBlipCoordinates()
  if result then -- если на карте установлена метка
      CoordMaster(x, y, z, 40, 300) -- каждый тп на 40 метров, между ними 300 мс
  end
end
 
Последнее редактирование:

meowprd

Тот самый Котовский
Проверенный
1,280
712
Описание: Поворот камеры на координаты с настраиваемой скоростью
Lua:
-- setAngle(float x, float y, float distance, float speed)
function setAngle(x, y, distance, speed)
    local source_x = fix(representIntAsFloat(readMemory(0xB6F248, 4, false)))
    local source_z = fix(representIntAsFloat(readMemory(0xB6F258, 4, false))) + math.pi
    local angle = GetAngleBeetweenTwoPoints(x,y) - source_z - math.pi

    if distance > 1.8 then
        if angle > -0.1 and angle < 0.03 then setCameraPositionUnfixed(-0.3, GetAngleBeetweenTwoPoints(x,y))
        elseif angle < -5.7 and angle > -5.93 then setCameraPositionUnfixed(-0.3, GetAngleBeetweenTwoPoints(x,y))
        elseif angle < -6.0 and angle > -6.4 then setCameraPositionUnfixed(-0.3, GetAngleBeetweenTwoPoints(x,y))
        elseif angle > 0.04 then setCameraPositionUnfixed(-0.3, fix(representIntAsFloat(readMemory(0xB6F258, 4, false)))+speed)
        elseif angle < -3.5 and angle > -5.67 then setCameraPositionUnfixed(-0.3, fix(representIntAsFloat(readMemory(0xB6F258, 4, false)))+speed)
        else setCameraPositionUnfixed(-0.3, fix(representIntAsFloat(readMemory(0xB6F258, 4, false)))-speed)
        end
    else setCameraPositionUnfixed(source_x, GetAngleBeetweenTwoPoints(x,y)) end
end

function GetAngleBeetweenTwoPoints(x2,y2)
    local x1, y1, z1 = getCharCoordinates(playerPed)
    local plus = 0.0
    local mode = 1
    if x1 < x2 and y1 > y2 then plus = math.pi/2; mode = 2; end
    if x1 < x2 and y1 < y2 then plus = math.pi; end
    if x1 > x2 and y1 < y2 then plus = math.pi*1.5; mode = 2; end
    local lx = x2 - x1
    local ly = y2 - y1
    lx = math.abs(lx)
    ly = math.abs(ly)
    if mode == 1 then ly = ly/lx;
    else ly = lx/ly; end 
    ly = math.atan(ly)
    ly = ly + plus
    return ly
end

function fix(angle)
    while angle > math.pi do
        angle = angle - (math.pi*2)
    end
    while angle < -math.pi do
        angle = angle + (math.pi*2)
    end
    return angle
end
Пример использования:
Lua:
-- Рекомендую использовать скорость 0.04 как основную, довольно таки плавно и быстро, достаточно сбалансированное значение
-- Мега плавность
while true do
    wait(0)
    local pX, pY, pZ = getCharCoordinates(playerPed)
    local distance = getDistanceBetweenCoords3d(-118.2401,128.8386,3.1272, pX, pY, pZ)
    setAngle(-118.2401, 128.8386, distance, 0.0001)
end

-- Относительно быстрый поворот на координаты
while true do
    wait(0)
    local pX, pY, pZ = getCharCoordinates(playerPed)
    local distance = getDistanceBetweenCoords3d(-118.2401,128.8386,3.1272, pX, pY, pZ)
    setAngle(-118.2401, 128.8386, distance, 0.1)
end

Update: дополнил функции (забыл добавить их сразу)
 
Последнее редактирование:

imring

Ride the Lightning
Всефорумный модератор
2,355
2,516
Lua:
if angle > -0.1 and angle < 0.03 then setCameraPositionUnfixed(-0.3, GetAngleBeetweenTwoPoints(x,y))
elseif angle < -5.7 and angle > -5.93 then setCameraPositionUnfixed(-0.3, GetAngleBeetweenTwoPoints(x,y))
elseif angle < -6.0 and angle > -6.4 then setCameraPositionUnfixed(-0.3, GetAngleBeetweenTwoPoints(x,y))
можно объединить в одну проверку
Lua:
elseif angle > 0.04 then setCameraPositionUnfixed(-0.3, fix(representIntAsFloat(readMemory(0xB6F258, 4, false)))+speed)
elseif angle < -3.5 and angle > -5.67 then setCameraPositionUnfixed(-0.3, fix(representIntAsFloat(readMemory(0xB6F258, 4, false)))+speed)
аналогично