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

Double Tap Inside

Известный
Проверенный
1,916
1,256
Может у кого-то есть аналог printStringNow() на рендерах? чтобы я снова не изобретал велосипед.
Хочу в том же месте и с такими же выравниванием размещать текст на русском.

45125
 

astynk

Известный
Проверенный
741
532
Как узнать ид гана который у меня в руках?
Lua:
getCurrentCharWeapon(1)
Может у кого-то есть аналог printStringNow() на рендерах? чтобы я снова не изобретал велосипед.
Хочу в том же месте и с такими же выравниванием размещать текст на русском.

Посмотреть вложение 45125
 

Angr

Известный
291
99
Блин, а для полученного ид авто написать таблицу, типо если допустим ид авто 411 то вместо ида будет название авто т.е Инфернус?

Пытался это сделать по типу этого:
Код:
function GetZone()
    local x, y, z = GetCoordinates()
    local znnm = getNameOfZone(x, y, z)
    for k, v in pairs(zones) do znnm = znnm:gsub(k, v) end
    return znnm
end



zones =
{
    ['PER1'] = "Pershing Square",
    ['SAN_AND'] = "San Andreas",
    ['COM'] = "Commercial Area",
    ['BLUF'] = "Verdant Bluffs",
    ['LMEX'] = "Little Mexico",
    ['ELCO'] = "El Corona",
    ['CONF'] = "Conference Center",
    ['VERO'] = "Verona Beach",
    ['MAR'] = "Cause",
    ['SMB'] = "Santa Maria Beach",
    ['ROD'] = "Rodeo Drive",
    ['LA'] = "Los Santos",
    ['LAIR'] = "LS Airport",
    ['LDT'] = "Los Santos Center",
    ['MULINT'] = "Mallholland Crossroads",
    ['GLN'] = "Glen Park",
    ['CHC'] = "Las Colinas",
    ['JEF'] = "Jefferson",
    ['ELS'] = "East Los Santos",
    ['LFL'] = "Las Flores",
    ['EBE'] = "East Beach",
    ['LIND'] = "Willowfield",
    ['PLS'] = "Sevilles Boulevard",
    ['LDOC'] = "Los Santos Port",
    ['MKT'] = "Market",
    ['CauseKST'] = "Cause 'Market'",
    ['VIN'] = "Vinewood Street",
    ['SUN'] = "Temple Drive",
    ['MUL'] = "Mallholland"
}
Model ты уже получил
Lua:
GxtString name = getNameOfVehicleModel(Model model)
 

Kotovasya

Участник
85
13
Есть ли функция, проверяющая, находится ли игрок в режиме прицеливания с пассажирского места (H)?
 

Уникод

Потрачен
19
17
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
как сделать что бы после 5 секунд скрипт сам выключался
wait(5000)
thisScript():unload()
Есть ли функция, проверяющая, находится ли игрок в режиме прицеливания с пассажирского места (H)?
Только проверять на анимацию
 

Adler

Участник
38
14
Возможно ли считать и сверить весь текст со всех строк из imgui.InputTextMultiline?
Я использовал вот это.
Lua:
if bles1.v == test then
Я делал и так.
Lua:
test = [[
first line
two line
three line]]
В итоге считывал успешно только первую строку, а именно, если сделать так.
Lua:
test = [[
first line]]
 

Musaigen

abobusnik
Проверенный
1,620
1,404
Возможно ли считать и сверить весь текст со всех строк из imgui.InputTextMultiline?
Я использовал вот это.
Lua:
if bles1.v == test then
Я делал и так.
Lua:
test = [[
first line
two line
three line]]
В итоге считывал успешно только первую строку, а именно, если сделать так.
Lua:
test = [[
first line]]
Lua:
for line in string.gmatch(input_text.v, "[^\r\n]+") do
    print(line)
end
 
  • Нравится
Реакции: Adler

Adler

Участник
38
14
Как нажимать на строку в диалоге с названием ("Репорт")
Только samp.lua не забудь подключить к скрипту.
Lua:
function hook.onShowDialog(id, style, title, button1, button2, text)
    if id == ... then -- id диалога
        sampSendDialogResponse(..., 1, .., -1) -- заместо ... - id диалога, .. - строку от нуля в диалоге.
    end
end
Если ты про заголовок, то.
Lua:
function hook.onShowDialog(id, style, title, button1, button2, text)
    if title == 'Репорт' then
        sampSendDialogResponse(..., 1, .., -1) -- заместо ... - id диалога, .. - строку от нуля в диалоге.
    end
end
 
  • Нравится
Реакции: Fabregoo

Fabregoo

Известный
656
129
Только samp.lua не забудь подключить к скрипту.
Lua:
function hook.onShowDialog(id, style, title, button1, button2, text)
    if id == ... then -- id диалога
        sampSendDialogResponse(..., 1, .., -1) -- заместо ... - id диалога, .. - строку от нуля в диалоге.
    end
end
Если ты про заголовок, то.
Lua:
function hook.onShowDialog(id, style, title, button1, button2, text)
    if title == 'Репорт' then
        sampSendDialogResponse(..., 1, .., -1) -- заместо ... - id диалога, .. - строку от нуля в диалоге.
    end
