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

The Spark

frontend
Проверенный
704
726
шо за 1 и 2 хаха. Смотри!

Lua:
-- В НАЧАЛО КОДА СУЕШЬ
local ymniy = imgui.ImBool(false)   -- false - По дефолту галочка не стоит, если true то стоит
local bidlo =  imgui.ImBool(false)  -- false - По дефолту галочка не стоит, если true то стоит

if window.v then
imgui.SetNextWindowPos(imgui.ImVec2(settings.cord.reconnakx, settings.cord.reconnaky), imgui.ImVec2(0.5, 0.0))
  imgui.SetNextWindowSize(imgui.ImVec2(153, 143), imgui.Cond.FirstUseEver)
  imgui.Begin(u8"Быстрые наказания##reconPl2", _, imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoResize + imgui.WindowFlags.NoMove + imgui.WindowFlags.NoBringToFrontOnFocus + imgui.WindowFlags.NoSavedSettings)
 
imgui.Checkbox(u8'C ноги в лицо?',ymniy)
 imgui.SameLine() -- Сразу после первого чекбокса чтобы шел на этой же линии второй чекбокс
 imgui.Checkbox(u8'С кошачей ляшки по лицу?',bidlo)

imgui.End()
end
Вот и готово,а ты боялся. Если тебе надо чтобы выполнялось какое либо условие в зависимости от чекбоксов то пишешь где-то в коде или цикле

if ymniy.v then
sampAddChatMessage("Я УМНЫЙ",-1)
elseif bidlo.v then
sampAddChatMessage("Я БЫЛОКОДЕР",-1)
end
upload_2019-5-5_23-1-48.png

Нужно мне Что-бы чексБокс был прямо под текстом "Отображение", всё делаю правильно, но мешает толстая кнопка "Отображение". Как мне сделать как тут
upload_2019-5-5_23-3-26.png
 

DeMoN3D

Известный
368
77
Помогите ребят с биндером
Нужно крч чтоб когда ты наводился через ПКМ и нажимал какую-то клавишу которую забиндил (например ПКМ+Р) то пошла такая отыгровка:
/me заломал руку {его nickname} и повел его за собой
---
Еще так же нужно и с ID, т.е
/связать 85 (Где 85 - ид его)
пойдет отыгровка:
/me взял веревки и связал {nickname игрока с таким id} руки


Это на Луа все должно быть
тебе в заказы, здесь лишь помогают с ошибками и наработками
 

~Justie~

Участник
133
26
Lua:
if text:find('IP:') then
         sampAddChatMessage(tag .. c_white .. "Строка была удалена.", 0xFFFFFF)
         return false    
end
Как бы странно это не звучало, но оно все равно отказывается работать. Вчера это работало, видимо, проблема в целом коде. Сможешь пойти в вк? Я тебе кину весь код
 

Leatington

Фанат Рейзора
264
75
Нужно мне Что-бы чексБокс был прямо под текстом "Отображение", всё делаю правильно, но мешает толстая кнопка "Отображение". Как мне сделать как тут
29489
Сделать BeginChild

Как бы странно это не звучало, но оно все равно отказывается работать. Вчера это работало, видимо, проблема в целом коде. Сможешь пойти в вк? Я тебе кину весь код
Ты его в какой хук засовываешь то?
 
  • Нравится
Реакции: atizoff

The Spark

frontend
Проверенный
704
726
Перед чекбоксом ставь.
Lua:
imgui.SetCursorPos(imgui.ImVec2(x, y))
Спасибо папаша что сказал мне как юзать нормальные координаты, а не ебаться с imgui.SameLine(). Спасибо

BeginChild? С этого момента поподробнее, а вообще можно мне темку где показаны все возможности imgui и пример как это юзать
 
  • Нравится
Реакции: atizoff

trefa

3d print
Всефорумный модератор
2,123
1,288
Спасибо папаша что сказал мне как юзать нормальные координаты, а не ебаться с imgui.SameLine(). Спасибо


BeginChild? С этого момента поподробнее, а вообще можно мне темку где показаны все возможности imgui и пример как это юзать
https://github.com/ocornut/imgui/blob/v1.52/imgui.h
 

EvilCoder

Участник
147
1
Мужики. Короче, помогите. Идет действие, после чего должно оно остановиться и продолжиться после нажатия клавиши.
Lua:
if imgui.Button(u8"-Собеска.") then
lua_thread.create(function()
sampSendChat('/me достал форму')
-- Тут должна быть пауза
sampSendChat('Действие после паузы')
end)
end
 

tlwsn

Известный
537
85
Мужики. Короче, помогите. Идет действие, после чего должно оно остановиться и продолжиться после нажатия клавиши.
Lua:
if imgui.Button(u8"-Собеска.") then
lua_thread.create(function()
sampSendChat('/me достал форму')
-- Тут должна быть пауза
sampSendChat('Действие после паузы')
end)
end
while not wasKeyPressed(int key) do wait(0) end
 

~Justie~

Участник
133
26
Ты его в какой хук засовываешь то?
аоаоао, что за хук? Не шарю

У тебя точно переменные tag и c_white есть?
Да
Вот фулл код:
Lua:
require "lib.moonloader" -- подключаем мунлоалер
local imgui = require 'imgui' -- подключаем имгуи
local sampev = require 'lib.samp.events'
local encoding = require 'encoding' -- подключаем кодировки
local keys = require 'vkeys' -- подключаем кнопки
local iScreenWidth, iScreenHeight = getScreenResolution() -- указываем, что такое iScreenHeight и iScreenWidth
local tag = '{00cd66}[MDM.dev]: ' -- переменная
local m_color = 0x00cd66 -- переменная
local tm_color = "{00cd66}" -- переменная
local c_white = "{ffffff}" -- переменная
local main_window_state = imgui.ImBool(false) -- статус имгуи
local report_window_state = imgui.ImBool(false)
local gomp_window_state = imgui.ImBool(false)
local mhelp_window_state = imgui.ImBool(false)
local gun_window_state = imgui.ImBool(false)
local getban_window_state = imgui.ImBool(false)
local jail_window_state = imgui.ImBool(false)
local mute_window_state = imgui.ImBool(false)
local kick_window_state = imgui.ImBool(false)
local skick_window_state = imgui.ImBool(false)
local fastnak_window_state = imgui.ImBool(false)
local auto_tp_status = imgui.ImBool(false)
local offip_status = false

