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

Cyprien Lortie

Участник
64
18
ну вот тебе это и нужно,только там на 0 и 3 интк проверку сделай,когда на улицу входишь и выходишь,при 0 Инте поворот на 90 градусов
Допрело...
Получается так:
if ...:
rotatePlayer(PLAYER_PED, 90)
else
yes?

ну вот тебе это и нужно,только там на 0 и 3 интк проверку сделай,когда на улицу входишь и выходишь,при 0 Инте поворот на 90 градусов
А есть ли функция, которая проверяет смену инты или как ее можно заменить?
 
Последнее редактирование:

HogeR

Участник
21
4

Для таких целей лучше использовать таблицы, но можно и наговнить:
Lua:
gun10 = 'text'
print(_G['gun' .. etCurrentCharWeapon(PLAYER_PED)])
смотри а как то можно заменить gun0 в зависимости от оружия игрока к примеру у игрока ид оружия 38 (minigun) то будет вызываться gun38
Lua:
-- main
gun0 = renderLoadTextureFromFile('moonloader/Images/Gunid0.png')
gun1 = renderLoadTextureFromFile('moonloader/Images/Gunid1.png')
gun2 = renderLoadTextureFromFile('moonloader/Images/Gunid2.png')
gun3 = renderLoadTextureFromFile('moonloader/Images/Gunid3.png')
-- и т.д.
-- main

-- while
renderDrawTexture(gun0, nrX/2, nrY-340, 30, 30, 0, 0xFFFFFFFF) -- нужно заменять gun0 на любой другой в зависимости от оружия у игрока в руках
 

Cyprien Lortie

Участник
64
18
@ChromiusJ
Сделал проверку инты и оно работает, спору нет, но единоразово.
Как сделать так, чтобы человек ввел команду "/pov" и она начала проверку и каждый раз от команды к команде?
povorot:
local isNotRotated = true
local state = false

function main()
    while not isSampAvailable() do wait(0) end
    while true do
        while true do
            wait(0)
            local inta = getActiveInterior()
            if inta == 0 then
                isNotRotated = true
                rotatePlayer(PLAYER_PED, 90)
                isNotRotated = false
            end
        end
    end
end

function rotatePlayer(handle, angle)
    local heading = getCharHeading(handle)
    setCharHeading(handle, heading - angle)
    if handle == playerPed then
        setCameraBehindPlayer()
    end
end
 

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Друг
8,776
11,226


смотри а как то можно заменить gun0 в зависимости от оружия игрока к примеру у игрока ид оружия 38 (minigun) то будет вызываться gun38
Lua:
-- main
gun0 = renderLoadTextureFromFile('moonloader/Images/Gunid0.png')
gun1 = renderLoadTextureFromFile('moonloader/Images/Gunid1.png')
gun2 = renderLoadTextureFromFile('moonloader/Images/Gunid2.png')
gun3 = renderLoadTextureFromFile('moonloader/Images/Gunid3.png')
-- и т.д.
-- main

-- while
renderDrawTexture(gun0, nrX/2, nrY-340, 30, 30, 0, 0xFFFFFFFF) -- нужно заменять gun0 на любой другой в зависимости от оружия у игрока в руках
Я же тебе поуазал пример.
да и твой код полное говно, можно сделатт все гораздо проще
Lua:
local gunTexture = {}

for gunId = 0, 46 do
    if doesFileExist('moonloader\\Images\\Gunid' .. gunId .. '.png') then
        gunTexture[gunId] = renderLoadTextureFromFile('moonloader/Images/Gunid' .. gunId .. '.png')
    end
