Sistema de elaboración de FiveM: bancos de ox_inventory y elaboración personalizada

Construye elaboración en FiveM: bancos de elaboración de ox_inventory en data/crafting.lua con ingredientes y zonas, una receta verificada personalizada por el servidor, y consejos anti-duplicación.

Elaboración significa que un jugador convierte algunos artículos en otro artículo. Puedes usar los bancos de elaboración integrados en ox_inventory, o escribir tu propia receta en un script. Este artículo muestra ambos, y luego las comprobaciones que evitan que los jugadores dupliquen artículos.

Bancos de elaboración de ox_inventory

Abre ox_inventory/data/crafting.lua. Devuelve una lista de bancos. Cada banco tiene una lista de artículos elaborables y un lugar en el mundo:

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),
        },
    },
}

Lo que hace cada campo:

Campo Significado
name El artículo que se produce
ingredients Nombres de artículos y el recuento de cada uno necesario
duration Tiempo de elaboración en milisegundos
count Cuántos del resultado obtienes por elaboración
points Coordenadas donde se puede usar el banco
zones Zonas de caja para ox_target, como alternativa a points

Todo lo nombrado en name o ingredients debe existir en data/items.lua. Ve adding items to ox_inventory. Reinicia ox_inventory después de editar el archivo.

Consejo: un valor de ingrediente por debajo de 1 no consume el artículo, usa esa fracción de su durabilidad. Un valor de 0.1 en una herramienta con durabilidad usa el diez por ciento de ella.

Zonas en lugar de puntos

Una zona es una caja que el jugador puede dirigir:

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

Las zonas necesitan que ox_target se esté ejecutando. Mira los ejemplos en tu copia de data/crafting.lua para los campos exactos de tu versión, ya que el formato cambia entre lanzamientos. Para restringir un banco a un trabajo, ox_inventory también lee groups en el banco, la misma idea que en ox_inventory stashes.

Una receta personalizada con comprobaciones del servidor

Si quieres tus propias reglas, como un nivel de habilidad, un costo o una barra de progreso propia, escribe la receta en tu script y deja que ox_inventory solo maneje los artículos. La parte importante es que el servidor hace todo:

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)

El cliente pide, reproduce la barra de progreso, y solo lee la respuesta:

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

Para las funciones de devolución de llamada y notificación, ve server callbacks on ESX, QBCore and ox_lib.

Consejos anti-duplicación

La elaboración es un lugar clásico para la duplicación de artículos, porque los artículos se eliminan y se añaden en dos pasos. Mantén estas reglas:

  • Solo servidor. El servidor comprueba ingredientes y da el resultado. El cliente envía «Quiero elaborar la receta X», nunca recuentos o nombres de artículos que se inventó.
  • Comprueba, luego elimina, luego añade. Nunca añadas el resultado antes de que la eliminación tenga éxito. Si la adición falla, devuelve los ingredientes.
  • Una elaboración a la vez. Una bandera por jugador, como crafting[source] anterior, detiene un evento spammed de ejecutar la receta varias veces en paralelo.
  • Comprueba CanCarryItem primero. Un inventario lleno es la razón habitual por la que AddItem falla, y el jugador perdería los ingredientes.
  • Comprueba la distancia. Si la receta pertenece a un banco, compara las coordenadas del jugador con el banco en el servidor.
  • Limpia el estado al caer. Restablece la bandera cuando un jugador se va, para que una desconexión en el medio no bloquee la receta.
lua
AddEventHandler('playerDropped', function()
    crafting[source] = nil
end)

Para más información sobre la protección de eventos, ve securing server events.

Lista de verificación

Síntoma Solución
El banco no aparece Edita data/crafting.lua, luego reinicia ox_inventory
Errores de receta al iniciar Un artículo en name o ingredients falta en data/items.lua
La zona no hace nada ox_target debe estar en funcionamiento, y los campos de zona deben coincidir con tu versión
Ingredientes perdidos, sin resultado Comprueba CanCarryItem primero y devuelve cuando AddItem falla
Artículos duplicados Mueve la receta completa al servidor, añade una bandera de uno a la vez
La elaboración funciona desde lejos Comprueba la distancia del jugador al banco en el servidor

Respuestas rápidas

¿Cómo añado un banco de elaboración a ox_inventory?

Añade una entrada a ox_inventory/data/crafting.lua con items (cada una con ingredients y duration) y points o zones donde se ubica el banco. Reinicia ox_inventory.

¿Puede una receta usar parte de la durabilidad de un artículo?

Sí. Un valor de ingrediente por debajo de 1 usa esa fracción de la durabilidad de un artículo que lo tiene, en lugar de consumir el artículo.

¿Cómo evito que los jugadores dupliquen artículos mientras elaboran?

Haz la receta completa en el servidor: comprueba los ingredientes, elimínalos, luego añade el resultado, y rechaza iniciar una segunda elaboración mientras una se está ejecutando para ese jugador.

Scripts que evitan este problema

Item Creator V2Crea items usables con animaciones, props, efectos y más — sin escribir código.Ver script →Shop CreatorCrea una tienda en menos de un minuto — dueños, empleados, caja fuerte y atracos.Ver script →Quest CreatorUn editor visual de misiones y diálogos con NPC, nodo a nodo dentro del juego.Ver script →

Sigue leyendo