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

sat0ry

Известный
1,084
301
sampfuncs console:
[ML] (error) script.lua: opcode '0984' call caused an unhandled exception
stack traceback:
    [C]: in function 'getObjectModel'
    D:\ARIZONA GAMES\bin\Arizona\moonloader\script.lua:10: in function <D:\ARIZONA GAMES\bin\Arizona — êîïèÿ\moonloader\script.lua:9>
[ML] (error) script.lua: Script died due to an error. (05F4DBB4)
Сам код скрипта:
LUA:
require 'moonloader'

local font = renderCreateFont('Arial', 15, 15)

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

    sampRegisterChatCommand('klad', function()
        local model = getObjectModel(v)
        if model == 2680 then
            local _, x, y, z = getObjectCoordinates(v)
            if isPointOnScreen(x, y, z) then
                local x1, y1 = convert3DCoordsToScreen(x,y,z)
                local x2,y2,z2 = getCharCoordinates(PLAYER_PED)
                local x10, y10 = convert3DCoordsToScreen(x2,y2,z2)
                local distance = string.format("%.1f", getDistanceBetweenCoords3d(x, y, z, x2, y2, z2))
                if model == 2680 then
                    renderFontDrawText(font, 'Клад', x1, y1, 0xFFFFFFFF, 0x90000000)
                end
            end
        end

        for v = 1, #t do
            pos1X, pos1Y, pos1Z = getBodyPartCoordinates(t[v], cped)
            pos2X, pos2Y, pos2Z = getBodyPartCoordinates(t[v] + 1, cped)
            pos1, pos2 = convert3DCoordsToScreen(pos1X, pos1Y, pos1Z)
            pos3, pos4 = convert3DCoordsToScreen(pos2X, pos2Y, pos2Z)
            renderDrawLine(pos1, pos2, pos3, pos4, 1, color)
        end
        for v = 4, 5 do
            pos2X, pos2Y, pos2Z = getBodyPartCoordinates(v * 10 + 1, cped)
            pos3, pos4 = convert3DCoordsToScreen(pos2X, pos2Y, pos2Z)
            renderDrawLine(pos1, pos2, pos3, pos4, 1, color)
        end
        local t = {53, 43, 24, 34, 6}
        for v = 1, #t do
            posX, posY, posZ = getBodyPartCoordinates(t[v], cped)
            pos1, pos2 = convert3DCoordsToScreen(posX, posY, posZ)
        end
    end)
    wait(-1)
end

Собственно говоря, хуле он падает?
 

Rice.

Известный
Модератор
1,760
1,712
sampfuncs console:
[ML] (error) script.lua: opcode '0984' call caused an unhandled exception
stack traceback:
    [C]: in function 'getObjectModel'
    D:\ARIZONA GAMES\bin\Arizona\moonloader\script.lua:10: in function <D:\ARIZONA GAMES\bin\Arizona — êîïèÿ\moonloader\script.lua:9>
[ML] (error) script.lua: Script died due to an error. (05F4DBB4)
Сам код скрипта:
LUA:
require 'moonloader'

local font = renderCreateFont('Arial', 15, 15)

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

    sampRegisterChatCommand('klad', function()
        local model = getObjectModel(v)
        if model == 2680 then
            local _, x, y, z = getObjectCoordinates(v)
            if isPointOnScreen(x, y, z) then
                local x1, y1 = convert3DCoordsToScreen(x,y,z)
                local x2,y2,z2 = getCharCoordinates(PLAYER_PED)
                local x10, y10 = convert3DCoordsToScreen(x2,y2,z2)
                local distance = string.format("%.1f", getDistanceBetweenCoords3d(x, y, z, x2, y2, z2))
                if model == 2680 then
                    renderFontDrawText(font, 'Клад', x1, y1, 0xFFFFFFFF, 0x90000000)
                end
            end
        end

        for v = 1, #t do
            pos1X, pos1Y, pos1Z = getBodyPartCoordinates(t[v], cped)
            pos2X, pos2Y, pos2Z = getBodyPartCoordinates(t[v] + 1, cped)
            pos1, pos2 = convert3DCoordsToScreen(pos1X, pos1Y, pos1Z)
            pos3, pos4 = convert3DCoordsToScreen(pos2X, pos2Y, pos2Z)
            renderDrawLine(pos1, pos2, pos3, pos4, 1, color)
        end
        for v = 4, 5 do
            pos2X, pos2Y, pos2Z = getBodyPartCoordinates(v * 10 + 1, cped)
            pos3, pos4 = convert3DCoordsToScreen(pos2X, pos2Y, pos2Z)
            renderDrawLine(pos1, pos2, pos3, pos4, 1, color)
        end
        local t = {53, 43, 24, 34, 6}
        for v = 1, #t do
            posX, posY, posZ = getBodyPartCoordinates(t[v], cped)
            pos1, pos2 = convert3DCoordsToScreen(posX, posY, posZ)
        end
    end)
    wait(-1)
end

Собственно говоря, хуле он падает?
У тебя нету переменной "v"
local model = getObjectModel(v)
UPD:
Lua:
sampRegisterChatCommand('klad', function()
    for k, v in pairs(getAllObjects())
        local model = getObjectModel(v)
        -- код дальше
    end
end)

sampfuncs console:
[ML] (error) script.lua: D:\ARIZONA GAMES\bin\Arizona — êîïèÿ\moonloader\script.lua:19: 'do' expected near 'local'
[ML] (error) script.lua: Script died due to an error. (89D8D624)
lua:
require 'moonloader'

local font = renderCreateFont('Arial', 15, 15)

local work = false

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

    sampRegisterChatCommand('zakladka', function()
        work = not work
    end)

    while true do
        wait(0)
        if work then
            for k, v in pairs(getAllObjects())
                local model = getObjectModel(v)
                if model==1575 or model==1576 or model==1577 or model==1578 or model==1579 or model==1580 then
                local _, x, y, z = getObjectCoordinates(v)
                if isPointOnScreen(x, y, z) then
                    local x1, y1 = convert3DCoordsToScreen(x,y,z)
                    local x2,y2,z2 = getCharCoordinates(PLAYER_PED)
                    local x10, y10 = convert3DCoordsToScreen(x2,y2,z2)
                    local distance = string.format("%.1f", getDistanceBetweenCoords3d(x, y, z, x2, y2, z2))
                    if model == 1575 then
                        renderFontDrawText(font, 'Закладка 1', x1, y1, 0xFFFFFFFF, 0x90000000)
                    end
                    if model == 1576 then
                        renderFontDrawText(font, 'Закладка 2', x1, y1, 0xFFFFFFFF, 0x90000000)
                    end
                    if model == 1577 then
                        renderFontDrawText(font, 'Закладка 3', x1, y1, 0xFFFFFFFF, 0x90000000)
                    end
                    if model == 1578 then
                        renderFontDrawText(font, 'Закладка 4', x1, y1, 0xFFFFFFFF, 0x90000000)
                    end
                    if model == 1579 then
                        renderFontDrawText(font, 'Закладка 5', x1, y1, 0xFFFFFFFF, 0x90000000)
                    end
                    if model == 1580 then
                        renderFontDrawText(font, 'Закладка 6', x1, y1, 0xFFFFFFFF, 0x90000000)
                    end
                end
            end
        end
    end
end

а забей

нашел проблему
I'm sorry

Lua:
for k, v in pairs(getAllObjects()) do -- Забыл do поставить
    local model = getObjectModel(v)
    -- код дальше
end
 
Последнее редактирование:
  • Влюблен
Реакции: sat0ry

sat0ry

Известный
1,084
301
У тебя нету переменной "v"
local model = getObjectModel(v)
UPD:
Lua:
sampRegisterChatCommand('klad', function()
    for k, v in pairs(getAllObjects())
        local model = getObjectModel(v)
        -- код дальше
    end
end)


I'm sorry

Lua:
for k, v in pairs(getAllObjects()) do -- Забыл do поставить
    local model = getObjectModel(v)
    -- код дальше
end
Забей, исправил уже, спасибо огромное!
 

Rice.

Известный
Модератор
1,760
1,712
как из ColorEdit4 вытащить hex?
Lua:
-- bool
local clr = 4294967295
local color = imgui.ImFloat4(imgui.ImColor(clr):GetFloat4())

