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

Frapsy

Известный
Проверенный
393
228
Можно ли как-то писать в чат сампа переменные. Плохо знаю Lua(Искал в инете не нашёл). Что-бы в чате писалось "Вы находитесь на координате X: 10", как это реализовать в коде?
sampAddChatMessage("Вы находитесь на координате X: "..coordX..".", -1)
Или же
sampAddChatMessage(string.format("Вы находитесь на координате %s.", coordX), -1)
coordX - твоя координата X.
 
  • Нравится
Реакции: lorgon

lorgon

Известный
656
273
Можно ли округлять числа с запятой до целых? К примеру a = 0,751 a ≈ 1
 

lorgon

Известный
656
273
В чём проблема кода? Телепорт телепортирует не туда. А так-же вопрос где найти генератор цветов для moonloader`а (пример: 0xFF8000)
Lua:
function main()
    while not isSampAvailable() do
        wait(100)
    end
    sampRegisterChatCommand('teleportcoord',tpc)
    while true do
        wait(0)
    end
end
function tpc(x, y, z)
    setCharCoordinates(PLAYER_PED,x,y,z)
    sampAddChatMessage("Teleport to coordinates: You've teleported successfully!", 0xFF8000)
end
 
Последнее редактирование:

AnWu

Известный
Всефорумный модератор
4,780
5,412
В чём проблема кода? Телепорт телепортирует не туда. А так-же вопрос где найти генератор цветов для moonloader`а (пример: 0xFF8000)
Lua:
function main()
    while not isSampAvailable() do
        wait(100)
    end
    sampRegisterChatCommand('teleportcoord',tpc)
    while true do
        wait(0)
    end
end
function tpc(x, y, z)
    setCharCoordinates(PLAYER_PED,x,y,z)
    sampAddChatMessage("Teleport to coordinates: You've teleported successfully!", 0xFF8000)
end
Потому-что неверное разделение параметров
Lua:
function main()
    while not isSampAvailable() do
        wait(100)
    end
    sampRegisterChatCommand('teleportcoord',tpc)
    while true do
        wait(0)
    end
end
function tpc(param)
    local x, y, z = string.match(param, "(%d+) (%d+) (%d+)")
    if x and y and z then
        setCharCoordinates(PLAYER_PED,x,y,z)
        sampAddChatMessage("Teleport to coordinates: You've teleported successfully!", 0xFF8000)
    end
end

По поводу цветов это обычный формат RRGGBBAA. Любой генератор цветов способен выдать АРГБ формат.
 
  • Нравится
Реакции: lorgon

AnWu

Известный
Всефорумный модератор
4,780
5,412

lorgon

Известный
656
273
Потому-что неверное разделение параметров
Lua:
function main()
    while not isSampAvailable() do
        wait(100)
    end
    sampRegisterChatCommand('teleportcoord',tpc)
    while true do
        wait(0)
    end
end
function tpc(param)
    local x, y, z = string.match(param, "(%d+) (%d+) (%d+)")
    if x and y and z then
        setCharCoordinates(PLAYER_PED,x,y,z)
        sampAddChatMessage("Teleport to coordinates: You've teleported successfully!", 0xFF8000)
    end
end

По поводу цветов это обычный формат RRGGBBAA. Любой генератор цветов способен выдать АРГБ формат.
Данный код тоже телепортирует в дэфолтное место(центр карты)
 

Ken Block

Известный
432
31
Lua:
if text:find("Используйте %{6699FF}/eat %{CECECE}чтобы поесть или %{6699FF}/put %{CECECE}чтобы положить поднос с едой") and eat == true then
  lua_thread.create(function()
    sampSendChat("/eat")
        wait(500)
    sampSendChat("/anim")
    if text:find("Список анимаций загружен. Введите команду ещё раз") then
      sampSendChat("/anim")
    end
    while not sampIsDialogActive() do wait(0) end
    if sampGetCurrentDialogId() == 11 then sampSendDialogResponse(11, 1, 78, 1)
    return false
     end
    while not sampIsDialogActive() do wait(0) end
    if sampGetCurrentDialogId() == 0 then sampCloseCurrentDialogWithButton(1)
            return false
    end
  end)
end
После того как скрипт прописывает /anim диалог всё равно открывается. Как отправлять инфу серверу без открытия этих диалогов?
 

checkdasound

Известный
Проверенный
963
410
Lua:
if text:find("Используйте %{6699FF}/eat %{CECECE}чтобы поесть или %{6699FF}/put %{CECECE}чтобы положить поднос с едой") and eat == true then
  lua_thread.create(function()
    sampSendChat("/eat")
        wait(500)
    sampSendChat("/anim")
    if text:find("Список анимаций загружен. Введите команду ещё раз") then
      sampSendChat("/anim")
    end
    while not sampIsDialogActive() do wait(0) end
    if sampGetCurrentDialogId() == 11 then sampSendDialogResponse(11, 1, 78, 1)
    return false
     end
    while not sampIsDialogActive() do wait(0) end
    if sampGetCurrentDialogId() == 0 then sampCloseCurrentDialogWithButton(1)
            return false
    end
  end)
end
После того как скрипт прописывает /anim диалог всё равно открывается. Как отправлять инфу серверу без открытия этих диалогов?

SAMP.Lua
Lua:
local samp = require 'lib.samp.events'
function samp.onShowDialog(dialogId)
    if dialogId == 11 then
        sampSendDialogResponse(11 , 1, 78, 1) return false
    end
end

:69: sol: no matching function call takes this number of arguments and the specified types
stack traceback:
[C]: in function 'ImBuffer'
:69: in main chunk
Все значения в ини, кроме тех, которые заменяют ImBuffer, работают.
Lua:
-- code maini load inicfg
REPAIR = '82'
repairKey = imgui.ImBuffer(mainIni.KeyBinds.REPAIR, 256)
69: repairKey = imgui.ImBuffer(mainIni.KeyBinds.REPAIR, 256)
 
Последнее редактирование модератором:

#Northn

Pears Project — уже запущен!
Всефорумный модератор
2,652
2,550
opcode '00A0' call caused an unhandled exception stack traceback: [C]: in function 'getCharCoordinates'

Lua:
lua_thread.create(function()
        local names = {}
        sampSendChat('/find')
        while not sampIsDialogActive() do wait(0) end
        for w in sampGetDialogText():gmatch('(%a+_?%a+%[%d+%])') do
            local id = w:match('%a+_?%a+%[(%d+)%]')

            if id then
                local _, handle = sampGetCharHandleBySampPlayerId(id)
                local x, y, z = getCharCoordinates(handle)
                local mx, my, mz = getCharCoordinates(PLAYER_PED)
                local dist = getDistanceBetweenCoords3d(mx, my, mz, x, y, z)

                if doesCharExist(handle) then
                    if dist <= 30 then
                        names[#names+1] = sampGetPlayerNickname(id):gsub('_', ' ')
                    end
                end
            end
        end
        sampAddChatMessage('Нашли:', -1)
        for i = 1, #names do
            sampAddChatMessage(names[i], -1)
        end
    end)

Жалуется на local x, y, z = getCharCoordinates(handle).
Ты проверяешь на наличие такого хендла после того, как пытаешься получить координаты.
Lua:
lua_thread.create(function()
    local names = {}
    sampSendChat('/find')
    while not sampIsDialogActive() do wait(0) end
    for w in sampGetDialogText():gmatch('(%a+_?%a+%[%d+%])') do
        local id = w:match('%a+_?%a+%[(%d+)%]')
        local res, dist = sampGetDistanceLocalPlayerToPlayerByPlayerId(id)
        if res and dist <= 30 then
            names[#names+1] = sampGetPlayerNickname(id):gsub('_', ' ')
        end
    end
end)

function sampGetDistanceLocalPlayerToPlayerByPlayerId(playerId)
    local playerId = tonumber(playerId, 10)
    if not playerId then return end
    local res, han = sampGetCharHandleBySampPlayerId(playerId)
    if res then
        local x, y, z = getCharCoordinates(playerPed)
        local xx, yy, zz = getCharCoordinates(han)
        return true, getDistanceBetweenCoords3d(x, y, z, xx, yy, zz)
    end
    return false
end
 

AnWu

Известный
Всефорумный модератор
4,780
5,412
:69: sol: no matching function call takes this number of arguments and the specified types
stack traceback:
[C]: in function 'ImBuffer'
:69: in main chunk
Все значения в ини, кроме тех, которые заменяют ImBuffer, работают.
Lua:
-- code maini load inicfg
REPAIR = '82'
repairKey = imgui.ImBuffer(mainIni.KeyBinds.REPAIR, 256)
69: repairKey = imgui.ImBuffer(mainIni.KeyBinds.REPAIR, 256)
Не используй устаревшую библиотеку hotkey.
 

checkdasound

Известный
Проверенный
963
410
Смотри мои темы или раздел Луа. Там новейшая, не баганая. А еще есть тема Перфект Биндера. Там подробный пример работы.
А без всех этих либ нельзя?
Вот так тоже не получилось, та же ошибка.
Lua:
vkeys = require 'vkeys'
-- ini cfg
REPAIR = vkeys.VK_R
repairKey = imgui.ImBuffer(ini.Keybinds.REPAIR, 256)