Вопросы по 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,704
Lua:
[ML] (error) GiveAway.lua: D:\GTA San Andreas\moonloader\GiveAway.lua:61: attempt to compare string with number
stack traceback:
    D:\GTA San Andreas\moonloader\GiveAway.lua:61: in function 'OnDrawFrame'
    D:\GTA San Andreas\moonloader\lib\imgui.lua:1378: in function <D:\GTA San Andreas\moonloader\lib\imgui.lua:1367>

Lua:
if #member > members.v then sampAddChatMessage('Достигнут лимит участников! Начинаю розыгрыш', -1) hook = true end

Почему вылазит эта ошибка? Я не сравниваю строку с числом, я добавил возле member #
#member возвращает число.
если member - массив, то # возвращает кол-во элементов в массиве
если member - строка, то # возвращает кол-во символов в строке
 
  • Нравится
Реакции: Sanchez.

Sanchez.

Известный
705
188
Lua:
local imgui = require 'imgui'
local encoding = require 'encoding'
local sampev = require 'lib.samp.events'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local window = imgui.ImBool(false)

local nickname, id, msg = nil,nil,nil

local sw, sh = getScreenResolution()

local members = imgui.ImBuffer(256)

--ocal members1 = 0

local prize = imgui.ImBuffer(256)

local mesta = imgui.ImBuffer(256)

local giveaway = false

local hook = false

local member = {}

function imgui.CenterButton(text)
    local width = imgui.GetWindowWidth()
    local calc = imgui.CalcTextSize(text)
    imgui.SetCursorPosX( width / 2 - calc.x / 2 )
    imgui.Button(text)
end

function main()
    while not isSampAvailable() do wait(200) end

    sampRegisterChatCommand('giveaway', function()
        window.v = not window.v
    end)

    while true do
        wait(0)
        imgui.Process = window.v
    end
end

