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

komnatq

Известный
203
91
Оно никакого эффекта не даёт....
Lua:
local CruiseSpeed = 1.0
function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand('bspeed', function(arg)
        if not arg or not tonumber(arg) then return sampAddChatMessage('Use /bspeed [speed]', 0xFF3333) end
        CruiseSpeed = tonumber(arg)
        sampAddChatMessage(string.format('CruiseSpeed set to %.3f', CruiseSpeed), 0x33ff33)
    end)
    while true do wait(0)
        if isCharInAnyBoat(PLAYER_PED) then
            local veh = storeCarCharIsInNoSave(1)
            setBoatCruiseSpeed(veh, CruiseSpeed)
            printStringNow(string.format('In boat~n~Speed: ~b~%.3f~n~~w~Limit: ~b~%.3f', getCarSpeed(veh), CruiseSpeed), 1000)
        end
    end
end
Я только на 0:50 вспомнил, что у меня есть скрипт, который отключает волны... смотри с 0:50....
Понял, буду думать костыли. Кидало в лоадинг на большой скорости, поставил фикс SAP, проблему исправляет, но на моменте ожидаемого лоадинга просто фризит скорость в 0. Итого не плывешь, а дергаешься
 

CaJlaT

07.11.2024 14:55
Модератор
2,830
2,660
Понял, буду думать костыли. Кидало в лоадинг на большой скорости, поставил фикс SAP, проблему исправляет, но на моменте ожидаемого лоадинга просто фризит скорость в 0. Итого не плывешь, а дергаешься
Тоже сталкивался с этим, ещё на аризоне при отключении волн спидер с коленом сп+ и чипом ст3 хуярит 420км и кикает
 

Strand

Участник
48
27
Нужен хук(ивент) чтобы получить новое сообщение на клиентсайде
Либо же хук(ивент), который дает срабатывает при создании скриншота
 

YarikVL

Известный
Проверенный
4,767
1,820
Нужен хук(ивент) чтобы получить новое сообщение на клиентсайде
Имеешь ввиду это: https://wiki.blast.hk/ru/moonloader/lua/sampGetChatString ?
Либо же хук(ивент), который дает срабатывает при создании скриншота
Если ты имел ввиду самповский скриншот тип F8 то вот: https://www.blast.hk/threads/69973/post-607278
 

Julimba

Участник
108
10
Здарова, возможно тупой вопрос, но..
Есть такая тема, хз как она называется, таблица, массив или что то в этом роде
Lua:
local AC2 = {
    bot1 = {
        bb1 = 'ты не бот',
        bb2 = 'ты возможно не бот',
    },
    Acc1 = {
        cc1 = '12', '13', '14', '15',
        cc2 = '(%d*)', '(%.*)',
    },
}
Как сделать чтобы в сс1 и сс2 проверялось каждое условие, типо возможно оно подойдет. И сразу просьба, объясните где это нужно будет писать, а то я в данном плане туговат.


Lua:
if text:find(AC2.Acc1.cc1) then
    local nick, hid = text:match(AC2.Acc1.cc2)

код написан чисто для примера
 

qdIbp

Автор темы
Проверенный
1,434
1,174
Здарова, возможно тупой вопрос, но..
Есть такая тема, хз как она называется, таблица, массив или что то в этом роде
Lua:
local AC2 = {
    bot1 = {
        bb1 = 'ты не бот',
        bb2 = 'ты возможно не бот',
    },
    Acc1 = {
        cc1 = '12', '13', '14', '15',
        cc2 = '(%d*)', '(%.*)',
    },
}
Как сделать чтобы в сс1 и сс2 проверялось каждое условие, типо возможно оно подойдет. И сразу просьба, объясните где это нужно будет писать, а то я в данном плане туговат.


Lua:
if text:find(AC2.Acc1.cc1) then
    local nick, hid = text:match(AC2.Acc1.cc2)

код написан чисто для примера
cc1 = {'12', '13', '14', '15'},
cc2 = {'(%d*)', '(%.*)}',
 

ChаtGPT

Активный
368
90
Возможно как-то получить экранные координаты ДРУГОГО игрока? Не меня
 
  • Грустно
Реакции: qdIbp

chapo

чопа сребдс // @moujeek
Модератор
8,861
11,547
Возможно как-то получить экранные координаты ДРУГОГО игрока? Не меня
Lua:
bool result = isCharOnScreen(Ped ped)
float positionX, float positionY, float positionZ = getCharCoordinates(Ped ped)
float wposX, float wposY = convert3DCoordsToScreen(float posX, float posY, float posZ)
 
D

deleted-user-139653

Гость
как сделать сраный checkbox, 2 часа сижу себе ломаю голову, это пиздец(соре за мат) p.s полный 0 в imgui =)

Код:
типа надо для этой функции сделать

ini.time.on - путь к true/false

if time.v then
time = sampTextdrawGetString(0)
hour, minute = time:match("~w~(%d+)~y~:~w~(%d+)")
local text = string.format("%s:%s", hour, minute)
renderFontDrawText(font, text, ini.time.x, ini.time.y, -1)
end
 

Julimba

Участник
108
10
cc1 = {'12', '13', '14', '15'},
cc2 = {'(%d*)', '(%.*)}',
[ML] (error) verytest.lua: ...ser\Desktop\maxshrinkedByKichiro\moonloader\verytest.lua:43: bad argument #1 to 'find' (string expected, got table)
stack traceback:
[C]: in function 'find'
...ser\Desktop\maxshrinkedByKichiro\moonloader\verytest.lua:43: in function 'callback'
...maxshrinkedByKichiro\moonloader\lib\samp\events\core.lua:79: in function <...maxshrinkedByKichiro\moonloader\lib\samp\events\core.lua:53>
[ML] (error) verytest.lua: Script died due to an error. (01D68364)
 

ChаtGPT

Активный
368
90
Как сделать уведомления в группу ВК через игру? Написал "/cmd hello" и это "hello" отправилось в группу ВК

как сделать сраный checkbox, 2 часа сижу себе ломаю голову, это пиздец(соре за мат) p.s полный 0 в imgui =)

Код:
типа надо для этой функции сделать

ini.time.on - путь к true/false

if time.v then
time = sampTextdrawGetString(0)
hour, minute = time:match("~w~(%d+)~y~:~w~(%d+)")
local text = string.format("%s:%s", hour, minute)
renderFontDrawText(font, text, ini.time.x, ini.time.y, -1)
end
Код:
--function imgui.onDrawFrame
checkbox = imgui.ImBool(false)

imgui.Checkbox(u8 'Checkbox', checkbox) then
 
D

deleted-user-139653

Гость
Как сделать уведомления в группу ВК через игру? Написал "/cmd hello" и это "hello" отправилось в группу ВК


Код:
--function imgui.onDrawFrame
checkbox = imgui.ImBool(false)

imgui.Checkbox(u8 'Checkbox', checkbox) then
та я делал так, вылазит ошибка
stack index 2, expected userdata, received boolean: value is not a valid userdata (bad argument into 'bool(const char*, ImValue<bool>*)')
 
D

deleted-user-139653

Гость
Код:
local fa = require 'fAwesome5'
local imgui = require("imgui")
local inicfg = require("inicfg")
local encoding = require ("encoding")
encoding.default = ("CP1251")
local u8 = encoding.UTF8


local path = getWorkingDirectory() .. "\\config\\Hud.ini"
local ini = inicfg.load({
    time = {
        on = true,
        x = 0,
        y = 0
      }
}, path)

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
        fa_font = imgui.GetIO().Fonts:AddFontFromFileTTF('moonloader/resource/fonts/fa-solid-900.ttf', 13.0, font_config, fa_glyph_ranges)
    end
end

local main_window_state = imgui.ImBool(false)

local menu = {
   true,
   false,
   false,
   false,
   false
}

function main()
    while not isSampAvailable() do wait(100) end
    
    local font = renderCreateFont(Arial, 10, 13)
    
    sampAddChatMessage('Скрипт успешно загружен. | Меню: F2 |', -1)

    while true do
        wait(0)   
        if isKeyJustPressed(113) then
            main_window_state.v  = not main_window_state.v
        end
        imgui.Process = main_window_state.v
        
        time = sampTextdrawGetString(0)
        hour, minute = time:match("~w~(%d+)~y~:~w~(%d+)")
        local text = string.format("%s:%s", hour, minute)
        renderFontDrawText(font, text, ini.time.x, ini.time.y, -1)
    end
end

function imgui.OnDrawFrame()
    local sw, sh = getScreenResolution()
    imgui.SetNextWindowSize(imgui.ImVec2(570, 350))
    imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.Begin(fa.ICON_FA_DESKTOP .. "  her", window, imgui.WindowFlags.AlwaysAutoResize + imgui.WindowFlags.NoCollapse)
        imgui.BeginChild('##left', imgui.ImVec2(150, 300), true)
        if imgui.Button(fa.ICON_FA_CLOCK .. u8(' Профиль'), imgui.ImVec2(-1, 20)) then
            menu = 1
        end
        if imgui.Button(u8('Время'), imgui.ImVec2(-1, 20)) then
            menu = 2
        end
        if imgui.Button(u8('Дата'), imgui.ImVec2(-1, 20)) then
            menu = 3
        end
        if imgui.Button(u8('Уровень'), imgui.ImVec2(-1, 20)) then
            menu = 4
        end
        imgui.EndChild()
        imgui.SameLine()
        imgui.BeginChild('##right', imgui.ImVec2(400, 300), true)
        if menu == 1 then   
        if imgui.Button(u8"Позиция", imgui.ImVec2(150, 25)) then
                main_window_state.v = false
                lua_thread.create(function ()
                    while not isKeyJustPressed(0x01) do wait(0)
                        sampSetCursorMode(4)
                        local posX, posY = getCursorPos()
                        ini.time.x = posX
                        ini.time.y = posY
                    end
                    main_window_state.v = true
                    sampSetCursorMode(0)
                    inicfg.save(ini, path)
                end)
            end
        end
        if menu == 2 then
        end
        if menu == 3 then
        end
        if menu == 4 then
        end
        imgui.EndChild()
    imgui.End()
end