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

Anti...

Участник
243
18
как экранировать '/' в регулярке? XD


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


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

ARMOR

kjor32 is legend
Модератор
4,852
6,081
что за рендеры? мне команда нужна текстдрава на изменение его фона и прозрачности (НЕ ТЕКСТАБ фона)
М...
Lua:
local ev = require 'lib.samp.events'

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

T1cKz

Известный
596
246
что за рендеры? мне команда нужна текстдрава на изменение его фона и прозрачности (НЕ ТЕКСТАБ фона)
редактировать их нужно при появлении, а не после. в 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

kjor32 is legend
Модератор
4,852
6,081
Неприемлемое поведение
А прозрачность как?
Ты заебешь сука, ты учи луа нахуй, а не выпрашивай фулл код блядь. Если ты не знаешь как работает HEX цвет, то чем я тебе помогу сука? Я вижу ты в этой теме только вопросы за вопросами задаешь.
 
  • Нравится
Реакции: YarikVL и IlyaHL2

T1cKz

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

ARMOR

kjor32 is legend
Модератор
4,852
6,081
Не быкуй) Он же ещё не сеньор что бы уметь гуглить правильно XD
Ты полистай эту тему, и посмотри насколько у него тупые вопросы, он не учит lua, он чисто выпрашивает код. И ещё люди что-то за Венни говорят
 

T1cKz

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

Anti...

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

PanSeek

t.me/dailypanseek
Всефорумный модератор
899
1,745
А прозрачность как?
В цвете и есть прозрачность.
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. и Anti...

XRLM

Известный
2,544
863
почему не работает функция 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
 

PanSeek

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

T1cKz

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

PanSeek

t.me/dailypanseek
Всефорумный модератор
899
1,745
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