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

Qsany

Потрачен
464
147
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Lua:
local ev = require 'lib.samp.events'
local damaglog = {out = {}, inc = {}}
local timetoshow = 0
local lasttime = 1
local weaponz = ""
local weaponz2 = ""

local names = {
  [0] = "Fist",
  [1] = "Brass Knuckles",
  [2] = "Golf Club",
  [3] = "Nightstick",
  [4] = "Knife",
  [5] = "Baseball Bat",
  [6] = "Shovel",
  [7] = "Pool Cue",
  [8] = "Katana",
  [9] = "Chainsaw",
  [10] = "Purple Dildo",
  [11] = "Dildo",
  [12] = "Vibrator",
  [13] = "Silver Vibrator",
  [14] = "Flowers",
  [15] = "Cane",
  [16] = "Grenade",
  [17] = "Tear Gas",
  [18] = "Molotov Cocktail",
  [22] = "9mm",
  [23] = "Silenced 9mm",
  [24] = "Desert Eagle",
  [25] = "Shotgun",
  [26] = "Sawnoff Shotgun",
  [27] = "Combat Shotgun",
  [28] = "Micro SMG/Uzi",
  [29] = "MP5",
  [30] = "AK-47",
  [31] = "M4",
  [32] = "Tec-9",
  [33] = "Country Rifle",
  [34] = "Sniper Rifle",
  [35] = "RPG",
  [36] = "HS Rocket",
  [37] = "Flamethrower",
  [38] = "Minigun",
  [39] = "Satchel Charge",
  [40] = "Detonator",
  [41] = "Spraycan",
  [42] = "Fire Extinguisher",
  [43] = "Camera",
  [44] = "Night Vis Goggles",
  [45] = "Thermal Goggles",
  [46] = "Parachute" }

