Вопросы по 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
 
Последнее редактирование:

Dmitriy Makarov

25.05.2021
Проверенный
2,478
1,113
К сожалению такая же тема и ничего не происходит при наведении таргета
Вынеси цвета с кавычек.
А тот, который HEX "{000cff}" – убери оттуда. Либо же достань его Decimal код, как и остальные.
 
  • Влюблен
Реакции: Julimba

Julimba

Участник
108
10
Вынеси цвета с кавычек.
А тот, который HEX "{000cff}" – убери оттуда. Либо же достань его Decimal код, как и остальные.
А он никак не участвует в цепочке этой, да и если убрать его, то ничего не меняется.
upd. я рукожоп и все работает, огромное спасибо парни за помощь.
 
  • Нравится
Реакции: why ega

sosnov

Известный
331
115
сейчас работаю с пакетами бота, точнее с его вводом пароля, можно ли как то сделать так чтоб он использовал разные варианты регистрации? к примеру:

Lua:
function onBotIncomingRPC(bot, rpcId, bs)
if --пакет какой то
--код какого то пакета
end
or
if -- этот же пакет
--код этого же пакета только под другую систему регистрации
end
end

что то такое, мне бы пример кода желательно, а если и тут как я привёл всё норм, то так и скажите
 

Julimba

Участник
108
10
qq, тупой вопрос конечно, крч у меня есть тоглы батоны и их положение true/false заносится в ini , внимание вопрос, как сделать чтобы они перезаходе/перезагрузки скрипта они оставались в сохраненном ранее положение в ini


Lua:
if imgui.ToggleButton(u8"По таргету", toggle_status_1) then
    mainIni.config.target = toggle_status_1.v
    inicfg.save(mainIni, directIni)
end
 

why ega

РП игрок
Модератор
2,551
2,244
сейчас работаю с пакетами бота, точнее с его вводом пароля, можно ли как то сделать так чтоб он использовал разные варианты регистрации? к примеру:

Lua:
function onBotIncomingRPC(bot, rpcId, bs)
if --пакет какой то
--код какого то пакета
end
or
if -- этот же пакет
--код этого же пакета только под другую систему регистрации
end
end

что то такое, мне бы пример кода желательно, а если и тут как я привёл всё норм, то так и скажите
Lua:
function onBotIncomingRPC(bot, rpcId, bs)
    if rpcId == 63 then -- на примере диалогов
        -- тут читаешь заголовок диалога
        if title:find("Регистрация") then
            -- тут для такого диалога
        elseif title:find("РЕГИСТРАЦИЯ")
            -- тут для другого
        end
    end
end
А вообще, если ты знаешь, на каких серверах будут запускать твой скрипт - напиши, скажу как можно реализовать +- нормально

qq, тупой вопрос конечно, крч у меня есть тоглы батоны и их положение true/false заносится в ini , внимание вопрос, как сделать чтобы они перезаходе/перезагрузки скрипта они оставались в сохраненном ранее положение в ini


Lua:
if imgui.ToggleButton(u8"По таргету",) then
    mainIni.config.target = toggle_status_1.v
    inicfg.save(mainIni, directIni)
end
Lua:
-- в начале скрипта заменяешь объявление переменной toggle_status_1 на такое

local toggle_status_1 = imgui.ImBool(mainIni.config.target)
 
  • Влюблен
  • Нравится
Реакции: Julimba и sosnov

sosnov

Известный
331
115
А вообще, если ты знаешь, на каких серверах будут запускать твой скрипт - напиши, скажу как можно реализовать +- нормально
желательно на многих нубо арз, рдс и хмс
но тупые мододелы нубо аризон скачивают всё непойми с каких сайтов свои долбанные моды и у них то ид отличается,то ошибки в словах, они короче ваще дурочки.
Lua:
function onBotIncomingRPC(bot, rpcId, bs)
    if rpcId == 63 then -- на примере диалогов
        -- тут читаешь заголовок диалога
        if title:find("Регистрация") then
            -- тут для такого диалога
        elseif title:find("РЕГИСТРАЦИЯ")
            -- тут для другого
        end
    end
end
А вообще, если ты знаешь, на каких серверах будут запускать твой скрипт - напиши, скажу как можно реализовать +- нормально


Lua:
-- в начале скрипта заменяешь объявление переменной toggle_status_1 на такое

local toggle_status_1 = imgui.ImBool(mainIni.config.target)
а вообще елсе иф типо как "или" используется? я правильно понимаю?
 

Smeruxa

Известный
1,302
683
желательно на многих нубо арз, рдс и хмс
но тупые мододелы нубо аризон скачивают всё непойми с каких сайтов свои долбанные моды и у них то ид отличается,то ошибки в словах, они короче ваще дурочки.

а вообще елсе иф типо как или используется? я правильно понимаю?
elseif - штука, которая используется, чтобы выполнилось строго одного из данных условий
Пример без elseif:
Lua:
a = 30
if a > 5 then
    print('123')
end
if a > 10 then
    print('321')
end

-- выполнится два условия
-- output: 
-- 123
-- 321
Пример с elseif
Lua:
a = 30
if a > 5 then
    print('123')
elseif a > 10 then
    print('321')
end

-- выполнится только первое условие
-- output: 123
 
  • Нравится
Реакции: YarikVL и sosnov

Julimba

