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

ARMOR

Waitin' on another black summer to end
Модератор
5,050
7,251
Посмотреть вложение 247694
Есть ли скрипт который убирает эту фигню?
Для R1
Lua:
function enableClassSelection(bValue) -- 1 или 0, true/false не подойдёт
    local pClassSelection = memory.getuint32(samp + 0x21A18C, true)
    memory.setint8(pClassSelection + 0x13, bValue, true)
end

Пример кода:
Lua:
local memory = require('memory')
local samp = getModuleHandle("samp.dll")
local bEnable = true;
function enableClassSelection(bValue)
    local pClassSelection = memory.getuint32(samp + 0x21A18C, true)
    memory.setint8(pClassSelection + 0x13, bValue, true)
end
function main()
    while not isSampAvailable() do wait(0) end
    while true do
        wait(0)
        if wasKeyPressed(49) then
            bEnable = not bEnable
            enableClassSelection(bEnable and 1 or 0)
        end
    end 
end
 
  • Нравится
Реакции: вайега52 и Samirca

chromiusj

fullstack eblan
Модератор
5,816
4,108
Если я хочу написать скрипт и выложить его, то как сделать код закрытым в .luac формате?
 
  • Нравится
Реакции: Samirca

fibagr123

Известный
20
2
imgui addon hotkey не дает зарегать бинд через лкм или пкм, а обычные клавиши a-z и 0-9 только по одной. Парный бинд получается только с шифтом, альтом и контролом.
Lua:
local binder = {
    {text = imgui.ImBuffer('first', 256), state = imgui.ImBool(false), keys = {v = {VK_RBUTTON, VK_1}}},
    {text = imgui.ImBuffer('second', 256), state = imgui.ImBool(false), keys = {v = {VK_RBUTTON, VK_2}}},
    {text = imgui.ImBuffer('third', 256), state = imgui.ImBool(false), keys = {v = {VK_RBUTTON, VK_3}}}
}
local tLastKeys = {}

-- main()
for i = 1, #binder do
        binder[i].bind = rkeys.registerHotKey(binder[i].keys.v, true, function ()
            sampAddChatMessage(binder[i].text.v, -1)
        end)
    end
-- OnDramFrame()
for i = 1, #binder do
            if binder[i] then
                imgui.ToggleButton('##toggleBinder' .. i, binder[i].state)
                imgui.SameLine()
                imgui.PushItemWidth(400)
                imgui.InputText('##test' .. i, binder[i].text)
                imgui.PopItemWidth()
                imgui.SameLine()
                if imgui.HotKey('##' .. i, binder[i].keys, tLastKeys, 100) then
                    rkeys.changeHotKey(binder[i].bind, binder[i].keys.v)
                end
                imgui.SameLine()
                if imgui.Button(u8'Удалить' .. '##' .. i) and #binder > 1 then
                    table.remove(binder, i)
                end
            end
        end
 

qdIbp

Автор темы
Проверенный
1,451
1,194
imgui addon hotkey не дает зарегать бинд через лкм или пкм, а обычные клавиши a-z и 0-9 только по одной. Парный бинд получается только с шифтом, альтом и контролом.
Lua:
local binder = {
    {text = imgui.ImBuffer('first', 256), state = imgui.ImBool(false), keys = {v = {VK_RBUTTON, VK_1}}},
    {text = imgui.ImBuffer('second', 256), state = imgui.ImBool(false), keys = {v = {VK_RBUTTON, VK_2}}},
    {text = imgui.ImBuffer('third', 256), state = imgui.ImBool(false), keys = {v = {VK_RBUTTON, VK_3}}}
}
local tLastKeys = {}

-- main()
for i = 1, #binder do
        binder[i].bind = rkeys.registerHotKey(binder[i].keys.v, true, function ()
            sampAddChatMessage(binder[i].text.v, -1)
        end)
    end
-- OnDramFrame()
for i = 1, #binder do
            if binder[i] then
                imgui.ToggleButton('##toggleBinder' .. i, binder[i].state)
                imgui.SameLine()
                imgui.PushItemWidth(400)
                imgui.InputText('##test' .. i, binder[i].text)
                imgui.PopItemWidth()
                imgui.SameLine()
                if imgui.HotKey('##' .. i, binder[i].keys, tLastKeys, 100) then
                    rkeys.changeHotKey(binder[i].bind, binder[i].keys.v)
                end
                imgui.SameLine()
                if imgui.Button(u8'Удалить' .. '##' .. i) and #binder > 1 then
                    table.remove(binder, i)
                end
            end
        end
