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

Next..

Известный
343
136
Ошибка выходит


[ML] (error) 1.lua: ...sers\ygyc\Desktop\GTA 140K BY DAPO SHOW\moonloader\1.lua:12: attempt to index global 'smapev' (a nil value)
stack traceback:
...sers\ygyc\Desktop\GTA 140K BY DAPO SHOW\moonloader\1.lua:12: in main chunk
[ML] (error) 1.lua: Script died due to an error. (01A3F724)
Библиотеку подключи
local smapev = require 'lib.samp.events'
 
  • Нравится
Реакции: Tristan

Tristan

Участник
43
0
А как поставить wait ? А то, когда текст выходит, то оно раньше самого текста даже выходит
 

Basho

Известный
148
52
А как поставить wait ? А то, когда текст выходит, то оно раньше самого текста даже выходит
wait(1000), 1000 мс = 1 сек, wait ставится в main либо в потоке

Представим, что есть бег по координатам с возвращением после выполнения функции:

Lua:
...runTo(x, y)
runTo(x, y) --1
runTo(x, y) --2
if (x,y = тыры-пыры) then
runTo(x, y) --3
runTo(x, y) --4
end
runTo(x, y) --2
runTo(x, y) --1
как сделать, чтобы возвращение (то есть выполнение после end - runto 1 и 2) начинало работать после того, как нашло текст:

Lua:
function sampev.onDisplayGameText(style, time, text)
    if text:find('~y~~h~~h~Done') then
        сюда может какую-нибудь переменную вставить и с ней работать? и в main'e проверять ее состояние?
    end
end
дублирую вопрос
 

Tristan

Участник
43
0
wait(1000), 1000 мс = 1 сек, wait ставится в main либо в потоке
У меня ошибка:


Код:
[ML] (error) 1.lua: ...sers\ygyc\Desktop\GTA 140K BY DAPO SHOW\moonloader\1.lua:15: attempt to yield across C-call boundary
stack traceback:
    [C]: in function 'wait'
    ...sers\ygyc\Desktop\GTA 140K BY DAPO SHOW\moonloader\1.lua:15: in function 'callback'
    ...TA 140K BY DAPO SHOW\moonloader\lib\samp\events\core.lua:80: in function <...TA 140K BY DAPO SHOW\moonloader\lib\samp\events\core.lua:54>
[ML] (error) 1.lua: Script died due to an error. (019BD9E4)


Поставил wait сюда:

Код:
function smapev.onServerMessage(color,text) -- для этой функции надо SAMP.LUA
    if text:find('TEXT') then --найти в чате слово TEXT
        wait(2000)
        sampAddChatMessage('Ok',-1) -- если найдено,писать Ok
    end
end
 

Adrian G.

Известный
Проверенный
519
458
как сделать так, что бы в диалоговом окне (2 id) был текст, например: "Привет". И когда нажимаешь на этот текст, в чате написалось "Привет" ?

У меня ошибка:


Код:
[ML] (error) 1.lua: ...sers\ygyc\Desktop\GTA 140K BY DAPO SHOW\moonloader\1.lua:15: attempt to yield across C-call boundary
stack traceback:
    [C]: in function 'wait'
    ...sers\ygyc\Desktop\GTA 140K BY DAPO SHOW\moonloader\1.lua:15: in function 'callback'
    ...TA 140K BY DAPO SHOW\moonloader\lib\samp\events\core.lua:80: in function <...TA 140K BY DAPO SHOW\moonloader\lib\samp\events\core.lua:54>
[ML] (error) 1.lua: Script died due to an error. (019BD9E4)


Поставил wait сюда:

Код:
function smapev.onServerMessage(color,text) -- для этой функции надо SAMP.LUA
    if text:find('TEXT') then --найти в чате слово TEXT
        wait(2000)
        sampAddChatMessage('Ok',-1) -- если найдено,писать Ok
    end
end
wait можно юзать только в function main() либо в потоке https://blast.hk/wiki/lua:luathread

Первое случайно процитировал, сорри.
 
  • Нравится
Реакции: Tristan

Basho

Известный
148
52
У меня ошибка:


Код:
[ML] (error) 1.lua: ...sers\ygyc\Desktop\GTA 140K BY DAPO SHOW\moonloader\1.lua:15: attempt to yield across C-call boundary
stack traceback:
    [C]: in function 'wait'
    ...sers\ygyc\Desktop\GTA 140K BY DAPO SHOW\moonloader\1.lua:15: in function 'callback'
    ...TA 140K BY DAPO SHOW\moonloader\lib\samp\events\core.lua:80: in function <...TA 140K BY DAPO SHOW\moonloader\lib\samp\events\core.lua:54>
