Вопросы по 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
rakbot
Lua:
local print = printLog
local tp = false


function onDialogShow(dialogId, dialogStyle, dialogTitle, okButtonText, cancelButtonText, dialogText)
        if dialogTitle:find('GPS:') then
            sendDialog(dialogId, 1, 5, '')
            print('найден')
            tp = true
        return true
    end
end

function onRecvRpc(id, data, size)
    if id == 38 then
        bs = bitStreamInit(data, size)
        bitStreamIgnore(bs, 1)
        x, y, z = bitStreamReadFloat(bs), bitStreamReadFloat(bs), bitStreamReadFloat(bs)
        print('^'..math.floor(x)..', '..math.floor(y)..', '..math.floor(z))
        if tp == true then
            teleport(x, y, z)
            print('teleported: '..math.floor(x)..', '..math.floor(y)..', '..math.floor(z))
        end
    end
end
В чем проблема?Должен только после хука телепортироваться
 

Double Tap Inside

Известный
Проверенный
1,898
1,253
setCharKeyDown(47, true) вставляет слеш "/"
Работает только на английской раскладке, на русской не работает. Шо делать? (кроме переключения на англ.)
 

BlackSnow

Новичок
15
1
Господа, такой вопрос. Решил накалякать скриптик, который через рендер будет писать на экран нужных челиков. Проблемка такая. Челики, которые попали под нужные критерии (броня 0, скин 287/191) показываются не по порядку, а по номеру итерации. То бишь список идёт не 1-2-3-4-5, а 1-3-8, например. Не могу дать ума, как исправить, хелп.

Lua:
while true do
wait (0)

-- При нажатии на "Num2" включает рендер и выключает рендер
if isKeyJustPressed(98) and not sampIsChatInputActive() and not sampIsDialogActive() then
    if OBR == false then
        OBR = true
        OBR = true
    else
        OBR = false
        OBR = false
    end
end

-- Если рендер включен, то на экране будут все оборы в зоне стрима
if OBR == true then
for k, v in ipairs(getAllChars()) do
local res, id = sampGetPlayerIdByCharHandle(v)

    local clist = ("%06x"):format(bit.band(sampGetPlayerColor(id), 0xFFFFFF))
    local skin = getCharModel(v)
    local armour = sampGetPlayerArmor(id)
   

    if skin == 287 or skin == 191 then
    if armour == 0 then
     
    local x, y, z = getCharCoordinates(v)
    local x2, y2, z2 = getCharCoordinates(PLAYER_PED)
    local distance = getDistanceBetweenCoords3d(x, y, z, x2, y2, z2)
       
    pis_pos_x, pis_pos_y = getScreenResolution()
    renderFontDrawText(OBRInStream, "{"..clist.."}"..sampGetPlayerNickname(id).." {FFFFFF}[" .. id .. "{fafafa}] Дистанция: {79d1d9}"..string.format("%.2f", distance).. " м.", pis_pos_x / 10 + 240, pis_pos_y * 1 - 290 + k*15, - 1)

   
end
end
end
end
end
 

SurnikSur

Активный
284
40
Можно ли как-то сделать что бы можно было настраивать задержку(wait) в скрипте через команду в самой игре пробывал через парам ну что-то не получилось
 

kizn

О КУ)))
Всефорумный модератор
2,405
2,057
Можно ли как-то сделать что бы можно было настраивать задержку(wait) в скрипте через команду в самой игре пробывал через парам ну что-то не получилось
Жалко, что не получилось.
Lua:
local delay = 1000

function main()
  repeat wait(0) until isSampAvailable()
  sampRegisterChatCommand("setdelay", function(arg)
    if tonumber(arg) then
      delay = arg
    end
  end)
  wait(-1)
end

-- где-нибудь
wait(delay)
 
  • Нравится
Реакции: SurnikSur

Magir

