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

cover

Известный
Проверенный
245
273
Как прочитать данные из файла(.path), в который побайтово записана информация ?

CLEO:
0A9E: writefile 0@ size 16 from 1@

В клео читал вот таким способом:

CLEO:
0A9D: readfile 0@ size 4 to 1@
0A9D: readfile 0@ size 4 to 2@
0A9D: readfile 0@ size 4 to 3@
0A9D: readfile 0@ size 4 to 4@
 

iqmaloy

Новичок
4
0
Здравствуйте уважаемые кодеры. Вопрос таков: Можете дать LUA скрипт, в котором будет 2 диалога. А то я вожусь, вожусь и ничего не получается.

Я сделал диалог в MAIN, как создать новый?

script_name("Leader Helper v1.0")
script_description("Leader Helper for Pears-Project")
script_version_number(1)
script_version("1.0")
script_authors("iqmaloy")

--- Меню гос. волны

function main()
while not isSampfuncsLoaded() do
wait(1000)
end
sampRegisterChatCommand("/menu", openmenu)
sampRegisterChatCommand("/gmenu", openmenu)

while true do
wait(0)
local resultMain, buttonMain, listMain = sampHasDialogRespond(109)
if resultMain == true then
if buttonMain == 1 then
if listMain == 0 then
sampSendChat(string.format("/d [Пра-во] Разрешите занять Ваше время?", id))
end
if listMain == 1 then
sampSendChat(string.format("/d [FBI] Разрешите занять Ваше время?", id))
end
if listMain == 2 then
sampSendChat(string.format("/d [Army] Разрешите занять Ваше время?", id))
end
if listMain == 3 then
sampSendChat(string.format("/d [PD] Разрешите занять Ваше время?", id))
end
if listMain == 4 then
sampSendChat(string.format("/d [CNN] Разрешите занять Ваше время?", id))
end
end
end
end
end

function openmenu()
sampShowDialog(109, "{ff7068}[L] {ffffff}Гос. волна", string.format("Правительство \nFBI \nArmy \nLSPD/SFPD \nCNN"), "Ok", "Exit", 2)
end

Дайте пожалуйста код, с новым диалогом. И объясните по полочке, как создавать ещё диалоги или новые команды.
 

imring

Ride the Lightning
Всефорумный модератор
2,355
2,516
Lua:
script_name("Leader Helper v1.0")
script_description("/gmenu")
script_version_number(1)
script_version("1.0")
script_authors("iqmaloy")
--- Помог imring :D
--- Меню гос. волны

function main()
while not isSampAvailable() do
wait(1000)
end
sampRegisterChatCommand("gmenu", openmenu)
while true do
wait(0)
local resultMain, buttonMain, listMain = sampHasDialogRespond(109)
if resultMain == true then
if buttonMain == 1 then
if listMain == 0 then
sampSendChat("/d [Пра-во] Разрешите занять Ваше время?") 
end
if listMain == 1 then
sampSendChat("/d [FBI] Разрешите занять Ваше время?") 
end
if listMain == 2 then
sampSendChat("/d [Army] Разрешите занять Ваше время?") 
end
if listMain == 3 then
sampSendChat("/d [PD] Разрешите занять Ваше время?") 
end
if listMain == 4 then
sampSendChat("/d [CNN] Разрешите занять Ваше время?") 
end
end
end
end
end

function openmenu()
sampShowDialog(109, "{ff7068}[L] {ffffff}Гос. волна", "Правительство \nFBI \nArmy \nPD \nCNN", "Ok", "Exit", 2)
end
Команда: [ /gmenu ]
 

iqmaloy

Новичок
4
0
Lua:
script_name("Leader Helper v1.0")
script_description("/gmenu")
script_version_number(1)
script_version("1.0")
script_authors("iqmaloy")
--- Помог imring :D
--- Меню гос. волны

function main()
while not isSampAvailable() do
wait(1000)
end
sampRegisterChatCommand("gmenu", openmenu)
while true do
wait(0)
local resultMain, buttonMain, listMain = sampHasDialogRespond(109)
if resultMain == true then
if buttonMain == 1 then
if listMain == 0 then
sampSendChat("/d [Пра-во] Разрешите занять Ваше время?")
end
if listMain == 1 then
sampSendChat("/d [FBI] Разрешите занять Ваше время?")
end
if listMain == 2 then
sampSendChat("/d [Army] Разрешите занять Ваше время?")
end
if listMain == 3 then
sampSendChat("/d [PD] Разрешите занять Ваше время?")
end
if listMain == 4 then
sampSendChat("/d [CNN] Разрешите занять Ваше время?")
end
end
end
end
end

