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

Pashyka

Участник
220
17
А зачем return false в конце функции то? Он все диалоги перестанет показывать
Lua:
if text:find("Вы получили $2100") and not text:find("говорит") and not text:find("- |") and not text:find("Тел.") and not text:find("News") and lovla == true or text:find("Вы получили $5500") and not text:find("говорит") and not text:find("- |") and not text:find("Тел.") and not text:find("News") and lovla == true then
        lua_thread.create(function()
            setVirtualKeyDown(27, true) -- зажатие 13 клавиши (Esc)
            wait(1)
            setVirtualKeyDown(27, false) -- отпускание 13 клавиши (Esc)
        end)
        lua_thread.create(function()
            lovla = false
            wait(10000)
            lovla = true
            sampAddChatMessage("Ловля активна снова", 0x00FF00)
        end)
    end

Чисто логически можно сделать и так, но если я иду на Альте к примеру игра сворачивается xD
 

Pashyka

Участник
220
17
покажи как юзал, мб с параметрами попутал
Lua:
if text:find("Вы получили $2100") and not text:find("говорит") and not text:find("- |") and not text:find("Тел.") and not text:find("News") and lovla == true or text:find("Вы получили $5500") and not text:find("говорит") and not text:find("- |") and not text:find("Тел.") and not text:find("News") and lovla == true then
        active = true
        lua_thread.create(function()
            lovla = false
            wait(10000)
            lovla = true
            sampAddChatMessage("Ловля активна снова", 0x00FF00)
        end)
    end
    if lovla == true then
        if text:find("На обработку объявлений пришло сообщение") and not sampIsCursorActive() and not text:find('говорит') and not text:find('- |') and not text:find('Тел.') and not text:find('News') or text:find("На обработку объявлений пришло VIP сообщение") and not text:find('говорит') and not text:find('- |') and not text:find('Тел.') and not text:find('News') and not sampIsCursorActive() then
            sampSendChat("/newsredak")
            sampSendDialogResponse(556, 1, 0, -1)
        end
    end
end
function hook.onShowDialog(dialogId, style, title, button1, button2, text) -- Хукаем текст с диалога
    if active then
        if id == 556 then
            sampSendDialogResponse(556, 0 , 0, nil)
            return false
        end
    end
end
 

Smeruxa

Известный
1,372
726
Lua:
if text:find("Вы получили $2100") and not text:find("говорит") and not text:find("- |") and not text:find("Тел.") and not text:find("News") and lovla == true or text:find("Вы получили $5500") and not text:find("говорит") and not text:find("- |") and not text:find("Тел.") and not text:find("News") and lovla == true then
        lua_thread.create(function()
            setVirtualKeyDown(27, true) -- зажатие 13 клавиши (Esc)
            wait(1)
            setVirtualKeyDown(27, false) -- отпускание 13 клавиши (Esc)
        end)
        lua_thread.create(function()
            lovla = false
            wait(10000)
            lovla = true
            sampAddChatMessage("Ловля активна снова", 0x00FF00)
        end)
    end

Чисто логически можно сделать и так, но если я иду на Альте к примеру игра сворачивается xD
проверку на Alt добавь
 
  • Нравится
Реакции: Pashyka

Kosatik