попробуй
 

fibagr123

Известный
20
2
попробуй
Проблемы именно в регистрации, а не использование. Если первой клавишей является a-z 0-9, то сразу происходит регистрации без возможности добавления второй клавиши

попробуй
Написал разрабу, оказалось это так и должно быть
 
Последнее редактирование:
  • Вау
Реакции: qdIbp

uvie

Известный
274
54
How could I adjust the script I have? it should show a FOR SALE house, when it is for sale, it should just show TRACER until this model mark, when driving the car between houses, it should show which house is for sale and which house has FOR SALE on the roof.
Wu0gwqL.png



Lua:
require 'lib.moonloader'
pcall(require, 'sflua')

local text-size = 11
local font = renderCreateFont("arial black", textsize)

function main()
 while not isSampAvailable() do
 waiting(0)
 end

 while true do
 waiting(0)

 for i = 1, 1000 do
 local obj = sampGetObjectHandleBySampId(i)
 if doesObjectExist(obj) then
 local res, x, y, z = getObjectCoordinates(obj)
 if res then
 local objmodel = getObjectModel(obj)
 if objmodel == 19470 then
 local px, py, pz = getCharCoordinates(PLAYER_PED)
 local rad = getDistanceBetweenCoords3d(px, py, pz, x, y, z)
 if rad <= 1000 then
 local onScreen, cx, cy = convert3DCoordsToScreen(x, y, z)
 if onScreen then
 renderFontDrawText(font, "{FF0000}FOR SALE", cx, cy, 0xFFBEBEBE)
 end
 end
 end
 end
 end
 end
 end
end

19470 model ID > model ID is in my LUA but it doesnt show up text on my screen when im nearby to house who has FOR SALE thing on roof.
 

fokichevskiy

Известный
502
295
How could I adjust the script I have? it should show a FOR SALE house, when it is for sale, it should just show TRACER until this model mark, when driving the car between houses, it should show which house is for sale and which house has FOR SALE on the roof.
Посмотреть вложение 247862


Lua:
require 'lib.moonloader'
pcall(require, 'sflua')

local text-size = 11
local font = renderCreateFont("arial black", textsize)

function main()
 while not isSampAvailable() do
 waiting(0)
 end

 while true do
 waiting(0)

 for i = 1, 1000 do
 local obj = sampGetObjectHandleBySampId(i)
 if doesObjectExist(obj) then
 local res, x, y, z = getObjectCoordinates(obj)
 if res then
 local objmodel = getObjectModel(obj)
 if objmodel == 19470 then
 local px, py, pz = getCharCoordinates(PLAYER_PED)
 local rad = getDistanceBetweenCoords3d(px, py, pz, x, y, z)
 if rad <= 1000 then
 local onScreen, cx, cy = convert3DCoordsToScreen(x, y, z)
 if onScreen then
 renderFontDrawText(font, "{FF0000}FOR SALE", cx, cy, 0xFFBEBEBE)
 end
 end
 end
 end
 end
 end
 end
end

19470 model ID > model ID is in my LUA but it doesnt show up text on my screen when im nearby to house who has FOR SALE thing on roof.
You can search for houses for sale using 3d text
Lua:
    while true do
        for i = 0, 2048 do
            if sampIs3dTextDefined(i) then
                local text, color, x, y, z, distance, ignoreWalls, playerId, vehicleId = sampGet3dTextInfoById(i)
                local myX, myY, myZ = getCharCoordinates(PLAYER_PED)
                local distance = getDistanceBetweenCoords3d(myX, myY, myZ, x, y, z)
                if text:find('Kaina') then
                    if isPointOnScreen(x, y, z, 0.2) then
                        if distance < 100 then
                                local tdX, tdY = convert3DCoordsToScreen(x, y, z)
                                local tdMyX, tdMyY = convert3DCoordsToScreen(myX, myY, myZ)
                                renderDrawLine(tdMyX, tdMyY, tdX, tdY, 1, 0xffcc66ff)
                            end
                        end
                    end
                end
            end
        end
        wait(0)
    end
 
  • Нравится
Реакции: uvie

uvie

