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

lorgon

Известный
657
268
хз чапо знает мб, чапо ты де
Ну я примерно нашёл, то что мне надо, но если бы кто помог разобраться, было бы отлично
SetNextWindowSizeConstraints(const ImVec2 size_min,const ImVec2 size_max,ImGuiSizeCallback custom_callback,void* custom_callback_data). Поэтому вопрос остаётся
 

de_clain

Активный
208
47
Ну я примерно нашёл, то что мне надо, но если бы кто помог разобраться, было бы отлично
SetNextWindowSizeConstraints(const ImVec2 size_min,const ImVec2 size_max,ImGuiSizeCallback custom_callback,void* custom_callback_data). Поэтому вопрос остаётся
function imgui.SetNextWindowSizeraints(size_min: any, size_max: any, ImGuiSizeCallbackcustom_callback: any, custom_callback_data: any) eto ? у chapo. нашел в плагинах
 

Sadow

Известный
1,438
592
Как сделать проверку на то виден ли на экране 3D текст или нет? По типу isObjectScreen
 

lorgon

Известный
657
268
Не, мне нужно чтобы соотношения сторон окна всегда сохранялись, типо, если сначала вывожу окно 300x300, а пользователь потянет за край окна, то при увелечение, соотношение всегда было 1 к 1, например 300x300, 400x400, 1000x1000, в какую бы сторону он не потянул.
Короче, поебался немного и вроде-бы нашёл решение.
Lua:
-- before im.OnFrame
function resize_callback(data)
    local ratio = data.CurrentSize.x / data.CurrentSize.y
    data.DesiredSize.x = data.DesiredSize.y
end
local callback = ffi.cast('ImGuiSizeCallback', resize_callback)

-- min_size / max_size - ImVec2
-- after im.OnFrame
im.SetNextWindowSizeConstraints(min_size, max_size, callback, nil)
im.Begin(...)
im.End()
Это просто пример, не советую использовать это для готового проекта!
 
  • Эм
Реакции: qdIbp

7 СМЕРТНЫХ ГРЕХОВ

Известный
515
159
Как сделать что бы я мог редактировать текст
LUA:
if int_item[0] == 1 then
    imgui.StrCopy(textBuffer, u8"{FFFFFF}Nick_Name[id] говорит:{B7AFAF} текст")
end
1681551535110.png

Когда пытаюсь что то другое написать оно просто возвращает обратно значение
 

MLycoris

Режим чтения
Проверенный
1,824
1,881
Как сделать что бы я мог редактировать текст
LUA:
if int_item[0] == 1 then
    imgui.StrCopy(textBuffer, u8"{FFFFFF}Nick_Name[id] говорит:{B7AFAF} текст")
end
Посмотреть вложение 197743
Когда пытаюсь что то другое написать оно просто возвращает обратно значение
Если я правильно понял, то вот
Lua:
 -- в начале где нибудь
local test = 'shit asdlds'
local textBuffer = new.char[256](test)

-- в окне
if imgui.InputText("##Text", textBuffer, 256) then
    test = u8:decode(ffi.string(textBuffer)) -- переписываем значение test
end
 
  • Нравится
Реакции: de_clain

7 СМЕРТНЫХ ГРЕХОВ

Известный
515
159
Если я правильно понял, то вот
Lua:
 -- в начале где нибудь
local test = 'shit asdlds'
local textBuffer = new.char[256](test)

-- в окне
if imgui.InputText("##Text", textBuffer, 256) then
    test = u8:decode(ffi.string(textBuffer)) -- переписываем значение test
end
выбор идет через комбо
1681552659504.png


LUA:
if int_item[0] == 1 then
    imgui.StrCopy(textBuffer, u8"{FFFFFF}Nick_Name[id] говорит:{B7AFAF} текст")
end
if int_item[0] == 2 then
    imgui.StrCopy(textBuffer, u8"{FF99FF}Nick_Name[id] рп текст")
end
if int_item[0] == 3 then
    imgui.StrCopy(textBuffer, u8"{4682B4}  .  - |  Nick_Name[id]")
