Register Usable Item¶
Short reference for using cv.inventory.registerUsableItem to make items usable in the inventory system.
Concepts¶
cv.inventory.registerUsableItemregisters an item as "usable" with a callback function that executes when a player uses the item from their inventory.- The function is server-side only - callbacks execute on the server when items are used.
- Once registered, items automatically show as usable in the client inventory UI.
- The callback receives player context, item details, and metadata for processing the item use.
Notes:
- Always validate that the player and character context exist before processing item use.
- By default, the inventory UI closes after using an item. This can be controlled with options.
- Items must exist in the
item_definitionsdatabase table before being registered as usable. - The
isUsableflag is automatically set totruein the item definitions cache when registered.
Server-Side Registration¶
Basic Syntax¶
Parameters:
- itemName (string): The name of the item (must match item_definitions.name in database)
- callback (function): Function called when the item is used
- options (table|nil): Optional configuration table
Callback Parameters: The callback function receives the following parameters:
function(source, itemName, slot, quantity, metadata)
-- source: Player server ID (number)
-- itemName: Name of the item being used (string)
-- slot: Inventory slot number (number)
-- quantity: Amount of items in that slot (number)
-- metadata: Item metadata table (table)
end
Options Table:
Examples¶
Simple Food Item¶
cv.inventory.registerUsableItem("burger", function(source, itemName, slot, quantity, metadata)
local player = cv.player.getPlayer(source)
if not player or not player.charId then return end
-- Remove the item from inventory
cv.inventory.removeItem(player.charId, itemName, 1)
-- Add hunger
exports.cv_framework:AddHunger(source, 50)
-- Notify player
cv.notify(source, 'Hunger', 'You ate a burger', 'success')
-- Play eating animation
TriggerClientEvent('cv_framework:hunger:playAnimation', source, 'mp_player_inteat@burger', 'mp_player_int_eat_burger', 3000)
end)
Item with Validation¶
cv.inventory.registerUsableItem("water", function(source, itemName, slot, quantity, metadata)
local player = cv.player.getPlayer(source)
if not player or not player.charId then return end
-- Check if player actually has the item
local hasItem, count = cv.inventory.hasItem(player.charId, itemName, 1)
if not hasItem then
cv.notify(source, 'Error', 'You don\'t have this item', 'error')
return
end
-- Remove the item
cv.inventory.removeItem(player.charId, itemName, 1)
-- Add thirst
exports.cv_framework:AddThirst(source, 30)
-- Notify and animate
cv.notify(source, 'Thirst', 'You drank water', 'success')
TriggerClientEvent('cv_framework:thirst:playAnimation', source, 'mp_player_intdrink', 'loop_bottle', 3000)
end)
Item That Keeps Inventory Open¶
cv.inventory.registerUsableItem("phone", function(source, itemName, slot, quantity, metadata)
local player = cv.player.getPlayer(source)
if not player or not player.charId then return end
-- Open phone UI
TriggerClientEvent('phone:open', source)
-- Note: Inventory stays open because of options.closeInventory = false
end, {
closeInventory = false
})
Batch Registration¶
local consumables = {
{ name = "water", thirst = 30 },
{ name = "coffee", thirst = 15 },
{ name = "burger", hunger = 45 },
{ name = "pizza", hunger = 60 }
}
for _, item in ipairs(consumables) do
cv.inventory.registerUsableItem(item.name, function(source, itemName, slot, quantity, metadata)
local player = cv.player.getPlayer(source)
if not player or not player.charId then return end
-- Remove item
cv.inventory.removeItem(player.charId, itemName, 1)
-- Apply effects
if item.thirst then
exports.cv_framework:AddThirst(source, item.thirst)
cv.notify(source, 'System', 'You drank ' .. cv.inventory.getItemLabel(itemName), 'success')
elseif item.hunger then
exports.cv_framework:AddHunger(source, item.hunger)
cv.notify(source, 'System', 'You ate ' .. cv.inventory.getItemLabel(itemName), 'success')
end
end)
end
Item with Metadata Processing¶
cv.inventory.registerUsableItem("lockpick", function(source, itemName, slot, quantity, metadata)
local player = cv.player.getPlayer(source)
if not player or not player.charId then return end
-- Check durability from metadata
local durability = metadata.durability or 100
if durability <= 0 then
cv.notify(source, 'Error', 'This lockpick is broken', 'error')
cv.inventory.removeItem(player.charId, itemName, 1, slot)
return
end
-- Start lockpicking minigame
TriggerClientEvent('lockpick:startMinigame', source, {
itemSlot = slot,
durability = durability
})
end, {
closeInventory = true
})
Related Functions¶
Check if Item is Usable¶
Server:
Client:
Trigger Item Use from Client¶
Get Item Definition¶
local itemDef = cv.inventory.getItemDefinition(itemName)
-- Returns: { name, label, weight, type, description, isUsable, ... }
Common Patterns¶
Character Validation Pattern¶
Always validate player and character context:
cv.inventory.registerUsableItem("myitem", function(source, itemName, slot, quantity, metadata)
local player = cv.player.getPlayer(source)
if not player or not player.charId then
return -- Silently fail if no character loaded
end
-- Safe to proceed with character operations
end)
Item Removal Pattern¶
Remove items after use:
-- Remove 1 item
cv.inventory.removeItem(player.charId, itemName, 1)
-- Remove from specific slot
cv.inventory.removeItem(player.charId, itemName, 1, slot)
-- Remove all of the item
local hasItem, count = cv.inventory.hasItem(player.charId, itemName)
cv.inventory.removeItem(player.charId, itemName, count)
Animation Pattern¶
Play animations when using consumables:
-- Eating animation
TriggerClientEvent('cv_framework:hunger:playAnimation', source,
'mp_player_inteat@burger', 'mp_player_int_eat_burger', 3000)
-- Drinking animation
TriggerClientEvent('cv_framework:thirst:playAnimation', source,
'mp_player_intdrink', 'loop_bottle', 3000)
Important Notes¶
- Database Dependency: Items must exist in the
item_definitionstable before registration - Load Order: Register usable items after the inventory module loads (in
server.luaor after resource start) - Global State: Usable items are stored globally and persist across resource restarts
- Client Sync: When items are registered after server start, item definitions are automatically broadcasted to all connected clients
- Default Behavior: By default, using an item closes the inventory UI
- Validation: Always validate player context - callbacks can be triggered even if player disconnects
Debugging¶
Enable debug mode to see registration logs:
Logs will show:
- [Inventory] Registered usable item: itemName
- [Inventory] Registered usable item (cache updated): itemName (if cache already loaded)