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

Azller Lollison

ещкере
Друг
1,349
2,314
Блэт, ладно, тогда подскажи почему инфа с диалога парситься от начала Регистрационный IP: и до конца диалога, а надо чтобы только айпишник после Регистрационный IP: и Текущий IP: брал. В чём проблема?
Lua:
function sampev.onShowDialog(id, style, title, btn1, btn2, text)
    print(text)
    ip123 = string.match(text, '.+\nРегистрационный IP: (.*)\n.+')
    if ip123 ~= nil then
    print(ip123)
    sampAddChatMessage(ip123, 0xC1C1C1)
    ip12 = string.match(ip123, '.+\nТекущий IP: (.*)\n.+')
    sampAddChatMessage(ip12, 0xC1C1C1)
end
end
Текст диалога:
Код:
- Аккаунт.
ID Аккаунта: 6454
Премиум аккаунт: Нет
Регистрационный IP: 1.2.3.4
Текущий IP: 5.6.7.8
Money: 0
Дата регистрации: 01.01.2918
тут я уж совсем бессилен ибо я практически не юзаю регулярки)
 

RTD

Потужно
Модератор
399
471
Блэт, ладно, тогда подскажи почему инфа с диалога парситься от начала Регистрационный IP: и до конца диалога, а надо чтобы только айпишник после Регистрационный IP: и Текущий IP: брал. В чём проблема?
Lua:
function sampev.onShowDialog(id, style, title, btn1, btn2, text)
    print(text)
    ip123 = string.match(text, '.+\nРегистрационный IP: (.*)\n.+')
    if ip123 ~= nil then
    print(ip123)
    sampAddChatMessage(ip123, 0xC1C1C1)
    ip12 = string.match(ip123, '.+\nТекущий IP: (.*)\n.+')
    sampAddChatMessage(ip12, 0xC1C1C1)
end
end
Текст диалога:
Код:
- Аккаунт.
ID Аккаунта: 6454
Премиум аккаунт: Нет
Регистрационный IP: 1.2.3.4
Текущий IP: 5.6.7.8
Money: 0
Дата регистрации: 01.01.2918
?
Lua:
local ip1, ip2 = string.match(text, 'Регистрационный IP: (.+)\nТекущий IP: (.+)\n')
sampAddChatMessage(ip1 .. ' - ' ip2, -1)
 

Azller Lollison

ещкере
Друг
1,349
2,314
Бля, а в sampSendChat можно как то вставить значение с иника? например у меня в инике line = 14 и надо шоб писало sampSendChat('piska и тут значение с иника'), пробовал ini.settings.line - не пашет
можно. sampSendChat('piska '..ini.settings.line)
 
  • Нравится
Реакции: Patrickkk

Cutler18

