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

imring

Ride the Lightning
Всефорумный модератор
2,355
2,517
Как добавить проверку если ли такой ник в файле или нету ? Если есть то проходим мимо, если нету добавляем
Lua:
text = 'Администратор Rick_Auditore забанил игрока Lauren_Monroe на 20 дней. Причина: ГМ кар от Роберто'
local nick = text:match('Администратор (.*) забанил.+')
if #nick > 0 then     local file = io.open('moonloader/file.txt', 'a')
file:write(nick) 
file:close()
end
Lua:
text = 'Администратор Rick_Auditore забанил игрока Lauren_Monroe на 20 дней. Причина: ГМ кар от Роберто'
local nick = text:match('Администратор (.*) забанил.+')
if nick then
    local file = io.open('moonloader/file.txt', 'a')
    if not file:read('*a'):find(nick) then
        file:write(nick..'\n')
    end
    file:close()
end
 
Последнее редактирование:
  • Нравится
Реакции: deddosouru

ShuffleBoy

Известный
Друг
754
429
Как добавить проверку если ли такой ник в файле или нету ? Если есть то проходим мимо, если нету добавляем
Lua:
text = 'Администратор Rick_Auditore забанил игрока Lauren_Monroe на 20 дней. Причина: ГМ кар от Роберто'
local nick = text:match('Администратор (.*) забанил.+')
if #nick > 0 then     local file = io.open('moonloader/file.txt', 'a')   
file:write(nick)    
file:close()
end
Lua:
f = io.open(file path, 'r')
for line in f:lines do
    table.insert(nicks, line)
end

for i=1,#nicks do
    if i == nick then
        HaveNick = true
        break
    end
end
Подкорректирруй, с телефона писал
 
  • Нравится
Реакции: deddosouru

Neo Romero

Новичок
17
4
Не работает хук на onServerMessage, moonloader 026, логи чисты, весь остальной функционал работает, код который не работает:
Lua:
function hook.onServerMessage(color, message)
    sampAddChatMessage(message,-1)
end

На 025 работает, установил 026, не внося изменений в скрипт - не работает
 

Cutler18

Известный
160
2
Lua:
function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand("medh", showdialog)
    while true do
    wait(0)
        result, button, list, input = sampHasDialogRespond(100)
        if result and button == 1 then
            if list == 0 then
                sampSendChat('/me осмотрел пациента')
                wait(1000)
                sampSendChat('/me поставил диагноз')
                wait(1000)
                sampSendChat('Я выпишу Вам "Цитрамон". Его стоимость: 150$')
                wait(1000)
                sampSendChat('/me достал "Цитрамон" из мед.сумки')
                wait(1000)
                sampSendChat('/me передал пациенту лекарство')
                sampSendChat('/medhelp '..id)
           end
        end
    end
end

function showdialog(param)
    id = string.match(param, '(%d+)')
sampShowDialog(100, "Меню лечения", 'Голова \0', "Выбрать", "Закрыть", 2)
end
А почему когда 2 раза ставлю /medhelp ..id То оно не работает?


Lua:
function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand("medh", showdialog)
    while true do
    wait(0)
        result, button, list, input = sampHasDialogRespond(100)
        if result and button == 1 then
            if list == 0 then
                sampSendChat('/me осмотрел пациента')
                wait(1000)
                sampSendChat('/me поставил диагноз')
                wait(1000)
                sampSendChat('Я выпишу Вам "Цитрамон". Его стоимость: 150$')
                wait(1000)
                sampSendChat('/me достал "Цитрамон" из мед.сумки')
                wait(1000)
                sampSendChat('/me передал пациенту лекарство')
                sampSendChat('/medhelp '..id)       
elseif list == 1 then
                sampSendChat("/me осмотрел пациента")
                wait(1000)
                sampSendChat("/me поставил диагноз")
                wait(1000)
                sampSendChat('Я выпишу Вам "Но-шпа". Его стоимость: 150$')
                wait(1000)
                sampSendChat('/me достал "Но-шпа" из мед.сумки')
                wait(1000)
                sampSendChat("/me передал пациенту лекарство")
                sampSendChat('/medhelp '..id))
           end
        end
    end
end

function showdialog(param)
    id = string.match(param, '(%d+)')
sampShowDialog(100, "Меню лечения", 'Голова \nЖивот \0', "Выбрать", "Закрыть", 2)
end
 
1,417
1,029
А почему когда 2 раза ставлю /medhelp ..id То оно не работает?


Lua:
function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand("medh", showdialog)
    while true do
    wait(0)
        result, button, list, input = sampHasDialogRespond(100)
        if result and button == 1 then
            if list == 0 then
                sampSendChat('/me осмотрел пациента')
                wait(1000)
                sampSendChat('/me поставил диагноз')
                wait(1000)
                sampSendChat('Я выпишу Вам "Цитрамон". Его стоимость: 150$')
                wait(1000)
                sampSendChat('/me достал "Цитрамон" из мед.сумки')
                wait(1000)
                sampSendChat('/me передал пациенту лекарство')
                sampSendChat('/medhelp '..id)      
elseif list == 1 then
                sampSendChat("/me осмотрел пациента")
                wait(1000)
                sampSendChat("/me поставил диагноз")
                wait(1000)
                sampSendChat('Я выпишу Вам "Но-шпа". Его стоимость: 150$')
                wait(1000)
                sampSendChat('/me достал "Но-шпа" из мед.сумки')
                wait(1000)
                sampSendChat("/me передал пациенту лекарство")
                sampSendChat('/medhelp '..id))
           end
        end
    end