function openmenu()
sampShowDialog(109, "{ff7068}[L] {ffffff}Гос. волна", "Правительство \nFBI \nArmy \nPD \nCNN", "Ok", "Exit", 2)
end
Команда: [ /gmenu ]

Ты не понял, 1 диалог я создал. Он работает, как мне создать ещё один диалог в этом же LUA скрипте? Например, чтобы это было главное меню. В нём несколько пунктов, я жму на первый пункт "Меню гос. волны" и оно перекидывает на 109 диалог.(Где "разрешите занять волну").

И можешь расписать, как создавать ещё новые команды, по типу: пишу "//invite <ID>" - а оно отыгрывает и потом идёт инвайт и айди который указал.
 

imring

Ride the Lightning
Всефорумный модератор
2,355
2,516
Ты не понял, 1 диалог я создал. Он работает, как мне создать ещё один диалог в этом же LUA скрипте? Например, чтобы это было главное меню. В нём несколько пунктов, я жму на первый пункт "Меню гос. волны" и оно перекидывает на 109 диалог.(Где "разрешите занять волну").

И можешь расписать, как создавать ещё новые команды, по типу: пишу "//invite <ID>" - а оно отыгрывает и потом идёт инвайт и айди который указал.


Lua:
script_name("Leader Helper v1.0")
script_description("/gmenu")
script_version_number(1)
script_version("1.0")
script_authors("iqmaloy")

-- Помог [ imring ]

function main()
    while not isSampAvailable() dowait(1000) end
    sampRegisterChatCommand("llmenu", leadMenu)
    sampRegisterChatCommand("invite", leadInvite)
    while true do
        wait(0)
        local resultMain, buttonMain, listMain = sampHasDialogRespond(109)
        if resultMain == true and buttonMain == 1 then
            if listMain == 0 then
                sampShowDialog(109, "{ff7068}[L] {ffffff}Гос. волна", "Пра-во [GOV]\nФБР [FBI\nАрмия [NGSA]\nПолиция [PD]\nАгенство Новостей [CNN]", "Далее", "Закрыть", 2)
            end
        end
        local resultMain, buttonMain, listMain = sampHasDialogRespond(109)
        if resultMain == true and buttonMain == 1 then
            if listMain == 0 then sampSendChat("/d to GOV | Разрешите занять Ваше время?") end
            if listMain == 1 then sampSendChat("/d to FBI | Разрешите занять Ваше время?") end
            if listMain == 2 then sampSendChat("/d to NGSA | Разрешите занять Ваше время?") end
            if listMain == 3 then sampSendChat("/d to PD | Разрешите занять Ваше время?") end
            if listMain == 4 then sampSendChat("/d to CNN | Разрешите занять Ваше время?") end
        end
    end
end

function leadMenu() sampShowDialog(108, "{ff7068}[L] {ffffff}Меню Лидера", "Попросить гос. волну\nСвой текст\nСвой текст", "Далее", "Закрыть", 2) end

function leadInvite(id)
    local idplayer = string.match(id, '(%d+)')
    if idplayer ~= nil then
        -- Отыгровка
        sampSendChat(string.format("/invite %d", idplayer))
    else sampSendChat("/invite") end
end
Команды: [ /llmenu ] [ /invite ]

p.s. Для Pears Project уже есть подобное, название leadFAST (на этом форуме его нету, он на форуме сервера Pears Project)
 

FYP

Известный
Автор темы
Администратор
1,758
5,722
Как прочитать данные из файла(.path), в который побайтово записана информация ?

CLEO:
0A9E: writefile 0@ size 16 from 1@

В клео читал вот таким способом:

CLEO:
0A9D: readfile 0@ size 4 to 1@
0A9D: readfile 0@ size 4 to 2@
0A9D: readfile 0@ size 4 to 3@
0A9D: readfile 0@ size 4 to 4@
Lua:
local f = io.open('file.path', 'rb')
local v1 = f:read(4)
для чтения чисел результат чтения нужно преобразовывать из бинарных данных в число, а лучше всего сделать структуру и работать с данными с помощью FFI.
 

HURACAN

Известный
42
3
Lua:
script_name("Leader Helper v1.0")
script_description("/gmenu")
script_version_number(1)
script_version("1.0")
script_authors("iqmaloy")

-- Помог [ imring ]

