> For the complete documentation index, see [llms.txt](https://atiysus-organization.gitbook.io/aty-scripts/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://atiysus-organization.gitbook.io/aty-scripts/inventory/features/consumables-and-portions.md).

# Consumables & Portions

## Consumables & Portions

#### Effects

An item's `effect` is what using it does.

```lua
burger = {
    label    = 'Burger',
    weight   = 700,
    useTime  = 2500,
    effect   = { hunger = 25 },
}
```

Effects are applied by the server when the use **completes**. A cancelled animation applies nothing.

`anim` names the clip from `Config.Anim` (`eat`, `drink`, `bandage`, `pill`, ...). The clip carries a default object for the hand; an item that looks like something else names its own with `prop`, and only the object changes:

```lua
cola   = { effect = { thirst = 22, anim = 'drink', prop = 'prop_ecola_can' } },
coffee = { effect = { thirst = 15, anim = 'drink', prop = 'p_amb_coffeecup_01' } },
```

`prop` can also be a table — `{ model = ..., bone = ..., offset = vector3(...), rot = vector3(...) }` — for a model whose origin sits differently in the hand. Props hang off `PH_R_Hand` (bone 60309), the bone the game puts held objects on, and the shipped food and drink carry the position each was measured at.

Finding those numbers is a matter of looking, not arithmetic:

```
invprop <playerId> prop_ecola_can
```

puts the model in that player's hand with the clip running — arrows move, SHIFT rotates, CTRL for fine steps, ENTER prints the line to paste, both for `data/items.lua` and for the admin panel's **Held object** box.

#### Who runs an item

**A framework handler wins.** If qb has a `CreateUseableItem` for the item, that handler runs it end to end — its progress bar, its animation, its prop, its numbers, and its own `RemoveItem`. The inventory does not consume the item first and does not apply its own effect on top, even when `data/items.lua` describes the same name.

That is deliberate. Your framework's food, drink and medical items already work and your scripts are written around them; replacing their behaviour because this inventory happens to be installed is a change nobody asked for. The catalogue here describes items — it does not claim them.

Two things overrule a handler, and both are a decision somebody made on this server:

1. **A claim.** `RegisterUsable(name, ...)` from a resource that means to own the item.
2. **A takeover on the admin panel.** Set a **Use animation**, a **Held object** or an effect amount (**Hunger**, **Thirst**, **Health**, **Armour**) on the item screen, and the inventory runs that item from then on: its bar, its clip, its prop, its effect. Clear the fields to hand it back.

Items nothing else handles — the ones only this catalogue knows — are run here, because there is nobody else to run them.

```
invroute cola
[route] cola — Cola  (defined in data/items.lua)
   used by: the framework handler (its own bar, clip and prop)
   framework handler: yes, and it runs this item
```

`invroute <item>` answers the whole question for any item: who runs it, whether a handler exists and is being overruled, which clip and prop the player will see, and whether the item has a condition.

#### Portions

Off by default, as in ox\_inventory: with `Config.Portions.enabled = false` every item is worth exactly one use and `portions` is ignored. A unit that was already part-eaten when portions were turned off finishes on its next use. Turn it on to have bites:

```lua
Config.Portions = { enabled = true }
```

`portions = 4` means one burger is four bites. Each use spends one portion; the unit disappears when the last one is gone. Portions live on the unit's metadata, so a half-eaten burger stays half-eaten when it is traded or stored.

```lua
exports.aty_inventory:GetPortions(inv, slot)
exports.aty_inventory:TakePortion(inv, slot)
```

#### Use time and cancellation

`useTime` is how long the action bar runs. An item without one is used at once, with no bar, as ox\_inventory does without `usetime`. The shipped food, drink and bandage take 2.5 s and body armour 3.5 s, ox's own numbers. Two rules matter:

**The portion is spent at the end, never at the start.** A player who cancels half way through has not eaten anything.

**Cancelling actually cancels.** Dying, or the cancel key on an item that allows it, stops the action and nothing is applied. Following ox\_inventory, only an item that says `cancel = true` can be cancelled with the key (the shipped water does), and getting into a car no longer interrupts a use (`Config.Consume.cancelOnVehicle = false`).

`disable = { move = true, sprint = true, car = true, combat = true }` on an item is what the player cannot do while using it. Combat is off during every use unless the item says `combat = false`; the shipped bandage also stops you walking and driving. The table is handed to ox\_lib's or qb's bar when one draws the action, and applied by this inventory when it draws its own.

**Using an item closes the inventory**, as in ox\_inventory. An item that should leave it open says `close = false`; adopted items keep ox's `close` and qb's `shouldClose`. If you are extending this, make sure your handler answers the cancellation — a handler that ignores it produces the worst bug in this area: the progress bar disappears but the effect still lands.

```lua
exports.aty_inventory:StartConsume(src, slot)
exports.aty_inventory:CancelConsume(src)
exports.aty_inventory:IsConsuming(src)
```

**One bar, whoever draws it.** An item that the framework already has a handler for — a qb `CreateUseableItem` — is handed straight to that handler, with no action bar from the inventory first: qb handlers run their own progress bar, and running both showed two bars for one item. A handler registered through `RegisterUsable` is timed by the inventory as before; one that draws its own bar says so with `bar = false` and keeps the timing, the cancellation and the portion bookkeeping.

```lua
exports.aty_inventory:RegisterUsable('bandage', {
    useTime = 4000,
    bar     = false,   -- your own progress bar, on aty_inventory:consumeBegin
    use     = function(src, info) ... end,
})
```

#### Whose progress bar

A server that runs ox\_lib or qb's `progressbar` already has a bar its players know. By default every timed action here — eating, drinking, bandages, a body search, a timed reload — is drawn on that bar, with the same label, duration, animation and object in the hand.

```lua
Config.Consume.progress = 'auto'   -- 'auto' | 'ox_lib' | 'qb' | 'aty'
```

| Value            | Draws with                                                                                                         |
| ---------------- | ------------------------------------------------------------------------------------------------------------------ |
| `auto` (default) | ox\_lib when it is started, else qb's `progressbar` when qb-core and it are started, else this inventory's own bar |
| `ox_lib`         | ox\_lib's `progressBar`                                                                                            |
| `qb`             | qb's `progressbar`                                                                                                 |
| `aty`            | this inventory's own bar and animation                                                                             |

ox\_lib is not a dependency: it is only asked when it is running, and a provider that is named but not running falls back to `aty`. The other bar only decides when the client says it finished — the server still checks the time before anything is spent, and cancelling (the cancel key where the item allows it, dying) still spends nothing. The setting can be changed live from the admin panel's **Settings** tab.

#### Cooldowns

```lua
adrenaline = {
    cooldown = 120000,   -- two minutes between uses
}
```

Cooldowns are per player per item and are enforced on the server. The shipped items carry none, as ox\_inventory's do; the field is there for an item that needs one.

#### Custom usables

Register a handler for anything the built-in effects cannot express:

```lua
exports.aty_inventory:RegisterUsable('radio', function(src, info)
    -- info = { slot, name, label, metadata, spoiled, ... }
    TriggerClientEvent('my_radio:open', src)
end)
```

The item itself still has to say `usable = true`, or using it is refused before any handler is asked. Add `consume = false` when using it should not spend it — a radio, a phone.

A worked example ships in `examples/usable_handler.lua`.

{% hint style="warning" %}
`RegisterUsable` replaces any previous handler for that item name. Registering the same name from two resources means the later one wins; the console says which resource took it over. Use `invusables` to list what is currently registered.
{% endhint %}
