Система крафтинга FiveM: верстаки ox_inventory и пользовательский крафтинг

Создавайте крафтинг на FiveM: верстаки крафтинга ox_inventory в data/crafting.lua с ингредиентами и зонами, пользовательский рецепт, проверяемый сервером, и советы против дублирования.

Крафтинг означает, что игрок превращает некоторые предметы в другой предмет. Вы можете использовать верстаки крафтинга, встроенные в ox_inventory, или написать свой собственный рецепт в скрипте. Эта статья показывает обе, а затем проверки, которые держат игроков от дублирования предметов.

Верстаки крафтинга ox_inventory

Откройте ox_inventory/data/crafting.lua. Он возвращает список верстаков. Каждый верстак имеет список предметов для крафтинга и место в мире:

lua
return {
    {
        items = {
            {
                name = 'lockpick',
                ingredients = {
                    scrap_metal = 5,
                    plastic = 2,
                },
                duration = 5000,
                count = 1,
            },
            {
                name = 'bandage',
                ingredients = {
                    cloth = 2,
                },
                duration = 3000,
            },
        },
        points = {
            vec3(1087.3, -3099.4, -39.0),
        },
    },
}

Что делает каждое поле:

Поле Значение
name Предмет, который производится
ingredients Имена предметов и количество каждого необходимого
duration Время крафтинга в миллисекундах
count Сколько результата вы получаете за крафт
points Координаты, где верстак может быть использован
zones Коробовидные зоны для ox_target как альтернатива points

Все названное в name или ingredients должно существовать в data/items.lua. Смотрите adding items to ox_inventory. Перезагрузите ox_inventory после редактирования файла.

Совет: значение ингредиента ниже 1 не потребляет предмет, он использует эту часть его прочности. Значение 0.1 на инструменте с прочностью использует десять процентов этого.

Зоны вместо точек

Зона — это коробка, которую игрок может целевить:

lua
zones = {
    {
        coords = vec3(1087.3, -3099.4, -39.0),
        size = vec3(1.5, 1.0, 1.0),
        distance = 1.5,
        rotation = 45.0,
    },
},

Зонам нужен ox_target для работы. Посмотрите примеры в вашей копии data/crafting.lua для точных полей вашей версии, так как формат меняется между выпусками. Для ограничения верстака работой, ox_inventory также читает groups на верстаке, такая же идея как в ox_inventory stashes.

Пользовательский рецепт с проверками сервера

Если вы хотите свои собственные правила, такие как уровень мастерства, стоимость или полоса прогресса вашей собственной, напишите рецепт в вашем скрипте и позвольте ox_inventory только обрабатывать предметы. Важная часть в том, что сервер делает все:

lua
-- server.lua
local crafting = {}

local recipe = {
    result = 'lockpick',
    ingredients = { scrap_metal = 5, plastic = 2 },
}

lib.callback.register('my_script:craft', function(source)
    if crafting[source] then return false end
    crafting[source] = true

    local ok = false

    -- 1. check every ingredient
    local hasAll = true
    for item, count in pairs(recipe.ingredients) do
        if exports.ox_inventory:Search(source, 'count', item) < count then
            hasAll = false
            break
        end
    end

    -- 2. check the player can carry the result
    if hasAll and exports.ox_inventory:CanCarryItem(source, recipe.result, 1) then
        -- 3. remove, then add
        local removed = {}
        local allRemoved = true
        for item, count in pairs(recipe.ingredients) do
            if exports.ox_inventory:RemoveItem(source, item, count) then
                removed[item] = count
            else
                allRemoved = false
                break
            end
        end

        if allRemoved and exports.ox_inventory:AddItem(source, recipe.result, 1) then
            ok = true
        else
            -- give back what was removed
            for item, count in pairs(removed) do
                exports.ox_inventory:AddItem(source, item, count)
            end
        end
    end

    crafting[source] = nil
    return ok
end)

Клиент спрашивает, воспроизводит полоску прогресса и только читает ответ:

lua
-- client.lua
if lib.progressBar({ duration = 5000, label = 'Crafting' }) then
    local ok = lib.callback.await('my_script:craft', false)
    lib.notify({ description = ok and 'Crafted' or 'Missing items', type = ok and 'success' or 'error' })
