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

Rice.

Известный
Модератор
1,756
1,623
как из 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

Известный
673
371
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

чопа сребдс // @moujeek
Модератор
8,865
11,552
как из 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

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

moreveal

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

YourAssistant

Участник
144
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

Известный
Проверенный
921
618
Есть диалог, при каждом его открытии строчка %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?
 
Последнее редактирование:

lorgon

Известный
656
271
В чём проблема? (отступа сверху быть не должно)
1649816740900.png


Lua:
imgui.PushStyleVarVec2(imgui.StyleVar.WindowPadding, imgui.ImVec2(0, 0))
imgui.BeginChild("##main", imgui.ImVec2(1000, 1000), true)
    -- ...
imgui.EndChild()
imgui.PopStyleVar(1)

-- UPD
Так и не понял, как сделать это только для нужного элемента, т. к. работает только на всё окно.
 
Последнее редактирование:

coderko61

Участник
55
0


Lua:
distance = string.format("%.0f", getDistanceBetweenCoords3d(oX,oY,oZ, x2, y2, z2))
Это дистанция между двумя точками в пространстве.
В твоём случае между координатами твоего персонажа и координатами объекта.
Я бы сделал проверку на касание объекта с твоим персонажем.


Скинь полностью код скрипта.
Lua:
font = renderCreateFont('Century Gothic', 12, 5)
function main()
while not isSampAvailable() do wait(0) end wait(1)
while true do
wait(0)
for _, v in pairs(getAllObjects()) do
local asd
if sampGetObjectSampIdByHandle(v) ~= -1 then
asd = sampGetObjectSampIdByHandle(v)
end
if isObjectOnScreen(v) then
local result, oX, oY, oZ = getObjectCoordinates(v)
local x1, y1 = convert3DCoordsToScreen(oX,oY,oZ)
local objmodel = getObjectModel(v)
local x2,y2,z2 = getCharCoordinates(PLAYER_PED)
local x10, y10 = convert3DCoordsToScreen(x2,y2,z2)
distance = string.format("%.0f", getDistanceBetweenCoords3d(oX,oY,oZ, x2, y2, z2))

local touchobj = isCharTouchingObject(PLAYER_PED, objmodel)

if touchobj then return break else
if objmodel == 18974 or objmodel == 19036 or objmodel == 19037 or objmodel == 19038 or objmodel == 19801 then renderFontDrawText(font,"{ff0000}В маске!\nДистанция: "..distance, x1, y1, -1) end
end

end
end
end 
end
правильно? можно пример?
 

YourAssistant

Участник
144
17
В чём проблема? (отступа сверху быть не должно)
Посмотреть вложение 143208

Lua:
imgui.PushStyleVarVec2(imgui.StyleVar.WindowPadding, imgui.ImVec2(0, 0))
imgui.BeginChild("##main", imgui.ImVec2(1000, 1000), true)
    -- ...
imgui.EndChild()
imgui.PopStyleVar(1)

-- UPD
Так и не понял, как сделать это только для нужного элемента, т. к. работает только на всё окно.
Lua:
imgui.SetCursorPosX(1)
imgui.SetCursorPosY(1)
 
  • Злость
Реакции: lorgon

Dashok.

Участник
228
9
Скрипт должен считывать код с диалога, и автоматически вписывать его в инпут, но сервер пишет что код не верный, хотя в чате все верно

lua:
local pattern = "Введите данный код в поле внизу: (.+)"
if text:find(pattern) then
    local n1 = text:match(pattern)
    sampAddChatMessage(n1, -1)
    local crl = "{FFFFFF}"..n1
    sampSendDialogResponse(7987, 1, 0, ""..n1)
end

sa-mp-020.png