# 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.


---

# 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://corex-zombies.gitbook.io/corex-docs/resources/systems/corex-inventory.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.
