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

Дядя Энрик.

Активный
338
81
приветствую, подскажите, как выделить ник игрока из строчки сампа, чтобы потом использовать этот ник дальше в коде?
К примеру есть строка "Отредактировал сотрудник СМИ Nick_Name". Как мне выделить этот ник в коде и использовать потом в скрипте?
Lua:
local nick = 'Nick_Name'
require('lib.samp.events').onServerMessage = function(color, text)
    if text:find('Отредактировал сотрудник СМИ '..nick) then
        sampAddChatMessage(nick, -1)
    end
end

require('lib.samp.events').onServerMessage = function(color, text)
    if text:find('Отредактировал сотрудник СМИ %a+_%a+') then
        nick = text:match('Отредактировал сотрудник СМИ (%a+_%a+)')
        sampAddChatMessage('Отредактировал сотрудник СМИ '..nick, -1)
    end
end
 

sirues

Новичок
4
0
Здравствуйте, мне нужна функция, которая блокирует анимацию жестов речи, которую отправляет сервер. Не могли бы вы создать ее для меня, я не знаю, как программировать Lua...
 

MSIshka

Новичок
9
0
Всем привет, можно ли как-то реализовать проверку на кол-во отправленных мне @Name, и если их 3 за допустим 3 секунды выдавать /mute /amute?

Lua:
function sampev.onServerMessage(color, text)
    if act then
        local playerid2 = select(2,sampGetPlayerIdByCharHandle(PLAYER_PED))
        local name = sampGetPlayerNickname(playerid2)      
        lua_thread.create(function()
        if text:find(u8:decode("@") .. name) or text:find(u8:decode("@") .. name:lower()) then
                if text:find(u8:decode("-")) then
                    sampSendChat(u8:decode('[Авто-ответ] Уже бегу отвечать! Среднее время ожидания: 2 минуты'))
                    wait(500)
                    sampSendChat(u8:decode('[Авто-ответ] Если прошло 5 минут и я не ответил,'))
                    wait(500)
                    sampSendChat(u8:decode('[Авто-ответ] Отправьте ещё раз. Попытка флуда карается МУТОМ!'))
                elseif text:find(u8:decode("%[%+%]")) then
                    sampAddChatMessage(u8:decode('Пропускаю лишний спам'),-1)

                elseif text:find(u8:decode("от%sсаппорта%s(%w+_%w+):")) then
                    local nicka = text:match(u8:decode("от%sсаппорта%s(%w+_%w+):"))
                    local ida = sampGetPlayerIdByNickname(nicka)
                    sampSendChat(u8:decode('/pm ') .. ida .. u8:decode(' [Авто-ответ] Уже бегу отвечать! Среднее время ожидания: 2 минуты'))
                    sampSendChat(u8:decode('/pm ') .. ida .. u8:decode(' [Авто-ответ] Если прошло 5 минут и я не ответил,'))
                    sampSendChat(u8:decode('/pm ') .. ida .. u8:decode(' [Авто-ответ] Отправьте ещё раз. Попытка флуда карается МУТОМ!'))
                    goto end_chat

                elseif text:find(u8:decode("от%sадмина%s(%w+_%w+):")) then
                    local nicka = text:match(u8:decode("от%sадмина%s(%w+_%w+):"))
                    local ida = sampGetPlayerIdByNickname(nicka)
                    sampSendChat(u8:decode('/pm ') .. ida .. u8:decode(' [Авто-ответ] Уже бегу отвечать! Среднее время ожидания: 2 минуты'))
                    sampSendChat(u8:decode('/pm ') .. ida .. u8:decode(' [Авто-ответ] Если прошло 5 минут и я не ответил,'))
                    sampSendChat(u8:decode('/pm ') .. ida .. u8:decode(' [Авто-ответ] Отправьте ещё раз. Попытка флуда карается МУТОМ!'))
                    goto end_chat
                else
                    sampSendChat(u8:decode('/a [Авто-ответ] Уже бегу отвечать! Среднее время ожидания: 2 минуты'))
                    wait(500)
                    sampSendChat(u8:decode('/a [Авто-ответ] Если прошло 5 минут и я не ответил,'))
                    wait(500)
                    sampSendChat(u8:decode('/a [Авто-ответ] Отправьте ещё раз. Попытка флуда карается МУТОМ!'))
                end
            ::end_chat::
            sendTelegramNotification(text)
        end
end)
 

