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

McLore

Известный
559
279
почему он должен? он ничего не сохраняет, ты передаёшь пустую таблицу, т.е. {}, сначала её заполни
1603718673654.png


Он это делает при запуске самого файла, это чисто пример
Я кнш не экспер, можешь написать свою точку зрения и как это работает
 

wulfandr

Известный
637
260
Посмотреть вложение 73161

Он это делает при запуске самого файла, это чисто пример
Я кнш не экспер, можешь написать свою точку зрения и как это работает
Lua:
local inicfg = require 'inicfg'

local mainini = inicfg.load({
    online =
    {
        onlinfo = {},
        day = os.date("%d-%m-%y")
    }
}, "test")
 

function main()
    if not doesFileExist(getWorkingDirectory()..'\\config\\test.ini') then
        inicfg.save(cfg, 'test.ini')
    end
    mainini.online.onlinfo = os.time()
    
    inicfg.save(mainini, 'test.ini')
    while true do
        wait(0)
    end
end
 

McLore

Известный
559
279
Lua:
local inicfg = require 'inicfg'

local mainini = inicfg.load({
    online =
    {
        onlinfo = {},
        day = os.date("%d-%m-%y")
    }
}, "test")


function main()
    if not doesFileExist(getWorkingDirectory()..'\\config\\test.ini') then
        inicfg.save(cfg, 'test.ini')
    end
    mainini.online.onlinfo = os.time()
   
    inicfg.save(mainini, 'test.ini')
    while true do
        wait(0)
    end
end
Да это все ясно, но мне нужен ключ day из ини, пример как должно это выглядить
1603719192185.png
 

CaJlaT

Овощ
Модератор
2,807
2,617
Да это все ясно, но мне нужен ключ day из ини, пример как должно это выглядить
Посмотреть вложение 73162
Lua:
local inicfg = require 'inicfg'


local mainini = inicfg.load({
    online ={}
}, "test")
if not doesFileExist('moonloader/config/test.ini') then inicfg.save(mainini, 'test.ini') end

function main()
    local day = os.date("%d-%m-%y")
    if not doesFileExist(getWorkingDirectory()..'\\config\\test.ini') then
        inicfg.save(cfg, 'test.ini')
    end
    if not mainini.online[day] then
        mainini.online[day] = 0
        inicfg.save(mainini, 'test.ini')
    end
    while true do
        wait(0)
        day = os.date("%d-%m-%y")
        if not mainini.online[day] then
            mainini.online[day] = 0
            inicfg.save(mainini, 'test.ini')
        end
    end
end
1603719948597.png
 
  • Нравится
Реакции: McLore

McLore

Известный
559
279
Lua:
local inicfg = require 'inicfg'


local mainini = inicfg.load({
    online ={}
}, "test")
if not doesFileExist('moonloader/config/test.ini') then inicfg.save(mainini, 'test.ini') end

function main()
    local day = os.date("%d-%m-%y")
    if not doesFileExist(getWorkingDirectory()..'\\config\\test.ini') then
        inicfg.save(cfg, 'test.ini')
    end
    if not mainini.online[day] then
        mainini.online[day] = 0
        inicfg.save(mainini, 'test.ini')
    end
    while true do
        wait(0)
        day = os.date("%d-%m-%y")
        if not mainini.online[day] then
            mainini.online[day] = 0
            inicfg.save(mainini, 'test.ini')
        end
    end
end
Посмотреть вложение 73168
Спасибо, понял в чем ошибка была
 

Мира

Участник
455
9
почему-то не появляется окно imgui...
Lua:
script_name('New sctript') -- название скрипта
script_author('FORMYS') -- автор скрипта
script_description('Command') -- описание скрипта

require "lib.moonloader" -- подключение библиотеки
local imgui = require 'imgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local tag = '[My First Script]:' -- локальная переменная

local main_window_state = imgui.ImBool(false)
local text_buffer = imgui.ImBuffer(256)

