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

Rice.

Известный
Модератор
1,758
1,714
Lua:
openStats = true
sampSendChat('/stats')

function sampev.onShowDialog(dialogid, style, title, button1, button2, text)
    if openStats and dialogid == 1500 then
        text:match('{66FFCC}Эксперт')
    else
        thisScript():unload()
        openStats = false
        return false
   end
что не так? скрипт оффается ещё до того как игрок не зашёл на сервер
Lua:
local openStats = false

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(200) end
    
    sampAddChatMessage('Loaded!', -1)
    
    while not sampIsLocalPlayerSpawned() do wait(0) end
    wait(2000)
    
    lua_thread.create(check)
    
    while true do
    wait(0)
    end
end
    
function check()
    openStats = true
    sampSendChat('/stats')
end

function sampev.onShowDialog(dialogid, style, title, button1, button2, text)
    if openStats and dialogid == 1500 then
       text:match('{66FFCC}Эксперт')
    else
       thisScript():unload()
       openStats = false
       return false
    end
end
 

Anton Nixon

Известный
474
48
вопрос такого характера, есть такой вот код чекера

lua:
if imgui_imbool.friend_online.v then -- друзья в сети
                FriendTitle = "Друзья в сети:"
                renderFontDrawText(friendfont, FriendTitle, check_X, check_Y, 4211081215)
                local string_friend_height = renderGetFontDrawHeight(friendfont)
                local new_Y = string_friend_height + 0.5
                check_Y = check_Y - new_Y
                local last_friend_list = ""
                local count = 1
                local FriendText = ""
                for k, v in pairs(friends) do
                    friendStreamed = sampGetCharHandleBySampPlayerId(idbynick(v.nick))
                    friendPaused = sampIsPlayerPaused(idbynick(v.nick))
                    friendColor = sampGetPlayerColor(idbynick(v.nick))
                    local aa, rr, gg, bb = explode_argb(friendColor)
                    if sampIsLocalPlayerSpawned() then
                        if sampIsPlayerConnected(idbynick(v.nick)) then
                            if friendStreamed then
                                if friendPaused then
                                    friendList = string.format("{%0.2X%0.2X%0.2X}%i. %s [%i] {FF0000}[AFK] {808080}[#]", rr, gg, bb, count, v.nick, idbynick(v.nick))
                                else
                                    friendList = string.format("{%0.2X%0.2X%0.2X}%i. %s [%i] {808080}[#]", rr, gg, bb, count, v.nick, idbynick(v.nick))
                                end
                            else
                                friendList = string.format("{%0.2X%0.2X%0.2X}%i. %s [%i]", rr, gg, bb, count, v.nick, idbynick(v.nick))
                            end
                            count = count + 1
                            FriendText = string.format("%s\n", friendList)
                        end
                    end
                    local string_lead_height = renderGetFontDrawHeight(friendfont)
                    if last_friend_list ~= friendList then
                        local new_Y = string_friend_height + 0.5
                        check_Y = check_Y + new_Y
                        renderFontDrawText(friendfont, FriendText, check_X, check_Y, 4294967295)
                    end
                    last_friend_list = friendList
                end
                if FriendText:len() <= 0 then
                    FriendText = '{808080}Друзей в сети нет'
                    local new_Y = string_friend_height + 0.5
                    check_Y = check_Y + new_Y
                    renderFontDrawText(friendfont, FriendText, check_X, check_Y, 1694498815)
                end
                local string_friend_height = renderGetFontDrawHeight(friendfont)
                local new_Y = string_friend_height * 1.3
                check_Y = check_Y + new_Y
            end
Вот так это выглядит
Посмотреть вложение 117702
Все работает +- хорошо, но когда сети всего лишь один человек из списка, то ничего не отображается
Посмотреть вложение 117703
Помогите исправить, чтобы все ровно отображалось
актуально
 

Anton Nixon

Известный
474
48
Почему всегда выводится, что Игрок не в сети, хотя он в сети
lua:
if adm_command:find("/hp") then
                    adm_chat_cmd_player_id, adm_chat_cmd_player_val = string.match(adm_command, "/hp%s+(%d+)%s+(%d+)") -- hp
                    if adm_chat_cmd_player_id ~= nil then
                        local player_conn = sampIsPlayerConnected(adm_chat_cmd_player_id)
                        if player_conn then
                            adm_chat_cmd_player_name = sampGetPlayerNickname(adm_chat_cmd_player_id)
                            text = string.format("Администратор %s[%d] хочет изменить HP игроку {ffd700}%s[%d]{ffffff}.", adm_name, adm_id, adm_chat_cmd_player_name, adm_chat_cmd_player_id)
                            message(text)
                            command_from_admin_chat_status = false
                            adm_chat_cmd_tick = localClock()
                        else
                            if imgui_imbool.notf_chat.v == true then
                                command_from_admin_chat_status = false
                                adm_name = string.match(adm_name, "%a+")
                                notf_text = string.format("/a %s, игрока с ID %d нет в сети.", adm_name, adm_chat_cmd_player_id)
                                sampSendChat(notf_text)
                                --sampAddChatMessage(adm_chat_cmd_player_val, -1)
                            end
                        end
                    end
                end
 

MAHEKEH

Известный
2,002
503
как задать шрифт для текста окна имгуи?
еще интересует как придать обводку окну как на картинке

2021-10-13_113526.jpg
 

savasmentukas

Новичок
16
1
Привет, видите ли, в окне чата я получаю процент до того, сколько времени ждать, когда 3dtext будет таким же, как в окне чата, я хочу автоматически нажимать "Y", как это сделать?
проценты могут быть разными, не обязательно "45"
 
Последнее редактирование:

Rice.

Известный
Модератор
1,758
1,714
как задать шрифт для текста окна имгуи?
еще интересует как придать обводку окну как на картинке

Посмотреть вложение 117722
Шрифт:
Lua:
-- где-то в коде
local fa_afont = nil
function imgui.BeforeDrawFrame()
    if fa_afont == nil then
        fa_afont = imgui.GetIO().Fonts:AddFontFromFileTTF(getFolderPath(0x14) .. '\\trebucbd.ttf', 16.5, nil, imgui.GetIO().Fonts:GetGlyphRangesCyrillic()) -- 16.5 - размер стандартного шрифта для имгуи | \\trebucbd.ttf - название шрифта
    end
end
--

-- имгуи
imgui.PushFont(fa_afont)
imgui.Text('Test Text')
imgui.PopFont()

Почему всегда выводится, что Игрок не в сети, хотя он в сети
lua:
if adm_command:find("/hp") then
                    adm_chat_cmd_player_id, adm_chat_cmd_player_val = string.match(adm_command, "/hp%s+(%d+)%s+(%d+)") -- hp
                    if adm_chat_cmd_player_id ~= nil then
                        local player_conn = sampIsPlayerConnected(adm_chat_cmd_player_id)
                        if player_conn then
                            adm_chat_cmd_player_name = sampGetPlayerNickname(adm_chat_cmd_player_id)
                            text = string.format("Администратор %s[%d] хочет изменить HP игроку {ffd700}%s[%d]{ffffff}.", adm_name, adm_id, adm_chat_cmd_player_name, adm_chat_cmd_player_id)
                            message(text)
                            command_from_admin_chat_status = false
                            adm_chat_cmd_tick = localClock()
                        else
                            if imgui_imbool.notf_chat.v == true then
                                command_from_admin_chat_status = false
                                adm_name = string.match(adm_name, "%a+")
                                notf_text = string.format("/a %s, игрока с ID %d нет в сети.", adm_name, adm_chat_cmd_player_id)
                                sampSendChat(notf_text)
                                --sampAddChatMessage(adm_chat_cmd_player_val, -1)
                            end
                        end
                    end
                end
Попробуй поменять немного код:
Lua:
if sampIsPlayerConnected(tonumber(adm_chat_cmd_player_id)) then
    adm_chat_cmd_player_name = sampGetPlayerNickname(tonumber(adm_chat_cmd_player_id))
    text = string.format("Администратор %s[%d] хочет изменить HP игроку {ffd700}%s[%d]{ffffff}.", adm_name, adm_id, adm_chat_cmd_player_name, adm_chat_cmd_player_id)
    message(text)
    command_from_admin_chat_status = false
    adm_chat_cmd_tick = localClock()
else
    if imgui_imbool.notf_chat.v == true then
        command_from_admin_chat_status = false
        adm_name = string.match(adm_name, "%a+")
        notf_text = string.format("/a %s, игрока с ID %d нет в сети.", adm_name, adm_chat_cmd_player_id)
        sampSendChat(notf_text)
        --sampAddChatMessage(adm_chat_cmd_player_val, -1)
    end
end
 
Последнее редактирование:

Anton Nixon

Известный
474
48
Шрифт:
Lua:
-- где-то в коде
local fa_afont = nil
function imgui.BeforeDrawFrame()
    if fa_afont == nil then
        fa_afont = imgui.GetIO().Fonts:AddFontFromFileTTF(getFolderPath(0x14) .. '\\trebucbd.ttf', 16.5, nil, imgui.GetIO().Fonts:GetGlyphRangesCyrillic()) -- 16.5 - размер стандартного шрифта для имгуи | \\trebucbd.ttf - название шрифта
    end
end
--

-- имгуи
imgui.PushFont(fa_afont)
imgui.Text('Test Text')
imgui.PopFont()


Попробуй поменять немного код:
Lua:
if sampIsPlayerConnected(tonumber(adm_chat_cmd_player_id)) then
    adm_chat_cmd_player_name = sampGetPlayerNickname(tonumber(adm_chat_cmd_player_id))
    text = string.format("Администратор %s[%d] хочет изменить HP игроку {ffd700}%s[%d]{ffffff}.", adm_name, adm_id, adm_chat_cmd_player_name, adm_chat_cmd_player_id)
    message(text)
    command_from_admin_chat_status = false
    adm_chat_cmd_tick = localClock()
else
    if imgui_imbool.notf_chat.v == true then
        command_from_admin_chat_status = false
        adm_name = string.match(adm_name, "%a+")
        notf_text = string.format("/a %s, игрока с ID %d нет в сети.", adm_name, adm_chat_cmd_player_id)
        sampSendChat(notf_text)
        --sampAddChatMessage(adm_chat_cmd_player_val, -1)
    end
end
не помогло
 

Rice.

Известный
Модератор
1,758
1,714
а как сделать чтобы и на свой id срабатывало?
Lua:
-- wait(0)
myid = sampGetPlayerIdByCharHandle(PLAYER_PED)

-- код
if sampIsPlayerConnected(tonumber(adm_chat_cmd_player_id)) then
    adm_chat_cmd_player_name = sampGetPlayerNickname(tonumber(adm_chat_cmd_player_id))
    text = string.format("Администратор %s[%d] хочет изменить HP игроку {ffd700}%s[%d]{ffffff}.", adm_name, adm_id, adm_chat_cmd_player_name, adm_chat_cmd_player_id)
    message(text)
    command_from_admin_chat_status = false
    adm_chat_cmd_tick = localClock()
elseif tonumber(adm_chat_cmd_player_id) == tonumber(myid) then
    adm_chat_cmd_player_name = sampGetPlayerNickname(PLAYER_PED)
    text = string.format("Администратор %s[%d] хочет изменить HP игроку {ffd700}%s[%d]{ffffff}.", adm_name, adm_id, adm_chat_cmd_player_name, adm_chat_cmd_player_id)
    message(text)
    command_from_admin_chat_status = false
    adm_chat_cmd_tick = localClock()
else
    if imgui_imbool.notf_chat.v == true then
        command_from_admin_chat_status = false
        adm_name = string.match(adm_name, "%a+")
        notf_text = string.format("/a %s, игрока с ID %d нет в сети.", adm_name, adm_chat_cmd_player_id)
        sampSendChat(notf_text)
        --sampAddChatMessage(adm_chat_cmd_player_val, -1)
    end
end

а как сделать чтобы и на свой id срабатывало?
Моя ошибка.
Lua:
-- wait(0)
_, myid = sampGetPlayerIdByCharHandle(PLAYER_PED)

-- код
if sampIsPlayerConnected(tonumber(adm_chat_cmd_player_id)) then
    adm_chat_cmd_player_name = sampGetPlayerNickname(tonumber(adm_chat_cmd_player_id))
    text = string.format("Администратор %s[%d] хочет изменить HP игроку {ffd700}%s[%d]{ffffff}.", adm_name, adm_id, adm_chat_cmd_player_name, adm_chat_cmd_player_id)
    message(text)
    command_from_admin_chat_status = false
    adm_chat_cmd_tick = localClock()
elseif tonumber(adm_chat_cmd_player_id) == tonumber(myid) then
    adm_chat_cmd_player_name = sampGetPlayerNickname(myid)
    text = string.format("Администратор %s[%d] хочет изменить HP игроку {ffd700}%s[%d]{ffffff}.", adm_name, adm_id, adm_chat_cmd_player_name, adm_chat_cmd_player_id)
    message(text)
    command_from_admin_chat_status = false
    adm_chat_cmd_tick = localClock()
else
    if imgui_imbool.notf_chat.v == true then
        command_from_admin_chat_status = false
        adm_name = string.match(adm_name, "%a+")
        notf_text = string.format("/a %s, игрока с ID %d нет в сети.", adm_name, adm_chat_cmd_player_id)
        sampSendChat(notf_text)
        --sampAddChatMessage(adm_chat_cmd_player_val, -1)
    end
end
 
Последнее редактирование:
  • Нравится
Реакции: Anton Nixon

Anton Nixon

Известный
474
48
Lua:
-- wait(0)
myid = sampGetPlayerIdByCharHandle(PLAYER_PED)

-- код
if sampIsPlayerConnected(tonumber(adm_chat_cmd_player_id)) then
    adm_chat_cmd_player_name = sampGetPlayerNickname(tonumber(adm_chat_cmd_player_id))
    text = string.format("Администратор %s[%d] хочет изменить HP игроку {ffd700}%s[%d]{ffffff}.", adm_name, adm_id, adm_chat_cmd_player_name, adm_chat_cmd_player_id)
    message(text)
    command_from_admin_chat_status = false
    adm_chat_cmd_tick = localClock()
elseif tonumber(adm_chat_cmd_player_id) == tonumber(myid) then
    adm_chat_cmd_player_name = sampGetPlayerNickname(PLAYER_PED)
    text = string.format("Администратор %s[%d] хочет изменить HP игроку {ffd700}%s[%d]{ffffff}.", adm_name, adm_id, adm_chat_cmd_player_name, adm_chat_cmd_player_id)
    message(text)
    command_from_admin_chat_status = false
    adm_chat_cmd_tick = localClock()
else
    if imgui_imbool.notf_chat.v == true then
        command_from_admin_chat_status = false
        adm_name = string.match(adm_name, "%a+")
        notf_text = string.format("/a %s, игрока с ID %d нет в сети.", adm_name, adm_chat_cmd_player_id)
        sampSendChat(notf_text)
        --sampAddChatMessage(adm_chat_cmd_player_val, -1)
    end
end


Моя ошибка.
Lua:
-- wait(0)
_, myid = sampGetPlayerIdByCharHandle(PLAYER_PED)

-- код
if sampIsPlayerConnected(tonumber(adm_chat_cmd_player_id)) then
    adm_chat_cmd_player_name = sampGetPlayerNickname(tonumber(adm_chat_cmd_player_id))
    text = string.format("Администратор %s[%d] хочет изменить HP игроку {ffd700}%s[%d]{ffffff}.", adm_name, adm_id, adm_chat_cmd_player_name, adm_chat_cmd_player_id)
    message(text)
    command_from_admin_chat_status = false
    adm_chat_cmd_tick = localClock()
elseif tonumber(adm_chat_cmd_player_id) == tonumber(myid) then
    adm_chat_cmd_player_name = sampGetPlayerNickname(myid)
    text = string.format("Администратор %s[%d] хочет изменить HP игроку {ffd700}%s[%d]{ffffff}.", adm_name, adm_id, adm_chat_cmd_player_name, adm_chat_cmd_player_id)
    message(text)
    command_from_admin_chat_status = false
    adm_chat_cmd_tick = localClock()
else
    if imgui_imbool.notf_chat.v == true then
        command_from_admin_chat_status = false
        adm_name = string.match(adm_name, "%a+")
        notf_text = string.format("/a %s, игрока с ID %d нет в сети.", adm_name, adm_chat_cmd_player_id)
        sampSendChat(notf_text)
        --sampAddChatMessage(adm_chat_cmd_player_val, -1)
    end
end
а с этим поможешь?
 

chapo

tg/inst: @moujeek
Всефорумный модератор
9,238
12,672
какие адреса памяти отвечают за pagesize, timestamp, fontweight и fontface?