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

Fott

Простреленный
3,461
2,374
Lua:
script_name('Версия 0.1')
script_author('Автор A')
script_description('rfam')
require "lib.moonloader"

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(2000) end
    sampAddChatMessage('текст')
    sampRegisterChatCommand('rfam', rfam)
    while true do
        wait(0)
    end
end

function rfam()
    local peds = getAllChars()
    for _, v in pairs(peds) do
        local result, myid = sampGetPlayerIdByCharHandle(playerPed)
        local mx, my, mz = getCharCoordinates(playerPed)
        local x, y, z = getCharCoordinates(v)
        local distance = getDistanceBetweenCoords3d(mx, my, mz, x, y, z)
        local result, id = sampGetPlayerIdByCharHandle(v)
        if result and id ~= sampGetPlayerIdByCharHandle(PLAYER_PED) and distance < 12.0 then
            if id ~= myid then
                sampSendChat('/faminvite '..tonumber(id))
            end
        end
    end
end
скопировал твой код и у меня работает..
 
  • Нравится
Реакции: deleted-user-210352

si0z

Участник
37
2
Как сделать так, чтобы эти три значения можно было менять сразу в игре?
 

Manuel Leon

Известный
266
169
Как узнать текст текстуры? Это не 3д текст.

1589999486669.png
 

NetyEgo

Участник
164
10
Вот создал строки РадиоБатон
imgui.RadioButton(u8"Команды Diamond RP.", cmdserver, 1)
imgui.RadioButton(u8"Команды Arizona RP.", cmdserver, 2)
и хочу сделать, если нажата кнопка(Команды Arizona RP.) то, началась работа скрипта(Например в чат вывелось: ку-ку)
А если нажата другая кнопка(Команды Diamond RP.) то, началась другая работа скрипта(Например в чат вывелось: пока)
И да, мне не нужен код, просто проверка(Не знаю как сделать)
 

no3jour

Участник
55
0
Попытался сделать 2 окна imgui, но крашит скрипт
PHP:
local imgui = require 'imgui'
local key = require 'vkeys'
local label = 0
local login = 0
local encoding = require 'encoding' -- загружаем библиотеку
encoding.default = 'CP1251' -- указываем кодировку по умолчанию, она должна совпадать с кодировкой файла. CP1251 - это Windows-1251
u8 = encoding.UTF8 -- и создаём короткий псевдоним для кодировщика UTF-8
local apass = imgui.ImBuffer(256)
local imgui_1 = imgui.ImBool(false)
local imgui_2 = imgui.ImBool(false)
function imgui.OnDrawFrame()
  if imgui_1.v then
    imgui.SetNextWindowSize(imgui.ImVec2(250, 100), imgui.Cond.FirstUseEver) -- меняем размер
    imgui.Begin(u8'Авторизация') -- обратите внимание на u8 перед текстом, это и есть преобразование кодировки
    imgui.Text(u8'Введите свой пароль для авторизации')
    imgui.Text(u8'Пароль:')
    imgui.SameLine();
    if imgui.InputText(u8'', apass, imgui.ImVec2(25, 0)) then end
    if imgui.Button(u8'Авторизоваться') then
      checkpassd(arg)
    end
end
  if imgui_2.v then
      imgui.SetNextWindowSize(imgui.ImVec2(250, 200), imgui.Cond.FirstUseEver)
      imgui.Begin('Второе окно', s_openn, imgui.WindowFlags.MenuBar)
      imgui.Text(u8'Какой-то текст уляля')
      imgui.End()
      end
  end
local function commandsReg()
  sampRegisterChatCommand("test", test)
end
local function welcome()
  if label == 1 then
    sampAddChatMessage("{FFFFFF}Скрипт не загружен. Автор: NickName")
      thisScript():unload();
  else
    sampAddChatMessage("{ffffff}Загрузка скрипта произошла успешно. Автор скрипта: NickName")
    sampAddChatMessage("{ffffff}Для активации скрипта нажмите клавишу M(англ)")
  end
end
function main()
  if not isSampLoaded() or not isSampfuncsLoaded() then return end
  while not isSampAvailable() do wait(100) end
  commandsReg();
  welcome();
  while true do
    wait(0)
    if wasKeyPressed(key.VK_X) then
      imgui_1.v = not imgui_1.v
    end
    if wasKeyPressed(key.VK_Z) then
      imgui_2.v = not imgui_2.v
    end
    imgui.Process = imgui_1.v
    imgui.Process = imgui_2.v
  end
end
function checkpassd(arg)
  arg = apass.v
  if tonumber(login) == 0 then
    if #arg == 0 or tonumber(arg) == nil or type(tonumber(arg)) ~= "number" then
      sampAddChatMessage('Доступны только цифры')
    else
      if tonumber(arg) == 5555 then --Тут твой пароль
        sampAddChatMessage('{ffffff}Авторизация выполнена успешно.')
        login = 1
        imgui_1.v = false
      else
        sampAddChatMessage('{FFFFFF}Ошибка авторизации.')
        login = 0
      end
    end
  else
    sampAddChatMessage('{ffffff}Ошибка, вы уже авторизованы')
  end
end
function test(arg)
  if tonumber(login) == 1 then
    sampAddChatMessage('{ffffff}Действия прошли успешно, вы авторизованы.')
  else
    sampAddChatMessage('{ffffff}Ошибка, вы не авторизовались, нажмите клавишу M(англ)')
  end
end
--function teleport()
--    while not isSampAvailable() do wait(100) end
--    bool,x,y,z = getTargetBlipCoordinates()
--    if bool then setCharCoordinates(playerPed,x,y,z) 
--  end 
--end
--    while true do wait(0) 
--  end 
--end
 

fleysher

Новичок
9
1
1. Если текст в имгуи на русском, при его открытии крашит игру (ошибки вообще нет), если же язык английский - всё норм, код:

Код:
local imgui = require 'imgui'
local main_window_state = imgui.ImBool(false)
local encoding = require 'encoding'
nick = imgui.ImBuffer(256)
local u8 = encoding.UTF8

function main()
    repeat wait(0) until isSampAvailable()
        wait(1000)
        sampAddChatMessage('{FFFFFF}Ат души и ат стезеба!', -1)
        sampRegisterChatCommand('recon', recon)
         imgui.Process = true
        while true do
            wait(0)
            if isKeyJustPressed(90) then
         main_window_state.v = not main_window_state.v
 end
 imgui.Process = main_window_state.v
        end
end

function recon()
    main_window_state.v = not main_window_state.v
end

function imgui.OnDrawFrame()
     if main_window_state.v then
      imgui.SetNextWindowSize(imgui.ImVec2(1024, 512), imgui.Cond.FirstUseEver)
   imgui.Begin('Reconnect')
     imgui.InputText(u8'Введи ник(Пока что просто так)', nick)
     if imgui.Button('Phoenix') then
         printStringNow('Reconnect!', 1000)
         sampConnectToServer('185.169.134.3','7777')
     end
    if imgui.Button('Secret server') then
        printStringNow('Reconnect!', 1000)
         sampConnectToServer('37.230.162.117','7777')
     end
     if imgui.Button('Secret function') then
         sampSendChat('Stizzib krytoy!')
     end
   imgui.End()
 end
end
2. Что нужно для того, чтоб окно было по середине? Пытался сделать - не смог
3. Как можно вставить в скрипт какое-то фото?
Версия мун лоадера - 0.26
 

tamperplay

Новичок
16
0
Видел пример, возле которого было указано, пример как обезвредить, а так как я нуб, не понимаю, но как я понял, скрипт ниже еще не обезвреживает данную функцию, прошу помочь
function thisScript()
local function unload() print("oooppps :(((") end
return {["unload"] = unload}
end
 

Mr_Incognito

Активный
329
51
Подскажите, пожалуйста.
Вот есть imgui окошко. Хочу чтоб там был текст из txt файла.
Погуглил тут и нашел способ.

