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

Eugene Crabs

Активный
544
30
это не сайт гадалок, без кода понять в чем проблема не получится
Код на 500 строчек. Если я его выложу - мало кто будет читать его полностью. Так что в начале следует вообще понять из-за чего возникают эти ошибки, чтобы я мог выложить нужный кусок кода.

Вопрос: Как исправить ошибки "cannot resume non-suspended coroutine" и "not enough memory" (в moonloader.log)?
Как можно сделать проверку на координаты? К примеру: у меня есть координаты и мне нужно если они равны - запустить код
if не пашет?
 
Последнее редактирование:

astynk

Известный
Проверенный
742
530
Код на 500 строчек. Если я его выложу - мало кто будет читать его полностью. Так что в начале следует вообще понять из-за чего возникают эти ошибки, чтобы я мог выложить нужный кусок кода.

Вопрос: Как исправить ошибки "cannot resume non-suspended coroutine" и "not enough memory" (в moonloader.log)?
Первое - скорее всего связано с потоками.
Второе - не сталкивался лично, но судя по названию, грубая ошибка в алгоритме. Выполняешь тяжеловесные операции в бесконечном цикле.

Скинь хотя бы строчки, на которые ругается.
 

[SA ARZ]

Известный
390
8
помогите улучшить систему покраски ника в /r /f

2:
if funcColorRadio and string.match(text,"^%[.+%]%s%[.+%]:%s.+%s%a+_%a+%[.+%]: .+") then -- покраска ников в /r, /f чатах
        local chat, tagRadio, zvan, nick, id, text2 = text:match('^%[(.+)%]%s%[(.+)%]:%s(.+)%s(%a+_%a+)%[(%d+)%]: (.+)')
        local chats = { ['F'] = true, ['R'] = true, ['T'] = true }
        if tagRadio == "ВВС" then
            tagRadioNew = "AF"
        elseif tagRadio == "ВМФ" then
            tagRadioNew = "Navy"
        elseif tagRadio == "СВ" then
            tagRadioNew = "GF"
        else
            tagRadioNew = tagRadio
        end
        if zvan:find(RangLeaders1) or zvan:find(RangLeaders2) or zvan:find(RangLeaders3) or zvan:find(RangLeaders4) then
            print("1 | SystemRadio - FFFFFF")
            if systemMM and zvan:find(RangLeaders5) then
                return { color, '['..chat..'] '..zvan..' {FFFFFF}'..nick..'['..id..']: {'..string.format('%X', bit.rshift(color, 8))..'}'..text2 }
            else
                return { color, '['..chat..'] '..zvan..' {FFFFFF}'..nick..'['..id..']: {'..string.format('%X', bit.rshift(color, 8))..'}'..text2 }
            end
        else
            for k, v in ipairs(tablePremium) do
                if v[1] ~= nil then
                    if nick:find(v[1]) then
                        colorPremiumRadio = v[2]
                        break
                    else
                        colorPremiumRadio = string.format('%X', bit.rshift(color, 8))               
                    end
                end
            end
            print("2 | SystemRadio - "..colorPremiumRadio.."")
            return { color, '['..chat..'] ['..tagRadioNew..'] '..zvan..' {'..colorPremiumRadio..'}'..nick..'['..id..']: {'..string.format('%X', bit.rshift(color, 8))..'}'..text2 }
        end
end
 

astynk

Известный
Проверенный
742
530
Как можно сделать проверку на координаты? К примеру: у меня есть координаты и мне нужно если они равны - запустить код
Равны они никогда не будут, надо сравнивать примерное соответствие
Lua:
if getDistanceBetweenCoords3d(getCharCoordinates(PLAYER_PED), x, y, z) < 1 then
 

neverlane

t.me/neverlane00
Друг
1,000
1,139
Как сделать чтоб строка не отображалась в чате?
Вот как я пытался сделать, но робит.
zQM4KwQ.png

Lua:
if text:find('Ок да') then
    return false
end
 

Eugene Crabs

Активный
544
30
Первое - скорее всего связано с потоками.
Второе - не сталкивался лично, но судя по названию, грубая ошибка в алгоритме. Выполняешь тяжеловесные операции в бесконечном цикле.

Скинь хотя бы строчки, на которые ругается.
По поводу первого: В скрипте всего 1 поток, он запускает функцию, которая активирует другие функции.
По поводу второго: Да, бесконечный цикл есть. Тяжеловесные операции? Это как?

Строчки ниже
Первое, Лог:
[20:02:25.618150] (error) Программа4.lua: cannot resume non-suspended coroutine
stack traceback:
[C]: in function 'processLineOfSight'
...ltiPlayer Clear\moonloader\Программа4.lua:135: in function ''Qwerty"
...ltiPlayer Clear\moonloader\Программа4.lua:95: in function <...ltiPlayer Clear\moonloader\Программа4.lua:62>

Первое, строчка кода:
result, colPoint = processLineOfSight(currect[1], currect[2], currect[3], X, Y, Z, true, true, false, false, false, false, false, false)

p.s. Находится внутри цикла (For, а сам For в While).
p.p.s. Также он с такой же ошибкой ругался на рандомную "getDistanceBetweenToCoords" в программе. Она тоже в цикле, если это поможет (For, а сам For в While).


