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

YourAssistant

Участник
144
17
1) Почему в данном случае сравнение выполняется только первых двух "elseif"? 3 и 4 никак не выполняются.
Как бы я не менял последовательность - работает только первые два "elseif";
2) Возможно ли как-то оптимизировать? Нужно результат функции сравнить с содержимым 3 массивов, не важно какой последовательностью. 4 массив будет отбрасываться, не важно какой по счету.

Lua:
function control_message()

  if table1 and table_imgui[218] == 4 then
      for i, v in ipairs(table1) do
        if message() == v then
           sampAddChatMessage("Совпадение найдено в " .. v, -1)
           table_imgui[218] = 3
           table_imgui[215] = 1
           table_imgui[216] = 2
           table_imgui[217] = 3
        end  
      end
    elseif table2 and table_imgui[217] == 3 then
      for i, v in ipairs(table2) do
        if message() == v then
          sampAddChatMessage("Совпадение найдено в " .. v, -1)
          table_imgui[217] = 2
          table_imgui[216] = 2
          table_imgui[215] = 1
          table_imgui[218] = 4
        end
      end
    elseif table3 and table_imgui[216] == 2 then
      for i, v in ipairs(table3) do
        if message() == v then
          sampAddChatMessage("Совпадение найдено в " .. v, -1)
          table_imgui[216] = 1
          table_imgui[217] = 3
          table_imgui[215] = 1
          table_imgui[218] = 4
        end
      end
    elseif table4 and table_imgui[215] == 1 then
      for i, v in ipairs(table4) do
        if message() == v then
          sampAddChatMessage("Совпадение найдено в " .. v, -1)
          table_imgui[215] = 2
          table_imgui[216] = 2
          table_imgui[217] = 3
          table_imgui[218] = 4
        end
      end
    end
end
 

Pashyka

Участник
220
17
Доброго времени суток, возникла небольшая сложность, подскажите пожалуйста, как сменить цвет определенного слова/слов в чате.
Код ниже меняет всю строку в красную, мне нужно изменить определенное слово, а именно практикант

Регулярки построены по предложению ниже

[R] Практикант Rayan_Broun[837]: (( 1 ))

Lua:
if text:find("%[R%] .+ %w+_%w+%[%d+%]: %(%( .- %)%)") then
    return {0xFF0000AA, text}
end
 

moreveal

Известный
Проверенный
859
539
Как сделать, чтобы выполнение скрипта продолжалось лишь после выполнения асинхронной функции? Функция не успевает записать значению в переменную, а скрипт уже крашится из-за того, что переменная не объявлена

Как можно изменить гравитацию через ffi?
Lua:
local ffi = require "ffi"
ffi.cdef[[
    struct stServerPresets
    {
        uint8_t     byteCJWalk;
        int         m_iDeathDropMoney;
        float        fWorldBoundaries[4];
        bool        m_bAllowWeapons;
        float        fGravity;
        uint8_t     byteDisableInteriorEnterExits;
        uint32_t    ulVehicleFriendlyFire;
        bool        m_byteHoldTime;
        bool        m_bInstagib;
        bool        m_bZoneNames;
        bool        m_byteFriendlyFire;
        int            iClassesAvailable;
        float        fNameTagsDistance;
        bool        m_bManualVehicleEngineAndLight;
        uint8_t     byteWorldTime_Hour;
        uint8_t     byteWorldTime_Minute;
        uint8_t     byteWeather;
        uint8_t     byteNoNametagsBehindWalls;
        int         iPlayerMarkersMode;
        float        fGlobalChatRadiusLimit;
        uint8_t     byteShowNameTags;
        bool        m_bLimitGlobalChatRadius;
    }__attribute__ ((packed));
]]
function main()
    repeat wait(0) until isSampAvailable()
    local server = ffi.cast('struct stServerPresets*', sampGetServerSettingsPtr())
    server.fGravity = 800
end
 
Последнее редактирование:

YourAssistant

Участник
144
17
Работает только для одного. Как сделать для более одного?

Lua:
function event.onSendChat(msg)
  if msg:find("{message_r}") then
    local message_r = msg:gsub("{message_r}", m1())
    return {message_r}
  elseif msg:find("{message_rb}") then
    local message_rb = msg:gsub("{message_rb}", m2())
    return {message_rb}
  end
end
 

moreveal

Известный
Проверенный
859
539
Работает только для одного. Как сделать для более одного?