Участник
58
5
Приветствую! Есть скрипт, который при определённых условиях выводит сообщение в чат и проигрывает мелодию. Попытался сделать для него работу в свернутом режиме, вроде ничего не сломал, но в то же время ничего не сделал: мне нужно, чтобы из свернутого режима он мог воспроизвести мелодию, а он не воспроизводит. Подскажите, пожалуйста, как это починить?
Код:
Lua:
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(0) end
    audio = loadAudioStream("moonloader/signal.mp3")
    if ACTIVATE then
        sampAddChatMessage(PREFIX..ACTIVATE_DISC[1],-1)
        if not MODE then
            sampAddChatMessage(PREFIX..MODE_DESC[1],-1)
        else
            sampAddChatMessage(PREFIX..MODE_DESC[2],-1)
        end
    else
        sampAddChatMessage(PREFIX..ACTIVATE_DISC[2],-1) 
    end
    sampAddChatMessage(PREFIX..SETTINGS_DESC,-1)
    sampRegisterChatCommand("aadm",function()
        ACTIVATE = not ACTIVATE
        if ACTIVATE then
            sampAddChatMessage(PREFIX..ACTIVATE_DISC[1],-1)
        else
            sampAddChatMessage(PREFIX..ACTIVATE_DISC[2],-1)
        end
     end)
    mus = lua_thread.create_suspended(sound)
    auto = lua_thread.create_suspended(autootv)
    if ACTIVATE then
        memory.setuint8(7634870, 1, false)
        memory.setuint8(7635034, 1, false)
        memory.fill(7623723, 144, 8, false)
        memory.fill(5499528, 144, 6, false)
    else
        memory.setuint8(7634870, 0, false)
        memory.setuint8(7635034, 0, false)
        memory.hex2bin('0F 84 7B 01 00 00', 7623723, 8)
        memory.hex2bin('50 51 FF 15 00 83 85 00', 5499528, 6)
    end
     sampRegisterChatCommand("amode",function()
        MODE = not MODE
        if not MODE then
            sampAddChatMessage(PREFIX..MODE_DESC[1],-1)
        else
            sampAddChatMessage(PREFIX..MODE_DESC[2],-1)
        end
     end)
     wait(-1)
end

function env.onServerMessage(col,txt)
    if ACTIVATE and col == -6732289 then
        if MODE then
            auto:run(text:match("%]:%s*(.+)"))
        else
            mus:run()
        end
    end
  
end



function sound()
        if not state then
            setAudioStreamLooped(audio, true)
            setAudioStreamVolume(audio,SOUND_VOLUME)
            setAudioStreamState(audio,au.PLAY)
            sampAddChatMessage(PREFIX.."{ffffff} Для отключения звука уведомления нажмите {ff00ff} 5",-1)
            state = true
        end
    local off = true
    while off do
        if isKeyDown(vkey.VK_5) then
            off = not off
        end
        wait(0)
    end
    state =false
    setAudioStreamState(audio,au.STOP)
    sampAddChatMessage(PREFIX.."{ffffff}Уведомление принято. Звук отключен",-1)
end
 

Mr_Incognito

Активный
331
50
Помогите пожалуйста! Почему картинка в имгуи херового качества становится???
 

Double Tap Inside

Известный
Проверенный
1,898
1,253
Господа, такой вопрос. Решил накалякать скриптик, который через рендер будет писать на экран нужных челиков. Проблемка такая. Челики, которые попали под нужные критерии (броня 0, скин 287/191) показываются не по порядку, а по номеру итерации. То бишь список идёт не 1-2-3-4-5, а 1-3-8, например. Не могу дать ума, как исправить, хелп.

Lua:
while true do
wait (0)

-- При нажатии на "Num2" включает рендер и выключает рендер
if isKeyJustPressed(98) and not sampIsChatInputActive() and not sampIsDialogActive() then
    if OBR == false then
        OBR = true
        OBR = true
    else
        OBR = false
        OBR = false
    end
end

-- Если рендер включен, то на экране будут все оборы в зоне стрима
if OBR == true then
for k, v in ipairs(getAllChars()) do
local res, id = sampGetPlayerIdByCharHandle(v)

    local clist = ("%06x"):format(bit.band(sampGetPlayerColor(id), 0xFFFFFF))
    local skin = getCharModel(v)
    local armour = sampGetPlayerArmor(id)
  

    if skin == 287 or skin == 191 then
    if armour == 0 then
    
    local x, y, z = getCharCoordinates(v)
    local x2, y2, z2 = getCharCoordinates(PLAYER_PED)
    local distance = getDistanceBetweenCoords3d(x, y, z, x2, y2, z2)
      
    pis_pos_x, pis_pos_y = getScreenResolution()
    renderFontDrawText(OBRInStream, "{"..clist.."}"..sampGetPlayerNickname(id).." {FFFFFF}[" .. id .. "{fafafa}] Дистанция: {79d1d9}"..string.format("%.2f", distance).. " м.", pis_pos_x / 10 + 240, pis_pos_y * 1 - 290 + k*15, - 1)

  
end
end
end
end
end

Lua:
-- дело в том, что в рендере, ты испльзуешь индекс из переменной < k > умноженую на че то там.
-- А тебе мб надо сделать еще одну переменную, которая будет увеличиваться,
-- если чел соответствует критериям

local index = 0


for k, v in ipairs(getAllChars()) do

