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

Rental

Участник
60
1
Если открыт dxut диалог я хочу закрыть его на Esc, как со стандартными. Как можно заморозить Esc в gta sa и оставить активной для скрипта. Или как ещё можно это решить, может как-то отключить меню паузы.

dxutAddStatic(dx, 3, "{87084a}Обращение с оружием. \n Если все так расказывать то тот не там и.", 00, 0, 600, 100) - Все нормально.
Если изменить цвет после заголовка "\n {000000} Если" то все плывет.
Когда после \n идет изменение цвета.
Вот при таком коде это выходит.
Lua:
dxutAddStatic(dx, 3, "{00DD66}Обращение с оружием.\n {000000} Если все так расказывать то тот не там и.", 0, 0, 600, 100)

+ почему туда влазит мало текста(Предложения 5)? Это так и задумано?
 

AnWu

Guardian of Order
Всефорумный модератор
4,690
5,189
Почему при вызове функции sampSendChat() внутри обработчика событий onSendTakeDamage() первая функция срабатывает дважды, хотя обработчик - всего единожды, и как это пофиксить?
К примеру, та же самая sampAddChatMessage() срабатывает только один раз.
Lua:
function sampev.onSendTakeDamage(playerID, damage, weapon, bodypart)
    sampSendChat("message")
end
создай поток и задержку на 1 кадр.

Как правильно использовать рендер объектов\машин, что бы не было мерцания на экране?
Пример как я использовал:
Lua:
while true do
wait(0)
if dactive == true then
local x,y,z = getCharCoordinates(playerPed)
local result, car = findAllRandomVehiclesInSphere(x, y, z, 300.0, true, true)
if result == true then
local doorStatus = getCarDoorLockStatus(car)
if doorStatus ~= 2 then
local cx, cy, cz = getCarCoordinates(car)
local px, py = convert3DCoordsToScreen(cx, cy, cz)
renderFontDrawText(itsFont, doorStatus, px, py, 0xFFFFFFFF)
end
end
end
end
Использовать getAllVehicle()

Если открыт dxut диалог я хочу закрыть его на Esc, как со стандартными. Как можно заморозить Esc в gta sa и оставить активной для скрипта. Или как ещё можно это решить, может как-то отключить меню паузы.

dxutAddStatic(dx, 3, "{87084a}Обращение с оружием. \n Если все так расказывать то тот не там и.", 00, 0, 600, 100) - Все нормально.
Если изменить цвет после заголовка "\n {000000} Если" то все плывет.
Когда после \n идет изменение цвета.
Вот при таком коде это выходит.
Lua:
dxutAddStatic(dx, 3, "{00DD66}Обращение с оружием.\n {000000} Если все так расказывать то тот не там и.", 0, 0, 600, 100)

+ почему туда влазит мало текста(Предложения 5)? Это так и задумано?
Почитать о onWindowMessage
 

checkdasound

Известный
Проверенный
963
406
К примеру, true = gmCar. Можно ли как-то перевернуть true в false и наоборот, чтобы использовать в других функциях.
setCarCanBeDamaged(veh, gmCar). К примеру так, а мне нужно, чтобы, когда gmCar = true, то SetCarCanBeDamaged(veh, false).
 

AnWu

Guardian of Order
Всефорумный модератор
4,690
5,189
К примеру, true = gmCar. Можно ли как-то перевернуть true в false и наоборот, чтобы использовать в других функциях.
setCarCanBeDamaged(veh, gmCar). К примеру так, а мне нужно, чтобы, когда gmCar = true, то SetCarCanBeDamaged(veh, false).
SetCarCanBeDamaged(veh, not gmCar)
 
  • Нравится
Реакции: checkdasound

checkdasound

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

[ML] (error) funcs.lua: opcode '02AC' call caused an unhandled exception
stack traceback:
[C]: in function 'setCarProofs'
moonloader\funcs.lua:62: in function 'OnDrawFrame'
moonloader\lib\imgui.lua:1377: in function <moonloader\lib\imgui.lua:1366>
[ML] (error) funcs.lua: Script died due to an error. (019678F4)

Lua:
local gmCar = imgui.ImBool(false)
--code
           if imgui.Checkbox(u8'ГМ кар', gmCar) then
               setCarProofs(veh, gmCar.v, gmCar.v, gmCar.v, gmCar.v, gmCar.v)
               setCarCanBeDamaged(veh, not gmCar.v)
           end
--code
 

checkdasound

Известный
Проверенный
963
406
Вех сразу же после onDrawFrame
local veh = storeCarCharIsInNoSave(PLAYER_PED)

Вех сразу же после onDrawFrame
local veh = storeCarCharIsInNoSave(PLAYER_PED)
Кхм, я даже ничего не убирал из скрипта и ничего не менял, но перезагрузил и все работает.
Оказывается, это было из-за того, что я нажимал на чекбокс, когда был не в машине.
А когда сижу в машине, все ок меняется.
 
