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

[SA ARZ]

Известный
392
8
Вопрос, как сделать imgui.Button("Изменить положение окна GG") и после этого он может менять
imgui.Begin('GG', nil, imgui.WindowFlags.NoResize + imgui.WindowFlags.AlwaysAutoResize + imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoMove)
это окно на новое место, а после нажатие опять кнопки - оно сохранило новое положение
 

Harryss

Участник
233
26
Lua:
local anotherIni = inicfg.load(nil, "healme") -- пытаемся загрузить ini
if anotherIni == nil then -- если ини такого нету, то создаём
local settingst = { -- структура ini
settings = {
text = "ну типа ини"
}
}
inicfg.save(settingst, "healme") -- сохраняем
end--
set = inicfg.load(nil,"healme") -- загрузка ини
print(set.settings.text) -- в консоли будет "ну типа ини"
Тогда я не очень понимаю, как изменять значение text через команду. При вводе команды скрипт крашит, ругается на отсутствие значения у settingst. Если вместо settingst указать anotherIni, то тогда начнет работать, однако при условии что .ini файл создан, а у тех, у кого он только создаться тогда команда не будет менять значение.
Код:
function cmd_setname(data)
    local text = string.match(data, '%s*(.+)')
    settingst.settings.prefix = text
    inicfg.save(settingst, "healme")
    sampAddChatMessage("{FF7F50}[-] {ccffcc}Completed", 0xC1C1C1)
end
 

xSpiridon

Известный
74
21
Помогите пожалуйста разобрать строку на составляющие, не могу разобратся в регулярках.
Строка: {FF8C00}SMS: {FFFF00}сообщение {FF8C00}| {FFFF00}Отправитель: Nick_Name (тел. 653653)
Нужно достать из нее сообщение, отправителя (ник) и номер телефона.
 

Aniki

🐰
Администратор
1,232
1,579
Помогите пожалуйста разобрать строку на составляющие, не могу разобратся в регулярках.
Строка: {FF8C00}SMS: {FFFF00}сообщение {FF8C00}| {FFFF00}Отправитель: Nick_Name (тел. 653653)
Нужно достать из нее сообщение, отправителя (ник) и номер телефона.
Lua:
local text, name, num = text:match('{FF8C00}SMS: {FFFF00}(.-) {FF8C00}| {FFFF00}Отправитель: (.-) %(тел. (%d+)%)')
Как работает getHeadingFromVector2d ? Можно ли её на другие языки как-то перевести?
Получает направление вектора, проведенного из первой точки во вторую, результат выдает в градусной мере где 0(или 360) это север и увеличивается градус по часовой стрелке
 
  • Нравится
Реакции: xSpiridon

MITQAA

Известный
17
0
Всем доброго дня, подскажите, пожалуйста
Сделал проверку для дальнейшего продолжения, однако выдает вот такую ошибку. Весь код в main
Lua:
 test.lua: ...es (x86)\GTA San Andreas MultiPlayer\moonloader\test.lua:45: attempt to call global 'iskeydown' (a nil value)
stack traceback:
    ...es (x86)\GTA San Andreas MultiPlayer\moonloader\test.lua: in function <...es (x86)\GTA San Andreas MultiPlayer\moonloader\test.lua:13>
[ML] (error) test.lua: Script died due to an error. (0B7E41B4)

Сам код:
Lua:
    if resultheal and isKeyDown(VK_H) then -- Если зажата пкм и кнопка 1 на игроке, то...
        name = sampGetPlayerNickname(playerid) -- получаем nickname игрока по ранее полученному ID.
               sampAddChatMessage("{ffffff}* [Helper{77dd77}for{ffffff}Doctor]:  {77dd77}Вы начали взаимодействие с {ffffff}"..name.."["..playerid.."]", 0xC1C1C1)
               wait(1400)
               sampSendChat("Добрый день! Я ваш лечащий врач. Чем могу помочь?")
               wait(2000)
         sampAddChatMessage("{ffffff}* [Helper{77dd77}for{ffffff}Doctor]:  {77dd77}Для продолжения нажмите {ffffff} Y", 0xC1C1C1)
         if iskeydown(0x59) and resultheal then
                sampSendChat("/me осмотрел(а) пациента и поставил(а) диагноз")
                wait(2000)
                sampSendChat("/me открыл(а) медицинскую сумку")
                wait(2000)
                sampSendChat("/me достал(а) из медицинской сумки лекарство")
                wait(2000)
                sampSendChat("/do В руках стакан воды и лекарство.")
                wait(2000)
                sampSendChat("Держите, сейчас Вам станет легче.")
                wait(2000)
                sampSendChat("/me передал(а) стакан воды и лекарство")
                wait(2000)
                sampSendChat("Удачного дня, не болейте!")
                wait(2000)
                sampSendChat("/heal "..playerid.." 100")
                wait(700)
                sampSendChat("/time")
         end
     end
 

