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

fsrxvdd

Активный
282
70
У кого есть код на луа на ввод команды по нажатию клавиши пример на L /flock /lock?
Lua:
function main()
    repeat wait(0) until isSampAvailable()
    while true do
        wait(0)
        if isKeyJustPressed(76) and not sampIsChatInputActive() and not sampIsDialogActive() then
            sampSendChat("/lock")
        end
    end
end
если надо измени команду на /flock

подскажите плиз, как сделать так, чтобы при возникновении диалога под айди к примеру 1488, скрипт автоматически выбирал 5-й пункт и нажимал "далее"?
 
Последнее редактирование:
  • Эм
Реакции: qdIbp

Naito

Активный
166
36
что именно ты хочешь сделать прозрачным? или полностью отключить отрисовку чата?
Make it a little transparent, something like this code but for the chat::

Code:
local ffi = require("ffi")

function SetRwObjectAlpha(handle, alpha)
    local pedEn = getCharPointer(handle)
    if pedEn ~= 0 then
        ffi.cast("void (__thiscall *)(int, int)", 0x5332C0)(pedEn, alpha)
    end
end

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

    while true do
        wait(0)
        SetRwObjectAlpha(playerPed, 100)
    end
end
 

Winstаl

Известный
1,002
414
Make it a little transparent, something like this code but for the chat::

Code:
local ffi = require("ffi")

function SetRwObjectAlpha(handle, alpha)
    local pedEn = getCharPointer(handle)
    if pedEn ~= 0 then
        ffi.cast("void (__thiscall *)(int, int)", 0x5332C0)(pedEn, alpha)
    end
end

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

    while true do
        wait(0)
        SetRwObjectAlpha(playerPed, 100)
    end
end
https://www.blast.hk/threads/13380/post-599831
 

kyrtion

Известный
1,320
485
она уже 1251, но всё равно не работает. Возможно это из за дебагера? Подскажите кто как выводит скрипт.
попробуй это:

Убедись что в твоем скрипте не связанно с MoonLoader иначе сообщит ошибку что такой нет функи вроде wait(...), sampSendChat(...)
затем добавить каталог luajit в патч, как примет в силу, то в кмд пишешь luajit test.lua и выполнит работу
 

fsrxvdd

Активный
282
70
подскажите плиз, как сделать так, чтобы при возникновении диалога под айди к примеру 1488, скрипт автоматически выбирал 5-й пункт и нажимал "далее"?
 

kyrtion

Известный
1,320
485
подскажите плиз, как сделать так, чтобы при возникновении диалога под айди к примеру 1488, скрипт автоматически выбирал 5-й пункт и нажимал "далее"?
все просто
Подробнее - sampSendDialogResponse

Lua:
подскажите плиз, как сделать так, чтобы при возникновении диалога под айди к примеру 1488,
скрипт автоматически выбирал 5-й пункт и нажимал "далее"?

local sampev = require 'samp.events'

function sampev.onShowDialog(dialogId, style, title, button1, button2, text)
    if dialogId == 1488 and style == ?? then
        -- sampSendDialogResponse(int dialogId, int button, int listitem, zstring input)
        sampSendDialogResponse(1488, 1, 4, "")
        -- listitem = начиная с 0, если нужно указать пункт 5, то отнимаем на -1
        -- button 1 = Левая кнопка как ОК
        -- button 0 = Правая кнопка как Отмена/Назад
        return false -- не показываем диалог в игре
    end
end
 
  • Нравится
Реакции: fsrxvdd

Fr3sH_HP

Новичок
5
0
Посмотреть вложение 257140
как собрать лицензионные часы (например, водительские права: 124 Hours) и отобразить их в чате? пример:
КОМАНДА: /checklic <имя пользователя> ; информацию возьмите отсюда: https://www.rpg.b-zone.ro/players/general/Username
Отобразите их в чате следующим образом:
Driving: 124 ; Flying: 70; Sailing: 70; ETC
 

chromiusj

модерирую шмодерирую
Модератор
5,953
4,285
Посмотреть вложение 257140
как собрать лицензионные часы (например, водительские права: 124 Hours) и отобразить их в чате? пример:
КОМАНДА: /checklic <имя пользователя> ; информацию возьмите отсюда: https://www.rpg.b-zone.ro/players/general/Username
Отобразите их в чате следующим образом:
Driving: 124 ; Flying: 70; Sailing: 70; ETC
Ну используй это
И регулярками вытягивай че тебе надо
 

llistenok

Известный
89
27
Это дамаг информер, все цвета ников нормальные кроме белых - их рендерит полупрозрачными слабочитаемыми
Может кто-нибудь отредачить, чтобы убрать прозрачность?

