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

percheklii

Известный
747
280
Как проверить состояние AFK игрока?
/afk id
Lua:
function main()
    sampRegisterChatCommand("afk", function(arg)
        local id = tonumber(arg)
        local isPaused = sampIsPlayerPaused(id)
        local nickname = sampGetPlayerNickname(id)
        if isPaused then
            sampAddChatMessage("Игрок " .. nickname .. "AFK.", 0xFFFFFF)
        else
            sampAddChatMessage("Игрок " .. nickname .. " не AFK.", 0xFFFFFF)
        end
    end)
    wait(-1)
end
 

sssilvian

Активный
234
25
/afk id
Lua:
function main()
    sampRegisterChatCommand("afk", function(arg)
        local id = tonumber(arg)
        local isPaused = sampIsPlayerPaused(id)
        local nickname = sampGetPlayerNickname(id)
        if isPaused then
            sampAddChatMessage("Игрок " .. nickname .. "AFK.", 0xFFFFFF)
        else
            sampAddChatMessage("Игрок " .. nickname .. " не AFK.", 0xFFFFFF)
        end
    end)
    wait(-1)
end
Можете ли вы помочь мне интегрировать его сюда? Мне нужно, чтобы на экране отображалось, находится ли игрок в AFK или нет. Я сделал этот скрипт несколько недель назад, и я не могу понять, где сделать функцию и как.
Lua:
    sampRegisterChatCommand('track', function(arg)
        local id = tonumber(arg)
        local isPaused = sampIsPlayerPaused(id)
        if not id or not sampIsPlayerConnected(id) then
        sampTextdrawDelete(2228)
        sampTextdrawDelete(2229)
        sampAddChatMessage('{aa3333}[Hitmen Helper]{ffffff} Distance Tracker este {aa3333}dezactivat.', -1)
        sampAddChatMessage('{aa3333}[Hitmen Helper]{ffffff} Foloseste {aa3333}/track <ID>{ffffff} pentru a-l activa.', -1)
        end
        playerId = id
    end)
    while true do
        wait(0)
        if playerId then
            local result, ped, result2 = sampGetCharHandleBySampPlayerId(playerId)
            sampTextdrawCreate(2228, "Tracker:", 584.5, 397)
    sampTextdrawSetLetterSizeAndColor(2228, 0.19, 1.05, 0xFFAA3333)
    sampTextdrawSetOutlineColor(2228, 0.5, 0xFF000000)
    sampTextdrawSetStyle(2228, 1)
    sampTextdrawSetAlign(2228, 0)
            sampTextdrawCreate(2229, "ON", 609.5, 397)
    sampTextdrawSetLetterSizeAndColor(2229, 0.15, 1.1, 0xFFFFFFFF)
    sampTextdrawSetOutlineColor(2229, 0.5, 0xFF000000)
    sampTextdrawSetStyle(2229, 1)
    sampTextdrawSetAlign(2229, 0)
           
            if result then
                local x, y, z = getCharCoordinates(ped)
                local dist = getDistanceBetweenCoords3d(x, y, z, getCharCoordinates(playerPed))
                                sampTextdrawCreate(2231, string.format("%.2fm", dist), 410, 390)
    sampTextdrawSetLetterSizeAndColor(2231, 0.25, 1.75, 0xFF00FF78)
    sampTextdrawSetOutlineColor(2231, 0.5, 0xFF000000)
    sampTextdrawSetStyle(2231, 1)
    sampTextdrawSetAlign(2231, 0)
                                if isKeyDown(VK_RBUTTON) then
                    weapon = getCurrentCharWeapon(playerPed)
                    if weapon == 34 then
                                sampTextdrawCreate(2230, string.format("%.2fm", dist), 325, 229)
    sampTextdrawSetLetterSizeAndColor(2230, 0.45, 2.25, 0xFFAA3333)
    sampTextdrawSetOutlineColor(2230, 0.5, 0xFF000000)
    sampTextdrawSetStyle(2230, 1)
    sampTextdrawSetAlign(2230, 0)

                    end
                    end
                    if isPaused then
                                                            sampTextdrawCreate(2235, "AFK", 410, 390)
    sampTextdrawSetLetterSizeAndColor(2235, 0.25, 1.75, 0xFF00FF78)
    sampTextdrawSetOutlineColor(2235, 0.5, 0xFF000000)
    sampTextdrawSetStyle(2235, 1)
    sampTextdrawSetAlign(2235, 0)
    end
                if dist < mainIni.config.dist then
                                             sampTextdrawCreate(2230, " ", 325, 229)
    sampTextdrawSetLetterSizeAndColor(2230, 0.45, 2.25, 0xFFAA3333)
    sampTextdrawSetOutlineColor(2230, 0.5, 0xFF000000)
    sampTextdrawSetStyle(2230, 1)
    sampTextdrawSetAlign(2230, 0)
                                sampTextdrawCreate(2231, string.format("%.2fm", dist), 410, 390)
    sampTextdrawSetLetterSizeAndColor(2231, 0.25, 1.75, 0xFFAA3333)
    sampTextdrawSetOutlineColor(2231, 0.5, 0xFF000000)
    sampTextdrawSetStyle(2231, 1)
    sampTextdrawSetAlign(2231, 0)

                if     isCurrentCharWeapon(PLAYER_PED, 34) then
                printStringNow('TINTA ESTE ~r~PREA APROAPE, ~w~NU POTI ECHIPA SNIPERUL!', 3000)
                setCurrentCharWeapon(PLAYER_PED, 0)
                end
                end
            end
        end
    end
end

Можете ли вы помочь мне интегрировать его сюда? Мне нужно, чтобы на экране отображалось, находится ли игрок в AFK или нет. Я сделал этот скрипт несколько недель назад, и я не могу понять, где сделать функцию и как.
Lua:
    sampRegisterChatCommand('track', function(arg)
        local id = tonumber(arg)
        local isPaused = sampIsPlayerPaused(id)
        if not id or not sampIsPlayerConnected(id) then
        sampTextdrawDelete(2228)
        sampTextdrawDelete(2229)
        sampAddChatMessage('{aa3333}[Hitmen Helper]{ffffff} Distance Tracker este {aa3333}dezactivat.', -1)
        sampAddChatMessage('{aa3333}[Hitmen Helper]{ffffff} Foloseste {aa3333}/track <ID>{ffffff} pentru a-l activa.', -1)
        end
        playerId = id
    end)
    while true do
        wait(0)
        if playerId then
            local result, ped, result2 = sampGetCharHandleBySampPlayerId(playerId)
            sampTextdrawCreate(2228, "Tracker:", 584.5, 397)
    sampTextdrawSetLetterSizeAndColor(2228, 0.19, 1.05, 0xFFAA3333)
    sampTextdrawSetOutlineColor(2228, 0.5, 0xFF000000)
    sampTextdrawSetStyle(2228, 1)
    sampTextdrawSetAlign(2228, 0)
            sampTextdrawCreate(2229, "ON", 609.5, 397)
    sampTextdrawSetLetterSizeAndColor(2229, 0.15, 1.1, 0xFFFFFFFF)
    sampTextdrawSetOutlineColor(2229, 0.5, 0xFF000000)
    sampTextdrawSetStyle(2229, 1)
    sampTextdrawSetAlign(2229, 0)
          
            if result then
                local x, y, z = getCharCoordinates(ped)
                local dist = getDistanceBetweenCoords3d(x, y, z, getCharCoordinates(playerPed))
                                sampTextdrawCreate(2231, string.format("%.2fm", dist), 410, 390)
    sampTextdrawSetLetterSizeAndColor(2231, 0.25, 1.75, 0xFF00FF78)
    sampTextdrawSetOutlineColor(2231, 0.5, 0xFF000000)
    sampTextdrawSetStyle(2231, 1)
    sampTextdrawSetAlign(2231, 0)
                                if isKeyDown(VK_RBUTTON) then
                    weapon = getCurrentCharWeapon(playerPed)
                    if weapon == 34 then
                                sampTextdrawCreate(2230, string.format("%.2fm", dist), 325, 229)
    sampTextdrawSetLetterSizeAndColor(2230, 0.45, 2.25, 0xFFAA3333)
    sampTextdrawSetOutlineColor(2230, 0.5, 0xFF000000)
    sampTextdrawSetStyle(2230, 1)
    sampTextdrawSetAlign(2230, 0)

                    end
                    end
                    if isPaused then
                                                            sampTextdrawCreate(2235, "AFK", 410, 390)
    sampTextdrawSetLetterSizeAndColor(2235, 0.25, 1.75, 0xFF00FF78)
    sampTextdrawSetOutlineColor(2235, 0.5, 0xFF000000)
    sampTextdrawSetStyle(2235, 1)
    sampTextdrawSetAlign(2235, 0)
    end
                if dist < mainIni.config.dist then
                                             sampTextdrawCreate(2230, " ", 325, 229)
    sampTextdrawSetLetterSizeAndColor(2230, 0.45, 2.25, 0xFFAA3333)
    sampTextdrawSetOutlineColor(2230, 0.5, 0xFF000000)
    sampTextdrawSetStyle(2230, 1)
    sampTextdrawSetAlign(2230, 0)
                                sampTextdrawCreate(2231, string.format("%.2fm", dist), 410, 390)
    sampTextdrawSetLetterSizeAndColor(2231, 0.25, 1.75, 0xFFAA3333)
    sampTextdrawSetOutlineColor(2231, 0.5, 0xFF000000)
    sampTextdrawSetStyle(2231, 1)
    sampTextdrawSetAlign(2231, 0)

                if     isCurrentCharWeapon(PLAYER_PED, 34) then
                printStringNow('TINTA ESTE ~r~PREA APROAPE, ~w~NU POTI ECHIPA SNIPERUL!', 3000)
                setCurrentCharWeapon(PLAYER_PED, 0)
                end
                end
            end
        end
    end
end
Вот полный скрипт для чего угодно.
 
  • Эм
Реакции: percheklii

ShawGluz

Известный
70
4
CustomNameTags.lua:545: '<eof>' expected near 'end'

Я просто взял несколько автоматических загрузок из скрипта, и он перестал работать

Python:
cript_name('Custom NameTags')
script_author('SK1DGARD')
script_description('Кастомные name tag\'y ajustes detallados')
script_version(2)
script_dependencies('Imgui', 'FontAwesome 5', 'SAMPFUNCS')

local sampev = require('lib.samp.events')

local encoding = require 'encoding'
encoding.default = 'CP1251'
local u8 = encoding.UTF8

local fa = require 'fAwesome5'
local imgui = require 'imgui'
local window_state = imgui.ImBool(false)

local memory = require 'memory'
local ffi = require('ffi')
local get_bone_pos = ffi.cast("int (__thiscall*)(void*, float*, int, bool)", 0x5E4280)


local inicfg = require'inicfg'

local ini = inicfg.load({
  NICKNAME = {
    enabled = true,
        vertical_offset = 16,
        font_name = 'Arial',
        font_size = 10,
    font_flag = 13,
    opacity = 255,
    display_afk = true
  },
  HEALTH_BAR = {
    enabled = true,
    size_x = 80,
        size_y = 10,
        border_size = 1,
        main_color = 0xFFFF0000,
        border_color = 0xFF000000,
        background_color = 0x68000000
  },
  ARMOR_BAR = {
    enabled = true,
    indent = 3,
        size_x = 80,
        size_y = 10,
        border_size = 1,
        main_color = 0xFFFFFFFF,
        border_color = 0xFF000000,
        background_color = 0x68000000
  },
  HEALTH_COUNT = {
    enabled = true,
    font_name = 'Arial',
        font_size = 7,
        font_flag = 5,
        font_color = 0xFFFFFFFF
  },
  ARMOR_COUNT = {
    enabled = true,
    font_name = 'Arial',
        font_size = 7,
        font_flag = 5,
        font_color = 0xFFFFFFFF
  },
  CHAT_BUBBLE = {
    enabled = true,
    font_name = 'Arial',
        font_size = 7,
        font_flag = 5,
    opacity = 255,
    max_symbols = 15,
    indent = 10,
    line_offset = 2
  },
  GENERAL = {
    on = true,
    vertical_indent = 0.3
  }
}, 'Custom NameTags\\Custom NameTags.ini')

local nick_buffer = imgui.ImBuffer(256)                  --IMGUI FONT BUFFERS
local hp_buffer = imgui.ImBuffer(256)                    --IMGUI FONT BUFFERS
local armor_buffer = imgui.ImBuffer(256)                 --IMGUI FONT BUFFERS
local bubble_buffer = imgui.ImBuffer(256)                --IMGUI FONT BUFFERS

local nick_font, hp_font, armor_font, bubble_font = nil  --FONTS

local current_table = 1                                  --SELECTED IMGUI TABLE

local nt_drawdist = 40                                   --NT DRAW DISTANCE

local bubble_pool = {}                                   -- ['player_id'] = text, color, remove_time, distance

function main()
  if not doesDirectoryExist('moonloader\\config') then createDirectory('moonloader\\config') end
    if not doesDirectoryExist('moonloader\\config\\Custom NameTags') then createDirectory('moonloader\\config\\Custom NameTags') end
    if not doesFileExist('Custom NameTags\\Custom NameTags.ini') then
        if not inicfg.save(ini, 'Custom NameTags\\Custom NameTags.ini') then sampAddChatMessage('{FB4343}[Custom NameTags]{FFFFFF}: El script no puede crear el archivo de configuracion. :(', 0xFFFFFF) end
    end
    
  while not isSampAvailable() do wait(0) end

  sampAddChatMessage('{FB4343}[Custom NameTags]{FFFFFF}: El guion esta activado. Activacion: {FB4343}/cusnt', -1)

  while not isCharOnScreen(PLAYER_PED) do wait(0) end

  local pStSet = sampGetServerSettingsPtr()
  memory.setint8(pStSet + 56, ini.GENERAL.on and 0 or 1) --DISABLE NT
  nt_drawdist = memory.getfloat(pStSet + 39)             --GET NT DRAWDIST
  nt_drawdist = nt_drawdist * nt_drawdist - 1            --GET NT SQUARED
  to_imgui()
  load_fonts()
 
  sampRegisterChatCommand('cusnt', function() window_state.v = not window_state.v end)

  while true do wait(0)

    if ini.GENERAL.on then
      local ped_pool = getAllChars()
      local cam_x, cam_y, cam_z = getActiveCameraCoordinates()
      for _, ped in pairs(ped_pool) do
        if ped ~= PLAYER_PED and isCharOnScreen(ped) then
          local x, y, z = get_bodypart_coordinates(ped, 5)
          
          local alive, player_id = sampGetPlayerIdByCharHandle(ped)
          
          if isLineOfSightClear(cam_x, cam_y, cam_z, x, y, z, true, false, false, true, false) and alive and get_dist_squared(x, y, z, cam_x, cam_y, cam_z) < nt_drawdist and is_nt_visible(player_id) then
            z = z + ini.GENERAL.vertical_indent.v

            local hp = limit_input(sampGetPlayerHealth(player_id), 0, 100)
                      local armor = sampGetPlayerArmor(player_id)
            
            local pl_x, pl_y, pl_z = getCharCoordinates(PLAYER_PED)
            local distance_sq = get_dist_squared(pl_x, pl_y, pl_z, x, y, z)

            local screen_x, screen_y = convert3DCoordsToScreen(x, y, z)
            draw_nt(ped, player_id, screen_x, screen_y, hp, armor, distance_sq, ini.NICKNAME.enabled.v, ini.HEALTH_BAR.enabled.v, ini.ARMOR_BAR.enabled.v, ini.HEALTH_COUNT.enabled.v, ini.ARMOR_COUNT.enabled.v, ini.CHAT_BUBBLE.enabled.v)
          end
        end
      end
    end

    imgui.Process = window_state.v
  end
