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

Pakulichev

Software Developer & System Administrator
Друг
1,789
2,133
Помогите с кодом, не работает чёт
Lua:
local kolichestvo = 100
local price = 2750
-- хуй
local sampev = require 'lib.samp.events'
local key = require 'vkeys'

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
    while true do
        wait(0)
        if not sampIsChatInputActive() and not isSampfuncsConsoleActive() and not sampIsDialogActive() then
            if isKeyJustPressed(key.VK_SUBTRACT) then
                sampSendChat('/sellbrill')
            end
        end
    end
end

function sampev.onShowDialog(id, style, title, b1, b2, text)
    if id == 996 then
        sampSendDialogResponse(id, 1, -1, tostring(kolichestvo))
        if id = 997 then
            sampSendDialogResponse(id, 1, -1, tostring(price))
            end
    end
end

function sampev.onSendEditObject(playerObject, objectId, response, position, rotation)
    return {playerObject, objectId, 1, position, rotation}
end
Попробуй таким образом
Lua:
local kolichestvo = 100
local price = 2750
local sampev = require("samp.events")

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    repeat wait(0) until isSampAvailable()
    while true do wait(0)
        if not sampIsChatInputActive() and not isSampfuncsConsoleActive() and not sampIsDialogActive() then
            if isKeyJustPressed(VK_SUBTRACT) then sampSendChat("/sellbrill") end
        end
    end
end
 

savvin

Известный
407
140
Скиньте плез тему(-ы) для изучения json файлов,как выводить таблицу и тд
Синтаксис JSON найдешь в гугле, расскажу только как работать с JSON

Преобразует таблицу в JSON
Lua:
string json = encodeJson(table data)

-- Использование

local jsonFile = io.open('moonloader/files/test.json', 'w') -- чтение json файла / w - режим записи в файл, заменяя все его содержимое / если файла нет - будет создан
if jsonFile then -- если файл существует и открыт, тогда выполняется код
    local jsonTable =
    {
        name = 'Название',
        text = 'Текст'
    }
    -- преобразуемая таблица
    
    jsonFile:write(encodeJson(jsonTable)) -- преобразование таблицы в JSON и запись в файл
    jsonFile:close() -- закрыть файл записи
end

-- Результат файла "../moonloader/files/test.json"
{
    "name": "Название",
    "text": "Текст"
}

Преобразует JSON в таблицу
Lua:
table luaData = decodeJson(string json)

-- Использование

local jsonTable = {} -- где-то в теле скрипта глобальная переменная

local jsonFile = io.open('moonloader/files/test.json', 'r') -- чтение файла в формате полного содержания
if jsonFile then -- если файл существует, выполняем код
    jsonTable = decodeJson(jsonFile:read('a*')) -- выгружаем JSON в таблицу
    jsonFile:close() -- закрываем файл
end

-- Результат

-- содержание JSON файла
{
    "name": "Название",
    "text": "Текст"
}

-- содержание таблицы после преобразования
print(jsonTable['name'], jsonTable['text']) -- "Название Текст"
Есть еще один ньюанс, JSON принимает кодировку текста в UTF8, самповскую CP1251 брать не хочет, поэтому ругается
 
  • Нравится
Реакции: mld

Dmitriy Makarov

25.05.2021
Проверенный
2,478
1,113
если я пытаюсь получить этот текст в регулярке
Nick_Name[10]:
то это будет правильно?
Lua:
%a+_%a+%[%d+%]:
насчет двоеточия я хз как экранировать его..
и как получить текст после двоеточия
Nick_Name[10]: Привет
 
Последнее редактирование:

Akionka

akionka.lua
Проверенный
742
500
если я пытаюсь получить этот текст в регулярке
Nick_Name[10]:
то это будет правильно?
Lua:
%a+_%a+%[%d+%]:
насчет двоеточия я хз как экранировать его..
и как получить текст после двоеточия
Nick_Name[10]: Привет
%a+_%a+%[%d+%]: (.+)
 
  • Нравится
Реакции: Dmitriy Makarov

Dmitriy Makarov

25.05.2021
Проверенный
2,478
1,113
можно ли сделать проверку на то есть ли в зоне стрима NPS персонаж?
 

