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

Sanchez.

Известный
704
187
Посмотреть вложение 111767
Lua:
require "lib.moonloader"

function main()
     if not isSampLoaded() or not isSampfuncsLoaded() then return end
      sampRegisterChatCommand("fuck", fuck)
        wait(-1)
end

function fuck()
for k,v in pairs(getAllChars()) do
    local x,y,z = getCharCoordinates(1)
    local px,py,pz = getCharCoordinates(v)
    local id = sampGetPlayerIdByCharHandle(v)
    local dist = getDistanceBetweenCoords3d(x,y,z,px,py,pz)
 
    if dist < 50 then -- если расстояние меньше 50 метров
        sampSendChat('/filscar '..id)
        end
    end
end
Дядь, шо у тебя энд после сампсендчат забыл? + где end который должен закрыть функцию fuck()?
 

СоМиК

Известный
457
311
Lua:
require "lib.moonloader"

function main()
     if not isSampLoaded() or not isSampfuncsLoaded() then return end
     while not isSampAvailable() do wait(100) end
     sampRegisterChatCommand("fuck", fuck)
end

function fuck()
    for k,v in pairs(getAllChars()) do
        local x,y,z = getCharCoordinates(1)
        local px,py,pz = getCharCoordinates(v)
        local id = sampGetPlayerIdByCharHandle(v)
        local dist = getDistanceBetweenCoords3d(x,y,z,px,py,pz)
 
        if dist < 50 then -- если расстояние меньше 50 метров
            sampSendChat('/filscar '..id)
        end
    end
end
На
Кстать объясните мне пожалуйста как работает for. Много сайтов чекал, так и не понял, прям на своих словах объясните пожалуйста. Вот пример который я взял с этой темы:
Lua:
for k,v in pairs(getAllChars()) do
    local x,y,z = getCharCoordinates(1)
    local px,py,pz = getCharCoordinates(v)
    local id = sampGetPlayerIdByCharHandle(v)
    local dist = getDistanceBetweenCoords3d(x,y,z,px,py,pz)
 
    if dist < 50 then -- если расстояние меньше 50 метров
        sampSendChat('/filscar '..id)
    end
end
Объясните пожалуйста как работает.
Что значит к, в ин пэйрс
 
Последнее редактирование:

Smeruxa

Известный
1,301
681
Lua:
require "lib.moonloader"

function main()
     if not isSampLoaded() or not isSampfuncsLoaded() then return end
     while not isSampAvailable() do wait(100) end
     sampRegisterChatCommand("fuck", fuck)
end

function fuck()
    for k,v in pairs(getAllChars()) do
        local x,y,z = getCharCoordinates(1)
        local px,py,pz = getCharCoordinates(v)
        local id = sampGetPlayerIdByCharHandle(v)
        local dist = getDistanceBetweenCoords3d(x,y,z,px,py,pz)

        if dist < 50 then -- если расстояние меньше 50 метров
            sampSendChat('/filscar '..id)
        end
    end
end
На
Кстать объясните мне пожалуйста как работает for. Много сайтов чекал, так и не понял, прям на своих словах объясните пожалуйста. Вот пример который я взял с этой темы:
Lua:
for k,v in pairs(getAllChars()) do
    local x,y,z = getCharCoordinates(1)
    local px,py,pz = getCharCoordinates(v)
    local id = sampGetPlayerIdByCharHandle(v)
    local dist = getDistanceBetweenCoords3d(x,y,z,px,py,pz)

    if dist < 50 then -- если расстояние меньше 50 метров
        sampSendChat('/filscar '..id)
    end
end
Объясните пожалуйста как работает.
Что значит к, в ин пэйрс
написал 3 раза - for повторил тебе весь твой код 3 раза
Дядь, шо у тебя энд после сампсендчат забыл? + где end который должен закрыть функцию fuck()?
вместе 3 энда закрыли и условие и цикл и функцию :DDDDDDDDD
 
  • Ха-ха
Реакции: Sanchez.

#SameLine