end

function onScriptTerminate(script, _)
  if script == thisScript() then
    local pStSet = sampGetServerSettingsPtr()
    memory.setint8(pStSet + 56, 1)
  end
end

function sampev.onPlayerChatBubble(playerId, color, distance, duration, message)
  lua_thread.create(
    function()
      while isGamePaused() do wait(0) end

      if ini.GENERAL.on and ini.CHAT_BUBBLE.enabled.v and playerId ~= nil then
        local var = {
          ['text'] = message,
          ['color'] = rgba_to_argb(color),
          ['remove_time'] = os.time() + duration / 1000.0,
          ['distance'] = distance * distance
        }
        table.insert(bubble_pool, playerId, var)
      end
    end)
  return false
end

function sampev.onPlayerQuit(playerId, _)
  if bubble_pool[playerId] ~= nil then table.remove(bubble_pool, playerId) end
end

local fa_font = nil
local fa_glyph_ranges = imgui.ImGlyphRanges({ fa.min_range, fa.max_range })

function imgui.BeforeDrawFrame()
  if fa_font == nil then
    local font_config = imgui.ImFontConfig()
    font_config.MergeMode = true
        font_config.SizePixels = 15.0;
        font_config.GlyphExtraSpacing.x = 0.1
    fa_font = imgui.GetIO().Fonts:AddFontFromFileTTF('moonloader\\config\\Custom NameTags\\fa5.ttf', font_config.SizePixels, font_config, fa_glyph_ranges)
  end
end

