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

Howl1337

Известный
236
146
Один из вариантов, словить onCreatePickup и записывать все пикапы в массив. Затем перебрать массив на дистанцию, взять самый ближний и затем setCharCoordinates.


Lua:
local samp = require 'lib.samp.events'

function samp.onServerMessage(color, text)
    if text:find('Успех') then
        activation = false
    end
end

if activation then
    -- код
end
думаю то что мне и нужно, но я думаю не получиться у меня это сделать (словить onCreatePickup и записывать все пикапы в массив. Затем перебрать массив на дистанцию, взять самый ближний)
 

Terratomorf

Известный
315
58
На готовом не научишься.

Lua:
local samp = require 'lib.samp.events'
activation = true -- активируем изначально

function samp.onServerMessage(color, text)
    if text:find('Успешно') then
        activation = false -- при нахождении строки сбрасываем активацию
    end
end

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    sampRegisterChatCommand("start", function()
        lua_thread.create(function()
            while true do -- бесконечный цикл
                wait(0)
                if activation then -- если активация, значит выполняем до бесконечности
                -- при сбросе цикл будет продолжать работать, проверяя переменную.
                -- можешь затем снова присвоить ей true и далее выполнять действие пока не найдешь надпись, и так по кругу
                sampSendChat("/sur "..i)
                wait(50)
                end
            end
        end)
    end)
    wait(-1) -- либо сразу ставь wait(-1) либо делай while true do wait(0) end
end
[20:45:04.023875] (error) 1.lua: ...to San Andreas + MultiPlayer [0.3e]\moonloader\1.lua:19: attempt to concatenate global 'i' (a nil value)
stack traceback:
...to San Andreas + MultiPlayer [0.3e]\moonloader\1.lua: in function <...to San Andreas + MultiPlayer [0.3e]\moonloader\1.lua:13>
[20:45:04.023875] (error) 1.lua: Script died due to an error. (0B72D884)
 

Nishikinov

Известный
148
34
[20:45:04.023875] (error) 1.lua: ...to San Andreas + MultiPlayer [0.3e]\moonloader\1.lua:19: attempt to concatenate global 'i' (a nil value)
stack traceback:
...to San Andreas + MultiPlayer [0.3e]\moonloader\1.lua: in function <...to San Andreas + MultiPlayer [0.3e]\moonloader\1.lua:13>
[20:45:04.023875] (error) 1.lua: Script died due to an error. (0B72D884)
А, это я не заметил, тебе нужно по нарастающей флудить цифрами?
Тогда замени while true do на свой цикл обратно.
 

checkdasound

Известный
Проверенный
963
406
Там они рандомно эти пикапы(лесопилка ДРП, дерево меняется), нужно телепортироваться, а не просто подобрать
Ну так модель у них одинаковая (стрелочка или что какая там модель у них?). По иду модели получай серверный ид и проделывай уже вышеперечисленные действия.
 

Nishikinov

Известный
148
34
Lua:
local wow = false

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
   while not isSampAvailable() do wait(0) end
   if KeyJustPressed(45) and not sampIsChatInputActive() then
     wow = not wow -- меняем значение переменной
       if ggwp then
          sampAddChatMessage("555", -1)
       else
           sampAddChatMessage("666", -1)
         end
       end
     end
Дайте правильный код вывода в чат через sampSendChat() и sampAddMessage() С меня "Мне нравится"
https://blast.hk/wiki/lua:sampsendchat
https://blast.hk/wiki/lua:sampaddchatmessage
 

Howl1337

Известный
236
146
Ну так модель у них одинаковая (стрелочка или что какая там модель у них?). По иду модели получай серверный ид и проделывай уже вышеперечисленные действия.
как понимаю серверный ид можно узнать через собейт?
 

checkdasound

Известный
Проверенный
963
406
как понимаю серверный ид можно узнать через собейт?
Да, только какой в этом смысл, если, как ты говоришь, там рандомный ид серверный, поэтому узнай также через собейт ид модели и уже от этого отталкивайся.
 

Howl1337

Известный
236
146
Да, только какой в этом смысл, если, как ты говоришь, там рандомный ид серверный, поэтому узнай также через собейт ид модели и уже от этого отталкивайся.
19198 модель айди пикапа, можно просто телепортироваться на пикап с таким modelID в радиусе 30?
 

Petr_Sergeevich

Известный
Проверенный
707
296
Lua:
async_http_request('POST', 'https://scorcher.ru/app/crypto_form.php', {params = {password = 'pass', text = "content"}},
function(response)
    print(response.text)
end,
nil

Каким образом подтвердить нажатие кнопки "Зашифровать"? Параметры передать получается, а результат получить нет
 

checkdasound

Известный
Проверенный
963
406
покажи пожалуйста как, если не сложно
Уже выше показал, дальше сам.
Для определения радиуса, используй получение расстояния от себя до координат при помощи:
Lua:
float distance = getDistanceBetweenCoords3d(float x1, float y1, float z1, float x2, float y2, float z2)
 

Nishikinov

Известный
148
34
Lua:
async_http_request('POST', 'https://scorcher.ru/app/crypto_form.php', {params = {password = 'pass', text = "content"}},
function(response)
    print(response.text)
end,
nil

Каким образом подтвердить нажатие кнопки "Зашифровать"? Параметры передать получается, а результат получить нет
Никаким. Если ты отправляешь запрос, значит идешь в обход всех кнопок.

Прожимай F12 и во вкладке сеть отслеживай адрес, по которому сайт отправляет запрос и получает ответ.
UPD. Если получаешь пустой ответ, попробуй передать все параметры, например submit, что означает отправку.
 

Howl1337

Известный
236
146
Уже выше показал, дальше сам.
Для определения радиуса, используй получение расстояния от себя до координат при помощи:
Lua:
float distance = getDistanceBetweenCoords3d(float x1, float y1, float z1, float x2, float y2, float z2)

Lua:
float distance = getDistanceBetweenCoords3d(float x1, float y1, float z1, float x2, float y2, float z2)
float xyz1 - начальные координаты, float xyz2 - прибавить к начальным координатам 30?