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

Luis_Mora

Участник
31
1
Привет. telegram
Есть такая штука как телеграм контрол самп. https://www.blast.hk/threads/62811
Интересует вопрос. Можно ли как то отлавливать сообщения НЕ от пользователей.
Т.е. меня интересует непосредственно отловить сообщение которое туда отправляет сам бот.
Я по определённой команде отправляю сообщение в канал в телеграме, от лица бота.
Если допустим человек в этом же канале пишет /send вывпвып, то всем у кого настроен данный скрипт, соответственно придёт в чат "вывпвып"
Мне нужно чтобы бот, при такой отправке, сам же смог отловить условно эту же команду. Т.е. посылаем в канал через команду /test сообщение /send sdfsdf от лица бота, и сам же бот его принимает и выполняет.
Может кто знает как это сделать можно.
 

Tak

Известный
176
70
Аризона лаунчер и onSetMapIcon
Если использовать библиотеку для обработки сетевых пакетов SAMP.Lua.
И пытаться получить TYPE (с помощью onSetMapIcon) иконок с карты на ArizonaRP (лаунчер), то будут несоответствующие типы указанным здесь: Сайт с иконками
(Как же всё-таки найти эти неизвестные иконки?)
Решение: лезем в hud.txd файл игры лаунчера и находим там иконки с 64 по 127 ID, это как раз те неизвестные иконки
Вот и всё =)

(спрашивал об этой проблеме здесь, но нашел решение позже сам)
сам спросил сам ответил
 
Последнее редактирование:

The Spark

Известный
653
671
Я так понимаю, у тебя что-то на подобии кликера, где баланс доходит до гигантских чисел. В таких играх никто не использует целые числа, а используют абстракции, например:

Числа 0-999 будем записывать в виде целого, без постфикса, числа 1000-999999 в виде "1-999K", 1000000-999999999 "1-999М" и тд. И того в конфиге сохраняется значение не более 10 тысяч. ("99.833М" - 99.833.000. От точности мы отказываемся по мере возрастания числа)
Проблему с конфигом решили, а как в коде обрабатывать?

В коде ты также должен приводить все операции с этим числом в упрощенный тип. Например:
Хотим прибавить 99.831М + 1К. Получаем 99.832М. Если нужно будет прибавить 500, то тут проблема, ведь точности нет. Скорее всего такие малые суммы уже прибавлять будет не нужно, а если и нужно, то веди отдельное число точности, к которому будут прибавляться маленькие числа.
При использовании 64 битных чисел, через ffi.new, или 1ULL через компиляцию luaJIT тебе придется пилить сложные математические преобразования, что точно не нужно
 
  • Нравится
Реакции: why ega

sosnov

Известный
331
115
как сделать так чтоб плеер пед не падал с велика?
Lua:
SetCharCanBeKnockedOffBike(PLAYER_PED, false)
эта строка не работает,надо либо ее менять,либо другую ставить
 

why ega

РП игрок
Модератор
2,540
2,229
мне нужно вызвать у bs метод, который хранится в переменной, пробовал делать через ключ - крашит скрипт. Решил попробовать сделать это через load(), но она загружают в локальную область, как я понимаю, из-за чего она не видит bs. как можно реализовать вызов метода через строку?
Lua:
local bs = RakLuaBitStream.new()

bs[("write%s"):format(data[1])](data[2][0]) -- ошибка: received nil for 'self' argument (use ':' for accessing member functions, make sure member variables are preceeded by the actual object with '.' syntax)

load(("bs:write%s(data[2][0])"):format(data[1]))() -- 2 варик, не видит bs

как сделать так чтоб плеер пед не падал с велика?
Lua:
SetCharCanBeKnockedOffBike(PLAYER_PED, false)
эта строка не работает,надо либо ее менять,либо другую ставить
setCharCanBeKnockedOffBike(PLAYER_PED, false)
 

Leon_Trotsky

Участник
39
2
Что за ошибка может быть?

Код:
[ML] (error) AdminTools: C:\Users\marke\Desktop\Ìîÿ ñáîðêà\moonloader\ATools.lua:10798: attempt to call global 'update' (a boolean value)
stack traceback:
    C:\Users\marke\Desktop\Ìîÿ ñáîðêà\moonloader\ATools.lua:10798: in function <C:\Users\marke\Desktop\Ìîÿ ñáîðêà\moonloader\ATools.lua:10797>
[ML] (error) AdminTools: Script died due to an error. (16DBD5A4)

Первый раз функция отрабатывает нормально, во второй умирает скрипт

Lua:
    sampRegisterChatCommand("upd", function()
        update()
    end)

update:
function update()
    local fpath = os.getenv('TEMP') .. '\\Admin Tools.json' -- куда будет качаться наш файл для сравнения версии
    downloadUrlToFile('https://pastebin.com/raw/bgkgsSy5', fpath, function(id, status, p1, p2) -- ссылку на ваш гитхаб где есть строчки которые я ввёл в теме или любой другой сайт
      if status == dlstatus.STATUS_ENDDOWNLOADDATA then
      local f = io.open(fpath, 'r') -- открывает файл
      if f then
        local info = decodeJson(f:read('*a')) -- читает
        updatelink = info.updateurl
        if info and info.latest then
          version = tonumber(info.latest) -- переводит версию в число
        if version > tonumber(thisScript().version) then -- если версия больше чем версия установленная то...
            lua_thread.create(goupdate)
        else -- если меньше, то
            update = false
            lua_thread.create(nonupdate)
        end
        end
      end
    end
  end)
end
  --------------------------------------------[[UPDATE 2]]-------------------------------------------------
function goupdate()
    mod.addNotification('Начинаю загрузку обновления.\n{ffa500}Ожидайте', 5)
    wait(300)
    downloadUrlToFile(updatelink, thisScript().path, function(id3, status1, p13, p23) -- качает ваш файлик с latest version
    if status1 == dlstatus.STATUS_ENDDOWNLOADDATA then
        thisScript():reload()
    end
  end)
end

function nonupdate()
    sampAddChatMessage('{ffa500}Admin Tools {FFFFFF}| Версия скрипта актуальна', -1)
end
 

imring

Ride the Lightning
Всефорумный модератор
2,355
2,516
Что за ошибка может быть?

Код:
[ML] (error) AdminTools: C:\Users\marke\Desktop\Ìîÿ ñáîðêà\moonloader\ATools.lua:10798: attempt to call global 'update' (a boolean value)
stack traceback:
    C:\Users\marke\Desktop\Ìîÿ ñáîðêà\moonloader\ATools.lua:10798: in function <C:\Users\marke\Desktop\Ìîÿ ñáîðêà\moonloader\ATools.lua:10797>
[ML] (error) AdminTools: Script died due to an error. (16DBD5A4)

Первый раз функция отрабатывает нормально, во второй умирает скрипт

Lua:
    sampRegisterChatCommand("upd", function()
        update()
    end)

update:
function update()
    local fpath = os.getenv('TEMP') .. '\\Admin Tools.json' -- куда будет качаться наш файл для сравнения версии
    downloadUrlToFile('https://pastebin.com/raw/bgkgsSy5', fpath, function(id, status, p1, p2) -- ссылку на ваш гитхаб где есть строчки которые я ввёл в теме или любой другой сайт
      if status == dlstatus.STATUS_ENDDOWNLOADDATA then
      local f = io.open(fpath, 'r') -- открывает файл
      if f then
        local info = decodeJson(f:read('*a')) -- читает
        updatelink = info.updateurl
        if info and info.latest then
          version = tonumber(info.latest) -- переводит версию в число
        if version > tonumber(thisScript().version) then -- если версия больше чем версия установленная то...
            lua_thread.create(goupdate)
        else -- если меньше, то
            update = false
            lua_thread.create(nonupdate)
        end
        end
      end
    end
  end)
end
  --------------------------------------------[[UPDATE 2]]-------------------------------------------------
function goupdate()
    mod.addNotification('Начинаю загрузку обновления.\n{ffa500}Ожидайте', 5)
    wait(300)
    downloadUrlToFile(updatelink, thisScript().path, function(id3, status1, p13, p23) -- качает ваш файлик с latest version
    if status1 == dlstatus.STATUS_ENDDOWNLOADDATA then
        thisScript():reload()
    end
  end)
end

function nonupdate()
    sampAddChatMessage('{ffa500}Admin Tools {FFFFFF}| Версия скрипта актуальна', -1)
end
update стала состоянием после вызова update(). смотри 14 строку, где update = false
 
  • Нравится
Реакции: Leon_Trotsky

yung milonov

Известный
974
476
мне нужно вызвать у bs метод, который хранится в переменной, пробовал делать через ключ - крашит скрипт. Решил попробовать сделать это через load(), но она загружают в локальную область, как я понимаю, из-за чего она не видит bs. как можно реализовать вызов метода через строку?
Lua:
local bs = RakLuaBitStream.new()

bs[("write%s"):format(data[1])](data[2][0]) -- ошибка: received nil for 'self' argument (use ':' for accessing member functions, make sure member variables are preceeded by the actual object with '.' syntax)

load(("bs:write%s(data[2][0])"):format(data[1]))() -- 2 варик, не видит bs
с loadstring пробовал?