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

FBenz

Активный
328
40
Что делать, если мне нужно загрузить в память скрипта более 1000 картинок, но если я столько гружу, он просто крашит игру, еще не запустившись? Как выгрузить картинки из памяти?
 

Yuan

Участник
77
26
Что делать, если мне нужно загрузить в память скрипта более 1000 картинок, но если я столько гружу, он просто крашит игру, еще не запустившись? Как выгрузить картинки из памяти?
Зачем по 20 раз один и тот же вопрос? Достаточно открыть файл imgui.lua и найти там нужную функцию imgui.ReleaseTexture(texture). Держать все 1000 картинок сразу будет бредово, пожалуй. Лучше подгружать их по мере надобности и выгружать, если уже не требуются.
 
  • Нравится
Реакции: FBenz

FBenz

Активный
328
40
Зачем по 20 раз один и тот же вопрос? Достаточно открыть файл imgui.lua и найти там нужную функцию imgui.ReleaseTexture(texture). Держать все 1000 картинок сразу будет бредово, пожалуй. Лучше подгружать их по мере надобности и выгружать, если уже не требуются.
Подгружать пробовал. Провисания сильные идут во время загрузки в память, если грузить во время выполнения кода. Даже один раз. Там разом надо по 300+ картинок грузить циклом. И вот пока цикл загрузки всех картинок не выполнится - игра виснет и отвисает только когда загрузятся все 300.
Функция Release крашит игру при использовании.
 

Yuan

Участник
77
26
Подгружать пробовал. Провисания сильные идут во время загрузки в память, если грузить во время выполнения кода. Даже один раз. Там разом надо по 300+ картинок грузить циклом. И вот пока цикл загрузки всех картинок не выполнится - игра виснет и отвисает только когда загрузятся все 300.
Функция Release крашит игру при использовании.
Тебе прямо 300 нужны сразу? Если нет, то лучше по одиночке подгружать. Сейчас попробую заюзать функцию ту, но как по мне, должна работать.

UPD: У меня функция работает нормально. Использовал так:

Lua:
local texture = imgui.CreateTextureFromFile("image.png")
imgui.ReleaseTexture(texture)
 

Di3

Участник
432
20
Lua:
    imgui.Columns(4)
        imgui.Separator()
        imgui.SetColumnWidth(-1, 75); imgui.Text(u8'1-я ячейка'); imgui.NextColumn()
        imgui.SetColumnWidth(-1, 80) imgui.Text(u8('3-я ячейка'));  imgui.NextColumn()
        imgui.SetColumnWidth(-1, 80); imgui.Text(u8'2-я ячейка') imgui.NextColumn()  imgui.SetColumnWidth(-1, 80) imgui.Text(u8('4-я ячейка')); imgui.NextColumn()
        imgui.Separator()
                                imgui.Columns(1)
Есть такая табличка. Проблема в том что с помощью ПКМ можно двигать вертикальные линии,каким образом это исправить?
Актуально
 

Swayze.

Известный
27
0
Помогите пожалуйста, вырезал езду из рекордера ковра но не хочет ехать
Lua:
function reproduction(mode)
while true do
    wait(0)

    if mode == 1 then

local data = read_route_information()
if data then
    for key, value in pairs(data) do
        local PosX,PosY,PosZ sprintorSpeed, jump = value:match('{(.*)}:{(.*)}:{(.*)}:{(.*)}')
        if posX and PosY and PosZ and sprintorSpeed and jump then
            repeat
                wait(0)
                drawline(tonumber(posX), tonumber(PosY), tonumber(PosZ))
                local car = storeCarCharIsInNoSave(PLAYER_PED)
                if key % 2 > 0 then
                    local carPosX, carPosY, carPosZ = GetCarCoordinates(car)
                    turning_mechanism(tonumber(posX), tonumber(PosY), tonumber(PosZ), carPosX, carPosY, carPosZ, car)
                    if getcarSpeed(car) < sprintorSpeed + 0.2 then
                            press_gas()
                        else
                            press_brake()
                        end
                    else
                        break
                    end
            until LocateCharInCar2d(PLAYER_PED, tonumber(posX), tonumber(PosY), tonumber(PosZ), 7.0, 7.0, false)
            end
        end
    end
end
end
end


function turning_mechanism(posX, posY, carPosX, carPosY, car)
    local heading = math.rad(getHeadingFromVector2d(posX - carPosX, posY - carPosY) + math.abs(getCarHeading(car) - 360.0))
    local heading = getHeadingFromVector2d(math.deg(math.sin(heading)), math.deg(math.cos(heading)))
    if heading > 180.0 and 355.0 > heading then -- press left
        setGameKeyState(0, -128)
    else
        if heading > 5.0 and 180.0 >= heading then -- press right
            setGameKeyState(0, 128)
        else
            setGameKeyState(0, 0)
        end
    end
end

function press_gas()
    writeMemory(0xB73458 + 0x20, 1, 255, false)
end

function press_brake()
    writeMemory(0xB73458 + 0xC, 1, 255, false)
end