Известный
274
54
You can search for houses for sale using 3d text
Lua:
    while true do
        for i = 0, 2048 do
            if sampIs3dTextDefined(i) then
                local text, color, x, y, z, distance, ignoreWalls, playerId, vehicleId = sampGet3dTextInfoById(i)
                local myX, myY, myZ = getCharCoordinates(PLAYER_PED)
                local distance = getDistanceBetweenCoords3d(myX, myY, myZ, x, y, z)
                if text:find('Kaina') then
                    if isPointOnScreen(x, y, z, 0.2) then
                        if distance < 100 then
                                local tdX, tdY = convert3DCoordsToScreen(x, y, z)
                                local tdMyX, tdMyY = convert3DCoordsToScreen(myX, myY, myZ)
                                renderDrawLine(tdMyX, tdMyY, tdX, tdY, 1, 0xffcc66ff)
                            end
                        end
                    end
                end
            end
        end
        wait(0)
    end
I'm trying to do it without it

You can search for houses for sale using 3d text
Lua:
    while true do
        for i = 0, 2048 do
            if sampIs3dTextDefined(i) then
                local text, color, x, y, z, distance, ignoreWalls, playerId, vehicleId = sampGet3dTextInfoById(i)
                local myX, myY, myZ = getCharCoordinates(PLAYER_PED)
                local distance = getDistanceBetweenCoords3d(myX, myY, myZ, x, y, z)
                if text:find('Kaina') then
                    if isPointOnScreen(x, y, z, 0.2) then
                        if distance < 100 then
                                local tdX, tdY = convert3DCoordsToScreen(x, y, z)
                                local tdMyX, tdMyY = convert3DCoordsToScreen(myX, myY, myZ)
                                renderDrawLine(tdMyX, tdMyY, tdX, tdY, 1, 0xffcc66ff)
                            end
                        end
                    end
                end
            end
        end
        wait(0)
    end
Lua:
function main()
    while not isSampAvailable() do
        wait(0)
    end

    while true do
        wait(0)

        for i = 0, 2048 do
            if sampIs3dTextDefined(i) then
                local text, color, x, y, z, distance, ignoreWalls, playerId, vehicleId = sampGet3dTextInfoById(i)
                local myX, myY, myZ = getCharCoordinates(PLAYER_PED)
                local distance = getDistanceBetweenCoords3d(myX, myY, myZ, x, y, z)
                if text:find('Kaina') then
                    if isPointOnScreen(x, y, z, 0.2) then
                        if distance < 100 then
                            local tdX, tdY = convert3DCoordsToScreen(x, y, z)
                            local tdMyX, tdMyY = convert3DCoordsToScreen(myX, myY, myZ)
                            renderDrawLine(tdMyX, tdMyY, tdX, tdY, 1, 0xffcc66ff)
                        end
                    end
                end
            end
        end
    end
end

[20:30:59.542789] (error) plest_xatas.lua: C:\Users\User\Desktop\SA\moonloader\plest_xatas.lua:2: attempt to call global 'isSampAvailable' (a nil value)
stack traceback:
C:\Users\User\Desktop\SA\moonloader\plest_xatas.lua: in function <C:\Users\User\Desktop\SA\moonloader\plest_xatas.lua:1>
[20:30:59.542789] (error) plest_xatas.lua: Script died due to an error. (1911E96C)
 
Последнее редактирование:

[SA ARZ]

Известный
394
8
Подскажите, как сделать чтоб удалял все по порядку и не быстро, каждое удаление 300 мс и писало, после сохранял таблицу


код:
sampRegisterChatCommand('cleardesc', function(args)
       if #list_punish > 0 then
            for k, txt in ipairs(list_punish) do
                if get_online_players(txt[k][1], 'status') == '{00FF00}В игре' then
                    sampAddChatMessage('{FFA500}[LRD] {F5FFFA}Запись {00FF00}'..i..' ('..txt[k][1]..') {F5FFFA}удалена!', 0xF5FFFA)
                    table.remove(list_punish, k)
                end
            end
        end
        jsonSave(list_punish)
    end)
help
 

RaMero

Известный
436
126
Как сделать проверку на состояние радара? Скрытый, или видемый?
 

chromiusj

fullstack eblan
Модератор
5,816
4,108
Как сделать проверку на состояние радара? Скрытый, или видемый?
Lua:
function checkRadarMode()
    local mode = ffi.cast("uint8_t*", 0xBA6748 + 0x24)
    if mode[0] == 0 then
        print("радар включен")
    elseif mode[0] == 1 then
        print("ток иконки")
    elseif mode[0] == 2 then
        print("радар выключен")
    end
