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

samespoon

Известный
163
20
а на чё там гайд делать то
1. Все есть в книге по lua или в гугле
Лично мне очень сложно понять данную инфу с помощью гугла, а бесплатную загрузку книги я не нашёл(если знаешь где скачать, пиши)

--------------------------------------------------------------------------------------------------------------------------
2. В компе время может быть не точным, а брать время с инета не оч т.к легче из /time вытащить
Если брать время из интернета, то оно может оказаться точнее серверного времени. И да - для меня брать время из интернета будет проще, чем из тайма из-за выше затронутой причины.

--------------------------------------------------------------------------------------------------------------------------
Так ты про обычное время, а я про сыгранное время за этот сеанс.
Возможно, что кому-то данная инфа пригодится, но, думаю, что тому, кто изначально задал сей вопрос это совсем не нужно.

--------------------------------------------------------------------------------------------------------------------------
Подскажите как словить event, когда PLAYER_PED садится в любой транспорт. Я пробовал onPlayerEnterVehicle, но где-то я видимо срукожопил и работало только когда остальные игроки садились в машину, на меня почему-то не работало.
Lua:
function sampev.onSendEnterVehicle(vehicleID, passenger)
      -- что-то
end
 
  • Нравится
Реакции: r4nx

kraft1k

Вынь х*й из головы и все получится © hnnssy
Друг
1,479
1,163
Ребят, помогите пожалуйста. Есть скрипт. После написания команды он нажимает F, в диалоге выбирает "Да", тыкает по указанному TextDraw'у, в следующем диалоговом окне пишет 1000 и в нем же нажимает "Да". После ждет чуть больше 15 секунд, и повторяет все действия. И так пока опять не пропишешь комманду. Собственно, он просто флудит буквой F, после чего отказывается работать, не видит команду. Объясните, пожалуйста, мне, нубасу, в чем дело...
Lua:
script_name("123456")
script_authors("1", "2")

require("vkeys")
require("lib.moonloader")

function main()
sampRegisterChatCommand("azino777", casic)
wait(-1)
end

function casic()
  enabled = not enabled
  if enabled then
    sampAddChatMessage("123", 0xFFFFFF)
  else
    sampAddChatMessage("456", 0xFFFFFF)
  end
--------------------------------------------------------------

  setVirtualKeyDown(VK_F, true)
  wait(200)
  setVirtualKeyDown(VK_F, false)
  wait(200)
  sampCloseCurrentDialogWithButton(1)
  wait(200)
  sampSendClickTextdraw(309)
  wait(200)
  sampSendDialogResponse(29101, 0, 0, "1000")
  wait(15100)
  repeat until enabled
end
Id первого диалога есть?

Lua:
local sampev = require "samp.events"

function sampev.onShowDialog(dialogId, style, title, button1, button2, text)
  if enabled and dialogId == 29101 then sampSendDialogResponse(29101, 0, 0, "1000") return false end
end

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(0) end
    while not sampIsLocalPlayerSpawned() do wait(0) end
    sampRegisterChatCommand("azino777", casic)

  while true do wait(0)
    if enabled then
      setGameKeyState(15, 255)
      wait(200)
      sampCloseCurrentDialogWithButton(1)
      wait(200)
      sampSendClickTextdraw(309)
      wait(15100)
    end
  end
end

function casic()
 enabled = not enabled
  if enabled then
    sampAddChatMessage("123", 0xFFFFFF)
  else
    sampAddChatMessage("456", 0xFFFFFF)
  end
end
 
Последнее редактирование:
  • Нравится
Реакции: NeathA

Cameron_Bawerman

Участник
99
1
а можно как то сделать что бы он искать тоже текст /kick 15 DM только под Сaps Lock
Например: /KICK 15 DM

Lua:
function ev.onServerMessage(color, msg)
    if msg:find("%a+_%a+%[%d+%]: /kick%s*%d+.+") then
        msg1 = msg
        lua_thread.create(function()
        local surname, id, reason = msg1:match("_(%a+)%[%d+%]: /kick%s*(%d+)%s*(.+)")
        wait(0)
        sampAddChatMessage("Нажмите \"F2\" чтобы принять наказание и \"F3\" чтобы отменить наказание", -1)
        repeat
        wait(0)
        if isKeyJustPressed(VK_F2) then
            sampAddChatMessage("Вы приняли наказание", -1)
            sampAddChatMessage("/kick "..id.." "..reason.." | "..surname.."",-1)
        elseif isKeyJustPressed(VK_F3) then
            sampAddChatMessage("Вы отменили наказание", -1)
        end
        until isKeyJustPressed(VK_F2) or isKeyJustPressed(VK_F3)
        end)
    end
end

Помогите если не сложно пж
 

Oreshka23

Известный
338
164
а можно как то сделать что бы он искать тоже текст /kick 15 DM только под Сaps Lock
Например: /KICK 15 DM