Willy4ka

вилличка
Модератор
501
817
How to wallhack an NPC? I mean a skin?
do you want to use chams? or just...
Lua:
local font = renderCreateFont('Arial', 10, 5)
function main()
    while not isSampAvailable() do wait(0) end
    while true do
        wait(0)
        for k, ped in pairs(getAllChars()) do
            if isCharOnScreen(ped) then
                if not sampGetPlayerIdByCharHandle(ped) then -- NPC check
                    local skin = getCharModel(ped)
                    local pos = {getCharCoordinates(ped)}
                    local x, y = convert3DCoordsToScreen(pos[1], pos[2], pos[3])
                    renderFontDrawText(font, skin, x, y, -1)
                end
            end
        end
    end
end
if you meant chams then use https://www.blast.hk/threads/13380/post-650507
 
  • Нравится
Реакции: Naito

Willy4ka

вилличка
Модератор
501
817
Здравствуйте, мне нужна функция, которая блокирует анимацию жестов речи, которую отправляет сервер. Не могли бы вы создать ее для меня, я не знаю, как программировать Lua...
Lua:
local sampev = require('lib.samp.events')
function sampev.onApplyPlayerAnimation(playerId, animLib, animName, frameDelta, loop, lockX, lockY, freeze, time)
    if playerId == select(2, sampGetPlayerIdByCharHandle(1)) then
        if (animLib == "PED" and animName == "IDLE_CHAT") or (animLib == "CARRY" and animName == "crry_prtial") then
            return false
        end
    end
end
 

Naito

Активный
158
35
do you want to use chams? or just...
Lua:
local font = renderCreateFont('Arial', 10, 5)
function main()
    while not isSampAvailable() do wait(0) end
    while true do
        wait(0)
        for k, ped in pairs(getAllChars()) do
            if isCharOnScreen(ped) then
                if not sampGetPlayerIdByCharHandle(ped) then -- NPC check
                    local skin = getCharModel(ped)
                    local pos = {getCharCoordinates(ped)}
                    local x, y = convert3DCoordsToScreen(pos[1], pos[2], pos[3])
                    renderFontDrawText(font, skin, x, y, -1)
                end
            end
        end
    end
end
if you meant chams then use https://www.blast.hk/threads/13380/post-650507
I want me to dial a skin id or name that I want, it is to create a wallhack for a server event
 

Naito

Активный
158
35
[CÓDIGO=lua]sampev local = require('lib.samp.events')
función sampev.onApplyPlayerAnimation(playerId, animLib, animName, frameDelta, loop, lockX, lockY, congelar, tiempo)
si playerId == select(2, sampGetPlayerIdByCharHandle(1)) entonces
si (animLib == "PED" y animName == "IDLE_CHAT") o (animLib == "CARRY" y animName == "crry_prtial") entonces
devolver falso
fin
fin
fin[/CÓDIGO]

wallhack for a specific skin id?
I tried but it doesn't work for me

script_name('WH Skins')
script_author('Naito')
script_version(1.1)
script_description('Para activar/desactivar detección de skins escribe /whfant')

require "lib.moonloader"

local skins = {
[78] = "Fantasma",
}

local activ = false
local font = renderCreateFont('ShellyAllegroC', 8, 7)

function main()
repeat wait(11000) until isSampAvailable()
sampAddChatMessage("{66CDAA}[WH Skins by Naito]: {FFFFFF}Autor del script: {00FF7F}Naito", 0xFFFFFF)
sampAddChatMessage("{66CDAA}[WH Skins by Naito]: {FFFFFF}Para activar/desactivar detección de skins escribe {00FF7F}/whfant", 0xFFFFFF)

sampRegisterChatCommand('whfant', function()
activ = not activ
sampAddChatMessage('[WH Skins by Naito]: '..(activ and '{00FF00}Activado.' or '{FF0000}Desactivado.'), 0xFFFFFF)
end)

while true do
wait(0)
if activ then
for _, ped in pairs(getAllChars()) do
local skinId = getCharModel(ped)
local skinName = skins[skinId]
if skinName and isCharOnScreen(ped) then
local x, y, z = getCharCoordinates(PLAYER_PED)
local res, x1, y1, z1 = getCharCoordinates(ped)
if res then
local dist = math.floor(getDistanceBetweenCoords3d(x, y, z, x1, y1, z1))
local c1, c2 = convert3DCoordsToScreen(x, y, z)
local p1, p2 = convert3DCoordsToScreen(x1, y1, z1)
local text = '{00FF00}'..skinName..'\n{C0C0C0}Distancia: '..dist..'m.'
renderDrawLine(c1, c2, p1, p2, 3, 0xFF00D000)
renderFontDrawText(font, text, p1, p2, -1)
end
end
end
end
end
end

wallhack for a specific skin id?
yeah, yes
 

Willy4ka

вилличка
Модератор
501
817
Lua:
local font = renderCreateFont('Arial', 10, 5)
local skins = {
    [59] = 'skinname'
}
local select_id = 0
function main()
    while not isSampAvailable() do wait(0) end
    sampRegisterChatCommand('wh', function (params)
        if #params > 0 then
            if tonumber(params) then
                select_id = tonumber(params)
            else
                local result, id = table_find(skins, params)
                if result then
                    select_id = id
                end
            end
        end
    end)
    while true do
        wait(0)
        for k, ped in pairs(getAllChars()) do
            if isCharOnScreen(ped) then
                if not sampGetPlayerIdByCharHandle(ped) then -- NPC check
                    local skin = getCharModel(ped)
                    if skin == select_id then
                        local pos = {getCharCoordinates(ped)}
                        local x, y = convert3DCoordsToScreen(pos[1], pos[2], pos[3])
                        renderFontDrawText(font, skin, x, y, -1)
                    end
                end
            end
        end
    end
end
function table_find(t, value)
    for k, v in pairs(t) do
        if v == value then
            return true, k
        end
    end
    return false, -1
end
 
  • Влюблен
Реакции: Naito

Naito

Активный
158
35
Lua:
local font = renderCreateFont('Arial', 10, 5)
local skins = {
    [59] = 'skinname'
}
local select_id = 0
function main()
    while not isSampAvailable() do wait(0) end
    sampRegisterChatCommand('wh', function (params)
        if #params > 0 then
            if tonumber(params) then
                select_id = tonumber(params)
            else
                local result, id = table_find(skins, params)
                if result then
                    select_id = id
                end
            end
        end
    end)
    while true do
        wait(0)
        for k, ped in pairs(getAllChars()) do
            if isCharOnScreen(ped) then
                if not sampGetPlayerIdByCharHandle(ped) then -- NPC check
                    local skin = getCharModel(ped)
                    if skin == select_id then
                        local pos = {getCharCoordinates(ped)}
                        local x, y = convert3DCoordsToScreen(pos[1], pos[2], pos[3])
                        renderFontDrawText(font, skin, x, y, -1)
                    end
                end
            end
        end
    end
end
function table_find(t, value)
    for k, v in pairs(t) do
        if v == value then
            return true, k
        end
    end
    return false, -1
end
thank youaaaaaassss i loveee
 
  • Нравится
Реакции: Willy4ka

sirues

