One Studios
Client

Exports

Client-side exports.

All client exports are called as exports.one_inventory:Name(...) from a client script. Read-only exports are served from a local mirror that refreshes whenever the server pushes inventory state, so they don't round-trip the network.

Slot table format

Every export below that returns a slot returns the same standardized table.

name
string
Item definition name.
slot
number
Slot index the item sits in.
count
number
Stack count in the slot.
weight
number
The slot's effective weight in grams (per-unit weight times count).
metadata
table
The item's metadata: ammo, serial, components, and any custom keys. Absent when the slot has none.
label
string
Display label, from the item definition.
description
string
Description, from the item definition.
image
string
Image name, from the item definition.

Reads

SearchInventory

Search the local inventory mirror for items by name (and optional metadata filter).

exports.one_inventory:SearchInventory(searchType, itemName, metadata)
searchType
string required
'count' returns a summed number. 'slots' returns the matching slot list.
itemName
string required
Item name to match.
metadata
table
Optional metadata filter.

Returns: number | table[] - a count, or an array of slot tables in 'slots' mode.


GetInventoryItems

Every populated slot in the local inventory mirror.

exports.one_inventory:GetInventoryItems()

Returns: table[] - an array of slot tables.


GetSlot

Slot data at a given slot index.

exports.one_inventory:GetSlot(slot)
slot
number required
Slot index to read.

Returns: table | nil - a slot table, or nil if empty.


GetSlotWithItem

First slot containing the named item, optionally filtered by metadata.

exports.one_inventory:GetSlotWithItem(itemName, metadata)
itemName
string required
Item name to match.
metadata
table
Optional metadata filter.

Returns: table | nil - a slot table, or nil if not found.


GetSlotsWithItem

Every slot containing the named item, optionally filtered by metadata.

exports.one_inventory:GetSlotsWithItem(itemName, metadata)
itemName
string required
Item name to match.
metadata
table
Optional metadata filter.

Returns: table[] - array of slot tables; empty when no matches.


GetSlotIdWithItem

First slot index containing the item.

exports.one_inventory:GetSlotIdWithItem(itemName, metadata)
itemName
string required
Item name to match.
metadata
table
Optional metadata filter.

Returns: number | nil.


GetSlotIdsWithItem

Every slot index containing the item.

exports.one_inventory:GetSlotIdsWithItem(itemName, metadata)
itemName
string required
Item name to match.
metadata
table
Optional metadata filter.

Returns: number[] | nil - nil when no matches.


GetItemCount

Total count of an item across every slot in the local mirror.

exports.one_inventory:GetItemCount(itemName, metadata)
itemName
string required
Item name to match.
metadata
table
Optional metadata filter.

Returns: number.


HasItem

Same signature as qb-inventory's HasItem. Accepts a single name, an array of names, or a { name = required } map.

exports.one_inventory:HasItem(items, amount)
items
string | string[] | table<string, number> required
Single name, array of names, or per-item required counts.
amount
number
Required count when items is a string or array. Defaults to 1.

Returns: boolean.

Weight

GetWeightHolding

Current weight the player is carrying (grams).

exports.one_inventory:GetWeightHolding()

Returns: number.


GetMaxWeight

Maximum weight the player's inventory can hold (grams).

exports.one_inventory:GetMaxWeight()

Returns: number.

Weapons

GetEquippedWeapon

Currently-equipped weapon entry from the local mirror.

exports.one_inventory:GetEquippedWeapon()

Returns: table | nil - a slot table where metadata holds ammo / serial / components, or nil when no weapon is equipped.


DisarmPlayer

Unequip the local player's currently-equipped weapon. The item stays in the inventory. No-op when nothing is equipped.

exports.one_inventory:DisarmPlayer(noAnim)
noAnim
boolean
true skips the holster animation.

Clothing

These exports operate on the local player only; there is no src argument because they always target the calling client. Add or remove the clothing items themselves through the player's regular inventory via AddItem / RemoveItem; use the exports below to actually equip / unequip them on the ped.

GetEquippedClothing

Currently equipped clothing.

exports.one_inventory:GetEquippedClothing()

Returns: table - map of { [componentType] = slot }, where each value is a slot table plus the clothing-specific fields componentType, drawable, and texture. Empty components are absent. Returns {} when nothing is equipped.


SyncClothingFromPed

Re-read the ped's current outfit and refresh the local clothing mirror from it.

exports.one_inventory:SyncClothingFromPed()

EquipClothing

Equip a clothing item from the player's inventory. Round-trips to the server; the ped auto-updates when the server pushes the new state back.

local ok, reason = exports.one_inventory:EquipClothing(item, metadata)
item
string required
Item name to equip.
metadata
table
Optional metadata filter, used to disambiguate stacks when the item appears multiple times.

Returns: boolean, string? - ok, plus a reason on failure: no_player, no_clothing_inv, not_clothing, item_not_in_inventory, invalid_component, no_room, unknown_error, no_response.


UnequipClothing

Unequip a clothing component and return the item to the player's inventory. Round-trips to the server.

local ok, reason = exports.one_inventory:UnequipClothing(componentType)
componentType
string required
One of hat, mask, glasses, ear, chain, shirt, armor, jacket, bag, gloves, pants, shoes, watch, bracelet.

Returns: boolean, string? - ok, plus a reason on failure: no_player, no_clothing_inv, invalid_component, nothing_equipped, inventory_full, no_response.

inventory_full also covers the case where the underlying addItem returns no_slot server-side, so a single failure reason is enough to drive UI feedback.

SetClothingPollingEnabled

Pause or resume the clothing polling thread (the loop that reads the ped to auto-create items for appearance scripts without a save event). Pause it around a custom clothing-shop or character-creator preview so intermediate try-on looks aren't captured as items.

exports.one_inventory:SetClothingPollingEnabled(enabled)
enabled
boolean required
false pauses the thread, true resumes it.
Pauses ONLY the polling thread. Appearance scripts that expose a save event keep syncing while it is paused.

Definitions

GetItemDefinition

Definition by name (label, weight, stack rules, metadata defaults, ...). Resolves any definition type (item, weapon, ammo, component, container, clothing); the returned table carries a type field. Lazy-fetched from the server on first call (5s timeout) and cached for the rest of the client session.

exports.one_inventory:GetItemDefinition(itemName)
itemName
string required
Definition name to look up.

Returns: table | nil - the definition with an added type field, or nil if unknown.


GetAllItemDefinitions

Complete { [name] = definition } map across all definition types, each tagged with a type field. Same backing cache as GetItemDefinition.

exports.one_inventory:GetAllItemDefinitions(filter)
filter
string | string[]
Narrow to one or more types, e.g. 'weapon' or { 'weapon', 'ammo' }. Omit (or pass an empty value) to return everything.

Returns: table<string, table> - each definition carries a type field.

These definition lists rarely change at runtime, so most scripts call them once and cache the result. When a definition is created, edited, or deleted from any source, the one_inventory:onDefinitionsUpdated event fires (coalesced, no payload). The client definition cache is already refreshed before the event fires, so GetAllItemDefinitions / GetItemDefinition return fresh data inside the handler with no restart needed:

AddEventHandler('one_inventory:onDefinitionsUpdated', function()
    local defs = exports.one_inventory:GetAllItemDefinitions()
    -- rebuild your cached list here
end)

Config

GetClientConfig

A copy of the shared, client-facing config table (locale, keybinds, appearance, gameplay, ...). The same export is available server-side; it never exposes server-only keys.

exports.one_inventory:GetClientConfig()

Returns: table - a copy of the client-facing config. Mutating it does not affect the live config.

There is no client-side equivalent for the server-only config. GetServerConfig is server-side only.

UI

OpenInventory

Open a secondary inventory locally. Honors every per-type security gate (distance, lock, ownership, access). Use the server-side OpenInventory export to bypass those checks.

exports.one_inventory:OpenInventory(invType, data)
invType
string required
One of stash, shop, crafting, drop, vehicle:trunk, vehicle:glovebox, player, license.
data
string | number | table
Identifier shorthand or full data table - meaning varies by invType (see below).

Returns: boolean.

Vehicle inventories resolve locally: vehicle:glovebox opens the seated vehicle (no id), vehicle:trunk opens the nearest vehicle within interact distance while the ped is not seated.container and dumpster are intentionally rejected here: containers open from inside an existing inventory, dumpsters from the world interaction loop.

Data fields (per invType)

invTypeData
stash{ id, owner?, slots?, maxWeight?, label?, groups? } - slots / maxWeight apply on auto-create AND live-resize
shop'<shop name>'
crafting'<bench name>'
drop'<drop id>'
vehicle:trunkomit - nearest vehicle
vehicle:gloveboxomit - seated vehicle
player<target server id>
license'<license name>'

Examples

The owner field controls how the stash contents are isolated. groups optionally gates access by job. slots, maxWeight, and label apply on auto-create AND resize an already-loaded stash live.

ownerFlavourBehaviour
omit / falseSharedOne bucket. Everyone with access sees the same contents.
truePer-playerPer-opener private bucket, keyed automatically by the opener's identifier.
'<identifier>'OwnedIdentifier should match with this one on server
exports.one_inventory:OpenInventory('stash', { id = 'evidence_locker' })