end
renderDrawTexture(gunTexture[getCurrentCharWeapon(PLAYER_PED), ...)
Этот код автоматичесуи попробует загрузитт все картинки с gunid0.png до gunid46.png
 
  • Нравится
Реакции: HogeR и MLycoris

HogeR

Участник
21
4
Я же тебе поуазал пример.
да и твой код полное говно, можно сделатт все гораздо проще
Lua:
local gunTexture = {}

for gunId = 0, 46 do
    if doesFileExist('moonloader\\Images\\Gunid' .. gunId .. '.png') then
        gunTexture[gunId] = renderLoadTextureFromFile('moonloader/Images/Gunid' .. gunId .. '.png')
    end
end
renderDrawTexture(gunTexture[getCurrentCharWeapon(PLAYER_PED), ...)
Этот код автоматичесуи попробует загрузитт все картинки с gunid0.png до gunid46.png
От души душевно в душу
 

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Друг
8,776
11,226
Нужна помощь в скрипте.
Делаю скрипт, который при определённом номере интерьера будет поворачивать камеру на нужные мне координаты
Нашел пару возможно нужных функций, но ничего не работало.
Lua:
require 'lib.moonloader'

function main()
    local X = 1000
    local Y = 300
    local Z = 30

    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand("test",function()
        X, Y, Z = getDebugCameraPointAt()
        interior = getActiveInterior()
        sampAddChatMessage(interior,-1)
    end)
    wait(-1)
end
Перелазил все вики, но не нашел ничего нужного.
Lua:
local sampev = require('lib.samp.events')
function sampev.onSetInterior(intId)
    if intId == ид_интерьера then
        rotatePlayer(PLAYER_PED, 90)
    end
end

function rotatePlayer(handle, angle)
    local heading = getCharHeading(handle)
    setCharHeading(handle, heading - angle)
    if handle == playerPed then
        setCameraBehindPlayer()
    end
end
 

kuboni

Участник
111
2
[20:02:10.875669] (error) capcha-rcp.lua: opcode '01BB' call caused an unhandled exception
stack traceback:
[C]: in function 'getObjectCoordinates'
D:\GTA Sa\GTA Sa\sagta\moonloader\capcha-rcp.lua:8: in function <D:\GTA Sa\GTA Sagta\moonloader\capcha-rcp.lua:3>
[20:02:10.875669] (error) capcha-rcp.lua: Script died due to an error. (1B23B03C)
help me fix
 

Вложения

  • capcha.lua
    2.9 KB · Просмотры: 1

хромиус)

спокойно, это всего лишь слива
Друг
4,958
3,236
[20:02:10.875669] (error) capcha-rcp.lua: opcode '01BB' call caused an unhandled exception
stack traceback:
[C]: in function 'getObjectCoordinates'
D:\GTA Sa\GTA Sa\sagta\moonloader\capcha-rcp.lua:8: in function <D:\GTA Sa\GTA Sagta\moonloader\capcha-rcp.lua:3>
[20:02:10.875669] (error) capcha-rcp.lua: Script died due to an error. (1B23B03C)
help me fix
1706619995973.png
 

хромиус)

спокойно, это всего лишь слива
Друг
4,958
3,236
Sorry, Russian is quite difficult. Can you translate it into English so I can understand better?
You need to check is object exist,after check you can get object coordinates. In your situation, your variable is named like "_", so, you can rename it in "res/bool/etc.",to make the code more readable. So,after it will be like:
if _(res/bool/etc.) then
-- code.
end
 
  • Нравится
Реакции: kuboni

7 СМЕРТНЫХ ГРЕХОВ

Известный
515
159
Почему скипает все 215 пакеты ?


LUA:
local bytes = { 2, 0, 0, 0, 0, 0, 16, 0, 0, 0, 79, 110, 68, 105, 97, 108, 111, 103, 82, 101, 115, 112, 111, 110, 115, 101, 8, 0, 0, 0, 100, 0, 0, 0, 0, 100 }
function onReceivePacket(id, bs)
    if id == 215 and skip[0] then
        raknetBitStreamIgnoreBits(bs, 8)
        if raknetBitStreamReadInt16(bs) == 2 then
            raknetBitStreamReadInt32(bs)
            local e = {}
            for i = 1, raknetBitStreamReadInt8(bs) do
                local l = raknetBitStreamReadInt32(bs)
                table.insert(e, raknetBitStreamReadString(bs, l))
            end
            if table.getn(e) > 0 then
                local text = e[1]
                if text:find("text") or ("text") then
                    sendDialogResponse(1,0,'by 7sg')
                    return false
                elseif text:find("text") then
                    local bs = raknetNewBitStream()
                    local bytes = { 2, 0, 0, 0, 0, 0, 16, 0, 0, 0, 79, 110, 68, 105, 97, 108, 111, 103, 82, 101, 115, 112, 111, 110, 115, 101, 8, 0, 0, 0, 100, 0, 0, 0, 0, 100 }
                    raknetBitStreamWriteInt8(bs, 215)
                    for i = 1, #bytes do
                        raknetBitStreamWriteInt8(bs, bytes[i])
                    end
                    raknetBitStreamWriteInt32(bs, 1)
                    raknetBitStreamWriteInt8(bs, 100)
                    raknetBitStreamWriteInt32(bs, 0)
                    raknetBitStreamWriteInt8(bs, 115)
                    raknetBitStreamWriteInt32(bs, 8)
                    raknetSendBitStreamEx(bs, 1, 7, 1)
                    raknetDeleteBitStream(bs)
                end
            end
        end
    end
end

function sendDialogResponse(button, list, text)
    local bs = raknetNewBitStream()
    raknetBitStreamWriteInt8(bs, 215)
    for i = 1, #bytes do
        raknetBitStreamWriteInt8(bs, bytes[i])
    end
    raknetBitStreamWriteInt32(bs, button)
    raknetBitStreamWriteInt8(bs, 100)
    raknetBitStreamWriteInt32(bs, list)
    raknetBitStreamWriteInt8(bs, 115)
    raknetBitStreamWriteInt32(bs, #text)
    raknetBitStreamWriteString(bs, text)
    raknetSendBitStreamEx(bs, 1, 7, 1)
    raknetDeleteBitStream(bs)
end
?
 

danduk_oil

Участник
49
6
Хукается, но не прокликивается текстдрав на RakSAMP (этот же код на сампе работает нормально)


Lua:
local sampev = require("samp.events")

function sampev.onShowTextDraw(id, data)
    newTask(function()
        if data.modelId == 228  then
            wait(1000)
            sendClickTextdraw(id)
        end
    end)
end
 

recxvery

Участник
91
28