Usable Items
There are three ways to make an item "do something" when a player uses it. Pick the tab for how your other resources are written.
Creating Usables
Recommended. Create an export or event on your own resource, then bind its name into the item's serverExport / clientExport / serverEvent / clientEvent field in the admin panel item editor.
resource.functionName string (for exports) or an event name (for events). In the admin panel item editor, fill the serverExport / clientExport / serverEvent / clientEvent field with that string, e.g. myresource.myItem.Server-side export - params come from the item-use flow. Returning false cancels the use (skips the client pipeline, consume, status and durability):
-- in myresource (DB field: serverExport = "myresource.myItem")
exports('myItem', function(src, itemName, slot, metadata)
-- do server-side stuff
-- return false to cancel the use
end)
Server-side event - same params. Fire-and-forget: the return value is ignored, so a server event cannot cancel the use.
-- DB field: serverEvent = "myresource:myItem"
RegisterNetEvent('myresource:myItem', function(src, itemName, slot, metadata)
-- do server-side stuff
end)
Client-side export - runs after the progress bar / animation completes. If the progress bar is cancelled, this never runs and the use is cancelled server-side too:
-- DB field: clientExport = "myresource.myItem"
exports('myItem', function(itemName, slot, metadata)
-- do client-side stuff
end)
Client-side event - same params, fired right after the client export:
-- DB field: clientEvent = "myresource:myItem"
AddEventHandler('myresource:myItem', function(itemName, slot, metadata)
-- do client-side stuff
end)
Register the item the standard ESX way. one_inventory consumes ESX's native usable-item registry, so existing RegisterUsableItem calls keep working unchanged.
ESX.RegisterUsableItem('myItem', function(src)
-- ESX passes only the player source
end)
Register the item the standard QBCore way. one_inventory consumes the native registry, so existing CreateUseableItem calls keep working unchanged.
QBCore.Functions.CreateUseableItem('myItem', function(src, item)
-- `item` is the full slot table (name, count, slot, metadata)
end)
How one_inventory decides which handler to run
When an item is used, one_inventory first checks whether the item has any one_inventory-side use config set in the admin panel. That means any of:
serverExport, clientExport, serverEvent, clientEvent, close, consume, notification, animationId, propId, the hunger/thirst status effects (statusHunger, statusThirst), or any of the disable* flags (disableMove, disableCar, disableCombat, disableMouse, disableSprint).
If an item is configured both ways (registered through ESX/QB and given a use field in our panel), our flow wins and one_inventory prints a one-time warning so you can spot it.
Controlling the full use flow
For full control, combine the primitives we already ship into a three-stage pattern:
- Gate the use before anything runs with the
beforeItemUsehook (returnfalseto cancel):exports.one_inventory:RegisterHook('beforeItemUse', function(payload) if not isAllowed(payload.source) then return false end end) - Side-effects during the use with the bound
serverExport/clientExport. - Post-use cleanup / logging with the
onItemUsedevent:AddEventHandler('one_inventory:onItemUsed', function(payload) -- payload: { source, item, slot, metadata } on the server end)
onItemUsed fires on the server (payload { source, item, slot, metadata }) and on the client (payload { item, slot, metadata }, no source). See Server events and Client events.Coming from ox_inventory?
ox-style (event, item, inventory, slot, data) use callbacks are not backwards compatible. Rewrite the handler against the signatures shown in the one_inventory tab above, it's about five lines.
For everything else (data reads like AddItem, RemoveItem, Search, useItem, ...), the ox exports keep working through our compatibility layer. See Backwards Compatibility.