JustFedot

Известный
279
280
Подскажите мне пожалуйста, что это вообще такое, как называться?:

Снимок.PNG

Так-же подскажите пожалуйста как работать с такими вот штуками по типу text:match или ещё как...
Пытался найти инфу сам, но даже не нашел названия этой штуки.
 

astynk

Известный
Проверенный
742
530
Подскажите мне пожалуйста, что это вообще такое, как называться?:


Так-же подскажите пожалуйста как работать с такими вот штуками по типу text:match или ещё как...
Пытался найти инфу сам, но даже не нашел названия этой штуки.
Первое - RPC ChatBubble.
Lua:
INCOMING_RPCS[RPC.CHATBUBBLE]                 = {'onPlayerChatBubble', {playerId = 'int16'}, {color = 'int32'}, {distance = 'float'}, {duration = 'int32'}, {message = 'string8'}}

По второму ищи в гугле, там куча сайтов.
можно ли сделать проверку на то есть ли в зоне стрима NPS персонаж?
Если динамичный нпц, то sampIsPlayerNpc
Если статичный, то делай цикл по getAllChars() и ищи таких педов, у которых нельзя взять ID.
 
  • Нравится
Реакции: JustFedot

JustFedot

Известный
279
280
Ребята, как правильно использовать getRadioChannel?
Попробовал вот так:
Lua:
function func2()
    local result, radio = getRadioChannel(playerPed)
    if result then
        sampAddChatMessage('Радио: '..radio, -1)
    end
end
Выдает ошибку о том что radio это nil значение.

UPD:
Прошу прощения за беспокойство, проблема решена.

Lua:
function func2()
    local radio = getRadioChannel(playerPed)
    if radio < 12 then
        setRadioChannel(12)
    end
end
 
Последнее редактирование:

utmpL

Активный
309
65
есть код
Lua:
for k, i in ipairs(objects) do
    if doesObjectExist(i) and isObjectOnScreen(i) then
        local result, x, y, z = getObjectCoordinates(i)
        if result then
            local model = getObjectModel(i)
            if model == 2814 then
                --BeginToPoint(x, y, z, 1.000000, -255, true)
            end
        end
    end
end
как сделать чтобы я бежал к ближайшему объекту ко мне, а не к рандомному?
 

trefa

Известный
Всефорумный модератор
2,097
1,231
Первое - RPC ChatBubble.
Lua:
INCOMING_RPCS[RPC.CHATBUBBLE]                 = {'onPlayerChatBubble', {playerId = 'int16'}, {color = 'int32'}, {distance = 'float'}, {duration = 'int32'}, {message = 'string8'}}

По второму ищи в гугле, там куча сайтов.

Если динамичный нпц, то sampIsPlayerNpc
Если статичный, то делай цикл по getAllChars() и ищи таких педов, у которых нельзя взять ID.
Что за дезинфа это вообще 3d text а не ChatBubble.
 

savvin

Известный
407
140
есть код
Lua:
for k, i in ipairs(objects) do
    if doesObjectExist(i) and isObjectOnScreen(i) then
        local result, x, y, z = getObjectCoordinates(i)
        if result then
            local model = getObjectModel(i)
            if model == 2814 then
                --BeginToPoint(x, y, z, 1.000000, -255, true)
            end
        end
    end
end
как сделать чтобы я бежал к ближайшему объекту ко мне, а не к рандомному?
Создаешь таблицу и заполняешь ее ID и расстояние до него всеми объектами в зоне стрима и потом сортируешь таблицу

Lua:
local closestObjectsStream = {}

for _, i in ipairs(getAllObjects()) then
    if doesObjectExist(i) and isObjectOnScreen(i) then
        local result, ox, oy, oz = getObjectCoordinates(i)
        local px, py, pz = getCharCoordinates(PLAYED_PED)
        
        local distance = getDistanceBetweenCoords3d(ox, oy, oz, px, py, pz)
        
        table.insert(closestObjectsStream, {id, distance})
    end
end

table.sort(closestObjectsStream, function(a, b) return (a[2] < b[2]) end)

-- Ближайший handle объекта будет closestObjectsStream[1][1]
 
  • Нравится
Реакции: utmpL