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

auf.exe

Участник
41
12
Lua:
require 'lib.moonloader'

local rk = require 'rkeys'
local imgui = require 'imgui'
local sampev = require 'lib.samp.events'
local vk = require 'vkeys'
local imadd = require 'imgui_addons'
local inicfg = require 'inicfg'
local noctf = import 'imgui_notf.lua'
local directini = 'moonloader\\settings.ini'
imgui.HotKey = require('imgui_addons').HotKey


local mainini = inicfg.load(nil, directini)

if mainini.HotKey == nil then
    mainini.HotKey = {
        bind1 = "[18, 82]",
        bind2 = "[18, 83]"
    }
end

local tLastKeys = { }

local ActiveClockKeys = {
    v = decodeJson(mainini.HotKey.bind1),
    v = decodeJson(mainini.HotKey.bind2)
}

local main_window = imgui.ImBool(false)
local textbuffer = imgui.ImBuffer(256)

local sw, sr = getScreenResolution()

function main()
    while not isSampAvailable() do wait(0) end
    sampAddChatMessage('qq Binder tuta', -1)
    sampRegisterChatCommand('Lox', imgui1)

    bindClock = rk.registerHotKey(ActiveClockKeys, true, bind)
    bindClock2 = rk.registerHotKey(ActiveClockKeys, true, bind)

    while true do
        wait(0)
        if isKeyJustPressed(VK_M) then
            main_window.v = not main_window.v
            imgui.Process = main_window.v
        end
    end
end

function bind()
    sampSendChat(textbuffer.v)
    noctf.addNotify("Задача выполнена!, Ваша задача была успешно выполнена!", 5, 2)
end

function imgui.OnDrawFrame()

    imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sr / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(300, 250), imgui.Cond.FirstUseEver)

    if not main_window.v then
        imgui.Process = false
    end
    imgui.Begin("Binder by auf.exe", main_window)

   

    if imgui.HotKey('##1', ActiveClockKeys, tLastKeys, 100) then
        rk.changeHotKey(bindClock, ActiveClockKeys.v)
    end
    imgui.SameLine()
    imgui.InputText('Some Text', textbuffer1)
    imgui.Radiator()
    if imgui.HotKey('##2', ActiveClockKeys, tLastKeys, 100) then
        rk.changeHotKey(bindClock2, ActiveClockKeys.v)
    end
   
    mainini.HotKey.bind1 = encodeJson(ActiveClockKeys.v)
    mainini.HotKey.bind2 = encodeJson(ActiveClockKeys.v)
    inicfg.save(mainini, directini)
    imgui.End()