--local recon_window_state = imgui.ImBool(false)

local version = "1.5.3"

local text_buffer= imgui.ImBuffer(256) -- буфер текста
local mp_name= imgui.ImBuffer(256) -- буфер текста
local mp_priz= imgui.ImBuffer(256) -- буфер текста

--local result, playerId = sampGetPlayerIdByCharHandle(playerPed) -- id
--        if result then
--            playerNick = sampGetPlayerNickname(id) -- nick
--        end

encoding.default = 'CP1251' -- кодировка по дефолту
u8 = encoding.UTF8 -- кодировка u8
playerId = -1

function apply_custom_style()
    local style = imgui.GetStyle()
    local colors = style.Colors
    local clr = imgui.Col
    local ImVec4 = imgui.ImVec4
 
    style.WindowRounding = 2.0
    style.WindowTitleAlign = imgui.ImVec2(0.5, 0.84)
    style.ChildWindowRounding = 2.0
    style.FrameRounding = 2.0
    style.ItemSpacing = imgui.ImVec2(5.0, 4.0)
    style.ScrollbarSize = 13.0
    style.ScrollbarRounding = 0
    style.GrabMinSize = 8.0
    style.GrabRounding = 1.0
    -- style.Alpha =
    -- style.WindowPadding =
    -- style.WindowMinSize =
    -- style.FramePadding =
    -- style.ItemInnerSpacing =
    -- style.TouchExtraPadding =
    -- style.IndentSpacing =
    -- style.ColumnsMinSpacing = ?
    -- style.ButtonTextAlign =
    -- style.DisplayWindowPadding =
    -- style.DisplaySafeAreaPadding =
    -- style.AntiAliasedLines =
    -- style.AntiAliasedShapes =
    -- style.CurveTessellationTol =

    colors[clr.Text]                   = ImVec4(1.00, 1.00, 1.00, 1.00)
    colors[clr.TextDisabled]           = ImVec4(0.50, 0.50, 0.50, 1.00)
    colors[clr.WindowBg]               = ImVec4(0.06, 0.06, 0.06, 0.94)
    colors[clr.ChildWindowBg]          = ImVec4(1.00, 1.00, 1.00, 0.00)
    colors[clr.PopupBg]                = ImVec4(0.08, 0.08, 0.08, 0.94)
    colors[clr.ComboBg]                = colors[clr.PopupBg]
    colors[clr.Border]                 = ImVec4(0.43, 0.43, 0.50, 0.50)
    colors[clr.BorderShadow]           = ImVec4(0.00, 0.00, 0.00, 0.00)
    colors[clr.FrameBg]                = ImVec4(0.16, 0.29, 0.48, 0.54)
    colors[clr.FrameBgHovered]         = ImVec4(0.26, 0.59, 0.98, 0.40)
    colors[clr.FrameBgActive]          = ImVec4(0.26, 0.59, 0.98, 0.67)
    colors[clr.TitleBg]                = ImVec4(0.04, 0.04, 0.04, 1.00)
    colors[clr.TitleBgActive]          = ImVec4(0.16, 0.29, 0.48, 1.00)
    colors[clr.TitleBgCollapsed]       = ImVec4(0.00, 0.00, 0.00, 0.51)
    colors[clr.MenuBarBg]              = ImVec4(0.14, 0.14, 0.14, 1.00)
    colors[clr.ScrollbarBg]            = ImVec4(0.02, 0.02, 0.02, 0.53)
    colors[clr.ScrollbarGrab]          = ImVec4(0.31, 0.31, 0.31, 1.00)
    colors[clr.ScrollbarGrabHovered]   = ImVec4(0.41, 0.41, 0.41, 1.00)
    colors[clr.ScrollbarGrabActive]    = ImVec4(0.51, 0.51, 0.51, 1.00)
    colors[clr.CheckMark]              = ImVec4(0.26, 0.59, 0.98, 1.00)
    colors[clr.SliderGrab]             = ImVec4(0.24, 0.52, 0.88, 1.00)
    colors[clr.SliderGrabActive]       = ImVec4(0.26, 0.59, 0.98, 1.00)
    colors[clr.Button]                 = ImVec4(0.26, 0.59, 0.98, 0.40)
    colors[clr.ButtonHovered]          = ImVec4(0.26, 0.59, 0.98, 1.00)
    colors[clr.ButtonActive]           = ImVec4(0.06, 0.53, 0.98, 1.00)
    colors[clr.Header]                 = ImVec4(0.26, 0.59, 0.98, 0.31)
    colors[clr.HeaderHovered]          = ImVec4(0.26, 0.59, 0.98, 0.80)
    colors[clr.HeaderActive]           = ImVec4(0.26, 0.59, 0.98, 1.00)
    colors[clr.Separator]              = colors[clr.Border]
    colors[clr.SeparatorHovered]       = ImVec4(0.26, 0.59, 0.98, 0.78)
    colors[clr.SeparatorActive]        = ImVec4(0.26, 0.59, 0.98, 1.00)
    colors[clr.ResizeGrip]             = ImVec4(0.26, 0.59, 0.98, 0.25)
    colors[clr.ResizeGripHovered]      = ImVec4(0.26, 0.59, 0.98, 0.67)
    colors[clr.ResizeGripActive]       = ImVec4(0.26, 0.59, 0.98, 0.95)
    colors[clr.CloseButton]            = ImVec4(0.41, 0.41, 0.41, 0.50)
    colors[clr.CloseButtonHovered]     = ImVec4(0.98, 0.39, 0.36, 1.00)
    colors[clr.CloseButtonActive]      = ImVec4(0.98, 0.39, 0.36, 1.00)
    colors[clr.PlotLines]              = ImVec4(0.61, 0.61, 0.61, 1.00)
    colors[clr.PlotLinesHovered]       = ImVec4(1.00, 0.43, 0.35, 1.00)
    colors[clr.PlotHistogram]          = ImVec4(0.90, 0.70, 0.00, 1.00)
    colors[clr.PlotHistogramHovered]   = ImVec4(1.00, 0.60, 0.00, 1.00)
    colors[clr.TextSelectedBg]         = ImVec4(0.26, 0.59, 0.98, 0.35)
    colors[clr.ModalWindowDarkening]   = ImVec4(0.80, 0.80, 0.80, 0.35)
