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

l-m

Новичок
28
1
выводи sampAddChatMessage

Lua:
function xz--[[твоя функция]]()
    sampAddChatMessage('хуя заработало',-1)
-- you code
end
Ты не понял) Мне нужно сделать невидимой для скрипта команду, если он уже выполняет её, потому что если дважды он увидит команду, будет дважды флудить одним и тем же.
 
  • Эм
Реакции: qdIbp

qdIbp

Автор темы
Проверенный
1,434
1,174
Ты не понял) Мне нужно сделать невидимой для скрипта команду, если он уже выполняет её, потому что если дважды он увидит команду, будет дважды флудить одним и тем же.
?
Lua:
local wast = 0

function main()
    while not sampIsLocalPlayerSpawned() do wait(100) end
    sampRegisterChatCommand('off',function()
        wast = 0
    end)
    while true do wait(0)
        for i = 1, wast do
            sampSendChat('/c xz')
            wait(123)
        end
    end
end

require('lib.samp.events').onSendCommand = function(cmd)
    if string.match(cmd,'^/test') then
        if wast == 0 then
            sampAddChatMessage('Ухх пошла жара',-1)
        end
        wast = wast + 1
    end
end
 

chapo

чопа сребдс // @moujeek
Модератор
8,862
11,550
Спасибо


Произошел один ньюанс:
Lua:
local carLabel = string.format("%s[%d]\nHealth: %d\nX: %d | Y: %d | Z: %d\nDistance: %d", modelLabel, modelId, carHealth, carX, carY, carZ, distance)
Вроде бы все хорошо, но функция
Lua:
local carLabelWidth = renderGetFontDrawTextLength(smallFont, carLabel, false)
Получает длину строки с учетом (\n), а не делает каждую строку по центру.
Как можно реализовать центрирование, без прибегания к костылям по типу
Lua:
local carLabelWidth1 = renderGetFontDrawTextLength(smallFont, carLabel1, false)
local carLabelWidth2 = renderGetFontDrawTextLength(smallFont, carLabel2, false)
local carLabelWidth3 = renderGetFontDrawTextLength(smallFont, carLabel3, false)

if carLabelWidth1 > carLabelWidth2 then
...
end
?
Lua:
        local veh = хендл машины
            if isCarOnScreen(veh) then
                local x, y = convert3DCoordsToScreen(getCarCoordinates(veh))
                local lines = {
                    ('%s [%s]'):format(getNameOfVehicleModel(getCarModel(veh)) or 'UNKNOWN', getCarModel(veh)),
                    ('Health: %s'):format(getCarHealth(veh)),
                    ('XYZ: %s'):format(table.concat({getCarCoordinates(veh)}, ', '))
                }
                for i, text in ipairs(lines) do
                    renderFontDrawText(font, text, x - renderGetFontDrawTextLength(font, text) / 2, y, 0xFFffffff)
                    y = y + renderGetFontDrawHeight(font)
                end
            end
Lua:
local font = renderCreateFont('Trebuchet MS', 9, 5)

function main()
    while not isSampAvailable() do wait(0) end
    while true do
        wait(0)
        for _, veh in ipairs(getAllVehicles()) do
            if isCarOnScreen(veh) then
                local x, y = convert3DCoordsToScreen(getCarCoordinates(veh))
                local lines = {
                    ('%s [%s]'):format(getNameOfVehicleModel(getCarModel(veh)) or 'UNKNOWN', getCarModel(veh)),
                    ('Health: %s'):format(getCarHealth(veh)),
                    ('XYZ: %s'):format(table.concat({getCarCoordinates(veh)}, ', '))
                }
                for i, text in ipairs(lines) do
                    renderFontDrawText(font, text, x - renderGetFontDrawTextLength(font, text) / 2, y, 0xFFffffff)
                    y = y + renderGetFontDrawHeight(font)
                end
            end
        end
    end
end
1673693430746.png
 
  • Ха-ха
Реакции: qdIbp

l-m

Новичок
28
1
?
Lua:
local wast = 0

function main()
    while not sampIsLocalPlayerSpawned() do wait(100) end
    sampRegisterChatCommand('off',function()
        wast = 0
    end)
    while true do wait(0)
        for i = 1, wast do
            sampSendChat('/c xz')
            wait(123)
        end
    end
end

require('lib.samp.events').onSendCommand = function(cmd)
    if string.match(cmd,'^/test') then
        if wast == 0 then
            sampAddChatMessage('Ухх пошла жара',-1)
        end
        wast = wast + 1
    end