Код:
function ev.onServerMessage(color, msg)
    if msg:find("%a+_%a+%[%d+%]: /kick%s*%d+.+") then
        msg1 = msg
        lua_thread.create(function()
        local surname, id, reason = msg1:match("_(%a+)%[%d+%]: /kick%s*(%d+)%s*(.+)")
        wait(0)
        sampAddChatMessage("Нажмите \"F2\" чтобы принять наказание и \"F3\" чтобы отменить наказание", -1)
        repeat
        wait(0)
        if isKeyJustPressed(VK_F2) then
            sampAddChatMessage("Вы приняли наказание", -1)
            sampAddChatMessage("/kick "..id.." "..reason.." | "..surname.."",-1)
        elseif isKeyJustPressed(VK_F3) then
            sampAddChatMessage("Вы отменили наказание", -1)
        end
        until isKeyJustPressed(VK_F2) or isKeyJustPressed(VK_F3)
        end)
    end
end

Помогите если не сложно пж
Lua:
if msg:find("%a+_%a+%[%d+%]: /kick%s*%d+.+") or msg:find("%a+_%a+%[%d+%]: /KICK%s*%d+.+") then
 

NeathA

Новичок
45
4
Id первого диалога есть?

Lua:
local sampev = require "samp.events"

function sampev.onShowDialog(dialogId, style, title, button1, button2, text)
  if enabled and dialogId == 29101 then sampSendDialogResponse(29101, 0, 0, "1000") return false end
end

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(0) end
    while not sampIsLocalPlayerSpawned() do wait(0) end
    sampRegisterChatCommand("azino777", casic)

  while true do wait(0)
    if enabled then
      setGameKeyState(15, 255)
      wait(200)
      sampCloseCurrentDialogWithButton(1)
      wait(200)
      sampSendClickTextdraw(309)
      wait(15100)
    end
  end
end

function casic()
 enabled = not enabled
  if enabled then
    sampAddChatMessage("123", 0xFFFFFF)
  else
    sampAddChatMessage("456", 0xFFFFFF)
  end
end
Айди первого диалога 29100
А так, вечером попробую. Благодарю.
 

Cameron_Bawerman

Участник
99
1
Как сделать тогда что бы он искал последние /kick 15 DM а не по всему чату?

Lua:
function ev.onServerMessage(color, msg)
    if msg:find("%a+_%a+%[%d+%]: /kick%s*%d+.+") then
        msg1 = msg
        lua_thread.create(function()
        local surname, id, reason = msg1:match("_(%a+)%[%d+%]: /kick%s*(%d+)%s*(.+)")
        wait(0)
        sampAddChatMessage("Нажмите \"F2\" чтобы принять наказание и \"F3\" чтобы отменить наказание", -1)
        repeat
        wait(0)
        if isKeyJustPressed(VK_F2) then
            sampAddChatMessage("Вы приняли наказание", -1)
            sampAddChatMessage("/kick "..id.." "..reason.." | "..surname.."",-1)
        elseif isKeyJustPressed(VK_F3) then
            sampAddChatMessage("Вы отменили наказание", -1)
        end
        until isKeyJustPressed(VK_F2) or isKeyJustPressed(VK_F3)
        end)
    end
end
 

WebDim

Участник
59
3
Прошу помощи по:
Lua:
INCOMING_RPCS[RPC.SHOWTEXTDRAW] = {'onShowTextDraw', handler.on_show_textdraw_reader, handler.on_show_textdraw_writer}
Как обращаться к "handler.on_show_textdraw_reader" или "handler.on_show_textdraw_reader"
 

ШPEK

Известный
1,476
525
Лично мне очень сложно понять данную инфу с помощью гугла, а бесплатную загрузку книги я не нашёл(если знаешь где скачать, пиши)

--------------------------------------------------------------------------------------------------------------------------

Если брать время из интернета, то оно может оказаться точнее серверного времени. И да - для меня брать время из интернета будет проще, чем из тайма из-за выше затронутой причины.

--------------------------------------------------------------------------------------------------------------------------

Возможно, что кому-то данная инфа пригодится, но, думаю, что тому, кто изначально задал сей вопрос это совсем не нужно.

--------------------------------------------------------------------------------------------------------------------------

Lua:
function sampev.onSendEnterVehicle(vehicleID, passenger)
      -- что-то
end
http://f.aui.su/data/uploads/lua-2015.pdf плохо искал
 

ШPEK

Известный
1,476
525
Как сделать тогда что бы он искал последние /kick 15 DM а не по всему чату?