end
apply_custom_style()

function cmd_request()
    sampShowDialog(1, c_white .. "Команды для быстрых просьб для {00cd66}Мл.Администрации", "{00cd66}/fcheat {00cd66}[id] {ffffff}- Просьба забанить за читы \n{00cd66}/fmama {00cd66}[id] {ffffff}- Просьба забанить за оскорбление родных \n{00cd66}/fsp {00cd66}[id] {ffffff}- Просьба выдать 0 хп игроку \n{00cd66}/fjail [id] {ffffff}- Просьба посадить игрока за читы{00cd66}(когда нет 3+)\n{00cd66}/fcapt{ffffff} - Просьба остановить капт", "OK")
end

function cmd_fastnak()
    sampShowDialog(1, c_white .. "Меню быстрой выдачи наказаний", "{00cd66}/osk - {ffffff}Выдать мут за Оскорбление игроков \n{00cd66}/up - {ffffff}Выдать мут за Упоминание родных \n{00cd66}/troll - {ffffff}Выдать мут за Троллинг администрации \n{00cd66}/offtop - {ffffff}Выдать мут за Оффтоп в репорт \n{00cd66}/flood - {ffffff}Выдать мут за Флуд \n{00cd66}/caps - {ffffff}Выдать мут за Капс \n{00cd66}/noise - {ffffff}Кикнуть за помеху \n{00cd66}/tk - {ffffff}Кикнуть за ТК", "OK")
end

function cmd_fcheat(arg)
    if #arg == 0 then
        sampAddChatMessage(tag .. c_white .. "Используйте " .. tm_color .. "/fcheat [id]", 0xFFFFFF)
    else
        sampSendChat("/a /ban " .. arg .. " 30 Cheat")
        arg = 0
    end
end

function cmd_fmama(arg)
    if #arg == 0 then
        sampAddChatMessage(tag .. c_white .. "Используйте " .. tm_color .. "/fmama [id]", 0xFFFFFF)
    else
        sampSendChat("/a /ban " .. arg .. " 30 Оскорбление родных")
        arg = 0
    end
end

function cmd_fsp(arg)
    if #arg == 0 then
        sampAddChatMessage(tag .. c_white .. "Используйте " .. tm_color .. "/fsp [id]", 0xFFFFFF)
    else
        sampSendChat("/a /sethp " .. arg .. " 0")
        arg = 0
    end
end

function cmd_fjail(arg)
    if #arg == 0 then
        sampAddChatMessage(tag .. c_white .. "Используйте " .. tm_color .. "/fjail [id]", 0xFFFFFF)
    else
        sampSendChat("/a /jail " .. arg .. " 60 Cheat")
        arg = 0
    end
end

function cmd_fcapt(arg)
    sampSendChat("/a /scapt Кусок/Обрез")
    arg = 0
end

function cmd_osk(arg)
    if #arg == 0 then
        sampAddChatMessage(tag .. c_white .. "Используйте " .. tm_color .. "/osk [id]", 0xFFFFFF)
    else
        sampSendChat("/mute " .. arg .. " 30 Оскорбление игроков")
        arg = 0
    end
end

function cmd_up(arg)
    if #arg == 0 then
        sampAddChatMessage(tag .. c_white .. "Используйте " .. tm_color .. "/up [id]", 0xFFFFFF)
    else
        sampSendChat("/mute " .. arg .. " 180 Упоминание родных")
        arg = 0
    end
end

function cmd_troll(arg)
    if #arg == 0 then
        sampAddChatMessage(tag .. c_white .. "Используйте " .. tm_color .. "/troll [id]", 0xFFFFFF)
    else
        sampSendChat("/mute " .. arg .. " 120 Троллинг администрации")
        arg = 0
    end
end

function cmd_offtop(arg)
    if #arg == 0 then
        sampAddChatMessage(tag .. c_white .. "Используйте " .. tm_color .. "/offtop [id]", 0xFFFFFF)
    else
        sampSendChat("/mute " .. arg .. " 15 Оффтоп в репорт")
        arg = 0
    end
end

function cmd_flood(arg)
    if #arg == 0 then
        sampAddChatMessage(tag .. c_white .. "Используйте " .. tm_color .. "/flood [id]", 0xFFFFFF)
    else
        sampSendChat("/mute " .. arg .. " 15 Flood")
        arg = 0
    end
end

function cmd_caps(arg)
    if #arg == 0 then
        sampAddChatMessage(tag .. c_white .. "Используйте " .. tm_color .. "/caps [id]", 0xFFFFFF)
    else
        sampSendChat("/mute " .. arg .. " 15 Caps")
        arg = 0
    end
