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

Benya

Активный
145
44
да
вот код
Lua:
        local valid, ped = getCharPlayerIsTargeting(PLAYER_HANDLE)
        if valid and doesCharExist(ped) then
            local result, id = sampGetPlayerIdByCharHandle(ped)
            if result and isKeyJustPressed(VK_E) then
                local nick = sampGetPlayerNickname(id):gsub('_', ' ')
                sampSendChat('/me ударив '..nick..' по голове')
                wait(500)
                sampSendChat('/try вырубил '..nick..'')
end
надо чтобы отыгровка была такая, если в руке есть какое-то оружие
Lua:
/me ударив прикладом оружия (оружие которое в руке) '..nick..' по голове
если оружии нету (кулак), то отыгровка остается как есть
Lua:
/me ударив '..nick..' по голове
wait(500)
/try вырубил '..nick..'


Можешь попробовать так.

Lua:
local key = require "lib.vkeys"

local namesgun = { -- создаешь масив с названиями ганов
    [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 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] = "Огнетушитель",
    [43] = "Camera",
    [44] = "Night Vis Goggles",
    [45] = "Thermal Goggles",
[46] = "Parachute" }


function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    while true do
        wait(0)
        if isKeyJustPressed(key.VK_NUMPAD7) then -- если нажата клавиша NumPad7
            local idgun = getCurrentCharWeapon(PLAYER_PED) -- получаешь ID текущего оружия в руках
            local nazvaniniegun = gunname(idgun) -- переменная с названием оружие
            if idgun == 0 then -- проверяешь если в кулак текущее оружие
                sampSendChat('/me ударил человека по голове') -- если кулак отыгровка такая и так далее...
            else
                sampSendChat("/me ударил оружием "..nazvaniniegun.." по голове") -- если в руке не кулак, отыгровка такая.
                wait(500)
                sampSendChat("/try вырубил человека")
            end
        end
    end
end



function gunname(gun) -- функция которая возвращает название оружие по его ID
    return namesgun[gun]
end


Что-то типо такого
 
Последнее редактирование:

EvilCoder

Участник
147
1
Смотрите. у меня есть функция RunToPoint, которая там воспроизводит координаты. Функцию вставил в код, как теперь сделать так, что ыб когда я нажимаю на Медная руда - воспроизводился маршрут
Lua:
if imgui.Checkbox(u8(play.v and "Медная руда" or "Медная руда"), play) then
    sampAddChatMessage(play.v and '{00f70c}Бот активирован' or '{ed1313}Бот деактивирован', -1)
end
 

AnWu

Guardian of Order
Всефорумный модератор
4,687
5,164
Можешь попробовать так.

Lua:
local key = require "lib.vkeys"

local namesgun = { -- создаешь масив с названиями ганов
    [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 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] = "Огнетушитель",
    [43] = "Camera",
    [44] = "Night Vis Goggles",
    [45] = "Thermal Goggles",
[46] = "Parachute" }


function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    while true do
        wait(0)
        if isKeyJustPressed(key.VK_NUMPAD7) then -- если нажата клавиша F7
            local idgun = getCurrentCharWeapon(PLAYER_PED) -- получаешь ID текущего оружия в руках
            local nazvaniniegun = gunname(idgun) -- переменная с названием оружие
            if idgun == 0 then -- проверяешь если в кулак текущее оружие
                sampSendChat('/me ударил человека по голове') -- если кулак отыгровка такая и так далее...
            else
                sampSendChat("/me ударил оружием "..nazvaniniegun.." по голове") -- если в руке не кулак, отыгровка такая.
                wait(500)
                sampSendChat("/try вырубил человека")
            end
        end
    end
end



function gunname(gun) -- функция которая возвращает название оружие по его ID
    return namesgun[gun]
end


Что-то типо такого
вместо таблицы используй библиотеку из стандартного набора муна Weapon.
Lua:
local wap = require 'game.wapons'
 
Последнее редактирование:

Dmitriy Makarov

25.05.2021
Проверенный
2,478
1,113
Можешь попробовать так.

Lua:
local key = require "lib.vkeys"

local namesgun = { -- создаешь масив с названиями ганов
    [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 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] = "Огнетушитель",
    [43] = "Camera",
    [44] = "Night Vis Goggles",
    [45] = "Thermal Goggles",
[46] = "Parachute" }


