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

danywa

Активный
358
49
Lua:
local bs = raknetNewBitStream()
raknetBitStreamWriteInt8(bs, 212)
raknetBitStreamSetWriteOffset(bs, 6)
x = raknetBitStreamWriteFloat(bs, 1300)
y = raknetBitStreamWriteFloat(bs, 1200)
z = raknetBitStreamWriteFloat(bs, 20)
raknetSendBitStream((212, bs)
printStringNow('x '..x..' y '..y..' z '..z, 1000)
raknetDeleteBitStream(bs)
как проверять работает ли отправление пакета или нет?
 

Andrinall

Известный
679
532
Lua:
local bs = raknetNewBitStream()
raknetBitStreamWriteInt8(bs, 212)
raknetBitStreamSetWriteOffset(bs, 6)
x = raknetBitStreamWriteFloat(bs, 1300)
y = raknetBitStreamWriteFloat(bs, 1200)
z = raknetBitStreamWriteFloat(bs, 20)
raknetSendBitStream((212, bs)
printStringNow('x '..x..' y '..y..' z '..z, 1000)
raknetDeleteBitStream(bs)
как проверять работает ли отправление пакета или нет?
В таком исполнении, которое приложено - работать не будет.
А вообще вот:
Lua:
function sendSpectatingSync(lrKeys, udKeys, keys, x, y, z)
    local bs = raknetNewBitStream()
    raknetBitStreamWriteInt8(bs, 212)
    raknetBitStreamWriteInt16(bs, lrKeys)
    raknetBitStreamWriteInt16(bs, udKeys)
    raknetBitStreamWriteInt16(bs, keys)
    raknetBitStreamWriteFloat(bs, x)
    raknetBitStreamWriteFloat(bs, y)
    raknetBitStreamWriteFloat(bs, z)
    raknetSendBitStream(bs)
    raknetDeleteBitStream(bs)
end

-- main or other
sendSpectatingSync(0, 0, 0, 1300, 1200, 20)
Скрин из консоли сервера.
изображение_2023-09-07_170136695.png

Как получить целое число скорости?
Используй math.floor() на переменной, в которую сохраняется скорость.
 

danywa

Активный
358
49
В таком исполнении, которое приложено - работать не будет.
А вообще вот:
Lua:
function sendSpectatingSync(lrKeys, udKeys, keys, x, y, z)
    local bs = raknetNewBitStream()
    raknetBitStreamWriteInt8(bs, 212)
    raknetBitStreamWriteInt16(bs, lrKeys)
    raknetBitStreamWriteInt16(bs, udKeys)
    raknetBitStreamWriteInt16(bs, keys)
    raknetBitStreamWriteFloat(bs, x)
    raknetBitStreamWriteFloat(bs, y)
    raknetBitStreamWriteFloat(bs, z)
    raknetSendBitStream(bs)
    raknetDeleteBitStream(bs)
end

-- main or other
sendSpectatingSync(0, 0, 0, 1300, 1200, 20)
Скрин из консоли сервера.
Посмотреть вложение 214485


Используй math.floor() на переменной, в которую сохраняется скорость.
На какое время отсылается пакет, если не использовать в вечном цикле?
 

!Sam#0235

Активный
122
40
How to create the same dialog hook in Lua?

CLEO:
:isDialogResponded
{
    IF 0AB1: @isDialogResponded 0 _Returned: id 0@ button 1@ list_item 2@ input_text 3@
}
IF 0AA2: 31@ = "samp.dll"
THEN 
    CONST
    VAR1 = $2AFD
    VAR2 = $2BEC
    VAR3 = $2CDE
    VAR4 = $2DCB
    END
    
    0AB1: @get_samp_version_id 0 _returned: ID 17@
    IF 17@ > 0
    THEN
        IF 17@ == 1 // 0.3.7 R1
        THEN
            0A8E: 30@ = 31@ + 0x21A0B8 // SAMP_DIALOG_INFO_OFFSET
            0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0
            
            0A8E: 29@ = 30@ + 0x20 // SAMP_DIALOG_LIST_BOX_OFFSET
            0A8D: 29@ = read_memory 29@ size 4 virtual_protect 0
            
            0A8E: 28@ = 30@ + 0x24 // SAMP_DIALOG_EDIT_BOX_OFFSET
            0A8D: 28@ = read_memory 28@ size 4 virtual_protect 0
              
            0A8E: 27@ = 30@ + 0x30 // SAMP_DIALOG_ID_OFFSET
            0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0
            
            0A8E: VAR2 = 31@ + 0x6C04D // SAMP_DIALOG_RESPONSE_OFFSET + 0xD
            
            0A8E: 26@ = 31@ + 0x84850 // SAMP_GET_DIALOG_LIST_ITEM_OFFSET
            0AA8: call_function_method 26@ struct 29@ num_params 1 pop 0 -1 _Return: 25@
            
            0A8E: 24@ = 31@ + 0x81030 // SAMP_GET_DIALOG_EDIT_BOX_TEXT_OFFSET
            0AA8: call_function_method 24@ struct 28@ num_params 0 pop 0 _Returned: Input Text 23@
        END
        IF 17@ == 2 // 0.3.7 R2
        THEN
            0A8E: 30@ = 31@ + 0x21A0C0 // SAMP_DIALOG_INFO_OFFSET
            0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0
            
            0A8E: 29@ = 30@ + 0x20 // SAMP_DIALOG_LIST_BOX_OFFSET
            0A8D: 29@ = read_memory 29@ size 4 virtual_protect 0
            
            0A8E: 28@ = 30@ + 0x24 // SAMP_DIALOG_EDIT_BOX_OFFSET
            0A8D: 28@ = read_memory 28@ size 4 virtual_protect 0
              
            0A8E: 27@ = 30@ + 0x30 // SAMP_DIALOG_ID_OFFSET
            0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0
            
            0A8E: VAR2 = 31@ + 0x6C0FD // SAMP_DIALOG_RESPONSE_OFFSET + 0xD
            
            0A8E: 26@ = 31@ + 0x848F0 // SAMP_GET_DIALOG_LIST_ITEM_OFFSET
            0AA8: call_function_method 26@ struct 29@ num_params 1 pop 0 -1 _Return: 25@
            
            0A8E: 24@ = 31@ + 0x810D0 // SAMP_GET_DIALOG_EDIT_BOX_TEXT_OFFSET
            0AA8: call_function_method 24@ struct 28@ num_params 0 pop 0 _Returned: Input Text 23@
        END
      
        IF 17@ == 3 // 0.3.DL
        THEN
            0A8E: 30@ = 31@ + 0x21A0C0 // SAMP_DIALOG_INFO_OFFSET
            0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0
            
            0A8E: 29@ = 30@ + 0x20 // SAMP_DIALOG_LIST_BOX_OFFSET
            0A8D: 29@ = read_memory 29@ size 4 virtual_protect 0
            
            0A8E: 28@ = 30@ + 0x24 // SAMP_DIALOG_EDIT_BOX_OFFSET
            0A8D: 28@ = read_memory 28@ size 4 virtual_protect 0
              
            0A8E: 27@ = 30@ + 0x30 // SAMP_DIALOG_ID_OFFSET
            0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0
            
            0A8E: VAR2 = 31@ + 0x700DD // SAMP_DIALOG_RESPONSE_OFFSET + 0xD
            
            0A8E: 26@ = 31@ + 0x888F0 // SAMP_GET_DIALOG_LIST_ITEM_OFFSET
            0AA8: call_function_method 26@ struct 29@ num_params 1 pop 0 -1 _Return: 25@
            
            0A8E: 24@ = 31@ + 0x850D0 // SAMP_GET_DIALOG_EDIT_BOX_TEXT_OFFSET
            0AA8: call_function_method 24@ struct 28@ num_params 0 pop 0 _Returned: Input Text 23@
        END
      
        IF 17@ == 4 // 0.3.7 R3
        THEN
            0A8E: 30@ = 31@ + 0x26E898 // SAMP_DIALOG_INFO_OFFSET
            0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0
            
            0A8E: 29@ = 30@ + 0x20 // SAMP_DIALOG_LIST_BOX_OFFSET
            0A8D: 29@ = read_memory 29@ size 4 virtual_protect 0
            
            0A8E: 28@ = 30@ + 0x24 // SAMP_DIALOG_EDIT_BOX_OFFSET
            0A8D: 28@ = read_memory 28@ size 4 virtual_protect 0
              
            0A8E: 27@ = 30@ + 0x30 // SAMP_DIALOG_ID_OFFSET
            0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0
            
            0A8E: VAR2 = 31@ + 0x6FF4D // SAMP_DIALOG_RESPONSE_OFFSET + 0xD
            
            0A8E: 26@ = 31@ + 0x88760 // SAMP_GET_DIALOG_LIST_ITEM_OFFSET
            0AA8: call_function_method 26@ struct 29@ num_params 1 pop 0 -1 _Return: 25@
            
            0A8E: 24@ = 31@ + 0x84F40 // SAMP_GET_DIALOG_EDIT_BOX_TEXT_OFFSET
            0AA8: call_function_method 24@ struct 28@ num_params 0 pop 0 _Returned: Input Text 23@
        END
      
        IF 17@ == 5 // 0.3.7 R4
        THEN
            0A8E: 30@ = 31@ + 0x26E9C8 // SAMP_DIALOG_INFO_OFFSET
            0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0
            
            0A8E: 29@ = 30@ + 0x20 // SAMP_DIALOG_LIST_BOX_OFFSET
            0A8D: 29@ = read_memory 29@ size 4 virtual_protect 0
            
            0A8E: 28@ = 30@ + 0x24 // SAMP_DIALOG_EDIT_BOX_OFFSET
            0A8D: 28@ = read_memory 28@ size 4 virtual_protect 0
              
            0A8E: 27@ = 30@ + 0x30 // SAMP_DIALOG_ID_OFFSET
            0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0
            
            0A8E: VAR2 = 31@ + 0x7066D // SAMP_DIALOG_RESPONSE_OFFSET + 0xD
            
            0A8E: 26@ = 31@ + 0x88EA0 // SAMP_GET_DIALOG_LIST_ITEM_OFFSET
            0AA8: call_function_method 26@ struct 29@ num_params 1 pop 0 -1 _Return: 25@
            
            0A8E: 24@ = 31@ + 0x85680 // SAMP_GET_DIALOG_EDIT_BOX_TEXT_OFFSET
            0AA8: call_function_method 24@ struct 28@ num_params 0 pop 0 _Returned: Input Text 23@
        END
      
        IF 17@ == 6 // 0.3.7 R4 - v2
        THEN
            0A8E: 30@ = 31@ + 0x26E9C8 // SAMP_DIALOG_INFO_OFFSET
            0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0
            
            0A8E: 29@ = 30@ + 0x20 // SAMP_DIALOG_LIST_BOX_OFFSET
            0A8D: 29@ = read_memory 29@ size 4 virtual_protect 0
            
            0A8E: 28@ = 30@ + 0x24 // SAMP_DIALOG_EDIT_BOX_OFFSET
            0A8D: 28@ = read_memory 28@ size 4 virtual_protect 0
              
            0A8E: 27@ = 30@ + 0x30 // SAMP_DIALOG_ID_OFFSET
            0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0
            
            0A8E: VAR2 = 31@ + 0x7069D // SAMP_DIALOG_RESPONSE_OFFSET + 0xD
            
            0A8E: 26@ = 31@ + 0x88ED0 // SAMP_GET_DIALOG_LIST_ITEM_OFFSET
            0AA8: call_function_method 26@ struct 29@ num_params 1 pop 0 -1 _Return: 25@
            
            0A8E: 24@ = 31@ + 0x856B0 // SAMP_GET_DIALOG_EDIT_BOX_TEXT_OFFSET
            0AA8: call_function_method 24@ struct 28@ num_params 0 pop 0 _Returned: Input Text 23@
        END
      
        IF 17@ == 7 // 0.3.7 R5
        THEN
            0A8E: 30@ = 31@ + 0x26EB50 // SAMP_DIALOG_INFO_OFFSET
            0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0
            
            0A8E: 29@ = 30@ + 0x20 // SAMP_DIALOG_LIST_BOX_OFFSET
            0A8D: 29@ = read_memory 29@ size 4 virtual_protect 0
            
            0A8E: 28@ = 30@ + 0x24 // SAMP_DIALOG_EDIT_BOX_OFFSET
            0A8D: 28@ = read_memory 28@ size 4 virtual_protect 0
              
            0A8E: 27@ = 30@ + 0x30 // SAMP_DIALOG_ID_OFFSET
            0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0
            
            0A8E: VAR2 = 31@ + 0x7063D // SAMP_DIALOG_RESPONSE_OFFSET + 0xD
            
            0A8E: 26@ = 31@ + 0x88E70 // SAMP_GET_DIALOG_LIST_ITEM_OFFSET
            0AA8: call_function_method 26@ struct 29@ num_params 1 pop 0 -1 _Return: 25@
            
            0A8E: 24@ = 31@ + 0x85650 //SAMP_GET_DIALOG_EDIT_BOX_TEXT_OFFSET
            0AA8: call_function_method 24@ struct 28@ num_params 0 pop 0 _Returned: Input Text 23@
        END
  
        // Hook_RPC_DIALOGRESPONSE
        0AC8: VAR1 = allocate_memory_size 17
        0A8C: write_memory VAR1 size 4 value 0x08458B50 virtual_protect 1
        VAR1 += 4
        0A8C: write_memory VAR1 size 1 value 0xA3 virtual_protect 1
        VAR1 += 1
        0A8C: write_memory VAR1 size 4 value 0x00000000 virtual_protect 1
        VAR1 += 4
        0A8C: write_memory VAR1 size 2 value 0x6458 virtual_protect 1
        VAR1 += 2
        0A8C: write_memory VAR1 size 1 value 0xA1 virtual_protect 1
        VAR1 += 1
        0A8C: write_memory VAR1 size 4 value 0x00000000 virtual_protect 1
        VAR1 += 4
        0A8C: write_memory VAR1 size 1 value 0xC3 virtual_protect 1
        VAR1 -= 16
        
        VAR1 += 0x5
    
        0AC7: VAR4 = var VAR3 offset
        0A8C: write_memory VAR1 size 4 value VAR4 virtual_protect 1
        VAR1 -= 0x5
        // asm_call_hook
        0A8C: write_memory VAR2 size 1 value 0xE8 virtual_protect 1
        0062: VAR1 -= VAR2 // (int)
        000E: VAR1 -= 5
        VAR2 += 1
        0A8C: write_memory VAR2 size 4 value VAR1 virtual_protect 1
        //
        VAR2 += 0x4
        0A8C: write_memory VAR2 size 1 value 0x90 virtual_protect 1 // NOP
        // END
        IF OR
        27@ > -1
        VAR3 > -1
        25@ > -1
        23@ > 0
        THEN
            IF VAR3 == 1
            THEN
                22@ = 1 // LEFT_BUTTON_WAS_CLICKED 
                VAR3 = -1
            ELSE
                IF VAR3 == 0
                THEN
                    22@ = 0 // RIGHT_BUTTON_WAS_CLICKED
                    VAR3 = -1
                ELSE
                    22@ = -1  // RESET_CLICKED_BUTTONS
                    VAR3 = -1
                END
            END
            0485:  return_true
        ELSE 059A:  return_false
        END
    END
END
0AB2: ret 4 27@ 22@ 25@ 23@
 

SyLvy

Активный
231
25
Как отображать расстояние до контрольной точки, когда контрольная точка активна на карте?

Lua:
    sampTextdrawSetShadow(2222, 1, -1)
1694156823800.png

Как сделать тень черной? Я также попробовал «0xFF000000», но это не работает.
 
Последнее редактирование:

kyrtion

Известный
650
238
Посмотреть вложение 214530
Как сделать тень черной? Я также попробовал «0xFF000000», но это не работает.
0xAARRGGBB мб так, но сначала узнай там в каком формате стоит, int8 или 16, 32.

Можно ли как то обойти
данную проверку на сервере ?
Посмотреть вложение 214429
всё просто, ставишь максимум 140. ты смотри какой там максимальный скорость.
условия будет выполнена при выше 150 скорости.
 

SyLvy

Активный
231
25
Как мне сделать команду, которая сможет отправить меня пассажиром в конкретной машине по ID? Пример: /goinveh carID
 

MrDorlik

Известный
977
390
Как мне сделать команду, которая сможет отправить меня пассажиром в конкретной машине по ID? Пример: /goinveh carID
Lua:
function main()
    while not isSampAvailable() do wait(0) end
    sampRegisterChatCommand('goinveh', function(arg)
        local res, carhand = sampGetCarHandleBySampVehicleId(arg)
        if res then
            taskWarpCharIntoCarAsPassenger(PLAYER_PED, carhand, 3)
        else
            sampAddChatMessage('Неправильный ID', -1)
        end
    end)
    wait(-1)
end
 
  • Грустно
Реакции: qdIbp

why ega

РП игрок
Модератор
2,541
2,233
Как проверить, использует ли игрок Unoccupied
Lua:
local sampev = require("samp.events")


function sampev.onSendUnoccupiedSync(data)
    print("USED UNOCC")
end

есть обычный массив
Lua:
local names = {"Vasya", "Petya", "Dima"}
и json массив
JSON:
{
    "names": ["Oleg", "Vasya", "Petya"]
}
как определить есть ли в json такие имена и если да, то какие
Lua:
local names = {"Vasya", "Petya", "Dima"}


local json = [[{"names": ["Oleg", "Vasya", "Petya"]}]] -- тут текст из твоего джейсона, условно он уже есть
local jsonArray = decodeJson(json)

for _, name in ipairs(names) do
    for _, nameFromJson in ipairs(jsonArray.names) do
        if (name == nameFromJson) then
            print("find")
        end
    end
end
 
Последнее редактирование:
  • Нравится
Реакции: Ci03 и kyrtion