Последнее редактирование:

AnWu

Guardian of Order
Всефорумный модератор
4,690
5,189
Вех сразу же после onDrawFrame
local veh = storeCarCharIsInNoSave(PLAYER_PED)


Кхм, я даже ничего не убирал из скрипта и ничего не менял, но перезагрузил и все работает.
Рискну предположить что нету проверки на авто.
 

штейн

Известный
Проверенный
1,001
687
Lua:
function sampev.onServerMessage(color, text)
    if text:find('%{.+%}%[ ADM %]: (%S+)%[%d+%] Подозрение на .+ %{cccccc%}%[ Отправлен на Спавн %]') then
        print('1')
        local nick, id, cause = text:match('%{.+%}%[ ADM %]: (%S+)%[%d+%] Подозрение на .+ %{cccccc%}%[ Отправлен на Спавн %]')
        print('2')
        if nick and id and cause then
            print(id, nick, cause)
        end
    end
end
че не работает
строка: [ ADM ]: Viktor_Blom[8] Подозрение на Aim Bot {cccccc}[ Отправлен на Спавн ]
 

checkdasound

Известный
Проверенный
963
406
Lua:
if isCharInAnyCar(playerPed) then
    -- code
end
Lua:
           if imgui.Checkbox('gmCar', gmCar) and isCharInAnyCar(PLAYER_PED) then
               setCarProofs(veh, gmCar.v, gmCar.v, gmCar.v, gmCar.v, gmCar.v)
               setCarCanBeDamaged(veh, not gmCar.v)
           elseif gmCar.v and not isCharInAnyCar(PLAYER_PED) then
               sampAddChatMessage('[gmCar] Ты не в машине!', -1)
           end
Я так и сделал, но только вот проблема, как только я нажал галочку в чекбоксе, то у меня спамит это сообщение в чат, а мне нужно, чтобы было только один раз.
 

штейн

Известный
Проверенный
1,001
687
Lua:
           if imgui.Checkbox('gmCar', gmCar) and isCharInAnyCar(PLAYER_PED) then
               setCarProofs(veh, gmCar.v, gmCar.v, gmCar.v, gmCar.v, gmCar.v)
               setCarCanBeDamaged(veh, not gmCar.v)
           elseif gmCar.v and not isCharInAnyCar(PLAYER_PED) then
               sampAddChatMessage('[gmCar] Ты не в машине!', -1)
           end
Я так и сделал, но только вот проблема, как только я нажал галочку в чекбоксе, то у меня спамит это сообщение в чат, а мне нужно, чтобы было только один раз.
break не подойдет?
 

checkdasound

Известный
Проверенный
963
406
break не подойдет?
пишет, что нет loop, я уже пробовал.
Могу предложить такое
Lua:
if imgui.Checkbox('gmCar', gmCar) then
    if isCharInAnyCar(PLAYER_PED)
        setCarProofs(veh, gmCar.v, gmCar.v, gmCar.v, gmCar.v, gmCar.v)
        setCarCanBeDamaged(veh, not gmCar.v)
    else
        sampAddChatMessage('[gmCar] Ты не в машине!', -1)
        gmCar.v = false
    end
end
Спс
p.s. ты во второй строке then не написал.
 

#Northn

Police Helper «Reborn» — уже ШЕСТЬ лет!
Всефорумный модератор
2,634
2,484
Lua:
if color == tonumber('-8224086') and text:find('//') then
    local text = text:gsub('//', '', 1)
    print(text)
    local text = text:gsub('**', '')
    print(text)
    local text = text:gsub('{.+}', '')
    print(text)
    local text = text:gsub('  ', ' ')
    sampAddChatMessage('(({ff8585}'..text..'{FFBFB4}))', 0xFFBFB4)
    return false
end

Возвращает ничего(пустоту) (не nil) при взаимодействии с этой строкой:
{FF0000}** [Правительство] Президент Cain_Beckenbauer[82]: {FFA800} // katsuro nimfoman. {FF0000}**

А должен возвращать:
(( [Правительство] Президент Cain_Beckenbauer[82]: katsuro nimfoman. {FFBFB4}))

Возвращает пустоту после 3-го print()-a
Из-за чего может быть?

Первый print(()
{FF0000}** [Правительство] Президент Cain_Beckenbauer[82]: {FFA800} katsuro nimfoman. {FF0000}**
Всё нормально.

Второй print()
{FF0000} [Правительство] Президент Cain_Beckenbauer[82]: {FFA800} katsuro nimfoman. {FF0000}
Всё нормально.

Третий print() - пустота.

P.S. Делаю через sampev.onServerMessage(color, text)