qbcore-framework/qb-inventory

qbcore inventory

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 citizenidCopy

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 OpenShopis 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;

License

Leave a Comment

Your email address will not be published. Required fields are marked *


Get 20% off any Full QBCore Servers
en_USEnglish