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

checkdasound

Известный
Проверенный
963
411
Lua:
count = 0

function ot()
    count = count + 1
    --твой код
end

function count()
    sampAddChatMessage(count, -1)
end


Секунды всеровно летят как бешенные, т.е. поток вообще не реагирует на эту задержку wait(1000)
Lua:
if not isGamePaused() and ini.settings.playTimeCheck then
    lua_thread.create(function()
        wait(1000)
        seconds = seconds + 1
        seconds1 = seconds1 + 1
        if seconds == 60 and ini.settings.minutes then
            ini.settings.minutes = ini.settings.minutes + 1
            minutes = minutes + 1
            seconds1 = 0
            seconds = 0
            inicfg.save(ini, 'fds')
        end
        if ini.settings.minutes == 60 then
            ini.settings.hours = ini.settings.hours + 1
            hours = hours + 1
            minutes = 0
            ini.settings.minutes = 0
            inicfg.save(ini, 'fsd')
        end
    end)
end
 

Patrickkk

Участник
162
19
Lua:
if not isGamePaused() and ini.settings.playTimeCheck then
    lua_thread.create(function()
        wait(1000)
        seconds = seconds + 1
        seconds1 = seconds1 + 1
        if seconds == 60 and ini.settings.minutes then
            ini.settings.minutes = ini.settings.minutes + 1
            minutes = minutes + 1
            seconds1 = 0
            seconds = 0
            inicfg.save(ini, 'fds')
        end
        if ini.settings.minutes == 60 then
            ini.settings.hours = ini.settings.hours + 1
            hours = hours + 1
            minutes = 0
            ini.settings.minutes = 0
            inicfg.save(ini, 'fsd')
        end
    end)
end
Аналогичная ситуация. С чем это связано вообще?
 

#Northn

Pears Project — уже запущен!
Всефорумный модератор
2,651
2,550
засунул код в lua_thread.create, теперь эта секунда заддержки которая там есть выполняется в 100 раз быстрее, и время со скоростью света считает.
Lua:
lua_thread.create(function(time)
        if not isGamePaused() and ini.settings.playTimeCheck then
            wait(1000)
            seconds = seconds + 1
                seconds1 = seconds1 + 1
            if seconds == 60 and ini.settings.minutes then
                ini.settings.minutes = ini.settings.minutes + 1
                    minutes = minutes + 1
                    seconds1 = 0
                seconds = 0
                inicfg.save(ini, 'fds')
            end
            if ini.settings.minutes == 60 then
                ini.settings.hours = ini.settings.hours + 1
                    hours = hours + 1
                    minutes = 0
                ini.settings.minutes = 0
                inicfg.save(ini, 'fsd')
            end
        end
end, time)
Lua:
function main()
  lua_thread.create(function()
    while true do wait(0)
      --тот самый кусок кода, который нужно отдельно делать
    end
  end)
  while true do wait(0)
    -- другой шлак
  end
end
 

Adventurer

Известный
151
69
А затем?
if ... then
main_window_state.v = not main_window_state.v
end
?

Как сделать чтобы при нажатии кнопки в окне imgui открывалось следующее окно.
И да, как сделать поддержку кириллицы или же это невозможно?
Lua:
    sampRegisterChatCommand("imgui", function() -- можно и убрать funciton() отсюда
    window.v = not window.v
    end)


Кириллицу сделать никак. Есть вариант такой: сохранять скрипт в кодировкe cirillyc1251 (chcp1251 / windows1251), а в скрипте использовать кодировку UTF8
Lua:
encoding.default = 'CP1251'
u8 = encoding.UTF8 
--эти строчки в начало скрипта. Использование:
imgui.Text(u8'Что, шуток не понимаешь, да?')


Открытие нового Imgui - окна по нажатию кнопкии
Lua:
if imgui.Button(u8'русская кодировка, новое окно') then second_window.v = not second_window.v end
 
  • Нравится
Реакции: biscuitt

IZDATXXX

Известный
Проверенный
172
253
Этот код:
Lua:
local vector_distance = 0.0
local vector_distance_minimal = 0.0
local vector_distance_minimal_bool = false
vector_distance = getDistanceBetweenCoords3d(cam_x, cam_y, cam_z, ped_x, ped_y, ped_z)
if (vector_distance_minimal == 0.0) or (vector_distance <= vector_distance_minimal) then
    vector_distance_minimal_bool = true
end
выдаёт в moonloader.log следующее в строке с условием:
Код:
attempt to compare nil with number
как это исправить?
 

ШPEK

Известный
1,474
526
Как отключить пикап???
function ev.onSendPickedUpPickup()
return false
end
не работает
 

Musaigen

dead eyes
Проверенный
1,665
1,485
Этот код:
Lua:
local vector_distance = 0.0
local vector_distance_minimal = 0.0
local vector_distance_minimal_bool = false
vector_distance = getDistanceBetweenCoords3d(cam_x, cam_y, cam_z, ped_x, ped_y, ped_z)
if (vector_distance_minimal == 0.0) or (vector_distance <= vector_distance_minimal) then
    vector_distance_minimal_bool = true
end
выдаёт в moonloader.log следующее в строке с условием:
Код:
attempt to compare nil with number
как это исправить?
Ты пытаешься сравнить ничего с числом. Проверь через print что хранят в себе переменные.
 
  • Нравится
Реакции: IZDATXXX

Petr_Sergeevich

Известный
Проверенный
707
298
Lua:
local isFlag = false

function sampev.onServerMessage(color, message)
    if message:find("1") then
        isFlag = true
        while isFlag do
            -- секундомер
        end
    end

    if message:find("Конец для 1") then
        isFlag = false
        print(время, которое истекло с момента запуска)
    end
end

Например, в чат с разным промежутком времени отправляются рандомные числа. После того, как мы находим число, запускается секундомер (отдельный для каждого числа) и работать он должен до тех пор, пока в чате снова не появится надпись "конец для числа N". Выше небольшой набросок того, как у меня реализовано сейчас, но это работает только для одного последнего сообщения, с помощью флага.

Как сделать так, чтобы сообщения выводились для всех завершенных чисел, независимо от флага?
 

Adventurer

Известный
151
69
Как сделать секундомер* ака "Время работы скрипта"?
Lua:
kek = 0 while true do kek = kek + 1 wait(1000) end
хз конечно, может это лучше, может хуже, но можно делать и так:

Lua:
startfrom = os.clock() -- вне цикла
imgui.Text(u8(string.format('Последнее онбовление информации: %d сек. назад.', os.clock("%H:%S:%M") - startfrom))) -- в цикле
 
  • Нравится
Реакции: inf