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

malis

Участник
41
4
Lua:
imgui.SetNextWindowSize(imgui.ImVec2(700, 520), imgui.Cond.FirstUseEver)
"imgui.Cond.FirstUserEver" -что за флаг?
 

lorgon

Известный
657
268
Возможно, нет прав для создания файла именно там. Попробуй вручную его создать или изменить директорию на диск D, например.
Сам сталкивался с такой проблемой
На всякий случай запусал скрипт через права администратора, диска D у меня нет. Мне надо что-бы он сам его создал.
Lua:
imgui.SetNextWindowSize(imgui.ImVec2(700, 520), imgui.Cond.FirstUseEver)
"imgui.Cond.FirstUserEver" -что за флаг?
По моему что он всегда используется первым относительно других менюшек. (Становится на первое место)
Строка
Код:
File = io.open("C:\\Users\\bantebe\\test.txt", "w")
не создаёт файл. Ошибка: attempt to index global 'File' (a nil value). Скрипт запускаю от имени администратора.
 
Последнее редактирование:

Vayrex.

Новичок
13
0
Как вытащить аргумент из отправляемой команды?
function onSendCommand(command)
if command == '/invite' then
--и здесь нужно найди аргумент команды инвайт.
 

lazarenok

Известный
15
0
есть код
как сделать,что бы при нажатии на кнопку допустим "У пациента болит голова"в чат выводились отыгровки
(и можно ли это делать вне цикла)

while true
do wait(0)

local valid, ped = getCharPlayerIsTargeting(PLAYER_HANDLE)
if valid and doesCharExist(ped) then
local result, id = sampGetPlayerIdByCharHandle(ped)
if result and isKeyJustPressed(VK_X) then
local nick = sampGetPlayerNickname(id):gsub('_', ' ')
sampShowDialog(228, "Помощь пациенту", string.format("1.У пациента болит голова/живот\n2.У пациента болит горло\n3.Потеря сознания\n4.Сделать Сеанс\n5.Сделать Рентген\n6. у пациента перелом конечностей\n7.Перелом позвоночника/ребер\n8.Глубокий порез\n9.Пулевое ранение "), "Выбрать", "Закрыть", 2)
end
end
if main_window_state.v == false then
imgui.Process = false
end
 
Последнее редактирование:

DolgorukovGTA

Известный
Проверенный
652
345
Как вытащить аргумент из отправляемой команды?
function onSendCommand(command)
if command == '/invite' then
--и здесь нужно найди аргумент команды инвайт.
Lua:
local sampev = require "lib.samp.events"

function sampev.onSendCommand(command)
    if command:find("/invite %d+") then
        local id = command:match("/invite (%d+)")
        print(id)
    end
end
 

Dmitriy Makarov

25.05.2021
Проверенный
2,481
1,113
есть код
как сделать,что бы при нажатии на кнопку допустим "У пациента болит голова"в чат выводились отыгровки
(и можно ли это делать вне цикла)

while true
do wait(0)

local valid, ped = getCharPlayerIsTargeting(PLAYER_HANDLE)
if valid and doesCharExist(ped) then
local result, id = sampGetPlayerIdByCharHandle(ped)
if result and isKeyJustPressed(VK_X) then
local nick = sampGetPlayerNickname(id):gsub('_', ' ')
sampShowDialog(228, "Помощь пациенту", string.format("1.У пациента болит голова/живот\n2.У пациента болит горло\n3.Потеря сознания\n4.Сделать Сеанс\n5.Сделать Рентген\n6. у пациента перелом конечностей\n7.Перелом позвоночника/ребер\n8.Глубокий порез\n9.Пулевое ранение "), "Выбрать", "Закрыть", 2)
end
end
if main_window_state.v == false then
imgui.Process = false
end
Lua:
-- беск цикл
local result, button, list, input = sampHasDialogRespond(228) -- 228 ид диалога
    if result then
        if button == 1 and list == 0 then -- button1 - кнопка слева, button0 - справа, list 0 - 1 строка, строки с 0 начинаются
            lua_thread.create(function()
            -- отыгровка
            end)
        end
    end
 
  • Нравится
Реакции: lazarenok

MrCold

Активный
364
118
Lua:
if imgui.Button(u8("Переход по ссылке")) then
    os.execute("explorer 'google.com'")
end



Lua:
local arg = imgui.ImBool(false) -- за пределами imgui.OnDrawFrame()
if imgui.Checkbox("Заголовок", arg) then
    sampAddChatMessage(("Галочка %s"):format(arg.v and "поставлена" or "снята"), -1)