function imgui.OnDrawFrame()
    if window.v then
        imgui.SetNextWindowSize(imgui.ImVec2(250, 225), imgui.Cond.FirstUseEver)

        imgui.SetNextWindowPos(imgui.ImVec2((sw / 2), sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.Begin('GiveAway || BETA', window)
        --imgui.SameLine(60)
        if imgui.Button(giveaway and u8'Остановить розыгрыш' or u8'Запустить розыгрыш', imgui.ImVec2(-1, 35)) then
            if members.v == "" or mesta.v == "" or prize.v == "" then
                sampAddChatMessage('Недостаточно аргументов', -1)
            else
                giveaway = not giveaway
                proverka()
                hook = not hook
            end
        end
        --if #member > members.v then sampAddChatMessage('Достигнут лимит участников! Начинаю розыгрыш', -1) hook = true end
        --if members.v > #member then podchet = true en
        if #member > members.v then sampAddChatMessage('Достигнут лимит участников. Начинаю розыгрыш!', -1) hook = true end

        imgui.Separator()
        imgui.PushItemWidth(50)
        imgui.InputText(u8' || Кол-во участников', members)
        imgui.PopItemWidth()
        imgui.PushItemWidth(50)
        imgui.InputText(u8' || Сколько призовых мест', mesta)
        imgui.PopItemWidth()
        imgui.PushItemWidth(50)
        imgui.InputText(u8' || Приз на каждого', prize)
        imgui.PopItemWidth()
        imgui.Separator()
        --imgui.NewLine()
        --imgui.NewLine()
        --imgui.SameLine(63)
        imgui.BeginChild('##memberrss', imgui.ImVec2(-1, -1), true)
        imgui.Text(u8'Список участников:')
        imgui.SameLine()
        if imgui.Button(u8'Очистить', imgui.ImVec2(-1, 18)) then member = {} end
        for i=1, #member do
            imgui.Text(member[i])
        end
        --if members.v ~= "" and giveaway then
        --end
        imgui.NewLine()
        imgui.EndChild()
        imgui.End()
    end
end

function sampev.onServerMessage(color, text)
    if giveaway and hook then
        if text:find('{......}(%S+)%[(%d+)%] говорит:{B7AFAF}  %+') and #member ~= nickname then
            nickname, id, msg = text:match('{......}(%S+)%[(%d+)%] говорит:{B7AFAF}  %+')
            table.insert(member, string.format('%s[%d]', nickname, id))
            --members = members + 1
        end
    end
end
Помогите пожалуйста подправить код, в консоле вот такая ошибка [ML] (error) GiveAway.lua: D:\GTA San Andreas\moonloader\GiveAway.lua:67: attempt to compare string with number stack traceback: Кто может помогите прошу, я ебусь с этой хуетой пол дня. В пустой мозг ничего не приходит
 

paulohardy

вы еще постите говно? тогда я иду к вам
Всефорумный модератор
1,920
1,292
Помогите пожалуйста исправить код, в консоле вот такая ошибка [ML] (error) GiveAway.lua: D:\GTA San Andreas\moonloader\GiveAway.lua:67: attempt to compare string with number stack traceback: Кто может помогите прошу, я ебусь с этой хуетой пол дня
тебе же ответили уже
ты пытаешься сравнить число и строку, так делать нельзя
1628367278938.png
 
  • Нравится
Реакции: Sanchez.

kizn

q(≧▽≦q)
Всефорумный модератор
2,409
2,101
Lua:
local imgui = require 'imgui'
local encoding = require 'encoding'
local sampev = require 'lib.samp.events'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local window = imgui.ImBool(false)

local nickname, id, msg = nil,nil,nil

local sw, sh = getScreenResolution()

local members = imgui.ImBuffer(256)

--ocal members1 = 0

local prize = imgui.ImBuffer(256)

local mesta = imgui.ImBuffer(256)

local giveaway = false

local hook = false

local member = {}

function imgui.CenterButton(text)
    local width = imgui.GetWindowWidth()
    local calc = imgui.CalcTextSize(text)
    imgui.SetCursorPosX( width / 2 - calc.x / 2 )
    imgui.Button(text)
end

function main()
    while not isSampAvailable() do wait(200) end

    sampRegisterChatCommand('giveaway', function()
        window.v = not window.v
    end)

    while true do
        wait(0)
        imgui.Process = window.v
    end
end

function imgui.OnDrawFrame()
    if window.v then
        imgui.SetNextWindowSize(imgui.ImVec2(250, 225), imgui.Cond.FirstUseEver)

        imgui.SetNextWindowPos(imgui.ImVec2((sw / 2), sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.Begin('GiveAway || BETA', window)
        --imgui.SameLine(60)
        if imgui.Button(giveaway and u8'Остановить розыгрыш' or u8'Запустить розыгрыш', imgui.ImVec2(-1, 35)) then
            if members.v == "" or mesta.v == "" or prize.v == "" then
                sampAddChatMessage('Недостаточно аргументов', -1)
            else
                giveaway = not giveaway
                proverka()
                hook = not hook
            end
        end
        --if #member > members.v then sampAddChatMessage('Достигнут лимит участников! Начинаю розыгрыш', -1) hook = true end
        --if members.v > #member then podchet = true en
        if #member > members.v then sampAddChatMessage('Достигнут лимит участников. Начинаю розыгрыш!', -1) hook = true end

        imgui.Separator()
        imgui.PushItemWidth(50)
        imgui.InputText(u8' || Кол-во участников', members)
        imgui.PopItemWidth()
        imgui.PushItemWidth(50)
        imgui.InputText(u8' || Сколько призовых мест', mesta)
        imgui.PopItemWidth()
        imgui.PushItemWidth(50)
        imgui.InputText(u8' || Приз на каждого', prize)
        imgui.PopItemWidth()
        imgui.Separator()
        --imgui.NewLine()
        --imgui.NewLine()
        --imgui.SameLine(63)
        imgui.BeginChild('##memberrss', imgui.ImVec2(-1, -1), true)
        imgui.Text(u8'Список участников:')
        imgui.SameLine()
        if imgui.Button(u8'Очистить', imgui.ImVec2(-1, 18)) then member = {} end
        for i=1, #member do
            imgui.Text(member[i])
        end
        --if members.v ~= "" and giveaway then
        --end
        imgui.NewLine()
        imgui.EndChild()
        imgui.End()
    end
end

function sampev.onServerMessage(color, text)
    if giveaway and hook then
        if text:find('{......}(%S+)%[(%d+)%] говорит:{B7AFAF}  %+') and #member ~= nickname then
            nickname, id, msg = text:match('{......}(%S+)%[(%d+)%] говорит:{B7AFAF}  %+')
            table.insert(member, string.format('%s[%d]', nickname, id))
            --members = members + 1
        end
    end
end
Помогите пожалуйста подправить код, в консоле вот такая ошибка [ML] (error) GiveAway.lua: D:\GTA San Andreas\moonloader\GiveAway.lua:67: attempt to compare string with number stack traceback: Кто может помогите прошу, я ебусь с этой хуетой пол дня. В пустой мозг ничего не приходит
#member > #members.v
 
  • Нравится
Реакции: Sanchez.

bab0n

Известный
95
10
Попытка сделать так
Lua:
picks = getAllPickups()
Приводит к такому:
attempt to call global 'getAllPickups' (a nil value)
stack traceback:
E:\sa_mp\moonloader\fullghettohelper.lua: in function <E:\sa_mp\moonloader\fullghettohelper.lua:200>
[ML] (error) fullghettohelper.lua: Script died due to an error. (07D15F04)

Возможно баг @FYP
Если есть альтернатива, подскажите пожалуйста
 

Dmitriy Makarov

25.05.2021
Проверенный
2,505
1,134
Попытка сделать так
Lua:
picks = getAllPickups()
Приводит к такому:
attempt to call global 'getAllPickups' (a nil value)
stack traceback:
E:\sa_mp\moonloader\fullghettohelper.lua: in function <E:\sa_mp\moonloader\fullghettohelper.lua:200>
[ML] (error) fullghettohelper.lua: Script died due to an error. (07D15F04)
На MoonLoader 0.27 работает эта функция вроде.
 
  • Нравится
Реакции: bab0n

lorgon

Известный
656
271
Можно ли сохранять объёмные таблицы(больше 300к строк) в ini конфигах? Стоит ли для этого использовать json и есть ли для него библиотека(что-бы самому не писать функции сохранения/чтения и т. п.)
 

AnWu

Известный
Всефорумный модератор
4,777
5,402
Можно ли сохранять объёмные таблицы(больше 300к строк) в ini конфигах? Стоит ли для этого использовать json и есть ли для него библиотека(что-бы самому не писать функции сохранения/чтения и т. п.)
сомневаюсь, разумно использовать json. либы точно есть, на гитхабе поищи. однако лучше самому написать 4 строки, ладно 8 на две функции
 
  • Нравится
Реакции: lorgon

JustFedot

Известный
338
338
Утро доброе ребята.
Давно меня не было, уже всё позабывал, вот пытаюсь восстановиться.
Подскажите мне пожалуйста, как можно узнать что меня отключило от сервера?
Знаю способ через беск. цикл с sampGetGamestate(), но может можно что-то использовать без беск. цикла....
сомневаюсь, разумно использовать json. либы точно есть, на гитхабе поищи. однако лучше самому написать 4 строки, ладно 8 на две функции
Какраз вопрос по этому поводу.
В чём разница между json и ini если шо то шо то используется в скрипте по сути как текстовый файл? Я всё ещё нуб, объясните пожалуйста.
 
Последнее редактирование:

Aniki

🐰
Администратор
1,229
1,568
Утро доброе ребята.
Давно меня не было, уже всё позабывал, вот пытаюсь восстановиться.
Подскажите мне пожалуйста, как можно узнать что меня отключило от сервера?
Знаю способ через беск. цикл с sampGetGamestate(), но может можно что-то использовать без беск. цикла....

Какраз вопрос по этому поводу.
В чём разница между json и ini если шо то шо то используется в скрипте по сути как текстовый файл? Я всё ещё нуб, объясните пожалуйста.
1. По идее можно это детектить по приходу пакетов с id 32 и 33, но я не тестил, мб там другие числа
2. Разница в формате данных, json является более продвинутым, так как позволяет хранить таблицы с сильной вложенностью, в то время как .ini позволяет лишь хранить пары ключ-значение в различных секциях, то есть от силы два уровня вложенности
 
Последнее редактирование:
  • Нравится
Реакции: JustFedot

JustFedot

Известный
338
338
1. По идее можно это детектить по приходу пакетов с id 32 и 33, но я не тестил, мб там другие числа
2. Разница в формате данных, json является более продвинутым, так как позволяет хранить таблицы с сильной вложенностью, в то время как .ini позволяет лишь хранить пары ключ-значение в различных секциях, то есть от силы два уровня вложенности
Как-то так?

Lua:
function onReceivePacket(id)
    if id == 34 then
        print('Долбаная арз опять упала')
    end
end
Никогда не работал с этим событием так шо лучше уточню.

С json внутри скрипта работать так-же как и с ini, тоесть как с текстовым файлом?
 

Aniki

🐰
Администратор
1,229
1,568
Как-то так?

Код:
function onReceivePacket(id)
    if id == 32 then
        print('Прошла любовь, завяли помидоры, арз опять вылетела...')
    end
end
Никогда не работал с этим событием так шо лучше уточню.

С json внутри скрипта работать так-же как и с ini, тоесть как с текстовым файлом?
Да, как то так, возможно стоит проверять id == 32 or id == 33 так как возможны разные пакеты для потерянного и закрытого соединения.
С json работать очень просто, данные которые следует сохранить нужно держать в одной таблице и перед сохранением в файл делать s = encodeJson(t) и сохранять s как обычный текст в файле, и наоборот, при чтении из файла делать t = decodeJson(s) и на выходе получать сохраненную таблицу.
 
  • Влюблен
Реакции: JustFedot

Carozza

Новичок
2
0
Привет парни, извините конечно за такой вопрос, просто я сейчас переписываю скрипт, и у меня возникла проблема. Я не понимаю каким образом можно сделать так, чтобы сотрудник ПД написав команду которая уже готова /pdmenu выбрал сам себе там ТЭГ и чтобы допустим когда он выходил в патруль, нажимал кнопочку и ТЭГ автоматически шел в рацию который он сам написал. Да и чтобы при обычном разговоре в рацию он шел, очень сильно нужна ваша помощь.
То есть пример:
/r [Тэг который написал сам] Патрулирую район Маркет.
Вот скрины самого скрипта.
n_LrL039Yek.jpg

3b97Qh2KJp0.jpg
 
Последнее редактирование модератором:

Warklot

Известный
112
3
Hi how to display FromPos, destPos, rotation information? like i wanna see numbers but instead i get blank like nothing showing
Lua:
function sampev.onMoveObject(objectId,fromPos,destPos,speed,rotation)

sampAddChatMessage(FromPos, 0xFFD00000)
sampAddChatMessage (destPos, 0xFFD00000)
sampAddChatMessage (rotation, 0xFFD00000)
end
 

Aniki

🐰
Администратор
1,229
1,568
Hi how to display FromPos, destPos, rotation information? like i wanna see numbers but instead i get blank like nothing showing
Lua:
function sampev.onMoveObject(objectId,fromPos,destPos,speed,rotation)

sampAddChatMessage(FromPos, 0xFFD00000)
sampAddChatMessage (destPos, 0xFFD00000)
sampAddChatMessage (rotation, 0xFFD00000)
end
You should use fromPos.x, fromPos.y, fromPos.z and so on to get values from vector3d type. Also, variables in lua are case-sensitive, you typed FromPos instead of fromPos in sampAddChatMessage, dont forget to fix this too
 
Последнее редактирование:
  • Нравится
Реакции: Warklot