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

percheklii

Известный
727
267
Lua:
imgui.ColorEdit3("Color", color, imgui.ColorEditFlags.NoInputs)
Код:
[14:42:14.078300] (error)    Hud: C:\Program Files (x86)\GTA\moonloader\Hud.lua:886: stack index 2, expected userdata, received sol.ImArray<float,4>: value at this index does not properly reflect the desired type (bad argument into 'bool(const char*, ImArray<float,3>*, sol::optional<int>)')
stack traceback:
    [C]: in function 'ColorEdit3'
    C:\Program Files (x86)\GTA\moonloader\Hud.lua:886: in function 'OnDrawFrame'
    C:\Program Files (x86)\GTA\moonloader\lib\imgui.lua:1378: in function <C:\Program Files (x86)\GTA\moonloader\lib\imgui.lua:1367>
[14:42:14.079299] (error)    Hud: Script died due to an error. (0ED7246C)
 

percheklii

Известный
727
267
Покажи как ты делаешь.
Изначально было так
Код:
if imgui.ColorEdit4(u8"Цвет полоски", set.imguicolor1) then
                ini.health.color1 = getColorEditColor(set.imguicolor1)
                inicfg.save(ini, path)
            end

Потом по твоему совету...
Код:
if imgui.ColorEdit3(u8"Цвет текста", set.imguimoneycolor, imgui.ColorEditFlags.NoInputs) then
                ini.money.color = getColorEditColor(set.imguimoneycolor)
                inicfg.save(ini, path)
            end
 

ARMOR

kjor32 is legend
Модератор
4,852
6,081
Изначально было так
Код:
if imgui.ColorEdit4(u8"Цвет полоски", set.imguicolor1) then
                ini.health.color1 = getColorEditColor(set.imguicolor1)
                inicfg.save(ini, path)
            end

Потом по твоему совету...
Код:
if imgui.ColorEdit3(u8"Цвет текста", set.imguimoneycolor, imgui.ColorEditFlags.NoInputs) then
                ini.money.color = getColorEditColor(set.imguimoneycolor)
                inicfg.save(ini, path)
            end
Lua:
imgui.ColorEdit4("Тут название", set.imguicolor1, imgui.ColorEditFlags.NoInputs)
 
  • Нравится
Реакции: percheklii

percheklii

Известный
727
267
Lua:
imgui.ColorEdit4("Тут название", set.imguicolor1, imgui.ColorEditFlags.NoInputs)
Еще такой вопрос, не знаешь как убрать этот костыль? "0x" .. ini.fuel.color


Код:
local function hex_to_decimal(argb)
    local argb = argb == nil and "FFFFFFFF" or tostring(argb):upper()
    local argb = argb:len() == 6 and "FF" .. argb or argb
    return tonumber(argb, 16)
end

local function explode_argb(argb)
    local a = bit.band(bit.rshift(argb, 24), 0xFF)
    local r = bit.band(bit.rshift(argb, 16), 0xFF)
    local g = bit.band(bit.rshift(argb, 8), 0xFF)
    local b = bit.band(argb, 0xFF)
    return a, r, g, b
end

local function join_argb(a, r, g, b)
    local argb = b  -- b
    local argb = bit.bor(argb, bit.lshift(g, 8))  -- g
    local argb = bit.bor(argb, bit.lshift(r, 16)) -- r
    local argb = bit.bor(argb, bit.lshift(a, 24)) -- a
    return argb
end

local function ARGB(argb)
    local a, r, g, b = explode_argb(argb)
    return bit.tohex(join_argb(a, b, g, r))
end

local function getImguiColor(color)
    return imgui.ImFloat4(imgui.ImColor(hex_to_decimal(ARGB(hex_to_decimal(color)))):GetFloat4())
end

local function getColorEditColor(color)
    local value = imgui.ImColor.FromFloat4(color.v[3], color.v[2], color.v[1], color.v[4]):GetU32()
    return bit.tohex(value):upper()
end
 

why ega

РП игрок
Модератор
2,541
2,234
  • Нравится
Реакции: Tango

percheklii

Известный
727
267
как сделать если нашло это
Код:
>> ПМ от nick(id): hpme
то в ответ отправило это
Код:
/sethp id 160
 
Последнее редактирование:

Tango

Новичок
28
4
3:
function sampev.onShowDialog(id, style, title, button1, button2, text)
 