local sw, sh = getScreenResolution()

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
    
    sampRegisterChatCommand("imgui", cmd_imgui)
    
    imgui.Process = false
    
    -- Блок выполнняющийся один раз после старта сампа
    
    while true do
        wait(0)
        
        if main_window_state.v == false then
            imgui.Process = false
        end
        
        -- Блок выполнняющийся бесконечно (пока самп активен)
        
    end
end

function cmd_imgui(arg)
    main_window_state.v = not main_window_state.v
    imgui.Process = main_window_state.v
end

function imgui.onDrawFrame()
    
    imgui.SetNextWindowSize(imgui.ImVec2(500, 500), imgui.Cond.FirstUseEver)
    imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    
    imgui.Begin(u8"Привет", main_window_state)
    imgui.InputText(u8'‚Вводить текст сюда', text_buffer)
    imgui.Text(text_buffer.v)
    if imgui.Button('Press me') then
        sampAddChatMessage(u8:decode(text_buffer.v), -1)
    end
    imgui.End()
end
 

Luis_Mora

Участник
31
1
Как задать поиск первого символа ":" (двоеточие) в text:match. Чтобы я определял текст до двоеточия и после него, но в случае если есть второй символ далее то он он бы заносился во вторую перменную искомого текста.

Условно — ( Текст Текст ) : ( текстексте : текст текст)
*скобки показывают разные переменные текста.
UP
 

wulfandr

Известный
637
260
почему-то не появляется окно imgui...
Lua:
script_name('New sctript') -- название скрипта
script_author('FORMYS') -- автор скрипта
script_description('Command') -- описание скрипта

require "lib.moonloader" -- подключение библиотеки
local imgui = require 'imgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local tag = '[My First Script]:' -- локальная переменная

local main_window_state = imgui.ImBool(false)
local text_buffer = imgui.ImBuffer(256)

local sw, sh = getScreenResolution()

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
  
    sampRegisterChatCommand("imgui", cmd_imgui)
  
    imgui.Process = false
  
    -- Блок выполнняющийся один раз после старта сампа
  
    while true do
        wait(0)
      
        if main_window_state.v == false then
            imgui.Process = false
        end
      
        -- Блок выполнняющийся бесконечно (пока самп активен)
      
    end
end

function cmd_imgui(arg)
    main_window_state.v = not main_window_state.v
    imgui.Process = main_window_state.v
end

function imgui.onDrawFrame()
  
    imgui.SetNextWindowSize(imgui.ImVec2(500, 500), imgui.Cond.FirstUseEver)
    imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
  
    imgui.Begin(u8"Привет", main_window_state)
    imgui.InputText(u8'‚Вводить текст сюда', text_buffer)
    imgui.Text(text_buffer.v)
    if imgui.Button('Press me') then
        sampAddChatMessage(u8:decode(text_buffer.v), -1)
    end
    imgui.End()
end
если не ошибаюсь тебе уже не первый раз помогают
почему-то не появляется окно imgui...
Lua:
script_name('New sctript') -- название скрипта
script_author('FORMYS') -- автор скрипта
script_description('Command') -- описание скрипта

require "lib.moonloader" -- подключение библиотеки
local imgui = require 'imgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local tag = '[My First Script]:' -- локальная переменная

local main_window_state = imgui.ImBool(false)
local text_buffer = imgui.ImBuffer(256)

local sw, sh = getScreenResolution()

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
   
    sampRegisterChatCommand("imgui", cmd_imgui)
   
    imgui.Process = false
   
    -- Блок выполнняющийся один раз после старта сампа
   
    while true do
        wait(0)
       
        if main_window_state.v == false then
            imgui.Process = false
        end
       
        -- Блок выполнняющийся бесконечно (пока самп активен)
       
    end
end

function cmd_imgui(arg)
    main_window_state.v = not main_window_state.v
    imgui.Process = main_window_state.v
end

