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

mafizik

Участник
18
5
длину и высоту подели на 2
renderDrawBox дает координаты двух точек начала прямоугольника, длину, ширину, как мне вывести текст через renderFontDrawText по середине кв, если там надо указывать координаты и мне ширина и высота прямоугольника ничего не дает
 

trefa

3d print
Всефорумный модератор
2,130
1,308
Из конечных координат, вычитаешь начальные и делишь на 2. Потом этот результат прибавляешь к начальным
 

trefa

3d print
Всефорумный модератор
2,130
1,308
Код:
x,y       -------------         x + sizeX,y
         |             |
         |             |
          -------------
x,y + sizeY           x + sizeX, у + sizeY
Cередину получить так
xs = x + (sizeX / 2)
ys = y + (sizeY / 2)
 
  • Нравится
Реакции: mafizik

Maksimmm1

Новичок
2
0
Может кто может помочь, я полный нуль в этом.
Как совместить отдельный скрипт хоткеев с моим, чтобы кнопки были во вкладке информация, очень спасете если покажете как. Не шарю совсем.+не могу понять как сохранять подсказки которые я сам создаю во 2 окне, вот я создал подсказку, пере захожу, а там пусто все. И что бы курсор ставился перед знаком $..

Lua:
require('lib.moonloader')
local imgui = require 'mimgui'
local ffi = require 'ffi'
local encoding = require 'encoding'
encoding.default = 'CP1251'
local u8 = encoding.UTF8
local new, str = imgui.new, ffi.string


local inicfg = require 'inicfg'

local settings = inicfg.load({
    mygui = {
        chatCommands = {}
    }
}, 'Test.ini')

-- Проверка и инициализация chatCommands
if not settings.mygui.chatCommands or type(settings.mygui.chatCommands) ~= "table" then
    settings.mygui.chatCommands = {}
end

local inputField = new.char[256]()
local WinState1 = new.bool()
local WinState2 = new.bool()
local settingsFile = "my_gui_settings.txt" -- Файл для настроек

local function loadSettings()
    local file = io.open(settingsFile, "r")
    if file then
        local line = file:read()
        if line then
            local x, y, w, h = string.match(line, "^(%d+), (%d+), (%d+), (%d+)$")
            if x and y and w and h then
                return tonumber(x), tonumber(y), tonumber(w), tonumber(h)
            end
        end
        file:close()
    end
    return 350, 350, 250, 250 -- Значения по умолчанию
end

local function saveSettings(x, y, w, h)
    local file = io.open(settingsFile, "w")
    if file then
        file:write(string.format("%d, %d, %d, %d", x, y, 250, 650))
        file:close()
    end
end

local windowX1, windowY1, windowW1, windowH1 = 1400, 250, 460, 580
local windowX2, windowY2, windowW2, windowH2 = 100, 400, 530, 350
local tabData = {}

local function updateGUI()
    if WinState1[0] then
        imgui.SetNextWindowPos(imgui.ImVec2(windowX1, windowY1), imgui.Cond.FirstUseEver)
        imgui.SetNextWindowSize(imgui.ImVec2(windowW1, windowH1), imgui.Cond.FirstUseEver)
        if imgui.Begin(u8('Хелпер')) then
            if imgui.BeginTabBar(u8("Информация")) then -- Начало таб бара
                if imgui.BeginTabItem(u8("Подсказки")) then -- Вкладка с кнопками из tabData
                    for i, tab in ipairs(tabData) do
                        local tabName = tab[1]
                        local items = tab[2]
                        if imgui.CollapsingHeader(u8(tabName)) then
                            local buttonsInRow = 0
                            for j, item in ipairs(items) do
                                local message1 = item[1]
                                local message2 = item[2]
                                if imgui.Button(u8(message1)) then
                                    sampSetCurrentDialogEditboxText(message2)
                                end
                                if imgui.IsItemHovered() then
                                    imgui.BeginTooltip()
                                    imgui.Text(u8(message2))
                                    imgui.EndTooltip()
                                end
                                buttonsInRow = buttonsInRow + 1
                                if buttonsInRow < 3 and j < #items then
                                    imgui.SameLine()
                                elseif buttonsInRow == 3 then
                                    buttonsInRow = 0
                                end
                            end
                        end
                    end
                    imgui.EndTabItem()
                end
                if imgui.BeginTabItem(u8("Информация")) then -- Вкладка с кнопкой Binder
                    if imgui.Button(u8("Вспомогательное окно")) then
                        WinState2[0] = not WinState2[0]
                    end
                    imgui.EndTabItem()
                end
                imgui.EndTabBar()
            end
            imgui.End()
            saveSettings(imgui.GetWindowPos().x, imgui.GetWindowPos().y, imgui.GetWindowSize().x, imgui.GetWindowSize().y)
        end
    end



    if WinState2[0] then
        imgui.SetNextWindowPos(imgui.ImVec2(windowX2, windowY2), imgui.Cond.FirstUseEver)
        imgui.SetNextWindowSize(imgui.ImVec2(windowW2, windowH2), imgui.Cond.FirstUseEver)
        if imgui.Begin(u8('Вспомогательное окно'), WinState2, imgui.WindowFlags_NoMove) then
            if imgui.InputTextWithHint(u8'Введите подсказку:', u8'Текст подсказки', inputField, 256) then
                -- Нет необходимости сохранять в settings.mygui.inputsaved
            end

            if imgui.Button(u8('Сохранить')) then
                local newCommandText = u8:decode(str(inputField))
                if newCommandText ~= "" then
                    table.insert(settings.mygui.chatCommands, { text = newCommandText })
                end
            end

            for i, command in ipairs(settings.mygui.chatCommands) do
                if imgui.Button(u8(command.text)) then
                    sampSetCurrentDialogEditboxText(command.text, -1)
                end
            end
            imgui.End()
            inicfg.save(settings, 'Test.ini')
        end
    end
