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

ChаtGPT

Активный
403
97
как экранировать '/' в регулярке? XD


Если оружие на теле игрока
Lua:
bool result = isObjectAttached(Object object)
А вообще, если именно в руках оружие, то нужно перебирать игроков, а не объекты, т.к. в руке у перса не объект, а именно оружие
Lua:
local int = getCurrentCharWeapon(Ped ped)
ID оружий думаю прогуглить сможешь


лучше делай через рендеры, больше возможностей, меньше багов
что за рендеры? мне команда нужна текстдрава на изменение его фона и прозрачности (НЕ ТЕКСТАБ фона)
 

ARMOR

Мне кажется, я всё проебал
Модератор
5,018
7,092
что за рендеры? мне команда нужна текстдрава на изменение его фона и прозрачности (НЕ ТЕКСТАБ фона)
М...
Lua:
local ev = require 'lib.samp.events'

function ev.onShowTextDraw(id, data)
    if id == ид текстдрава then
        data.color = 0xFFFFFFFF
        return {id, data}
    end
end
 

T1cKz

Известный
595
245
что за рендеры? мне команда нужна текстдрава на изменение его фона и прозрачности (НЕ ТЕКСТАБ фона)
редактировать их нужно при появлении, а не после. в events библиотеке отслеживать появление и затем делать редактор(как это делать описали выше)
Lua:
INCOMING_RPCS[RPC.SHOWTEXTDRAW]               = {'onShowTextDraw',
  {textdrawId = 'uint16'},
  {textdraw = {
    {flags = 'uint8'},
    {letterWidth = 'float'},
    {letterHeight = 'float'},
    {letterColor = 'int32'},
    {lineWidth = 'float'},
    {lineHeight = 'float'},
    {boxColor = 'int32'},
    {shadow = 'uint8'},
    {outline = 'uint8'},
    {backgroundColor = 'int32'},
    {style = 'uint8'},
    {selectable = 'uint8'},
    {position = 'vector2d'},
    {modelId = 'uint16'},
    {rotation = 'vector3d'},
    {zoom = 'float'},
    {color = 'int32'},
    {text = 'string16'}
  }}
}

А прозрачность как?
Lua:
data.color = 0xFFFFFFFF -- Первые 2 - Прозрачность, дальше RGB (или наоборот)
 

ARMOR

Мне кажется, я всё проебал
Модератор
5,018
7,092
Неприемлемое поведение
А прозрачность как?
Ты заебешь сука, ты учи луа нахуй, а не выпрашивай фулл код блядь. Если ты не знаешь как работает HEX цвет, то чем я тебе помогу сука? Я вижу ты в этой теме только вопросы за вопросами задаешь.
 
  • Нравится
Реакции: YarikVL и IlyaHL2

T1cKz

Известный
595
245
Ты заебешь сука, ты учи луа нахуй, а не выпрашивай фулл код блядь. Если ты не знаешь как работает HEX цвет, то чем я тебе помогу сука? Я вижу ты в этой теме только вопросы за вопросами задаешь.
Не быкуй) Он же ещё не сеньор что бы уметь гуглить правильно XD
 

ARMOR

Мне кажется, я всё проебал
Модератор
5,018
7,092
Не быкуй) Он же ещё не сеньор что бы уметь гуглить правильно XD
Ты полистай эту тему, и посмотри насколько у него тупые вопросы, он не учит lua, он чисто выпрашивает код. И ещё люди что-то за Венни говорят
 

T1cKz

Известный
595
245
Ты полистай эту тему, и посмотри насколько у него тупые вопросы, он не учит lua, он чисто выпрашивает код. И ещё люди что-то за Венни говорят
Мой вопрос тоже тупой. Как экранировать / ? XD
Но по поводу скриптинга. я его +- так же учил, только потом додумался изучать библиотеки в lib и по их примерам тестить и писать софт)
 

ChаtGPT

Активный
403
97
Ты заебешь сука, ты учи луа нахуй, а не выпрашивай фулл код блядь. Если ты не знаешь как работает HEX цвет, то чем я тебе помогу сука? Я вижу ты в этой теме только вопросы за вопросами задаешь.
Я в текстдравах не шарю, в гугле одно pawno, больше спросить где нету, спрашваю обо всём, даже лишнее про запас
 
  • Bug
Реакции: YarikVL

PanSeek

t.me/dailypanseek
Всефорумный модератор
910
1,779
А прозрачность как?
В цвете и есть прозрачность.
0xFFFFFFFF - разбей 8 F на 4 части в парах, получится: FF FF FF FF

Первая пара отвечает за красный цвет
Вторая пара отвечает за зеленый цвет
Третья пара отвечает за синий цвет
Четвертая пара отвечает за прозрачность

Например тебе нужен красно-полупрозрачный цвет, будет вот так: 0xFF000080

P.S. Если не понимаешь, что такое FF, то это значение 255 в 16-ной сс (системе счисления), аналогично 0x00 (16сс) -> 0 (10сс).

На будущее: (UPD)
Стоит учесть, что не везде формат RGBA (Красный; Зеленый; Синий; Прозрачность), где-то просто RGB, где-то ARGB.
Ты можешь открыть библиотеку и нужный файл, скорее всего там и есть документация или информация которая тебе нужна. В данном случае: lib/samp/events.lua
 
  • Нравится
  • Влюблен