function imgui.onDrawFrame()
   
    imgui.SetNextWindowSize(imgui.ImVec2(500, 500), imgui.Cond.FirstUseEver)
    imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
   
    imgui.Begin(u8"Привет", main_window_state)
    imgui.InputText(u8'‚Вводить текст сюда', text_buffer)
    imgui.Text(text_buffer.v)
    if imgui.Button('Press me') then
        sampAddChatMessage(u8:decode(text_buffer.v), -1)
    end
    imgui.End()
end
потому что OnDrawFrame был написан неверно, т.е. с маленькой буквы
Lua:
script_name('New sctript') -- название скрипта
script_author('FORMYS') -- автор скрипта
script_description('Command') -- описание скрипта

require "lib.moonloader" -- подключение библиотеки
local imgui = require 'imgui'
local encoding = require 'encoding'

encoding.default = 'CP1251'
u8 = encoding.UTF8

local tag = '[My First Script]:' -- локальная переменная

local main_window_state = imgui.ImBool(false)
local text_buffer = imgui.ImBuffer(256)


function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
    
    sampRegisterChatCommand("imgui", function()
        main_window_state.v = not main_window_state.v
    end)
    
    while true do wait(0)
        imgui.Process = main_window_state.v
    end
end


function imgui.OnDrawFrame()
    if main_window_state.v then
        local sw, sh = getScreenResolution()
        
        imgui.SetNextWindowSize(imgui.ImVec2(500, 500), imgui.Cond.FirstUseEver)
        imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        
        imgui.Begin(u8"Привет", main_window_state)
        imgui.InputText(u8'‚Вводить текст сюда', text_buffer)
        imgui.Text(text_buffer.v)
        if imgui.Button('Press me') then
            sampAddChatMessage(u8:decode(text_buffer.v), -1)
        end
    end
    imgui.End()
end
 
  • Влюблен
Реакции: Мира

bomj227

Новичок
4
2
здрасти, такой вопрос. начинаю разбираться с событиями.
не могу найти подходящее и хз, есть ли такое в принципе.
допустим, мой скрипт по нажатию ALT + ЛКМ делает некоторые действия, и в игре персонаж бьет кулаком или стреляет. есть ли возможность перехватить и отключить "огонь" на ЛКМ при зажатом ALT?
 

Dmitriy Makarov

25.05.2021
Проверенный
2,481
1,113
Не знаете почему картинки не появляются в хронологическом порядке?) (То есть в том порядке, в каком они находятся в самой папке)
Lua:
local VehicleImages = {}
for i = 400, 610 do
    VehicleImages[i] = imgui.CreateTextureFromFile(getGameDirectory() .. '\\moonloader\\vehicles.img\\'..i..'.jpg')
end
Результат в игре:
1603725598796.png

В папке:
1603725630269.png
 

Мира

Участник
455
9
решил добавить в imgui изображение, добавить добавил, но не так как надо. почему-то начинает сильно лагать, 8 фпс и картинка вообще в другом окне вылезает.
Lua:
script_name('New sctript') -- название скрипта
script_author('FORMYS') -- автор скрипта
script_description('Command') -- описание скрипта

require "lib.moonloader" -- подключение библиотеки
local imgui = require 'imgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local tag = '[My First Script]:' -- локальная переменная

local main_window_state = imgui.ImBool(false)
local text_buffer = imgui.ImBuffer(256)

local sw, sh = getScreenResolution()

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
    
    sampRegisterChatCommand("imgui", cmd_imgui)
    
    imgui.Process = false
    
    -- Блок выполнняющийся один раз после старта сампа
    
    while true do
        wait(0)
        
        if main_window_state.v == false then
            imgui.Process = false
        end
        
        -- Блок выполнняющийся бесконечно (пока самп активен)
        
    end
end

function cmd_imgui(arg)
    main_window_state.v = not main_window_state.v
    imgui.Process = main_window_state.v
end

