Вопросы по Lua скриптингу

Общая тема для вопросов по разработке скриптов на языке программирования Lua, в частности под MoonLoader.
  • Задавая вопрос, убедитесь, что его нет в списке частых вопросов и что на него ещё не отвечали (воспользуйтесь поиском).
  • Поищите ответ в теме посвященной разработке Lua скриптов в MoonLoader
  • Отвечая, убедитесь, что ваш ответ корректен.
  • Старайтесь как можно точнее выразить мысль, а если проблема связана с кодом, то обязательно прикрепите его к сообщению, используя блок [code=lua]здесь мог бы быть ваш код[/code].
  • Если вопрос связан с MoonLoader-ом первым делом желательно поискать решение на wiki.

Частые вопросы

Как научиться писать скрипты? С чего начать?
Информация - Гайд - Всё о Lua скриптинге для MoonLoader(https://blast.hk/threads/22707/)
Как вывести текст на русском? Вместо русского текста у меня какие-то каракули.
Изменить кодировку файла скрипта на Windows-1251. В Atom: комбинация клавиш Ctrl+Shift+U, в Notepad++: меню Кодировки -> Кодировки -> Кириллица -> Windows-1251.
Как получить транспорт, в котором сидит игрок?
Lua:
local veh = storeCarCharIsInNoSave(PLAYER_PED)
Как получить свой id или id другого игрока?
Lua:
local _, id = sampGetPlayerIdByCharHandle(PLAYER_PED) -- получить свой ид
local _, id = sampGetPlayerIdByCharHandle(ped) -- получить ид другого игрока. ped - это хендл персонажа
Как проверить, что строка содержит какой-то текст?
Lua:
if string.find(str, 'текст', 1, true) then
-- строка str содержит "текст"
end
Как эмулировать нажатие игровой клавиши?
Lua:
local game_keys = require 'game.keys' -- где-нибудь в начале скрипта вне функции main

setGameKeyState(game_keys.player.FIREWEAPON, -1) -- будет сэмулировано нажатие клавиши атаки
Все иды клавиш находятся в файле moonloader/lib/game/keys.lua.
Подробнее о функции setGameKeyState здесь: lua - setgamekeystate | BlastHack — DEV_WIKI(https://www.blast.hk/wiki/lua:setgamekeystate)
Как получить id другого игрока, в которого целюсь я?
Lua:
local valid, ped = getCharPlayerIsTargeting(PLAYER_HANDLE) -- получить хендл персонажа, в которого целится игрок
if valid and doesCharExist(ped) then -- если цель есть и персонаж существует
  local result, id = sampGetPlayerIdByCharHandle(ped) -- получить samp-ид игрока по хендлу персонажа
  if result then -- проверить, прошло ли получение ида успешно
    -- здесь любые действия с полученным идом игрока
  end
end
Как зарегистрировать команду чата SAMP?
Lua:
-- До бесконечного цикла/задержки
sampRegisterChatCommand("mycommand", function (param)
     -- param будет содержать весь текст введенный после команды, чтобы разделить его на аргументы используйте string.match()
    sampAddChatMessage("MyCMD", -1)
end)
Крашит игру при вызове sampSendChat. Как это исправить?
Это происходит из-за бага в SAMPFUNCS, когда производится попытка отправки пакета определенными функциями изнутри события исходящих RPC и пакетов. Исправления для этого бага нет, но есть способ не провоцировать его. Вызов sampSendChat изнутри обработчика исходящих RPC/пакетов нужно обернуть в скриптовый поток с нулевой задержкой:
Lua:
function onSendRpc(id)
  -- крашит:
  -- sampSendChat('Send RPC: ' .. id)

  -- норм:
  lua_thread.create(function()
    wait(0)
    sampSendChat('Send RPC: ' .. id)
  end)
end
 
Последнее редактирование:

ARMOR

kjor32 is legend
Модератор
4,843
6,061
Lua:
local ev = require("lib.samp.events")

function ev.onShowDialog(dialogId, style, title, button1, button2, text)
    if dialogId == 41 then
        -- читаешь инфу
        return false
    end
end
И получаешь баг из-за которого не сможешь взаимодействовать потом с инвентарем аризоны и т.д
Перед return false нужно отправлять sampSendDialogResponse
 
  • Вау
Реакции: why ega

why ega

РП игрок
Модератор
2,540
2,223
Как лучше удалять значение из таблицы?
Lua:
local arr = {"a", "b", "c", "d"}

arr[3] = nil
-- или
table.remove(arr, 3)
 

Anti...

Участник
232
16
Есть функция от Cosmo которая получает хэндл ближайшего транспорта к экрану. есть пример использования видео
Собственно, как сделать renderDrawLine между мной и ближайшего транспорта? я делал но у меня не получилось, кто знает напишите пожалуйста
Получает хэндл ближайшего транспорта к центру экрана:
function getNearCarToCenter(radius)
    local arr = {}
    local sx, sy = getScreenResolution()
    for _, car in ipairs(getAllVehicles()) do
        if isCarOnScreen(car) and getDriverOfCar(car) ~= playerPed then
            local carX, carY, carZ = getCarCoordinates(car)
            local cX, cY = convert3DCoordsToScreen(carX, carY, carZ)
            local distBetween2d = getDistanceBetweenCoords2d(sx / 2, sy / 2, cX, cY)
            if distBetween2d <= tonumber(radius and radius or sx) then
                table.insert(arr, {distBetween2d, car})
            end
        end
    end
    if #arr > 0 then
        table.sort(arr, function(a, b) return (a[1] < b[1]) end)
        return arr[1][2]
    end
    return nil
end
ИСПОЛЬЗОВАНИЕ:
local car = getNearCarToCenter(150)
if car then
    local carId = select(2, sampGetVehicleIdByCarHandle(car))
    print('Ближайшее к центру атво с ID: '..carId)
else -- nil
    print('Ближайшее к центру авто в указаном радиусе не найдено')
end
 

XRLM

Известный
2,532
847
Как лучше удалять значение из таблицы?
Lua:
local arr = {"a", "b", "c", "d"}

arr[3] = nil
-- или
table.remove(arr, 3)
лучше юзай table.remove, когда делаешь так, как армор посоветовал, то arr[3] у тебя будет равно nil, а table.remove вообще удалит arr[3] и поставит на его место arr[4].

Есть функция от Cosmo которая получает хэндл ближайшего транспорта к экрану. есть пример использования видео
Собственно, как сделать renderDrawLine между мной и ближайшего транспорта? я делал но у меня не получилось, кто знает напишите пожалуйста
Получает хэндл ближайшего транспорта к центру экрана:
function getNearCarToCenter(radius)
    local arr = {}
    local sx, sy = getScreenResolution()
    for _, car in ipairs(getAllVehicles()) do
        if isCarOnScreen(car) and getDriverOfCar(car) ~= playerPed then
            local carX, carY, carZ = getCarCoordinates(car)
            local cX, cY = convert3DCoordsToScreen(carX, carY, carZ)
            local distBetween2d = getDistanceBetweenCoords2d(sx / 2, sy / 2, cX, cY)
            if distBetween2d <= tonumber(radius and radius or sx) then
                table.insert(arr, {distBetween2d, car})
            end
        end
    end
    if #arr > 0 then
        table.sort(arr, function(a, b) return (a[1] < b[1]) end)
        return arr[1][2]
    end
    return nil
end
ИСПОЛЬЗОВАНИЕ:
local car = getNearCarToCenter(150)
if car then
    local carId = select(2, sampGetVehicleIdByCarHandle(car))
    print('Ближайшее к центру атво с ID: '..carId)
else -- nil
    print('Ближайшее к центру авто в указаном радиусе не найдено')
end
чекаешь свои корды и корды тачки, вставляешь их в renderDrawLine и все типа.

если тебе надо сделать так как на видео, то чекай корды своего прицела и тачки. а окружность можно нарисовать через имгуи функцию, в сниппетах вроде она есть

это ебани в любое место кода
Lua:
function getNearCarToCenter(radius)
    local arr = {}
    local sx, sy = getScreenResolution()
    for _, car in ipairs(getAllVehicles()) do
        if isCarOnScreen(car) and getDriverOfCar(car) ~= playerPed then
            local carX, carY, carZ = getCarCoordinates(car)
            local cX, cY = convert3DCoordsToScreen(carX, carY, carZ)
            local distBetween2d = getDistanceBetweenCoords2d(sx / 2, sy / 2, cX, cY)
            if distBetween2d <= tonumber(radius and radius or sx) then
                table.insert(arr, {distBetween2d, car})
            end
        end
    end
    if #arr > 0 then
        table.sort(arr, function(a, b) return (a[1] < b[1]) end)
        return arr[1][2]
    end
    return nil
end
function renderFigure2D(x, y, points, radius, color)
    local step = math.pi * 2 / points
    local render_start, render_end = {}, {}
    for i = 0, math.pi * 2, step do
        render_start[1] = radius * math.cos(i) + x
        render_start[2] = radius * math.sin(i) + y
        render_end[1] = radius * math.cos(i + step) + x
        render_end[2] = radius * math.sin(i + step) + y
        renderDrawLine(render_start[1], render_start[2], render_end[1], render_end[2], 1, color)
    end
end
function get_crosshair_position()
    local vec_out = ffi.new("float[3]")
    local tmp_vec = ffi.new("float[3]")
    ffi.cast(
        "void (__thiscall*)(void*, float, float, float, float, float*, float*)",
        0x514970
    )(
        ffi.cast("void*", 0xB6F028),
        15.0,
        tmp_vec[0], tmp_vec[1], tmp_vec[2],
        tmp_vec,
        vec_out
    )
    return vec_out[0], vec_out[1], vec_out[2]
end
это сам рендер, мб не будет работать, не проверял
Lua:
local radius = 150
--while true do
    local car = getNearCarToCenter(radius)
    if car then
        local cX, cY = get_crosshair_position()
        local pX, pY = getCarCoordinates(car)
        renderDrawLine(cX, cY, pX, pY, 5, 0xFFFFFFFF)
        renderFigure2D(250, 250, 16, radius, 0xFFFFFFFF)
        renderDrawPolygon(cX, cY, 10, 10, 15, 0, 0xFFFFFFFF)
        renderDrawPolygon(pX, pY, 10, 10, 15, 0, 0xFFFFFFFF)
    end
 
Последнее редактирование:

percheklii

Известный
707
257
Как подгрузить кастомные иконки для ганов? @chapo

Код:
local weapon = getCurrentCharWeapon(PLAYER_PED)
        if weapon > 1 then
        local guns = string.upper(game_weapons.get_name(weapon))..(weapon > 16 and weapon ~= 46 and ' ('..getAmmoInClip() ..'-'.. getAmmoInCharWeapon(PLAYER_PED, weapon) - getAmmoInClip()..')' or '')
        renderFontDrawText(font, guns, mainIni.Guns.posX - renderGetFontDrawTextLength(font, guns), mainIni.Guns.posY, -1)
        end
 
Последнее редактирование:

loverhasha

Участник
33
8
ребзя помогите плез тупому быдлокодеру как без потока (что би в альт+таб работало) сделать что бы у меня чел пробежал вперёд на пару сек и на право тоже на пару сек
нашёл что-то типо моего:
Lua:
local timepress = os.time()
while os.time() - timepress < 2 do wait(0) setGameKeyState(1,1024) end
setGameKeyState(1,0)
но не разобрался и не работает
 
У

Удалённый пользователь 441169

Гость
Как лучше удалять значение из таблицы?
Lua:
local arr = {"a", "b", "c", "d"}

arr[3] = nil
-- или
table.remove(arr, 3)
У обоих способов есть свои особенности
В случае с arr[3] = nil будет просто обнулена третья ячейка массива и ничего кроме этого не изменится
В случае с table.remove будет удалена 3 ячейка, а остальные элементы которые идут дальше подряд будут сдвинуты влево, то есть
Lua:
local arr = {"a", "b", "c", "d"}

arr[3] = nil
--получим arr = {"a", "b", nil, "c"}
-- или
table.remove(arr, 3)
--получим arr = {"a", "b", "c"}
По итогу, если тебе важно чтобы в массиве были элементы подряд без пропусков (чтобы корректно работали ipairs и # например), то следует использовать table.remove, если же просто удалить значение из таблицы, где элементы идут не подряд или наличие пропущенных элементов не критично, то первым способом.
 
  • Нравится
Реакции: Quasper и why ega

CaJlaT

Овощ
Модератор
2,806
2,603
Б плез тупому быдлокодеру как без потока (что би в альт+таб работало) сделать что бы у меня чел пробежал вперёд на пару сек и на право тоже на пару сек
нашёл что-то типо моего:
Lua:
local timepress = os.time()
while os.time() - timepress < 2 do wait(0) setGameKeyState(1,1024) end
setGameKeyState(1,0)
но не разобрался и не работает
Без потока функция wait не работает, а без нее бесконечный цикл просто зафризит тебе игру
 

the same

Активный
173
25
renderDrawTexture ставляю данную функцию в main , но ничего не происходит (enderLoadTextureFromFile сделал)
Lua:
function main ()
   
        if not isSampLoaded()  or not isSampfuncsLoaded() then return end
        while not isSampAvailable() do wait(100) end
        imge = renderLoadTextureFromFile(getGameDirectory().."\\moonloader\\config\\logo.png")
        renderDrawTexture(imge, 946, 541, 100, 10, 10,  0xFFFFFFFF)
       

       
        while true do
            wait(0)
            renderDrawTexture(imge, 946, 541, 100, 10, 10,  0xFFFFFFFF)
        end
   
end
 

Quasper

Известный
834
354
renderDrawTexture ставляю данную функцию в main , но ничего не происходит (enderLoadTextureFromFile сделал)
Lua:
function main ()
  
        if not isSampLoaded()  or not isSampfuncsLoaded() then return end
        while not isSampAvailable() do wait(100) end
        imge = renderLoadTextureFromFile(getGameDirectory().."\\moonloader\\config\\logo.png")
        renderDrawTexture(imge, 946, 541, 100, 10, 10,  0xFFFFFFFF)
      

      
        while true do
            wait(0)
            renderDrawTexture(imge, 946, 541, 100, 10, 10,  0xFFFFFFFF)
        end
  
end
я не знаю почему так работает но попробуй переименовать файл (много подобных ошибок решалось так)
 

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Друг
8,763
11,198
допустим у меня есть треугольник, нарисованный через drawlist, как мне задать ему угол поворота (0-360)?
Lua:
                        -->> triangle
                        local center = imgui.ImVec2(500, 500)
                        local size = 150
                        DL:AddTriangleFilled(
                            imgui.ImVec2(center.x - size, center.y),
                            imgui.ImVec2(center.x + size, center.y),
                            imgui.ImVec2(center.x, center.y + size),
                            0xFFffffff
                        )