end
Флуд 'Ухх пошла жара' и кикает с сервера. Возможно ошибка в коде, возможно я не правильно объяснил. Я ввожу команду, и начинается производится текст который я забиндил с задержкой. Если к примеру трижды прописать команду, то одновременно в 3 строки будет производится текст. Так вот, я хочу сделать блокировку команды. Если я первый раз ввёл команду, начинает работать биндер с текстом, но, если этот биндер не дошёл до конца, то ввод команды будет не возможен.
1673722154604.png

Если ввести быстро несколько раз команду, то начинается флуд и кикает из сервера
 

CaJlaT

07.11.2024 14:55
Модератор
2,830
2,660
Флуд 'Ухх пошла жара' и кикает с сервера. Возможно ошибка в коде, возможно я не правильно объяснил. Я ввожу команду, и начинается производится текст который я забиндил с задержкой. Если к примеру трижды прописать команду, то одновременно в 3 строки будет производится текст. Так вот, я хочу сделать блокировку команды. Если я первый раз ввёл команду, начинает работать биндер с текстом, но, если этот биндер не дошёл до конца, то ввод команды будет не возможен.
Посмотреть вложение 185993
Если ввести быстро несколько раз команду, то начинается флуд и кикает из сервера
создавай поток, при повторном вводе команды удаляй его....
Lua:
function main()
    sampRegisterChatCommand('aboba', function()
        if thread then
            thread:terminate()
            thread = nil
            sampAddChatMessage('Флудер остановлен', -1)
            return
        end
        sampAddChatMessage('Флудер запущен', -1)
        thread = lua_thread.create(function()
            while true do
                sampAddChatMessage('ABOBA', -1)
                wait(100)
            end
        end)
    end)
    wait(-1)
end
1673722949727.png
 
  • Нравится
Реакции: qdIbp

l-m

Новичок
28
1
создавай поток, при повторном вводе команды удаляй его....
Lua:
function main()
    sampRegisterChatCommand('aboba', function()
        if thread then
            thread:terminate()
            thread = nil
            sampAddChatMessage('Флудер остановлен', -1)
            return
        end
        sampAddChatMessage('Флудер запущен', -1)
        thread = lua_thread.create(function()
            while true do
                sampAddChatMessage('ABOBA', -1)
                wait(100)
            end
        end)
    end)
    wait(-1)
end
Посмотреть вложение 185995
Не через main получится? Чтобы вот в этот код))))
Lua:
function sampev.onServerMessage(color--[[Цвет]], text--[[Текст]]) -- Этот хук ловит сообщения в чате
    lua_thread.create(function() -- создаем поток -- позволяет использовать wait
        if status then
            if text:find('[R].*: /driver') then -- если найден текст "test" то
                wait(100) -- отвечает за ожидание в размере секунды БЫЛО 1000 сек
                sampSendChat('/r Вызываю эвакуатор через 10 секунд')
                wait(5000)
                sampSendChat('/r (( /drive 5 sek ))')
                wait(4000)
                sampSendChat('/r Вызываю эвакуатор через 1 секунду, кто не успел тот опоздал')
                wait(1000)
                sampSendChat('/drive') -- если в чате засветится сообщение test, то хук поймает данное сообщение, дальше скрипт подождет 1 секунду и выведет "Не тест"
                wait(2000)
                sampCloseCurrentDialogWithButton(1) --закрывает окно с нажатием кнопки
            elseif text:find('[R].*: /cancel') then
                sampSendChat("/r (( drive disabled ))")
                wait(500)
                thisScript():reload() 
            end    
        end    
    end)-- закрываем поток
end
 

Arseniy_Verteich

Новичок
1
0
Ребят, помогите пожалуйста, в медхелпере при вводе команды /hl (id) отыгрывается рп, и после должно хилить игрока, но после обновлений нужно писать цену хила, изза этого выдает ошибку, в самой аризоне, мол введите цену за лечение , в хелпере есть политика цен, но она не работает. Как сделать так, что бы хелпер работал по команде /hl (id) (цена) и в после выдавал /heal (id) (цена) А не просто /heal (id). Да знаю, это сделать вроде-бы просто, но я новичок, и не разбираюсь в этом.
Нужно сделать перепенную, но как?
 

Julimba

Участник
108
10
Хелпаните пж
<eof>' expected near 'end'

