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

sep

Известный
714
79
Попробуй onChatMessage:

Lua:
function sampev.onChatMessage(playerId, text)
    -- ...
end
реагирую не на целые слова а на любое часть слова
как сделать чтобы реашировало на целые слова

реагирует хоть на ку хать на кушь и тд
if text:find('ку') or text:find('qq') then
sampSendChat(" привет")
end
 

Cottage

Новичок
18
3
Что не так здесь? Логика правильная, но не работает в игре. Я правильно использую hasCharGotWeapon?


switch weapon:
function main()
    repeat wait(0) until isSampAvailable()
        wait(2000)
        sampAddChatMessage("[Swap]{686868}", 0x686868)
        sampRegisterChatCommand("tube", tube)
        sampRegisterChatCommand("m4", m4)
        while true do
        wait(50)
    end
end

function tube()
    if hasCharGotWeapon(PLAYER_PED, 31) == true then
        sampSendChat("/place 31")
        sampSendChat("/takegun 1")

function m4()
    if hasCharGotWeapon(PLAYER_PED, 25) == true then
        sampSendChat("/place 25")
        sampSendChat("/takegun 3")
    else
        sampSendChat("/takegun 3")
    end
end
 

Andrinall

Известный
702
527
Что не так здесь? Логика правильная, но не работает в игре. Я правильно использую hasCharGotWeapon?


switch weapon:
function main()
    repeat wait(0) until isSampAvailable()
        wait(2000)
        sampAddChatMessage("[Swap]{686868}", 0x686868)
        sampRegisterChatCommand("tube", tube)
        sampRegisterChatCommand("m4", m4)
        while true do
        wait(50)
    end
end

function tube()
    if hasCharGotWeapon(PLAYER_PED, 31) == true then
        sampSendChat("/place 31")
        sampSendChat("/takegun 1")

function m4()
    if hasCharGotWeapon(PLAYER_PED, 25) == true then
        sampSendChat("/place 25")
        sampSendChat("/takegun 3")
    else
        sampSendChat("/takegun 3")
    end
end
Табуляция пиздец.
Закрытие end'ами не везде (из-за этого скрипт и крашит)

Lua:
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    repeat wait(0) until isSampAvailable()
 
    wait(2000)

    sampAddChatMessage("[Swap]{686868}", 0x686868)
    sampRegisterChatCommand("tube", tube)
    sampRegisterChatCommand("m4", m4)
   
    while true do
        wait(50)
    end
end

function tube()
    if not hasCharGotWeapon(PLAYER_PED, 31) then
        return
    end

    sampSendChat("/place 31")
    sampSendChat("/takegun 1")
end

function m4()
    if not hasCharGotWeapon(PLAYER_PED, 25) then
        sampSendChat("/takegun 3")
        return
    end

    sampSendChat("/place 25")
    sampSendChat("/takegun 3")
end
 

Cottage

Новичок
18
3
Да, я исправил код, закрыв конечные операторы. Но вот новая проблема: отправка двух команд одновременно не работает. Есть идеи, почему?


working:
function tube()
    if hasCharGotWeapon(PLAYER_PED, 31) == true then
        sampSendChat("/place 31")
    end
end

not working:
function tube()
    if hasCharGotWeapon(PLAYER_PED, 31) == true then
        sampSendChat("/place 31")
        wait(50)
        sampSendChat("/takegun 1")
    else
        sampSendChat("/takegun 1")
    end
end
 

Andrinall

Известный
702
527
Да, я исправил код, закрыв конечные операторы. Но вот новая проблема: отправка двух команд одновременно не работает. Есть идеи, почему?


working:
function tube()
    if hasCharGotWeapon(PLAYER_PED, 31) == true then
        sampSendChat("/place 31")
    end
end

not working:
function tube()
    if hasCharGotWeapon(PLAYER_PED, 31) == true then
        sampSendChat("/place 31")
        wait(50)
        sampSendChat("/takegun 1")
    else
        sampSendChat("/takegun 1")
    end
end
Антифлуд от сервера скорее всего. (если без wait кидать команды подряд)
А вот использовать wait вне потока - идея так себе.|
Lua:
local tube_thread = lua_thread.create_suspended(function() -- создаём замороженный поток
    if not hasCharGotWeapon(PLAYER_PED, 31) then
        sampSendChat("/takegun 1")
        return
    end

    sampSendChat("/place 31")
    wait(500)
    sampSendChat("/takegun 1")
end)