end
если ты про переключение в настройках
 
  • Вау
  • Нравится
Реакции: Corenale и RaMero

Baika

Участник
56
33
Помогите мне чайнику, как сделать так чтобы после того как бот достиг координат 3 д текста он бежал на обычные координаты например такие: -104.59384918213 99.912292480469 и так по кругу
Lua:
function main()
    while not isSampAvailable() do wait(0) end
    sampRegisterChatCommand("fan",function () act = not act sampAddChatMessage(act and "Активирован" or "Деактивирован",-1 )end)
    while true do wait(0)
        for id = 0, 2048 do
            if sampIs3dTextDefined(id) then
                local text, _, x, y, _, _, _, _, _ = sampGet3dTextInfoById(id)
                if text:find("Куст") and act then
                    runToPoint(x,y)
                end
             
            end
        end
       
    end
end


function runToPoint(tox, toy)
    local x, y, z = getCharCoordinates(PLAYER_PED)
    local angle = getHeadingFromVector2d(tox - x, toy - y)
    local xAngle = math.random(-50, 50)/100
    setCameraPositionUnfixed(xAngle, math.rad(angle - 90))
    stopRun = false
    while getDistanceBetweenCoords2d(x, y, tox, toy) > 0.8 and act  do
        result, text, color, posX, posY, posZ, distance, ignoreWalls, player, vehicle = Search3Dtext(x, y, z, 3, "Куст")
        if result then
            break
        end
       
        setGameKeyState(1, -255)
        setGameKeyState(16, 1)
        wait(1)
        x, y, z = getCharCoordinates(PLAYER_PED)
        angle = getHeadingFromVector2d(tox - x, toy - y)
        setCameraPositionUnfixed(xAngle, math.rad(angle - 90))
        if stopRun then
            stopRun = false
            break
        end
    end
end
function Search3Dtext(x, y, z, radius, patern)
    local text = ""
    local color = 0
    local posX = 0.0
    local posY = 0.0
    local posZ = 0.0
    local distance = 0.0
    local ignoreWalls = false
    local player = -1
    local vehicle = -1
    local result = false

    for id = 0, 2048 do
        if sampIs3dTextDefined(id) then
            local text2, color2, posX2, posY2, posZ2, distance2, ignoreWalls2, player2, vehicle2 = sampGet3dTextInfoById(id)
            if getDistanceBetweenCoords3d(x, y, z, posX2, posY2, posZ2) < radius then
               
                if string.len(patern) ~= 0 then
                    if string.match(text2, patern, 0) ~= nil then result = true end
                else
                    result = true
                end
                if result then
                    text = text2
                    color = color2
                    posX = posX2
                    posY = posY2
                    posZ = posZ2
                    distance = distance2
                    ignoreWalls = ignoreWalls2
                    player = player2
                    vehicle = vehicle2
                    radius = getDistanceBetweenCoords3d(x, y, z, posX, posY, posZ)
                end
            end
        end
    end

    return result, text, color, posX, posY, posZ, distance, ignoreWalls, player, vehicle
end
 

uvie

Известный
274
54

in the video, you can see how a green tracer appears and tracer numbers at the end, [machines] this is the work of thieves, while driving, the thief must find a certain hidden machine, would it be possible to reproduce the same tracer? 2. Find By car number plate
How i can make it? I only have 2 snipperS

Lua:
:SAMPGetCarNumberPlateByVehicleID

{
    0.3.7 - R5

    0AB1: @SAMPGetCarNumberPlateByVehicleID 1 VehicleID 1249 _Returned: NumberPlate 0@
}
IF 0AA2: 10@ = "samp.dll"
THEN
    10@ += 0x26EB94 // SAMP_INFO_OFFSET
    0A8D: 10@ readMem 10@ sz 4 vp 0
    10@ += 0x3DE // SAMP_PPOOLS_OFFSET
    0A8D: 10@ readMem 10@ sz 4 vp 0
    10@ += 0x0 // SAMP_PPOOL_VEHICLE_OFFSET
    0A8D: 10@ readMem 10@ sz 4 vp 0
    0@ *= 0x4 // VEHICLE_ID * 0x14
    0@ += 0x1134
    005A: 10@ += 0@
    0A8D: 10@ = readMem 10@ sz 4 vp 0
    10@ += 0x93 // SAMP_VEHICLE_NUMBER_PLATE_OFFSET
    0A8D: 4@ = readMem 10@ sz 1 vp 0
    IF 4@ > 0
    THEN 0485:  return_true
    ELSE
        059A:  return_false
        10@ = 0
    END
