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

Nagenbl4

Новичок
107
2
Нужно вывести 3 переменные из function sampev.onShowDialog(dialogid, dialogstyle, title, b1, b2, text) и вставить их в function imgui.OnDrawFrame() .
Как?
 

штейн

Известный
Проверенный
1,002
688
Нужно вывести 3 переменные из function sampev.onShowDialog(dialogid, dialogstyle, title, b1, b2, text) и вставить их в function imgui.OnDrawFrame() .
Как?
объяви эти три переменные как глобальные (xui1 = 123, xui2 = 456, xui3 = 789) и используй в другой функции??
 

Lil Xean

о да моя госпожа
214
225
(error) test.lua: opcode '00A0' call caused an unhandled exception
stack traceback:
[C]: in function 'getCharCoordinates'
E:\GTA San Andreas123\moonloader\test.lua:14: in function <E:\GTA San Andreas123\moonloader\test.lua:6>
[ML] (error) test.lua: Script died due to an error. (097603FC)
Lua:
sampRegisterChatCommand('flyy', function(arg)
            if arg ~= nil then
                playerId = tonumber(arg)
                local ped = sampGetCharHandleBySampPlayerId(playerId)
                if isCharInAnyCar(PLAYER_PED) then
                    local car = storeCarCharIsInNoSave(PLAYER_PED)
                    local carid = sampGetVehicleIdByCarHandle(car)
                    local X,Y,Z = getCharCoordinates(ped)
                    print(X,Y,Z)
                end
            end              
    end)
 

.Makarov.

Известный
190
36
Здравствуйте. Нужна помощь с проверкой на ник из таблицы в диалоге.
Вот сама таблица:
Lua:
acceptnicks = {
"Типа первый ник",
"Типа второй ник",
"Типа третий ник",
"Ну и четвертый ник"
}
Вот сама проверка:
Lua:
if not scriptcheck then
    if dialogId == 235 then
        for _,checkname in ipairs(acceptnicks) do
            if string.find(text, checkname) then
                sampAddChatMessage("Успешно, Ваш ник есть в таблице",-1)
                return false
            else
                sampAddChatMessage("Увы, не судьба(",-1)
                return false
            end
        end
    end
end
Ну так вот в чем вся суть проблемы. Если мой ник находится первый в таблице. Мне пишет "Успешно, Ваш ник есть в таблице". Но а если второй, третий, четвертый - пишет мол "Увы, не судьба(". Как сделать чтоб при открытии 235 диалога (/stats), искало ник в таблице до тех пор, пока не найдет ник с диалога. А не останавливалось на первом. Заранее спасибо
 

Petr_Sergeevich

Известный
Проверенный
707
298
(error) test.lua: opcode '00A0' call caused an unhandled exception
stack traceback:
[C]: in function 'getCharCoordinates'
E:\GTA San Andreas123\moonloader\test.lua:14: in function <E:\GTA San Andreas123\moonloader\test.lua:6>
[ML] (error) test.lua: Script died due to an error. (097603FC)
Lua:
sampRegisterChatCommand('flyy', function(arg)
            if arg ~= nil then
                playerId = tonumber(arg)
                local ped = sampGetCharHandleBySampPlayerId(playerId)
                if isCharInAnyCar(PLAYER_PED) then
                    local car = storeCarCharIsInNoSave(PLAYER_PED)
                    local carid = sampGetVehicleIdByCarHandle(car)
                    local X,Y,Z = getCharCoordinates(ped)
                    print(X,Y,Z)
                end
            end          
    end)
bool result, Ped ped = sampGetCharHandleBySampPlayerId(int id)

Здравствуйте. Нужна помощь с проверкой на ник из таблицы в диалоге.
Вот сама таблица:
Lua:
acceptnicks = {
"Типа первый ник",
"Типа второй ник",
"Типа третий ник",
"Ну и четвертый ник"
}
Вот сама проверка:
Lua:
if not scriptcheck then
    if dialogId == 235 then
        for _,checkname in ipairs(acceptnicks) do
            if string.find(text, checkname) then
                sampAddChatMessage("Успешно, Ваш ник есть в таблице",-1)
                return false
            else
                sampAddChatMessage("Увы, не судьба(",-1)
                return false
            end
        end
    end
end
Ну так вот в чем вся суть проблемы. Если мой ник находится первый в таблице. Мне пишет "Успешно, Ваш ник есть в таблице". Но а если второй, третий, четвертый - пишет мол "Увы, не судьба(". Как сделать чтоб при открытии 235 диалога (/stats), искало ник в таблице до тех пор, пока не найдет ник с диалога. А не останавливалось на первом. Заранее спасибо

Lua:
-- ...
if dialogId == 235 then
    sampAddChatMessage(isNicknameFound(text) and "Успех" or "Провал", -1)
    return false
end
-- ...

function isNicknameFound(text)
    for i = 1, #acceptnicks do
        if text:find(acceptnicks[i], 1, true) then
            return true
        end
    end
    return false
end
 
  • Нравится
Реакции: .Makarov. и Lil Xean

dhhh

Известный
51
1
Lua:
local main_window_state = imgui.ImBool(false)
local test_text_buffer = imgui.ImBuffer(256)
local cd = imgui.ImBool(false)
local checkboxes = imgui.ImBool(false)


function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    gg = lua_thread.create_suspended(onShowDialog)
    sampRegisterChatCommand("gos", gos)
    imgui.Process = false
    while true do
    wait(0)
        if main_window_state.v == false then
            imgui.Process = false
        end

    end
end
function gos(arg)
main_window_state.v = not main_window_state.v
imgui.Process = main_window_state.v
end
function imgui.OnDrawFrame()
    local cb = imgui.ImBool(false)
