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

Nishikinov

Известный
148
34
какие проверки юзать?


Спасибо помог) Теперь не крашит.
Я полного кода не видел, поэтому точно не скажу. Но помни, что какие-то условия могут не выполниться и лучше впихнуть лишний if then, чтобы скрипт не упал.
 

Licht

Известный
238
32
какие проверки юзать?


Спасибо помог) Теперь не крашит.
И старайся обращаться к логам почаще :)

string.gsub, если я не ошибаюсь.
Мож помочь? нужно в скрипт написать который будет выдавать розыск по нажатию клавиши типо: в меня стрельнули нажал допустим X и выдало розыск за вооруженное нападение, а например ударили выдало на нападение просто.
 

777qwerty777

Известный
62
18
И старайся обращаться к логам почаще :)


Мож помочь? нужно в скрипт написать который будет выдавать розыск по нажатию клавиши типо: в меня стрельнули нажал допустим X и выдало розыск за вооруженное нападение, а например ударили выдало на нападение просто.
Не проверял, но должно работать
Lua:
id, time, gun = 0, os.time(), 0
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
    while true do wait(0)
        if time <= os.time() then
            local result, ped = sampGetCharHandleBySampPlayerId(id)
            if result then
                local x1, y1, z1 = getCharCoordinates(ped)
                local x2, y2, z2 = getCharCoordinates(PLAYER_PED)
                if getDistanceBetweenCoords3d(x1, y1, z1, x2, y2, z2) <= 40 then
                    if not sampIsChatInputActive() and not sampIsDialogActive() and wasKeyPressed(88) then
                        if gun >= 24 and gun <= 33 then
                            sampSendChat("/su "..id.." 3 пиу пиу")
                        elseif gun == 0 then
                            sampSendChat("/su "..id.." 3 бац и мимо")
                        end
                    end
                end
            end
        end
    end
end
function sampev.onSendTakeDamage(playerId, damage, weapon, bodypart)
    if sampIsPlayerConnected(playerId) then
        id, time, gun = playerId, (os.time() + 15), weapon
    end
end
 

Licht

Известный
238
32
Lua:
function docs()           
wait(0)
sampSendChat("Вас беспокоит сотрудник правоохранительных органов (имя фамилия)")
wait(1500)
sampSendChat("предъявите документы, удостоверяющие вашу личность.")
end

Как сделать функцию чтоб писало где (Имя Фамилия) мой ник?
 

4el0ve4ik

Известный
Всефорумный модератор
1,548
1,338
И старайся обращаться к логам почаще :)


Мож помочь? нужно в скрипт написать который будет выдавать розыск по нажатию клавиши типо: в меня стрельнули нажал допустим X и выдало розыск за вооруженное нападение, а например ударили выдало на нападение просто.
хукаешь GiveTakeDamage, там есть ид игрока, который нанес тебе урон, ид оружия с которого его тебе нанесли. Дальше проверяешь ид оружия на огнестрел и выдаешь розыск за вооруженное, и с вторым случаем аналогично.
 

Lyonya Decart

Участник
140
22
Lua:
function main
if not isSampfuncsLoaded() or not isSampLoaded() then return end
while not isSampAvailable() do wait(0) end
    sampAddChatMessage('{756767}[Скрипт успешно загружен]{FF4500} Создатель: vk.com/decartfamily ', -1)
   


    waint(-1)
    end

function quest()
local x,y,z = getCha Coordinates(player Ped)
local dist = getDistCoord2d(x,y,z,xx,yy,zz)
if dist < 1.0 then
    sampSendDialogRespond
    setVirtualKeyState
end
Скрипт не загружается в игру. И помогите сделать так, чтобы при подходе к квестовому персу на аризоне. Бот брал квест. А еще автоматическую активацию всех функций в скрипте.
 

Licht

Известный
238
32
Как я люблю луа тем, что можно функции в функции вкладывать.
Lua:
sampSendChat("Вас беспокоит сотрудник правоохранительных органов "..sampGetPlayerNickname(select(2, sampGetPlayerIdByCharHandle(PLAYER_PED))):gsub("_", " "))
А как взять ник ближайшего игрока?
:help:
[TBODY] [/TBODY]

:help:
[TBODY] [/TBODY]

:help:
[TBODY] [/TBODY]
 
Последнее редактирование:

Harryss

Участник
233
26
Каким образом можно делать записи в реестр на Lua? Существует ли какой-то пример? Хочу найти замену .ini файлу.
 

mrdiimax

Известный
566
79
При входе в игру автоматически крашит, версию саму ПРОВЕРЯЕТ, но дальше при открытии окна имгуи крашит, небо не успевает прогружаться - игра намертво зависает.

