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

MLycoris

Режим чтения
Проверенный
1,826
1,867
можно сделать чтобы скрипт какнибуть определял что перед ним диалог ( ну например через id диалога ), и после того как он понял что перед ним вылезло окно он нажимал кнопку чтобы его закрыть (допустим enter)

Код:
    setVirtualKeyDown(VK_RETURN, true) -- скрипт нажал на enter
    wait(30)
    setVirtualKeyDown(VK_RETURN, false) -- скрипт отпустил enter

Виртуальные клавиши: https://api.farmanager.com/ru/winapi/virtualkeycodes.html
1 - левая кнопка, 0 - правая
Lua:
local sampev = require 'lib.samp.events'
function sampev.onShowDialog(id, style, title, button1, button2, text)
end

-- ну или
if sampIsDialogActive() then
    sampCloseCurrentDialogWithButton(0)
    return false
end
 

tyukapa

Активный
299
65
Как сделать чтобы в имгуи при нажатии кнопки делалось text = true и после этого function text() начинала работать
Код:
-- код

    if imgui.Button(u8'Включить') then
        sampAddChatMessage('Включено', -1)
        text = true
     end

--код

function text()
    while true do
        wait(600)
        if text then
        sampSendChat(u8:decode(text_buffer.v))
        end
    end
end

-- код

и чтобы при нажатии другой кнопки "выключить" function text() выключался

Как сделать чтобы в имгуи при нажатии кнопки делалось text = true и после этого function text() начинала работать
Код:
-- код

    if imgui.Button(u8'Включить') then
        sampAddChatMessage('Включено', -1)
        text = true
     end

--код

function text()
    while true do
        wait(600)
        if text then
        sampSendChat(u8:decode(text_buffer.v))
        end
    end
end

-- код

и чтобы при нажатии другой кнопки "выключить" function text() выключался
уже решил

как сделать так чтобы в imgui.InputText(u8"", text_buffer1) можно было вписать текст и после нажатия кнопки "применить" оно сохранялось в ini.
и потом чтобы в wait() в скобках была та задержка которая была указана в ini

Код:
-- код

local inicfg = require ('inicfg')
local directIni = ('moonloader\\config\\flood.ini')
local mainIni = inicfg.load({
    config = {
      wait =
    }
}, "flood.ini")
inicfg.save(mainIni, 'flood.ini')

-- код

imgui.InputText(u8"", text_buffer1)
     if imgui.Button(u8"Применить") then
        mainIni.config.wait = text_buffer1.v
        inicfg.save(mainIni, 'flood.ini')
     end
    
-- код
 
Последнее редактирование:

Dmitriy Makarov

25.05.2021
Проверенный
2,478
1,113
Как сделать чтобы в имгуи при нажатии кнопки делалось text = true и после этого function text() начинала работать
Код:
-- код

    if imgui.Button(u8'Включить') then
        sampAddChatMessage('Включено', -1)
        text = true
     end

--код

function text()
    while true do
        wait(600)
        if text then
        sampSendChat(u8:decode(text_buffer.v))
        end
    end
end

-- код

и чтобы при нажатии другой кнопки "выключить" function text() выключался


уже решил

как сделать так чтобы в imgui.InputText(u8"", text_buffer1) можно было вписать текст и после нажатия кнопки "применить" оно сохранялось в ini.
и потом чтобы в wait() в скобках была та задержка которая была указана в ini

Код:
-- код

local inicfg = require ('inicfg')
local directIni = ('moonloader\\config\\flood.ini')
local mainIni = inicfg.load({
    config = {
      wait =
    }
}, "flood.ini")
inicfg.save(mainIni, 'flood.ini')

-- код

imgui.InputText(u8"", text_buffer1, imgui.InputTextFlags.CharsDecimal)
     if imgui.Button(u8"Применить") then
        mainIni.config.wait = text_buffer1.v
        inicfg.save(mainIni, 'flood.ini')
     end
   
-- код
Как-то так, хз.
Lua:
local inicfg = require ('inicfg')
local directIni = ('moonloader\\config\\flood.ini')
local mainIni = inicfg.load({
    config = {
      wait = 0
    }
}, "flood.ini")
inicfg.save(mainIni, 'flood.ini')

local text_buffer1 = imgui.ImBuffer(tostring(mainIni.config.wait), 256)

imgui.InputText(u8"", text_buffer1)
if imgui.Button(u8"Применить") then
    mainIni.config.wait = tonumber(text_buffer1.v)
    inicfg.save(mainIni, 'flood.ini')
end
    
-- Use: wait(mainIni.config.wait)
 

tyukapa

Активный
299
65
Как-то так, хз.
Lua:
local inicfg = require ('inicfg')
local directIni = ('moonloader\\config\\flood.ini')
local mainIni = inicfg.load({
    config = {
      wait = 0
    }
}, "flood.ini")
inicfg.save(mainIni, 'flood.ini')

