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

xdswd

Известный
364
253
Вот написал:
Lua:
require "lib.moonloader"
function main()
    if not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    sampAddChatMessage('Test',-1)
    wait(-1)
end

Не работает:(
Lua:
function main()
    if not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    sampAddChatMessage('Test',-1)
    while true do
        wait(-1) -- если будешь использовать бесконечный поток, ставь тут 0
    end
end
 

Vritz

Новичок
13
0
Lua:
function main()
    if not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    sampAddChatMessage('Test',-1)
    while true do
        wait(-1) -- если будешь использовать бесконечный поток, ставь тут 0
    end
end
Ну тип ничего не помогает, я до этого тоже написал скрипт, там тип imgui и все такое,
не сработало, потом забрал функцию: or not isSampfuncsLoaded(), так как на Radmir нету SAMPFUNCS, там запуск через лаунчер идет. Тоже не помогло.
Хз даже что делать..
 

trefa

3d print
Всефорумный модератор
2,113
1,280
Ну тип ничего не помогает, я до этого тоже написал скрипт, там тип imgui и все такое,
не сработало, потом забрал функцию: or not isSampfuncsLoaded(), так как на Radmir нету SAMPFUNCS, там запуск через лаунчер идет. Тоже не помогло.
Хз даже что делать..
Это самповские функции для их работы нужен сампфункс.
 

ГОХА | GoxaShow

временно заказы не делаю, с хуйней - нахуй
Проверенный
1,892
1,923
всем пис, решил написать скрипт на imgui и там куча всего перечислить, вопрос, как обойти
function at line 176 has more than 60 upvalues
 

Izvinisb

Известный
Проверенный
963
600
всем пис, решил написать скрипт на imgui и там куча всего перечислить, вопрос, как обойти
function at line 176 has more than 60 upvalues
Создавать функцию вне ondrawframe или как ее там, писать в новой функции код так же, как писал бы в ondrawframe и вызывать в ondrawframe. Надеюсь, понятно 🙃
 
  • Нравится
Реакции: ГОХА | GoxaShow

ГОХА | GoxaShow

временно заказы не делаю, с хуйней - нахуй
Проверенный
1,892
1,923
Может скинуть нужно 176 строку?
function imgui.OnDrawFrame()
как будто тебе это чтото даст...
а весь код сюда не хочу кидать)
могу сказать,что там просто перечисление кнопок
Создавать функцию вне ondrawframe или как ее там, писать в новой функции код так же, как писал бы в ondrawframe и вызывать в ondrawframe. Надеюсь, понятно 🙃
смотри, у меня там кнопок, МНОГО..) и просто создать функцию с ними и там вызывать ее?
Создавать функцию вне ondrawframe или как ее там, писать в новой функции код так же, как писал бы в ondrawframe и вызывать в ondrawframe. Надеюсь, понятно 🙃
а, рили работает, спасибо)
 

riassemss

Новичок
22
5
привет, в общем я решил написать скрипт, сделал команду, но она не работает, не знаю почему, можете помочь?

Lua:
function funin(arg)
  if arg:match('(%d+)') then 
    if tonumber(arg) and sampIsPlayerConnected(arg) then
        lua_thread.create(function()
            id = tonumber(arg)
            wait(100)
            sampSendChat("/famuninvite '..id...' выгнан'")
        end)
    end
  end
end
 

Izvinisb

Известный
Проверенный
963
600
привет, в общем я решил написать скрипт, сделал команду, но она не работает, не знаю почему, можете помочь?

Lua:
function funin(arg)
  if arg:match('(%d+)') then
    if tonumber(arg) and sampIsPlayerConnected(arg) then
        lua_thread.create(function()
            id = tonumber(arg)
            wait(100)
            sampSendChat("/famuninvite '..id...' выгнан'")
        end)
    end
  end
end
Lua:
sampSendChat('/famuninvite '..id..' выгнан')
 
  • Нравится
Реакции: riassemss

back.DEV

Известный
71
6
Привет, у меня есть у меня imgui окошко, в котором стоит флаг imgui.WindowFlags.AlwaysAutoResize, в окошке imgui у меня есть таблица (а.к.а imgui.Columns), почему когда я добавляю элементы в таблицу, окошко не становится больше, а нужно его листать, можно это как нибудь исправить?
 

