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

Andrinall

Известный
680
532
Как скрыть курсор после открытия окна в mimgui ?
Куда только уже imgui.ShowCursor = false не пихал, но чёт нифига. Простой showCursor(false) начинает моргать курсором. А как тогда?)
 

Fott

Простреленный
3,435
2,280
Lua:
local Directory = getWorkingDirectory()..'\\moonloader\\'
local file = io.open(Directory..str(Name_New_File)..'.lua', 'w')
Есть такой код, он должен создавать файл в папке moonloader, но он их не создает, что не так?
getWorkingDirectory и так возвращает путь к папке муна. А слэш надо 1
 
  • Нравится
Реакции: HpP

Fott

Простреленный
3,435
2,280
Как скрыть курсор после открытия окна в mimgui ?
Куда только уже imgui.ShowCursor = false не пихал, но чёт нифига. Простой showCursor(false) начинает моргать курсором. А как тогда?)
Lua:
local newFrame = imgui.OnFrame(
    function() return renderWindow[0] end,
    function(player)
       --пос бегин и тд
       player.HideCursor = true
    end
)
upd: либо так
Lua:
local newFrame = imgui.OnFrame(
    function() return renderWindow[0] end,
    function()
--всяка штуковина
).HideCursor = true
 
  • Нравится
Реакции: Andrinall

D.Makarov

Участник
146
3
Lua:
function getNearestPickup()
    local minDist = 333
    local nearestPickup = -1
    local mX, mY, mZ = getCharCoordinates(PLAYER_PED)
    for _, v in pairs(getAllPickups()) do
        local x, y, z = getPickupCoordinates(v)
        dist = math.sqrt((x - mX)^2 + (y - mY)^2 + (z - mZ)^2)
        if dist < minDist then
            minDist = dist
            nearestPickup = v
        end
    end
    local x, y, z = getPickupCoordinates(nearestPickup)
    local pX, pY = convert3DCoordsToScreen(x, y, z)
    local draw1, draw2 = convert3DCoordsToScreen(mX, mY, mZ)
    renderDrawLine(draw1, draw2, pX, pY, 2.0, 0xFFD00000)
    renderFontDrawText(my_font, string.format("{0089FF}Distance: {FFFFFF}%0.fm", dist), pX, pY, -1)
end
P.S: Имгур 3 секунды начала сожрал, сорян.
А можно как-то реализовать.Например у меня есть функция бег по координатам а как сделать к ближайшему пикаму
Lua:
function runToPoint(tox, toy)
    local x, y, z = getCharCoordinates(PLAYER_PED)
    local angle = getHeadingFromVector2d(tox - x, toy - y)
    local xAngle = math.random(-50, 50)/100
    setCameraPositionUnfixed(xAngle, math.rad(angle - 90))
    stopRun = false
    while getDistanceBetweenCoords2d(x, y, tox, toy) > 0.1 do
        setGameKeyState(1, -255)
        --setGameKeyState(16, 1)
        wait(1)
        x, y, z = getCharCoordinates(PLAYER_PED)
        angle = getHeadingFromVector2d(tox - x, toy - y)
        setCameraPositionUnfixed(xAngle, math.rad(angle - 90))
        if stopRun then
            stopRun = false
            break
        end
    end
end
 

Andrinall

Известный
680
532
Lua:
local newFrame = imgui.OnFrame(
    function() return renderWindow[0] end,
    function(player)
       --пос бегин и тд
       player.HideCursor = true
    end
)
upd: либо так
Lua:
local newFrame = imgui.OnFrame(
    function() return renderWindow[0] end,
    function()
--всяка штуковина
).HideCursor = true

ну, как-то не особо.
Попробовал ставить вообще во многих местах в окне, но курсор всё равно оставался, убирать флаги тоже пробовал.
Закомментировал все HideCursor, где пытался вставить.