function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    while true do
        wait(0)
        if isKeyJustPressed(key.VK_NUMPAD7) then -- если нажата клавиша NumPad7
            local idgun = getCurrentCharWeapon(PLAYER_PED) -- получаешь ID текущего оружия в руках
            local nazvaniniegun = gunname(idgun) -- переменная с названием оружие
            if idgun == 0 then -- проверяешь если в кулак текущее оружие
                sampSendChat('/me ударил человека по голове') -- если кулак отыгровка такая и так далее...
            else
                sampSendChat("/me ударил оружием "..nazvaniniegun.." по голове") -- если в руке не кулак, отыгровка такая.
                wait(500)
                sampSendChat("/try вырубил человека")
            end
        end
    end
end



function gunname(gun) -- функция которая возвращает название оружие по его ID
    return namesgun[gun]
end


Что-то типо такого
как мне совместить твой код с этим кодом?:

Lua:
        local valid, ped = getCharPlayerIsTargeting(PLAYER_HANDLE)
        if valid and doesCharExist(ped) then
            local result, id = sampGetPlayerIdByCharHandle(ped)
            if result and isKeyJustPressed(VK_E) then
                local nick = sampGetPlayerNickname(id):gsub('_', ' ')
                sampSendChat('/me ударив '..nick..' по голове')
                wait(500)
                sampSendChat('/try вырубил '..nick..'')
         end
end
 

AnWu

Guardian of Order
Всефорумный модератор
4,687
5,164
как мне совместить твой код с этим кодом?:

Lua:
        local valid, ped = getCharPlayerIsTargeting(PLAYER_HANDLE)
        if valid and doesCharExist(ped) then
            local result, id = sampGetPlayerIdByCharHandle(ped)
            if result and isKeyJustPressed(VK_E) then
                local nick = sampGetPlayerNickname(id):gsub('_', ' ')
                sampSendChat('/me ударив '..nick..' по голове')
                wait(500)
                sampSendChat('/try вырубил '..nick..'')
         end
end
Добавить условия оружия. Попробуй логически сравнить твой код и его код. Проговаривай каждое условие "Если что-то равно тому-что то". Полезно.
 
  • Нравится
Реакции: Dmitriy Makarov

Benya

Активный
145
44
как мне совместить твой код с этим кодом?:

Если я правильно тебя понял, при нажатие на клаивишу E, при условии что ты целишься в игрока. Будет отыгровка.

Lua:
local key = require "lib.vkeys"
local namesgun = { -- создаешь масив с названиями ганов
    [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 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] = "Огнетушитель",
    [43] = "Camera",
    [44] = "Night Vis Goggles",
    [45] = "Thermal Goggles",
    [46] = "Parachute" }

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    while true do
        wait(0)
        if isKeyJustPressed(key.VK_E) then -- если нажата клавиша E и ты целишься в игрока 
            local valid, ped = getCharPlayerIsTargeting(PLAYER_HANDLE) -- получаешь хендл персонажа в которого целишься
            if valid and doesCharExist(ped) then -- если результат равен true (целишься) и и если он существует
                local result, id = sampGetPlayerIdByCharHandle(ped) -- получаешь ID по хендлу
                local nick = sampGetPlayerNickname(id):gsub('_', ' ') -- получаешь ник по ID удаляешь знак _ из ника
                local idgun = getCurrentCharWeapon(PLAYER_PED) -- получаешь ID текущего оружия в руках
                local nazvaniniegun = gunname(idgun) -- переменная с названием оружие
                if idgun == 0 then -- проверяешь если в кулак текущее оружие
                    sampSendChat('/me ударил человека по голове') -- если кулак отыгровка такая и так далее...
                else
                    sampSendChat("/me ударил "..nick.." оружием "..nazvaniniegun) -- если в руке не кулак, отыгровка такая.
                    wait(500)
                    sampSendChat("/try вырубил человека")
                end
            end
        end
    end
end
function gunname(gun) -- функция которая возвращает название оружие по его ID
    return namesgun[gun]
end


В итоге получается такая отыгровка
Если в руке кулак: /me ударил человека по голове
Если в руке оружие: /me ударил Vasya Pukin оружием Deseart Deagle
 
Последнее редактирование:

ninjaWRD

Участник
71
54
Помогите, как все сокращённые серверные команды из массива выводить в чат со всеми параметрами?
Lua:
local samp = require 'samp.events'

cmds = {
    ['/repair'] = '/rc'
    ['/refill'] = '/rf'
    ['/mcontract'] = '/mc'
}

function  hooksamp.onSendCommand(cmd)
    local hook = cmds:match
 

Dmitriy Makarov

25.05.2021
Проверенный
2,478
1,113
Что не правильно?

