Вопросы по 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,476
525
Lua:
local inicfg = require 'inicfg'
-- производить загрузку кофигов можно и вне 'main'
local mainIni = inicfg.load({
  settings =
  {
    title = "text",
    text_color = "0xAABBCC"
  },
  location =
  {
    width = 100,
    height = 200,
    pos_x = 20,
    pos_y = 50
  }
}) -- загрузим основной конфиг. путь к файлу не указан, а значит будет загружен файл по пути ./moonloader/config/example.lua.ini
function main()
  -- таблица со значениями по умолчаниями не указана, поэтому если файл не удастся прочитать, будет возвращён nil
  local anotherIni = inicfg.load(nil, "example_another_config")
  -- если файл был успешно загружен
  if anotherIni ~= nil then
    -- выводим прочитанные значения
    sampAddChatMessage("Old value 1 = " .. anotherIni.main.value1)
    sampAddChatMessage("Old value 2 = " .. anotherIni.main.value2)
    -- просто сгенерируем 2 случайных значения
    local newV1, newV2 = math.random(100, 1000), math.random(100, 1000)
    -- теперь создадим таблицу с новыми значениями
    local newData = {
      main = {
        value1 = newV1,
        value2 = newV2,
        -- и добавим к ним сумму этих двух значений
        sum = newV1 + newV2
      }
    }
    -- можно сохранять
    if inicfg.save(newData, "example_another_config") then
      print("Success.")
    end
  end
  -- выведем основной конфиг
  sampAddChatMessage(mainIni.settings.title .. ", color = " .. mainIni.settings.text_color)
  sampAddChatMessage("Position: ", mainIni.location.pos_x, mainIni.location.pos_y, "Size: ", mainIni.location.width, mainIni.location.height)
  -- отредактируем и сохраним его
  mainIni.settings.title = "Hello"
  mainIni.location.pos_x = 100
  mainIni.location.pos_y = 75
  inicfg.save(mainIni)
end
Что такое "example_another_config" в 19 строке? Когда я пробовал запустить этот. Самого файла "example_another_config" не существует, но почему-то поиск не равен nil, почему так?
 

rraggerr

проверенный какой-то
1,626
847
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Lua:
local inicfg = require 'inicfg'
-- производить загрузку кофигов можно и вне 'main'
local mainIni = inicfg.load({
  settings =
  {
    title = "text",
    text_color = "0xAABBCC"
  },
  location =
  {
    width = 100,
    height = 200,
    pos_x = 20,
    pos_y = 50
  }
}) -- загрузим основной конфиг. путь к файлу не указан, а значит будет загружен файл по пути ./moonloader/config/example.lua.ini
function main()
  -- таблица со значениями по умолчаниями не указана, поэтому если файл не удастся прочитать, будет возвращён nil
  local anotherIni = inicfg.load(nil, "example_another_config")
  -- если файл был успешно загружен
  if anotherIni ~= nil then
    -- выводим прочитанные значения
    sampAddChatMessage("Old value 1 = " .. anotherIni.main.value1)
    sampAddChatMessage("Old value 2 = " .. anotherIni.main.value2)
    -- просто сгенерируем 2 случайных значения
    local newV1, newV2 = math.random(100, 1000), math.random(100, 1000)
    -- теперь создадим таблицу с новыми значениями
    local newData = {
      main = {
        value1 = newV1,
        value2 = newV2,
        -- и добавим к ним сумму этих двух значений
        sum = newV1 + newV2
      }
    }
    -- можно сохранять
    if inicfg.save(newData, "example_another_config") then
      print("Success.")
    end
  end
  -- выведем основной конфиг
  sampAddChatMessage(mainIni.settings.title .. ", color = " .. mainIni.settings.text_color)
  sampAddChatMessage("Position: ", mainIni.location.pos_x, mainIni.location.pos_y, "Size: ", mainIni.location.width, mainIni.location.height)
  -- отредактируем и сохраним его
  mainIni.settings.title = "Hello"
  mainIni.location.pos_x = 100
  mainIni.location.pos_y = 75
  inicfg.save(mainIni)
end
Что такое "example_another_config" в 19 строке? Когда я пробовал запустить этот. Самого файла "example_another_config" не существует, но почему-то поиск не равен nil, почему так?
название конфига, ты вообще читаешь что там фип пишет? Там выше об этом написано
 

T1cKz