Lua:
local flag = imgui.WindowFlags
local new_frame = imgui.OnFrame(function() return new_window_state[0] end, function(self)
    --self.HideCursor = true
    local sw, sh = getScreenResolution()

    --self.HideCursor = true
  
    imgui.SetNextWindowPos(imgui.ImVec2(sw / 1.161, sh / 2.6), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(275, 140), imgui.Cond.FirstUseEver)
    --self.HideCursor = true
  
    imgui.Begin('test', dost_window_state, flag.NoResize + flag.NoCollapse + flag.NoMove + flag.NoScrollbar + flag.NoMouseInputs + flag.NoFocusOnAppearing + flag.NoBringToFrontOnFocus + flag.NoNavInputs + flag.NoNavFocus)
  
    --self.HideCursor = true
      
    -- Основной код окна...
      
    --self.HideCursor = true
    imgui.End()
    --self.HideCursor = true
end)

а на это вообще выдаёт ошибку " unexpected symbol near '=' " ->
Lua:
local newFrame = imgui.OnFrame(
    function() return renderWindow[0] end,
    function()
--всяка штуковина
).HideCursor = true
 
Последнее редактирование:

Corrygаn

Участник
225
6
Флудер:
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end

    imgui.Process = false
    apply_custom_style()

    while true do
        wait(0)
        if main_window_helper.v == false then
            imgui.Process = false
        end
    end
end

imgui.Begin("", main_window_helper, imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoResize)
imgui.PushItemWidth(500)
imgui.InputText(u8"Первая строка  ", text_buffer)
imgui.SameLine()
imgui.PushItemWidth(100)
imgui.InputText(u8"Задержка  ", text_zader)
if imgui.Button("Start flood", imgui.ImVec2(210, 40)) the
    sampAddChatMessage("[Central Market Helper]: " .. white_colour .. "Флудер активирован.", 0x0066FF)
    proflood = true
end
imgui.End()



function proflood()
    while true do
        wait(text_zader.v) --здесь типо инпут текст с задержкой
        if proflood then
            sampSendChat(u8:decode(text_buffer.v))
        end
    end
end
Это флудер. Можно ли как-то сделать так, чтобы он флудил в игре, даже когда игрок в афк?
 

Andrinall

Известный
680
532
ну, как-то не особо.
Попробовал ставить вообще во многих местах в окне, но курсор всё равно оставался, убирать флаги тоже пробовал.
Закомментировал все HideCursor, где пытался вставить.

Lua:
local flag = imgui.WindowFlags
local new_frame = imgui.OnFrame(function() return new_window_state[0] end, function(self)
    --self.HideCursor = true
    local sw, sh = getScreenResolution()

    --self.HideCursor = true

    imgui.SetNextWindowPos(imgui.ImVec2(sw / 1.161, sh / 2.6), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(275, 140), imgui.Cond.FirstUseEver)
    --self.HideCursor = true

    imgui.Begin('test', dost_window_state, flag.NoResize + flag.NoCollapse + flag.NoMove + flag.NoScrollbar + flag.NoMouseInputs + flag.NoFocusOnAppearing + flag.NoBringToFrontOnFocus + flag.NoNavInputs + flag.NoNavFocus)

    --self.HideCursor = true
    
    -- Основной код окна...
    
    --self.HideCursor = true
    imgui.End()
    --self.HideCursor = true
end)

а на это вообще выдаёт ошибку " unexpected symbol near '=' " ->
Lua:
local newFrame = imgui.OnFrame(
    function() return renderWindow[0] end,
    function()
--всяка штуковина
).HideCursor = true
Отбой тревоге. Каким-то образом получилось заставить курсор исчезнуть. Мб проблема была в том, что в скрипте 2 окна, этого мне не ведомо.
FooOoott, благодарю за помощь, лайк поставил)

upd:
нашёл виновника проблемы, забавно лоханулся... курсор, оказывается, показывался от первого окна т.к. туда передавалось true с переменной, предназначенной для второго окна xD
Lua:
local test_frame = imgui.OnFrame( function() return main_window_state[0] or new_window_state[0] end, function(self)
-- дальше код...
end)
 
Последнее редактирование:

Snoopcheg

Известный
151
82
Отбой тревоге. Каким-то образом получилось заставить курсор исчезнуть. Мб проблема была в том, что в скрипте 2 окна, этого мне не ведомо.
FooOoott, благодарю за помощь, лайк поставил)

