> For the complete documentation index, see [llms.txt](https://oph3zdev.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://oph3zdev.gitbook.io/docs/paid-scripts/inventory/exports/server.md).

# Server

### AddItem

Gives an item, with optional metadata.

```lua
exports["oph3z-inventory"]:AddItem(src, "water_bottle", 1, metadata)
```

### RemoveItem

Removes an item, optionally only one matching the metadata.

```lua
exports["oph3z-inventory"]:RemoveItem(src, "water_bottle", 1, metadata)
```

### HasItem

Does the player carry at least this amount.

```lua
exports["oph3z-inventory"]:HasItem(src, "lockpick", 1)
```

### GetItemCount

Total amount carried, optionally filtered by metadata. `GetItemsTotalAmount` is the same export under another name.

```lua
exports["oph3z-inventory"]:GetItemCount(src, "cloth")
```

### GetItemByName

The first matching item, with its slot and metadata. `GetItem` is the same export under another name.

```lua
exports["oph3z-inventory"]:GetItemByName(src, "weapon_pistol")
```

### GetItemsByName

Every matching item as an array. `Search` is the same export under another name.

```lua
exports["oph3z-inventory"]:GetItemsByName(src, "water_bottle")
```

### GetItemBySlot

The item sitting in a slot.

```lua
exports["oph3z-inventory"]:GetItemBySlot(src, 3)
```

### SetItemBySlot

Replaces the item at a slot, `nil` removes it.

```lua
exports["oph3z-inventory"]:SetItemBySlot(src, 3, { name = "cloth", amount = 5, metadata = {} })
```

### GetFirstsSlotByItem

The lowest slot containing the item.

```lua
exports["oph3z-inventory"]:GetFirstsSlotByItem(src, "bandage")
```

### GetItemsWeight

Current carry weight in grams.

```lua
exports["oph3z-inventory"]:GetItemsWeight(src)
```

### CanCarry

Would this amount still fit the weight limit.

```lua
exports["oph3z-inventory"]:CanCarry(src, "scrap_metal", 10)
```

### RegisterUsableItem

Callback when the item is used.

```lua
exports["oph3z-inventory"]:RegisterUsableItem("bandage", function(src, name, metadata) end)
```

### GenerateSerial

An unused serial number for non-weapon items.

```lua
exports["oph3z-inventory"]:GenerateSerial("phone")
```

### GetItemList

The full item definition table.

```lua
exports["oph3z-inventory"]:GetItemList()
```

### CheckItemValid

Does an item with this name exist.

```lua
exports["oph3z-inventory"]:CheckItemValid("water_bottle")
```

### GetItemLabel

The display label of an item.

```lua
exports["oph3z-inventory"]:GetItemLabel("water_bottle")
```

### GetInventory

A player's full inventory.

```lua
exports["oph3z-inventory"]:GetInventory(src) -- { items, hotbar, equipment }
```

### SetInventoryItems

Replaces the item list.

```lua
exports["oph3z-inventory"]:SetInventoryItems(src, items)
```

### LoadInventory

Makes sure the inventory is loaded, pushes the UI, returns it.

```lua
exports["oph3z-inventory"]:LoadInventory(src)
```

### SaveInventory

Force-saves to the database.

```lua
exports["oph3z-inventory"]:SaveInventory(src)
```

### ClearInventory

With a server id it wipes items, hotbar and equipment. With an identifier string it deletes ALL of that character's inventory data (pockets, confiscated, personal stashes, craft queues), works offline.

```lua
exports["oph3z-inventory"]:ClearInventory(src)
exports["oph3z-inventory"]:ClearInventory("license:ab12cd34")
```

### GetInventoryById

Any inventory by its id.

```lua
exports["oph3z-inventory"]:GetInventoryById("stash:evidence_locker")
-- { id, type, label, slots, maxWeight, grid, weight, cold, items, hotbar, equipment }
```

### GetStashItems

A stash's item array.

```lua
exports["oph3z-inventory"]:GetStashItems("evidence_locker")
```

### UpdateStash

Replaces stash contents, live for anyone looking at it.

```lua
exports["oph3z-inventory"]:UpdateStash("evidence_locker", items)
```

### RegisterStash

Registers a stash at runtime.

```lua
exports["oph3z-inventory"]:RegisterStash("apartment_5", { label = "Apartment", slots = 30, maxWeight = 60000 })
```

### MoveItem

Moves one item between any two inventories, offline included, metadata intact. Validates weight and space, restores on failure.

```lua
exports["oph3z-inventory"]:MoveItem(src, 3, "stash:evidence_locker")
```

### AddItemTo

Adds an item directly into ANY inventory - stash, trunk, glovebox, drop or player. Uses the `target` system from Addressing a single item, so offline inventories work too. Unique items get their serials, perishables start fresh, weight and space are validated.

```lua
exports["oph3z-inventory"]:AddItemTo("trunk:ABC123", "bandage", 5)
exports["oph3z-inventory"]:AddItemTo("stash:evidence", "weapon_pistol", 1, { evidence = "CASE-1042" })
```

### RemoveItemFrom

Removes an item from ANY inventory. With metadata only exactly matching items are taken, and removal spreads across stacks. Refused when the inventory does not hold enough.

```lua
exports["oph3z-inventory"]:RemoveItemFrom("stash:evidence", "weapon_pistol", 1)
exports["oph3z-inventory"]:RemoveItemFrom("trunk:ABC123", "cloth", 3, { dyed = "red" })
```

### CreateDrop

Creates a ground drop from a script - loot, airdrops, death scripts. Returns the drop id, which works as a `target` for the other exports.

```lua
exports["oph3z-inventory"]:CreateDrop(vector3(250.5, 350.5, 10.0), {
    { name = "cloth", amount = 5 },
    { name = "weapon_pistol", amount = 1, metadata = { durability = 60 } }
}, "Airdrop")
```

### OpenInventory

Opens an inventory for a player from the server: no id = their own inventory, a stash id opens that stash (created on the fly with the optional `data` capacity table).

```lua
exports["oph3z-inventory"]:OpenInventory(src)
exports["oph3z-inventory"]:OpenInventory(src, "gang_stash", { label = "Gang Stash", slots = 30, maxWeight = 60000 })
```

### OpenInventoryById

Opens another player's inventory for a player from the server.

```lua
exports["oph3z-inventory"]:OpenInventoryById(src, targetSrc)
```

### OpenShop

Opens a shop for a player from the server, by its id from `config/shops.lua`.

```lua
exports["oph3z-inventory"]:OpenShop(src, "ammunation")
```

### CloseInventory

Force-closes a player's inventory from the server.

```lua
exports["oph3z-inventory"]:CloseInventory(src)
```

### ConfiscateInventory

Moves everything into `confiscated:<identifier>`.

```lua
exports["oph3z-inventory"]:ConfiscateInventory(src)
```

### ReturnInventory

Gives a confiscated inventory back.

```lua
exports["oph3z-inventory"]:ReturnInventory(src)
```

### WipeOnDeath

Wipes the inventory except `Config.KeepOnDeath` items and money. Call it on death or respawn.

```lua
exports["oph3z-inventory"]:WipeOnDeath(src)
```

### GetMetadata

An item's metadata, as a copy. The metadata and freshness exports all take the `target` + `ref` pair explained in Addressing a single item.

```lua
exports["oph3z-inventory"]:GetMetadata(src, 3)
```

### SetMetadata

Replaces the whole metadata table. `SetItemMetaData` is the same export under another name.

```lua
exports["oph3z-inventory"]:SetMetadata(src, 3, { evidence = "CASE-1042" })
```

### PatchMetadata

Merges keys into the metadata, leaving durability, freshness and ammo alone. Pass `"__nil__"` as a value to delete a key. Returns the new metadata.

```lua
exports["oph3z-inventory"]:PatchMetadata(src, 3, { evidence = "CASE-1042" })
```

### SearchMetadata

Every item anywhere with that metadata key (and value, if given). Throttled by `Config.MetadataSearch`, second return says whether the result came from cache.

```lua
exports["oph3z-inventory"]:SearchMetadata("evidence", "CASE-1042")
```

### FindSerial

Finds a serial in the live cache.

```lua
exports["oph3z-inventory"]:FindSerial("PIS-0A3F91") -- { inventory, item }
```

### RegisterColdStorage

Marks an inventory as cold storage.

```lua
exports["oph3z-inventory"]:RegisterColdStorage("apartment_fridge_5", 0.2)
```

### RemoveColdStorage

Back to normal decay speed.

```lua
exports["oph3z-inventory"]:RemoveColdStorage("apartment_fridge_5")
```

### SetColdMultiplier

Changes the rate at runtime (power cuts, broken fridges).

```lua
exports["oph3z-inventory"]:SetColdMultiplier("apartment_fridge_5", 1.0)
```

### GetColdStorage

A cold storage's current state.

```lua
exports["oph3z-inventory"]:GetColdStorage("apartment_fridge_5") -- { id, cold, multiplier, rate }
```

### GetFreshness

An item's remaining freshness.

```lua
exports["oph3z-inventory"]:GetFreshness(src, 3) -- { percent, stage, seconds, hours, shelfLife, cold }
```

### SetFreshness

Sets an item's remaining freshness to an exact percent.

```lua
exports["oph3z-inventory"]:SetFreshness(src, 3, 80)
```

### AddFreshness

Shifts an item's remaining freshness up or down.

```lua
exports["oph3z-inventory"]:AddFreshness(src, 3, 25)
```

### Disarm

Removes the drawn weapon.

```lua
exports["oph3z-inventory"]:Disarm(src)
```

### InspectWeapon

The weapon the player is holding, or `nil` if unarmed. `serial` is `nil` when it has been filed off.

```lua
exports["oph3z-inventory"]:InspectWeapon(src)
-- { name, label, serial, filed, durability, ammo, craftedBy, tint, attachments }
```

### FindWeaponBySerial

Looks a known serial up in that player's inventory.

```lua
exports["oph3z-inventory"]:FindWeaponBySerial(src, "PIS-0A3F91")
```

### IsSerialFiled

For metadata you already hold.

```lua
exports["oph3z-inventory"]:IsSerialFiled(metadata)
```

### SetWeaponsDisabled

Blocks or unblocks weapon equipping.

```lua
exports["oph3z-inventory"]:SetWeaponsDisabled(src, true)
```

### SetEquipment

Replaces the worn equipment table.

```lua
exports["oph3z-inventory"]:SetEquipment(src, { shirt = { name = "clothing_shirt", amount = 1, metadata = { drawable = 11, texture = 0, gender = "male" } } })
```

### GetEquipmentFor

A character's equipment by identifier, works offline.

```lua
exports["oph3z-inventory"]:GetEquipmentFor("license:ab12cd34")
```

### GetAppearanceModes

Which clothing modes are active.

```lua
exports["oph3z-inventory"]:GetAppearanceModes()
```

### WearClothingSet

Outfit reconcile: wears the pieces the player owns and reports what is missing.

```lua
exports["oph3z-inventory"]:WearClothingSet(src, wanted, atWardrobe)
-- { ok, missing = { { slot, label } } }
```

### GetWardrobeData

What the wardrobe screen shows.

```lua
exports["oph3z-inventory"]:GetWardrobeData(src, atWardrobe) -- { wearing, storage, bag, slots }
```

### Wardrobe actions

Move clothing pieces between worn, wardrobe storage and the bag: `WardrobeStoreWorn`, `WardrobeWearStored`, `WardrobeTakeToBag`, `WardrobeStoreFromBag` and `WardrobeWearFromBag`.

```lua
exports["oph3z-inventory"]:WardrobeStoreWorn(src, "shirt")
exports["oph3z-inventory"]:WardrobeWearStored(src, index, name)
exports["oph3z-inventory"]:WardrobeTakeToBag(src, index, name)
exports["oph3z-inventory"]:WardrobeStoreFromBag(src, index, name)
exports["oph3z-inventory"]:WardrobeWearFromBag(src, index, name, atWardrobe)
```

### Crafting XP and levels

Read and change crafting progress at a station: `GetCraftingXP`, `GetCraftingLevel`, `AddCraftingXP`, `RemoveCraftingXP` and `SetCraftingLevel`. Every crafting export accepts a server id or an identifier string, so offline characters work.

```lua
exports["oph3z-inventory"]:GetCraftingLevel(src, "workshop")
exports["oph3z-inventory"]:AddCraftingXP(src, "workshop", 50)
exports["oph3z-inventory"]:SetCraftingLevel(src, "workshop", 10)
```

### Recipes and blueprints

Recipe knowledge: `TeachRecipe`, `UnteachRecipe`, `HasLearnedRecipe`, `GetLearnedRecipes`, and `GiveBlueprint` for handing out a blueprint item for a recipe.

```lua
exports["oph3z-inventory"]:TeachRecipe(src, "workshop", "extended_clip")
exports["oph3z-inventory"]:HasLearnedRecipe(src, "workshop", "extended_clip")
exports["oph3z-inventory"]:GiveBlueprint(src, "workshop", "extended_clip", 1)
```

### Crafting skill tree

Skill points and nodes: `GetCraftingPoints`, `GrantCraftingPoints`, `HasCraftingNode`, `GetOwnedNodes`, and `ResetCraftingTree` which wipes the station's nodes and refunds the points.

```lua
exports["oph3z-inventory"]:GrantCraftingPoints(src, "workshop", 2)
exports["oph3z-inventory"]:HasCraftingNode(src, "workshop", "gunsmith")
exports["oph3z-inventory"]:ResetCraftingTree(src, "workshop")
```

### Notify

Shows an inventory toast.

```lua
exports["oph3z-inventory"]:Notify(src, { type = "success", message = "Done!" })
```

### StartTradeRequest

Sends a trade request from one player to another.

```lua
exports["oph3z-inventory"]:StartTradeRequest(src, targetSrc)
```

### IsTrading

True while the player is in an active trade.

```lua
exports["oph3z-inventory"]:IsTrading(src)
```

### Addressing a single item

The newer exports (`GetMetadata`, `PatchMetadata`, `MoveItem`, `GetFreshness`, ...) all take the same `target` + `ref` pair, so a script can reach any item anywhere without knowing how inventories are stored.

**`target`** - a player server id (number), or an inventory id (string): `"player:<identifier>"`, `"stash:<id>"`, `"container:<id>"`, `"trunk:<plate>"`, `"glovebox:<plate>"`, `"drop:<id>"`, `"confiscated:<identifier>"`, `"wardrobe:<identifier>"`. Offline characters work - the record is loaded from the database on demand.

**`ref`** - a slot number, a serial string, or a table: `{ type = "player"|"hotbar"|"equipment", slot = 3 }`, `{ type = "hotbar", index = 0 }`, `{ type = "equipment", eq = "bag" }`, `{ x = 2, y = 1 }` in grid mode, or `{ serial = "PIS-0A3F91" }`.

```lua
-- tag the pistol in a player's third slot without touching durability or attachments
exports["oph3z-inventory"]:PatchMetadata(source, 3, { evidence = "CASE-1042", locked = "Held as evidence" })

-- same thing addressed by serial, in an offline character's stash
exports["oph3z-inventory"]:PatchMetadata("stash:evidence_locker", { serial = "PIS-0A3F91" }, { evidence = "CASE-1042" })

-- move it into the evidence locker, whether or not the owner is online
exports["oph3z-inventory"]:MoveItem(source, 3, "stash:evidence_locker")

-- find everything tagged with that case
exports["oph3z-inventory"]:SearchMetadata("evidence", "CASE-1042")
```

**Locking an item** - set `metadata.locked` and the move engine refuses to move, drop, split, give, trade or unequip it, with the reason shown to the player. A string is the displayed reason, `true` uses a generic one. Clear it with `PatchMetadata(target, ref, { locked = "__nil__" })`.