if mode == 3 and #myBuyArray <= 0 and text:find('Прекратить покупку товара') and text:find('Удалить товар с продажи') then
    sms('Список товаров на скуп пустой')
    mode = 0
  end

  if mode == 3 and #myBuyArray > 0 then
    for i, data in ipairs(myBuyArray) do
      if mode == 3 and text:find('Удалить товар с продажи') and text:find('Прекратить покупку товара') and #myBuyArray > 0 then
        lua_thread.create(function ()
          wait(tw)
          sampSendDialogResponse(id, 1, getLineOnTextDialog(text, 'Добавить товар на покупку %(поиск по предметам%)'), nil)
        end)
      end
   
      if mode == 3 and text:find('Введите наименование товара, который хотите найти и выставить на скупку.') and #myBuyArray > 0 then
        lua_thread.create(function ()
          wait(tw)
          sampSendDialogResponse(id, 1, nil, data[1])
        end)
      end

      if mode == 3 and title:find('Поиск товара') and not text:find('Введите наименование товара, который хотите найти и выставить на скупку.') and #myBuyArray > 0 then
        lua_thread.create(function ()
          wait(tw)
                  local text = text:gsub('{......}', '')
          local text = text:gsub('%d.','')
          sampSendDialogResponse(id, 1, 0, nil)
        end)
      end

      if mode == 3 and text:find('Введите цену за товар') then
        lua_thread.create(function ()
          wait(tw)
          sampSendDialogResponse(id, 1, nil, data[3])
        end)
      end

      if mode == 3 and text:find('Введите количество и цену за один товар') then
        lua_thread.create(function ()
          wait(tw)
          sampSendDialogResponse(id, 1, nil, data[2]..','..data[3])
        end)
      end

    end
end
  end
Надеюсь будет понятно и без обьяснений функций, крч как правильно перебрать массив myBuyArray в ивенте onshowdialog. Он при окончании по новой тоже самое делает
 

percheklii

Известный
727
267
есть нормальный адрес, который отвечает за "Дальности прорисовки" чтобы можно быль использовать без FixDist.cleo?
 

XRLM

Известный
2,542
861
3:
function sampev.onShowDialog(id, style, title, button1, button2, text)
 
if mode == 3 and #myBuyArray <= 0 and text:find('Прекратить покупку товара') and text:find('Удалить товар с продажи') then
    sms('Список товаров на скуп пустой')
    mode = 0
  end

  if mode == 3 and #myBuyArray > 0 then
    for i, data in ipairs(myBuyArray) do
      if mode == 3 and text:find('Удалить товар с продажи') and text:find('Прекратить покупку товара') and #myBuyArray > 0 then
        lua_thread.create(function ()
          wait(tw)
          sampSendDialogResponse(id, 1, getLineOnTextDialog(text, 'Добавить товар на покупку %(поиск по предметам%)'), nil)
        end)
      end
  
      if mode == 3 and text:find('Введите наименование товара, который хотите найти и выставить на скупку.') and #myBuyArray > 0 then
        lua_thread.create(function ()
          wait(tw)
          sampSendDialogResponse(id, 1, nil, data[1])
        end)
      end

      if mode == 3 and title:find('Поиск товара') and not text:find('Введите наименование товара, который хотите найти и выставить на скупку.') and #myBuyArray > 0 then
        lua_thread.create(function ()
          wait(tw)
                  local text = text:gsub('{......}', '')
          local text = text:gsub('%d.','')
          sampSendDialogResponse(id, 1, 0, nil)
        end)
      end

      if mode == 3 and text:find('Введите цену за товар') then
        lua_thread.create(function ()
          wait(tw)
          sampSendDialogResponse(id, 1, nil, data[3])
        end)
      end

      if mode == 3 and text:find('Введите количество и цену за один товар') then
        lua_thread.create(function ()
          wait(tw)
          sampSendDialogResponse(id, 1, nil, data[2]..','..data[3])
        end)
      end

    end
end
  end
Надеюсь будет понятно и без обьяснений функций, крч как правильно перебрать массив myBuyArray в ивенте onshowdialog. Он при окончании по новой тоже самое делает
где сам массив
 
  • Клоун
Реакции: Air_Official

aidzava