По поводу второго: Эта ошибка исчезла. Но ругалась она только на рандомную функцию "getDistanceBetweenToCoords" в программе. Появится снова - отпишусь

p.p.p.s Все числа округлены до десятых
 

Thief

Участник
108
12
можно ли как-то сделать, чтобы скрипт удалял сам себя перед отгрузкой?
 

daite na_vodky

Известный
147
47
нужно получить пол и ранг в байкерах (Prospect) из этого диалога. Как это сделать?


Код:
{FFFFFF}Номер аккаунта:         {0099ff}0
{FFFFFF}Имя:                 {0099ff}Nick
{FFFFFF}Уровень:             {0099ff}0
{FFFFFF}Очки опыта:             {0099ff}0 из {0099ff}0
{FFFFFF}Предупреждений:         {0099ff}0

{FFFFFF}Номер телефона:         {0099ff}0
{FFFFFF}На счету телефона:        {0099ff}0

{FFFFFF}Законопослушность:         {0099ff}0
{FFFFFF}Уровень розыска:         {0099ff}0
{FFFFFF}Купоны рулетки:         {0099ff}0
{FFFFFF}Бриллианты:             {0099ff}0
{FFFFFF}Фишки Four Dragons:         {0099ff}0
{FFFFFF}Фишки Royale:             {0099ff}0
{FFFFFF}Семейные очки:             {0099ff}0

{FFFFFF}Пол:                 {0099ff}Женский
{FFFFFF}Возраст:             {0099ff}0
{FFFFFF}Муж/Жена:             {0099ff}Отсутствует
{FFFFFF}Национальность:             {0099ff}Американец

{FFFFFF}Организация:             {0099ff}Отсутствует
{FFFFFF}Работа/Должность:         {0099ff}Водитель автобуса
{FFFFFF}Ранг:                 {0099ff}0
{FFFFFF}Выговоров:                 {0099ff}0

{FFFFFF}Дома:                 {0099ff}Отсутствуют
{FFFFFF}Бизнесы:             {0099ff}Отсутствуют
{FFFFFF}Отель:                 {0099ff}Отсутствует
{FFFFFF}Клуб байкеров:         {0099ff}Bandidos {FFFFFF}(Prospect)

{FFFFFF}Время:                 {0099ff}20:13:38
{FFFFFF}Дата:                 {0099ff}14.01.2020
 

Lucifer Melton

Активный
164
57
помогите улучшить систему покраски ника в /r /f

2:
if funcColorRadio and string.match(text,"^%[.+%]%s%[.+%]:%s.+%s%a+_%a+%[.+%]: .+") then -- покраска ников в /r, /f чатах
        local chat, tagRadio, zvan, nick, id, text2 = text:match('^%[(.+)%]%s%[(.+)%]:%s(.+)%s(%a+_%a+)%[(%d+)%]: (.+)')
        local chats = { ['F'] = true, ['R'] = true, ['T'] = true }
        if tagRadio == "ВВС" then
            tagRadioNew = "AF"
        elseif tagRadio == "ВМФ" then
            tagRadioNew = "Navy"
        elseif tagRadio == "СВ" then
            tagRadioNew = "GF"
        else
            tagRadioNew = tagRadio
        end
        if zvan:find(RangLeaders1) or zvan:find(RangLeaders2) or zvan:find(RangLeaders3) or zvan:find(RangLeaders4) then
            print("1 | SystemRadio - FFFFFF")
            if systemMM and zvan:find(RangLeaders5) then
                return { color, '['..chat..'] '..zvan..' {FFFFFF}'..nick..'['..id..']: {'..string.format('%X', bit.rshift(color, 8))..'}'..text2 }
            else
                return { color, '['..chat..'] '..zvan..' {FFFFFF}'..nick..'['..id..']: {'..string.format('%X', bit.rshift(color, 8))..'}'..text2 }
            end
        else
            for k, v in ipairs(tablePremium) do
                if v[1] ~= nil then
                    if nick:find(v[1]) then
                        colorPremiumRadio = v[2]
                        break
                    else
                        colorPremiumRadio = string.format('%X', bit.rshift(color, 8))              
                    end
                end
            end
            print("2 | SystemRadio - "..colorPremiumRadio.."")
            return { color, '['..chat..'] ['..tagRadioNew..'] '..zvan..' {'..colorPremiumRadio..'}'..nick..'['..id..']: {'..string.format('%X', bit.rshift(color, 8))..'}'..text2 }
        end
end
Lua:
    if message:find("%[(.*)%] (.*) (%w+_%w+%[%d+%]): (.*)") then
        local radio, rang, nick_id, text = message:match("%[(.*)%] (.*) (%w+_%w+%[%d+%]): (.*)")
        local rang = rang:gsub("ВВС", "AF"); local rang = rang:gsub("СВ", "GF"); local rang = rang:gsub("ВМФ", "Navy")
        if rang:find("Лейтенант") then
            return {color, "["..radio.."] "..rang.." {FFFFFF}"..nick_id..": {"..("%0.6x"):format(bit.rshift(color, 8)).."}"..text}
        end
        return {color, "["..radio.."] "..rang.." "..nick_id..": "..text}
    end