Новичок
4
0
Lua:
local sampev = require('lib.samp.events')
function sampev.onApplyPlayerAnimation(playerId, animLib, animName, frameDelta, loop, lockX, lockY, freeze, time)
    if playerId == select(2, sampGetPlayerIdByCharHandle(1)) then
        if (animLib == "PED" and animName == "IDLE_CHAT") or (animLib == "CARRY" and animName == "crry_prtial") then
            return false
        end
    end
end
Спасибо большое, вопрос, как добавить еще одну анимацию в блок?
 

Ancwork

Участник
42
3
Как с ini работать в imgui. Хочу сохранение из imgui.InputText

Lua:
local inicfg = require('inicfg');
local IniFilename = 'setting.ini'
local ini = inicfg.load({
    player = {
        name = 'Ivan Ivanov',
        phone = '123-123'
    }
}, IniFilename);
inicfg.save(ini, IniFilename);
local main_window_state = imgui.ImBool(false)

function imgui.OnDrawFrame()
  if main_window_state.v then
    imgui.SetNextWindowSize(imgui.ImVec2(600, 300), imgui.Cond.FirstUseEver)
    imgui.Begin('Setting', main_window_state)
    imgui.Text('')
    imgui.End()
  end
end
 

coulside

Участник
39
0
[ML] (script) meteoAvtoScrin.lua: Сообщение в диалоге 46 не найдено.
Не выводит сообщение из диалога, в чем ошибка?


Lua:
local sampev = require 'lib.samp.events'

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end

    while true do
        wait(0)
      
        if isKeyJustPressed(VK_F8) then
            makeScreenshot()
        end
    end
end

function sampev.onShowDialog(id, style, title, button1, button2, dialogText)
    local pattern = "-%s*Метеоролог:%s*Отличная%s*работа,%s*вот%s*твои%s*деньги!%s*Мы%s*немедленно%s*подключим%s*метеозонд%s*к%s*нашей%s*сети%s*и%s*начнем%s*принимать%s*с%s*него%s*данные!%s*"

    if id == 46 and dialogText:match(pattern) then
        -- Сообщение найдено
        print("Сообщение найдено: - Метеоролог: Отличная работа, вот твои деньги! Мы немедленно подключим метеозонд к нашей сети и начнем принимать с него данные!")
    else
        -- Сообщение не найдено
        print("Сообщение в диалоге 46 не найдено.")
    end
end

function makeScreenshot(disable)
    if disable then
        displayHud(false)
        sampSetChatDisplayMode(0)
    end

    require('memory').setuint8(sampGetBase() + 0x119CBC, 1)

    if disable then
        displayHud(true)
        sampSetChatDisplayMode(2)
    end
end

сам диалог:
- Метеоролог: Отличная работа, вот твои деньги! Мы немедленно подключим метеозонд к нашей сети и начнем принимать с него данные!
 

Вложения

  • изображение_2024-11-03_020654369.png
    изображение_2024-11-03_020654369.png
    30.1 KB · Просмотры: 10
  • изображение_2024-11-03_020709298.png
    изображение_2024-11-03_020709298.png
    2.8 KB · Просмотры: 11

Naito

Активный
158
35
How to make the line reach up to 1000 meters or 1500 meters across the entire map?, and not have to look everywhere to detect something

if skinName then
local pos = {getCharCoordinates(ped)}
local x, y, z = pos[1], pos[2], pos[3]
local dist = math.floor(getDistanceBetweenCoords3d(playerX, playerY, playerZ, x, y, z))

local c1, c2 = convert3DCoordsToScreen(playerX, playerY, playerZ)
local o1, o2 = convert3DCoordsToScreen(x, y, z)
local text = '{6400FF}'..skinName..' (ID: '..skin..')\n{C0C0C0}Distancia: '..dist..'m.'

if skinName then
renderDrawLine(c1, c2, o1, o2, 3, 0xFF800080)
renderFontDrawText(font, text, o1, o2, -1)
end
end
end
end
end
end
end
end