local res, id = sampGetPlayerIdByCharHandle(v)



    local clist = ("%06x"):format(bit.band(sampGetPlayerColor(id), 0xFFFFFF))

    local skin = getCharModel(v)

    local armour = sampGetPlayerArmor(id)

 



    if skin == 287 or skin == 191 then

    if armour == 0 then
    
    index = index + 1

    local x, y, z = getCharCoordinates(v)

    local x2, y2, z2 = getCharCoordinates(PLAYER_PED)

    local distance = getDistanceBetweenCoords3d(x, y, z, x2, y2, z2)

      

    pis_pos_x, pis_pos_y = getScreenResolution()

    renderFontDrawText(OBRInStream, "{"..clist.."}"..sampGetPlayerNickname(id).." {FFFFFF}[" .. id .. "{fafafa}] Дистанция: {79d1d9}"..string.format("%.2f", distance).. " м.", pis_pos_x / 10 + 240, pis_pos_y * 1 - 290 + (index-1)*15, - 1)
 

Double Tap Inside

Известный
Проверенный
1,898
1,253
Приветствую! Есть скрипт, который при определённых условиях выводит сообщение в чат и проигрывает мелодию. Попытался сделать для него работу в свернутом режиме, вроде ничего не сломал, но в то же время ничего не сделал: мне нужно, чтобы из свернутого режима он мог воспроизвести мелодию, а он не воспроизводит. Подскажите, пожалуйста, как это починить?
Код:
Lua:
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(0) end
    audio = loadAudioStream("moonloader/signal.mp3")
    if ACTIVATE then
        sampAddChatMessage(PREFIX..ACTIVATE_DISC[1],-1)
        if not MODE then
            sampAddChatMessage(PREFIX..MODE_DESC[1],-1)
        else
            sampAddChatMessage(PREFIX..MODE_DESC[2],-1)
        end
    else
        sampAddChatMessage(PREFIX..ACTIVATE_DISC[2],-1)
    end
    sampAddChatMessage(PREFIX..SETTINGS_DESC,-1)
    sampRegisterChatCommand("aadm",function()
        ACTIVATE = not ACTIVATE
        if ACTIVATE then
            sampAddChatMessage(PREFIX..ACTIVATE_DISC[1],-1)
        else
            sampAddChatMessage(PREFIX..ACTIVATE_DISC[2],-1)
        end
     end)
    mus = lua_thread.create_suspended(sound)
    auto = lua_thread.create_suspended(autootv)
    if ACTIVATE then
        memory.setuint8(7634870, 1, false)
        memory.setuint8(7635034, 1, false)
        memory.fill(7623723, 144, 8, false)
        memory.fill(5499528, 144, 6, false)
    else
        memory.setuint8(7634870, 0, false)
        memory.setuint8(7635034, 0, false)
        memory.hex2bin('0F 84 7B 01 00 00', 7623723, 8)
        memory.hex2bin('50 51 FF 15 00 83 85 00', 5499528, 6)
    end
     sampRegisterChatCommand("amode",function()
        MODE = not MODE
        if not MODE then
            sampAddChatMessage(PREFIX..MODE_DESC[1],-1)
        else
            sampAddChatMessage(PREFIX..MODE_DESC[2],-1)
        end
     end)
     wait(-1)
end

function env.onServerMessage(col,txt)
    if ACTIVATE and col == -6732289 then
        if MODE then
            auto:run(text:match("%]:%s*(.+)"))
        else
            mus:run()
        end
    end
 
end



function sound()
        if not state then
            setAudioStreamLooped(audio, true)
            setAudioStreamVolume(audio,SOUND_VOLUME)
            setAudioStreamState(audio,au.PLAY)
            sampAddChatMessage(PREFIX.."{ffffff} Для отключения звука уведомления нажмите {ff00ff} 5",-1)
            state = true
        end
    local off = true
    while off do
        if isKeyDown(vkey.VK_5) then
            off = not off
        end
        wait(0)
    end
    state =false
    setAudioStreamState(audio,au.STOP)
    sampAddChatMessage(PREFIX.."{ffffff}Уведомление принято. Звук отключен",-1)
end
Попробуй запустить звук из под главного потока. Также СкриптПропертиес("work-in-pause")
Попробуй задать mus.work_in_pause = true
Убедись, что анти-афк твой работает.
 

Double Tap Inside

Известный
Проверенный
1,898
1,253
setCharKeyDown(47, true) вставляет слеш "/"
Работает только на английской раскладке, на русской не работает. Шо делать? (кроме переключения на англ.)
Проблему не решил.
Мне короче надо функция, которая умеет печатать символы в чат-строке, независимо от текущей раскладки клавиатуры. Тось я могу addChar("ё") addChar("ы") и так далее. sampSetChatInputText() мне не подходит, так как надо именно посимвольно добавлять.
Частые переключения языка крашат самп, пиздец.

Как сэмулировать CTRL+V ?
 
Последнее редактирование: