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

l-m

Новичок
28
1
Объясните пожалуйста КАК ЄТО РАБОТАЕТ, не могу засветить кнопку при нажатии на нее, да и вообще функционал с этими кнопка в Sweet Connect
Исходник, пример кода: https://www.blast.hk/threads/64892/
image.png

image.png
 

Карен

Участник
112
17
Lua:
[/B]
function runToPoint(tox, toy)
    lua_thread.create(function()
        local x, y, z = getCharCoordinates(PLAYER_PED)
        local angle = getHeadingFromVector2d(tox - x, toy - y)
        local xAngle = math.random(-50, 50)/100
        setCameraPositionUnfixed(xAngle, math.rad(angle - 90))
        stopRun = false
        while getDistanceBetweenCoords2d(x, y, tox, toy) > 0.8 do
            setGameKeyState(1, -255)
            --setGameKeyState(16, 1)
            wait(1)
            x, y, z = getCharCoordinates(PLAYER_PED)
            angle = getHeadingFromVector2d(tox - x, toy - y)
            setCameraPositionUnfixed(xAngle, math.rad(angle - 90))
            if stopRun then
                stopRun = false
                break
            end
        end
    end)
end
[B]

Как сделать чтобы runToPoint бежал к самому близкому обьекту, а не к самому дальному?
 

why ega

РП игрок
Модератор
2,539
2,230
не, проверка, является ли аргумент текстом.
upd. уже нашел способ решения.
tonumber() не предназначена для проверки именно типа, она просто переводит какой-то тип в число и если это строка, которая состоит только из чисел или это уже число, т.е. true, то возвращает это число, иначе nil - т.е. false.
1680108150965.png

вот именно проверка типа:
Lua:
local text = 313

if type(text) == "string" then
    ...
else
    print("не строка")
end
1680108232790.png


кстати, я так понимаю ты не совсем понимаешь, что такое типы в луа, поэтому вот небольшой отрывок из статейки

2.1 – Значения и типы​

Lua динамически типизированный язык. Это означает, что значения не имеют типов; только значения. Язык не имеет определений типов. Все значения несут свой собственный тип.

Все значения в Lua первоклассные. Это означает что все значения могут быть сохранены в переменных, переданы как аргументы другим функциям, и возвращены как результаты.

В Lua существует восемь базовых типов: nil, boolean, number, string, function, userdata, thread и table.

Тип nil (нуль) имеет одно единственное значение, nil, его главное свойство это отличаться от любых других значений; обычно это означает отсутствие используемого значения.

Тип boolean (логический) имеет два значения: false (ложь) и true (истина). Оба nil и false означают false; любое другое значение означает true.

Тип number (число) представляет целые (integer) и вещественные (float) числа.

Тип string (строка) представляет неизменные последовательности байт. Строки в Lua могут содержать любое 8-битное значение, включая нули ('\0'). Также Lua противник кодировок; никаких предположений о содержимом строки не делается.

Тип number использует два внутренних представления, или два подтипа, один называется integer (целое), второй float (число с плавающей запятой). Lua имеет явные правила о том, когда какое представление использовать, но при необходимости автоматически конвертирует значение между ними (см. §3.4.3). Следовательно, в большистве случаев программист может игнорировать разницу между целыми и реальными числами, или получить полный контроль над представлением каждого числа. Стандартный Lua использует 64-битные целые (integer) и вещественные числа двойной точности (double 64-bit), но также возможно скомпилировать Lua так, чтобы использовались 32-битные целые и/или вещественные числа одинарной точности (float 32-bit). Эта опция с 32 битами для целых и вещественных чисел особенно актуальна для малых машин и встроенных систем. (Смотри макрос LUA_32BITS в файле luaconf.h.)

Lua может вызывать и манипулировать функциями написанными на Lua и на С (см. §3.4.10). Оба типа функций в Lua представлены типом function (функция).

Тип userdata (пользовательские данные) предназначен для хранения произвольных С данных в Lua переменных. Значение userdata представляет блок памяти (raw memory). Существуют два типа пользовательских данных: full userdata (полные пользовательские данные) - объект с блоком памяти, которым управляет Lua, и light userdata (лёгкие пользовательские данные) - простой С указатель. Пользовательские данные не имеют предопределенных операторов в Lua, кроме оператора присвоения и сравнения на идентичность. Используя метатаблицы, программист может определить операции для значений full userdata (см. §2.4). Значения userdata не могут быть созданы или изменены в Lua, это возможно только через C API. Это гарантирует целостность данных, которыми владеет хост-программа.

Тип thread (поток) представляет независимый поток выполнения и используется для реализации сопрограмм (coroutine) (см. §2.6). Lua потоки это не реальные потоки операционной системы. Lua поддерживает сопрограммы на всех системах, даже на тех, где это не поддерживается операционной системой.

