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

inf

Известный
77
89
Ищу способ получить точку коллизии автомобиля с чем-либо, именно кузова. Фары, панели, вот эти все дела. Можно сказать так: "точка, откуда идут искры, если машина скребет кузовом или крышей по асфальту или об бордюры, дома, другие машины и т.д".
По каким адресам куда пролезть не могу найти(
 

FYP

Известный
Автор темы
Администратор
1,763
5,906
Ищу способ получить точку коллизии автомобиля с чем-либо, именно кузова. Фары, панели, вот эти все дела. Можно сказать так: "точка, откуда идут искры, если машина скребет кузовом или крышей по асфальту или об бордюры, дома, другие машины и т.д".
По каким адресам куда пролезть не могу найти(
[SA]Get a vehicle's collision points - Coding(http://gtaforums.com/topic/708854-saget-a-vehicles-collision-points/?p=1065397980)
оно?
 
  • Нравится
Реакции: eiuhuth и inf

inf

Известный
77
89
Да, спасибо, это то самое. Как раз по пути посмотрел кто от кого наследуется и вроде как получилось, что getCarPointer(car) указывает на CPlaceable, родительский класс для движущихся объектов, через который уже можно спуститься до CVehicle, ну или самое нижнее CAutomobile или CBike, ну или хз как, поправьте если не прав. Просто хочу разобраться,

Ищу способ получить точку коллизии автомобиля с чем-либо, именно кузова. Фары, панели, вот эти все дела. Можно сказать так: "точка, откуда идут искры, если машина скребет кузовом или крышей по асфальту или об бордюры, дома, другие машины и т.д".
По каким адресам куда пролезть не могу найти(
Lua:
local mem = require "memory"
local font = nil

function main()
    repeat wait(0) until isSampAvailable()
    font = renderCreateFont("Small Fonts", 8, FCR_BORDER)
    w, h = getScreenResolution()
    while true do
        local car = nil
        if isCharInAnyCar(playerPed) then
            car = storeCarCharIsInNoSave(playerPed)
        end
        if car then car = getCarPointer(car) end -- CPlaceable +0x00
        if car ~= nil then
            local panelid = mem.getuint16(car+0xF8) -- CPlaceable > CEntity > CPhysical +0xF8
            local colx = mem.getfloat(car+0xEC+0) -- CPlaceable > CEntity > CPhysical +0xEC
            local coly = mem.getfloat(car+0xEC+4)
            local colz = mem.getfloat(car+0xEC+8)
            renderFontDrawText(font, string.format("panel 0x%x colpoint %.2f %.2f %.2f", panelid, colx, coly, colz), w/2, h/2, 0xffffffff)
        end
        wait(1)
    end
end

function onExitScript()
    if font then renderReleaseFont(font) end
end
 
  • Нравится
Реакции: romacaddy

ynhhoJ

Известный
102
6
Приветствую.
Можно ли создать таймер на LUA?
К примеру, нужно что бы скрипт писал сообщение "Test script" раз в одну минуту, либо в 30 минут.
Т.е. что бы она вызывалась через определённое время...

Если это возможно, то как это можно создать?

Нашел это в интернете: SpellLibrary/timers.lua at master · Pizzalol/SpellLibrary · GitHub(https://github.com/Pizzalol/SpellLibrary/blob/master/game/scripts/vscripts/timers.lua)
Надеюсь что есть вариант по проще...
 

itsLegend

Фонд борьбы за жуков 🐞
Администратор
2,696
1,468
Он использует функции из доты.
Самый легкий - os.clock - отметка, и os.clock - текущий. Во время работы цикла проверяешь сколько времени прошло путем вычитания текущего времени и отметки.
Вместо os.clock можешь использовать lua - gameclock | BlastHack — DEV_WIKI(https://blast.hk/wiki/lua:gameclock)
 
  • Нравится
Реакции: ynhhoJ

ynhhoJ

Известный
102
6
Он использует функции из доты.
Самый легкий - os.clock - отметка, и os.clock - текущий. Во время работы цикла проверяешь сколько времени прошло путем вычитания текущего времени и отметки.
Вместо os.clock можешь использовать lua - gameclock | BlastHack — DEV_WIKI(https://blast.hk/wiki/lua:gameclock)
Спасибо!
Есть какие нибудь примеры с этой функцией?
Если нет, придется пробовать методом проб и ошибок, всё-же, огромное спасибо.
 

FYP

Известный
Автор темы
Администратор
1,763
5,906
@Johhny ещё можно просто создать отдельный поток и в нём с помощью обычного wait делать нужную задержку
 
  • Нравится
Реакции: ynhhoJ, eiuhuth и imring

ynhhoJ

Известный
102
6
@Johhny ещё можно просто создать отдельный поток и в нём с помощью обычного wait делать нужную задержку

Нашел такой вариант:
Lua:
local clock = os.clock
function sleep(n)  -- seconds
  local t0 = clock()
  while clock() - t0 <= n do end
  sampfuncsLog("{B22222}[Reference]:{FFFFFF} +")
  sampDestroy3dText(text)
end
на lua-users wiki: Sleep Function(http://lua-users.org/wiki/SleepFunction)
Проблема в том что когда выполняется эта функция, игру фризит на секунду...потом всё хорошо.
А как использовать: lua - gameclock | BlastHack — DEV_WIKI(https://blast.hk/wiki/lua:gameclock) , я не разобрался

Update
Вызываю я данную функцию так:
Lua:
sleep(10)

Какое число указано в sleep, на такое время игра и зависает...

Update v2
Lua:
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end  
  
    wait(-1)
end
function createtext()
    ....
    sleep()
    ....
end

function sleep()  -- seconds
    wait(1500) -- one second
    sampDestroy3dText(text)
    print("+")
end

Появляется ошибка: attempt to yield across C-call boundary
 
Последнее редактирование:

memir

🇷🇺
Всефорумный модератор
339
611
Нашел такой вариант:
Lua:
local clock = os.clock
function sleep(n)  -- seconds
  local t0 = clock()
  while clock() - t0 <= n do end
  sampfuncsLog("{B22222}[Reference]:{FFFFFF} +")
  sampDestroy3dText(text)
end
на lua-users wiki: Sleep Function(http://lua-users.org/wiki/SleepFunction)
Проблема в том что когда выполняется эта функция, игру фризит на секунду...потом всё хорошо.
А как использовать: lua - gameclock | BlastHack — DEV_WIKI(https://blast.hk/wiki/lua:gameclock) , я не разобрался

Update
Вызываю я данную функцию так:
Lua:
sleep(10)

Какое число указано в sleep, на такое время игра и зависает...
Функция sleep полностью замораживает поток на время которое ты указал, поэтому его вообще юзать не стоит.
По таймеру на os clock все расписал
Код:
function clock()
  clock = os.clock() -- получаем время работы программы
  while (os.clock() - clock < 5) do -- пока не пройдем 5 секунд после первого вызова ничего не делаем
    wait(0)
  end
  sampAddChatMessage("Прошло 5 секунд", 0xFFFFF) -- по прохождению 5 секунд уведомляем об этом в чат
end
 
  • Нравится
Реакции: ynhhoJ

ynhhoJ

Известный
102
6
Функция sleep полностью замораживает поток на время которое ты указал, поэтому его вообще юзать не стоит.
По таймеру на os clock все расписал
Код:
function clock()
  clock = os.clock()
  while (os.clock() - clock < 5) do
    wait(0) -- тут ошибка
  end
  sampAddChatMessage("Прошло 5 секунд", 0xFFFFF)
end
При вызове clock() крашит и показывает ошибку: attempt to yield across C-call boundary
Lua:
function clock()
  clock = os.clock()
  while (os.clock() - clock < 5) do
    wait(0) -- тут ошибка
  end
  sampAddChatMessage("Прошло 5 секунд", 0xFFFFF) 
end
 

4el0ve4ik

Известный
Всефорумный модератор
1,550
1,343
При вызове clock() крашит и показывает ошибку: attempt to yield across C-call boundary
Lua:
function clock()
  clock = os.clock()
  while (os.clock() - clock < 5) do
    wait(0) -- тут ошибка
  end
  sampAddChatMessage("Прошло 5 секунд", 0xFFFFF)
end
в комманде нельзя использовать бесконечные циклы и задержки.
 

ynhhoJ

Известный
102
6
в комманде нельзя использовать бесконечные циклы и задержки.
В таком варианте:
Lua:
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
 
    wait(-1)
end
function createtext()
    ....
    sleep()
    ....
end

function sleep()
    wait(1500) -- ругается на него
    sampDestroy3dText(text)
    print("+")
end

Тоже проблема с wait, не могу понять почему...
 

kraft1k

Вынь х*й из головы и все получится © hnnssy
Друг
1,480
1,168
Почему не работает рендер?

Lua:
while true do--
        wait(0)--
            for object = 0, MAX_OBJECTS do
                local result1, objecthandle = sampGetObjectHandleBySampId(object)
                if result1 then
                 if doesObjectExist(objecthandle) then
                    local modelId = getObjectModel(objecthandle)
                    local str = getObj(modelId)
                    if str ~= nil then
                        local X, Y, Z = getOffsetFromObjectInWorldCoords(objecthandle, 0.0, 0.0, 0.0)
                        local objectOnSreen = isPointOnScreen(X, Y, Z, 0.0)
                        if objectOnSreen then
                            local wposX, wposY = convert3DCoordsToScreen(X, Y, Z)
                            renderFontDrawText(font, str, wposX, wposY, -1)
                        end
                    end
                end
            end
        end
    end

function getObj(model)
    local Obj =
    {
        [11736] = "{0094c8}Kraft1k{FFFFFF}:{e3dc0b}Бинт",
        [11738] = "{0094c8}Kraft1k{FFFFFF}:{e3dc0b}Аптечка",
        [19823] = "{0094c8}Kraft1k{FFFFFF}:{e3dc0b}Снадобье",
        [335] = "{0094c8}Kraft1k{FFFFFF}:{e3dc0b}Нож"
    }
    return Obj[model]
end
 
  • Нравится
Реакции: Config

FYP

Известный
Автор темы
Администратор
1,763
5,906
@kraft1k цикл внутри main? если да, то из-за MAX_OBJECTS, добавь require 'sampfuncs' в начало