function tube()
    if not tube_thread.dead then -- проверяем поток на выполнение (или tube_thread:status() == "running", если это не работает)
        sampAddChatMessage("Не так часто!", -1)
        return
    end
    tube_thread:run() -- выполнение потока
end
 

Июнь

Участник
19
16
Как в mimgui получить возможный размер окна по содержимому?
Есть такой флаг - imgui.WindowFlags.AlwaysAutoResize - он подгоняет размеры окна под его содержимое.
Есть ли способ получить размер, который выдал бы imgui.WindowFlags.AlwaysAutoResize, или другой способ, способный подгонять окно по содержимому?

На примере кода ниже нужен способ, который получил бы размер, не расширяя окно.
К примеру, когда мы откроем вкладку (она по содержанию по ширине явно больше, так как там "Сейчас открыта вторая вкладка! ..............."), но размеры окна остались от предыдущей вкладки, так как у нас не встроен флаг/способ, который расширял бы окно автоматически.

И нужно получить высоту/ширину, которую установил бы autoresize. Нужен именно способ, который определяет размер по содержимому.
Считать (calc'ать) каждый текст вручную - такое решение мне не подойдет, и это только в этом случае дело в тексте; в других это могут быть кнопки, вкладки и т. д.

Интересует решение, если таковое есть, с минималистичным кодом (желательно парой строк :) ).
Прибегал к GetContentRegion, но у меня или лыжи не едут, или он измеряет только видимую область.
Вполне возможно, я делал что-то не так. Мб можно как то с помощью effil?
HELP!!


code::
local imgui = require 'mimgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
local u8 = encoding.UTF8

local WinState = imgui.new.bool()

imgui.OnFrame(function() return WinState[0] end, function(player)
    imgui.SetNextWindowPos(imgui.ImVec2(500, 500), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.Begin(u8'Пример', WinState)
   
    if imgui.BeginTabBar('Tabs') then
        if imgui.BeginTabItem(u8'Первая') then
            imgui.Text(u8'Сейчас открыта первая вкладка')
            imgui.EndTabItem()
        end
        if imgui.BeginTabItem(u8'Вторая') then
            imgui.Text(u8'Сейчас открыта вторая вкладка! ............................................................. ')
            if imgui.Button('Test') then
                sampAddChatMessage('Вы нажали кнопку во второй вкладке',-1)
            end
            imgui.EndTabItem()
        end
        imgui.EndTabBar()
    end
    imgui.End()
end)

function main()
    sampRegisterChatCommand('cmd', function() WinState[0] = not WinState[0] end)
    wait(-1)
end
UP
 

sep

Известный
714
79
плиз помогите голову сломал

54885558102_6cd63f409a_m.jpg

function sampev.onShowTextDraw(id, data)
if data.position.x > 530 and data.position.y < 26 then
return false
end
end

данная функция убирает все что на скрине а мне надо оставть ид 218 и 219
как это сделать
((ид постоянно меняются))

как скоректировать data.position.x > 530 and data.position.y < 26 в душе не ебу
 

chapo

tg/inst: @moujeek
Всефорумный модератор
9,235
12,650
плиз помогите голову сломал

54885558102_6cd63f409a_m.jpg

function sampev.onShowTextDraw(id, data)
if data.position.x > 530 and data.position.y < 26 then
return false
end
end

данная функция убирает все что на скрине а мне надо оставть ид 218 и 219
как это сделать
((ид постоянно меняются))

как скоректировать data.position.x > 530 and data.position.y < 26 в душе не ебу
Получи точные координаты этих двух текстдравов и добавь and x ~= *** and y ~= ***, либо проверку по спрайту (data.text)
 
  • Нравится
Реакции: sep

sep

Известный
714
79
Получи точные координаты этих двух текстдравов и добавь and x ~= *** and y ~= ***, либо проверку по спрайту (data.text)
ID: 218 | Text: HUD:radar_burgershot Pos X: 614 | Pos Y: 6

1) а куда добавить ?
если сюда
if data.position.x > 530 and data.position.y < 26 then
return false
то они будут также не видны

2) скажите как кликнуть по тексдруйву x и y

-- Функция, выполняющая одиночный клик левой кнопкой мыши по указанным координатам
function clickAt(x, y)
performMouseClick("left", x, y)
end