Проверка версии
Lua:
function update() -- проверка обновлений
    local zapros = https.request("https://gitlab.com/ThisCold/arx-helpers/raw/master/update.json")

    if zapros ~= nil then
        local info2 = decodeJson(zapros)

        if info2.latest_number ~= nil and info2.latest ~= nil and info2.drop ~= nil then
            updatever = info2.latest
            version = tonumber(info2.latest_number)
            dropver = tonumber(info2.drop)

            print("[Update] Начинаем контроль версий")

            if tonumber(thisScript().version_num) <= dropver then
                print("[Update] Used non supported version: "..thisScript().version_num..", actual: "..version)
                sampAddChatMessage("[Arx]{FFFFFF} Ваша версия более не поддерживается разработчиком, работа скрипта невозможна.", 0x046D63)
                reloadScript = true
                thisScript():unload()
            elseif version > tonumber(thisScript().version_num) then
                print("[Update] Обнаружено обновление")
                sampAddChatMessage("[Arx-Helper]{FFFFFF} Обнаружено обновление до версии "..updatever..".", 0x046D63)
                active_update.v = true
                UpdateNahuy = true
            else
                print("[Update] Новых обновлений нет, контроль версий пройден")
                if checkupd then
                    sampAddChatMessage("[Arx]{FFFFFF} У вас стоит актуальная версия скрипта: "..thisScript().version..".", 0x046D63)
                    sampAddChatMessage("[Arx]{FFFFFF} Необходимости обновлять скрипт - нет, приятного пользования.", 0x046D63)
                    checkupd = false
                end
                UpdateNahuy = true
            end
        else
            sampAddChatMessage("[Arx]{FFFFFF} Ошибка при получении информации об обновлении.", 0x046D63)
            print("[Update] JSON file read error")
            UpdateNahuy = true
        end
    else
        sampAddChatMessage("[Arx]{FFFFFF} Не удалось проверить наличие обновлений, попробуйте позже.", 0x046D63)
        UpdateNahuy = true
    end
end


Она вроде как работает нормально ..
И функция из-за которой предполагаемый краш:
Имгуи:
Lua:
if active_update.v then -- окно обновления скрипта
        local sw, sh = getScreenResolution()
        imgui.SetNextWindowPos(imgui.ImVec2(sw/2, sh/2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
                imgui.SetNextWindowSize(imgui.ImVec2(450, 200), imgui.Cond.FirstUseEver)
                imgui.Begin(u8('Обновление'), nil, imgui.WindowFlags.NoResize)
        imgui.Text(u8'Обнаружено обновление до версии: '..updatever)
        imgui.Separator()
        imgui.TextWrapped(u8("Для установки обновления необходимо подтверждение пользователя, разработчик настоятельно рекомендует принимать обновления ввиду того, что прошлые версии через определенное время отключаются и более не работают."))
        if imgui.Button(u8'Скачать и установить обновление', btn_size) then
            async_http_request('GET', 'https://gitlab.com/ThisCold/arx-helpers/raw/master/ARX-Helper_v0_1b.luac', nil,
                function(response) -- вызовется при успешном выполнении и получении ответа
                local f = assert(io.open(getWorkingDirectory() .. '/ARX-Helper_v0_1b.luac', 'wb'))
                f:write(response.text)
                f:close()
                sampAddChatMessage("[Arx-Helper]{FFFFFF} Обновление успешно, перезагружаем скрипт.", 0x046D63)
                thisScript():reload()
            end,
            function(err) -- вызовется при ошибке, err - текст ошибки. эту функцию можно не указывать
                print(err)
                sampAddChatMessage("[Arx-Helper]{FFFFFF} Произошла ошибка при обновлении, попробуйте позже.", 0x046D63)
                active_update.v = not active_update.v
                return
            end)
        end
        if imgui.Button(u8'Закрыть', btn_size) then active_update.v = not active_update.v end
        imgui.End()
    end
 

Licht

Известный
238
32
Lua:
if active_update.v then -- окно обновления скрипта
        local sw, sh = getScreenResolution()
        imgui.SetNextWindowPos(imgui.ImVec2(sw/2, sh/2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
                imgui.SetNextWindowSize(imgui.ImVec2(450, 200), imgui.Cond.FirstUseEver)
                imgui.Begin(u8('Обновление'), nil, imgui.WindowFlags.NoResize)
        imgui.Text(u8'Обнаружено обновление до версии: '..updatever)
        imgui.Separator()
        imgui.TextWrapped(u8("Для установки обновления необходимо подтверждение пользователя, разработчик настоятельно рекомендует принимать обновления ввиду того, что прошлые версии через определенное время отключаются и более не работают."))
        if imgui.Button(u8'Скачать и установить обновление', btn_size) then
            async_http_request('GET', 'https://gitlab.com/ThisCold/arx-helpers/raw/master/ARX-Helper_v0_1b.luac', nil,
                function(response) -- вызовется при успешном выполнении и получении ответа
                local f = assert(io.open(getWorkingDirectory() .. '/ARX-Helper_v0_1b.luac', 'wb'))
                f:write(response.text)
                f:close()
                sampAddChatMessage("[Arx-Helper]{FFFFFF} Обновление успешно, перезагружаем скрипт.", 0x046D63)
                thisScript():reload()
            end,
            function(err) -- вызовется при ошибке, err - текст ошибки. эту функцию можно не указывать
                print(err)
                sampAddChatMessage("[Arx-Helper]{FFFFFF} Произошла ошибка при обновлении, попробуйте позже.", 0x046D63)
                active_update.v = not active_update.v
                return
            end)
        end
        if imgui.Button(u8'Закрыть', btn_size) then active_update.v = not active_update.v end
        imgui.End()
    end

Разъясните что как и где.. мне такая штука нужна (чекать обновы моих скриптов которые я пишу и при появлении обновы чтоб он загружал её и тд, можно без imgui)
 

Shamanhcik

Известный
33
7
Каким образом можно сделать дополнительные анимации, с активацией и деактивацией?