end
При открытии имгуи самп крашит незнаю почему(
Блин помогите уже
 

Dmitriy Makarov

25.05.2021
Проверенный
2,501
1,131
if imgui.HotKey('##2', ActiveClockKeys, tLastKeys, 100) then rk.changeHotKey(bindClock2, ActiveClockKeys.v) end mainini.HotKey.bind1 = encodeJson(ActiveClockKeys.v) mainini.HotKey.bind2 = encodeJson(ActiveClockKeys.v) inicfg.save(mainini, directini)
Это вроде должно быть вот так:
Lua:
if imgui.HotKey('##2', ActiveClockKeys, tLastKeys, 100) then
    rk.changeHotKey(bindClock2, ActiveClockKeys.v)
    mainini.HotKey.bind1 = encodeJson(ActiveClockKeys.v)
    mainini.HotKey.bind2 = encodeJson(ActiveClockKeys.v)
    inicfg.save(mainini, directini)
end
И ещё вроде нельзя вот так регать клавиши:
Lua:
local ActiveClockKeys = {
    v = decodeJson(mainini.HotKey.bind1),
    v = decodeJson(mainini.HotKey.bind2)
}
Каждая клавиша по отдельности:
Lua:
local ActiveClockKeys = {
    v = decodeJson(mainini.HotKey.bind1)
}
local ActiveClockKeys2 = {
    v = decodeJson(mainini.HotKey.bind2)
}
 

Varik_Soft

Участник
72
3
Всем привет ! У меня есть вот такая строчка
lua:
if input:find('Трейд') then
    sampAddChatMessage(id,-1)
end
Как можно проверить слово 'трейд', не зависимо от его регистра ?
К примеру если в чате будет 'ТрЕйд' или 'тРейд', то input:find('Трейд') было бы истинной ?
 

YarikVL

Известный
Проверенный
4,769
1,816
Всем привет ! У меня есть вот такая строчка
lua:
if input:find('Трейд') then
    sampAddChatMessage(id,-1)
end
Как можно проверить слово 'трейд', не зависимо от его регистра ?
К примеру если в чате будет 'ТрЕйд' или 'тРейд', то input:find('Трейд') было бы истинной ?
Если я правильно понял то вот: https://www.blast.hk/threads/60445/
 

qdIbp

Автор темы
Проверенный
1,421
1,169
как завести двигатель авто типа есть boatStop(Vehicle car) он глушит авто, а есть строка/команда/хз чтобы завести машину
 

Dmitriy Makarov

25.05.2021
Проверенный
2,501
1,131
как завести двигатель авто типа есть boatStop(Vehicle car) он глушит авто, а есть строка/команда/хз чтобы завести машину
Хз что из этого за что конкретно отвечает, но вот что я нарыл на вики
 
  • Нравится
Реакции: qdIbp

SurnikSur

Активный
284
40
Как отправить взрыв тс на сервер(тоесть чтобы у всех в зоне стрима я взорвался а для себя нет)
 

_Nelit_

Потрачен
109
39
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.

Rice.

Известный
Модератор
1,731
1,589
Как можно через регулярные выражения проверить одно слово на множество вариаций символов верхнего регистра?
Пример:
Lua:
-- samp.lua
if text:find('Привет') then -- Игрок может написать слово 'Привет' как 'ПРИВЕТ' или 'ПРиВет', я надеюсь, что Вы поняли
    --code
end
 

_Nelit_

Потрачен
109
39
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Привет! Сейчас вспомнил про луа скриптинг, хотелось бы вспомнить пару моментов. Как найти строку в диалоге например "Пол" и вытащить от туда значение "Мужчина" или "Женщина". Это как пример. ПОжалуйста
 

Rice.

Известный
Модератор
1,731
1,589
Привет! Сейчас вспомнил про луа скриптинг, хотелось бы вспомнить пару моментов. Как найти строку в диалоге например "Пол" и вытащить от туда значение "Мужчина" или "Женщина". Это как пример. ПОжалуйста
Lua:
if sampevcheck then
    function sampev.onShowDialog(dialogId, style, title, button1, button2, text)
        if dialogId == 235 and getRankInStats then
            for DialogLine in text:gmatch('[^\r\n]+') do
                local nameRankStats, getStatsRank = DialogLine:match('Должность: {......}(.+)%((%d+)%)')
                local pol = DialogLine:match('Пол: {......}%[(.+)%]')
                if pol == 'Мужчина' and FirstSettings.v == false then
                    GHsms('Пол автоматически установлен "Мужчина". Изменить можно в настройках скрипта.')
                    sex.v = 1
                    cfg.Settings.sex = sex.v
                    FirstSettings.v = true
                    cfg.Settings.FirstSettings = FirstSettings.v
                    inicfg.save(cfg, 'Government Helper.ini')
                    elseif pol == 'Женщина' and FirstSettings.v == false then
                    GHsms('Пол автоматически установлен "Женщина". Изменить можно в настройках скрипта.')
                    sex.v = 2
                    cfg.Settings.sex = sex.v
                    FirstSettings.v = true
                    cfg.Settings.FirstSettings = FirstSettings.v
                    inicfg.save(cfg, 'Government Helper.ini')
                end
            end
            sampSendDialogResponse(dialogId, 0, _, _)
            getRankInStats = false
            return false
        end
    end
end
 
  • Нравится
Реакции: _Nelit_

_Nelit_

Потрачен
109
39
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Lua:
if sampevcheck then
    function sampev.onShowDialog(dialogId, style, title, button1, button2, text)
        if dialogId == 235 and getRankInStats then
            for DialogLine in text:gmatch('[^\r\n]+') do
                local nameRankStats, getStatsRank = DialogLine:match('Должность: {......}(.+)%((%d+)%)')
                local pol = DialogLine:match('Пол: {......}%[(.+)%]')
                if pol == 'Мужчина' and FirstSettings.v == false then
                    GHsms('Пол автоматически установлен "Мужчина". Изменить можно в настройках скрипта.')
                    sex.v = 1
                    cfg.Settings.sex = sex.v
                    FirstSettings.v = true
                    cfg.Settings.FirstSettings = FirstSettings.v
                    inicfg.save(cfg, 'Government Helper.ini')
                    elseif pol == 'Женщина' and FirstSettings.v == false then
                    GHsms('Пол автоматически установлен "Женщина". Изменить можно в настройках скрипта.')
                    sex.v = 2
                    cfg.Settings.sex = sex.v
                    FirstSettings.v = true
                    cfg.Settings.FirstSettings = FirstSettings.v
                    inicfg.save(cfg, 'Government Helper.ini')
                end
                if tonumber(getStatsRank) then
                    if tonumber(getStatsRank) ~= cfg.Settings.rankAndNumber then
                        cfg.Settings.rankAndNumber = tonumber(getStatsRank)
                        cfg.Settings.rank = tostring(nameRankStats)
                        GHsms('Ранг обновлён на '..tostring(nameRankStats)..'('..tostring(getStatsRank)..')')
                        inicfg.save(cfg, 'Government Helper.ini')
                        else
                        GHsms('Ваша должность соответствует данным из статистики.')
                    end
                end
            end
            sampSendDialogResponse(dialogId, 0, _, _)
            getRankInStats = false
            return false
        end
    end
end
Спасибо!

Lua:
if sampevcheck then
    function sampev.onShowDialog(dialogId, style, title, button1, button2, text)
        if dialogId == 235 and getRankInStats then
            for DialogLine in text:gmatch('[^\r\n]+') do
                local nameRankStats, getStatsRank = DialogLine:match('Должность: {......}(.+)%((%d+)%)')
                local pol = DialogLine:match('Пол: {......}%[(.+)%]')
                if pol == 'Мужчина' and FirstSettings.v == false then
                    GHsms('Пол автоматически установлен "Мужчина". Изменить можно в настройках скрипта.')
                    sex.v = 1
                    cfg.Settings.sex = sex.v
                    FirstSettings.v = true
                    cfg.Settings.FirstSettings = FirstSettings.v
                    inicfg.save(cfg, 'Government Helper.ini')
                    elseif pol == 'Женщина' and FirstSettings.v == false then
                    GHsms('Пол автоматически установлен "Женщина". Изменить можно в настройках скрипта.')
                    sex.v = 2
                    cfg.Settings.sex = sex.v
                    FirstSettings.v = true
                    cfg.Settings.FirstSettings = FirstSettings.v
                    inicfg.save(cfg, 'Government Helper.ini')
                end
                if tonumber(getStatsRank) then
                    if tonumber(getStatsRank) ~= cfg.Settings.rankAndNumber then
                        cfg.Settings.rankAndNumber = tonumber(getStatsRank)
                        cfg.Settings.rank = tostring(nameRankStats)
                        GHsms('Ранг обновлён на '..tostring(nameRankStats)..'('..tostring(getStatsRank)..')')
                        inicfg.save(cfg, 'Government Helper.ini')
                        else
                        GHsms('Ваша должность соответствует данным из статистики.')
                    end
                end
            end
            sampSendDialogResponse(dialogId, 0, _, _)
            getRankInStats = false
            return false
        end
    end
end
Можешь код пояснить чуть чуть? Например комментариями. Пожалуйста
 

Rice.

Известный
Модератор
1,731
1,589
Спасибо!


Можешь код пояснить чуть чуть? Например комментариями. Пожалуйста
Lua:
local sampevcheck, sampev = pcall(require, "samp.events")

if sampevcheck then -- Проверяем наличие библиотеки SAMP.Lua
    function sampev.onShowDialog(dialogId, style, title, button1, button2, text) -- Функция для работы с диалогом
        if dialogId == 235 and getRankInStats then -- Если ид диалога == 235 и включена функция getRankInStats (Данная функция создана, чтобы скрипт не проверял диалог, если это не нужно), то
            for DialogLine in text:gmatch('[^\r\n]+') do -- Разбиваем диалог на строчки с помощью for
                local nameRankStats, getStatsRank = DialogLine:match('Должность: {......}(.+)%((%d+)%)') -- Данная строчка тебе не нужна, т.к. код из моего скрипта
                local pol = DialogLine:match('Пол: {......}%[(.+)%]') -- Записываем переменную pol из строчки с тексом "Пол:"
                if pol == 'Мужчина' and FirstSettings.v == false then -- Если в переменной записано 'Мужчина', то
                    GHsms('Пол автоматически установлен "Мужчина". Изменить можно в настройках скрипта.') -- Выводим в чат сообщение
                    sex.v = 1 -- Устанавливаем переменной sex = 1, которая у нас должна быть вначале скрипта (local sex = imgui.ImInt(cfg.Settings.sex))
                    cfg.Settings.sex = sex.v -- Сохраняем в Ini Конфиг
                    FirstSettings.v = true -- Это нужно было для моего скрипта
                    cfg.Settings.FirstSettings = FirstSettings.v -- Это нужно было для моего скрипта
                    inicfg.save(cfg, 'Government Helper.ini') -- Сохраняем конфиг
                    elseif pol == 'Женщина' and FirstSettings.v == false then -- Если в переменной записано 'Женщина', то
                    GHsms('Пол автоматически установлен "Женщина". Изменить можно в настройках скрипта.') -- Выводим в чат сообщение
                    sex.v = 2 -- Устанавливаем переменной sex = 1, которая у нас должна быть вначале скрипта (local sex = imgui.ImInt(cfg.Settings.sex))
                    cfg.Settings.sex = sex.v -- Работа с конфигом, сорян, устал писать
                    FirstSettings.v = true -- Для другого скрипта
                    cfg.Settings.FirstSettings = FirstSettings.v -- Для другого скрипта
                    inicfg.save(cfg, 'Government Helper.ini') -- Сохраняем в конфиг
                end -- Закрывам проверку текста
            end -- Заканчиваем обрабатывать диалог с помощью for
            sampSendDialogResponse(dialogId, 0, _, _) -- Закрываем серверно диалог (нажимая на правую кнопку)
            getRankInStats = false -- Данная функция создана, чтобы скрипт не проверял диалог, если это не нужно. Выключаем её.
            return false -- Закрываем визуально диалог
        end
    end -- Закрываем функцию работы с диалогом
end -- Закрываем проверку библиотеки
 
  • Нравится
Реакции: _Nelit_