end

function cmd_noise(arg)
    if #arg == 0 then
        sampAddChatMessage(tag .. c_white .. "Используйте " .. tm_color .. "/noise [id]", 0xFFFFFF)
    else
        sampSendChat("/kick " .. arg .. " Помеха")
        arg = 0
    end
end

function cmd_tk(arg)
    if #arg == 0 then
        sampAddChatMessage(tag .. c_white .. "Используйте " .. tm_color .. "/tk [id]", 0xFFFFFF)
    else
        sampSendChat("/kick " .. arg .. " TeamKill")
        arg = 0
    end
end

function cmd_menu(arg)
    if #arg == 0 then
        sampAddChatMessage(tag .. c_white .. "Используйте " .. tm_color .. "/m [id]", 0xFFFFFF)
    else
    playerId = arg
    main_window_state.v = not main_window_state.v
    imgui.Process = main_window_state.v
    end
end

function cmd_report(arg)
    if #arg == 0 then
        sampAddChatMessage(tag .. c_white .. "Используйте " .. tm_color .. "/p [id]", 0xFFFFFF)
    else
    playerId = arg
    report_window_state.v = not report_window_state.v
    imgui.Process = report_window_state.v
    end
end

function cmd_mhelp(arg)
    mhelp_window_state.v = not mhelp_window_state.v
    imgui.Process = mhelp_window_state.v
end

function cmd_gomp(arg)
    gomp_window_state.v = not gomp_window_state.v
    imgui.Process = gomp_window_state.v
end

function sampev.onServerMessage(color, text)
    if string.find(text, "отвечает", 1, true) then
        return false
    end
end

function mp_thr_func()
    result, playerId = sampGetPlayerIdByCharHandle(playerPed) -- id
        if result then
            playerNick = sampGetPlayerNickname(id) -- nick
        end
    sampSendChat("/msg Уважаемые игроки, сейчас пройдет мероприятие '" .. u8:decode(mp_name.v) .. "'")    ----------------------------- ЭТО ПОТОК ДЛЯ ОБЪЯВЛЕНИЯ МП
    wait(3500)
    sampSendChat("/msg Для принятия участия нужно всего лишь написать /sms " .. playerId .. " +")
    wait(3500)
    sampSendChat("/msg Приз мероприятия: " .. u8:decode(mp_priz.v) .. "")
end

function sampev.onServerMessage(color, text)
    if auto_tp_status.v and string.find(text, "+", 1, true) then
        lolNick, lolId = string.match(text, "%{FFD700%}SMS от (.*) %[ID%:(%d+)%]")                         --------------        ЭТО НАХОДИТ СТРОКУ С ПЛЮСИКОМ В СМС
        --ssampAddChatMessage("Твой ид: " .. lolId .. ", а ник " .. lolNick .. ", вот я маг, да", 0xFFFFFF)
        wait_for_tpks:run()
    end
    llolId = lolId
end

function wait_for_tpks_mp()
    wait(10)                                                      ----------------------------                 ЭТО ТЕЛЕПОРТИРУЕТ ЧЕЛИКА КОТОРЫЙ ПЛЮСИК НАПИСАЛ
    sampSendChat("/tpks " .. llolId)
    sampSendChat("/resgun " .. llolId)
end

