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

RedApple

Известный
41
0
Значит с серверной стороны диалог не активен или ты что-то неправильно указываешь


sampProcessChatInput(string)
диалог активен, создан сервером.
сначала вызываю диалог - например /menu
потом через 100 мс хочу выбрать пункт в диалоге и меня кикает.
п.с. диалог у меня открывается кнопкой (на сервере так сделано)
Lua:
setVirtualKeyDown(50, true)
    wait(100)
    setVirtualKeyDown(50, false)
    wait(100)
    sampSendDialogResponse(10, 0, 8, -1)
    wait(50)
    sampCloseCurrentDialogWithButton(0)
Ид диалога 10, кнопку хочу нажать левую, восьмой пункт если считать сверху начиная с нуля
 

Fomikus

Известный
Проверенный
473
341
Хочу найти координаты обьекта
Lua:
local objpos, x, y, z = getObjectCoordinates(19320) 
local x, y, z = getObjectCoordinates(19320)
Оба варианта не работают, скрипт просто умирает на этой строчке
 

Petr_Sergeevich

Известный
Проверенный
707
296
Хочу найти координаты обьекта
Lua:
local objpos, x, y, z = getObjectCoordinates(19320)
local x, y, z = getObjectCoordinates(19320)
Оба варианта не работают, скрипт просто умирает на этой строчке

getObjectCoordinates(Object object) принимает хэндл объекта, получить можно так:
Object object = sampGetObjectHandleBySampId(int id)
 
Последнее редактирование:
  • Нравится
Реакции: MasonQQ

ChickenYaki

Участник
55
0
thing = string.match (arg, '(. +)')
if thing == nil or == "" then
sampAddChat ('', -1)
elseif thing == "mat"
sampsendchat ('' ..thing)

In this code, if I type 'Mat' then it doesnt work , I have to type 'mat' .what should I do?

I want to set it to similar input
 

samespoon

Известный
163
20
thing = string.match (arg, '(. +)')
if thing == nil or == "" then
sampAddChat ('', -1)
elseif thing == "mat"
sampsendchat ('' ..thing)

In this code, if I type 'Mat' then it doesnt work , I have to type 'mat' .what should I do?

I want to set it to similar input
Lua:
thing = string.match (arg, '(. +)')
if thing == nil or == "" then
    sampAddChatMessage('', -1)
elseif thing == "mat" then -- wrong here (you don't write "then")
    sampSendChat('' ..thing)
 

Petr_Sergeevich

Известный
Проверенный
707
296
thing = string.match (arg, '(. +)')
if thing == nil or == "" then
sampAddChat ('', -1)
elseif thing == "mat"
sampsendchat ('' ..thing)

In this code, if I type 'Mat' then it doesnt work , I have to type 'mat' .what should I do?

I want to set it to similar input
Lua:
thing = arg:match("(.+)")
if thing == nil or thing == "" then
    sampAddChatMessage("...", -1)
elseif thing:lower() == "mat" then
    sampSendChat(thing)
end

Lua:
thing = string.match (arg, '(. +)')
if thing == nil or == "" then
    sampAddChatMessage('', -1)
elseif thing == "mat" then -- wrong here (you don't write "then")
    sampSendChat('' ..thing)

Он имел ввиду регистр, а не ошибку в коде, с таким успехом код бы просто не работал, а он заявляет обратное.
 

vlads250

Известный
27
0
Есть скрипт, как сделать его активацию по вводу команды в чат? А то он активируется, только когда в чате видит [A] Nick_Name: /money id
Код:
script_name("Money")
script_version_number(0.1)
script_author("///")

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
    adminlvl = 999
    lua_thread.create(money)
end
function money()
    while true do
        money, _ , _ , _ = sampGetChatString(99)
        if money ~= textmoney and adminlvl >= 2 then
            if string.match(money, "A] [A-z]+_[A-z]+[[0-9]+]: /money [0-9]+") ~= nil then
                moneyid = string.match(string.match(money, "/money %d+.-$"), "%d+")
                nickname = sampGetPlayerNickname(moneyid)
                sampSendChat("/money "..moneyid)
                while not sampIsDialogActive() do wait(0) end
                wait(200)
                dialogtext = sampGetDialogText()
                getMoney()
                sampAddChatMessage("[A] Деньги игрока "..nickname..":", 0x7ACC29)
                sampAddChatMessage("[A] Наличные: "..money1.."$ | Осн. банк. счет: "..money2.." | На всех счетах: "..money3.."$.", 0x7ACC29)
                sampAddChatMessage("[A] Всего денег: "..money4.."$.", 0x7ACC29)
            end
        end
        textmoney = money
        wait(0)
    end
end
function getMoney()
    money1 = string.match(string.match(dialogtext, "Наличные деньги:        [0-9]+"),"[0-9]+")
    money2 = string.match(string.match(dialogtext, "Осн. банковский счёт:        [0-9]+"), "[0-9]+")
    money3 = string.match(string.match(dialogtext, "На всех доп. банк. счетах:    [0-9]+"), "[0-9]+")
    money4 = money1 + money2 + money3
end
function getDevNick(name)
    name=string.gsub(name, "_", " ")
    p1=string.match(name, "[A-Z]")
    p2=string.match(name, " .-$")
    p3=p1..". "..p2
end
 

Petr_Sergeevich

Известный
Проверенный
707
296
Есть скрипт, как сделать его активацию по вводу команды в чат? А то он активируется, только когда в чате видит [A] Nick_Name: /money id
Код:
script_name("Money")
script_version_number(0.1)
script_author("///")

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
    adminlvl = 999
    lua_thread.create(money)
end
function money()
    while true do
        money, _ , _ , _ = sampGetChatString(99)
        if money ~= textmoney and adminlvl >= 2 then
            if string.match(money, "A] [A-z]+_[A-z]+[[0-9]+]: /money [0-9]+") ~= nil then
                moneyid = string.match(string.match(money, "/money %d+.-$"), "%d+")
                nickname = sampGetPlayerNickname(moneyid)
                sampSendChat("/money "..moneyid)
                while not sampIsDialogActive() do wait(0) end
                wait(200)
                dialogtext = sampGetDialogText()
                getMoney()
                sampAddChatMessage("[A] Деньги игрока "..nickname..":", 0x7ACC29)
                sampAddChatMessage("[A] Наличные: "..money1.."$ | Осн. банк. счет: "..money2.." | На всех счетах: "..money3.."$.", 0x7ACC29)
                sampAddChatMessage("[A] Всего денег: "..money4.."$.", 0x7ACC29)
            end
        end
        textmoney = money
        wait(0)
    end
end
function getMoney()
    money1 = string.match(string.match(dialogtext, "Наличные деньги:        [0-9]+"),"[0-9]+")
    money2 = string.match(string.match(dialogtext, "Осн. банковский счёт:        [0-9]+"), "[0-9]+")
    money3 = string.match(string.match(dialogtext, "На всех доп. банк. счетах:    [0-9]+"), "[0-9]+")
    money4 = money1 + money2 + money3
end
function getDevNick(name)
    name=string.gsub(name, "_", " ")
    p1=string.match(name, "[A-Z]")
    p2=string.match(name, " .-$")
    p3=p1..". "..p2
end

Lua:
isActivate = false -- в начало
sampRegisterChatCommand("act", function()
    isActivate = not isActivate
    sampAddChatMessage(isActivate and "Скрипт включен" or "Скрипт выключен", -1)
end) -- в main

while true do
    wait(0)
    if isActivate then
        -- code
    end
end
 

SanyaVersus

Участник
65
1
Lua:
local ev = require("samp.events")

function main()
wait(-1)
end

function ev.onServerMessage(_, msg)
  if msg:gsub("{......}", ""):find("Нужный тебе текст") then
    sampAddChatMessage("Было написано \""..msg.."\"", -1)
  end
end
Код:
require "lib.moonloader"
local imgui = require 'imgui'
local notf = import 'imgui_notf.lua'
local ev = require("samp.events")
function main()
  if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while not isSampAvailable() do wait(100) end
  while true do
  wait(0)
  if not sampIsChatInputActive() then
    if not sampIsDialogActive() then
  if isKeyJustPressed(VK_R) then
    sampSendChat("/healme")
    notf.addNotification("Уведомление\n\nВы использовали аптечку", 5)
  end
end
  end
end
end
function ev.onServerMessage(_, msg)
  if msg:gsub("{......}", ""):find("Вы взяли маску (/mask)") then
    sampSendChat("/mask")
        notf.addNotification("Уведомление\n\nВы надели маску", 5)
  end
end
Не работает, в чём дело?
P.S Не работает именно от function ev.onServerMessage(_, msg) и до end
 

ШPEK

Известный
1,476
525
Код:
require "lib.moonloader"
local imgui = require 'imgui'
local notf = import 'imgui_notf.lua'
local ev = require("samp.events")
function main()
  if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while not isSampAvailable() do wait(100) end
  while true do
  wait(0)
  if not sampIsChatInputActive() then
    if not sampIsDialogActive() then
  if isKeyJustPressed(VK_R) then
    sampSendChat("/healme")
    notf.addNotification("Уведомление\n\nВы использовали аптечку", 5)
  end
end
  end
end
end
function ev.onServerMessage(_, msg)
  if msg:gsub("{......}", ""):find("Вы взяли маску (/mask)") then
    sampSendChat("/mask")
        notf.addNotification("Уведомление\n\nВы надели маску", 5)
  end
end
Не работает, в чём дело?
P.S Не работает именно от function ev.onServerMessage(_, msg) и до end
Скинь с нормальной табуляцией и синтаксисом и возможно помогуу
 

SanyaVersus

Участник
65
1
Код:
require "lib.moonloader"
local imgui = require 'imgui'
local notf = import 'imgui_notf.lua'
local ev = require("samp.events")
function main()
  if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while not isSampAvailable() do wait(100) end
  while true do
    wait(0)
    if not sampIsChatInputActive() then
      if not sampIsDialogActive() then
        if isKeyJustPressed(VK_R) then
          sampSendChat("/healme")
          notf.addNotification("Уведомление\n\nВы использовали аптечку", 5)
        end
      end
    end
  end
end
function ev.onServerMessage(_, msg)
  if msg:gsub("{......}", ""):find("Вы взяли маску (/mask)") then
    sampSendChat("/mask")
    notf.addNotification("Уведомление\n\nВы надели маску", 5)
  end
end

Скинь с нормальной табуляцией и синтаксисом и возможно помогуу
Код:
require "lib.moonloader"
local imgui = require 'imgui'
local notf = import 'imgui_notf.lua'
local ev = require("samp.events")
function main()
  if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while not isSampAvailable() do wait(100) end
  while true do
    wait(0)
    if not sampIsChatInputActive() then
      if not sampIsDialogActive() then
        if isKeyJustPressed(VK_R) then
          sampSendChat("/healme")
          notf.addNotification("Уведомление\n\nВы использовали аптечку", 5)
        end
      end
    end
  end
end
function ev.onServerMessage(_, msg)
  if msg:gsub("{......}", ""):find("Вы взяли маску (/mask)") then
    sampSendChat("/mask")
    notf.addNotification("Уведомление\n\nВы надели маску", 5)
  end
end
[code]