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

ШPEK

Известный
1,474
525
Братики, чет башка не варит вообще.
Нужно реализовать автовыдачу, тобишь.
[A] Admin_1337: /ban 132 30 лох.
[Автовыдача]: Admin_1337 запросил выдачу наказания для игрока(132). Нажмите F2, для выдачи.
YaKrutoyAdmin заблокировал игрока Chiter на 30 дней. Причина: лох || A. 1337

-----
upd. и еще бы, хотелось бы узнать, как сделать не только одну команду /ban, но и другие, допустим /warn, /mute и т.д
Lua:
local ev = require("samp.events")
require("moonloader")
function main() wait(-1) end
local adminnick, narid, nardays, narreason
function ev.onServerMessage(_, msg)
    if msg:find("%[A%] .+_.+: /ban %d+ %d+ .+") then
        adminnick, narid, nardays, narreason = msg:match("%[A%] (.+_.+): /ban (%d+) (%d+) (.+)")
        lua_thread.create(function()
        local timer = 0
            wait(0)
            sampAddChatMessage(string.format("Админ %s запросил бан %d id, зажмите кнопку F2 чтобы забанить", adminnick, narid), -1)
            repeat
                wait(100)
                timer = timer+1
                if timer == 150 then
                    timer = 0
                    return false
                end
            until isKeyDown(VK_F2)
            sampSendChat(string.format("/ban %d %d %s || ©%s", narid, nardays, narreason, string.sub(adminnick, 1, 1).."."..adminnick:match(".+_(.+)")))
            sampAddChatMessage("sdasd")
        end)
    end
end
 
Последнее редактирование:
  • Нравится
Реакции: Natami

trefa

3d print
Всефорумный модератор
2,107
1,264
Нужен скрипт который видит в чате: [A] Nick_Name[мой ID]: /*jail/mute/warn/ban* *id нарушителя* *время наказания* *причина*
И у меня должна срабатывать команда /ans *id нарушителя* Для подачи жалобы сделайте скриншот наказания. [F8]

Пример:
[13:41:16] [A] Nick_Name[62]: /jail 5 120 дм
У меня сразу пишет /ans 5 Для подачи жалобы сделайте скриншот наказания. [F8]

Тоже самое должно быть с командами /mute /jail /ban /warn

То есть скрипт отслеживает админ чат и когда видит строчку с любым наказанием, именно которую ты написал, пишет команду
Lua:
cmd = {"/warn","/ban"}

function sampev.onSendCommand(command)
    for _, val in ipairs(cmd) do
        if string.find(val,command) then
            sampSendChat("/ans "..string.match(command,"^"..val.."%s(%d+)").." Для подачи жалобы сделайте скриншот наказания. [F8]")
        end
     end
end
 

ШPEK

Известный
1,474
525
Как тип userdata перевести в функцию?
При записи imgui.ImInt(0) записывает 1=userdata: 0x06869b88
 

#Northn

Pears Project — уже запущен!
Всефорумный модератор
2,654
2,535
Почему не рандомит?
Пишет всегда последнее значение в таблице
Lua:
    local tabletest = { 'a', 'f', 'c', 's'}
    sampSendChat(tabletest[math.random(1, #tabletest)])
math.randomseed(os.time())

Как тип userdata перевести в функцию?
При записи imgui.ImInt(0) записывает 1=userdata: 0x06869b88
Значение.v
 
  • Нравится
Реакции: LZTD и ШPEK

ШPEK

Известный
1,474
525
Как ссылку userdata перевести в imgui.ImInt(value)?
p.s при записи imgui.ImInt в файл ini записывается ссылка, а не imgui.ImInt
 

Musaigen

abobusnik
Проверенный
1,607
1,365
Как ссылку userdata перевести в imgui.ImInt(value)?
p.s при записи imgui.ImInt в файл ini записывается ссылка, а не imgui.ImInt
Блять, тебе несколько человек ответили что .v нужно поставить, ты досихпор спрашиваешь как перевести userdata в int
 

ШPEK

Известный
1,474
525
Lua:
local imgui = require("imgui")
local x2, y2 = getScreenResolution()
local checkbox = imgui.ImBool(false)
local encoding = require ("encoding")
local traser = imgui.ImBool(false)
local enab = imgui.ImBool(true)
local inicfg = require("inicfg")
encoding.default = "CP1251"
u8 = encoding.UTF8
local inputs11 = {
tabl = {
121212, 1221
}
}
    local style = imgui.GetStyle()
    local colors = style.Colors
    local clr = imgui.Col
    local ImVec4 = imgui.ImVec4
    colors[clr.TitleBg]                = ImVec4(255, 0, 0, 1)
    colors[clr.TitleBgActive]          = ImVec4(255, 0, 0, 1)
    colors[clr.TitleBgCollapsed]       = ImVec4(255, 0, 0, 0.1)
function main()
while not isSampAvailable() do wait(100) end
local font = renderCreateFont("Arial", 7, 4)
sampRegisterChatCommand("renderob", function() enab.v = not enab.v end)
    if not doesDirectoryExist("moonloader//config") then
        createDirectory("moonloader//config")
        inicfg.save(inputs11, "objwallhack")
    end
    inputs = inicfg.load(nil, "objwallhack")
    if inputs == nil then
        inicfg.save(inputs11, "objwallhack")
       inputs = inicfg.load(nil, "objwallhack")
    end
    while true do
    wait(0)
    imgui.Process = enab.v
        for _, v in pairs(getAllObjects()) do
            if isObjectOnScreen(v) then
                local _, x, y, z = getObjectCoordinates(v)
                local x1, y1 = convert3DCoordsToScreen(x,y,z)
                local model = getObjectModel(v)
                local x2,y2,z2 = getCharCoordinates(PLAYER_PED)
                local x10, y10 = convert3DCoordsToScreen(x2,y2,z2)
                if checkbox.v then
                    renderFontDrawText(font, model, x1, y1, -1)
                    if traser.v then
                        renderDrawLine(x10, y10, x1, y1, 1.0, -1)
                    end
                else
                    for _, v2 in ipairs(inputs) do
                        if v2.v == model then
                            renderFontDrawText(font, model, x1, y1, -1)
                        elseif traser.v and v2.v ~= model then
                                renderDrawLine(x10, y10, x1, y1, 1.0, -1)
                        end
                        end
                    end
            end
        end
    end
end

function imgui.OnDrawFrame()
if enab.v then
    imgui.SetNextWindowPos(imgui.ImVec2(x2 / 2, y2 / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(300, 400), imgui.Cond.FirstUseEver)
    imgui.Begin("Render objects", enab, imgui.WindowFlags.AlwaysUseWindowPadding + imgui.WindowFlags.NoResize + imgui.WindowFlags.AlwaysUseWindowPadding)
    imgui.Checkbox(u8("Найти все объекты"), checkbox)
    imgui.Checkbox(u8("Включить трейсер"), traser)
    if imgui.Button(u8("Добавить новое условие")) then
        table.insert(inputs.tabl, #inputs.tabl + 1)
        inicfg.save(inputs, "objwallhack")
        inputs = inicfg.load(nil, "objwallhack")
    end
    if #inputs.tabl > 0 then
        if imgui.Button(u8("Удалить последнее условие")) then
        table.remove(inputs.tabl, #inputs.tabl)
        inicfg.save(inputs, "objwallhack")
        inputs = inicfg.load(nil, "objwallhack")
        end
    end
    imgui.BeginChild("inputs", imgui.ImVec2(287, 270), true)
    for i, val in ipairs(inputs.tabl) do
        if imgui.InputInt("input"..i, imgui.ImInt(val), 0, -1) then
        inputs.tabl.i = val
        end
    end
     imgui.EndChild()
    imgui.End()
end
end
Почему при изменении в inputint число остаётся прежним?
 

trefa

3d print
Всефорумный модератор
2,107
1,264
не работает

Вот так должно быть как у Tommy_Martelly, только сообщение должно быть от Ralph_Nomad автоматом отправляться
Посмотреть вложение 18933
Я знаю как должно быть
Lua:
cmd = {"/warn","/ban"}

function sampev.onSendCommand(command)
    for _, val in ipairs(cmd) do
        if string.find(command,val) then
        id = string.match(command,"^"..val.."%s(%d+)")
            if id ~= nil then
                sampSendChat("/ans "..id.." Для подачи жалобы сделайте скриншот наказания. [F8]")
            end
        end
     end
end
 

Hatiko

Известный
Проверенный
1,502
620
Смотри, для инпута есть окно, куда ты вбиваешь инфу. Она должна где-то хранится, т.е. имет ькакоцй-то буфер. Ты же вставил другую функцию, которая имеет другое предназначение. Тебе нужно объявить по началу какую-то переменную с присваиванием imgui.ImBuffer(256). Где 256 объем вместимой информации. Чтобы получить содержимое переменной буфера нужно к переменной приписать .v
 

lorgon

Известный
656
271
В чём измеряется скорость в функции speed = getCarSpeed(Vehicle car) , в км/ч или в милях? Можно ли как-то ограничить макс скорость? Как получить машину в которой сижу я?
 

ШPEK

Известный
1,474
525
Смотри, для инпута есть окно, куда ты вбиваешь инфу. Она должна где-то хранится, т.е. имет ькакоцй-то буфер. Ты же вставил другую функцию, которая имеет другое предназначение. Тебе нужно объявить по началу какую-то переменную с присваиванием imgui.ImBuffer(256). Где 256 объем вместимой информации. Чтобы получить содержимое переменной буфера нужно к переменной приписать .v
ImBuffer для string, ImInt для int. Ты неправильно сказал
 

trefa

3d print
Всефорумный модератор
2,107
1,264
Мне нужно чтобы из чата отслеживалось, когда именно я напишу в админ чат команду
Оно и так будет работать, хоть любой админ закажет, AdminTools пишет через sampSendChat, и хук это должен отловить.
 

lorgon

Известный
656
271
Как нарисовать слайдер с цифрами, к примеру тянешь ползунок вправо цифры увеличиваются на 20