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

Макс | Lycorn

Участник
156
13
дай код этого окна
Lua:
imgui.BeginChild('##bindertext', imgui.ImVec2(620, 387), true)
            imgui.Text(u8'Введите команду:')
            imgui.SameLine()
            imgui.PushItemWidth(150)
            imgui.InputText(u8'##bindercmd', bindersettings.commands.bindercmd1)
            imgui.PopItemWidth()
            imgui.Text(u8'Введите кнопку:')
            imgui.SameLine()
            imgui.PushItemWidth(150)
            imgui.InputText(u8'##binderhotkey', bindersettings.hotkeys.binderhotkey1)
            imgui.PopItemWidth()
            imgui.Text(u8'Введите задержку в секундах')
            imgui.SameLine()
            imgui.PushItemWidth(150)
            imgui.InputInt(u8'##binderdelay', bindersettings.delay.binderdelay1)
            imgui.PopItemWidth()
            imgui.BeginChild('##textbinder', imgui.ImVec2(605,30), true)
            imgui.CenterText(u8'Введите текст')
            imgui.EndChild()
            imgui.InputTextMultiline(u8"##", bindersettings.text.bindertext1, imgui.ImVec2(605,265))
            imgui.EndChild()
 

why ega

РП игрок
Модератор
2,547
2,238
Здравствуйте, как можно сделать проверку на то, находится ли игрок на определённых координатах? (Независимо от координат по высоте, Z)
Lua:
local tx, ty = 300, 400


-- в бесконечном цикле
if (getDistanceBetweenCoords2d(tx, ty, getCharCoordinates(PLAYER_PED)) < 1) then
    print("Ээ, браток, наша остановочка")
end
Есть такой хук:
INCOMING_RPCS[RPC.SERVERJOIN] = {'onPlayerJoin', {playerId = 'uint16'}, {color = 'int32'}, {isNpc = 'bool8'}, {nickname = 'string8'}}
Но он, если не ошибаюсь, срабатывает ещё до авторизации.
Лучше использовать хук входящего пакета PACKET_CONNECTION_REQUEST_ACCEPTED[ID: 34], т.к. SERVERJOIN срабатывает вроде тогда, когда ты пробуешь подключиться на сервер, а не когда ты подключился.
 

tyukapa

Активный
298
65
Lua:
local tx, ty = 300, 400


-- в бесконечном цикле
if (getDistanceBetweenCoords2d(tx, ty, getCharCoordinates(PLAYER_PED)) < 1) then
    print("Ээ, браток, наша остановочка")
end

Лучше использовать хук входящего пакета PACKET_CONNECTION_REQUEST_ACCEPTED[ID: 34], т.к. SERVERJOIN срабатывает вроде тогда, когда ты пробуешь подключиться на сервер, а не когда ты подключился.
Спасибо, но как я уже выше написал есть прикол что работает как переключатель, я нажимаю на чекбокс, скрипт бежит на координату 1, и всё, отдыхает. При выключении чекбокса скрипт бежит на 2 координату
 
  • Вау
Реакции: why ega

Revavi

Участник
101
24
не совсем понял
то есть просто проверять sampIsLocalPlayerSpawned()?
1. true connect о том что зашел на коннектов сервера.
2. Если успешно авторизован и прочее херни, то ищем положительное connect и спавн педа (sampIsLocalPlayerSpawned())
3. Если заспавнен, то connect false, прописываем /stats.
*. Если вдруг отсоединится снова - то connect ставить true и переходим на 2.

а 34 пакет и 25 рпс это одно и то же? просто они одновременно отправляются
если есть разница, то какая?
 
Последнее редактирование:

Sadow

Известный
1,439
588
Как получить текст который ввёл игрок в поле ввода в диалоге, без использования samp events?
 

why ega

РП игрок
Модератор
2,547
2,238

а 34 пакет и 25 рпс это одно и то же? просто они одновременно отправляются
если есть разница, то какая?
Если правильно помню, 25 рпц отправляется тобой в том случае, когда ты пробуешь подключиться, а 34 пакет, когда сервер уже одобрил твое подключение

не совсем понял
то есть просто проверять sampIsLocalPlayerSpawned()?
Да, эта функция проверяет, заспавнен или нет, локальный игрок (ты). Но она зависит от сампфункса и вроде бы плохо работает на р3