-- Пример использования: кликнем по точке (500, 300)
clickAt(500, 300)
то что я нашёл напашет
ид тексдрава постоянно меняется поэтому только 1 способ кликнуть по координатам
текст тоже у 1 отсутстует
ID: 2050 | Text: Box
ID: 2054 | Text: particle:lamp_shad_64
ID: 2069 | Text: _
также пробывал


function sampev.onShowTextDraw(id, data)
if data.position.x == положениеX and data.position.y == положениеY then
sampSendClickTextdraw(id)
end
end

тоже что то не пашет
если указат ид sampSendClickTextdraw("2096") конешно работает но ид меняются постоянно
 
Последнее редактирование:

chapo

tg/inst: @moujeek
Всефорумный модератор
9,235
12,650
ID: 218 | Text: HUD:radar_burgershot Pos X: 614 | Pos Y: 6

1) а куда добавить ?
если сюда
if data.position.x > 530 and data.position.y < 26 then
return false
то они будут также не видны

2) скажите как кликнуть по тексдруйву x и y

-- Функция, выполняющая одиночный клик левой кнопкой мыши по указанным координатам
function clickAt(x, y)
performMouseClick("left", x, y)
end

-- Пример использования: кликнем по точке (500, 300)
clickAt(500, 300)
то что я нашёл напашет
ид тексдрава постоянно меняется поэтому только 1 способ кликнуть по координатам
текст тоже у 1 отсутстует
ID: 2050 | Text: Box
ID: 2054 | Text: particle:lamp_shad_64
ID: 2069 | Text: _
также пробывал


function sampev.onShowTextDraw(id, data)
if data.position.x == положениеX and data.position.y == положениеY then
sampSendClickTextdraw(id)
end
end

тоже что то не пашет
если указат ид sampSendClickTextdraw("2096") конешно работает но ид меняются постоянно
бля, братиш, я в ахуе, ты уже который год задаешь сюда самые банальные вопросы. Такое ощущение что ты даже и не пытаешься что-либо понять.

1. получаешь data.text этих двух текстдравов
2.
Lua:
function sampev.onShowTextDraw(textdrawId, data)
    if data.position.x > 530 and data.position.y < 26 and data.text ~= 'текст первого' and data.text ~= 'текст второго' then
        return false
    end
end
 
  • Грустно
Реакции: sep

chapo

tg/inst: @moujeek
Всефорумный модератор
9,235
12,650
2) скажите как кликнуть по тексдруйву x и y

-- Функция, выполняющая одиночный клик левой кнопкой мыши по указанным координатам
function clickAt(x, y)
performMouseClick("left", x, y)
end

-- Пример использования: кликнем по точке (500, 300)
clickAt(500, 300)
то что я нашёл напашет
ид тексдрава постоянно меняется поэтому только 1 способ кликнуть по координатам
текст тоже у 1 отсутстует
ID: 2050 | Text: Box
ID: 2054 | Text: particle:lamp_shad_64
ID: 2069 | Text: _
также пробывал


function sampev.onShowTextDraw(id, data)
if data.position.x == положениеX and data.position.y == положениеY then
sampSendClickTextdraw(id)
end
end

тоже что то не пашет
если указат ид sampSendClickTextdraw("2096") конешно работает но ид меняются постоянно
Lua:
-- способ 1
local targetTextdraw = {
    x = 123,
    y = 123,
    id = nil
};

local function click()
    sampSendClickTextdraw(targetTextdraw.id);
end

function sampev.onShowTextDraw(textdrawId, data)
    if data.position.x == targetTextdraw.x and data.position.y == targetTextdraw.y then
        targetTextdraw.id = textdrawId;
    end
end

-- способ 2
local function clickAtTextdrawAtPos(x, y)
    for id = 0, 4096 do
        if (sampTextdrawIsExists(id)) then
            local tdX, tdY = sampTextdrawGetPos(id);
            if (tdX == x and tdY == y) then
                sampSendClickTextdraw(id);
            end
        end
    end
end
 
  • Нравится
Реакции: sep

sep

Известный
714
79
бля, братиш, я в ахуе, ты уже который год задаешь сюда самые банальные вопросы. Такое ощущение что ты даже и не пытаешься что-либо понять.
да есть веши которые я просто не понимаю

а ты сам понел что написал ?


луа:
function sampev.onShowTextDraw(textdrawId, data)
    if data.position.x > 530 and data.position.y < 26 and data.text ~= 'текст первого' and data.text ~= 'текст второго' then
        return false
    end