upd:
нашёл виновника проблемы, забавно лоханулся... курсор, оказывается, показывался от первого окна т.к. туда передавалось true с переменной, предназначенной для второго окна xD
Lua:
local test_frame = imgui.OnFrame( function() return main_window_state[0] or new_window_state[0] end, function(self)
-- дальше код...
end)
Так, а зачем делать в одном фрейме два окна на мимгуи, если рекомендуется для каждого окна свой фрейм?)
Взято с гайда по mimgui:
Lua:
local imgui = require 'mimgui' -- Подключаем саму библиотеку

local newFrame = imgui.OnFrame( --[[Сама функция создания фрейма, их может быть сколько вашей душе угодно.
                                    Обратите внимание, что в mimgui рекомендуется создавать отдельный
                                    фрейм для каждого окна, однако это не является обязательным.]]
    function() return true end, -- Определяет, выполняется/отображается ли текущий фрейм.
    function(player)            --[[Сама область, в которой уже будем рисовать элементы.
                                    В функцию в качестве первой переменной передаются список функций
                                    для взаимодействия с локальным игроком и рядом нескольких возможностей.]]
        imgui.Begin("Main Window")  -- Создаём новое окно с заголовком 'Main Window'
        imgui.Text("Hello")         -- Добавляем туда текст 'Hello'
        imgui.End()                 -- Объявляем конец данного окна
    end
)

function main()
    wait(-1)
end
 
  • Нравится
Реакции: Vintik

pavl1nio

Участник
95
13
Lua:
require "lib.moonloader"
local sampev = require "lib.samp.events"
local id = sampGetPlayerIdByCharHandle(ped)

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(2000) end
end

function onServerMessage(text)
    if text:find("Администратор") then
        SampSendChat ("я макака")
    end
end
помогите фиксануть пожалуйста
 

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Друг
8,777
11,224
ты забыл вставить sampev. в function onServerMessage(text)
 

Vintik

Мечтатель
Проверенный
1,473
922
Lua:
require "lib.moonloader"
local sampev = require "lib.samp.events"
local id = sampGetPlayerIdByCharHandle(ped)

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(2000) end
end

function onServerMessage(text)
    if text:find("Администратор") then
        SampSendChat ("я макака")
    end
end
помогите фиксануть пожалуйста
Тебе лучше ознакомиться с матчастью.
Lua:
local sampev = require 'lib.samp.events'
local id = select(2, sampGetPlayerIdByCharHandle(PLAYER_PED))

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(0) end
    wait(-1)
end

function sampev.onServerMessage(color, text)
    if text:find('Администратор') then
        SampSendChat('я макака')
    end
end
 
  • Нравится
Реакции: pavl1nio

Andrinall

Известный
680
532
Так, а зачем делать в одном фрейме два окна на мимгуи, если рекомендуется для каждого окна свой фрейм?)
Взято с гайда по mimgui:
Lua:
local imgui = require 'mimgui' -- Подключаем саму библиотеку

local newFrame = imgui.OnFrame( --[[Сама функция создания фрейма, их может быть сколько вашей душе угодно.
                                    Обратите внимание, что в mimgui рекомендуется создавать отдельный
                                    фрейм для каждого окна, однако это не является обязательным.]]
    function() return true end, -- Определяет, выполняется/отображается ли текущий фрейм.
    function(player)            --[[Сама область, в которой уже будем рисовать элементы.
                                    В функцию в качестве первой переменной передаются список функций
                                    для взаимодействия с локальным игроком и рядом нескольких возможностей.]]
        imgui.Begin("Main Window")  -- Создаём новое окно с заголовком 'Main Window'
        imgui.Text("Hello")         -- Добавляем туда текст 'Hello'
        imgui.End()                 -- Объявляем конец данного окна
    end
)

function main()
    wait(-1)
end
Это "or" осталось с тех времён, когда я только начал разбираться и переводить старый говнокод на mimgui, так у меня 2 фрейма..
Lua:
local main_frame = imgui.OnFrame( --......
end)

-- и ещё..
local new_frame = imgui.OnFrame( --......
end)
 

HpP

Известный
368
117
Можете подсказать хорошую функцию для сохранения информации из переменной char по кнопке в отдельный файл?