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

Petr_Sergeevich

Известный
Проверенный
707
296
Не обычное, оно всегда на экране и убрать / перетащить его тоже нельзя
Тогда вопрос должен был прозвучать так: "Как запретить перемещение imgui окна по экрану и сделать его постоянно активным?"
А "шняга, которая не зависит от пользователя" - это пиздец) Ну и да, это обычное окно.

В начале кода
Lua:
local isMenuActive = imgui.ImBool(true)

main, бесконечный цикл
Lua:
imgui.Process = isMenuActive.v

imgui.OnDrawFrame
Lua:
if isMenuActive.v then
    local sX, sY = getScreenResolution()
    imgui.ShowCursor = false
    imgui.SetMouseCursor(-1)

    imgui.SetNextWindowPos(imgui.ImVec2(sX/2, sY/2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(250, 120), imgui.Cond.FirstUseEver)

    imgui.Begin(u8("..."), isMenuActive, imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoResize + imgui.WindowFlags.NoMove + imgui.WindowFlags.NoTitleBar)
        -- ...
    imgui.End()
end
 
  • Нравится
Реакции: lemonager

Natami

Участник
377
26
Есть функция sampev.onShowDialog
Как сделать, чтобы он искал определенную строку, а не 1 (Чтобы находил в этих строках мой ник и выполнял действие по ID)

(Каждая строка одинакова, отличается только ID игрока, Уровень, Ник)
 

lemonager

;)
Всефорумный модератор
809
1,702
Есть функция sampev.onShowDialog
Как сделать, чтобы он искал определенную строку, а не 1

(Каждая строка одинакова, отличается только ID игрока)
Lua:
function hook.onShowDialog(dialogId, dialogStyle, dialogTitle, okButtonText, cancelButtonText, dialogText)
if dialogText:find("я ебу собак") then
--code
   end
end
ищет определенный текст из всего диалога, тебе это надо?
 

Natami

Участник
377
26
Lua:
function hook.onShowDialog(dialogId, dialogStyle, dialogTitle, okButtonText, cancelButtonText, dialogText)
if dialogText:find("я ебу собак") then
--code
   end
end
ищет определенный текст из всего диалога, тебе это надо?
Не, у меня там

ID Уровень Ник
И надо,чтобы из этого списка он отыскал меня и написал
sampAddChatMessage("Ваш уровень "..lvl.."!", -1)
 

Belo4ka_belka

Известный
191
7
Здравствуйте товарищи! Пытаюсь прикрепить к игроку 3D текст: нахожу имена всех вокруг и прикрепляю к каждому игроку определенный текст с ini файла. Код следующий:
Код:
                while true do
                    Mem_Index = Mem_Index + 1
                    if table.maxn (clNames) == Mem_Index then
                        --print("break")
                        break
                    end

                    if MembersIni.Require[clNames[Mem_Index]] ~= nil then
                        print("" .. MembersIni.Require[clNames[Mem_Index]].. " [" .. clIDs[Mem_Index] .."]")
                        texID = 10000 + clIDs[Mem_Index]
                        texText = MembersIni.Require[clNames[Mem_Index]] -- в Ini файле все записано под ключем ИмяИгрока=Значение
                        textCID = clIDs[Mem_Index] - ключи у clIDs и clNames идентичны потому что заносятся в одном условии.
                        sampCreate3dTextEx(texID, texText, 0xFFFF0000, 0, 0, 0, 50, true, textCID)
                    end
                end
Ini файл существует, значение есть (принт выводит правильные значения), то же самое касается и массивов с именами и ID. Видимо проблема чисто в sampcreate... Текста не видно. Ошибок никаких нет, все работает (в плане того что скрипт не падает). Подскажите что я делаю не так, пожалуйста.
Второй вопрос не обязательный, но интересно, я в идентификатор текста могу любое число записать? Оно не будет конфликтовать с 3D текстом созданным сервером (менять/скрывать и т.д.)?