Lua:
function sampev.onPlayerDeathNotification(killerId, killedId, reason)
    if isGameWindowForeground() and not isPauseMenuActive() and not isGamePaused() then
        local nick = sampGetPlayerNickname(killerId)
        sampAddChatMessage(tag.. '{FFFFFF}Игрок {30d5c8}' ..nick.. '[' ..killerId.. '] {FFFFFF}убил другого игрока', -1)
        sampAddChatMessage(tag.. '{FFFFFF}Чтобы объявить в розыск, нажми - {99FF00}End', -1)
        local CLOCK = os.clock()
            lua_thread.create(function()
                while true do wait(1)
                    if isKeyJustPressed(106) then break end
                    if isKeyJustPressed(35) then
                        sampSendChat('/su ' ..killerId.. ' 4 14.1 ')
                        sampAddChatMessage(tag.. '{FFFFFF}Вы выдали розыск игроку{30d5c8}'..nick..'[' ..killerId.. ']', -1)
                        break
                    end
                    if os.clock()-CLOCK > 10 then
                    sampAddChatMessage(tag.. '{FFFFFF}Вы не успели выдать розыск игроку', -1)
                        break
                    end
                end
            end)
        end
    end
end
 

sdfy

Известный
348
229
Хелпаните пж
<eof>' expected near 'end'

Lua:
function sampev.onPlayerDeathNotification(killerId, killedId, reason)
    if isGameWindowForeground() and not isPauseMenuActive() and not isGamePaused() then
        local nick = sampGetPlayerNickname(killerId)
        sampAddChatMessage(tag.. '{FFFFFF}Игрок {30d5c8}' ..nick.. '[' ..killerId.. '] {FFFFFF}убил другого игрока', -1)
        sampAddChatMessage(tag.. '{FFFFFF}Чтобы объявить в розыск, нажми - {99FF00}End', -1)
        local CLOCK = os.clock()
            lua_thread.create(function()
                while true do wait(1)
                    if isKeyJustPressed(106) then break end
                    if isKeyJustPressed(35) then
                        sampSendChat('/su ' ..killerId.. ' 4 14.1 ')
                        sampAddChatMessage(tag.. '{FFFFFF}Вы выдали розыск игроку{30d5c8}'..nick..'[' ..killerId.. ']', -1)
                        break
                    end
                    if os.clock()-CLOCK > 10 then
                    sampAddChatMessage(tag.. '{FFFFFF}Вы не успели выдать розыск игроку', -1)
                        break
                    end
                end
            end)
        end
    end
end
Зачем локал эндом закрыл
Lua:
function sampev.onPlayerDeathNotification(killerId, killedId, reason)
    if isGameWindowForeground() and not isPauseMenuActive() and not isGamePaused() then
        local nick = sampGetPlayerNickname(killerId)
        sampAddChatMessage(tag.. '{FFFFFF}Игрок {30d5c8}' ..nick.. '[' ..killerId.. '] {FFFFFF}убил другого игрока', -1)
        sampAddChatMessage(tag.. '{FFFFFF}Чтобы объявить в розыск, нажми - {99FF00}End', -1)
        local CLOCK = os.clock()
        lua_thread.create(function()
            while true do wait(1)
                if isKeyJustPressed(106) then break end
                if isKeyJustPressed(35) then
                    sampSendChat('/su ' ..killerId.. ' 4 14.1 ')
                    sampAddChatMessage(tag.. '{FFFFFF}Вы выдали розыск игроку{30d5c8}'..nick..'[' ..killerId.. ']', -1)
                    break
                end
                if os.clock()-CLOCK > 10 then
                    sampAddChatMessage(tag.. '{FFFFFF}Вы не успели выдать розыск игроку', -1)
                    break
                end
            end
        end)
    end
end
 
  • Нравится
Реакции: Julimba, YarikVL и qdIbp

Sadow

Известный
1,428
592
Как сделать проверку на то активен ли курсор или нет. Нужна проверка не только на самповский курсор, а вообще. sampIsCursorActive() только на самповский работает
 

qdIbp

Автор темы
Проверенный
1,434
1,174
Как сделать проверку на то активен ли курсор или нет. Нужна проверка не только на самповский курсор, а вообще. sampIsCursorActive() только на самповский работает
 

Sqzlly

Активный
71
25
Как сделать снег в окне imgui, чтобы при открытие ИМУГИ в заднем фоне снег падал
 

Fire666

Новичок
1
0
Как прописать маркер для машини?
Пример перевозка медикаментов.