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

Warklot

Известный
112
3
Hi as you can see i check information on moving objects, but i want to check objects information only if they are on my screen.How to do that? i know there is "isObjectOnScreen" but i don't know how to implement it in functions.

Lua:
 function sampev.onMoveObject(objectId,fromPos,destPos,speed,rotation)

if objectId~=1 then
 
sampAddChatMessage(objectId, 0xFFD00000)
 sampAddChatMessage(speed, 0xFFD00000)

   sampAddChatMessage("PosX "..fromPos.x, 0xFFD00000)
   sampAddChatMessage("PosY "..fromPos.y, 0xFFD00000)
    sampAddChatMessage("PosZ "..fromPos.z, 0xFFD00000)
 sampAddChatMessage("destX "..destPos.x, 0xFFD00000)
   sampAddChatMessage("destY "..destPos.y, 0xFFD00000)
    sampAddChatMessage("destZ "..destPos.z, 0xFFD00000)
    sampAddChatMessage("rotationx "..rotation.x, 0xFFD00000)
    sampAddChatMessage("rotationy "..rotation.y, 0xFFD00000)
  sampAddChatMessage("rotationZ "..rotation.z, 0xFFD00000)
end
end
 

Мира

Участник
455
9
как избавиться от флуда? чтобы на 1 игрока только 1 раз прописывалась и всё.
чтобы было не - если игрок рядом, то постоянно пишется это
а было - если игрок рядом, то напишется раз и всё
Lua:
local peds = getAllChars() -- объявляем массив с хэндлами всех созданных персонажей, включая персонажа игрока.
local res, ped = sampGetCharHandleBySampPlayerId(id)
for _, v in pairs(peds) do -- организуем перебор элементов массива через цикл for
    local result, id = sampGetPlayerIdByCharHandle(v) -- получаем ID игрока через хэндл-элемент массива
    local _, my_id = sampGetPlayerIdByCharHandle(PLAYER_PED) -- отводим отдельную переменную конкретно под собственный ID
    local x, y, z = getCharCoordinates(PLAYER_PED)
    local mX, mY, mZ = getCharCoordinates(v)
    local dist = getDistanceBetweenCoords3d(x, y, z, mX, mY, mZ)
    if result and id ~= my_id and dist <= 5 then -- проверяем успешность; не является ли ID твоим (чтобы не отправить сообщение самому себе)
        --sampAddChatMessage(id, -1) -- выполняем конкантенсацию и отправляем строку в чат
        sampAddChatMessage('Дистанция между вами: '..dist, 0x00DD00)
        --sampAddChatMessage('++', -1)
    end -- закрываем блок условного оператора
end -- закрываем цикл for
 

Aniki

🐰
Администратор
1,229
1,568
как избавиться от флуда? чтобы на 1 игрока только 1 раз прописывалась и всё.
чтобы было не - если игрок рядом, то постоянно пишется это
а было - если игрок рядом, то напишется раз и всё
Lua:
local peds = getAllChars() -- объявляем массив с хэндлами всех созданных персонажей, включая персонажа игрока.
local res, ped = sampGetCharHandleBySampPlayerId(id)
for _, v in pairs(peds) do -- организуем перебор элементов массива через цикл for
    local result, id = sampGetPlayerIdByCharHandle(v) -- получаем ID игрока через хэндл-элемент массива
    local _, my_id = sampGetPlayerIdByCharHandle(PLAYER_PED) -- отводим отдельную переменную конкретно под собственный ID
    local x, y, z = getCharCoordinates(PLAYER_PED)
    local mX, mY, mZ = getCharCoordinates(v)
    local dist = getDistanceBetweenCoords3d(x, y, z, mX, mY, mZ)
    if result and id ~= my_id and dist <= 5 then -- проверяем успешность; не является ли ID твоим (чтобы не отправить сообщение самому себе)
        --sampAddChatMessage(id, -1) -- выполняем конкантенсацию и отправляем строку в чат
        sampAddChatMessage('Дистанция между вами: '..dist, 0x00DD00)
        --sampAddChatMessage('++', -1)
    end -- закрываем блок условного оператора