-- Imgui
if imgui.ColorEdit4('Test', color, imgui.ColorEditFlags.NoAlpha) then
    clr = imgui.ImColor.FromFloat4(color.v[1], color.v[2], color.v[3], color.v[4]):GetU32()
end

-- Hex
local color_hex = ('%06X'):format(join_argb(0, color.v[1] * 255, color.v[2] * 255, color.v[3] * 255))
print(color_hex) -- Выведет FFFFFF
 
  • Нравится
Реакции: ewin

ewin

Известный
672
376
Lua:
-- bool
local clr = 4294967295
local color = imgui.ImFloat4(imgui.ImColor(clr):GetFloat4())

-- Imgui
if imgui.ColorEdit4('Test', color, imgui.ColorEditFlags.NoAlpha) then
    clr = imgui.ImColor.FromFloat4(color.v[1], color.v[2], color.v[3], color.v[4]):GetU32()
end

-- Hex
local color_hex = ('%06X'):format(join_argb(0, color.v[1] * 255, color.v[2] * 255, color.v[3] * 255))
print(color_hex) -- Выведет FFFFFF
на mimgui нужно
 

chapo

tg/inst: @moujeek
Всефорумный модератор
9,228
12,634
как из ColorEdit4 вытащить hex?
говнокод, но зато работает
Lua:
-- в начало кода
local col = imgui.new.float[4](1, 0, 0, 1)
function join_argb(a, r, g, b)
    local argb = b  -- b
    argb = bit.bor(argb, bit.lshift(g, 8))  -- g
    argb = bit.bor(argb, bit.lshift(r, 16)) -- r
    argb = bit.bor(argb, bit.lshift(a, 24)) -- a
    return argb
end

-- окно
imgui.ColorEdit4('Color', col)
imgui.Text('{'..string.sub(bit.tohex(join_argb(col[3] * 255, col[0] * 255, col[1] * 255, col[2] * 255)), 3, 8)..'}')
1649776363936.png
 
  • Нравится
Реакции: ewin

ewin

Известный
672
376
в других языках при использовании цикла можно пропустить один луп функцией continue(), есть то же самое в луа?
 

moreveal

Известный
988
722
в других языках при использовании цикла можно пропустить один луп функцией continue(), есть то же самое в луа?
нет (необходимо ставить условие внутри цикла, которое будет истинным только для нужных тебе итераций)
 
  • Грустно
Реакции: ewin

YourAssistant

Участник
145
17
в других языках при использовании цикла можно пропустить один луп функцией continue(), есть то же самое в луа?
Если это JS, то continue() тоже срабатывает при "условии внутри цикла, которое будет истинным только для нужных тебе итераций":
Lua:
for i = 1, 10 do
 if i%2~=0 then
   print(i)
 end
end
 

Dashok.

Участник
228
9
Есть диалог, при каждом его открытии строчка %d+. Получить приз
Становится на рандомное место по списку.
Как сделать выбор в диалоге этого пункта?
sa-mp-019.png
 

nikusik

Новичок
22
0
Привет всем! У кого нибудь есть код для авторедактированния обьявление вообще на любой проект? Если есть то дайте пожалуйста, мне просто очень нужен любой пример этой системы! Заранее спасибо.

Привет, есть вопросик, получается если приходит смс от любого человека в чат, допустим: "вам прислал сообщение Nick_Name , содержимое сообщение: бла бла бла" каким образом можно вынуть ник чела в переменную и в другую переменную его сообщение? Буду благодарен.
 

moreveal

Известный
988
722
Есть диалог, при каждом его открытии строчка %d+. Получить приз
Становится на рандомное место по списку.
Как сделать выбор в диалоге этого пункта?Посмотреть вложение 143192
Lua:
local sampev = require 'samp.events'

function sampev.onShowDialog(dialogid, style, title, b1, b2, text)
    if dialogid == 1 then -- id диалога
        local count = -1
        for line in text:gmatch("[^\n]+") do
            count = count + 1
            if line:find("Получить приз") then
                 sampSendDialogResponse(dialogid, 1, count, -1)
                 break
            end
        end
    end
end

как сделать перенос текста на новую строку при достижении определенного количества символов в imgui.InputTextMultiline?
 
Последнее редактирование: