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

# corex-inventory

> Grid-based inventory. Items take shape (1×1, 2×1, 3×2…). Weight gates carry capacity. Drops are world-persistent within a decay window.

{% hint style="info" %}
**Required:** Strongly recommended · **Depends on:** `corex-core` · **Version:** `1.0.0`
{% endhint %}

## Quick Facts

| Dependencies | Server Exports | Client Exports | Events |
| ------------ | -------------- | -------------- | ------ |
| `corex-core` | 16             | 3              | 5+     |

## Overview

Full-featured inventory with a visual grid editor. Items have physical dimensions that must fit; weight has a hard cap. Dropped items become world entities with a configurable decay. Ships with a catalog system for items, weapons, and ammo, plus a shop layer.

## Quick Start

```cfg
ensure corex-core
ensure corex-notify
ensure corex-inventory
```

```lua
-- server
local ok = exports['corex-inventory']:AddItem(source, 'bandage', 3)
if exports['corex-inventory']:HasItem(source, 'bandage', 1) then
    exports['corex-inventory']:RemoveItem(source, 'bandage', 1)
end
```

## Configuration

| Key                          | Type      | Default     | Description                               |
| ---------------------------- | --------- | ----------- | ----------------------------------------- |
| `Config.Debug`               | `boolean` | `false`     | Debug logging                             |
| `Config.MaxWeight`           | `number`  | `200.0`     | Kg cap per player                         |
| `Config.GridWidth`           | `number`  | `8`         | Grid columns                              |
| `Config.GridHeight`          | `number`  | `10`        | Grid rows                                 |
| `Config.DefaultSize`         | `table`   | `{w=1,h=1}` | Default item footprint                    |
| `Config.DropExpireTime`      | `number`  | `1800`      | Seconds before a dropped item despawns    |
| `Config.EnableMarkers`       | `boolean` | `true`      | Show world markers for drops              |
| `Config.PropSyncRadius`      | `number`  | `50.0`      | World sync radius for drop props (meters) |
| `Config.PickupDistance`      | `number`  | `3.0`       | Max distance to pick up                   |
| `Config.GiveDistance`        | `number`  | `5.0`       | Max distance for player-to-player trade   |
| `Config.PropSyncInterval`    | `number`  | `10000`     | Ms between drop resync ticks              |
| `Config.MarkerRadius`        | `number`  | `15.0`      | Radius for full marker visibility         |
| `Config.MarkerCloseRange`    | `number`  | `5.0`       | Close-range marker intensification        |
| `Config.MarkerCacheInterval` | `number`  | `100`       | Ms between marker cache ticks             |

Item and weapon definitions live in `shared/items.lua` and `shared/weapons.lua`.

### Weapon Recoil System

`Config.Recoil` controls weapon recoil, screen shake, weapon kick animation, and attachment modifiers.

**Top-level:**

| Key                     | Default | Description                               |
| ----------------------- | ------- | ----------------------------------------- |
| `Config.Recoil.Enabled` | `true`  | Master toggle for the whole recoil system |

**Screen shake (`Config.Recoil.ScreenShake`):**

| Field       | Default | Description                 |
| ----------- | ------- | --------------------------- |
| `Enabled`   | `true`  | Toggle camera shake on fire |
| `Intensity` | `0.08`  | Shake strength              |
| `Duration`  | `70`    | Shake duration in ms        |

**Weapon kick (`Config.Recoil.WeaponKick`):**

| Field              | Default | Description               |
| ------------------ | ------- | ------------------------- |
| `Enabled`          | `true`  | Toggle weapon visual kick |
| `GlobalMultiplier` | `2.0`   | Scales all patterns       |
| `RecoverySpeed`    | `0.05`  | Return-to-center rate     |

**Patterns (`Config.Recoil.Patterns`)** — per-category recoil profile. Keys: `pistol`, `smg`, `rifle`, `shotgun`, `sniper`. Each profile:

| Field           | Description                                               |
| --------------- | --------------------------------------------------------- |
| `vertical`      | Vertical kick magnitude                                   |
| `horizontal`    | Horizontal drift magnitude                                |
| `kickVariation` | Randomness on each shot                                   |
| `recovery`      | Return-to-center factor (closer to 1.0 = slower recovery) |