END
0AB2: ret 1 10@



Lua:
:SAMPGetVehicleIDbyCarHandle // if 0AB1: @SAMPGetVehicleIDbyCarHandle 1 _OfCarHandle 0@ _StoreVehicleID 29@
if 0AA2: 31@ = load_dynamic_library "samp.dll" // pSAMPBase // no need to Free Memory
then
    31@ += 0x26EB94
    0A8D: 31@ = read_memory 31@ size 4 virtual_protect 0 // stSAMPInfo
    if 31@ > 0
    then
        31@ += 0x3DE
        0A8D: 31@ = read_memory 31@ size 4 virtual_protect 0 // stSAMPPools
        if 31@ > 0
        then
            31@ += 0x0
            0A8D: 31@ = read_memory 31@ size 4 virtual_protect 0 // stVehiclePool
            if 31@ > 0
            then
                0A97: 30@ = vehicle 0@ struct
                for 29@ = 0 to 8000 step 4 // vehicle index = max vehicle * 4 = 2000 * 4
                    0A8E: 28@ = 29@ + 31@
                    0A8E: 27@ = 28@ + 0x3074
                    0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0 // iIsListed
                    if 27@ > 0
                    then
                        0A8E: 27@ = 28@ + 0x1134
                        0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0 // pSAMP_Vehicle
                        if 27@ > 0
                        then
                            27@ += 0x4C
                            0A8D: 26@ = read_memory 27@ size 4 virtual_protect 0 // pGTA_Vehicle
                            if 003B: 26@ == 30@  // our vehicle matched
                            then
                                29@ /= 4
                                0485:  return_true
                                ret 1 29@ // I now Got the Vehicle ID
                            end
                        end
                    end
                end
            end
        end
    end
end
059A:  return_false
ret 1 -1 // null Vehicle ID





Lua:
function FindVehicleByNumberPlate(targetNumberPlate)
    local sampDLL = loadLibrary("samp.dll")
    if sampDLL then
        local stSAMPInfo = readMemory(sampDLL + 0x26EB94, 4)
        if stSAMPInfo > 0 then
            local stSAMPPools = readMemory(stSAMPInfo + 0x3DE, 4)
            if stSAMPPools > 0 then
                local stVehiclePool = readMemory(stSAMPPools + 0x0, 4)
                if stVehiclePool > 0 then
                    for i = 0, 2000 do
                        local vehicleIndex = i * 4
                        local vehicleAddr = readMemory(stVehiclePool + vehicleIndex + 0x1134, 4)
                        if vehicleAddr > 0 then
                            local numberPlate = readMemory(vehicleAddr + 0x93, 1)
                            if numberPlate == targetNumberPlate then
                                return vehicleAddr
                            end
                        end
                    end
                end
            end
        end
    end
    return nil
end

function CreateTracerToVehicle(vehicleAddr)
    if vehicleAddr then
        local vehiclePosition = GetVehiclePosition(vehicleAddr)
        local playerPosition = GetPlayerPosition()
        if vehiclePosition and playerPosition then
            local direction = {
                x = vehiclePosition.x - playerPosition.x,
                y = vehiclePosition.y - playerPosition.y,
                z = vehiclePosition.z - playerPosition.z
            }

            local magnitude = math.sqrt(direction.x^2 + direction.y^2 + direction.z^2)
            direction.x = direction.x / magnitude
            direction.y = direction.y / magnitude
            direction.z = direction.z / magnitude

            RenderTracer(playerPosition, direction, "green", magnitude)
        end
    else
        print("Vehicle not found.")
    end
end

local numberPlateToFind = "ABC123"
local vehicleAddress = FindVehicleByNumberPlate(numberPlateToFind)

if vehicleAddress then
    CreateTracerToVehicle(vehicleAddress)
else
    print("Vehicle with number plate ".. numberPlateToFind .." not found.")
end
 

Вложения

  • image.png
    image.png
    204.9 KB · Просмотры: 15
  • Эм
Реакции: Baika