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

chapo

чопа сребдс // @moujeek
Модератор
8,934
11,700
  • Нравится
  • Bug
Реакции: sep, Gorskin и Kozlik Mad

yoozee

Новичок
12
0
хелп почему когда у пишу mgui.InputText('Введите текст!', text_buffer) пишет нормально а когда пишу mgui.InputText(u8'Введите текст!', text_buffer) появляются иероглифы хотя должно быть наоборот


Lua:
 script_name("imgui")
script_author("zabivnoy")
require('moonloader')
local imgui = require('imgui')
local encoding = require("encoding")
encoding.default = "CP1251"
u8 = encoding.UTF8
local main_window_state = imgui.ImBool(false)
local text_buffer = imgui.ImBuffer(256)
local checked_test = imgui.ImBool(false)
local checked_test_2 = imgui.ImBool(false)
local checked_radio = imgui.ImInt(1)
local combo_select = imgui.ImInt(0)
local arr_str = {"Салам", "test2", "test3"}
function main()
if (not isSampLoaded() or not isSampfuncsLoaded() or not isCleoLoaded())then return end
while (not isSampAvailable()) do wait(200) end
sampRegisterChatCommand('zbind', function() main_window_state.v = not main_window_state.v print(main_window_state.v)end)
sampRegisterChatCommand('check', cmd_check)
while true do wait(0) --беск цикл отсутст.
imgui.Process = main_window_state.v --процесс отсутст
end
end
       