P.S. Лишь одна просьба - не указывать на недостаток с применением while вместо for если это не является прямой причиной моей проблемы. С for у меня определенные трудности возникают, ввиду недостаточных знаний конкретно этого языка, потому пока применяю while.
 
Последнее редактирование:

Yuan

Участник
77
26
Как вывести в чат ид игрока по нику?
В сниппетах вроде как была такая функция. Если её там уже нет, то просто прогони в цикле от 0 до 999 получение ников по хендлу и сравнение со своим.
UPD: вот функция.
Здравствуйте товарищи! Пытаюсь прикрепить к игроку 3D текст: нахожу имена всех вокруг и прикрепляю к каждому игроку определенный текст с ini файла. Код следующий:
Код:
                while true do
                    Mem_Index = Mem_Index + 1
                    if table.maxn (clNames) == Mem_Index then
                        --print("break")
                        break
                    end

                    if MembersIni.Require[clNames[Mem_Index]] ~= nil then
                        print("" .. MembersIni.Require[clNames[Mem_Index]].. " [" .. clIDs[Mem_Index] .."]")
                        texID = 10000 + clIDs[Mem_Index]
                        texText = MembersIni.Require[clNames[Mem_Index]] -- в Ini файле все записано под ключем ИмяИгрока=Значение
                        textCID = clIDs[Mem_Index] - ключи у clIDs и clNames идентичны потому что заносятся в одном условии.
                        sampCreate3dTextEx(texID, texText, 0xFFFF0000, 0, 0, 0, 50, true, textCID)
                    end
                end
Ini файл существует, значение есть (принт выводит правильные значения), то же самое касается и массивов с именами и ID. Видимо проблема чисто в sampcreate... Подскажите что я делаю не так, пожалуйста.
Второй вопрос не обязательный, но интересно, я в идентификатор текста могу любое число записать? Оно не будет конфликтовать с 3D текстом созданным сервером (менять/скрывать и т.д.)?

P.S. Лишь одна просьба - не указывать на недостаток с применением while вместо for если это не является прямой причиной моей проблемы. С for у меня определенные трудности возникают, ввиду недостаточных знаний конкретно этого языка, потому пока применяю while.
Так а какая проблема-то? Просто не показывает? Показывает ошибку? Или что?
 

Belo4ka_belka

Известный
191
7
В сниппетах вроде как была такая функция. Если её там уже нет, то просто прогони в цикле от 0 до 999 получение ников по хендлу и сравнение со своим.
UPD: вот функция.

Так а какая проблема-то? Просто не показывает? Показывает ошибку? Или что?
Мой косяк, проблему не указал, исправил. Просто не показывает. Ошибок нет, все запускается, все проходит. Принтами чекаю что до этой строчки код доходит и не крашится (следующие итерации запускаются). Возможно координаты текста являются абсолютными координатами на карте а не относительными к игроку которому я пытаюсь прикрепить? Или он полностью прозрачный что я не вижу его?
 

trefa

Известный
Всефорумный модератор
2,097
1,233
В сниппетах вроде как была такая функция. Если её там уже нет, то просто прогони в цикле от 0 до 999 получение ников по хендлу и сравнение со своим.
UPD: вот функция.

Так а какая проблема-то? Просто не показывает? Показывает ошибку? Или что?
В цикле нежелательно 3d текст создавать
 

#kweeZ

Известный
577
122
Можно ли как-то проверить прогрузилась зона стрима или нет?
 

Belo4ka_belka

Известный
191
7
В цикле нежелательно 3d текст создавать
Тогда можете подсказать примерный алгоритм: мне необходимо всем игрокам вокруг прикреплять 3D текст постоянно (ну точнее если он в прорисовке и если над ним текста нет или текущий текст не соответствует тому что записан в ini файле). Как лучше применять?
 

trefa

Известный
Всефорумный модератор
2,097
1,233
Тогда можете подсказать примерный алгоритм: мне необходимо всем игрокам вокруг прикреплять 3D текст постоянно (ну точнее если он в прорисовке и если над ним текста нет или текущий текст не соответствует тому что записан в ini файле). Как лучше применять?
Хук на вхождение игрока в зону стрима юзай
 
  • Нравится
