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

James Hawk

Известный
919
217
Пример
Lua:
sampSendDialogResponse(2431, 1, 1, -1)
-- 2431 - id диалога, 1 - кнопка ОК, 1 - 2 пункт, -1 - отсутствие текста
 

LuaMaster

Известный
147
17
Пример
Lua:
sampSendDialogResponse(2431, 1, 1, -1)
-- 2431 - id диалога, 1 - кнопка ОК, 1 - 2 пункт, -1 - отсутствие текста
if string.find(caption,"Рыболовный магазин") then
lua_thread.create(function () wait(1000) sampSendDialogResponse(id, 1, 2, 0) end)
lua_thread.create(function () wait(1000) sampSendDialogResponse(id, 1, 1, 0) end)
end
делал вот так, неработает!
 

James Hawk

Известный
919
217
if string.find(caption,"Рыболовный магазин") then
lua_thread.create(function () wait(1000) sampSendDialogResponse(id, 1, 2, 0) end)
lua_thread.create(function () wait(1000) sampSendDialogResponse(id, 1, 1, 0) end)
end
делал вот так, неработает!
sampSendDialogResponse(id, 1, 2, 0)
Ты айди диалога не указал
 

LuaMaster

Известный
147
17
ид диалога кто указывать будет?
Сорян, не весь код кинул)
Вот код который работает на 1 пункт
if string.find(caption, "Рыболовный магазин") then
local id = sampGetCurrentDialogId()
lua_thread.create(function () wait(1000) sampSendDialogResponse(id, 1, 2, 0) end)
end

Сорян, не весь код кинул)
Вот код который работает на 1 пункт
if string.find(caption, "Рыболовный магазин") then
local id = sampGetCurrentDialogId()
lua_thread.create(function () wait(1000) sampSendDialogResponse(id, 1, 2, 0) end)
end
на под пункт я незнаю как делать
 

James Hawk

Известный
919
217
Сорян, не весь код кинул)
Вот код который работает на 1 пункт
if string.find(caption, "Рыболовный магазин") then
local id = sampGetCurrentDialogId()
lua_thread.create(function () wait(1000) sampSendDialogResponse(id, 1, 2, 0) end)
end


на под пункт я незнаю как делать
После выбора пункта в диалоге открывается следующий диалог. Повторяешь то же самое, но уже с другими значениями (ид диалога, пункт)
 

LuaMaster

Известный
147
17
if string.find(caption, "Рыболовный магазин") then
id = sampGetCurrentDialogId()
lua_thread.create(function () wait(1000) sampSendDialogResponse(id, 1, 2, 0) end)
if string.find(caption, "Покупка: Нажива") then
id = sampGetCurrentDialogId()
lua_thread.create(function () wait(1000) sampSendDialogResponse(id, 1, 1, 0) end)
end
end
Вроде написал но опять тот же результат, выбирает правильно только в 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
 

FBenz

Активный
328
40
Ребят, делал код с использованием большого кол-ва картинок.

Так вот оказывается есть лимит этих самых текстур. Можно ли как-то выгрузить из памяти эти текстуры, чтобы загрузить новые?

Код в начале скрипта для создания текстур:
Lua:
local vehImage = {}
for i = 400, 611 do
vehImage[i] = imgui.CreateTextureFromFile(wdirect .. '/путь.jpg')
end
 

James Hawk

Известный
919
217
if string.find(caption, "Рыболовный магазин") then
id = sampGetCurrentDialogId()
lua_thread.create(function () wait(1000) sampSendDialogResponse(id, 1, 2, 0) end)
if string.find(caption, "Покупка: Нажива") then
id = sampGetCurrentDialogId()
lua_thread.create(function () wait(1000) sampSendDialogResponse(id, 1, 1, 0) end)
end
end
Вроде написал но опять тот же результат, выбирает правильно только в 1 пункте...
Пробуй
Lua:
lua_thread.create(function()
    if string.find(caption, "Рыболовный магазин") then
        local id = sampGetCurrentDialogId()
        wait(1000)
        sampSendDialogResponse(id, 1, 2, 0)
        if string.find(caption, "Покупка: Нажива") then
            local id = sampGetCurrentDialogId()
            wait(1000)
            sampSendDialogResponse(id, 1, 1, 0)
        end
    end
end)
 

LuaMaster

Известный
147
17
Пробуй
Lua:
lua_thread.create(function()
    if string.find(caption, "Рыболовный магазин") then
        local id = sampGetCurrentDialogId()
        wait(1000)
        sampSendDialogResponse(id, 1, 2, 0)
        if string.find(caption, "Покупка: Нажива") then
            local id = sampGetCurrentDialogId()
            wait(1000)
            sampSendDialogResponse(id, 1, 1, 0)
        end
    end
end)
Такая же ситуация, на 1 листе кликает, на 2 нет, тоесть вообще ничего не кликает...
 

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)
Есть такая табличка. Проблема в том что с помощью ПКМ можно двигать вертикальные линии,каким образом это исправить?