end
вот код с моими окнами

а это с хоткеем

Lua:
local imgui = require 'mimgui'
local hotkey = require 'mimgui_hotkeys'
local inicfg = require 'inicfg'
-- Создаём конфиг
local cfg = inicfg.load({
    config = {
        bind = '[16, 67]',
        bind_new = '[16, 55]' -- это и есть наши клавиши по умолчанию. Если хоткей нужно оставить пустым, можно вписать просто {}
    },
}, 'inifile.ini')
inicfg.save(cfg, 'inifile.ini')

local sw, sh = getScreenResolution()
local mainWindow = imgui.new.bool(false)
local exampleHotKey -- эта переменная позже будет хранить в себе хоткей
local exampleHotKey_1 -- эта переменная позже будет хранить в себе хоткей

exampleHotKey = hotkey.RegisterHotKey('random hotkey 1', false, decodeJson(cfg.config.bind), function() sampAddChatMessage('Keys have been pressed', -1) end)
exampleHotKey_1 = hotkey.RegisterHotKey('random hotkey 2', false, decodeJson(cfg.config.bind_new), function() sampAddChatMessage('Keys have been pressed', -1) end)

function main()
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand('menu1', function() mainWindow[0] = not mainWindow[0] end)
    wait(-1)
end

imgui.OnInitialize(function()
    imgui.GetIO().IniFilename = nil
end)

mainFrame = imgui.OnFrame(
    function() return mainWindow[0] end,
    function(window)
        imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(500, 500), imgui.Cond.FirstUseEver)
        imgui.Begin('Example HotKey Window', mainWindow)
        if exampleHotKey:ShowHotKey() then -- создаем условие, которое будет срабатывать при обновлении бинда пользователем
            cfg.config.bind = encodeJson(exampleHotKey:GetHotKey()) -- заносим в конфиг изменённую пользователем комбинацию клавиш
            inicfg.save(cfg, 'inifile.ini') -- не забываем конфиг сохранит
        end
        if exampleHotKey_1 ~= nil then
            -- CODE
            if exampleHotKey_1:ShowHotKey() then -- создаем условие, которое будет срабатывать при обновлении бинда пользователем
                cfg.config.bind_new = encodeJson(exampleHotKey_1:ShowHotKey()) -- заносим в конфиг изменённую пользователем комбинацию клавиш
                inicfg.save(cfg, 'inifile.ini') -- не забываем конфиг сохранить
            end
        end
        imgui.End()
    end
)
 
Последнее редактирование:

KyRDa

Активный
107
67
как сделать подчеркнутый текст в мимгуи
1740926519260.png

Lua:
function imgui.UnderlineText(text)
    local dl = imgui.GetWindowDrawList()
    local p = imgui.GetCursorScreenPos()

    imgui.Text(text)

    local size = imgui.GetItemRectSize()
    local Y = p.y + size.y

    dl:AddLine(imgui.ImVec2(p.x, Y), imgui.ImVec2(p.x + size.x, Y), imgui.GetColorU32(imgui.Col.Text), 1)
end
Держи, специально для тебя сделал,
Последний параметр dl:AddLine отвечает за жирность линии
 

AndergrOynd

Участник
106
20
Как остановить функцию нажатием кнопки
function msm(arg)
msm = arg
if act then
act = false
sampAddChatMessage(tag.. u8:decode' {FFFFFF}Слежка окончена ID: ' ..msm, -1)
else
if msm:match('%d+') then
act = true
sampAddChatMessage(tag.. u8:decode"{FFFFFF}Начал отслеживать ID: " ..msm, -1)