Lua:
--******[ Описание Скрипта ]*******
script_authors('Leon4ik')
script_version('1.4')
script_version_number(2)
--******[ Библиотеки ]*******
require ('lib.moonloader')
local sampev = require ('lib.samp.events')
local vkeys = require ('vkeys')
local inicfg = require ('inicfg')
-- Inicfg
local ini = "DamageInformer/settings.ini"
local mainini = inicfg.load(nil, ini)
if mainini == nil then
    main =  {
        main =
        {
            nicks = true,
            takedamage = true,
            givedamage = true,
            TDx = 700,
            TDy = 450,
            GDx = 1100,
            GDy = 450,
            kolokol=true,
            volume=1
        }
    }
        inicfg.save(main, ini)
        mainini = inicfg.load(nil, ini)
end
-- variables
local font = renderCreateFont("Arial Black", 13, 12)
local font2 = renderCreateFont("Libre Sans", 18, 13)
local TID = nil
local GID = nil
local TakeDamage = nil
local GiveDamage = nil
local combo = {}
local Render_y = mainini.main.GDy
local Render_y2 = mainini.main.TDy
local active = false
local shara = nil
local mode, mode2 = false, false

for i=0,1000 do
    table.insert(combo, {0,nil})
end

local Texts = {"Обосран","Выебан","Опущен","Унижен"}

function main()
    while not isSampAvailable() do wait(100) end
    repeat wait(0) until sampIsLocalPlayerSpawned()
    sampAddChatMessage('[{1E90FF}DMGInformer{FFFFFF}] Author:{42aaff} Leon4ik{FFFFFF}. /dmgi', -1)
    
    sampRegisterChatCommand("dmgi",function()
        sampAddChatMessage("[{1E90FF}DMGInformer{FFFFFF}]:",-1)
        sampAddChatMessage("{1E90FF}/dmgtake{FFFFFF} - включить/выключить полученный урон",-1)
        sampAddChatMessage("{1E90FF}/dmggive{FFFFFF} - включить/выключить наносимый урон",-1)
        sampAddChatMessage("{1E90FF}/dmgnick{FFFFFF} - включить/выключить ники",-1)
        sampAddChatMessage("{1E90FF}/dmgkol{FFFFFF} - включить/выключить колокол",-1)
        sampAddChatMessage("{1E90FF}/dmgkolv{FFFFFF} - Сменить громкость колокола от 0 до 100",-1)
        sampAddChatMessage("{1E90FF}/dmgс 1-2{FFFFFF} - Сменить положение Получаемого[1] или Наносимого[2] урона",-1)
    end)
    sampRegisterChatCommand("dmgс",function(arg)
        if tonumber(arg) == 1 then
            set()
        elseif tonumber(arg) == 2 then
            set2()
        else
            sampAddChatMessage('[{1E90FF}DMGInformer{FFFFFF}]: Неправильный режим. Нужно 1 или 2.',-1)
        end
    end)
    sampRegisterChatCommand("dmgkolv",function(arg)
        if type(tonumber(arg)) == 'number' then
            if tonumber(arg) > 0 and tonumber(arg) < 101 then
                sampAddChatMessage(mainini.main.takedamage and '[{1E90FF}DMGInformer{FFFFFF}]: Звук сменён с {008000}'..mainini.main.volume ..'{FFFFFF} на {008000}'..arg,-1)
                mainini.main.volume = tonumber(arg)
                inicfg.save(mainini, ini)
            else sampAddChatMessage('[{1E90FF}DMGInformer{FFFFFF}]: Нужно число больше 0 и не больше 100!',-1) end
        else sampAddChatMessage('[{1E90FF}DMGInformer{FFFFFF}]: Нужно число!',-1) end
    end)

    sampRegisterChatCommand("dmgtake",function()
        mainini.main.takedamage = not mainini.main.takedamage
        sampAddChatMessage(mainini.main.takedamage and '[{1E90FF}DMGInformer{FFFFFF}]: Полученный урон {008000}включён' or '[{1E90FF}DMGInformer{FFFFFF}]: Полученный урон {ff0000}выключен',-1)
        inicfg.save(mainini, ini)
    end)
        
    sampRegisterChatCommand("dmgnick",function()
        mainini.main.nicks = not mainini.main.nicks
        sampAddChatMessage(mainini.main.nicks and '[{1E90FF}DMGInformer{FFFFFF}]: Ники {008000}включены' or '[{1E90FF}DMGInformer{FFFFFF}]: Ники {ff0000}выключены',-1 )
        inicfg.save(mainini, ini)
    end)
        
    sampRegisterChatCommand("dmggive",function()
        mainini.main.givedamage = not mainini.main.givedamage

        sampAddChatMessage(mainini.main.givedamage and '[{1E90FF}DMGInformer{FFFFFF}]: Нанесёный урон {008000}включён' or '[{1E90FF}DMGInformer{FFFFFF}]: Нанесёный урон {ff0000}выключен',-1)
        inicfg.save(mainini, ini)
    end)
    sampRegisterChatCommand("dmgkol",function()
        mainini.main.kolokol = not mainini.main.kolokol

        sampAddChatMessage(mainini.main.kolokol and '[{1E90FF}DMGInformer{FFFFFF}]: Колокол {008000}включён' or '[{1E90FF}DMGInformer{FFFFFF}]: Колокол {ff0000}выключен',-1)
        inicfg.save(mainini, ini)
    end)

    lua_thread.create(times)
    lua_thread.create(render)