Lua:
function event.onSendChat(msg)
  if msg:find("{message_r}") then
    local message_r = msg:gsub("{message_r}", m1())
    return {message_r}
  elseif msg:find("{message_rb}") then
    local message_rb = msg:gsub("{message_rb}", m2())
    return {message_rb}
  end
end
использовать только if/end, elseif не выполнится, если начальное if - false
 

YourAssistant

Участник
144
17
Почему при вызове менюшки скрипт ламается
Lua:
local imgui = require "imgui"

local main_window_state = imgui.ImBool(false)

function main()
    repeat wait(0) until isSampAvailable()
    sampRegisterChatCommand("a", function()
        bool = not bool
    end)
    while true do wait(0)
        if bool then
            main_window_state.v = not main_window_state.v
            imgui.Process = main_window_state.v
        end
    end
end

function imgui.OnDrawFrame()
    imgui.Begin()
    imgui.End()
end
imgui.Begin("Name", main_window_state)
/a дублирует действия, можно сразу виндов = нот виндов


Можно как-то изменить размер imgui.Begin, например, нажатием на кнопку?
 
Последнее редактирование:

Rice.

Известный
Модератор
1,698
1,466
imgui.Begin("Name", main_window_state)
/a дублирует действия, можно сразу виндов = нот виндов


Можно как-то изменить размер imgui.Begin, например, нажатием на кнопку?
Lua:
local size = 0

--imgui
function imgui.OnDrawFrame()
    if size == 1 then imgui.SetNextWindowSize(imgui.ImVec2(500, 500), imgui.Cond.Always) end
    if size == 0 then imgui.SetNextWindowSize(imgui.ImVec2(200, 200), imgui.Cond.Always) end
    imgui.Begin('Test')
    if imgui.Button('Size big') then size = 1 end
    if imgui.Button('Size small') then size = 0 end
    imgui.End()
end
 
  • Нравится
Реакции: YourAssistant

b1coo

Участник
56
18
Подскажите код для создания визуальной GangZone для себя
Код:
require "lib.moonloader" -- подключение библиотеки
local sampev = require 'lib.samp.events' -- подключение евент
function main()
 if not isSampLoaded() or not isSampfuncsLoaded() then return end
 while not isSampAvailable() do wait(100) end
 -- бесконечная работа при запущенном сампе
function sampev.CreateGangZone(zoneId, squareStart, squareEnd, color)
 GangZoneCreate(80, 739.5, 180, 839.5, 0xFF0000FF)
 sampAddChatMessage(zoneId, color)
 sampAddChatMessage(squareStart, color)
 sampAddChatMessage(squareEnd, color)
 sampAddChatMessage(color, color)
 end
end
Пробую разные варианты, "GangZoneCreate" ничего не происходит
 

Dmitriy Makarov

25.05.2021
Проверенный
2,481
1,113
Подскажите код для создания визуальной GangZone для себя
Код:
require "lib.moonloader" -- подключение библиотеки
local sampev = require 'lib.samp.events' -- подключение евент
function main()
 if not isSampLoaded() or not isSampfuncsLoaded() then return end
 while not isSampAvailable() do wait(100) end
 -- бесконечная работа при запущенном сампе
function sampev.CreateGangZone(zoneId, squareStart, squareEnd, color)
 GangZoneCreate(80, 739.5, 180, 839.5, 0xFF0000FF)
 sampAddChatMessage(zoneId, color)
 sampAddChatMessage(squareStart, color)
 sampAddChatMessage(squareEnd, color)
 sampAddChatMessage(color, color)
 end
end
Пробую разные варианты, "GangZoneCreate" ничего не происходит
Когда-то для себя делал МО Хелпер. Код остался. Держи.
48d.jpg

Lua:
-- В начало куда-то
local gang_zones = {
    {1000, -1523, 358, -1486, 460, 0x50511919}, -- ID, left, up, right, down, color (ид, коорды каждых углов прямоугольника и цвет его)
    {1001, -1573, 283, -1469, 359, 0x50511919},
    {1002, -1554, 461, -1501, 501, 0x50511919},
    {1003, -1468, 482, -1243, 517, 0x50511919},
}

-- main
for i = 1, #gang_zones do
    addGangZone(gang_zones[i][1], gang_zones[i][2], gang_zones[i][3], gang_zones[i][4], gang_zones[i][5], gang_zones[i][6])
end