Тип table (таблица) реализует ассоциативные массивы, это значит, что массив может быть проиндексирован не только числами, но и любым Lua значением, кроме nil и NaN. (Not a Number специальное значение для представления неопределенных и непредставимых числовых результатов, таких как 0/0.) Таблицы могут быть гетерогенными (разнородными); т.е. могут содержать значения всех типов (кроме nil). Любой ключ со значением nil не считается частью таблицы. И наоборот, любой ключ, не являющийся частью таблицы, имеет ассоциированное значение nil.

Таблицы единственный механизм структурирования данных в Lua; они могут использоваться для представления обычных массивов, последовательностей, таблиц символов, множеств, записей, графов, деревьев и т.п. Для представления записей, Lua использует имена полей как индекс. Язык поддерживает представление a.name, как синтаксическое украшение a["name"]. Существуют различные пути создания таблиц в Lua (см. §3.4.9).

Мы используем термин последовательность (sequence) чтобы обозначить таблицу, где все ключи это натуральные числа {1..n} (1,2,3,...), где n - длина последовательности (см. §3.4.7).

Как и индексы, значения полей в таблице могут быть любого типа. В частности, т.к. функции это первоклассные значения, поля таблицы могут содержать функции. Такие таблицы также могут содержать методы (см. §3.4.11).

Индексирование в таблицах следует принципу "сырого" (raw) равенства в языке. Выражения a и a[j] определяют один и тот же элемент таблицы, если и только если i и j равны (raw equal) (значит, равны без метаметодов). В частности, вещественные числа (float) с целыми значениями равны соответствующим целым (integer), т.е., 1.0 == 1. Во избежание неоднозначностей, любое реальное число с целым значением, которое испльзуется как ключ, конвертируется в соответствующее ему целое число. Например, если написать a[2.0] = true, фактически в таблицу будет вставлен целочисленный (integer) ключ 2. С другой стороны, 2 and "2" разные Lua значения и следовательно обозначают разные данные в таблице.

Таблицы, функции, потоки и пользовательские данные (userdata) - это объекты: переменные фактически не содержат их значений, только ссылки на них. Присвоение, передача параметров и возврат из функций всегда манипулируют ссылками на эти значения; эти операции не подразумевают никакого типа копирования.

Библиотечная функция type возвращает строку с названием переданного ей типа (см. §6.1).

Взято от сюда (можешь почитать на досуге полностью статью, возможно не сразу все дойдет, но рано или поздно сможешь осилить): https://lua.org.ru/manual_ru.html#pdf-type
 
Последнее редактирование:

rissing

Потрачен
8
2
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
ку, как сделать ColorEdit4 и сохранение чтобы потом можно было заменять текст в чате на этот цвет?
 

why ega

РП игрок
Модератор
2,539
2,230
ку, как сделать ColorEdit4 и сохранение чтобы потом можно было заменять текст в чате на этот цвет?
 

sosnov

Известный
331
115
изучаю ини конфиг, и как с ним работать, но столкнулся с проблемой в мимгуи)
вот код:
Lua:
local imgui = require 'mimgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
local u8 = encoding.UTF8

--подключаем всё необходимое
local inicfg = require 'inicfg'
local settings = inicfg.load({
    otveti =
    {
        slova = false
    }}, 'testini.ini')
local status = inicfg.load(settings, 'testini.ini')
if not doesFileExist('moonloader/config/testini.ini') then inicfg.save(settings, 'testini.ini') end

local inputtextwords = imgui.new.bool(settings.otveti.slova) 
---------------------------------
local renderWindow = imgui.new.bool(), imgui.new.bool()

local inputtextwords = new.char[256]()newFrame = imgui.OnFrame(function() return renderWindow[0] end,
    function(player)
        imgui.SetNextWindowPos(imgui.ImVec2(500,500), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(245, 270), imgui.Cond.FirstUseEver)
        imgui.Begin('Test', renderWindow, imgui.WindowFlags.NoResize)
        if imgui.InputText('Save that##inputtextwords', inputtextwords, sizeof(inputtextwords)) then
      
        end
        if imgui.Button(u8"Сохранить") then
            settings.otveti.slova = inputtextwords[0]
            inicfg.save(settings, 'testini.ini')
            sampAddChatMessage('Изменения сохранены',-1)
        end
        imgui.End()
    end
)

function main()
    sampRegisterChatCommand('testini', function() renderWindow[0] = not renderWindow[0] end)
    wait(-1)
end
ошибка жалуется на глобальную new🤬
 

ALCAPONE2225

Известный
37
0
как в mimgui поставить сразу два InputTextFlags?
например imgui.InputTextFlags.Password и imgui.InputTextFlags.EnterReturnsTrue
 

YarikVL

Известный
Проверенный
4,812
1,819
как в mimgui поставить сразу два InputTextFlags?
например imgui.InputTextFlags.Password и imgui.InputTextFlags.EnterReturnsTrue
Символом + соединяй их, так вроде должно работать:
Lua:
imgui.InputTextFlags.Password + imgui.InputTextFlags.EnterReturnsTrue
 
  • Нравится
Реакции: why ega и ALCAPONE2225