Inventoryintermediate10 min readupdated 11 Sept 2026

Setting up a police armory

The short answer

Define an armory shop in ox_inventory with groups = { police = 0 } so only police can open it, give items a grade for rank requirements and price = 0 (or a small fee) for service weapons, and add metadata = { registered = true } so each weapon gets a serial registered to the officer. Add personal lockers (owner = true stashes), an evidence stash for seized items and a routine for returning weapons at the end of shift.

A police armory decides who carries what: cadets with a taser and pistol, sergeants with a carbine, SWAT with everything. With ox_inventory it is a job-restricted shop with grade requirements, plus lockers and an evidence room built from stashes.

Setting up a police armory — illustrated with a FiveM-compatible minimap render

#The armory shop

ox_inventory/data/shops.lua
PoliceArmoury = {
    name = 'Police Armoury',
    groups = { police = 0 },
    blip = { id = 110, colour = 84, scale = 0.8 },
    inventory = {
        { name = 'WEAPON_STUNGUN', price = 0, metadata = { registered = true } },
        { name = 'WEAPON_COMBATPISTOL', price = 0, metadata = { registered = true } },
        { name = 'ammo-9', price = 0 },
        { name = 'WEAPON_CARBINERIFLE', price = 0, grade = 3, metadata = { registered = true } },
        { name = 'ammo-rifle', price = 0, grade = 3 },
        { name = 'armour', price = 0 },
    },
    locations = { vec3(452.6, -980.0, 30.7) },
},

Field reference: shops config. Serials: serial numbers.

#Lockers and evidence

StorageSetup
Personal lockerStash with owner = true, groups = { police = 0 }
Shared squad lockerStash with groups = { police = 2 }, no owner
Evidence roomStash with a higher grade requirement and logging hooks

Stash setup: ox_inventory stashes. Log evidence moves with a swapItems hook — see hooks.

#End of shift

server.lua — remove service weapons when going off duty
local SERVICE = { WEAPON_STUNGUN = true, WEAPON_COMBATPISTOL = true, WEAPON_CARBINERIFLE = true }

local function returnServiceWeapons(src)
    for _, item in pairs(exports.ox_inventory:GetInventoryItems(src) or {}) do
        if SERVICE[item.name] then
            exports.ox_inventory:RemoveItem(src, item.name, item.count, item.metadata, item.slot)
        end
    end
end

Call it from your duty toggle. It prevents officers keeping carbines in their personal inventory after shift.

#On other inventories

QBCore servers usually configure the armory inside the police job resource (items with grade requirements) with qb-inventory; ESX servers use the police job’s armory menu or ox_inventory. The concepts — job lock, grade lock, registered weapons, lockers — stay the same. See inventory systems compared.

Share this guideXRedditFacebook

Questions

How do I make a police armory in ox_inventory?
Create a shop with groups = { police = 0 }, add weapons with price = 0 and optional grade, and give them metadata = { registered = true }.
How do I lock weapons to a rank?
Set grade on the item in the shop inventory.
How do I stop officers keeping weapons after shift?
Remove service weapons on the server when they go off duty.
Where do seized weapons go?
Into an evidence stash with restricted access and logging.

Ready to pick a map?

Twelve themes on three base map styles, $8 each, instant download.

Relevant to what you just read

The tool for this

Twenty theme pairs for ox_lib and ox_inventory From $15, built in the browser, exported as a drop-in resource.