Features
- Stashes (Personal and/or Shared)
- Vehicle Trunk & Glovebox
- Weapon Attachments
- Shops
- Item Drops
Download
Documentation
Introduction
- Handles all the player’s storage such as personal, vehicle, stash, drops
- qb-shops integration for displaying all items available to buy
- Built-in support for usable vending machines
All exports listed are SERVER only unless specified
Inventory State
The inventory state is controlled via state bags using a state bag name of inv_busy
. You can use this state to control whether the inventory should be able to be opened or not
Example (server):
Copy
RegisterCommand('checkState', function(source)
local player = Player(source)
local state = player.state.inv_busy
print('Inventory current state is', state)
end, true)
RegisterCommand('lockInventory', function(source)
local player = Player(source)
player.state.inv_busy = true
print('Inventory current state is', state)
end, true)
RegisterCommand('unlockInventory', function(source)
local player = Player(source)
player.state.inv_busy = false
print('Inventory current state is', state)
end, true)
Example (client):
Copy
RegisterCommand('lockInventory', function()
LocalPlayer.state:set('inv_busy', true, true)
end, false)
RegisterCommand('unlockInventory', function()
LocalPlayer.state:set('inv_busy', false, true)
end, false)
Item Info
You can use SetItemData to achieve this
Items support additional information that can be added to them via an info
attribute. This information will display on the item when the player hovers over it in a key,value pair format
Example:
Copy
RegisterCommand('addItemWithInfo', function(source, args)
local itemName = args[1]
if not itemName then return end
local info = {
uniqueData1 = 'uniqueData1',
uniqueData2 = 'uniqueData2',
uniqueData3 = 'uniqueData3',
uniqueData4 = 'uniqueData4',
}
exports['qb-inventory']:AddItem(source, itemName, 1, false, info, 'qb-inventory:testAdd')
end, true)
RegisterCommand('editItemWithInfo', function(source)
local Player = QBCore.Functions.GetPlayer(source)
if not Player then return end
local items = Player.PlayerData.items
local itemInfo = items[1]
print(json.encode(itemInfo, { indent = true }))
itemInfo.info = {
newInfo = 'New Info'
}
print(json.encode(itemInfo, { indent = true }))
items[1] = itemInfo
Player.Functions.SetPlayerData('items', items)
end, true)
LoadInventory
This function will retrieve the players inventory from the database via their unique identifier aka citizenid
Copy
exports['qb-inventory']:LoadInventory(source, citizenid)
- source:
number
- citizenid:
string
- returns:
table
Copy
RegisterCommand('getInv', function(source)
local Player = QBCore.Functions.GetPlayer(source)
local citizenId = Player.PlayerData.citizenid
local items = exports['qb-inventory']:LoadInventory(source, citizenid)
print(json.encode(items, { indent = true }))
end)
SaveInventory
This function saves the players current items to the databaseCopy
exports['qb-inventory']:SaveInventory(source, offline)
- source:
number
- offline:
boolean
Example:
Copy
RegisterCommand('saveInv', function(source)
exports['qb-inventory']:SaveInventory(source, false)
end)
ClearInventory
Copy
exports['qb-inventory']:ClearInventory(source, filterItems)
- source:
number
- filterItems:
string | table
Example:Copy
RegisterCommand('clearInventoryExcludeItem', function(source, args)
local filterItem = args[1]
if not filterItem then return end
exports['qb-inventory']:ClearInventory(source, filterItem)
print('Inventory cleared for player '..source..', excluding item: '..filterItem)
end, true)
RegisterCommand('clearInventoryExcludeItems', function(source)
local filterItems = {'item1', 'item2'}
exports['qb-inventory']:ClearInventory(source, filterItems)
print('Inventory cleared for player '..source..', excluding items: '..table.concat(filterItems, ', '))
end, true)
CloseInventory
Copy
exports['qb-inventory']:CloseInventory(source, identifier)
- source:
number
- identifier:
string
Example:Copy
RegisterCommand('closeInventory', function(source)
exports['qb-inventory']:CloseInventory(source)
print('Inventory closed for player '..source)
end, true)
RegisterCommand('closeInventoryByName', function(source, identifier)
exports['qb-inventory']:CloseInventory(source, identifier)
print('Inventory closed for player '..source..' and inventory '..identifier..' set to closed')
end, true)
OpenInventory
Copy
exports['qb-inventory']:OpenInventory(source, identifier, data)
- source:
number
- identifier:
string | optional
- data:
table | optional
Example:
Copy
RegisterCommand('openinv', function(source)
exports['qb-inventory']:OpenInventory(source)
end, true)
RegisterCommand('openinvbyname', function(source, args)
local inventoryName = args[1]
exports['qb-inventory']:OpenInventory(source, inventoryName)
end, true)
RegisterCommand('openinvbynamewithdata', function(source, args)
local inventoryName = args[1]
local data = { label = 'Custom Stash', maxweight = 400000, slots = 500 }
exports['qb-inventory']:OpenInventory(source, inventoryName, data)
end, true)
OpenInventoryById
Copy
exports['qb-inventory']:OpenInventoryById(source, playerId)
- source:
number
- playerId:
number
Example:
Copy
RegisterCommand('openplayerinv', function(source, args)
local playerId = tonumber(args[1])
exports['qb-inventory']:OpenInventoryById(source, playerId)
end, true)
OpenInventoryById
will close the target players inventory (if open) and lock it via state. It will then unlock when the opening player closes it
CreateShop
Copy
exports['qb-inventory']:CreateShop(shopData)
- shopData:
table
Copy
local items = {
{ name = 'sandwich', amount = 10, price = 5 }
}
RegisterCommand('createShop', function(source)
local playerPed = GetPlayerPed(source)
local playerCoords = GetEntityCoords(playerPed)
exports['qb-inventory']:CreateShop({
name = 'testShop',
label = 'Test Shop',
coords = playerCoords, -- optional
slots = #items,
items = items
})
end, true)
Coords being passed to createShop
will be checked against the player’s current coords when OpenShop
is called if coords were provided during createShop
OpenShop
Copy
exports['qb-inventory']:OpenShop(source, name)
- source:
number
- name:
string
Copy
RegisterCommand('openShop', function(source)
exports['qb-inventory']:OpenShop(source, 'testShop')
end)
CanAddItem
Copy
exports['qb-inventory']:CanAddItem(source, item, amount)
- source:
number
- item:
string
- amount:
number
- returns:
boolean
Example:Copy
RegisterCommand('canAddItem', function(source, args)
local itemName = args[1]
local amount = tonumber(args[2])
if not itemName or not amount then return end
local canAdd, reason = exports['qb-inventory']:CanAddItem(source, itemName, amount)
if canAdd then
print('Can add '..amount..' of item '..itemName)
else
print('Cannot add '..amount..' of item '..itemName..'. Reason: '..reason)
end
end, true)
AddItem
Copy
exports['qb-inventory']:AddItem(identifier, item, amount, slot, info, reason)
- identifier:
number
- item:
string
- amount:
number
- slot:
number | boolean
- info:
table | boolean
- reason:
string
- returns:
boolean
Example:
Copy
RegisterCommand('addItem', function(source, args)
local itemName = args[1]
if not itemName then return end
exports['qb-inventory']:AddItem(source, itemName, 1, false, false, 'qb-inventory:testAdd')
end, true)
RemoveItem
Copy
exports['qb-inventory']:RemoveItem(identifier, item, amount, slot, reason)
- identifier:
number
- item:
string
- amount:
number
- slot:
number | boolean
- reason:
string
- returns:
boolean
Copy
RegisterCommand('removeItem', function(source, args)
local itemName = args[1]
if not itemName then return end
exports['qb-inventory']:RemoveItem(source, itemName, 1, false, 'qb-inventory:testRemove')
end, true)
SetInventory
Copy
exports['qb-inventory']:SetInventory(source, items)
- source:
number
- items:
table
Example:Copy
RegisterCommand('setInventory', function(source)
local items = {
{
name = 'sandwich',
amount = 10,
type = 'item',
info = {},
slot = 1
},
{
name = 'water_bottle',
amount = 10,
type = 'item',
info = {},
slot = 2
}
}
exports['qb-inventory']:SetInventory(source, items)
end, true)
SetItemData
This function uses GetItemByName to find the itemName being passedCopy
exports['qb-inventory']:SetItemData(source, itemName, key, val)
- source:
number
- itemName:
string
- key:
string
- val:
string | table
- returns:
boolean
Example:Copy
RegisterCommand('setItemData', function(source, args)
local itemName = args[1]
local key = args[2]
local val = args[3]
if not itemName or not key or not val then return end
local success = exports['qb-inventory']:SetItemData(source, itemName, key, val)
if success then
print('Set data for item '..itemName..': '..key..' = '..val)
else
print('Failed to set data for item '..itemName)
end
end, true)
Item Info Example:
Copy
RegisterCommand('setItemData', function(source)
local itemName = 'markedbills'
local key = 'info'
local val = { worth = 1000 }
if not itemName or not key or not val then return end
local success = exports['qb-inventory']:SetItemData(source, itemName, key, val)
if success then
print('Set data for item '..itemName..': '..key..' = '..json.encode(val, { indent = true }))
else
print('Failed to set data for item '..itemName)
end
end, true)
UseItem
Copy
exports['qb-inventory']:UseItem(itemName, ...)
- itemName:
string
- . . . :
function
Example:Copy
RegisterCommand('useItem', function(source, args)
local itemName = args[1]
if not itemName then return end
exports['qb-inventory']:Useitem(itemName, function()
print('Used item with the name of '..itemName)
end)
end, true)
HasItem
This export is also available to use on the clientCopy
exports['qb-inventory']:HasItem(source, items, amount)
- source:
number
- items:
string | table
- amount:
number
- returns:
boolean
Example:Copy
RegisterCommand('hasSingleItem', function(source)
local item = 'item1'
local amount = 5
local hasItem = exports['qb-inventory']:HasItem(source, item, amount)
if hasItem then
print('Player '..source..' has '..amount..' of '..item)
else
print('Player '..source..' does not have '..amount..' of '..item)
end
end, true)
RegisterCommand('hasMultipleItems', function(source)
local items = {'item1', 'item2'}
local amount = 5
local hasItems = exports['qb-inventory']:HasItem(source, items, amount)
if hasItems then
print('Player '..source..' has '..amount..' of each item: '..table.concat(items, ', '))
else
print('Player '..source..' does not have '..amount..' of each item: '..table.concat(items, ', '))
end
end, true)
RegisterCommand('hasMultipleItemsWithAmounts', function(source)
local itemsWithAmounts = {item1 = 5, item2 = 10}
local hasItemsWithAmounts = exports['qb-inventory']:HasItem(source, itemsWithAmounts)
if hasItemsWithAmounts then
print('Player '..source..' has the specified items with their amounts')
else
print('Player '..source..' does not have the specified items with their amounts')
end
end, true)
GetSlotsByItem
Copy
exports['qb-inventory']:GetSlotsByItem(items, itemName)
- items:
table
- itemName:
string
- returns:
table
Example:Copy
RegisterCommand('getSlots', function(source, args)
local itemName = args[1]
if not itemName then return end
local Player = QBCore.Functions.GetPlayer(source)
local items = Player.PlayerData.Items
local slots = exports['qb-inventory']:GetSlotsByItem(items, itemName)
for _, slot in ipairs(slots) do
print(slot)
end
end, true)
GetFirstSlotByItem
Copy
exports['qb-inventory']:GetFirstSlotByItem(items, itemName)
- items:
table
- itemName:
string
- returns:
number
Example:Copy
RegisterCommand('getFirstSlot', function(source, args)
local itemName = args[1]
if not itemName then return end
local Player = QBCore.Functions.GetPlayer(source)
local items = Player.PlayerData.Items
local slot = exports['qb-inventory']:GetFirstSlotByItem(items, itemName)
if slot then
print('First slot containing item '..itemName..' is: '..slot)
else
print('No slot found containing item '..itemName)
end
end, true)
GetItemBySlot
Copy
exports['qb-inventory']:GetItemBySlot(source, slot)
- source:
number
- slot:
number
- returns:
table
Example:Copy
RegisterCommand('getItem', function(source, args)
local slot = tonumber(args[1])
if not slot then return end
local item = exports['qb-inventory']:GetItemBySlot(source, slot)
if item then
print('Item in slot '..slot..' is: '..item.name)
else
print('No item found in slot '..slot)
end
end, true)
GetItemByName
exports['qb-inventory']:GetItemByName(source, item)
- source:
number
- item:
string
- returns:
table
RegisterCommand('getItemByName', function(source, args)
local itemName = args[1]
if not itemName then return end
local item = exports['qb-inventory']:GetItemByName(source, itemName)
if item then
print('First occurrence of item '..itemName..' is in slot: '..item.slot)
else
print('No item found with name '..itemName)
end
end, true)
GetItemsByName
exports['qb-inventory']:GetItemsByName(source, item)
- source:
number
- item:
string
- returns:
table
Example:Copy
RegisterCommand('getItemsByName', function(source, args)
local itemName = args[1]
if not itemName then return end
local items = exports['qb-inventory']:GetItemsByName(source, itemName)
if #items > 0 then
print('Items named '..itemName..' found in slots:')
for _, item in ipairs(items) do
print(item.slot)
end
else
print('No items found with name '..itemName)
end
end, true)
GetItemCount
exports['qb-inventory']:GetItemCount(source, items)
- source:
number
- items:
string | table
- returns:
number
Example:Copy
RegisterCommand(‘getItemCount’, function(source, args) local itemName = args[1] if not itemName then return end local itemCount = exports[‘qb-inventory’]:GetItemCount(source, itemName) if itemCount and itemCount > 0 then print(‘You have ‘..itemCount..’ of item: ‘..itemName) else print(‘No items found with name ‘..itemName) end end, true)RegisterCommand(‘getItemCounts’, function(source) local itemNames = {“apple”, “banana”, “orange”} local itemCount = exports[‘qb-inventory’]:GetItemCount(source, itemNames) if itemCount and itemCount > 0 then print(‘You have ‘..itemCount..’ of the items: ‘..table.concat(itemNames, “, “)) else print(‘No items found with the names: ‘..table.concat(itemNames, “, “)) end end, true)
Installation
Manual
- Download the script and put it in the
[qb]
directory. - Import
qb-inventory.sql
in your database - Add the following code to your server.cfg/resouces.cfg
Migrating from old qb-inventory
Database
Upload the new inventory.sql
file to create the new inventories
table
Use the provided migrate.sql
file to migrate all of your saved inventory data from stashes, trunks, etc
Once complete, you can delete gloveboxitems
stashitems
and trunkitems
tables from your database
CREATE TABLE IF NOT EXISTS `inventories` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `identifier` VARCHAR(50) NOT NULL, `items` LONGTEXT DEFAULT ('[]'), PRIMARY KEY (`identifier`), KEY `id` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;