end
Немного разъясню на аризоне на контрабанде, допустим цевьё и наркотики, каждый раз меняют строки, можно ли не по номеру строки, а по названию?...
 

S-Sirius

Известный
351
21
Код:
sampRegisterChatCommand("heal", heal)
local id1 = tonumber(heal)

function heal()
        lua_thread.create(function()
    sampSendChat("/todo Хорошо, я выпишу Вам лекарство, оно поможет в течении двух минут.*протянув руку к мед. сумке.")
    wait(2000)
    sampSendChat("/me открыл медицинскую сумку и достал оттуда упаковку таблеток.")
    wait(2000)
    sampSendChat("/me выдавил одну таблетку из пластинки, затем передал ее пациенту.")
    wait(2000)
    sampSendChat("/todo Держите, оплату произведете в регистратуре*передавая таблетку пациенту.")
    sampSendChat('/heal'..id1)
        end)
end
допустим пишу /heal [id] всё нормально отыгровка идёт но sampSendChat('/heal'..id1) не выбивает
function heal(param)
--kod
sampSendChat('/heal'..param)
 
Последнее редактирование:

Warflex

Участник
158
17
function heal(param)
--kod
sampSendChat('/heal'..param)

______________________________________________________________________________________________________

Добрый день. Писал скрипт для обмена сообщениями с ВК на SAMP и обратно. Допустим писал в чат что то, бот его отправит в беседу ВК а если писал что в в беседу то отправляет в самп, но бот не не отправляет свои сообщения в самп. Как делать так чтобы когда пишу в чат самп сообщение бот его отправил в беседу ВК а с беседы в самп чате?

Lua:
function threadHandle(runner, url, args, resolve, reject) -- обработка effil потока без блокировок
    local t = runner(url, args)
    local r = t:get(0)
    while not r do
        r = t:get(0)
        wait(0)
    end
    local status = t:status()
    if status == 'completed' then
        local ok, result = r[1], r[2]
        if ok then resolve(result) else reject(result) end
    elseif err then
        reject(err)
    elseif status == 'canceled' then
        reject(status)
    end
    t:cancel(0)
end

function requestRunner() -- создание effil потока с функцией https запроса
    return effil.thread(function(u, a)
        local https = require 'ssl.https'
        local ok, result = pcall(https.request, u, a)
        if ok then
            return {true, result}
        else
            return {false, result}
        end
    end)
end

function async_http_request(url, args, resolve, reject)
    local runner = requestRunner()
    if not reject then reject = function() end end
    lua_thread.create(function()
        threadHandle(runner, url, args, resolve, reject)
    end)
end

local vkerr, vkerrsend -- сообщение с текстом ошибки, nil если все ок


function loop_async_http_request(url, args, reject)
    local runner = requestRunner()
    lua_thread.create(function()
        while true do
            while not key do wait(0) end
            url = server .. '?act=a_check&key=' .. key .. '&ts=' .. ts .. '&wait=25' --меняем url каждый новый запрос потокa, так как server/key/ts могут изменяться
            threadHandle(runner, url, args, longpollResolve, reject)
        end
    end)
end

function longpollResolve(result)
    if result then
        if not result:sub(1,1) == '{' then
            vkerr = 'Ошибка!\nПричина: Нет соединения с VK!'
            return
        end
            for k, v in ipairs(t.updates) do
                if v.type == 'message_new' then
                    local text = v.object.text .. ' ' --костыль на случай если одна команда является подстрокой другой (!d и !dc как пример)
                    text = text:sub(1, text:len() - 1)
                        sampAddChatMessage("{20997c}[SVC]: {0088ff}ВКонтакте {ffffff}| {333333}Основатель{ffffff}:{98fb98} "..u8:decode(text), 0x20997cff)
                    end
                end
        end
end

function longpollGetKey()
    async_http_request('https://api.vk.com/method/groups.getLongPollServer?group_id='..group_id..'&access_token='..group_token..'&v=5.80', '', function (result)
        if result then
            if not result:sub(1,1) == '{' then
                vkerr = 'Ошибка!\nПричина: Нет соединения с VK!'
                return
            end
            local t = decodeJson(result)
            if t.error then
                vkerr = 'Ошибка!\nКод: ' .. t.error.error_code .. ' Причина: ' .. t.error.error_msg
                return
            end
            server = t.response.server
            ts = t.response.ts
            key = t.response.key
            vkerr = nil
        end
    end)
end

function vk_request(msg)
    msg = msg:gsub('{......}', '')
    msg = u8(msg)
    msg = url_encode(msg)
    async_http_request('https://api.vk.com/method/messages.send', 'peer_id='..chat_id..'&message=' .. msg .. '&access_token='..group_token..'&v=5.80',
    function (result)
        local t = decodeJson(result)
        if not t then
            print(result)
            return
        end
        if t.error then
            vkerrsend = 'Ошибка!\nКод: ' .. t.error.error_code .. ' Причина: ' .. t.error.error_msg
            return
        end
        vkerrsend = nil
    end)
end
спасибо за помошь
как сделать в SampShowDialog цветной текст?
 
Последнее редактирование:
  • Нравится
Реакции: S-Sirius