lua_thread.create(function ()
while act do
wait(slider[0] * 1000)
sampSendChat('/setmark '..msm)
end
end)
lua_thread.create(function ()
while act do
wait(not_slider[0] * 1000)
sampAddChatMessage(tag.. u8:decode'Отслеживается: ' ..msm , -1)
end
end)
else
sampAddChatMessage(tag .. u8:decode'{FFFFFF}Похоже, ты не ввел ID...', -1)
end
end
end
 

chuvakda

Участник
48
3

Как остановить функцию нажатием кнопки
function msm(arg)
msm = arg
if act then
act = false
sampAddChatMessage(tag.. u8:decode' {FFFFFF}Слежка окончена ID: ' ..msm, -1)
else
if msm:match('%d+') then
act = true
sampAddChatMessage(tag.. u8:decode"{FFFFFF}Начал отслеживать ID: " ..msm, -1)

lua_thread.create(function ()
while act do
wait(slider[0] * 1000)
sampSendChat('/setmark '..msm)
end
end)
lua_thread.create(function ()
while act do
wait(not_slider[0] * 1000)
sampAddChatMessage(tag.. u8:decode'Отслеживается: ' ..msm , -1)
end
end)
else
sampAddChatMessage(tag .. u8:decode'{FFFFFF}Похоже, ты не ввел ID...', -1)
end
end
end
Скрытое содержимое для пользователя(ей):
 
  • Нравится
Реакции: AndergrOynd

johnnysins

Участник
29
2
здравствуйте, как сделать чтобы выводилось сообщение введенное в строку в чат по нажатию кнопки в imgui окошке, при этом чтобы если строка была пустая выводилось сообщение что то типа вы не ввели ничего в строку короче просто посмотрите код

Код:
function imgui.OnDrawFrame()
    imgui.Begin(u8'menu', main_window_state)
    imgui.InputText(u8'вводить текст сюда', text_buffer)
    if imgui.Button('press me') but #text_buffer == 0 then
        sampAddChatMessage(u8'вы не ввели число', -1)
    else
        sampAddChatMessage(u8'вы указали аргумент: ' .. text_buffer, -1)
    end
      --  sampAddChatMessage(u8:decode(text_buffer.v), -1)
    imgui.End()
end

264934
 

arsvaser

Новичок
8
0
Переписал под новые сокращенные строчки цефов, при этом подставляя пакет нажатия утки все работает, а анимка нет(Rodina(
lua:
function main()
    while true do
        wait(0)
        if wasKeyPressed(0x38) and canuse then
            cef()
        end
    end
end

function cef()
    local str = 'playAnimation|0'
    local bs = raknetNewBitStream()
    raknetBitStreamWriteInt8(bs, 220)
    raknetBitStreamWriteInt8(bs, 18)
    raknetBitStreamWriteInt16(bs, #str)
    raknetBitStreamWriteString(bs, str)
    raknetBitStreamWriteInt32(bs, 0)
    raknetSendBitStream(bs)
    raknetDeleteBitStream(bs)
end
 

Mercyline

Новичок
26
0
Как сохранить весь текст из /admins в переменную, не выводя его в чат?
 

kultizdat.

Известный
161
13
Как получить данную инфу об актере на Аризоне? Имя, хп, броню? Копался в пакетах, кроме нанесения урона и текста, тот что над головой "появляется" ничего путного не нашел
 

Вложения

  • Screenshot_2025-03-05-22-06-07-90_99c04817c0de5652397fc8b56c3b3817.jpg
    Screenshot_2025-03-05-22-06-07-90_99c04817c0de5652397fc8b56c3b3817.jpg
    244.2 KB · Просмотры: 17
Последнее редактирование:

AndergrOynd

Участник
106
20
Замени последний
здравствуйте, как сделать чтобы выводилось сообщение введенное в строку в чат по нажатию кнопки в imgui окошке, при этом чтобы если строка была пустая выводилось сообщение что то типа вы не ввели ничего в строку короче просто посмотрите код

Код:
function imgui.OnDrawFrame()
    imgui.Begin(u8'menu', main_window_state)
    imgui.InputText(u8'вводить текст сюда', text_buffer)
    if imgui.Button('press me') but #text_buffer == 0 then
        sampAddChatMessage(u8'вы не ввели число', -1)
    else
        sampAddChatMessage(u8'вы указали аргумент: ' .. text_buffer, -1)
    end
      --  sampAddChatMessage(u8:decode(text_buffer.v), -1)
    imgui.End()
end

264934
Замени последний sampAddChatMessage на sampSendChat




*** Скрытый текст не может быть процитирован. ***
Скрытое содержимое для пользователя(ей):
 
Последнее редактирование:
  • Эм
Реакции: johnnysins