function imgui.OnDrawFrame() -- функция, где рисуется имгуи

    if gomp_window_state.v then
        local btn_size = imgui.ImVec2(-0.1, 0)    
        imgui.SetNextWindowSize(imgui.ImVec2(400, 295), imgui.Cond.FirstUseEver)
        imgui.SetNextWindowPos(imgui.ImVec2(iScreenWidth / 2, iScreenHeight / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.Begin(u8"Меню мероприятий", gomp_window_state) -- открывает меню
        imgui.InputText(u8"Название МП", mp_name)
        imgui.InputText(u8"Приз", mp_priz)
        if imgui.Button(u8"Объявить") then
            mp_thr:run()
        end
        imgui.Checkbox(u8"Авто телепорт", auto_tp_status)
        imgui.End()
    end

    if main_window_state.v then
        local btn_size = imgui.ImVec2(-0.1, 0)    
        imgui.SetNextWindowSize(imgui.ImVec2(400, 295), imgui.Cond.FirstUseEver)
        imgui.SetNextWindowPos(imgui.ImVec2(iScreenWidth / 2, iScreenHeight / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.Begin(u8"Взаимодействие", main_window_state) -- открывает меню
        if imgui.Button(u8"Забанить", btn_size) then -- кнопка
            getban_window_state.v = not getban_window_state.v
        end
        if imgui.Button(u8"Посадить в тюрьму", btn_size) then -- кнопка
            jail_window_state.v = not jail_window_state.v
        end
        if imgui.Button(u8"Выдать мут", btn_size) then -- кнопка
            mute_window_state.v = not mute_window_state.v
        end
        if imgui.Button(u8"Кикнуть", btn_size) then -- кнопка
            kick_window_state.v = not kick_window_state.v
        end
        if imgui.Button(u8"Тихо кикнуть", btn_size) then -- кнопка
            skick_window_state.v = not skick_window_state.v
        end
        if imgui.Button(u8"Слапнуть", btn_size) then -- кнопка
            sampSendChat("/slap " .. playerId)
        end
        if imgui.Button(u8"Заспавнить", btn_size) then -- кнопка
            sampSendChat("/sethp " .. playerId .. " 0")
        end
        if imgui.Button(u8"Выдать оружие", btn_size) then -- кнопка
            gun_window_state.v = not gun_window_state.v
        end
        if imgui.Button(u8"Забрать оружие", btn_size) then -- кнопка
            sampSendChat("/resgun " .. playerId)
        end
        if imgui.Button(u8"Телепортироваться", btn_size) then -- кнопка
            sampSendChat("/tpkn " .. playerId)
        end
        if imgui.Button(u8"Телепортировать к себе", btn_size) then -- кнопка
            sampSendChat("/tpks " .. playerId)
        end
        imgui.End() -- завершает работу
    end
 
    if report_window_state.v then
        local btn_size = imgui.ImVec2(-0.1, 0)    
        imgui.SetNextWindowSize(imgui.ImVec2(400, 295), imgui.Cond.FirstUseEver)
        imgui.SetNextWindowPos(imgui.ImVec2(iScreenWidth / 2, iScreenHeight / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.Begin(u8"Меню быстрых ответов на репорт", report_window_state) -- открывает меню
        imgui.Text(u8"     [!] Если флудить ответами, Вас может забанить система [!]")
        if imgui.Button(u8"Наблюдаю за данным игроком", btn_size) then -- кнопка
            sampSendChat("/pm " .. playerId .. " Наблюдаю за данным игроком, ожидайте.")
            report_window_state.v = not report_window_state.v
            --sampAddChatMessage(tm_color .. "[MDM:Отладка] - " .. c_white .. "/pm " .. playerId .. " Наблюдаю за данным игроком, ожидайте.", 0xFFFFFF)
        end
        if imgui.Button(u8"Нарушений не обнаружено", btn_size) then -- кнопка
            sampSendChat("/pm " .. playerId .. " Нарушений не обнаружено.")
            report_window_state.v = not report_window_state.v
            --sampAddChatMessage(tm_color .. "[MDM:Отладка] - " .. c_white .. "/pm " .. playerId .. " Нарушений не обнаружено.", 0xFFFFFF)
        end
        if imgui.Button(u8"Игрок, указанный в Вашей жалобе был наказан", btn_size) then -- кнопка
            sampSendChat("/pm " .. playerId .. " Игрок, указанный в Вашей жалобе был наказан.")
            report_window_state.v = not report_window_state.v
            --sampAddChatMessage(tm_color .. "[MDM:Отладка] - " .. c_white .. "/pm " .. playerId .. " Игрок, указанный в Вашей жалобе был наказан.", 0xFFFFFF)
        end
        if imgui.Button(u8"Игрок, указанный в Вашей жалобе вышел из игры", btn_size) then -- кнопка
            sampSendChat("/pm " .. playerId .. " Игрок, указанный в Вашей жалобе вышел из игры.")
            report_window_state.v = not report_window_state.v
            --sampAddChatMessage(tm_color .. "[MDM:Отладка] - " .. c_white .. "/pm " .. playerId .. " Игрок, указанный в Вашей жалобе вышел из игры.", 0xFFFFFF)
        end
        if imgui.Button(u8"Игрок, указанный в Вашей жалобе стоит в AFK", btn_size) then -- кнопка
            sampSendChat("/pm " .. playerId .. " Игрок, указанный в Вашей жалобе стоит в AFK.")
            report_window_state.v = not report_window_state.v
            --sampAddChatMessage(tm_color .. "[MDM:Отладка] - " .. c_white .. "/pm " .. playerId .. " Игрок, указанный в Вашей жалобе стоит в AFK.", 0xFFFFFF)
        end
        if imgui.Button(u8"Пишите жалобу на администратора на форум", btn_size) then -- кнопка
            sampSendChat("/pm " .. playerId .. " Пишите жалобу на администратора на форум.")
            report_window_state.v = not report_window_state.v
            --sampAddChatMessage(tm_color .. "[MDM:Отладка] - " .. c_white .. "/pm " .. playerId .. " Пишите жалобу на администратора на форум.", 0xFFFFFF)
        end
        if imgui.Button(u8"Ответ на: 'Как получить админку?'", btn_size) then -- кнопка
            sampSendChat("/pm " .. playerId .. " Админку можно купить на сайте, а так же захватить все территории гетто под лидерством.")
            report_window_state.v = not report_window_state.v
            --sampAddChatMessage(tm_color .. "[MDM:Отладка] - " .. c_white .. "/pm " .. playerId .. " Админку можно купить на сайте, а так же захватить все территории гетто под лидерством.", 0xFFFFFF)
        end
        if imgui.Button(u8"Ответ на: 'Как получить лидерку?'", btn_size) then -- кнопка
            sampSendChat("/pm " .. playerId .. " Нужно сделать больше всех убийств на капте.")
            report_window_state.v = not report_window_state.v
            --sampAddChatMessage(tm_color .. "[MDM:Отладка] - " .. c_white .. "/pm " .. playerId .. " Нужно сделать больше всех убийств на капте.", 0xFFFFFF)
        end
        if imgui.Button(u8"Ответ на: 'Какие возможности у VIP?'", btn_size) then -- кнопка
            sampSendChat("/pm " .. playerId .. " Смотрите /mn -> 9 -> 1 -> 1")
            report_window_state.v = not report_window_state.v
            --sampAddChatMessage(tm_color .. "[MDM:Отладка] - " .. c_white .. "/pm " .. playerId .. " Смотрите /mn -> 9 -> 1 -> 1", 0xFFFFFF)
        end
        if imgui.Button(u8"Ответ на: 'Как писать в общий чат?'", btn_size) then -- кнопка
            sampSendChat("/pm " .. playerId .. " /o [Текст] | Работает, только если у Вас больше 200 убийств.")
            report_window_state.v = not report_window_state.v
            --sampAddChatMessage(tm_color .. "[MDM:Отладка] - " .. c_white .. "/pm " .. playerId .. " /o [Текст] | Работает, только если у Вас больше 200 убийств.", 0xFFFFFF)
        end
        imgui.End() -- завершает работу
    end

    if mhelp_window_state.v then
        local btn_size = imgui.ImVec2(-0.1, 0)    
        imgui.SetNextWindowSize(imgui.ImVec2(490, 120), imgui.Cond.FirstUseEver)
        imgui.SetNextWindowPos(imgui.ImVec2(iScreenWidth / 2, iScreenHeight / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.Begin(u8"Помощь по командам скрипта", mhelp_window_state) -- открывает меню
        imgui.Text(u8"/m [id] - Открыть меню взаимодействия с игроком\n/p [id] - Открыть меню быстрых ответов на репорт\n/fastnak - Открыть список команд для быстрой выдачи наказаний\n/request - Отурыть список команд для бстрых просьб для Мл.Администрации\n/offip - Отключить появление в чате IP-адресов\n/gomp - Открыть меню мероприятий")
        imgui.End() -- завершает работу
    end
 
    --if recon_window_state.v then
    --    playerName = sampGetPlayerNickname(playerId)
    --    playerKills = sampGetPlayerScore(playerId)
    --    playerHealth = sampGetPlayerHealth(playerId)
    --
    --
    --    imgui.SetNextWindowSize(imgui.ImVec2(200, 100), imgui.Cond.FirstUseEver)
    --    imgui.SetNextWindowPos(imgui.ImVec2(iScreenWidth / 2, iScreenHeight / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    --    local btn_size = imgui.ImVec2(-0.1, 0)
    --
    --    imgui.Begin(u8"Recon Info", recon_window_state) -- открывает меню
    --    imgui.Text(u8"Ник: " .. playerName)
    --    imgui.Text(u8"Киллы: " .. playerKills)
    --    imgui.Text(u8"ХП: " .. playerHealth)
    --    imgui.End() -- завершает работу
    --end
 
    if skick_window_state.v then
        imgui.SetNextWindowSize(imgui.ImVec2(300, 80), imgui.Cond.FirstUseEver)
        imgui.SetNextWindowPos(imgui.ImVec2(iScreenWidth / 2, iScreenHeight / 1.47), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        local btn_size = imgui.ImVec2(-0.1, 0)
    
        imgui.Begin(u8"Тихо кикнуть", skick_window_state)
        imgui.InputText(u8" - Прична", text_buffer)
        if imgui.Button(u8"Выполнить") then -- кнопка
            sampSendChat("/skick " ..  playerId .. " " .. u8:decode(text_buffer.v))
            skick_window_state.v = not skick_window_state.v
        end
        imgui.End()
    end
 
    if getban_window_state.v then
        imgui.SetNextWindowSize(imgui.ImVec2(300, 297), imgui.Cond.FirstUseEver)
        imgui.SetNextWindowPos(imgui.ImVec2(iScreenWidth / 2, iScreenHeight / 1.28), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        local btn_size = imgui.ImVec2(-0.1, 0)
    
        imgui.Begin(u8"Забанить", getban_window_state)
        if imgui.Button(u8"Cheat(4+)", btn_size) then -- кнопка
            sampSendChat("/cban " .. playerId .. " 30 Cheat")
            getban_window_state.v = not getban_window_state.v
        end
        if imgui.Button(u8"Cheat(3)", btn_size) then -- кнопка
            sampSendChat("/ban " .. playerId .. " 30 Cheat")
            getban_window_state.v = not getban_window_state.v
        end
        if imgui.Button(u8"Оскорбление в нике(4+)", btn_size) then -- кнопка
            sampSendChat("/sban " .. playerId .. " 30 Nick")
            getban_window_state.v = not getban_window_state.v
        end
        if imgui.Button(u8"Оскорбление в нике(3)", btn_size) then -- кнопка
            sampSendChat("/ban " .. playerId .. " 30 Nick")
            sampSendChat("/rr")
            getban_window_state.v = not getban_window_state.v
        end
        if imgui.Button(u8"Оскорбление родных", btn_size) then -- кнопка
            sampSendChat("/ban " .. playerId .. " 30 Оскорбление родных")
            getban_window_state.v = not getban_window_state.v
        end
        if imgui.Button(u8"Реклама(4+)", btn_size) then -- кнопка
            sampSendChat("/cban " .. playerId .. " 30 Реклама")
            getban_window_state.v = not getban_window_state.v
        end
        if imgui.Button(u8"Реклама(3)", btn_size) then -- кнопка
            sampSendChat("/ban " .. playerId .. " 30 Реклама")
            getban_window_state.v = not getban_window_state.v
        end
        if imgui.Button(u8"Оскорбление администрации", btn_size) then -- кнопка
            sampSendChat("/ban " .. playerId .. " 30 Оскорбление администрации")
            getban_window_state.v = not getban_window_state.v
        end
        if imgui.Button(u8"Оскорбление проекта(4+)", btn_size) then -- кнопка
            sampSendChat("/cban " .. playerId .. " 90 Оскорбление проекта")
            getban_window_state.v = not getban_window_state.v
        end
        if imgui.Button(u8"Неадекватное поведение", btn_size) then -- кнопка
            sampSendChat("/ban " .. playerId .. " 3 Недекватное поведение")
            getban_window_state.v = not getban_window_state.v
        end
        if imgui.Button(u8"Обман администрации", btn_size) then -- кнопка
            sampSendChat("/ban " .. playerId .. " 10 Обман администрации")
            getban_window_state.v = not getban_window_state.v
        end
        imgui.End()
    end
 
    if mute_window_state.v then
        imgui.SetNextWindowSize(imgui.ImVec2(350, 297), imgui.Cond.FirstUseEver)
        imgui.SetNextWindowPos(imgui.ImVec2(iScreenWidth / 1.43, iScreenHeight / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        local btn_size = imgui.ImVec2(-0.1, 0)
    
        imgui.Begin(u8"Выдать мут", mute_window_state)
        if imgui.Button(u8"Упоминание родных", btn_size) then -- кнопка
            sampSendChat("/mute " .. playerId .. " 180 Упоминание родных")
            mute_window_state.v = not mute_window_state.v
        end
        if imgui.Button(u8"Оскорбление администрации", btn_size) then -- кнопка
            sampSendChat("/mute " .. playerId .. " 180 Оскорбление администрации")
            mute_window_state.v = not mute_window_state.v
        end
        if imgui.Button(u8"Обсуждение действий администрации", btn_size) then -- кнопка
            sampSendChat("/mute " .. playerId .. " 120 Обсуждение действий администрации")
            mute_window_state.v = not mute_window_state.v
        end
        if imgui.Button(u8"Оскорбление игроков", btn_size) then -- кнопка
            sampSendChat("/mute " .. playerId .. " 30 Оскорбление игроков")
            mute_window_state.v = not mute_window_state.v
        end
        if imgui.Button(u8"Неуважение к администрации", btn_size) then -- кнопка
            sampSendChat("/mute " .. playerId .. " 60 Неуважение к администрации")
            mute_window_state.v = not mute_window_state.v
        end
        if imgui.Button(u8"Оффтоп в репорт", btn_size) then -- кнопка
            sampSendChat("/mute " .. playerId .. " 15 Оффтоп в репорт")
            mute_window_state.v = not mute_window_state.v
        end
        if imgui.Button(u8"Мат в репорт", btn_size) then -- кнопка
            sampSendChat("/mute " .. playerId .. " 15 Мат в репорт")
            mute_window_state.v = not mute_window_state.v
        end
        if imgui.Button(u8"Флуд", btn_size) then -- кнопка
            sampSendChat("/mute " .. playerId .. " 10 Flood")
            mute_window_state.v = not mute_window_state.v
        end
        if imgui.Button(u8"Капс", btn_size) then -- кнопка
            sampSendChat("/mute " .. playerId .. " 10 Caps")
            mute_window_state.v = not mute_window_state.v
        end
        if imgui.Button(u8"Торговля", btn_size) then -- кнопка
            sampSendChat("/mute " .. playerId .. " 60 Торговля")
            mute_window_state.v = not mute_window_state.v
        end
        if imgui.Button(u8"Розжиг", btn_size) then -- кнопка
            sampSendChat("/mute " .. playerId .. " 120 Розжиг")
            mute_window_state.v = not mute_window_state.v
        end
        imgui.End()
    end
 
    if kick_window_state.v then
        imgui.SetNextWindowSize(imgui.ImVec2(350, 177), imgui.Cond.FirstUseEver)
        imgui.SetNextWindowPos(imgui.ImVec2(iScreenWidth / 2, iScreenHeight / 3.62), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        local btn_size = imgui.ImVec2(-0.1, 0)
    
        imgui.Begin(u8"Кикнуть", kick_window_state)
        if imgui.Button(u8"Чит (Когда нет старшей администрации)", btn_size) then -- кнопка
            sampSendChat("/kick " .. playerId .. " Cheat")
            kick_window_state.v = not kick_window_state.v
        end
        if imgui.Button(u8"Помеха проходу/спавну/капту", btn_size) then -- кнопка
            sampSendChat("/kick " .. playerId .. " Помеха проходу/спавну/капту")
            kick_window_state.v = not kick_window_state.v
        end
        if imgui.Button(u8"Оскорбление в нике", btn_size) then -- кнопка
            sampSendChat("/kick " .. playerId .. " Оскорбление в нике")
            kick_window_state.v = not kick_window_state.v
        end
        if imgui.Button(u8"TK", btn_size) then -- кнопка
            sampSendChat("/kick " .. playerId .. " TK")
            kick_window_state.v = not kick_window_state.v
        end
        if imgui.Button(u8"SK", btn_size) then -- кнопка
            sampSendChat("/kick " .. playerId .. " SK")
            kick_window_state.v = not kick_window_state.v
        end
        if imgui.Button(u8"DB", btn_size) then -- кнопка
            sampSendChat("/kick " .. playerId .. " DB")
            kick_window_state.v = not kick_window_state.v
        end
        imgui.End()
    end
 
    if jail_window_state.v then
        imgui.SetNextWindowSize(imgui.ImVec2(300, 130), imgui.Cond.FirstUseEver)
        imgui.SetNextWindowPos(imgui.ImVec2(iScreenWidth / 1.46, iScreenHeight / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        local btn_size = imgui.ImVec2(-0.1, 0)
 
        imgui.Begin(u8"Посадить в тюрьму", jail_window_state)
        if imgui.Button(u8"Читы(Когда нет старшей администрации)", btn_size) then -- кнопка
            sampSendChat("/jail " .. playerId .. " 60 Cheat")
            jail_window_state.v = not jail_window_state.v
        end
        if imgui.Button(u8"Багоюз", btn_size) then -- кнопка
            sampSendChat("/jail " .. playerId .. " 15 Багоюз")
            jail_window_state.v = not jail_window_state.v
        end
        if imgui.Button(u8"Капт куском / обрезом + остановить капт", btn_size) then -- кнопка
            sampSendChat("/scapt Капт куском / обрезом")
            sampSendChat("/jail " .. playerId .. " 5 Капт куском / обрезом")
            jail_window_state.v = not jail_window_state.v
        end
        if imgui.Button(u8"Многократное SK, помеха проходу", btn_size) then -- кнопка
            sampSendChat("/jail " .. playerId .. " 10 Многократное SK, помеха проходу")
            jail_window_state.v = not jail_window_state.v
        end
        imgui.End()
    end
 
    if gun_window_state.v then
        imgui.SetNextWindowSize(imgui.ImVec2(350, 417), imgui.Cond.FirstUseEver)
        imgui.SetNextWindowPos(imgui.ImVec2(iScreenWidth / 1.44, iScreenHeight / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        local btn_size = imgui.ImVec2(-0.1, 0)
    
        imgui.Begin(u8"Выдать оружие", gun_window_state)
        if imgui.Button(u8"Дигл", btn_size) then -- кнопка
            sampSendChat("/givegun " .. playerId .. " 24 999")
        end
        if imgui.Button(u8"M4", btn_size) then -- кнопка
            sampSendChat("/givegun " .. playerId .. " 31 999")
        end
        if imgui.Button(u8"Shotgun", btn_size) then -- кнопка
            sampSendChat("/givegun " .. playerId .. " 25 999")
        end
        if imgui.Button(u8"Бита", btn_size) then -- кнопка
            sampSendChat("/givegun " .. playerId .. " 5 1")
        end
        if imgui.Button(u8"Пистолет с глушителем", btn_size) then -- кнопка
            sampSendChat("/givegun " .. playerId .. " 23 999")
        end
        if imgui.Button(u8"Бензопила", btn_size) then -- кнопка
            sampSendChat("/givegun " .. playerId .. " 9 999")
        end
        if imgui.Button(u8"Цветы", btn_size) then -- кнопка
            sampSendChat("/givegun " .. playerId .. " 14 999")
        end
        if imgui.Button(u8"Скорострельный дробовик", btn_size) then -- кнопка
            sampSendChat("/givegun " .. playerId .. " 27 999")
        end
        if imgui.Button(u8"Обрез", btn_size) then -- кнопка
            sampSendChat("/givegun " .. playerId .. " 26 999")
        end
        if imgui.Button(u8"АК-47", btn_size) then -- кнопка
            sampSendChat("/givegun " .. playerId .. " 30 999")
        end
        if imgui.Button(u8"MP-5", btn_size) then -- кнопка
            sampSendChat("/givegun " .. playerId .. " 29 999")
        end
        if imgui.Button(u8"Rifle", btn_size) then -- кнопка
            sampSendChat("/givegun " .. playerId .. " 33 999")
        end
        if imgui.Button(u8"RPG", btn_size) then -- кнопка
            sampSendChat("/givegun " .. playerId .. " 35 999")
        end
        if imgui.Button(u8"Camera", btn_size) then -- кнопка
            sampSendChat("/givegun " .. playerId .. " 43 999")
        end
        if imgui.Button(u8"Minigun", btn_size) then -- кнопка
            sampSendChat("/givegun " .. playerId .. " 38 999")
        end
        if imgui.Button(u8"Dildo", btn_size) then -- кнопка
            sampSendChat("/givegun " .. playerId .. " 10 999")
        end
        imgui.End()
    end
end

function main() -- главная функция
    if not isSampLoaded() or not isSampfuncsLoaded() then return end -- проверка, если самп не загружен или не загружен сампфункс, то заверщаем работу
    while not isSampAvailable() do wait(100) end -- если самп еще не загрузился, то ждем 100 милисекунд
 
    sampAddChatMessage(tag .. c_white .. "Скрипт успешно загружен. Версия: " .. tm_color .. version .. ".", 0xFFFFFF)
    sampAddChatMessage(tag .. c_white .. "Что-бы посмотреть список доступных команд, введите " .. tm_color .. "/mhelp", 0xFFFFFF)
 
    mp_thr = lua_thread.create_suspended(mp_thr_func)
    wait_for_tpks = lua_thread.create_suspended(wait_for_tpks_mp)
 
    imgui.Process = false
 
    sampRegisterChatCommand("m", cmd_menu) -- регистрируем команду
    sampRegisterChatCommand("p", cmd_report)
    sampRegisterChatCommand("fastnak", cmd_fastnak)
    sampRegisterChatCommand("request", cmd_request)
    sampRegisterChatCommand("offip", function() offip_status = not offip_status sampAddChatMessage(offip_status and "{00cd66}[MDM]: {ffffff}Удаление IP-адресов включено" or "{00cd66}[MDM]: {ffffff}Удаление IP-адресов выключено", -1) end)
    sampRegisterChatCommand("mhelp", cmd_mhelp)
    sampRegisterChatCommand("gomp", cmd_gomp)
    sampRegisterChatCommand("osk", cmd_osk)
    sampRegisterChatCommand("up", cmd_up)
    sampRegisterChatCommand("troll", cmd_troll)
    sampRegisterChatCommand("offtop", cmd_offtop)
    sampRegisterChatCommand("flood", cmd_flood)
    sampRegisterChatCommand("caps", cmd_caps)
    sampRegisterChatCommand("noise", cmd_noise)
    sampRegisterChatCommand("tk", cmd_tk)
    sampRegisterChatCommand("fcheat", cmd_fcheat)
    sampRegisterChatCommand("fmama", cmd_fmama)
    sampRegisterChatCommand("fsp", cmd_fsp)
    sampRegisterChatCommand("fjail", cmd_fjail)
    sampRegisterChatCommand("fcapt", cmd_fcapt)
 
    while true do -- пока правда
        wait(0) -- нулевая задержка
        imgui.Process = main_window_state.v or report_window_state.v or mhelp_window_state.v    or gomp_window_state.v
    end
end

------------------------------------ СПИСОК ИЗМИНЕНИЙ ----------------------------------------------

--1. Добавлена команда /mhelp
--2. Меню /p закрывается после нажатия на одну из кнопок
--3. Добавлена команда /offip, которая позволяет отключить появление в чате различных IP-адресов, в том числе и показ IP админа при заходе в игру. Поможет тем, кто снимает видеоролики на админке.
--4. Добавлено меню /gomp
На комменты не смотрите, просто для себя писал