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

Petr_Sergeevich

Известный
Проверенный
707
296
Помогите! пишет
Код:
[ML] (error) leaders.lua: D:\Games\GTA San Andreas\moonloader\leaders.lua:18: attempt to compare nil with number
stack traceback:
    D:\Games\GTA San Andreas\moonloader\leaders.lua: in function <D:\Games\GTA San Andreas\moonloader\leaders.lua:3>
[ML] (error) leaders.lua: Script died due to an error. (01B4BB1C)
из за этого
Lua:
  while true do
    wait(0)
    if isCharInAnyCar(PLAYER_PED) then
        if isKeyJustPressed(0x46) and tonumber(speed) < 1 then
            local veh = storeCarCharIsInNoSave(PLAYER_PED)
            local speed = getCarSpeed(veh)
            print(speed)
        end
    end
  end
что не так, хелпаните плз

Кстати, код не будет работать, так как ты проверяешь скорость, которую даже не получил ещё в условии. Пиши лучше так, не вижу смысла получать её по нажатию кнопки, это бред

Lua:
while true do
    wait(0)
    if isCharInAnyCar(PLAYER_PED) then
        local speed = getCarSpeed(storeCarCharIsInNoSave(PLAYER_PED))
        if isKeyJustPressed(0x46) and speed < 1 then
            -- Если скорость < 1 и нажата кнопка "F", то принтим скорость
            print(speed)
        end
    end
end
 
Последнее редактирование:
  • Нравится
Реакции: asocial demon

TheDed

Участник
99
14
Сорян, конечно, но этот кал не читаемый, даже с расставленной табуляцией. Как это вообще работает? :D
Lua:
if Run then
    Run = false
    reboot = true
end

sampCloseCurrentDialogWithButton(0)

runTo(****)
wait(3000)
flat = flat + 1
runType = 7

elseif runType == 7 then
 
runTo(****)
runTo(****)
wait(3000)

if newdata == 0 then
    runTo(****)
    runTo(****)
    wait(3000)
end

elseif runType == 8 then
 
if reboot then
    Run = true
    reboot = false
end

runTo(****)
wait(3000)
--------------------
function MovePlayer(move_code, Run, dis)
    if Run then
        setGameKeyState(1, move_code)
        setGameKeyState(16, 255)
    else
        setGameKeyState(1, move_code)
    end
end
Я половину кода вырезал, чтобы видно было только то, что должно быть видно.
Хочешь больше подробностей - в ЛС.
 

Petr_Sergeevich

Известный
Проверенный
707
296
почему ты юзаешь if внутри if приэтом его не закрыв? Если тебе нужно 2 условия то используй if and
Всё у него нормально с if'aми. Сначала бесконечный цикл закрывает, потом два условия.
 
  • Нравится
Реакции: asocial demon

Shamanije

Известный
Друг
961
922
Помогите! пишет
Код:
[ML] (error) leaders.lua: D:\Games\GTA San Andreas\moonloader\leaders.lua:18: attempt to compare nil with number
stack traceback:
    D:\Games\GTA San Andreas\moonloader\leaders.lua: in function <D:\Games\GTA San Andreas\moonloader\leaders.lua:3>
[ML] (error) leaders.lua: Script died due to an error. (01B4BB1C)
из за этого
Lua:
  while true do
    wait(0)
    if isCharInAnyCar(PLAYER_PED) then
        if isKeyJustPressed(0x46) and speed < 1 then
            local veh = storeCarCharIsInNoSave(PLAYER_PED)
            local speed = getCarSpeed(veh)
            print(speed)
        end
    end
  end
что не так, хелпаните плз
Ты юзаешь юзловие speed, не объявив его.
 

sakovnv

Участник
72
0
Как в имгуи сделать чтобы некоторые окна зависели от одного окна, а одно окно не зависело от него?
 

Shamanije

Известный
Друг
961
922
напиши, видимо я что то не знаю...
@Petr_Sergeevich скидывал уже
Lua:
while true do
    wait(0)
    if isCharInAnyCar(PLAYER_PED) then
        local speed = getCarSpeed(storeCarCharIsInNoSave(PLAYER_PED))
        if isKeyJustPressed(0x46) and speed < 1 then
            -- Если скорость < 1 и нажата кнопка "F", то принтим скорость
            print(speed)
        end
    end
end
 

egor230

Участник
47
16
Скажите, пожалуйста, как проверить находится ли машина в заданных координатах? Функция locateCar3d(mycar, x, y, z, 0.0, 0.0, 0.0, 0) не работает должным образом. Нужно если машина достигала заданных координат, вывести сообщения.
Lua:
script_author("Egor")
script_name("readcodinat")
require "lib.moonloader"
function codinat() -- 
--printStringNow('~g~play', 1500)-- вывод текста
str = 0 -- счетчик строк
local a = {} -- массив
for i in pairs (a) do a [i] = nil end -- очистить массив
num = num +1 -- номер читаемой строки
local cod = "moonloader/codinat.txt"-- имя файла
local file = io.open(cod, "r+") -- открыть файл для чтении
if file ~= nil -- если файл не пуст
then
for i in io.lines(cod) do 
 str = str + 1
 st = str
 end -- посчитать кол-во строк в файле