end

Для функций обратного вызова и уведомлений смотрите server callbacks on ESX, QBCore and ox_lib.

Советы против дублирования

Крафтинг — это классическое место для дублирования предметов, потому что предметы удаляются и добавляются в два шага. Держите эти правила:

  • Только сервер. Сервер проверяет ингредиенты и дает результат. Клиент отправляет "Я хочу создать рецепт X", никогда количества или имена предметов, которые он составил.
  • Проверь, затем удали, затем добавь. Никогда не добавляйте результат перед тем как удаление удалось. Если добавление не сработает, дайте ингредиенты обратно.
  • Один крафт за раз. Флаг за игрока, как crafting[source] выше, останавливает заспамированное событие от запуска рецепта несколько раз параллельно.
  • Проверьте CanCarryItem первым. Полный инвентарь — обычная причина, почему AddItem не сработает, и игрок потеряет ингредиенты.
  • Проверьте расстояние. Если рецепт принадлежит верстаку, сравните координаты игрока с верстаком на сервере.
  • Очистите состояние на падение. Сбросьте флаг, когда игрок уходит, так что отключение в середине не заблокирует рецепт.
lua
AddEventHandler('playerDropped', function()
    crafting[source] = nil
end)

Для большего на защиту событий смотрите securing server events.

Контрольный список

Симптом Исправление
Верстак не появляется Отредактируйте data/crafting.lua, затем перезагрузите ox_inventory
Ошибки рецепта при запуске Предмет в name или ingredients отсутствует из data/items.lua
Зона ничего не делает ox_target должен работать, и поля зоны должны совпадать с вашей версией
Ингредиенты потеряны, нет результата Проверьте CanCarryItem первым и верните когда AddItem не сработает
Предметы продублированы Переместите весь рецепт на сервер, добавьте флаг по-одному за раз
Крафт работает издалека Проверьте расстояние игрока к верстаку на сервере

Короткие ответы

Как мне добавить верстак крафтинга в ox_inventory?

Добавьте запись в ox_inventory/data/crafting.lua с items (каждый с ingredients и duration) и либо points, либо zones для того, где стоит верстак. Перезагрузите ox_inventory.

Может ли рецепт использовать часть прочности предмета?

Да. Значение ингредиента ниже 1 использует эту часть прочности предмета, который его имеет, а не потребляет предмет.

Как мне остановить игроков от дублирования предметов во время крафтинга?

Делайте весь рецепт на сервере: проверьте ингредиенты, удалите их, затем добавьте результат, и отказывайте начать второй крафт, пока один работает для этого игрока.

Скрипты без этой проблемы

Item Creator V2Создавайте используемые предметы с анимациями, пропами, эффектами и не только — без кода.Смотреть скрипт →Shop CreatorМагазин меньше чем за минуту — владельцы, сотрудники, сейфы и ограбления в комплекте.Смотреть скрипт →Quest CreatorВизуальный редактор квестов и диалогов с NPC — узел за узлом прямо в игре.Смотреть скрипт →

Читайте также

ox_libESXQBoxКак добавлять элементы в ox_inventory: items.lua, изображения и используемые элементыДобавьте пользовательский элемент в ox_inventory: запись data/items.lua, изображение в web/images, предоставление его с AddItem и делание его используемым с экспортом клиента.1 октября 2026 г. · 3 мин чтенияЧитать →ox_libESXQBoxМетаданные элементов ox_inventory: AddItem, Search, SetMetadata и уникальные элементыИспользуйте метаданные в ox_inventory: добавляйте элементы с данными, ищите и читайте слоты, обновляйте с помощью SetMetadata, показывайте пользовательскую метку и описание, и создавайте уникальные элементы, такие как ID и ключи.1 октября 2026 г. · 3 мин чтенияЧитать →ox_libESXQBoxМагазины ox_inventory: data/shops.lua, RegisterShop и значкиКак создать магазин в ox_inventory: запись data/shops.lua, цены и валюта, местоположения и цели, магазины, ограниченные работой, RegisterShop из другого ресурса и значки.1 октября 2026 г. · 3 мин чтенияЧитать →