function imgui.OnDrawFrame()
  if window_state.v then
    imgui.SetNextWindowPos(imgui.ImVec2(imgui.GetIO().DisplaySize.x / 4, imgui.GetIO().DisplaySize.y / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(723, 420), imgui.Cond.FirstUseEver)
    apply_style()
    imgui.Begin(fa.ICON_COGS .. u8('  Custom name tags | Author: SK1DGARD'), window_state, imgui.WindowFlags.AlwaysAutoResize)
    
    imgui.BeginChild(1, imgui.ImVec2(85, 85), true)
          imgui.SetCursorPos(imgui.ImVec2(5, 5))
      
      if imgui.CustomButton(
        fa.ICON_POWER_OFF,
        ini.GENERAL.on and imgui.ImVec4(0.15, 0.59, 0.18, 0.7) or imgui.ImVec4(1, 0.19, 0.19, 0.5),
        ini.GENERAL.on and imgui.ImVec4(0.15, 0.59, 0.18, 0.5) or imgui.ImVec4(1, 0.19, 0.19, 0.3),
        ini.GENERAL.on and imgui.ImVec4(0.15, 0.59, 0.18, 0.4) or imgui.ImVec4(1, 0.19, 0.19, 0.2),
        imgui.ImVec2(75, 75)) then
        
        ini.GENERAL.on = not ini.GENERAL.on
        sampAddChatMessage(string.format('{FB4343}[Custom NameTags]{FFFFFF}: Guion %s.', ini.GENERAL.on and '{5BFF83}Encendido' or '{FB4343}Apagado'), -1)
        local pStSet = sampGetServerSettingsPtr()
        memory.setint8(pStSet + 56, ini.GENERAL.on and 0 or 1)
      end
    imgui.EndChild()

    imgui.SetCursorPosY(112)

    imgui.BeginChild(2, imgui.ImVec2(85, 313), true)
      imgui.SetCursorPos(imgui.ImVec2(5, 5))

          if imgui.CustomButton(
        fa.ICON_SAVE,
        imgui.ImVec4(0.16, 0.16, 0.16, 0.9),
        imgui.ImVec4(0.40, 0.12, 0.12, 1),
        imgui.ImVec4(0.30, 0.08, 0.08, 1),
        imgui.ImVec2(75, 75)) then

        from_imgui()
        if inicfg.save(ini, 'Custom NameTags\\Custom NameTags.ini') then
          sampAddChatMessage('{FB4343}[Custom NameTags]{FFFFFF}: ajustes correctamente {5BFF83}guardados.', -1)
        else
          sampAddChatMessage('{FB4343}[Custom NameTags]{FFFFFF}: La configuracion no se guarda, no se puede hacer nada{FB4343} :(', -1)
        end
        to_imgui()
      end
      
      imgui.SetCursorPos(imgui.ImVec2(5, 81))

          if imgui.CustomButton(
        fa.ICON_REDO_ALT,
        imgui.ImVec4(0.16, 0.16, 0.16, 0.9),
        imgui.ImVec4(0.40, 0.12, 0.12, 1),
        imgui.ImVec4(0.30, 0.08, 0.08, 1),
        imgui.ImVec2(75, 75)) then

        ini = {
          NICKNAME = {
            enabled = true,
            vertical_offset = 16,
            font_name = 'Arial',
            font_size = 10,
            font_flag = 13,
            opacity = 255,
            display_afk = true
          },
          HEALTH_BAR = {
            enabled = true,
            size_x = 80,
            size_y = 10,
            border_size = 1,
            main_color = 0xFFFF0000,
            border_color = 0xFF000000,
            background_color = 0x68000000
          },
          ARMOR_BAR = {
            enabled = true,
            indent = 3,
            size_x = 80,
            size_y = 10,
            border_size = 1,
            main_color = 0xFFFFFFFF,
            border_color = 0xFF000000,
            background_color = 0x68000000
          },
          HEALTH_COUNT = {
            enabled = true,
            font_name = 'Arial',
            font_size = 7,
            font_flag = 5,
            font_color = 0xFFFFFFFF
          },
          ARMOR_COUNT = {
            enabled = true,
            font_name = 'Arial',
            font_size = 7,
            font_flag = 5,
            font_color = 0xFFFFFFFF
          },
          CHAT_BUBBLE = {
            enabled = true,
            font_name = 'Arial',
            font_size = 7,
            font_flag = 5,
            opacity = 255,
            max_symbols = 15,
            indent = 10,
            line_offset = 2
          },
          GENERAL = {
            on = true,
            vertical_indent = 0.3
          }
        }
        to_imgui()
        load_fonts()
        sampAddChatMessage('{FB4343}[Custom Nametags]{FFFFFF}: reiniciar la configuracion', -1)
      end

      imgui.SetCursorPos(imgui.ImVec2(5, 157))

      end

      imgui.SetCursorPos(imgui.ImVec2(5, 233))

      if imgui.CustomButton(
        fa.ICON_PAPER_PLANE,
        imgui.ImVec4(0.207, 0.674, 0.878, 0.7),
        imgui.ImVec4(0.207, 0.674, 0.878, 0.5),
        imgui.ImVec4(0.207, 0.674, 0.878, 0.4),
        imgui.ImVec2(75, 75)) then

        os.execute('explorer "hhhhh"')
      end
      
    imgui.EndChild()
    
    imgui.SetCursorPos(imgui.ImVec2(92, 28))

    imgui.BeginChild(3, imgui.ImVec2(615, 85), true)
      
      imgui.SetCursorPos(imgui.ImVec2(5,5))
      if imgui.CustomButton(fa.ICON_MALE .. '  Nombre',
        current_table == 1 and imgui.ImVec4(0.56, 0.16, 0.16, 1) or imgui.ImVec4(0.16, 0.16, 0.16, 0.9),
        imgui.ImVec4(0.40, 0.12, 0.12, 1),
        imgui.ImVec4(0.30, 0.08, 0.08, 1),
        imgui.ImVec2(100, 75)) then
        
        current_table = 1
      end

      imgui.SetCursorPos(imgui.ImVec2(106, 5))
      
      if imgui.CustomButton(fa.ICON_HEART .. '  Barra vida',
        current_table == 2 and imgui.ImVec4(0.56, 0.16, 0.16, 1) or imgui.ImVec4(0.16, 0.16, 0.16, 0.9),
        imgui.ImVec4(0.40, 0.12, 0.12, 1),
        imgui.ImVec4(0.30, 0.08, 0.08, 1),
        imgui.ImVec2(100, 75)) then
      
        current_table = 2
      end

      imgui.SetCursorPos(imgui.ImVec2(207, 5))

      if imgui.CustomButton(fa.ICON_SHIELD_ALT .. '  Barra chaleco',
        current_table == 3 and imgui.ImVec4(0.56, 0.16, 0.16, 1) or imgui.ImVec4(0.16, 0.16, 0.16, 0.9),
        imgui.ImVec4(0.40, 0.12, 0.12, 1),
        imgui.ImVec4(0.30, 0.08, 0.08, 1),
        imgui.ImVec2(100, 75)) then
      
        current_table = 3
      end

      imgui.SetCursorPos(imgui.ImVec2(308, 5))

      if imgui.CustomButton(fa.ICON_HEARTBEAT .. '  Status vida',
        current_table == 4 and imgui.ImVec4(0.56, 0.16, 0.16, 1) or imgui.ImVec4(0.16, 0.16, 0.16, 0.9),
        imgui.ImVec4(0.40, 0.12, 0.12, 1),
        imgui.ImVec4(0.30, 0.08, 0.08, 1),
        imgui.ImVec2(100, 75)) then
      
        current_table = 4
      end

      imgui.SetCursorPos(imgui.ImVec2(409, 5))

      if imgui.CustomButton(fa.ICON_SHIELD_ALT .. '  Status chaleco',
        current_table == 5 and imgui.ImVec4(0.56, 0.16, 0.16, 1) or imgui.ImVec4(0.16, 0.16, 0.16, 0.9),
        imgui.ImVec4(0.40, 0.12, 0.12, 1),
        imgui.ImVec4(0.30, 0.08, 0.08, 1),
        imgui.ImVec2(100, 75)) then
      
        current_table = 5
      end
      imgui.SetCursorPos(imgui.ImVec2(510, 5))
 
      if imgui.CustomButton(fa.ICON_PENCIL_ALT .. '  Burbuja chat',
        current_table == 6 and imgui.ImVec4(0.56, 0.16, 0.16, 1) or imgui.ImVec4(0.16, 0.16, 0.16, 0.9),
        imgui.ImVec4(0.40, 0.12, 0.12, 1),
        imgui.ImVec4(0.30, 0.08, 0.08, 1),
        imgui.ImVec2(100, 75)) then
      
        current_table = 6
      end
    imgui.EndChild()

    imgui.SetCursorPos(imgui.ImVec2(92, 112))

    imgui.BeginChild(4, imgui.ImVec2(615, 276), true)
      if current_table == 1 then
        imgui.PushItemWidth(300)
        imgui.Checkbox('Draw player nicknames##nick', ini.NICKNAME.enabled)

        imgui.InputText('##font_nick', nick_buffer)

        imgui.SameLine()
        imgui.SetCursorPosX(312)

        if imgui.Button(fa.ICON_CHECK .. ' Confirm##nick', imgui.ImVec2(94, 20)) then
          ini.NICKNAME.font_name = u8:decode(nick_buffer.v)
          nick_font = renderCreateFont(ini.NICKNAME.font_name, ini.NICKNAME.font_size.v, ini.NICKNAME.font_flag.v)
        end

        imgui.SameLine()
        imgui.SetCursorPosX(412)

        imgui.Text(fa.ICON_FONT .. u8(string.format('  Font Name (%s)', ini.NICKNAME.font_name)))

        if imgui.InputInt(fa.ICON_TEXT_WIDTH .. "  Font size##nick", ini.NICKNAME.font_size) then
          ini.NICKNAME.font_size.v = limit_input(ini.NICKNAME.font_size.v, 1, 145)
          nick_font = renderCreateFont(ini.NICKNAME.font_name, ini.NICKNAME.font_size.v, ini.NICKNAME.font_flag.v)
        end

        if imgui.InputInt(fa.ICON_FLAG .. "  Font flag##nick", ini.NICKNAME.font_flag) then
          ini.NICKNAME.font_flag.v = limit_input(ini.NICKNAME.font_flag.v, 0, 600)
          nick_font = renderCreateFont(ini.NICKNAME.font_name, ini.NICKNAME.font_size.v, ini.NICKNAME.font_flag.v)
        end

        imgui.SliderInt(fa.ICON_ARROW_UP .. '  Nickname offset by Y axis##nick', ini.NICKNAME.vertical_offset, -100, 100)

        imgui.SliderInt(fa.ICON_MOON .. '  Nickname color opacity##nick', ini.NICKNAME.opacity, 0, 255)
        
        imgui.Checkbox('Display indicator if player is Paused', ini.NICKNAME.display_afk)
        imgui.PopItemWidth()
      end
      if current_table == 2 then
        imgui.PushItemWidth(460)
        imgui.Checkbox('Display player health bar##hpbar', ini.HEALTH_BAR.enabled)
        imgui.SliderInt(fa.ICON_SLIDERS_H .. ' Health bar width##hpbar', ini.HEALTH_BAR.size_x, 0, 400)
        imgui.SliderInt(fa.ICON_SLIDERS_H .. ' Health bar height##hpbar', ini.HEALTH_BAR.size_y, 0, 400)
        imgui.SliderInt(fa.ICON_SLIDERS_H .. ' Border thickness##hpbar', ini.HEALTH_BAR.border_size, 0, 60)
        imgui.ColorEdit4(fa.ICON_SPINNER .. "  Main color##hpbar", ini.HEALTH_BAR.main_color)
        imgui.ColorEdit4(fa.ICON_SPINNER .. "  Background color##hpbar", ini.HEALTH_BAR.background_color)
        imgui.ColorEdit4(fa.ICON_SPINNER .. "  Border color##hpbar", ini.HEALTH_BAR.border_color)
        imgui.PopItemWidth()
      end
      if current_table == 3 then
        imgui.PushItemWidth(460)
        imgui.Checkbox('Display player armor bar##armor', ini.ARMOR_BAR.enabled)
        imgui.SliderInt(fa.ICON_SLIDERS_H .. ' Armor bar width##armor', ini.ARMOR_BAR.size_x, 0, 400)
        imgui.SliderInt(fa.ICON_SLIDERS_H .. ' armor bar height##armor', ini.ARMOR_BAR.size_y, 0, 400)
        imgui.SliderInt(fa.ICON_SLIDERS_H .. ' Border thickness##armor', ini.ARMOR_BAR.border_size, 0, 60)
        imgui.ColorEdit4(fa.ICON_SPINNER .. "  Main color##armor", ini.ARMOR_BAR.main_color)
        imgui.ColorEdit4(fa.ICON_SPINNER .. "  Background color##armor", ini.ARMOR_BAR.background_color)
        imgui.ColorEdit4(fa.ICON_SPINNER .. "  Border color##armor", ini.ARMOR_BAR.border_color)
        imgui.SliderInt(fa.ICON_SLIDERS_H .. ' Armor vertical offset##armor', ini.ARMOR_BAR.indent, 0, 200)
        imgui.PopItemWidth()
      end
      if current_table == 4 then
        imgui.PushItemWidth(300)

        imgui.Checkbox('Draw player health count##hpcount', ini.HEALTH_COUNT.enabled)

        imgui.ColorEdit4(fa.ICON_SPINNER .. ' Font color##hpcount', ini.HEALTH_COUNT.font_color)

        imgui.PopItemWidth()
      end
      if current_table == 5 then
        imgui.PushItemWidth(300)
 
        imgui.Checkbox('Draw player armor count##armorcount', ini.ARMOR_COUNT.enabled)
 
        imgui.InputText('##font_armor', armor_buffer)
        imgui.SameLine()
        imgui.SetCursorPosX(312)
      
        if imgui.Button(fa.ICON_CHECK .. ' Confirm##armorcount', imgui.ImVec2(94, 20)) then
          ini.ARMOR_COUNT.font_name = u8:decode(armor_buffer.v)
          armor_font = renderCreateFont(ini.ARMOR_COUNT.font_name, ini.ARMOR_COUNT.font_size.v, ini.ARMOR_COUNT.font_flag.v)
        end
 
        imgui.SameLine()
        imgui.SetCursorPosX(412)
        imgui.Text(fa.ICON_FONT .. u8(string.format('  Font Name (%s)', ini.ARMOR_COUNT.font_name)))
 
        if imgui.InputInt(fa.ICON_TEXT_WIDTH .. "  Font size##armorcount", ini.ARMOR_COUNT.font_size) then
          ini.ARMOR_COUNT.font_size.v = limit_input(ini.ARMOR_COUNT.font_size.v, 1, 145)
          armor_font = renderCreateFont(ini.ARMOR_COUNT.font_name, ini.ARMOR_COUNT.font_size.v, ini.ARMOR_COUNT.font_flag.v)
        end
 
        if imgui.InputInt(fa.ICON_FLAG .. "  Font flag##armorcount", ini.ARMOR_COUNT.font_flag) then
          ini.ARMOR_COUNT.font_flag.v = limit_input(ini.ARMOR_COUNT.font_flag.v, 0, 600)
          armor_font = renderCreateFont(ini.ARMOR_COUNT.font_name, ini.ARMOR_COUNT.font_size.v, ini.ARMOR_COUNT.font_flag.v)
        end
 
        imgui.ColorEdit4(fa.ICON_SPINNER .. ' Font color##armorcount', ini.ARMOR_COUNT.font_color)
          
        imgui.PopItemWidth()
      end
      if current_table == 6 then
        imgui.PushItemWidth(300)
 
        imgui.Checkbox('Draw player chat bubble##chatbubble', ini.CHAT_BUBBLE.enabled)
 
        imgui.InputText('##font_chatbubble', bubble_buffer)
        imgui.SameLine()
        imgui.SetCursorPosX(312)
      
        if imgui.Button(fa.ICON_CHECK .. ' Confirm##chatbubble', imgui.ImVec2(94, 20)) then
          ini.CHAT_BUBBLE.font_name = u8:decode(bubble_buffer.v)
          bubble_font = renderCreateFont(ini.CHAT_BUBBLE.font_name, ini.CHAT_BUBBLE.font_size.v, ini.CHAT_BUBBLE.font_flag.v)
        end
 
        imgui.SameLine()
        imgui.SetCursorPosX(412)
        imgui.Text(fa.ICON_FONT .. u8(string.format('  Font Name (%s)', ini.CHAT_BUBBLE.font_name)))
 
        if imgui.InputInt(fa.ICON_TEXT_WIDTH .. "  Font size##chatbubble", ini.CHAT_BUBBLE.font_size) then
          ini.CHAT_BUBBLE.font_size.v = limit_input(ini.CHAT_BUBBLE.font_size.v, 1, 145)
          bubble_font = renderCreateFont(ini.CHAT_BUBBLE.font_name, ini.CHAT_BUBBLE.font_size.v, ini.CHAT_BUBBLE.font_flag.v)
        end
 
        if imgui.InputInt(fa.ICON_FLAG .. "  Font flag##chatbubble", ini.CHAT_BUBBLE.font_flag) then
          ini.CHAT_BUBBLE.font_flag.v = limit_input(ini.CHAT_BUBBLE.font_flag.v, 0, 600)
          bubble_font = renderCreateFont(ini.CHAT_BUBBLE.font_name, ini.CHAT_BUBBLE.font_size.v, ini.CHAT_BUBBLE.font_flag.v)
        end
        imgui.SliderInt(fa.ICON_SPINNER .. ' Chat bubble text opacity', ini.CHAT_BUBBLE.opacity, 0, 255)
        imgui.SliderInt(fa.ICON_ARROW_UP .. ' Chat bubble offset by Y axis', ini.CHAT_BUBBLE.indent, 0, 200)
        imgui.SliderInt(fa.ICON_SLIDERS_H .. ' Offset between lines', ini.CHAT_BUBBLE.line_offset, 0, 200)
        if imgui.InputInt(fa.ICON_FONT .. ' Maximal symbols in chat bubble line', ini.CHAT_BUBBLE.max_symbols) then
          ini.CHAT_BUBBLE.max_symbols.v = limit_input(ini.CHAT_BUBBLE.max_symbols.v, 1, 500)
        end
        imgui.PopItemWidth()
      end
    imgui.EndChild()

    imgui.SetCursorPos(imgui.ImVec2(92, 387))

    imgui.BeginChild(5, imgui.ImVec2(615, 38), true)
      imgui.SetCursorPos(imgui.ImVec2(10, 10)) 
      imgui.PushItemWidth(430)
      imgui.SliderFloat(fa.ICON_COGS .. '  NameTag vertical offset', ini.GENERAL.vertical_indent, -2, 2)
      imgui.PopItemWidth()
    imgui.EndChild()
    imgui.End()
  end
end

function draw_nt(ped, player_id, screen_x, screen_y, hp, armor, distance_sq, draw_nick, draw_health_bar, draw_armor_bar, draw_health_count, draw_armor_count, draw_chat_bubble)
  if draw_health_bar then
    renderDrawBoxWithBorder(
      screen_x - ini.HEALTH_BAR.size_x.v / 2,
      screen_y - ini.HEALTH_BAR.size_y.v / 2,
      ini.HEALTH_BAR.size_x.v,
      ini.HEALTH_BAR.size_y.v,
      imgui.ImColor(imgui.ImColor.FromFloat4(ini.HEALTH_BAR.background_color.v[3], ini.HEALTH_BAR.background_color.v[2], ini.HEALTH_BAR.background_color.v[1], ini.HEALTH_BAR.background_color.v[4]):GetVec4()):GetU32(),
      ini.HEALTH_BAR.border_size.v,
      imgui.ImColor(imgui.ImColor.FromFloat4(ini.HEALTH_BAR.border_color.v[3], ini.HEALTH_BAR.border_color.v[2], ini.HEALTH_BAR.border_color.v[1], ini.HEALTH_BAR.border_color.v[4]):GetVec4()):GetU32())
    renderDrawBox(
      screen_x - ini.HEALTH_BAR.size_x.v / 2 + ini.HEALTH_BAR.border_size.v,
      screen_y - ini.HEALTH_BAR.size_y.v / 2 + ini.HEALTH_BAR.border_size.v,
      (ini.HEALTH_BAR.size_x.v - ini.HEALTH_BAR.border_size.v * 2) * hp / 100.0,
      ini.HEALTH_BAR.size_y.v - ini.HEALTH_BAR.border_size.v * 2,
      imgui.ImColor(imgui.ImColor.FromFloat4(ini.HEALTH_BAR.main_color.v[3], ini.HEALTH_BAR.main_color.v[2], ini.HEALTH_BAR.main_color.v[1], ini.HEALTH_BAR.main_color.v[4]):GetVec4()):GetU32())
  end

  if draw_health_count then
        renderFontDrawText(
            hp_font,
            hp,
            screen_x - renderGetFontDrawTextLength(hp_font, hp) / 2,
            screen_y - renderGetFontDrawHeight(hp_font) / 2,
            imgui.ImColor(imgui.ImColor.FromFloat4(ini.HEALTH_COUNT.font_color.v[3], ini.HEALTH_COUNT.font_color.v[2], ini.HEALTH_COUNT.font_color.v[1], ini.HEALTH_COUNT.font_color.v[4]):GetVec4()):GetU32())
  end
 
  if armor > 0 then
    screen_y = screen_y - ini.HEALTH_BAR.size_y.v / 2 - ini.ARMOR_BAR.indent.v - ini.ARMOR_BAR.size_y.v

    if draw_armor_bar then
      renderDrawBoxWithBorder(
        screen_x - ini.ARMOR_BAR.size_x.v / 2,
        screen_y,
        ini.ARMOR_BAR.size_x.v,
        ini.ARMOR_BAR.size_y.v,
        imgui.ImColor(imgui.ImColor.FromFloat4(ini.ARMOR_BAR.background_color.v[3], ini.ARMOR_BAR.background_color.v[2], ini.ARMOR_BAR.background_color.v[1], ini.ARMOR_BAR.background_color.v[4]):GetVec4()):GetU32(),
        ini.ARMOR_BAR.border_size.v,
        imgui.ImColor(imgui.ImColor.FromFloat4(ini.ARMOR_BAR.border_color.v[3], ini.ARMOR_BAR.border_color.v[2], ini.ARMOR_BAR.border_color.v[1], ini.ARMOR_BAR.border_color.v[4]):GetVec4()):GetU32())
      renderDrawBox(
        screen_x - ini.ARMOR_BAR.size_x.v / 2 + ini.ARMOR_BAR.border_size.v,
        screen_y + ini.ARMOR_BAR.border_size.v,
        (ini.ARMOR_BAR.size_x.v - ini.ARMOR_BAR.border_size.v * 2) * armor / 100.0,
        ini.ARMOR_BAR.size_y.v - ini.ARMOR_BAR.border_size.v * 2,
        imgui.ImColor(imgui.ImColor.FromFloat4(ini.ARMOR_BAR.main_color.v[3], ini.ARMOR_BAR.main_color.v[2], ini.ARMOR_BAR.main_color.v[1], ini.ARMOR_BAR.main_color.v[4]):GetVec4()):GetU32())
    end

    if draw_armor_count then
      renderFontDrawText(
        armor_font,
        armor,
        screen_x - renderGetFontDrawTextLength(armor_font, armor) / 2,
        screen_y + (ini.ARMOR_BAR.size_y.v / 2 - renderGetFontDrawHeight(armor_font) / 2),
        imgui.ImColor(imgui.ImColor.FromFloat4(ini.ARMOR_COUNT.font_color.v[3], ini.ARMOR_COUNT.font_color.v[2], ini.ARMOR_COUNT.font_color.v[1], ini.ARMOR_COUNT.font_color.v[4]):GetVec4()):GetU32())
    end
  end
 
  if draw_nick then
    screen_y = screen_y - ini.NICKNAME.vertical_offset.v - renderGetFontDrawHeight(nick_font) / 2
    local ped_nick = sampGetPlayerNickname(player_id)
    ped_nick = string.format('%s[%d]%s', ped_nick, player_id, (ini.NICKNAME.display_afk.v and sampIsPlayerPaused(player_id)) and ' {FFFFFF}<AFK>' or '')
    local clr = argb_to_rgb(sampGetPlayerColor(player_id), ini.NICKNAME.opacity.v)
    renderFontDrawText(
      nick_font,
      ped_nick,
      screen_x - renderGetFontDrawTextLength(nick_font, ped_nick) / 2,
      screen_y,
      clr)
  end

  if draw_chat_bubble and bubble_pool[player_id] ~= nil and distance_sq < bubble_pool[player_id].distance then
    if os.time() < bubble_pool[player_id].remove_time then
    render_text_wrapped(
      bubble_font,
      screen_x,
      screen_y - ini.CHAT_BUBBLE.indent.v,
      bubble_pool[player_id].text,
      bubble_pool[player_id].color,
      ini.CHAT_BUBBLE.max_symbols.v,
      ini.CHAT_BUBBLE.line_offset.v)
    else
      table.remove(bubble_pool, player_id)
    end
  end
end

function render_text_wrapped(font, x, y, text, color, max_symbols, line_offset)
  local str_list = {}
  local last_str = ''
  for i = 1, #text do
    if #last_str == max_symbols then
      table.insert(str_list, last_str)
      last_str = ''
    end
    last_str = last_str .. string.sub(text, i, i)
  end
  if #last_str > 0 then table.insert(str_list, last_str) end
  for i = 1, #str_list do
    renderFontDrawText(
      font,
      str_list[i],
      x - renderGetFontDrawTextLength(font, str_list[i]) / 2,
      y - renderGetFontDrawHeight(font) * (#str_list - i ) - line_offset * (#str_list - i - 1),
      color)
  end
end

function get_dist_squared(x1, y1, z1, x2, y2, z2)
  return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2)
end

function limit_input(var, min, max)
    if var < min then var = min end
    if max < var then    var = max end
    return var
end

function rgba_to_argb(rgba)
  local r, g, b, a = hex_to_argb(rgba)
  return argb_to_hex(ini.CHAT_BUBBLE.opacity.v, r, g, b)
end

function argb_to_rgb(argb, new_a)
  local a, r, g, b = hex_to_argb(argb)
    return argb_to_hex(new_a, r, g, b)
end

function argb_to_hex(a, r, g, b)
  local argb = b
  argb = bit.bor(argb, bit.lshift(g, 8))
  argb = bit.bor(argb, bit.lshift(r, 16))
  argb = bit.bor(argb, bit.lshift(a, 24))
  return argb
end

function hex_to_argb(hex)
  return
    bit.band(bit.rshift(hex, 24), 255),
    bit.band(bit.rshift(hex, 16), 255),
    bit.band(bit.rshift(hex, 8), 255),
    bit.band(hex, 255)
end

function is_nt_visible(id)
  local StructPtr = readMemory(sampGetPlayerStructPtr(id), 4, true)
  local Element = getStructElement(StructPtr, 179, 2, false)
  if Element == 0 then return false else return true end
end

function get_bodypart_coordinates(handle, id)
    if doesCharExist(handle) then
        local pedptr = getCharPointer(handle)
        local vec = ffi.new("float[3]")
        get_bone_pos(ffi.cast("void*", pedptr), vec, id, true)
        return vec[0], vec[1], vec[2]
    end
end

function imgui.CustomButton(name, color, colorHovered, colorActive, size)
  local clr = imgui.Col
  imgui.PushStyleColor(clr.Button, color)
  imgui.PushStyleColor(clr.ButtonHovered, colorHovered)
  imgui.PushStyleColor(clr.ButtonActive, colorActive)
  if not size then size = imgui.ImVec2(0, 0) end
  local result = imgui.Button(name, size)
  imgui.PopStyleColor(3)
  return result
end

function load_fonts()
  nick_font = renderCreateFont(ini.NICKNAME.font_name, ini.NICKNAME.font_size.v, ini.NICKNAME.font_flag.v)
  hp_font = renderCreateFont(ini.HEALTH_COUNT.font_name, ini.HEALTH_COUNT.font_size.v, ini.HEALTH_COUNT.font_flag.v)
  armor_font = renderCreateFont(ini.ARMOR_COUNT.font_name, ini.ARMOR_COUNT.font_size.v, ini.ARMOR_COUNT.font_flag.v)
  bubble_font = renderCreateFont(ini.CHAT_BUBBLE.font_name, ini.CHAT_BUBBLE.font_size.v, ini.CHAT_BUBBLE.font_flag.v)
end

function to_imgui()
  local temp_a, temp_r, temp_g, temp_b = nil

  ini.NICKNAME.enabled = imgui.ImBool(ini.NICKNAME.enabled)
    ini.NICKNAME.vertical_offset =  imgui.ImInt(ini.NICKNAME.vertical_offset)
    --ini.NICKNAME.font_name =
    ini.NICKNAME.font_size = imgui.ImInt(ini.NICKNAME.font_size)
  ini.NICKNAME.font_flag = imgui.ImInt(ini.NICKNAME.font_flag)
  ini.NICKNAME.opacity = imgui.ImInt(ini.NICKNAME.opacity)
  ini.NICKNAME.display_afk = imgui.ImBool(ini.NICKNAME.display_afk)

  ini.HEALTH_BAR.enabled = imgui.ImBool(ini.HEALTH_BAR.enabled)
  ini.HEALTH_BAR.size_x = imgui.ImInt(ini.HEALTH_BAR.size_x)
  ini.HEALTH_BAR.size_y = imgui.ImInt(ini.HEALTH_BAR.size_y)
  ini.HEALTH_BAR.border_size = imgui.ImInt(ini.HEALTH_BAR.border_size)
  temp_a, temp_r, temp_g, temp_b = hex_to_argb(ini.HEALTH_BAR.main_color)
  ini.HEALTH_BAR.main_color = imgui.ImFloat4(imgui.ImColor(temp_r, temp_g, temp_b, temp_a):GetFloat4())
  temp_a, temp_r, temp_g, temp_b = hex_to_argb(ini.HEALTH_BAR.border_color)
  ini.HEALTH_BAR.border_color = imgui.ImFloat4(imgui.ImColor(temp_r, temp_g, temp_b, temp_a):GetFloat4())
  temp_a, temp_r, temp_g, temp_b = hex_to_argb(ini.HEALTH_BAR.background_color)
  ini.HEALTH_BAR.background_color = imgui.ImFloat4(imgui.ImColor(temp_r, temp_g, temp_b, temp_a):GetFloat4())

  ini.ARMOR_BAR.enabled = imgui.ImBool(ini.ARMOR_BAR.enabled)
  ini.ARMOR_BAR.indent = imgui.ImInt(ini.ARMOR_BAR.indent)
  ini.ARMOR_BAR.size_x = imgui.ImInt(ini.ARMOR_BAR.size_x)
  ini.ARMOR_BAR.size_y = imgui.ImInt(ini.ARMOR_BAR.size_y)
  ini.ARMOR_BAR.border_size = imgui.ImInt(ini.ARMOR_BAR.border_size)
  temp_a, temp_r, temp_g, temp_b = hex_to_argb(ini.ARMOR_BAR.main_color)
  ini.ARMOR_BAR.main_color = imgui.ImFloat4(imgui.ImColor(temp_r, temp_g, temp_b, temp_a):GetFloat4())
  temp_a, temp_r, temp_g, temp_b = hex_to_argb(ini.ARMOR_BAR.border_color)
  ini.ARMOR_BAR.border_color = imgui.ImFloat4(imgui.ImColor(temp_r, temp_g, temp_b, temp_a):GetFloat4())
  temp_a, temp_r, temp_g, temp_b = hex_to_argb(ini.ARMOR_BAR.background_color)
  ini.ARMOR_BAR.background_color = imgui.ImFloat4(imgui.ImColor(temp_r, temp_g, temp_b, temp_a):GetFloat4())

  ini.HEALTH_COUNT.enabled = imgui.ImBool(ini.HEALTH_COUNT.enabled)
  --ini.HEALTH_COUNT.font_name =
  ini.HEALTH_COUNT.font_size = imgui.ImInt(ini.HEALTH_COUNT.font_size)
  ini.HEALTH_COUNT.font_flag = imgui.ImInt(ini.HEALTH_COUNT.font_flag)
  temp_a, temp_r, temp_g, temp_b = hex_to_argb(ini.HEALTH_COUNT.font_color)
  ini.HEALTH_COUNT.font_color = imgui.ImFloat4(imgui.ImColor(temp_r, temp_g, temp_b, temp_a):GetFloat4())

  ini.ARMOR_COUNT.enabled = imgui.ImBool(ini.ARMOR_COUNT.enabled)
  --ini.ARMOR_COUNT.font_name =
  ini.ARMOR_COUNT.font_size = imgui.ImInt(ini.ARMOR_COUNT.font_size)
  ini.ARMOR_COUNT.font_flag = imgui.ImInt(ini.ARMOR_COUNT.font_flag)
  temp_a, temp_r, temp_g, temp_b = hex_to_argb(ini.ARMOR_COUNT.font_color)
  ini.ARMOR_COUNT.font_color = imgui.ImFloat4(imgui.ImColor(temp_r, temp_g, temp_b, temp_a):GetFloat4())


  ini.CHAT_BUBBLE.enabled = imgui.ImBool(ini.CHAT_BUBBLE.enabled)
  --ini.CHAT_BUBBLE.font_name =
  ini.CHAT_BUBBLE.font_size = imgui.ImInt(ini.CHAT_BUBBLE.font_size)
  ini.CHAT_BUBBLE.font_flag = imgui.ImInt(ini.CHAT_BUBBLE.font_flag)
  ini.CHAT_BUBBLE.opacity = imgui.ImInt(ini.CHAT_BUBBLE.opacity)
  ini.CHAT_BUBBLE.max_symbols = imgui.ImInt(ini.CHAT_BUBBLE.max_symbols)
  ini.CHAT_BUBBLE.indent = imgui.ImInt(ini.CHAT_BUBBLE.indent)
  ini.CHAT_BUBBLE.line_offset = imgui.ImInt(ini.CHAT_BUBBLE.line_offset)

  --ini.GENERAL.on = imgui.ImBool(ini.GENERAL.on)
  ini.GENERAL.vertical_indent = imgui.ImFloat(ini.GENERAL.vertical_indent)
end

function from_imgui()
  ini.NICKNAME.enabled = ini.NICKNAME.enabled.v
    ini.NICKNAME.vertical_offset =  ini.NICKNAME.vertical_offset.v
    ini.NICKNAME.font_size = ini.NICKNAME.font_size.v
  ini.NICKNAME.font_flag = ini.NICKNAME.font_flag.v
  ini.NICKNAME.opacity = ini.NICKNAME.opacity.v
  ini.NICKNAME.display_afk = ini.NICKNAME.display_afk.v

  ini.HEALTH_BAR.enabled = ini.HEALTH_BAR.enabled.v
  ini.HEALTH_BAR.size_x = ini.HEALTH_BAR.size_x.v
  ini.HEALTH_BAR.size_y = ini.HEALTH_BAR.size_y.v
  ini.HEALTH_BAR.border_size = ini.HEALTH_BAR.border_size.v
  ini.HEALTH_BAR.main_color = imgui.ImColor(imgui.ImColor.FromFloat4(ini.HEALTH_BAR.main_color.v[3], ini.HEALTH_BAR.main_color.v[2], ini.HEALTH_BAR.main_color.v[1], ini.HEALTH_BAR.main_color.v[4]):GetVec4()):GetU32()
  ini.HEALTH_BAR.border_color = imgui.ImColor(imgui.ImColor.FromFloat4(ini.HEALTH_BAR.border_color.v[3], ini.HEALTH_BAR.border_color.v[2], ini.HEALTH_BAR.border_color.v[1], ini.HEALTH_BAR.border_color.v[4]):GetVec4()):GetU32()
  ini.HEALTH_BAR.background_color = imgui.ImColor(imgui.ImColor.FromFloat4(ini.HEALTH_BAR.background_color.v[3], ini.HEALTH_BAR.background_color.v[2], ini.HEALTH_BAR.background_color.v[1], ini.HEALTH_BAR.background_color.v[4]):GetVec4()):GetU32()

  ini.ARMOR_BAR.enabled = ini.ARMOR_BAR.enabled.v
  ini.ARMOR_BAR.indent = ini.ARMOR_BAR.indent.v
  ini.ARMOR_BAR.size_x = ini.ARMOR_BAR.size_x.v
  ini.ARMOR_BAR.size_y = ini.ARMOR_BAR.size_y.v
  ini.ARMOR_BAR.border_size = ini.ARMOR_BAR.border_size.v
  ini.ARMOR_BAR.main_color = imgui.ImColor(imgui.ImColor.FromFloat4(ini.ARMOR_BAR.main_color.v[3], ini.ARMOR_BAR.main_color.v[2], ini.ARMOR_BAR.main_color.v[1], ini.ARMOR_BAR.main_color.v[4]):GetVec4()):GetU32()
  ini.ARMOR_BAR.border_color = imgui.ImColor(imgui.ImColor.FromFloat4(ini.ARMOR_BAR.border_color.v[3], ini.ARMOR_BAR.border_color.v[2], ini.ARMOR_BAR.border_color.v[1], ini.ARMOR_BAR.border_color.v[4]):GetVec4()):GetU32()
  ini.ARMOR_BAR.background_color = imgui.ImColor(imgui.ImColor.FromFloat4(ini.ARMOR_BAR.background_color.v[3], ini.ARMOR_BAR.background_color.v[2], ini.ARMOR_BAR.background_color.v[1], ini.ARMOR_BAR.background_color.v[4]):GetVec4()):GetU32()

  ini.HEALTH_COUNT.enabled = ini.HEALTH_COUNT.enabled.v
  ini.HEALTH_COUNT.font_size = ini.HEALTH_COUNT.font_size.v
  ini.HEALTH_COUNT.font_flag = ini.HEALTH_COUNT.font_flag.v
  ini.HEALTH_COUNT.font_color = imgui.ImColor(imgui.ImColor.FromFloat4(ini.HEALTH_COUNT.font_color.v[3], ini.HEALTH_COUNT.font_color.v[2], ini.HEALTH_COUNT.font_color.v[1], ini.HEALTH_COUNT.font_color.v[4]):GetVec4()):GetU32()

  ini.ARMOR_COUNT.enabled = ini.ARMOR_COUNT.enabled.v
  ini.ARMOR_COUNT.font_size = ini.ARMOR_COUNT.font_size.v
  ini.ARMOR_COUNT.font_flag = ini.ARMOR_COUNT.font_flag.v
  ini.ARMOR_COUNT.font_color = imgui.ImColor(imgui.ImColor.FromFloat4(ini.ARMOR_COUNT.font_color.v[3], ini.ARMOR_COUNT.font_color.v[2], ini.ARMOR_COUNT.font_color.v[1], ini.ARMOR_COUNT.font_color.v[4]):GetVec4()):GetU32()


  ini.CHAT_BUBBLE.enabled = ini.CHAT_BUBBLE.enabled.v
  ini.CHAT_BUBBLE.font_size = ini.CHAT_BUBBLE.font_size.v
  ini.CHAT_BUBBLE.font_flag = ini.CHAT_BUBBLE.font_flag.v
  ini.CHAT_BUBBLE.opacity = ini.CHAT_BUBBLE.opacity.v
  ini.CHAT_BUBBLE.max_symbols = ini.CHAT_BUBBLE.max_symbols.v
  ini.CHAT_BUBBLE.indent = ini.CHAT_BUBBLE.indent.v
  ini.CHAT_BUBBLE.line_offset = ini.CHAT_BUBBLE.line_offset.v

  ini.GENERAL.vertical_indent = ini.GENERAL.vertical_indent.v
end

function apply_style()
    imgui.SwitchContext()
    local ImVec4 = imgui.ImVec4
    local ImVec2 = imgui.ImVec2
    local style = imgui.GetStyle()
    style.WindowRounding = 0
    style.WindowPadding = ImVec2(8, 8)
    style.WindowTitleAlign = ImVec2(0.5, 0.5)
    style.ChildWindowRounding = 0
    style.FrameRounding = 0
    style.ItemSpacing = ImVec2(8, 4)
    style.ScrollbarSize = 10
    style.ScrollbarRounding = 3
    style.GrabMinSize = 10
    style.GrabRounding = 0
    style.Alpha = 1
    style.FramePadding = ImVec2(4, 3)
    style.ItemInnerSpacing = ImVec2(4, 4)
    style.TouchExtraPadding = ImVec2(0, 0)
    style.IndentSpacing = 21
    style.ColumnsMinSpacing = 6
    style.ButtonTextAlign = ImVec2(0.5, 0.5)
    style.DisplayWindowPadding = ImVec2(22, 22)
    style.DisplaySafeAreaPadding = ImVec2(4, 4)
    style.AntiAliasedLines = true
    style.AntiAliasedShapes = true
    style.CurveTessellationTol = 1.25
    local colors = style.Colors
    local clr = imgui.Col
    colors[clr.FrameBg]                = ImVec4(0.48, 0.16, 0.16, 0.54)
    colors[clr.FrameBgHovered]         = ImVec4(0.98, 0.26, 0.26, 0.40)
    colors[clr.FrameBgActive]          = ImVec4(0.98, 0.26, 0.26, 0.67)
    colors[clr.TitleBg]                = ImVec4(0.04, 0.04, 0.04, 1.00)
    colors[clr.TitleBgActive]          = ImVec4(0.48, 0.16, 0.16, 1.00)
    colors[clr.TitleBgCollapsed]       = ImVec4(0.00, 0.00, 0.00, 0.51)
    colors[clr.CheckMark]              = ImVec4(0.98, 0.26, 0.26, 1.00)
    colors[clr.SliderGrab]             = ImVec4(0.88, 0.26, 0.24, 1.00)
    colors[clr.SliderGrabActive]       = ImVec4(0.98, 0.26, 0.26, 1.00)
    colors[clr.Button]                 = ImVec4(0.98, 0.26, 0.26, 0.40)
    colors[clr.ButtonHovered]          = ImVec4(0.98, 0.26, 0.26, 1.00)
    colors[clr.ButtonActive]           = ImVec4(0.98, 0.06, 0.06, 1.00)
    colors[clr.Header]                 = ImVec4(0.98, 0.26, 0.26, 0.31)
    colors[clr.HeaderHovered]          = ImVec4(0.98, 0.26, 0.26, 0.80)
    colors[clr.HeaderActive]           = ImVec4(0.98, 0.26, 0.26, 1.00)
    colors[clr.Separator]              = colors[clr.Border]
    colors[clr.SeparatorHovered]       = ImVec4(0.75, 0.10, 0.10, 0.78)
    colors[clr.SeparatorActive]        = ImVec4(0.75, 0.10, 0.10, 1.00)
    colors[clr.ResizeGrip]             = ImVec4(0.98, 0.26, 0.26, 0.25)
    colors[clr.ResizeGripHovered]      = ImVec4(0.98, 0.26, 0.26, 0.67)
  colors[clr.ResizeGripActive]       = ImVec4(0.98, 0.26, 0.26, 0.95)
    colors[clr.TextSelectedBg]         = ImVec4(0.98, 0.26, 0.26, 0.35)
    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.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.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.ModalWindowDarkening]   = ImVec4(0.80, 0.80, 0.80, 0.35)
end
 

sssilvian

Активный
234
25
1692442867120.png

Как создать аналогичный textdraw на экране (сервер samp textdraw), который показывает имя игрока (вас) и ID, разделенные скобками?
 
Последнее редактирование:
  • Ха-ха
Реакции: Sadow

Dewize

Известный
437
88

solid - тип иконок, так же есть thin, regular, light и duotone в чём разница?

 

хромиус)

:steamhappy:
Друг
4,976
3,242

Dmitriy Makarov

25.05.2021
Проверенный
2,484
1,114
CustomNameTags.lua:545: '<eof>' expected near 'end'

Я просто взял несколько автоматических загрузок из скрипта, и он перестал работать

Python:
cript_name('Custom NameTags')
script_author('SK1DGARD')
script_description('Кастомные name tag\'y ajustes detallados')
script_version(2)
script_dependencies('Imgui', 'FontAwesome 5', 'SAMPFUNCS')

local sampev = require('lib.samp.events')

local encoding = require 'encoding'
encoding.default = 'CP1251'
local u8 = encoding.UTF8

local fa = require 'fAwesome5'
local imgui = require 'imgui'
local window_state = imgui.ImBool(false)

local memory = require 'memory'
local ffi = require('ffi')
local get_bone_pos = ffi.cast("int (__thiscall*)(void*, float*, int, bool)", 0x5E4280)


local inicfg = require'inicfg'

local ini = inicfg.load({
  NICKNAME = {
    enabled = true,
        vertical_offset = 16,
        font_name = 'Arial',
        font_size = 10,
    font_flag = 13,
    opacity = 255,
    display_afk = true
  },
  HEALTH_BAR = {
    enabled = true,
    size_x = 80,
        size_y = 10,
        border_size = 1,
        main_color = 0xFFFF0000,
        border_color = 0xFF000000,
        background_color = 0x68000000
  },
  ARMOR_BAR = {
    enabled = true,
    indent = 3,
        size_x = 80,
        size_y = 10,
        border_size = 1,
        main_color = 0xFFFFFFFF,
        border_color = 0xFF000000,
        background_color = 0x68000000
  },
  HEALTH_COUNT = {
    enabled = true,
    font_name = 'Arial',
        font_size = 7,
        font_flag = 5,
        font_color = 0xFFFFFFFF
  },
  ARMOR_COUNT = {
    enabled = true,
    font_name = 'Arial',
        font_size = 7,
        font_flag = 5,
        font_color = 0xFFFFFFFF
  },
  CHAT_BUBBLE = {
    enabled = true,
    font_name = 'Arial',
        font_size = 7,
        font_flag = 5,
    opacity = 255,
    max_symbols = 15,
    indent = 10,
    line_offset = 2
  },
  GENERAL = {
    on = true,
    vertical_indent = 0.3
  }
}, 'Custom NameTags\\Custom NameTags.ini')

local nick_buffer = imgui.ImBuffer(256)                  --IMGUI FONT BUFFERS
local hp_buffer = imgui.ImBuffer(256)                    --IMGUI FONT BUFFERS
local armor_buffer = imgui.ImBuffer(256)                 --IMGUI FONT BUFFERS
local bubble_buffer = imgui.ImBuffer(256)                --IMGUI FONT BUFFERS

local nick_font, hp_font, armor_font, bubble_font = nil  --FONTS

local current_table = 1                                  --SELECTED IMGUI TABLE

local nt_drawdist = 40                                   --NT DRAW DISTANCE

local bubble_pool = {}                                   -- ['player_id'] = text, color, remove_time, distance

function main()
  if not doesDirectoryExist('moonloader\\config') then createDirectory('moonloader\\config') end
    if not doesDirectoryExist('moonloader\\config\\Custom NameTags') then createDirectory('moonloader\\config\\Custom NameTags') end
    if not doesFileExist('Custom NameTags\\Custom NameTags.ini') then
        if not inicfg.save(ini, 'Custom NameTags\\Custom NameTags.ini') then sampAddChatMessage('{FB4343}[Custom NameTags]{FFFFFF}: El script no puede crear el archivo de configuracion. :(', 0xFFFFFF) end
    end
   
  while not isSampAvailable() do wait(0) end

  sampAddChatMessage('{FB4343}[Custom NameTags]{FFFFFF}: El guion esta activado. Activacion: {FB4343}/cusnt', -1)

  while not isCharOnScreen(PLAYER_PED) do wait(0) end

  local pStSet = sampGetServerSettingsPtr()
  memory.setint8(pStSet + 56, ini.GENERAL.on and 0 or 1) --DISABLE NT
  nt_drawdist = memory.getfloat(pStSet + 39)             --GET NT DRAWDIST
  nt_drawdist = nt_drawdist * nt_drawdist - 1            --GET NT SQUARED
  to_imgui()
  load_fonts()
 
  sampRegisterChatCommand('cusnt', function() window_state.v = not window_state.v end)

  while true do wait(0)

    if ini.GENERAL.on then
      local ped_pool = getAllChars()
      local cam_x, cam_y, cam_z = getActiveCameraCoordinates()
      for _, ped in pairs(ped_pool) do
        if ped ~= PLAYER_PED and isCharOnScreen(ped) then
          local x, y, z = get_bodypart_coordinates(ped, 5)
         
          local alive, player_id = sampGetPlayerIdByCharHandle(ped)
         
          if isLineOfSightClear(cam_x, cam_y, cam_z, x, y, z, true, false, false, true, false) and alive and get_dist_squared(x, y, z, cam_x, cam_y, cam_z) < nt_drawdist and is_nt_visible(player_id) then
            z = z + ini.GENERAL.vertical_indent.v

            local hp = limit_input(sampGetPlayerHealth(player_id), 0, 100)
                      local armor = sampGetPlayerArmor(player_id)
           
            local pl_x, pl_y, pl_z = getCharCoordinates(PLAYER_PED)
            local distance_sq = get_dist_squared(pl_x, pl_y, pl_z, x, y, z)

            local screen_x, screen_y = convert3DCoordsToScreen(x, y, z)
            draw_nt(ped, player_id, screen_x, screen_y, hp, armor, distance_sq, ini.NICKNAME.enabled.v, ini.HEALTH_BAR.enabled.v, ini.ARMOR_BAR.enabled.v, ini.HEALTH_COUNT.enabled.v, ini.ARMOR_COUNT.enabled.v, ini.CHAT_BUBBLE.enabled.v)
          end
        end
      end
    end

    imgui.Process = window_state.v
  end
end

function onScriptTerminate(script, _)
  if script == thisScript() then
    local pStSet = sampGetServerSettingsPtr()
    memory.setint8(pStSet + 56, 1)
  end
end

function sampev.onPlayerChatBubble(playerId, color, distance, duration, message)
  lua_thread.create(
    function()
      while isGamePaused() do wait(0) end

      if ini.GENERAL.on and ini.CHAT_BUBBLE.enabled.v and playerId ~= nil then
        local var = {
          ['text'] = message,
          ['color'] = rgba_to_argb(color),
          ['remove_time'] = os.time() + duration / 1000.0,
          ['distance'] = distance * distance
        }
        table.insert(bubble_pool, playerId, var)
      end
    end)
  return false
end

function sampev.onPlayerQuit(playerId, _)
  if bubble_pool[playerId] ~= nil then table.remove(bubble_pool, playerId) end
end

local fa_font = nil
local fa_glyph_ranges = imgui.ImGlyphRanges({ fa.min_range, fa.max_range })

function imgui.BeforeDrawFrame()
  if fa_font == nil then
    local font_config = imgui.ImFontConfig()
    font_config.MergeMode = true
        font_config.SizePixels = 15.0;
        font_config.GlyphExtraSpacing.x = 0.1
    fa_font = imgui.GetIO().Fonts:AddFontFromFileTTF('moonloader\\config\\Custom NameTags\\fa5.ttf', font_config.SizePixels, font_config, fa_glyph_ranges)
  end
end

function imgui.OnDrawFrame()
  if window_state.v then
    imgui.SetNextWindowPos(imgui.ImVec2(imgui.GetIO().DisplaySize.x / 4, imgui.GetIO().DisplaySize.y / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(723, 420), imgui.Cond.FirstUseEver)
    apply_style()
    imgui.Begin(fa.ICON_COGS .. u8('  Custom name tags | Author: SK1DGARD'), window_state, imgui.WindowFlags.AlwaysAutoResize)
   
    imgui.BeginChild(1, imgui.ImVec2(85, 85), true)
          imgui.SetCursorPos(imgui.ImVec2(5, 5))
     
      if imgui.CustomButton(
        fa.ICON_POWER_OFF,
        ini.GENERAL.on and imgui.ImVec4(0.15, 0.59, 0.18, 0.7) or imgui.ImVec4(1, 0.19, 0.19, 0.5),
        ini.GENERAL.on and imgui.ImVec4(0.15, 0.59, 0.18, 0.5) or imgui.ImVec4(1, 0.19, 0.19, 0.3),
        ini.GENERAL.on and imgui.ImVec4(0.15, 0.59, 0.18, 0.4) or imgui.ImVec4(1, 0.19, 0.19, 0.2),
        imgui.ImVec2(75, 75)) then
       
        ini.GENERAL.on = not ini.GENERAL.on
        sampAddChatMessage(string.format('{FB4343}[Custom NameTags]{FFFFFF}: Guion %s.', ini.GENERAL.on and '{5BFF83}Encendido' or '{FB4343}Apagado'), -1)
        local pStSet = sampGetServerSettingsPtr()
        memory.setint8(pStSet + 56, ini.GENERAL.on and 0 or 1)
      end
    imgui.EndChild()

    imgui.SetCursorPosY(112)

    imgui.BeginChild(2, imgui.ImVec2(85, 313), true)
      imgui.SetCursorPos(imgui.ImVec2(5, 5))

          if imgui.CustomButton(
        fa.ICON_SAVE,
        imgui.ImVec4(0.16, 0.16, 0.16, 0.9),
        imgui.ImVec4(0.40, 0.12, 0.12, 1),
        imgui.ImVec4(0.30, 0.08, 0.08, 1),
        imgui.ImVec2(75, 75)) then

        from_imgui()
        if inicfg.save(ini, 'Custom NameTags\\Custom NameTags.ini') then
          sampAddChatMessage('{FB4343}[Custom NameTags]{FFFFFF}: ajustes correctamente {5BFF83}guardados.', -1)
        else
          sampAddChatMessage('{FB4343}[Custom NameTags]{FFFFFF}: La configuracion no se guarda, no se puede hacer nada{FB4343} :(', -1)
        end
        to_imgui()
      end
     
      imgui.SetCursorPos(imgui.ImVec2(5, 81))

          if imgui.CustomButton(
        fa.ICON_REDO_ALT,
        imgui.ImVec4(0.16, 0.16, 0.16, 0.9),
        imgui.ImVec4(0.40, 0.12, 0.12, 1),
        imgui.ImVec4(0.30, 0.08, 0.08, 1),
        imgui.ImVec2(75, 75)) then

        ini = {
          NICKNAME = {
            enabled = true,
            vertical_offset = 16,
            font_name = 'Arial',
            font_size = 10,
            font_flag = 13,
            opacity = 255,
            display_afk = true
          },
          HEALTH_BAR = {
            enabled = true,
            size_x = 80,
            size_y = 10,
            border_size = 1,
            main_color = 0xFFFF0000,
            border_color = 0xFF000000,
            background_color = 0x68000000
          },
          ARMOR_BAR = {
            enabled = true,
            indent = 3,
            size_x = 80,
            size_y = 10,
            border_size = 1,
            main_color = 0xFFFFFFFF,
            border_color = 0xFF000000,
            background_color = 0x68000000
          },
          HEALTH_COUNT = {
            enabled = true,
            font_name = 'Arial',
            font_size = 7,
            font_flag = 5,
            font_color = 0xFFFFFFFF
          },
          ARMOR_COUNT = {
            enabled = true,
            font_name = 'Arial',
            font_size = 7,
            font_flag = 5,
            font_color = 0xFFFFFFFF
          },
          CHAT_BUBBLE = {
            enabled = true,
            font_name = 'Arial',
            font_size = 7,
            font_flag = 5,
            opacity = 255,
            max_symbols = 15,
            indent = 10,
            line_offset = 2
          },
          GENERAL = {
            on = true,
            vertical_indent = 0.3
          }
        }
        to_imgui()
        load_fonts()
        sampAddChatMessage('{FB4343}[Custom Nametags]{FFFFFF}: reiniciar la configuracion', -1)
      end

      imgui.SetCursorPos(imgui.ImVec2(5, 157))

      end

      imgui.SetCursorPos(imgui.ImVec2(5, 233))

      if imgui.CustomButton(
        fa.ICON_PAPER_PLANE,
        imgui.ImVec4(0.207, 0.674, 0.878, 0.7),
        imgui.ImVec4(0.207, 0.674, 0.878, 0.5),
        imgui.ImVec4(0.207, 0.674, 0.878, 0.4),
        imgui.ImVec2(75, 75)) then

        os.execute('explorer "hhhhh"')
      end
     
    imgui.EndChild()
   
    imgui.SetCursorPos(imgui.ImVec2(92, 28))

    imgui.BeginChild(3, imgui.ImVec2(615, 85), true)
     
      imgui.SetCursorPos(imgui.ImVec2(5,5))
      if imgui.CustomButton(fa.ICON_MALE .. '  Nombre',
        current_table == 1 and imgui.ImVec4(0.56, 0.16, 0.16, 1) or imgui.ImVec4(0.16, 0.16, 0.16, 0.9),
        imgui.ImVec4(0.40, 0.12, 0.12, 1),
        imgui.ImVec4(0.30, 0.08, 0.08, 1),
        imgui.ImVec2(100, 75)) then
       
        current_table = 1
      end

      imgui.SetCursorPos(imgui.ImVec2(106, 5))
     
      if imgui.CustomButton(fa.ICON_HEART .. '  Barra vida',
        current_table == 2 and imgui.ImVec4(0.56, 0.16, 0.16, 1) or imgui.ImVec4(0.16, 0.16, 0.16, 0.9),
        imgui.ImVec4(0.40, 0.12, 0.12, 1),
        imgui.ImVec4(0.30, 0.08, 0.08, 1),
        imgui.ImVec2(100, 75)) then
     
        current_table = 2
      end

      imgui.SetCursorPos(imgui.ImVec2(207, 5))

      if imgui.CustomButton(fa.ICON_SHIELD_ALT .. '  Barra chaleco',
        current_table == 3 and imgui.ImVec4(0.56, 0.16, 0.16, 1) or imgui.ImVec4(0.16, 0.16, 0.16, 0.9),
        imgui.ImVec4(0.40, 0.12, 0.12, 1),
        imgui.ImVec4(0.30, 0.08, 0.08, 1),
        imgui.ImVec2(100, 75)) then
     
        current_table = 3
      end

      imgui.SetCursorPos(imgui.ImVec2(308, 5))

      if imgui.CustomButton(fa.ICON_HEARTBEAT .. '  Status vida',
        current_table == 4 and imgui.ImVec4(0.56, 0.16, 0.16, 1) or imgui.ImVec4(0.16, 0.16, 0.16, 0.9),
        imgui.ImVec4(0.40, 0.12, 0.12, 1),
        imgui.ImVec4(0.30, 0.08, 0.08, 1),
        imgui.ImVec2(100, 75)) then
     
        current_table = 4
      end

      imgui.SetCursorPos(imgui.ImVec2(409, 5))

      if imgui.CustomButton(fa.ICON_SHIELD_ALT .. '  Status chaleco',
        current_table == 5 and imgui.ImVec4(0.56, 0.16, 0.16, 1) or imgui.ImVec4(0.16, 0.16, 0.16, 0.9),
        imgui.ImVec4(0.40, 0.12, 0.12, 1),
        imgui.ImVec4(0.30, 0.08, 0.08, 1),
        imgui.ImVec2(100, 75)) then
     
        current_table = 5
      end
      imgui.SetCursorPos(imgui.ImVec2(510, 5))
 
      if imgui.CustomButton(fa.ICON_PENCIL_ALT .. '  Burbuja chat',
        current_table == 6 and imgui.ImVec4(0.56, 0.16, 0.16, 1) or imgui.ImVec4(0.16, 0.16, 0.16, 0.9),
        imgui.ImVec4(0.40, 0.12, 0.12, 1),
        imgui.ImVec4(0.30, 0.08, 0.08, 1),
        imgui.ImVec2(100, 75)) then
     
        current_table = 6
      end
    imgui.EndChild()

    imgui.SetCursorPos(imgui.ImVec2(92, 112))

    imgui.BeginChild(4, imgui.ImVec2(615, 276), true)
      if current_table == 1 then
        imgui.PushItemWidth(300)
        imgui.Checkbox('Draw player nicknames##nick', ini.NICKNAME.enabled)

        imgui.InputText('##font_nick', nick_buffer)

        imgui.SameLine()
        imgui.SetCursorPosX(312)

        if imgui.Button(fa.ICON_CHECK .. ' Confirm##nick', imgui.ImVec2(94, 20)) then
          ini.NICKNAME.font_name = u8:decode(nick_buffer.v)
          nick_font = renderCreateFont(ini.NICKNAME.font_name, ini.NICKNAME.font_size.v, ini.NICKNAME.font_flag.v)
        end

        imgui.SameLine()
        imgui.SetCursorPosX(412)

        imgui.Text(fa.ICON_FONT .. u8(string.format('  Font Name (%s)', ini.NICKNAME.font_name)))

        if imgui.InputInt(fa.ICON_TEXT_WIDTH .. "  Font size##nick", ini.NICKNAME.font_size) then
          ini.NICKNAME.font_size.v = limit_input(ini.NICKNAME.font_size.v, 1, 145)
          nick_font = renderCreateFont(ini.NICKNAME.font_name, ini.NICKNAME.font_size.v, ini.NICKNAME.font_flag.v)
        end

        if imgui.InputInt(fa.ICON_FLAG .. "  Font flag##nick", ini.NICKNAME.font_flag) then
          ini.NICKNAME.font_flag.v = limit_input(ini.NICKNAME.font_flag.v, 0, 600)
          nick_font = renderCreateFont(ini.NICKNAME.font_name, ini.NICKNAME.font_size.v, ini.NICKNAME.font_flag.v)
        end

        imgui.SliderInt(fa.ICON_ARROW_UP .. '  Nickname offset by Y axis##nick', ini.NICKNAME.vertical_offset, -100, 100)

        imgui.SliderInt(fa.ICON_MOON .. '  Nickname color opacity##nick', ini.NICKNAME.opacity, 0, 255)
       
        imgui.Checkbox('Display indicator if player is Paused', ini.NICKNAME.display_afk)
        imgui.PopItemWidth()
      end
      if current_table == 2 then
        imgui.PushItemWidth(460)
        imgui.Checkbox('Display player health bar##hpbar', ini.HEALTH_BAR.enabled)
        imgui.SliderInt(fa.ICON_SLIDERS_H .. ' Health bar width##hpbar', ini.HEALTH_BAR.size_x, 0, 400)
        imgui.SliderInt(fa.ICON_SLIDERS_H .. ' Health bar height##hpbar', ini.HEALTH_BAR.size_y, 0, 400)
        imgui.SliderInt(fa.ICON_SLIDERS_H .. ' Border thickness##hpbar', ini.HEALTH_BAR.border_size, 0, 60)
        imgui.ColorEdit4(fa.ICON_SPINNER .. "  Main color##hpbar", ini.HEALTH_BAR.main_color)
        imgui.ColorEdit4(fa.ICON_SPINNER .. "  Background color##hpbar", ini.HEALTH_BAR.background_color)
        imgui.ColorEdit4(fa.ICON_SPINNER .. "  Border color##hpbar", ini.HEALTH_BAR.border_color)
        imgui.PopItemWidth()
      end
      if current_table == 3 then
        imgui.PushItemWidth(460)
        imgui.Checkbox('Display player armor bar##armor', ini.ARMOR_BAR.enabled)
        imgui.SliderInt(fa.ICON_SLIDERS_H .. ' Armor bar width##armor', ini.ARMOR_BAR.size_x, 0, 400)
        imgui.SliderInt(fa.ICON_SLIDERS_H .. ' armor bar height##armor', ini.ARMOR_BAR.size_y, 0, 400)
        imgui.SliderInt(fa.ICON_SLIDERS_H .. ' Border thickness##armor', ini.ARMOR_BAR.border_size, 0, 60)
        imgui.ColorEdit4(fa.ICON_SPINNER .. "  Main color##armor", ini.ARMOR_BAR.main_color)
        imgui.ColorEdit4(fa.ICON_SPINNER .. "  Background color##armor", ini.ARMOR_BAR.background_color)
        imgui.ColorEdit4(fa.ICON_SPINNER .. "  Border color##armor", ini.ARMOR_BAR.border_color)
        imgui.SliderInt(fa.ICON_SLIDERS_H .. ' Armor vertical offset##armor', ini.ARMOR_BAR.indent, 0, 200)
        imgui.PopItemWidth()
      end
      if current_table == 4 then
        imgui.PushItemWidth(300)

        imgui.Checkbox('Draw player health count##hpcount', ini.HEALTH_COUNT.enabled)

        imgui.ColorEdit4(fa.ICON_SPINNER .. ' Font color##hpcount', ini.HEALTH_COUNT.font_color)

        imgui.PopItemWidth()
      end
      if current_table == 5 then
        imgui.PushItemWidth(300)
 
        imgui.Checkbox('Draw player armor count##armorcount', ini.ARMOR_COUNT.enabled)
 
        imgui.InputText('##font_armor', armor_buffer)
        imgui.SameLine()
        imgui.SetCursorPosX(312)
     
        if imgui.Button(fa.ICON_CHECK .. ' Confirm##armorcount', imgui.ImVec2(94, 20)) then
          ini.ARMOR_COUNT.font_name = u8:decode(armor_buffer.v)
          armor_font = renderCreateFont(ini.ARMOR_COUNT.font_name, ini.ARMOR_COUNT.font_size.v, ini.ARMOR_COUNT.font_flag.v)
        end
 
        imgui.SameLine()
        imgui.SetCursorPosX(412)
        imgui.Text(fa.ICON_FONT .. u8(string.format('  Font Name (%s)', ini.ARMOR_COUNT.font_name)))
 
        if imgui.InputInt(fa.ICON_TEXT_WIDTH .. "  Font size##armorcount", ini.ARMOR_COUNT.font_size) then
          ini.ARMOR_COUNT.font_size.v = limit_input(ini.ARMOR_COUNT.font_size.v, 1, 145)
          armor_font = renderCreateFont(ini.ARMOR_COUNT.font_name, ini.ARMOR_COUNT.font_size.v, ini.ARMOR_COUNT.font_flag.v)
        end
 
        if imgui.InputInt(fa.ICON_FLAG .. "  Font flag##armorcount", ini.ARMOR_COUNT.font_flag) then
          ini.ARMOR_COUNT.font_flag.v = limit_input(ini.ARMOR_COUNT.font_flag.v, 0, 600)
          armor_font = renderCreateFont(ini.ARMOR_COUNT.font_name, ini.ARMOR_COUNT.font_size.v, ini.ARMOR_COUNT.font_flag.v)
        end
 
        imgui.ColorEdit4(fa.ICON_SPINNER .. ' Font color##armorcount', ini.ARMOR_COUNT.font_color)
         
        imgui.PopItemWidth()
      end
      if current_table == 6 then
        imgui.PushItemWidth(300)
 
        imgui.Checkbox('Draw player chat bubble##chatbubble', ini.CHAT_BUBBLE.enabled)
 
        imgui.InputText('##font_chatbubble', bubble_buffer)
        imgui.SameLine()
        imgui.SetCursorPosX(312)
     
        if imgui.Button(fa.ICON_CHECK .. ' Confirm##chatbubble', imgui.ImVec2(94, 20)) then
          ini.CHAT_BUBBLE.font_name = u8:decode(bubble_buffer.v)
          bubble_font = renderCreateFont(ini.CHAT_BUBBLE.font_name, ini.CHAT_BUBBLE.font_size.v, ini.CHAT_BUBBLE.font_flag.v)
        end
 
        imgui.SameLine()
        imgui.SetCursorPosX(412)
        imgui.Text(fa.ICON_FONT .. u8(string.format('  Font Name (%s)', ini.CHAT_BUBBLE.font_name)))
 
        if imgui.InputInt(fa.ICON_TEXT_WIDTH .. "  Font size##chatbubble", ini.CHAT_BUBBLE.font_size) then
          ini.CHAT_BUBBLE.font_size.v = limit_input(ini.CHAT_BUBBLE.font_size.v, 1, 145)
          bubble_font = renderCreateFont(ini.CHAT_BUBBLE.font_name, ini.CHAT_BUBBLE.font_size.v, ini.CHAT_BUBBLE.font_flag.v)
        end
 
        if imgui.InputInt(fa.ICON_FLAG .. "  Font flag##chatbubble", ini.CHAT_BUBBLE.font_flag) then
          ini.CHAT_BUBBLE.font_flag.v = limit_input(ini.CHAT_BUBBLE.font_flag.v, 0, 600)
          bubble_font = renderCreateFont(ini.CHAT_BUBBLE.font_name, ini.CHAT_BUBBLE.font_size.v, ini.CHAT_BUBBLE.font_flag.v)
        end
        imgui.SliderInt(fa.ICON_SPINNER .. ' Chat bubble text opacity', ini.CHAT_BUBBLE.opacity, 0, 255)
        imgui.SliderInt(fa.ICON_ARROW_UP .. ' Chat bubble offset by Y axis', ini.CHAT_BUBBLE.indent, 0, 200)
        imgui.SliderInt(fa.ICON_SLIDERS_H .. ' Offset between lines', ini.CHAT_BUBBLE.line_offset, 0, 200)
        if imgui.InputInt(fa.ICON_FONT .. ' Maximal symbols in chat bubble line', ini.CHAT_BUBBLE.max_symbols) then
          ini.CHAT_BUBBLE.max_symbols.v = limit_input(ini.CHAT_BUBBLE.max_symbols.v, 1, 500)
        end
        imgui.PopItemWidth()
      end
    imgui.EndChild()

    imgui.SetCursorPos(imgui.ImVec2(92, 387))

    imgui.BeginChild(5, imgui.ImVec2(615, 38), true)
      imgui.SetCursorPos(imgui.ImVec2(10, 10))
      imgui.PushItemWidth(430)
      imgui.SliderFloat(fa.ICON_COGS .. '  NameTag vertical offset', ini.GENERAL.vertical_indent, -2, 2)
      imgui.PopItemWidth()
    imgui.EndChild()
    imgui.End()
  end
end

function draw_nt(ped, player_id, screen_x, screen_y, hp, armor, distance_sq, draw_nick, draw_health_bar, draw_armor_bar, draw_health_count, draw_armor_count, draw_chat_bubble)
  if draw_health_bar then
    renderDrawBoxWithBorder(
      screen_x - ini.HEALTH_BAR.size_x.v / 2,
      screen_y - ini.HEALTH_BAR.size_y.v / 2,
      ini.HEALTH_BAR.size_x.v,
      ini.HEALTH_BAR.size_y.v,
      imgui.ImColor(imgui.ImColor.FromFloat4(ini.HEALTH_BAR.background_color.v[3], ini.HEALTH_BAR.background_color.v[2], ini.HEALTH_BAR.background_color.v[1], ini.HEALTH_BAR.background_color.v[4]):GetVec4()):GetU32(),
      ini.HEALTH_BAR.border_size.v,
      imgui.ImColor(imgui.ImColor.FromFloat4(ini.HEALTH_BAR.border_color.v[3], ini.HEALTH_BAR.border_color.v[2], ini.HEALTH_BAR.border_color.v[1], ini.HEALTH_BAR.border_color.v[4]):GetVec4()):GetU32())
    renderDrawBox(
      screen_x - ini.HEALTH_BAR.size_x.v / 2 + ini.HEALTH_BAR.border_size.v,
      screen_y - ini.HEALTH_BAR.size_y.v / 2 + ini.HEALTH_BAR.border_size.v,
      (ini.HEALTH_BAR.size_x.v - ini.HEALTH_BAR.border_size.v * 2) * hp / 100.0,
      ini.HEALTH_BAR.size_y.v - ini.HEALTH_BAR.border_size.v * 2,
      imgui.ImColor(imgui.ImColor.FromFloat4(ini.HEALTH_BAR.main_color.v[3], ini.HEALTH_BAR.main_color.v[2], ini.HEALTH_BAR.main_color.v[1], ini.HEALTH_BAR.main_color.v[4]):GetVec4()):GetU32())
  end

  if draw_health_count then
        renderFontDrawText(
            hp_font,
            hp,
            screen_x - renderGetFontDrawTextLength(hp_font, hp) / 2,
            screen_y - renderGetFontDrawHeight(hp_font) / 2,
            imgui.ImColor(imgui.ImColor.FromFloat4(ini.HEALTH_COUNT.font_color.v[3], ini.HEALTH_COUNT.font_color.v[2], ini.HEALTH_COUNT.font_color.v[1], ini.HEALTH_COUNT.font_color.v[4]):GetVec4()):GetU32())
  end
 
  if armor > 0 then
    screen_y = screen_y - ini.HEALTH_BAR.size_y.v / 2 - ini.ARMOR_BAR.indent.v - ini.ARMOR_BAR.size_y.v

    if draw_armor_bar then
      renderDrawBoxWithBorder(
        screen_x - ini.ARMOR_BAR.size_x.v / 2,
        screen_y,
        ini.ARMOR_BAR.size_x.v,
        ini.ARMOR_BAR.size_y.v,
        imgui.ImColor(imgui.ImColor.FromFloat4(ini.ARMOR_BAR.background_color.v[3], ini.ARMOR_BAR.background_color.v[2], ini.ARMOR_BAR.background_color.v[1], ini.ARMOR_BAR.background_color.v[4]):GetVec4()):GetU32(),
        ini.ARMOR_BAR.border_size.v,
        imgui.ImColor(imgui.ImColor.FromFloat4(ini.ARMOR_BAR.border_color.v[3], ini.ARMOR_BAR.border_color.v[2], ini.ARMOR_BAR.border_color.v[1], ini.ARMOR_BAR.border_color.v[4]):GetVec4()):GetU32())
      renderDrawBox(
        screen_x - ini.ARMOR_BAR.size_x.v / 2 + ini.ARMOR_BAR.border_size.v,
        screen_y + ini.ARMOR_BAR.border_size.v,
        (ini.ARMOR_BAR.size_x.v - ini.ARMOR_BAR.border_size.v * 2) * armor / 100.0,
        ini.ARMOR_BAR.size_y.v - ini.ARMOR_BAR.border_size.v * 2,
        imgui.ImColor(imgui.ImColor.FromFloat4(ini.ARMOR_BAR.main_color.v[3], ini.ARMOR_BAR.main_color.v[2], ini.ARMOR_BAR.main_color.v[1], ini.ARMOR_BAR.main_color.v[4]):GetVec4()):GetU32())
    end

    if draw_armor_count then
      renderFontDrawText(
        armor_font,
        armor,
        screen_x - renderGetFontDrawTextLength(armor_font, armor) / 2,
        screen_y + (ini.ARMOR_BAR.size_y.v / 2 - renderGetFontDrawHeight(armor_font) / 2),
        imgui.ImColor(imgui.ImColor.FromFloat4(ini.ARMOR_COUNT.font_color.v[3], ini.ARMOR_COUNT.font_color.v[2], ini.ARMOR_COUNT.font_color.v[1], ini.ARMOR_COUNT.font_color.v[4]):GetVec4()):GetU32())
    end
  end
 
  if draw_nick then
    screen_y = screen_y - ini.NICKNAME.vertical_offset.v - renderGetFontDrawHeight(nick_font) / 2
    local ped_nick = sampGetPlayerNickname(player_id)
    ped_nick = string.format('%s[%d]%s', ped_nick, player_id, (ini.NICKNAME.display_afk.v and sampIsPlayerPaused(player_id)) and ' {FFFFFF}<AFK>' or '')
    local clr = argb_to_rgb(sampGetPlayerColor(player_id), ini.NICKNAME.opacity.v)
    renderFontDrawText(
      nick_font,
      ped_nick,
      screen_x - renderGetFontDrawTextLength(nick_font, ped_nick) / 2,
      screen_y,
      clr)
  end

  if draw_chat_bubble and bubble_pool[player_id] ~= nil and distance_sq < bubble_pool[player_id].distance then
    if os.time() < bubble_pool[player_id].remove_time then
    render_text_wrapped(
      bubble_font,
      screen_x,
      screen_y - ini.CHAT_BUBBLE.indent.v,
      bubble_pool[player_id].text,
      bubble_pool[player_id].color,
      ini.CHAT_BUBBLE.max_symbols.v,
      ini.CHAT_BUBBLE.line_offset.v)
    else
      table.remove(bubble_pool, player_id)
    end
  end
end

function render_text_wrapped(font, x, y, text, color, max_symbols, line_offset)
  local str_list = {}
  local last_str = ''
  for i = 1, #text do
    if #last_str == max_symbols then
      table.insert(str_list, last_str)
      last_str = ''
    end
    last_str = last_str .. string.sub(text, i, i)
  end
  if #last_str > 0 then table.insert(str_list, last_str) end
  for i = 1, #str_list do
    renderFontDrawText(
      font,
      str_list[i],
      x - renderGetFontDrawTextLength(font, str_list[i]) / 2,
      y - renderGetFontDrawHeight(font) * (#str_list - i ) - line_offset * (#str_list - i - 1),
      color)
  end
end

function get_dist_squared(x1, y1, z1, x2, y2, z2)
  return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2)
end

function limit_input(var, min, max)
    if var < min then var = min end
    if max < var then    var = max end
    return var
end

function rgba_to_argb(rgba)
  local r, g, b, a = hex_to_argb(rgba)
  return argb_to_hex(ini.CHAT_BUBBLE.opacity.v, r, g, b)
end

function argb_to_rgb(argb, new_a)
  local a, r, g, b = hex_to_argb(argb)
    return argb_to_hex(new_a, r, g, b)
end

function argb_to_hex(a, r, g, b)
  local argb = b
  argb = bit.bor(argb, bit.lshift(g, 8))
  argb = bit.bor(argb, bit.lshift(r, 16))
  argb = bit.bor(argb, bit.lshift(a, 24))
  return argb
end

function hex_to_argb(hex)
  return
    bit.band(bit.rshift(hex, 24), 255),
    bit.band(bit.rshift(hex, 16), 255),
    bit.band(bit.rshift(hex, 8), 255),
    bit.band(hex, 255)
end

function is_nt_visible(id)
  local StructPtr = readMemory(sampGetPlayerStructPtr(id), 4, true)
  local Element = getStructElement(StructPtr, 179, 2, false)
  if Element == 0 then return false else return true end
end

function get_bodypart_coordinates(handle, id)
    if doesCharExist(handle) then
        local pedptr = getCharPointer(handle)
        local vec = ffi.new("float[3]")
        get_bone_pos(ffi.cast("void*", pedptr), vec, id, true)
        return vec[0], vec[1], vec[2]
    end
end

function imgui.CustomButton(name, color, colorHovered, colorActive, size)
  local clr = imgui.Col
  imgui.PushStyleColor(clr.Button, color)
  imgui.PushStyleColor(clr.ButtonHovered, colorHovered)
  imgui.PushStyleColor(clr.ButtonActive, colorActive)
  if not size then size = imgui.ImVec2(0, 0) end
  local result = imgui.Button(name, size)
  imgui.PopStyleColor(3)
  return result
end

function load_fonts()
  nick_font = renderCreateFont(ini.NICKNAME.font_name, ini.NICKNAME.font_size.v, ini.NICKNAME.font_flag.v)
  hp_font = renderCreateFont(ini.HEALTH_COUNT.font_name, ini.HEALTH_COUNT.font_size.v, ini.HEALTH_COUNT.font_flag.v)
  armor_font = renderCreateFont(ini.ARMOR_COUNT.font_name, ini.ARMOR_COUNT.font_size.v, ini.ARMOR_COUNT.font_flag.v)
  bubble_font = renderCreateFont(ini.CHAT_BUBBLE.font_name, ini.CHAT_BUBBLE.font_size.v, ini.CHAT_BUBBLE.font_flag.v)
end

function to_imgui()
  local temp_a, temp_r, temp_g, temp_b = nil

  ini.NICKNAME.enabled = imgui.ImBool(ini.NICKNAME.enabled)
    ini.NICKNAME.vertical_offset =  imgui.ImInt(ini.NICKNAME.vertical_offset)
    --ini.NICKNAME.font_name =
    ini.NICKNAME.font_size = imgui.ImInt(ini.NICKNAME.font_size)
  ini.NICKNAME.font_flag = imgui.ImInt(ini.NICKNAME.font_flag)
  ini.NICKNAME.opacity = imgui.ImInt(ini.NICKNAME.opacity)
  ini.NICKNAME.display_afk = imgui.ImBool(ini.NICKNAME.display_afk)

  ini.HEALTH_BAR.enabled = imgui.ImBool(ini.HEALTH_BAR.enabled)
  ini.HEALTH_BAR.size_x = imgui.ImInt(ini.HEALTH_BAR.size_x)
  ini.HEALTH_BAR.size_y = imgui.ImInt(ini.HEALTH_BAR.size_y)
  ini.HEALTH_BAR.border_size = imgui.ImInt(ini.HEALTH_BAR.border_size)
  temp_a, temp_r, temp_g, temp_b = hex_to_argb(ini.HEALTH_BAR.main_color)
  ini.HEALTH_BAR.main_color = imgui.ImFloat4(imgui.ImColor(temp_r, temp_g, temp_b, temp_a):GetFloat4())
  temp_a, temp_r, temp_g, temp_b = hex_to_argb(ini.HEALTH_BAR.border_color)
  ini.HEALTH_BAR.border_color = imgui.ImFloat4(imgui.ImColor(temp_r, temp_g, temp_b, temp_a):GetFloat4())
  temp_a, temp_r, temp_g, temp_b = hex_to_argb(ini.HEALTH_BAR.background_color)
  ini.HEALTH_BAR.background_color = imgui.ImFloat4(imgui.ImColor(temp_r, temp_g, temp_b, temp_a):GetFloat4())

  ini.ARMOR_BAR.enabled = imgui.ImBool(ini.ARMOR_BAR.enabled)
  ini.ARMOR_BAR.indent = imgui.ImInt(ini.ARMOR_BAR.indent)
  ini.ARMOR_BAR.size_x = imgui.ImInt(ini.ARMOR_BAR.size_x)
  ini.ARMOR_BAR.size_y = imgui.ImInt(ini.ARMOR_BAR.size_y)
  ini.ARMOR_BAR.border_size = imgui.ImInt(ini.ARMOR_BAR.border_size)
  temp_a, temp_r, temp_g, temp_b = hex_to_argb(ini.ARMOR_BAR.main_color)
  ini.ARMOR_BAR.main_color = imgui.ImFloat4(imgui.ImColor(temp_r, temp_g, temp_b, temp_a):GetFloat4())
  temp_a, temp_r, temp_g, temp_b = hex_to_argb(ini.ARMOR_BAR.border_color)
  ini.ARMOR_BAR.border_color = imgui.ImFloat4(imgui.ImColor(temp_r, temp_g, temp_b, temp_a):GetFloat4())
  temp_a, temp_r, temp_g, temp_b = hex_to_argb(ini.ARMOR_BAR.background_color)
  ini.ARMOR_BAR.background_color = imgui.ImFloat4(imgui.ImColor(temp_r, temp_g, temp_b, temp_a):GetFloat4())

  ini.HEALTH_COUNT.enabled = imgui.ImBool(ini.HEALTH_COUNT.enabled)
  --ini.HEALTH_COUNT.font_name =
  ini.HEALTH_COUNT.font_size = imgui.ImInt(ini.HEALTH_COUNT.font_size)
  ini.HEALTH_COUNT.font_flag = imgui.ImInt(ini.HEALTH_COUNT.font_flag)
  temp_a, temp_r, temp_g, temp_b = hex_to_argb(ini.HEALTH_COUNT.font_color)
  ini.HEALTH_COUNT.font_color = imgui.ImFloat4(imgui.ImColor(temp_r, temp_g, temp_b, temp_a):GetFloat4())

  ini.ARMOR_COUNT.enabled = imgui.ImBool(ini.ARMOR_COUNT.enabled)
  --ini.ARMOR_COUNT.font_name =
  ini.ARMOR_COUNT.font_size = imgui.ImInt(ini.ARMOR_COUNT.font_size)
  ini.ARMOR_COUNT.font_flag = imgui.ImInt(ini.ARMOR_COUNT.font_flag)
  temp_a, temp_r, temp_g, temp_b = hex_to_argb(ini.ARMOR_COUNT.font_color)
  ini.ARMOR_COUNT.font_color = imgui.ImFloat4(imgui.ImColor(temp_r, temp_g, temp_b, temp_a):GetFloat4())


  ini.CHAT_BUBBLE.enabled = imgui.ImBool(ini.CHAT_BUBBLE.enabled)
  --ini.CHAT_BUBBLE.font_name =
  ini.CHAT_BUBBLE.font_size = imgui.ImInt(ini.CHAT_BUBBLE.font_size)
  ini.CHAT_BUBBLE.font_flag = imgui.ImInt(ini.CHAT_BUBBLE.font_flag)
  ini.CHAT_BUBBLE.opacity = imgui.ImInt(ini.CHAT_BUBBLE.opacity)
  ini.CHAT_BUBBLE.max_symbols = imgui.ImInt(ini.CHAT_BUBBLE.max_symbols)
  ini.CHAT_BUBBLE.indent = imgui.ImInt(ini.CHAT_BUBBLE.indent)
  ini.CHAT_BUBBLE.line_offset = imgui.ImInt(ini.CHAT_BUBBLE.line_offset)

  --ini.GENERAL.on = imgui.ImBool(ini.GENERAL.on)
  ini.GENERAL.vertical_indent = imgui.ImFloat(ini.GENERAL.vertical_indent)
end

function from_imgui()
  ini.NICKNAME.enabled = ini.NICKNAME.enabled.v
    ini.NICKNAME.vertical_offset =  ini.NICKNAME.vertical_offset.v
    ini.NICKNAME.font_size = ini.NICKNAME.font_size.v
  ini.NICKNAME.font_flag = ini.NICKNAME.font_flag.v
  ini.NICKNAME.opacity = ini.NICKNAME.opacity.v
  ini.NICKNAME.display_afk = ini.NICKNAME.display_afk.v

  ini.HEALTH_BAR.enabled = ini.HEALTH_BAR.enabled.v
  ini.HEALTH_BAR.size_x = ini.HEALTH_BAR.size_x.v
  ini.HEALTH_BAR.size_y = ini.HEALTH_BAR.size_y.v
  ini.HEALTH_BAR.border_size = ini.HEALTH_BAR.border_size.v
  ini.HEALTH_BAR.main_color = imgui.ImColor(imgui.ImColor.FromFloat4(ini.HEALTH_BAR.main_color.v[3], ini.HEALTH_BAR.main_color.v[2], ini.HEALTH_BAR.main_color.v[1], ini.HEALTH_BAR.main_color.v[4]):GetVec4()):GetU32()
  ini.HEALTH_BAR.border_color = imgui.ImColor(imgui.ImColor.FromFloat4(ini.HEALTH_BAR.border_color.v[3], ini.HEALTH_BAR.border_color.v[2], ini.HEALTH_BAR.border_color.v[1], ini.HEALTH_BAR.border_color.v[4]):GetVec4()):GetU32()
  ini.HEALTH_BAR.background_color = imgui.ImColor(imgui.ImColor.FromFloat4(ini.HEALTH_BAR.background_color.v[3], ini.HEALTH_BAR.background_color.v[2], ini.HEALTH_BAR.background_color.v[1], ini.HEALTH_BAR.background_color.v[4]):GetVec4()):GetU32()

  ini.ARMOR_BAR.enabled = ini.ARMOR_BAR.enabled.v
  ini.ARMOR_BAR.indent = ini.ARMOR_BAR.indent.v
  ini.ARMOR_BAR.size_x = ini.ARMOR_BAR.size_x.v
  ini.ARMOR_BAR.size_y = ini.ARMOR_BAR.size_y.v
  ini.ARMOR_BAR.border_size = ini.ARMOR_BAR.border_size.v
  ini.ARMOR_BAR.main_color = imgui.ImColor(imgui.ImColor.FromFloat4(ini.ARMOR_BAR.main_color.v[3], ini.ARMOR_BAR.main_color.v[2], ini.ARMOR_BAR.main_color.v[1], ini.ARMOR_BAR.main_color.v[4]):GetVec4()):GetU32()
  ini.ARMOR_BAR.border_color = imgui.ImColor(imgui.ImColor.FromFloat4(ini.ARMOR_BAR.border_color.v[3], ini.ARMOR_BAR.border_color.v[2], ini.ARMOR_BAR.border_color.v[1], ini.ARMOR_BAR.border_color.v[4]):GetVec4()):GetU32()
  ini.ARMOR_BAR.background_color = imgui.ImColor(imgui.ImColor.FromFloat4(ini.ARMOR_BAR.background_color.v[3], ini.ARMOR_BAR.background_color.v[2], ini.ARMOR_BAR.background_color.v[1], ini.ARMOR_BAR.background_color.v[4]):GetVec4()):GetU32()

  ini.HEALTH_COUNT.enabled = ini.HEALTH_COUNT.enabled.v
  ini.HEALTH_COUNT.font_size = ini.HEALTH_COUNT.font_size.v
  ini.HEALTH_COUNT.font_flag = ini.HEALTH_COUNT.font_flag.v
  ini.HEALTH_COUNT.font_color = imgui.ImColor(imgui.ImColor.FromFloat4(ini.HEALTH_COUNT.font_color.v[3], ini.HEALTH_COUNT.font_color.v[2], ini.HEALTH_COUNT.font_color.v[1], ini.HEALTH_COUNT.font_color.v[4]):GetVec4()):GetU32()

  ini.ARMOR_COUNT.enabled = ini.ARMOR_COUNT.enabled.v
  ini.ARMOR_COUNT.font_size = ini.ARMOR_COUNT.font_size.v
  ini.ARMOR_COUNT.font_flag = ini.ARMOR_COUNT.font_flag.v
  ini.ARMOR_COUNT.font_color = imgui.ImColor(imgui.ImColor.FromFloat4(ini.ARMOR_COUNT.font_color.v[3], ini.ARMOR_COUNT.font_color.v[2], ini.ARMOR_COUNT.font_color.v[1], ini.ARMOR_COUNT.font_color.v[4]):GetVec4()):GetU32()


  ini.CHAT_BUBBLE.enabled = ini.CHAT_BUBBLE.enabled.v
  ini.CHAT_BUBBLE.font_size = ini.CHAT_BUBBLE.font_size.v
  ini.CHAT_BUBBLE.font_flag = ini.CHAT_BUBBLE.font_flag.v
  ini.CHAT_BUBBLE.opacity = ini.CHAT_BUBBLE.opacity.v
  ini.CHAT_BUBBLE.max_symbols = ini.CHAT_BUBBLE.max_symbols.v
  ini.CHAT_BUBBLE.indent = ini.CHAT_BUBBLE.indent.v
  ini.CHAT_BUBBLE.line_offset = ini.CHAT_BUBBLE.line_offset.v

  ini.GENERAL.vertical_indent = ini.GENERAL.vertical_indent.v
end

function apply_style()
    imgui.SwitchContext()
    local ImVec4 = imgui.ImVec4
    local ImVec2 = imgui.ImVec2
    local style = imgui.GetStyle()
    style.WindowRounding = 0
    style.WindowPadding = ImVec2(8, 8)
    style.WindowTitleAlign = ImVec2(0.5, 0.5)
    style.ChildWindowRounding = 0
    style.FrameRounding = 0
    style.ItemSpacing = ImVec2(8, 4)
    style.ScrollbarSize = 10
    style.ScrollbarRounding = 3
    style.GrabMinSize = 10
    style.GrabRounding = 0
    style.Alpha = 1
    style.FramePadding = ImVec2(4, 3)
    style.ItemInnerSpacing = ImVec2(4, 4)
    style.TouchExtraPadding = ImVec2(0, 0)
    style.IndentSpacing = 21
    style.ColumnsMinSpacing = 6
    style.ButtonTextAlign = ImVec2(0.5, 0.5)
    style.DisplayWindowPadding = ImVec2(22, 22)
    style.DisplaySafeAreaPadding = ImVec2(4, 4)
    style.AntiAliasedLines = true
    style.AntiAliasedShapes = true
    style.CurveTessellationTol = 1.25
    local colors = style.Colors
    local clr = imgui.Col
    colors[clr.FrameBg]                = ImVec4(0.48, 0.16, 0.16, 0.54)
    colors[clr.FrameBgHovered]         = ImVec4(0.98, 0.26, 0.26, 0.40)
    colors[clr.FrameBgActive]          = ImVec4(0.98, 0.26, 0.26, 0.67)
    colors[clr.TitleBg]                = ImVec4(0.04, 0.04, 0.04, 1.00)
    colors[clr.TitleBgActive]          = ImVec4(0.48, 0.16, 0.16, 1.00)
    colors[clr.TitleBgCollapsed]       = ImVec4(0.00, 0.00, 0.00, 0.51)
    colors[clr.CheckMark]              = ImVec4(0.98, 0.26, 0.26, 1.00)
    colors[clr.SliderGrab]             = ImVec4(0.88, 0.26, 0.24, 1.00)
    colors[clr.SliderGrabActive]       = ImVec4(0.98, 0.26, 0.26, 1.00)
    colors[clr.Button]                 = ImVec4(0.98, 0.26, 0.26, 0.40)
    colors[clr.ButtonHovered]          = ImVec4(0.98, 0.26, 0.26, 1.00)
    colors[clr.ButtonActive]           = ImVec4(0.98, 0.06, 0.06, 1.00)
    colors[clr.Header]                 = ImVec4(0.98, 0.26, 0.26, 0.31)
    colors[clr.HeaderHovered]          = ImVec4(0.98, 0.26, 0.26, 0.80)
    colors[clr.HeaderActive]           = ImVec4(0.98, 0.26, 0.26, 1.00)
    colors[clr.Separator]              = colors[clr.Border]
    colors[clr.SeparatorHovered]       = ImVec4(0.75, 0.10, 0.10, 0.78)
    colors[clr.SeparatorActive]        = ImVec4(0.75, 0.10, 0.10, 1.00)
    colors[clr.ResizeGrip]             = ImVec4(0.98, 0.26, 0.26, 0.25)
    colors[clr.ResizeGripHovered]      = ImVec4(0.98, 0.26, 0.26, 0.67)
  colors[clr.ResizeGripActive]       = ImVec4(0.98, 0.26, 0.26, 0.95)
    colors[clr.TextSelectedBg]         = ImVec4(0.98, 0.26, 0.26, 0.35)
    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.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.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.ModalWindowDarkening]   = ImVec4(0.80, 0.80, 0.80, 0.35)