function cmd_check(arg)
sampAddChatMessage(checked_radio.v, -1)
if checked_test.v then sampAddChatMessage("Галочка стоит!", -1) end
sampAddChatMessage(u8:decode(arr_str[combo_select.v +1]), -1)
end
function imgui.OnDrawFrame()
sizeX, sizeY = getScreenResolution()--получение разр.экрана отсутст
if main_window_state.v then print('+++')
imgui.SetNextWindowSize(imgui.ImVec2(500, 300), imgui.Cond.FirstUseEver)
imgui.SetNextWindowPos(imgui.ImVec2(sizeX / 2, sizeY / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
imgui.Begin("Z-binder by zabivnoy", main_window_state)
imgui.Text("z-binder")
imgui.InputText('Введите текст!', text_buffer) --отсутст u8
x, y, z = getCharCoordinates(PLAYER_PED)
imgui.Text("Ваша позиция: X:" .. math.floor(x) .. "  | Y: " .. math.floor(y) .. " | Z: " .. math.floor(z))
imgui.Text(text_buffer.v)
imgui.SetCursorPosY(120)
imgui.Separator()
imgui.SetCursorPosY(140)
imgui.Text("Это наша выборка")
imgui.SameLine()
imgui.SetCursorPosX(200)
imgui.Checkbox("Checkbox 1", checked_test)
imgui.SameLine()
imgui.Checkbox("Checkbox 2", checked_test_2)
imgui.SetCursorPosY(180)
imgui.Separator()
imgui.RadioButton("Radio 1", checked_radio, 3)
imgui.SameLine()
imgui.RadioButton("Radio 2", checked_radio, 4)
imgui.SameLine()
imgui.RadioButton("Radio 3", checked_radio, 5)
imgui.PushItemWidth(120)
imgui.SetCursorPosY(250)
imgui.SetCursorPosX(200)
imgui.Combo("Combo 1", combo_select, arr_str, #arr_str)
imgui.End()
end
end
 

Dashok.

Участник
228
9
Почему пед не бежит к пикапу?

lua:
local PICKUP_HANDLE = sampGetPickupHandleBySampId(id)
                if PICKUP_HANDLE ~= 0 then
                    local oX, oY, oZ = getCharCoordinates(PLAYER_PED)
                    local pX, pY, pZ = getPickupCoordinates(PICKUP_HANDLE)
                    if getDistanceBetweenCoords3d(oX, oY, oZ, pX, pY, pZ) and isPointOnScreen(pX, pY, pZ, 1.0) then
                        zX, zY = convert3DCoordsToScreen(pX, pY, pZ)
                       -- renderFontDrawText(font, string.format('P_ID: %d\nM_ID: %d', id, getPickupModel(id)), pX, pY, 0xFF55FFFF, 0xFF000000)
                        runToPoint(zX, yX)
                    end
                  
                end
 

Pashyka

Участник
220
17
В чем проблема?
Иногда вводит команду, но репорт не открывает, тогда просто отключает функцию

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


Lua:
if hookrep then
    if text:find("%[Жалоба%] от .+%[%d+%]:{......} .+ Уже {......}%d+{......} жалоб!!!") then
        sampSendChat("/ot")
        hookrep = false
    end
end
 

linmsqn

Участник
337
9
как записывать сколько людей я наказал? типо мне нужно подсчитывать строки с банами и мутами. если я выдал бан или какое-то другое наказание, то в конфиг будет записываться сколько человек я уже наказал. наказал одного человека - добавился один, двух - добавились два. счетчик наказаний короче

а теперь для другого, как мне сбрасывать это число при выходе из игры? типо я вышел и число из конфига сбросилось до нуля, только можно два примера сразу, потому что будет реализовано сразу две функции
 

S7XA

Активный
109
69
code::
local requests = require 'requests'
local active = false

text = 'sss'
idvk = '543860918'
token = 'token'
gid = '207587396'


function main()
  if not isSampLoaded() or not isSampfuncsLoaded() then return end
  while not isSampAvailable() do wait(100) end
  sampRegisterChatCommand("request", cmd_request)
  active = not active
  wait(-1)
end

function cmd_request()
    if active then
    end
    if text:find("find") then --
         requests.get('https://api.vk.com/method/messages.send?message='..text..'&peer_id='..idvk..'&access_token='..token..'&group_id='..gid..'&v=5.131&random_id=0')       
    end
end

Что не так? Ошибки нет.

Нужно что бы после активации команды request скрипт ждал - text:find("find") и выполнял действие requests.get
 

Pashyka

Участник
220
17
как записывать сколько людей я наказал? типо мне нужно подсчитывать строки с банами и мутами. если я выдал бан или какое-то другое наказание, то в конфиг будет записываться сколько человек я уже наказал. наказал одного человека - добавился один, двух - добавились два. счетчик наказаний короче

а теперь для другого, как мне сбрасывать это число при выходе из игры? типо я вышел и число из конфига сбросилось до нуля, только можно два примера сразу, потому что будет реализовано сразу две функции

Прочитай документацию samp.events и inicfg, регулярные выражения, все поймешь сразу
а так помощь(За говнокод не бейте)))

Lua:
require "lib.moonloader"
local inicfg = require "inicfg"
local hook = require 'lib.samp.events'

local mainIni = inicfg.load({
    mute = 0,
    ban = 0
}, "config")

if not doesFileExist("moonloader/config/config.ini") then
    inicfg.save(mainIni, "config.ini")
end

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then error(script_name..' needs SA:MP and SAMPFUNCS!') end
    while not isSampAvailable() do wait(100) end
    while true do wait(0) end
end

function hook.onServerMessage(color, text)
 --[[Тут ищешь свои наказания в чате, путем использования регулярных выражений
потом,если найдено, сохраняешь в конфиг]]

-- Если найден мут от тебя
    mainIni.mute = mainIni.mute + 1
-- Если бан
    mainIni.ban = mainIni.ban + 1
    inicfg.save(mainIni, "config.ini")

end
 
  • Нравится
Реакции: linmsqn
У

Удалённый пользователь 448549

Гость
Как сделать что бы функция выполнялась бесконечно пока не будет прописана команда деактивации?
Lua:
require('moonloader')

local state = false

function main()

    if (not isSampLoaded() or not isSampfuncsLoaded() or not isCleoLoaded()) then
        return
    end
    while (not isSampAvailable()) do
        wait(200)
    end

    sampRegisterChatCommand('cmd', function ()
        state = not state
        sampAddChatMessage(state and 'on' or 'off', -1)
    end)

    while (true) do

        if (state) then
            -- Бесконечно :)
            printString('123', 0)
        end

        wait(0)
    end
end
 
У

Удалённый пользователь 448549