Участник
108
10
qq, в чем моя очередная ошибка? Задача скрипта выдать id игроков, которые находятся в указанном радиусе.
Скрипт так же запускается, но не выполняет задачу.

Lua:
local radius = 7

-- Бесконечный цикл в мейне
if toggle_status.v and isGameWindowForeground() and not isPauseMenuActive() and not isGamePaused() then
        wait(1000)
        local x, y, z = getCharCoordinates(PLAYER_PED)
        local _, ped = findAllRandomCharsInSphere(x, y, z, radius, true, true)
        if _ then
            local _, pid = sampGetPlayerIdByCharHandle(ped)
            if _ then
                sampAddChatMessage(tag.. 'Вот такой вот результат:' ..pid, -1)
                wait(500)
            end
        end
    end
end
 

why ega

РП игрок
Модератор
2,551
2,244
qq, в чем моя очередная ошибка? Задача скрипта выдать id игроков, которые находятся в указанном радиусе.
Скрипт так же запускается, но не выполняет задачу.

Lua:
local radius = 7

-- Бесконечный цикл в мейне
if toggle_status.v and isGameWindowForeground() and not isPauseMenuActive() and not isGamePaused() then
        wait(1000)
        local x, y, z = getCharCoordinates(PLAYER_PED)
        local _, ped = findAllRandomCharsInSphere(x, y, z, radius, true, true)
        if _ then
            local _, pid = sampGetPlayerIdByCharHandle(ped)
            if _ then
                sampAddChatMessage(tag.. 'Вот такой вот результат:' ..pid, -1)
                wait(500)
            end
        end
    end
end
Чему равна переменная radius?
 

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Друг
8,777
11,225
qq, в чем моя очередная ошибка? Задача скрипта выдать id игроков, которые находятся в указанном радиусе.
Скрипт так же запускается, но не выполняет задачу.

Lua:
local radius = 7

-- Бесконечный цикл в мейне
if toggle_status.v and isGameWindowForeground() and not isPauseMenuActive() and not isGamePaused() then
        wait(1000)
        local x, y, z = getCharCoordinates(PLAYER_PED)
        local _, ped = findAllRandomCharsInSphere(x, y, z, radius, true, true)
        if _ then
            local _, pid = sampGetPlayerIdByCharHandle(ped)
            if _ then
                sampAddChatMessage(tag.. 'Вот такой вот результат:' ..pid, -1)
                wait(500)
            end
        end
    end
end
Lua:
function getAllPlayersInRadius(radius)
    local list, x, y, z = {}, getCharCoordinates(ped)
    for _, ped in ipairs(getAllChars()) do
        if getDistanceBetweenCoords3d(x, y, z, getCharCoordinates(ped)) <= radius then
            local result, id = sampGetPlayerIdByCharHandle(ped)
            if result then
                table.insert(list, { id = id, handle = ped})
            end
        end
    end
    return list
end

-- code
for _, player in ipairs(getAllPlayersInRadius(5)) do
    sampAddChatMessage(('ID: %s, name: %s'):format(player.id, sampGetPlayerNickname(player.id)), -1)
    wait(500)
end
 
  • Влюблен
Реакции: Julimba

roman_vodola

Участник
157
16
Как я могу получить адрес сервера к, которому бот подключается(например сервер заполнен). sampGetCurrentServerAddress() выдает ошибку, если выполнить её не находясь на сервере.
 

Julimba

Участник
108
10
Lua:
function getAllPlayersInRadius(radius)
    local list, x, y, z = {}, getCharCoordinates(ped)
    for _, ped in ipairs(getAllChars()) do
        if getDistanceBetweenCoords3d(x, y, z, getCharCoordinates(ped)) <= radius then
            local result, id = sampGetPlayerIdByCharHandle(ped)
            if result then
                table.insert(list, { id = id, handle = ped})
            end
        end
    end
    return list
end

-- code
for _, player in ipairs(getAllPlayersInRadius(5)) do
    sampAddChatMessage(('ID: %s, name: %s'):format(player.id, sampGetPlayerNickname(player.id)), -1)
    wait(500)
end
Рукожопость моя подтверждается крч, хз в чем трабл

[ML] (error) AFKhelper.lua: opcode '00A0' call caused an unhandled exception
stack traceback:
[C]: in function 'getCharCoordinates'
D:\Games\GTA SA\Sasok\moonloader\AFKhelper.lua:55: in function 'getAllPlayersInRadius'
D:\Games\GTA SA\Sasok\moonloader\AFKhelper.lua:83: in function <D:\Games\GTA SA\Sasok\moonloader\AFKhelper.lua:68>
[ML] (error) AFKhelper.lua: Script died due to an error. (0633B0B4)
 

roman_vodola

Участник
157
16
Какой бот? Мунбот?
да обычный самописный луа бот. мне нужно закинуть айпи адрес на окно гта. это я делаю через ffi.C.SetWindowTextA только мне нужно получать айпи адресс сервера , чтобы вставить в окно процесса. во время коннекта выдает ошибку. думаю это потому, что sampGetCurrentServerAddress() работает по принципу: взять айпи адресс сервера ,к которому ты уже подключен, но поскольку я только нахожусь в процессе подключения он выдает исключение, ну а я думаю, что можно взять адресс сервера ,к которому ты подключаешься , ибо в чате пишет , что идет подключение к такому-то айпи адрессу.