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

tsunamiqq

Участник
429
16
Вообще умею.

Lua:
imgui.Text(u8'Roy Shelby')
imgui.Separator()
imgui.Columns(2, "columns", true) -- создаёт 2 колонки
-- lvl
imgui.Text(u8'Уровень')
imgui.NextColumn()
imgui.Text(u8'21')
imgui.Separator()
imgui.NextColumn()
-- frac
imgui.Text(u8'Фракция')
imgui.NextColumn()
imgui.Text(u8'Полиция')
imgui.Separator()
imgui.NextColumn()
-- hp
imgui.Text(u8'Здоровье')
imgui.NextColumn()
imgui.Text(u8'160')
imgui.Separator()
imgui.NextColumn()
-- ... (и так далее)
Так мне еще проверки над, на лвл, хп и тд

Что делать если меню не открывается, а виден только курсор.
Lua:
if interaction_window_state.v then
        imgui.SetNextWindowSize(imgui.ImVec2(900, 350), imgui.Cond.FirstUseEver)
        imgui.Begin(u8'Взаимодействие', interaction_window_state, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoCollapse)
        imgui.BeginChild('##121', imgui.ImVec2(270, 300), true)
        imgui.Separator()
        imgui.Columns(2, "Columns", true)
        imgui.CenterColumnText(u8'Уровень:')
        imgui.NextColumn()
        imgui.SetColumnWidth(-1, 195)
        imgui.CenterColumnText(u8(sampGetPlayerScore(id)))
        imgui.NextColumn()
        imgui.CenterColumnText(u8'Фракция:')
        imgui.NextColumn()
        imgui.Separator()
        imgui.SetColumnWidth(-1, 195)
        imgui.CenterColumnText(u8(sampGetPlayerOrganisation(id)))
        imgui.NextColumn()
        imgui.CenterColumnText(u8'Здоровье:')
        imgui.NextColumn()
        imgui.Separator()
        imgui.SetColumnWidth(-1, 195)
        imgui.CenterColumnText(u8(sampGetPlayerHealth(id)))
        imgui.NextColumn()
        imgui.CenterColumnText(u8'Бронь:')
        imgui.NextColumn()
        imgui.Separator()
        imgui.SetColumnWidth(-1, 195)
        imgui.CenterColumnText(u8(sampGetPlayerArmor(id)))
        imgui.NextColumn()
        imgui.CenterColumnText(u8'Оружие:')
        imgui.NextColumn()
        imgui.Separator()
        imgui.SetColumnWidth(-1, 195)
        imgui.CenterColumnText(u8(sampGetPlayerGun(id)))
        imgui.NextColumn()
        imgui.CenterColumnText(u8'Пинг:')
        imgui.NextColumn()
        imgui.Separator()
        imgui.SetColumnWidth(-1, 195)
        imgui.CenterColumnText(u8(sampGetPlayerPing(id)))
        imgui.NextColumn()
        imgui.CenterColumnText(u8'Скин:')
        imgui.NextColumn()
        imgui.Separator()
        imgui.SetColumnWidth(-1, 195)
        imgui.CenterColumnText(u8(sampGetPlayerSkin(id)))
        imgui.NextColumn()
        imgui.CenterColumnText(u8'АФК:')
        imgui.NextColumn()
        imgui.Separator()
        imgui.SetColumnWidth(-1, 195)
        imgui.CenterColumnText(u8(sampIsPlayerPaused(id)))
        imgui.EndChild()
        imgui.SameLine()
        if act == 0 then
            imgui.BeginChild('##once', imgui.ImVec2(320, 300), true)
            imgui.EndChild()
        elseif act == 1 then
            imgui.BeginChild('##twice', imgui.ImVec2(320, 300), true)
            imgui.EndChild()
        end
        imgui.SameLine()
        imgui.BeginChild('##tabs2', imgui.ImVec2(270, 300), true)
        if imgui.Button('') then act = 0 end
        if imgui.Button('') then act = 1 end
        imgui.EndChild()
        imgui.End()
    end
    end
    local id = 0
 
Последнее редактирование модератором:

trefa

Известный
Всефорумный модератор
2,097
1,231
Так мне еще проверки над, на лвл, хп и тд
Тебе тут не заказ скриптов на бесплатной основе, тебе написали пример дальше сам. И да по поводу твоих ранее сообщений, ещё такое попрошайничество будет наказуемо "Режимом чтения"
 
  • Нравится
Реакции: SurnikSur и Adrian G.

Vintik

Мечтатель
Проверенный
1,473
922
Так мне еще проверки над, на лвл, хп и тд
Там всё есть. Если совсем ничего не знаешь, то рекомендую прочитать это:
 

copypaste_scripter

Известный
1,218
224
как сделать хук текста в диалоге, и чтобы тот текст который там есть вписался в диалоговое окно

короче кто играет на арз тот поймет лучше. а так обясню

открывается окно покупки товара у развозчика, 429ид диалога. на месте Х написано количество продуктов которых смогу купить (скил качаю) и надо чтобы скрипт самому понимал этот текст и вставил в диалоге, после чего нажал ентер (и все это скрипт понимает и активируется автоматом когда открываю диалог)

дальше я везу продукты в закуп, и это количество который я купил надо вписать в диалог окно 8762. тут легче, можно сделать переменную от предидущего диалога. или вот над грузовиком надпись можно хукнуть