function set_camera_pos_unfix(posX, posY)
    local cPosX, cPosY, cPosZ = getActiveCameraCoordinates()
    setCameraPositionUnfixed(0.0, (getHeadingFromVector2d(posX - cPosX, posY - cPosY) - 90.0) / 57.2957795)
end

function draw_line(posX, posY)
    local chPosX, chPosY, chPosZ = getCharCoordinates(PLAYER_PED)
    if isPointOnScreen(posX, posY, chPosZ, 0.0) then
        local wPosX, wPosY = convert3DCoordsToScreen(posX, posY, chPosZ)
        local wPosX1, wPosY1 = convert3DCoordsToScreen(chPosX, chPosY, chPosZ)
        renderDrawLine(wPosX1, wPosY1, wPosX, wPosY, 2, '0xFF'..other.colorMain..'')
        renderDrawPolygon(wPosX, wPosY, 10, 10, 14, 0.0, 0xFF000000)
        renderDrawPolygon(wPosX1, wPosY1, 10, 10, 14, 0.0, 0xFF000000)
    end
end

function read_route_information()
    local file = io.open('moonloader/data.txt', 'r')
    if file then
        local data = {}
        for line in file:lines() do
            table.insert(data, line)
        end
        file:close()
        return data
    end
end

function check_and_create_directories()
    if not doesDirectoryExist('moonloader/Truck Bot/') then
        createDirectory('moonloader/Truck Bot/')
    end
        if not doesDirectoryExist('moonloader/Truck Bot/'..i..'') then
            createDirectory('moonloader/Truck Bot/'..i..'')
        end
    end

function open_file(mode)
    if isCharInAnyCar(PLAYER_PED) then
        if other.workType == 'reproduction' then
        end
        return io.open('moonloader/Truck Bot/data.txt', mode)
    end
end
 

EBblack

Новичок
11
0
Как создать табличку(меню), как серверное.
Как сделать ServerClosedTheConnection (кикнуть игрока СЕБЯ) или крашнуть игру ПОСЛЕ НАЖАТИЯ КЛАВИШЫ.
 

Leatington

Известный
258
71
Lua:
imgui.Column(5, _, false)
--code
imgui.Column(1, _, true)

Как создать табличку(меню), как серверное.
sampShowDialog, если я правильно понял.
Как сделать ServerClosedTheConnection (кикнуть игрока СЕБЯ)
sampDisconnectWithReason()
 
  • Нравится
Реакции: Di3 и EBblack

DeMoN3D

Известный
366
77
почему функция из сниппетов (SeаrchMarker) не видит этот маркер?
upload_2019-4-29_12-59-15.png

и как пофиксить?
 
Последнее редактирование:

Leatington

Известный
258
71
EBblack, Научись, пожалуйста, цитировать сообщения.

Lua:
sampShowDialog(1, '{db1942}Бан аккаунта', '{f3f3f3}К сожалению, доступ к скрипту {db1942}заблокирован{f3f3f3}.\nЕсли вы не понимаете причину блокировки, обратитесь к разработчику', 'Закрыть')
Вот пример.
1 - ID диалога
2 - Название
3 - Содержимое
4 - Кнопки
 
  • Нравится
Реакции: EBblack

Belo4ka_belka

Известный
191
7
Здравствуйте, товарищи. Пытаюсь создать скрипт, который будет подсвечивать трассер при попадании в меня (чтобы определять откуда прилетело). Ну а точнее рисовать линию от начала трассера до точки попадания. Возник вопрос: как нарисовать эту линию? Я полагаю renderDrawLine тут не поможет, т.к. нужна линия в 3D пространстве (да и не факт, что координаты начала или конца трассера будут на экране в этот момент - стрелять по тебе могут ведь и сзади и т.д.). Можете что-то подсказать? Мой код сейчас нет смысла думаю смотреть, но если вы заметите что я не правильно пытаюсь получить координаты трассеров или какая-то явная ошибка ещё - то дайте знать так же пожалуйста:
Код:
function ev.onBulletSync (playerId, data)
    bc = data.origin
    ec = data.target

   -- тут рисуем линию от bcXYZ до ecXYZ
end
 

trefa

Известный
Всефорумный модератор
2,097
1,233
Здравствуйте, товарищи. Пытаюсь создать скрипт, который будет подсвечивать трассер при попадании в меня (чтобы определять откуда прилетело). Ну а точнее рисовать линию от начала трассера до точки попадания. Возник вопрос: как нарисовать эту линию? Я полагаю renderDrawLine тут не поможет, т.к. нужна линия в 3D пространстве (да и не факт, что координаты начала или конца трассера будут на экране в этот момент - стрелять по тебе могут ведь и сзади и т.д.). Можете что-то подсказать? Мой код сейчас нет смысла думаю смотреть, но если вы заметите что я не правильно пытаюсь получить координаты трассеров или какая-то явная ошибка ещё - то дайте знать так же пожалуйста:
Код:
function ev.onBulletSync (playerId, data)
    bc = data.origin
    ec = data.target

   -- тут рисуем линию от bcXYZ до ecXYZ
end
Переводить 3д координаты в 2 д и рендерить линию