end

function times()
    while true do wait(30)
        Render_y = Render_y - 1
        if Render_y < mainini.main.GDy - 50 then Render_y = mainini.main.GDy  GiveDamage = nil TID = nil end
        Render_y2 = Render_y2 - 1
        if Render_y2 < mainini.main.TDy - 50 then Render_y2 = mainini.main.TDy  TakeDamage = nil GID = nil end
    end
end

function render()
    while true do wait(0)
        if GiveDamage ~= nil and GID ~= nil and not sampIsPlayerPaused(GID) then
            if mainini.main.givedamage then
                renderFontDrawText(font,string.format('{29871f}%0.1f'.."{ff0000}(x"..combo[GID][1]..")",GiveDamage), mainini.main.GDx, Render_y, -1)
            end
            if mainini.main.nicks then
                renderFontDrawText(font2,sampGetPlayerNickname(GID).."["..GID.."]", mainini.main.GDx, mainini.main.GDy+30, sampGetPlayerColor(GID))
            end
        elseif GiveDamage ~= nil and GID ~= nil and  sampIsPlayerPaused(GID) then
            if mainini.main.givedamage then
                renderFontDrawText(font,'{ffff00}AFK', mainini.main.GDx, Render_y, -1)
            end
            if mainini.main.nicks then
                renderFontDrawText(font2,sampGetPlayerNickname(GID).."["..GID.."]", mainini.main.GDx, mainini.main.GDy+30, sampGetPlayerColor(GID))
            end
        end
        
        if TakeDamage ~= nil and sampIsPlayerConnected(TID) and TID ~= nil then
            if mainini.main.takedamage then
                renderFontDrawText(font,string.format('{83020e}%0.1f',TakeDamage), mainini.main.TDx, Render_y2, -1)
            end
            if  mainini.main.nicks and mainini.main.takedamage then
                renderFontDrawText(font2,sampGetPlayerNickname(TID).."["..TID.."]", mainini.main.TDx, mainini.main.TDy+30, sampGetPlayerColor(TID))
            end
        end
        if mainini.main.givedamage and active then
            renderFontDrawText(font,'{83020e}'..shara, mainini.main.GDx, mainini.main.GDy-70, -1)
        end
        if mode then  -- нижняя панель
            local nx, ny = getCursorPos()
            mainini.main.TDx = nx
            mainini.main.TDy = ny
            if isKeyJustPressed(13) then
                showCursor(false, false)
                mode = false
                inicfg.save(mainini, ini)
            end
        end
        if mode2 then  -- нижняя панель
            local nx, ny = getCursorPos()
            mainini.main.GDx = nx
            mainini.main.GDy = ny
            if isKeyJustPressed(13) then
                showCursor(false, false)
                mode2 = false
                inicfg.save(mainini, ini)
            end
        end
        for k,v in ipairs(combo) do
            if combo[k][1] > 0 and combo[k][2] ~= nil and os.time() - combo[k][2] > 5 then combo[k][1] = 0 combo[k][2] = nil end
        end
    end
end

function sampev.onPlayerDeath(id)
    if id == GID then
        lua_thread.create(function()
            shara = Texts[math.random(1,#Texts)]
            active = true
            wait(1000)
            shara = nil
            active = false
        end)
    end
end


function sampev.onSendTakeDamage(playerId, damage, weapon, bodypart)
    TakeDamage = damage
    TID = playerId
    Render_y2 = mainini.main.TDy
end

function sampev.onSendGiveDamage(playerId, damage, weapon, bodypart)
    GiveDamage = damage
    GID = playerId
    combo[GID][1] = combo[GID][1] + 1
    combo[GID][2] = os.time()
    Render_y = mainini.main.GDy
    if mainini.main.kolokol and doesFileExist('moonloader/config/DamageInformer/kolokol.mp3') then
        local audio = loadAudioStream('moonloader/config/DamageInformer/kolokol.mp3')
        setAudioStreamState(audio, 1)
        setAudioStreamVolume(audio, mainini.main.volume)
    end
end

function set() -- перемещение
    sampAddChatMessage('[{1E90FF}DMGInformer{FFFFFF}]: Нажмите {ffff00}Enter {FFFFFF} чтобы сохранить координаты',-1)
    mode = true
    showCursor(true, true)
end
function set2() -- перемещение
    sampAddChatMessage('[{1E90FF}DMGInformer{FFFFFF}]: Нажмите {ffff00}Enter {FFFFFF} чтобы сохранить координаты',-1)
    mode2 = true
    showCursor(true, true)
end
 

Вложения

  • DamageInformer.lua
    8.4 KB · Просмотры: 3

Орк

Известный
399
344
  • Нравится
Реакции: Naito

Naito

Активный
166
36
Как увеличить скоростной режим автомобиля? Например, буйвол достигает 188 км, и я хочу изменить его на 200 км.