> For the complete documentation index, see [llms.txt](https://coderanch-redm-store.gitbook.io/coderanch-redm-store-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://coderanch-redm-store.gitbook.io/coderanch-redm-store-docs/coderanch-vorp_inventory.md).

# CodeRanch - vorp\_inventory

This document covers installation notes, export usage, integration patterns, and the practical API surface exposed by this resource.

## Installation Summary

### Required startup order

```cfg
ensure oxmysql
ensure vorp_core
ensure vorp_progressbar
ensure vorp_inventory
```

### Notes

* `vorp_progressbar` is only needed if you use the repair flow
* The UI is already built in `ui/`
* The source UI lives in `web/`
* Slot and durability columns are auto-migrated on startup
* Craft stations can now be configured as plain points or NPC ped stations

## Resource Structure

* `client/exports.lua`\
  Main documented client export wrappers
* `client/services/NUIService.lua`\
  Inventory open/close/use behavior and additional client exports
* `server/services/inventoryApiService.lua`\
  Main server export surface
* `server/vorpInventoryApi.lua`\
  Deprecated compatibility wrapper export
* `shared/services/UtilityService.lua`\
  Shared utility functions and exports
* `shared/services/Regex.js`\
  Shared regex export

## Export Overview

### Client exports

Use these from another client resource with:

```lua
exports.vorp_inventory:exportName(...)
```

### Server exports

Use these from another server resource with:

```lua
exports.vorp_inventory:exportName(...)
```

### Shared exports

These are utility helpers available as resource exports and are intended for lightweight shared logic.

## Client Exports

### Inventory control

#### `openInventory()`

Opens the player's main inventory UI.

```lua
exports.vorp_inventory:openInventory()
```

#### `closeInventory()`

Closes the inventory UI.

```lua
exports.vorp_inventory:closeInventory()
```

#### `toggleInventory()`

Opens the inventory if closed, or closes it if already open.

```lua
exports.vorp_inventory:toggleInventory()
```

#### `isInventoryOpen()`

Returns `true` when the inventory is currently open on the client.

```lua
local isOpen = exports.vorp_inventory:isInventoryOpen()
```

#### `setInventoryDisabled(state)`

Disables or re-enables inventory opening on the client.

```lua
exports.vorp_inventory:setInventoryDisabled(true)
exports.vorp_inventory:setInventoryDisabled(false)
```

### Client item / weapon use

#### `useItem(data)`

Triggers the standard item-use flow.

Expected `data` shape:

```lua
{
    item = "consumable_raspberrywater",
    type = "item_standard",
}
```

Example:

```lua
exports.vorp_inventory:useItem({
    id = itemId,
    item = "consumable_raspberrywater",
    type = "item_standard"
})
```

#### `useWeapon(data)`

Triggers the weapon-equip/use flow for an inventory weapon entry.

Expected `data` shape:

```lua
{
    id = 123,
    type = "item_weapon"
}
```

Example:

```lua
exports.vorp_inventory:useWeapon({
    id = 123,
    type = "item_weapon"
})
```

### Client lookup helpers

#### `getWeaponDefaultWeight(hash)`

Returns the configured default weapon weight.

#### `getWeaponDefaultDesc(hash)`

Returns the configured default weapon description.

#### `getWeaponDefaultLabel(hash)`

Returns the configured default weapon label.

#### `getWeaponName(hash)`

Returns the configured weapon name from a hash.

#### `getWeaponsDefaultData(request)`

Returns default weapon data based on the request expected by the utility layer.

#### `getWeaponAmmoTypes(group)`

Returns ammo types for a weapon group.

#### `getAmmoLabel(ammo)`

Returns the label for an ammo type.

#### `getInventoryItem(name)`

Returns a client-side inventory item definition by name.

#### `getInventoryItems()`

Returns the client-side item definition table.

#### `getServerItem(data)`

Returns server item information resolved through the client utility bridge.

Example:

```lua
local item = exports.vorp_inventory:getInventoryItem("water")
if item then
    print(item.label)
end
```

## Server Exports

Many server exports can be used as direct-return helpers, but any export backed by async database queries should be treated as callback-friendly first. If an export accepts a callback in the signature, use the callback form when you are unsure.

## Deprecated compatibility export

### `vorp_inventoryApi()`

Returns the legacy compatibility API table from `server/vorpInventoryApi.lua`.

Example:

```lua
local Inventory = exports.vorp_inventory:vorp_inventoryApi()
Inventory.addItem(source, "water", 1)
```

Use direct exports when possible. The wrapper exists mainly for backward compatibility.

## Server Exports Reference

### Carry checks

#### `canCarryItems(source, amount)`

Checks whether the player can carry additional total item weight/count.

#### `canCarryItem(source, itemName, amount)`

Checks whether the player can carry a specific item amount.

Example:

```lua
if exports.vorp_inventory:canCarryItem(source, "water", 5) then
    exports.vorp_inventory:addItem(source, "water", 5)
end
```

#### `canCarryWeapons(source, amount, cb, weaponName)`

Checks whether the player can carry more weapons.

`weaponName` can be a weapon name or hash.

### Item registration / usable items

#### `registerUsableItem(name, callback)`

Registers an item use callback.

Callback receives:

```lua
{
    source = source,
    item = {
        id = itemId,
        item = "item_name",
        name = "item_name",
        label = "Item Label",
        metadata = {},
        count = 1,
        percentage = 100,
        isDegradable = false
    }
}
```

Example:

```lua
exports.vorp_inventory:registerUsableItem("bandage", function(data)
    local src = data.source
    local itemId = data.item.id
    TriggerClientEvent("my_resource:useBandage", src, itemId)
end)
```

#### `unRegisterUsableItem(name)`

Removes a previously registered usable item callback.

### Player item queries

#### `getUserInventoryItems(source)`

Returns the player's normal inventory items.

#### `getItemCount(source, cb, itemName, metadata, percentage)`

Returns item count.

Notes:

* `metadata` narrows to matching metadata
* `percentage` is relevant for degradable items

#### `getItemDB(itemName)`

Returns the base item definition from the database-backed item cache.

#### `getItemByName(source, itemName)`

Returns an item instance by name.

#### `getItemContainingMetadata(source, itemName, metadata)`

Returns the first item containing the provided metadata subset.

#### `getItemMatchingMetadata(source, itemName, metadata)`

Returns the first item matching merged metadata exactly in the inventory search flow.

#### `getItemByMainId(source, itemId)`

Returns a single inventory item entry by its main inventory id.

#### `getItem(source, itemName, metadata)`

General item lookup helper. Use this for metadata-aware item retrieval.

Example:

```lua
local lockpick = exports.vorp_inventory:getItem(source, "lockpick")
if lockpick then
    print(lockpick.name, lockpick.count)
end
```

### Player item mutations

#### `addItem(source, name, amount, metadata, cb, allow, degradation, percentage)`

Adds an item to the player's default inventory.

Common use:

```lua
exports.vorp_inventory:addItem(source, "water", 2)
exports.vorp_inventory:addItem(source, "document", 1, {
    label = "Signed Contract",
    description = "Property transfer papers"
})
```

#### `subItem(source, name, amount, metadata, cb, allow, percentage)`

Removes item amount from the player's default inventory.

#### `subItemID(source, itemId, cb, allow, amount)`

Removes an item by its exact item id.

Alias also available:

#### `subItemById(source, itemId, cb, allow, amount)`

#### `setItemMetadata(source, itemId, metadata, amount, cb)`

Updates item metadata. This is especially useful for unique items, notes, licenses, recipes, or custom descriptions.

Example:

```lua
local item = exports.vorp_inventory:getItemByMainId(source, itemId)
if item then
    exports.vorp_inventory:setItemMetadata(source, itemId, {
        label = "Deputy Badge",
        description = "Issued by the Valentine sheriff office",
        badgeNumber = "VAL-014"
    })
end
```

### Weapon queries

#### `getUserWeapon(source, weaponId)`

Returns one weapon entry.

#### `getUserInventoryWeapons(source)`

Returns all player weapons.

#### `getWeaponBullets(source, weaponId)`

Returns stored ammo data for a weapon.

#### `getWeaponComponents(source, weaponId)`

Returns saved weapon components.

### Weapon mutations

#### `createWeapon(source, weaponName, ammos, components, comps, cb, wepId, customSerial, customLabel, customDesc)`

Creates/registers a weapon for the player.

Minimal example:

```lua
local weaponId = exports.vorp_inventory:createWeapon(
    source,
    "WEAPON_REVOLVER_CATTLEMAN",
    {},
    {},
    {},
    nil,
    nil,
    "SERIAL-1001",
    "Marshal Revolver",
    "Custom issue sidearm"
)
```

#### `giveWeapon(source, weaponId, target)`

Transfers a weapon from one player to another.

#### `subWeapon(source, weaponId)`

Removes/subtracts a weapon from the player.

#### `deleteWeapon(source, weaponId)`

Deletes a weapon record.

#### `setWeaponCustomLabel(weaponId, label)`

Sets a weapon custom label.

#### `setWeaponSerialNumber(weaponId, serial)`

Sets a weapon serial number.

#### `setWeaponCustomDesc(weaponId, desc)`

Sets a weapon custom description.

### Ammo exports

#### `getUserAmmo(source)`

Returns the player's saved ammo table.

#### `addBullets(source, bulletType, amount)`

Adds ammo to the player.

#### `subBullets(weaponId, bulletType, amount)`

Subtracts ammo from a weapon flow.

#### `removeAllUserAmmo(source)`

Clears all user ammo.

Example:

```lua
exports.vorp_inventory:addBullets(source, "ammorevolvernormal", 24)
```

### Custom inventory registration and control

#### `registerInventory(data)`

Registers a custom inventory.

Common fields:

```lua
{
    id = "my_stash",
    name = "My Stash",
    limit = 50,
    acceptWeapons = true,
    shared = false,
    ignoreItemStackLimit = false,
    whitelistItems = false,
    UsePermissions = false,
    UseBlackList = false,
    whitelistWeapons = false,
    useWeight = false,
    weight = 0.0
}
```

Example:

```lua
exports.vorp_inventory:registerInventory({
    id = "smithy_storage",
    name = "Smithy Storage",
    limit = 80,
    acceptWeapons = true,
    shared = true,
    ignoreItemStackLimit = false,
    whitelistItems = false,
    UsePermissions = false,
    UseBlackList = false,
    whitelistWeapons = false
})
```

#### `removeInventory(id)`

Unregisters a custom inventory.

#### `openInventory(source, id)`

Opens:

* the main inventory if `id` is omitted
* the custom inventory if `id` is provided

Examples:

```lua
exports.vorp_inventory:openInventory(source)
exports.vorp_inventory:openInventory(source, "smithy_storage")
```

#### `closeInventory(source, id)`

Closes the inventory for the player. If `id` is passed, it closes the custom inventory flow.

#### `isCustomInventoryRegistered(id)`

Returns whether a custom inventory is already registered.

#### `getCustomInventoryData(id)`

Returns the registration/config data for a custom inventory.

#### `updateCustomInventoryData(id, data)`

Updates registration/config data for a custom inventory.

### Custom inventory permissions and limits

#### `AddPermissionMoveToCustom(id, jobName, grade)`

Allows a job/grade to move items into a custom inventory.

#### `AddPermissionTakeFromCustom(id, jobName, grade)`

Allows a job/grade to take items from a custom inventory.

#### `AddCharIdPermissionMoveToCustom(id, charId, state)`

Allows a specific character id to move items into a custom inventory.

`state` can be used to add, remove, or update temporary char-based permission handling.

#### `AddCharIdPermissionTakeFromCustom(id, charId, state)`

Allows a specific character id to take items from a custom inventory.

#### `BlackListCustomAny(id, itemName)`

Blacklists an item from a custom inventory.

#### `updateCustomInventorySlots(id, slots)`

Updates custom inventory slot capacity.

#### `getCustomInventorySlots(id)`

Returns custom inventory slot capacity.

#### `setCustomInventoryItemLimit(id, itemName, limit)`

Sets the max amount of one item name allowed inside that custom inventory.

#### `setCustomInventoryWeaponLimit(id, weaponName, limit)`

Sets the max amount of one weapon type allowed inside that custom inventory.

### Custom inventory contents

#### `addItemsToCustomInventory(id, items, charid, callback, identifier)`

Adds items directly into a custom inventory.

`items` format:

```lua
{
    { name = "water", amount = 10, metadata = {} },
    { name = "bread", amount = 5, metadata = {} }
}
```

Example:

```lua
exports.vorp_inventory:addItemsToCustomInventory("smithy_storage", {
    { name = "iron", amount = 20 },
    { name = "wood", amount = 10 }
}, charId)
```

#### `addWeaponsToCustomInventory(id, weapons, charid)`

Adds weapons to a custom inventory.

#### `getCustomInventoryItemCount(id, itemName, itemCraftedId, callback, metadata)`

Returns the amount of an item inside a custom inventory.

#### `getCustomInventoryWeaponCount(id, weaponName)`

Returns the amount of a weapon inside a custom inventory.

#### `removeItemFromCustomInventory(id, itemName, amount, itemCraftedId)`

Removes item quantity from a custom inventory.

#### `removeWeaponFromCustomInventory(id, weaponName)`

Removes a weapon by weapon name from a custom inventory.

#### `removeCustomInventoryWeaponById(id, weaponId)`

Removes a weapon by exact weapon id from a custom inventory.

#### `getCustomInventoryItems(id)`

Returns all normal items in a custom inventory.

#### `getCustomInventoryWeapons(id)`

Returns all weapons in a custom inventory.

#### `updateCustomInventoryItem(id, itemId, metadata, amount, callback, identifier)`

Updates a custom inventory item record.

#### `deleteCustomInventory(id)`

Clears cached and stored custom inventory contents.

## Open Player Inventory Export

### `openPlayerInventory(data, callback)`

Opens another player's inventory through the built-in player inventory flow.

Expected `data` shape:

```lua
{
    title = "Player Search",
    source = source,
    target = targetSource,
    blacklist = {},
    timeout = 30,
    itemsLimit = {
        items = {
            itemType = "item_standard",
            limit = 10
        },
        weapons = {
            itemType = "item_weapon",
            limit = 1
        }
    }
}
```

This is an advanced flow used by scripts that need controlled player-to-player inventory access.

## Shared Exports

### `checkRegex(regex, str)`

Regex validation helper from `shared/services/Regex.js`.

Example:

```lua
local ok = exports.vorp_inventory:checkRegex("^[0-9]+$", "12345")
```

### `tableEquals(a, b, ignore_mt)`

Deep table equality helper.

### `tableContains(a, b)`

Returns `true` when table `a` contains the key/value structure of table `b`.

### `mergeTables(a, b)`

Merges two tables or JSON-like payloads into a Lua table.

Example:

```lua
local merged = exports.vorp_inventory:mergeTables(
    { label = "License" },
    { owner = "John Marston" }
)
```

### `isValueInArray(value, array)`

Simple array membership helper.

## Common Integration Recipes

{% stepper %}
{% step %}

### Register a stash from another resource

```lua
exports.vorp_inventory:registerInventory({
    id = "doctor_storage",
    name = "Doctor Storage",
    limit = 100,
    acceptWeapons = false,
    shared = true,
    ignoreItemStackLimit = false,
    whitelistItems = false,
    UsePermissions = true,
    UseBlackList = false,
    whitelistWeapons = false
})

exports.vorp_inventory:AddPermissionMoveToCustom("doctor_storage", "doctor", 0)
exports.vorp_inventory:AddPermissionTakeFromCustom("doctor_storage", "doctor", 0)
```

{% endstep %}

{% step %}

### Open that stash for a player

```lua
exports.vorp_inventory:openInventory(source, "doctor_storage")
```

{% endstep %}

{% step %}

### Add a metadata-driven document

```lua
exports.vorp_inventory:addItem(source, "document", 1, {
    label = "Business Contract",
    description = "Signed by both parties",
    contractId = "CNT-204"
})
```

{% endstep %}

{% step %}

### Check and remove a required ingredient

```lua
local count = exports.vorp_inventory:getItemCount(source, nil, "water")
if count >= 2 then
    exports.vorp_inventory:subItem(source, "water", 2)
end
```

{% endstep %}

{% step %}

### Create a custom weapon reward

```lua
local created = exports.vorp_inventory:createWeapon(
    source,
    "WEAPON_REVOLVER_CATTLEMAN",
    {},
    {},
    {},
    nil,
    nil,
    "EVENT-001",
    "Prize Revolver",
    "Awarded to the tournament winner"
)
```

{% endstep %}
{% endstepper %}

## Crafting Notes

* Recipes are stored in `config/craft.lua`
* Craft workspace contents are saved in `craft_inventories.json`
* Crafting stations are prompt-driven
* Each craft location can be a normal no-ped station or an NPC ped station
* The resource checks recipe completion against current craft slots before allowing crafting

### Craft station config format

Basic no-ped station:

```lua
Config.CraftLocations = {
    {
        coord = vector3(-369.51, 796.07, 116.2),
        label = "Craft Station",
        interactDistance = 2.0,
    }
}
```

NPC ped station:

```lua
Config.CraftLocations = {
    {
        coord = vector3(-365.12, 792.84, 116.18),
        label = "Camp Cook",
        interactDistance = 2.0,
        ped = {
            enabled = true,
            model = "U_M_M_NbxGeneralStoreOwner_01",
            heading = 180.0,
            scenario = "WORLD_HUMAN_SMOKE",
        }
    }
}
```

Supported craft location fields:

* `coord`\
  Base interaction position for the craft station
* `label`\
  Prompt group label shown to the player
* `interactDistance`\
  Distance required to interact with the station
* `ped.enabled`\
  Set `true` to spawn an NPC crafter at that location
* `ped.model`\
  Ped model name or hash
* `ped.heading`\
  Ped heading
* `ped.scenario`\
  Optional idle scenario
* `ped.coords`\
  Optional separate ped spawn position if you do not want the NPC exactly on the interaction point

## Stash Notes

* Config stashes are auto-registered on server start
* Job checks for config stashes are handled in `server/server.lua`
* You can also register additional inventories dynamically through exports

## Durability Notes

* Durability data is stored per weapon
* Weapon repair uses repair locations defined in `config/config.lua`
* Repair flow depends on `vorp_progressbar`

## Best Practice Notes

* Prefer exports over directly editing core inventory logic
* Use metadata for unique items instead of making many duplicate item names
* Use `registerUsableItem` for gameplay interactions
* Use custom inventories for businesses, jobs, wagons, housing, or mission containers
* Keep `DevMode` disabled on live servers

## Troubleshooting

### Inventory opens but items are missing

* Check your database `items` table
* Confirm item names match what other scripts are adding
* Confirm item images exist if the UI appears blank for those items

### Repair does not work

* Confirm `vorp_progressbar` is running
* Confirm durability is enabled in config
* Confirm repair locations are configured

### Custom inventory will not open

* Confirm it was registered first
* Confirm another player is not already using it
* Confirm permission settings are not blocking access

### Shared/client export call fails

* Confirm the resource name is exactly `vorp_inventory`
* Confirm your call is made from the correct side
* Confirm your script starts after this resource


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://coderanch-redm-store.gitbook.io/coderanch-redm-store-docs/coderanch-vorp_inventory.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