Участник
113
20
чел, не надо флудить, напиши что ты хочешь сделать с этим скриптом и кому будет не лень тот сделает. Просто такое ощущение что тебе самому это не очень то и надо. Почему например у тебя test начинается с одиночкой кавычки ('), а закрывается двойными кавычками?(")?Посмотреть вложение 83544

Зачем вместо "ссылки" на функцию пытатся сделать ее в той же строке если ты не умеешь этого делать?
у тебя так:

Посмотреть вложение 83547

а должно быть так:
Посмотреть вложение 83549
или так:
Посмотреть вложение 83550
понимаешь я бы не был бы против от помощи но я хочу скрипт выложить на бх та и учусь мы можем вместе сделать. Понимаешь смысл тогда от програмированния если тебе напишут скрипт
 

chapo

чопа сребдс // @moujeek
Модератор
8,935
11,704
Как изменить положение piemenu? Поиск по форуму не дал внятного ответа
Lua:
local imgui = require 'imgui';
local pie = require 'imgui_piemenu';
local key = require 'vkeys';
local x, y = getScreenResolution()

local piemenu  = imgui.ImBool(false);

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end;
    while not isSampAvailable() do wait(100) end;
    while true do
        wait(0)
        imgui.Process = piemenu.v
        if wasKeyPressed(key.VK_K) then
            piemenu.v = not piemenu.v
        end
    end
end

function imgui.OnDrawFrame()
    if piemenu.v then
        imgui.OpenPopup('PieMenu')
        if pie.BeginPiePopup('PieMenu', 1) then
        if pie.PieMenuItem('Test1') then end
        if pie.PieMenuItem('Test2') then end
        --if pie.PieMenuItem('Test5') then end
        if pie.PieMenuItem('Test3', false) then end
        if pie.BeginPieMenu('Sub') then
            if pie.BeginPieMenu('Sub sub\nmenu') then
            if pie.PieMenuItem('SubSub') then end
            if pie.PieMenuItem('SubSub2') then end
            pie.EndPieMenu()
            end
            if pie.PieMenuItem('TestSub') then end
            if pie.PieMenuItem('TestSub2') then end
        pie.EndPieMenu()
        end
        pie.EndPiePopup()
        end
    end
end
 

Smeruxa

Известный
1,372
726
Как изменить положение piemenu? Поиск по форуму не дал внятного ответа
Lua:
local imgui = require 'imgui';
local pie = require 'imgui_piemenu';
local key = require 'vkeys';
local x, y = getScreenResolution()

local piemenu  = imgui.ImBool(false);

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end;
    while not isSampAvailable() do wait(100) end;
    while true do
        wait(0)
        imgui.Process = piemenu.v
        if wasKeyPressed(key.VK_K) then
            piemenu.v = not piemenu.v
        end
    end
end

function imgui.OnDrawFrame()
    if piemenu.v then
        imgui.OpenPopup('PieMenu')
        if pie.BeginPiePopup('PieMenu', 1) then
        if pie.PieMenuItem('Test1') then end
        if pie.PieMenuItem('Test2') then end
        --if pie.PieMenuItem('Test5') then end
        if pie.PieMenuItem('Test3', false) then end
        if pie.BeginPieMenu('Sub') then
            if pie.BeginPieMenu('Sub sub\nmenu') then
            if pie.PieMenuItem('SubSub') then end
            if pie.PieMenuItem('SubSub2') then end
            pie.EndPieMenu()
            end
            if pie.PieMenuItem('TestSub') then end
            if pie.PieMenuItem('TestSub2') then end
        pie.EndPieMenu()
        end
        pie.EndPiePopup()
        end
    end
end
пробовал imgui.SetCursorPosX(),imgui.SetCursorPosY()?
 

chapo

чопа сребдс // @moujeek
Модератор
8,935
11,704
пробовал imgui.SetCursorPosX(),imgui.SetCursorPosY()?
Lua:
function imgui.OnDrawFrame()
    if piemenu.v then
        imgui.SetCursorPosX(500)
        imgui.SetCursorPosY(500)
        imgui.OpenPopup('PieMenu')
        if pie.BeginPiePopup('PieMenu', 1) then
        if pie.PieMenuItem('Test1') then end
        if pie.PieMenuItem('Test2') then end
        --if pie.PieMenuItem('Test5') then end
        if pie.PieMenuItem('Test3', false) then end
        if pie.BeginPieMenu('Sub') then
            if pie.BeginPieMenu('Sub sub\nmenu') then
            if pie.PieMenuItem('SubSub') then end
            if pie.PieMenuItem('SubSub2') then end
            pie.EndPieMenu()
            end
            if pie.PieMenuItem('TestSub') then end
            if pie.PieMenuItem('TestSub2') then end
        pie.EndPieMenu()
        end
        pie.EndPiePopup()
        end
    end
end
1611170533799.png
 
  • Грустно
Реакции: Smeruxa

Smeruxa

Известный
1,372
726
Lua:
function imgui.OnDrawFrame()
    if piemenu.v then
        imgui.SetCursorPosX(500)
        imgui.SetCursorPosY(500)
        imgui.OpenPopup('PieMenu')
        if pie.BeginPiePopup('PieMenu', 1) then
        if pie.PieMenuItem('Test1') then end
        if pie.PieMenuItem('Test2') then end
        --if pie.PieMenuItem('Test5') then end
        if pie.PieMenuItem('Test3', false) then end
        if pie.BeginPieMenu('Sub') then
            if pie.BeginPieMenu('Sub sub\nmenu') then
            if pie.PieMenuItem('SubSub') then end
            if pie.PieMenuItem('SubSub2') then end
            pie.EndPieMenu()
            end
            if pie.PieMenuItem('TestSub') then end
            if pie.PieMenuItem('TestSub2') then end
        pie.EndPieMenu()
        end
        pie.EndPiePopup()
        end
    end
end
Посмотреть вложение 83560
перемести с верхних строк, к строке, что после BeginPiePopup
 

monolith04

Известный
71
6
В общем, сделал вот окно (см. скрин в спойлере), при нажатии на эти строчки слева, справа должен появляться другой текст/кнопка, НО, нажав на первую строчку (текст появился) перестают работать все следующие. Если с конца по порядку нажимать то работает, но в обратном порядке уже не будет работать. Почему так? Как это исправить?
Lua:
if organisations.v then
    imgui.SetNextWindowSize(imgui.ImVec2(630,500), imgui.Cond.FirstUseEver)
    imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.Begin(fa.ICON_COG..u8' Настройки организаций', organisations, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoCollapse)
    imgui.BeginChild("OrgSetList", imgui.ImVec2(210, 155), true)
      imgui.Columns(1, 'OrgSetList')
      if imgui.Selectable(u8'Общие', false) then common = true end
      if imgui.Selectable(u8'Министерство обороны', false) then orgmo = true end
      if imgui.Selectable(u8'Министерство здравоохранения', false) then health = true end
      if imgui.Selectable(u8'Министерство внутренних дел', false) then pd = true end
      if imgui.Selectable(u8'Средства массовой информации', false) then tv = true end
      if imgui.Selectable(u8'Правительство', false) then gov = true end
    imgui.EndChild()
    imgui.SameLine()
    imgui.BeginChild('OrgSet', imgui.ImVec2(0, 0), false)
    if common then
      imgui.Text('text1')
    elseif orgmo then
      imgui.Text('text2')
    elseif health then
      imgui.Button('button1')
    end
    imgui.EndChild()
    imgui.End()
  end
Проблема все еще актуальна.
 

chapo

чопа сребдс // @moujeek
Модератор
8,935
11,704
перемести с верхних строк, к строке, что после BeginPiePopup
Lua:
[ML] (error) govnishe.lua: cannot resume non-suspended coroutine
stack traceback:
    [C]: in function 'SetCursorPosX'
    ...asi loader\GTA San Andreas\moonloader\govnishe.lua:16: in function <...asi loader\GTA San Andreas\moonloader\govnishe.lua:8>
[ML] (error) govnishe.lua: Script died due to an error. (01B67E2C)
 

Smeruxa

Известный
1,372
726
Проблема все еще актуальна.
ты каждой переменной задаешь true, когда активировано одно, другое на поверх другого накладывается, просто создай одну переменную, типа int, и задавай, например test = 1, test = 2, а дальше проверку if test == 1 then
 
  • Нравится
Реакции: monolith04