Как получить текст который ввёл игрок в поле ввода в диалоге, без использования samp events?
Lua:
function onSendRpc(id, bs, priority, reliability, orderingChannel, shiftTs)
    if (id == 62) then
        local dialogId = raknetBitStreamReadInt16(bs)
        local button = raknetBitStreamReadInt8(bs)
        local listboxId = raknetBitStreamReadInt16(bs)
        local input = raknetBitStreamReadString(bs, raknetBitStreamReadInt8(bs))
        print("Текст:", input)
    end
end

кто может убрать команду и поставить на кнопку сбив?
Lua:
local hitler = false


function main()
    while not isSampAvailable() do wait(0) end
    while true do wait(0)
        if hitler then
            taskPlayAnim(PLAYER_PED, "Pointup_loop", "ON_LOOKERS", 12, true, false, false, false, -1)          
        end    
    end
end


addEventHandler("onWindowMessage", function(msg, wparam)
    if not isPauseMenuActive() then
        if (msg == 0x100) or (msg == 0x101) then
            if (wparam == 113) then
                consumeWindowMessage(true, false)
                if (msg == 0x101) then
                    hitler = not hitler
                end
            elseif (wparam == 46) and not sampIsCursorActive() then
                consumeWindowMessage(true, false)
                if (msg == 0x101) then
                    hitler = false
                    clearCharTasks(PLAYER_PED)
                end              
            end
        end
    end
end)
 
Последнее редактирование:

tyukapa

Активный
298
65
Как в чекбоксе сделать цикл с проверкой?

Lua:
            if imgui.Checkbox(u8'test', test) then
                runToPoint:run(2480, -1668)
                local tx, ty = 2480, -1668
                if (getDistanceBetweenCoords2d(tx, ty, getCharCoordinates(PLAYER_PED)) < 1) then
                    runToPoint:run(2452, -1667)
                end
            end
 

why ega

РП игрок
Модератор
2,547
2,238
Как в чекбоксе сделать цикл с проверкой?

Lua:
            if imgui.Checkbox(u8'test', test) then
                runToPoint:run(2480, -1668)
                local tx, ty = 2480, -1668
                if (getDistanceBetweenCoords2d(tx, ty, getCharCoordinates(PLAYER_PED)) < 1) then
                    runToPoint:run(2452, -1667)
                end
            end
можно так, но я подозреваю, что в твоем случае лучше использовать другое
Lua:
if imgui.Checkbox(u8'test', test) then
    lua_thread.create(function()
        local rand = 0
        while (rand ~= 4) do
            rand = math.random(0, 10)
        end
        print("end")
    )
end
 
  • Нравится
Реакции: tyukapa

XRLM

Известный
2,540
859
Как получить текст который ввёл игрок в поле ввода в диалоге, без использования samp events?
хук onSendDialogResponse

можно так, но я подозреваю, что в твоем случае лучше использовать другое
Lua:
if imgui.Checkbox(u8'test', test) then
    lua_thread.create(function()
        local rand = 0
        while (rand ~= 4) do
            rand = math.random(0, 10)
        end
        print("end")
    )
end
вроде как создавать треад не обязательно во фрейме
 
  • Вау
Реакции: why ega

ChromiusJ

PARΛDIGM ΛSS
Друг
4,907
3,196
как получить смещение от координат на функции getCharCoordinates()?
возможно долбаебский вопрос,допустим если X отклонилась на 1 координату,то вызвался бы там синий экран смерти,или просто написало,что отклонилось на 1 координату
 

XRLM

Известный
2,540
859
как получить смещение от координат на функции getCharCoordinates()?
возможно долбаебский вопрос,допустим если X отклонилась на 1 координату,то вызвался бы там синий экран смерти,или просто написало,что отклонилось на 1 координату
типо расстояние от первой точки до точки смещения или прям сколько сместилось по x, по y, по z?
 

why ega

РП игрок
Модератор
2,547
2,238
как получить смещение от координат на функции getCharCoordinates()?
возможно долбаебский вопрос,допустим если X отклонилась на 1 координату,то вызвался бы там синий экран смерти,или просто написало,что отклонилось на 1 координату