end



Lua:
if imgui.Button("Здарова", imgui.ImVec2(80, 20)) then
    imgui.OpenPopup("##Подтверждение")
end

imgui.SetNextWindowSize(imgui.ImVec2(300, 90), imgui.Cond.FirstUseEver)
if imgui.BeginPopupModal("##Подтверждение", 1, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoTitleBar) then
    imgui.SetCursorPos(imgui.ImVec2(10, 7))
    imgui.Text("Поздароваться в ответ?")

    imgui.SetCursorPos(imgui.ImVec2(10, imgui.GetCursorPosY() + 3))
    if imgui.Button(u8("Да"), imgui.ImVec2(50, 23)) then
        sampAddChatMessage("Привет!", -1)
        imgui.CloseCurrentPopup()
    end

    imgui.SameLine(0, 5)
    if imgui.Button(u8("Нет"), imgui.ImVec2(60, 23)) then
        imgui.CloseCurrentPopup()
    end

    imgui.EndPopup()
end


У тебя конфиг в таблице config (судя по сохранению), но ты изменяешь какую-то таблицу status
p.s. Координаты можно получить сразу, не надо всё в строку переводить, лишние действия
Lua:
sampRegisterChatCommand("save_fh", function(args)
    local a_1, a_2, a_3, a_4 = args:match("(%d+) (%d+) (%d+) (%d+)")
end)

Ещё, если не ошибаюсь, при отсутствии секции в конфиге, её сначала нужно создать, а потом с ней работать (но это не точно)
Например,
Lua:
config["d_" .. a_1] = {}
config["d_" .. a_1].X = a_2
config["d_" .. a_1].Y = a_3
config["d_" .. a_1].Z = a_4
Твоя идея не совсем правильная. Она ругается на то, ккогда я хочу записать что-то в ини и сохранить. Но перед этим всё хорошо. Вот мой конфиг:
Lua:
local config = {
    d_0 = {
        X = 1885.88,
        Y = -1113.53,
        Z = 26.28
    },
    d_196 = {
        X = 167.07,
        Y = -1758.95,
        Z = 6.80
    }
}

local status = inicfg.load(config, 'FindHouses.ini')
if not doesFileExist('moonloader/config/FindHouses.ini') then inicfg.save(config, 'FindHouses.ini') end
 

lorgon

Известный
657
268
Не работает код:
Открытие файла:
file = io.open("C:\\Users\\none\\Рабочий стол\\lua\\test.txt", "r+")
file.write("Qwert")
file.close()
. P.S. Файл уже создан, но он его открыть не может. attempt to index global 'file' (a nil value). Когда пытаюсь создать файл, показывает такую же ошибку. (Файл создаю так file = io.open("C:\\Users\\none\\Рабочий стол\\lua\\test.txt", "w"))
 

KKamoto

Потрачен
120
9
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Как записать в значение (цифрой) всех игроков в зоне стрима? getallchars даёт таблицу с хендлами, но мне нужно кол-во людей в зоне стрима
 

DolgorukovGTA

Известный
Проверенный
652
345
Не работает код:
Открытие файла:
file = io.open("C:\\Users\\none\\Рабочий стол\\lua\\test.txt", "r+")
file.write("Qwert")
file.close()
. P.S. Файл уже создан, но он его открыть не может. attempt to index global 'file' (a nil value). Когда пытаюсь создать файл, показывает такую же ошибку. (Файл создаю так file = io.open("C:\\Users\\none\\Рабочий стол\\lua\\test.txt", "w"))
Lua:
function main()
    local f = io.open("moonloader//t.txt", "a") -- открываем файл, если такого не будет - создастся автоматически
    f:write('Hello world\n') -- записываем в файл информацию
    f:close() -- закрываем файл
    wait(-1)
end
 

KKamoto

Потрачен
120
9
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
глупый вопрос, как сделать чтобы в чате находилось сообщение "привет", и тогда выполнялась какая либо функция?

local ev = require 'samp.events'

тут цикл main

function ev.onServerMessage (color, text)
if text:find == 'привет' then пишешь назву функи
end
end
 

DolgorukovGTA

Известный
Проверенный
652
345
Как записать в значение (цифрой) всех игроков в зоне стрима? getallchars даёт таблицу с хендлами, но мне нужно кол-во людей в зоне стрима
Получая длину массива:
Lua:
print(#getAllChars())
attempt to index local 'f' (a nil value)
Директория значит указана неверно, используй лучше вывод внутри папки с гташкой.
 
  • Нравится
Реакции: KKamoto