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

Ke4yp

Новичок
34
0
Lua:
potok = lua_thread.create(function()
код
end)
прерывать этот цикл вот так
Lua:
lua_thread:terminate()
Lua:
 function main()
while not isSampAvailable() do wait(2000) end
::startoflua::
    sampRegisterChatCommand('p1', fp)
    sampRegisterChatCommand('p2', sp)
    sampRegisterChatCommand('p3', p3)
    sampRegisterChatCommand('p4', p4)
    sampRegisterChatCommand('start', start)
    sampRegisterChatCommand("stop", stop)
    --while true do
            --wait(0)
            --if p==1 then
            --runTo(x1, y1)
            --runTo(x2, y2)
            --runTo(x3, y3)
            --runTo(x4, y4)
        --end end
    wait(-1) end

function p4()
    x4,y4,z4 = getCharCoordinates(playerPed)
    sampAddChatMessage("{00ff08}1", -1)   
end   
   
function p3()
    x3,y3,z3 = getCharCoordinates(playerPed)
    sampAddChatMessage("{00ff08}1", -1)   
    end
   
function fp()
    x1,y1,z1 = getCharCoordinates(playerPed)
    sampAddChatMessage("{00ff08}1", -1)   
end

function sp()
    x2,y2,z2 = getCharCoordinates(playerPed)
    sampAddChatMessage("{00ff08}2", -1)
end

function stop()
    thisScript():reload()
end

function runTo(x, y)
    repeat
        setGameKeyState(1, -255)
        local x1, y1, _ = getCharCoordinates(PLAYER_PED)
        set_camera_pos_unfix(x, y)
        wait(0)
    until getDistanceBetweenCoords2d(x, y, x1, y1) < 0.5
end


function set_camera_pos_unfix(posX, posY)
    local cPosX, cPosY, cPosZ = getActiveCameraCoordinates()
    setCameraPositionUnfixed(0.0, (getHeadingFromVector2d(posX - cPosX, posY - cPosY) - 90.0) / 57.2957795)
end

function start()
    lua_thread.create(function()
    wait(0)
    while not isKeyJustPressed(0x79) do
            wait(0)
            runTo(x1, y1)
            runTo(x2, y2)
            runTo(x3, y3)
            runTo(x4, y4)
        end
        end)
end
Почему при нажатии F10 скрипт не остонавливаеться, чтоб перестал блет бегать?
 

Terratomorf

Известный
315
58
Как сделать чтоб он кликал каждые 10 сек
Код:
function onTextDrawShow(textDrawId, positionX, positionY, textDrawString)
    if textDrawId == 2055 then
        clickTextDraw(2055)
    end
end
 

Ke4yp

Новичок
34
0
Как сделать чтоб он кликал каждые 10 сек
Код:
function onTextDrawShow(textDrawId, positionX, positionY, textDrawString)
    if textDrawId == 2055 then
        clickTextDraw(2055)
    end
end
Lua:
function onTextDrawShow(textDrawId, positionX, positionY, textDrawString)
lua_thread.create(function()
while true do
wait(10000)
    if textDrawId == 2055 then
        clickTextDraw(2055)
    end end)
end
 

Terratomorf

Известный
315
58

Kirya1232123213

Новичок
8
0
Lua:
local imgui = require 'imgui'
local key = require 'vkeys'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8


local test_text_buffer = imgui.ImBuffer(256)
local main_window_state = imgui.ImBool(false)
function imgui.OnDrawFrame()
if main_window_state.v then
imgui.SetNextWindowSize(imgui.ImVec2(600, 200), imgui.Cond.FirstUseEver)
imgui.Begin(u8'Bomj Helper', main_window_state)
if imgui.InputText(u8'<-- Ваша должность в BomjGang', test_text_buffer) then
sampSendChat(u8:decode(test_text_buffer.v) )
end
if imgui.Button(u8'Показать удостоверение') then   
sampSendChat('/me достал удостоверение')
sampSendChat('/me показал его человеку напротив')
sampSendChat('/do В удостоверении написанна должность: ', u8:decode(test_text_buffer.v))
end

imgui.End()
end
end

function main()
while true do
wait(0)
if wasKeyPressed(key.VK_X) then
main_window_state.v = not main_window_state.v
end
imgui.Process = main_window_state.v
end
end
Надо сделать так чтобы при вводе символов в строку ImGui в чат не пересылались сразу же символы и сделать так чтобы при активации кнопки "Показать удостоверение" считывались данные с этой строки...
Карочь я чайник, помогайте плс
 

Terratomorf

Известный
315
58
Как сделать чтоб он кликал каждые 10 сек,это для рак бота
Код:
function onTextDrawShow(textDrawId, positionX, positionY, textDrawString)
    if textDrawId == 2055 then
        clickTextDraw(2055)
        
  end
end
 

[Dark]Moran

Новичок
3
6
Помогите пожалуйста перевести с cleo на lua кусок кода. Заранее спасибо
Код:
0C0D: struct 3@ offset 6 size 4 = 0@
0C0D: struct 3@ offset 10 size 4 = 1@
0C0D: struct 3@ offset 14 size 4 = 2@
4@ = BitStream.New()
BitStream.Write(4@, 212, BS_TYPE_BYTE, 1)
BitStream.Write(4@, 3@, BS_TYPE_ARRAY, 18)
RakNet.LiteSend(4@)
BitStream.Delete(4@)
 
  • Нравится
Реакции: executor_lzt

Musaigen