-- Отдельно. Это я у Xavier'a Adamson'a взял. Хз откуда он взял.
function addGangZone(id, left, up, right, down, color) -- Создание ганг-зоны.
    local bs = raknetNewBitStream()
    raknetBitStreamWriteInt16(bs, id)
    raknetBitStreamWriteFloat(bs, left)
    raknetBitStreamWriteFloat(bs, up)
    raknetBitStreamWriteFloat(bs, right)
    raknetBitStreamWriteFloat(bs, down)
    raknetBitStreamWriteInt32(bs, color)
    raknetEmulRpcReceiveBitStream(108, bs)
    raknetDeleteBitStream(bs)
end

function removeGangZone(id) -- Удаление ганг-зоны по ID (первый аргумент функции выше)
    local bs = raknetNewBitStream()
    raknetBitStreamWriteInt16(bs, id)
    raknetEmulRpcReceiveBitStream(120, bs)
    raknetDeleteBitStream(bs)
end
 
  • Нравится
Реакции: iEramur

sep

Известный
673
76
как запретить воспроизводить нужную анимацию полностью (анимацию курения)
и yкак узнать что эта за анимка ? название итд
ИМЕННО НЕ СБИВ АНИМАЦИИ А ПОЛНЫЙ ЗАПРЕТ НА ВОИСПРОИЗВЕДЕНИЕ АНИМАЦИИ
 

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Друг
8,776
11,226
и yкак узнать что эта за анимка ? название итд
1643402035917.png

в коде перепутал рендер IFP и NAME (например на скрине на самом деле IFP = PED и NAME = JUMP_GLIDE)
Lua:
local font = renderCreateFont('Trebuchet MS', 10, 5)

function main()
    while not isSampAvailable() do wait(0) end
      
    while true do
        wait(0)
        local animId = sampGetPlayerAnimationId(select(2, sampGetPlayerIdByCharHandle(PLAYER_PED)))
        local animName, animIfp = sampGetAnimationNameAndFile(animId)
        renderFontDrawText(font, '[ANIM] ID: '..animId..', IFP: '..animIfp..', NAME: '..animName, 700, 600, 0xFFFFFFFF, 0x90000000)
    end
end
Запрет:
Lua:
local sampev = require 'lib.samp.events'

function sampev.onApplyPlayerAnimation(playerId, IFP, NAME, frameDelta, loop, lockX, lockY, freeze, time)
    if playerId == select(2, sampGetPlayerIdByCharHandle(PLAYER_PED)) then
        if IFP == 'НАЗВАНИЕ IFP' and NAME == 'НАЗВАНИЕ NAME' then
            return false
        end
    end
end
 
Последнее редактирование:
  • Нравится
Реакции: sep

sep

Известный
673
76
Посмотреть вложение 133842
в коде перепутал рендер IFP и NAME (например на скрине на самом деле IFP = PED и NAME = JUMP_GLIDE)
Lua:
local font = renderCreateFont('Trebuchet MS', 10, 5)

function main()
    while not isSampAvailable() do wait(0) end
   
    while true do
        wait(0)
        local animId = sampGetPlayerAnimationId(select(2, sampGetPlayerIdByCharHandle(PLAYER_PED)))
        local animName, animIfp = sampGetAnimationNameAndFile(animId)
        renderFontDrawText(font, '[ANIM] ID: '..animId..', IFP: '..animIfp..', NAME: '..animName, 700, 600, 0xFFFFFFFF, 0x90000000)
    end
end
Запрет:
Lua:
local sampev = require 'lib.samp.events'

function sampev.onApplyPlayerAnimation(playerId, IFP, NAME, frameDelta, loop, lockX, lockY, freeze, time)
    if playerId == select(2, sampGetPlayerIdByCharHandle(PLAYER_PED)) then
        if IFP == 'НАЗВАНИЕ IFP' and NAME == 'НАЗВАНИЕ NAME' then
            return false
        end
    end
end
я понимаю тут незя писать слОва типо спасибо итд НО ОЧЕНЬ ХОЧИТСЯ СПАСИБО + лайк 👍!!!!!
ps:модеры простите меня
 

Kegwineye.

Участник
478
20
Какая функция в ImGui отвечает за вертикальную линию?(Как imgui.Separator() только вверх)
 

DeKzer

Известный
518
220
Можно-ли как-то изменить полученные координаты? Допустим, я получил коорды своего педа, и мне надо к z плюсануть еще какое-то число