local text_buffer1 = imgui.ImBuffer(tostring(mainIni.config.wait), 256)

imgui.InputText(u8"", text_buffer1)
if imgui.Button(u8"Применить") then
    mainIni.config.wait = tonumber(text_buffer1.v)
    inicfg.save(mainIni, 'flood.ini')
end
   
-- Use: wait(mainIni.config.wait)
спасиб, но я уже сам нашёл решение. ну тип wait(text_buffer1.v)

Код:
-- код

imgui.InputText(u8"", text_buffer1)

-- код

wait(text_buffer1.v)

-- код
 

DedPoet

Участник
98
18
как доставать определенный текст из текстдрава и выводить в имгуи окно по очереди
хочу понять как вытягивать этот текст, чет попробовал но крашит скрипт
сэмпл:
textst = 'No info'

-- где то в function main()
local idstxt = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} -- Каждая строка на определенном айди текстдрава
  
if sampTextdrawIsExists(idstxt) then
  
local textst = sampTextdrawGetString(idstxt)
  
warnnick, nickid, reasonwarn = text:match("(warning)~n~.+_.+_(%d+)~n~reason:_.+")
  
end
-- end main'a

function imgui.OnDrawFrame()
local sw, sh = getScreenResolution()
if imgui_react.v then
    imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(100, 150), imgui.Cond.FirstUseEver)
    imgui.Text(u8"Никнейм"..textst)
  end
  end

1681652796227.png
 
Последнее редактирование:

MLycoris

Режим чтения
Проверенный
1,826
1,867
как доставать определенный текст из текстдрава и выводить в имгуи окно по очереди
хочу понять как вытягивать этот текст, чет попробовал но крашит скрипт
сэмпл:
textst = 'No info'

-- где то в function main()
local idstxt = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} -- Каждая строка на определенном айди текстдрава
 
if sampTextdrawIsExists(idstxt) then
 
local textst = sampTextdrawGetString(idstxt)
 
warnnick, nickid, reasonwarn = text:match("(warning)~n~.+_.+_(%d+)~n~reason:_.+")
 
end
-- end main'a

function imgui.OnDrawFrame()
local sw, sh = getScreenResolution()
if imgui_react.v then
    imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(100, 150), imgui.Cond.FirstUseEver)
    imgui.Text(u8"Никнейм"..textst)
  end
  end

Посмотреть вложение 197938
в теории должно работать, регулярки перепроверь
Lua:
-- в начале
local table = {}

-- в окне
for k, v in pairs(table) do
    imgui.Text(u8'Ник: '..v[1]..u8' Ид: '..v[2]..u8' Причина: '..v[3])
end

-- где угодно
function sampev.onShowTextDraw(id, data) -- текстдрав
    if data.text:find('(warning)~n~.+_.+_(%d+)~n~reason:_.+') then
        warnnick, nickid, reasonwarn = data.text:match("(warning)~n~.+_.+_(%d+)~n~reason:_.+")
        table.insert(table,{warnnick, nickid, reasonwarn})
    end
end
 

sosnov

Известный
331
115
что означает последнее из приведённой ниже строки?:
Lua:
['ICON_FA_HAND_POINT_UP'] = "\xea\x9b\xb0"
я понимаю что это означает изображение, но как понять это изображение и изменить его? то есть эту ссылку или как это назвать....
 

tyukapa

Активный
299
65
как можно сделать так чтобы в имгуи при включенном режиме скрипт убивал игрока через setCharHealth(PLAYER_PED, 0) если хп меньше 20? и так чтобы скрипт всё время проверял если он в режими "вкл" сколько у игрока хп

Код:
-- код

        if selected_menu == 1 then

        -------------
        if imgui.Combo(u8'АнтиКилл', selected_item, {u8'Выкл', u8'Вкл'}, 2) then
        if selected_item.v == 0 then

        end
        if selected_item.v == 1 then
        setCharHealth(PLAYER_PED, 0)
        end
        end
        
-- код
 

MLycoris

Режим чтения
Проверенный
1,826
1,867
как можно сделать так чтобы в имгуи при включенном режиме скрипт убивал игрока через setCharHealth(PLAYER_PED, 0) если хп меньше 20? и так чтобы скрипт всё время проверял если он в режими "вкл" сколько у игрока хп
а чем тебя обычный чекбокс не возбуждает? просто по-моему комбо для проверки состояния это такое себе решение
а так вот держи, это в беск цикле
Lua:
if selected_item.v ==1 and getCharHealth(1) <= 20 then
    setCharHealth(1,0)
end
 

Revavi

Участник
101
24
как в imgui.selectable сделать текст по центру?
как вообще реализовать подобное?
1681657172720.png
 

MLycoris

Режим чтения
Проверенный
1,826
1,867
Ты эту фигню, что я кинул вставляй в бесконечном цикле main, я тестил и без проблем работало