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

Bogach

Активный
558
27
Всем привет, пришел к вам за советом.
Вот по этому коду
Lua:
while true do
        wait(0)
          if sampIsChatInputActive() then
               if flagchat then
                     local Data = inicfg.load(Data, "configacc.ini")
                         local Accent = Data.settings.Accent
                         sampSetChatInputText(string.format("[%s]:",Accent))
                         flagchat = false
                 end
            end
            if not sampIsChatInputActive() then
                 if flagchat == false then
                        flagchat = true
                 end
            end
        end
end
Такой код нормальный или можно сделать проще?
 

Bogach

Активный
558
27
Расскажи, что должен делать этот код
Я думал и так понятно, ну ладно, в общем, при открытии чата в чате должен появляться акцент ( например [Американский акцент]: )
А после закрытия чата переменная flagchat должна приравнятся к "true". Собственно код работоспособен, просто интересно есть ли вариант получше, может можно как - то проще сделать?
 

Dark_Knight

Me, me and me.
Друг
4,078
2,095
Я думал и так понятно, ну ладно, в общем, при открытии чата в чате должен появляться акцент ( например [Американский акцент]: )
А после закрытия чата переменная flagchat должна приравнятся к "true". Собственно код работоспособен, просто интересно есть ли вариант получше, может можно как - то проще сделать?
Если тебе надо добавлять только текст, то через хуки делай. Одной булевой переменной проверяешь нужно ли отправлять хватит с головой.
 
Последнее редактирование:

FYP

Известный
Автор темы
Администратор
1,763
5,906
@Robert Daniels while true do должен быть внутри функции main и там же должна быть проверка на загруженность сампа.
Lua:
local _, myid = sampGetPlayerIdByCharHandle(PLAYER_PED)
if not sampIsPlayerPaused(myid) then
этот фрагмент бессмысленен, sampIsPlayerPaused применим только к другим игрокам.
и вообще твой код в целом - это какой-то пиздец.
Я думал и так понятно, ну ладно, в общем, при открытии чата в чате должен появляться акцент ( например [Американский акцент]: )
А после закрытия чата переменная flagchat должна приравнятся к "true". Собственно код работоспособен, просто интересно есть ли вариант получше, может можно как - то проще сделать?
Lua:
while true do
  wait(0)
  if sampIsChatInputActive() then
    if not flagchat then
     local Data = inicfg.load(Data, "configacc.ini")
     local Accent = Data.settings.Accent
     sampSetChatInputText(string.format("[%s]:",Accent))
     flagchat = true
    end
  elseif flagchat then
    flagchat = false
  end
end
 

Robert Daniels

Известный
12
0
Сенсей @FYP
Да, код у меня не идеальный, но пока что я не знаю .LUA на 100%, поэтому пытаюсь так.

while true do, находится в function main(), только намноооооого ниже.
Собственно, вот она.
Lua:
function main()
  while not isSampAvailable() do
    wait(1000)
  end
Ниже него у меня грузится конфиг и всё что мне нужно. Далее объявление различных команд и там уже идёт while true do.
Попробую показать на скриншотах.

wuDnaXM.png

HktRlnm.png

bhhGzPE.png

Опять же, убираю это:

Lua:
local _, myid = sampGetPlayerIdByCharHandle(PLAYER_PED)
if not sampIsPlayerPaused(myid) then
и скрипт просто не отвечает...
 
Последнее редактирование:

Moonlight_Ru

Известный
66
21
После того, как ФИП поведал мне о существовании потоков и я научился их юзать, использую их везде, по несколько штук на скрипт, удобно это :)
Стоит ли так делать или лучше в main весь код засунуть? На что может повлиять использование множества потоков в одном скрипте?
Есть ли какой-то ещё способ запускать выполнение отдельного куска кода из другой части этого кода?

И ещё похожий вопрос: Есть ли способ в Lua как-то перескочить на определённое кол-во строк выше или ниже (примерно как с помощью jump в клео)?
Вот например я создал обычный диалог (DIALOG_STYLE_LIST), в нём создал элемент списка, который открывает другой диалог, а в этом диалоге есть две кнопки > "Назад" и "Закрыть", кнопка закрыть завершает поток, прекращая тем самым работу с диалогами, а при нажатии кнопки "Назад" я хочу сделать, чтобы снова открывался первый диалог, при этом мне нужно сделать такое ветвление более одного раза, то есть чтобы из диалога 1 открывался диалог 2, из диалога 2 - диалог 3, из диалога 3 и 2 можно было попасть кнопкой "Назад" в диалог 2 и 1 соответственно. Возможно ли такое реализовать и если возможно, то подскажите как?
 

4el0ve4ik

Известный
Всефорумный модератор
1,550
1,343
Как можно пройтись по всем цветам, что бы один плавно менялся на другой?
 

Moonlight_Ru

Известный
66
21
Как можно пройтись по всем цветам, что бы один плавно менялся на другой?
Говнокод, конечно, но с задачей справляется, хотя я не уверен, что это то, что ты просил. Попробуй короче.

Lua:
function main()
    while not isSampAvailable() do wait(0) end
    while true do
            color = 0xFF0000FF
            while color < 0xFF00FFFF do
                    color = color + 0x100 -- 0xFF00FFFF
                    renderDrawBox(30, 300, 50, 50, color)
                    wait(0)
            end
            while color > 0xFF00FF00  do
                color = color - 0x1 -- 0xFF00FF00
                renderDrawBox(30, 300, 50, 50, color)
                wait(0)
            end
            while color < 0xFFFFFF00 do
                color = color + 0x10000 -- 0xFFFFFF00
                renderDrawBox(30, 300, 50, 50, color)
                wait(0)
            end
            while color > 0xFFFF0000 do
                color = color - 0x100 -- 0xFFFF0000
                renderDrawBox(30, 300, 50, 50, color)
                wait(0)
            end
            while color < 0xFFFF00FF do
                color = color + 0x1 -- 0xFFFF00FF
                renderDrawBox(30, 300, 50, 50, color)
                wait(0)
            end
            while color > 0xFF0000FF do
                color = color - 0x10000 -- 0xFF0000FF
                renderDrawBox(30, 300, 50, 50, color)
                wait(0)
            end
        end
end
 
  • Нравится
Реакции: 4el0ve4ik

FYP

Известный
Автор темы
Администратор
1,763
5,906
Стоит ли так делать или лучше в main весь код засунуть? На что может повлиять использование множества потоков в одном скрипте?
Есть ли какой-то ещё способ запускать выполнение отдельного куска кода из другой части этого кода?
потоки не обязательно использовать без необходимости, потоки нужны лишь для (псевдо)параллельного выполнения, т.е. для использования отдельных таймеров (wait) в разных функциях. в остальных случаях используй обычные функции - это и есть стандартный способ "запускать выполнение отдельного куска кода из другой части этого кода". но тем не менее, потоки не добавляют сильную нагрузку, так что можно не опасаться насчёт производительности.
Есть ли способ в Lua как-то перескочить на определённое кол-во строк выше или ниже (примерно как с помощью jump в клео)?
в луа есть goto - это то же самое, что и jump в клео. только используй его с умом.
 
  • Нравится
Реакции: Moonlight_Ru