Реакции: Yuan

Belo4ka_belka

Известный
191
7
Здравствуйте товарищи! Пытаюсь прикрепить к игроку 3D текст: нахожу имена всех вокруг и прикрепляю к каждому игроку определенный текст с ini файла. Код следующий:
Код:
                while true do
                    Mem_Index = Mem_Index + 1
                    if table.maxn (clNames) == Mem_Index then
                        --print("break")
                        break
                    end

                    if MembersIni.Require[clNames[Mem_Index]] ~= nil then
                        print("" .. MembersIni.Require[clNames[Mem_Index]].. " [" .. clIDs[Mem_Index] .."]")
                        texID = 10000 + clIDs[Mem_Index]
                        texText = MembersIni.Require[clNames[Mem_Index]] -- в Ini файле все записано под ключем ИмяИгрока=Значение
                        textCID = clIDs[Mem_Index] - ключи у clIDs и clNames идентичны потому что заносятся в одном условии.
                        sampCreate3dTextEx(texID, texText, 0xFFFF0000, 0, 0, 0, 50, true, textCID)
                    end
                end
Ini файл существует, значение есть (принт выводит правильные значения), то же самое касается и массивов с именами и ID. Видимо проблема чисто в sampcreate... Текста не видно. Ошибок никаких нет, все работает (в плане того что скрипт не падает). Подскажите что я делаю не так, пожалуйста.
Второй вопрос не обязательный, но интересно, я в идентификатор текста могу любое число записать? Оно не будет конфликтовать с 3D текстом созданным сервером (менять/скрывать и т.д.)?

P.S. Лишь одна просьба - не указывать на недостаток с применением while вместо for если это не является прямой причиной моей проблемы. С for у меня определенные трудности возникают, ввиду недостаточных знаний конкретно этого языка, потому пока применяю while.
UPD: для наглядности приведу строчку из лога, в которой выведены все применяемые в функции переменные (и несколько контрольных переменных полученных другими путями). Для удобства непосредственно аргументы для команды в левой части, контрольные аргументы в правой.
Код:
if MembersIni ~= nil then
                Mem_Index = 0
                clNames, clIDs, clPeds = getClosestPlayersId()
            --    print(table.concat(clIDs))
                while true do
                    Mem_Index = Mem_Index + 1
                    if table.maxn (clNames) == Mem_Index then
                        --print("break")
                        break
                    end

                    if MembersIni.Require[clNames[Mem_Index]] ~= nil then
                        texID = 10000 + clIDs[Mem_Index]
                        texText = MembersIni.Require[clNames[Mem_Index]]
                        textCID = clIDs[Mem_Index]
                        tX, tY, tZ = getCharCoordinates(clPeds[Mem_Index])
                        res, dddid = sampGetPlayerIdByCharHandle(clPeds[Mem_Index])
                        print("Text ID:" .. texID .. "; text: " .. texText .. "; targetID: " .. textCID .. "; x:" .. tX .. "y: " .. tY .. "; z:" .. tZ .. "; ped:" .. clPeds[Mem_Index] .. "; idByPed:" .. dddid .. "")
                    --    print("" .. MembersIni.Require[clNames[Mem_Index]].. " [" .. clIDs[Mem_Index] .."]")
                        sampCreate3dTextEx(texID, texText, 0xFFFF0000, tX, tY, tZ, 5000, true, textCID)
                    end
                end
        end

Лог:
Код:
13:05:06.154515] (script)    Overlay.lua: Text ID:10509; text: Капитан; targetID: 509; x:89.009750366211y: 1934.052734375; z:17.927118301392; ped:5121; idByPed:509

trefa, спасибо за совет. Как только разберусь с вышеобозначенной проблемой я начну оптимизировать алгоритм по вашему совету.
 

Natami

Участник
377
26
Есть диалог, в котором написано:
ID Уровень Ник
И надо,чтобы из этого списка он отыскал меня и написал
sampAddChatMessage("Ваш уровень "..lvl.."!", -1)