function imgui.OnDrawFrame()
    
    imgui.SetNextWindowSize(imgui.ImVec2(1000, 1000), imgui.Cond.FirstUseEver)
    imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    
    img = imgui.CreateTextureFromFile(getGameDirectory() .. "\\moonloader\\images\\cat.jpg")
    imgui.Image(img, imgui.ImVec2(880, 740))
    
    imgui.Begin(u8"Привет", main_window_state)
    imgui.InputText(u8'Вводить текст сюда', text_buffer)
    imgui.Text(text_buffer.v)
    if imgui.Button('Press me') then
        sampAddChatMessage(u8:decode(text_buffer.v), -1)
    end
    imgui.End()
end
1603725771094.png
 

Dmitriy Makarov

25.05.2021
Проверенный
2,481
1,113
решил добавить в imgui изображение, добавить добавил, но не так как надо. почему-то начинает сильно лагать, 8 фпс и картинка вообще в другом окне вылезает.
Lua:
script_name('New sctript') -- название скрипта
script_author('FORMYS') -- автор скрипта
script_description('Command') -- описание скрипта

require "lib.moonloader" -- подключение библиотеки
local imgui = require 'imgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local tag = '[My First Script]:' -- локальная переменная

local main_window_state = imgui.ImBool(false)
local text_buffer = imgui.ImBuffer(256)

local sw, sh = getScreenResolution()

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
  
    sampRegisterChatCommand("imgui", cmd_imgui)
  
    imgui.Process = false
  
    -- Блок выполнняющийся один раз после старта сампа
  
    while true do
        wait(0)
      
        if main_window_state.v == false then
            imgui.Process = false
        end
      
        -- Блок выполнняющийся бесконечно (пока самп активен)
      
    end
end

function cmd_imgui(arg)
    main_window_state.v = not main_window_state.v
    imgui.Process = main_window_state.v
end

function imgui.OnDrawFrame()
  
    imgui.SetNextWindowSize(imgui.ImVec2(1000, 1000), imgui.Cond.FirstUseEver)
    imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
  
    img = imgui.CreateTextureFromFile(getGameDirectory() .. "\\moonloader\\images\\cat.jpg")
    imgui.Image(img, imgui.ImVec2(880, 740))
  
    imgui.Begin(u8"Привет", main_window_state)
    imgui.InputText(u8'Вводить текст сюда', text_buffer)
    imgui.Text(text_buffer.v)
    if imgui.Button('Press me') then
        sampAddChatMessage(u8:decode(text_buffer.v), -1)
    end
    imgui.End()
end
Посмотреть вложение 73192
Перетащи этот код:
img = imgui.CreateTextureFromFile(getGameDirectory() .. "\\moonloader\\images\\cat.jpg")
Куда-нибудь в function main() либо вне main, например, к тем локалкам, которые в начале скрипта.)
 

Мира

Участник
455
9
Он лагает, потому что информация в окне обновляется раз в кадр (ФПС), ну и картинка, соответственно, тоже.))
Перетащи этот код:
img = imgui.CreateTextureFromFile(getGameDirectory() .. "\\moonloader\\images\\cat.jpg")
Куда-нибудь в function main() либо вне main, например, к тем локалкам, которые в начале скрипта.)
local помог избавиться от 8 фпс, но картинка всё равно в отдельном imgui окне. сейчас попытаюсь поместить чуть ниже

UPD

imgui.Image(img, imgui.ImVec2(880, 740)) под imgui.Begin(u8"Привет", main_window_state) и всё стало GOOD
 

wulfandr

Известный
637
260
Не знаете почему картинки не появляются в хронологическом порядке?) (То есть в том порядке, в каком они находятся в самой папке)
Lua:
local VehicleImages = {}
for i = 400, 610 do
    VehicleImages[i] = imgui.CreateTextureFromFile(getGameDirectory() .. '\\moonloader\\vehicles.img\\'..i..'.jpg')
end
Результат в игре:
Посмотреть вложение 73189
В папке:
Посмотреть вложение 73191
попробуй сделать через for k, i in pairs(VehicleImages) do imgui.image end