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

_-Sasha-_

Новичок
24
1
Можно ли как-то заменить серверный диалог на свой?
То есть, понятно, что нужно перехватить пакет показа диалога с помощью SAMP.events - есть. Теперь нужно как-то отобразить диалог с помощью imgui. Вопрос: Как?
 

utmpL

Активный
309
65
Lua:
myNickname = sampGetPlayerNickname(select(2, sampGetPlayerIdByCharHandle(PLAYER_PED)))
Как при получении ника заменить символ "_" пробелом?
через твою функцию не очень получилось, но попробуй это
Lua:
_, myid = sampGetPlayerIdByCharHandle(playerPed)
mynick = sampGetPlayerNickname(myid):gsub('_', ' ')
 
  • Нравится
Реакции: 7PEX

dmitri4

Известный
452
79
Если во время работы скрипта умереть то на секунду появляешься в скине CJ, можно ли как то исправить?
 

Di3

Участник
432
20
Как получить количество мест в ТС по handle
И получить PED игроков находящихся на этих местах?
Рылся, чет не нашел эту функцию

Возможно ли заменить стандартный textdraw на ImGui? и как.
Да.
Я делал вот так

Lua:
function sampev.onShowTextDraw(idtextdraw,data)
if idtextdraw == 1234  then  -- Если открылся textdraw id 1234,то
        show_main_recon.v = true -- включает ImGui
return false -- не отображает TextDraw  c этим ид
end
end

Как сделать так , чтобы скрипт нажмил клавишу?
Lua:
setVirtualKeyDown(49,true) -- Зажать клавишу 1
setVirtualKeyDown(49,false) -- Отпустить клавишу 1
 
  • Нравится
Реакции: chikibamboni95 и Natami

Kotovasya

Участник
85
13
При выходе из игры, нужно что бы скрипт выполнил некий код (выход может быть и /q, и через меню, и alt+F4, и закрыв окно не находясь в игре). Возможно ли такое реализовать?
 

suouca

Новичок
68
11
При выходе из игры, нужно что бы скрипт выполнил некий код (выход может быть и /q, и через меню, и alt+F4, и закрыв окно не находясь в игре). Возможно ли такое реализовать?
onQuitGame()
sampProcessChatInput(zstring text)
[TBODY] [/TBODY]


Короче, в txt файле периодическая таблица. 118 строк примерно такого формата: 1 H Hydrogen Водород
хочу записать все это в таблицу по такой структуре:
Lua:
peridocTable[num] = {
        symbol,
        name1,
        name2
}
Я попытался сделать такое:
Lua:
peridocTable = {}
local f = io.open('moonloader/periodic.txt')
for line in f:lines() do
    local num, symbol, name1, name2 = string.match(line, '(%d+) (%s+) (%s+) (%s+)')
    peridocTable[num] = {
        symbol,
        name1,
        name2
    }
end
но в логе пишет что индекс таблицы = nil
как я понял, у меня проблемы с паттернами в string.match
помогите расставить их правильно
 

ufdhbi

Известный
Проверенный
1,455
861
onQuitGame()
sampProcessChatInput(zstring text)
[TBODY] [/TBODY]


Короче, в txt файле периодическая таблица. 118 строк примерно такого формата: 1 H Hydrogen Водород
хочу записать все это в таблицу по такой структуре:
Lua:
peridocTable[num] = {
        symbol,
        name1,
        name2
}
Я попытался сделать такое:
Lua:
peridocTable = {}
local f = io.open('moonloader/periodic.txt')
for line in f:lines() do
    local num, symbol, name1, name2 = string.match(line, '(%d+) (%s+) (%s+) (%s+)')
    peridocTable[num] = {
        symbol,
        name1,
        name2
    }
end
но в логе пишет что индекс таблицы = nil
как я понял, у меня проблемы с паттернами в string.match
помогите расставить их правильно
line:match('(.+) (.+) (.+) (.+)')
 
  • Нравится
Реакции: suouca

Cutler18

