Itens ESX: a tabela items, RegisterUsableItem e addInventoryItem

Adicione um item ao ESX: a tabela SQL items, ESX.RegisterUsableItem para torná-lo utilizável, addInventoryItem, removeInventoryItem, getInventoryItem e canCarryItem, mais a nota sobre ox_inventory.

Você quer um novo item no seu servidor ESX: um hambúrguer, um telefone, uma chave de impacto. No ESX, um item é uma linha no banco de dados, e um script o dá, remove e usa através do objeto do jogador. Este artigo cobre a tabela items, tornando um item utilizável, as funções xPlayer que você usa todos os dias e o que muda quando o servidor executa ox_inventory.

A tabela items

ESX lê seus itens da tabela items. Suas colunas são:

Coluna Significado
name O nome do item usado em código. Minúsculas, sem espaços
label O nome que os jogadores veem
weight Peso de um item
rare Mantido para usos mais antigos, normalmente 0
can_remove 1 se os jogadores podem descartar ou remover o item

Adicione um item com SQL:

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

Reinicie ESX ou o servidor inteiro, para que recarregue a tabela. Se seu banco de dados mostrar um conjunto diferente de colunas, siga as colunas que ele tem, pois as versões diferem um pouco. Se você não tiver certeza de como executar uma consulta, veja guia de consultas oxmysql.

Atenção: o nome do item é a chave. burger e Burger são diferentes, e um item adicionado com a ortografia errada falha silenciosamente na maioria dos scripts.

Torne um item utilizável

Registre o item no servidor, em um 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)

O callback é executado no servidor quando o jogador usa o item. Ele não remove o item por si só, então você o remove. Faça a remoção no servidor, depois diga ao cliente para reproduzir a animação. Se o objeto for nil, veja ESX é nil: corrigindo getSharedObject.

No cliente, o evento apenas precisa reproduzir o efeito:

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

Dê, remova e verifique itens

Estas são as funções xPlayer que você precisa:

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 retorna uma tabela com pelo menos count, label e name. Se o item não existir na tabela, o resultado pode ser nil em algumas versões, então verifique antes de ler count.

Um padrão confiável é verificar antes de remover:

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

Verifique o peso primeiro: canCarryItem

Antes de dar um item, pergunte se o jogador pode carregá-lo. Se você não fizer, addInventoryItem pode falhar em um inventário cheio e o jogador perde a 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 o peso do item com o peso livre do jogador. Use-o em todos os lugares onde um script recompensa um item: empregos, artesanato, saque. Para outros auxiliares, veja configuração de emprego ESX.

Um exemplo: uma loja que vende um item

Junte os pedaços no servidor, com uma verificação de dinheiro e 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)

O preço e o item são fixos no servidor. O cliente apenas diz "Quero um hambúrguer", nunca envia o preço. Veja eventos de servidor seguro para entender o porquê.

ESX com ox_inventory

Muitos servidores ESX executam ox_inventory em vez do inventário padrão. Então:

  • os itens são definidos em ox_inventory/data/items.lua, não na tabela SQL
  • a família xPlayer.addInventoryItem ainda funciona, pois ESX a passa para ox_inventory
  • ESX.RegisterUsableItem ainda funciona, então scripts mais antigos não precisam de alterações
  • o item deve existir em items.lua, ou a chamada falha

Para mudar, siga a configuração do ox_inventory para ESX e defina a opção de inventário personalizado na configuração es_extended para que ESX saiba qual inventário está em uso. Para adicionar um item do jeito ox_inventory, veja como adicionar itens ao ox_inventory.

Dica: se você não quiser editar SQL ou Lua para cada novo item, Item Creator permite que você crie itens no jogo.

Lista de verificação

Sintoma Correção
Item não existe Adicione uma linha à tabela items ou a items.lua com ox_inventory
Item não faz nada quando usado Registre-o com ESX.RegisterUsableItem no servidor
addInventoryItem não dá nada Nome errado ou o jogador não pode carregá-lo; verifique xPlayer.canCarryItem
Item não removido após o uso O callback deve chamar removeInventoryItem ele mesmo
getInventoryItem é nil O nome do item não está na tabela items
Falta de correspondência de nome Os nomes diferenciam maiúsculas de minúsculas; use o valor name exato

Respostas rápidas

Onde adiciono um novo item no ESX?

Na tabela items do seu banco de dados, com um nome, um rótulo e um peso. Em um servidor executando ox_inventory, os itens são definidos em ox_inventory/data/items.lua em vez disso.

Como faço um item ESX utilizável?

Registre-o no servidor com ESX.RegisterUsableItem('itemname', function(source) ... end). O nome do item deve corresponder ao name na tabela items.

Por que addInventoryItem não faz nada?

O nome do item não está na tabela items, o jogador não pode carregá-lo, ou você usou um nome com capitalização diferente. Verifique se o item existe e teste com xPlayer.canCarryItem primeiro.

Scripts sem esse problema

Item Creator V2Crie itens usáveis com animações, props, efeitos e muito mais — sem escrever código.Ver script →Shop CreatorMonte uma loja em menos de um minuto — donos, funcionários, cofres e assaltos inclusos.Ver script →

Continue lendo