imgui.Begin("Binder GOS", main_window_state)
imgui.InputText(u8"Введите текст", test_text_buffer)
imgui.Text("TEXT")
if imgui.Checkbox(u8("текст"), checkboxes) then
    gg:run()
end
imgui.End()
end
function onShowDialog(dialogId)
    sampAddChatMessage(dialogId, -1)
end
Почему ид диалога не выводится?
 

штейн

Известный
Проверенный
1,002
688
Lua:
local main_window_state = imgui.ImBool(false)
local test_text_buffer = imgui.ImBuffer(256)
local cd = imgui.ImBool(false)
local checkboxes = imgui.ImBool(false)


function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    gg = lua_thread.create_suspended(onShowDialog)
    sampRegisterChatCommand("gos", gos)
    imgui.Process = false
    while true do
    wait(0)
        if main_window_state.v == false then
            imgui.Process = false
        end

    end
end
function gos(arg)
main_window_state.v = not main_window_state.v
imgui.Process = main_window_state.v
end
function imgui.OnDrawFrame()
    local cb = imgui.ImBool(false)
imgui.Begin("Binder GOS", main_window_state)
imgui.InputText(u8"Введите текст", test_text_buffer)
imgui.Text("TEXT")
if imgui.Checkbox(u8("текст"), checkboxes) then
    gg:run()
end
imgui.End()
end
function onShowDialog(dialogId)
    sampAddChatMessage(dialogId, -1)
end
Почему ид диалога не выводится?
local sampev = require 'lib.samp.events'

function sampev.onShowDialog(dialogId)
 

Petr_Sergeevich

Известный
Проверенный
707
298
Lua:
local main_window_state = imgui.ImBool(false)
local test_text_buffer = imgui.ImBuffer(256)
local cd = imgui.ImBool(false)
local checkboxes = imgui.ImBool(false)


function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    gg = lua_thread.create_suspended(onShowDialog)
    sampRegisterChatCommand("gos", gos)
    imgui.Process = false
    while true do
    wait(0)
        if main_window_state.v == false then
            imgui.Process = false
        end

    end
end
function gos(arg)
main_window_state.v = not main_window_state.v
imgui.Process = main_window_state.v
end
function imgui.OnDrawFrame()
    local cb = imgui.ImBool(false)
imgui.Begin("Binder GOS", main_window_state)
imgui.InputText(u8"Введите текст", test_text_buffer)
imgui.Text("TEXT")
if imgui.Checkbox(u8("текст"), checkboxes) then
    gg:run()
end
imgui.End()
end
function onShowDialog(dialogId)
    sampAddChatMessage(dialogId, -1)
end
Почему ид диалога не выводится?
Многое в разделе вопросов можно встретить, но это просто пиздец)
Рекомендую ознакомиться лишний раз с основными темами по разработке, лишним явно не будет.
https://blast.hk/threads/19292/, https://blast.hk/threads/14624/, https://blast.hk/threads/22707/, https://blast.hk/threads/13315/
Lua:
-- Подключение библиотек, модулей
local sampev = require 'lib.samp.events'

-- Положение окна ImGUI
local isMenuActive = imgui.ImBool(false)
-- Буфер для хранения текста
local textBuffer = imgui.ImBuffer(256)
-- Значение чекбокса
local isPressed = imgui.ImBool(false)
-- Переменная, которая будет хранить последний отображенный ID диалога
local lastDialogID = -1

-- Подробнее в SAMP.lua (ссылку приложил)
function sampev.onShowDialog(id, style, title, b1, b2, text)
    lastDialogID = id
end

function imgui.OnDrawFrame()
    imgui.Begin("Binder GOS", isMenuActive)
        -- Поле для ввода текста
        imgui.InputText(u8("Введите текст"), textBuffer)

        -- Обычный текст
        imgui.Text(u8("Обычный текст"))

        -- Чекбокс
        if imgui.Checkbox(u8("Чекбокс"), isPressed) then
            sampAddChatMessage(("Последний id: %s"):format(lastDialogID), -1)
        end
    imgui.End()
end

function main()
    while not isSampAvailable() do wait(0) end
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
 
    sampRegisterChatCommand("gos", function()
        isMenuActive.v = not isMenuActive.v
    end)
 
    while true do
        wait(0)
        imgui.Process = isMenuActive.v
    end
end
 

Petr_Sergeevich

Известный
Проверенный
707
298
А как сделать чтоб в случае "Успех" или "Провал" было действие? Например если "Успех": scriptcheck = true. А если "Провал": sampSendChat("!")
Измени тернарный оператор на обычную конструкцию if ... then ... else ... end
Lua:
if isNicknameFound(text) then
  -- ...
else
  -- ...
end
 
  • Нравится
Реакции: .Makarov.

Scrip

Новичок
7
1
Общая тема для вопросов по разработке скриптов на языке программирования 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)





Пацаны, помогите пожалуйста. Пытаюсь научиться lua, строго за кривую херню не судите


[ML] (error) TimeScript: D:\GTA San Andreas\moonloader\chatscript.lua:9: attempt to call global 'isSampFuncsLoaded' (a nil value)
stack traceback:
D:\GTA San Andreas\moonloader\chatscript.lua: in function <D:\GTA San Andreas\moonloader\chatscript.lua:8>
[ML] (error) TimeScript: Script died due to an error. (07206F8C


Сам скрипт (ничего из себя не представляет, я просто учусь, извините)
Код:
script_name ('TimeScript')
script_author ('sexAgent777')
script_description ('fuck off pls')

require "lib.moonloader"


function main ()
if not isSampLoaded() or not isSampFuncsLoaded() then return end
while not isSampAvailable() do wait(100) end

while true do
wait (100)
sampAddChatMessage(tag.." Ya pristupil c rabote", 0xFFFFFF)
end
end
[code=lua]