end

я просил не удалить ID: 218 | Text: HUD:radar_burgershot Pos X: 614 | Pos Y: 6
а наоборот показать а ты его суешь в перед return false
а насколько я знаю return false для того чтобы скрыть
а мне надо показать и текст бывает не у всех
вот пример ID: 2069 | Text: _
 

chapo

tg/inst: @moujeek
Всефорумный модератор
9,235
12,650
да есть веши которые я просто не понимаю

а ты сам понел что написал ?

луа:
function sampev.onShowTextDraw(textdrawId, data)
    if data.position.x > 530 and data.position.y < 26 and data.text ~= 'текст первого' and data.text ~= 'текст второго' then
        return false
    end
end

я просил не удалить ID: 218 | Text: HUD:radar_burgershot Pos X: 614 | Pos Y: 6
а наоборот показать а ты его суешь в перед return false
а насколько я знаю return false для того чтобы скрыть
а мне надо показать и текст бывает не у всех
вот пример ID: 2069 | Text: _
Что блять? Он его и не удалит если ты укажешь текст этого текстдрава.
 

sep

Известный
714
79
Что блять? Он его и не удалит если ты укажешь текст этого текстдрава.
стаю на асфальте я в лыже обутый толь лыжы не едут толь я ебанутый
без скрипта
54887052609_37ff8c6b17_m.jpg

со скриптом
54885937697_99625759ee_m.jpg

chapo плиз научи придурка богу молится​

плиз почему без скрипта ид логотипа не скрываются
а со скриптом скрываются

мне надо чтобы скрывались все что на скрине кроме бургера вот его данные
ID: 218 | Text: HUD:radar_burgershot Pos X: 614 | Pos Y: 6
зеленый лототип это другой скрипт эго не удаляем удаляем стандартный

ПО МОЕМУ ЕБАНУТОМУ МНЕНИЮ ДАННАЯ ХУЙНЯ

ЛУА:
function sampev.onShowTextDraw(id, data)
    if data.position.x  > 530 and data.position.y < 26 then
        return false
    end
end

и скрывает старый логотип

=========================================================================================


Что блять? Он его и не удалит если ты укажешь текст этого текстдрава.
ага блять return false а он его не удалить ладно я рукажопый а ты что курил ?

вот так работает не знаю мож это и колхоз но пашет
function sampev.onShowTextDraw(id, data)

if id == 218 then
return true -- показывает
end

if data.position.x > 530 and data.position.y < 26 then
return false -- удаляет
end

end
 
Последнее редактирование:

chapo

tg/inst: @moujeek
Всефорумный модератор
9,235
12,650
стаю на асфальте я в лыже обутый толь лыжы не едут толь я ебанутый
без скрипта
54887052609_37ff8c6b17_m.jpg

со скриптом
54885937697_99625759ee_m.jpg

chapo плиз научи придурка богу молится​

плиз почему без скрипта ид логотипа не скрываются
а со скриптом скрываются

мне надо чтобы скрывались все что на скрине кроме бургера вот его данные
ID: 218 | Text: HUD:radar_burgershot Pos X: 614 | Pos Y: 6
зеленый лототип это другой скрипт эго не удаляем удаляем стандартный

ПО МОЕМУ ЕБАНУТОМУ МНЕНИЮ ДАННАЯ ХУЙНЯ

ЛУА:
function sampev.onShowTextDraw(id, data)
    if data.position.x  > 530 and data.position.y < 26 then
        return false
    end
end

и скрывает старый логотип

=========================================================================================



ага блять return false а он его не удалить ладно я рукажопый а ты что курил ?

вот так работает не знаю мож это и колхоз но пашет
function sampev.onShowTextDraw(id, data)

if id == 218 then
return true -- показывает
end

if data.position.x > 530 and data.position.y < 26 then
return false -- удаляет
end

end
так ты блять перечитай еще и еще раз.
Lua:
function sampev.onShowTextDraw(textdrawId, data)
    if data.position.x > 530 and data.position.y < 26 and not data.text:find('radar_burgershot') then
        --[[
            код который находится тут сработает (текстдрав удалится) только если:
            1. x текстдрава более 530
            2. y текстдрава < 26
            3. текст текстдрава это НЕ ЕБАНЫЫЙ БУРГЕР (для олигофренов: бургер не удалится)
        ]]
        return false
    end
end