trefa

3d print
Всефорумный модератор
2,124
1,288
Всем доброго дня, подскажите, пожалуйста
Сделал проверку для дальнейшего продолжения, однако выдает вот такую ошибку. Весь код в main
Lua:
 test.lua: ...es (x86)\GTA San Andreas MultiPlayer\moonloader\test.lua:45: attempt to call global 'iskeydown' (a nil value)
stack traceback:
    ...es (x86)\GTA San Andreas MultiPlayer\moonloader\test.lua: in function <...es (x86)\GTA San Andreas MultiPlayer\moonloader\test.lua:13>
[ML] (error) test.lua: Script died due to an error. (0B7E41B4)

Сам код:
Lua:
    if resultheal and isKeyDown(VK_H) then -- Если зажата пкм и кнопка 1 на игроке, то...
        name = sampGetPlayerNickname(playerid) -- получаем nickname игрока по ранее полученному ID.
               sampAddChatMessage("{ffffff}* [Helper{77dd77}for{ffffff}Doctor]:  {77dd77}Вы начали взаимодействие с {ffffff}"..name.."["..playerid.."]", 0xC1C1C1)
               wait(1400)
               sampSendChat("Добрый день! Я ваш лечащий врач. Чем могу помочь?")
               wait(2000)
         sampAddChatMessage("{ffffff}* [Helper{77dd77}for{ffffff}Doctor]:  {77dd77}Для продолжения нажмите {ffffff} Y", 0xC1C1C1)
         if iskeydown(0x59) and resultheal then
                sampSendChat("/me осмотрел(а) пациента и поставил(а) диагноз")
                wait(2000)
                sampSendChat("/me открыл(а) медицинскую сумку")
                wait(2000)
                sampSendChat("/me достал(а) из медицинской сумки лекарство")
                wait(2000)
                sampSendChat("/do В руках стакан воды и лекарство.")
                wait(2000)
                sampSendChat("Держите, сейчас Вам станет легче.")
                wait(2000)
                sampSendChat("/me передал(а) стакан воды и лекарство")
                wait(2000)
                sampSendChat("Удачного дня, не болейте!")
                wait(2000)
                sampSendChat("/heal "..playerid.." 100")
                wait(700)
                sampSendChat("/time")
         end
     end
Проверка должна быть в цикле
Lua:
local key = require 'vkeys'

wasKeyPressed(key.VK_Q)
 

atizoff

приобретаю кашель за деньги
Проверенный
1,296
1,178
Как сделать такую же менюшку справа?
16677
 

Babayka2016

Известный
51
2
Помогите пожалуйста, как сделана функция getCarHeading()? Именно в плане кода. Какой она андрес читает? Какой адрес нужно прочитать, чтобы получить то же самое, что возвращает getCarHeading?
 
Последнее редактирование:

trefa

3d print
Всефорумный модератор
2,124
1,288
Нет, а как сделать вот это вот "Информация" "Настройка"?
Вот так же как показал
Lua:
imgui.BeginChild("##fdg", imgui.ImVec2(100, 50),true)

if imgui.Selectable(u8"Настройки") then
end

if imgui.Selectable(u8"Информация") then
end

imgui.EndChild()
 
  • Нравится
Реакции: atizoff

atizoff

приобретаю кашель за деньги
Проверенный
1,296
1,178
Вот так же как показал
Lua:
imgui.BeginChild("##fdg", imgui.ImVec2(100, 50),true)

if imgui.Selectable(u8"Настройки") then
end

if imgui.Selectable(u8"Информация") then
end

imgui.EndChild()
Блин, trefa_, извини, что задаю такие тупые вопросы, я бы уже лопнул, но я тупой, и хз, куда вставить?

Lua:
local imgui = require 'imgui'
local key = require 'vkeys'
local sampev = require 'lib.samp.events'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
--
function imgui.OnDrawFrame()
    imgui.BeginChild("##fdg", imgui.ImVec2(100, 50),true)

    if imgui.Selectable(u8"Настройки") then
    end
   
    if imgui.Selectable(u8"Информация") then
    end
   
    imgui.EndChild()
end
 

trefa

3d print
Всефорумный модератор
2,124
1,288
Блин, trefa_, извини, что задаю такие тупые вопросы, я бы уже лопнул, но я тупой, и хз, куда вставить?

Lua:
local imgui = require 'imgui'
local key = require 'vkeys'
local sampev = require 'lib.samp.events'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
--
function imgui.OnDrawFrame()
    imgui.BeginChild("##fdg", imgui.ImVec2(100, 50),true)

    if imgui.Selectable(u8"Настройки") then
    end
  
    if imgui.Selectable(u8"Информация") then
    end
  
    imgui.EndChild()