local n = 0
for lin in io.lines(cod) do n = n+1
 if n == num 
 then line = lin 
  break;
  end
 file:close() 
end
end
for i in string.gmatch(line, "[^%s]+") do table.insert(a,i) -- записать числа по отдельности в массив
end
x = a[1]
y = a[2]
z = a[3]
return x,y,z, st, num
end
function createcar()
 m = 415 -- id модели машины
requestModel(m)
 if isModelAvailable(m) -- ждать пока отпустим кнопку
 then
 posX, posY, posZ = getCharCoordinates(playerPed) -- координаты cj       
 posY = posY + 10         
 mycar = createCar(m, posX, posY, posZ) -- создать машину от 10 м от cj
 setCarCruiseSpeed(mycar, 10.0) -- 00AD: set_car 36@ max_speed_to 10.0
end
end
function main()
while true do
wait(0)
num = 0
if wasKeyPressed(VK_P) -- клавиша P 
then while isKeyDown(VK_P) do wait(0) end -- ждать пока отпустим кнопку
createcar()
x,y,z,st,num = codinat()
carGotoCoordinates(mycar, x, y, z) -- 00A7: car 99@ drive_to 252@ 253@ 254@
if locateCar3d(mycar, x, y, z, 0.0, 0.0, 0.0, 0) -- 
then
 printStringNow('~g~et', 2000)-- вывод текста
end 
end
end
end
 

asocial demon

Потрачен
175
14
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Скажите, пожалуйста, как проверить находится ли машина в заданных координатах? Функция locateCar3d(mycar, x, y, z, 0.0, 0.0, 0.0, 0) не работает должным образом. Нужно если машина достигала заданных координат, вывести сообщения.
Lua:
script_author("Egor")
script_name("readcodinat")
require "lib.moonloader"
function codinat() --
--printStringNow('~g~play', 1500)-- вывод текста
str = 0 -- счетчик строк
local a = {} -- массив
for i in pairs (a) do a [i] = nil end -- очистить массив
num = num +1 -- номер читаемой строки
local cod = "moonloader/codinat.txt"-- имя файла
local file = io.open(cod, "r+") -- открыть файл для чтении
if file ~= nil -- если файл не пуст
then
for i in io.lines(cod) do
 str = str + 1
 st = str
 end -- посчитать кол-во строк в файле
local n = 0
for lin in io.lines(cod) do n = n+1
 if n == num
 then line = lin
  break;
  end
 file:close()
end
end
for i in string.gmatch(line, "[^%s]+") do table.insert(a,i) -- записать числа по отдельности в массив
end
x = a[1]
y = a[2]
z = a[3]
return x,y,z, st, num
end
function createcar()
 m = 415 -- id модели машины
requestModel(m)
 if isModelAvailable(m) -- ждать пока отпустим кнопку
 then
 posX, posY, posZ = getCharCoordinates(playerPed) -- координаты cj      
 posY = posY + 10        
 mycar = createCar(m, posX, posY, posZ) -- создать машину от 10 м от cj
 setCarCruiseSpeed(mycar, 10.0) -- 00AD: set_car 36@ max_speed_to 10.0
end
end
function main()
while true do
wait(0)
num = 0
if wasKeyPressed(VK_P) -- клавиша P
then while isKeyDown(VK_P) do wait(0) end -- ждать пока отпустим кнопку
createcar()
x,y,z,st,num = codinat()
carGotoCoordinates(mycar, x, y, z) -- 00A7: car 99@ drive_to 252@ 253@ 254@
if locateCar3d(mycar, x, y, z, 0.0, 0.0, 0.0, 0) --
then
 printStringNow('~g~et', 2000)-- вывод текста
end
end
end
end
float positionX, float positionY, float positionZ = getCarCoordinates(Vehicle car)
 

ШPEK

Известный
1,476
525
Прошу прощения @Phelarmad, Скажите пожалуйста что вы имеете в виду вашим ответом?
Вот ваша функция которую вы искали, она определяет находится ли автомобиль в указанной квадратной зоне
bool result = isCarInArea3d(Vehicle car, float cornerAX, float cornerAY, float cornerAZ, float cornerBX, float cornerBY, float cornerBZ, bool sphere)
или locateCar3d если тебе лень указывать 2 координаты и нужна сфера а не квадратная зона.
Но радиус у тебя 0.0, 0.0, 0.0 поэтому будет срабатывать если только координата точно соответствует, увеличь радиус
 
  • Нравится
Реакции: petuch228 и egor230

Шурик

Активный
216
42
Как проверять валидность JSON'a?
Я получаю текст из файла и декодирую из JSON'a, но иногда (когда файл пустой) у меня выдаёт ошибку:
Код:
Expected value but found T_END at character 1
Как проверить валидность JSON'a? Пробовал использовать валидатор, но он чего-то не фурычит (возможно я туплю).
Погуглил и нашёл cjson.null, но как применять не ясно. Прошу помочь @FYP, @DonHomka
Актуальная проблема.
 

SAMP.ASI

Известный
223
53
Как получить результат sampsendchat('/try тест')?
Чтоб в случае удачно что то выполнялось и в обратном случае.
Если делать евентом онсервермсг то оно будет реагировать и на чужую отыгровку того же самого