end
Кажется, "end" на 310-й строке лишний.
 

MLycoris

Режим чтения
Проверенный
1,830
1,900

solid - тип иконок, так же есть thin, regular, light и duotone в чём разница?

 

Vabots

Участник
62
0
Требуется взять ближайший пикап БЕЗ ХУКА.

Мне требуется функция, которая получит сначала пикапы в зоне стрима. А потом определит ближайший ко мне.
Я знаю, что писали на ракботе, но можно это сделать для обычной ГТАшки?
 

Akionka

akionka.lua
Проверенный
742
500
Требуется взять ближайший пикап БЕЗ ХУКА.

Мне требуется функция, которая получит сначала пикапы в зоне стрима. А потом определит ближайший ко мне.
Я знаю, что писали на ракботе, но можно это сделать для обычной ГТАшки?
хз не проверял в игре а то забанят ещё:
  local nearest = nil
  local nearest_dist = math.huge
  local x, y, z = getCharCoordinates(PLAYER_PED)
  for _, pickup in ipairs(getAllPickups()) do
    local pick_x, pick_y, pick_z = getPickupCoordinates(pickup)
    local dist = math.sqrt((x - pick_x)^2 + (y - pick_y)^2 + (z - pick_z)^2)
    if dist < nearest_dist then
      nearest = pickup
      nearest_dist = dist
    end
  end
  if nearest then
    print('nearest pickup', nearest, nearest_dist)
    sampSendPickedUpPickup(sampGetPickupSampIdByHandle(nearest))
  else
    print('no nearest pickup found')
  end
 
  • Нравится