end
if int_item[0] == 4 then
    imgui.StrCopy(textBuffer, u8"{FFFFFF}''текст'', - сказал(а) Nick_Name[id],{FF99FF} рп текст.")
end
 

CaJlaT

Овощ
Модератор
2,808
2,619
выбор идет через комбо Посмотреть вложение 197744

LUA:
if int_item[0] == 1 then
    imgui.StrCopy(textBuffer, u8"{FFFFFF}Nick_Name[id] говорит:{B7AFAF} текст")
end
if int_item[0] == 2 then
    imgui.StrCopy(textBuffer, u8"{FF99FF}Nick_Name[id] рп текст")
end
if int_item[0] == 3 then
    imgui.StrCopy(textBuffer, u8"{4682B4}  .  - |  Nick_Name[id]")
end
if int_item[0] == 4 then
    imgui.StrCopy(textBuffer, u8"{FFFFFF}''текст'', - сказал(а) Nick_Name[id],{FF99FF} рп текст.")
end
Вызывай imgui.StrCopy только внутри колбэка imgui.Combo, иначе у тебя в цикле будет перезаписываться значение, что не даст тебе изменить инпут
Lua:
if imgui.Combo() then
    if int_item[0] == 1 then
        imgui.StrCopy(textBuffer, u8"{FFFFFF}Nick_Name[id] говорит:{B7AFAF} текст")
    end
    if int_item[0] == 2 then
        imgui.StrCopy(textBuffer, u8"{FF99FF}Nick_Name[id] рп текст")
    end
    if int_item[0] == 3 then
        imgui.StrCopy(textBuffer, u8"{4682B4}  .  - |  Nick_Name[id]")
    end
    if int_item[0] == 4 then
        imgui.StrCopy(textBuffer, u8"{FFFFFF}''текст'', - сказал(а) Nick_Name[id],{FF99FF} рп текст.")
    end
end
 

MLycoris

Режим чтения
Проверенный
1,824
1,881
тогда попробуй так
Lua:
-- В начале
local ComboTest = new.int()
local item_list = {u8'Раз', u8'Два', u8'Три'} -- твоё комбо
local ImItems = new['const char*'][#item_list](item_list)

local table = { -- твои бинды
    'фывфыв',
    'ав',
    'asdasd'
}

local shit = new.char[256](u8(table[ComboTest[0]+1])) -- буфер для инпута

-- в окне
if imgui.Combo(u8'Список',ComboTest,ImItems, #item_list) then
    imgui.StrCopy(shit, u8(table[ComboTest[0]+1]))
end
if imgui.InputText('ssd',shit,256) then
    table[ComboTest[0]+1] = u8:decode(ffi.string(shit)) -- перезаписываем значение в таблицы, ну и сохраняем
end
 

santyy13gg

Новичок
9
1
при заходе на сервер во время тех рестарта на Аризоне выдает диалоговое окно, как его закрыть?
 

tyukapa

Активный
299
65
Как правильно сюда вставить u8. Чтобы место каракуль писало нормальный текст

Код:
     if imgui.Button(u8"Начать") then
     sampAddChatMessage(mainIni.config.flood .. "",-1)
     end
 

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Друг
8,776
11,226
Как правильно сюда вставить u8. Чтобы место каракуль писало нормальный текст

Код:
     if imgui.Button(u8"Начать") then
     sampAddChatMessage(mainIni.config.flood .. "",-1)
     end
Lua:
 sampAddChatMessage(u8:decode(mainIni.config.flood),-1)
 
  • Нравится
Реакции: tyukapa

tyukapa

Активный
299
65
при заходе на сервер во время тех рестарта на Аризоне выдает диалоговое окно, как его закрыть?
можно сделать чтобы скрипт какнибуть определял что перед ним диалог ( ну например через id диалога ), и после того как он понял что перед ним вылезло окно он нажимал кнопку чтобы его закрыть (допустим enter)

Код:
    setVirtualKeyDown(VK_RETURN, true) -- скрипт нажал на enter
    wait(30)
    setVirtualKeyDown(VK_RETURN, false) -- скрипт отпустил enter

Виртуальные клавиши: https://api.farmanager.com/ru/winapi/virtualkeycodes.html
 
  • Bug
Реакции: chapo