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

7 СМЕРТНЫХ ГРЕХОВ

пісюнковий злочинець
522
163
Как сделать что бы я мог редактировать текст
LUA:
if int_item[0] == 1 then
    imgui.StrCopy(textBuffer, u8"{FFFFFF}Nick_Name[id] говорит:{B7AFAF} текст")
end
1681551535110.png

Когда пытаюсь что то другое написать оно просто возвращает обратно значение
 

MLycoris

На вид оружие массового семяизвержения
Проверенный
1,975
2,209
Как сделать что бы я мог редактировать текст
LUA:
if int_item[0] == 1 then
    imgui.StrCopy(textBuffer, u8"{FFFFFF}Nick_Name[id] говорит:{B7AFAF} текст")
end
Посмотреть вложение 197743
Когда пытаюсь что то другое написать оно просто возвращает обратно значение
Если я правильно понял, то вот
Lua:
 -- в начале где нибудь
local test = 'shit asdlds'
local textBuffer = new.char[256](test)

-- в окне
if imgui.InputText("##Text", textBuffer, 256) then
    test = u8:decode(ffi.string(textBuffer)) -- переписываем значение test
end
 
  • Нравится
Реакции: de_clain

7 СМЕРТНЫХ ГРЕХОВ

пісюнковий злочинець
522
163
Если я правильно понял, то вот
Lua:
 -- в начале где нибудь
local test = 'shit asdlds'
local textBuffer = new.char[256](test)

-- в окне
if imgui.InputText("##Text", textBuffer, 256) then
    test = u8:decode(ffi.string(textBuffer)) -- переписываем значение test
end
выбор идет через комбо
1681552659504.png


LUA:
if int_item[0] == 1 then
    imgui.StrCopy(textBuffer, u8"{FFFFFF}Nick_Name[id] говорит:{B7AFAF} текст")
end
if int_item[0] == 2 then
    imgui.StrCopy(textBuffer, u8"{FF99FF}Nick_Name[id] рп текст")
end
if int_item[0] == 3 then
    imgui.StrCopy(textBuffer, u8"{4682B4}  .  - |  Nick_Name[id]")
end
if int_item[0] == 4 then
    imgui.StrCopy(textBuffer, u8"{FFFFFF}''текст'', - сказал(а) Nick_Name[id],{FF99FF} рп текст.")
end
 

CaJlaT

07.11.2024 14:55
Модератор
2,857
2,721
выбор идет через комбо Посмотреть вложение 197744

LUA:
if int_item[0] == 1 then
    imgui.StrCopy(textBuffer, u8"{FFFFFF}Nick_Name[id] говорит:{B7AFAF} текст")
end
if int_item[0] == 2 then
    imgui.StrCopy(textBuffer, u8"{FF99FF}Nick_Name[id] рп текст")
end
if int_item[0] == 3 then
    imgui.StrCopy(textBuffer, u8"{4682B4}  .  - |  Nick_Name[id]")
end
if int_item[0] == 4 then
    imgui.StrCopy(textBuffer, u8"{FFFFFF}''текст'', - сказал(а) Nick_Name[id],{FF99FF} рп текст.")
end
Вызывай imgui.StrCopy только внутри колбэка imgui.Combo, иначе у тебя в цикле будет перезаписываться значение, что не даст тебе изменить инпут
Lua:
if imgui.Combo() then
    if int_item[0] == 1 then
        imgui.StrCopy(textBuffer, u8"{FFFFFF}Nick_Name[id] говорит:{B7AFAF} текст")
    end
    if int_item[0] == 2 then
        imgui.StrCopy(textBuffer, u8"{FF99FF}Nick_Name[id] рп текст")
    end
    if int_item[0] == 3 then
        imgui.StrCopy(textBuffer, u8"{4682B4}  .  - |  Nick_Name[id]")
    end
    if int_item[0] == 4 then
        imgui.StrCopy(textBuffer, u8"{FFFFFF}''текст'', - сказал(а) Nick_Name[id],{FF99FF} рп текст.")
    end
end
 

MLycoris

На вид оружие массового семяизвержения
Проверенный
1,975
2,209
тогда попробуй так
Lua:
-- В начале
local ComboTest = new.int()
local item_list = {u8'Раз', u8'Два', u8'Три'} -- твоё комбо
local ImItems = new['const char*'][#item_list](item_list)

local table = { -- твои бинды
    'фывфыв',
    'ав',
    'asdasd'
}

local shit = new.char[256](u8(table[ComboTest[0]+1])) -- буфер для инпута

-- в окне
if imgui.Combo(u8'Список',ComboTest,ImItems, #item_list) then
    imgui.StrCopy(shit, u8(table[ComboTest[0]+1]))
end
if imgui.InputText('ssd',shit,256) then
    table[ComboTest[0]+1] = u8:decode(ffi.string(shit)) -- перезаписываем значение в таблицы, ну и сохраняем
end
 

santyy13gg

Новичок
9
1
при заходе на сервер во время тех рестарта на Аризоне выдает диалоговое окно, как его закрыть?
 

goodflex

Активный
280
58
Как правильно сюда вставить u8. Чтобы место каракуль писало нормальный текст

Код:
     if imgui.Button(u8"Начать") then
     sampAddChatMessage(mainIni.config.flood .. "",-1)
     end
 

chapo

tg/inst: @moujeek
Всефорумный модератор
9,202
12,520
Как правильно сюда вставить u8. Чтобы место каракуль писало нормальный текст

Код:
     if imgui.Button(u8"Начать") then
     sampAddChatMessage(mainIni.config.flood .. "",-1)
     end
Lua:
 sampAddChatMessage(u8:decode(mainIni.config.flood),-1)
 
  • Нравится
Реакции: goodflex

goodflex

Активный
280
58
при заходе на сервер во время тех рестарта на Аризоне выдает диалоговое окно, как его закрыть?
можно сделать чтобы скрипт какнибуть определял что перед ним диалог ( ну например через id диалога ), и после того как он понял что перед ним вылезло окно он нажимал кнопку чтобы его закрыть (допустим enter)

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

Виртуальные клавиши: https://api.farmanager.com/ru/winapi/virtualkeycodes.html
 
  • Bug
Реакции: chapo

MLycoris

На вид оружие массового семяизвержения
Проверенный
1,975
2,209
можно сделать чтобы скрипт какнибуть определял что перед ним диалог ( ну например через 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
 

Dmitriy Makarov

25.05.2021
Проверенный
2,515
1,141
Как сделать чтобы в имгуи при нажатии кнопки делалось 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)
 

DedPoet

Участник
99
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,975
2,209
как доставать определенный текст из текстдрава и выводить в имгуи окно по очереди
хочу понять как вытягивать этот текст, чет попробовал но крашит скрипт
сэмпл:
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

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