Гость
Как сделать авторегистрацию на ник? Почитал различные темы, не понял
Надеюсь все понятно расписал
Lua:
require('moonloader')
local sampev = require('samp.events')
--[[
Немножко о https://wiki.blast.hk/ru/moonloader/lua/sampSendDialogResponse
      
Если зайдем на ссылку выше, там будет данная функция - sampSendDialogResponse(int id, int button, int listitem, zstring input)

Аргументы:
int id ид диалога
int button ид кнопки (0 / 1)
int listitem номер элемента списка (от 0)
zstring input текст введенный в поле

----------------------------------------------------

1) Символ '_' используется в качестве аргумента тогда, когда хочешь проигнорировать аргумент функции

2) Почему стоит % перед скобками? Пример: %[%]. Когда используешь string:find и хочешь найти допустим '[Test]', тебе надо поставить перед
скобками %, иначе не найдет. string:find('%[Test%]')

3) Как понять ButtonId когда используешь sampSendDialogResponse()?

 -------   -------  |  -------------   -----------
|   1   | |   0   | | |   Принять   | |   Выход   |
 -------   -------  |  -------------   -----------

4) ListItem. Приведу пример из диалога выбора пола.

---------[2/4] Выберите ваш пол---------
---------Мужской---------
---------Женский---------

Нумирация начинается с 0, т.е.
0) ---------Мужской---------
1) ---------Женский---------
2) ---------Средний---------
3) ---------итд---------

]]--

function sampev.onShowDialog(dialogId, dialogStyle, dialogTitle, dialogButton1, dialogButton2, dialogText)
    -- Выводит в чат Id диалога который был показан
    sampAddChatMessage(string.format('DialogId: %s', dialogId), -1)

    -- На аризонке регистрация через диалог под номером 1
    -- Если Id диалога = 1, получить Id диалога можно строчкой выше
    if (dialogId == 1) then
        -- Заголовок(Title) 1-ого диалога на аризоне это -> (1/4) Пароль
        if (dialogTitle:find('%(1/4%) Пароль')) then -- (1/4) Пароль
            --[[
                Аргументы:
                1) DialogId = 1
                2) ButtonId = 1 (Принять)
                3) Пропускаем аргумент, т.к. ListItem'a там нету
                4) InpupText = 123123, т.к. пароль от 6 символов
            ]]-- 
            sampSendDialogResponse(1, 1, _, '123123')
        end

        -- Заголовок(Title) 2-ого диалога на аризоне это -> [2/4] Выберите ваш пол
        if (dialogTitle:find('%[2/4%] Выберите ваш пол')) then -- [2/4] Выберите ваш пол
            --[[
                Аргументы:
                1) DialogId = 1
                2) ButtonId = 1 (Принять)
                3) ListItem выбираем 0, т.е. Мужской
                4) Пропускаем аргумент, т.к. InputText'a там нету
            ]]-- 
            sampSendDialogResponse(1, 1, 0, _)
        end

        -- Заголовок(Title) 3-его диалога на аризоне это -> [3/4] Выберите цвет кожи
        if (dialogTitle:find('%[3/4%] Выберите цвет кожи')) then -- [3/4] Выберите цвет кожи
            --[[
                Аргументы:
                1) DialogId = 1
                2) ButtonId = 1 (Принять)
                3) ListItem выбираем 0, т.е. Светлый
                4) Пропускаем аргумент, т.к. InputText'a там нету
            ]]--
            sampSendDialogResponse(1, 1, 0, _)
        end

        -- Заголовок(Title) 4-ого диалога на аризоне это -> [4/4] Откуда вы о нас узнали?
        if (dialogTitle:find('%[4/4%] Откуда вы о нас узнали?')) then -- [4/4] Откуда вы о нас узнали?
            --[[
                Аргументы:
                1) DialogId = 1
                2) ButtonId = 1 (Принять)
                3) ListItem выбираем 0, т.е. Вкладка "Hosted"
                4) Пропускаем аргумент, т.к. InputText'a там нету
            ]]--
            sampSendDialogResponse(1, 1, 0, _)
        end

    end
end
 
  • Нравится
Реакции: Willy4ka