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

ШPEK

Известный
1,474
526
Как вывести мой текст на скин или над головой игрок, то есть после ввода команды будет писать у всех игроков на скине текст, код если можно (я новичек). Зарание спасибо
Через 3d текст можно просто написать id игрока и закрепить над ним его, но с этим способом будет сложнее его убрать.
Можно сделать через render как написал выше Trefa_
 

checkdasound

Известный
Проверенный
963
410
Как вывести мой текст на скин или над головой игрок, то есть после ввода команды будет писать у всех игроков на скине текст, код если можно (я новичек). Зарание спасибо
Вот, только не факт, что сто процентов работать будет, я его из другого своего скрипта взял.
Lua:
ffi = require "ffi"
getBonePosition = ffi.cast("int (__thiscall*)(void*, float*, int, bool)", 0x5E4280)

DIST = 25.5 -- Дистанция отрисовки нужного тебе текста.
status = true -- при заходе в игру скрипт уже будет работать.

function main()
    font = renderCreateFont('Tahoma', 10, 13) -- создание шрифта
    while true do wait(0)
        if status then
            for k, PED in pairs(getAllChars()) do -- перебор всех игроков в зоне стрима, где PED - хэндл
                local res, id = sampGetPlayerIdByCharHandle(PED) -- получение id этих игроков
                if res then -- если получение ид прошло успешно, то
                    if isCharOnScreen(PED) and PED ~= PLAYER_PED and not sampIsPlayerNpc(id) then -- если игрок на экране и этот игрок не наш и игрок не npc, то
                        local x, y, z = getCharCoordinates(PED) -- получаем координаты игрока
                        local x2, y2, z2 = getCharCoordinates(PLAYER_PED) -- получаем свои координаты
                        local distance = getDistanceBetweenCoords3d(x, y, z, x2, y2, z2) -- получаем расстояние от себя до игрока
                        if distance <= DIST and isPointOnScreen(x, y, z, 0.0) then -- если дистанция меньше или равна указанной в переменной DIST, то
                            local x6, y6, z6 = GetBodyPartCoordinates(6, PED) -- получение координатов кости под идом 6 (голова).
                            local x6, y6 = convert3DCoordsToScreen(x6, y6, z6) -- Конвертация 3д координаты в координаты экрана.
                            local color = sampGetPlayerColor(id) -- получение цвета игрока
                            if sampIsPlayerPaused(id) then -- если игрок на паузе, то
                                renderFontDrawText(font, '[AFK]', x6, y6 / 1.14, color) -- также если тебе нужно, чтобы было над головой, то делай небольшое смещение от координат головы,
                                -- в данном случае 1.14, если тебе нужно более высокое расположение, то увеличивай это значение.
                            end
                        end
                    end
                end
            end
        end
    end
end
     
     
function GetBodyPartCoordinates(id, handle)
  local pedptr = getCharPointer(handle)
  local vec = ffi.new("float[3]")
  getBonePosition(ffi.cast("void*", pedptr), vec, id, true)
  return vec[0], vec[1], vec[2]
end


Впорос:
Как можно реализовать получение ближайшего к прицелу игрока? Понятно, что в цикле надо получать координаты всех игроков, переводить в 2д и отмерять от центра экрана расстояние. Но как потом рассортировать их, чтобы скрипт понимал какой игрок ближе.
 

BARRY BRADLEY

Известный
711
177
Впорос:
Как можно реализовать получение ближайшего к прицелу игрока? Понятно, что в цикле надо получать координаты всех игроков, переводить в 2д и отмерять от центра экрана расстояние. Но как потом рассортировать их, чтобы скрипт понимал какой игрок ближе.
А что такое "ffi"? Библиотека?
 

uryukhai

Активный
196
104
поч не робит?
Lua:
weapon_table = {[335] = 'Knife',[346] = 'Pistol',[347] = 'Silenced Pistol',[348] = 'Desert Eagle',[349] = 'Shotgun',[350] = 'Sawnoff',[351] = 'Combat Shotgun',
    [352] = 'Micro Uzi',[353] = 'MP5',[355] = 'AK-47',[356] = 'M4',[357] = 'Country Rifle',[358] = 'Sniper Rifle',[359] = 'RPG',[360] = 'HS Rocket',[361] = 'Flamethrower',
    [362] = 'Minigun',[370] = 'Jetpack',[372] = 'Tec-9',[373] = 'Armour'}

        for _, v in pairs(weapon_table) do
            if v ~= nil and doesObjectExist(v) then
                _, x, y, z = getObjectCoordinates(v)
                objmodel = getObjectModel(v)
                px, py, pz = getCharCoordinates(playerPed)
                r = getDistanceBetweenCoords3d(px, py, pz, x, y, z)
                if isPointOnScreen(x, y, z, 0) and r <= 310 then
                    cx, zy = convert3DCoordsToScreen(x, y, z)
                    renderFontDrawText(font2, objmodel, cx, zy, -1)
                end
            end
        end
 

ШPEK

Известный
1,474
526
поч не робит?
Lua:
weapon_table = {[335] = 'Knife',[346] = 'Pistol',[347] = 'Silenced Pistol',[348] = 'Desert Eagle',[349] = 'Shotgun',[350] = 'Sawnoff',[351] = 'Combat Shotgun',
    [352] = 'Micro Uzi',[353] = 'MP5',[355] = 'AK-47',[356] = 'M4',[357] = 'Country Rifle',[358] = 'Sniper Rifle',[359] = 'RPG',[360] = 'HS Rocket',[361] = 'Flamethrower',
    [362] = 'Minigun',[370] = 'Jetpack',[372] = 'Tec-9',[373] = 'Armour'}

        for _, v in pairs(weapon_table) do
            if v ~= nil and doesObjectExist(v) then
                _, x, y, z = getObjectCoordinates(v)
                objmodel = getObjectModel(v)
                px, py, pz = getCharCoordinates(playerPed)
                r = getDistanceBetweenCoords3d(px, py, pz, x, y, z)
                if isPointOnScreen(x, y, z, 0) and r <= 310 then
                    cx, zy = convert3DCoordsToScreen(x, y, z)
                    renderFontDrawText(font2, objmodel, cx, zy, -1)
                end
            end
        end
перепутал названия с хэндлом
 

petuch228

Новичок
82
2
Потому что когда к тебе приходит RPC onVehicleStreamIn собственно транспорт еще не существует, поэтому ты не можешь получить его хендл по айди. Чтобы его получить нормально, нужна хотя бы нулевая задержка, а проверить готовность можно с помощью doesVehicleExists(vehHandle)

Нужно сделать корректное условие (например регулярное выражение) для нужной тебе 3д надписи
Даже с нулевой задержкой не срабатывает иногда
 

checkdasound

Известный
Проверенный
963
410
Как можно реализовать получение ближайшего к прицелу игрока? Понятно, что в цикле надо получать координаты всех игроков, переводить в 2д и отмерять от центра экрана расстояние. Но как потом рассортировать их, чтобы скрипт понимал какой игрок ближе.