DobrayaPchela

Участник
79
8
Напишите активацию и деактивацию при которой будет писать в чат "Activate" и "Deactivate"

Lua:
local as = {
    STOP   = 0,
    PLAY   = 1,
    PAUSE  = 2,
    RESUME = 3
  }
 
  local vol = 10
  timer = os.clock()
 
 function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
    local sound = loadAudioStream(getWorkingDirectory()..'\\resource\\audio\\fist.mp3')
    wait(2000)
    setAudioStreamState(sound, as.PLAY)
    setAudioStreamVolume(sound, vol)
    while true do wait(100)
      wp = getCurrentCharWeapon(PLAYER_PED)
      if wp == 0 then
        if getAudioStreamState(sound) ~= 1 then setAudioStreamState(sound, as.PLAY) end
        setAudioStreamVolume(sound, 10)
        vol = os.clock() + 2
      else
        q = vol - os.clock()
        if q > 0 then
          setAudioStreamVolume(sound, q * 2)
        else
          setAudioStreamState(sound, as.STOP)
        end
      end
    end
  end
 

Double Tap Inside

Известный
Проверенный
1,916
1,256
Как в окне imgui перехватить нажатие на "Крестик", чтобы выполнить код после нажатия на него?

На подобие кнопоки:
Lua:
if imgui.Button(...) then
   -- code
end

--[[

if imgui.CloseButton() then
   -- code on close window
end

--]]

---
Походу решил, чекнуть переменную вконце окна.
Lua:
            if not imw_saving_current_dialog.v then
                sampAddChatMessage("cyka", -1)
                user_title = nil
            end
        imgui.End()
 
Последнее редактирование:
  • Нравится
Реакции: Cosmo

Cosmo

Известный
Друг
656
2,752
Где можно найти тему с гайдом по работе с библиотекой FFI? В разделе Разработка | LUA не нашёл, возможно плохо искал.
В гугле всё на инглише и не для сампа, мне бы с примерами по работе в сампе
 
Последнее редактирование:

Anton Nixon

Известный
474
48
Почему крашит игру при попытке открыть PieMenu
Код скопировал у кого-то из комментариев:
Lua:
require "lib.moonloader"
require "lib.sampfuncs"
local imgui = require 'imgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
local key = require 'vkeys'
local pie = require 'imgui_piemenu'

local pie_mode = imgui.ImBool(true)
local pie_keyid = 1 -- 0 ЛКМ, 1 ПКМ, 2 СКМ

local pie_elements =
{
  {name = 'Сказать привет', action = function() sampSendChat('Привет.') end, next = nil},
  {name = 'Сказать пока', action = function() sampSendChat('Пока.') end, next = nil},
  {name = 'Сказать что-то', action = function() end, next = {
    {name = 'Сказать как дела', action = function() sampSendChat('Как дела.') end, next = nil},
    {name = 'Сказать ку-ку', action = function() sampSendChat('Ку-ку.') end, next = nil},
    {name = 'Сказать дароу', action = function() sampSendChat('Дароу.') end, next = nil}
  }}
}

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
   
    while true do
        wait(100)
        imgui.Process = pie_mode.v
    end
end

function imgui.OnDrawFrame()
    if pie_mode.v then
        imgui.OpenPopup('PieMenu')
        if pie.BeginPiePopup('PieMenu', pie_keyid) then
            for k, v in ipairs(pie_elements) do
                if v.next == nil then if pie.PieMenuItem(u8(v.name)) then v.action() end
                elseif type(v.next) == 'table' then drawPieSub(v) end
            end
            pie.EndPiePopup()
        end
        imgui.ShowCursor = (pie_mode.v and imgui.IsMouseDown(pie_keyid))
    end
end

function drawPieSub(v)
    if pie.BeginPieMenu(u8(v.name)) then
      for i, l in ipairs(v.next) do
        if l.next == nil then
          if pie.PieMenuItem(u8(l.name)) then l.action() end
        elseif type(l.next) == 'table' then
          drawPieSub(l)
        end
      end
      pie.EndPieMenu()
    end
  end
Хелп ми, хочу разобраться с этой штукой