function ev.onSendGiveDamage(playerId,damage,weapon)
    timetoshow=lasttime+3
    if #damaglog.out > 0 then
        ch = false
        for k,v in pairs(damaglog.out) do
            if v.id == playerId then
                weaponz = tostring(names[weapon])
                v.damage = v.damage + damage
                ch = true
            end
        end
        if not ch then
            table.insert(damaglog.out,1,{id = playerId,damage = damage})
            if #damaglog.out > 6 then
                table.remove(#damaglog.out,6)
            end
        end
    else
        table.insert(damaglog.out,1,{id = playerId,damage = damage})
    end
end
function ev.onSendTakeDamage(playerId,damage,weapon)
    timetoshow=lasttime+3
    if #damaglog.inc > 0 then
        ch = false
        for k,v in pairs(damaglog.inc) do
            if v.id == playerId then
                weaponz2 = tostring(names[weapon])
                v.damage = v.damage + damage
                ch = true
            end
        end
        if not ch then
            table.insert(damaglog.inc,1,{id = playerId,damage = damage})
            if #damaglog.inc > 6 then
                table.remove(#damaglog.inc,6)
            end
        end
    else
        table.insert(damaglog.inc,1,{id = playerId,damage = damage})
    end
end
function main()
    while not isSampAvailable() do wait(0) end
    font = renderCreateFont("Arial", 15, 8)
    while true do wait(0)
        health = getCharHealth(playerPed)
        if health == 0 then damaglog = {out = {}, inc = {}} end
        local posx, posy = convertGameScreenCoordsToWindowScreenCoords(150,400)
        local posx2 = convertGameScreenCoordsToWindowScreenCoords(450)
        lasttime=os.clock()
        if timetoshow > lasttime then
            if #damaglog.out > 0 then
                for k,v in pairs(damaglog.out) do
                    renderFontDrawText(font,sampGetPlayerNickname(v.id)..' - '..weaponz..' +'..string.format('%.2f',v.damage), posx,posy-renderGetFontDrawHeight(font)*k,0xff26e01d)
                end
            end
            if #damaglog.inc > 0 then
                for k,v in pairs(damaglog.inc) do
                    renderFontDrawText(font,sampGetPlayerNickname(v.id)..' - '..weaponz2..' -'..string.format('%.2f',v.damage), posx2,posy-renderGetFontDrawHeight(font)*k,0xFF44A6C5)
                end
            end
        else
            damaglog = {out = {}, inc = {}}
        end
    end
end



скипт умирает после 2 смертей
автор bladee
помогите пофиксить
 

BARRY BRADLEY

Известный
711
177
Lua:
sampRegisterChatCommand('test', function(texts)
    sampAddChatMessage('> Текст: ' .. texts, -1)    
end)

Вот создал команду /test [texts]. А как создать команду /test [text] [texts]. (чтоб было 2 параметра)
 

asocial demon

Потрачен
175
14
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.

xISRAPILx

Перепишу свою жизнь на PHP
Проверенный
247
165
  • Нравится
Реакции: BARRY BRADLEY

BARRY BRADLEY

Известный
711
177
Lua:
    sampRegisterChatCommand('test', function(strana, texts)
        if strana == 'ls' then
            sampSendChat('/sms radiols')
     
            --- Нужна проверка что в диалоге нет определенного текста. Если его нет, то выполним код ниже
     
            while not sampIsDialogActive() do wait(0) end
                sampCloseCurrentDialogWithButton(1)
         
            while not sampIsDialogActive() do wait(0) end
                sampSetCurrentDialogEditboxText(texts)
                sampCloseCurrentDialogWithButton(1)
         
            while not sampIsDialogActive() do wait(0) end
                sampCloseCurrentDialogWithButton(0)
         
            sampAddChatMessage('{00FF00}> Ваш текст оправлен на радио. {FFFFFF}Текст: ' .. texts, -1)
        else
           sampAddChatMessage('ПОТОМ' .. texts, -1)
        end
    end)

Нужно сделать проверку на текст в диалоге. Диалог создан сервером
 

xISRAPILx

Перепишу свою жизнь на PHP
Проверенный
247
165
Lua:
    sampRegisterChatCommand('test', function(strana, texts)
        if strana == 'ls' then
            sampSendChat('/sms radiols')
    
            --- Нужна проверка что в диалоге нет определенного текста. Если его нет, то выполним код ниже
    
            while not sampIsDialogActive() do wait(0) end
                sampCloseCurrentDialogWithButton(1)
        
            while not sampIsDialogActive() do wait(0) end
                sampSetCurrentDialogEditboxText(texts)
                sampCloseCurrentDialogWithButton(1)
        
            while not sampIsDialogActive() do wait(0) end
                sampCloseCurrentDialogWithButton(0)
        
            sampAddChatMessage('{00FF00}> Ваш текст оправлен на радио. {FFFFFF}Текст: ' .. texts, -1)
        else
           sampAddChatMessage('ПОТОМ' .. texts, -1)
        end
    end)

Нужно сделать проверку на текст в диалоге. Диалог создан сервером
if not string.find(sampGetDialogText(), "stroka")
 
  • Нравится
Реакции: BARRY BRADLEY

Danil_Hades

Новичок
131
3
Код:
function main()
  if not isSampLoaded() or not isSampfuncsLoaded() then return end
  while not isSampAvailable() do wait(100)
  end
  sampRegisterChatCommand("in", inv)
  wait(-1)
end

function inv(arg)
    local name = sampGestPlayerNickname(arg)
    sampSendChat("/me достал бандану и передал ее " .. name:gsub("_", " "))
    sampSendChat("/invite " .. arg)
end
почему не раблтает
 
  • Нравится
Реакции: strngexit

tlwsn

Известный
537
85
как отсюда получить ID игрока?
OiLELK6.png
 

Petr_Sergeevich

Известный
Проверенный
707
298
Как завершить процесс gta_sa.exe? Читал что-то про os.exit(), но не догнал, как использовать
 

atizoff

приобретаю кашель за деньги
Проверенный
1,296
1,181
Попробуй
Lua:
require 'lib.moonloader'
local key = require ("vkeys")

function main()
sampRegisterChatCommand("altik",function() lua_thread.create(alt) end)
while true do wait(1)
end

function alt()
setVirtualKeyDown(key.VK_LMENU, true)
while true do wait(5000)
end
ты чо ему дал? у него альт будет нажимается после введения комманды /altik pizdec. и только 1 раз.

Lua:
local flood = false
require "lib.moonloader"
local key = require ("vkeys")

function main()
sampRegisterChatCommand("obyav", function() flood = not flood end)
while true do
  wait(0)
  if flood then
    setVirtualKeyDown(key.VK_LMENU, true)
    wait(20)
    setVirtualKeyDown(key.VK_LMENU, false)
  end
end
end

Код:
function main()
  if not isSampLoaded() or not isSampfuncsLoaded() then return end
  while not isSampAvailable() do wait(100)
  end
  sampRegisterChatCommand("in", inv)
  wait(-1)
end

function inv(arg)
    local name = sampGestPlayerNickname(arg)
    sampSendChat("/me достал бандану и передал ее " .. name:gsub("_", " "))
    sampSendChat("/invite " .. arg)
end
почему не раблтает
ты пишешь arg, но не используешь её вообще. жди пока помогут
 

Petr_Sergeevich

Известный
Проверенный
707
298
Код:
function main()
  if not isSampLoaded() or not isSampfuncsLoaded() then return end
  while not isSampAvailable() do wait(100)
  end
  sampRegisterChatCommand("in", inv)
  wait(-1)
end

function inv(arg)
    local name = sampGestPlayerNickname(arg)
    sampSendChat("/me достал бандану и передал ее " .. name:gsub("_", " "))
    sampSendChat("/invite " .. arg)
end
почему не раблтает


Lua:
function main()
    while not isSampAvailable() do wait(0) end
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    sampRegisterChatCommand("in", inv)
    wait(-1)
end

function inv(arg)
    if arg ~= nil then
        lua_thread.create(function()
            local nickname = sampGetPlayerNickname(tonumber(arg))
            wait(300)
            sampSendChat("/me достал бандану и передал ее " .. nickname:gsub("_", " "))
            wait(100)
            sampSendChat("/invite " .. arg)
        end)
    end
end
 

#Northn

Pears Project — уже запущен!
Всефорумный модератор
2,652
2,549
Есть код:
Lua:
local newspotlight = imgui.ImBool(data.download.newspotlight)

--imgui ondrawframe
imgui.TextColored(RGBtoImVec4('000000'), u8'Красивый свет от уличных фонарей')
imgui.SameLine(225)
ShowHelpMarker('Модификация, улучшающая качество света от уличных фонарей. Работает только ночью.')
imgui.SameLine(250)
if imgui.ToggleButton("Test##5", newspotlight) then
    data.download.newspotlight  = tostring(newspotlight.v)
    inicfg.save(data, 'PHelper.ini')
end
И .ini файл:
Lua:
[download]
newtab=true
rpgun=false
newspotlight=false
newmenu=true
newid=true
[options]
hotkey=1
stroboscope=true
cidd=0
poswd=1
chwd=true
wdsize=2
poshudy=307
speedox=45
nadzir=0
speedoy=481
dea=0
chud=true
chposh=545
newchat=true
chposw=1018
ooc=true
suspend=true
speedo=true
poshudx=992
swat=0
cida=0
Если поставить newspotlight true - скрипт крашит при попытке отобразить ту самую включалку, если false - всё работает нормально, не понимаю в чём дело. С другими включателями, у которых код ТОЧЬ В ТОЧЬ одинаковый - не крашит, я ваще хз почему. Попробовал поставить true вручную (не через скрипт) - всё равно крашит. Может, знает кто решение?

[16:15:08.392730] (error) Police Helper: C:\Users\ediro\AppData\Local\Temp\PHelperTEST.lua:1570: attempt to index local 'bool' (a boolean value)
stack traceback:
C:\Users\ediro\AppData\Local\Temp\PHelperTEST.lua:1570: in function 'ToggleButton'
C:\Users\ediro\AppData\Local\Temp\PHelperTEST.lua:676: in function 'OnDrawFrame'
D:\Games\GTA San Andreas\moonloader\lib\imgui.lua:1378: in function <D:\Games\GTA San Andreas\moonloader\lib\imgui.lua:1367>
[16:15:08.400725] (error) Police Helper: Script died due to an error. (1CE4432C)

Вот код, в котором всё работает отлично:
Lua:
imgui.TextColored(RGBtoImVec4('000000'), u8'Кастомный [ /id ]')
imgui.SameLine(225)
ShowHelpMarker('Модификация, позволяющая заменить стандартный,\nскучный серверный [ /id ] на кастомный, с большими возможностями.')
imgui.SameLine(250)
if imgui.ToggleButton("Test##1", customid) then
    data.download.newid  = tostring(customid.v)
    inicfg.save(data, 'PHelper.ini')
end
 
Последнее редактирование:

Hatiko

Известный
Проверенный
1,516
633
Как можно перехватить интернет потоки, тип какой файл к чему обратился в инет или обратно. Хочу сделать внутри игровой лог потоков интернета.
 

Cutler18

Известный
163
2
Lua:
if list == 0 then
                sampSendChat('Ты')
                wait(1000)
                sampSendChat('Лох')
                wait(1000)
                sampSendChat('мой ид '..sampGetPlayerIdByCharHandle(playerPed))
Должен появится свой ид, только скрипт на этом моменте вырубается