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

dmitri4

Известный
452
79
как можно получить время МСК, пробовал воспользоваться https://blast.hk/threads/13380/page-2#post-212153
но при значении 0 оно тупо показывается твое время а если поменять на любую цифру то к твоему времени прибавляет данное число но время с сервера не получает
 

madrasso

Потрачен
883
325
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Как лучше сделать? чтоб просто вносил ник в таблицу, а само добавляло онлайн и оффлайн и выводило в диалог?


Lua:
function checkFriend()
    local friends = {
        ['Misha_Marcello'] = true,
        ['Mickey_Fiorentino'] = true,
        ['Sofia_Andreeva'] = true,
        ['William_Konta'] = true
    }
    if sampGetPlayerIdByNickname("Misha_Marcello") == 'offline' then
        onlineFriend = string.format('{ff0000}не в игре')
    else
        onlineFriend = string.format('{66cc00}в игре')
    end
    if sampGetPlayerIdByNickname("Mickey_Fiorentino") == 'offline' then
        onlineFriend = string.format('{ff0000}не в игре')
    else
        onlineFriend = string.format('{66cc00}в игре')
    end
    if sampGetPlayerIdByNickname("Sofia_Andreeva") == 'offline' then
        onlineFriend = string.format('{ff0000}не в игре')
    else
        onlineFriend = string.format('{66cc00}в игре')
    end
    if sampGetPlayerIdByNickname("William_Konta") == 'offline' then
        onlineFriend = string.format('{ff0000}не в игре')
    else
        onlineFriend = string.format('{66cc00}в игре')
    end
    sampShowDialog(102, "{5F9EA0}U.S MoD {F5FFFA}» "..gameServer.." {F5FFFA}» Друзья мои", "Sofia_Andreeva \t\t"..onlineFriend.."\nWilliam_Konta \t\t"..onlineFriend.."\nMisha_Marcello \t\t"..onlineFriend.."\nMickey_Fiorentino \t\t"..onlineFriend.."\n", "Выбрать", "закрыть", 2)
end
Lua:
function checkFriend()
    local for_dialog = '';
    local friends = {
        ['Misha_Marcello'] = '',
        ['Mickey_Fiorentino'] = '',
        ['Sofia_Andreeva'] = '',
        ['William_Konta'] = ''
    }
    for k, v in pairs(friends) do
        friends[k] = sampGetPlayerIdByNickname(k)
        for_dialog = for_dialog .. k .. '\t\t' .. friends[k] .. '\n'
    end
    sampShowDialog(102, "{5F9EA0}U.S MoD {F5FFFA}» "..gameServer.." {F5FFFA}» Друзья мои", for_dialog, "Выбрать", "Закрыть", 2)
end

function sampGetPlayerIdByNickname(p_nick)
    for k, v in pairs(getAllChars()) do
        local result, id = sampGetPlayerIdByCharHandle(v)
        if result and id ~= -1 then
            local nick = sampGetPlayerNickname(id)
            if tostring(nick) == tostring(p_nick) then
                return '{66cc00}в игре'
            end
        end
    end
    return '{ff0000}не в игре'
end
 

asocial demon

Потрачен
175
14
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
текст который рендерится - мигает, если поменять в findAllRandomVehiclesInSphere первый true на false, то все ок работает, но рендерит только один кар, а мне надо чтобы все в радиусе рендерило
Lua:
local font = renderCreateFont("Arial", 10, 5)

function main()
    repeat wait(0) until isSampAvailable()
    while true do
        wait(0)
        local X, Y, Z = getCharCoordinates(PLAYER_PED)
        local _, veh = findAllRandomVehiclesInSphere(X, Y, Z, 7, true, true)
        if _ then
            local pX, pY, pZ = getCarCoordinates(veh)
            local wX, wY = convert3DCoordsToScreen(pX, pY, pZ)
            local res, carId = sampGetVehicleIdByCarHandle(veh)
            local status = getCarDoorLockStatus(veh)
            if status == 0 then
                renderFontDrawText(font, string.format("{4FE517}Opened\nVehicleId: %s", carId), wX, wY, -1)
            else
                renderFontDrawText(font, string.format("{E51D17}Closed\nVehicleId: %s", carId), wX, wY, -1)
            end
        end
    end
end
 

ne4estno

Участник
79
0
Имеется такой код -
Lua:
function sampev.onServerMessage(color, chat)
          if chat:find("%[Информация%] {......}%w+_%w+ предлагает бросить кости. Ставка: %d+") then
               local stv = chat:match("  %[Информация%] {......}%w+_%w+ предлагает бросить кости. Ставка: (%d+)")
               sampAddChatMessage('Ставка - {ffffff}'..stv, 0xff9600)
          end
               if chat:find(nameGB) then
                    local one, two = text:match(".+%: %{CC9900%}(%d+) : (%d+)")
                    print(one)
                    print(two)
               end
     end
после него выдается такая ошибка, не знаю из-за чего выдает nil, хотя все вроде правильно
 

Lil Xean

о да моя госпожа
214
225
Имеется такой код -
Lua:
function sampev.onServerMessage(color, chat)
          if chat:find("%[Информация%] {......}%w+_%w+ предлагает бросить кости. Ставка: %d+") then
               local stv = chat:match("  %[Информация%] {......}%w+_%w+ предлагает бросить кости. Ставка: (%d+)")
               sampAddChatMessage('Ставка - {ffffff}'..stv, 0xff9600)
          end
               if chat:find(nameGB) then
                    local one, two = text:match(".+%: %{CC9900%}(%d+) : (%d+)")
                    print(one)
                    print(two)
               end
     end
после него выдается такая ошибка, не знаю из-за чего выдает nil, хотя все вроде правильно
Lua:
function sampev.onServerMessage(color, text)
    if text:find("%[Информация%] %{ffffff%}.+ предлагает бросить кости%. Ставка%: %d+") then -- цвет ffffff взят для примера
        local stv = text:match("  %[Информация%] %{ffffff%}.+ предлагает бросить кости%. Ставка%: (%d+)")
        sampAddChatMessage('Ставка - {ffffff}'..stv, 0xff9600)
    end
    --[[if text:find(nameGB) then
        local one, two = text:match(".+%: %{CC9900%}(%d+) : (%d+)")
        print(one)
        print(two)
        end]]
end -- данный блок мне вообще не понятен

Трабл в том, что раньше все работало)
мб потому что ты забыл экранизировать точки и двоеточия?
 
  • Нравится
Реакции: asocial demon

ne4estno

Участник
79
0
Lua:
function sampev.onServerMessage(color, text)
    if text:find("%[Информация%] %{ffffff%}.+ предлагает бросить кости%. Ставка%: %d+") then -- цвет ffffff взят для примера
        local stv = text:match("  %[Информация%] %{ffffff%}.+ предлагает бросить кости%. Ставка%: (%d+)")
        sampAddChatMessage('Ставка - {ffffff}'..stv, 0xff9600)
    end
    --[[if text:find(nameGB) then
        local one, two = text:match(".+%: %{CC9900%}(%d+) : (%d+)")
        print(one)
        print(two)
        end]]
end -- данный блок мне вообще не понятен
Первая часть работала 100%, пока я не добавил 2 говнокод, и теперь когда я его убираю - он, что логично, не работает
 

asocial demon

Потрачен
175
14
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
текст который рендерится - мигает, если поменять в findAllRandomVehiclesInSphere первый true на false, то все ок работает, но рендерит только один кар, а мне надо чтобы все в радиусе рендерило
Lua:
local font = renderCreateFont("Arial", 10, 5)

function main()
    repeat wait(0) until isSampAvailable()
    while true do
        wait(0)
        local X, Y, Z = getCharCoordinates(PLAYER_PED)
        local _, veh = findAllRandomVehiclesInSphere(X, Y, Z, 7, true, true)
        if _ then
            local pX, pY, pZ = getCarCoordinates(veh)
            local wX, wY = convert3DCoordsToScreen(pX, pY, pZ)
            local res, carId = sampGetVehicleIdByCarHandle(veh)
            local status = getCarDoorLockStatus(veh)
            if status == 0 then
                renderFontDrawText(font, string.format("{4FE517}Opened\nVehicleId: %s", carId), wX, wY, -1)
            else
                renderFontDrawText(font, string.format("{E51D17}Closed\nVehicleId: %s", carId), wX, wY, -1)
            end
        end
    end
end
Актуально
 

Shamanije

Известный
Друг
957
924
isGameWindowForeground() возвращает всегда true. Эта функция сломана?
Не сломана, фолс будет возвращать если свернешься с включенным noafk

Рендерит последний найденный айди. Если нужно в виде списка то создавай массив или добавляй новый рендер для каждого авто
p.s: это гениально
Lua:
local _, veh = findAllRandomVehiclesInSphere(X, Y, Z, 7, true, true)
if _ then

Первая часть работала 100%, пока я не добавил 2 говнокод, и теперь когда я его убираю - он, что логично, не работает
Зачем экранить фигурные скобки? Это цветокод, метод find скипает его. По сути ты парсишь не белое сообщение, а сообщение "[Информация] {ffffff} предлагает бросить кости"
 
Последнее редактирование: