Oggetti ESX: la tabella items, RegisterUsableItem e addInventoryItem

Aggiungi un oggetto a ESX: la tabella SQL items, ESX.RegisterUsableItem per renderlo utilizzabile, addInventoryItem, removeInventoryItem, getInventoryItem e canCarryItem, più la nota ox_inventory.

Vuoi un nuovo oggetto sul tuo server ESX: un hamburger, un telefono, un grimaldello. In ESX un oggetto è una riga nel database, e uno script lo fornisce, lo rimuove e lo utilizza attraverso l'oggetto del giocatore. Questo articolo copre la tabella items, rendere un oggetto utilizzabile, le funzioni xPlayer che usi ogni giorno e cosa cambia quando il server esegue ox_inventory.

La tabella items

ESX legge i suoi oggetti dalla tabella items. Le sue colonne sono:

Colonna Significato
name Il nome dell'oggetto usato nel codice. Minuscolo, nessuno spazio
label Il nome che i giocatori vedono
weight Peso di un oggetto
rare Conservato per usi più vecchi, normalmente 0
can_remove 1 se i giocatori possono eliminare o rimuovere l'oggetto

Aggiungi un oggetto con SQL:

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

Riavvia ESX, o l'intero server, in modo che ricarichi la tabella. Se il tuo database mostra un set diverso di colonne, segui le colonne che ha, poiché le versioni differiscono un po'. Se non sei sicuro come eseguire una query, vedi Guide alle query oxmysql.

Attenzione: il nome dell'oggetto è la chiave. burger e Burger sono diversi, e un oggetto aggiunto con l'ortografia sbagliata fallisce silenziosamente nella maggior parte degli script.

Rendi un oggetto utilizzabile

Registra l'oggetto sul server, in uno 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)

Il callback viene eseguito sul server quando il giocatore utilizza l'oggetto. Non rimuove l'oggetto da solo, quindi lo rimuovi tu stesso. Fai la rimozione sul server, poi dici al client di riprodurre l'animazione. Se l'oggetto è nil, vedi ESX è nil: correzione di getSharedObject.

Sul client, l'evento deve solo riprodurre l'effetto:

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

Dai, rimuovi e controlla gli oggetti

Queste sono le funzioni xPlayer di cui hai bisogno:

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 restituisce una tabella con almeno count, label e name. Se l'oggetto non esiste nella tabella, il risultato può essere nil in alcune versioni, quindi controlla prima di leggere count.

Un modello affidabile è controllare prima di rimuovere:

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

Controlla il peso prima: canCarryItem

Prima di dare un oggetto, chiedi se il giocatore può portarlo. Se non lo fai, addInventoryItem può fallire in un inventario pieno e il giocatore perde la ricompensa:

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

canCarryItem(name, count) confronta il peso dell'oggetto con il peso libero del giocatore. Usalo ovunque uno script premi un oggetto: lavori, crafting, bottino. Per altri aiutanti, vedi Configurazione del lavoro ESX.

Un esempio: un negozio che vende un oggetto

Metti insieme i pezzi sul server, con un controllo per soldi 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)

Il prezzo e l'oggetto sono fissi sul server. Il client dice solo "Voglio un hamburger", non invia mai il prezzo. Vedi protezione degli eventi del server per sapere perché.

ESX con ox_inventory

Molti server ESX eseguono ox_inventory invece dell'inventario predefinito. Allora:

  • gli oggetti sono definiti in ox_inventory/data/items.lua, non nella tabella SQL
  • la famiglia xPlayer.addInventoryItem funziona ancora, poiché ESX la consegna a ox_inventory
  • ESX.RegisterUsableItem funziona ancora, quindi gli script più vecchi non hanno bisogno di cambiamenti
  • l'oggetto deve esistere in items.lua, o la chiamata fallisce

Per passare, segui la configurazione di ox_inventory per ESX e imposta l'opzione di inventario personalizzato nella config es_extended in modo che ESX sappia quale inventario è in uso. Per aggiungere un oggetto nel modo di ox_inventory, vedi come aggiungere oggetti a ox_inventory.

Suggerimento: se non vuoi modificare SQL o Lua per ogni nuovo oggetto, Item Creator ti consente di creare oggetti nel gioco.

Lista di controllo

Sintomo Soluzione
L'oggetto non esiste Aggiungi una riga alla tabella items, o a items.lua con ox_inventory
L'oggetto non fa nulla quando viene usato Registralo con ESX.RegisterUsableItem sul server
addInventoryItem non dà nulla Nome sbagliato, o il giocatore non può portarlo; controlla xPlayer.canCarryItem
L'oggetto non viene rimosso dopo l'uso Il callback deve chiamare removeInventoryItem da solo
getInventoryItem è nil Il nome dell'oggetto non è nella tabella items
Mancata corrispondenza del nome I nomi distinguono tra maiuscole e minuscole; usa il valore name esatto

Risposte rapide

Dove aggiungo un nuovo oggetto in ESX?

Nella tabella items del tuo database, con un nome, un'etichetta e un peso. Su un server che esegue ox_inventory, gli oggetti sono invece definiti in ox_inventory/data/items.lua.

Come rendo un oggetto ESX utilizzabile?

Registralo sul server con ESX.RegisterUsableItem('itemname', function(source) ... end). Il nome dell'oggetto deve corrispondere al name nella tabella items.

Perché addInventoryItem non fa nulla?

Il nome dell'oggetto non è nella tabella items, il giocatore non può portarlo, o hai usato un nome con una capitalizzazione diversa. Controlla che l'oggetto esista e prova con xPlayer.canCarryItem prima.

Script senza questo problema

Item Creator V2Crea oggetti utilizzabili con animazioni, props, effetti e altro — senza scrivere codice.Vedi script →Shop CreatorCrea un negozio in meno di un minuto — proprietari, dipendenti, casseforti e rapine inclusi.Vedi script →

Continua a leggere