end

function showdialog(param)
    id = string.match(param, '(%d+)')
sampShowDialog(100, "Меню лечения", 'Голова \nЖивот \0', "Выбрать", "Закрыть", 2)
end
30 строка, одну скобку убери.
 
  • Нравится
Реакции: ufdhbi и deddosouru

imring

Ride the Lightning
Всефорумный модератор
2,355
2,517
Подскажите как таймер сделать ?
Lua:
clock = os.clock()
delay = math.random(2,5)
while (os.clock() - clock < delay)
wait(0)
renderFontDrawText(font2, string.format('Осталось: {FF0000}%.2f', delay-(os.clock() - clock)), x/2, y/2, 0xFFFF0000)
end

Lua:
if getCarSpeed(car) == 0.0 and clock ~= nil then
e_time = 900
cur_time = (e_time-(os.clock() - clock))
min = math.floor(cur_time / 60)
sec=cur_time % 60
renderFontDrawText(font, string.format('%d:%d', math.floor(min), math.floor(sec)), rx-105, ry/4.5, 0xFFFF0000)
else
renderFontDrawText(font, "15:00", rx-105, ry/4.5, 0xFFFF0000)
clock = os.clock()
end
обратный счетчик от 15 минут
 
  • Нравится
Реакции: ufdhbi и AnWu

AnWu

Guardian of Order
Всефорумный модератор
4,690
5,202
всё еще интерисует как получить список папок в определенной папке
 

imring

Ride the Lightning
Всефорумный модератор
2,355
2,517
всё еще интерисует как получить список папок в определенной папке
Lua:
local h, n = findFirstFile('*') -- папка твоей GTA.
while true do wait(0)
    if h then
        if n then
            local f = io.open(n)
            if not f then print('Directory: '..n)
            else print('File: '..n) end
            n = findNextFile(h)
        else findClose(h) end
    end
end
 
  • Нравится
Реакции: ufdhbi и AnWu

RoffDaniel

Известный
77
20
Подскажите пожалуйста, как можно сделать проверку на содержание ini файла? Например, до обновления было так:
Lua:
local Data =
{
    Gnews =
    {
        First = 'AoP | Первая строка трестрочной гос. новости',
        Second = 'AoP | Вторая строка трестрочной гос. новости',
        Third = 'AoP | Третья строка трестрочной гос. новости',
        Alone = 'AoP | Одна строка однострочной гос. новости',
        Wait = 500
    }
}
После обновления так:
Lua:
local Data =
{
    Gnews =
    {
        First = 'AoP | Первая строка трестрочной гос. новости',
        Second = 'AoP | Вторая строка трестрочной гос. новости',
        Third = 'AoP | Третья строка трестрочной гос. новости',
        Alone = 'AoP | Одна строка однострочной гос. новости',
        Wait = 500
    },
    Others =
    {
        Tag = 'Тэг'
    }
}
И для того что бы ini файл обновился, пользователю прийдется же удалять его перед обновлением. Но это не очень, по этому обращаюсь к вам. Я пытался сделать через это:
Lua:
    for w in pairs(Data) do
        for d in pairs(Data) do
            if w == d then w = nil break end
        end
        if w ~= nil then
            inicfg.save(Data, path)
            sampAddChatMessage('{CECECE}[{CCFF00}GOV-Helper{CECECE}] Файл с дополнительными настройками обновлен.', -1)
        break
        end
    end
Но без успешно. Подскажите пожалуйста. Заранее, спасибо.
 

AnWu

Guardian of Order
Всефорумный модератор
4,690
5,202
Подскажите пожалуйста, как можно сделать проверку на содержание ini файла? Например, до обновления было так:
Lua:
local Data =
{
    Gnews =
    {
        First = 'AoP | Первая строка трестрочной гос. новости',
        Second = 'AoP | Вторая строка трестрочной гос. новости',
        Third = 'AoP | Третья строка трестрочной гос. новости',
        Alone = 'AoP | Одна строка однострочной гос. новости',
        Wait = 500
    }
}
После обновления так:
Lua:
local Data =
{
    Gnews =
    {
        First = 'AoP | Первая строка трестрочной гос. новости',
        Second = 'AoP | Вторая строка трестрочной гос. новости',
        Third = 'AoP | Третья строка трестрочной гос. новости',
        Alone = 'AoP | Одна строка однострочной гос. новости',
        Wait = 500
    },
    Others =
    {
        Tag = 'Тэг'
    }
}
И для того что бы ini файл обновился, пользователю прийдется же удалять его перед обновлением. Но это не очень, по этому обращаюсь к вам. Я пытался сделать через это:
Lua:
    for w in pairs(Data) do
        for d in pairs(Data) do
            if w == d then w = nil break end
        end
        if w ~= nil then
            inicfg.save(Data, path)
            sampAddChatMessage('{CECECE}[{CCFF00}GOV-Helper{CECECE}] Файл с дополнительными настройками обновлен.', -1)
        break
        end
    end
Но без успешно. Подскажите пожалуйста. Заранее, спасибо.
в чем проблема читать ини? inicfg.load()
 
  • Нравится
Реакции: imring