end -- закрываем цикл for
Если оно у тебя флудит, то этот код вызывается или в бесконечном цикле, или в событии которое постоянно триггерится
Hi as you can see i check information on moving objects, but i want to check objects information only if they are on my screen.How to do that? i know there is "isObjectOnScreen" but i don't know how to implement it in functions.

Lua:
 function sampev.onMoveObject(objectId,fromPos,destPos,speed,rotation)

if objectId~=1 then

sampAddChatMessage(objectId, 0xFFD00000)
sampAddChatMessage(speed, 0xFFD00000)

   sampAddChatMessage("PosX "..fromPos.x, 0xFFD00000)
   sampAddChatMessage("PosY "..fromPos.y, 0xFFD00000)
    sampAddChatMessage("PosZ "..fromPos.z, 0xFFD00000)
sampAddChatMessage("destX "..destPos.x, 0xFFD00000)
   sampAddChatMessage("destY "..destPos.y, 0xFFD00000)
    sampAddChatMessage("destZ "..destPos.z, 0xFFD00000)
    sampAddChatMessage("rotationx "..rotation.x, 0xFFD00000)
    sampAddChatMessage("rotationy "..rotation.y, 0xFFD00000)
  sampAddChatMessage("rotationZ "..rotation.z, 0xFFD00000)
end
end
isObjectOnScreen requires object handle as arguement, which could be obtained by using sampGetObjectHandleBySampId(int id)
 
  • Нравится
Реакции: Warklot

Warklot

Известный
112
3
It presses space button but it doesn't release after wait time
Lua:
if speed>0.30 then
setVirtualKeyDown(VK_SPACE, true)
wait(100)
setVirtualKeyDown(VK_SPACE, false)
       end
 

Biuti