Новичок
20
0
у меня допустим есть ники, мне нужно, что-бы если этот чел находился на сервере, и скрипт из его ника выдавал ид. пытался сделать не робит

[ML] (error) auto_forms: ...mes\Arizona Games Launcher\bin\moonloader\auto_forms.lua:82: attempt to concatenate global 'ruk_id' (a nil value)
stack traceback:
...mes\Arizona Games Launcher\bin\moonloader\auto_forms.lua: in function <...mes\Arizona Games Launcher\bin\moonloader\auto_forms.lua:76>
stack traceback:
[C]: in function 'create'
...mes\Arizona Games Launcher\bin\moonloader\auto_forms.lua:76: in function 'callback'
...a Games Launcher\bin\moonloader\lib\samp\events\core.lua:79: in function <...a Games Launcher\bin\moonloader\lib\samp\events\core.lua:53>
[ML] (error) auto_forms: Script died due to an error. (1805723C)





Lua:
no_forms = {'Ricky_Late', 'Farmer', 'Sam_Mason', 'Conor', 'Dorian_Gray', 'Stalker_Team', 'Sebastian_Disney', 'Jackie_Wilson', 'Derick_Stealer', 'Sapphire_Davydov', 'Maxim_Cordero', 'Don_Morrison', 'Nicolas_Source', 'Alfredo Reynolds'}



function sampGetPlayerIdByNickname(nick)
    nick = tostring(nick)
    local _, myid = sampGetPlayerIdByCharHandle(PLAYER_PED)
    if nick == sampGetPlayerNickname(myid) then return myid end
    for i = 0, 1003 do
        if sampIsPlayerConnected(i) and sampGetPlayerNickname(i) == nick then
        return i
        end
    end
end

ruk_id = sampGetPlayerIdByNickname(no_forms)

function se.onServerMessage(color, text)
    if text:match('%[A%] %{......%}(.*)%[(%d+)%]%{......%}: /(.*) '..ruk_id..'%s(.*)') then
    -- code
    end
end
 

madrasso

Потрачен
883
324
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
у меня допустим есть ники, мне нужно, что-бы если этот чел находился на сервере, и скрипт из его ника выдавал ид. пытался сделать не робит

[ML] (error) auto_forms: ...mes\Arizona Games Launcher\bin\moonloader\auto_forms.lua:82: attempt to concatenate global 'ruk_id' (a nil value)
stack traceback:
...mes\Arizona Games Launcher\bin\moonloader\auto_forms.lua: in function <...mes\Arizona Games Launcher\bin\moonloader\auto_forms.lua:76>
stack traceback:
[C]: in function 'create'
...mes\Arizona Games Launcher\bin\moonloader\auto_forms.lua:76: in function 'callback'
...a Games Launcher\bin\moonloader\lib\samp\events\core.lua:79: in function <...a Games Launcher\bin\moonloader\lib\samp\events\core.lua:53>
[ML] (error) auto_forms: Script died due to an error. (1805723C)





Lua:
no_forms = {'Ricky_Late', 'Farmer', 'Sam_Mason', 'Conor', 'Dorian_Gray', 'Stalker_Team', 'Sebastian_Disney', 'Jackie_Wilson', 'Derick_Stealer', 'Sapphire_Davydov', 'Maxim_Cordero', 'Don_Morrison', 'Nicolas_Source', 'Alfredo Reynolds'}



function sampGetPlayerIdByNickname(nick)
    nick = tostring(nick)
    local _, myid = sampGetPlayerIdByCharHandle(PLAYER_PED)
    if nick == sampGetPlayerNickname(myid) then return myid end
    for i = 0, 1003 do
        if sampIsPlayerConnected(i) and sampGetPlayerNickname(i) == nick then
        return i
        end
    end
end

ruk_id = sampGetPlayerIdByNickname(no_forms)

function se.onServerMessage(color, text)
    if text:match('%[A%] %{......%}(.*)%[(%d+)%]%{......%}: /(.*) '..ruk_id..'%s(.*)') then
    -- code
    end
end
Делаешь какой то бред, к тому же не объясняешь что тебе конкретно нужно. Подробнее можно пожалуйста, что за строка в onServerMessage, и что ты от неё хочешь.

есть нормальный адрес, который отвечает за "Дальности прорисовки" чтобы можно быль использовать без FixDist.cleo?
 
  • Злость
  • Нравится
Реакции: percheklii и YarikVL