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

coulside

Участник
40
1
[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 · Просмотры: 9
  • изображение_2024-11-03_020709298.png
    изображение_2024-11-03_020709298.png
    2.8 KB · Просмотры: 10

Naito

Активный
126
32
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
 

Дядя Энрик.

Активный
337
81
[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

сам диалог:
- Метеоролог: Отличная работа, вот твои деньги! Мы немедленно подключим метеозонд к нашей сети и начнем принимать с него данные!
Lua:
require('lib.samp.events').onShowDialog = function(dialogId, style, title, button1, button2, text)
    if dialogId == 46 then
        if text:find('Отличная работа, вот твои деньги! Мы немедленно подключим метеозонд к нашей сети и начнем принимать с него данные!') then
            sampAddChatMessage('done', -1)
        end
    end
end
 
  • Нравится
Реакции: coulside

kuboni

Потрачен
154
2
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
setVirtualKeyState
Does anyone have the code to click y using raknet?
 

coulside

Участник
40
1
Lua:
require('lib.samp.events').onShowDialog = function(dialogId, style, title, button1, button2, text)
    if dialogId == 46 then
        if text:find('Отличная работа, вот твои деньги! Мы немедленно подключим метеозонд к нашей сети и начнем принимать с него данные!') then
            sampAddChatMessage('done', -1)
        end
    end
end
cпасибо <3, как задержку правильно добавить? Скриншот делается раньше появления диалога
 

chapo

чопа сребдс // @moujeek
Модератор
8,892
11,625
cпасибо <3, как задержку правильно добавить? Скриншот делается раньше появления диалога
Lua:
require('lib.samp.events').onShowDialog = function(dialogId, style, title, button1, button2, text)
    if dialogId == 46 then
        if text:find('Отличная работа, вот твои деньги! Мы немедленно подключим метеозонд к нашей сети и начнем принимать с него данные!') then
            lua_thread.create(function()
                wait(1000) -- 1 sec
                sampAddChatMessage('done', -1)
            end)
        end
    end
end
 

coulside

Участник
40
1
реализовал по другому, через wait ошибку выдает
Lua:
local sampev = require 'lib.samp.events'
local screenshotPending = false

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

    
    while true do
        wait(0)

        if screenshotPending then
            wait(1000)
            makeScreenshot()
            sampAddChatMessage('{ff0000}[Meteo]:{FFFFFF} Скриншот сделан.', -1)
            screenshotPending = false
        end
    end
end

require('lib.samp.events').onShowDialog = function(dialogId, style, title, button1, button2, text)
    if dialogId == 46 then
        if text:find('Отличная работа, вот твои деньги! Мы немедленно подключим метеозонд к нашей сети и начнем принимать с него данные!') then
            sampAddChatMessage('{ff0000}[Meteo]:{FFFFFF} Скриншот выполнен...', -1)
            screenshotPending = true
        end
    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
 

Орк

Известный
242
152
Есть такой код https://github.com/JuniorDjjr/SA-Mi...b4c45658fbaaa9ec7d90/MixSets/ReadIni.cpp#L863
C++:
    if (ReadIniInt(ini, &lg, "Graphics", "CameraPhotoQuality", &i)) {
        G_CameraPhotoQuality = i;
        injector::MakeInline<0x5D04E1, 0x5D04E1 + 7>([](injector::reg_pack& regs)
        {
            *(uint32_t*)(regs.esp + 0x0E8) = regs.edi;
            ((void(__cdecl*)(int, signed int, char))0x5C6FA0)(regs.ecx, G_CameraPhotoQuality, true);
        });
    }
Как его перевести в луа?
1730632959195.png
 

MSIshka

Новичок
8
0
Как реализовать систему авто-мута, если допустим 3 раза упопомянули в течении 3 секунд вводить команду /mute?
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)
 

Дядя Энрик.

Активный
337
81
реализовал по другому, через wait ошибку выдает
Lua:
local sampev = require 'lib.samp.events'
local screenshotPending = false

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

   
    while true do
        wait(0)

        if screenshotPending then
            wait(1000)
            makeScreenshot()
            sampAddChatMessage('{ff0000}[Meteo]:{FFFFFF} Скриншот сделан.', -1)
            screenshotPending = false
        end
    end
end

require('lib.samp.events').onShowDialog = function(dialogId, style, title, button1, button2, text)
    if dialogId == 46 then
        if text:find('Отличная работа, вот твои деньги! Мы немедленно подключим метеозонд к нашей сети и начнем принимать с него данные!') then
            sampAddChatMessage('{ff0000}[Meteo]:{FFFFFF} Скриншот выполнен...', -1)
            screenshotPending = true
        end
    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
Lua:
local sampev = require 'lib.samp.events'
local screenshotPending = false

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

    
    while true do
        wait(0)

        if screenshotPending then
            makeScreenshot()
            screenshotPending = false
        end
    end
end

require('lib.samp.events').onShowDialog = function(dialogId, style, title, button1, button2, text)
    if dialogId == 46 then
        if text:find('Отличная работа, вот твои деньги! Мы немедленно подключим метеозонд к нашей сети и начнем принимать с него данные!') then
            lua_thread.create(function() wait(1000)
                screenshotPending = true
                sampAddChatMessage('{ff0000}[Meteo]:{FFFFFF} Скриншот выполнен...', -1)
            end)
        end
    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
 

Naito

Активный
126
32
How to send a message to the chat when I collide with the vehicle? That is, when I collide with my vehicle, a message is sent to the chat saying that it crashed.
 

Wer_tyn

Новичок
27
0
Как сделать чтобы если у персонажа был определенный скин, например 13 то выполнялось какое-то действие? MoonLoader
 

Wer_tyn

Новичок
27
0
setCharKeyDown(int ckey, bool down) - нажимает клавишу? Или какая? Чтобы персонаж двинулся например, или сел в машину, ну чтобы реагировал сервер