Реакции: Vabots

tsunamiqq

Участник
429
16
Как я понимаю, если BeginPopup в for, то он работает не будет, как по другому замутить?
Lua:
        for k, v in ipairs(onlineMemb) do
            imgui.TextColoredRGB(u8(k)..'. '..(v))
            if imgui.IsItemHovered() then
                imgui.BeginTooltip()
                imgui.TextColoredRGB(u8'{00FF00}online')
                imgui.EndTooltip()
            end
            imgui.SameLine(170)
            imgui.Button(u8'Повысить')
            imgui.SameLine(240)
            imgui.Button(u8'Уволить')
            imgui.SameLine(301)
            imgui.Button(u8'Выдать выговор')
            imgui.SameLine(409)
            imgui.Button(u8'Снять выговор')
            imgui.SameLine()
            if imgui.Button(faicons('GEAR')) then
                imgui.OpenPopup(faicons('GEAR'))
            end
            if imgui.BeginPopupModal(faicons('GEAR'), _, imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoScrollbar + imgui.WindowFlags.NoResize) then
                if imgui.Button(u8'Закрыть', imgui.ImVec2(300,25)) then
                    imgui.CloseCurrentPopup()
                end
            end
        end
 

MLycoris

Режим чтения
Проверенный
1,830
1,900
Как я понимаю, если BeginPopup в for, то он работает не будет, как по другому замутить?
Lua:
        for k, v in ipairs(onlineMemb) do
            imgui.TextColoredRGB(u8(k)..'. '..(v))
            if imgui.IsItemHovered() then
                imgui.BeginTooltip()
                imgui.TextColoredRGB(u8'{00FF00}online')
                imgui.EndTooltip()
            end
            imgui.SameLine(170)
            imgui.Button(u8'Повысить')
            imgui.SameLine(240)
            imgui.Button(u8'Уволить')
            imgui.SameLine(301)
            imgui.Button(u8'Выдать выговор')
            imgui.SameLine(409)
            imgui.Button(u8'Снять выговор')
            imgui.SameLine()
            if imgui.Button(faicons('GEAR')) then
                imgui.OpenPopup(faicons('GEAR'))
            end
            if imgui.BeginPopupModal(faicons('GEAR'), _, imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoScrollbar + imgui.WindowFlags.NoResize) then
                if imgui.Button(u8'Закрыть', imgui.ImVec2(300,25)) then
                    imgui.CloseCurrentPopup()
                end
            end
        end
В название кнопок, бегинапопы и подобного добавляй ##'..k
 
  • Нравится
Реакции: tsunamiqq

alarm0

Участник
44
3
Можно ли как-то дебажить скрипт, смотреть что в нем вызывается, активные потоки и т.д.?