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

b0ga9

Новичок
14
0
Короче, лютая проблема над которой вожусь около часа. Как сохранять данные из ini в
imgui.ImBuffer? А то после закрытия скрипта или перезахода вся инфа из inputText пропадает

Желательно пойти в вк b0ga_9
 

[SA ARZ]

Известный
392
8
Помогите расставить и вытащить номер, ник, тип и тип страховки данные

text dialog:
{ffffff}Заявление {ffff00}№1 {ffffff}от {ffff00}Jhon_Leonidov:

{ffffff}Тип имущества: {ffff00}Автомобиль(Lamborghini Aventador SVJ)
{ffffff}Тип страхования: {ffff00}повреждение автомобиля
 

Rice.

Известный
Модератор
1,756
1,624
Помогите расставить и вытащить номер, ник, тип и тип страховки данные

text dialog:
{ffffff}Заявление {ffff00}№1 {ffffff}от {ffff00}Jhon_Leonidov:

{ffffff}Тип имущества: {ffff00}Автомобиль(Lamborghini Aventador SVJ)
{ffffff}Тип страхования: {ffff00}повреждение автомобиля
Lua:
local number, nick = 0, ''
local tip, tip_st = '', ''

local samp = require('samp.events')
function samp.onShowDialog(dialogId, style, title, button1, button2, text)
    for line in text:gmatch("[^\n]+") do
        if line:find('{ffffff}Заявление {ffff00}№%d+ {ffffff}от {ffff00}.+:') then
            number, nick = line:match('{ffffff}Заявление {ffff00}№(%d+) {ffffff}от {ffff00}(.+):')
        end
        if line:find('Тип имущества: {ffff00}.+%(.+%)') then
            tip = line:match('Тип имущества: {ffff00}(.+)%(.+%)')
        end
        if line:find('Тип страхования: {ffff00}.+') then
            tip_st = line:match('Тип страхования: {ffff00}(.+)')
        end
    end
end
 

FakeSince