Известный
161
2
Lua:
sampRegisterChatCommand('rn', function(t)
    sampSendChat('/r'..(#t > 0) and ' (( '..t..' ))' or '')
end)
Lua:
require "lib.moonloader"
function main()
  if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while not isSampAvailable() do wait(100) end
sampRegisterChatCommand('rn', function(t)   sampSendChat('/r'..(#t > 0) and ' (( '..t..' ))' or '') end)
  while true do
  wait(0)
    if isKeyJustPressed(VK_P) then
      sampSendChat("my first binder")
    end
  end
  end
Так? Правильно?
 
1,417
1,033
Во второй твоей строке:
patscript.lua:8: ')' expected near 'ip2'

Да и если поменять вторую твою строку на:
print(ip1)
print(ip2)
выдает
Код:
[ML] (error) patsctipt.lua: D:\Games\GTA SA\moonloader\patsctipt.lua:11: bad argument #1 to 'match' (string expected, got nil)
stack traceback:
    [C]: in function 'match'
    D:\Games\GTA SA\moonloader\patsctipt.lua:11: in function 'callback'
    D:\Games\GTA SA\moonloader\lib\samp\events\core.lua:77: in function 'process_event'
    D:\Games\GTA SA\moonloader\lib\samp\events\core.lua:100: in function 'process_packet'
    D:\Games\GTA SA\moonloader\lib\samp\events\core.lua:127: in function <D:\Games\GTA SA\moonloader\lib\samp\events\core.lua:126>
[ML] (error) patsctipt.lua: Script died due to an error. (0A9E4EDC)
весь код скинь.
 

RTD

Потужно
Модератор
399
471
Проблему решил, это я чу-чуть кривым оказался, чуваку выше огромный респект, где ты раньше был? o_O
Смотрел в монитор, на котором ничего не происходит, пытался найти тайну, которую спрятали разрабы моника.
Еще бы вы мне сказали как менять значения в инике через команду в игре, вам бы цены не было)
Просто изменить значение в таблице, которую записываешь в ini.
 

vadimka0216

Известный
38
63
Не подскажите, как можно "вытащить" конкретную строчку(по порядку) из текстового файла. Например, мне нужно достать из файла 3 строчку, в файле написано так:
Первая1029
Вторая...
Треть3333
Четветая, здесь какой-то текст
Напишите мне пример такого кода, пожалуйста
 
  • Нравится
Реакции: executor_lzt

Cutler18

Известный
161
2
Правильно сделал с командой /rn?
Lua:
require "lib.moonloader"
function main()
  if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while not isSampAvailable() do wait(100) end
sampRegisterChatCommand('rn', function(t)   sampSendChat('/r'..(#t > 0) and ' (( '..t..' ))' or '') end)
  while true do
  wait(0)
    if isKeyJustPressed(VK_P) then
      sampSendChat("my first binder")
    end
  end
  end
 

imring

Ride the Lightning
Всефорумный модератор
2,365
2,552
Правильно сделал с командой /rn?
Lua:
require "lib.moonloader"
function main()
  if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while not isSampAvailable() do wait(100) end
sampRegisterChatCommand('rn', function(t)   sampSendChat('/r'..(#t > 0) and ' (( '..t..' ))' or '') end)
  while true do
  wait(0)
    if isKeyJustPressed(VK_P) then
      sampSendChat("my first binder")
    end
  end
  end
да.
 

Ken Block

Известный
432
31
Скрипт запускается но команда не работает
Lua:
function main()
  if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while not isSampAvailable() do wait(100) end
  sampRegisterChatCommand("rn", rn)
  while true do
    wait(0)
  end
end


function rn(args)
  if args ~= '' then sampSendChat("/r (( "..args .." ))")
  else sampAddChatMessage("Введите /rn [text]", 0xFF0000)
  end
end
 
  • Нравится
Реакции: Cutler18

Cutler18

Известный
161
2
Lua:
function main()
  if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while not isSampAvailable() do wait(100) end
  sampRegisterChatCommand("rn", rn)
  while true do
    wait(0)
  end
end


function rn(args)
  if args ~= '' then sampSendChat("/r (( "..args .." ))")
  else sampAddChatMessage("Введите /rn [text]", 0xFF0000)
  end
end
Спасибо большое)
 

Cutler18

Известный
161
2
Есть команда /dav например
Хочу что бы можно было после нее писать цифру 1,2 или 3, больше никаких
И что бы каждая цифра вывела в чат определенный текст
Как можно это реализовать?
 

hnnssy

Известный
Друг
2,684
2,765
Почему не пашет sampSendChat('/pagesize 20') ?
Я так понимаю из-за того что клиентская команда, ибо если убрать слэш или написать не клиентскую команду то всё пашет на ура.
Как фиксить?
sampProcessChatInput("/pagesize 20")
И еще хотел спросить, как можно посчитать строки в чате, т.е. например прошло 10 строк - скрипт сделал что-то там и т.п.
хук на clientmessage и +1 каждый раз
 

imring

Ride the Lightning
Всефорумный модератор
2,365
2,552
Еще такой вопрос, почему диалог не закрывает? И когда пишу например вместо sampCloseCurrentDialogWithButton(0) нажатие энтера или например посылаю еще одно сообщение, выдаёт ошибку:
Код:
ua:62: attempt to yield across C-call boundary
stack traceback:
    [C]: in function 'wait'
Lua:
function ip(id)
  local pid = string.match(id, '(%d+)')
  if pid ~= nil then
    sampSendChat('/stats '..pid)
    sampCloseCurrentDialogWithButton(0)
  else
    sampAddChatMessage("{6C519A}error", 0xC1C1C1)
  end
end
Lua:
function ip(id)
  local pid = string.match(id, '(%d+)')
  if pid ~= nil then
    sampSendChat('/stats '..pid)
    enableDialog(false) 
else
    sampAddChatMessage("{6C519A}error", 0xC1C1C1)
  end
end

function enableDialog(bool)
    local memory = require 'memory'
    memory.setint32(sampGetDialogInfoPtr()+40, bool and 1 or 0, true)
    sampToggleCursor(bool)
end