abobusnik
Проверенный
1,585
1,309
Помогите пожалуйста перевести с cleo на lua кусок кода. Заранее спасибо
Код:
0C0D: struct 3@ offset 6 size 4 = 0@
0C0D: struct 3@ offset 10 size 4 = 1@
0C0D: struct 3@ offset 14 size 4 = 2@
4@ = BitStream.New()
BitStream.Write(4@, 212, BS_TYPE_BYTE, 1)
BitStream.Write(4@, 3@, BS_TYPE_ARRAY, 18)
RakNet.LiteSend(4@)
BitStream.Delete(4@)
Вы находитесь в разделе "Разработка" (само название уже должно выдавать смысл сего раздела).
Пожалуйста, не сорите здесь просьбами о написании какой-то программы (т.е. требуете уже готовый продукт).
 

AlexLightovich

Новичок
13
0
Еще раз приветсвую, помогите пожалуйста с отправкой значения в Ком-порт при определенной ситуации в игре.
Нужно, чтобы при определенной ситуации отправлялось значение "1" в COM6. Интересует сама отправка, не условие.

Lua:
local imgui = require 'imgui'
local key = require 'vkeys'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8


local test_text_buffer = imgui.ImBuffer(256)
local main_window_state = imgui.ImBool(false)
function imgui.OnDrawFrame()
if main_window_state.v then
imgui.SetNextWindowSize(imgui.ImVec2(600, 200), imgui.Cond.FirstUseEver)
imgui.Begin(u8'Bomj Helper', main_window_state)
if imgui.InputText(u8'<-- Ваша должность в BomjGang', test_text_buffer) then
sampSendChat(u8:decode(test_text_buffer.v) )
end
if imgui.Button(u8'Показать удостоверение') then
sampSendChat('/me достал удостоверение')
sampSendChat('/me показал его человеку напротив')
sampSendChat('/do В удостоверении написанна должность: ', u8:decode(test_text_buffer.v))
end

imgui.End()
end
end

function main()
while true do
wait(0)
if wasKeyPressed(key.VK_X) then
main_window_state.v = not main_window_state.v
end
imgui.Process = main_window_state.v
end
end
Надо сделать так чтобы при вводе символов в строку ImGui в чат не пересылались сразу же символы и сделать так чтобы при активации кнопки "Показать удостоверение" считывались данные с этой строки...
Карочь я чайник, помогайте плс
Код:
sampSendChat(u8:decode(test_text_buffer.v) )
Из условия убери
 

Fomikus

Известный
Проверенный
474
343
Как фиксануть срабатывание в инте и при спавне?
Lua:
--code
local inta = getActiveInterior()
if inta = 0 then -- 0 по дефолту игровой мир
        sampAddChatMessage('{FF5300}Вы не в инте')
else -- if inta ~= 0
        sampAddChatMessage('{FF5300}Вы в инте')
end

Вообщем в самп ивентах есть onPlayerQuit()
Как чекать определенный диапазон ID на выход? (Задается командой в чат например)
и как выполнить что-либо если один из этих ID вышел
 

v.schinckarev2013

Известный
24
0
Как считать номера из чата? При этом отправить смс на их номера.
Пример:
Механики:
Huy_Sobaki [тел: 228778]
Zalupa_Edinoroga [тел: 777888]
 

mrdiimax

Известный
566
79
Lua:
ocal bfile = getWorkingDirectory() .. "\\config\\MoD-Helper\\key.bind" -- путь к файлу для хранения клавиш
local tBindList = {}
if doesFileExist(bfile) then
    local fkey = io.open(bfile, "r")
    if fkey then
        tBindList = decodeJson(fkey:read("*a"))
        fkey:close()
    end
else
    tBindList = {
        [1] = { text = "Тайм", v = {} },
        [2] = { text = "/gate", v = {} },
        [3] = { text = "Сотрудники", v = {} },
        [4] = { text = "Carlock", v = {} },
        [5] = { text = "In SMS", v = {} },
        [6] = { text = "Out SMS", v = {} },
        [7] = { text = "Реконнект", v = {} },
        [8] = { text = "АвтоСтрой", v = {} },
        [9] = { text = "P.E.S. Help", v = {} },
        [10] = { text = "Принять P.E.S.", v = {} },
        [11] = { text = "VK Int.", v = {} },
        [12] = { text = "Снять маркер", v = {} },
        [13] = { text = "Меню скрипта", v = {} }
    }
end

Ошибка [ML] (error) C:\Чистая ГТА\moonloader\mo(opensource).lua:286: bad argument #1 to 'read' (invalid option)
stack traceback:
[C]: in function 'read'

В чем трабл?
 

Bogach

Активный
558
27
Почему не пашет ?
Lua:
function sampev.onShowDialog(dialogId, style, title, button1, button2, text)
     if GoParsData then
          if dialogId == 1 then
               --print(dialogId,title,text)
                 local NumberAcc,NickName,MobileNumber,Sex,Job = text:match('%{FFFFFF%}Номер аккаунта:%s+%{0099ff%}(%d+)%s+%{FFFFFF%}Имя:%s+%{0099ff%}(%g+).*%{FFFFFF%}Номер телефона:%s+%{0099ff%}(%d+).*%{FFFFFF%}Пол:%s+%{0099ff%}([А-я]+).*%{FFFFFF%}Работа/Должность:%s+%{0099ff%}(.*).*%{FFFFFF%}Ранг:.*')
                 if NumberAcc ~= nil then
                      lua_thread.create(function()
                        wait(150)
                      print(NumberAcc,NickName,MobileNumber,Sex,Job)
                        sampCloseCurrentDialogWithButton(1)
                 end
         end
     end
end
Чтобы не переносить с помощью переменной одну строчку в основной цикл, решил сделать поток, вроде как можно, что я не так сделал ?
Появляется такая ошибка:
Указывает на второй "end".