Активный
243
56
Есть скрипт, как из него сделать чтоб при вводе /luxury [цифра] эта цифра использовалась в 46 строке как ответ диалогу? Например - /luxury 1, оно отправляет sampSendDialogResponse(id, 1, nil, "1"), и в 29 строке указывалась эта цифра, например: printStringNow('~w~[~r~~h~Concept Car Luxury~w~] Kol-vo: '..arg..' ~b~~h~Dialogs Per Second~w~: ' .. #counter .. ' / ~r~~h~SEC', 100)
Lua:
local samp =  require 'samp.events'

local state = false
local counter = {}

function main()
while not isSampAvailable() do wait(0) end wait(1)
wait(1300)
sampAddChatMessage("{FFFFFF}[{4b8078}Concept Car Luxury lovec{FFFFFF}] - {4b6980}Loaded",-1)
    sampRegisterChatCommand('luxury', function()
        state = not state
    end)
   
    sampRegisterChatCommand('rstream', function()
        for _, ped in ipairs(getAllChars()) do
            if doesCharExist(ped) and ped ~= PLAYER_PED then
                removePlayer(select(2, sampGetPlayerIdByCharHandle(ped)))
            end
        end
    end)

    while true do wait(0)
        if state then
            for k, v in ipairs(counter) do
                if (os.clock() - v) > 1.0 then
                    table.remove(counter, k)
                end
            end
            printStringNow('~w~[~r~~h~Concept Car Luxury~w~] ~b~~h~Dialogs Per Second~w~: ' .. #counter .. ' / ~r~~h~SEC', 100)
            setGameKeyState(21, 255)
            wait(100)
            setGameKeyState(21, 0)
        end
    end
end

function samp.onServerMessage(clr, msg)
    if state and msg:find('Сейчас в магазине нет видеокарт') then
        return false
    end

end

function samp.onShowDialog(id, style, title, but_1, but_2, text)
    if state and id == 25191 then
        sampSendDialogResponse(id, 1, nil, nil)
        counter[#counter + 1] = os.clock()
        return false
    end
    if state and id == 0 then
        sampSendDialogResponse(id, 1, nil, nil)
        counter[#counter + 1] = os.clock()
        return false
    end
end

function removePlayer(id)
    local bs = raknetNewBitStream()
    raknetBitStreamWriteInt16(bs, id)
    raknetEmulRpcReceiveBitStream(163, bs)
    raknetDeleteBitStream(bs)
end
 

Rice.

Известный
Модератор
1,756
1,624
Есть скрипт, как из него сделать чтоб при вводе /luxury [цифра] эта цифра использовалась в 46 строке как ответ диалогу? Например - /luxury 1, оно отправляет sampSendDialogResponse(id, 1, nil, "1"), и в 29 строке указывалась эта цифра, например: printStringNow('~w~[~r~~h~Concept Car Luxury~w~] Kol-vo: '..arg..' ~b~~h~Dialogs Per Second~w~: ' .. #counter .. ' / ~r~~h~SEC', 100)
Lua:
local samp =  require 'samp.events'

local state = false
local counter = {}

function main()
while not isSampAvailable() do wait(0) end wait(1)
wait(1300)
sampAddChatMessage("{FFFFFF}[{4b8078}Concept Car Luxury lovec{FFFFFF}] - {4b6980}Loaded",-1)
    sampRegisterChatCommand('luxury', function()
        state = not state
    end)
 
    sampRegisterChatCommand('rstream', function()
        for _, ped in ipairs(getAllChars()) do
            if doesCharExist(ped) and ped ~= PLAYER_PED then
                removePlayer(select(2, sampGetPlayerIdByCharHandle(ped)))
            end
        end
    end)

    while true do wait(0)
        if state then
            for k, v in ipairs(counter) do
                if (os.clock() - v) > 1.0 then
                    table.remove(counter, k)
                end
            end
            printStringNow('~w~[~r~~h~Concept Car Luxury~w~] ~b~~h~Dialogs Per Second~w~: ' .. #counter .. ' / ~r~~h~SEC', 100)
            setGameKeyState(21, 255)
            wait(100)
            setGameKeyState(21, 0)
        end
    end
end

function samp.onServerMessage(clr, msg)
    if state and msg:find('Сейчас в магазине нет видеокарт') then
        return false
    end

end

function samp.onShowDialog(id, style, title, but_1, but_2, text)
    if state and id == 25191 then
        sampSendDialogResponse(id, 1, nil, nil)
        counter[#counter + 1] = os.clock()
        return false
    end
    if state and id == 0 then
        sampSendDialogResponse(id, 1, nil, nil)
        counter[#counter + 1] = os.clock()
        return false
    end
end

function removePlayer(id)
    local bs = raknetNewBitStream()
    raknetBitStreamWriteInt16(bs, id)
    raknetEmulRpcReceiveBitStream(163, bs)
    raknetDeleteBitStream(bs)
end
Lua:
local arg_luxury = 0 -- где-то около переменных

sampRegisterChatCommand('luxury', function(arg) -- команда с аргументом: /luxury цифра
    if arg ~= nil and arg ~= '' and tonumber(arg) then
        arg_luxury = tonumber(arg)
        state = not state
    end
end)

sampSendDialogResponse(id, 1, nil, arg_luxury) -- 46 строка

printStringNow('~w~[~r~~h~Concept Car Luxury~w~] Kol-vo: '..arg_luxury..' ~b~~h~Dialogs Per Second~w~: ' .. #counter .. ' / ~r~~h~SEC', 100) -- 29 строка
 

Zmeenoset

Новичок
6
1
Помогите пожалуйста пытался при основе скрипта на лён и хлопок арз переделать под мины на 23 февраля мне нужно чтобы скрипт не бегал за льном и хлопком, а бегал за объектом мины "1366" может я что-то не так делаю
 

Вложения

  • cottonbot.lua
    10.6 KB · Просмотры: 3

Rice.

Известный
Модератор
1,756
1,624
Помогите пожалуйста пытался при основе скрипта на лён и хлопок арз переделать под мины на 23 февраля мне нужно чтобы скрипт не бегал за льном и хлопком, а бегал за объектом мины "1366" может я что-то не так делаю
Доброго времени суток!
В этом скрипте нету никакой проверки на ID объекта, поэтому не получится переделать скрипт для мин одной строчкой.
 

Yardatian

Новичок
3
0
Hello, can u make a script that autopasses box like this( https://prnt.sc/_B4mDFmbTo6H ). We have box like this and math equation here, can u make lua,cs or anyother script that can solve this and put answer in box. I'll be very thankfull to you. Everytime equation is new and randomized.
 

S7XA

Активный
109
69
code::
local sampev = require 'lib.samp.events'
local textCoords = {x = nil, y = nil, z = nil}

function main()
    while not isSampAvailable() do wait(0) end
    while true do
        wait(0)
        if textCoords.x then
            if isCharInArea3d(PLAYER_PED, textCoords.x - 3, textCoords.y - 3, textCoords.z - 3, textCoords.x + 3, textCoords.y + 3, textCoords.z + 3, false) then
                sampAddChatMessage('Действие', -1)
            end
            --или
            x, y, z = getCharCoordinates(PLAYER_PED)
            if getDistanceBetweenCoords3d(x, y, z, textCoords.x, textCoords.y, textCoords.z) <= 3 then
                sampAddChatMessage('Действие', -1)
            end
        end
    end
end

function sampev.onCreate3DText(id, color, position, distance, testLOS, attPid, attVid, text)
    if text:find('3д Текст.') then
        textCoords.x = position.x
        textCoords.y = position.y
        textCoords.z = position.z
    end
end

Что не так? Ошибок не выдает но когда подхожу к 3д Тексту ничего не происходит.
 

zTechnology

Известный
1,101
486
code::
local sampev = require 'lib.samp.events'
local textCoords = {x = nil, y = nil, z = nil}

function main()
    while not isSampAvailable() do wait(0) end
    while true do
        wait(0)
        if textCoords.x then
            if isCharInArea3d(PLAYER_PED, textCoords.x - 3, textCoords.y - 3, textCoords.z - 3, textCoords.x + 3, textCoords.y + 3, textCoords.z + 3, false) then
                sampAddChatMessage('Действие', -1)
            end
            --или
            x, y, z = getCharCoordinates(PLAYER_PED)
            if getDistanceBetweenCoords3d(x, y, z, textCoords.x, textCoords.y, textCoords.z) <= 3 then
                sampAddChatMessage('Действие', -1)
            end
        end
    end
end

function sampev.onCreate3DText(id, color, position, distance, testLOS, attPid, attVid, text)
    if text:find('3д Текст.') then
        textCoords.x = position.x
        textCoords.y = position.y
        textCoords.z = position.z
    end
end

Что не так? Ошибок не выдает но когда подхожу к 3д Тексту ничего не происходит.
поставь кодировку cp1251 либо используй библиотеку encoding для русских текстов при UTF8
 

FakeSince

Активный
243
56
Ку, подскажите пожалуйста, как в этих строках:
Lua:
    while true do wait(0)
        if state then
            for k, v in ipairs(counter) do 
                if (os.clock() - v) > 1.0 then 
                    table.remove(counter, k)
                end
            end
            printStringNow('~w~[~r~~h~BTCSeller~w~] Kol-vo: '..arg_luxury..' ~b~~h~Dialogs Per Second~w~: ' .. #counter .. ' / ~r~~h~SEC', 100) 
            setGameKeyState(10, 255)
            wait(0)
            setGameKeyState(10, 0)
        end
    end
Выставить повторение этого цикла раз в 200 мс? Пробовал и в while true do wait(0) поставить 200, кикает на АРЗ за спам функциями, ставил 1000, ничего не менялось. Пробовал и в конце цикла добавить wait(200), wait(1000), ничего не менялось.