Реакции: YarikVL, Rice. и ChаtGPT

PanSeek

t.me/dailypanseek
Всефорумный модератор
910
1,779
почему не работает функция onShowDialog?
Lua:
require 'lib.moonloader'
local sampev = require 'lib.samp.events'

local enable = false

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
  
    sampAddChatMessage("[TPizzaBot]: {FFFFFF}Загружен. {FFFFFF}Активация/Деактивация: {8A2BE2}NumPad 7!", 0x8A2BE2)
  
    while true do
    wait(0)
        if isKeyJustPressed(103) then
            enable = not enable
            sampAddChatMessage(enable and "{FFFFFF}Активирован" or "{FFFFFF}Деактивирован", -1)
        end
    end
end

function sampev.onServerMessage(color, text)
    if enable then
        if text:find('Сядьте на ваш мотоцикл и доставьте пиццу к дому %(обозначено чекпоинтом%)%.') or text:find('Вы успешно доставили пиццу и заработали {33CC33}(%d+)%$') then
            lua_thread.create(function()
                sampProcessChatInput('/stpc')
                wait(1000)
                sampProcessChatInput('/stpc')
            end)
        end
    end
end

function sampev.onShowDialog(id, style, title, button1, button2, text)
    if enable then
        sampCloseCurrentDialogWithButton(0)
    end
end
Скорее всего из-за того, что событие приходит быстрее, чем сама команда. Либо используй костыль в виде lua_thread.create(args), либо просто используй return false - правильный способ. Но учти, что все диалоги будут игнорироваться, лучше игнорируй диалог только тот который тебе нужен.

UPD:
Lua:
function sampev.onShowDialog(id, style, title, button1, button2, text)
    if enable then
        return false
    end
end

-- лучше вот так:

function sampev.onShowDialog(id, style, title, button1, button2, text)
    if enable and id == 420 then -- вместо 420 твой ID диалога
        return false
    end
end

Если тебе нужно помимо скрытия его еще и закрывать, можешь делать так:
Lua:
function sampev.onShowDialog(id, style, title, button1, button2, text)
    if enable and id == 420 then -- вместо 420 твой ID диалога
        sampSendDialogResponse(id, --[[args]])
        return false
    end
end
 
  • Нравится
Реакции: XRLM

PanSeek

t.me/dailypanseek
Всефорумный модератор
910
1,779
как экранировать '/' в регулярке? XD
Не совсем понятен твой вопрос.
Его не нужно экранировать никак. Экранируются только эти: . ( ) [ ] % ? $ + - * ^.
Возможно поможет бэкслеш \ -> \/, например: \/sms.
 

T1cKz

Известный
595
245
Не совсем понятен твой вопрос.
Его не нужно экранировать никак. Экранируются только эти: . ( ) [ ] % ? $ + - * ^.
Возможно поможет бэкслеш \ -> \/, например: \/sms.
Нет не помогает.
Вот знаешь нуборп где говорит решать примеры, так вот есть же слеш, или у них это разделить и я его не могу найти через text:match("(.*)/(.*)") он попросту не видит его
 

PanSeek

t.me/dailypanseek
Всефорумный модератор
910
1,779
Lua:
        for _, v in pairs(getAllObjects()) do
            if isObjectOnScreen(v) then
                local model = getObjectModel(v)
                local _, x, y, z = getObjectCoordinates(v)
                local x1, y1 = convert3DCoordsToScreen(x,y,z)
                local x2,y2,z2 = getCharCoordinates(PLAYER_PED)
                local x10, y10 = convert3DCoordsToScreen(x2,y2,z2)
                local distance = string.format("%.0f", getDistanceBetweenCoords3d(x, y, z, x2, y2, z2))
                if model == 331 or model == 334 or model == 336 or model == 347 or model == 348 or model == 349 or model == 350 or model == 353 or model == 355 or model == 356 or model == 357 or model == 358 or model == 365 then
                    if tonumber(distance) > 1 then
                        renderFontDrawText(font, '{ff0000}Вооружен! '..'['..distance..']', x1, y1, -1)
                        renderDrawLine(x10, y10, x1, y1, 5.0, 0xff0000)
                    end
                end
               
            end
        end

хочу получить информацию, есть ли оружие в руках персонажей. многое перепробовал, работает только на объектах интерьеров.
Lua:
local weapon = require 'game.weapons'
local font = renderCreateFont("Tahoma", 9, 5)

function onD3DPresent()
    if isSampAvailable() then
        for id = 0, sampGetMaxPlayerId(true) do
            local res, handle = sampGetCharHandleBySampPlayerId(id)
            if res then
                local pX, pY, pZ = getCharCoordinates(handle)
                local x, y = convert3DCoordsToScreen(pX, pY, pZ)
                local weapon_id = getCurrentCharWeapon(handle)

                if isCharOnScreen(handle) and weapon_id > 0 then
                    renderFontDrawText(font, string.format('Вооружен %s[%d]', weapon.get_name(weapon_id), weapon_id), x, y, 0xFFFFFFFF)
                end
            end
        end
    end
end
 

Strone

Участник
66
13
Ребятки как сделать так, чтобы vkeys работал на нажатие вне чата. Просто когда ты нажимаешь кнопку чата, а потом кнопку включения скрипта он включается 0_0