Installation · origen_inventory
Follow the steps below to install origen_inventory on your server.
1. Add the resource to your server
Copy the origen_inventory folder into your resources directory and add it to your server.cfg.
The ensure order is important — every dependency must be running before origen_inventory.
# server.cfg
ensure oxmysql
ensure ox_lib
ensure qb-core # or es_extended / qbx_core
# Optional integrations
ensure qs-smartphone-pro # or lb-phone
ensure origen_clothing # only if you use Clothes-As-Item
ensure origen_inventoryNever start origen_inventory before oxmysql and your framework core. Without them the database driver and bridge layer will fail to initialize and inventories will not load.
2. Replace your previous inventory
If you are migrating from another inventory resource you must remove (or disable) it before starting origen_inventory. There can only be one active inventory provider at a time.
If your other scripts depend on qb-inventory or ox_inventory exports, open fxmanifest.lua and uncomment the matching provide line so those export calls resolve to origen_inventory:
-- Uncomment if you have old scripts that use qb-inventory
-- provide 'qb-inventory'
-- Uncomment if you have qbx_core installed
-- provide 'ox_inventory'3. Import the SQL schema
Import the file origen_inventory.sql into your database. It creates the four tables required by the resource: gloveboxitems, stashitems, trunkitems, origen_customitems and origen_inventory_equipped_clothes.
CREATE TABLE IF NOT EXISTS `gloveboxitems` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`plate` VARCHAR(255) NOT NULL COLLATE 'latin1_swedish_ci',
`items` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`label` VARCHAR(100) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`slots` INT(11) NULL DEFAULT NULL,
`personal` VARCHAR(255) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`weight` INT(11) NULL DEFAULT NULL,
`job` VARCHAR(100) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
PRIMARY KEY (`plate`) USING BTREE,
INDEX `id` (`id`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=152;
CREATE TABLE IF NOT EXISTS `stashitems` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`stash` VARCHAR(255) NOT NULL COLLATE 'latin1_swedish_ci',
`items` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`label` VARCHAR(100) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`slots` INT(11) NULL DEFAULT NULL,
`job` VARCHAR(100) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`personal` VARCHAR(255) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`weight` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`stash`) USING BTREE,
INDEX `id` (`id`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;
CREATE TABLE IF NOT EXISTS `trunkitems` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`plate` VARCHAR(255) NOT NULL COLLATE 'latin1_swedish_ci',
`items` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`label` VARCHAR(100) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`personal` VARCHAR(255) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`weight` INT(11) NULL DEFAULT NULL,
`slots` INT(11) NULL DEFAULT NULL,
`job` VARCHAR(100) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
PRIMARY KEY (`plate`) USING BTREE,
INDEX `id` (`id`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;
DROP TABLE IF EXISTS `origen_customitems`;
CREATE TABLE `origen_customitems` (
`name` VARCHAR(100) NOT NULL COLLATE 'utf8mb4_unicode_ci',
`label` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_unicode_ci',
`weight` INT(11) NOT NULL DEFAULT '0',
`type` VARCHAR(50) NOT NULL DEFAULT 'item' COLLATE 'utf8mb4_unicode_ci',
`image` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`description` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`unique` TINYINT(1) NOT NULL DEFAULT '0',
`rarity` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`stack` TINYINT(1) NOT NULL DEFAULT '0',
`close` TINYINT(1) NOT NULL DEFAULT '1',
`server` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`client` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`decay` INT(11) NULL DEFAULT NULL,
`buttons` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
PRIMARY KEY (`name`) USING BTREE,
CONSTRAINT `server` CHECK (json_valid(`server`)),
CONSTRAINT `client` CHECK (json_valid(`client`)),
CONSTRAINT `buttons` CHECK (json_valid(`buttons`))
)
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB
;
CREATE TABLE IF NOT EXISTS `origen_inventory_equipped_clothes` (
`identifier` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_unicode_ci',
`data` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`last_updated` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`identifier`) USING BTREE,
CONSTRAINT `data_json` CHECK (json_valid(`data`))
)
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB
;origen_customitems is dropped and recreated by the import file. If you already have custom items registered, back them up before running the SQL again.
4. Items
origen_inventory ships its own item dictionary (config/items.lua and config/weapons.lua). When you replace your previous inventory:
- QBCore / QBX: You can keep using your existing
shared/items.luaif your scripts depend on it. The bridge inbridge/qbcore/server/items.luaandbridge/qbx/server/players.luareads through both sources. - ESX: Items declared in the framework
itemstable will be loaded as well viabridge/esx/server/items.lua. - Custom items: Items added at runtime through
exports.origen_inventory:AddCustomItem(...)are persisted inorigen_customitemsand reloaded automatically on resource start.
5. ESX bridge setup
This step is only required if you are running ESX (es_extended). QBCore and QBX users can skip to step 6.
origen_inventory ships two override files that must be placed inside es_extended so the framework delegates all inventory calls to origen_inventory instead of its built-in inventory.
Where to place the files
Copy both files from the bridge/esx/overrides/ folder inside origen_inventory into your es_extended resource:
Source file (inside origen_inventory) | Destination (inside es_extended) |
|---|---|
bridge/esx/overrides/origeninventory.lua | es_extended/overrides/origeninventory.lua |
bridge/esx/overrides/origeninventory_player.lua | es_extended/overrides/origeninventory_player.lua |
Then make sure both files are declared in es_extended/fxmanifest.lua under server_scripts:
-- es_extended/fxmanifest.lua
server_scripts {
-- ... existing entries ...
'overrides/origeninventory.lua',
'overrides/origeninventory_player.lua',
}What each file does
origeninventory.lua — overrides the ESX item and usable-item functions so that calls to ESX.GetItemLabel, ESX.RegisterUsableItem and ESX.UseItem route to origen_inventory instead of the default ESX dictionary. It also handles starting account money and starting inventory items for new characters.
if Config.CustomInventory ~= "origen_inventory" then return end
MySQL.ready(function()
TriggerEvent("__cfx_export_origen_inventory_Items", function(ref)
if ref then
ESX.Items = exports.origen_inventory:Items()
end
end)
end)
---@diagnostic disable-next-line: duplicate-set-field
ESX.GetItemLabel = function(itemName)
local item = exports.origen_inventory:Items(itemName)
if item then
return item.label
end
print(('[^3WARNING^7] Attemting to get invalid Item -> ^5%s^7'):format(itemName))
end
---@diagnostic disable-next-line: duplicate-set-field
function ESX.RegisterUsableItem(item, cb)
Core.UsableItemsCallbacks[item] = cb
exports.origen_inventory:CreateUseableItem(item, cb)
end
---@diagnostic disable-next-line: duplicate-set-field
function ESX.UseItem(source, item, ...)
local src, itm = source, item
if type(src) == 'string' then item = src source = itm end
if ESX.Items[item] then
return exports['origen_inventory']:UseItem(item, source, ...)
else
print(('[^3WARNING^7] Item ^5"%s"^7 was used but does not exist!'):format(item))
end
end
exports("GetUseablesItems", function()
return Core.UsableItemsCallbacks
end)
function setPlayerInventory(playerId, xPlayer, inventory, isNew)
if isNew then
local shared = json.decode(GetConvar("inventory:accounts", '"money"'))
for i = 1, #shared do
local name = shared[i]
local account = Config.StartingAccountMoney[name]
if account then
exports.origen_inventory:AddItem(playerId, name, account)
end
end
if Config.StartingInventoryItems and type(Config.StartingInventoryItems) == "table" then
for item, count in pairs(Config.StartingInventoryItems) do
exports.origen_inventory:AddItem(playerId, item, count)
end
end
end
endorigeninventory_player.lua — injects Core.PlayerFunctionOverrides.OrigenInventory, replacing the default player inventory methods (getInventory, addInventoryItem, removeInventoryItem, hasItem, addWeapon, canCarryItem, etc.) with their origen_inventory equivalents. This ensures any internal ESX call that touches player inventory goes through origen_inventory.
------ Dont touch this file unless you know what you are doing
------ This file is used to override the inventory functions
---
---
---- Origen_File_Version - 4
---
---
if Config.CustomInventory ~= "origen_inventory" then return end
Core.PlayerFunctionOverrides.OrigenInventory = {
getInventory = function(self)
return function(minimal)
local inventory = exports.origen_inventory:GetPlayerInventory(self.source)
return inventory
end
end,
getLoadout = function(self)
return function()
return {}
end
end,
getInventoryItem = function(self)
return function(name, metadata)
local item = exports.origen_inventory:getItem(self.source, name)
if not item then
return {
count = 0,
}
end
return item
end
end,
addInventoryItem = function(self)
return function(name, count, metadata, slot)
return exports.origen_inventory:AddItem(self.source, name, count or 1, metadata, slot, true)
end
end,
removeInventoryItem = function(self)
return function(name, count, metadata, slot)
return exports.origen_inventory:RemoveItem(self.source, name, count or 1, metadata, slot, false)
end
end,
setInventoryItem = function(self)
return function(name, count, metadata)
return exports.origen_inventory:SetInventoryItems(self.source, name, count, metadata)
end
end,
save = function(self)
return function(inventory)
Core.SavePlayer(self)
end
end,
canCarryItem = function(self)
return function(name, count, metadata)
return exports['origen_inventory']:CanCarryItem(self.source, name, count)
end
end,
canSwapItem = function(self)
return function(firstItem, firstItemCount, testItem, testItemCount)
return true
end
end,
setMaxWeight = function(self)
return function() end
end,
addWeapon = function(self)
---@param weaponName item weapon
---@param ammo amount
return function(weaponName, ammo)
return exports['origen_inventory']:GiveWeaponToPlayer(self.source, weaponName, ammo)
end
end,
addWeaponComponent = function(self)
return function() end
end,
addWeaponAmmo = function(self)
return function() end
end,
updateWeaponAmmo = function(self)
return function() end
end,
setWeaponTint = function(self)
return function() end
end,
getWeaponTint = function(self)
return function() end
end,
removeWeapon = function(self)
return function() end
end,
removeWeaponComponent = function(self)
return function() end
end,
removeWeaponAmmo = function(self)
return function() end
end,
hasWeaponComponent = function(self)
return function()
return false
end
end,
hasWeapon = function(self)
return function()
return false
end
end,
hasItem = function(self)
return function(name, metadata)
return exports.origen_inventory:getItem(self.source, name, metadata)
end
end,
getWeapon = function(self)
return function() end
end,
}Both files guard themselves with if Config.CustomInventory ~= "origen_inventory" then return end, so they are safe to leave in place if you ever switch inventories — they will simply no-op.
6. Configure the resource
Open config.lua, config_sv.lua and the files inside config/ and adjust them for your server. See the Configuration page for the full list of options.
The minimum you should review before going live:
Config.Framework(auto-detected; only override if you run a custom fork)Config.LanguageConfig.Phone.ResourceConfig.ProgressbarConfig.Player.MaxWeightandConfig.Player.MaxInventorySlots- Webhook URLs in
config_sv.lua
7. Verify installation
After starting the server, join with a player and confirm:
- Pressing
F2opens the player inventory. - Pressing
TABtoggles the hotbar (ifConfig.UI.Hotbar = true). - Vehicle trunks open at the back of the vehicle (within
Config.TrunkOpenDistance). - Vehicle gloveboxes open while inside the vehicle.
- Stashes declared in
config/stashes.luashow their marker on the configured locations. - Shops declared in
config/shops.luashow their blip and marker. - Items are saved between sessions (player disconnect / reconnect).