Активный
417
37
Почему когда пользуюсь чекбокс, стоит галочка потом сохраняю ini.cfg, стоит галочка, но когда зажимаю CNTRL + R reload_all, и открываю это окно, там чекбоксы без галочек
 

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Друг
8,778
11,221
Почему когда пользуюсь чекбокс, стоит галочка потом сохраняю ini.cfg, стоит галочка, но когда зажимаю CNTRL + R reload_all, и открываю это окно, там чекбоксы без галочек
Lua:
local inicfg = require 'inicfg'
local directIni = 'файл.ini'
local ini = inicfg.load(inicfg.load({
    main = {
        checkbox = true,
    },
}, directIni))
inicfg.save(ini, directIni)

local check = imgui.ImBool(ini.main.checkbox)

--сохранение
ini.main.checkbox = check.v
 

#SameLine

Активный
417
37
Lua:
ini = inicfg.load({
    settings = {
        checkbox_1 = false,
        checkbox_2 = false,
        checkbox_3 = false,
        checkbox_4 = false,
        checkbox_5 = false
    }
})

imBox_1 = imgui.ImBool(ini.settings.checkbox_1)
imBox_2 = imgui.ImBool(ini.settings.checkbox_2)
imBox_3 = imgui.ImBool(ini.settings.checkbox_3)
imBox_4 = imgui.ImBool(ini.settings.checkbox_4)
imBox_5 = imgui.ImBool(ini.settings.checkbox_5)

-- Frame
imgui.Checkbox(u8'Информационная панель', imBox_4)
            
if imgui.Button(u8'Сохранить настройки', imgui.ImVec2(-0.1, 25)) then
    inicfg.save(ini)
end
 

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Друг
8,778
11,221
Lua:
ini = inicfg.load({
    settings = {
        checkbox_1 = false,
        checkbox_2 = false,
        checkbox_3 = false,
        checkbox_4 = false,
        checkbox_5 = false
    }
})

imBox_1 = imgui.ImBool(ini.settings.checkbox_1)
imBox_2 = imgui.ImBool(ini.settings.checkbox_2)
imBox_3 = imgui.ImBool(ini.settings.checkbox_3)
imBox_4 = imgui.ImBool(ini.settings.checkbox_4)
imBox_5 = imgui.ImBool(ini.settings.checkbox_5)

-- Frame
imgui.Checkbox(u8'Информационная панель', imBox_4)
           
if imgui.Button(u8'Сохранить настройки', imgui.ImVec2(-0.1, 25)) then
    inicfg.save(ini)
end
перед inicfg.save добавь
Lua:
ini.settings.checkbox_1 = imBox_1.v
ini.settings.checkbox_2 = imBox_2.v
ini.settings.checkbox_3 = imBox_3.v
ini.settings.checkbox_4 = imBox_4.v
ini.settings.checkbox_5 = imBox_5.v
 

Sanchez.

Известный
704
187
Lua:
ini = inicfg.load({
    settings = {
        checkbox_1 = false,
        checkbox_2 = false,
        checkbox_3 = false,
        checkbox_4 = false,
        checkbox_5 = false
    }
})

imBox_1 = imgui.ImBool(ini.settings.checkbox_1)
imBox_2 = imgui.ImBool(ini.settings.checkbox_2)
imBox_3 = imgui.ImBool(ini.settings.checkbox_3)
imBox_4 = imgui.ImBool(ini.settings.checkbox_4)
imBox_5 = imgui.ImBool(ini.settings.checkbox_5)

-- Frame
imgui.Checkbox(u8'Информационная панель', imBox_4)
           
if imgui.Button(u8'Сохранить настройки', imgui.ImVec2(-0.1, 25)) then
    inicfg.save(ini)
end
Ну конечно у тебя не будет сохранятся. Во первых, в inicfg.save() после ini должно быть название файла твоего конфига. Во вторых, ты должен сначала присвоить новые значения переменных конфигу, а потом уже сохранять
 

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Друг
8,778
11,221
Lua:
ini = inicfg.load({
    settings = {
        checkbox_1 = false,
        checkbox_2 = false,
        checkbox_3 = false,
        checkbox_4 = false,
        checkbox_5 = false
    }
})