Lua:
local file = io.open("moonloader/testt.txt")
for lines in file:lines(file) do
    imgui.TextWrapped(lines)
end

Он работает, НО скрипт крашится через 5-7 секунд с такой ошибкой

Код:
[ML] (error) imguiii.lua: C:\GAMES\GTA San Andreas\moonloader\imguiii.lua:17: attempt to index local 'file' (a nil value)
stack traceback:
 

Howl1337

Известный
235
146
Как в в главном окне ImGui вызвать второе окно, которые не будет закрываться при закрытии первого окна?
 

tamperplay

Новичок
16
0
Каким скриптом запретить выгрузку скрипта?
По этому примеру как реализовать?

function thisScript()
local function unload() print("oooppps :(((") end
return {["unload"] = unload}
end

И как вызвать window_main окно на imgui?)))) Прошу помощи)))
 

samartinell1

Участник
98
14
Здравствуйте, решил написать скриптик для ловли объявлений в СМИ простой, но столкнулся с кучей проблем, одну из которой я до сих пор решить не смог, а в интернете инфы нет никакой.
Код:
label = 0 -- устанавливаю дефолтное значение для ловли
  sampAddChatMessage(tag_color .. '[MM Editor]:' .. " {D3D3D3}Скрипт успешно активирован. Для ловли нажмите клавишу {1E90FF}F3{D3D3D3}.", 0xD3D3D3)
  sampRegisterChatCommand('f3', cmd_f3)
  while true do
  if label == 0 then renderFontDrawText(my_font, 'Ловля{1E90FF} [F3]{FFFFFFFF}:\n{FFFFFFFF}Режим ожидания..', 10, 1030, 0xFFFFFFFF) end
  if label == 1 then renderFontDrawText(my_font, 'Ловля{1E90FF} [F3]{FFFFFFFF}:\n{1E90FF}Идёт ловля.', 10, 1030, 0xFFFFFFFF) end
  if label == 2 then renderFontDrawText(my_font, 'Ловля{1E90FF} [F3]{FFFFFFFF}:\n{8B0000}Ошибка.', 10, 1030, 0xFFFFFFFF) end
  if label == 5 then renderFontDrawText(my_font, 'Ловля{1E90FF} [F3]{FFFFFFFF}:\n{8B0000}Перезапуск ловли.', 10, 1030, 0xFFFFFFFF) end
    wait(0) -- беск цикл
  if isKeyJustPressed(VK_F3) and label == 0 or isKeyJustPressed(VK_F3) and label == 2 or label == 5 then
    wait(10)
    sampAddChatMessage(tag_color .. '[MM Editor]:' .. " {D3D3D3}Ловля активирована. Для приостановки зажмите клавишу F3.", 0xD3D3D3)
    label = 1 -- изменяю значение на 1 и говорю ей че делать
      repeat
      wait(100)
      sampSendChat('/edit')
      wait(1400)
      until
      label == 2 or isKeyDown(VK_F3) and label == 1
      wait(100)
      if label == 1 then sampAddChatMessage(tag_color .. '[MM Editor]:' .. " {D3D3D3}Ловля приостановлена. Для возобновления нажмите клавишу F3.", 0xD3D3D3) wait(300) label = 0 wait(300) else sampAddChatMessage(tag_color .. '[MM Editor]:' .. " {D3D3D3}Ловля принудительно остановлена для избежания кика.", 0xD3D3D3) wait(10) sampAddChatMessage(tag_color .. '[MM Editor]:' .. " {D3D3D3}Ловля будет продолжена автоматически через 10 секунд.", 0xD3D3D3) wait(10000) label = 5
      end
    end
  end -- беск цикл конец
end
как то так выглядит почти весь код (да-да, я говнокодер, для себя не жалко) и я не могу понять каким образом сделать так, чтобы при разных label отображался разный текст в текстдраве, он у меня отображается при дефолтном значении, а когда идёт сама ловля или перезапуск её ничего отображаться не хочет(тк функция не прошла полный круг), если вставляю в нужную ситуацию через while, то тогда сама ловля не идёт и скрипт отказывается работать дальше. Возможно есть какой-то аналог repeat, чтобы он работал без условия или можно его как то подставить? В общем жду реальной help in this question, потому что я не знаю как дальше двигаться, а без текстдрава моя затея подучить Луа была бы глупой, ведь то же самое можно было сделать по сути и в биндере((
 

niki4

Участник
92
10
Здравствуйте, решил написать скриптик для ловли объявлений в СМИ простой, но столкнулся с кучей проблем, одну из которой я до сих пор решить не смог, а в интернете инфы нет никакой.
Код:
label = 0 -- устанавливаю дефолтное значение для ловли
  sampAddChatMessage(tag_color .. '[MM Editor]:' .. " {D3D3D3}Скрипт успешно активирован. Для ловли нажмите клавишу {1E90FF}F3{D3D3D3}.", 0xD3D3D3)
  sampRegisterChatCommand('f3', cmd_f3)
  while true do
  if label == 0 then renderFontDrawText(my_font, 'Ловля{1E90FF} [F3]{FFFFFFFF}:\n{FFFFFFFF}Режим ожидания..', 10, 1030, 0xFFFFFFFF) end
  if label == 1 then renderFontDrawText(my_font, 'Ловля{1E90FF} [F3]{FFFFFFFF}:\n{1E90FF}Идёт ловля.', 10, 1030, 0xFFFFFFFF) end
  if label == 2 then renderFontDrawText(my_font, 'Ловля{1E90FF} [F3]{FFFFFFFF}:\n{8B0000}Ошибка.', 10, 1030, 0xFFFFFFFF) end
  if label == 5 then renderFontDrawText(my_font, 'Ловля{1E90FF} [F3]{FFFFFFFF}:\n{8B0000}Перезапуск ловли.', 10, 1030, 0xFFFFFFFF) end
    wait(0) -- беск цикл
  if isKeyJustPressed(VK_F3) and label == 0 or isKeyJustPressed(VK_F3) and label == 2 or label == 5 then
    wait(10)
    sampAddChatMessage(tag_color .. '[MM Editor]:' .. " {D3D3D3}Ловля активирована. Для приостановки зажмите клавишу F3.", 0xD3D3D3)
    label = 1 -- изменяю значение на 1 и говорю ей че делать
      repeat
      wait(100)
      sampSendChat('/edit')
      wait(1400)
      until
      label == 2 or isKeyDown(VK_F3) and label == 1
      wait(100)
      if label == 1 then sampAddChatMessage(tag_color .. '[MM Editor]:' .. " {D3D3D3}Ловля приостановлена. Для возобновления нажмите клавишу F3.", 0xD3D3D3) wait(300) label = 0 wait(300) else sampAddChatMessage(tag_color .. '[MM Editor]:' .. " {D3D3D3}Ловля принудительно остановлена для избежания кика.", 0xD3D3D3) wait(10) sampAddChatMessage(tag_color .. '[MM Editor]:' .. " {D3D3D3}Ловля будет продолжена автоматически через 10 секунд.", 0xD3D3D3) wait(10000) label = 5
      end
    end
  end -- беск цикл конец
end
как то так выглядит почти весь код (да-да, я говнокодер, для себя не жалко) и я не могу понять каким образом сделать так, чтобы при разных label отображался разный текст в текстдраве, он у меня отображается при дефолтном значении, а когда идёт сама ловля или перезапуск её ничего отображаться не хочет(тк функция не прошла полный круг), если вставляю в нужную ситуацию через while, то тогда сама ловля не идёт и скрипт отказывается работать дальше. Возможно есть какой-то аналог repeat, чтобы он работал без условия или можно его как то подставить? В общем жду реальной help in this question, потому что я не знаю как дальше двигаться, а без текстдрава моя затея подучить Луа была бы глупой, ведь то же самое можно было сделать по сути и в биндере((
У тебя сразу же меню редактирования открывается по команде /edit?