Известный
595
246
Lua:
local inicfg = require 'inicfg'
-- производить загрузку кофигов можно и вне 'main'
local mainIni = inicfg.load({
  settings =
  {
    title = "text",
    text_color = "0xAABBCC"
  },
  location =
  {
    width = 100,
    height = 200,
    pos_x = 20,
    pos_y = 50
  }
}) -- загрузим основной конфиг. путь к файлу не указан, а значит будет загружен файл по пути ./moonloader/config/example.lua.ini
function main()
  -- таблица со значениями по умолчаниями не указана, поэтому если файл не удастся прочитать, будет возвращён nil
  local anotherIni = inicfg.load(nil, "example_another_config")
  -- если файл был успешно загружен
  if anotherIni ~= nil then
    -- выводим прочитанные значения
    sampAddChatMessage("Old value 1 = " .. anotherIni.main.value1)
    sampAddChatMessage("Old value 2 = " .. anotherIni.main.value2)
    -- просто сгенерируем 2 случайных значения
    local newV1, newV2 = math.random(100, 1000), math.random(100, 1000)
    -- теперь создадим таблицу с новыми значениями
    local newData = {
      main = {
        value1 = newV1,
        value2 = newV2,
        -- и добавим к ним сумму этих двух значений
        sum = newV1 + newV2
      }
    }
    -- можно сохранять
    if inicfg.save(newData, "example_another_config") then
      print("Success.")
    end
  end
  -- выведем основной конфиг
  sampAddChatMessage(mainIni.settings.title .. ", color = " .. mainIni.settings.text_color)
  sampAddChatMessage("Position: ", mainIni.location.pos_x, mainIni.location.pos_y, "Size: ", mainIni.location.width, mainIni.location.height)
  -- отредактируем и сохраним его
  mainIni.settings.title = "Hello"
  mainIni.location.pos_x = 100
  mainIni.location.pos_y = 75
  inicfg.save(mainIni)
end
Что такое "example_another_config" в 19 строке? Когда я пробовал запустить этот. Самого файла "example_another_config" не существует, но почему-то поиск не равен nil, почему так?
Он создаст конфиг с названием скрипта

В самое начало скрипта
Lua:
require 'lib.moonloader'
Не, ну я не настолько даун...
Я беру с ini файла клавишу, и записываю её в переменную, через показ её в чат - работает, а так не хочет
 

rraggerr

проверенный какой-то
1,626
847
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Lua:
local key = VK_F9

if wasKeyPressed(key) == true
Что не так?
wasKeyPressed автоматически возвращает true если ты нажал кнопку key , так же подключи библиотеку vkeys
if wasKeyPressed(key) then

end
 

#Northn

Police Helper «Reborn» — уже ШЕСТЬ лет!
Всефорумный модератор
2,641
2,491
wasKeyPressed автоматически возвращает true если ты нажал кнопку key , так же подключи библиотеку vkeys
if wasKeyPressed(key) then

end
Либа vkeys не обязательна, и без неё может работать.
 

AnWu

https://t.me/anwublog
Всефорумный модератор
4,708
5,252
Lua:
local inicfg = require 'inicfg'
-- производить загрузку кофигов можно и вне 'main'
local mainIni = inicfg.load({
  settings =
  {
    title = "text",
    text_color = "0xAABBCC"
  },
  location =
  {
    width = 100,
    height = 200,
    pos_x = 20,
    pos_y = 50
  }
}) -- загрузим основной конфиг. путь к файлу не указан, а значит будет загружен файл по пути ./moonloader/config/example.lua.ini
function main()
  -- таблица со значениями по умолчаниями не указана, поэтому если файл не удастся прочитать, будет возвращён nil
  local anotherIni = inicfg.load(nil, "example_another_config")
  -- если файл был успешно загружен
  if anotherIni ~= nil then
    -- выводим прочитанные значения
    sampAddChatMessage("Old value 1 = " .. anotherIni.main.value1)
    sampAddChatMessage("Old value 2 = " .. anotherIni.main.value2)
    -- просто сгенерируем 2 случайных значения
    local newV1, newV2 = math.random(100, 1000), math.random(100, 1000)
    -- теперь создадим таблицу с новыми значениями
    local newData = {
      main = {
        value1 = newV1,
        value2 = newV2,
        -- и добавим к ним сумму этих двух значений
        sum = newV1 + newV2
      }
    }
    -- можно сохранять
    if inicfg.save(newData, "example_another_config") then
      print("Success.")
    end
  end
  -- выведем основной конфиг
  sampAddChatMessage(mainIni.settings.title .. ", color = " .. mainIni.settings.text_color)
  sampAddChatMessage("Position: ", mainIni.location.pos_x, mainIni.location.pos_y, "Size: ", mainIni.location.width, mainIni.location.height)
  -- отредактируем и сохраним его
  mainIni.settings.title = "Hello"
  mainIni.location.pos_x = 100
  mainIni.location.pos_y = 75
  inicfg.save(mainIni)
end
Что такое "example_another_config" в 19 строке? Когда я пробовал запустить этот. Самого файла "example_another_config" не существует, но почему-то поиск не равен nil, почему так?
Файл с этим именем и расширенем ini создатся в папке moonloader/config

Либа vkeys не обязательна, и без неё может работать.
Ты читал moonloader.lua?) Там либу vkeys режет и делает глобальной. Либа vkeys обязательна только для удобства, и её правильно использовать вместо ml.lua.
local vk = require 'vkeys'
vk.VK_F9
 

™ ChipFamily

По ту сторону надежды.
5,144
1,981
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Есть вот телепорт. после того как написал /tpc тебя телепортирует на чекпоинт.
Но проблема.. после телепорта на чекпоинт спавнит. как решить
Lua:
local sampev = require 'lib.samp.events'


function main()

    repeat wait(0) until isSampAvailable();
    sampRegisterChatCommand("tpc", tpp)
    sampRegisterChatCommand("tp", function()
    result, x, y, _ = getTargetBlipCoordinates()
    if result then lua_thread.create(teleport)
    else sampAddChatMessage("{ffc60a}[Grand RP] {ff7070}Поставь метку!", -1) end end)
    wait (-1)
end

function tpp()
    result, posX, posY, posZ = SearchMarker()
    if result then
        activate = true
        requestCollision(posX, posY)
        loadScene(posX, posY, posZ)
        setCharCoordinates(PLAYER_PED, posX, posY, posZ)
        sampRequestClass()
        wait(2000)
        activate = false
    else
        sampAddChatMessage("{ffc60a}[Grand RP] {ff7070}Чекпоинта ж нет нихуя ты че блят", -1)
    end
end

function teleport()
    activate = true
    requestCollision(x,y)
    loadScene(x,y,z)
    setCharCoordinates(PLAYER_PED, x,y,-999.0)
    sampRequestClass()
    wait (2000)
    activate = false
end


function sampev.onRequestClassResponse()
    if activate then
    return false else return true
end end

function sampev.onRequestSpawnResponse()
    if activate then
    return false else return true
end end

function sampev.onSetPlayerPos()
    if isCharInAnyCar(PLAYER_PED) and activate then
        return false else return true end
end

function SearchMarker(posX, posY, posZ, radius, isRace)
    local ret_posX = 0.0
    local ret_posY = 0.0
    local ret_posZ = 0.0
        local radius = 0.0
    local isFind = false
isRace = true

    for id = 0, 31 do
        local MarkerStruct = 0
        if isRace then MarkerStruct = 0xC7F168 + id * 56
        else MarkerStruct = 0xC7DD88 + id * 160 end
        local MarkerPosX = representIntAsFloat(readMemory(MarkerStruct + 0, 4, false))
        local MarkerPosY = representIntAsFloat(readMemory(MarkerStruct + 4, 4, false))
        local MarkerPosZ = representIntAsFloat(readMemory(MarkerStruct + 8, 4, false))

        if MarkerPosX ~= 0.0 or MarkerPosY ~= 0.0 or MarkerPosZ ~= 0.0 then
            if getDistanceBetweenCoords3d(MarkerPosX, MarkerPosY, MarkerPosZ) > radius then
                ret_posX = MarkerPosX
                ret_posY = MarkerPosY
                ret_posZ = MarkerPosZ
                isFind = true
                radius = getDistanceBetweenCoords3d(MarkerPosX, MarkerPosY, MarkerPosZ)
            end
        end
    end
    return isFind, ret_posX, ret_posY, ret_posZ
end
 

ШPEK

Известный
1,476
525
Сделайте пример кода: автотэг, тэг будет браться из ini файла.
 

#Northn

Police Helper «Reborn» — уже ШЕСТЬ лет!
Всефорумный модератор
2,641
2,491