imBox_1 = imgui.ImBool(ini.settings.checkbox_1)
imBox_2 = imgui.ImBool(ini.settings.checkbox_2)
imBox_3 = imgui.ImBool(ini.settings.checkbox_3)
imBox_4 = imgui.ImBool(ini.settings.checkbox_4)
imBox_5 = imgui.ImBool(ini.settings.checkbox_5)

-- Frame
imgui.Checkbox(u8'Информационная панель', imBox_4)
           
if imgui.Button(u8'Сохранить настройки', imgui.ImVec2(-0.1, 25)) then
    inicfg.save(ini)
end
вот пример имгуи окна с сохранением
Lua:
local imgui = require('imgui')
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local window = imgui.ImBool(false)

local inicfg = require 'inicfg'
local directIni = 'mySettings.ini'
local ini = inicfg.load(inicfg.load({
    main = {
        checkbox = true,
    },
}, directIni))
inicfg.save(ini, directIni)

local check = imgui.ImBool(ini.main.checkbox)

function main()
    while not isSampAvailable() do wait(200) end
    imgui.Process = false
    window.v = true  --show window
    while true do
        wait(0)
        imgui.Process = window.v
    end
end

function imgui.OnDrawFrame()
    if window.v then
        imgui.SetNextWindowPos(imgui.ImVec2(350.0, 250.0), imgui.Cond.FirstUseEver)
        imgui.SetNextWindowSize(imgui.ImVec2(280.0, 70.0), imgui.Cond.FirstUseEver)
        imgui.Begin('Window Title', window)

        imgui.Checkbox('CHECKBOX', check)

        if imgui.Button('Save settings') then
            save()
        end

        imgui.End()
    end
end

function save()
    ini.main.checkbox = check.v
    inicfg.save(ini, directIni)
end
 

Gorskin

{Reverse Developer} ✓
Проверенный
1,249
1,049
Можно ли как-то воспроизвести звук из одиночной гта са или звук проигрыша в казино?
Именно игровой звук, не загружаемый в папку файл или по ссылке.
 

#SameLine

Активный
417
37
Ну конечно у тебя не будет сохранятся. Во первых, в inicfg.save() после ini должно быть название файла твоего конфига. Во вторых, ты должен сначала присвоить новые значения переменных конфигу, а потом уже сохранять
Нечего конечно не понял, но дело в том что код работает только галочка не остаётся по сохранению
 

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Друг
8,778
11,221
Можно ли как-то воспроизвести звук из одиночной гта са или звук проигрыша в казино?
Именно игровой звук, не загружаемый в папку файл или по ссылке.
Lua:
addOneOffSound(0, 0, 0, ид звука)
 
  • Нравится
Реакции: Gorskin

Sanchez.

Известный
704
187
Lua:
require "lib.moonloader"

function main()
     if not isSampLoaded() or not isSampfuncsLoaded() then return end
     while not isSampAvailable() do wait(100) end
     sampRegisterChatCommand("fuck", fuck)
end

function fuck()
    for k,v in pairs(getAllChars()) do
        local x,y,z = getCharCoordinates(1)
        local px,py,pz = getCharCoordinates(v)
        local id = sampGetPlayerIdByCharHandle(v)
        local dist = getDistanceBetweenCoords3d(x,y,z,px,py,pz)

        if dist < 50 then -- если расстояние меньше 50 метров
            sampSendChat('/filscar '..id)
        end
    end
end
На
Кстать объясните мне пожалуйста как работает for. Много сайтов чекал, так и не понял, прям на своих словах объясните пожалуйста. Вот пример который я взял с этой темы:
Lua:
for k,v in pairs(getAllChars()) do
    local x,y,z = getCharCoordinates(1)
    local px,py,pz = getCharCoordinates(v)
    local id = sampGetPlayerIdByCharHandle(v)
    local dist = getDistanceBetweenCoords3d(x,y,z,px,py,pz)

    if dist < 50 then -- если расстояние меньше 50 метров
        sampSendChat('/filscar '..id)
    end
end
Объясните пожалуйста как работает.
Что значит к, в ин пэйрс
k, v - это переменные в цикле для массива. k - это номер элемента, v - это сам элемент. А в in pairs() в скобки нужно вписать сам массив
Нечего конечно не понял, но дело в том что код работает только галочка не остаётся по сохранению
Ну я же тебе про это только что объяснил