function main()
    while not isSampAvailable() dowait(1000) end
    sampRegisterChatCommand("llmenu", leadMenu)
    sampRegisterChatCommand("invite", leadInvite)
    while true do
        wait(0)
        local resultMain, buttonMain, listMain = sampHasDialogRespond(109)
        if resultMain == true and buttonMain == 1 then
            if listMain == 0 then
                sampShowDialog(109, "{ff7068}[L] {ffffff}Гос. волна", "Пра-во [GOV]\nФБР [FBI\nАрмия [NGSA]\nПолиция [PD]\nАгенство Новостей [CNN]", "Далее", "Закрыть", 2)
            end
        end
        local resultMain, buttonMain, listMain = sampHasDialogRespond(109)
        if resultMain == true and buttonMain == 1 then
            if listMain == 0 then sampSendChat("/d to GOV | Разрешите занять Ваше время?") end
            if listMain == 1 then sampSendChat("/d to FBI | Разрешите занять Ваше время?") end
            if listMain == 2 then sampSendChat("/d to NGSA | Разрешите занять Ваше время?") end
            if listMain == 3 then sampSendChat("/d to PD | Разрешите занять Ваше время?") end
            if listMain == 4 then sampSendChat("/d to CNN | Разрешите занять Ваше время?") end
        end
    end
end

function leadMenu() sampShowDialog(108, "{ff7068}[L] {ffffff}Меню Лидера", "Попросить гос. волну\nСвой текст\nСвой текст", "Далее", "Закрыть", 2) end

function leadInvite(id)
    local idplayer = string.match(id, '(%d+)')
    if idplayer ~= nil then
        -- Отыгровка
        sampSendChat(string.format("/invite %d", idplayer))
    else sampSendChat("/invite") end
end
Команды: [ /llmenu ] [ /invite ]

p.s. Для Pears Project уже есть подобное, название leadFAST (на этом форуме его нету, он на форуме сервера Pears Project)
не робит :C
 

HURACAN

Известный
42
3
Помогите..
Первый пункт работает, все пишет в чат норм, но как сделать, чтобы свой текст открывался так же?
Lua:
script_name("Leader Helper v1.0")
script_description("/gmenu")
script_version_number(1)
script_version("1.0")
script_authors("iqmaloy")
-- Помог [ imring ]
function main()
while not isSampAvailable() do wait(1000) end
sampRegisterChatCommand("llmenu", leadMenu)
while true do
wait(0)
local resultMain, buttonMain, listMain = sampHasDialogRespond(109)
if resultMain == true and buttonMain == 1 then
if listMain == 0 then
sampShowDialog(110, "{ff7068}[L] {ffffff}Гос. волна", "Пра-во [GOV]\nФБР [FBI\nАрмия [NGSA]\nПолиция [PD]\nАгенство Новостей [CNN]", "Далее", "Закрыть", 2)
end
end
local resultMain, buttonMain, listMain = sampHasDialogRespond(110)
if resultMain == true and buttonMain == 1 then
if listMain == 0 then sampSendChat("to GOV | Разрешите занять Ваше время?") end
if listMain == 1 then sampSendChat("to FBI | Разрешите занять Ваше время?") end
if listMain == 2 then sampSendChat("to NGSA | Разрешите занять Ваше время?") end
if listMain == 3 then sampSendChat("to PD | Разрешите занять Ваше время?") end
if listMain == 4 then sampSendChat("to CNN | Разрешите занять Ваше время?") end
end
end
end
function leadMenu() sampShowDialog(109, "{ff7068}[L] {ffffff}Меню Лидера", "Попросить гос. волну\nСвой текст\nСвой текст", "Далее", "Закрыть", 2) end
 

imring