[ML] (error) 1.lua: Script died due to an error. (019BD9E4)


Поставил wait сюда:

Код:
function smapev.onServerMessage(color,text) -- для этой функции надо SAMP.LUA
    if text:find('TEXT') then --найти в чате слово TEXT
        wait(2000)
        sampAddChatMessage('Ok',-1) -- если найдено,писать Ok
    end
end
Lua:
function smapev.onServerMessage(color,text) -- для этой функции надо SAMP.LUA
    if text:find('TEXT') then --найти в чате слово TEXT
        lua_thread.create(function()
            wait(2000)
            sampAddChatMessage('Ok',-1) -- если найдено,писать Ok
        end)
    end
end
попробуй, другого решения я не знаю
 
  • Нравится
Реакции: Tristan

Eugene Crabs

Активный
544
30
wait можно юзать только в function main() либо в потоке https://blast.hk/wiki/lua:luathread

Первое случайно процитировал, сорри.
Кстать по поводу мэйна и потока. Хрен знает почему, но у меня и в функциях wait пашет исправно. Может это стереотип, который сформировался из-за старых версий moonloader?
 

Adrian G.

Известный
Проверенный
519
458
Кстать по поводу мэйна и потока. Хрен знает почему, но у меня и в функциях wait пашет исправно. Может это стереотип, который сформировался из-за старых версий moonloader?
Ты на какой версии? Я на 0.26 и скрипты выпиливаются, если вписать wait() неверно.
 

mrdiimax

Известный
566
79
Так не работает:
nowork:
if text:find("Squad") or text:find("Corporation") or text:find("Empire") or text:find("Brotherhood") or text:find("Family") or text:find("Dynasty") and checkbox[17].v then
    print(id)
end

А так уже работает:
work:
if checkbox[17].v then
        sampAddChatMessage("123", -1)
    end

Есть какой-то лимит в условии или что? Должно работать, если активен чекбокс и найдена строка. Строки находятся, однако на чекбокс не реагирует
 

earthlord

Известный
135
34
Так не работает:
nowork:
if text:find("Squad") or text:find("Corporation") or text:find("Empire") or text:find("Brotherhood") or text:find("Family") or text:find("Dynasty") and checkbox[17].v then
    print(id)
end

А так уже работает:
work:
if checkbox[17].v then
        sampAddChatMessage("123", -1)
    end

Есть какой-то лимит в условии или что? Должно работать, если активен чекбокс и найдена строка. Строки находятся, однако на чекбокс не реагирует
в круглые скобки все после if до and возьми
в луа and в приоритете и нет троичного оператора, поэтому вот так используют
 
  • Влюблен
Реакции: mrdiimax
D

deleted-user-210352

Гость
есть скрипт, который дает возможность узнать его шв и т.д?
 
  • Ха-ха
Реакции: Next..

Сheesecake

Участник
60
2
В чем трабл? Я писываю время в панельку и сохраняю, после сохранения в опр время происходит уведомление, НО..
Если я перезаускаю скрипт/перезахожу в игру, то больше не срабаывает, хотя настройки сохранены, что в ИНИ, что в спкрипте. Как пофиксить?
И, еще вопрос: Как сделать, чтоб в InputText нельзя было вписывать буквы/символы, онли числа?


Lua:
local Data = {
    settings = {
time = "55",
    },
}
cfg = inicfg.load(nil, 'Script\\settings.ini')

if cfg == nil then
    --print('Не найден файл конфига, создаю.')
    if inicfg.save(Data, 'Script\\settings.ini') then
        --print('Файл был с настройками был создан, ошибок нет.')
        cfg = inicfg.load(nil, 'Script\\settings.ini')
    end
end

local text_buffer = imgui.ImBuffer(256)
text_buffer.v = cfg.settings.time


-------------------------------------Это в имгуи----------------------------------
                    if imgui.InputText(u8"Введи текст", text_buffer) then
                        cfg.settings.time = text_buffer.v
                    end
                 
                    if imgui.Button(u8'save', imgui.ImVec2(-0.1, 25)) then
                        inicfg.save(cfg, "\\Script\\settings.ini")
                        sampAddChatMessage('Saved", -1)
                    end
                        imgui.End()
                    end

----------------------------------------------------------------------------
function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
res = false
---------------
while true do

    if res == false and os.date( "%M", os.time()) == cfg.settings.time then
        if os.date( "%S", os.time()) == "00" then
            sampAddChatMessage('Пора в школь, школьник', -1)
            res = true
        elseif os.date( "%S", os.time()) == "01" then
        end
    end
end