Lua:
function pass(arg)
    local id = tonumber(arg)
    if id ~= nil then
        if id >= 0 and id < 1000 then
            if sampIsPlayerConnected(id) then
                lua_thread.create(function()
                    sampSendChat('/me начал обыскивать карманы '..sampGetPlayerNickname(id):gsub('_', ' '))
                    wait(1000)
                    sampSendChat('/try нащупал паспорт '..sampGetPlayerNickname(id):gsub('_', ' ')..' в левом кармане штанов')
                    if str == "паспорт" then
                    end
                    if string.find(str, "{66CC00}| Удачно", 0, true) ~= nil then
                    sampAddChatMessage("Интервал /try запущен. Вы можете использовать /try через 15 секунд.")
                    end
                end)      
            else
               sampAddChatMessage("{25738B}[Mafia Helper] {FFFFFF}Игрок с ID: "..id.." не подключен к серверу.", 0x25738B, -1)
            end
        else
            sampAddChatMessage("{25738B}[Mafia Helper] {FFFFFF}ID должен быть в диапазоне от 0 до 999 включительно", 0x25738B, -1)
        end
    else
       sampAddChatMessage("{25738B}[Mafia Helper] {FFFFFF}Введите: /паспорт [id]", 0x25738B, -1)
    end
end
В консоли пишет это:
Код:
[ML] (error) AHK for Mafia.lua: D:\GTA San Andreas Multiplayer\moonloader\AHK for Mafia.lua:447: bad argument #1 to 'find' (string expected, got nil)
stack traceback:
    [C]: in function 'find'
    D:\GTA San Andreas Multiplayer\moonloader\AHK for Mafia.lua:447: in function <D:\GTA San Andreas Multiplayer\moonloader\AHK for Mafia.lua:441>
[ML] (error) AHK for Mafia.lua: Script died due to an error. (06B2843C)
Задумка была такая:
Если в /try | Удачно, в sampAddChatMessage пишет:
Интервал /try запущен. Вы можете использовать /try через 15 секунд.
Если /try | Неудачно, то тоже самое, только я с "Удачно" не разобрался пока что.
 

Petr_Sergeevich

Известный
Проверенный
707
296
Что не правильно?

Lua:
function pass(arg)
    local id = tonumber(arg)
    if id ~= nil then
        if id >= 0 and id < 1000 then
            if sampIsPlayerConnected(id) then
                lua_thread.create(function()
                    sampSendChat('/me начал обыскивать карманы '..sampGetPlayerNickname(id):gsub('_', ' '))
                    wait(1000)
                    sampSendChat('/try нащупал паспорт '..sampGetPlayerNickname(id):gsub('_', ' ')..' в левом кармане штанов')
                    if str == "паспорт" then
                    end
                    if string.find(str, "{66CC00}| Удачно", 0, true) ~= nil then
                    sampAddChatMessage("Интервал /try запущен. Вы можете использовать /try через 15 секунд.")
                    end
                end)    
            else
               sampAddChatMessage("{25738B}[Mafia Helper] {FFFFFF}Игрок с ID: "..id.." не подключен к серверу.", 0x25738B, -1)
            end
        else
            sampAddChatMessage("{25738B}[Mafia Helper] {FFFFFF}ID должен быть в диапазоне от 0 до 999 включительно", 0x25738B, -1)
        end
    else
       sampAddChatMessage("{25738B}[Mafia Helper] {FFFFFF}Введите: /паспорт [id]", 0x25738B, -1)
    end
end
В консоли пишет это:
Код:
[ML] (error) AHK for Mafia.lua: D:\GTA San Andreas Multiplayer\moonloader\AHK for Mafia.lua:447: bad argument #1 to 'find' (string expected, got nil)
stack traceback:
    [C]: in function 'find'
    D:\GTA San Andreas Multiplayer\moonloader\AHK for Mafia.lua:447: in function <D:\GTA San Andreas Multiplayer\moonloader\AHK for Mafia.lua:441>
[ML] (error) AHK for Mafia.lua: Script died due to an error. (06B2843C)
Задумка была такая:
Если в /try | Удачно, в sampAddChatMessage пишет:
Интервал /try запущен. Вы можете использовать /try через 15 секунд.
Если /try | Неудачно, то тоже самое, только я с "Удачно" не разобрался пока что.

Откуда переменная str?

Помогите, как все сокращённые серверные команды из массива выводить в чат со всеми параметрами?
Lua:
local samp = require 'samp.events'

cmds = {
    ['/repair'] = '/rc'
    ['/refill'] = '/rf'
    ['/mcontract'] = '/mc'
}

function  hooksamp.onSendCommand(cmd)
    local hook = cmds:match
Какими параметрами? Что конкретно тебе нужно? Напиши пример, нихрена не понятно
p.s. у тебя events это 'samp', а не 'hooksamp'