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

Cameron_Bawerman

Участник
99
1
Вопросик, почему крашит когда я лажу по диалогам
Warning(s007): Exception 0xC0000005 at 0x60645C70
Warning(s007): Exception 0xC0000005 at 0x606452B5
вот ошибка
Код:
[ML] (error) TEST.lua: cannot resume non-suspended coroutine
stack traceback:
    [C]: in function 'create'
    D:\gnta\moonloader\TEST.lua:105: in function <D:\gnta\moonloader\TEST.lua:97>
[ML] (error) TEST.lua: Script died due to an error. (18021F04)

а вот сам код из скрипта

Код:
sampShowDialog(100, u8("{"..DB4.."}["..script_name.."] {"..Wbe.."}Главная меню [v"..thisScript().version.."]"), u8("{"..DB4.."}1. {"..Wbe.."}Помощь\n{"..DB4.."}2. {"..Wbe.."}Настройки\n{"..DB4.."}3. {"..Wbe.."}Автор"), u8'Выбрать',u8'Закрыть', 2)
    lua_thread.create(function()
        repeat
        wait(0)
        result, button, list, input = sampHasDialogRespond(100)
        until result
        if button == 1 then
            if list == 0 then
                sampShowDialog(101, u8("{"..DB4.."}["..script_name.."] {"..Wbe.."}Помощь"), u8("{"..DB4.."}1. {"..Wbe.."}Cписок команд\n{"..DB4.."}2. {"..Wbe.."}Список клавиш"), u8'Выбрать',u8'Закрыть', 2)
                lua_thread.create(function()

тоесть выдает ошибку на lua_thread.create(function() что в 100 диалоге что и 101, кст может это быть не точно в этих диалогах, рамдомно


Может, есть какой то другой способ написание диалогов, подскажите?
 
Последнее редактирование:

xSpiridon

Участник
74
21
Вопросик, почему крашит когда я лажу по диалогам
Warning(s007): Exception 0xC0000005 at 0x60645C70
Warning(s007): Exception 0xC0000005 at 0x606452B5
вот ошибка
Код:
[ML] (error) TEST.lua: cannot resume non-suspended coroutine
stack traceback:
    [C]: in function 'create'
    D:\gnta\moonloader\TEST.lua:105: in function <D:\gnta\moonloader\TEST.lua:97>
[ML] (error) TEST.lua: Script died due to an error. (18021F04)

а вот сам код из скрипта

Код:
sampShowDialog(100, u8("{"..DB4.."}["..script_name.."] {"..Wbe.."}Главная меню [v"..thisScript().version.."]"), u8("{"..DB4.."}1. {"..Wbe.."}Помощь\n{"..DB4.."}2. {"..Wbe.."}Настройки\n{"..DB4.."}3. {"..Wbe.."}Автор"), u8'Выбрать',u8'Закрыть', 2)
    lua_thread.create(function()
        repeat
        wait(0)
        result, button, list, input = sampHasDialogRespond(100)
        until result
        if button == 1 then
            if list == 0 then
                sampShowDialog(101, u8("{"..DB4.."}["..script_name.."] {"..Wbe.."}Помощь"), u8("{"..DB4.."}1. {"..Wbe.."}Cписок команд\n{"..DB4.."}2. {"..Wbe.."}Список клавиш"), u8'Выбрать',u8'Закрыть', 2)
                lua_thread.create(function()

тоесть выдает ошибку на lua_thread.create(function() что в 100 диалоге что и 101, кст может это быть не точно в этих диалогах, рамдомно


Может, есть какой то другой способ написание диалогов, подскажите?
в основном цикле обрабатывай события диалога
 
  • Нравится
Реакции: Vlad44352

DolgorukovGTA

Известный
Проверенный
652
345
Вопросик, почему крашит когда я лажу по диалогам
Warning(s007): Exception 0xC0000005 at 0x60645C70
Warning(s007): Exception 0xC0000005 at 0x606452B5
вот ошибка
Код:
[ML] (error) TEST.lua: cannot resume non-suspended coroutine
stack traceback:
    [C]: in function 'create'
    D:\gnta\moonloader\TEST.lua:105: in function <D:\gnta\moonloader\TEST.lua:97>
[ML] (error) TEST.lua: Script died due to an error. (18021F04)

а вот сам код из скрипта

Код:
sampShowDialog(100, u8("{"..DB4.."}["..script_name.."] {"..Wbe.."}Главная меню [v"..thisScript().version.."]"), u8("{"..DB4.."}1. {"..Wbe.."}Помощь\n{"..DB4.."}2. {"..Wbe.."}Настройки\n{"..DB4.."}3. {"..Wbe.."}Автор"), u8'Выбрать',u8'Закрыть', 2)
    lua_thread.create(function()
        repeat
        wait(0)
        result, button, list, input = sampHasDialogRespond(100)
        until result
        if button == 1 then
            if list == 0 then
                sampShowDialog(101, u8("{"..DB4.."}["..script_name.."] {"..Wbe.."}Помощь"), u8("{"..DB4.."}1. {"..Wbe.."}Cписок команд\n{"..DB4.."}2. {"..Wbe.."}Список клавиш"), u8'Выбрать',u8'Закрыть', 2)
                lua_thread.create(function()

тоесть выдает ошибку на lua_thread.create(function() что в 100 диалоге что и 101, кст может это быть не точно в этих диалогах, рамдомно


Может, есть какой то другой способ написание диалогов, подскажите?
Lua:
sampShowDialog(6405, "Название", "Текст", "ОК", "Отмена", DIALOG_STYLE_LIST)
while sampIsDialogActive(6405) do wait(100) end
local _, button, list, _ = sampHasDialogRespond(6405)
-- if button == 1 then
-- if list == 1 then etc
 

Dmitriy Makarov

25.05.2021
Проверенный
2,478
1,113
Вопросик, почему крашит когда я лажу по диалогам
Warning(s007): Exception 0xC0000005 at 0x60645C70
Warning(s007): Exception 0xC0000005 at 0x606452B5
вот ошибка
Код:
[ML] (error) TEST.lua: cannot resume non-suspended coroutine
stack traceback:
    [C]: in function 'create'
    D:\gnta\moonloader\TEST.lua:105: in function <D:\gnta\moonloader\TEST.lua:97>
[ML] (error) TEST.lua: Script died due to an error. (18021F04)

а вот сам код из скрипта

Код:
sampShowDialog(100, u8("{"..DB4.."}["..script_name.."] {"..Wbe.."}Главная меню [v"..thisScript().version.."]"), u8("{"..DB4.."}1. {"..Wbe.."}Помощь\n{"..DB4.."}2. {"..Wbe.."}Настройки\n{"..DB4.."}3. {"..Wbe.."}Автор"), u8'Выбрать',u8'Закрыть', 2)
    lua_thread.create(function()
        repeat
        wait(0)
        result, button, list, input = sampHasDialogRespond(100)
        until result
        if button == 1 then
            if list == 0 then
                sampShowDialog(101, u8("{"..DB4.."}["..script_name.."] {"..Wbe.."}Помощь"), u8("{"..DB4.."}1. {"..Wbe.."}Cписок команд\n{"..DB4.."}2. {"..Wbe.."}Список клавиш"), u8'Выбрать',u8'Закрыть', 2)
                lua_thread.create(function()

тоесть выдает ошибку на lua_thread.create(function() что в 100 диалоге что и 101, кст может это быть не точно в этих диалогах, рамдомно


Может, есть какой то другой способ написание диалогов, подскажите?
перенеси это
Lua:
result, button, list, input = sampHasDialogRespond(100)
        until result
        if button == 1 then
            if list == 0 then
                sampShowDialog(101, u8("{"..DB4.."}["..script_name.."] {"..Wbe.."}Помощь"), u8("{"..DB4.."}1. {"..Wbe.."}Cписок команд\n{"..DB4.."}2. {"..Wbe.."}Список клавиш"), u8'Выбрать',u8'Закрыть', 2)
                lua_thread.create(function()
в бесконечный цикл
Как выключить скрипт функцией ?
 
  • Нравится
Реакции: Cameron_Bawerman

Cameron_Bawerman

Участник
99
1
Lua:
sampShowDialog(6405, "Название", "Текст", "ОК", "Отмена", DIALOG_STYLE_LIST)
while sampIsDialogActive(6405) do wait(100) end
local _, button, list, _ = sampHasDialogRespond(6405)
-- if button == 1 then
-- if list == 1 then etc
не работает!

Код:
require "lib.moonloader"
local sf = require 'sampfuncs'

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(2000) end
    
    sampRegisterChatCommand("test", dialog)
    end

function dialog()
    sampShowDialog(6405, "Название", "Текст", "ОК", "Отмена", 2)
    while sampIsDialogActive(6405) do wait(0) end
    local _, button, list, _ = sampHasDialogRespond(6405)
    -- if button == 1 then
    -- if list == 1 then etc
    if result then
    if button == 1 and list == 0 then  -- button == 1 это кнопка слева, button == 0 - справа, list == 0 - 1 строка в списке, номера стрк начинаются с 0
        ampAddChatMessage(u8("Вы нажали на 1 строку в списке"), -1)
    end
    if button == 1 and list == 1 then  -- button == 1 это кнопка слева, button == 0 - справа, list == 0 - 1 строка в списке, номера стрк начинаются с 0
        sampAddChatMessage(u8("Вы нажали на 2 строку в списке"), -1)
    end
end
end
 

Dmitriy Makarov

25.05.2021
Проверенный
2,478
1,113
while sampIsDialogActive(6405) do wait(0) end local _, button, list, _ = sampHasDialogRespond(6405) -- if button == 1 then -- if list == 1 then etc if result then if button == 1 and list == 0 then -- button == 1 это кнопка слева, button == 0 - справа, list == 0 - 1 строка в списке, номера стрк начинаются с 0 ampAddChatMessage(u8("Вы нажали на 1 строку в списке"), -1) end if button == 1 and list == 1 then -- button == 1 это кнопка слева, button == 0 - справа, list == 0 - 1 строка в списке, номера стрк начинаются с 0 sampAddChatMessage(u8("Вы нажали на 2 строку в списке"), -1) end end
это в бесконечный цикл перенеси
 
  • Нравится
Реакции: Cameron_Bawerman

xSpiridon

Участник
74
21
не работает!

Код:
require "lib.moonloader"
local sf = require 'sampfuncs'

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(2000) end
   
    sampRegisterChatCommand("test", dialog)
    end

function dialog()
    sampShowDialog(6405, "Название", "Текст", "ОК", "Отмена", 2)
    while sampIsDialogActive(6405) do wait(0) end
    local _, button, list, _ = sampHasDialogRespond(6405)
    -- if button == 1 then
    -- if list == 1 then etc
    if result then
    if button == 1 and list == 0 then  -- button == 1 это кнопка слева, button == 0 - справа, list == 0 - 1 строка в списке, номера стрк начинаются с 0
        ampAddChatMessage(u8("Вы нажали на 1 строку в списке"), -1)
    end
    if button == 1 and list == 1 then  -- button == 1 это кнопка слева, button == 0 - справа, list == 0 - 1 строка в списке, номера стрк начинаются с 0
        sampAddChatMessage(u8("Вы нажали на 2 строку в списке"), -1)
    end
end
end
Lua:
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(2000) end
    
    sampRegisterChatCommand("test", dialog)
    
    while true do
    wait(0)
    
        if sampIsDialogActive(6405) then
        local res, button, list, _ = sampHasDialogRespond(6405)
            if res then
                if button == 1 and list == 0 then  -- button == 1 это кнопка слева, button == 0 - справа, list == 0 - 1 строка в списке, номера стрк начинаются с 0
                  sampAddChatMessage(u8("Вы нажали на 1 строку в списке"), -1)
                end
                if button == 1 and list == 1 then  -- button == 1 это кнопка слева, button == 0 - справа, list == 0 - 1 строка в списке, номера стрк начинаются с 0
                  sampAddChatMessage(u8("Вы нажали на 2 строку в списке"), -1)
                end
            end
        end
    
    end
    
    end

function dialog()
sampShowDialog(6405, "Название", "Текст", "ОК", "Отмена", 2)
end
 
  • Нравится
Реакции: Vlad44352

Cameron_Bawerman

Участник
99
1
Lua:
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(2000) end
   
    sampRegisterChatCommand("test", dialog)
   
    while true do
    wait(0)
   
        if sampIsDialogActive(6405) then
        local res, button, list, _ = sampHasDialogRespond(6405)
            if res then
                if button == 1 and list == 0 then  -- button == 1 это кнопка слева, button == 0 - справа, list == 0 - 1 строка в списке, номера стрк начинаются с 0
                  sampAddChatMessage(u8("Вы нажали на 1 строку в списке"), -1)
                end
                if button == 1 and list == 1 then  -- button == 1 это кнопка слева, button == 0 - справа, list == 0 - 1 строка в списке, номера стрк начинаются с 0
                  sampAddChatMessage(u8("Вы нажали на 2 строку в списке"), -1)
                end
            end
        end
   
    end
   
    end

function dialog()
sampShowDialog(6405, "Название", "Текст", "ОК", "Отмена", 2)
end
кек, теперь другая проблема, когда пишешь команду /test а он следом "Вы нажали на 1 строку в списке" хотя я только прописал что бы выбрать
 

xSpiridon

Участник
74
21
кек, теперь другая проблема, когда пишешь команду /test а он следом "Вы нажали на 1 строку в списке" хотя я только прописал что бы выбрать
Lua:
local encoding = require 'encoding'
u8 = encoding.UTF8
encoding.default = 'CP1251'

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(2000) end
   
    sampRegisterChatCommand("test", dialog)
   
    while true do
    wait(0)
   
    local res, button, list, _ = sampHasDialogRespond(6405)
        if res then
            if button == 1 then
                if list == 0 then
                sampAddChatMessage(u8("Вы нажали на 1 строку в списке"), -1)
                end
                if list == 1 then
                sampAddChatMessage(u8("Вы нажали на 2 строку в списке"), -1)
                end
            end
        end
   
    end
   
    end

function dialog()
sampShowDialog(6405, u8("Название"), u8("Текст"), u8("ОК"), u8("Отмена"), 2)
end
вот так тогда
 
Последнее редактирование:
  • Нравится
Реакции: Vlad44352

Dmitriy Makarov

25.05.2021
Проверенный
2,478
1,113
кек, теперь другая проблема, когда пишешь команду /test а он следом "Вы нажали на 1 строку в списке" хотя я только прописал что бы выбрать
Lua:
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(2000) end
 
    sampRegisterChatCommand("test", dialog)
 
    while true do
    wait(0)
 
        local result, button, list, input = sampHasDialogRespond(6405)
                if result then
                if button == 1 and list == 0 then  -- button == 1 это кнопка слева, button == 0 - справа, list == 0 - 1 строка в списке, номера стрк начинаются с 0
                  sampAddChatMessage("Вы нажали на 1 строчку в списке", -1)
                end
                if button == 1 and list == 1 then  -- button == 1 это кнопка слева, button == 0 - справа, list == 0 - 1 строка в списке, номера стрк начинаются с 0
                  sampAddChatMessage("Вы нажали на 2 строку в списке", -1)
                end
            end
        end
 
    end
 
    end

function dialog()
sampShowDialog(6405, "Название", "Текст\nТекст2", "ОК", "Отмена", 2)
end
 
  • Нравится
Реакции: Cameron_Bawerman