не знаю какой лучше вариант, я придумал это а реализовать чет не смог. помогите плиз


update: нашел такую функцию как zstring text = sampGetCurrentDialogEditboxText() и могу получить введенный количество, но надо добавить +2 каждый раз, т.к. я повышаю скилл и дает возможность продать больше на 2
 

Вложения

  • 04.14.40.140.jpg
    04.14.40.140.jpg
    39.4 KB · Просмотры: 234
  • 429.jpg
    429.jpg
    38.6 KB · Просмотры: 242
  • 8762.jpg
    8762.jpg
    37 KB · Просмотры: 236
Последнее редактирование:

Corrygаn

Участник
225
6
Как сделать проверку на лвл, хп, пинг, оружие, скин, организацию, АФК или нет?
Lua:
_, id = sampGetPlayerIdByCharHandle(PLAYER_PED)
"Ваш уровень: " .. sampGetPlayerScore(id)
"Ваш уровень здоровья: " .. sampGetPlayerHealth(id)
"Ваша броня: " .. sampGetPlayerArmor(id)
дальше сам
 
Последнее редактирование модератором:

D.Makarov

Участник
146
3
Как можно заходить на другие сервера через луа, например конектиться на дргой сервер
 

Vintik

Мечтатель
Проверенный
1,473
922
Как можно заходить на другие сервера через луа, например конектиться на дргой сервер
Lua:
sampDisconnectWithReason(0) -- отключается от текущего сервера
sampConnectToServer('127.0.0.1', 7777) -- подключается к серверу 127.0.0.1:7777
 
  • Нравится
Реакции: Gorskin и SurnikSur

Vintik

Мечтатель
Проверенный
1,473
922
Бля, а как со сменой ника
Просто.
Lua:
sampDisconnectWithReason(0) -- отключается от текущего сервера
sampSetLocalPlayerName('Vintik') -- меняем ник на Vintik
sampConnectToServer('127.0.0.1', 7777) -- подключается к серверу 127.0.0.1:7777
 
  • Влюблен
Реакции: SurnikSur

DokumentRUS

Новичок
8
0
почему оно не работает, на серве пишет: нет такой команды
script_name('test')
require "lib.moonloader"

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

sampRegisterChatCommand("test", test_cmd)

end

function test_cmd()
sampAddChatMessage('test comanda', 0xffff00)
end
 

Fott

Простреленный
3,435
2,280
почему оно не работает, на серве пишет: нет такой команды
script_name('test')
require "lib.moonloader"

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

sampRegisterChatCommand("test", test_cmd)

end

function test_cmd()
sampAddChatMessage('test comanda', 0xffff00)
end
Lua:
script_name('test')
require "lib.moonloader"

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

sampRegisterChatCommand("test", test_cmd)
wait(-1)

end

function test_cmd()
sampAddChatMessage('test comanda', 0xffff00)
end
 
  • Нравится
Реакции: DokumentRUS

DokumentRUS

Новичок
8
0
Lua:
script_name('test')
require "lib.moonloader"

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

sampRegisterChatCommand("test", test_cmd)
wait(-1)

end

function test_cmd()
sampAddChatMessage('test comanda', 0xffff00)
end
не роботает, тоже самое, говорит нет такой команды
 

Vintik

Мечтатель
Проверенный
1,473
922
update: нашел такую функцию как zstring text = sampGetCurrentDialogEditboxText() и могу получить введенный количество, но надо добавить +2 каждый раз, т.к. я повышаю скилл и дает возможность продать больше на 2
Нет. Такой фигни точно не надо.
как сделать хук текста в диалоге, и чтобы тот текст который там есть вписался в диалоговое окно

короче кто играет на арз тот поймет лучше. а так обясню

открывается окно покупки товара у развозчика, 429ид диалога. на месте Х написано количество продуктов которых смогу купить (скил качаю) и надо чтобы скрипт самому понимал этот текст и вставил в диалоге, после чего нажал ентер (и все это скрипт понимает и активируется автоматом когда открываю диалог)

дальше я везу продукты в закуп, и это количество который я купил надо вписать в диалог окно 8762. тут легче, можно сделать переменную от предидущего диалога. или вот над грузовиком надпись можно хукнуть

не знаю какой лучше вариант, я придумал это а реализовать чет не смог. помогите плиз
И так. По сути нам надо получить последнюю цифру текста диалога, ID которого 429.
Lua:
local events = require 'lib.samp.events'

function events.onShowDialog(dialogId, style, title, button1, button2, text) -- вызывается при появлении любого диалога
  if dialogId == 429 then -- если нужный нам диалог
    -- далее ищем последнюю цифру строки text (текст диалога)
    local start_pos = text:len() -- начальная позиция последнего числа в тексте
    while text:sub(start_pos, start_pos) == 'number' do -- идём по циклу с конца строки до тех пор, пока будет не цифра
      start_pos = start_pos - 1
    end
    local prod = text:sub(start_pos + 1, text:len()) -- узнаем кол-во продуктов, обрезая строку (оставляем только последнее число)
    sampSendDialogResponse(dialogId, 1, nil, prod) -- отправляет серверу инфу, что мы нажали левую кнопку и ввели текст из переменной prod
    return false -- не даём нашему диалогу отобразитсья визуально (ты даже не увидешь его, а он уже закроется)
  end
end

не роботает, тоже самое, говорит нет такой команды
В папке со скриптом скинь файл moonloader.log