bridge/inventory.lua
-- ==========================================
-- INVENTORY BRIDGE (server-side only)
-- ==========================================
-- Auto-detects the active inventory resource and provides
-- a unified API so the main script never calls inventory
-- exports directly.
--
-- Supported inventories:
-- 1. ox_inventory
-- 2. tgiann-inventory
--
-- NOTE: qb-inventory is NOT supported — it does not reliably
-- persist item metadata which is required for drone serials,
-- battery charge levels, skin images, etc.
--
-- Global table: Inv
--
-- Normalised item format returned by Inv.GetItem / Inv.GetItems:
-- { name = 'item_name', amount = 1, info = { ... }, slot = 3 }
-- ==========================================
Inv = {}
-- ==========================================
-- AUTO-DETECT
-- ==========================================
local invType = Config.Setup and Config.Setup.inventory or 'ox'
-- Validate the configured inventory is actually running
local invResourceMap = {
ox = 'ox_inventory',
tgiann = 'tgiann-inventory',
}
if invType == 'qb' then
print('[fiveous_drones] ^1ERROR: qb-inventory is not supported — it does not reliably handle item metadata.^0')
print('[fiveous_drones] ^1 → Please switch to ox_inventory or tgiann-inventory and set Config.Setup.inventory accordingly.^0')
end
local expectedResource = invResourceMap[invType]
if not expectedResource then
-- Try auto-detect if invalid/unsupported value
if GetResourceState('ox_inventory') == 'started' then
invType = 'ox'
expectedResource = 'ox_inventory'
print('[fiveous_drones] ^3Auto-detected ox_inventory^0')
elseif GetResourceState('tgiann-inventory') == 'started' then
invType = 'tgiann'
expectedResource = 'tgiann-inventory'
print('[fiveous_drones] ^3Auto-detected tgiann-inventory^0')
else
print('[fiveous_drones] ^1ERROR: No supported inventory found! ox_inventory or tgiann-inventory is required.^0')
print('[fiveous_drones] ^1 → This script requires item metadata support for drone serials, battery charge, etc.^0')
end
elseif GetResourceState(expectedResource) ~= 'started' then
print('[fiveous_drones] ^1WARNING: Config.Setup.inventory = "' .. invType .. '" but ' .. expectedResource .. ' is not started!^0')
-- Try the other supported inventory
if invType == 'ox' and GetResourceState('tgiann-inventory') == 'started' then
invType = 'tgiann'
print('[fiveous_drones] ^3Falling back to tgiann-inventory^0')
elseif invType == 'tgiann' and GetResourceState('ox_inventory') == 'started' then
invType = 'ox'
print('[fiveous_drones] ^3Falling back to ox_inventory^0')
end
end
print('[fiveous_drones] Inventory bridge → ' .. invType)
-- ==========================================
-- OX_INVENTORY
-- ==========================================
if invType == 'ox' then
local ox = exports.ox_inventory
--- Normalise an ox item → unified format (.info, .amount)
local function norm(item)
if not item then return nil end
return {
name = item.name,
amount = item.count or item.amount or 1,
info = item.metadata or {},
metadata = item.metadata or {},
slot = item.slot,
label = item.label,
}
end
function Inv.AddItem(src, name, count, metadata, slot)
local ok = ox:AddItem(src, name, count or 1, metadata, slot)
return ok and true or false
end
function Inv.RemoveItem(src, name, count, slot)
local ok = ox:RemoveItem(src, name, count or 1, nil, slot)
return ok and true or false
end
function Inv.GetItem(src, name)
local items = ox:Search(src, 'slots', name)
if not items or #items == 0 then return nil end
return norm(items[1])
end
function Inv.GetItems(src)
local raw = ox:GetInventoryItems(src)
if not raw then return {} end
local out = {}
for _, item in pairs(raw) do
if item and item.slot then
out[item.slot] = norm(item)
end
end
return out
end
function Inv.HasItem(src, name, count)
local result = ox:Search(src, 'count', name)
return result and result >= (count or 1)
end
function Inv.RegisterUsableItem(name, cb)
-- Usable items are always registered through the framework, not the inventory.
-- QBCore / QBox handle this; ox_inventory does not provide its own export for it.
if Config.Setup and Config.Setup.framework == 'qbcore' then
local QBCore = exports['qb-core']:GetCoreObject()
QBCore.Functions.CreateUseableItem(name, function(source, item)
cb(source, norm(item) or item)
end)
end
end
-- ==========================================
-- TGIANN-INVENTORY
-- ==========================================
elseif invType == 'tgiann' then
local tg = exports['tgiann-inventory']
--- Normalise tgiann item → unified format
local function norm(item)
if not item then return nil end
return {
name = item.name,
amount = item.amount or item.count or 1,
info = item.info or item.metadata or {},
metadata = item.info or item.metadata or {},
slot = item.slot,
label = item.label,
}
end
function Inv.AddItem(src, name, count, metadata, slot)
local ok = tg:AddItem(src, name, count or 1, slot, metadata)
return ok and true or false
end
function Inv.RemoveItem(src, name, count, slot)
local ok = tg:RemoveItem(src, name, count or 1, slot)
return ok and true or false
end
function Inv.GetItem(src, name)
local item = tg:GetItemByName(src, name)
return norm(item)
end
function Inv.GetItems(src)
local raw = tg:GetPlayerItems(src)
if not raw then return {} end
local out = {}
for _, item in pairs(raw) do
if item and item.slot then
out[item.slot] = norm(item)
end
end
return out
end
function Inv.HasItem(src, name, count)
local item = Inv.GetItem(src, name)
return item ~= nil and (item.amount or 0) >= (count or 1)
end
function Inv.RegisterUsableItem(name, cb)
-- tgiann typically supports QBCore's CreateUseableItem too,
-- but we prefer the direct export for safety
local QBCore = exports['qb-core']:GetCoreObject()
QBCore.Functions.CreateUseableItem(name, function(source, item)
cb(source, norm(item) or item)
end)
end
end
-- ==========================================
-- SHARED HELPERS (work with any backend)
-- ==========================================
--- Convenience: get item metadata table regardless of key name
--- Works on raw items from any backend
--- @param item table
--- @return table metadata
function Inv.GetItemInfo(item)
if not item then return {} end
return item.info or item.metadata or {}
end
Last updated