Участник
165
8
Почему не работает?
[13:04:58.071728] (error) jdsgaf.lua: C:\Program Files (x86)\GTA [pink\moonloader\jdsgaf.lua:8: attempt to call global 'IsKeyJustPressed' (a nil value)
stack traceback:
C:\Program Files (x86)\GTA [pink\moonloader\jdsgaf.lua: in function <C:\Program Files (x86)\GTA [pink\moonloader\jdsgaf.lua:4>
[13:04:58.071728] (error) jdsgaf.lua: Script died due to an error. (10787984)

Lua:
require 'lib.moonloader'
local keys = require "vkeys"

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    while true do
        wait(0)
        if isKeyDown(VK_M) and IsKeyJustPressed(VK_N) then
            SampSendChat('/gotp')
            SetVirtualKeyDown(VK_RETURN, true)
            wait(200)
            SetVirtualKeyDown(VK_RETURN, false)
            SampAddChatMassege("fff")
        end
    end
end
 

Sanchez.

Известный
705
188
Почему не работает?
[13:04:58.071728] (error) jdsgaf.lua: C:\Program Files (x86)\GTA [pink\moonloader\jdsgaf.lua:8: attempt to call global 'IsKeyJustPressed' (a nil value)
stack traceback:
C:\Program Files (x86)\GTA [pink\moonloader\jdsgaf.lua: in function <C:\Program Files (x86)\GTA [pink\moonloader\jdsgaf.lua:4>
[13:04:58.071728] (error) jdsgaf.lua: Script died due to an error. (10787984)

Lua:
require 'lib.moonloader'
local keys = require "vkeys"

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    while true do
        wait(0)
        if isKeyDown(VK_M) and IsKeyJustPressed(VK_N) then
            SampSendChat('/gotp')
            SetVirtualKeyDown(VK_RETURN, true)
            wait(200)
            SetVirtualKeyDown(VK_RETURN, false)
            SampAddChatMassege("fff")
        end
    end
end
Вместо IsKeyJustPressed пиши isKeyJustPressed (отличие в том, что в начале у тебя i большая, а должна быть маленькая)
 

Мира

Участник
455
9
Если оно у тебя флудит, то этот код вызывается или в бесконечном цикле, или в событии которое постоянно триггерится

isObjectOnScreen requires object handle as arguement, which could be obtained by using sampGetObjectHandleBySampId(int id)
можно как-то исправить на одноразовое использование, дабы избежать флуд?
 

lorgon

Известный
656
271
сомневаюсь, разумно использовать json. либы точно есть, на гитхабе поищи. однако лучше самому написать 4 строки, ладно 8 на две функции
Нашёл небольшую библиотеку от Musaigen, если кому-то понадобится:
JSONCFG
jsoncfg - мини-файл для работы с файлами типа .json.
Установка: скачать jsoncfg.lua и перекинуть в папку moonloader/lib
read = прочитать данные внутри файла, возвращает LUA таблицу, требует путь до .json файла.
write = записать данные внутрь файла, требует путь до .json файла и LUA таблицу с данными.
 
  • Нравится
Реакции: AnWu

monolith04

Известный
71
6
Как при выборе (а именно нажатии) строки, возвратить текст самой строки?
Открыт диалог, я нажимаю первую кнопку диалога, тем самым выбирая определённую строку, и мне нужно возвратить текст этой строки. Как это сделать?
 

chapo

чопа сребдс // @moujeek
Модератор
8,934
11,704
Как при выборе (а именно нажатии) строки, возвратить текст самой строки?
Открыт диалог, я нажимаю первую кнопку диалога, тем самым выбирая определённую строку, и мне нужно возвратить текст этой строки. Как это сделать?
zstring text = sampGetListboxItemText(int item)
 
  • Нравится
Реакции: monolith04

qwеty

Известный
490
157
Возможно как-то проверить, прикреплен ли определенный определенный объект к машине?
UPD: точнее, сделать проверку на текстуру объекта
 
Последнее редактирование:

lorgon

Известный
656
271
Как получить угол поворота радиус-вектора? Мне не хватает знаний в математике, поэтому как правильно выразится - не знаю.


Как найти этот угол бета, зная вектор.

1628432942105.png


У меня есть код, но это какой-то мой говнокод(хоть и правильно показывает) -
Lua:
function getAngleFromVec(vect)
  vec = {0, len(vect)}
  return math.deg(math.asin(vect[1]/vec[2]))
end

print(getAngleFromVec({3, 0})) -- 90 градусов выводит.
========================================================================
UPD:
Как получить угол поворота радиус-вектора? Мне не хватает знаний в математике, поэтому как правильно выразится - не знаю.


Как найти этот угол бета, зная вектор.

1628432942105.png


У меня есть код, но это какой-то мой говнокод(хоть и правильно показывает) -
Lua:
function getAngleFromVec(vect)
  vec = {0, len(vect)}
  return math.deg(math.asin(vect[1]/vec[2]))
end

print(getAngleFromVec({3, 0})) -- 90 градусов выводит.
Так и не нашёл лучшее решение, поэтому вдруг кому-то пригодится:

Lua:
function len(vec)
  return math.abs(math.sqrt(vec[1]^2+vec[2]^2))
end
function getAngleFromVec(vect)
  vec = {0, len(vect)}
  return math.deg(2*math.pi-math.asin(vect[1]/vec[2]))
end

print(getAngleFromVec({3, 0})) -- 270 градусов
1628442041608.png
 
Последнее редактирование:

Curtis

Участник
282
10
В input строку вписываю некий текст, после чего он ниже в imgui окне отображает что я вписал в строку, но текст может быть разным, как сделать, чтобы результат( текст который выводится на окно) переносился на новую строку если он вылазит за рамки окна?