# Item Setup

***

### Overview

X8-Stash uses a single inventory item — `portable_safe` — to power the portable safe feature. Players can carry, drop, and pick up this item, and each one is uniquely tied to a specific vault through metadata.

The item must be registered in your inventory before the script can use it. The setup differs slightly between **ox\_inventory** and **qb-inventory**.

***

### ox\_inventory Setup

#### Step 1 — Register the Item

Open the file:

```
ox_inventory/data/items.lua
```

Add the following entry anywhere in the items table:

```lua
['portable_safe'] = {
    label       = 'Portable Safe',
    weight      = 5000,
    stack       = false,
    close       = true,
    description = 'A portable personal safe linked to your CitizenID.',
    client      = {
        export = 'X8-stash.usePortable'
    }
},
```

#### Field Reference

| Field           | Value                    | Purpose                                             |
| --------------- | ------------------------ | --------------------------------------------------- |
| `label`         | `'Portable Safe'`        | Display name shown in the inventory                 |
| `weight`        | `5000`                   | Weight in grams (5kg per safe)                      |
| `stack`         | `false`                  | Prevents stacking — each safe is unique             |
| `close`         | `true`                   | Closes the inventory when the item is used          |
| `description`   | string                   | Tooltip shown on hover                              |
| `client.export` | `'X8-stash.usePortable'` | The client-side export called when the item is used |

#### Step 2 — Restart Resources

```
restart ox_inventory
restart x8-stash
```

That's it. ox\_inventory will pick up the new item automatically and route the use action to the X8-Stash export.

> The export `X8-stash.usePortable` is registered automatically by the script. You don't need to add anything else.

***

### qb-inventory Setup

#### Step 1 — Register the Item

Open the file:

```
qb-core/shared/items.lua
```

Add the following entry inside `QBShared.Items`:

```lua
['portable_safe'] = {
    name        = 'portable_safe',
    label       = 'Portable Safe',
    weight      = 5000,
    type        = 'item',
    image       = 'safe.png',
    unique      = true,
    useable     = true,
    shouldClose = true,
    description = 'Portable personal safe.'
},
```

#### Field Reference

| Field         | Value             | Purpose                                                    |
| ------------- | ----------------- | ---------------------------------------------------------- |
| `name`        | `'portable_safe'` | Internal item name (must match `Config.Portable.itemName`) |
| `label`       | `'Portable Safe'` | Display name                                               |
| `weight`      | `5000`            | Weight in grams                                            |
| `type`        | `'item'`          | Standard item type                                         |
| `image`       | `'safe.png'`      | Inventory icon filename                                    |
| `unique`      | `true`            | Each safe is unique                                        |
| `useable`     | `true`            | Allows the player to "use" the item from inventory         |
| `shouldClose` | `true`            | Closes the inventory when used                             |
| `description` | string            | Tooltip text                                               |

#### Step 2 — Add the Item Image

Place an image named `safe.png` (or whatever you set in the `image` field) into:

```
qb-inventory/html/images/safe.png
```

Recommended size: **100×100 PNG** with a transparent background.

#### Step 3 — Register the Use Callback

qb-inventory does not auto-route item usage like ox\_inventory does. You need to register a use callback on the **server side**.

Open any server file in your script (or create a new one) and add:

```lua
QBCore.Functions.CreateUseableItem("portable_safe", function(source, item)
    TriggerClientEvent('custom-stash:client:usePortable', source, item.info or item.metadata)
end)
```

> If you're not sure where to place this, the X8-Stash server folder is the right location. Add it to a file that loads after `qb-core` is initialized.

#### Step 4 — Restart Resources

```
restart qb-core
restart qb-inventory
restart x8-stash
```

***

### Verifying the Setup

After installation, test that the item works:

1. Give yourself a portable safe with the admin command:

   ```
   /givevault <your_id>
   ```
2. Open your inventory — you should see the **Portable Safe** item
3. Use the item — the placement target should appear in front of you
4. Place the safe — a 3D safe object should spawn
5. Open it — the stash should open with the configured slots and weight
6. Pick it back up — the item should return to your inventory

If any step fails, check the troubleshooting section below.

***

### Troubleshooting

#### Item doesn't appear in inventory after `/givevault`

* Confirm the item name in `Config.Portable.itemName` matches exactly what you registered (`portable_safe` by default)
* Restart `ox_inventory` or `qb-core` after adding the item
* Check the server console for errors when running the give command

#### Using the item does nothing (ox\_inventory)

* Verify the export name is `X8-stash.usePortable` (case-sensitive)
* Check that x8-stash started without errors
* Look for the export registration in the x8-stash console output

#### Using the item does nothing (qb-inventory)

* Confirm `useable = true` is set in the item definition
* Confirm the `CreateUseableItem` callback is registered server-side
* Check that the event name in the trigger matches the script's listener (`custom-stash:client:usePortable`)
* Restart qb-core after editing `shared/items.lua`

#### Image is missing in qb-inventory

* The image must be exactly `safe.png` (or match the `image` field)
* Place it in `qb-inventory/html/images/`
* Clear the inventory cache and restart qb-inventory

#### Item weight feels wrong

* The weight is in **grams**, not kilograms
* `5000` = 5kg
* Lower it if portable safes feel too heavy in your economy

#### Multiple safes show the same data

* Confirm `unique = true` (qb) or `stack = false` (ox)
* If safes are stacking, the metadata is being lost — they must be unique items

***

### Customization

#### Change the Item Name

If you want to rename the item from `portable_safe` to something else:

1. Edit the item entry in your inventory (change the key)
2. Edit `Config.Portable.itemName` to match
3. If you're on qb-inventory, update the `CreateUseableItem` line to use the new name
4. Restart all affected resources

#### Change the Weight

Edit the `weight` field in the item definition. Remember it's in grams.

| Value   | In Game        |
| ------- | -------------- |
| `1000`  | 1 kg           |
| `5000`  | 5 kg (default) |
| `10000` | 10 kg          |
| `25000` | 25 kg (heavy)  |

#### Custom Description

Edit the `description` field. This text appears on hover/tooltip in both inventory systems.

```lua
description = 'A reinforced steel safe. Feels heavy. Smells like secrets.'
```

***

### Notes

* The item is **stackable disabled** by design — each safe must be unique to track its bound vault
* Metadata persists across server restarts as long as the inventory system supports persistent metadata (both ox and qb do by default)
* If a player loses their safe item (admin removes it, etc.), use the **management panel** → **Restore Item** action to give it back


---

# Agent Instructions: 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:

```
GET https://x8project.gitbook.io/x8project/projects/stash/item-setup.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