exports.one_inventory:OpenInventory('stash', {
  id    = 'personal_storage',
  owner = true,
})

exports.one_inventory:OpenInventory('stash', {
  id     = 'police_armory',
  groups = { { name = 'police', minGrade = 0 } },
})

-- Auto-creates a 100-slot warehouse OR live-resizes one that already exists.
exports.one_inventory:OpenInventory('stash', {
  id        = 'warehouse',
  label     = 'Warehouse',
  slots     = 100,
  maxWeight = 200000,
})

OpenNearbyInventory

Open the inventory of the nearest player within a 3m radius (the police "search nearby" feature). No-op if no eligible player is found.

exports.one_inventory:OpenNearbyInventory()

Returns: boolean.


CloseInventory

Close the inventory if it's open (no-op otherwise). Runs the full player-facing close: hides the NUI, releases the server-side viewers, and cleans up whatever secondary is open (vehicle doors / anim, stash, drop, containers, dumpster, player search).

exports.one_inventory:CloseInventory()
This is a forced close. Unlike the Escape key, it ignores the craft / action-busy guards and closes regardless.

SetCanOpenInventory

Set the hard lock on opening the inventory. The gate is binary:

  • SetCanOpenInventory(false) is a hard lock: the open keybind, every interaction (stash, shop, crafting, dumpster, trunk, glovebox) and the hotbar (both showing it and its 1-5 quick-use keys) are all blocked. The typical use is locking the inventory while another resource's UI is open.
  • SetCanOpenInventory(true) (or never calling it) just lets the normal eligibility checks run (not dead, not falling, no pause menu). It is not a force-open and does not bypass those checks.
exports.one_inventory:SetCanOpenInventory(allowed)
allowed
boolean required
false hard-locks opening, true restores normal eligibility.
Locking also hides the hotbar if it's currently on screen. It does not close an already-open inventory; pair it with CloseInventory for that. Server-forced opens (admin inspect, the server-side OpenInventory export) still bypass everything via an internal force path.

CanOpenInventory

Whether the player can open the inventory right now. Returns the combined result of the SetCanOpenInventory hard lock and the normal eligibility checks (not dead, not falling, no pause menu).

exports.one_inventory:CanOpenInventory()

Returns: boolean.

Custom death detection. The "dead" eligibility check reads the standard framework death and last-stand states, so it works out of the box on ESX, QB and QBox. If you run a custom ambulance or death script that tracks its own state, the death detection (client and server) is overridable in integrations/opensource.lua so you can adapt it.
CanUseInventory. A related internal check that also requires no inventory action to already be running (see the inv_busy state bag), used to gate the hotbar quick-use keys and UseItemInSlot. It isn't itself exported, but like the death detection above, it's overridable in integrations/opensource.lua.

UseItemInSlot

Trigger the standard "use item" flow on the given slot. Returns true only when the server actually consumed / used the item: filled slot, item registered usable, no hook or definition guard blocked it.

exports.one_inventory:UseItemInSlot(slot)
slot
number required
Slot index to use (coerced via tonumber).

Returns: boolean.


ShowItemMetadata

Register metadata key -> label mappings so an item whose metadata contains that key renders an extra tooltip line with the configured label.

exports.one_inventory:ShowItemMetadata(data, label, item)
data
string | table required
The mapping(s): a single key string, a { key = label } map, or a { { key, label }, ... } array.
label
string
Label to use, only when data is a single key string.
item
string
Restrict the labels to this item only. Omit to apply them to all items.

Returns: boolean - true when at least one mapping was registered.

Item buttons

RegisterItemButton

Add a right-click button to an item's context menu. This client-side variant runs fn client-side (on this client only) when the button is clicked. Available on the server too (where fn runs server-side and the payload also carries source).

exports.one_inventory:RegisterItemButton(itemName, label, fn)
itemName
string required
Item the button is shown on.
label
string required
Button text in the right-click menu.
fn
function required
Handler called with a single payload table (see below) when the button is clicked.

The fn payload (client side):

payload.slot
number
Slot the item sits in.
payload.item
string
Item name.
payload.count
number
Stack count.
payload.metadata
table
The slot's metadata.
payload.label
string
The item's label (not the button's).
payload.description
string
The item's description (not the button's).
The client payload has nosource field. Buttons are in memory only: they are not persisted, so re-register them on every resource restart. Clicking a button only runs its handler. It never uses or consumes the item.
Admin-panel item buttons (the event / export / function trigger types configured in the panel) also execute client-side and receive this same payload withoutsource.

Returns: boolean - false on invalid input.

exports.one_inventory:RegisterItemButton('water', 'Drink Water', function(payload)
    -- runs client-side; no payload.source
    print(('used slot %s'):format(payload.slot))
end)