Lua:
function ev.onServerMessage(color, msg)
    if msg:find("%a+_%a+%[%d+%]: /kick%s*%d+.+") then
        msg1 = msg
        lua_thread.create(function()
        local surname, id, reason = msg1:match("_(%a+)%[%d+%]: /kick%s*(%d+)%s*(.+)")
        wait(0)
        sampAddChatMessage("Нажмите \"F2\" чтобы принять наказание и \"F3\" чтобы отменить наказание", -1)
        repeat
        wait(0)
        if isKeyJustPressed(VK_F2) then
            sampAddChatMessage("Вы приняли наказание", -1)
            sampAddChatMessage("/kick "..id.." "..reason.." | "..surname.."",-1)
        elseif isKeyJustPressed(VK_F3) then
            sampAddChatMessage("Вы отменили наказание", -1)
        end
        until isKeyJustPressed(VK_F2) or isKeyJustPressed(VK_F3)
        end)
    end
end
Поставь $ в конце будет выглядить вот так
Lua:
%a+_%a+%[%d+%]: /kick%s*%d+.+$
p.s $ - это конец, ^ начало строки timestamp не входит в строку]

-----------------------------------------------------------------------------------------------------

а можно как то сделать что бы он искать тоже текст /kick 15 DM только под Сaps Lock
Например: /KICK 15 DM

Lua:
function ev.onServerMessage(color, msg)
    if msg:find("%a+_%a+%[%d+%]: /kick%s*%d+.+") then
        msg1 = msg
        lua_thread.create(function()
        local surname, id, reason = msg1:match("_(%a+)%[%d+%]: /kick%s*(%d+)%s*(.+)")
        wait(0)
        sampAddChatMessage("Нажмите \"F2\" чтобы принять наказание и \"F3\" чтобы отменить наказание", -1)
        repeat
        wait(0)
        if isKeyJustPressed(VK_F2) then
            sampAddChatMessage("Вы приняли наказание", -1)
            sampAddChatMessage("/kick "..id.." "..reason.." | "..surname.."",-1)
        elseif isKeyJustPressed(VK_F3) then
            sampAddChatMessage("Вы отменили наказание", -1)
        end
        until isKeyJustPressed(VK_F2) or isKeyJustPressed(VK_F3)
        end)
    end
end

Помогите если не сложно пж

%D тебе в помощь, будет искать любые буквы, символы кроме цифр
 
Последнее редактирование:

Cameron_Bawerman

Участник
99
1
Все ровно вот я кидаю в чат 2 прозьбы
и он по двум прозьбам кикает а не последнию
Lua:
if msg:find("%a+_%a+%[%d+%]: /kick%s*%d+.+$") then
        msg1 = msg
        lua_thread.create(function()
        local surname, id, reason = msg1:match("_(%a+)%[%d+%]: /kick%s*(%d+)%s*(.+)")
        wait(0)
        sampAddChatMessage("• {"..DB4.."}["..scriptname.." | Подсказка] {"..Wbe.."}Прозьба прописать команду: {"..Wvc.."}/kick "..id.." "..reason.."",-1)
        sampAddChatMessage("• {"..DB4.."}["..scriptname.." | Подсказка] {"..Wbe.."}Нажмите {7FFF00}Alt+Y {"..Wbe.."}для одобрение или {FC2847}Alt+N {"..Wbe.."}для отказа",-1)
        repeat
        wait(0)
        if isKeyDown(VK_MENU) and isKeyJustPressed(VK_Y) then
            sampAddChatMessage("• {"..DB4.."}["..scriptname.." | Информация] {"..Wbe.."}Вы приняли прозьбу", -1)
            sampAddChatMessage("/kick "..id.." "..reason.." | "..surname.."",-1)
        elseif isKeyDown(VK_MENU) and isKeyJustPressed(VK_N) then
            sampAddChatMessage("• {"..DB4.."}["..scriptname.." | Информация] {"..Wbe.."}Вы отказали прозьбу", -1)
        end
        until isKeyDown(VK_MENU) and isKeyJustPressed(VK_Y) or isKeyDown(VK_MENU) and isKeyJustPressed(VK_N)
        end)
    end
 
Последнее редактирование:
  • Нравится
Реакции: skillpz

ШPEK

Известный
1,476
525
как узнать в каком райне находится игрок?
либо GxtString nameB = getNameOfInfoZone(float atX, float atY, float atZ)
либо GxtString name = getNameOfZone(float X, float Y, float Z)
------------------------------------------------------------------------------------------
Зачем???
Посмотреть вложение 16787
 

checkdasound

Известный
Проверенный
963
407
Как сделать, чтобы было ограничение по количеству символов в InputText в имуги?
 
  • Нравится
Реакции: ШPEK

Cameron_Bawerman

Участник
99
1
либо GxtString nameB = getNameOfInfoZone(float atX, float atY, float atZ)
либо GxtString name = getNameOfZone(float X, float Y, float Z)
------------------------------------------------------------------------------------------

Зачем???
Посмотреть вложение 16787
Это тестил
если типо причины нету то он не давал выдавать, но на это пофиг вот как последнию сделать то?