Artículos ESX: la tabla items, RegisterUsableItem y addInventoryItem

Añade un artículo a ESX: la tabla SQL de items, ESX.RegisterUsableItem para hacerlo usable, addInventoryItem, removeInventoryItem, getInventoryItem y canCarryItem, más la nota de ox_inventory.

Quieres un artículo nuevo en tu servidor ESX: una hamburguesa, un teléfono, una ganzúa. En ESX un artículo es una fila en la base de datos, y un script lo da, lo quita y lo usa a través del objeto del jugador. Este artículo cubre la tabla items, haciendo un artículo usable, las funciones xPlayer que usas todos los días, y qué cambia cuando el servidor ejecuta ox_inventory.

La tabla items

ESX lee sus artículos de la tabla items. Sus columnas son:

Columna Significado
name El nombre del artículo usado en código. Minúsculas, sin espacios
label El nombre que ven los jugadores
weight Peso de un artículo
rare Mantenido para usos más antiguos, normalmente 0
can_remove 1 si los jugadores pueden soltar o quitar el artículo

Añade un artículo con SQL:

sql
INSERT INTO `items` (`name`, `label`, `weight`, `rare`, `can_remove`)
VALUES ('burger', 'Burger', 1, 0, 1);

Reinicia ESX, o el servidor completo, para que recargue la tabla. Si tu base de datos muestra un conjunto diferente de columnas, sigue las columnas que tiene, ya que las versiones difieren un poco. Si no estás seguro de cómo ejecutar una consulta, ve oxmysql queries.

Cuidado: el nombre del artículo es la clave. burger y Burger son diferentes, y un artículo añadido con la ortografía incorrecta falla silenciosamente en la mayoría de los scripts.

Hacer que un artículo sea usable

Registra el artículo en el servidor, en un script:

lua
ESX = exports['es_extended']:getSharedObject()

ESX.RegisterUsableItem('burger', function(source)
    local xPlayer = ESX.GetPlayerFromId(source)
    if not xPlayer then return end

    xPlayer.removeInventoryItem('burger', 1)
    TriggerClientEvent('my_script:eatBurger', source)
end)

La devolución de llamada se ejecuta en el servidor cuando el jugador usa el artículo. No lo quita a sí mismo, así que lo quitas tú. Haz la eliminación en el servidor, luego dile al cliente que toque la animación. Si el objeto es nil, ve ESX is nil: fixing getSharedObject.

En el cliente, el evento solo tiene que tocar el efecto:

lua
RegisterNetEvent('my_script:eatBurger', function()
    -- animation, progress bar, hunger update
end)

Dar, quitar y comprobar artículos

Estas son las funciones xPlayer que necesitas:

lua
local xPlayer = ESX.GetPlayerFromId(source)

-- give
xPlayer.addInventoryItem('burger', 2)

-- remove
xPlayer.removeInventoryItem('burger', 1)

-- read one item
local item = xPlayer.getInventoryItem('burger')
print(item.count)

getInventoryItem devuelve una tabla con al menos count, label y name. Si el artículo no existe en la tabla, el resultado puede ser nil en algunas versiones, así que comprueba antes de leer count.

Un patrón confiable es comprobar antes de quitar:

lua
local item = xPlayer.getInventoryItem('lockpick')
if item and item.count >= 1 then
    xPlayer.removeInventoryItem('lockpick', 1)
    -- do the action
else
    xPlayer.showNotification('You need a lockpick')
end

Comprueba el peso primero: canCarryItem

Antes de dar un artículo, pregunta si el jugador puede llevarlo. Si no, addInventoryItem puede fallar en un inventario lleno y el jugador pierde la recompensa:

lua
if xPlayer.canCarryItem('burger', 2) then
    xPlayer.addInventoryItem('burger', 2)
else
    xPlayer.showNotification('You cannot carry that much')
end

canCarryItem(name, count) compara el peso del artículo con el peso libre del jugador. Úsalo en todas partes donde un script recompensa un artículo: trabajos, elaboración, botín. Para otros ayudantes, ve ESX job setup.

Un ejemplo: una tienda que vende un artículo

Junta los pedazos en el servidor, con una comprobación de dinero y peso:

lua
RegisterNetEvent('my_script:buyBurger', function()
    local src = source
    local xPlayer = ESX.GetPlayerFromId(src)
    if not xPlayer then return end

    local price = 10
    if xPlayer.getAccount('money').money < price then
        return xPlayer.showNotification('Not enough money')
    end
    if not xPlayer.canCarryItem('burger', 1) then
        return xPlayer.showNotification('Your inventory is full')
    end

    xPlayer.removeAccountMoney('money', price)
    xPlayer.addInventoryItem('burger', 1)
end)

El precio y el artículo son fijos en el servidor. El cliente solo dice «Quiero una hamburguesa», nunca envía el precio. Ve securing server events para ver por qué.

ESX con ox_inventory

Muchos servidores ESX ejecutan ox_inventory en lugar del inventario predeterminado. Entonces:

  • los artículos se definen en ox_inventory/data/items.lua, no en la tabla SQL
  • la familia xPlayer.addInventoryItem sigue funcionando, ya que ESX se la entrega a ox_inventory
  • ESX.RegisterUsableItem sigue funcionando, por lo que los scripts más antiguos no necesitan cambiar
  • el artículo debe existir en items.lua, o la llamada falla

Para cambiar, sigue la configuración de ox_inventory para ESX, y establece la opción de inventario personalizado en la configuración es_extended para que ESX sepa qué inventario está en uso. Para añadir un artículo de la manera ox_inventory, ve how to add items to ox_inventory.

Consejo: si no quieres editar SQL o Lua para cada artículo nuevo, Item Creator te deja crear artículos en el juego.

Lista de verificación

Síntoma Solución
El artículo no existe Añade una fila a la tabla items, o a items.lua con ox_inventory
El artículo no hace nada cuando se usa Regístralo con ESX.RegisterUsableItem en el servidor
addInventoryItem no da nada Nombre incorrecto, o el jugador no puede llevarlo; comprueba xPlayer.canCarryItem
El artículo no se quita después del uso La devolución de llamada debe llamar a removeInventoryItem a sí misma
getInventoryItem es nil El nombre del artículo no está en la tabla items
Falta de coincidencia de nombre Los nombres son sensibles a mayúsculas; usa el valor exacto name

Respuestas rápidas

¿Dónde añado un artículo nuevo en ESX?

En la tabla items de tu base de datos, con un nombre, una etiqueta y un peso. En un servidor que ejecuta ox_inventory, los artículos se definen en ox_inventory/data/items.lua en su lugar.

¿Cómo hago que un artículo ESX sea usable?

Regístralo en el servidor con ESX.RegisterUsableItem('itemname', function(source) ... end). El nombre del artículo debe coincidir con el name en la tabla de items.

¿Por qué addInventoryItem no hace nada?

El nombre del artículo no está en la tabla items, el jugador no puede llevarlo, o usaste un nombre con capitalización diferente. Comprueba que el artículo existe y prueba con xPlayer.canCarryItem primero.

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 →

Sigue leyendo