end
Lua:
if main_window_state.v then
    imgui.SetNextWindowPos(imgui.ImVec2(1366 / 2, 768 / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(320, 100), imgui.Cond.FirstUseEver)
    imgui.Begin(u8'Моя первый имгуи скрипт!', main_window_state)
    imgui.Text(u8'Чтобы активировать скрипт, нажмите на кнопку.')
    imgui.BeginChild("##fdg", imgui.ImVec2(100, 50),true)

    if imgui.Selectable(u8"Настройки") then
    end
   
    if imgui.Selectable(u8"Информация") then
    end
   
    imgui.EndChild()
    imgui.End()
  end
 
  • Нравится
Реакции: atizoff

atizoff

приобретаю кашель за деньги
Проверенный
1,296
1,178
Почему не работает? В лог выбивает ошибку.
Lua:
local imgui = require 'imgui'
local key = require 'vkeys'
local sampev = require 'lib.samp.events'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
--
function imgui.ToggleButton(str_id, bool)

    local rBool = false
    if LastActiveTime == nil then
       LastActiveTime = {}
    end
    if LastActive == nil then
       LastActive = {}
    end
    local function ImSaturate(f)
       return f < 0.0 and 0.0 or (f > 1.0 and 1.0 or f)
    end
 
    local p = imgui.GetCursorScreenPos()
    local draw_list = imgui.GetWindowDrawList()
    local height = imgui.GetTextLineHeightWithSpacing() + (imgui.GetStyle().FramePadding.y / 2)
    local width = height * 1.55
    local radius = height * 0.50
    local ANIM_SPEED = 0.15
    if imgui.InvisibleButton(str_id, imgui.ImVec2(width, height)) then
       bool.v = not bool.v
       rBool = true
       LastActiveTime[tostring(str_id)] = os.clock()
       LastActive[str_id] = true
    end
    local t = bool.v and 1.0 or 0.0
    if LastActive[str_id] then
       local time = os.clock() - LastActiveTime[tostring(str_id)]
       if time <= ANIM_SPEED then
          local t_anim = ImSaturate(time / ANIM_SPEED)
          t = bool.v and t_anim or 1.0 - t_anim
       else
          LastActive[str_id] = false
       end
    end
    local col_bg
    if imgui.IsItemHovered() then
       col_bg = imgui.GetColorU32(imgui.GetStyle().Colors[imgui.Col.FrameBgHovered])
    else
       col_bg = imgui.GetColorU32(imgui.GetStyle().Colors[imgui.Col.FrameBg])
    end
    draw_list:AddRectFilled(p, imgui.ImVec2(p.x + width, p.y + height), col_bg, height * 0.5)
    draw_list:AddCircleFilled(imgui.ImVec2(p.x + radius + t * (width - radius * 2.0), p.y + radius), radius - 1.5, imgui.GetColorU32(bool.v and imgui.GetStyle().Colors[imgui.Col.ButtonActive] or imgui.GetStyle().Colors[imgui.Col.Button]))
    return rBool
end
--
local main_window_state = imgui.ImBool(false)
function imgui.OnDrawFrame()
    if main_window_state.v then
        imgui.SetNextWindowPos(imgui.ImVec2(1366 / 2, 800 / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(500, 350), imgui.Cond.FirstUseEver)
        imgui.Begin(u8'Моя первый имгуи скрипт!', main_window_state)
        imgui.BeginChild("##fdg", imgui.ImVec2(100, 300),true)
   
        if imgui.Selectable(u8"Активация", page_selected == 1) then
               imgui.AlignTextToFramePadding()
            imgui.Text(u8("Тупить сильнее когда говорят не тупи"))
            imgui.SameLine(365)
          if imgui.ToggleButton("Test##1", imBool) then
            sampAddChatMessage("You change status, new status: " .. tostring(imBool.v), -1)
          end
        end
        if imgui.Selectable(u8"Информация", page_selected == 2) then
        end
        imgui.EndChild()
        imgui.End()
      end
    end

function main()
    while true do
        wait(0)
        if wasKeyPressed(key.VK_Z) then
            main_window_state.v = not main_window_state.v
        end
        imgui.Process = main_window_state.v
    end
end

[ML] (error) anti1hour.lua: D:\sampv2\moonloader\anti1hour.lua:38: attempt to index local 'bool' (a nil value)
stack traceback:
D:\sampv2\moonloader\anti1hour.lua:38: in function 'ToggleButton'
D:\sampv2\moonloader\anti1hour.lua:75: in function 'OnDrawFrame'
D:\sampv2\moonloader\lib\imgui.lua:1377: in function <D:\sampv2\moonloader\lib\imgui.lua:1366>
[ML] (error) anti1hour.lua: Script died due to an error. (0E2E90BC)