Example — rifle default: `{ vertical = 0.28, horizontal = 0.14, kickVariation = 0.20, recovery = 0.93 }`.

**Attachment modifiers (`Config.Recoil.AttachmentModifiers`)** — multipliers applied when the attachment is equipped (< 1.0 reduces recoil):

| Attachment    | Multiplier |
| ------------- | ---------- |
| `grip`        | `0.65`     |
| `suppressor`  | `0.80`     |
| `compensator` | `0.60`     |
| `stock`       | `0.75`     |
| `heavybarrel` | `0.70`     |
| `muzzlebrake` | `0.68`     |

## Server Exports

### Catalog

* `GetItemsCatalog()` — full items table
* `GetWeaponsCatalog()` — full weapons table
* `GetAmmoCatalog()` — ammo definitions
* `GetFullCatalog()` — items + weapons + ammo combined
* `GetAllItemsData()` — same as `GetFullCatalog`; returns the merged table of items + weapons + ammo
* `GetItemData(itemName)` — single item definition
* `GetRarity()` — rarity tiers mapping

### Player inventory

* `GetInventory(source)` — full inventory table
* `AddItem(source, itemName, count, meta?)` — returns `ok, reason`
* `RemoveItem(source, itemName, count)` — returns `boolean`
* `HasItem(source, itemName, count?)` — returns `boolean`
* `GetItemCount(source, itemName)` — returns `number`

### Metadata on items

* `UpdateItemMeta(source, slot, meta)` — e.g. weapon durability
* `GetItemMeta(source, slot)`

### World drops

* `DropItem(source, itemName, count, coords?)` — creates a world drop
* `PickupItem(source, dropId)` — server-side validation + add

### Examples

```lua
-- Give a bandage to every player in a zone
for _, src in ipairs(exports['corex-core']:GetPlayersByState('active')) do
    exports['corex-inventory']:AddItem(src, 'bandage', 1)
end
```

```lua
-- Weapon with durability
exports['corex-inventory']:AddItem(source, 'WEAPON_PISTOL', 1, {
    durability = 100,
    serial = GenerateSerial(),
})
```

## Client Exports

* `OpenShop(shopId)` / `CloseShop()` — shop NUI
* `GetShopNPCs()` — list of nearby shopkeepers in range

## Events

{% hint style="warning" %}
Most `corex-inventory:*` events are **internal** net events (UI ↔ server RPCs). Prefer the exports above for integration. The full list lives in [API Reference → Events](https://github.com/ABUGIZA/corex-docs/blob/main/content/api-reference/events.md).
{% endhint %}

### Listens to

* `corex:server:playerReady` — load the inventory
* `playerDropped` (FiveM native) — save and clear

### Public hooks worth listening to

* `corex-inventory:client:update` — inventory state refreshed on the client
* `corex-inventory:client:useItem(itemName, slot)` — item was used; `corex-survival` hooks this for food/water

### Internal RPCs (do not trigger from third-party code)

* `corex-inventory:internal:addAmmo`
* `corex-inventory:internal:equipWeapon`
* `corex-inventory:internal:weaponDropped`

## StateBag Keys

None on players; drops are managed as world entities. Inventory contents live in a dedicated DB table and are fetched on demand.

## Database Schema

```sql
CREATE TABLE inventories (
    identifier  VARCHAR(60) PRIMARY KEY,
    items       LONGTEXT,   -- JSON: array of slot objects
    updated_at  TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```

Each slot:

```json
{
  "slot": 1,
  "name": "bandage",
  "count": 3,
  "x": 0, "y": 0, "w": 1, "h": 1,
  "meta": {}
}
```

## Troubleshooting

**"Inventory full" but UI shows empty slots.** → Check weight, not just slots. `Config.MaxWeight` caps total kg. Remove heavy items first.

**Dropped items vanish quickly.** → `Config.DropExpireTime`. Increase for late-retrieval, but be aware of memory cost.

**Items not syncing between players near a drop.** → `Config.PropSyncRadius` is too small for your scene. Increase cautiously — bigger radius = more network.

**Weapon durability resets on pickup.** → You're not preserving `meta` on `DropItem` / `PickupItem`. Pass through the slot's meta object.
