# corex-loot

> Defines lootable world containers (police lockers, medical cabinets, military crates, storage boxes) with per-type loot tables. Fixed spawn locations set in config.

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

## Quick Facts

| Dependencies                    | Server Exports | Container types | Events |
| ------------------------------- | -------------- | --------------- | ------ |
| `corex-core`, `corex-inventory` | 3              | 4               | 3      |

## Overview

Loot containers are fixed world entities defined in `Config.Locations`. Each container has a type (`police`, `medical`, `military`, `house`) which determines its model, search time, and loot pool. Respawn is random between `minTime` and `maxTime` seconds after looting.

## Quick Start

```cfg
ensure corex-core
ensure corex-inventory
ensure corex-loot
```

## Configuration

### Global defaults

| Key                             | Default            | Description                          |
| ------------------------------- | ------------------ | ------------------------------------ |
| `Config.Debug`                  | `false`            | Enable verbose loot-pipeline logging |
| `Config.ItemsPerContainer`      | `{ min=2, max=5 }` | Random item count per container      |
| `Config.Respawn.minTime`        | `900`              | Seconds min before respawn           |
| `Config.Respawn.maxTime`        | `1800`             | Seconds max before respawn           |
| `Config.Reveal.itemRevealDelay` | `1800`             | Ms before items appear after search  |
| `Config.Reveal.searchAnimDict`  | `'mini@repair'`    | Search animation dict                |
| `Config.Reveal.searchAnim`      | `'fixing_a_ped'`   | Search animation name                |

### Container types

`Config.ContainerTypes` defines the four built-in container styles:

| Type       | Model                | Search time | Icon               |
| ---------- | -------------------- | ----------- | ------------------ |
| `police`   | `prop_mil_crate_01`  | 4000 ms     | `fa-shield-halved` |
| `medical`  | `prop_med_bag_01b`   | 3000 ms     | `fa-kit-medical`   |
| `military` | `prop_box_ammo07a`   | 5000 ms     | `fa-crosshairs`    |
| `house`    | `prop_cs_cardbox_01` | 2000 ms     | `fa-box-open`      |

Each entry also has `label`, `interactLabel`, `interactDistance`, and a `blip` definition (sprite, color, scale, label).

### Loot tables

`Config.LootTables` is keyed by container type. Each is an array of weighted rarity tiers:

```lua
Config.LootTables = {
    police = {
        { chance = 0.45, items = { { name='pistol_ammo', min=5, max=15 }, ... } },
        { chance = ..., items = { ... } },
    },
    medical = { ... },
    military = { ... },
    house = { ... },
}
```

### Locations

`Config.Locations` is an array of container placements:

```lua
{ type = 'police', coords = vec3(..), heading = 90.0 },
```

Each entry maps a world position to a container type. The type determines both the visual prop and the loot pool.

## Server Exports

### `RegisterDynamicContainer(containerId, items, options)`

Spawn a one-off container for an event or quest reward.

```lua
local id = exports['corex-loot']:RegisterDynamicContainer('my-event-crate', {
    { item = 'WEAPON_PISTOL', count = 1 },
    { item = 'pistol_ammo', count = 30 },
}, {
    coords = vec3(1200, -450, 35.5),
})
```

### `UnregisterDynamicContainer(containerId)`

Despawns a dynamic container immediately.

### `DynamicContainerHasItems(containerId)`

Returns `true` if any items remain uncollected.

## Events

Server-side (net → server):

* `corex-loot:server:requestContainer` — client opens a container
* `corex-loot:server:takeItem` — client takes an item
* `corex-loot:server:closeContainer` — client closes the UI

Client-side (server → client):

* `corex-loot:client:containerOpened` — server granted the open request
* `corex-loot:client:containerClosed` — close confirmation
* `corex-loot:client:searchContainer` — start the search animation
* `corex-loot:client:searchFailed` — search was interrupted
* `corex-loot:client:takeResult` — result of a take attempt

{% hint style="info" %}
High-level "container emptied" signals are not emitted as events. Observe state via the `DynamicContainerHasItems(id)` export.
{% endhint %}

## Troubleshooting

**Containers always have the same items.** → RNG seed reused. Ensure `math.randomseed(os.time())` runs on boot.

**Dropped items from zombies don't appear as loot containers.** → `corex-zombies` has its own loot drop system (`Config.LootSystem` in that resource). `corex-loot` handles **world-placed** containers only.

**Respawn cadence broken after restart.** → By design — container state is not persisted across restarts. For persistence, store runtime state in metadata or a dedicated table.

**Adding a new container type.** → Extend `Config.ContainerTypes` with your type definition, add a matching `Config.LootTables[<yourType>]`, then reference it from `Config.Locations`.


---

# 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/world/corex-loot.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.