Известный
160
2
Lua:
local my_dialog = {
    {
        title = '{8B4513}Обыск',
        onclick = function()
            sampSendChat('/me просунул правую руку в сумочку, после достал резиновые перчатки из неё и одел их')
            wait(1500)
            sampSendChat('/me протянув обе руки в сторону подозреваемого, развёл его руки и ноги по обе стороны')
            wait(1500)
            sampSendChat('/me делая плавные движения руками, общупывает торс человека, пытаясь найти спрятанные предметы')
            wait(1500)
            sampSendChat('/me протянув обе руки в сторону подозреваемого, развёл его руки и ноги по обе стороны')
            wait(1500)
            sampSendChat('/anim 16')
            wait(1500)
                setVirtualKeyDown(0x10, true)
               wait(61)
               setVirtualKeyDown(0x10, false)
            sampSendChat('/me наклоняясь к земле, общупывает нижние части тела подозреваемого')
            wait(1500)
            sampSendChat('/anim 14')
            wait(1500)
            sampSendChat('/search '..id)
        end
    },
    {
        title = '{8B4513}Годен',
        onclick = function()
            sampSendChat('/me достал бланк призывника и ручку')
            wait(1000)
            sampSendChat('/me заполняет первый бланк')
            wait(1000)
            sampSendChat('/me заполняет второй бланк')
            wait(1000)
            sampSendChat('/me заполняет третий бланк')
            wait(1000)
            sampSendChat('/me поставил в бланке печать ГОДЕН')
            wait(1000)
            sampSendChat('/do Бланк призывника заполнен.')
            wait(1000)
            sampSendChat('Пройдемте за мной, Полковник или Генерал выдаст Вам форму.')
        end
    },
    {
        title = '{8B4513}Не годен',
            submenu = {
                {
                    title = '{FF0000}Бредит',
                        onclick = function()
                            sampSendChat('Не годны. Бредите')
                            wait(1000)
                            sampSendChat('/n Путаете реальную и информацию с игровой. Выучите что такое МГ')
                        end
                },
                {
                    title = '{FF0000}Розыск',
                        onclick = function()
                            sampSendChat('/me посмотрел ориентировки на стене')
                            wait(1000)
                            sampSendChat('/me сравнил ориентировку с человеком напротив и выявил сходство')
                            wait(1000)
                            sampSendChat('Вы находитесь в федеральном розыске.')
                            wait(1000)
                            sampSendChat('Покиньте военкомат, иначе мне придется позвонить в полицию.')
                        end
                }
            }
    },
}

function search(id)
local id = string.match(id, '(%d+)')
    if id ~= nil then
    submenus_show(my_dialog, '{FF0000}Обыск преступника')
    else
        sampAddChatMessage("Используйте: /search [id игрока]", 0x00FF00)
    end
end

почему вырубается? Функция submenus_show есть
 

штейн

Известный
Проверенный
1,001
687
Lua:
local my_dialog = {
    {
        title = '{8B4513}Обыск',
        onclick = function()
            sampSendChat('/me просунул правую руку в сумочку, после достал резиновые перчатки из неё и одел их')
            wait(1500)
            sampSendChat('/me протянув обе руки в сторону подозреваемого, развёл его руки и ноги по обе стороны')
            wait(1500)
            sampSendChat('/me делая плавные движения руками, общупывает торс человека, пытаясь найти спрятанные предметы')
            wait(1500)
            sampSendChat('/me протянув обе руки в сторону подозреваемого, развёл его руки и ноги по обе стороны')
            wait(1500)
            sampSendChat('/anim 16')
            wait(1500)
                setVirtualKeyDown(0x10, true)
               wait(61)
               setVirtualKeyDown(0x10, false)
            sampSendChat('/me наклоняясь к земле, общупывает нижние части тела подозреваемого')
            wait(1500)
            sampSendChat('/anim 14')
            wait(1500)
            sampSendChat('/search '..id)
        end
    },
    {
        title = '{8B4513}Годен',
        onclick = function()
            sampSendChat('/me достал бланк призывника и ручку')
            wait(1000)
            sampSendChat('/me заполняет первый бланк')
            wait(1000)
            sampSendChat('/me заполняет второй бланк')
            wait(1000)
            sampSendChat('/me заполняет третий бланк')
            wait(1000)
            sampSendChat('/me поставил в бланке печать ГОДЕН')
            wait(1000)
            sampSendChat('/do Бланк призывника заполнен.')
            wait(1000)
            sampSendChat('Пройдемте за мной, Полковник или Генерал выдаст Вам форму.')
        end
    },
    {
        title = '{8B4513}Не годен',
            submenu = {
                {
                    title = '{FF0000}Бредит',
                        onclick = function()
                            sampSendChat('Не годны. Бредите')
                            wait(1000)
                            sampSendChat('/n Путаете реальную и информацию с игровой. Выучите что такое МГ')
                        end
                },
                {
                    title = '{FF0000}Розыск',
                        onclick = function()
                            sampSendChat('/me посмотрел ориентировки на стене')
                            wait(1000)
                            sampSendChat('/me сравнил ориентировку с человеком напротив и выявил сходство')
                            wait(1000)
                            sampSendChat('Вы находитесь в федеральном розыске.')
                            wait(1000)
                            sampSendChat('Покиньте военкомат, иначе мне придется позвонить в полицию.')
                        end
                }
            }
    },
}

function search(id)
local id = string.match(id, '(%d+)')
    if id ~= nil then
    submenus_show(my_dialog, '{FF0000}Обыск преступника')
    else
        sampAddChatMessage("Используйте: /search [id игрока]", 0x00FF00)
    end
end

почему вырубается? Функция submenus_show есть
потому что задержку можно использовать только в потоках