Ride the Lightning
Всефорумный модератор
2,355
2,516
Помогите..
Первый пункт работает, все пишет в чат норм, но как сделать, чтобы свой текст открывался так же?
Lua:
script_name("Leader Helper v1.0")
script_description("/gmenu")
script_version_number(1)
script_version("1.0")
script_authors("iqmaloy")
-- Помог [ imring ]
function main()
while not isSampAvailable() do wait(1000) end
sampRegisterChatCommand("llmenu", leadMenu)
while true do
wait(0)
local resultMain, buttonMain, listMain = sampHasDialogRespond(109)
if resultMain == true and buttonMain == 1 then
if listMain == 0 then
sampShowDialog(110, "{ff7068}[L] {ffffff}Гос. волна", "Пра-во [GOV]\nФБР [FBI\nАрмия [NGSA]\nПолиция [PD]\nАгенство Новостей [CNN]", "Далее", "Закрыть", 2)
end
end
local resultMain, buttonMain, listMain = sampHasDialogRespond(110)
if resultMain == true and buttonMain == 1 then
if listMain == 0 then sampSendChat("to GOV | Разрешите занять Ваше время?") end
if listMain == 1 then sampSendChat("to FBI | Разрешите занять Ваше время?") end
if listMain == 2 then sampSendChat("to NGSA | Разрешите занять Ваше время?") end
if listMain == 3 then sampSendChat("to PD | Разрешите занять Ваше время?") end
if listMain == 4 then sampSendChat("to CNN | Разрешите занять Ваше время?") end
end
end
end
function leadMenu() sampShowDialog(109, "{ff7068}[L] {ffffff}Меню Лидера", "Попросить гос. волну\nСвой текст\nСвой текст", "Далее", "Закрыть", 2) end

Lua:
local resultMain, buttonMain, listMain = sampHasDialogRespond(109) 
if resultMain == true and buttonMain == 1 then 
 if listMain == 0 then
sampShowDialog(110, "{ff7068}[L] {ffffff}Гос. волна", "Пра-во [GOV]\nФБР [FBI\nАрмия [NGSA]\nПолиция [PD]\nАгенство Новостей [CNN]", "Далее", "Закрыть", 2) 
end 
if listMain == 1 then 
--Свой код 
end 
end
 

HURACAN

Известный
42
3
Lua:
local resultMain, buttonMain, listMain = sampHasDialogRespond(109)
if resultMain == true and buttonMain == 1 then
 if listMain == 0 then
sampShowDialog(110, "{ff7068}[L] {ffffff}Гос. волна", "Пра-во [GOV]\nФБР [FBI\nАрмия [NGSA]\nПолиция [PD]\nАгенство Новостей [CNN]", "Далее", "Закрыть", 2)
end
if listMain == 1 then
--Свой код
end
end
-
ne robit

Помогите..
Первый пункт работает, все пишет в чат норм, но как сделать, чтобы 2 пункт (свой текст) открывался так же?
Lua:
script_name("Leader Helper v1.0")
script_description("/gmenu")
script_version_number(1)
script_version("1.0")
script_authors("iqmaloy")
-- Помог [ imring ]
function main()
while not isSampAvailable() do wait(1000) end
sampRegisterChatCommand("llmenu", leadMenu)
while true do
wait(0)
local resultMain, buttonMain, listMain = sampHasDialogRespond(109)
if resultMain == true and buttonMain == 1 then
if listMain == 0 then
sampShowDialog(110, "{ff7068}[L] {ffffff}Гос. волна", "Пра-во [GOV]\nФБР [FBI\nАрмия [NGSA]\nПолиция [PD]\nАгенство Новостей [CNN]", "Далее", "Закрыть", 2)
end
end
local resultMain, buttonMain, listMain = sampHasDialogRespond(110)
if resultMain == true and buttonMain == 1 then
if listMain == 0 then sampSendChat("to GOV | Разрешите занять Ваше время?") end
if listMain == 1 then sampSendChat("to FBI | Разрешите занять Ваше время?") end
if listMain == 2 then sampSendChat("to NGSA | Разрешите занять Ваше время?") end
if listMain == 3 then sampSendChat("to PD | Разрешите занять Ваше время?") end
if listMain == 4 then sampSendChat("to CNN | Разрешите занять Ваше время?") end
end
end
end
function leadMenu() sampShowDialog(109, "{ff7068}[L] {ffffff}Меню Лидера", "Попросить гос. волну\nСвой текст\nСвой текст", "Далее", "Закрыть", 2) end
 
Последнее редактирование модератором:

makasinuch

Новичок
52
4
Как занести нужное мне количество текста в таблицу ( Например: 1) FCR 2) PCJ 3)...) и после проверять этот текст функцией if string.find(str, "FCR", 0, true) ~= nil then. Нужно проверять именно текст!
 

4el0ve4ik

Известный
Всефорумный модератор
1,548
1,338
Как занести нужное мне количество текста в таблицу ( Например: 1) FCR 2) PCJ 3)...) и после проверять этот текст функцией if string.find(str, "FCR", 0, true) ~= nil then. Нужно проверять именно текст!
Lua:
local model= {
    [1] = "FCR",
    [2] = "PCJ",
    [3] = "..."
}